diff --git a/docs/library/index.rst b/docs/library/index.rst index 43d9e87f3c..2536e8dc96 100644 --- a/docs/library/index.rst +++ b/docs/library/index.rst @@ -165,3 +165,14 @@ The following libraries are specific to the ESP8266 and ESP32. esp.rst esp32.rst + + +Libraries specific to the RP2040 +-------------------------------- + +The following libraries are specific to the RP2040, as used in the Raspberry Pi Pico. + +.. toctree:: + :maxdepth: 2 + + rp2.rst diff --git a/docs/library/machine.rst b/docs/library/machine.rst index f831049f88..0a1c1c9530 100644 --- a/docs/library/machine.rst +++ b/docs/library/machine.rst @@ -64,9 +64,11 @@ Interrupt related functions Power related functions ----------------------- -.. function:: freq() +.. function:: freq([hz]) - Returns CPU frequency in hertz. + Returns the CPU frequency in hertz. + + On some ports this can also be used to set the CPU frequency by passing in *hz*. .. function:: idle() diff --git a/docs/library/rp2.Flash.rst b/docs/library/rp2.Flash.rst new file mode 100644 index 0000000000..3b423adfdd --- /dev/null +++ b/docs/library/rp2.Flash.rst @@ -0,0 +1,36 @@ +.. currentmodule:: rp2 +.. _rp2.Flash: + +class Flash -- access to built-in flash storage +=============================================== + +This class gives access to the SPI flash memory. + +In most cases, to store persistent data on the device, you'll want to use a +higher-level abstraction, for example the filesystem via Python's standard file +API, but this interface is useful to :ref:`customise the filesystem +configuration ` or implement a low-level storage system for your +application. + + +Constructors +------------ + +.. class:: Flash() + + Gets the singleton object for accessing the SPI flash memory. + + +Methods +------- + +.. method:: Flash.readblocks(block_num, buf) + Flash.readblocks(block_num, buf, offset) +.. method:: Flash.writeblocks(block_num, buf) + Flash.writeblocks(block_num, buf, offset) +.. method:: Flash.ioctl(cmd, arg) + + These methods implement the simple and extended + :ref:`block protocol ` defined by + :class:`uos.AbstractBlockDev`. + diff --git a/docs/library/rp2.PIO.rst b/docs/library/rp2.PIO.rst new file mode 100644 index 0000000000..e0675af1e9 --- /dev/null +++ b/docs/library/rp2.PIO.rst @@ -0,0 +1,94 @@ +.. currentmodule:: rp2 +.. _rp2.PIO: + +class PIO -- advanced PIO usage +=============================== + +The :class:`PIO` class gives access to an instance of the RP2040's PIO +(programmable I/O) interface. + +The preferred way to interact with PIO is using :class:`rp2.StateMachine`, the +PIO class is for advanced use. + +For assembling PIO programs, see :func:`rp2.asm_pio`. + + +Constructors +------------ + +.. class:: PIO(id) + + Gets the PIO instance numbered *id*. The RP2040 has two PIO instances, + numbered 0 and 1. + + Raises a ``ValueError`` if any other argument is provided. + + +Methods +------- + +.. method:: PIO.add_program(program) + + Add the *program* to the instruction memory of this PIO instance. + + The amount of memory available for programs on each PIO instance is + limited. If there isn't enough space left in the PIO's program memory + this method will raise ``OSError(ENOMEM)``. + +.. method:: PIO.remove_program([program]) + + Remove *program* from the instruction memory of this PIO instance. + + If no program is provided, it removes all programs. + + It is not an error to remove a program which has already been removed. + +.. method:: PIO.state_machine(id, [program, ...]) + + Gets the state machine numbered *id*. On the RP2040, each PIO instance has + four state machines, numbered 0 to 3. + + Optionally initialize it with a *program*: see `StateMachine.init`. + + >>> rp2.PIO(1).state_machine(3) + StateMachine(7) + +.. method:: PIO.irq(handler=None, trigger=IRQ_SM0|IRQ_SM1|IRQ_SM2|IRQ_SM3, hard=False) + + Returns the IRQ object for this PIO instance. + + MicroPython only uses IRQ 0 on each PIO instance. IRQ 1 is not available. + + Optionally configure it. + + +Constants +--------- + +.. data:: PIO.IN_LOW + PIO.IN_HIGH + PIO.OUT_LOW + PIO.OUT_HIGH + + These constants are used for the *out_init*, *set_init*, and *sideset_init* + arguments to `asm_pio`. + +.. data:: PIO.SHIFT_LEFT + PIO.SHIFT_RIGHT + + These constants are used for the *in_shiftdir* and *out_shiftdir* arguments + to `asm_pio` or `StateMachine.init`. + +.. data:: PIO.JOIN_NONE + PIO.JOIN_TX + PIO.JOIN_RX + + These constants are used for the *fifo_join* argument to `asm_pio`. + +.. data:: PIO.IRQ_SM0 + PIO.IRQ_SM1 + PIO.IRQ_SM2 + PIO.IRQ_SM3 + + These constants are used for the *trigger* argument to `PIO.irq`. + diff --git a/docs/library/rp2.StateMachine.rst b/docs/library/rp2.StateMachine.rst new file mode 100644 index 0000000000..8d73ccf772 --- /dev/null +++ b/docs/library/rp2.StateMachine.rst @@ -0,0 +1,131 @@ +.. currentmodule:: rp2 +.. _rp2.StateMachine: + +class StateMachine -- access to the RP2040's programmable I/O interface +======================================================================= + +The :class:`StateMachine` class gives access to the RP2040's PIO (programmable +I/O) interface. + +For assembling PIO programs, see :func:`rp2.asm_pio`. + + +Constructors +------------ + +.. class:: StateMachine(id, [program, ...]) + + Get the state machine numbered *id*. The RP2040 has two identical PIO + instances, each with 4 state machines: so there are 8 state machines in + total, numbered 0 to 7. + + Optionally initialize it with the given program *program*: see + `StateMachine.init`. + + +Methods +------- + +.. method:: StateMachine.init(program, freq=-1, *, in_base=None, out_base=None, set_base=None, jmp_pin=None, sideset_base=None, in_shiftdir=None, out_shiftdir=None, push_thresh=None, pull_thresh=None) + + Configure the state machine instance to run the given *program*. + + The program is added to the instruction memory of this PIO instance. If the + instruction memory already contains this program, then its offset is + re-used so as to save on instruction memory. + + - *freq* is the frequency in Hz to run the state machine at. Defaults to + the system clock frequency. + + The clock divider is computed as ``system clock frequency / freq``, so + there can be slight rounding errors. + + The minimum possible clock divider is one 65536th of the system clock: so + at the default system clock frequency of 125MHz, the minimum value of + *freq* is ``1908``. To run state machines at slower frequencies, you'll + need to reduce the system clock speed with `machine.freq()`. + - *in_base* is the first pin to use for ``in()`` instructions. + - *out_base* is the first pin to use for ``out()`` instructions. + - *set_base* is the first pin to use for ``set()`` instructions. + - *jmp_pin* is the first pin to use for ``jmp(pin, ...)`` instructions. + - *sideset_base* is the first pin to use for side-setting. + - *in_shiftdir* is the direction the ISR will shift, either + `PIO.SHIFT_LEFT` or `PIO.SHIFT_RIGHT`. + - *out_shiftdir* is the direction the OSR will shift, either + `PIO.SHIFT_LEFT` or `PIO.SHIFT_RIGHT`. + - *push_thresh* is the threshold in bits before auto-push or conditional + re-pushing is triggered. + - *pull_thresh* is the threshold in bits before auto-push or conditional + re-pushing is triggered. + +.. method:: StateMachine.active([value]) + + Gets or sets whether the state machine is currently running. + + >>> sm.active() + True + >>> sm.active(0) + False + +.. method:: StateMachine.restart() + + Restarts the state machine and jumps to the beginning of the program. + + This method clears the state machine's internal state using the RP2040's + ``SM_RESTART`` register. This includes: + + - input and output shift counters + - the contents of the input shift register + - the delay counter + - the waiting-on-IRQ state + - a stalled instruction run using `StateMachine.exec()` + +.. method:: StateMachine.exec(instr) + + Execute a single PIO instruction. Uses `asm_pio_encode` to encode the + instruction from the given string *instr*. + + >>> sm.exec("set(0, 1)") + +.. method:: StateMachine.get(buf=None, shift=0) + + Pull a word from the state machine's RX FIFO. + + If the FIFO is empty, it blocks until data arrives (i.e. the state machine + pushes a word). + + The value is shifted right by *shift* bits before returning, i.e. the + return value is ``word >> shift``. + +.. method:: StateMachine.put(value, shift=0) + + Push a word onto the state machine's TX FIFO. + + If the FIFO is full, it blocks until there is space (i.e. the state machine + pulls a word). + + The value is first shifted left by *shift* bits, i.e. the state machine + receives ``value << shift``. + +.. method:: StateMachine.rx_fifo() + + Returns the number of words in the state machine's RX FIFO. A value of 0 + indicates the FIFO is empty. + + Useful for checking if data is waiting to be read, before calling + `StateMachine.get()`. + +.. method:: StateMachine.tx_fifo() + + Returns the number of words in the state machine's TX FIFO. A value of 0 + indicates the FIFO is empty. + + Useful for checking if there is space to push another word using + `StateMachine.put()`. + +.. method:: StateMachine.irq(handler=None, trigger=0|1, hard=False) + + Returns the IRQ object for the given StateMachine. + + Optionally configure it. + diff --git a/docs/library/rp2.rst b/docs/library/rp2.rst new file mode 100644 index 0000000000..b6e7fcf429 --- /dev/null +++ b/docs/library/rp2.rst @@ -0,0 +1,83 @@ +.. currentmodule:: rp2 + +:mod:`rp2` --- functionality specific to the RP2040 +=================================================== + +.. module:: rp2 + :synopsis: functionality specific to the RP2 + +The ``rp2`` module contains functions and classes specific to the RP2040, as +used in the Raspberry Pi Pico. + +See the `RP2040 Python datasheet +`_ +for more information, and `pico-micropython-examples +`_ +for example code. + + +PIO related functions +--------------------- + +The ``rp2`` module includes functions for assembling PIO programs. + +For running PIO programs, see :class:`rp2.StateMachine`. + +.. function:: asm_pio(*, out_init=None, set_init=None, sideset_init=None, in_shiftdir=0, out_shiftdir=0, autopush=False, autopull=False, push_thresh=32, pull_thresh=32, fifo_join=PIO.JOIN_NONE) + + Assemble a PIO program. + + The following parameters control the initial state of the GPIO pins, as one + of `PIO.IN_LOW`, `PIO.IN_HIGH`, `PIO.OUT_LOW` or `PIO.OUT_HIGH`. If the + program uses more than one pin, provide a tuple, e.g. + ``out_init=(PIO.OUT_LOW, PIO.OUT_LOW)``. + + - *out_init* configures the pins used for ``out()`` instructions. + - *set_init* configures the pins used for ``set()`` instructions. There can + be at most 5. + - *sideset_init* configures the pins used side-setting. There can be at + most 5. + + The following parameters are used by default, but can be overriden in + `StateMachine.init()`: + + - *in_shiftdir* is the default direction the ISR will shift, either + `PIO.SHIFT_LEFT` or `PIO.SHIFT_RIGHT`. + - *out_shiftdir* is the default direction the OSR will shift, either + `PIO.SHIFT_LEFT` or `PIO.SHIFT_RIGHT`. + - *push_thresh* is the threshold in bits before auto-push or conditional + re-pushing is triggered. + - *pull_thresh* is the threshold in bits before auto-push or conditional + re-pushing is triggered. + + The remaining parameters are: + + - *autopush* configures whether auto-push is enabled. + - *autopull* configures whether auto-pull is enabled. + - *fifo_join* configures whether the 4-word TX and RX FIFOs should be + combined into a single 8-word FIFO for one direction only. The options + are `PIO.JOIN_NONE`, `PIO.JOIN_RX` and `PIO.JOIN_TX`. + +.. function:: asm_pio_encode(instr, sideset_count) + + Assemble a single PIO instruction. You usually want to use `asm_pio()` + instead. + + >>> rp2.asm_pio_encode("set(0, 1)", 0) + 57345 + +.. class:: PIOASMError + + This exception is raised from `asm_pio()` or `asm_pio_encode()` if there is + an error assembling a PIO program. + + +Classes +------- + +.. toctree:: + :maxdepth: 1 + + rp2.Flash.rst + rp2.PIO.rst + rp2.StateMachine.rst