Skip to content

Instantly share code, notes, and snippets.

@jepler
Created March 27, 2024 15:36
Show Gist options
  • Save jepler/cf582975546f1aa0039ed88d3a991c66 to your computer and use it in GitHub Desktop.
Save jepler/cf582975546f1aa0039ed88d3a991c66 to your computer and use it in GitHub Desktop.
import ulab
import digitalio
import rp2pio
import array
import board
import adafruit_pioasm
import picodvi
import displayio
vsync = 11
hsync = 10
vdata = board.D9
pixel_sync_out = board.D5
pixel_frequency = 10_694_250 # oddly specific
clocks_per_pixel = 10
fine_pixel = clocks_per_pixel // 4-1
if 0:
with digitalio.DigitalInOut(board.D11) as v:
print(sum(v.value for _ in range(100_000)))
with digitalio.DigitalInOut(board.D10) as v:
print(sum(v.value for _ in range(100_000)))
with digitalio.DigitalInOut(board.D9) as v:
print(sum(v.value for _ in range(100_000)))
displayio.release_displays()
dvi_pins = dict(
clk_dp=board.CKP,
clk_dn=board.CKN,
red_dp=board.D0P,
red_dn=board.D0N,
green_dp=board.D1P,
green_dn=board.D1N,
blue_dp=board.D2P,
blue_dn=board.D2N,
)
dvi = picodvi.Framebuffer(640, 480, **dvi_pins, color_depth=1)
active_lines = 240
blanking_lines = 18
active_pixels = 640
blanking_pixels = 48
total_lines = active_lines + blanking_lines
def instruction_gen():
yield total_lines - 2
for _ in range(blanking_lines):
yield from (1, 0) # 0 active pixels is special-cased
for _ in range(active_lines):
yield from (blanking_pixels - 1, active_pixels - 1)
instruction = array.array("L", instruction_gen())
print(instruction)
jmp_0 = adafruit_pioasm.Program("jmp 0")
program = adafruit_pioasm.Program(
f"""
.side_set 1
.wrap_target
out y, 32 ; get total line count
wait 0, pin 2
wait 1, pin 2 ; wait for vsync
wait_line_inactive:
out x, 32 ; get total line count
wait 0, pin 1
wait 1, pin 1; wait for hsync
wait_line_active:
nop [{clocks_per_pixel-2}]
jmp x--, wait_line_active ; count off non-active pixels
out x, 32 [{fine_pixel}] ; get line active pixels & perform fine pixel adjust
jmp !x, wait_line_inactive ; no pixels this line, wait next hsync
capture_active_pixels:
in pins, 1 side 1
jmp x--, capture_active_pixels [{clocks_per_pixel-2}] ; more pixels
jmp y--, wait_line_inactive ; more lines?
.wrap
"""
)
pio = rp2pio.StateMachine(
program.assembled,
frequency=pixel_frequency * clocks_per_pixel,
first_in_pin=vdata,
in_pin_count=3,
#in_pin_pull_up=True,
first_sideset_pin=pixel_sync_out,
auto_pull=True,
pull_threshold=32,
auto_push=True,
push_threshold=32,
offset=0,
**program.pio_kwargs,
)
one_row = 640 // 32
buf = memoryview(dvi).cast('L')[:one_row * active_lines]
ulab.numpy.frombuffer(dvi, dtype=ulab.numpy.uint8)[:] = 0
print(len(buf))
b = array.array('L', [0])
fno = 0
while True:
fno += 1
# if fno % 100 == 0:
print(fno)
pio.run(jmp_0.assembled)
pio.clear_rxfifo()
pio.write_readinto(instruction, buf)
#pio.write(instruction)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment