Page 2 of 2
Re: PWM channel output pin not working
Posted: Fri Jan 10, 2025 4:57 am
by julian_lpp
ag123 wrote: Fri Jan 10, 2025 4:33 am
it would take reviewing the codes to figure out what is done, but that among the things that needs to be done at the register level are:
- to configure Timer (3) (e.g. output compare) and the output registers so that the timer output goes to the pin (seting the timer registers)
- to configure the GPIO pin so that it select AFIO instead of gpio (setting the gpio registers)
this 2 steps would make the Timer PWM outputs appear at the pin.
Cant find the sources of hardware timer lib (to watch SetMode code implementation) ... are they already in form of sources in the arduino installation or are compiled when the stm core is installed?
Off-topic:
for LCD I'd guess mainly SPI is used. So that is mainly for the backlight?
Excuse me cant guess if it was a question for me, i'm not a native speaker, not even with gpt was able to figure out this phrase

Re: PWM channel output pin not working
Posted: Fri Jan 10, 2025 5:13 am
by ag123
julian_lpp wrote: Fri Jan 10, 2025 4:57 am
ag123 wrote: Fri Jan 10, 2025 4:33 am
it would take reviewing the codes to figure out what is done, but that among the things that needs to be done at the register level are:
- to configure Timer (3) (e.g. output compare) and the output registers so that the timer output goes to the pin (seting the timer registers)
- to configure the GPIO pin so that it select AFIO instead of gpio (setting the gpio registers)
this 2 steps would make the Timer PWM outputs appear at the pin.
Cant find the sources of hardware timer lib (to watch SetMode code implementation) ... are they already in form of sources in the arduino installation or are compiled when the stm core is installed?
The 'core' is generally installed in
https://support.arduino.cc/hc/en-us/art ... r-computer
Windows: C:\Users\{username}\AppData\Local\Arduino15
macOS: /Users/{username}/Library/Arduino15
Linux: /home/{username}/.arduino15
and further in the 'hardware' folder.
In Github it is here
https://github.com/stm32duino/Arduino_C ... eTimer.cpp
One of your code is:
Code: Select all
T3_channel_3 = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(pin_T3_CH_3_PWM), PinMap_PWM));
gTimer3PWM->setMode(T3_channel_3, TIMER_OUTPUT_COMPARE_PWM1, pin_T3_CH_3_PWM);
for pinmap_function(), the declaration is here
https://github.com/stm32duino/Arduino_C ... nmap.h#L60
the definition is here
https://github.com/stm32duino/Arduino_C ... map.c#L355
and HardwareTimer->SetMode is here
https://github.com/stm32duino/Arduino_C ... r.cpp#L635
but I think the statement that configures the gpio is this
pinMode is here
https://github.com/stm32duino/Arduino_C ... ital.c#L29
all of them quite complex codes
Off-topic:
for LCD I'd guess mainly SPI is used. So that is mainly for the backlight?
Excuse me cant guess if it was a question for me, i'm not a native speaker, not even with gpt was able to figure out this phrase
I see you are using an LCD library in your code, so I think you are using an LCD e.g. ST7735
Code: Select all
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
//#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SPI.h>
So I'd guess that PWM is for the backlight?
Re: PWM channel output pin not working
Posted: Fri Jan 10, 2025 5:39 am
by julian_lpp
So I'd guess that PWM is for the backlight?
awww no. I just mentioned above I was using a tft display for debuging (in this case to see the fequency that is being captured by the timer 1)
I was unable yet to use the serial port with the stlink programmer, in fact I cant even program the blue pill from the arduino ide, need to output the compiled binary and send it through stlink utility.... so I use the tft to debug already...
The original code is for an automotive gauge (tachometer and speedometer) the pwm just emulate the pulses that in the final version would come from the ignition coil and from the speed sensor. So given that I have the wiring done, and the project uses already the tft, and having no serial port functional, I use it for kinda debug
btw In a quick read at the hardwaretimer source code it seems to me that calling "HAL_TIM_PWM_ConfigChannel" does all the configuration needed to set up the alternate pin function...
regards
julian
Re: PWM channel output pin not working
Posted: Fri Jan 10, 2025 5:48 am
by ag123
I see, I'm guessed incorrectly
oh and I think the statement that configures the PWM output on the pin is
HardwareTimer::setMode
https://github.com/stm32duino/Arduino_C ... r.cpp#L635
pretty complex configuration in the core HardwareTimer, which apparently configures the pin as well
Re: PWM channel output pin not working
Posted: Fri Jan 10, 2025 8:49 am
by fpiSTM
There is no issue with PB0.
Code: Select all
/*
PWM full configuration
This example shows how to fully configure a PWM with HardwareTimer.
PWM is generated on `LED_BUILTIN` if available.
PWM is generated by hardware: no CPU load.
Nevertheless, in this example both interruption callback are used on Compare match (Falling edge of PWM1 mode) and update event (rising edge of PWM1 mode).
Those call back are used to toggle a second pin: `pin2`.
Once configured, there is only CPU load for callbacks executions.
*/
// 'pin' PWM will be managed automatically by hardware whereas 'pin2' PWM will be managed by software through interrupt callback
#define pin2 LED_BUILTIN // PC13 Blue Pill
#define pin PB0_ALT1
void Update_IT_callback(void)
{ // Update event correspond to Rising edge of PWM when configured in PWM1 mode
digitalWrite(pin2, LOW); // pin2 will be complementary to pin
}
void Compare_IT_callback(void)
{ // Compare match event correspond to falling edge of PWM when configured in PWM1 mode
digitalWrite(pin2, HIGH);
}
void setup()
{
// No need to configure pin, it will be done by HardwareTimer configuration
// pinMode(pin, OUTPUT);
// Need to configure pin2, as it is not managed by HardwareTimer
pinMode(pin2, OUTPUT);
// Automatically retrieve TIM instance and channel associated to pin
// This is used to be compatible with all STM32 series automatically.
TIM_TypeDef *Instance = (TIM_TypeDef *)pinmap_peripheral(digitalPinToPinName(pin), PinMap_PWM);
uint32_t channel = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(pin), PinMap_PWM));
// Instantiate HardwareTimer object. Thanks to 'new' instantiation, HardwareTimer is not destructed when setup function is finished.
HardwareTimer *MyTim = new HardwareTimer(Instance);
MyTim->setMode(channel, TIMER_OUTPUT_COMPARE_PWM1, pin);
// MyTim->setPrescaleFactor(8); // Due to setOverflow with MICROSEC_FORMAT, prescaler will be computed automatically based on timer input clock
MyTim->setOverflow(100000, MICROSEC_FORMAT); // 100000 microseconds = 100 milliseconds
MyTim->setCaptureCompare(channel, 50, PERCENT_COMPARE_FORMAT); // 50%
MyTim->attachInterrupt(Update_IT_callback);
MyTim->attachInterrupt(channel, Compare_IT_callback);
MyTim->resume();
}
void loop()
{
/* Nothing to do all is done by hardware. Even no interrupt required. */
}

- Screenshot from 2025-01-10 09-47-23.png (69.51 KiB) Viewed 733 times
So if this code doesn't work issue come from your BP. As you said your are not sure it is note a fake stm32.
Re: PWM channel output pin not working
Posted: Fri Jan 10, 2025 11:13 am
by GonzoG
julian_lpp wrote: Fri Jan 10, 2025 4:57 am
Cant find the sources of hardware timer lib (to watch SetMode code implementation) ... are they already in form of sources in the arduino installation or are compiled when the stm core is installed?
All stm32duinio code for timers is in HardwareTimer.h and HardwareTimer.cpp:
https://github.com/stm32duino/Arduino_C ... areTimer.h
https://github.com/stm32duino/Arduino_C ... eTimer.cpp
But stm32duino is using STM32 HAL libraries and you probably will have to look in MCU specific HAL source code files:
https://github.com/stm32duino/Arduino_C ... em/Drivers
Re: PWM channel output pin not working
Posted: Fri Jan 10, 2025 3:28 pm
by julian_lpp
fpiSTM wrote: Fri Jan 10, 2025 8:49 am
There is no issue with PB0.
Indeed I was doing something wrong and you were absolutely right, all the issue was related to pin definition:
Code: Select all
#define pin_T3_CH_3_PWM PB0_ALT1 ///not PB0 !!
another interesting thing when using hardwaretimer lib is to note that:
Code: Select all
T3_channel_3 = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(pin_T3_CH_3_PWM), PinMap_PWM));
gTimer3PWM->setMode(T3_channel_3, TIMER_OUTPUT_COMPARE_PWM1, pin_T3_CH_3_PWM);
...STM_PIN_CHANNEL already "configures" the channel/pin. It is not enogh knowing which channel one wants to use. I could be sure "hey I know Im gonna use the channel 3!"
Code: Select all
gTimer3PWM->setMode(3, TIMER_OUTPUT_COMPARE_PWM1, pin_T3_CH_3_PWM);
well.... it doesnt work though
STM_PIN_CHANNEL is already STM_PIN_CONFIGURE_AND_RETRIEVE_CHANNEL_NUM
edit:
This way works as I thought
Code: Select all
T3_channel_3 = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(pin_T3_CH_3_PWM), PinMap_PWM));
gTimer3PWM->setMode(3, TIMER_OUTPUT_COMPARE_PWM1, pin_T3_CH_3_PWM);
regards
julian