We are using the LPC55S28 SPI in DMA/Transfer and Slave mode. We used the spi_dma_b2b_transfer_slave example as a template to transfer data from the Evaluation board to our custom board.
The slaveTxData[k] is updated in an interrupt routine triggered using a GPIO pin in the slave board (Evaluation board). The first block of data is transmitted without any issue, but the app crashes in the second transfer showing the attached Fault results.
The same master board and the same salve updating routine works well with FRDM-K64F (slave board) and it seems like the SPI-DMA transfer in Slave mode is different between LPC55S28 and Kinetis microcontroller.
Is there anything we should do to solve this issue?
Thanks for your help!
Hello @abi_farsoni
Recommend you debug step by step to check when run which code , it crash.
BR
Alice
Hi Alice,
Debugging the code step by step shows that after the first successful transfer and before the Callback is triggered the app crashes showing the attached debug info. The Callback is never triggered.
See the code below:
spi_slave_config_t slaveConfig;
/* Get default Slave configuration. */
SPI_SlaveGetDefaultConfig(&slaveConfig);
/* Initialize the SPI slave. */
slaveConfig.sselPol = (spi_spol_t)EXAMPLE_SLAVE_SPI_SPOL;
SPI_SlaveInit(EXAMPLE_SPI_SLAVE, &slaveConfig);
/* DMA init */
DMA_Init(EXAMPLE_DMA);
/* configure channel/priority and create handle for TX and RX. */
DMA_EnableChannel(EXAMPLE_DMA, EXAMPLE_SPI_SLAVE_TX_CHANNEL);
DMA_EnableChannel(EXAMPLE_DMA, EXAMPLE_SPI_SLAVE_RX_CHANNEL);
DMA_SetChannelPriority(EXAMPLE_DMA, EXAMPLE_SPI_SLAVE_TX_CHANNEL, kDMA_ChannelPriority0);
DMA_SetChannelPriority(EXAMPLE_DMA, EXAMPLE_SPI_SLAVE_RX_CHANNEL, kDMA_ChannelPriority1);
DMA_CreateHandle(&slaveTxHandle, EXAMPLE_DMA, EXAMPLE_SPI_SLAVE_TX_CHANNEL);
DMA_CreateHandle(&slaveRxHandle, EXAMPLE_DMA, EXAMPLE_SPI_SLAVE_RX_CHANNEL);
/* Transfer */
uint32_t i = 0U;
//spi_transfer_t slaveXfer;
/* Initialzie the transfer data */
for (i = 0U; i < 128; i++)
{
k=i*4;
slaveTxData[k] = i & 0x000000FF;
slaveTxData[k+1] = (i & 0x0000FF00) >>8;
slaveTxData[k+2] = (i & 0x00FF0000) >>16;
slaveTxData[k+3] = (i & 0xFF000000) >>24;
slaveRxData[i] = 0U;
}
/* Create handle for slave instance. */
SPI_SlaveTransferCreateHandleDMA(EXAMPLE_SPI_SLAVE, &slaveHandle, SPI_SlaveUserCallback, NULL, &slaveTxHandle, &slaveRxHandle);
slaveXfer.txData = (uint8_t *)&slaveTxData;
slaveXfer.rxData = (uint8_t *)&slaveRxData;
//slaveXfer.dataSize = TRANSFER_SIZE * sizeof(slaveTxData[0]);
//slaveXfer.dataSize = TRANSFER_SIZE * sizeof(slaveTxData[0]);
slaveXfer.dataSize = TRANSFER_SIZE;
slaveXfer.dataSize = TRANSFER_SIZE;
/* Start transfer, when transmission complete, the SPI_SlaveUserCallback will be called. */
if (kStatus_Success != SPI_SlaveTransferDMA(EXAMPLE_SPI_SLAVE, &slaveHandle, &slaveXfer))
{
PRINTF("There is an error when start SPI_SlaveTransferDMA \r\n");
}
Thanks for your help.
Abi
Hi @abi_farsoni
There are two scenarios for this case :
1. Slave selection pin state is not changed after the first transfer is complete.
2. Slave data buffer size may wrong ("slaveXfer.dataSize = TRANSFER_SIZE;")
Thanks
KalaimaniArumugam
Thanks for your comments.
After checking everything we found out that the problem is using ADC and SPI-DMA together in our application. In our "While ()" routine, we take a sample using the ADC:
adc_value = ((g_LpadcResultConfigStruct.convValue) >> 7U);
We noticed if we remove the above line, the Slave SPI is working with no problem and the app does not crash. If we remove SPI, the ADC is working with no issue.
We used the provided Examples for configuring the ADC and SPI-DMA. Probably there is a Fault Access between these two.
Thanks for your help.
Abi
Correction: We are using:
LPADC_DoSoftwareTrigger(DEMO_LPADC_BASE, 1U); /* 1U is trigger0 mask. */
while (!g_LpadcConversionCompletedFlag)
{
}
to get a sample using the ADC.
Abi