Skip to main content
Explorer
February 12, 2022
Question

Possible HAL spi bug?, also question on fast spi dma transfer initiation.

  • February 12, 2022
  • 6 replies
  • 1505 views

In :

/stm32h745nucleoTest_CM7/Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_dma.c

we find:

 if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */

 {

  /* Clear all interrupt flags at correct offset within the register */

  regs_dma->IFCR = 0x3FUL << (hdma->StreamIndex & 0x1FU);

surely 0x3FUL will over write the bottom bit of the next channel entry?

My next question:

I use:

HAL_SPI_Transmit_DMA(&hspi1, (uint8_t*)StartAddress, n);

to write a burst of 24 bit spi words.

However the HAL code is exhaustive and quite slow.

What do I need to do to quickly trigger another burst using the same spi and dma channels, but with a different source memory pointer, what is the minimum amount of register writes that are needed?. The following code is missing something vital, but I cant figure it out:

SPI2->CR1 &= ~1;

SPI2->CFG1 &= ~1<<15;//txdmaen

DMA1_Stream4->CR &= ~1;

DMA1_Stream4->CR |= 1<<5;

DMA1_Stream4->NDTR = n;

DMA1_Stream4->M0AR = StartAddress;

DMA1->HIFCR = 0x1f;

DMA1_Stream4->CR |= 1<<4;

DMA1_Stream4->CR |=1;

  SPI2->CR2 |= n;

SPI2->CFG1 |= 1<<15;//txdmaen

SPI2->CFG2 |= 1<22;// master mode bit set

SPI2->CR1 |= 1 ;

SPI2->CR1 |= 1<<9;

    This topic has been closed for replies.

    6 replies

    Super User
    February 13, 2022

    > In :/stm32h745nucleoTest_CM7/Drivers/STM32H7xx_HAL_Driver/stm32h7xx_hal_dma.c

    In the latest source - in following two lines:

    https://github.com/STMicroelectronics/stm32h7xx_hal_driver/blob/2bfa1cae79926af47ff79a48757d29a38c9c8978/Src/stm32h7xx_hal_dma.c#L851

    https://github.com/STMicroelectronics/stm32h7xx_hal_driver/blob/2bfa1cae79926af47ff79a48757d29a38c9c8978/Src/stm32h7xx_hal_dma.c#L1788

    > surely 0x3FUL will over write the bottom bit of the next channel entry?

    No it won't.. Each channel entry in DMA_LIFCR, DMA_HIFCR takes 6 bits (including one unused) so 3F is ok.

    --pa

    Visitor II
    February 13, 2022

    Could it be the sequence in wrong order?

    Ihawk.1Author
    Explorer
    February 13, 2022

    Hi Pavel, thanks, OK the bit fields are 6 wide, I hadnt noticed.

    .(customer)

    Yes, it could be that the register sequence is in the wrong order, or the wrong register values, or missing register values, or a combination or permutation of these. I have yet to find a working formula. I thought I had reproduced the sequence that occurs in the HAL calls, but I have spent hours on this and cant find the missing magic.

    Super User
    February 14, 2022

    Read out and check/post content of SPI, DMAMUX, DMA registers at the perceived point of failure.

    > DMA1_Stream4->CR &= ~1;

    A delay may be needed after disabling the stream, until it accepts further write into its registers. You are supposed to wait until hardware clears the same enable bit (this is not a memory-like register, read returns state of a different register than write writes into).

    JW

    Ihawk.1Author
    Explorer
    February 14, 2022

    Thanks JW, that might explain the apparent flakey operation of this code, I wonder if I would get enough delay by just reordering it to put a gap between the stream disable and the subsequent writes to DMA registers, a poling loop here would be ugly.

    SPI1->CFG1 &= ~1<<15;// SPI_CFG1_TXDMAEN

    SPI1->CR1 &= ~(1<<9);//c start

    DMA1_Stream3->CR &= ~1;//disable dma stream

      DMA1_Stream3->M0AR = StartAddress;

      DMA1_Stream3->PAR =  (uint32_t)&SPI1->TXDR;//0x40013020;

      DMA1_Stream3->NDTR = n;

      SPI1->CR2 = n ;// no words

    SPI1->CFG1 |= 23 | 1<<15 ;//txdmaen & no of bits in spi word

    SPI1->CR1 |= 1;

    DMA1_Stream3->CR |= 1<<4 | 1<<3 | 1;//enable dma stream//enable transfer complete interrupt and enable dma stream

    SPI1->CR1 |= 1<<9;//c start

    Super User
    February 14, 2022

    I believe that M0AR/PAR/NDTR are all write-protected until CR1.EN = 0. The RM says so.

    JW