AnsweredAssumed Answered

Problem with DMA on SPI Slave

Question asked by Mickael Leforestier on Dec 5, 2016
Latest reply on Dec 13, 2016 by Mickael Leforestier

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

Attachments

Outcomes