Force update SPI tx shift register

cancel
Showing results for 
Search instead for 
Did you mean: 

Force update SPI tx shift register

968 Views
jaredmcintyre
Contributor II

I'm experimenting with the SPI slave implementation on the K20 series by implementing a simple echo protocol. Master sends a word and the slave returns it immediately. The double buffered nature of the shift register is getting in my way. I've posted a simplified version of my interrupt handler below.

The problem is that when I push the value onto SPI0_PUSHR_SLAVE, whatever is in the shift register is pushed out. In order to have the frame immediately following the command contain the value of the command, I need to invalidate that shift register so that it will send out the value I just pushed on. I can't seem to find a mechanism to do this.

void spi0_isr(void)

{  

  if( false == writing )

  {

    uint8_t response;

    response = SPI0_POPR;

    writing = true;

    SPI0_PUSHR_SLAVE = response;

    SPI0_SR |= SPI_SR_RFDF;

  }

  else

  {

    uint8_t throw_away;

    throw_away = SPI0_POPR;

    SPI0_SR |= SPI_SR_RFDF;

    writing = false;

    command_phase = true;

  }

}

Labels (1)
5 Replies

208 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi

Please check the similar discussion with below thread:

https://community.nxp.com/thread/466937 

To save your time, please directly check the last four reply of above thread.

Wish it helps.


Have a great day,
Mike

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

208 Views
adamdu
Contributor II

I have the same problem...

0 Kudos

208 Views
noperator
Contributor I

Hi,

Did you ever find a solution to this problem? I am having the same problem where I need my SPI slave to echo bytes back to the master immediately after they are received. For example a sequence of "FF 00 03 20" from the master should result in the slave sending "XX FF 00 03". No matter how I configure or write to the SPI, there is always an extra byte delay, like "XX XX FF 00"

0 Kudos

208 Views
jaredmcintyre
Contributor II

I've moved the logic to the run loop and disabled interrupts. The goal is to immediately respond with the word that was sent in. I'm still getting a single overflow after having successfully pushed the response onto SPI0_PUSHR_SLAVE (the push completed, the fifo depth is 1, and the next pointer is pointing at the value pushed on in the stack), before the next word exchange is clocked by the master. Any thoughts on how to make this echo protocol work?

Note: I am pushing a word into the queue at initialization so there will be no underflow when the first word is exchanged.

void loop()

{

  if(SPI0_SR & SPI_SR_TFUF)

  {

    SPI0_SR &= SPI_SR_TFUF;

  }

  

  if(SPI0_SR & SPI_SR_RFDF)

  {  

    if( false == writing )

    {    

      uint8_t response = SPI0_POPR;

      SPI0_PUSHR_SLAVE = response;

      SPI0_SR |= SPI_SR_RFDF;

    

      writing = true;

    }

    else

    {    

      uint8_t throw_away;

      throw_away = SPI0_POPR;

      SPI0_SR |= SPI_SR_RFDF;

      SPI0_PUSHR_SLAVE = 0;

   

      writing = false;

      command_phase = true;

    }

  }

}

0 Kudos

208 Views
jaredmcintyre
Contributor II

I may be misunderstanding something about underflow. Is there any way to do the above with interrupts? I can't seem to run this without my first attempt to push data onto the FIFO transmit queue within the interrupt handler causing the subsequent send to trigger an undeflow. All attempts after the initial one to push onto the queue don't have this problem, but because of the first underflow, I'm not a frame off of what the master is expecting. I did validate that the queue believes that there is 1 frame to send after I've pushed on, and that the master only attempts clock one more byte, and that the clocking occurs well after the value was pushed onto the queue.

The interrupt is currently set as SPI_SR_RFDF | SPI_SR_TFUF, but I have tried a couple of others.

0 Kudos