cancel
Showing results for 
Search instead for 
Did you mean: 

DMA only working once

BRapo.1
Associate

Good day,

I'm trying to control this RGB leds N-PI55TAT
Datasheet 

I'm using an STM32H753VIT6


To do that I have to create a fairly fast burst of data with pulses of 0.6, 0.3  and 0.9 us.

To achieve this I set timer 7 to have an update even every 100nS then I set DMA2 stream 0 in memory to peripheral configuration.
The idea is to create a buffer, with the signal timing, and then set the DMA2 to transfer that buffer to the BSRR register of the port I have connected to the leds.

And it works, It generates the pulses every 100nS and then writting to the buffer where the sets and resets are I got my signal with pretty ok timing.

 

The problem is that it only works once.
Since I won't be updating the leds often, I don't want to create a circular buffer and load the DMA all the time. That's why I wanted to do a normal buffer, execute it once and execute it again when I need to change the colors.

 

BRapo1_0-1701943154582.png

BRapo1_1-1701943289052.png

 

While loop:

 

 

  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

	  iled_rst(); //Just a 200us low to reset the led
	  HAL_DMA_Start(&hdma_tim7_up, (uint32_t)bf, (uint32_t)&(GPIOE->BSRR), 289); //transfer buffer to BSRR
	  TIM7->DIER |= (1<<8); //I don't know what this is, but I read it's necesary
	  HAL_Delay(10); //10 ms is more than enough for the DMA to finish, the whole transfer takes about 20us
  }

 

 

Buffer:

 

 

  uint32_t bf[289] = {0};

//the buffer is then loaded with the corresponding data to time the signal

 

 

Init:

 

 

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_SPI1_Init();
  MX_USART3_UART_Init();
  MX_USART2_UART_Init();
  MX_I2C3_Init();
  MX_USART1_UART_Init();
  MX_TIM7_Init();
  MX_TIM6_Init();
  /* USER CODE BEGIN 2 */
  HAL_TIM_Base_Start(&htim6);


  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  HAL_TIM_Base_Start(&htim7);

 

 

 

If I put an interrupt before the while loop and set the logic analyzer to trigger, I get the signal sent once, perfectly done. But if I set the analyzer to trigger again the DMA just won't send the data anymore.

I tried clearing the interrupt flags of the DMA:

 

 

DMA2->HIFCR = 0x0FFFFFFF;
DMA2->LIFCR = 0x0FFFFFFF;

 

 

 

I read the status of DMA2 after the 10ms time

 

 

HAL_DMA_GetState(&hdma_tim7_up);

 

 

 

And its 2 HAL_DMA_STATE_BUSY = 0x02U, /*!< DMA process is ongoing */

I tried aborting after the 10ms

 

 

HAL_DMA_Abort(&hdma_tim7_up);

 

 

 

With no success.


Can you please explain to me why the DMA only transmits once?

Thank you very much

2 REPLIES 2
Pierre_Paris
ST Employee

Hello @BRapo.1,

Here some support :

  • Why are you transferring an array of size 289 into a single register of 32 bits ? Have you enabled the source increment ? "If the increment mode is enabled, the address of the next transfer is the address of the
    previous one incremented by 1 (for bytes), 2 (for half-words) or 4 (for words) depending on
    the data width programmed in the PSIZE or MSIZE bits in the DMA_SxCR register." (extract of chapter 15 of RM0433, I advise you to read more by clicking here).
  • Also, how are you filling bf ?
  • Can you please share your DMA handler?
  • Once the timer has been enabled, any time the counter is cleared, either due to a reset event or due to a counter roll-over, the repetition counter is decreased. When it reaches zero, a REP interrupt or a DMA request is issued if enabled (REPIE and REPDE bits in the HRTIM_DIER register). -> Your line 9 of while loop enable CPT2IE (Capture Interrupt Enable). Are you enabling REPIE (Bit 4) and REPDE (Bit 20) ?
  • I tried clearing the interrupt flags of the DMA: -> Which flags are enabled ? 

Best Regards,

Pierre

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

And why don't you simply use UART or SPI for that task?

See these topics for ideas:

https://community.st.com/t5/stm32-mcus-products/ws2812-library-does-not-work-on-stm32f40/m-p/603335#M226229

https://community.st.com/t5/stm32-mcus-products/stm32103-bluepill-bare-metal-ws2812b-neopixel-driver-no/td-p/144715/page/2

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice