Problem with DMA on SPI Slave

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

Problem with DMA on SPI Slave

Jump to solution
1,652 Views
mlefores
Contributor I

Hello,

I am facing problem when using DMA on the lpc54114. I try to receive data from SPI Slave driver through DMA.

What I remark is : I received a size of bytes that corresponds to nothing and I don't understand where I made an error.

There is my code :

#define TRANSFERT_DMA DMA0 // Only 1 dma on the µC
#define DMA_IRQ DMA0_IRQn

#define TRANSFERT_HSDC_DMA_CHANNEL 14

#define SPI_FLEXCOMM_CLK kFRO12M_to_FLEXCOMM7
#define SPI_FLEXCOMM_RST kFC7_RST_SHIFT_RSTn
#define HSDC_SPI_INSTANCE SPI7

#define SPI_DMA_TRANSFER_NB 8
#define SPI_DMA_WORDS_PER_TRANSFER 7
#define SPI_TRANSFER_SIZE_WORDS (SPI_DMA_WORDS_PER_TRANSFER*SPI_DMA_TRANSFER_NB)

static uint8_t spiSlaveRxData[2][SPI_TRANSFER_SIZE_WORDS]={0};

static dma_handle_t sWaveFormDmaHandle,sUselessDmaHandle;

static spi_slave_config_t sSpiSlaveConfig;
static spi_transfer_t sSpiSlaveXfer;
static spi_dma_handle_t sSpiSlaveDmaHandle;

CLOCK_AttachClk(SPI_FLEXCOMM_CLK);
RESET_PeripheralReset(SPI_FLEXCOMM_RST);
 // Configure SPI Slave device
 SPI_SlaveGetDefaultConfig(&sSpiSlaveConfig);
 sSpiSlaveConfig.enableSlave = false; // Avoid auto start SPI before end of configuration
SPI_SlaveInit(HSDC_SPI_INSTANCE, &sSpiSlaveConfig);
 // Configure DMA
 DMA_Init(TRANSFERT_DMA);
// Enable channels (SPI-RX/TX - otherwise no events occurred)
DMA_EnableChannel(TRANSFERT_DMA, TRANSFERT_HSDC_DMA_CHANNEL);
DMA_EnableChannel(TRANSFERT_DMA,TRANSFERT_HSDC_DMA_CHANNEL+1); // For SPI TX
// Set priorities
DMA_SetChannelPriority(TRANSFERT_DMA, TRANSFERT_HSDC_DMA_CHANNEL+1, kDMA_ChannelPriority7); // For SPI TX
DMA_SetChannelPriority(TRANSFERT_DMA, TRANSFERT_HSDC_DMA_CHANNEL, kDMA_ChannelPriority0);
// Creates DMA handles
DMA_CreateHandle(&sWaveFormDmaHandle, TRANSFERT_DMA, TRANSFERT_HSDC_DMA_CHANNEL);
DMA_CreateHandle(&sUselessDmaHandle,TRANSFERT_DMA, TRANSFERT_HSDC_DMA_CHANNEL+1); // For SPI TX
// Creates SPI-Handles
SPI_SlaveTransferCreateHandleDMA(HSDC_SPI_INSTANCE, &sSpiSlaveDmaHandle, spi_rxSlaveCallback,NULL,&sUselessDmaHandle , &sWaveFormDmaHandle);

// Configure Buffers for DMA
sSpiSlaveXfer.txData = (uint8_t *)&spiSlaveTxData;
//sSpiSlaveXfer.rxData = spiSlaveRxData;
sSpiSlaveXfer.rxData = (uint8_t*)spiSlaveRxData[sBufferId];
sSpiSlaveXfer.dataSize = SPI_TRANSFER_SIZE_BYTES;

// Configure DMA Transfer
SPI_SlaveTransferDMA(HSDC_SPI_INSTANCE, &sSpiSlaveDmaHandle, &sSpiSlaveXfer);
// Start Really DMA/SPI
SPI_Enable(HSDC_SPI_INSTANCE, true);

static void spi_rxSlaveCallback(SPI_Type *base, spi_dma_handle_t *handle, status_t status, void *userData)
{
    if(status == kStatus_Success)
    {

       GPIO_WritePinOutput(GPIO, 0, 26, val);

       val = !val;

        SPI_SlaveTransferDMA(HSDC_SPI_INSTANCE, &sSpiSlaveDmaHandle, &sSpiSlaveXfer);
    }
    else
        return;
}

Please find attach scope of the gpio that toggles when DMA system seems to have read 224 bytes ...

Yellow line is CSS driven by SPI master. There is 28 bytes per Frame of 125 µs.

Blue is GPIO that is toggling at each DMA interrupt. You can see that the IRQ switch too early (56 bytes).

Thanks in advance for your help.

Mickael

Labels (3)
0 Kudos
Reply
1 Solution
1,123 Views
mlefores
Contributor I

Hello,

If someone looks for the same problem, there is the solution/explaination.

DMA system required 32 bits buffer, even if 8-bits data are received by SPI slave driver. So, it is necessary to ask for X*sizeof(uint32_t) in sSpiSlaveXfer.dataSize.In DMA callback, you will have to extract useful data from uint32_t buffer of DMA.

Regards,

Mickael

View solution in original post

0 Kudos
Reply
1 Reply
1,124 Views
mlefores
Contributor I

Hello,

If someone looks for the same problem, there is the solution/explaination.

DMA system required 32 bits buffer, even if 8-bits data are received by SPI slave driver. So, it is necessary to ask for X*sizeof(uint32_t) in sSpiSlaveXfer.dataSize.In DMA callback, you will have to extract useful data from uint32_t buffer of DMA.

Regards,

Mickael

0 Kudos
Reply