# %%micropython
# Example using PIO to create a UART TX interface
from machine import Pin
from rp2 import PIO, StateMachine, asm_pio
# remove all programs from both PIOs
for n in (0, 1):
pio = PIO(n)
pio.remove_program()
# -----------------------------------------------
# Wiring scema for the DMX TX
pin_dmx_tx = Pin(15, Pin.OUT)
pin_dmx_rx = Pin(14, Pin.IN)
# Minimum universe length is ~5 channels / slots
@asm_pio(
set_init=PIO.OUT_LOW,
sideset_init=PIO.OUT_LOW,
out_init=PIO.OUT_LOW,
autopull=True, # ?
out_shiftdir=PIO.SHIFT_LEFT, # ?
)
# fmt: off
def dmx_send():
BREAK_LOOPS = 23
# Assert break condition
# Sender DMX break signal is 92us >, so we need to loop at least 92 / 8 = 12 times
# TODO: Actually should be at least 92us
set(x, 21) .side(0) # Preload bit counter, assert break condition for 176us
label("breakloop") # Loop X times, each loop iteration is 8 cycles.
jmp(x_dec, "breakloop") [7] # Each loop iteration is 8 cycles.
# Assert start condition
nop() [7] .side(1) # Assert MAB. 8 cycles nop and 8 cycles stop-bits = 16us
# Send data frame
wrap_target()
pull() .side(1) [7] # Assert 2 stop bits, or stall with line in idle state
set(x, 7) .side(0) [3] # load bit counter, assert start bit for 4 clocks
label("bitloop")
out(pins, 1) # Shift 1 bit from OSR to the first OUT pin
jmp(x_dec, "bitloop") .side(0) [2] # Each loop iteration is 4 cycles.
wrap()
# fmt: on
# Usage example
sm_dmx_tx = StateMachine(
0,
dmx_send,
freq=1_000_000,
set_base=pin_dmx_tx,
out_base=pin_dmx_tx,
sideset_base=pin_dmx_tx,
)
size = 8
print(size)
universe = bytearray(1 + size) # 1 start code + 512 channels
# set all channels to 0
for i in range(len(universe)):
universe[i] = 200
# for i in range(len(universe)):
# universe[i] = i % 256
sm_dmx_tx.active(1)
import time
while 1:
sm_dmx_tx.active(0)
sm_dmx_tx.restart()
sm_dmx_tx.active(1)
sm_dmx_tx.put(universe)
print("...")
time.sleep(0.1)