From d9a56cfa194a577f156523e3eceb24ddca9e14db Mon Sep 17 00:00:00 2001 From: James Smith Date: Tue, 13 Jan 2026 16:38:36 -0800 Subject: [PATCH] Split out RF-BM-BG22C3 board config, define a Mini Receiver board --- .github/workflows/build.yml | 2 +- firmware/app/src/main.c | 65 ++++++++----------- firmware/boards/efr32xg22e.slcc | 3 +- firmware/boards/rf-bm-bg22c3.slcc | 42 ++---------- .../boards/wavephoenix-mini-receiver.slcc | 43 ++++++++++++ firmware/bootloader/README.md | 7 +- 6 files changed, 82 insertions(+), 80 deletions(-) create mode 100644 firmware/boards/wavephoenix-mini-receiver.slcc diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 069aa08..855bbf1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -19,7 +19,7 @@ jobs: strategy: matrix: - board: ["efr32xg22e", "rf-bm-bg22c3"] + board: ["efr32xg22e", "wavephoenix-mini-receiver"] steps: # Checkout repository and submodules diff --git a/firmware/app/src/main.c b/firmware/app/src/main.c index f2f862c..ebfbb4f 100644 --- a/firmware/app/src/main.c +++ b/firmware/app/src/main.c @@ -75,7 +75,7 @@ struct { // Joybus state static struct joybus_gecko joybus_gecko; -static struct joybus_gc_controller joybus_gc_controller; +static struct joybus_gc_controller wavebird_controller; static struct joybus *joybus = JOYBUS(&joybus_gecko); // Buttons, switches, and LEDs @@ -99,25 +99,6 @@ void SysTick_Handler(void) millis++; } -// Initialize (or reinitialize) as a controller on the SI bus -static void initialize_controller(uint8_t controller_type) -{ - switch (controller_type) { - case WP_CONT_TYPE_GC_WIRED: - joybus_gc_controller_init(&joybus_gc_controller, JOYBUS_GAMECUBE_CONTROLLER); - break; - case WP_CONT_TYPE_GC_WIRED_NOMOTOR: - joybus_gc_controller_init(&joybus_gc_controller, JOYBUS_GAMECUBE_CONTROLLER | JOYBUS_ID_GCN_NO_MOTOR); - break; - default: - printf("Unknown controller type '%d', defaulting to WaveBird", controller_type); - /* fall through */ - case WP_CONT_TYPE_GC_WAVEBIRD: - joybus_gc_controller_init(&joybus_gc_controller, JOYBUS_WAVEBIRD_RECEIVER); - break; - } -} - #if HAS_PAIR_BTN // Begin or end pairing when the pair button is pressed static void handle_pair_button_press() @@ -164,13 +145,13 @@ static void handle_wavebird_packet(const uint8_t *packet) // Check the controller id is as expected if (settings.cont_type == WP_CONT_TYPE_GC_WAVEBIRD) { // Implement wireless ID pinning exactly as OEM WaveBird receivers do - if (joybus_gc_controller_wireless_id_fixed(&joybus_gc_controller)) { + if (joybus_gc_controller_wireless_id_fixed(&wavebird_controller)) { // Drop packets from other controllers if the ID has been fixed - if (joybus_gc_controller_get_wireless_id(&joybus_gc_controller) != wireless_id) + if (joybus_gc_controller_get_wireless_id(&wavebird_controller) != wireless_id) return; } else { // Set the controller ID if it is not fixed - joybus_gc_controller_set_wireless_id(&joybus_gc_controller, wireless_id); + joybus_gc_controller_set_wireless_id(&wavebird_controller, wireless_id); } } else { // Emulate wireless ID pinning for wired controllers @@ -196,15 +177,15 @@ static void handle_wavebird_packet(const uint8_t *packet) // // Copy the buttons from the WaveBird message - joybus_gc_controller.input.buttons &= ~JOYBUS_GCN_BUTTON_MASK; - joybus_gc_controller.input.buttons |= + wavebird_controller.input.buttons &= ~JOYBUS_GCN_BUTTON_MASK; + wavebird_controller.input.buttons |= ((message[3] & 0x80) >> 7) | ((message[2] & 0x0F) << 1) | ((message[3] & 0x7F) << 8); // Copy the stick, substick, and trigger values - memcpy(&joybus_gc_controller.input.stick_x, &message[4], 6); + memcpy(&wavebird_controller.input.stick_x, &message[4], 6); // Set the input state as valid, and (re)set the validity timer - joybus_gc_controller_input_valid(&joybus_gc_controller, true); + joybus_gc_controller_input_valid(&wavebird_controller, true); input_valid_until = millis + INPUT_VALID_MS; } else { // @@ -216,7 +197,7 @@ static void handle_wavebird_packet(const uint8_t *packet) wavebird_origin_copy((uint8_t *)&new_origin.stick_x, message); // Update the origin state in the Joybus device - joybus_gc_controller_set_origin(&joybus_gc_controller, &new_origin); + joybus_gc_controller_set_origin(&wavebird_controller, &new_origin); } } @@ -260,9 +241,6 @@ static void handle_pairing_finished(uint8_t status, uint8_t channel) // Set the LED solid for 1 second to indicate pairing success if (status_led) led_effect_blink(status_led, 1000, 1); - - // Reset the controller - initialize_controller(settings.cont_type); } else if (status == WB_RADIO_PAIRING_TIMEOUT) { printf("Pairing timed out\n"); @@ -378,12 +356,25 @@ int main(void) wavebird_radio_set_channel(settings.chan); } + // Initialize the WaveBird controller target + switch (settings.cont_type) { + case WP_CONT_TYPE_GC_WIRED: + joybus_gc_controller_init(&wavebird_controller, JOYBUS_GAMECUBE_CONTROLLER); + break; + case WP_CONT_TYPE_GC_WIRED_NOMOTOR: + joybus_gc_controller_init(&wavebird_controller, JOYBUS_GAMECUBE_CONTROLLER | JOYBUS_ID_GCN_NO_MOTOR); + break; + default: + printf("Unknown controller type '%d', defaulting to WaveBird", settings.cont_type); + /* fall through */ + case WP_CONT_TYPE_GC_WAVEBIRD: + joybus_gc_controller_init(&wavebird_controller, JOYBUS_WAVEBIRD_RECEIVER); + break; + } + // Initialize Joybus joybus_gecko_init(&joybus_gecko, JOYBUS_PORT, JOYBUS_PIN, JOYBUS_TIMER, JOYBUS_USART); - joybus_target_register(joybus, JOYBUS_TARGET(&joybus_gc_controller)); - - // Register to handle controller SI commands - initialize_controller(settings.cont_type); + joybus_target_register(joybus, JOYBUS_TARGET(&wavebird_controller)); // Enable Joybus joybus_enable(joybus); @@ -405,7 +396,7 @@ int main(void) led_effect_update(status_led, millis); // Invalidate stale inputs - if (joybus_gc_controller.input_valid && (int32_t)(millis - input_valid_until) >= 0) - joybus_gc_controller_input_valid(&joybus_gc_controller, false); + if (wavebird_controller.input_valid && (int32_t)(millis - input_valid_until) >= 0) + joybus_gc_controller_input_valid(&wavebird_controller, false); } } diff --git a/firmware/boards/efr32xg22e.slcc b/firmware/boards/efr32xg22e.slcc index ed01b9a..9fc62f3 100644 --- a/firmware/boards/efr32xg22e.slcc +++ b/firmware/boards/efr32xg22e.slcc @@ -1,6 +1,5 @@ id: efr32xg22e -label: efr32xg22e -package: "ext-comp" +package: ext-comp description: WavePhoenix board support for EFR32xG22E category: External quality: production diff --git a/firmware/boards/rf-bm-bg22c3.slcc b/firmware/boards/rf-bm-bg22c3.slcc index 723f08c..fe6f0f6 100644 --- a/firmware/boards/rf-bm-bg22c3.slcc +++ b/firmware/boards/rf-bm-bg22c3.slcc @@ -1,46 +1,16 @@ id: rf-bm-bg22c3 -label: rf-bm-bg22c3 -package: "ext-comp" -description: WavePhoenix board support for RF-BM-BG22C3 +package: ext-comp +description: Board support for RF-BM-BG22C3 based boards category: External quality: production requires: - name: efr32bg22c224f512gm32 -define: - # Joybus configuration - - name: JOYBUS_PORT - value: gpioPortA - - name: JOYBUS_PIN - value: 2 - - name: JOYBUS_TIMER - value: TIMER1 - - name: JOYBUS_USART - value: USART0 - - # Pair button configuration - - name: HAS_PAIR_BTN - value: 1 - - name: PAIR_BTN_PORT - value: gpioPortB - - name: PAIR_BTN_PIN - value: 0 - - name: HAS_STATUS_LED - value: 1 +provides: + - name: rf-bm-bg22c3 - # Status LED configuration - - name: STATUS_LED_PORT - value: gpioPortC - - name: STATUS_LED_PIN - value: 1 - - name: STATUS_LED_INVERT - value: 0 +define: + # Crystal oscillator tuning - name: SL_CLOCK_MANAGER_HFXO_CTUNE value: 72 - - # Bootloader button configuration - - name: SL_BTL_BUTTON_PORT - value: gpioPortB - - name: SL_BTL_BUTTON_PIN - value: 0 diff --git a/firmware/boards/wavephoenix-mini-receiver.slcc b/firmware/boards/wavephoenix-mini-receiver.slcc new file mode 100644 index 0000000..b05b1ff --- /dev/null +++ b/firmware/boards/wavephoenix-mini-receiver.slcc @@ -0,0 +1,43 @@ +id: wavephoenix-mini-receiver +package: ext-comp +description: Board support for the WavePhoenix Mini Receiver +category: External +quality: production + +requires: + - name: rf-bm-bg22c3 + +define: + # Joybus configuration + - name: JOYBUS_PORT + value: gpioPortA + - name: JOYBUS_PIN + value: 2 + - name: JOYBUS_TIMER + value: TIMER1 + - name: JOYBUS_USART + value: USART0 + + # Pair button configuration + - name: HAS_PAIR_BTN + value: 1 + - name: PAIR_BTN_PORT + value: gpioPortB + - name: PAIR_BTN_PIN + value: 0 + + # Status LED configuration + - name: HAS_STATUS_LED + value: 1 + - name: STATUS_LED_PORT + value: gpioPortC + - name: STATUS_LED_PIN + value: 1 + - name: STATUS_LED_INVERT + value: 0 + + # Bootloader button configuration + - name: SL_BTL_BUTTON_PORT + value: gpioPortB + - name: SL_BTL_BUTTON_PIN + value: 0 \ No newline at end of file diff --git a/firmware/bootloader/README.md b/firmware/bootloader/README.md index a69e3f2..96626d9 100644 --- a/firmware/bootloader/README.md +++ b/firmware/bootloader/README.md @@ -47,10 +47,9 @@ If you are using a generic SWD debug probe, you can use OpenOCD to flash the boo 3. If this is your first time flashing this chip, you'll need to do a full device erase to unlock the debug interface: ```bash - openocd -f interface/cmsis-dap.cfg \ - -c "transport select swd" \ - -f target/efm32s2.cfg \ - -c "init; halt; efm32 mass_erase 0; exit" + openocd -f "interface/cmsis-dap.cfg" \ + -f "target/efm32s2.cfg" \ + -c "init; efm32s2_dci_device_erase; shutdown" ``` 4. Disconnect then reconnect the debug probe.