2413103_en-US

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

2413103_en-US

2413103_en-US

Access to intA and intB of DMA descriptors when using SPI

Hello,

I am using the microcontroller LPC55S69 to communicate with a device via SPI, using DMA.

The device is spitting data every 2ms, and i am saving it automatically in each descriptor.

I have 4 descriptors, when descriptor 2 concludes saving the data, i want it to flag intA, and when descriptor 4 finished filling the data in the buffer i want it to flag intB.

I have the following callback functions:

void SPI_DMA_master_callback(SPI_Type *base, spi_dma_handle_t *masterHandle, status_t status, void *userData)

void SPI_RxDMACallback(dma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)

void SPI_TxDMACallback(dma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)


To know the state of intA or intB, i should read the variable "tcds", however it never enters in the SPI_RxDMACallback() or SPI_TxDMACallback(), the code only gets into the function SPI_DMA_master_callback() after finishing all the descriptors.


Is there a way to check when it occurs intA and intB?


Thank you,

Kans

LPC55xxRe: Access to intA and intB of DMA descriptors when using SPI

Hello,

The reason your code only triggers SPI_DMA_master_callback() at the end of the entire chain is that MCUXpresso’s high-level spi_dma_handle_t driver overwrites the individual DMA callbacks and disables intermediate descriptor interrupts (INTA/INTB) by default. The high-level driver only notifies you when the final descriptor completes.

Re: Access to intA and intB of DMA descriptors when using SPI

Thank you for the response.


Indeed i have noticed that, so i was trying to find a way to still have access to the descriptor interrupts (INTA/INTB)

I have tried to use a custom Callback, and it seems to be working for now, to have access to intA and intB states:


*defenitions*
dma_callback g_nxp_rx_callback = NULL;
void *g_nxp_rx_userData        = NULL;
void Custom_RxDmaCallback(dma_handle_t *handle, void *userData, bool transferDone, uint32_t tcds);


*initialisation*
    g_nxp_rx_callback = FLEXCOMM0_RX_Handle.callback;
    g_nxp_rx_userData = FLEXCOMM0_RX_Handle.userData;
    DMA_SetCallback(&FLEXCOMM0_RX_Handle, Custom_RxDmaCallback, NULL);


*callback*
void Custom_RxDmaCallback(dma_handle_t *handle, void *userData, bool transferDone, uint32_t tcds)
{
    // 1. Intercept intermediate descriptor interrupts
    if (tcds == kDMA_IntA)
    {
        // Descriptor middle finished: 1st buffer filled
    	transferDone = false;
    }
    else if (tcds == kDMA_IntB)
    {
    	// Descriptor final finished: 2nd buffer filled
    	transferDone = true;
    }
    if (transferDone && g_nxp_rx_callback != NULL)
    {
        g_nxp_rx_callback(handle, g_nxp_rx_userData, transferDone, tcds);
    }
}

This way it also goes to the SPI callback function when the communication is finished, however (correct me if i am wrong), by going into the SPI callback function it changes the internal state of SPI from kSPI_Busy to kSPI_Idle, while in reality i am in an infinite loop of descriptors (after last descriptor goes straight to first descriptor), so maybe this could generate some conflicts? 

Also avoiding to move from callback to callback. 

So i decided to keep it simple:


*initialisation*

DMA_SetCallback(&FLEXCOMM0_RX_Handle, Custom_RxDmaCallback, NULL);

*callback*
void Custom_RxDmaCallback(dma_handle_t *handle, void *userData, bool transferDone, uint32_t tcds)
{
    // 1. Intercept intermediate descriptor interrupts
    if (tcds == kDMA_IntA)
    {
        // Descriptor middle finished: 1st buffer filled
    }
    else if (tcds == kDMA_IntB)
    {
    	// Descriptor final finished: 2nd buffer filled
    }
}

Tags (1)
No ratings
Version history
Last update:
4 weeks ago
Updated by: