Skip to content
This repository has been archived by the owner on Sep 6, 2023. It is now read-only.

Add ESP32 PWM support, mirroring the API of the ESP8266. #79

Closed
wants to merge 1 commit into from
Closed

Conversation

vandys
Copy link

@vandys vandys commented May 7, 2017

Hi, first time contribution to micropython, so just let me know if anything should be changed
and bounce this request. Thanks!

@nickzoic
Copy link
Collaborator

nickzoic commented May 7, 2017 via email

@dpgeorge
Copy link
Member

dpgeorge commented May 9, 2017

@vandys thanks! For licensing/copyright purposes, can you please outline which parts of the code you wrote, which parts are copied (and from where), what information you used to work out the ESP32 API and what other code you looked at during the writing. For such a large piece of new code we need to be sure it can retain the MIT license.

Just a note on code style: maximum line length in this project is roughly 90-100 characters, so no need to break lines under that.

@vandys
Copy link
Author

vandys commented May 9, 2017

I started by copying the esp8266 machine_pwm.c. I used information from the ESP32 Technical Reference Manual, the esp-idf documentation, and the SDK's sample ledc example code (but I did not copy that code, just studied it to understand the SDK's API for PWM). So aside from the code copied from the esp8266 PWM support, everything else you see there is just new code I wrote.

I wasn't an employee of anybody when I wrote it, and I wrote it with the understanding and intention that it's simply a derivative work of the existing micropython code. I freely and willingly contribute it to the project and intend that it not change the legal status of the micropython code base in any way, even if it is included in that base in whole or part.

@mattytrentini mattytrentini mentioned this pull request May 10, 2017
@laurivosandi
Copy link

laurivosandi commented May 12, 2017

Hi, I tried to enable PWM for pin 13 - everything works great :)

Then for pin 34, which according to pinout should support PWM, it says:

E (169529) ledc: ledc_channel_config(258): LEDC GPIO output number error

As I understandand you used LEDC PWM backend for your code and for other PWM pins there is different implementation, which pins actually use LEDC?

Also it seems to think that enabling PWM for pin 15 is perfectly okay, pin 15 is connected to ground :D

@vandys
Copy link
Author

vandys commented May 12, 2017

The PWM code here is just using the SDK's API, and if there's some other PWM implementation then I haven't caught a whiff of it. In driver/gpio.h they list GPIO pins 0 through 33 as input and output. Pin 15 on my own board does not seem to be connected to ground, FWIW.

@laurivosandi
Copy link

laurivosandi commented May 12, 2017

Hi, where have here something similar to this https://raw.githubusercontent.com/gojimmypi/ESP32/master/images/myESP32%20DevKitC%20pinout.png

According to this PWM should work on 34

@vandys
Copy link
Author

vandys commented May 12, 2017

Well, you need to talk with the SDK folks at Espressif. For instance, from their headers:

  • Only pins that support both input & output have integrated pull-up and pull-down resistors. Input-only GPIOs 34-39 do not.

What in the image you sent makes you believe it'll do output on that pin?
You will want to get the ESP32 Technical Reference Manual. Section 4.3 applies here.

@MrSurly
Copy link
Contributor

MrSurly commented May 19, 2017

I was thinking of adding a wrapper around the MCPWM; PWM would be a sub-object of this module.

Mostly, I want to do accurate pulse timing. Yes, I'm aware of machine.time_pulse_us().

int x;

// Initial condition: no channels assigned
for (x = 0; x < LEDC_CHANNEL_MAX; ++x) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code style: variable decls go in the for loop (if not needed after the loop).

timer_cfg.freq_hz = newval;
if (ledc_timer_config(&timer_cfg) != ESP_OK) {
timer_cfg.freq_hz = oval;
return(0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code style: should be return 0;

// MicroPython bindings for PWM

STATIC void esp32_pwm_print(const mp_print_t *print,
mp_obj_t self_in, mp_print_kind_t kind) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code style: single line

if (self->active) {
mp_printf(print, ", freq=%u, duty=%u",
timer_cfg.freq_hz,
ledc_get_duty(PWMODE, self->channel));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only break the line if its larger than 90-100 chars.

}

// Maybe change PWM timer
tval = args[ARG_freq].u_int;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tval should be declared here.

if (channel >= LEDC_CHANNEL_MAX) {
if (avail == -1) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
"Out of PWM channels"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

error messages start with lower case letter

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, use the short-hand mp_raise_ValueError("...")

if (chan_gpio[channel] == -1) {
ledc_channel_config_t cfg = {
.channel = channel,
.duty = (1 << PWRES)/2,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code style: space around "/"

}

// Set duty cycle?
dval = args[ARG_duty].u_int;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

int dval

}

STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp32_pwm_freq_obj,
1, 2, esp32_pwm_freq);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

put on one line

@dpgeorge
Copy link
Member

@laurivosandi that pin out looks wrong.

@dpgeorge
Copy link
Member

I was thinking of adding a wrapper around the MCPWM; PWM would be a sub-object of this module.

It looks like MCPWM and LEDC are 2 different ways to do PWM on a pin. It doesn't really matter what the underlying implementation is, as long as the machine.PWM class works as expected (it's not yet properly specified in the docs so it's subject to change).

If MCPWM provides lots of extra functionality that doesn't fit a standard peripheral (is it similar enough to a Timer?) then it could go in a new "esp32" module as MCPWM class.

@vandys
Copy link
Author

vandys commented May 19, 2017

that pin out looks wrong.

I'm sorry, which pin out? The one from the earlier discussion? Pin 34?

@dpgeorge
Copy link
Member

I'm sorry, which pin out? The one from the earlier discussion? Pin 34?

Sorry, yes, the link that @laurivosandi posted above to "myESP32 DevKitC pinout.png" looks wrong in that it says all IO pins should be able to do PWM when (as you pointed out) higher-numbered pins are input only.

@vandys
Copy link
Author

vandys commented May 19, 2017

Ok, thanks. I'm closing this pull request too, will change code and re-test against new SDK.

@vandys vandys closed this May 19, 2017
@MrSurly
Copy link
Contributor

MrSurly commented May 19, 2017

If MCPWM provides lots of extra functionality that doesn't fit a standard peripheral (is it similar enough to a Timer?) then it could go in a new "esp32" module as MCPWM class.

It's more focused around motor control -- you could drive BLDC motors, for example. Or generate servo signals.

But, it has a separate "capture" module that's mostly for edge capture / pulse timing. Not purely PWM.

It looks like LEDC is more about using timers, and animating led brightness?

@dpgeorge
Copy link
Member

The follow-up to this was merged in #96

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants