MKE06 SPI slave communication MISO error

cancel
Showing results for 
Search instead for 
Did you mean: 

MKE06 SPI slave communication MISO error

84 Views
Contributor III

Hi everyone,

I'm writing because I encountered a very strange problem regarding the MISO pin of an SPI communication.

I have a MKE06Z128 set up as an SPI slave and I need to do the following:

  1. Receive a starting byte
  2. Receive a command byte
  3. Send data accordingly to the command received

The strange thing is that as I tell the driver to send my data the result is always a loopback of the received message.

The code below is the one I used inside the interrupt, both RxFull and TxEmpty interrupts are enabled.

void SPI0_IRQHandler(void) {
  uint8_t rx_data = 0x00;
  uint8_t tx_data = 0x00;
  if (SPI_GetStatusFlags(SPI0) & kSPI_RxBufferFullFlag) {
    rx_data = SPI_ReadData(SPI0);
    spi_data_buff_rx[spi_data_ptr_rx] = rx_data;
    switch (SPI_S_State) {
    case SPI_S_IDLE:
      tx_data = rx_data; // start character
      if ((rx_data == SPI_S_START_CHAR) && (spi_execute_comm == 0)) {
        SPI_S_State = SPI_S_SEND_COMM;
      }
      break;
    case SPI_S_SEND_COMM:
      spi_command = rx_data;
      tx_data = rx_data;
      spi_data_cnt = SPI_S_DATA_DIM;
      spi_data_type = SPI_S_RetrieveData(spi_command, spi_data);
      SPI_S_State = SPI_S_SEND_DATA;
      break;
    case SPI_S_SEND_DATA:
      if (spi_command & SPI_S_WRITE_MASK) {
        spi_data[SPI_S_DATA_DIM - spi_data_cnt] = rx_data;
      }
      switch(spi_data_type) {
      case 1:
        tx_data = rx_data;
        break;
      case 2:
        tx_data = spi_data[SPI_S_DATA_DIM - spi_data_cnt];
        break;
      case 0:
      default:
        tx_data = 0;
        break;
      }
      spi_data_cnt--;
      if (spi_data_cnt == 0) {
        SPI_S_State = SPI_S_SEND_TERM1;
      }
      break;
    case SPI_S_SEND_TERM1:
      tx_data = SPI_S_TERM1_CHAR;
      if (rx_data != SPI_S_TERM2_CHAR) {
        spi_command = 0x00;
        SPI_S_State = SPI_S_IDLE;
      } else {
        SPI_S_State = SPI_S_SEND_TERM2;
      }
      break;
    case SPI_S_SEND_TERM2:
      tx_data = SPI_S_TERM2_CHAR;
      if (rx_data != SPI_S_TERM1_CHAR) {
        spi_command = 0x00;
      } else {
        if (spi_command & SPI_S_WRITE_MASK) {
          spi_execute_comm = 1;
        }
      }
      SPI_S_State = SPI_S_IDLE;
      break;
    case SPI_S_MAX_STATES:
    default:
      SPI_S_State = SPI_S_IDLE;
      break;
    }
    SPI_WriteData(SPI0, (uint16_t)tx_data);
    spi_data_buff_tx[spi_data_ptr_rx] = tx_data;
    if (SPI_S_State == SPI_S_IDLE) {
      spi_data_ptr_rx = 0;
    } else {
      spi_data_ptr_rx++;
    }
  }
  if (SPI_GetStatusFlags(SPI0) & kSPI_TxBufferEmptyFlag) {
    SPI_WriteData(SPI0, (uint16_t)0xA5);
  }
}

The following data is the one I see from the master side

[TX] - 63 01 11 12 13 14 15 16 17 18 19 1A 1B 1C 23 21 00
[RX] - A5 63 01 11 12 13 14 15 16 17 18 19 1A 1B 1C 23 21

I also checked on the oscilloscope the correct behavior of the master and slave devices and it is all set up correctly on the waveform side.

I cannot fint the source of the problem, I see that the register used for the communication is the same for Tx and Rx, but it is overwritten to transmit different data.

I'm using the SDK 2.7.0 with MCUXpresso.

Any suggestions?

Thank you in advance.

Best Regards,

       Tommaso

Tags (4)
0 Kudos
1 Reply

10 Views
NXP TechSupport
NXP TechSupport

Hi Tommaso Bergero 

   FRDM-KE06 sdk has the SPI master and slave code, do you test that code, whether it works OK on your side or not?

pastedImage_1.png

When you want to send the data in the SPI slave, you need to write the related data to the Transmit FIFO:

void SPI_SLAVE_IRQHandler(void)
{
if ((SPI_GetStatusFlags(EXAMPLE_SPI_SLAVE) & kSPI_RxBufferFullFlag) && (rxIndex > 0U))
{
destBuff[BUFFER_SIZE - rxIndex] = SPI_ReadData(EXAMPLE_SPI_SLAVE);
rxIndex--;
}

if ((SPI_GetStatusFlags(EXAMPLE_SPI_SLAVE) & kSPI_TxBufferEmptyFlag) && (txIndex > 0U))
{
SPI_WriteData(EXAMPLE_SPI_SLAVE, (uint16_t)(srcBuff[BUFFER_SIZE - txIndex]));
txIndex--;
}

if ((rxIndex == 0U) && (txIndex == 0U))
{
slaveFinished = true;
SPI_DisableInterrupts(EXAMPLE_SPI_SLAVE, kSPI_RxFullAndModfInterruptEnable | kSPI_TxEmptyInterruptEnable);
}
SDK_ISR_EXIT_BARRIER;
}

i suggest you test the official SDK code:SDK_2.8.0_FRDM-KE06Z\boards\frdmke06z\driver_examples\spi\interrupt_b2b\slave

at first, which can be downloaded from this link:

Welcome | MCUXpresso SDK Builder 

Wish it helps you!

If you still have questions about it, pelase kindly let me know.

Best Regards,

Kerry

 

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

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos