Strange SPI status flag behavior

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Strange SPI status flag behavior

6,209 Views
Trace
Contributor I
Hi,

I'm trying to get the SPI up and running on an MC9S12DP256B however, I see some strange behavior.

Here is the setup:
Target: MC9S12DP256B
Compiler: MetroWerks C
Debugger: USB Multilink / HiWave

My SPI procedures are like this:

void SPI_INIT(void) {
SPI0CR1 = 0x50; // SPI enabled, master mode
SPI0CR2 = 0;
SPI0BR = 0x77; // Very slow baud
}

void SPI_ThrowCatch(unsigned char data) {
while(!(SPI0SR & 0x20)); /* Wait for SPTEF set */
SPI0DR = mydata;
while(!(SPI0SR & 0x80)); /* Wait for SPIF set */
return SPI0DR;
}

Now what happens is that when I try to send a byte it actually gets send (I have checked with a scope) however, the procedure stalls at the SPIF check! It never gets any further.
I don’t use any interrupts but the global interrupt is enabled. The uP never leaves this proc! I have tried setting up the SPI in all different ways with no result. Then I checked the assembler, and I see that compiler optimizes the byte check to a bit check… And that is my best answer to my problems. Maybe the flag can’t be checked just as a bit. In the datasheet it is described that to clear the flags one has to read the SPI0SR. I have tried to remove all optimizing in the compiler. However it still makes the check in bit level instead on byte level.

NB: EDIT! I have now tried: while(!((unsigned char) (SPI0SR & 0x80))); with no result. So it's not the bit check causing the problem!

Anyone have an idea about what could cause my problem?

Best regards
Jan Thogersen

Message Edited by Trace on 03-13-200607:17 AM

Labels (1)
0 Kudos
6 Replies

721 Views
EMontanez
NXP Employee
NXP Employee
Try closing the memory and data windows in the CodeWarrior debugger when you run this code and see if it helps. I've seen issues before where the flag becomes cleared because the debugger memory window performs are periodic read of the register including the flag.

This is just a quick shot in the dark. If it does not work, please give an update.

More detailed:
"This is a side effect of the debugger.

Remember that the SPIF is cleared by a read of SPISR followed be a read of the data register. Since the SR register is memory mapped before the data register when the debugger read memory for display, this condition is met.

Turn off all memory windows and data windows and code should work as expected."

Message Edited by EMontanez on 03-13-2006 09:33 AM

0 Kudos

721 Views
Trace
Contributor I
You are a true god :smileyhappy: Why didn't I think of that? However, with my many years of experience I have developed an ability to overlook the obvious and go for the complicated conspiracy theories instead :smileyhappy:

Thank you very much!

Best regards
Jan
0 Kudos

721 Views
TWY
Contributor I
Hi,
I´ve got exactly the same problem.
BUT I´ve tried closing Memory and data windows and the problem is still there. I also tried not using the debugger (just loading the project and switching the power supply off and on) and program stop.... I supose in the same code line....
 
Did you really solve the problem just closing Memory and Data windows?
 
If you or anyone has got any idea about what could it be happening, I would it very happy to hear it.
 
Thanks.
0 Kudos

721 Views
TWY
Contributor I
Sorry, I found out why my software wasn´t working.
 
I do had the same problem described above and I solved it by closing Memory and Data windows.
0 Kudos

721 Views
EMontanez
NXP Employee
NXP Employee
No problem! I see this issue ALL the time! Glad I could help.
0 Kudos

721 Views
pittbull
Contributor III
Hello,
I don't know if this helps you, but try it this way:

unsigned char SPI_ThrowCatch(unsigned char data)
{
if (SPI0SR & 0x20)
SPI0DR = data;
if (SPI0SR & 0x80)
return SPI0DR;
return 0;
}

or this way:

// single read
unsigned char SPI_ThrowCatch(unsigned char data)
{
unsigned char status = SPI0SR;
if (status & 0x20)
SPI0DR = data;
if (status & 0x80)
return SPI0DR;
return 0;
}

These functions do not block and return '0' if nothing received.
0 Kudos