From 655dc9fceaa8d7a6b58bea4765c7274239b76c28 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Tue, 19 Apr 2022 17:59:27 +0200 Subject: [PATCH] docs: Add documentation for the mimxrt Encoder/Counter class. This adds MIMXRT-specific arguments and methods, as a superset of the original Encoder/Counter documentation. The mimxrt pinout and quickref docs are updated with relevant information. Signed-off-by: robert-hh --- docs/library/machine.Counter.rst | 95 ++++++++++++++++++++++++++++-- docs/library/machine.Encoder.rst | 99 ++++++++++++++++++++++++++++++-- docs/mimxrt/pinout.rst | 58 +++++++++++++++++++ docs/mimxrt/quickref.rst | 49 ++++++++++++++++ 4 files changed, 290 insertions(+), 11 deletions(-) diff --git a/docs/library/machine.Counter.rst b/docs/library/machine.Counter.rst index f89a6d5b4f..23fa48e53d 100644 --- a/docs/library/machine.Counter.rst +++ b/docs/library/machine.Counter.rst @@ -7,14 +7,14 @@ class Counter -- pulse counter Counter implements pulse counting by monitoring an input signal and counting rising or falling edges. -Minimal example usage:: +Minimal ESP32 example usage:: from machine import Pin, Counter counter = Counter(0, Pin(0, Pin.IN)) # create Counter for pin 0 and begin counting value = counter.value() # retrieve current pulse count -Availability: **ESP32** +Availability: **ESP32, MIMXRT** Constructors ------------ @@ -47,12 +47,49 @@ Methods or ``Counter.FALLING``. *(Supported on ESP32)* - *direction* specifies the direction to count. Either ``Counter.UP`` (the - default) or ``Counter.DOWN``. *(Supported on ESP32)* + default) or ``Counter.DOWN``. *(Supported on ESP32 and MIMXRT)* + A :ref:`machine.Pin ` object as parameter argument specifies a + pin which controls the counting direction. Low: Count up, High: Count down. + *(Supported on MIMXRT)* - *filter_ns* specifies a minimum period of time in nanoseconds that the source signal needs to be stable for a pulse to be counted. Implementations should use the longest filter supported by the hardware that is less than - or equal to this value. The default is 0 (no filter). *(Supported on ESP32)* + or equal to this value. The default is 0 (no filter). *(Supported on ESP32 and MIMXRT)* + + - *max* Specify the upper counting range. The position counter will count up + from a *min* start value up to *max*, then roll over to the init value and + increase the cycles counter by one. When counting down, the cycles counter + decreases at the transition from *min* to *max*. The range is reset by defining + both *max* and *min* to 0. The default value is the hardware's counter range. + *(Supported by MIMXRT and the ESP32 PCNT module)* + + - *min* Specify the lower counting range. The default value is 0. + *(Supported by MIMXRT and the ESP32 PCNT module)* + + - *index* A Pin specifier telling to which pin the index pulse is connected. + At a rising slope of the index pulse the pulse counter is reset to the min value and + the cycles counter is increased or decreased by one, depending on the counting direction. + A *value* of *None* disables the index + input. *(Supported on MIMXRT)* + + - *reset* A Pin specifier telling to which pin the reset pulse is connected. + At a rising slope of the reset pulse the counter is set to the init + value, but the cycles counter is not changed. A *value* of *None* disables the reset input. + *(Supported on MIMXRT)* + + - *match* Set the counter value at which the interrupt IRQ_MATCH shall trigger. + The value is not checked for being in the bounds of the counter range. This option + if equivalent to the *threshold* options of the ESP32 PCNT module. + A *value* of *None* resets the match value and disables the IRQ_MATCH interrupt. + *(Supported on MIMXRT)* + + - *match_pin* A Pin specifier telling to which pin the match output is connected. + This output will have a high level as long as the counter matches the + match value. The signal is generated by the encoder logic and requires no + further software support. The pulse width is defined by the input signal frequency + and can be very short, like 20ns, or stay, if the counter stops at the match value. + A *value* of *None* disables the match output. *(Supported on MIMXRT)* .. method:: Counter.deinit() @@ -79,15 +116,63 @@ Methods the counter (i.e. to measure the counts since the last call), and this will avoid this problem. +.. method:: Counter.cycles([value]) + + Get or set the current cycles counter of the counter as signed 16 bit integer. + The value represents the overflow or underflow events of the count range. + With no arguments the actual cycles counter value is returned. + With a single *value* argument the cycles counter is set to that value. The + base counter is not changed. The method returns the previous value. + *(Supported on MIMXRT)* + +.. method:: Counter.irq(handler=None, trigger=0, hard=False) + + Specifies, that the *handler* is called when the respective *event* happens. + + *event* may be: + - Counter.IRQ_RESET Triggered with a transition at the *reset* input. + - Counter.IRQ_INDEX Triggered with a transition at the *index* input. + - Counter.IRQ_MATCH Triggered when the positions counter matches the match value. For fast signals, + the actual position counter value when retrieved in the callback may be different from the trigger value. + - Counter.IRQ_ROLL_OVER Triggered when the position counter rolls over from the highest + to the lowest value. + - Counter.IRQ_ROLL_UNDER Triggered when the position counter rolls under from the lowest + to the highest value. + + The callback function *handler* receives a single argument, which is the Counter object. All + events share the same callback. The event which triggers the callback can be identified + with the irq.flags() method. The argument *hard* specifies, whether the callback is called + as a hard interrupt or as regular scheduled function. Hard interrupts have always a short latency, + but are limited in that they must not allocate memory. Regular scheduled functions are not limited + in what can be used, but depending on the load of the device execution may be delayed. + Under low load, the difference in latency is minor. + + The default arguments values are handler=None, trigger=0, hard=False. The callback will be + disabled, when called with handler=None. + + The position match event is triggered as long as the position and match value are identical. + Therefore the position match callback is run in a one-shot fashion, and has to be enabled + again when the position has changed. It will be enabled by re-defining the trigger with either + :meth:`Counter.irq()` or :meth:`irq().trigger()`. For ESP32, Counter interrupts are handled + by the :ref:`PCNT`. *(Supported on MIMXRT)* + Constants --------- .. data:: Counter.RISING Counter.FALLING - Select the pulse edge. + Select the pulse edge. *(Supported on ESP32)* .. data:: Counter.UP Counter.DOWN Select the counting direction. + +.. data:: Counter.IRQ_RESET + Counter.IRQ_INDEX + Counter.IRQ_MATCH + Counter.IRQ_ROLL_OVER + Counter.IRQ_ROLL_UNDER + + Select the IRQ trigger event. *(Supported on MIMXRT)* diff --git a/docs/library/machine.Encoder.rst b/docs/library/machine.Encoder.rst index fc2de32084..a4eec591f4 100644 --- a/docs/library/machine.Encoder.rst +++ b/docs/library/machine.Encoder.rst @@ -8,14 +8,14 @@ Encoder implements decoding of quadrature signals as commonly output from rotary encoders, by counting either up or down depending on the order of two input pulses. -Minimal example usage:: +Minimal ESP32 example usage:: from machine import Pin, Encoder - counter = Counter(0, Pin(0, Pin.IN), Pin(1, Pin.IN)) # create Encoder for pins 0, 1 and begin counting - value = counter.value() # retrieve current count + encoder = Encoder(0, Pin(0, Pin.IN), Pin(1, Pin.IN)) # create Encoder for pins 0, 1 and begin counting + value = encoder.value() # retrieve current count -Availability: **ESP32** +Availability: **ESP32, MIMXRT** Constructors ------------ @@ -52,12 +52,46 @@ Methods - *filter_ns* specifies a minimum period of time in nanoseconds that the source signal needs to be stable for a pulse to be counted. Implementations should use the longest filter supported by the hardware that is less than - or equal to this value. The default is 0 (no filter). *(Supported on ESP32)* + or equal to this value. The default is 0 (no filter). *(Supported on ESP32 and MIMXRT)* - *phases* specifies the number of signal edges to count and thus the granularity of the decoding. e.g. 4 phases corresponds to "4x quadrature decoding", and will result in four counts per pulse. Ports may support - either 1, 2, or 4 phases and the default is 1 phase. *(Supported on ESP32)* + either 1, 2, or 4 phases and the default is 1 phase. *(Supported on ESP32 and MIMXRT)* + + - *max* Specify the upper counting range. The position counter will count up + from a *min* start value up to *max*, then roll over to the init value and + increase the cycles counter by one. When counting down, the cycles counter + decreases at the transition from *min* to *max*. The range is reset by defining + both *max* and *min* to 0. The default value is the hardware's counter range. + *(Supported by MIMXRT and the ESP32 PCNT module)* + + - *min*. Specify the lower counting range. The default value is 0. + *(Supported by MIMXRT and the ESP32 PCNT module)* + + - *index* A Pin specifier telling to which pin the index pulse is connected. + At a rising slope of the index pulse the encoder counter is set to the min value + and the cycles counter is increased or decreased by one, depending on + the input levels. A *value* of *None* disables the index input. + *(Supported on MIMXRT)* + + - *reset* A Pin specifier telling to which pin the reset pulse is connected. + At a rising slope of the reset pulse the position counter is set to the init + value, but the cycles counter is not changed. A *value* of *None* disables the reset input. + *(Supported on MIMXRT)* + + - *match* Set the counter value at which the interrupt IRQ_MATCH shall trigger. + The value is not checked for being in the bounds of the counter range. This option + if equivalent to the *threshold* options of the ESP32 PCNT module. + A *value* of *None* resets the match value and disables the IRQ_MATCH interrupt. + *(Supported on MIMXRT)* + + - *match_pin* A Pin specifier telling to which pin the match output is connected. + This output will have a high level as long as the position counter matches the + match value. The signal is generated by the encoder logic and requires no + further software support. The pulse width is defined by the input signal frequency + and can be very short, like 20ns, or stay, if the counter stops at the match position. + A *value* of *None* disables the match output. *(Supported on MIMXRT)* .. method:: Encoder.deinit() @@ -70,3 +104,56 @@ Methods Implementations should aim to do the get and set atomically. See :meth:`machine.Counter.value` for details about overflow of this value. + +.. method:: Encoder.cycles([value]) + + Get or set the current cycles counter of the counter as signed 16 bit integer. + The value represents the overflow or underflow events of the count range. + With no arguments the actual cycles counter value is returned. + With a single *value* argument the cycles counter is set to that value. The + base counter is not changed. The method returns the previous value. + *(Supported on MIMXRT)* + +.. method:: Encoder.irq(handler=None, trigger=0, hard=False) + + Specifies, that the *handler* is called when the respective *event* happens. + + *event* may be: + - Encoder.IRQ_RESET Triggered with a transition at the *reset* input. + - Encoder.IRQ_INDEX Triggered with a transition at the *index* input. + - Encoder.IRQ_MATCH Triggered when the position counter matches the *match* value. For fast signals, + the actual position counter value when retrieved in the callback may be different from the trigger value. + - Encoder.IRQ_ROLL_OVER Triggered when the position counter rolls over from the highest + to the lowest value. + - Encoder.IRQ_ROLL_UNDER Triggered when the position counter rolls under from the lowest + to the highest value. + + The callback function *handler* receives a single argument, which is the Encoder object. All + events share the same callback. The event which triggers the callback can be identified + with the irq.flags() method. The argument *hard* specifies, whether the callback is called + as a hard interrupt or as regular scheduled function. Hard interrupts have always a short latency, + but are limited in that they must not allocate memory. Regular scheduled functions are not limited + in what can be used, but depending on the load of the device execution may be delayed. + Under low load, the difference in latency is minor. + + The default arguments values are trigger=0, handler=None, hard=False. The callback will be + disabled, when called with handler=None. + + The position match event is triggered as long as the position and match value are identical. + Therefore the position match callback is run in a one-shot fashion, and has to be enabled + again when the position has changed. It will be enabled by re-defining the trigger with either + :meth:`Encoder.irq()` or :meth:`irq().trigger()`. For ESP32, Encoder interrupts are handled + by the :ref:`PCNT unit `. + + *(Supported on MIMXRT)* + +Constants +--------- + +.. data:: Encoder.IRQ_RESET + Encoder.IRQ_INDEX + Encoder.IRQ_MATCH + Encoder.IRQ_ROLL_OVER + Encoder.IRQ_ROLL_UNDER + + Select the IRQ trigger event. *(Supported on MIMXRT)* diff --git a/docs/mimxrt/pinout.rst b/docs/mimxrt/pinout.rst index 09953164bd..b2ff0683f7 100644 --- a/docs/mimxrt/pinout.rst +++ b/docs/mimxrt/pinout.rst @@ -419,3 +419,61 @@ Makerdiary RT1011 1 D8 SD1 D7 D4 D1 D2 D3 Symbolic pin names are provided for the MIMXRT_10xx_DEV boards. These are provided for the other boards as well. + +.. _mimxrt_encoder_counter_pinout: + +| +| + +Pin Assignment +-------------- + +Pins are specified in the same way as for the Pin class. The pins available for an +assignment to the Encoder or Counter are: + +**IMXRT1010_EVK**, **iMX RT1011 Nano Kit**, **Olimex RT1010Py**: + + Not supported. + +**IMXRT1015_EVK**: + + J30, pins 1 and 3, with the pin names "ENC1" and "ENC2". + +**IMXRT1020_EVK**: + + Pins D0 and D1. + +**IMXRT1050_EVK**, **IMXRT1050_EVKB**, **IMXRT1060_EVK**, **IMXRT1064_EBK**: + + Pins D2, D4, D5, D8, D9, D10, D11, D12, D13, D14, D15, A4, A5. + Depending on the board configuration, not all pins may be wired. + Pins D2, D4 and D5 cannot be used for the match output. + +**IMXRT1170_EVK**: + + Pins D0, D1, D2. + + D2 is connected to the 1G PHY chip as well. So levels may be distorted. + +**Teensy 4.0**: + + Pins D0, D1, D2, D3, D4, D5, D7, D8, D26, D27, D30, D31, D32, D33. + Pin D0 and D5 share the same signal and cannot be used independently. + Pins D26, D27, D30 and D31 cannot be used for the match output. + +**Teensy 4.1**: + + Pins D0, D1, D2, D3, D4, D5, D7, D8, D26, D27, D30, D31, D32, D33, + D37, D42, D43, D44, D45, D46 and D47. + Pins D26, D27, D30 and D31 cannot be used for the match output. + Some pins are assigned to the same signal and cannot be used independently. These are: + + - Pins D0, D5 and D37, + - Pins D2 and D43, + - Pins D3 and D42, and + - Pins D4 and D47. + +**Seeed ARCH MIX** + + Pins J3_14, J3_15, J4_19, J4_20, J5_15, J5_16, J5_17, J5_22, J5_23, J5_24, J5_25 and J5_26. + Pins J3_14 and J3_15 cannot be used for the match output. diff --git a/docs/mimxrt/quickref.rst b/docs/mimxrt/quickref.rst index 9f1efd4ffc..94cb2bc56c 100644 --- a/docs/mimxrt/quickref.rst +++ b/docs/mimxrt/quickref.rst @@ -556,6 +556,55 @@ port and LAN(1) for the 1G port. For details of the network interface refer to the class :ref:`network.LAN `. +class Counter -- Signal counter for i.MXRT MCUs +----------------------------------------------- + +This class provides a Counter service using the Quadrature Encoder module + +Example usage:: + + # Samples for Teensy + + from machine import Pin, Counter + + counter = Counter(0, Pin("D0")) # create Counter object + counter.value() # get current counter value + counter.value(0) # set the counter to 0 + counter.init(max=128) # set the upper counting range + counter.deinit() # turn off the Counter + counter.init(match=1000) # create a match event at count 1000 + counter.irq(handler, Counter.IRQ_MATCH) # call the function handler at a counter match + counter # show the Counter object properties + +The Counter is hardware based. It is available at all MIMXRT devices except the ones +based on the i.MX RT 1010 MCU. For details about using the Counter with a MIMXRT board +see :ref:`machine.Counter `: + +class Encoder -- Quadrature Encoder for i.MXRT MCUs +--------------------------------------------------- + +This class provides the Quadrature Encoder Service. + +Example usage:: + + # Samples for Teensy + + from machine import Pin, Encoder + + qe = Encoder(0, Pin("D0"), Pin("D1")) # create Quadrature Encoder object + qe.value() # get current counter values + qe.value(0) # set the counter value to 0 + qe.init(max=128) # specify 128 counts as upper range + qe.init(index=Pin("D3")) # specify Pin 3 as Index pulse input + qe.deinit() # turn off the Quadrature Encoder + qe.init(match=64) # set a match event at count 64 + qe.irq(handler, qe.IRQ_MATCH) # call the function handler at a match event + qe # show the Encoder object properties + +The Quadrature Encoder is hardware based. It is available at all MIMXRT devices except the ones +based on the i.MX RT 1010 MCU. For details about using the Encoder with a MIMXRT board +see :ref:`machine.Encoder `: + Transferring files ------------------