X-Git-Url: https://vault307.fbx.one/gitweb/micorpython_ir.git/blobdiff_plain/12683170548778e5d933f2f2052164547cc15113..2ebf5db498266618fc0f037469309a6ea1906304:/RP2_RMT.md diff --git a/RP2_RMT.md b/RP2_RMT.md new file mode 100644 index 0000000..8f86e6d --- /dev/null +++ b/RP2_RMT.md @@ -0,0 +1,94 @@ +# 1. Pulse train ouput on RP2 + +The `RP2_RMT` class provides functionality similar to that of the ESP32 `RMT` +class. It enables pulse trains to be output using a non-blocking driver. By +default the train occurs once. Alternatively it can repeat a defned number of +times, or can be repeated continuously. + +The class was designed for my [IR blaster](https://github.com/peterhinch/micropython_ir) +and [433MHz remote](https://github.com/peterhinch/micropython_remote) +libraries. It supports an optional carrier frequency, where each high pulse can +appear as a burst of a defined carrier frequency. The class can support both +forms concurrently on a pair of pins: one pin produces pulses while a second +produces carrier bursts. + +Pulse trains are specified as arrays with each element being a duration in μs. +Arrays may be of integers or half-words depending on the range of times to be +covered. The duration of a "tick" is 1μs by default, but this can be changed. + +# 2. The RP2_RMT class + +## 2.1 Constructor + +This takes the following args: + 1. `pin_pulse=None` If an ouput `Pin` instance is provided, pulses will be + output on it. + 2. `carrier=None` To output a carrier, a 3-tuple should be provided comprising + `(pin, freq, duty)` where `pin` is an output pin instance, `freq` is the + carrier frequency in Hz and `duty` is the duty ratio in %. + 3. `sm_no=0` State machine no. + 4. `sm_freq=1_000_000` Clock frequency for SM. Defines the unit for pulse + durations. + +## 2.2 Methods + +### 2.2.1 send + +This returns "immediately" with a pulse train being emitted as a background +process. Args: + 1. `ar` A zero terminated array of pulse durations in μs. See notes below. + 2. `reps=1` No. of repetions. 0 indicates continuous output. + 3. `check=True` By default ensures that the pulse train ends in the inactive + state. + +In normal operation, between pulse trains, the pulse pin is low and the carrier +is off. A pulse train ends when a 0 pulse width is encountered: this allows +pulse trains to be shorter than the array length, for example where a +pre-allocated array stores pulse trains of varying lengths. In RF transmitter +applications ensuring the carrier is off between pulse trains may be a legal +requirement, so by default the `send` method enforces this. + +The first element of the array defines the duration of the first high going +pulse, with the second being the duration of the first `off` period. If there +are an even number of elements prior to the terminating 0, the signal will end +in the `off` state. If the `check` arg is `True`, `.send()` will check for an +odd number of elements; in this case it will overwrite the last element with 0 +to enforce a final `off` state. + +This check may be skipped by setting `check=False`. This provides a means of +inverting the normal sense of the driver: if the first pulse train has an odd +number of elements and `check=False` the pin will be left high (and the carrier +on). Subsequent normal pulsetrains will start and end in the high state. + +### 2.2.2 busy + +No args. Returns `True` if a pulse train is being emitted. + +### 2.2.3 cancel + +No args. If a pulse train is being emitted it will continue to the end but no +further repetitions will take place. + +# 3. Design + +The class constructor installs one of two PIO scripts depending on whether a +`pin_pulse` is specified. If it is, the `pulsetrain` script is loaded which +drives the pin directly from the PIO. If no `pin_pulse` is required, the +`irqtrain` script is loaded. Both scripts cause an IRQ to be raised at times +when a pulse would start or end. + +The `send` method loads the transmit FIFO with initial pulse durations and +starts the state machine. The `._cb` ISR keeps the FIFO loaded with data until +a 0 entry is encountered. It also turns the carrier on and off (using a PWM +instance). This means that there is some latency between the pulse and the +carrier. However latencies at start and end are effectively identical, so the +duration of a carrier burst is correct. + +# 4. Limitations + +While the tick interval can be reduced to provide timing precision better than +1μs, the design of this class will not support very high pulse repetition +frequencies. This is because each pulse causes an interrupt: MicroPython is +unable to support high IRQ rates. +[This library](https://github.com/robert-hh/RP2040-Examples/tree/master/pulses) +is more capable in this regard.