2021-06-22 05:26 AM
It finally happened, i need two pins without pwm functionality to output pwm signals (minimum 1kHz)
Im using an STM32f072R8Tx clocked with HSI48Mhz, my TIM1 is available.
My idea is:
TIM1 channels 1 and 2 set up as PWM NO OUTPUT with interruption enabled, discriminate the source of the interruption (channel).
Toggle the corresponding GPIOs inside the IRQ function.
Is there another magical way that doesnt interrupt my programm every milisecond?
Solved! Go to Solution.
2021-07-06 02:23 AM
@Community member thanks for your help.
It works now, i had some issues with choosing the incorrect timer/trigger and i didnt know this very important function
__HAL_TIM_ENABLE_DMA(&htim6, TIM_DMA_UPDATE);//https://metebalci.com/blog/stm32h7-gpio-toggling/
tim6 update trigering dma does the job for me.
/* USER CODE BEGIN PV */
uint32_t data[2]={GPIO_PIN_6,GPIO_PIN_6<<16};
/* USER CODE END PV */
....
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start(&htim6);
HAL_DMA_Start(&hdma_tim6_up, (uint32_t)&(data[0]), (uint32_t)&(GPIOC->BSRR), sizeof(data)/sizeof(data[0]));
__HAL_TIM_ENABLE_DMA(&htim6, TIM_DMA_UPDATE);
/* USER CODE END 2 */
https://www.hackster.io/javier-munoz-saez/all-pins-as-pwm-at-the-same-time-baremetal-stm32-1df86f
2021-06-22 08:17 AM
Use a TIM-driven DMA from memory to GPIO.
JW
2021-06-22 08:19 AM
@Community member but wouldnt DMA (mem-peripheral) override the entire GPIO bank? not just the ones i need.
2021-06-22 08:21 AM
Use GPIO_BSRR.
JW
2021-06-22 08:40 AM
@Community member okay i will look into that.
So i need to set DMA (mem -mem) to set the register GPIOA->BSRR= whateveriwant;
2021-06-22 08:51 AM
Yes.
whateveriwant should have bits set in lower 16 bits wherever you want to set a pin high, and bits set in higher 16 bits to set a pin low.
Experiment in the debugger by manually writing into GPIO_BSRR to get a grip on this. Start with one pin.
Then set up a simple array of two words in memory, with the whateveriwant values to set and clear the pin, and in a timer-driven DMA transfer cyclically from that array to given GPIO_BSRR. Start simply, with DMA driven from timer's Update (i.e. TIMx_SR.UDE=1); this will yield a toggling pin, i.e. 50% PWM.
Now how do you proceed from that depends on what exactly do you want to achieve. One simple method might be to expand the array in memory e.g. to 100 words (and setting DMA's NDTR to 100), strategically placing the whateveriwants so that the pin is set to any time pieces out of 100 as you want.
JW
2021-06-23 03:44 AM
So im setting up a
uint32_t softpwm_values[100];
And i would like to use a (mem to mem) DMA channel in a circular mode with each transaction being triggered by a timer (timer freq= pwmfreq*100).
memory source is &softpwm_values (index increment) ,
memory dest is GPIOC->BSRR register
The problems i have now is:
I found this interesting discussion, they point to the AN4666 app note
2021-06-23 04:42 AM
> And i would like to use a (mem to mem)
No. The "direction" is quite misleading, it implies different variants of DMA behaviour of which "direction" is just one portion. M2M ignores the triggers. You want M2P.
I don't know how to click this in CubeMX. DMA is quite simple to set up normally by writing into DMA registers.
JW
2021-07-06 12:38 AM
@Community member
My best unssuccesfull attempt so far:
No dma is triggered, but tim_up interruptions are hapening
uint32_t data[100];
HAL_DMA_Start(&hdma_tim1_up, data, &(GPIOC->BSRR), sizeof(data));
Ill do some more clicks in cubeMX to see if i get somewhere
Interesting links:
some guy doing this with an stm32f205 and arduino
this other guy deeper lower level explanation <--- thisone was the winner for me
2021-07-06 02:23 AM
@Community member thanks for your help.
It works now, i had some issues with choosing the incorrect timer/trigger and i didnt know this very important function
__HAL_TIM_ENABLE_DMA(&htim6, TIM_DMA_UPDATE);//https://metebalci.com/blog/stm32h7-gpio-toggling/
tim6 update trigering dma does the job for me.
/* USER CODE BEGIN PV */
uint32_t data[2]={GPIO_PIN_6,GPIO_PIN_6<<16};
/* USER CODE END PV */
....
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start(&htim6);
HAL_DMA_Start(&hdma_tim6_up, (uint32_t)&(data[0]), (uint32_t)&(GPIOC->BSRR), sizeof(data)/sizeof(data[0]));
__HAL_TIM_ENABLE_DMA(&htim6, TIM_DMA_UPDATE);
/* USER CODE END 2 */
https://www.hackster.io/javier-munoz-saez/all-pins-as-pwm-at-the-same-time-baremetal-stm32-1df86f