Trouble using I2C in CircuitPython (working MicroPython example)

I'm trying to write some code to run on a Pi Pico to interface with a SNES Mini controller & provide a normal gamepad output (HID device style).

So I finished the following MicroPython code before realising MicroPython (on the Pico) can't do any sort of HID device stuff:

import machine
import time
GAMEPAD_ADDR = 0x52
FREQ_MOD = 3
i2c = machine.I2C(0, scl=machine.Pin( 17), sda=machine.Pin(16), freq=int(100000 * FREQ_MOD))
i2c.writeto_mem(GAMEPAD_ADDR, 0x40, b'\x00')
time.sleep(0.05)
def reconnect(): i2c.writeto_mem(GAMEPAD_ADDR, 0x40, b'\x00') time.sleep(0.05 / FREQ_MOD)
while True: i2c.writeto(GAMEPAD_ADDR, b'\x00') time.sleep(0.05 / FREQ_MOD) data = i2c.readfrom(GAMEPAD_ADDR, 6) if (data[1] == 255): reconnect() else: dataA = 0x17 + (0x17 ^ data[4]) dataB = 0x17 + (0x17 ^ data[5]) if not (dataB & ~0b11111110): print("UP") if not (dataB & ~0b11111101): print("LEFT") if not (dataA & ~0b10111111): print("DOWN") if not (dataA & ~0b01111111): print("RIGHT") if not (dataA & ~0b11011111): print("L") if not (dataA & ~0b11111101): print("R") if not (dataB & ~0b11101111): print("A") if not (dataB & ~0b10111111): print("B") if not (dataB & ~0b11011111): print("Y") if not (dataB & ~0b11110111): print("X") if not (dataA & ~0b11101111): print("SELECT") if not (dataA & ~0b11111011): print("START")

Which isn't neat but it works, (the reconnect bit is a little weird not sure why it disconnects & needs the set up byte again), it'll print out whichever key is being pressed.

So far I've got the following CircuitPython code:

import time
import board
import busio
from adafruit_bus_device.i2c_device import I2CDevice
FREQ_MOD = 3
i2c = busio.I2C(board.GP17, board.GP16, frequency=30000)
while not i2c.try_lock(): pass
time.sleep(0.01)
print([hex(x) for x in i2c.scan()])
time.sleep(0.01)
data = bytearray(6)
i2c.writeto(0x52, bytes([0x40, 0x00]))
time.sleep(0.01)
while True: i2c.writeto_then_readfrom(0x52, bytes([0x00]), data, out_start=0) print(data) time.sleep(1)
i2c.deinit()

But I'm not able to do the setup bit correctly so it just keeps reading bytearray(b'\xff\xff\xff\xff\xff\xff').

I think I just need the CircuitPython equivalent to MicroPython's i2c.writeto_mem(0x52, 0x40, b'\x00') then I should be fine from there.

It could also be that the writeto_then_readfrom isn't equivalent to what's done in the MicroPython.

Thanks

1 Answer

Just worked it out immediately after posting - the writeto_then_readfrom isn't what I wanted to use.

while True: i2c.writeto(0x52, bytes([0x00])) time.sleep(0.01) i2c.readfrom_into(0x52, data) print(data) time.sleep(1)

This gets CircuitPython behaving in the way MicroPython was (but seemingly without the random disconnect, which is nice).

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like