PWM channel output pin not working

Post here first, or if you can't find a relevant section!
julian_lpp
Posts: 25
Joined: Tue Dec 24, 2024 4:32 pm

Re: PWM channel output pin not working

Post 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 :D
ag123
Posts: 1898
Joined: Thu Dec 19, 2019 5:30 am
Answers: 30

Re: PWM channel output pin not working

Post 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

Code: Select all

pinMode(pin_T3_CH_3_PWM, OUTPUT);
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 :D
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?
Last edited by ag123 on Fri Jan 10, 2025 5:46 am, edited 2 times in total.
julian_lpp
Posts: 25
Joined: Tue Dec 24, 2024 4:32 pm

Re: PWM channel output pin not working

Post 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
ag123
Posts: 1898
Joined: Thu Dec 19, 2019 5:30 am
Answers: 30

Re: PWM channel output pin not working

Post 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
fpiSTM
Posts: 1944
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 108
Location: Le Mans
Contact:

Re: PWM channel output pin not working

Post 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
Screenshot from 2025-01-10 09-47-23.png (69.51 KiB) Viewed 727 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.
GonzoG
Posts: 491
Joined: Wed Jan 15, 2020 11:30 am
Answers: 36
Location: Prudnik, Poland

Re: PWM channel output pin not working

Post 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
julian_lpp
Posts: 25
Joined: Tue Dec 24, 2024 4:32 pm

Re: PWM channel output pin not working

Post 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 :D

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
Post Reply

Return to “General discussion”