| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- // PicoPuck main — core0 cooperative loop.
- //
- // Presents either the Valve puck (Steam/Lizard) or an emulated controller
- // (Xbox/Switch/PS5/PS3/…) over USB, fed by controllers connected over Bluetooth.
- // The active mode is loaded from flash at boot; switching it persists + reboots.
- //
- // SPDX-License-Identifier: AGPL-3.0-or-later
- #include "config/picopuck_config.h"
- #include "config/modes.h"
- #include "puck/identity.h"
- #include "puck/slots.h"
- #include "puck/personality.h"
- #include "puck/emu_present.h"
- #include "puck/xinput.h"
- #include "usb_mount.h"
- #include "usb/usb_tx.h"
- #include "usb/usb_descriptors.h"
- #include "usb/webusb.h"
- #include "bt/bt_host.h"
- #include "sys/settings.h"
- #include "pico/stdlib.h"
- #include "pico/cyw43_arch.h"
- #include "hardware/watchdog.h"
- #include "tusb.h"
- int main(void)
- {
- stdio_init_all();
- settings_load(); // active USB mode (before descriptors)
- identity_init();
- slots_init();
- puck_personality_init();
- webusb_init();
- // Build the descriptor set for the active mode, then start USB.
- usb_descriptors_init();
- tud_init(0);
- bool puck = mode_is_puck(settings_mode());
- bool xinput = mode_is_xinput(settings_mode());
- // HID emulated modes present one gamepad per CONNECTED controller, mounted /
- // unmounted dynamically (no reboot) — same behaviour as OpenPuck. Puck and
- // XInput modes keep their fixed interface layout.
- if (!puck && !xinput)
- usb_mount_enable(true, PP_NSLOT);
- // The user LED hangs off the CYW43 chip; this init also hands the radio to
- // BTstack (btstack_cyw43_init on the async_context).
- bool have_radio = (cyw43_arch_init() == 0);
- bool have_bt = have_radio && bt_host_init();
- printf("\n[picopuck] boot commit=%s board=%d mode=%d radio=%d bt=%d\n",
- PICOPUCK_GIT_COMMIT, PP_BOARD, settings_mode(), have_radio,
- have_bt);
- watchdog_enable(PP_WATCHDOG_MS, /*pause_on_debug=*/true);
- absolute_time_t next_led = make_timeout_time_ms(PP_STATUS_LED_MS);
- bool led_on = false;
- while (1) {
- tud_task(); // USB device events
- usb_tx_pump(); // drain queued HID reports
- if (puck)
- puck_personality_task(); // puck 0x79 / 0x7B / 0x43 + synth stream
- else if (xinput)
- xinput_task(); // Xbox 360 XInput report stream
- else
- emu_present_task(); // emulated controller report stream
- usb_mount_task(); // dynamic mount/unmount on connect/disconnect (emu modes)
- webusb_task(); // panel commands (works in every mode)
- if (have_bt) {
- cyw43_arch_poll(); // services BTstack on its async_context
- bt_host_task(); // scan / battery / rssi / rumble
- } else if (have_radio) {
- cyw43_arch_poll();
- }
- if (absolute_time_diff_us(get_absolute_time(), next_led) <= 0) {
- led_on = !led_on;
- if (have_radio)
- cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN,
- led_on);
- next_led = make_timeout_time_ms(PP_STATUS_LED_MS);
- }
- watchdog_update();
- }
- return 0;
- }
|