SPI Slave GetBufferSize not correct

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
joli_601446
Level 5
Level 5
10 likes given 10 sign-ins 5 sign-ins

Hello, I am working on a small design where the PSOC is a SPI Slave and a DSP is the Master SPI. The SPI Slave is configure to use the RX_Interrupt ISR pin:

SPI_Slave.jpg

When the Master SPI device does a transmit it does enter the CY_ISR:

GetRxBuff.jpg

The above image shows the Debugger stopping at my break point inside my ISR.

This is good BUT the problem is when I try to read the SPIS_DSP_GetRxBufferSize() function.

It shows 0 words in the RX memory buffer. There should be 6 words in the memory buffer;

SPI_view.jpg

Above is a screen shot showing the 6 transfers.

I would like to read how many words are in the memory buffer and then read them out.

I will upload my code. I must be missing something.

Thank you very much.

Joe

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.

Hello all! My co-worker and I found the problem. I'm interfacing with a ARM-DSP from TI (66AK2H14) processor and it turns out that TI does their SPI modes (Polarity, Phase) a little different. I set the DSP to Polarity = 1 and Phase = 0 and I set the PSOC5 to (Polarity = 1 and Phase = 1)

I was making those devices the same mode but my co-worker said try changing the DSP's modes.  I found a configuration that worked.

DSP SPI MODE

POL = 1, Phase = 0

PSOC SPI Mode

POL = 1, Phase = 1

This version works only because of the 100msec delay in the forever will loop. The entire 10 words at a SPI Clock of 1Mhz takes about 87usec. If you take out the delay call it will always go into the if block, so keep the delay call.

I will upload my code.

So it turns out that my code was not problem, it was the Master SPI mode that needed changed.

Thank you everyone for all your suggestions.

Joe

View solution in original post

16 Replies
lock attach
Attachments are accessible only for community members.
joli_601446
Level 5
Level 5
10 likes given 10 sign-ins 5 sign-ins

Well, it looks like you are unable to do any SPI functions while you are in an ISR. I changed the code to only set a global variable high and in the main loop check that bit.

Although the SPI data looks corrects on the scope I am not reading the correct data from the Rx memory buffer.

I should read: 0xA, 0xB, 0xC, 0xD, 0xE, 0xF

but I'm ready 0xB, 0xB, 0xC, 0xD, 0xF, 0xB

Here is the SPI signal view:

SPI_View.jpg

Here is a view before reading the Rx Buffer. This code is not in the ISR:

Buffer_Size.jpg

I am able to run the SPIS_DSP_GetRxBufferSize() it returns 6 which is correct.

But when I read the RxBuffer the data is not correct:

Memory.jpg

I've uploaded my code. It must be something related to using interrupts. I notice that I enter the ISR 4 times.

Thank you,

Joe

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

I think that you have already found the reason,

the interrupt is taking place after each SPI transaction,

so at the first byte the first interrupt occurs.

Then the buffer size must be 1.

Then in the ISR, you are receiving the data if buffer size is not equal to 0,

so there won't be a time when the buffer size is 6.

When I saw your project, you set "Interrupt On SPI Done"

000-SPI-Config-Advanced.JPG

May be changing it to "Interrupt On Rx FIFO full" will you show the buffer size is 6.

001-SPI-Config-2.JPG

But then there will be a chance to miss the next transaction,

so after all I'd agree that you should set "Interrupt On SPI Done"

moto

0 Likes

Motoo,

Hello, thank you for responding to my message. I will try that first thing tomorrow.

Thank you,

Joe

0 Likes
lock attach
Attachments are accessible only for community members.

Moto,

Hello, quick question for you, in the Configure SPI window why is Interrupt on Rx FIFO Empty Grayed out?  The only way I can unclick this setting is to have a buff size of 4. If I try this setting and have the Master send 4 words then I get multiple interrupts. If I try having the buff size to 4 and only send 4 words then the interrupt goes low for the entire time of the 4 word transaction.

SPI_Cofig.png

Here is my latest setting:

spi_config.jpg

Here is the transaction view:

spi_view.jpg

Signals 4 is the Rx interrupt, notice how it goes low as soon as an SPI transaction start. Signal 5 is the SPI done interrupt. I thought SPI done would be a high signal a the end of the transaction.

There must be some way to receive multiple SPI words and then read the RX memory buffer when you have read N words in the FIFO.

The above shows an interrupt but in the PSOC software it never entered the ISR.

Here is my code.

0 Likes

Moto,

Do I need to use a DMA in this case? I should be able to simply poll the SPIS_GetRxBufferSize() for the value of 10 and if equal to then read the Rx data. When the Master sends 10 bytes and I then step over the SPIS_GetRxBufferSize() it return 4.  I must not be understanding things. Will have to keep reading the datasheet.

Thank you for all your help.

Joe

0 Likes
joli_601446
Level 5
Level 5
10 likes given 10 sign-ins 5 sign-ins

!Hello, its the end of the day and I want to send my code, I only using one Rx interrupt. I've set the RxBuffer length to 100 hoping that would solve the problem. The Master is only sending 10 bytes. When I get the interrupt the number of words in the RxBuffer is 4 and I don't know why.

Here is my data:

spi_view.jpg

Here is my debug window. Notice that the data in the dsp_spi_rcv_buffer array does not match up with the data the Master sent.

screen.jpg

Finally here is my code. I thought I could solve things by putting a delay in the ISR thinking it would give the hardware time to fully receive the data into the RxBuffer before I start reading it.

0 Likes
lock attach
Attachments are accessible only for community members.

Here's my code.

I'm very thank for your help.

Joe

0 Likes

Dropping in a bit late....

As a general rule of thumb: do not put any delays (directly or indirectly) into an interrupt handler. Program might hang/stall.

For that reason do not send serial data from within a handler.

Best practice is: Set a (volatile!) flag in the handler, check for it in the main-loop, act accordingly and reset the flag.

Bob

0 Likes

Perhaps the PSOC needs a larger break between byte transfers? Could that be the problem? It can't handle  back-to-back SPI transfers.

Joe

0 Likes
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear Joe-san,

I tried some, but I'm not quite ready for providing you more/better information.

About the behavior of interrupt choices,

please refer to the datasheet of SPIS.

We can open the pdf from the configure window of the component.

Attached is the datasheet I got from the component's configure dialog.

Best Regards,

18-Aug-2019

Motoo Tanaka

0 Likes

Moto,

Hello, thanks for helping me. Is it possible that the PSOC cannot get up with the Master sending back-to-back SPI transactions? I'll keep working at it today.

Thanks,

Joe

0 Likes
lock attach
Attachments are accessible only for community members.

Well it looks like I've done a 360 and ended up where I started.

My SPI is 10 Bytes from Master

spi_view.jpg

I'm GetRxBufferSize() is return 10 which is good, but I'm missing bytes.

Debug_view.jpg

I'm missing F2 and F6 words.

I have slowed the SPI clock down on the Master and Slave to 100Khz hoping that may solve the problem.

I'll keep working.

Joe

0 Likes

I change the number of Bytes sent from the Master to 20. The good things is the Slave sends 20 back and the Master receives 20 expected values. At least that is working. What isn't working in the same as before, the Slave Receiver. For every 4 words received, the 3rd word is incorrect.

buffer.jpg

Something is over writing the data but I can't explain it.

Will keep working.

0 Likes

I'm having a little trouble with the Master running the SPI below 1Mhz, so it looks like that this the lowest clock rate I can use. I thought I could run lower but I was mistaken. I believe that using the Software Buffer as described on page 9 of the "Serial Peripheral Interface (SPI) Slave" document the clock rate is too fast for the transfer from hardware FIFO to software buffer.

I may need to try use a DMA.

Joe

0 Likes
lock attach
Attachments are accessible only for community members.

Hello all! My co-worker and I found the problem. I'm interfacing with a ARM-DSP from TI (66AK2H14) processor and it turns out that TI does their SPI modes (Polarity, Phase) a little different. I set the DSP to Polarity = 1 and Phase = 0 and I set the PSOC5 to (Polarity = 1 and Phase = 1)

I was making those devices the same mode but my co-worker said try changing the DSP's modes.  I found a configuration that worked.

DSP SPI MODE

POL = 1, Phase = 0

PSOC SPI Mode

POL = 1, Phase = 1

This version works only because of the 100msec delay in the forever will loop. The entire 10 words at a SPI Clock of 1Mhz takes about 87usec. If you take out the delay call it will always go into the if block, so keep the delay call.

I will upload my code.

So it turns out that my code was not problem, it was the Master SPI mode that needed changed.

Thank you everyone for all your suggestions.

Joe

Please check the MCUTEST7 output when the SPIS_DSP_GetRxBufferSize() is invoked.

0 Likes