usb_mount.h 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738
  1. // usb_mount.h -- dynamic USB mounting of ACTIVELY-CONNECTED controllers (emulated modes only).
  2. //
  3. // Problem: a puck can be bonded to several controllers but only some are powered on / linked at a time. The
  4. // emulated modes used to mount one USB HID gamepad per BONDED slot at boot, so the host saw phantom pads for
  5. // controllers that were off. This module makes the USB device present only the CONNECTED controllers, and
  6. // re-enumerate (NO MCU reboot -- RF links stay up) whenever that set changes.
  7. //
  8. // Model: a fixed pool of per-mode USB-slot objects (HID/XInput interfaces) is created ONCE at boot (locking
  9. // their TinyUSB instance indices). At any moment the k connected controllers are presented as a DENSE PREFIX
  10. // usbSlot 0..k-1 of that pool; usbSlot u is fed from bond slot g_usbToBond[u]. USB can't hold an interface
  11. // "gap", so the prefix is compacted -> player identity follows CONNECTION ORDER (a mid-set disconnect shifts
  12. // the rest down; a reconnect appends). Re-enumeration is debounced so an RF blip doesn't reshuffle.
  13. #pragma once
  14. #include <stdint.h>
  15. #include "bonds.h" // NSLOT
  16. // Active mount map. usbSlot (0..g_usbMountCount-1) -> bond slot; and the inverse for output-report routing.
  17. extern uint8_t g_usbMountCount; // # of currently-mounted (connected) controllers
  18. extern int8_t g_usbToBond[NSLOT]; // usbSlot -> bondSlot (-1 = unused)
  19. extern int8_t g_bondToUsb[NSLOT]; // bondSlot -> usbSlot (-1 = not mounted)
  20. // Enable the dynamic watcher for this boot (emulated modes call this; puck/lizard leave it off so their begin()
  21. // keeps the legacy behavior). maxSlots caps the mounted count to the mode's HID-instance budget (CFG_TUD_HID
  22. // minus the wake mouse, etc.). When disabled, usbMountTask() is a no-op.
  23. void usbMountEnable(bool on, uint8_t maxSlots);
  24. // Build g_usbToBond/g_bondToUsb + g_usbMountCount from the CURRENT connected set (bond-slot order). Called by
  25. // the boot enumerate and on every accepted change.
  26. void usbMountRebuildMap();
  27. // Per-loop watcher: detect a debounced change in the connected set and trigger usbReenumerate(k). No-op unless
  28. // dynamic mounting is enabled.
  29. void usbMountTask();
  30. // Provided by OpenPuck.ino: tear down + rebuild the USB config descriptor presenting `k` slot interfaces
  31. // (fixed interfaces -- WebUSB / wake mouse -- replayed too), then re-attach. NO MCU reboot. Call with the map
  32. // already rebuilt for k connected controllers.
  33. void usbReenumerate(uint8_t k);