125 lines
3.6 KiB
Python
125 lines
3.6 KiB
Python
|
import rp2
|
||
|
|
||
|
######################################################
|
||
|
## Define I2S PIO machines
|
||
|
## 16-bit slots, data
|
||
|
## read on falling edge of bit clock
|
||
|
######################################################
|
||
|
|
||
|
@rp2.asm_pio(sideset_init=[rp2.PIO.OUT_LOW]*2, fifo_join=rp2.PIO.JOIN_RX)
|
||
|
## bitclock and LR clock on the sidesets, respectively
|
||
|
def i2s_read_pio():
|
||
|
nop()[3] ## delay to sync up with write PIO -- empirically determined
|
||
|
wrap_target()
|
||
|
|
||
|
set(y,14) .side(0b00)[1] ## send 32 bits per LR read
|
||
|
label("L")
|
||
|
in_(pins, 1) .side(0b01)[1] ## Left, bits
|
||
|
jmp(y_dec, "L") .side(0b00)[1]
|
||
|
in_(pins, 1) .side(0b11)[1]
|
||
|
|
||
|
set(y,14) .side(0b10)[1]
|
||
|
label("R")
|
||
|
in_(pins,1) .side(0b11)[1] ## right, bits
|
||
|
jmp(y_dec, "R") .side(0b10)[1]
|
||
|
in_(pins,1) .side(0b01)
|
||
|
|
||
|
push(noblock) ## noblock keeps PIOs in sync
|
||
|
wrap()
|
||
|
|
||
|
## 10
|
||
|
|
||
|
@rp2.asm_pio(out_init=rp2.PIO.OUT_LOW, fifo_join=rp2.PIO.JOIN_TX)
|
||
|
## runs lockstep with read pio, spits out data when it's got it, zeros otherwise
|
||
|
def i2s_write_pio():
|
||
|
wrap_target()
|
||
|
|
||
|
pull(noblock) ## noblock keeps PIOs in sync
|
||
|
set(y,14) ## send 16 bits per LR clock
|
||
|
label("L")
|
||
|
out(pins,1) [1] ## Left, bits
|
||
|
jmp(y_dec, "L") [1]
|
||
|
out(pins,1) [1]
|
||
|
|
||
|
set(y,14) [1]
|
||
|
label("R")
|
||
|
out(pins,1) [1]
|
||
|
jmp(y_dec, "R") [1]
|
||
|
out(pins,1) [1]
|
||
|
wrap()
|
||
|
|
||
|
## 19
|
||
|
|
||
|
@rp2.asm_pio(in_shiftdir=1, out_shiftdir=1)
|
||
|
def bit_flipper_pio():
|
||
|
## takes in two 16-bit as signed/unsigned integers
|
||
|
## converts them by flipping MSBit of each 16-bitter
|
||
|
## tailored for reading X/Y channel from DAC and fitting
|
||
|
## the result on the (unsigned 8bit) screen
|
||
|
pull()
|
||
|
set(y,1)
|
||
|
label("twice")
|
||
|
|
||
|
in_(osr, 15) ## copy 15 LSB unchanged to output
|
||
|
out(null, 15) ## discard 15 bits from OSR to keep pace
|
||
|
|
||
|
mov(osr, invert(osr)) ## inverted what's left
|
||
|
in_(osr, 1) ## copy out one inverted bit
|
||
|
out(null, 1) ## drop that bit from OSR
|
||
|
mov(osr, invert(osr)) ## reinvert for the next word
|
||
|
|
||
|
jmp(y_dec, "twice")
|
||
|
push()
|
||
|
|
||
|
## 29
|
||
|
|
||
|
|
||
|
|
||
|
########################################################
|
||
|
## Pixel Pusher: Handle Screen Command
|
||
|
## Takes commands and data
|
||
|
## sends it to the screen pretty fast
|
||
|
## Format:
|
||
|
# 0 2A 0 X
|
||
|
# 0 2B 0 Y
|
||
|
# 0 2C C1 C2
|
||
|
## Screen expects 2A 0 X 0 X 2B 0 Y 0 Y 2C C1 C2
|
||
|
## with the commands framed by the DC line going low
|
||
|
## This PIO ignores the first byte,
|
||
|
## transmits the second, framed by DC,
|
||
|
## then doubles the second pair
|
||
|
## This means it actually transmits C1 C2 C1 C2, but
|
||
|
## the screen doesn't seem to care (hack, hack!)
|
||
|
########################################################
|
||
|
|
||
|
@rp2.asm_pio(out_init=rp2.PIO.OUT_LOW, set_init=rp2.PIO.OUT_HIGH,
|
||
|
sideset_init=rp2.PIO.OUT_LOW, autopull=True, autopush=True)
|
||
|
def handle_screen_command():
|
||
|
pull(block).side(0)
|
||
|
out(null, 8).side(0) ## drop initial zeros
|
||
|
|
||
|
set(pins, 0).side(0) ## DC set low, CMD mode
|
||
|
|
||
|
set(y,7).side(0) ## send 8 command bits
|
||
|
label("send_cmd")
|
||
|
out(pins, 1).side(0)
|
||
|
jmp(y_dec, "send_cmd").side(1)
|
||
|
|
||
|
set(pins, 1).side(0) ## DC set high, data mode
|
||
|
|
||
|
mov(x, osr).side(0) ## copy next bytes over, b/c going to send them twice
|
||
|
mov(osr, x).side(0) ## copy next bytes over, b/c going to send them twice
|
||
|
set(y,15).side(0) ## send 0, X
|
||
|
label("one_time")
|
||
|
out(pins, 1).side(0)
|
||
|
jmp(y_dec, "one_time").side(1)
|
||
|
|
||
|
mov(osr,x).side(0) ## copy bytes back
|
||
|
|
||
|
set(y,15).side(0) ## re-send 0, X
|
||
|
label("one_more_time")
|
||
|
out(pins, 1).side(0)
|
||
|
jmp(y_dec, "one_more_time").side(1)
|
||
|
|
||
|
# 16
|