9 Replies Latest reply on Nov 13, 2015 12:26 PM by user_78878863

    SPI Slave drops a byte from TX FIFO?

    peter.watkins_1510206

      I'm using the SPIS component with an interrupt handler on "Interrupt On Rx FIFO Not Empty". The master performs two-byte writes before pulling the slave select line high again.

         

      For testing purposes, after I receive the first byte, I send out 0x55 on MISO. After I recieve the second byte, I put 0x77 in the TX FIFO. This works fine except for the very first SPIS RX interrupt--in this case, one 0x77 that I put in the TX FIFO just isn't sent out. Notice in the spi.png file, there's a 0x55 following a 0x55 where 0x77 should be intervening.

         

      The RX interrupt handler is as follows:

         

          static uint8 toggle = 0;
          uint8 data = SPIS_1_ReadRxData();
          uint8 status = SPIS_1_ReadRxStatus();
          if (toggle == 0)
          {
              SPIS_1_WriteTxData(0x55);
          }
          else
          {
              SPIS_1_WriteTxData(0x77);
          }
          
          toggle = ~toggle;

         

       

         

      Any idea why one of the bytes in the FIFO isn't getting sent out? I also uploaded the project itself.

        • 1. Re: SPI Slave drops a byte from TX FIFO?
          user_1377889

          SPI works as follows: for every bit(byte) shifted in one bit (byte) is shifted out. Since you did not put a byte into Tx initially null is shifted out.

             

           

             

          Bob

          • 2. Re: SPI Slave drops a byte from TX FIFO?
            peter.watkins_1510206

            By null, you mean 0x00, right? I'm fine with that for the first byte. My problem is the 3rd byte--it's missing. It should be 0x77.

            • 3. Re: SPI Slave drops a byte from TX FIFO?
              user_78878863

              Where is the place where you are missing the 0x77? The first ReadRxData() happens at a time where nothing has been read by the SPI master, so it returns 0x00. Then your ISR sends a byte out, which also receives another byte (and thus triggers the ISR again).

              • 4. Re: SPI Slave drops a byte from TX FIFO?
                peter.watkins_1510206

                I'm running the SPI slave component on the PSoC, not SPI master. I know that there's RX data available for the slave because the code above is in the RX interrupt handler (which is driven by "Interrupt On Rx FIFO Not Empty"). Regarding the missing 0x77--that's shown in spi.png. According to the source, MISO should have 0x55, 0x77, 0x55, 0x77, etc. Instead, it has 0x55, 0x55, 0x77, 0x55, etc.

                   

                I would embed spi.png as an image, but I get an error: "The selected text format will not allow it to display images. The text format will need to be changed for this image to display properly when saved." when I attempt to do that with this forum. So for now, just download the attatchment from my original post.

                   

                   

                • 5. Re: SPI Slave drops a byte from TX FIFO?
                  user_78878863

                  Sorry, I somehow missed tha part about the SPI slave :(

                     

                  OK, so what you should get is a sequence of 0x00, 0x55, 0x77, 0x55, 0x77 (and so on). I have no idea, from looking at the code, why that one 0x77 gets swallowed.

                     

                  What you could do for debugging: have two output pins. Set one high during the time in your ISR. Set the other one according to the 'toggle' variable as soon as its changed. Then you can watch these two lines with your LA, maybe this gives a clue. The only other idea I have is that some code is clearing the TX buffer for some reason (though I cannot see why for now).

                  1 of 1 people found this helpful
                  • 6. Re: SPI Slave drops a byte from TX FIFO?
                    peter.watkins_1510206

                    I added the two outputs you suggested, "Toggle" and "ISR". They look like I would expect, though. I've attached two images from the LA--one zoomed in.

                    • 7. Re: SPI Slave drops a byte from TX FIFO?
                      peter.watkins_1510206

                      OK. I think I found the problem. Instead of calling SPIS_WriteTxData(), I should have been calling SPIS_WriteTxDataZero() to put a byte into the FIFO. This is because my SPI bus is configured in mode 0,0 (CPHA = 0, CPOL = 0). The comment on SPIS_WriteTxDataZero() reads as follows:

                         
                      *  Write a byte zero of data to be sent across the SPI. This must be used in *  Mode 00 and 01 if the FIFO is empty and data is not being sent.
                         

                       

                         

                      I believe that is the case for me. Now I can pre-load the TX FIFO with a byte and it will be clocked out as the first RX byte comes in. I also don't see a missing 0x77 when I use SPIS_WriteTxDataZero() instead of SPIS_WriteTxData().

                      1 of 1 people found this helpful
                      • 8. Re: SPI Slave drops a byte from TX FIFO?
                        user_1377889

                        Wow! To find out that bug must have taken some time! Thank you for keeping us informed.

                           

                         

                           

                        Bob

                        • 9. Re: SPI Slave drops a byte from TX FIFO?
                          user_78878863

                          Good find!

                             

                          I should have seen this while looking at the data sheet :( It actually is clearer than the code comment:

                             

                          Places a byte/word directly into the shift register for transmission. This byte/word will be
                          sent to the master device during the next clock phase.

                             

                          Required for modes where CPHA == 0 where data must be in the shift register before the
                          first clock edge.

                             

                          This is probably because your ISR runs while the SPI transfer is already in progress. So when you place the byte with WriteTxData, it will be put into the FIFO, but it doesn't get fast enough into the SPI write register itself.

                          1 of 1 people found this helpful