Skip to content

Instantly share code, notes, and snippets.

@n13i

n13i/main.py Secret

Last active December 10, 2022 07:11
Show Gist options
  • Save n13i/3256c9269badef6021778b8d4a66a617 to your computer and use it in GitHub Desktop.
Save n13i/3256c9269badef6021778b8d4a66a617 to your computer and use it in GitHub Desktop.
Communicate with N64 Controller using Raspberry Pi Pico with MicroPython
from rp2 import PIO, StateMachine, asm_pio
from machine import Pin
import time
dataPin = Pin(0) # GP0
@asm_pio(out_init=PIO.OUT_HIGH, set_init=PIO.OUT_HIGH, sideset_init=PIO.OUT_HIGH,
out_shiftdir=PIO.SHIFT_LEFT, pull_thresh=32, autopull=False,
in_shiftdir=PIO.SHIFT_LEFT, push_thresh=32, autopush=False)
def joybus_write_read():
# prepare for detect Controller Stop Bit
set(y, 0b1111)
# write data ------------------------
set(pindirs, 1).side(1) # 1:output
# 4 cycles loop
wrap_target()
pull(ifempty)
# to send Console Stop Bit, put 0xffffffff to osr
# normally osr has at least one 0 bit, so put(0xffffffff) to osr explicitly to stop
mov(x, invert(osr))
jmp(not_x, "send_stopbit")
out(pins, 1) # shift out from OSR
wrap()
# ------------------------
label("send_stopbit")
set(pins, 0)[3] # Console Stop Bit (1us LOW/>2us HIGH)
set(pindirs, 0) # 0:input
# if no controller connected, pin goes LOW here
# wait for falling edge
wait(0, pin, 0)
# ------------------------
# 4 cycles loop
label("readloop")
in_(pins, 1) # shift in
push(iffull)
# check Controller Stop Bit (2us LOW/>2us HIGH)
mov(x, isr)
jmp(x_not_y, "readloop")
label("end")
jmp("end")
def get_byte(in_bits):
# convert from lower 4 bits
# ex) 0001 0001 0001 0001 0001 0111 0001 0111
# (0) (0) (0) (0) (0) (1) (0) (1)
# -> 0x05 = 0b00000101
ib = in_bits
r = 0
for i in range(8):
r = r >> 1
if (ib & 0x0000000f) == 0b0111: # One
r = r | 0b10000000
ib = ib >> 4
print(f'>> {r:02x}: {in_bits:032b}')
return r
def get_bits(out_byte):
# convert from LSB
# ex) 0x12 = 0b00010010
# -> 0001 0001 0001 0111 0001 0001 0111 0001
ob = out_byte
r = 0
for i in range(8):
r = r << 4
if (ob & 0x80) == 0x80:
r = r | 0b0111 # One
else:
r = r | 0b0001 # Zero
ob = ob << 1
print(f'<< {out_byte:02x}: {r:032b}')
return r
def send_bits(sm, bits):
array = []
for a in bits:
array.append(get_bits(a))
array.append(0xffffffff) # Stop
for b in array:
sm.put(b)
def recv_bits(sm):
while sm.rx_fifo() > 0:
v = sm.get()
get_byte(v)
# 4MHz (0.25us/cycle)
sm = StateMachine(0, joybus_write_read, freq=4000000, set_base=dataPin,
sideset_base=dataPin, out_base=dataPin, in_base=dataPin)
sm.active(1)
while True:
print("send")
send_bits(sm, [0x01])
print("recv")
recv_bits(sm)
time.sleep_ms(100)
sm.restart()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment