cancel
Showing results for 
Search instead for 
Did you mean: 

PWM, DMA, how to change the waveform.

Alejandro Bizzotto
Associate III
Posted on January 03, 2018 at 11:20

The original post was too long to process during our migration. Please click on the attachment to read the original post.
1 ACCEPTED SOLUTION

Accepted Solutions
Posted on January 03, 2018 at 23:14

The HAL_TIM_PWM_Stop_DMA() it's not a Cube thing, but a HAL thing,

Cube is the library, containing both HAL and LL. The code generator is called (confusingly) CubeMX. But that's just terminology which does not really matter.

As I've said and you've confirmed, the function in question disables the

DMA triggering

in timer (by clearing the respective bit in TIMx_DIER) but does not disable the

DMA channel

(by clearing DMA_SxCR.EN). Only after DMA channel is disabled, the memory address register can be written - see DMA stream x memory 0 address register (DMA_SxM0AR) subchapter of DMA chapter in RM.

I don't know about the double buffer you say, where I can read more?

Reference manual for your SMT32, DMA chapter, Double buffer mode subchapter.

JW

View solution in original post

13 REPLIES 13
Posted on January 03, 2018 at 14:04

I want to change the array who sources the DMA, and I can't,

I don't Cube but having a cursory look at HAL_TIM_PWM_Stop_DMA() it appears that it does not stop DMA itself, only disables the trigger in timer.

If you want to change the memory pointer in DMA you can do that only if you disable the given DMA channel (or in double-buffer mode you can change the 'other' address, but that's not what you want). I don't know how to do it in Cube - this is exactly the reason why I don't use it.

JW

Andrew Neil
Evangelist
Posted on January 03, 2018 at 14:16

[code]  <--- FIXME: how I make this forum show the next paragraph like code???

 

But see also: 

 
Posted on January 03, 2018 at 19:52

hmmm, there is a '<>' and when I hover it, it displays the hint 'code' but it shows the code of the message, instead of giving me a space where I can put my code and make it look like a code

or there is another icon I don't see?

Posted on January 03, 2018 at 20:33

Yes - the '<>'  does seem entirely pointless!

Did you follow the route described in the linked thread:

 

But note the warning that it will get your post stuck in moderation!

 
Posted on January 03, 2018 at 22:50

 ,

 ,

The HAL_TIM_PWM_Stop_DMA() it's not a Cube thing, but a HAL thing, when I generate the code with Cube it not even put the function HAL_TIM_PWM_Start_DMA().

I didn't look it before, but now I can disagree with you. I was debugging the process step by step and when we reach the function HAL_TIM_PWM_Stop_DMA(), we are going here:

HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel)

 ,

{

 ,

 , /* Check the parameters */

 ,

 , assert_param(IS_TIM_CCXN_INSTANCE(htim->,Instance, Channel)),

 ,

 ,

 ,

 , switch (Channel)

 ,

 , {

 ,

 , , , case TIM_CHANNEL_1:

 ,

 , , , { , , , , ,  ,

 ,

 , , , , , /* Disable the TIM Output Compare DMA request */

 ,

 , , , , , __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1),

 ,

 , , , }

 ,

 , , , break,

 ,

 , ,  ,

 ,

 , , , case TIM_CHANNEL_2:

 ,

 , , , {

 ,

 , , , , , /* Disable the TIM Output Compare DMA request */

 ,

 , , , , , __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2),

 ,

 , , , }

 ,

 , , , break,

 ,

 , ,  ,

 ,

 , , , case TIM_CHANNEL_3:

 ,

 , , , {

 ,

 , , , , , /* Disable the TIM Output Compare DMA request */

 ,

 , , , , , __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3),

 ,

 , , , }

 ,

 , , , break,

 ,

 , ,  ,

 ,

 , , , case TIM_CHANNEL_4:

 ,

 , , , {

 ,

 , , , , , /* Disable the TIM Output Compare interrupt */

 ,

 , , , , , __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC4),

 ,

 , , , }

 ,

 , , , break,

 ,

 , ,  ,

 ,

 , , , default:

 ,

 , , , break,

 ,

 , }

 ,

 ,

 ,

 , /* Disable the Capture compare channel N */

 ,

 , TIM_CCxNChannelCmd(htim->,Instance, Channel, TIM_CCxN_DISABLE),

 ,

 ,

 ,

 , /* Disable the Main Output */

 ,

 , __HAL_TIM_MOE_DISABLE(htim),

 ,

 ,

 ,

 , /* Disable the Peripheral */

 ,

 , __HAL_TIM_DISABLE(htim),

 ,

 ,

 ,

 , /* Change the htim state */

 ,

 , htim->,State = HAL_TIM_STATE_READY,

 ,

 ,

 ,

 , /* Return function status */

 ,

 , return HAL_OK,

 ,

}

Then when I reach the bold function the DMA stops flushing numbers into CC1 (the pwm remains where it is), and when the function  , TIM_CCxNChannelCmd(htim->,Instance, Channel, TIM_CCxN_DISABLE), is processed then the pwm goes down.

Which is not clear yet is how much of 'disabled' is the DMA after __HAL_TIM_DISABLE_DMA, the definition of this is:

♯ define __HAL_TIM_DISABLE_DMA(__HANDLE__, __DMA__) , , , , , , , ((__HANDLE__)->,Instance->,DIER &,= ~(__DMA__))

from the file stm32f4xx_hal_tim.h

what else is needed to unlink the DMA from the current array? I tried with multidimensional array too, with the same result.

also, I don't know about the double buffer you say, where I can read more? I'm looking for a way to generate the array on the fly (because I will need many, and the memory will be not enough), and then change the array for the next step of the waveform. Thanks for your time!

Posted on January 03, 2018 at 22:51

I see now, Syntax Highlighter was not my first option to look at

Posted on January 03, 2018 at 23:14

The HAL_TIM_PWM_Stop_DMA() it's not a Cube thing, but a HAL thing,

Cube is the library, containing both HAL and LL. The code generator is called (confusingly) CubeMX. But that's just terminology which does not really matter.

As I've said and you've confirmed, the function in question disables the

DMA triggering

in timer (by clearing the respective bit in TIMx_DIER) but does not disable the

DMA channel

(by clearing DMA_SxCR.EN). Only after DMA channel is disabled, the memory address register can be written - see DMA stream x memory 0 address register (DMA_SxM0AR) subchapter of DMA chapter in RM.

I don't know about the double buffer you say, where I can read more?

Reference manual for your SMT32, DMA chapter, Double buffer mode subchapter.

JW

Posted on January 04, 2018 at 00:11

Fantastic!

changing the loop to this it works:

while (1)

  {

      HAL_Delay(500);

      if (act_seg == 0) {

          act_seg = 1;

          HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, act_seg);

          HAL_TIM_PWM_Stop_DMA (&htim3, TIM_CHANNEL_1);

          hdma_tim3_ch1_trig.Instance->M0AR = 0;

            HAL_TIM_PWM_Start_DMA(&htim3, TIM_CHANNEL_1, (uint32_t *) seg0, 8192);

      }

      else {

          act_seg = 0;

          HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, act_seg);

          HAL_TIM_PWM_Stop_DMA (&htim3, TIM_CHANNEL_1);

          hdma_tim3_ch1_trig.Instance->M0AR = 0;

            HAL_TIM_PWM_Start_DMA(&htim3, TIM_CHANNEL_1, (uint32_t *) seg1, 8192);

      }

0690X00000609KnQAI.png

Now I need to see the double buffer thing, seems interesting too. Thanks again!

Posted on January 04, 2018 at 02:39

Yes - not really  a very intuitive name, is it?

>:(