diff --git a/docs/esp32/general.rst b/docs/esp32/general.rst index 51918d4e18..8137c042d9 100644 --- a/docs/esp32/general.rst +++ b/docs/esp32/general.rst @@ -52,6 +52,7 @@ For your convenience, some of technical specifications are provided below: * I2S: 2 * ADC: 12-bit SAR ADC up to 18 channels * DAC: 2 8-bit DACs +* RMT: 8 channels allowing accurate pulse transmit/receive * Programming: using BootROM bootloader from UART - due to external FlashROM and always-available BootROM bootloader, the ESP32 is not brickable diff --git a/docs/esp32/quickref.rst b/docs/esp32/quickref.rst index ef9b0a2e8c..cfe31664e7 100644 --- a/docs/esp32/quickref.rst +++ b/docs/esp32/quickref.rst @@ -365,6 +365,20 @@ Notes: p1 = Pin(4, Pin.OUT, None) +RMT +--- + +The RMT is ESP32-specific and allows generation of accurate digital pulses with +12.5ns resolution. See :ref:`esp32.RMT ` for details. Usage is:: + + import esp32 + from machine import Pin + + r = esp32.RMT(0, pin=Pin(18), clock_div=8) + r # RMT(channel=0, pin=18, source_freq=80000000, clock_div=8) + # The channel resolution is 100ns (1/(source_freq/clock_div)). + r.write_pulses((1, 20, 2, 40), start=0) # Send 0 for 100ns, 1 for 2000ns, 0 for 200ns, 1 for 4000ns + OneWire driver -------------- diff --git a/docs/library/esp32.rst b/docs/library/esp32.rst index 68379624e6..467af0ff0f 100644 --- a/docs/library/esp32.rst +++ b/docs/library/esp32.rst @@ -1,3 +1,5 @@ +.. currentmodule:: esp32 + :mod:`esp32` --- functionality specific to the ESP32 ==================================================== @@ -86,6 +88,91 @@ Constants Used in `Partition.find` to specify the partition type. + +.. _esp32.RMT: + +RMT +--- + +The RMT (Remote Control) module, specific to the ESP32, was originally designed +to send and receive infrared remote control signals. However, due to a flexible +design and very accurate (as low as 12.5ns) pulse generation, it can also be +used to transmit or receive many other types of digital signals:: + + import esp32 + from machine import Pin + + r = esp32.RMT(0, pin=Pin(18), clock_div=8) + r # RMT(channel=0, pin=18, source_freq=80000000, clock_div=8) + # The channel resolution is 100ns (1/(source_freq/clock_div)). + r.write_pulses((1, 20, 2, 40), start=0) # Send 0 for 100ns, 1 for 2000ns, 0 for 200ns, 1 for 4000ns + +The input to the RMT module is an 80MHz clock (in the future it may be able to +configure the input clock but, for now, it's fixed). ``clock_div`` *divides* +the clock input which determines the resolution of the RMT channel. The +numbers specificed in ``write_pulses`` are multiplied by the resolution to +define the pulses. + +``clock_div`` is an 8-bit divider (0-255) and each pulse can be defined by +multiplying the resolution by a 15-bit (0-32,768) number. There are eight +channels (0-7) and each can have a different clock divider. + +So, in the example above, the 80MHz clock is divided by 8. Thus the +resolution is (1/(80Mhz/8)) 100ns. Since the ``start`` level is 0 and toggles +with each number, the bitstream is ``0101`` with durations of [100ns, 2000ns, +100ns, 4000ns]. + +For more details see Espressif's `ESP-IDF RMT documentation. +`_. + +.. Warning:: + The current MicroPython RMT implementation lacks some features, most notably + receiving pulses and carrier transmit. RMT should be considered a + *beta feature* and the interface may change in the future. + + +.. class:: RMT(channel, \*, pin=None, clock_div=8) + + This class provides access to one of the eight RMT channels. *channel* is + required and identifies which RMT channel (0-7) will be configured. *pin*, + also required, configures which Pin is bound to the RMT channel. *clock_div* + is an 8-bit clock divider that divides the source clock (80MHz) to the RMT + channel allowing the resolution to be specified. + +.. method:: RMT.source_freq() + + Returns the source clock frequency. Currently the source clock is not + configurable so this will always return 80MHz. + +.. method:: RMT.clock_div() + + Return the clock divider. Note that the channel resolution is + ``1 / (source_freq / clock_div)``. + +.. method:: RMT.wait_done(timeout=0) + + Returns True if `RMT.write_pulses` has completed. + + If *timeout* (defined in ticks of ``source_freq / clock_div``) is specified + the method will wait for *timeout* or until `RMT.write_pulses` is complete, + returning ``False`` if the channel continues to transmit. + +.. Warning:: + Avoid using ``wait_done()`` if looping is enabled. + +.. method:: RMT.loop(enable_loop) + + Configure looping on the channel, allowing a stream of pulses to be + indefinitely repeated. *enable_loop* is bool, set to True to enable looping. + +.. method:: RMT.write_pulses(pulses, start) + + Begin sending *pulses*, a list or tuple defining the stream of pulses. The + length of each pulse is defined by a number to be multiplied by the channel + resolution ``(1 / (source_freq / clock_div))``. *start* defines whether the + stream starts at 0 or 1. + + The Ultra-Low-Power co-processor --------------------------------