]> Repositories - Adafruit_Blinka-hackapet.git/blobdiff - src/adafruit_blinka/microcontroller/pico_u2if/pico_u2if.py
Moar pins
[Adafruit_Blinka-hackapet.git] / src / adafruit_blinka / microcontroller / pico_u2if / pico_u2if.py
index 97f699b875f05f83b0fc9f26129922205bec7bf9..687bfc033585b4212b5bd44945fee65c4140461f 100644 (file)
@@ -1,8 +1,13 @@
 """Chip Definition for Pico with u2if firmware"""
 # https://github.com/execuc/u2if
 
+import os
+import time
 import hid
 
+# Use to set delay between reset and device reopen. if negative, don't reset at all
+PICO_U2IF_RESET_DELAY = float(os.environ.get("PICO_U2IF_RESET_DELAY", 1))
+
 # pylint: disable=import-outside-toplevel,too-many-branches,too-many-statements
 # pylint: disable=too-many-arguments,too-many-function-args, too-many-public-methods
 
@@ -15,6 +20,7 @@ class Pico_u2if:
 
     # MISC
     RESP_OK = 0x01
+    SYS_RESET = 0x10
 
     # GPIO
     GPIO_INIT_PIN = 0x20
@@ -64,15 +70,11 @@ class Pico_u2if:
     PWM_SET_DUTY_NS = 0x36
     PWM_GET_DUTY_NS = 0x37
 
-    # UART
-    UART0_INIT = 0x50
-    UART0_DEINIT = 0x51
-    UART0_WRITE = 0x52
-    UART0_READ = 0x53
-
     def __init__(self):
         self._hid = hid.device()
         self._hid.open(Pico_u2if.VID, Pico_u2if.PID)
+        if PICO_U2IF_RESET_DELAY >= 0:
+            self._reset()
         self._i2c_index = None
         self._spi_index = None
         self._serial = None
@@ -90,6 +92,19 @@ class Pico_u2if:
             return self._hid.read(64)
         return None
 
+    def _reset(self):
+        self._hid_xfer(bytes([self.SYS_RESET]), False)
+        time.sleep(PICO_U2IF_RESET_DELAY)
+        start = time.monotonic()
+        while time.monotonic() - start < 5:
+            try:
+                self._hid.open(Pico_u2if.VID, Pico_u2if.PID)
+            except OSError:
+                time.sleep(0.1)
+                continue
+            return
+        raise OSError("Pico open error.")
+
     # ----------------------------------------------------------------
     # GPIO
     # ----------------------------------------------------------------
@@ -378,6 +393,8 @@ class Pico_u2if:
                 raise RuntimeError("Neopixel init error")
             self._neopixel_initialized = True
 
+        self._serial.reset_output_buffer()
+
         # write
         # command is done over HID
         remain_bytes = len(buf)
@@ -392,14 +409,24 @@ class Pico_u2if:
                     "Neopixel write error : too many pixel for the firmware."
                 )
             elif resp[2] == 0x02:
+                print(resp[0:10])
                 raise RuntimeError(
                     "Neopixel write error : transfer already in progress."
                 )
             else:
-                raise RuntimeError("Neopixel write error")
+                raise RuntimeError("Neopixel write error.")
         # buffer is sent over serial
         self._serial.write(buf)
+        # hack (see u2if)
+        if len(buf) % 64 == 0:
+            self._serial.write([0])
         self._serial.flush()
+        # polling loop to wait for write complete?
+        resp = self._hid.read(64)
+        while resp[0] != self.WS2812B_WRITE:
+            resp = self._hid.read(64)
+        if resp[1] != self.RESP_OK:
+            raise RuntimeError("Neopixel write (flush) error.")
 
     # ----------------------------------------------------------------
     # PWM