LPSPI strange behavior

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

LPSPI strange behavior

2,347 Views
davithakobyan
Contributor III

Dear all,

The lpspi_dma_s32k144 example for S32K144EVB-Q100 board poses some strange behavior (using S32K14x RTM SDK v2.0.0).

The example is slightly simplified to transfer just 5 bytes from between master and slave on the same board like this:

LPSPI_DRV_SlaveTransfer(RECEIVE, slave_buffer.tx, slave_buffer.rx, 5);

LPSPI_DRV_MasterTransferBlocking(SEND, master_buffer.tx,master_buffer.rx, 5, TIMEOUT);

which works. The problem occurs when the above first line is replaced with:

LPSPI_DRV_SlaveTransfer(RECEIVE, slave_buffer.tx, NULL, 5);

where one would expect for the slave to send just 5 bytes upon master request. However, the slave sends only two bytes.

When trying, instead, to receive only 5 bytes it works without problem. I.e. the following line works:

LPSPI_DRV_SlaveTransfer(RECEIVE, NULL, slave_buffer.rx, 5);

In the following figure one can see that the slave indeed sends only two bytes (yellow signal is the Serial Data Input pin for the master) upon master request (green signal is SCK).

pastedImage_5.png

Can someone from NXP comment on this?

Thanks a lot in advance.

10 Replies

1,850 Views
dragosrachitan
NXP Employee
NXP Employee

Hello Davit,

This problem was investigated and a bug was found. Until the bug is fixed, please use both Tx and Rx buffers for the LPSPI_DRV_SlaveTransfer() function while using DMA.

Thank you,

Dragos

0 Kudos

1,850 Views
davithakobyan
Contributor III

Hi Dragos,

Thanks a lot for the clarification. Do you know in which version will the fix be available?

When using LPSPI_DRV_SlaveTransfer with both TX and RX buffers non-NULL, in the Interrupt mode (i.e. the .transferType variable is set to LPSPI_USING_INTERRUPTS in Send.c and Receive.c files) the following lines:

LPSPI_DRV_SlaveTransfer(RECEIVE, slave_buffer.tx, slave_buffer.rx, 4);
LPSPI_DRV_MasterTransferBlocking(SEND, NULL, master_buffer.rx, 5, TIMEOUT);

end up in LPSPI_DRV_SlaveIRQHandler with LPSPI_TRANSMIT_ERROR set. In the DMA mode no error occurs, and the master node receives its 4 bytes from the slave.

In the interrupt mode despite the LPSPI_TRANSMIT_ERROR the master still receives the 4 bytes from the slave.

Is this another bug or an expected behavior?

Another problematic case

If one instead of the above two lines uses the following (in the interrupt mode):

LPSPI_DRV_SlaveTransfer(RECEIVE, slave_buffer.tx, slave_buffer.rx, 5);
LPSPI_DRV_MasterTransferBlocking(SEND, master_buffer.tx, NULL, 4, TIMEOUT);

LPSPI_DRV_SlaveTransfer(RECEIVE, slave_buffer.tx, slave_buffer.rx, 5);
LPSPI_DRV_MasterTransferBlocking(SEND, NULL, master_buffer.rx, 4, TIMEOUT);
__asm("BKPT #0\n\t");

Then BKPT line is never reached.

Thanks.

1,850 Views
razva_tilimpea
NXP Employee
NXP Employee

Hi,

The root cause for your first problem is the interrupt priorities.

Your application runs in the same time slave and master and probably the interrupt for master fill up have a higher priority than slave fill up. In this case when master sends data the slave FIFOs are empty and tx transfer error is detected on slave side.

For the second issue I will investigate more and I will come back with some updates.

Razvan

0 Kudos

1,850 Views
davithakobyan
Contributor III

Thanks you for the clarification. I'll look more closely to the interrupt priorities.

Would be great if you could comment also on the second issue.

Thanks a lot in advance.

0 Kudos

1,850 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hi,

I'm unable to reproduce that.

Please run the attached project on your side.

What is the return status of the function?

Please check LPSPI error flags.

Thanks,

Daniel

0 Kudos

1,850 Views
davithakobyan
Contributor III

Hi Daniel,

Thanks a lot.

Your example works, but it uses interrupts rather than DMA.

Does the DMA variant works in your case?

0 Kudos

1,850 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Hi Davit,

I have tried with the lpspi_dma_s32k144 SDK example.

pastedImage_3.png

The only modification:

pastedImage_2.png

Yet it works.

Can you try this example?

Can you share a test project?

Please check the return status of the function.

Thanks,

Daniel

0 Kudos

1,850 Views
davithakobyan
Contributor III

Hi Daniel,

Thanks again for your feedback and efforts.

Please find attached the project. It is just newly created from the example as you showed in the picture.

The problem with the original example with setting NULL in place of slave_buffer.rx still can be seen. Once a breakpoint is hit after the line:

LPSPI_DRV_MasterTransferBlocking(SEND, master_buffer.tx,master_buffer.rx, NUMBER_OF_FRAMES, TIMEOUT);

the muster_buffer.rx is mostly field correctly, except the last 4 records. The last 6 bytes of master_buffer.rx looks like the following:

Name : master_buffer.rx[94]
    Decimal:6
    Hex:0x6

Name : master_buffer.rx[95]
    Decimal:5
    Hex:0x5

Name : master_buffer.rx[96]
    Decimal:100
    Hex:0x64

Name : master_buffer.rx[97]
    Decimal:99
    Hex:0x63

Name : master_buffer.rx[98]
    Decimal:98
    Hex:0x62

Name : master_buffer.rx[99]
    Decimal:97
    Hex:0x61

So the buffer starting from address 96 seems to be wrong.

In addition if one sets the NUMBER_OF_FRAMES constant to 5 the same situation is observed which I described in the first post (i.e. only 2 bytes from the slave are sent). It seems that the DMA does something wrong with the last addresses.

0 Kudos

1,850 Views
danielmartynek
NXP TechSupport
NXP TechSupport

Davit, 

Indeed, I get the same result when NUMBER_OF_FRAMES = 5U.

The functions do not return any errors.

pastedImage_1.png

Interestingly, it works when 

pastedImage_2.png

pastedImage_3.png

Let me check with SDK design team,

Thanks, 

Daniel

0 Kudos

1,850 Views
davithakobyan
Contributor III

Daniel thanks a lot for your information.

I hope it will not put a noise to the problem, but one may notice another strange behavior with SPI.

In the same example if one tries to replace the former lines:

LPSPI_DRV_SlaveTransfer(RECEIVE, slave_buffer.tx,NULL/*slave_buffer.rx*/, NUMBER_OF_FRAMES);
LPSPI_DRV_MasterTransferBlocking(SEND, master_buffer.tx,master_buffer.rx, NUMBER_OF_FRAMES, TIMEOUT);

with the following lines:

LPSPI_DRV_SlaveTransfer(RECEIVE, NULL, slave_buffer.rx, 4);
LPSPI_DRV_MasterTransferBlocking(SEND, master_buffer.tx, NULL, 3, TIMEOUT);
__asm("BKPT #0\n\t");

i.e. making the slave to wait for 4 bytes while the master sends 3 bytes (omitting the merit of such a fancy coding), then  the modified example (at -O0 optimization) does not reach the BKPT (using Segger J-Link debugger).  The program does not seem to stay in some infinite loop or in a continuous interrupt since it is enough to press just the pause button and then the continue button again to make the program to reach the BKPT line. The slave_buffer.rx is then currectly filled with 3 bytes sent from master. This behavior seems to be present in both SPI DMA and non-DMA modes. There is a feeling that somehow this is related to LPSPI_DRV_SlaveIRQHandler interrupt and LPSPI_RECEIVE_ERROR but it is difficult to draw a defined logic.

I understand that this description may be too unspecific but still such behavior of S32K is rather confusing.

Could you please comment whether it is reproduced at your side?

Thanks a lot for your help.

0 Kudos