- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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:
When the Master SPI device does a transmit it does enter the CY_ISR:
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;
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
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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:
Here is a view before reading the Rx Buffer. This code is not in the ISR:
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:
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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"
May be changing it to "Interrupt On Rx FIFO full" will you show the buffer size is 6.
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Motoo,
Hello, thank you for responding to my message. I will try that first thing tomorrow.
Thank you,
Joe
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Here is my latest setting:
Here is the transaction view:
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
!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:
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.
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well it looks like I've done a 360 and ended up where I started.
My SPI is 10 Bytes from Master
I'm GetRxBufferSize() is return 10 which is good, but I'm missing bytes.
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Something is over writing the data but I can't explain it.
Will keep working.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Please check the MCUTEST7 output when the SPIS_DSP_GetRxBufferSize() is invoked.