Skip to content

ports/PWM: Reduce inconsistencies between the ports. #10850

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
May 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/esp32/quickref.rst
Original file line number Diff line number Diff line change
Expand Up @@ -305,8 +305,8 @@ Use the :ref:`machine.PWM <machine.PWM>` class::

from machine import Pin, PWM

pwm0 = PWM(Pin(0)) # create PWM object from a pin
freq = pwm0.freq() # get current frequency (default 5kHz)
pwm0 = PWM(Pin(0), freq=5000, duty_u16=32768) # create PWM object from a pin
freq = pwm0.freq() # get current frequency
pwm0.freq(1000) # set PWM frequency from 1Hz to 40MHz

duty = pwm0.duty() # get current duty cycle, range 0-1023 (default 512, 50%)
Expand Down
7 changes: 5 additions & 2 deletions docs/library/machine.PWM.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ Example usage::

from machine import PWM

pwm = PWM(pin) # create a PWM object on a pin
pwm = PWM(pin, freq=50, duty_u16=8192) # create a PWM object on a pin
# and set freq and duty
pwm.duty_u16(32768) # set duty to 50%

# reinitialise with a period of 200us, duty of 5us
Expand All @@ -23,7 +24,7 @@ Example usage::
Constructors
------------

.. class:: PWM(dest, *, freq, duty_u16, duty_ns)
.. class:: PWM(dest, *, freq, duty_u16, duty_ns, invert)

Construct and return a new PWM object using the following parameters:

Expand All @@ -34,10 +35,12 @@ Constructors
PWM cycle.
- *duty_u16* sets the duty cycle as a ratio ``duty_u16 / 65535``.
- *duty_ns* sets the pulse width in nanoseconds.
- *invert* inverts the respective output if the value is True

Setting *freq* may affect other PWM objects if the objects share the same
underlying PWM generator (this is hardware specific).
Only one of *duty_u16* and *duty_ns* should be specified at a time.
*invert* is not available at all ports.

Methods
-------
Expand Down
16 changes: 9 additions & 7 deletions docs/mimxrt/quickref.rst
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,12 @@ handling signal groups. ::

from machine import Pin, PWM

pwm2 = PWM(Pin(2)) # create PWM object from a pin
pwm2.freq() # get current frequency
pwm2.freq(1000) # set frequency
pwm2.duty_u16() # get current duty cycle, range 0-65535
pwm2.duty_u16(200) # set duty cycle, range 0-65535
# create PWM object from a pin and set the frequency and duty cycle
pwm2 = PWM(Pin(2), freq=2000, duty_u16=32768)
pwm2.freq() # get the current frequency
pwm2.freq(1000) # set/change the frequency
pwm2.duty_u16() # get the current duty cycle, range 0-65535
pwm2.duty_u16(200) # set the duty cycle, range 0-65535
pwm2.deinit() # turn off PWM on the pin
# create a complementary signal pair on Pin 2 and 3
pwm2 = PWM((2, 3), freq=2000, duty_ns=20000)
Expand Down Expand Up @@ -206,8 +207,9 @@ PWM Constructor
- *align*\=value. Shortcuts for the pulse center setting, causing the pulse either at
the center of the frame (value=0), the leading edge at the begin (value=1) or the
trailing edge at the end of a pulse period (value=2).
- *invert*\=True|False channel_mask. Setting a bit in the mask inverts the respective channel.
Bit 0 inverts the first specified channel, bit 2 the second. The default is 0.
- *invert*\=value channel_mask. Setting a bit in the mask inverts the respective channel.
Bit 0 inverts the first specified channel, bit 1 the second. The default is 0. For a
PWM object with a single channel, True and False may be used as values.
- *sync*\=True|False. If a channel of a module's submodule 0 is already active, other
submodules of the same module can be forced to be synchronous to submodule 0. Their
pulse period start then at at same clock cycle. The default is False.
Expand Down
27 changes: 19 additions & 8 deletions docs/rp2/quickref.rst
Original file line number Diff line number Diff line change
Expand Up @@ -146,19 +146,30 @@ See :ref:`machine.UART <machine.UART>`. ::
PWM (pulse width modulation)
----------------------------

There are 8 independent channels each of which have 2 outputs making it 16
PWM channels in total which can be clocked from 7Hz to 125Mhz.
There are 8 independent PWM generators called slices, which each have two
channels making it 16 PWM channels in total which can be clocked from
8Hz to 62.5Mhz at a machine.freq() of 125Mhz. The two channels of a
slice run at the same frequency, but can have a different duty rate.
The two channels are usually assigned to adjacent GPIO pin pairs with
even/odd numbers. So GPIO0 and GPIO1 are at slice 0, GPIO2 and GPIO3
are at slice 1, and so on. A certain channel can be assigned to
different GPIO pins (see Pinout). For instance slice 0, channel A can be assigned
to both GPIO0 and GPIO16.

Use the ``machine.PWM`` class::

from machine import Pin, PWM

pwm0 = PWM(Pin(0)) # create PWM object from a pin
pwm0.freq() # get current frequency
pwm0.freq(1000) # set frequency
pwm0.duty_u16() # get current duty cycle, range 0-65535
pwm0.duty_u16(200) # set duty cycle, range 0-65535
pwm0.deinit() # turn off PWM on the pin
# create PWM object from a pin and set the frequency of slice 0
# and duty cycle for channel A
pwm0 = PWM(Pin(0), freq=2000, duty_u16=32768)
pwm0.freq() # get the current frequency of slice 0
pwm0.freq(1000) # set/change the frequency of slice 0
pwm0.duty_u16() # get the current duty cycle of channel A, range 0-65535
pwm0.duty_u16(200) # set the duty cycle of channel A, range 0-65535
pwm0.duty_u16(0) # stop the output at channel A
print(pwm0) # show the properties of the PWM object.
pwm0.deinit() # turn off PWM of slice 0, stopping channels A and B

ADC (analog to digital conversion)
----------------------------------
Expand Down
2 changes: 1 addition & 1 deletion docs/samd/pinout.rst
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ or other combinations.

SAMD21 SPI assignments
``````````````````````
The I2C devices and signals must be chosen according to the following rules:
The SPI devices and signals must be chosen according to the following rules:

- The following pad number pairs are suitable for MOSI/SCK: 0/1, 2/3, 3/1, and 0/3.
- The MISO signal must be at a Pin with a different pad number than MOSI or SCK.
Expand Down
38 changes: 18 additions & 20 deletions docs/samd/quickref.rst
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ Use the :ref:`machine.Pin <machine.Pin>` class::
print(p2.value()) # get value, 0 or 1

p4 = Pin('D4', Pin.IN, Pin.PULL_UP) # enable internal pull-up resistor
p7 = Pin("PA07", Pin.OUT, value=1) # set pin high on creation
p7 = Pin('PA07', Pin.OUT, value=1) # set pin high on creation

Pins can be denoted by a string or a number. The string is either the
pin label of the respective board, like "D0" or "SDA", or in the form
Expand All @@ -157,7 +157,7 @@ See :ref:`machine.UART <machine.UART>`. ::
# Use UART 3 on a ItsyBitsy M4 board
from machine import UART

uart3 = UART(3, tx=Pin(1), rx=Pin(0), baudrate=115200)
uart3 = UART(3, tx=Pin('D1'), rx=Pin('D0'), baudrate=115200)
uart3.write('hello') # write 5 bytes
uart3.read(5) # read up to 5 bytes

Expand All @@ -178,11 +178,12 @@ It supports all basic methods listed for that class. ::

from machine import Pin, PWM

pwm = PWM(Pin(7)) # create PWM object from a pin
pwm.freq() # get current frequency
pwm.freq(1000) # set frequency
pwm.duty_u16() # get current duty cycle, range 0-65535
pwm.duty_u16(200) # set duty cycle, range 0-65535
# create PWM object from a pin and set the frequency and duty cycle
pwm = PWM(Pin('D7'), freq=2000, duty_u16=32768)
pwm.freq() # get the current frequency
pwm.freq(1000) # set/change the frequency
pwm.duty_u16() # get the current duty cycle, range 0-65535
pwm.duty_u16(200) # set the duty cycle, range 0-65535
pwm.deinit() # turn off PWM on the pin

pwm # show the PWM objects properties
Expand All @@ -191,7 +192,7 @@ It supports all basic methods listed for that class. ::
PWM Constructor
```````````````

.. class:: PWM(dest, freq, duty_u16, duty_ns, *, invert, device)
.. class:: PWM(dest, *, freq, duty_u16, duty_ns, invert, device)
:noindex:

Construct and return a new PWM object using the following parameters:
Expand All @@ -213,9 +214,6 @@ PWM Constructor
- *freq* should be an integer which sets the frequency in Hz for the
PWM cycle. The valid frequency range is 1 Hz to 24 MHz.
- *duty_u16* sets the duty cycle as a ratio ``duty_u16 / 65536``.
The duty cycle of a X channel can only be changed, if the A and B channel
of the respective submodule is not used. Otherwise the duty_16 value of the
X channel is 32768 (50%).
- *duty_ns* sets the pulse width in nanoseconds. The limitation for X channels
apply as well.
- *invert*\=True|False. Setting a bit inverts the respective output.
Expand Down Expand Up @@ -245,9 +243,9 @@ Use the :ref:`machine.ADC <machine.ADC>` class::

from machine import ADC

adc0 = ADC(Pin("A0")) # create ADC object on ADC pin, average=16
adc0 = ADC(Pin('A0')) # create ADC object on ADC pin, average=16
adc0.read_u16() # read value, 0-65536 across voltage range 0.0v - 3.3v
adc1 = ADC(Pin("A1"), average=1) # create ADC object on ADC pin, average=1
adc1 = ADC(Pin('A1'), average=1) # create ADC object on ADC pin, average=1

The resolution of the ADC is 12 bit with 12 bit accuracy, irrespective of the
value returned by read_u16(). If you need a higher resolution or better accuracy, use
Expand Down Expand Up @@ -341,7 +339,7 @@ Software SPI (using bit-banging) works on all pins, and is accessed via the
# construct a SoftSPI bus on the given pins
# polarity is the idle state of SCK
# phase=0 means sample on the first edge of SCK, phase=1 means the second
spi = SoftSPI(baudrate=100000, polarity=1, phase=0, sck=Pin(7), mosi=Pin(9), miso=Pin(10))
spi = SoftSPI(baudrate=100000, polarity=1, phase=0, sck=Pin('D7'), mosi=Pin('D9'), miso=Pin('D10'))

spi.init(baudrate=200000) # set the baud rate

Expand Down Expand Up @@ -388,7 +386,7 @@ accessed via the :ref:`machine.SoftI2C <machine.SoftI2C>` class::

from machine import Pin, SoftI2C

i2c = SoftI2C(scl=Pin(10), sda=Pin(11), freq=100000)
i2c = SoftI2C(scl=Pin('D10'), sda=Pin('D11'), freq=100000)

i2c.scan() # scan for devices

Expand Down Expand Up @@ -424,7 +422,7 @@ The OneWire driver is implemented in software and works on all pins::
from machine import Pin
import onewire

ow = onewire.OneWire(Pin(12)) # create a OneWire bus on GPIO12
ow = onewire.OneWire(Pin('D12')) # create a OneWire bus on GPIO12
ow.scan() # return a list of devices on the bus
ow.reset() # reset the bus
ow.readbyte() # read a byte
Expand Down Expand Up @@ -454,12 +452,12 @@ The DHT driver is implemented in software and works on all pins::
import dht
import machine

d = dht.DHT11(machine.Pin(4))
d = dht.DHT11(machine.Pin('D4'))
d.measure()
d.temperature() # eg. 23 (°C)
d.humidity() # eg. 41 (% RH)

d = dht.DHT22(machine.Pin(4))
d = dht.DHT22(machine.Pin('D4'))
d.measure()
d.temperature() # eg. 23.6 (°C)
d.humidity() # eg. 41.3 (% RH)
Expand All @@ -474,7 +472,7 @@ The APA102 on some Adafruit boards can be controlled using SoftSPI::

from machine import SoftSPI, Pin
# create the SPI object. miso can be any unused pin.
spi=SoftSPI(sck=Pin(25), mosi=Pin(26), miso=Pin(14))
spi=SoftSPI(sck=Pin('D25'), mosi=Pin('D26'), miso=Pin('D14'))

# define a little function that writes the data with
# preamble and postfix
Expand All @@ -499,7 +497,7 @@ with the Neopixel driver from the MicroPython driver library::
import machine

# 1 LED connected to Pin D8 on Adafruit Feather boards
p = machine.Pin(8, machine.Pin.OUT)
p = machine.Pin('D8', machine.Pin.OUT)
n = neopixel.NeoPixel(p, 1)

# set the led to red.
Expand Down
10 changes: 0 additions & 10 deletions extmod/machine_pwm.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,11 @@
#include MICROPY_PY_MACHINE_PWM_INCLUDEFILE
#endif

#if MICROPY_PY_MACHINE_PWM_INIT
STATIC mp_obj_t machine_pwm_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
mp_machine_pwm_init_helper(args[0], n_args - 1, args + 1, kw_args);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_pwm_init_obj, 1, machine_pwm_init);
#endif

// PWM.deinit()
STATIC mp_obj_t machine_pwm_deinit(mp_obj_t self_in) {
Expand Down Expand Up @@ -82,8 +80,6 @@ STATIC mp_obj_t machine_pwm_duty(size_t n_args, const mp_obj_t *args) {
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_pwm_duty_obj, 1, 2, machine_pwm_duty);
#endif

#if MICROPY_PY_MACHINE_PWM_DUTY_U16_NS

// PWM.duty_u16([value])
STATIC mp_obj_t machine_pwm_duty_u16(size_t n_args, const mp_obj_t *args) {
machine_pwm_obj_t *self = MP_OBJ_TO_PTR(args[0]);
Expand Down Expand Up @@ -114,21 +110,15 @@ STATIC mp_obj_t machine_pwm_duty_ns(size_t n_args, const mp_obj_t *args) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_pwm_duty_ns_obj, 1, 2, machine_pwm_duty_ns);

#endif

STATIC const mp_rom_map_elem_t machine_pwm_locals_dict_table[] = {
#if MICROPY_PY_MACHINE_PWM_INIT
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_pwm_init_obj) },
#endif
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_pwm_deinit_obj) },
{ MP_ROM_QSTR(MP_QSTR_freq), MP_ROM_PTR(&machine_pwm_freq_obj) },
#if MICROPY_PY_MACHINE_PWM_DUTY
{ MP_ROM_QSTR(MP_QSTR_duty), MP_ROM_PTR(&machine_pwm_duty_obj) },
#endif
#if MICROPY_PY_MACHINE_PWM_DUTY_U16_NS
{ MP_ROM_QSTR(MP_QSTR_duty_u16), MP_ROM_PTR(&machine_pwm_duty_u16_obj) },
{ MP_ROM_QSTR(MP_QSTR_duty_ns), MP_ROM_PTR(&machine_pwm_duty_ns_obj) },
#endif
};
STATIC MP_DEFINE_CONST_DICT(machine_pwm_locals_dict, machine_pwm_locals_dict_table);

Expand Down
2 changes: 0 additions & 2 deletions ports/esp32/mpconfigport.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,7 @@
#define MICROPY_PY_MACHINE_BITSTREAM (1)
#define MICROPY_PY_MACHINE_PULSE (1)
#define MICROPY_PY_MACHINE_PWM (1)
#define MICROPY_PY_MACHINE_PWM_INIT (1)
#define MICROPY_PY_MACHINE_PWM_DUTY (1)
#define MICROPY_PY_MACHINE_PWM_DUTY_U16_NS (1)
#define MICROPY_PY_MACHINE_PWM_INCLUDEFILE "ports/esp32/machine_pwm.c"
#define MICROPY_PY_MACHINE_I2C (1)
#define MICROPY_PY_MACHINE_I2C_TRANSFER_WRITE1 (1)
Expand Down
Loading
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy