summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSaulo VerĂ­ssimo <[email protected]>2026-04-07 23:46:10 -0300
committerSaulo VerĂ­ssimo <[email protected]>2026-05-12 11:07:45 -0300
commitb4880761bcadbee86d047e0a3b329859926caad5 (patch)
tree3be71a7713aa1c51625249242cf13b41faef461c
parentc4847006dbb7565b71055837103ec788c4cb6fee (diff)
refactor: replace midi2_host (Waveshare) with midi2_host_feather
Remove the Waveshare RP2350-USB-A host example and board definition. The Feather RP2040 USB Host is the TinyUSB reference board for PIO-USB host and does not require the CFG_TUSB_DEBUG workaround needed by the Waveshare (R13 pull-up issue). One host example is sufficient for the PR. The Feather variant has an improved display with splash, spinner, and 6-line live view.
-rw-r--r--examples/host/CMakeLists.txt2
-rw-r--r--examples/host/midi2_host/CMakeLists.txt38
-rw-r--r--examples/host/midi2_host/Makefile27
-rw-r--r--examples/host/midi2_host/src/display.c221
-rw-r--r--examples/host/midi2_host/src/display.h54
-rw-r--r--examples/host/midi2_host/src/font5x7.h107
-rw-r--r--examples/host/midi2_host/src/main.c326
-rw-r--r--examples/host/midi2_host/src/tusb_config.h91
-rw-r--r--hw/bsp/rp2040/boards/waveshare_rp2350_usb_a/board.cmake2
-rw-r--r--hw/bsp/rp2040/boards/waveshare_rp2350_usb_a/board.h49
10 files changed, 1 insertions, 916 deletions
diff --git a/examples/host/CMakeLists.txt b/examples/host/CMakeLists.txt
index 7c74e3c73..2cf2c10af 100644
--- a/examples/host/CMakeLists.txt
+++ b/examples/host/CMakeLists.txt
@@ -13,7 +13,7 @@ set(EXAMPLE_LIST
device_info
hid_controller
midi_rx
- midi2_host
+ midi2_host_feather
msc_file_explorer
msc_file_explorer_freertos
)
diff --git a/examples/host/midi2_host/CMakeLists.txt b/examples/host/midi2_host/CMakeLists.txt
deleted file mode 100644
index cd70d122a..000000000
--- a/examples/host/midi2_host/CMakeLists.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-cmake_minimum_required(VERSION 3.20)
-
-include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-
-project(midi2_host C CXX ASM)
-
-family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
-
-# This example requires PIO-USB and Pico SDK (I2C, SSD1306 display)
-if(NOT FAMILY STREQUAL "rp2040")
- return()
-endif()
-
-add_executable(${PROJECT_NAME})
-
-target_sources(${PROJECT_NAME} PUBLIC
- ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
- ${CMAKE_CURRENT_SOURCE_DIR}/src/display.c
-)
-
-target_include_directories(${PROJECT_NAME} PUBLIC
- ${CMAKE_CURRENT_SOURCE_DIR}/src
-)
-
-family_configure_host_example(${PROJECT_NAME} noos)
-
-# Waveshare RP2350-USB-A: PIO-USB on GP12/GP13
-target_compile_definitions(${PROJECT_NAME} PRIVATE
- PIO_USB_DP_PIN_DEFAULT=12
-)
-target_compile_options(${PROJECT_NAME} PRIVATE
- -Wno-type-limits
-)
-
-# SSD1306 display (I2C)
-target_link_libraries(${PROJECT_NAME} PUBLIC
- hardware_i2c
-)
diff --git a/examples/host/midi2_host/Makefile b/examples/host/midi2_host/Makefile
deleted file mode 100644
index 2b4660516..000000000
--- a/examples/host/midi2_host/Makefile
+++ /dev/null
@@ -1,27 +0,0 @@
-# This example requires RP2040/RP2350 (PIO-USB, Pico SDK I2C, SSD1306 display)
-ifeq (,$(findstring rp2040,$(FAMILY)))
-$(info Skipping midi2_host: requires FAMILY=rp2040)
-all:
- @:
-.DEFAULT:
- @:
-else
-
-include ../../../hw/bsp/family_support.mk
-
-INC += \
- src \
-
-# Example source
-EXAMPLE_SOURCE += \
- src/main.c \
- src/display.c \
-
-SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE))
-
-# Suppress pre-existing warning
-CFLAGS_GCC += -Wno-type-limits
-
-include ../../../hw/bsp/family_rules.mk
-
-endif
diff --git a/examples/host/midi2_host/src/display.c b/examples/host/midi2_host/src/display.c
deleted file mode 100644
index 4745c2961..000000000
--- a/examples/host/midi2_host/src/display.c
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2026 Saulo Verissimo
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-// SSD1306 OLED display driver (128x64, I2C) for MIDI 2.0 Host example.
-// Minimal text-only implementation, no graphics library.
-// I2C0: SDA = GP4, SCL = GP5, Address = 0x3C
-
-#include "display.h"
-#include <stdio.h>
-#include <string.h>
-#include "pico/stdlib.h"
-#include "hardware/i2c.h"
-#include "hardware/gpio.h"
-
-#define I2C_PORT i2c0
-#define I2C_SDA 4
-#define I2C_SCL 5
-#define I2C_FREQ 400000
-#define SSD1306_ADDR 0x3C
-
-#define SCR_W 128
-#define SCR_H 64
-#define PAGES (SCR_H / 8) // 8 pages
-#define CHARS_PER_LINE 21 // 128 / 6 = 21 chars
-
-// Framebuffer
-static uint8_t fb[SCR_W * PAGES];
-
-// Log buffer
-#define LOG_LINES 3
-static char log_lines[LOG_LINES][CHARS_PER_LINE + 1];
-static int log_count = 0;
-
-// Status line
-static char status_text[CHARS_PER_LINE + 1] = "";
-
-//--------------------------------------------------------------------+
-// Minimal 5x7 font (ASCII 32-126)
-//--------------------------------------------------------------------+
-#include "font5x7.h"
-
-//--------------------------------------------------------------------+
-// SSD1306 I2C commands
-//--------------------------------------------------------------------+
-
-static void ssd_cmd(uint8_t cmd) {
- uint8_t buf[2] = { 0x00, cmd }; // Co=0, D/C=0
- i2c_write_blocking(I2C_PORT, SSD1306_ADDR, buf, 2, false);
-}
-
-static void ssd_data(const uint8_t* data, size_t len) {
- uint8_t buf[SCR_W + 1];
- buf[0] = 0x40; // Co=0, D/C=1
- size_t chunk = (len > SCR_W) ? SCR_W : len;
- memcpy(buf + 1, data, chunk);
- i2c_write_blocking(I2C_PORT, SSD1306_ADDR, buf, chunk + 1, false);
-}
-
-static void ssd_flush(void) {
- ssd_cmd(0x21); ssd_cmd(0); ssd_cmd(127); // Column range
- ssd_cmd(0x22); ssd_cmd(0); ssd_cmd(7); // Page range
- for (int page = 0; page < PAGES; page++) {
- ssd_data(&fb[page * SCR_W], SCR_W);
- }
-}
-
-//--------------------------------------------------------------------+
-// Framebuffer drawing
-//--------------------------------------------------------------------+
-
-static void fb_clear(void) {
- memset(fb, 0, sizeof(fb));
-}
-
-static void fb_char(int x, int y, char c) {
- if (c < 32 || c > 126) c = '?';
- const uint8_t* glyph = font5x7 + (c - 32) * 5;
- int page = y / 8;
- int bit_offset = y % 8;
-
- if (page >= PAGES || x + 5 > SCR_W) return;
-
- for (int col = 0; col < 5; col++) {
- uint8_t column_data = glyph[col];
- fb[(page * SCR_W) + x + col] |= (uint8_t)(column_data << bit_offset);
- if (bit_offset > 0 && page + 1 < PAGES) {
- fb[((page + 1) * SCR_W) + x + col] |= (uint8_t)(column_data >> (8 - bit_offset));
- }
- }
-}
-
-static void fb_string(int x, int y, const char* str) {
- while (*str) {
- fb_char(x, y, *str);
- x += 6;
- if (x + 6 > SCR_W) break;
- str++;
- }
-}
-
-//--------------------------------------------------------------------+
-// Display API
-//--------------------------------------------------------------------+
-
-void display_init(void) {
- i2c_init(I2C_PORT, I2C_FREQ);
- gpio_set_function(I2C_SDA, GPIO_FUNC_I2C);
- gpio_set_function(I2C_SCL, GPIO_FUNC_I2C);
- gpio_pull_up(I2C_SDA);
- gpio_pull_up(I2C_SCL);
-
- sleep_ms(100);
-
- // SSD1306 init sequence
- ssd_cmd(0xAE); // Display off
- ssd_cmd(0xD5); ssd_cmd(0x80); // Clock div
- ssd_cmd(0xA8); ssd_cmd(0x3F); // Multiplex 64
- ssd_cmd(0xD3); ssd_cmd(0x00); // Display offset
- ssd_cmd(0x40); // Start line 0
- ssd_cmd(0x8D); ssd_cmd(0x14); // Charge pump on
- ssd_cmd(0x20); ssd_cmd(0x00); // Horizontal addressing
- ssd_cmd(0xA1); // Segment remap
- ssd_cmd(0xC8); // COM scan direction
- ssd_cmd(0xDA); ssd_cmd(0x12); // COM pins
- ssd_cmd(0x81); ssd_cmd(0xCF); // Contrast
- ssd_cmd(0xD9); ssd_cmd(0xF1); // Pre-charge
- ssd_cmd(0xDB); ssd_cmd(0x40); // VCOMH deselect
- ssd_cmd(0xA4); // Display from RAM
- ssd_cmd(0xA6); // Normal display
- ssd_cmd(0xAF); // Display on
-
- fb_clear();
- fb_string(0, 0, "MIDI 2.0 Host");
- ssd_flush();
-}
-
-void display_checklist_update(const checklist_t* ck) {
- struct { const char* label; bool ok; } items[] = {
- { "PWR", ck->pwr_on },
- { "TinyUSB", ck->tusb_init },
- { "USB bus", ck->bus_active },
- { "Device", ck->device_connected },
- { "Descript", ck->descriptor_parsed },
- { "Alt1 UMP", ck->alt_setting_ok },
- { "Mount", ck->mounted },
- { "RX UMP", ck->receiving },
- };
-
- // Clear checklist area (lines 1-4, two columns)
- for (int p = 1; p <= 4; p++) {
- memset(&fb[p * SCR_W], 0, SCR_W);
- }
-
- for (int i = 0; i < 8; i++) {
- int col = (i < 4) ? 0 : 64;
- int row = (i < 4) ? i : i - 4;
- int y = 9 + row * 8;
- char line[12];
- snprintf(line, sizeof(line), "%s %s", items[i].ok ? "OK" : "..", items[i].label);
- fb_string(col, y, line);
- }
-
- ssd_flush();
-}
-
-void display_log(const char* text, uint16_t color) {
- (void)color; // SSD1306 is monochrome
-
- if (log_count >= LOG_LINES) {
- for (int i = 0; i < LOG_LINES - 1; i++) {
- strncpy(log_lines[i], log_lines[i + 1], CHARS_PER_LINE);
- log_lines[i][CHARS_PER_LINE] = '\0';
- }
- log_count = LOG_LINES - 1;
- }
-
- strncpy(log_lines[log_count], text, CHARS_PER_LINE);
- log_lines[log_count][CHARS_PER_LINE] = '\0';
- log_count++;
-
- // Draw log area (pages 5-6, y=40-55)
- memset(&fb[5 * SCR_W], 0, SCR_W);
- memset(&fb[6 * SCR_W], 0, SCR_W);
-
- for (int i = 0; i < log_count && i < LOG_LINES; i++) {
- fb_string(0, 41 + i * 8, log_lines[i]);
- }
-
- ssd_flush();
-}
-
-void display_status(const char* text) {
- strncpy(status_text, text, CHARS_PER_LINE);
- status_text[CHARS_PER_LINE] = '\0';
-
- // Status on last page (y=56)
- memset(&fb[7 * SCR_W], 0, SCR_W);
- fb_string(0, 56, status_text);
- ssd_flush();
-}
diff --git a/examples/host/midi2_host/src/display.h b/examples/host/midi2_host/src/display.h
deleted file mode 100644
index a8b0a4b5e..000000000
--- a/examples/host/midi2_host/src/display.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2026 Saulo Verissimo
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef DISPLAY_H_
-#define DISPLAY_H_
-
-#include <stdint.h>
-#include <stdbool.h>
-
-typedef struct {
- bool pwr_on;
- bool tusb_init;
- bool bus_active;
- bool device_connected;
- bool descriptor_parsed;
- bool alt_setting_ok;
- bool mounted;
- bool receiving;
-} checklist_t;
-
-// Initialize SSD1306 display (I2C on GP4/GP5)
-void display_init(void);
-
-// Redraw the checklist area (top portion)
-void display_checklist_update(const checklist_t* ck);
-
-// Add a line to the scrolling log area
-void display_log(const char* text, uint16_t color);
-
-// Update the status bar (bottom line)
-void display_status(const char* text);
-
-#endif
diff --git a/examples/host/midi2_host/src/font5x7.h b/examples/host/midi2_host/src/font5x7.h
deleted file mode 100644
index e515faac1..000000000
--- a/examples/host/midi2_host/src/font5x7.h
+++ /dev/null
@@ -1,107 +0,0 @@
-// Minimal 5x7 font, ASCII 32-126. Public domain.
-// 5 bytes per character (5 columns, 7 rows, LSB=top row)
-
-#ifndef FONT5X7_H_
-#define FONT5X7_H_
-
-#include <stdint.h>
-
-static const uint8_t font5x7[] = {
- 0x00,0x00,0x00,0x00,0x00, // 32 (space)
- 0x00,0x00,0x5F,0x00,0x00, // 33 !
- 0x00,0x07,0x00,0x07,0x00, // 34 "
- 0x14,0x7F,0x14,0x7F,0x14, // 35 #
- 0x24,0x2A,0x7F,0x2A,0x12, // 36 $
- 0x23,0x13,0x08,0x64,0x62, // 37 %
- 0x36,0x49,0x55,0x22,0x50, // 38 &
- 0x00,0x05,0x03,0x00,0x00, // 39 '
- 0x00,0x1C,0x22,0x41,0x00, // 40 (
- 0x00,0x41,0x22,0x1C,0x00, // 41 )
- 0x08,0x2A,0x1C,0x2A,0x08, // 42 *
- 0x08,0x08,0x3E,0x08,0x08, // 43 +
- 0x00,0x50,0x30,0x00,0x00, // 44 ,
- 0x08,0x08,0x08,0x08,0x08, // 45 -
- 0x00,0x60,0x60,0x00,0x00, // 46 .
- 0x20,0x10,0x08,0x04,0x02, // 47 /
- 0x3E,0x51,0x49,0x45,0x3E, // 48 0
- 0x00,0x42,0x7F,0x40,0x00, // 49 1
- 0x42,0x61,0x51,0x49,0x46, // 50 2
- 0x21,0x41,0x45,0x4B,0x31, // 51 3
- 0x18,0x14,0x12,0x7F,0x10, // 52 4
- 0x27,0x45,0x45,0x45,0x39, // 53 5
- 0x3C,0x4A,0x49,0x49,0x30, // 54 6
- 0x01,0x71,0x09,0x05,0x03, // 55 7
- 0x36,0x49,0x49,0x49,0x36, // 56 8
- 0x06,0x49,0x49,0x29,0x1E, // 57 9
- 0x00,0x36,0x36,0x00,0x00, // 58 :
- 0x00,0x56,0x36,0x00,0x00, // 59 ;
- 0x00,0x08,0x14,0x22,0x41, // 60 <
- 0x14,0x14,0x14,0x14,0x14, // 61 =
- 0x41,0x22,0x14,0x08,0x00, // 62 >
- 0x02,0x01,0x51,0x09,0x06, // 63 ?
- 0x32,0x49,0x79,0x41,0x3E, // 64 @
- 0x7E,0x11,0x11,0x11,0x7E, // 65 A
- 0x7F,0x49,0x49,0x49,0x36, // 66 B
- 0x3E,0x41,0x41,0x41,0x22, // 67 C
- 0x7F,0x41,0x41,0x22,0x1C, // 68 D
- 0x7F,0x49,0x49,0x49,0x41, // 69 E
- 0x7F,0x09,0x09,0x01,0x01, // 70 F
- 0x3E,0x41,0x41,0x51,0x32, // 71 G
- 0x7F,0x08,0x08,0x08,0x7F, // 72 H
- 0x00,0x41,0x7F,0x41,0x00, // 73 I
- 0x20,0x40,0x41,0x3F,0x01, // 74 J
- 0x7F,0x08,0x14,0x22,0x41, // 75 K
- 0x7F,0x40,0x40,0x40,0x40, // 76 L
- 0x7F,0x02,0x04,0x02,0x7F, // 77 M
- 0x7F,0x04,0x08,0x10,0x7F, // 78 N
- 0x3E,0x41,0x41,0x41,0x3E, // 79 O
- 0x7F,0x09,0x09,0x09,0x06, // 80 P
- 0x3E,0x41,0x51,0x21,0x5E, // 81 Q
- 0x7F,0x09,0x19,0x29,0x46, // 82 R
- 0x46,0x49,0x49,0x49,0x31, // 83 S
- 0x01,0x01,0x7F,0x01,0x01, // 84 T
- 0x3F,0x40,0x40,0x40,0x3F, // 85 U
- 0x1F,0x20,0x40,0x20,0x1F, // 86 V
- 0x7F,0x20,0x18,0x20,0x7F, // 87 W
- 0x63,0x14,0x08,0x14,0x63, // 88 X
- 0x03,0x04,0x78,0x04,0x03, // 89 Y
- 0x61,0x51,0x49,0x45,0x43, // 90 Z
- 0x00,0x00,0x7F,0x41,0x41, // 91 [
- 0x02,0x04,0x08,0x10,0x20, // 92 backslash
- 0x41,0x41,0x7F,0x00,0x00, // 93 ]
- 0x04,0x02,0x01,0x02,0x04, // 94 ^
- 0x40,0x40,0x40,0x40,0x40, // 95 _
- 0x00,0x01,0x02,0x04,0x00, // 96 `
- 0x20,0x54,0x54,0x54,0x78, // 97 a
- 0x7F,0x48,0x44,0x44,0x38, // 98 b
- 0x38,0x44,0x44,0x44,0x20, // 99 c
- 0x38,0x44,0x44,0x48,0x7F, // 100 d
- 0x38,0x54,0x54,0x54,0x18, // 101 e
- 0x08,0x7E,0x09,0x01,0x02, // 102 f
- 0x08,0x14,0x54,0x54,0x3C, // 103 g
- 0x7F,0x08,0x04,0x04,0x78, // 104 h
- 0x00,0x44,0x7D,0x40,0x00, // 105 i
- 0x20,0x40,0x44,0x3D,0x00, // 106 j
- 0x00,0x7F,0x10,0x28,0x44, // 107 k
- 0x00,0x41,0x7F,0x40,0x00, // 108 l
- 0x7C,0x04,0x18,0x04,0x78, // 109 m
- 0x7C,0x08,0x04,0x04,0x78, // 110 n
- 0x38,0x44,0x44,0x44,0x38, // 111 o
- 0x7C,0x14,0x14,0x14,0x08, // 112 p
- 0x08,0x14,0x14,0x18,0x7C, // 113 q
- 0x7C,0x08,0x04,0x04,0x08, // 114 r
- 0x48,0x54,0x54,0x54,0x20, // 115 s
- 0x04,0x3F,0x44,0x40,0x20, // 116 t
- 0x3C,0x40,0x40,0x20,0x7C, // 117 u
- 0x1C,0x20,0x40,0x20,0x1C, // 118 v
- 0x3C,0x40,0x30,0x40,0x3C, // 119 w
- 0x44,0x28,0x10,0x28,0x44, // 120 x
- 0x0C,0x50,0x50,0x50,0x3C, // 121 y
- 0x44,0x64,0x54,0x4C,0x44, // 122 z
- 0x00,0x08,0x36,0x41,0x00, // 123 {
- 0x00,0x00,0x7F,0x00,0x00, // 124 |
- 0x00,0x41,0x36,0x08,0x00, // 125 }
- 0x10,0x08,0x08,0x10,0x08, // 126 ~
-};
-
-#endif
diff --git a/examples/host/midi2_host/src/main.c b/examples/host/midi2_host/src/main.c
deleted file mode 100644
index e23fbfc87..000000000
--- a/examples/host/midi2_host/src/main.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2026 Saulo Verissimo
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-// MIDI 2.0 Host Receiver Example
-//
-// Receives UMP from a MIDI 2.0 Device via PIO-USB Host.
-// SSD1306 OLED (I2C, 128x64) shows boot checklist then received UMP messages.
-
-#include <stdio.h>
-#include <string.h>
-#include "bsp/board_api.h"
-#include "tusb.h"
-#include "class/midi/midi2_host.h"
-#include "class/midi/midi.h"
-#include "display.h"
-
-//--------------------------------------------------------------------+
-// Checklist state
-//--------------------------------------------------------------------+
-
-static checklist_t ck = { 0 };
-static uint32_t note_count = 0;
-static uint8_t midi2_idx = 0xFF; // invalid until mount
-
-//--------------------------------------------------------------------+
-// Note name helper
-//--------------------------------------------------------------------+
-
-static const char* NOTE_NAMES[] = {
- "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"
-};
-
-static void note_name(uint8_t pitch, char* buf, size_t len) {
- int octave = (pitch / 12) - 1;
- snprintf(buf, len, "%s%d", NOTE_NAMES[pitch % 12], octave);
-}
-
-//--------------------------------------------------------------------+
-// UMP Message Type names
-//--------------------------------------------------------------------+
-
-static const char* mt_name(uint8_t mt) {
- switch (mt) {
- case 0x0: return "Utility";
- case 0x1: return "System";
- case 0x2: return "M1 CVM";
- case 0x3: return "SysEx7";
- case 0x4: return "M2 CVM";
- case 0x5: return "SysEx8";
- case 0xD: return "Flex";
- case 0xF: return "Stream";
- default: return "?";
- }
-}
-
-//--------------------------------------------------------------------+
-// UMP decoder - extract and display MIDI 2.0 messages
-//--------------------------------------------------------------------+
-
-static void decode_ump(const uint32_t* words, uint8_t word_count) {
- uint8_t mt = (uint8_t)((words[0] >> 28) & 0x0F);
- char line[64];
-
- if (mt == 0x4 && word_count >= 2) {
- // MIDI 2.0 Channel Voice Message
- uint8_t status = (uint8_t)((words[0] >> 20) & 0x0F);
- uint8_t channel = (uint8_t)((words[0] >> 16) & 0x0F);
-
- switch (status) {
- case 0x9: { // Note On
- uint8_t pitch = (uint8_t)((words[0] >> 8) & 0x7F);
- uint16_t vel = (uint16_t)((words[1] >> 16) & 0xFFFF);
- char nn[6];
- note_name(pitch, nn, sizeof(nn));
- snprintf(line, sizeof(line), "NoteOn %s ch%u vel=0x%04X", nn, channel, vel);
- display_log(line, 0x07E0); // green
- note_count++;
- break;
- }
- case 0x8: { // Note Off
- uint8_t pitch = (uint8_t)((words[0] >> 8) & 0x7F);
- char nn[6];
- note_name(pitch, nn, sizeof(nn));
- snprintf(line, sizeof(line), "NoteOff %s ch%u", nn, channel);
- display_log(line, 0x8410); // grey
- break;
- }
- case 0xB: { // CC
- uint8_t idx = (uint8_t)((words[0] >> 8) & 0x7F);
- snprintf(line, sizeof(line), "CC%-3u = 0x%08lX", idx, (unsigned long)words[1]);
- display_log(line, 0x001F); // blue
- break;
- }
- case 0xC: { // Program Change
- uint8_t prog = (uint8_t)((words[1] >> 24) & 0x7F);
- snprintf(line, sizeof(line), "ProgChg %u", prog);
- display_log(line, 0xFFE0); // yellow
- break;
- }
- case 0xE: { // Pitch Bend
- snprintf(line, sizeof(line), "PBend = 0x%08lX", (unsigned long)words[1]);
- display_log(line, 0xF81F); // magenta
- break;
- }
- case 0xD: { // Channel Pressure
- snprintf(line, sizeof(line), "CPress = 0x%08lX", (unsigned long)words[1]);
- display_log(line, 0xFC10); // orange
- break;
- }
- case 0xA: { // Poly Pressure
- uint8_t pitch = (uint8_t)((words[0] >> 8) & 0x7F);
- char nn[6];
- note_name(pitch, nn, sizeof(nn));
- snprintf(line, sizeof(line), "PolyP %s = 0x%08lX", nn, (unsigned long)words[1]);
- display_log(line, 0xFC10);
- break;
- }
- case 0xF: { // Per-Note Management
- uint8_t pitch = (uint8_t)((words[0] >> 8) & 0x7F);
- uint8_t flags = (uint8_t)(words[0] & 0xFF);
- snprintf(line, sizeof(line), "PN-Mgmt note=%u flags=0x%02X", pitch, flags);
- display_log(line, 0x07FF); // cyan
- break;
- }
- default: {
- snprintf(line, sizeof(line), "M2CVM status=0x%X", status);
- display_log(line, 0xFFFF);
- break;
- }
- }
- } else if (mt == 0x0) {
- // Utility (JR Timestamp, NOOP)
- uint8_t status = (uint8_t)((words[0] >> 20) & 0x0F);
- if (status == 0x2) {
- uint16_t ts = words[0] & 0xFFFF;
- snprintf(line, sizeof(line), "JR-TS = 0x%04X", ts);
- display_log(line, 0x8410);
- }
- } else {
- snprintf(line, sizeof(line), "MT=0x%X (%s) w0=0x%08lX",
- mt, mt_name(mt), (unsigned long)words[0]);
- display_log(line, 0xFFFF);
- }
-}
-
-//--------------------------------------------------------------------+
-// MIDI 2.0 Host Callbacks
-//--------------------------------------------------------------------+
-
-void tuh_midi2_descriptor_cb(uint8_t idx, const tuh_midi2_descriptor_cb_t* d) {
- (void)idx;
- ck.descriptor_parsed = true;
- char line[48];
-
- snprintf(line, sizeof(line), "bcdMSC=0x%02X%02X proto=%s",
- d->bcdMSC_hi, d->bcdMSC_lo,
- d->protocol_version ? "MIDI2" : "MIDI1");
- display_log(line, 0x07E0);
-
- snprintf(line, sizeof(line), "Cables: RX=%u TX=%u",
- d->rx_cable_count, d->tx_cable_count);
- display_log(line, 0x07E0);
-
- display_checklist_update(&ck);
-}
-
-void tuh_midi2_mount_cb(uint8_t idx, const tuh_midi2_mount_cb_t* m) {
- midi2_idx = idx;
- ck.alt_setting_ok = true;
- ck.mounted = true;
-
- char line[48];
- snprintf(line, sizeof(line), "Mounted addr=%u alt=%u",
- m->daddr, m->alt_setting_active);
- display_log(line, 0x07E0);
-
- if (m->protocol_version) {
- display_log("MIDI 2.0 ready", 0x07E0);
- } else {
- display_log("MIDI 1.0 only", 0xFFE0);
- }
-
- display_checklist_update(&ck);
-}
-
-void tuh_midi2_rx_cb(uint8_t idx, uint32_t xferred_bytes) {
- (void)xferred_bytes;
- if (!ck.receiving) {
- ck.receiving = true;
- display_checklist_update(&ck);
- }
-
- uint32_t words[16];
- while (1) {
- uint32_t n = tuh_midi2_ump_read(idx, words, 16);
- if (n == 0) break;
-
- // Decode complete UMP messages
- uint32_t i = 0;
- while (i < n) {
- uint8_t mt = (uint8_t)((words[i] >> 28) & 0x0F);
- uint8_t wc = midi2_ump_word_count(mt);
- if (i + wc > n) break;
- decode_ump(&words[i], wc);
- i += wc;
- }
- }
-}
-
-void tuh_midi2_tx_cb(uint8_t idx, uint32_t xferred_bytes) {
- (void)idx; (void)xferred_bytes;
-}
-
-void tuh_midi2_umount_cb(uint8_t idx) {
- (void)idx;
- midi2_idx = 0xFF;
- ck.device_connected = false;
- ck.descriptor_parsed = false;
- ck.alt_setting_ok = false;
- ck.mounted = false;
- ck.receiving = false;
- note_count = 0;
-
- display_log("Device disconnected", 0xF800);
- display_checklist_update(&ck);
-}
-
-//--------------------------------------------------------------------+
-// Main
-//--------------------------------------------------------------------+
-
-int main(void) {
- board_init();
-
- display_init();
-
- ck.pwr_on = true;
- display_checklist_update(&ck);
-
- // Init TinyUSB Host (BSP handles PIO-USB configuration via tuh_configure)
- tusb_rhport_init_t host_init = {
- .role = TUSB_ROLE_HOST,
- .speed = TUSB_SPEED_FULL,
- };
- tusb_init(BOARD_TUH_RHPORT, &host_init);
-
- ck.tusb_init = true;
- ck.bus_active = true;
- display_checklist_update(&ck);
-
- char dbg[40];
- snprintf(dbg, sizeof(dbg), "RHPORT=%u PIO_USB=%u",
- BOARD_TUH_RHPORT, CFG_TUH_RPI_PIO_USB);
- display_log(dbg, 0xFFE0); // yellow
- display_status("Waiting for device...");
-
- uint32_t last_status_ms = 0;
- static uint32_t loop_count = 0;
-
- while (1) {
- tuh_task();
- loop_count++;
-
- // Update status every 2 seconds
- uint32_t now = tusb_time_millis_api();
- if (now - last_status_ms > 2000) {
- last_status_ms = now;
- char line[22];
- if (ck.receiving) {
- snprintf(line, sizeof(line), "Notes:%lu", (unsigned long)note_count);
- } else if (ck.mounted) {
- snprintf(line, sizeof(line), "Mounted OK!");
- } else if (ck.device_connected) {
- snprintf(line, sizeof(line), "Dev found, mounting..");
- } else {
- snprintf(line, sizeof(line), "Wait.. t=%lu", (unsigned long)(now/1000));
- }
- display_status(line);
- }
- }
-
- return 0;
-}
-
-// Generic USB device mount/unmount (any class)
-void tuh_mount_cb(uint8_t daddr) {
- char line[32];
- uint16_t vid, pid;
- tuh_vid_pid_get(daddr, &vid, &pid);
- snprintf(line, sizeof(line), "USB %04X:%04X a%u", vid, pid, daddr);
- display_log(line, 0x07E0);
- ck.device_connected = true;
- display_checklist_update(&ck);
-}
-
-void tuh_umount_cb(uint8_t daddr) {
- (void)daddr;
- display_log("USB disconnected", 0xF800);
- ck.device_connected = false;
- ck.descriptor_parsed = false;
- ck.alt_setting_ok = false;
- ck.mounted = false;
- ck.receiving = false;
- display_checklist_update(&ck);
-}
diff --git a/examples/host/midi2_host/src/tusb_config.h b/examples/host/midi2_host/src/tusb_config.h
deleted file mode 100644
index 650df97e1..000000000
--- a/examples/host/midi2_host/src/tusb_config.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2026 Saulo Verissimo
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef TUSB_CONFIG_H_
-#define TUSB_CONFIG_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-//--------------------------------------------------------------------
-// Common Configuration
-//--------------------------------------------------------------------
-
-#ifndef CFG_TUSB_MCU
-#error CFG_TUSB_MCU must be defined
-#endif
-
-#ifndef CFG_TUSB_OS
-#define CFG_TUSB_OS OPT_OS_NONE
-#endif
-
-#ifndef CFG_TUSB_DEBUG
-#define CFG_TUSB_DEBUG 0
-#endif
-
-#ifndef CFG_TUH_MEM_SECTION
-#define CFG_TUH_MEM_SECTION
-#endif
-
-#ifndef CFG_TUH_MEM_ALIGN
-#define CFG_TUH_MEM_ALIGN __attribute__ ((aligned(4)))
-#endif
-
-//--------------------------------------------------------------------
-// Host Configuration
-// Waveshare RP2350-USB-A: PIO-USB on GP12/GP13 (USB-A Host port)
-//--------------------------------------------------------------------
-
-#define CFG_TUH_ENABLED 1
-
-// PIO-USB Host on rhport 1 (USB-A connector on GP12/GP13)
-#define CFG_TUH_RPI_PIO_USB 1
-#define BOARD_TUH_RHPORT 1
-
-#ifndef BOARD_TUH_MAX_SPEED
-#define BOARD_TUH_MAX_SPEED OPT_MODE_FULL_SPEED
-#endif
-
-#define CFG_TUH_MAX_SPEED BOARD_TUH_MAX_SPEED
-
-//--------------------------------------------------------------------
-// Driver Configuration
-//--------------------------------------------------------------------
-
-#define CFG_TUH_ENUMERATION_BUFSIZE 256
-
-#define CFG_TUH_HUB 0
-#define CFG_TUH_DEVICE_MAX 1
-
-// MIDI 2.0 Host
-#define CFG_TUH_MIDI2 1
-#define CFG_TUH_MIDI2_RX_BUFSIZE 512
-#define CFG_TUH_MIDI2_TX_BUFSIZE 512
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/hw/bsp/rp2040/boards/waveshare_rp2350_usb_a/board.cmake b/hw/bsp/rp2040/boards/waveshare_rp2350_usb_a/board.cmake
deleted file mode 100644
index e888c7fb3..000000000
--- a/hw/bsp/rp2040/boards/waveshare_rp2350_usb_a/board.cmake
+++ /dev/null
@@ -1,2 +0,0 @@
-set(PICO_PLATFORM rp2350-arm-s)
-set(PICO_BOARD waveshare_rp2350_usb_a)
diff --git a/hw/bsp/rp2040/boards/waveshare_rp2350_usb_a/board.h b/hw/bsp/rp2040/boards/waveshare_rp2350_usb_a/board.h
deleted file mode 100644
index 0af8a695f..000000000
--- a/hw/bsp/rp2040/boards/waveshare_rp2350_usb_a/board.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2026 Saulo Verissimo
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- * This file is part of the TinyUSB stack.
- */
-
-/* metadata:
- name: Waveshare RP2350-USB-A
- url: https://www.waveshare.com/wiki/RP2350-USB-A
-*/
-
-#ifndef TUSB_BOARD_H
-#define TUSB_BOARD_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-//--------------------------------------------------------------------+
-// PIO_USB
-//--------------------------------------------------------------------+
-// Waveshare RP2350-USB-A: PIO-USB on GP12 (D+) / GP13 (D-)
-// PICO_DEFAULT_PIO_USB_DP_PIN already defined in SDK board header
-
-#ifdef __cplusplus
- }
-#endif
-
-#endif