LPC54628 as SPI slave

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC54628 as SPI slave

987 Views
aswinprabhu
Contributor III

Hi,

There are two LPC54628 of which one acts as SPI Master and the other SPI Slave.

This is my requirement:

The SPI master sends 5 bytes of data in 8 bit SPI mode: the first 3 are data bytes and the 4th is checksum (XOR of first 3 bytes). After this, the master sends 8 clock cycles (5th byte) in order receive acknowledgement from the slave to know whether it received data without errors.

The SPI Slave receives the four bytes from the Master, calculates checksum and compares with the received checksum. If they match, the slave loads a acknowledgment signal (0xAA) which gets shifted out from the slave to the master as the master sends the 8 clock cycles.

What works:
The master works fine. The slave works fine till the calculation and comparison of checksum.

What doesn't work:

When I load the acknowledgment byte 0xAA into the SPI slave, I expect it to be shifted out to the master as the master sends 8 clock cycles in the 5th byte of a frame. But on probing, i find that the ack byte is being sent out only in the 1st byte of the next frame. What is happening? Please help.

// Interrupt Service Routine for SPI-Slave where all action takes place

uint8_t SPI_Rx[5] = {0,0,0,0,0};
uint8_t SPI_DO_BUFFERSIZE = 0x05;
uint8_t slave_RxIndex = 0x05;

void ISR_Slave_FC5_SPI_DOBoard(void){
    if (SPI_GetStatusFlags(FC5_SPI_PERIPHERAL) & kSPI_RxNotEmptyFlag) {
        SPI_Rx[SPI_DO_BUFFERSIZE - slave_RxIndex] = SPI_ReadData(FC5_SPI_PERIPHERAL);   // save to array       
        slave_RxIndex--;

        if (slave_RxIndex > 1U){      // load 0x00 as MISO data until the 8 clocks are not received
            SPI_WriteData(FC5_SPI_PERIPHERAL, 0x00, 0);
        }
        else if (slave_RxIndex == 1U){
            calculatedChksum = SPI_Rx[0] ^ SPI_Rx[1] ^ SPI_Rx[2] ;   // calculate chksum by XOR of 3 bytes
            if (calculatedChksum == SPI_Rx[3]){
                SPI_WriteData(FC5_SPI_PERIPHERAL, 0xAA, 0); // load 0xAA as ACK which will be sent out when Master sends 8 clocks during 5th byte
            }
        }
        else if (slave_RxIndex == 0U){
            slaveFinished = true;
            SPI_WriteData(FC5_SPI_PERIPHERAL, 0x00, 0);   // load 0x00 so that next frame onwards 0x00 is the MISO data
            slave_RxIndex = 5U;
        }
    }


/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
    exception return operation might vector to incorrect interrupt */
#if defined __CORTEX_M && (__CORTEX_M == 4U)
    __DSB();
#endif
}

// SPI Slave settings

const spi_slave_config_t FC5_SPI_config = {
  .enableSlave = true,
  .polarity = kSPI_ClockPolarityActiveHigh,
  .phase = kSPI_ClockPhaseFirstEdge,
  .direction = kSPI_MsbFirst,
  .dataWidth = kSPI_Data8Bits,
  .sselPol = kSPI_SpolActiveAllLow,
  .txWatermark = kSPI_TxFifo0,
  .rxWatermark = kSPI_RxFifo1
};

SPI Master settings are near identical, with baud rate set at 50kbps. Both microcontrollers run at 96MHz.

scope_1 - Copy (2).bmp

Labels (3)
Tags (2)
0 Kudos
3 Replies

747 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Aswin,

I think there is a bug when the SPI module is used as slave device and transmitter, the workaround is to fill the 8 level transmitter FIFO with dummy data before the SPI slave transmits any data.

Hope it can help you

BR

XiangJun Rong

0 Kudos

747 Views
aswinprabhu
Contributor III

Hi,

I was able to solve the issue by setting SPI_ClockPhase as kSPI_ClockPhaseSecondEdge instead of FirstEdge.

Thank you.

0 Kudos

747 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Aswin,

If you toggle the /SS pin of slave SPI for each data transfer, the bug does not appear.

BR

XiangJun Rong

0 Kudos