This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MibSPI Receive Question



Hi,

I have a question about the receive mechanism.

I have configured transfer-group 0 at the MibSPI3 (slave) to be 4 buffers. When I (accidently) receive 5 words (which is a receive overrun), the last word received will be written in the first buffer.

My question is, when a new transmission occurs, why is the first received word stored in the second buffer of transfer group 0 and not in the first?

Or in other words: Why does the transmission start with the next buffer after the overwritten buffer after a receive overrun occured and not with the first buffer of the transfer group?

Thanks in advance.

Dominik

  • Dominik,

    If the buffer has not been reset, then the next transmission is the 6th received word. As such, I would expect it to go into slot 1.

    Best Regards,

    Forum Support

  • Hi Kevin,

    what do you mean with reset?

    Best Regards,

    Dominik

  • In my code the 6th word goes into buffer 2 but I want it to go into buffer 1.

    What can I do to achieve that?

  • Dominik,

    Every buffer has a status register which includes the RXEMPTY bit. When the buffer has received data, the bit is set from a 1 to a 0. Then, the PCURRENT address is incremented to the next buffer. When the RXEMPTY bit is set in the last buffer of a transfer group,

    • RXINT is generated, telling the CPU that the buffer is full and should be read.
    • PCURRENT is set back to PSTART

    As the buffers are read, the RXEMPTY bit is cleared from 1 back to 0. Thus, when you do not have an overrun, the transfer group's status returns to its original value after the CPU reads all of the buffers.

    The receive-overrun error is a serious error that indicates you have lost data. An overrun occurs when you receive more data before the buffers are read. Since PCURRENT was reset to PSTART after the last buffer of the transfer group was written, an extra transmission will be written into the first buffer of the transfer group; and subsequent data will be written into the sequentially next buffers (e.g. second buffer for the 6th data word). The overrun bit is set when data is written into a buffer in which RXEMPTY is already cleared to 0 (indicating unread data in that buffer).

    An overrun indicates an unexpected data transmission which must be handled before the next transmission. In case of a data overrun, the software should disable the transfer group, reconfigure it, and then re-enable it. Now, the PCURRENT address points to the first word of the transfer group.

    Best Regards,

    Forum Support

     

  • Dominik,

    If you set the ONESHOT bit in the TGxCTRL register, the transfer group will stop after receiving 4 data (you buffer size is 4). If you do not set the ONESHOT bit, the transfer is always triggered by the data coming in. The fifth data actually starts next group transfer. But the receive overrun error flag will be set. Any way, you need to make sure that your application does not accidentally send extra data because I do not see a simple method to solve this issue. Here is why.

    If the ONESHOT bit is enabled, the transfer group is disabled after receiving the 4th data. The 5th data will be discarded. But there must be some handshaking mechanism for the master to know that slave is ready to receive the 6th data. If we use the 4 pin mode, master will hold transfer until slave is ready. But the 5th data is already in the master transmit buffer, it will go first after slave is ready. the 5th data will show up at the 1st slot in the slave receive buffer.

    Please let me know if the above answers your question.

    Thanks and regards,

    Zhaohong

  • Kevin and Zhaohong,

    I use 4 pin mode with CS. I do not use ENA because the pins are not available. Because I can't use the ENA handshaking, I have implemented my own handshaking with normal IO-pins (the slave notifys the master when it has read transfer group 0). All my buffers use buffer-mode 0x4.

    In my receive overrun interrupt I disable the transfer group, reconfigure it and re-enable it. As expected PCURRENT is reset to PSTART.

    But although I reset transfer group 0, after the next transmission (which transmitts the correct amount of bytes) PCURRENT has the value 1 and not 0 as I would expect.

    Oneshot is not enabled at the slave.

    I don't care when data is discarded, because  when I recognise a faulty transmission I notify the master and he resends the data.

    Is there something else I have to do after a overrun, so that the next transmission will start at the beginning oft the transfer group?

    Thanks and regards,

    Dominik

  • Dominik,

    I think that you have a received data that is still in a buffer so that it fills buffer0 when the target group is re-enabled. I need to look a little further to understand how to work around that.

    Best Regards,

    Kevin Lavery

  • Dominik,

    Can you verify the number of transfers? I think you may be getting more than 5 transfers in the errant transmission.

    Best Regards,

    Forum Support

  • Hi Kevin,

    yes I checked with a oszilloskope and I receive 5 words.

    I also tryed out what happens when I configure the slave transfer group to be only 3 buffers long. Then PCURRENT is 2 after the erroneous transmission. But as I mentioned already above, I reset the transfer groups after a transmission so that PCURRENT is reset to 0. Then the following correct transmission sets PCURRENT back to 2 again.

    Maybe I should check for TGINSERVICE == 0 before doing anything in the receive interrupt?

    Regards,

    Dominik

  • Dominik,

    I can clearly reproduce what you report.

    I can also unconditionally correct the problem by disabling the MiBSPI (on an OVERRUN) and then re-enabling. In my code, it looks like:

    mibspiREG3->GCR0 = 0U;

    delay = 20;

    while(delay-- > 0)

    {}

    mibspiInit();

    delay = 20;

    while(delay-- > 0)

    {}

    The delays are added just for fun and could certainly be optimized.  Is this scheme acceptable?

     

    Best Regards,

    Kevin Lavery