SPI problem Specifically about SPIDR

Started by amit shrigondekar April 14, 2010
Hi everyone ..
I have a problem with SPI bus and I have pasted belowinit functions
for master and slave.

if any body had the same problem, kindly let me know how to get around that.

Problem:
1) when I read SPIDR register it gives me random values and once in a
while correct value

2) Also it does not copy any value in the arr[] it just copies first
location in arr

void interrupt 19 getData1(void)
{
char arr[50],temp;
unsigned int i ;

if(i>=50)
i=0;

temp= SPIDR ;
arr[i] = temp ;
i = i + 1 ;
}

void spi_Comm_Master(unsigned char ch) {

unsigned char ctemp;

PTT = PTT & ~0x80 ; // select slave

/*wait for SPITEF */
while((SPISR & 0x20)==0);
SPIDR = ch ;

/*wait for SPIF Interrupt Flag to set */
while((SPISR & 0x80)==0);
ctemp = SPIDR ;

/*SPIF Interrupt Flag is cleared by reading SPIDR */

}
void spi_Init_Master() {
/*Setting MOSI, SS and SCK as outputs */
DDRM |= DDRM_DDRM3_MASK | DDRM_DDRM4_MASK | DDRM_DDRM5_MASK ;

/* Setting MISO as input */
DDRM &= ~DDRM_DDRM2_MASK;

SPICR1 = 0x52;
//bit7 - SPI Interrupt Enable Bit
//bit6 - SPI System Enable Bit
//bit5 - SPI Transmit Interrupt Enable
//bit4 - SPI Master/Slave Mode Select Bit
//bit3 - SPI Clock Polarity Bit
//bit2 - SPI Clock Phase Bit
//bit1 - Slave Select Output Enable
//bit0 - LSB-First Enable

SPICR2 = 0x10;
//bit 4 - Mode Fault Enable Bit
//bit 3 - Output Enable in the Bidirectional Mode of Operation
//bit 1 - SPI Stop in LCDdelay Mode Bit
//bit 0 - Serial Pin Control Bit 0
//MISO - Master In, Serial Out
//MOSI - Master Out, Serial In

SPIBR = 0x00 ; // 1 MHz SPI Clock
}
spi_slave_init()
{
DDRM |= DDRM_DDRM2_MASK ;

SPICR1 = 0xC0;

SPICR2 = 0; // non bidirectional mode

SPIBR = 0x70 ; // 1 MHz SPI Clock
}

--Thanks
Amit
In the getData1 ISR local variables arr[] and i are not initialized, neither
they are static. All local nonstatic variables are allocated on the stack
and their value is random every time your ISR is called. You should change
your code like this

void interrupt 19 getData1(void)
{
static char arr[50],
char temp;
static unsigned int i ;
...

I didn't check the rest of your code. Try fix above issue first.

Edward
----- Original Message -----
From: "amit shrigondekar"
To: <6...>
Sent: Wednesday, April 14, 2010 06:50
Subject: [68HC12] SPI problem Specifically about SPIDR
Hi everyone ..
I have a problem with SPI bus and I have pasted below init functions
for master and slave.

if any body had the same problem, kindly let me know how to get around that.

Problem:
1) when I read SPIDR register it gives me random values and once in a
while correct value

2) Also it does not copy any value in the arr[] it just copies first
location in arr

void interrupt 19 getData1(void)
{
char arr[50],temp;
unsigned int i ;

if(i>P)
i=0;

temp= SPIDR ;
arr[i] = temp ;
i = i + 1 ;
}

void spi_Comm_Master(unsigned char ch) {

unsigned char ctemp;

PTT = PTT & ~0x80 ; // select slave

/*wait for SPITEF */
while((SPISR & 0x20)==0);
SPIDR = ch ;

/*wait for SPIF Interrupt Flag to set */
while((SPISR & 0x80)==0);
ctemp = SPIDR ;

/*SPIF Interrupt Flag is cleared by reading SPIDR */

}
void spi_Init_Master() {
/*Setting MOSI, SS and SCK as outputs */
DDRM |= DDRM_DDRM3_MASK | DDRM_DDRM4_MASK | DDRM_DDRM5_MASK ;

/* Setting MISO as input */
DDRM &= ~DDRM_DDRM2_MASK;

SPICR1 = 0x52;
//bit7 - SPI Interrupt Enable Bit
//bit6 - SPI System Enable Bit
//bit5 - SPI Transmit Interrupt Enable
//bit4 - SPI Master/Slave Mode Select Bit
//bit3 - SPI Clock Polarity Bit
//bit2 - SPI Clock Phase Bit
//bit1 - Slave Select Output Enable
//bit0 - LSB-First Enable

SPICR2 = 0x10;
//bit 4 - Mode Fault Enable Bit
//bit 3 - Output Enable in the Bidirectional Mode of Operation
//bit 1 - SPI Stop in LCDdelay Mode Bit
//bit 0 - Serial Pin Control Bit 0
//MISO - Master In, Serial Out
//MOSI - Master Out, Serial In

SPIBR = 0x00 ; // 1 MHz SPI Clock
}
spi_slave_init()
{
DDRM |= DDRM_DDRM2_MASK ;

SPICR1 = 0xC0;

SPICR2 = 0; // non bidirectional mode

SPIBR = 0x70 ; // 1 MHz SPI Clock
}

--Thanks
Amit
Thanks for your reply

But can you please tell me,

what can be wrong if I can see receive Interrupt is getting called every
time, (I am sending data to other controller in while(1) loop) but still
getting wrong values on SPIDR. Its kinda weird cause I see clock is also
proper on sck line.

when I was sending one continuously from master, I was getting 128 from
SPIDR in slave and few times correct output as 1 .

Can you guess what could be the prob?
--Thanks
Amit

On Tue, Apr 13, 2010 at 11:46 PM, Edward Karpicz wrote:

> In the getData1 ISR local variables arr[] and i are not initialized,
> neither
> they are static. All local nonstatic variables are allocated on the stack
> and their value is random every time your ISR is called. You should change
> your code like this
>
> void interrupt 19 getData1(void)
> {
> static char arr[50],
> char temp;
> static unsigned int i ;
> ...
>
> I didn't check the rest of your code. Try fix above issue first.
>
> Edward
> ----- Original Message -----
> From: "amit shrigondekar"
> To: <6...>
> Sent: Wednesday, April 14, 2010 06:50
> Subject: [68HC12] SPI problem Specifically about SPIDR
> Hi everyone ..
> I have a problem with SPI bus and I have pasted below init functions
> for master and slave.
>
> if any body had the same problem, kindly let me know how to get around
> that.
>
> Problem:
> 1) when I read SPIDR register it gives me random values and once in a
> while correct value
>
> 2) Also it does not copy any value in the arr[] it just copies first
> location in arr
>
> void interrupt 19 getData1(void)
> {
> char arr[50],temp;
> unsigned int i ;
>
> if(i>=50)
> i=0;
>
> temp= SPIDR ;
> arr[i] = temp ;
> i = i + 1 ;
> }
>
> void spi_Comm_Master(unsigned char ch) {
>
> unsigned char ctemp;
>
> PTT = PTT & ~0x80 ; // select slave
>
> /*wait for SPITEF */
> while((SPISR & 0x20)==0);
> SPIDR = ch ;
>
> /*wait for SPIF Interrupt Flag to set */
> while((SPISR & 0x80)==0);
> ctemp = SPIDR ;
>
> /*SPIF Interrupt Flag is cleared by reading SPIDR */
>
> }
> void spi_Init_Master() {
> /*Setting MOSI, SS and SCK as outputs */
> DDRM |= DDRM_DDRM3_MASK | DDRM_DDRM4_MASK | DDRM_DDRM5_MASK ;
>
> /* Setting MISO as input */
> DDRM &= ~DDRM_DDRM2_MASK;
>
> SPICR1 = 0x52;
> //bit7 - SPI Interrupt Enable Bit
> //bit6 - SPI System Enable Bit
> //bit5 - SPI Transmit Interrupt Enable
> //bit4 - SPI Master/Slave Mode Select Bit
> //bit3 - SPI Clock Polarity Bit
> //bit2 - SPI Clock Phase Bit
> //bit1 - Slave Select Output Enable
> //bit0 - LSB-First Enable
>
> SPICR2 = 0x10;
> //bit 4 - Mode Fault Enable Bit
> //bit 3 - Output Enable in the Bidirectional Mode of Operation
> //bit 1 - SPI Stop in LCDdelay Mode Bit
> //bit 0 - Serial Pin Control Bit 0
> //MISO - Master In, Serial Out
> //MOSI - Master Out, Serial In
>
> SPIBR = 0x00 ; // 1 MHz SPI Clock
> }
> spi_slave_init()
> {
> DDRM |= DDRM_DDRM2_MASK ;
>
> SPICR1 = 0xC0;
>
> SPICR2 = 0; // non bidirectional mode
>
> SPIBR = 0x70 ; // 1 MHz SPI Clock
> }
>
> --Thanks
> Amit
>
How do you decide you are reading wrong received data from SPIDR? Do you
examine contents of arr[] ? If so then I answered why it doesn't work.

Your problem is not clear to me.

Make sure clock phase and polarity settings match between devices.

Are you debugging using BDM connecttion? Then you should make sure debugger
isn't reading SPI registers. For example debugger data window can be made
showing SPI registers. Update of data window contents can lead to reading of
SPISR, then reading SPIDR and .. removing received data from SPIDR buffer.

Edward

----- Original Message -----
From: "amit shrigondekar"
To: <6...>
Sent: Wednesday, April 14, 2010 09:04
Subject: Re: [68HC12] SPI problem Specifically about SPIDR
Thanks for your reply

But can you please tell me,

what can be wrong if I can see receive Interrupt is getting called every
time, (I am sending data to other controller in while(1) loop) but still
getting wrong values on SPIDR. Its kinda weird cause I see clock is also
proper on sck line.

when I was sending one continuously from master, I was getting 128 from
SPIDR in slave and few times correct output as 1 .

Can you guess what could be the prob?
--Thanks
Amit

On Tue, Apr 13, 2010 at 11:46 PM, Edward Karpicz wrote:

> In the getData1 ISR local variables arr[] and i are not initialized,
> neither
> they are static. All local nonstatic variables are allocated on the stack
> and their value is random every time your ISR is called. You should change
> your code like this
>
> void interrupt 19 getData1(void)
> {
> static char arr[50],
> char temp;
> static unsigned int i ;
> ...
>
> I didn't check the rest of your code. Try fix above issue first.
>
> Edward
> ----- Original Message -----
> From: "amit shrigondekar"
> To: <6...>
> Sent: Wednesday, April 14, 2010 06:50
> Subject: [68HC12] SPI problem Specifically about SPIDR
> Hi everyone ..
> I have a problem with SPI bus and I have pasted below init functions
> for master and slave.
>
> if any body had the same problem, kindly let me know how to get around
> that.
>
> Problem:
> 1) when I read SPIDR register it gives me random values and once in a
> while correct value
>
> 2) Also it does not copy any value in the arr[] it just copies first
> location in arr
>
> void interrupt 19 getData1(void)
> {
> char arr[50],temp;
> unsigned int i ;
>
> if(i>P)
> i=0;
>
> temp= SPIDR ;
> arr[i] = temp ;
> i = i + 1 ;
> }
>
> void spi_Comm_Master(unsigned char ch) {
>
> unsigned char ctemp;
>
> PTT = PTT & ~0x80 ; // select slave
>
> /*wait for SPITEF */
> while((SPISR & 0x20)==0);
> SPIDR = ch ;
>
> /*wait for SPIF Interrupt Flag to set */
> while((SPISR & 0x80)==0);
> ctemp = SPIDR ;
>
> /*SPIF Interrupt Flag- is cleared by reading SPIDR */
>
> }
> void spi_Init_Master() {
> /*Setting MOSI, SS and SCK as outputs */
> DDRM |= DDRM_DDRM3_MASK | DDRM_DDRM4_MASK | DDRM_DDRM5_MASK ;
>
> /* Setting MISO as input */
> DDRM &= ~DDRM_DDRM2_MASK;
>
> SPICR1 = 0x52;
> //bit7 - SPI Interrupt Enable Bit
> //bit6 - SPI System Enable Bit
> //bit5 - SPI Transmit Interrupt Enable
> //bit4 - SPI Master/Slave Mode Select Bit
> //bit3 - SPI Clock Polarity Bit
> //bit2 - SPI Clock Phase Bit
> //bit1 - Slave Select Output Enable
> //bit0 - LSB-First Enable
>
> SPICR2 = 0x10;
> //bit 4 - Mode Fault Enable Bit
> //bit 3 - Output Enable in the Bidirectional Mode of Operation
> //bit 1 - SPI Stop in LCDdelay Mode Bit
> //bit 0 - Serial Pin Control Bit 0
> //MISO - Master In, Serial Out
> //MOSI - Master Out, Serial In
>
> SPIBR = 0x00 ; // 1 MHz SPI Clock
> }
> spi_slave_init()
> {
> DDRM |= DDRM_DDRM2_MASK ;
>
> SPICR1 = 0xC0;
>
> SPICR2 = 0; // non bidirectional mode
>
> SPIBR = 0x70 ; // 1 MHz SPI Clock
> }
>
> --Thanks
> Amit
>