diff --git a/CMakeLists.txt b/CMakeLists.txt index 44de74d..b72355d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,7 @@ pico_sdk_init() add_executable(picomap picomap.cpp + usb.cpp w6300/w6300.cpp ) @@ -23,9 +24,9 @@ target_compile_options(picomap PRIVATE -Wall -Wextra -Wno-unused-parameter) pico_generate_pio_header(picomap ${CMAKE_CURRENT_LIST_DIR}/w6300/qspi.pio) -pico_enable_stdio_usb(picomap 1) +pico_enable_stdio_usb(picomap 0) pico_enable_stdio_uart(picomap 0) pico_add_extra_outputs(picomap) -target_link_libraries(picomap pico_stdlib hardware_pio hardware_spi hardware_dma hardware_clocks) +target_link_libraries(picomap pico_stdlib tinyusb_device tinyusb_board hardware_pio hardware_spi hardware_dma hardware_clocks) diff --git a/include/tusb_config.h b/include/tusb_config.h new file mode 100644 index 0000000..f2d0b6d --- /dev/null +++ b/include/tusb_config.h @@ -0,0 +1,7 @@ +#pragma once + +#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE +#define CFG_TUD_CDC 1 +#define CFG_TUD_CDC_RX_BUFSIZE 256 +#define CFG_TUD_CDC_TX_BUFSIZE 256 +#define CFG_TUD_CDC_EP_BUFSIZE 64 diff --git a/picomap.cpp b/picomap.cpp index 36072f1..f6dcab4 100644 --- a/picomap.cpp +++ b/picomap.cpp @@ -1,16 +1,28 @@ -#include #include "pico/stdlib.h" #include "pico/bootrom.h" #include "pico/unique_id.h" +#include "tusb.h" #include "wire.h" #include "w6300.h" -static void send_bytes(const std::vector &data) { - for (auto b : data) { - putchar(b); +static void usb_write(const uint8_t* data, uint32_t len) { + while (len > 0) { + uint32_t avail = tud_cdc_write_available(); + if (avail == 0) { + tud_task(); + continue; + } + uint32_t chunk = len < avail ? len : avail; + tud_cdc_write(data, chunk); + tud_cdc_write_flush(); + data += chunk; + len -= chunk; } - stdio_flush(); +} + +static void send_bytes(const std::vector &data) { + usb_write(data.data(), data.size()); } static bool w6300_init() { @@ -35,20 +47,22 @@ static bool w6300_init() { } int main() { - stdio_init_all(); - stdio_set_translate_crlf(&stdio_usb, false); + tusb_init(); if (!w6300_init()) { - printf("W6300 init failed\n"); } static static_vector rx_buf; while (true) { - int c = getchar_timeout_us(100000); - if (c == PICO_ERROR_TIMEOUT) continue; + tud_task(); - rx_buf.push_back(static_cast(c)); + if (!tud_cdc_available()) continue; + + uint8_t byte; + if (tud_cdc_read(&byte, 1) != 1) continue; + + rx_buf.push_back(byte); auto msg = try_decode(rx_buf); if (!msg) { diff --git a/usb.cpp b/usb.cpp new file mode 100644 index 0000000..6cf1c64 --- /dev/null +++ b/usb.cpp @@ -0,0 +1,82 @@ +#include +#include "pico/unique_id.h" +#include "tusb.h" + +constexpr uint16_t USB_VID = 0x2E8A; +constexpr uint16_t USB_PID = 0x000A; + +static constexpr tusb_desc_device_t desc_device = { + sizeof(tusb_desc_device_t), + TUSB_DESC_DEVICE, + 0x0200, + TUSB_CLASS_MISC, + MISC_SUBCLASS_COMMON, + MISC_PROTOCOL_IAD, + CFG_TUD_ENDPOINT0_SIZE, + USB_VID, + USB_PID, + 0x0100, + 1, 2, 3, + 1, +}; + +enum { ITF_NUM_CDC, ITF_NUM_CDC_DATA, ITF_NUM_TOTAL }; + +constexpr uint8_t EPNUM_CDC_NOTIF = 0x81; +constexpr uint8_t EPNUM_CDC_OUT = 0x02; +constexpr uint8_t EPNUM_CDC_IN = 0x82; +constexpr uint16_t CONFIG_TOTAL_LEN = TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN; + +static uint8_t const desc_configuration[] = { + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), + TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 0, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64), +}; + +static constexpr const char* string_desc[] = { + "\x09\x04", + "picomap", + "picomap", + nullptr, +}; + +static uint16_t desc_str_buf[33]; + +extern "C" { + +uint8_t const* tud_descriptor_device_cb(void) { + return reinterpret_cast(&desc_device); +} + +uint8_t const* tud_descriptor_configuration_cb(uint8_t index) { + return desc_configuration; +} + +uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) { + uint8_t chr_count; + + if (index == 0) { + memcpy(&desc_str_buf[1], string_desc[0], 2); + chr_count = 1; + } else if (index == 3) { + pico_unique_board_id_t uid; + pico_get_unique_board_id(&uid); + chr_count = 0; + for (int i = 0; i < 8; i++) { + desc_str_buf[1 + chr_count++] = "0123456789ABCDEF"[uid.id[i] >> 4]; + desc_str_buf[1 + chr_count++] = "0123456789ABCDEF"[uid.id[i] & 0xF]; + } + } else { + if (index >= sizeof(string_desc) / sizeof(string_desc[0])) return nullptr; + const char* str = string_desc[index]; + if (!str) return nullptr; + chr_count = strlen(str); + if (chr_count > 31) chr_count = 31; + for (uint8_t i = 0; i < chr_count; i++) + desc_str_buf[1 + i] = str[i]; + } + + desc_str_buf[0] = static_cast((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); + return desc_str_buf; +} + +} // extern "C" diff --git a/w6300/w6300.cpp b/w6300/w6300.cpp index 0be652c..4b786b0 100644 --- a/w6300/w6300.cpp +++ b/w6300/w6300.cpp @@ -1,4 +1,3 @@ -#include #include #include #include "pico/stdlib.h"