cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7 SPI DMA not working

AAnt.1
Associate II

STM32H7 SPI DMA not working

Hi. I have stm32H745 nucleo board, in my project i want send data from MOSI via DMA (i did the same on old F4 discovery correctly).

PE_14, SPI4 , DMA2_stream3, DMUX11=84 (for tx spi4)

In project i need to send data (fb[][]) then generated interrupt. For exam for correct work the IRQ_handler inside interrupt function i switched PG_9.

It did not work, dma don't send data, there no switching PG_9 inside handler function.

Could anybody help me ?

Me code bellow

Function for SPI_DMA initialisation:

void SPI_Configuration(void)

{

   SPI_InitTypeDef         SPI_InitStructure;

   DMA_InitTypeDef         DMA_InitStructure;

   GPIO_InitTypeDef        GPIO_InitStructure;

   SPI_HandleTypeDef       SpiHandle;

 //static

      DMA_HandleTypeDef hdma_tx;   

 #define SPIx                            SPI4 

   #define SPIx_MOSI_GPIO_CLK_ENABLE()     __HAL_RCC_GPIOE_CLK_ENABLE()

   #define SPIx_CLK_ENABLE()               __HAL_RCC_SPI4_CLK_ENABLE()

 #define DMAx_CLK_ENABLE()               __HAL_RCC_DMA2_CLK_ENABLE()

   /*##-1- Enable peripherals and GPIO Clocks #################################*/

 /* Enable GPIO TX/RX clock */

 SPIx_MOSI_GPIO_CLK_ENABLE();

 /* Enable SPI1 clock */

 SPIx_CLK_ENABLE();

 /* Enable DMA clock */

 DMAx_CLK_ENABLE();

    // Common configuration for all channels

 GPIO_InitStructure.Pin = GPIO_PIN_14 ;

   GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;

 GPIO_InitStructure.Pull = GPIO_NOPULL;

 GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

 GPIO_InitStructure.Alternate = GPIO_AF5_SPI4;

 HAL_GPIO_Init(GPIOE, &GPIO_InitStructure);

 /*##-3- Configure the DMA ##################################################*/

 /* Configure the DMA handler for Transmission process */

 hdma_tx.Instance                = DMA2_Stream3; // SPI4 maybe?

 hdma_tx.Init.FIFOMode           = DMA_FIFOMODE_DISABLE;

 hdma_tx.Init.FIFOThreshold      = DMA_FIFO_THRESHOLD_FULL;

 hdma_tx.Init.MemBurst           = DMA_MBURST_INC4;

 hdma_tx.Init.PeriphBurst        = DMA_PBURST_INC4;

 hdma_tx.Init.Request            = DMA_REQUEST_SPI4_TX;

 hdma_tx.Init.Direction          = DMA_MEMORY_TO_PERIPH;

 hdma_tx.Init.PeriphInc          = DMA_PINC_DISABLE;

 hdma_tx.Init.MemInc             = DMA_MINC_ENABLE;

 hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;

 hdma_tx.Init.MemDataAlignment   = DMA_MDATAALIGN_BYTE;

 hdma_tx.Init.Mode               = DMA_NORMAL;

 hdma_tx.Init.Priority           = DMA_PRIORITY_LOW;

 HAL_DMA_Init(&hdma_tx);

   /* Associate the initialized DMA handle to the the SPI handle */

   //__HAL_LINKDMA(SPI4, hdmatx, hdma_tx);      // navisho ???

 /*##-1- Configure the SPI peripheral #######################################*/

 /* Set the SPI parameters */

 SpiHandle.Instance              = SPI4;

 SpiHandle.Init.Mode             = SPI_MODE_MASTER;

 SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64; // use 4 for 400 pixels, 2 for 800 pixels

 SpiHandle.Init.Direction        = SPI_DIRECTION_1LINE;

 SpiHandle.Init.CLKPhase         = SPI_PHASE_2EDGE;

 SpiHandle.Init.CLKPolarity      = SPI_POLARITY_LOW;

 SpiHandle.Init.DataSize         = SPI_DATASIZE_8BIT;

 SpiHandle.Init.FirstBit         = SPI_FIRSTBIT_MSB;

 SpiHandle.Init.TIMode           = SPI_TIMODE_DISABLE;

 SpiHandle.Init.CRCCalculation   = SPI_CRCCALCULATION_DISABLE;

 SpiHandle.Init.CRCPolynomial    = 7;

 SpiHandle.Init.CRCLength        = SPI_CRC_LENGTH_8BIT;

 SpiHandle.Init.NSS              = SPI_NSS_SOFT;

 SpiHandle.Init.NSSPMode         = SPI_NSS_PULSE_DISABLE;

 SpiHandle.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_ENABLE; /* Recommanded setting to avoid glitches */

 HAL_SPI_Init(&SpiHandle);

 /*##-4- Configure the NVIC for DMA #########################################*/

 /* NVIC configuration for DMA transfer complete interrupt (SPI4_TX) */

 HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 1, 1);

 HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);

 SPI4->CR1 &= ~SPI_CR1_SPE;

 // SPI4->CR2 = 7;

 DMA_STREAM->CR&= ~DMA_SxCR_EN; // clear the EN bit to disable the stream

 DMA_STREAM->PAR = (uint32_t) &(SPI4->TXDR);

   DMA_STREAM->NDTR = VTOTAL;            // set number of bytes to transfer

   DMA_STREAM->M0AR = (u32) &fb[0][0];      // set start of frame buffer

 DMA_STREAM->CR|=DMA_SxCR_CIRC | DMA_SxCR_TCIE;

    DMAMUX1_Channel11->CCR = 84; //SPI4_TX vs DMA2_Stream3;

   DMAMUX1_Channel11->CCR |=DMAMUX_CxCR_EGE ; //| DMAMUX_SPI1_RX_ID;

 //SPI4->IER |= SPI_IER_TXPIE;

 SPI4->CFG1 |= SPI_CFG1_TXDMAEN;

   //SPI4->CR1 |= SPI_CR1_CSTART;   

 SPI4->CR1 |= SPI_CR1_SPE;

 DMA_STREAM->CR|= DMA_SxCR_EN; // set the EN bit to disable the stream

   // DMAMUX1 channels 8 to 15 are connected to DMA2 channels 0 to 7

   // 84 spi4_tx_dma

   // DMA1_Stream_x -> DMAMUX1_Channel_x

 //DMA2_Stream_x -> DMAMUX1_Channel_(x+8)

}

Function for Interrupt

void DMA2_Stream3_IRQHandler(void)

{   

   VIDEO_DMA->LIFCR = DMA_LIFCR_CTCIF3;   // clear the transfer complete interrupt flag

   DMA_STREAM->CR &= ~DMA_SxCR_EN;         // clear the EN bit to disable the stream

   DMA_STREAM->NDTR = VTOTAL;            // reload the number of bytes to send

   HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_9);

}

3 REPLIES 3
Imen.D
ST Employee

Hello @AAnt.1​ and welcome to the Community 🙂

Perhaps this FAQ will help: DMA is not working on STM32H7 devices

Check the DMA status for errors.

You can check SPI examples in the STM32CubeH7 MCU package.

Imen

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen
AAnt.1
Associate II

Hi @Imen DAHMEN​ 

phanks for interst to my problem, but your topic i have been read in past.

It don't help me.

I use two core M7 and M4. M4 core (D2 domain) i use for transmit data trouth MOSI PE_14 DMA_2

M7 core i don't use with DMA.

When transaction will finish i need to generate interrupt - i didn't saw switching PG_9 inside interrupt function. DMA transaction don't start.

M4 core i use with SRAM1, SRAM2, SRAM3. In Keil i wrote IRAM1 addres 0x10 000 000 size 0x48000 - it don't help me. And i probed addres 0x30 000 000 same size - zero rezult.

I wrote my code upper, may be i got mistake with registers for SPI or DMA start ?

Hi to all! My old code:

https://community.st.com/s/question/0D53W00001atD9zSAE/stm32h7-spi-dma-not-working

I write modernized code - i could get only done function of IRQ_Handler, insite function LED switched, PD9 switched . That means - i can enter inside IRQ_handler and handler work, not stoped inside, but don't have any signal on MOSI SPI PIN .....

Me modernized code

function main.c

 DMA_HandleTypeDef hdma_tx;

   SPI_HandleTypeDef       SpiHandle;

#define TBS0 11

uint8_t TBuf0[TBS0]={0,1,2,3,4,5,6,7,8,9,11};

SPI_Configuration( );

.....

 while (1)

 {

   HAL_DMA_Start_IT(&hdma_tx, *TBuf0,(uint32_t) &(SPI4->TXDR),TBS0);

}

function for SPI_DMA init

#define VIDEO_DMA            DMA2

#define DMA_STREAM              DMA2_Stream3

#define DMA_CHANNEL             DMA_Channel_3

void SPI_Configuration( void ) 

{

   GPIO_InitTypeDef        GPIO_InitStructure;     

// RCC->AHB2ENR |= (RCC_AHB2ENR_D2SRAM1EN | RCC_AHB2ENR_D2SRAM2EN | RCC_AHB2ENR_D2SRAM3EN);  // Enable the SRAM

//   __HAL_RCC_D2SRAM1_CLK_ENABLE();

//   __HAL_RCC_D2SRAM2_CLK_ENABLE();

//   __HAL_RCC_D2SRAM3_CLK_ENABLE();

   #define SPI4_FORCE_RESET()              __HAL_RCC_SPI4_FORCE_RESET()

 #define SPI4_RELEASE_RESET()            __HAL_RCC_SPI4_RELEASE_RESET()

 #define SPIx                            SPI4 

   #define SPIx_MOSI_GPIO_CLK_ENABLE()     __HAL_RCC_GPIOE_CLK_ENABLE()

   #define SPIx_CLK_ENABLE()               __HAL_RCC_SPI4_CLK_ENABLE()

 #define DMAx_CLK_ENABLE()               __HAL_RCC_DMA2_CLK_ENABLE()

   SPI4_FORCE_RESET();

   SPI4_RELEASE_RESET();

      HAL_DMA_DeInit(&hdma_tx);

   // ##-1- Enable peripherals and GPIO Clocks #################################

 // Enable GPIO TX/RX clock

 SPIx_MOSI_GPIO_CLK_ENABLE();

 // Enable SPI1 clock

 SPIx_CLK_ENABLE();

 // Enable DMA clock

 DMAx_CLK_ENABLE();

    // Common configuration for all channels

 GPIO_InitStructure.Pin = GPIO_PIN_14 | GPIO_PIN_12; // PE12 SPI SCK

   GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;

 GPIO_InitStructure.Pull = GPIO_NOPULL;

 GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

 GPIO_InitStructure.Alternate = GPIO_AF5_SPI4;

 HAL_GPIO_Init(GPIOE, &GPIO_InitStructure);

 // ##-3- Configure the DMA

 // Configure the DMA handler for Transmission process

 hdma_tx.Instance                = DMA_STREAM; // SPI4 maybe?

 hdma_tx.Init.FIFOMode           = DMA_FIFOMODE_DISABLE;

 hdma_tx.Init.FIFOThreshold      = DMA_FIFO_THRESHOLD_FULL;

 hdma_tx.Init.MemBurst           = DMA_MBURST_SINGLE;

 hdma_tx.Init.PeriphBurst        = DMA_PBURST_SINGLE;

 hdma_tx.Init.Request            = DMA_REQUEST_SPI4_TX;

 hdma_tx.Init.Direction          = DMA_MEMORY_TO_PERIPH;

 hdma_tx.Init.PeriphInc          = DMA_PINC_DISABLE; 

 hdma_tx.Init.MemInc             = DMA_MINC_ENABLE;  

 hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;

 hdma_tx.Init.MemDataAlignment   = DMA_MDATAALIGN_BYTE;

 hdma_tx.Init.Mode               =  DMA_CIRCULAR; //DMA_NORMAL;  // ????? 

 hdma_tx.Init.Priority           = DMA_PRIORITY_HIGH; // ????

 HAL_DMA_Init(&hdma_tx);

 // ##-1- Configure the SPI peripheral

 // Set the SPI parameters

 SpiHandle.Instance              = SPI4;

 SpiHandle.Init.Mode             = SPI_MODE_MASTER;

 SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; 

 SpiHandle.Init.Direction        = SPI_DIRECTION_2LINES_TXONLY;

 SpiHandle.Init.CLKPhase         = SPI_PHASE_2EDGE;

 SpiHandle.Init.CLKPolarity      = SPI_POLARITY_LOW;

 SpiHandle.Init.DataSize         = SPI_DATASIZE_8BIT;

 SpiHandle.Init.FirstBit         = SPI_FIRSTBIT_MSB;

 SpiHandle.Init.TIMode           = SPI_TIMODE_DISABLE;

 SpiHandle.Init.CRCCalculation   = SPI_CRCCALCULATION_DISABLE;

 SpiHandle.Init.CRCPolynomial    = 7;

 SpiHandle.Init.CRCLength        = SPI_CRC_LENGTH_8BIT;

 SpiHandle.Init.NSS              = SPI_NSS_SOFT;

 SpiHandle.Init.NSSPMode         = SPI_NSS_PULSE_DISABLE;

 SpiHandle.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_ENABLE; 

 HAL_SPI_Init(&SpiHandle);

 // ##-4- Configure the NVIC for DMA

 // NVIC configuration for DMA transfer complete interrupt (SPI4_TX)

 HAL_NVIC_SetPriority(DMA_INTERRUPT, 1, 1); //DMA2_Stream3_IRQn

 HAL_NVIC_EnableIRQ(DMA_INTERRUPT);  //  DMA2_Stream3_IRQn

}

Function for INTERRUPT and switching PIN inside

void DMA2_Stream3_IRQHandler(void)

{   

   HAL_DMA_IRQHandler(&hdma_tx);

   HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0); // LD1 blinky

   HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_9); // PD9 blinky

}

If i understand, DMA start to work, because interrupt handler worked, but DMA don'nt send any signal to MOSI PE14 pin.....

Best regards.