Skip to content

Commit

Permalink
Merge pull request #429 from adafruit/ch32-core-support
Browse files Browse the repository at this point in the history
Add Ch32 built-inn core support
  • Loading branch information
hathach committed Jun 20, 2024
2 parents 6cc5113 + 8cb4032 commit a56612b
Show file tree
Hide file tree
Showing 25 changed files with 235 additions and 69 deletions.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
6 changes: 6 additions & 0 deletions examples/CDC/cdc_multi/.skip.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
feather_esp32s2
feather_esp32s3
funhouse
magtag
metroesp32s2
pico_rp2040_tinyusb_host
1 change: 1 addition & 0 deletions examples/CDC/serial_echo/serial_echo.ino
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

/* This sketch demonstrates USB CDC Serial echo (convert to upper case) using SerialTinyUSB which
* is available for both core with built-in USB support and without.
* Note: on core with built-in support Serial is alias to SerialTinyUSB
*/

void setup() {
Expand Down
7 changes: 0 additions & 7 deletions src/Adafruit_TinyUSB.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,6 @@
#ifndef ADAFRUIT_TINYUSB_H_
#define ADAFRUIT_TINYUSB_H_

// Error message for Core that must select TinyUSB via menu
#if !defined(USE_TINYUSB) && \
(defined(ARDUINO_ARCH_SAMD) || \
(defined(ARDUINO_ARCH_RP2040) && !defined(ARDUINO_ARCH_MBED)))
#error TinyUSB is not selected, please select it in "Tools->Menu->USB Stack"
#endif

// ESP32 out-of-sync
#ifdef ARDUINO_ARCH_ESP32
#include "arduino/ports/esp32/tusb_config_esp32.h"
Expand Down
17 changes: 14 additions & 3 deletions src/arduino/Adafruit_TinyUSB_API.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,24 @@
// TinyUSB_API, USBD_CDC, USBD_Device, USBD_Interface,
#define TINYUSB_API_VERSION 30000

#if defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_NRF52_ADAFRUIT) || \
defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_CH32) || \
(defined(ARDUINO_ARCH_RP2040) && !defined(ARDUINO_ARCH_MBED))
#define TINYUSB_HAS_BUITLTIN_CORE_SUPPORT
#endif

// Core that has built-in support: Adafruit SAMD, Adafruit nRF, rp2040, esp32
#if !(defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_NRF52_ADAFRUIT) || \
defined(ARDUINO_ARCH_ESP32) || \
(defined(ARDUINO_ARCH_RP2040) && !defined(ARDUINO_ARCH_MBED)))
#if !defined(TINYUSB_HAS_BUITLTIN_CORE_SUPPORT)
#define TINYUSB_NEED_POLLING_TASK
#endif

// Error message for Core that must select TinyUSB via menu (built-in except
// esp32)
#if !defined(USE_TINYUSB) && (defined(TINYUSB_HAS_BUITLTIN_CORE_SUPPORT) && \
!defined(ARDUINO_ARCH_ESP32))
#error TinyUSB is not selected, please select it in "Tools->Menu->USB Stack"
#endif

//--------------------------------------------------------------------+
// Core API
// Should be called by BSP Core to initialize, process task
Expand Down
6 changes: 4 additions & 2 deletions src/arduino/Adafruit_USBD_CDC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
#define TINYUSB_API_VERSION 0
#endif

#define BULK_PACKET_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)

// SerialTinyUSB can be macro expanding to "Serial" on supported cores
Adafruit_USBD_CDC SerialTinyUSB;

Expand Down Expand Up @@ -69,8 +71,8 @@ uint16_t Adafruit_USBD_CDC::getInterfaceDescriptor(uint8_t itfnum_deprecated,
uint8_t _strid = 0;
#endif

uint8_t const desc[] = {
TUD_CDC_DESCRIPTOR(itfnum, _strid, ep_notif, 8, ep_out, ep_in, 64)};
uint8_t const desc[] = {TUD_CDC_DESCRIPTOR(itfnum, _strid, ep_notif, 8,
ep_out, ep_in, BULK_PACKET_SIZE)};

uint16_t const len = sizeof(desc);

Expand Down
11 changes: 5 additions & 6 deletions src/arduino/Adafruit_USBD_CDC.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,16 +93,15 @@ class Adafruit_USBD_CDC : public Stream, public Adafruit_USBD_Interface {
bool isValid(void) { return _instance != INVALID_INSTANCE; }
};

// "Serial" is used with TinyUSB CDC
#if defined(USE_TINYUSB)
extern Adafruit_USBD_CDC Serial;
extern Adafruit_USBD_CDC SerialTinyUSB;

// Built-in support "Serial" is assigned to TinyUSB CDC
// CH32 defines Serial as alias in WSerial.h
#if defined(USE_TINYUSB) && !defined(ARDUINO_ARCH_CH32)
#define SerialTinyUSB Serial
#endif

// Serial is probably used with HW Uart
#ifndef SerialTinyUSB
extern Adafruit_USBD_CDC SerialTinyUSB;
#endif

#endif // else of ESP32
#endif // __cplusplus
Expand Down
2 changes: 1 addition & 1 deletion src/arduino/Adafruit_USBD_Interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#include <stddef.h>
#include <stdint.h>

#if defined(CH32V20x) || defined(CH32V30x)
#if defined(ARDUINO_ARCH_CH32) || defined(CH32V20x) || defined(CH32V30x)
// HACK: required for ch32 core version 1.0.4 or prior, removed when 1.0.5 is
// released
extern "C" void yield(void);
Expand Down
6 changes: 3 additions & 3 deletions src/arduino/midi/Adafruit_USBD_MIDI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
//--------------------------------------------------------------------+
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
//--------------------------------------------------------------------+
#define EPSIZE 64
#define BULK_PACKET_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)

// TODO multiple instances
static Adafruit_USBD_MIDI *_midi_dev = NULL;
Expand Down Expand Up @@ -103,7 +103,7 @@ uint16_t Adafruit_USBD_MIDI::getInterfaceDescriptor(uint8_t itfnum_deprecated,

// Endpoint OUT + jack mapping
{
uint8_t desc[] = {TUD_MIDI_DESC_EP(ep_out, EPSIZE, _n_cables)};
uint8_t desc[] = {TUD_MIDI_DESC_EP(ep_out, BULK_PACKET_SIZE, _n_cables)};
memcpy(buf + len, desc, sizeof(desc));
len += sizeof(desc);
}
Expand All @@ -116,7 +116,7 @@ uint16_t Adafruit_USBD_MIDI::getInterfaceDescriptor(uint8_t itfnum_deprecated,

// Endpoint IN + jack mapping
{
uint8_t desc[] = {TUD_MIDI_DESC_EP(ep_in, EPSIZE, _n_cables)};
uint8_t desc[] = {TUD_MIDI_DESC_EP(ep_in, BULK_PACKET_SIZE, _n_cables)};
memcpy(buf + len, desc, sizeof(desc));
len += sizeof(desc);
}
Expand Down
4 changes: 2 additions & 2 deletions src/arduino/msc/Adafruit_USBD_MSC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

#include "Adafruit_USBD_MSC.h"

#define EPSIZE 64 // TODO must be 512 for highspeed device
#define BULK_PACKET_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)

static Adafruit_USBD_MSC *_msc_dev = NULL;

Expand All @@ -52,7 +52,7 @@ uint16_t Adafruit_USBD_MSC::getInterfaceDescriptor(uint8_t itfnum_deprecated,
uint8_t const ep_out = TinyUSBDevice.allocEndpoint(TUSB_DIR_OUT);

uint8_t const desc[] = {
TUD_MSC_DESCRIPTOR(itfnum, _strid, ep_out, ep_in, EPSIZE)};
TUD_MSC_DESCRIPTOR(itfnum, _strid, ep_out, ep_in, BULK_PACKET_SIZE)};
uint16_t const len = sizeof(desc);

if (bufsize < len) {
Expand Down
100 changes: 77 additions & 23 deletions src/arduino/ports/ch32/Adafruit_TinyUSB_ch32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@

#include "tusb_option.h"

#if defined(CH32V20x) && CFG_TUD_ENABLED
#if CFG_TUD_ENABLED && \
(defined(ARDUINO_ARCH_CH32) || defined(CH32V20x) || defined(CH32V30x))

#include "Arduino.h"
#include "arduino/Adafruit_USBD_Device.h"
Expand All @@ -38,45 +39,63 @@
//--------------------------------------------------------------------+
extern "C" {

// USBFS
__attribute__((interrupt("WCH-Interrupt-fast"))) void USBHD_IRQHandler(void) {
#if CFG_TUD_WCH_USBIP_USBFS
// USBD (fsdev)
#if CFG_TUD_WCH_USBIP_FSDEV
__attribute__((interrupt("WCH-Interrupt-fast"))) void
USB_LP_CAN1_RX0_IRQHandler(void) {
tud_int_handler(0);
#endif
}

__attribute__((interrupt("WCH-Interrupt-fast"))) void
USBHDWakeUp_IRQHandler(void) {
#if CFG_TUD_WCH_USBIP_USBFS
USB_HP_CAN1_TX_IRQHandler(void) {
tud_int_handler(0);
#endif
}

// USBD (fsdev)
__attribute__((interrupt("WCH-Interrupt-fast"))) void
USB_LP_CAN1_RX0_IRQHandler(void) {
#if CFG_TUD_WCH_USBIP_FSDEV
USBWakeUp_IRQHandler(void) {
tud_int_handler(0);
}
#endif

// USBFS
#if CFG_TUD_WCH_USBIP_USBFS

#if defined(CH32V10x) || defined(CH32V20x)

#if defined(CH32V10x)
#define USBHDWakeUp_IRQHandler USBWakeUp_IRQHandler
#endif

__attribute__((interrupt("WCH-Interrupt-fast"))) void USBHD_IRQHandler(void) {
tud_int_handler(0);
}

__attribute__((interrupt("WCH-Interrupt-fast"))) void
USB_HP_CAN1_TX_IRQHandler(void) {
#if CFG_TUD_WCH_USBIP_FSDEV
USBHDWakeUp_IRQHandler(void) {
tud_int_handler(0);
#endif
}
#endif

__attribute__((interrupt("WCH-Interrupt-fast"))) void
USBWakeUp_IRQHandler(void) {
#if CFG_TUD_WCH_USBIP_FSDEV
#ifdef CH32V30x
__attribute__((interrupt("WCH-Interrupt-fast"))) void OTG_FS_IRQHandler(void) {
tud_int_handler(0);
}
#endif

#endif

// USBHS
#if CFG_TUD_WCH_USBIP_USBHS
__attribute__((interrupt("WCH-Interrupt-fast"))) void USBHS_IRQHandler(void) {
tud_int_handler(0);
}
#endif

void yield(void) {
tud_task();
// flush cdc
if (tud_cdc_connected()) {
tud_cdc_write_flush();
}
}
}

Expand All @@ -85,21 +104,45 @@ void yield(void) {
//--------------------------------------------------------------------+

void TinyUSB_Port_InitDevice(uint8_t rhport) {
#if CFG_TUD_WCH_USBIP_FSDEV || CFG_TUD_WCH_USBIP_USBFS
// Full speed OTG or FSDev

#if defined(CH32V10x)
EXTEN->EXTEN_CTR |= EXTEN_USBHD_IO_EN;
EXTEN->EXTEN_CTR &= ~EXTEN_USB_5V_SEL;

#define RCC_AHBPeriph_OTG_FS RCC_AHBPeriph_USBHD
#endif

uint8_t usb_div;
switch (SystemCoreClock) {
#if defined(CH32V20x) || defined(CH32V30x)
case 48000000:
usb_div = RCC_USBCLKSource_PLLCLK_Div1;
break;
usb_div = 0;
break; // div1
case 96000000:
usb_div = RCC_USBCLKSource_PLLCLK_Div2;
break;
usb_div = 1;
break; // div2
case 144000000:
usb_div = RCC_USBCLKSource_PLLCLK_Div3;
usb_div = 2;
break; // div3
#elif defined(CH32V10x)
case 48000000:
usb_div = RCC_USBCLKSource_PLLCLK_Div1;
break;
case 72000000:
usb_div = RCC_USBCLKSource_PLLCLK_1Div5;
break;
#endif
default:
return; // unsupported
}

#if defined(CH32V30x)
RCC_OTGFSCLKConfig(usb_div);
#else
RCC_USBCLKConfig(usb_div);
#endif

#if CFG_TUD_WCH_USBIP_FSDEV
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE);
Expand All @@ -108,6 +151,17 @@ void TinyUSB_Port_InitDevice(uint8_t rhport) {
#if CFG_TUD_WCH_USBIP_USBFS
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_OTG_FS, ENABLE);
#endif
#endif

#if CFG_TUD_WCH_USBIP_USBHS
// High speed USB: currently require 144MHz HSE, update later
RCC_USBCLK48MConfig(RCC_USBCLK48MCLKSource_USBPHY);
RCC_USBHSPLLCLKConfig(RCC_HSBHSPLLCLKSource_HSE);
RCC_USBHSConfig(RCC_USBPLL_Div2);
RCC_USBHSPLLCKREFCLKConfig(RCC_USBHSPLLCKREFCLK_4M);
RCC_USBHSPHYPLLALIVEcmd(ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_USBHS, ENABLE);
#endif

tud_init(rhport);
}
Expand Down
21 changes: 12 additions & 9 deletions src/arduino/ports/ch32/tusb_config_ch32.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@ extern "C" {
//--------------------------------------------------------------------
// COMMON CONFIGURATION
//--------------------------------------------------------------------
#if defined(CH32V20x)
#if defined(CH32V10x)
#define CFG_TUSB_MCU OPT_MCU_CH32V103
#warnning "CH32v103 is not working yet"
#elif defined(CH32V20x)
#define CFG_TUSB_MCU OPT_MCU_CH32V20X
#define CFG_TUD_WCH_USBIP_FSDEV 1 // use USBD
#elif defined(CH32V30x)
#define CFG_TUSB_MCU OPT_MCU_CH32V307
#endif
Expand Down Expand Up @@ -106,8 +108,8 @@ extern "C" {
#define CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE 256

// CDC FIFO size of TX and RX
#define CFG_TUD_CDC_RX_BUFSIZE 256
#define CFG_TUD_CDC_TX_BUFSIZE 256
#define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 256)
#define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 256)

// MSC Buffer size of Device Mass storage
#define CFG_TUD_MSC_EP_BUFSIZE 512
Expand All @@ -121,17 +123,17 @@ extern "C" {

// Vendor FIFO size of TX and RX
#ifndef CFG_TUD_VENDOR_RX_BUFSIZE
#define CFG_TUD_VENDOR_RX_BUFSIZE 64
#define CFG_TUD_VENDOR_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
#endif

#ifndef CFG_TUD_VENDOR_TX_BUFSIZE
#define CFG_TUD_VENDOR_TX_BUFSIZE 64
#define CFG_TUD_VENDOR_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
#endif

//--------------------------------------------------------------------
// Host Configuration
//--------------------------------------------------------------------

#if 0
// Size of buffer to hold descriptors and other data used for enumeration
#define CFG_TUH_ENUMERATION_BUFSIZE 256

Expand Down Expand Up @@ -159,8 +161,8 @@ extern "C" {
#define CFG_TUH_CDC_CH34X 1

// RX & TX fifo size
#define CFG_TUH_CDC_RX_BUFSIZE 64
#define CFG_TUH_CDC_TX_BUFSIZE 64
#define CFG_TUH_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
#define CFG_TUH_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)

// Set Line Control state on enumeration/mounted:
// DTR ( bit 0), RTS (bit 1)
Expand All @@ -171,6 +173,7 @@ extern "C" {
// This need Pico-PIO-USB at least 0.5.1
#define CFG_TUH_CDC_LINE_CODING_ON_ENUM \
{ 115200, CDC_LINE_CONDING_STOP_BITS_1, CDC_LINE_CODING_PARITY_NONE, 8 }
#endif

#ifdef __cplusplus
}
Expand Down
4 changes: 3 additions & 1 deletion src/arduino/video/Adafruit_USBD_Video.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@

#include "Adafruit_USBD_Video.h"

#define BULK_PACKET_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)

Adafruit_USBD_Video::Adafruit_USBD_Video(void) {
_vc_id = 0;
memset(&_camera_terminal, 0, sizeof(_camera_terminal));
Expand Down Expand Up @@ -231,7 +233,7 @@ uint16_t Adafruit_USBD_Video::getInterfaceDescriptor(uint8_t itfnum_deprecated,

.bEndpointAddress = ep_in,
.bmAttributes = {.xfer = TUSB_XFER_BULK, .sync = 0, .usage = 0},
.wMaxPacketSize = 64,
.wMaxPacketSize = BULK_PACKET_SIZE,
.bInterval = 1}};

uint16_t const len_iad = sizeof(desc_iad);
Expand Down
Loading

0 comments on commit a56612b

Please sign in to comment.