SPI Slave DMA Received and Transmit Data Repeating and Missing

cancel
Showing results for 
Search instead for 
Did you mean: 

SPI Slave DMA Received and Transmit Data Repeating and Missing

473 Views
giantmango
Contributor II

Hello,

I'm using LPC55S16-EVK and MCUXpresso SDK version is 2.11.0.

I'm working on a project, in which LPC55s16 needs to act as an SPI slave and continuously receive 32 bytes of data from an ADC. I kept on running into a problem that received data is missing bytes. So I ran a test by filling slaveTxData with zeros and checked the MISO pin and it did not behave as I expected.

giantmango_0-1647600171980.png

SCK is 4 MHz.

I also tried filling slaveTxData with 0x00 to 0x1F. And got this

giantmango_1-1647601124736.png

It's missing some bytes and repeating one of the bytes.

 

Here's my code:

/*******************************************************************************
 * Definitions
 ******************************************************************************/
#define SPI_SLAVE                                   SPI1
#define SPI_SLAVE_IRQ                           FLEXCOMM1_IRQn
#define SPI_SSEL                                     1
#define SLAVE_DMA                                 DMA1
#define SPI_SLAVE_RX_CHANNEL         6
#define SPI_SLAVE_TX_CHANNEL         7
#define SLAVE_SPI_SPOL                       kSPI_SpolActiveAllLow
#define DATA_SIZE                                  32

#define SPI_MASTER                               SPI7
#define SPI_MASTER_IRQ                       FLEXCOMM7_IRQn
#define SPI_MASTER_CLK_SRC             kCLOCK_Flexcomm7
#define SPI_MASTER_CLK_FREQ          CLOCK_GetFlexCommClkFreq(7U)
#define SPI_SSEL                                     1
#define MASTER_DMA                             DMA0
#define SPI_MASTER_RX_CHANNEL     18
#define SPI_MASTER_TX_CHANNEL     19
#define Master_SPI_SPOL                        kSPI_SpolActiveAllLow
#define MASTER_CMD_SIZE                   2U
 
#define DRDY                                            kINPUTMUX_GpioPort1Pin4ToPintsel
 

 

/*!
 * @brief Main function
 */
int main(void)
{
    /* Initialzie board setting. */
    /* set BOD VBAT level to 1.65V */
    POWER_SetBodVbatLevel(kPOWER_BodVbatLevel1650mv, kPOWER_BodHystLevel50mv, false);
    /* attach 12 MHz clock to FLEXCOMM0 (debug console) */
    CLOCK_AttachClk(kFRO12M_to_FLEXCOMM0);

    /* attach 12 MHz clock to SPI3 */
    CLOCK_AttachClk(kFRO_HF_DIV_to_FLEXCOMM1); //SPI_SLAVE
    CLOCK_AttachClk(kPLL0_DIV_to_FLEXCOMM7); //SPI_MASTER

    /* reset FLEXCOMM for SPI */
    RESET_PeripheralReset(kFC1_RST_SHIFT_RSTn);
    RESET_PeripheralReset(kFC7_RST_SHIFT_RSTn);

    BOARD_InitBootPins();
    BOARD_InitBootClocks();
    BOARD_InitDebugConsole();
    BOARD_BootClockPLL150M();
 
    /* Initialize the SPI slave instance. */
    SlaveInit();
    MasterInit();

    /* Configure DMA for slave SPI. */
    SlaveDMASetup();
    MasterDMASetup();  
 
    /* Setup PINT */
    INPUTMUX_Init(INPUTMUX);
    INPUTMUX_AttachSignal(INPUTMUX, kPINT_PinInt1, DRDY);
    INPUTMUX_Deinit(INPUTMUX);
    PINT_Init(PINT);
    PINT_PinInterruptConfig(PINT, kPINT_PinInt1, kPINT_PinIntEnableRiseEdge, SlaveStartDMATransfer);
    PINT_EnableCallbackByIndex(PINT, kPINT_PinInt1);
}
 
static void SlaveStartDMATransfer(void)
{
    spi_transfer_t slaveXfer;

    SPI_Enable(SPI_SLAVE, true);
    /* Create handle for slave instance. */
    SPI_SlaveTransferCreateHandleDMA(SPI_SLAVE, &slaveHandle, SPI_SlaveUserCallback, NULL, &slaveTxHandle&slaveRxHandle);

    slaveXfer.txData   = (uint8_t *)&slaveTxData;
    slaveXfer.rxData   = (uint8_t *)&slaveRxData;
    slaveXfer.dataSize = 32; //transfer bytes DMA requires 32 bits of buffer

    /* Start transfer, when transmission complete, the SPI_SlaveUserCallback will be called. */
    if (kStatus_Success != SPI_SlaveTransferDMA(SPI_SLAVE, &slaveHandle, &slaveXfer))
    {
        PRINTF("There is an error when start SPI_SlaveTransferDMA \r\n");    
    } else {
        for (uint8_t i = 0; i < DATA_SIZE; i++)
        {
            slaveTxData[i] = 0;
        }
    }
}
 
Other functions were not altered except for changing DMA channel priority. So I only post 
SlaveStartDMATransfer(), which I've made the most amendments.
 
Thanks! Hope you all have a good day.
Labels (1)
Tags (1)
0 Kudos
4 Replies

458 Views
giantmango
Contributor II

Thanks for replying!

While I was trying to capture the weird data received by LPC55s16, it seems to be working fine. Strange.

I tried only receiving data from the master and not sending data out. LPC55s16 is acting as a slave to receive data from ADC. Based on my observation, ADC is doing a good job sending data out, while there's a delay in LPC55s16 when receiving data.

The data format ADC sent looked like this:

giantmango_0-1648001611771.png

Start with a byte of header like 0x10 0x11 0x12, followed by 3 bytes of data.

 

This is what LPC55s16 received from ADC:

giantmango_1-1648001771869.png

 

The red marks are the headers from ADC and are followed by 3 bytes.

It's missing data from 0x10 to 0x12. Don't know how to fix this situation.

Thanks.

 

Best,

Taylor

0 Kudos

423 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello, 

Yes, it seems it missing the first three data, what about the power up sequence? How about first power on slave first?  And how about try only send three data. 

There is spi-dmi-slave demo under SDK you also can have a look:

Alice_Yang_0-1648440343859.png

 

BR

Alice

 

0 Kudos

465 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello ,

From signal picture, it seems from two transfers, it insert other stable data.

How about check your Mater side, master send data to Slave, while slave not send to master immediately, so master receive wrong value.

 

BR

Alice

0 Kudos

448 Views
giantmango
Contributor II

I made some changes to the code and it starts to show the phenomenon, which received data is missing bytes.

Code:

static void SlaveStartDMATransfer(void)
{
    spi_transfer_t slaveXfer;
   
    SPI_Enable(SPI_SLAVE, true);
    /* Create handle for slave instance. */
    SPI_SlaveTransferCreateHandleDMA(SPI_SLAVE, &slaveHandle, SPI_SlaveUserCallback, NULL, &slaveTxHandle, &slaveRxHandle);

    slaveXfer.txData   = (uint8_t *)&slaveTxData;
    slaveXfer.rxData   = (uint8_t *)&slaveRxData;
    slaveXfer.dataSize = 32; //transfer bytes DMA requires 32 bits of buffer

    /* Start transfer, when transmission complete, the SPI_SlaveUserCallback will be called. */
    if (kStatus_Success != SPI_SlaveTransferDMA(SPI_SLAVE, &slaveHandle, &slaveXfer))
    {
        PRINTF("There is an error when start SPI_SlaveTransferDMA \r\n");
    // }
    } else {
        if (SPI_SLAVE->FIFOSTAT == 0x000808c3){
            PRINTF("FIFO overflow\r\n");
        } else {
            if (counter == RECORD_TIME) {
                counter = 0;
                PrintEEGData();
            } else {
                for (uint8_t i = 0; i < DATA_SIZE; i++)
                {
                    data[i + counter * DATA_SIZE] = slaveRxData[i];
                }
                counter ++;
            }
        }
    }
}

 

Printed data:

giantmango_0-1648030362387.png

In this figure, there should be 3 bytes of data following 0x13 instead of 2. And the highlighted 0x16, I thought it was repeated, but now I'm wondering if the slave misses 32 bytes so it looks like it's repeated.

0 Kudos