cancel
Showing results for 
Search instead for 
Did you mean: 

Arbitrary waveform by timer using DMA

RAltm
Senior

Hello,

I want to generate an arbitrary waveform by a timer using DMA. The waveform is using different pulse widths and also varying periods in multiples of 25µs.

By reading AN4776 and HAL documentation I figured out it should be possible with HAL_TIM_DMABurst_MultiWriteStart() function. Unfortunately I don't get an output signal except after reset where a short pulse can be seen. I assume this pulse is due to port configuration during initialization. After that pulse, the signal stays high.

My setup (CubeMX):

  • Nucleo32-L432, core clock 80MHz
  • Used timer is Tim16
    • Prescaler is set to 399 => 80 MHz / 400 = 5µs resolution
    • ARR and CCR preload enabled
    • ARR and CCR set to 0 (initialized in source code)
    • DMA enabled
      • normal mode
      • memory to peripheral
      • Word / Word
      • increment address on memory
      • interrupt enabled

For a first run I want to use fixed pulse widths and varying periods, so all my code does is the following:

/* USER CODE BEGIN 2 */
htim16.Instance->ARR = 39;	//40 * 5µs = 200µs period
htim16.Instance->CCR1 = 4;	//5 * 5µs = 25µs pulse
HAL_TIM_DMABurst_MultiWriteStart(&htim16, TIM_DMABASE_ARR, TIM_DMA_UPDATE, (uint32_t *) Buffer, TIM_DMABURSTLENGTH_1TRANSFER, sizeof(Buffer) / sizeof(Buffer[0]));
HAL_TIM_PWM_Start(&htim16, TIM_CHANNEL_1);
/* USER CODE END 2 */

As far as I understood I need to initiate the first pulse by calling HAL_TIM_PWM_Start() and HAL_TIM_DMABurst_MultiWriteStart() setup the DMA to handle the subsequent transfers. 

When running that code, I get a single pulse of ~3.4µs at a period of 5.8µs, after that the output stays high. Since this is my first encounter with DMA I'm a bit lost. I don't get what I'm missing because other forum entries use basically the same approach as far as I can see.

Regards

3 REPLIES 3
waclawek.jan
Super User

> ARR and CCR set to 0 (initialized in source code)

ARR = 0 means, that the timer is stopped. As you also set ARR preload, and there is no Update event which would transfer the new ARR to the "active" register and start the timer, so it remains stopped.

JW

Hello JW,

I tried both deactivating preload and using non-zero values for ARR/CCR directly in CubeMX. No change in behaviour. Any other ideas what might be the issue?

Regards

RAltm
Senior

Update: seems that the silicon has a bug :( I used the Nucleo board reset button to restart and got the described behaviour. When doing a power reset it seems to (almost) work as expected.
I checked the errata sheet, but I couldn't find anything regarding the reset input only working partially...

Regards