Using sdma and ecspi with M4 on imx8mq

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

Using sdma and ecspi with M4 on imx8mq

1,068 Views
pdubois
Contributor II

Hi,

I want to use the escpi with the sdma on the m4. As the MIMXMQ6 doesn't have the sdma driver in the mcuxpresso sdk, I copied the files fsl_sdma.h/.c, fsl_ecspi_sdma.h/.c and fsl_memory.h from MIMXMM6 since the two processors are similar. I added missing defines to MIMx8mq6_cm4.h and MIMX8MQ6_cm4_features.h and modified some struct.

The code compiles and run to the end but nothing on the ecspi lines, ECSPI_MasterTransferSDMA and SDMA_GetErrorStatus return 0. I can send data manually with ECSPI_MasterTransferBlocking(). I also modified the fsl-imx8mq-var-dart-common.dtsi to disable the sdma1 and sdma2.

I'm not sure if it is possible to use the sdma with m4 on imx8mq, I find it strange some sdma defines are present but not all (FSL_FEATURE_SOC_SDMA_COUNT is missing, but FSL_FEATURE_SDMA_MODULE_CHANNEL is present).

I don't understand why in examples for mx8mm the sdma channel request was offset by 2 unlike the Applications Processors Reference Manual (7.1.4 SDMA event mapping) for escpi and uart, or did I miss something? I tried to use the value in datasheet but the SDMA_GetErrorStatus returns the ecspi TX dma channel (not the channel request).

 

#define RTE_SPI1_DMA_TX_CH_REQUEST (3U)
#define RTE_SPI1_DMA_RX_CH_REQUEST (2U)

pastedImage_5.png

or for uart 3:

#define DEMO_UART UART3
#define UART_RX_DMA_REQUEST (28)
#define UART_TX_DMA_REQUEST (29)

pastedImage_6.png

To debug, I redefined the SDMA1_IRQHandler(), and it was called after ECSPI_MasterTransferSDMA() two times with SDMA_GetChannelInterruptStatus() equal to 1 and 1. As the SDMA1_IRQHandler is define in fsl_sdma.c, I normally comment my IRQHandler.

My code:

#define ECSPI_TRANSFER_BAUDRATE 10000000U
#define ECSPI_MASTER_BASEADDR ECSPI1
#define ECSPI_MASTER_CLK_FREQ \
CLOCK_GetPllFreq(kCLOCK_SystemPll1Ctrl) / (CLOCK_GetRootPreDivider(kCLOCK_RootEcspi1)) / \
(CLOCK_GetRootPostDivider(kCLOCK_RootEcspi1))
#define ECSPI_MASTER_TRANSFER_CHANNEL kECSPI_Channel0

#define DRIVER_MASTER_SPI_DMA_BASE SDMAARM1
#define RTE_SPI1_DMA_TX_CH (2U)
#define RTE_SPI1_DMA_TX_CH_REQUEST (3U)
#define RTE_SPI1_DMA_TX_CH_PRIORITY (3U)
#define RTE_SPI1_DMA_RX_CH (1U)
#define RTE_SPI1_DMA_RX_CH_REQUEST (2U)
#define RTE_SPI1_DMA_RX_CH_PRIORITY (2U)

AT_NONCACHEABLE_SECTION_ALIGN(ecspi_sdma_handle_t g_escpiSdmaHandle, 4);
AT_NONCACHEABLE_SECTION_ALIGN(sdma_handle_t g_escpiTxSdmaHandle, 4);
AT_NONCACHEABLE_SECTION_ALIGN(sdma_handle_t g_escpiRxSdmaHandle, 4);

AT_NONCACHEABLE_SECTION_ALIGN(sdma_context_data_t context_Tx, 4);
AT_NONCACHEABLE_SECTION_ALIGN(sdma_context_data_t context_Rx, 4);

AT_NONCACHEABLE_SECTION_ALIGN(ecspi_transfer_t sendXfer, 4);
AT_NONCACHEABLE_SECTION_ALIGN(ecspi_transfer_t receiveXfer, 4);


AT_NONCACHEABLE_SECTION_ALIGN(uint32_t g_txBuffer[TRANSFER_SIZE], 4);
AT_NONCACHEABLE_SECTION_ALIGN(uint32_t g_rxBuffer[TRANSFER_SIZE], 4);

// To Debug
/* void SDMA1_IRQHandler(void)
{
//PRINTF("SDMA1_IRQHandler");

uint32_t val = SDMA_GetChannelInterruptStatus(SDMAARM1);

PRINTF("dma val:%x", val);

SDMA_ClearChannelInterruptStatus(SDMAARM1, val);

#if defined __CORTEX_M && (__CORTEX_M == 4U)
__DSB();
#endif
}
*/

void ecspiCallBack(ECSPI_Type* base, ecspi_sdma_handle_t* handle, status_t status, void* userData)
{
PRINTF("ECSPI Callback");
}

int main()
{

/*set SDMA1 PERIPH to M4 Domain(DID=1),due to UART not be accessible by DID=0 by default*/
rdc_domain_assignment_t assignment = { 0 };
assignment.domainId = BOARD_DOMAIN_ID;
RDC_SetMasterDomainAssignment(RDC, kRDC_Master_SDMA1_PERIPH, &assignment);

BOARD_RdcInit();

BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();
BOARD_InitMemory();
APP_RDC_Periph();

CLOCK_SetRootMux(kCLOCK_RootEcspi1, kCLOCK_EcspiRootmuxSysPll1); /* Set ECSPI1 source to SYSTEM PLL1 800MHZ */
CLOCK_SetRootDivider(kCLOCK_RootEcspi1, 1U, 1U); 


NVIC_SetPriority(ECSPI1_IRQn, 7);
EnableIRQ(ECSPI1_IRQn);

// Init ecspi

ecspi_master_config_t masterConfig;
ECSPI_MasterGetDefaultConfig(&masterConfig);

masterConfig.channelConfig.polarity = kECSPI_PolarityActiveHigh;
masterConfig.channelConfig.phase = kECSPI_ClockPhaseSecondEdge;
masterConfig.baudRate_Bps = ECSPI_TRANSFER_BAUDRATE;
masterConfig.channelConfig.waveForm = kECSPI_WaveFormSingle;

ECSPI_MasterInit(ECSPI_MASTER_BASEADDR, &masterConfig, ECSPI_MASTER_CLK_FREQ);

sdma_config_t sdmaConfig;

SDMA_EnableChannelErrorInterrupts(DRIVER_MASTER_SPI_DMA_BASE, RTE_SPI1_DMA_TX_CH);
SDMA_EnableChannelErrorInterrupts(DRIVER_MASTER_SPI_DMA_BASE, RTE_SPI1_DMA_RX_CH);

SDMA_GetDefaultConfig(&sdmaConfig);


SDMA_Init(DRIVER_MASTER_SPI_DMA_BASE, &sdmaConfig);


SDMA_CreateHandle(&g_escpiTxSdmaHandle, DRIVER_MASTER_SPI_DMA_BASE, RTE_SPI1_DMA_TX_CH, &context_Tx);
SDMA_CreateHandle(&g_escpiRxSdmaHandle, DRIVER_MASTER_SPI_DMA_BASE, RTE_SPI1_DMA_RX_CH, &context_Rx);


SDMA_SetChannelPriority(DRIVER_MASTER_SPI_DMA_BASE, RTE_SPI1_DMA_TX_CH, RTE_SPI1_DMA_TX_CH_PRIORITY);
SDMA_SetChannelPriority(DRIVER_MASTER_SPI_DMA_BASE, RTE_SPI1_DMA_RX_CH, RTE_SPI1_DMA_RX_CH_PRIORITY);

ECSPI_MasterTransferCreateHandleSDMA(ECSPI_MASTER_BASEADDR, &g_escpiSdmaHandle, ecspiCallBack, NULL, &g_escpiTxSdmaHandle, &g_escpiRxSdmaHandle, RTE_SPI1_DMA_TX_CH_REQUEST, RTE_SPI1_DMA_RX_CH_REQUEST, RTE_SPI1_DMA_TX_CH, RTE_SPI1_DMA_RX_CH);

uint32_t txData[10] = {0x11, 0x31, 0x77,0x44,0x12,0x99,0x69,0x34,0x25,0x22};

memcpy(g_txBuffer, txData, sizeof(uint32_t) * 10);

sendXfer.txData = g_txBuffer;
sendXfer.rxData = g_rxBuffer;
sendXfer.dataSize = 10;
sendXfer.channel = kECSPI_Channel0;
status_t status = ECSPI_MasterTransferSDMA(ECSPI_MASTER_BASEADDR, &g_escpiSdmaHandle, &sendXfer);
PRINTF("status = %i", status);

uint32_t err = SDMA_GetErrorStatus(DRIVER_MASTER_SPI_DMA_BASE);
PRINTF("err = %x", err);

}

Thanks.

Labels (1)
0 Kudos
0 Replies