Skip to main content
Visitor II
March 7, 2018
Solved

[SOLVED] STM32H7 SPI does not seem to work with DMA

  • March 7, 2018
  • 11 replies
  • 11504 views
Posted on March 07, 2018 at 13:01

EDIT: 14/03/2018

https://community.st.com/people/Schwaninger.Hannes

‌ found that we need to use RAM_D1 and not DTCMRAM of the memory area. This is not made by default when we use STM32CubeMx to set SPI and DMA together. Hello, I am working on a full duplex SPI communication through DMA using STM32H7. So, I have bought 2 NUCLEO-H743ZI, one to be the master, the other to be the slave. I have downloaded, built and flashed SPI_FullDuplex_ComDMA example via TrueStudio. As there is no ''TrueStudio format'' example, I have generated the project with STM32CubeMx and replace Inc and Src generated files with SPI_FullDuplex_ComDMAfiles. And tadada! ... It is not working correctly....... Only a few bytes are sent and Rxbuffer is never filled.

0690X00000609ynQAA.png

I have made connexion wires as short as possible and I have increased spi clock prescaler to get ''slow, nice and smooth'' signals. Electronic not seems to be the problem. I have modified the example to run it without DMA by replacing :

HAL_SPI_TransmitReceive_DMA(&SpiHandle, (uint8_t*)aTxBuffer, (uint8_t *)aRxBuffer, BUFFERSIZE)�?�?�?�?�?�?�?�?�?�?

With :

HAL_SPI_TransmitReceive(&SpiHandle, (uint8_t*)aTxBuffer, (uint8_t *)aRxBuffer, BUFFERSIZE,5000)�?�?�?�?�?�?�?�?�?�?

And now it's working! But not with the DMA .... This test shows that SPI is set and works correctly. aRxBuffer is filled with the good values.

0690X00000609w9QAA.png

Back in my code, I am trying now to send data through DMA with master and read them with slave:

// Master
HAL_SPI_Transmit_DMA(&SpiHandle, (uint8_t*)aTxBuffer, BUFFERSIZE)
// Slave
HAL_SPI_TransmitReceive(&SpiHandle, (uint8_t*)aTxBuffer, (uint8_t *)aRxBuffer, BUFFERSIZE, 5000)�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

It's working! Master sends DATA through DMA and my aRxBuffer is correctly filled on slave.

However, I have never been able to read DATA on master or slave with one of these functions:

HAL_SPI_TransmitReceive_DMA(&SpiHandle, (uint8_t*)aTxBuffer, (uint8_t *)aRxBuffer, BUFFERSIZE)
HAL_SPI_Receive_DMA(&SpiHandle, (uint8_t *)aRxBuffer, BUFFERSIZE)�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

I have tried to set DMA and SPI with STM32CubeMx but the problem remains the same. HAL_SPI_TransmitReceive_DMA always returns HAL_OK but code quickly falls into HAL_SPI_ErrorCallback. That only happens with DMA, never wih SPI only...

I do not think that I am doing something wrong as I have not modified the SPI_FullDuplex_ComDMA''example'' Src and Inc files...

EDIT: 13/03/2018

I have tried HAL_SPI_TransmitReceive_DMA and HAL_SPI_Receive_DMA on a STM32F7 to be sure that there is no technological problem on Cortex-M7. All DMA functions are working perfectly with F7.

EDIT: 14/03/2018

https://community.st.com/people/Schwaninger.Hannes

has tested SPI_FullDuplex_ComDMA example with Keil and it seems to work. However, he can't make it work with same configuration files if he creates a new project.

For me there is a problem with files generated by STM32CubeMX.

Does anyone have already made a full duplex spi communication with dma on a stm32h7 with a new STM32CubeMx project?

Thanks for your help!

#dma #spi #nucleo-h743zi #stm32h7 #hal
    This topic has been closed for replies.
    Best answer by H S
    Posted on March 14, 2018 at 18:03

    I've just found the difference between the HAL Nucelo example projects and the CubeMX generated projects.The problem for the DMA transfer error is that we use the false RAM!!

    I have changed the settings in MDK-ARM from

    IRAM1 (default setting from CubeMX) to

    IRAM2 (same is in the example projects) and now the SPI DMA transfer runs without error.

    0690X0000060A89QAE.png

    I've found out, that with this memory address

    IRAM1 is the

    DTCM-RAM and

    IRAM2 is the

    AXI SRAM D1.

     

    enjolras.g

    please check also in your project with TrueStudio and if it works, please share also the correct settings.

    11 replies

    Visitor II
    June 18, 2022

    Hi to all!

    @Geo En​  @Community member​ 

    I have read this post, but could not understand how to edit code for DMA SPI transmit.

    It is my post about problem https://community.st.com/s/question/0D53W00001atD9zSAE/stm32h7-spi-dma-not-working

    I have STM32H745 nucleo. I want to use M4 core . In D2 domain i use SRAM1-SRAM3, DMA2 . I need to send data via SPI-DMA (SPI4, PE14 MOSI, DMA2_stream3, DMAUX11 ) I dont have any on MOSI pin + DMA2_IRQ_Handler don't work.

    The same i have corectly did on stm32f407 - all worked good and spi dma transaction work.

    Could you look my code and help me to edited SPI-DMA transaction ?

    On STM32H745 i get correct work only SPI transmiting with out DMA

    Could any body help me and explain how to solve my problem ?

    Here i don't get helping about my problem https://community.st.com/s/article/FAQ-DMA-is-not-working-on-STM32H7-devices (((

    Best regards

    Visitor II
    June 19, 2022

    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.