SPI DMA STM32U031 wrong data
Hi everyone,
Im currently trying to use SPI with DMA mode on STM32U031G6 with an S2LP,
In this specific case I want to obtain the number of bytes present in my FIFO (10 bytes here), but the problem is that my reading through DMA mode does not work.
Below is the data that I analyze in SPI using a logic analyzer :

we have the read command (0x01) + the FIFO status command (0x90) + the command (0x00) where I get my response 0x0A or my 10 bytes.
What I don't understand is that the read_1_registre_DMA function returns 1 on the 3rd data item that I want to read as below :

Below is the function where I give my 3 Tx commands and where I expect 3 responses in return for Rx but the data is not correct for RX[2] (3rd element, or for me I should find my 0xA):
//-----------------------------------------------------------------------------
uint8_t S2LP_Read1Registre (uint8_t address)
//-----------------------------------------------------------------------------
{
S2LP_Init_DMA_Mode();
// Préparer les commandes SPI (HEADER + adresse FIFO)
g_SPI_DMA_TxBuffer[0] = (HEADER_READ | HEADER_ADDRESS);
g_SPI_DMA_TxBuffer[1] = address;
g_SPI_DMA_TxBuffer[2] = (0x00);
// Sélection du S2LP
S2LP_CS_DEBUT;
// Setup CNDTR
DMA1_Channel2->CNDTR = 0x03; // RX
DMA1_Channel1->CNDTR = 0x03; // TX
// Lancer RX puis TX
DMA1_Channel2->CCR |= DMA_CCR_EN;
DMA1_Channel1->CCR |= DMA_CCR_EN;
// Attente fin TX (canal 1), puis RX (canal 2)
while(DMA1_Channel1->CNDTR != 0) asm("nop");
while(DMA1_Channel2->CNDTR != 0) asm("nop");
// Fin de communication
S2LP_CS_FIN;
// Désactiver les DMA
DMA1_Channel1->CCR &= ~DMA_CCR_EN;
DMA1_Channel2->CCR &= ~DMA_CCR_EN;
uint8_t toto = g_SPI_DMA_RxBuffer[2]; //--- lecture data recue
return toto;
}
And the init_DMA Function:
uint8_t g_SPI_DMA_TxBuffer[BUF_SIZE] = {0};
uint8_t g_SPI_DMA_RxBuffer[BUF_SIZE] = {0};
void S2LP_Init_DMA_Mode (void)
{
RCC->AHBENR |= RCC_AHBENR_DMA1EN; // Horloge DMA1 ON
//Config Tx
DMA1_Channel1->CPAR = (uint32_t) &(SPI1->DR); // Definie l'adresse SPI.DR comme adresse peripherique
DMA1_Channel1->CMAR = (uint32_t) &(g_SPI_DMA_TxBuffer[0]); // Definie l'adresse tableau comme buffer Tx
DMA1_Channel1->CCR = 0; // Pour etre sur de commencer la config à vide
DMA1_Channel1->CCR |= (DMA_CCR_DIR); // Direction vers peripherique (TX)
DMA1_Channel1->CCR |= (DMA_CCR_MINC); // MEM increment mode
DMA1_Channel1->CCR |= (DMA_CCR_PL_1); // Haute priorite pour le SPI gere uniquement les operations faites en DMA
//DMA1_Channel1->CNDTR = 0x03; // 3 data
//Config Rx
DMA1_Channel2->CPAR = (uint32_t) &(SPI1->DR); // Definie l'adresse SPI.DR comme adresse peripherique
DMA1_Channel2->CMAR = (uint32_t) &(g_SPI_DMA_RxBuffer[0]); // Definie l'adresse tableau comme buffer Rx
DMA1_Channel2->CCR = 0; // Pour etre sur de commencer la config à vide
// Attention ici on active pas DMA_CCR_DIR car on va dans le sens inverse justement !
DMA1_Channel2->CCR |= (DMA_CCR_MINC); //MEM increment mode
DMA1_Channel2->CCR |= (DMA_CCR_PL_0 | DMA_CCR_PL_1); // Haute priorite pour le SPI gere uniquement les opérations faites en DMA
//DMA1_Channel2->CNDTR = 0x01; //1 data
// -- Usage DMA MUX --
// Selection du MUX DMAMUX1 channel_x <=HARD=> DMA_Channel_x+1
//----------------------------------------------------------
DMAMUX1_Channel0->CCR = 37; // Selection du MUX DMAMUX1 channel_0 <=HARD=> DMA_Channel_1
DMAMUX1_Channel1->CCR = 36; // Selection du MUX DMAMUX1 channel_1 <=HARD=> DMA_Channel_2
// ... ...
}
Thanks for your time !
