Skip to main content
Graduate II
July 2, 2025
Solved

SPI GPIOs don't work (except SCK) using DMA

  • July 2, 2025
  • 3 replies
  • 867 views

Hi, 

I am using an STM32H7RSxx device and I need to use the SPI6 (both full and half duplex) with the DMA.

The problem I am facing on is the MOSI pin doesn't transmit anything.Only the SCK is working.

Despite having configured it for SPI6 Alternate Function (according to datasheet)

simozz_0-1751471885253.png

 // SPI6 pins
 // SCLK, MISO, MISO, NSS
 GPIO_InitStruct.Pin = LL_GPIO_PIN_4 | LL_GPIO_PIN_5 | LL_GPIO_PIN_6 | LL_GPIO_PIN_7;
 GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
 GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
 GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
 GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
 GPIO_InitStruct.Alternate = LL_GPIO_AF_8;
 LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

it always stays to low level.

What is strange is the fact that if I use PB5 as SPI6 MOSI 

simozz_1-1751471952301.png

I can see as the pin stays at high level in idle state, but low for the rest of transmission, and this is quiet confusing.

If I am not blind at all, the TRM and datasheet does not say anything about it..

Of course the DMA transmission buffer is not zero.

I have read on another post that the order of initialization can matter, but honestly, I could not figure out the solution.

I attached a small working example of what I am doing, I hope I will receive some hint.

Thanks,

s.

 

    This topic has been closed for replies.
    Best answer by TDK

    If cache is enabled in the bootloader, it's still enabled in the application.

     

    SCB_EnableDCache() is executed in Boot/Src/main.c otherwise the FW does not run at all.

    Perhaps look into this. There is certainly a bug here which is causing this issue. Debug the program so you can elaborate on "does not run at all". See where execution stops, and why, and fix it.

     

    > I understand that cache should not be used at all, right?

    Cache is fine to use, but it must be managed appropriately. Cleaned and invalidated at appropriate times. This is often done incorrectly and when using DMA, the symptom is that you are sending data that has been written to cache but not to memory, so it shows up as bogus data (0x00).

    For debugging, the simple way to diagnose and fix this issue is to disable cache. The more complicated way is to handle cache appropriately.

    Level 1 cache on STM32F7 Series and STM32H7 Series

    3 replies

    Super User
    July 2, 2025

    Almost certainly a cache problem. Try disabling data cache while you are debugging.

     

    The posted code doesn't seem to use SPI at all.

    TDK_0-1751480099581.png

     

    simo zzAuthor
    Graduate II
    July 2, 2025

    Hello @TDK

    Thanks, interesting the cache hint. I will try as soon as possible.

    The SPI DMA transfer is triggered from EXTI13_IRQHandler() in stm32h7rsxx_it.c.

    As a push button handling is quiet horrible without a timer de-bounce delay but does the job for testing purpose only.

    s.

    simo zzAuthor
    Graduate II
    July 3, 2025

    Hi,

    I have tried to disable Data cache from Appli's main.c

     /* Enable I-Cache---------------------------------------------------------*/
     SCB_EnableICache();
     /* EnableDisable D-Cache---------------------------------------------------------*/
     SCB_DisableDCache();

    But nothing changes. Calling SCB_DisableDCache() from Boot's main.c makes the FW to don't work at all.

    Also, setting 

    MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;

    in MPU_Config(), nothing changes.

    MOSI pin remains tied to 0...

    I am going to look DTCM shared configuration...

    s.

    Technical Moderator
    July 3, 2025

    @simo zz wrote:

    But nothing changes. Calling SCB_DisableDCache() from Boot's main.c makes the FW to don't work at all..


    You don't have to disable the cache as it is disabled after reset. disabling the cache without enabling it previously may introduce issues in your application. and that's what you are facing.

    If you need to disable the cache from the beginning either to:  

    - To not enable the cache at all

    - Use MPU to set the memory region you want to be not cacheable

    simo zzAuthor
    Graduate II
    July 3, 2025

    @mƎALLEm OK thanks.

    However, explicitely disabling the DCache using SCB_DisableDCache() or without calling SCB_EnableDCache() does not solve the issue.

    Super User
    July 3, 2025

    Can you post code that has data cache disabled, uses the SPI, and exhibits the behavior you describe in the OP?

    simo zzAuthor
    Graduate II
    July 3, 2025

    Here it is attached.

    Basically, 

    1. SCB_EnableDCache() is executed in Boot/Src/main.c otherwise the FW does not run at all. Despite all test I have to debug where the FW stalls in this case.. This is a situation on trial and error, which I hate the most. 
    2. SCB_EnableDCache() is not executed in Appli/Src/main.c. Executing SCB_DisableDCache() instead does not change the behavior.
    3. In MPU_Config() from Boot/Src/main.c, I set MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE for MPU_InitStruct.BaseAddress = 0x70000000 (running Appli from external QSPI - this is a NUCLEO-H7S3L8 board.

    I understand that cache should not be used at all, right?

    .