SPI output, waiting for SPI-idle fails? (LPC1549)

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

SPI output, waiting for SPI-idle fails? (LPC1549)

915 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DennisFrie on Sun May 11 18:06:03 MST 2014
I've been setting up SPI for LPC1549, but have have a problem when waiting for SPI-idle.

SPI is running in master-mode, 8 bit length, ignoring RX, 2 SPI-clocks in all delay-blocks.

I'm sending multiple bytes in the same frame, which works just fine when done like here:

while( (LPC_SPI0 -> STAT & (1<<1)) == 0); // Wait until new data can be accepted in buffer

LPC_SPI0 -> TXDATCTL =
 0xFF | // Data
 ((8-1)<<24) | // Set length
 (0 << 20) | // Set EOT false
 (1 << 22) | // Ignore RX
 (0 << 16);

while( (LPC_SPI0 -> STAT & (1<<1)) == 0); // Wait until new data can be accepted in buffer

LPC_SPI0 -> TXDATCTL =
 0xFF | 1 | // Data
 ((8-1)<<24) | // Set length
 (1 << 20) | // Set EOT true
 (1 << 22) | // Ignore RX
 (0 << 16);



Problem is, for the last byte I have to change some pin-settings, but using the SPI-idle byte from the SPI status register doesn't seem to work. Using this code, it never gets past the while-loop checking the status-register.
while( (LPC_SPI0 -> STAT & (1<<1)) == 0); // Wait for new data to be accepted

LPC_SPI0 -> TXDATCTL =
 0xFF | 1 | // Data
 ((8-1)<<24) | // Set length
 (0 << 20) | // Set EOT 
 (1 << 22) | // Ignore RX
 (0 << 16);

       // This one is never false?
while(~LPC_SPI0->STAT & SPI_STAT_MSTIDLE);; // Wait for all data to be transmitted

LPC_SPI0 -> TXDATCTL =
 0xFF | 1 | // Data
 ((8-1)<<24) | // Set length
 (1 << 20) | // Set EOT 
 (1 << 22) | // Ignore RX
 (0 << 16);


I'm sure this is just a stupid mistake. It seems so simple, but I just can't see the problem.
Labels (1)
0 Kudos
2 Replies

742 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DennisFrie on Mon May 12 11:38:58 MST 2014
Hi Noah
Thanks for your time.

It should have been this: (edited in first post)
while(~LPC_SPI0->STAT & SPI_STAT_MSTIDLE);

Quick copy-paste error - sorry.

I tested a bit more today and it seems you are right. Setting EOT to zero will never allow SPI to go into idle. It just seems like the only way, to check if the transfer from the buffer is completed. Atm. I'm controlling SSEL0 manually instead, to work around this. Seems to work as I can control the frame like this instead, just hoped it could be done a bit more elegant.

0 Kudos

742 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by noahk on Mon May 12 11:12:31 MST 2014
Hi Dennis,

I am confused by the last polling line. It looks like you are polling for TxRdy, and not Idle:

// This one is never false?
while( (LPC_SPI0 -> STAT & (1<<1)) == 0); // Wait for all data to be transmitted

The Idle bit is set once the transfer is complete (EOT done). Does that explain the behavior you are seeing? If you truly want to know that the tx shifting is done, you might use receive data to be sure that you got data back. That will work for modes where rx follows tx, like mode 1 and mode 3 (CPHA == 1). But for modes where tx follows rx, the receive data will come in before the final shift is done. Due to stall logic, you will never get the final transmit edge until you provide the next buffer (if there was no EOT). But the lines will be stable, and perhaps you can make your changes without adverse effects in that situation.

Noah
0 Kudos