K22F SPI recieving 0

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

K22F SPI recieving 0

1,292 Views
asfarley
Contributor IV

I'm working with an SPI barometer trying to get the K22F reading SPI responses using an SPIMaster_LDD PE component. I've scoped the bus lines - everything looks correct. K22F sends a "read address" byte, barometer then clocks out the values for the byte, then CS is set high. I'm manually driving CS to ensure that it stays low between request/read transmissions.

I've had to add a work-around for the PE SPI driver bug where the function SM1_GetBlockReceivedStatus returns before the byte is actually recieved by adding a fixed delay afterwards:

char RecieveByteSPI1()
{
char b, dummy;
dummy = 0;
LDD_TError er;

er = SM1_ReceiveBlock(SPI1DeviceDataPtr, &b, 1);
er = SM1_SendBlock(SPI1DeviceDataPtr, &dummy, 1);
while (!SM1_GetBlockSentStatus(SPI1DeviceDataPtr)) {
SM1_Main(SPI1DeviceDataPtr);
}
// /* Wait until data block is transmitted/received */
while (!SM1_GetBlockReceivedStatus(SPI1DeviceDataPtr)) {
SM1_Main(SPI1DeviceDataPtr);
}
WAIT1_Waitms(2);

return b;
}

Using the delay, I can see that the SPI bus transaction happens correctly at the electrical level. However, the variable b is not populated when the code returns. The SPI1 register POPR/RXDATA shows that it holds the expected value just before this function returns.

SPI1 is configured to *not* use interrupts. Aside from that, it's basically at default settings. Any idea what could be going wrong here?

----------------------------------------------------------------------------------------------

Updates:

1) Manually reading from POPR after receiving seems to fix the issue. Not sure why this is necessary:

b = (uint16_t)SPI_PDD_ReadPopRxFIFOReg(SPI1_BASE_PTR); /* Read character from receiver */

2) I found other reports (Is anyone really using PE Generated SPI driver with MQXLite? How? ) of PE SPI issues where GetBlockReceivedStatus wasn't working and a different flag was used to check if reception was complete. However, it looks like the receive-commplete flag is never set, and my SendByteSPI1 function hangs on this line:

while (!(SPI_PDD_GetInterruptFlags(SPI1_BASE_PTR) & SPI_SR_EOQF_MASK));//wait for the end of transfer

I just noticed this issue related to using a GPIO for CS, although I'm using a different MCU:

SPI with no CS. Problem with PE 

---------

Edit 2017-07-11

Here are a couple of discussions on what may be the same issue:

SPI Example 

https://community.nxp.com/thread/342498 

0 Kudos
8 Replies

698 Views
ZhangJennie
NXP TechSupport
NXP TechSupport

Hello Earl.

To solve your problem, we need to know your SW version:

- Start the IDE and click on Help | About CodeWarrior(KDS) Development Studio. Send me the version and build id.

- send me your demo code.

I will check it from my side. Thanks.


Have a great day,
Jennie Zhang

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

698 Views
asfarley
Contributor IV

I'm using KDS 3.2.0, I've pasted a screenshot of my Version IDs (build numbers?) for KDS prerequisites:pastedImage_2.png

My PE SPI settings are pasted below. This screenshot was taken today when I'd temporarily disabled the SPI module for unrelated reasons, but at the time I was debugging, it was enabled. 

pastedImage_1.png

Code samples:

------------------------------------------------------------------------------------------------------------------------------------

LDD_TDeviceData * SPI1DeviceDataPtr;

void InitSPI()

{

SPI1DeviceDataPtr = SM1_Init(NULL);

return;

}

void SendByteSPI1(byte data)

{

LDD_TError er = ERR_OK;

er = SM1_SendBlock(SPI1DeviceDataPtr, &data, 1);

while (!SM1_GetBlockSentStatus(SPI1DeviceDataPtr)) {

SM1_Main(SPI1DeviceDataPtr);

}

if (er != ERR_OK)

{

printf("Error sending byte on SPI1\n");

}

return;

}

char RecieveByteSPI1()

{

char b, dummy;

byte inBuffer [2];

dummy = 0;

LDD_TError er;

LDD_TData * receivePtr = &b;

er = SM1_ReceiveBlock(SPI1DeviceDataPtr, (LDD_TData*) &inBuffer, 1);

WAIT1_Waitms(2);

er = SM1_SendBlock(SPI1DeviceDataPtr, &dummy, 1);

WAIT1_Waitms(2);

while (!SM1_GetBlockSentStatus(SPI1DeviceDataPtr)) {

SM1_Main(SPI1DeviceDataPtr);

}

WAIT1_Waitms(2);

//TODO: Shouldn't be necessary to manually read from POPR register

b = (uint16_t)SPI_PDD_ReadPopRxFIFOReg(SPI1_BASE_PTR); /* Read character from receiver */

return b;

}

0 Kudos

698 Views
egoodii
Senior Contributor III

It's still not clear why you are spinning on a SENT status while waiting for a RECEIVE byte/word.  TX is 'done' at least 1/2 Sclk before RX.

0 Kudos

698 Views
asfarley
Contributor IV

I can't find the post now but at one point I saw another issue where the user was seeing that the RECEIVE flag was never being set. I used the SENT status as the next-best thing based on the idea that they're clocked in/out at the same time.

It didn't occur to me that there would be a difference between recieve-complete and send-complete in this situation, but I see what you mean about the 1/2 Sclk difference. That could have been part of the issue. 

Anyway, this issue is on hold for me since it's not pressing. I will post a cut-down example when I get a chance. 

0 Kudos

698 Views
asfarley
Contributor IV

Finally had a chance to update this issue. I've created a minimal example to demo this issue here:

https://u59343634.dl.dropboxusercontent.com/u/59343634/Minimal%20SPI%20Issue%20Demo.zip 

This project just sets up SPI1 and attempts to talk to a device on the other end. To recap, the current issues I'm seeing are:

1) The received bytes have to be read manually from POPR, they don't appear in the user-supplied receive buffer 

2) A mysterious 10ms delay is necessary between transmit and receive.

Thanks,

Alex

0 Kudos

698 Views
ZhangJennie
NXP TechSupport
NXP TechSupport

Hi Alex,

Please send us your demo project rather than a piece of code.

you posted a SPI setting screenshot, what is it related with your original question?

Jennie

0 Kudos

698 Views
asfarley
Contributor IV

Hi Jennie

Just wanted to bump this issue - I've uploaded a demo project to reproduce the issue. I don't know if you'll be able to reproduce without having another SPI device attached, but at least you can take a look. 

0 Kudos

698 Views
egoodii
Senior Contributor III

EOQ (end of queue) IS NOT a 'receive complete' flag.  That is a 'TX-FIFO flag' block-send can use.  Receive-data-available is RFDF.  As for CS, look into the CONT bit-setting to keep CS 'active' between 'parts' of an otherwise contiguous set of SPI transfers.

0 Kudos