arduino / ArduinoCore-mbed

347 stars 202 forks source link

mbed::PwmOut 2.2.0 -> 2.3.1 with Portenta H7 #293

Open MarcoRBosco opened 3 years ago

MarcoRBosco commented 3 years ago

### Problem with mbed::PwmOut with Portenta H7

IDE: Arduino IDE 1.8.15

Board: Portenta H7 and Portenta Breakout board

mbed::PwmOut was working perfectly in ArduinoCore-mbed 2.2.0 but since update 2.3.1 it is not possible to make two PWM channels work simultaneously. Not yet tested with more channels.

Test sketch:

#include "mbed.h"

using namespace mbed;

PwmOut pwm_a(PA_8);
PwmOut pwm_b(PC_6);

void setup() {

  pwm_a.period_us(5000);
  pwm_a.pulsewidth_us(50);

  pwm_b.period_us(5000);
  pwm_b.pulsewidth_us(50);

}

void loop() {

}

Output results with version 2.2.0 in pins PWM0 (yellow) and PWM1 (blue):

NewFile1

NewFile2

Output results with version 2.3.1 in pins PWM0 (yellow) and PWM1 (blue):

NewFile3

As we can see PWM0 channel is not generating the setted pulse.

Please let me know if you need more information or help.

facchinm commented 3 years ago

Hi @MarcoRBosco, thanks for reporting this. The issue is due to https://github.com/arduino/ArduinoCore-mbed/blob/master/patches/0092-Portenta-PWM-force-PA8-to-use-HRTIM.patch ; a little bit of explanation can help maybe :slightly_smiling_face: Basically, some of the pins marked as PWM were not working since they are not connected to any TIM channel but only to HRTIM (which had no mbed wrapper). We ported it to the mbed PwmOut infrastructure but there are some "hard" limitations that must be taken into account:

Now, your sketch should just work, so I'm investigating and I'll report back as soon as I have an answer

facchinm commented 3 years ago

I have to amend my comment, in fact the frequency you are requesting is 200Hz, so the HRTIM can't reach it. @sebromero is anything we can document / change?

MarcoRBosco commented 3 years ago

@facchinm thank you for your fast reply.

I think it would be great if documentation can be improved at least indicate which timer is attached to each PWM channel.

We are currently working on a project (PCB already build) were we do not use PK1, but we are using PA8 with frequencies up to 200 Hz, so we need PA8 connected to a TIM.

I'm still not familiarized with mbed os. It is possible to create a PeripheralPins.c specific to the project that overlays the default one for Portenta H7 inside arduino project?

facchinm commented 3 years ago

If you have a linux installation, rebuilding the mbed library is very easy.

mkdir portenta_pa8_tim && cd portenta_pa8_tim
git clone https://github.com/ARMmbed/mbed-os -depth 1 -b mbed-os-6.12.0
git clone https://github.com/arduino/ArduinoCore-mbed --depth 1
cd ArduinoCore-mbed
rm patches/0092-Portenta-PWM-force-PA8-to-use-HRTIM.patch
./mbed-os-to-arduino -r $PWD/../mbed-os -a PORTENTA_H7_M7:PORTENTA_H7_M7

You can then replace the original libmbed.a with the one generated inside variants/PORTENTA_H7_M7/libs

khoih-prog commented 3 years ago

Hi @MarcoRBosco

If you only need low frequency PWM, would you like to try Portenta_H7_Slow_PWM Library to see if it's working for your use-case.

jonwhick commented 2 years ago

This has been really frustrating to deal with. I had no idea the timers were so... un managed in the H7.

I need to implement some rather basic interrupt compatible state machines with PWM outputs, as my basis for a project. But I'm working through these PWM libraries lost because I have no idea what pins on the breakout even map to!

pennam commented 2 years ago

Hi @jonwhick for the pin mapping you can check this table https://github.com/arduino-libraries/Arduino_PortentaBreakout#peripherals-table