def assertAssemblesTo(self, source, expected): actual = adafruit_pioasm.assemble(source) expected_bin = [nice_opcode(x) for x in expected] actual_bin = [nice_opcode(x) for x in actual] self.assertEqual( expected_bin, actual_bin, f"Assembling {source!r}: Expected {expected_bin}, got {actual_bin}", )
def __init__(self, data, clock, strobe, n, *, num_strands=8, bpp=3, brightness=1.0, auto_write=True, pixel_order=None): if not _pin_directly_follows(data, clock): raise ValueError("clock pin must directly follow data pin") if not _pin_directly_follows(clock, strobe): raise ValueError("strobe pin must directly follow clock pin") if n % num_strands: raise ValueError("Length must be a multiple of num_strands") if not pixel_order: pixel_order = GRB if bpp == 3 else GRBW else: if isinstance(pixel_order, tuple): order_list = [RGBW[order] for order in pixel_order] pixel_order = "".join(order_list) super().__init__(n, brightness=brightness, byteorder=pixel_order, auto_write=auto_write) self._transposed = bytearray(bpp * n * 8 // num_strands) self._num_strands = num_strands self._sm = rp2pio.StateMachine( _assembled, frequency=800_000 * 52, init=adafruit_pioasm.assemble("set pindirs 7"), first_out_pin=data, out_pin_count=1, first_set_pin=data, set_pin_count=3, first_sideset_pin=clock, sideset_pin_count=2, auto_pull=True, out_shift_right=False, pull_threshold=8, )
class IncrementalEncoder: _state_look_up_table = array.array( "b", [ # Direction = 1 0, # 00 to 00 -1, # 00 to 01 +1, # 00 to 10 +2, # 00 to 11 +1, # 01 to 00 0, # 01 to 01 +2, # 01 to 10 -1, # 01 to 11 -1, # 10 to 00 +2, # 10 to 01 0, # 10 to 10 +1, # 10 to 11 +2, # 11 to 00 +1, # 11 to 01 -1, # 11 to 10 0, # 11 to 11 # Direction = 0 0, # 00 to 00 -1, # 00 to 01 +1, # 00 to 10 -2, # 00 to 11 +1, # 01 to 00 0, # 01 to 01 -2, # 01 to 10 -1, # 01 to 11 -1, # 10 to 00 -2, # 10 to 01 0, # 10 to 10 +1, # 10 to 11 -2, # 11 to 00 +1, # 11 to 01 -1, # 11 to 10 0, # 11 to 11 ], ) _sm_code = adafruit_pioasm.assemble(""" again: in pins, 2 mov x, isr jmp x!=y, push_data mov isr, null jmp again push_data: push mov y, x """) _sm_init = adafruit_pioasm.assemble("set y 31") def __init__(self, pin_a, pin_b): if not rp2pio.pins_are_sequential([pin_a, pin_b]): raise ValueError("Pins must be sequential") self._sm = rp2pio.StateMachine( self._sm_code, 160_000, init=self._sm_init, first_in_pin=pin_a, in_pin_count=2, pull_in_pin_up=0b11, in_shift_right=False, ) self._counter = 0 self._direction = 0 self._lut_index = 0 self._buffer = bytearray(1) def _update_state_machine(self, state): lut_index = self._lut_index | (state & 3) lut = self._state_look_up_table[lut_index] self._counter += lut if lut: self._direction = 1 if (lut > 0) else 0 self._lut_index = ((lut_index << 2) & 0b1100) | (self._direction << 4) def deinit(self): self._sm.deinit() @property def value(self): while self._sm.in_waiting: self._sm.readinto(self._buffer) self._update_state_machine(self._buffer[0]) return self._counter
s16 = array.array("H", [0] * 10000) # Capturing on the rising edge is the left PDM channel. To do right, swap the # side set values. # # push iffull means it'll push every 32 bits and noop otherwise. noblock causes # data to be dropped instead of stopping the clock. This allows the mic to warm # up before the readinto. program = """ .program pdmin .side_set 1 in pins 1 side 0b1 push iffull noblock side 0b0 """ assembled = adafruit_pioasm.assemble(program) sm = rp2pio.StateMachine( assembled, frequency=24000 * 2 * 32, first_in_pin=board.D12, first_sideset_pin=board.D11, auto_push=False, in_shift_right=True, push_threshold=32, ) # Give the mic a bit of time to warm up (thanks to our noblock.) time.sleep(0.1) print("starting read")
import board import rp2pio import adafruit_pioasm hello = """ .program hello loop: pull out pins, 1 ; This program uses a 'jmp' at the end to follow the example. However, ; in a many cases (including this one!) there is no jmp needed at the end ; and the default "wrap" behavior will automatically return to the "pull" ; instruction at the beginning. jmp loop """ assembled = adafruit_pioasm.assemble(hello) sm = rp2pio.StateMachine( assembled, frequency=2000, first_out_pin=board.LED, ) print("real frequency", sm.frequency) while True: sm.write(bytes((1, ))) time.sleep(0.5) sm.write(bytes((0, ))) time.sleep(0.5)
# SPDX-FileCopyrightText: 2021 Scott Shawcroft, written for Adafruit Industries # # SPDX-License-Identifier: MIT import rp2pio import board import time import adafruit_pioasm import digitalio squarewave = """ .program squarewave set pins 1 [1] ; Drive pin high and then delay for one cycle set pins 0 ; Drive pin low """ assembled = adafruit_pioasm.assemble(squarewave) sm = rp2pio.StateMachine(assembled, frequency=80, init=adafruit_pioasm.assemble("set pindirs 1"), first_set_pin=board.LED) print("real frequency", sm.frequency) time.sleep(120)
# SPDX-FileCopyrightText: 2021 Jeff Epler, written for Adafruit Industries # # SPDX-License-Identifier: MIT import rp2pio import adafruit_pioasm code = adafruit_pioasm.assemble(""" .program uart_rx_mini ; Minimum viable 8n1 UART receiver. Wait for the start bit, then sample 8 bits ; with the correct timing. ; IN pin 0 is mapped to the GPIO used as UART RX. ; Autopush must be enabled, with a threshold of 8. wait 0 pin 0 ; Wait for start bit set x, 7 [10] ; Preload bit counter, delay until eye of first data bit bitloop: ; Loop 8 times in pins, 1 ; Sample data jmp x-- bitloop [6] ; Each iteration is 8 cycles """) class RXUART: def __init__(self, pin, baudrate=9600): self.pio = rp2pio.StateMachine( code, first_in_pin=pin, frequency=8 * baudrate, auto_push=True,
def assemble_program(filename): with open(filename, "rt") as file: return assemble(file.read())
def create_state_machine(asm, freq, pin): assembled = adafruit_pioasm.assemble(asm) rp2pio.StateMachine(assembled, frequency = freq, first_set_pin = pin, exclusive_pin_use = False)
# Adapted from the example https://github.com/raspberrypi/pico-examples/tree/master/pio/pio_blink import array import time import board import rp2pio import adafruit_pioasm blink = adafruit_pioasm.assemble(""" .program blink pull block ; These two instructions take the blink duration out y, 32 ; and store it in y forever: mov x, y set pins, 1 ; Turn LED on lp1: jmp x-- lp1 ; Delay for (x + 1) cycles, x is a 32 bit number mov x, y set pins, 0 ; Turn LED off lp2: jmp x-- lp2 ; Delay for the same number of cycles again jmp forever ; Blink forever! """) while True: for freq in [5, 8, 30]: with rp2pio.StateMachine( blink, frequency=125_000_000, first_set_pin=board.LED, wait_for_txstall=False,
# SPDX-FileCopyrightText: 2021 Jeff Epler, written for Adafruit Industries # # SPDX-License-Identifier: MIT # # Adapted from the an example in Appendix C of RPi_PiPico_Digital_v10.pdf import time import board import rp2pio import adafruit_pioasm led_quarter_brightness = adafruit_pioasm.assemble( """ set pins, 0 [2] set pins, 1 """ ) led_half_brightness = adafruit_pioasm.assemble( """ set pins, 0 set pins, 1 """ ) led_full_brightness = adafruit_pioasm.assemble( """ set pins, 1 """ )
# are 2/3 duty cycle (~833ns). program = """ .program ws2812 .side_set 1 .wrap_target bitloop: out x 1 side 0 [1]; Side-set still takes place when instruction stalls jmp !x do_zero side 1 [1]; Branch on the bit we shifted out. Positive pulse do_one: jmp bitloop side 1 [1]; Continue driving high, for a long pulse do_zero: nop side 0 [1]; Or drive low, for a short pulse .wrap """ assembled = adafruit_pioasm.assemble(program) sm = rp2pio.StateMachine( assembled, frequency=800000 * 6, # 800khz * 6 clocks per bit init=adafruit_pioasm.assemble("set pindirs 1"), first_set_pin=board.D12, first_sideset_pin=board.D12, auto_pull=True, out_shift_right=False, pull_threshold=8, ) print("real frequency", sm.frequency) for i in range(100): sm.write(b"\x0a\x00\x00")
# SPDX-FileCopyrightText: 2021 Scott Shawcroft, written for Adafruit Industries # # SPDX-License-Identifier: MIT import time import rp2pio import board import adafruit_pioasm squarewave = """ .program squarewave set pins 1 ; Drive pin high and then delay for one cycle set pins 0 ; Drive pin low """ assembled = adafruit_pioasm.assemble(squarewave) sm = rp2pio.StateMachine( assembled, frequency=1000 * 2, first_set_pin=board.D13, ) print("real frequency", sm.frequency) time.sleep(120)