Ejemplo n.º 1
0
 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}",
     )
Ejemplo n.º 2
0
    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,
        )
Ejemplo n.º 3
0
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")
Ejemplo n.º 5
0
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)
Ejemplo n.º 7
0
# 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,
Ejemplo n.º 8
0
def assemble_program(filename):
    with open(filename, "rt") as file:
        return assemble(file.read())
Ejemplo n.º 9
0
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)
Ejemplo n.º 10
0
# 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,
Ejemplo n.º 11
0
# 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
"""
)
Ejemplo n.º 12
0
# 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")
Ejemplo n.º 13
0
# 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)