RAK3172 PWM tone function is working only with build-in LEDs


For my pet project I need enable PWM with 1.5MHz and read result with analogRead(pin_number);
The problem is: PWM is working only with build-in LED (Green and Blue on evaluation board).
Basically now, I am trying replicate following small project for ESP32 ESP32 PWM with Arduino IDE (Analog Output) | Random Nerd Tutorials with no luck so far.

Any ideas why tone function is working only for internal LEDs and how to fix it? Thanks!

uint8_t ledPin = PA1;	// BLUE LED - working
//uint8_t ledPin = PA0;	// GREEN LED - working
//uint8_t ledPin = PA8;	//IO2 - not working
//uint8_t ledPin = PB5;	//IO1 - not working

int freq = 5000;

void setup()
  pinMode(ledPin, OUTPUT);  
  tone(ledPin, freq);

void loop()
  for(int dutyCycle = 0; dutyCycle <= 255; dutyCycle++){   
    // changing the LED brightness with PWM
   	analogWrite(ledPin, dutyCycle);

  // decrease the LED brightness
  for(int dutyCycle = 255; dutyCycle >= 0; dutyCycle--){
    // changing the LED brightness with PWM
   	analogWrite(ledPin, dutyCycle);

Well, it looks like build-in Timers are attached to specific pins and cannot be re-configured like in ESP32.
I didn’t find source code original firmware, but at least 2 pins (PA1 and PA0) able to generate PWM up to 186kHz which pretty low frequency :sob:

Welcome to RAK forum @Diaver ,

1.5Mhz is fast. Are you doing some kind of controller - power, motor, etc.?

You might need to use MCUs optimized for this. Maybe some parts from Microchip, TI, Freescale(NXP), etc.

Thank you for reply @carlrowan !
1.5Mhz it is not really any special. As far as I know, any STM32 chip able to provide that PWM signal and even more. Basically you just need in STM32Cube select the right options for a timer like Prescale and Period and that is it.

In your wrapper for Arduino it is possible to, but not from API. Insead you can update one C file which is going together with Arduino package:

And use tone function with some specific pin like PA1 or PA0.
That is it!

Your insight is helpful to the community @Diaver . Thanks for sharing!

I was wrong with regards to saying that 1.5Mhz is fast. It is relative to what type of application. STM32 chip can “of course” produce such frequency. However when it comes to PWM, it is a compromise on resolution. If the resolution you got on the frequency you generated is a fit on the application, the module then is a good fit :+1:

Unfortunately, changing this at exposed RUI3 API might not be possible since it will add more to the size of already big RUI3. However, if you think there is an optimized setting for the timer used in PWM generation, I will gladly share it to our development team.

To keep RUI API small, I just would probably update function “tone” and put as input argument parameter “Period/Resolution” and keep “Prescaler” as 1 or 0 hardcoded. It will help users receive whatever frequency they need with desired resolution.
Also, I would update documentation to describe what pins can be used to produce PWM signal -I tried PA1 and PA0 and they are working as expected.