2026-02-06 5:33 AM
Hello Team,
I am currently working on QuadSPI with MDMA, but I am unable to locate the driver code for this functionality.
Could you please provide the required driver code?
For reference, I am working on the STM32MP133F series.
Regards,
Sreedhar Kaduru
2026-02-06 8:32 AM
Hi,
please see device tree bindings for Linux usage:
https://github.com/STMicroelectronics/linux/blob/v6.6-stm32mp/Documentation/devicetree/bindings/spi/st,stm32-qspi.yaml#L72
For bare-metal, please look for stm32mp13xx_hal_xspi.c
Regards
2026-02-09 1:38 AM
Hi,
Thanks for your quick reply.
I developed the following code to use QSPI with MDMA. During the transfer, when using MDMA, the BUSY bit in the QUADSPI status register gets set and does not clear.
Could you please let me know where I might be making a mistake?
// #includes
//
#include "stm32mp13xx.h" // STM32MP13xx Microprocessor specific definition
#include "MDMA_Private.h" // MDMA private interface
// ===============================================================================================================================
// Static/Global variables
//
// MDMA device channel available in STM32MP
MDMA_Channel_TypeDef* g_pastMDMAChannel[MDMA_CH_MAX] = { MDMA_Channel0, MDMA_Channel1, MDMA_Channel2, MDMA_Channel3, \
MDMA_Channel4, MDMA_Channel5, MDMA_Channel6, MDMA_Channel7, \
MDMA_Channel8, MDMA_Channel9, MDMA_Channel10, MDMA_Channel11, \
MDMA_Channel12, MDMA_Channel13, MDMA_Channel14, MDMA_Channel15,\
MDMA_Channel16, MDMA_Channel17, MDMA_Channel18, MDMA_Channel19,\
MDMA_Channel20, MDMA_Channel21, MDMA_Channel22, MDMA_Channel23,\
MDMA_Channel24, MDMA_Channel25, MDMA_Channel26, MDMA_Channel27,\
MDMA_Channel28, MDMA_Channel29, MDMA_Channel30, MDMA_Channel31 };
// MDMA device initialized flag
BOOL s_fMDMAInitialized = FALSE;
// ===============================================================================================================================
// API Functions
//3
//*********************************************************************************************************************************
// Function Name: MDMA_Init
//
// Prototype Description: Devices\Inc\MDMA_Private.h
//
// Algorithm:
//*********************************************************************************************************************************
VOID MDMA_Init(VOID)
{
if (s_fMDMAInitialized == FALSE)
{
// Enable clock for MDMA peripheral
RCC->MP_NS_AHB6ENSETR = RCC_MP_NS_AHB6ENSETR_MDMAEN;
// Enable clock for TZCEN
RCC->MP_APB5ENSETR = RCC_MP_APB5ENSETR_ETZPCEN;
// Set the flag to indicate that the MDMA transport has been initialized
s_fMDMAInitialized = TRUE;
}
}
//*********************************************************************************************************************************
// Function Name: MDMA_ConfigureChannel
//
// Prototype Description: Devices\Inc\MDMA_Private.h
//
// Algorithm:
//
//*********************************************************************************************************************************
UINT MDMA_ConfigureChannel( UCHAR ucMDMAChNo, MDMA_CONFIG* pstMDMAConfig)
{
UINT uiRetVal = SUCCESS;
// Validate the parameters
if ((ucMDMAChNo >= MDMA_CH_MAX) ||(pstMDMAConfig == NULL) ||
((pstMDMAConfig->uiDestinationaddr) == NULL) || ((pstMDMAConfig->uiSourceaddr) == NULL) ||
((pstMDMAConfig->uiNumbytes) == 0) )
{
uiRetVal = PARAMETER_ERROR;
}
else
{
// Clear MDMA channel
g_pastMDMAChannel[ucMDMAChNo]->CCR &= ~(MDMA_CCR_EN);
g_pastMDMAChannel[ucMDMAChNo]->CCR |= ((pstMDMAConfig->ePriorityLevel) << MDMA_CCR_PL_Pos);
g_pastMDMAChannel[ucMDMAChNo]->CTCR &= ~(MDMA_CTCR_SINC| MDMA_CTCR_DINC| MDMA_CTCR_SSIZE| MDMA_CTCR_DSIZE| MDMA_CTCR_TLEN);
if (pstMDMAConfig->uiTriggerSignal == MDMA_REQUEST_QUADSPI_TC)
{
g_pastMDMAChannel[ucMDMAChNo]->CTCR &= ~MDMA_CTCR_DINC_0;
g_pastMDMAChannel[ucMDMAChNo]->CTCR |= MDMA_CTCR_SINC_0;
g_pastMDMAChannel[ucMDMAChNo]->CTBR |= MDMA_REQUEST_QUADSPI_TC;
}
else
{
g_pastMDMAChannel[ucMDMAChNo]->CTCR &= ~MDMA_CTCR_SINC_0;
g_pastMDMAChannel[ucMDMAChNo]->CTCR |= MDMA_CTCR_DINC_0;
g_pastMDMAChannel[ucMDMAChNo]->CTBR |= MDMA_REQUEST_QUADSPI_FIFO_TH;
}
g_pastMDMAChannel[ucMDMAChNo]->CTCR |= (pstMDMAConfig->uiNumbytes - 1) << MDMA_CTCR_TLEN_Pos;
g_pastMDMAChannel[ucMDMAChNo]->CTCR |= MDMA_CTCR_TRGM_0;
g_pastMDMAChannel[ucMDMAChNo]->CBNDTR |= (pstMDMAConfig->uiNumbytes - 1);
g_pastMDMAChannel[ucMDMAChNo]->CSAR = pstMDMAConfig->uiSourceaddr;
g_pastMDMAChannel[ucMDMAChNo]->CDAR = pstMDMAConfig->uiDestinationaddr;
// Write Link Address Register
g_pastMDMAChannel[ucMDMAChNo]->CLAR = 0;
g_pastMDMAChannel[ucMDMAChNo]->CIFCR = MDMA_CIFCR_CTEIF | MDMA_CIFCR_CCTCIF | MDMA_CISR_BRTIF | MDMA_CISR_BTIF | MDMA_CISR_TCIF;
g_pastMDMAChannel[ucMDMAChNo]->CCR |= MDMA_CCR_TEIE | MDMA_CCR_BTIE | MDMA_CCR_CTCIE| MDMA_CCR_TCIE;
// Clear MDMA channel
g_pastMDMAChannel[ucMDMAChNo]->CCR |= MDMA_CCR_EN;
}
return uiRetVal;
}
2026-02-12 2:16 AM
2026-02-12 2:31 AM
Hi,
Maybe better to do a first try using available STM32CubeMP13 bare-metal libraries.
https://wiki.st.com/stm32mpu/wiki/STM32CubeMP13_Package#HAL_drivers
https://www.st.com/en/embedded-software/stm32cubemp13.html#get-software
https://github.com/STMicroelectronics/STM32CubeMP13
Regards.