MicroPython introduces a new @rp2.Asm_pio decorator and rp2.PIO class.
- The definition of the PIO program and the configuration of the state machine are divided into 2 logical parts:
1. Program definition, including how many pins are used and if they are in/out pins. This is defined in @rp2.asm_pio.
2. Program, which sets the frequency of the state machine and which pin to bind to. These parameters are set when a state machine is set up to run a specific program.
All program configuration (such as autopull) is done in the @asm_pio decorator. Only setting the frequency and base pins needs to be set in the StateMachine constructor.
@asm_pio
@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=0
)
- out_init: initialize the output pin
- set_init: set the pin initialization
- sideset_init: side set the pin initialization
- in_shiftdir: data input direction
- out_shiftdir: data output direction
- autopush: if it is enabled, ISR will be transmitted to RX-FIFO automatically when ISR has reached the threshold.
- autopull: if it is enabled, TX-FIFO will be transmitted to OSR automatically when OSR has reached the threshold.
- push_thresh: push threshold
- pull_thresh: pull threshold
- fifo_join: Fifo combination, specify a FIFO, close the other FIFO and add it to the FIFO to get a FIFO with deeper bits.
rp2.StateMachine Function
- rp2.StateMachine.init(sm_id ,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)
- sm_id: Use state machine ID
- program: PIO running program
- freq: the operating frequency of the state machine, the default is the system clock frequency,
- The distribution factor for the clock divider is calculated as "system clock frequency/frequency", so there may be slight rounding errors.
- The smallest possible clock divider is 1/65536 of the system clock: so at the default system clock frequency of 125MHz, the minimum is 1908.
- To run the state machine at a slower frequency, use "machine.freq()" to reduce the system clock speed.
- in_base: the first pin for the in() instruction
- out_base: the first pin for the out() instruction
- set_base: the first pin for the set() instruction
- jmp_pin: the first pin for the jmp(pin, …) instruction
- sideset_base: is the first pin for sideset.
- in_shiftdir: The direction in which the ISR will move, which can be PIO.SHIFT_LEFT or PIO.SHIFT_RIGHT
- out_shiftdir: The direction in which the OSR will move, which can be PIO.SHIFT_LEFT or PIO.SHIFT_RIGHT
- push_thresh: push threshold
- pull_thresh: pull threshold
- StateMachine.active([value])
- Gets or sets whether the state machine is currently running.
- When the value is not empty, set the state machine, otherwise get the running state.
- StateMachine.restart()
- Restart the state machine and jump to the beginning of the program.
- StateMachine.exec(instr)
- Execute a single PIO instruction. Use asm_pio_encode to encode instructions from the given string instr.
- StateMachine.get(buf=None, shift=0)
- Extract a word from the RX-FIFO of the state machine.
- If the FIFO is empty, it blocks until data arrives (ie the state machine pushes a word).
- shift is the number of shifts to the right before returning
- The return value is "word >> shift"
- StateMachine.put(value, shift=0)
- Push a word to the state machine's TX FIFO.
- If the FIFO is full, it blocks until there is room (i.e. the state machine pulls a word).
- shift is the number of shifts to the right before returning
- The return value is "word >> shift"
- StateMachine.rx_fifo()
- Returns the number of words in the state machine's RX FIFO. A value of 0 means the FIFO is empty.
- Used to check if data is waiting to be read before calling StateMachine.get().
- StateMachine.tx_fifo()
- Returns the number of words in the state machine's RX FIFO. A value of 0 means the FIFO is empty.
- Used to check if data is waiting to be read before calling StateMachine.put().
- StateMachine.irq(handler=None, trigger=0|1, hard=False)
- Returns an IRQ object for the given StateMachine.
PIO_ASM
1. target: Jump address, values 0-31 are allowed because PIO has only 32 instruction space. 2. condition :
- ! X OR !Y:
- X– OR Y–
- X!=Y :
- PIN :
- !(OSRE):
- The function of the JMP instruction is to jump the program to the specified address when certain conditions are met.
- When the condition is met, the program will jump to the specified address according to the target
Of course, you can also not fill in the conditions, and the specified address will be jumped unconditionally.
- WAIT Polarity Source Index
- Polarity: wait 0 OR 1
- Source: 1. GPIO: Absolute GPIO, 2. PIN: pin after pin mapping, 3. IRQ: Interrupt Flag
- Index: 1. GPIO_num: corresponding to GPIO source, GPIO value, 2. pin_num: corresponding to pin source, pin value, 3. IRQ_num: Corresponding to the IRQ source, specifying the waiting pin or bit, where IRQ_NUM also supports the use (_rel)
- The WAIT instruction acts to wait until the condition is met
- IN Source,Bitcount
- Source: 1. PINS, 2. X, 3. Y, 4. NULL, 5. ISR, 6. OSR
- Bitcount : the number of bits to read.
- The IN instruction functions to store data into the ISR register
- OUT destination,Bitcount
- destination: 1. PINS, 2. X, 3.Y, 4. NULL, 5. PINDIRS, 6. PC, 7. ISR, 8. OSR, 9. Bitcount : the number of bits to read.
- PUSH (IfFull) (Block/noBlock)
- IfFull, if it is 1, only the ISR can push the threshold when it reaches the threshold.
- Block, if it is 1 and the RX FIFO reaches the threshold, it will push the data to the ISR, otherwise it will wait for the RXFIO to reach the threshold. If it is 0, the RXFIFO will not reach the threshold, and it will not be pushed.
- The function of the PUSH instruction is to push the contents of the ISR to the RX FIFO and clear the ISR
- PULL (IfEmpty) (Block/noBlock)
- IfEmpty: If it is 1, only the OSR will receive the data of the TXFIFO.
- Block: 1, if the TXFIFO is empty, wait for the TXFIFO.
- The role of the PUSH instruction is to read data from the TXFIFO to the OSR register.
- MOV destinationmov,(Operation ),source
- destination: 1. PINS: output mapping, 2. X: 3. Y: 4. EXEC: decode register, 5. PC: PC register (JUM), 6. ISR, 7. EXEC:
- source: 1. PINS: 2. X, 3. Y, 4. NULL: empty, used for clearing, 5. STATUS: Indicates different states, such as fifo full or empty. 6. ISR: 7. OSR:
- Operation: 1. 00: No change, 2. 01: Bit inversion, 3. 10: Bit flip, high and low bits are swapped.
- The MOV instruction acts to move data from the source to the destination register.
- IRQ (option) irq_num (_rel)
- irq_num:0-7 Interrupt flag bit
- option: 1. set (default): set 2. nowait (default): do not wait for clearing, 3. wait: after waiting to clear, run, 4.clear: clear
- _rel: If it exists, add irq_num and state machine code sm_num and perform modulo four operation and set the high bit to 1. If state machine 2 sets interrupt flag 3, the interrupt value is 0X11
- irq_flag=(sm_id+irq_num) %4 + 0x10
- The IRQ instruction is used to set or clear the interrupt flag
- SET destination,data
- destination: destination address, 1. PINS :SET map pin, 2. PINDIRS: pin direction, map GPIO1 as output and 0 as input, 3. X : Temporary register, temporary data, 4. Y : Temporary storage register, temporary data storage
data : data, 0-31
- The set instruction will write data to the target address. Usually used to control the set map pin
Demo Address
This article is only for RP2040 MicroPython firmware, and the source code shall prevail. This article is written according to the official source code at the time of writing, which is used to provide convenience for beginners and is for reference only. Those who are capable are recommended to refer to MicroPython.