← index #5696Issue #2854
Related · high · value 2.408
QUERY · ISSUE

esp8266: open drain PWM?

openby osresearchopened 2020-02-25updated 2020-03-03
port-esp8266

When driving a high-side switching transistor with an external pull-up resistor the Pin.OPEN_DRAIN output works well (with negative logic, so grounding the output turns it on and letting it float turns it off). The PWM module however has a comment that it explicitly disables the open drain, which prevents the transistor from being able to fully turn off: https://github.com/micropython/micropython/blob/master/ports/esp8266/esppwm.c#L387

Is there a reason to do this rather than leaving the pin in the mode configured by the python code?

CANDIDATE · ISSUE

stmhal alt function open drain doesn't work

closedby chrismas9opened 2017-02-08updated 2018-12-04
ports

It appears that Open Drain doesn't work for Alt Functions (eg PWM) for pyb or machine. In both cases a high level drives the pin to VDD (eg 3.3V) irrespective of external connection.

Use case: I like to drive PWM LEDs from 5V using an open drain output. This way the PWM noise isn't coupled onto the ADC reference (3.3V).

Symptom: When the PWM duty cycle is set to 100% the LED glows dimly. This is because it has 1.7V across it (A=5V, K=3.3V). When the pin is configured as open drain GPIO the LED goes out. The LED is active low so 100% dc should be off.

Test hardware: pyboard v1.0 running pybv10-20170208-v1.8.7-202-gaf622eb.dfu
Connect a pullup resistor from X3 to 5V and a voltmeter from X3 to GND.
Run the two scripts below, one for pyb and one for machine.

When the pin is low the voltmeter will read approx. 0V.
When the pin is high the voltmeter will read approx. 5V if open drain is working or 3.3V if it is not working.

import pyb
from pyb import Timer
from pyb import Pin

# This tests the function of Pin.OUT_OD and Pin.AF_OD in pyb.Pin
# Connect a resistor of between 1k and 10k to pyboard pin X3 and 5V supply.
# In push pull_mode a '1' will read 3.3V, in open_drain mode it should read 5V.
print("pyb.Pin")
print("alternate function open_drain test, PWM 100%, pin X3 should be 5V")
# follwing test fails. Pin voltage is 3.3V
red_ext = Pin('X3', Pin.AF_OD, af = 2)
tim5 = Timer(5, freq=0.25)
red_ext_PWM = tim5.channel(3, pyb.Timer.PWM, pin=red_ext)
red_ext_PWM.pulse_width_percent(100)
pyb.delay(10000)

print("gpio open_drain test, writing 1, pin X3 should be 5V")
# following test passes. Pin voltage is 5V
red_ext = Pin('X3', Pin.OUT_OD)
red_ext.value(1)
import pyb
import machine
from pyb import Timer
from machine import Pin

# This tests the function of Pin.OPEN_DRAIN and Pin.ALT_OPEN_DRAIN in machine.Pin
# Connect a resistor of between 1k and 10k to pyboard pin X3 and 5V supply.
# In push pull_mode a '1' will read 3.3V, in open_drain mode it should read 5V.
print("machine.Pin")
print("alternate function open_drain test, PWM 100%, pin X3 should be 5V")
# follwing test fails. Pin voltage is 3.3V
red_ext = Pin('X3', Pin.ALT_OPEN_DRAIN, alt = 2)
tim5 = Timer(5, freq=0.25)
red_ext_PWM = tim5.channel(3, pyb.Timer.PWM, pin=red_ext)
red_ext_PWM.pulse_width_percent(100)
pyb.delay(10000)

print("gpio open_drain test, writing 1, pin X3 should be 5V")
# following test passes. Pin voltage is 5V
red_ext = Pin('X3', Pin.OPEN_DRAIN)
red_ext(1)

In stmhal/timer.c there is no support for open drain PWM.

///   - `mode` can be one of:
///     - `Timer.PWM` - configure the timer in PWM mode (active high).
///     - `Timer.PWM_INVERTED` - configure the timer in PWM mode (active low).

In the official docs there is a waiver that machine Pin.ALT_OPEN_DRAIN may not be supported by all ports but the pyb library is specific to the pyboard and lists Pin.AF_OD as a valid mode

Pin.AF_OD - configure the pin for alternate function, open-drain;

So there appears to be a discrepancy between the docs and actual implementation

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied