Skip to content

Commit 2e8f1b5

Browse files
committed
initial support for ch32 with usbd
1 parent c0e19ef commit 2e8f1b5

File tree

8 files changed

+335
-11
lines changed

8 files changed

+335
-11
lines changed

.github/workflows/githubci.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ jobs:
6262
uses: actions/checkout@v4
6363
with:
6464
repository: adafruit/ci-arduino
65-
ref: importable-build_platform
6665
path: ci
6766

6867
- name: pre-install
@@ -95,7 +94,6 @@ jobs:
9594
uses: actions/checkout@v4
9695
with:
9796
repository: adafruit/ci-arduino
98-
ref: importable-build_platform
9997
path: ci
10098

10199
- name: pre-install

examples/MassStorage/msc_ramdisk/msc_ramdisk.ino

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,10 @@ Adafruit_USBD_MSC usb_msc;
3737

3838
// the setup function runs once when you press reset or power the board
3939
void setup() {
40-
#if defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_RP2040)
41-
// Manual begin() is required on core without built-in support for TinyUSB such as
42-
// - mbed rp2040
43-
TinyUSB_Device_Init(0);
44-
#endif
40+
// Manual begin() is required on core without built-in support e.g. mbed rp2040
41+
if (!TinyUSBDevice.isInitialized()) {
42+
TinyUSBDevice.begin(0);
43+
}
4544

4645
#ifdef BTN_EJECT
4746
pinMode(BTN_EJECT, activeState ? INPUT_PULLDOWN : INPUT_PULLUP);
@@ -69,7 +68,10 @@ void setup() {
6968
}
7069

7170
void loop() {
72-
// nothing to do
71+
#ifdef TINYUSB_NEED_POLLING_TASK
72+
// Manual call tud_task since it isn't called by Core's background
73+
TinyUSBDevice.task();
74+
#endif
7375
}
7476

7577
// Callback invoked when received READ10 command.

src/Adafruit_TinyUSB.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@
2525
#ifndef ADAFRUIT_TINYUSB_H_
2626
#define ADAFRUIT_TINYUSB_H_
2727

28+
// Core that has built-in support: Adafruit SAMD, nRF, rp2040, esp32
29+
#if !(defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_NRF52_ADAFRUIT) || \
30+
defined(ARDUINO_ARCH_ESP32) || \
31+
(defined(ARDUINO_ARCH_RP2040) && !defined(ARDUINO_ARCH_MBED)))
32+
#define TINYUSB_NEED_POLLING_TASK
33+
#endif
34+
2835
// Error message for Core that must select TinyUSB via menu
2936
#if !defined(USE_TINYUSB) && \
3037
(defined(ARDUINO_ARCH_SAMD) || \

src/arduino/Adafruit_USBD_Device.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,11 @@ bool Adafruit_USBD_Device::begin(uint8_t rhport) {
269269
return true;
270270
}
271271

272+
bool Adafruit_USBD_Device::isInitialized(uint8_t rhport) {
273+
(void)rhport;
274+
return tud_inited();
275+
}
276+
272277
static int strcpy_utf16(const char *s, uint16_t *buf, int bufsize);
273278

274279
uint8_t Adafruit_USBD_Device::getSerialDescriptor(uint16_t *serial_utf16) {

src/arduino/Adafruit_USBD_Device.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ class Adafruit_USBD_Device {
115115
//------------- Control -------------//
116116

117117
bool begin(uint8_t rhport = 0);
118+
bool isInitialized(uint8_t rhport = 0);
118119
void task(void);
119120

120121
// physical disable/enable pull-up
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/*
2+
* The MIT License (MIT)
3+
*
4+
* Copyright (c) 2019, hathach for Adafruit
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*/
24+
25+
#include "tusb_option.h"
26+
27+
#if defined(CH32V20x) && CFG_TUD_ENABLED
28+
29+
#include "Arduino.h"
30+
#include "arduino/Adafruit_USBD_Device.h"
31+
32+
//--------------------------------------------------------------------+
33+
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
34+
//--------------------------------------------------------------------+
35+
36+
//--------------------------------------------------------------------+
37+
// Forward USB interrupt events to TinyUSB IRQ Handler
38+
//--------------------------------------------------------------------+
39+
extern "C" {
40+
41+
// USBFS
42+
__attribute__((interrupt("WCH-Interrupt-fast"))) void USBHD_IRQHandler(void) {
43+
#if CFG_TUD_WCH_USBIP_USBFS
44+
tud_int_handler(0);
45+
#endif
46+
}
47+
48+
__attribute__((interrupt("WCH-Interrupt-fast"))) void
49+
USBHDWakeUp_IRQHandler(void) {
50+
#if CFG_TUD_WCH_USBIP_USBFS
51+
tud_int_handler(0);
52+
#endif
53+
}
54+
55+
// USBD (fsdev)
56+
__attribute__((interrupt("WCH-Interrupt-fast"))) void
57+
USB_LP_CAN1_RX0_IRQHandler(void) {
58+
#if CFG_TUD_WCH_USBIP_FSDEV
59+
tud_int_handler(0);
60+
#endif
61+
}
62+
63+
__attribute__((interrupt("WCH-Interrupt-fast"))) void
64+
USB_HP_CAN1_TX_IRQHandler(void) {
65+
#if CFG_TUD_WCH_USBIP_FSDEV
66+
tud_int_handler(0);
67+
#endif
68+
}
69+
70+
__attribute__((interrupt("WCH-Interrupt-fast"))) void
71+
USBWakeUp_IRQHandler(void) {
72+
#if CFG_TUD_WCH_USBIP_FSDEV
73+
tud_int_handler(0);
74+
#endif
75+
}
76+
77+
void yield(void) {
78+
tud_task();
79+
// flush cdc
80+
}
81+
}
82+
83+
//--------------------------------------------------------------------+
84+
// Porting API
85+
//--------------------------------------------------------------------+
86+
87+
void TinyUSB_Port_InitDevice(uint8_t rhport) {
88+
uint8_t usb_div;
89+
switch (SystemCoreClock) {
90+
case 48000000:
91+
usb_div = RCC_USBCLKSource_PLLCLK_Div1;
92+
break;
93+
case 96000000:
94+
usb_div = RCC_USBCLKSource_PLLCLK_Div2;
95+
break;
96+
case 144000000:
97+
usb_div = RCC_USBCLKSource_PLLCLK_Div3;
98+
break;
99+
default:
100+
return; // unsupported
101+
}
102+
RCC_USBCLKConfig(usb_div);
103+
104+
#if CFG_TUD_WCH_USBIP_FSDEV
105+
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE);
106+
#endif
107+
108+
#if CFG_TUD_WCH_USBIP_USBFS
109+
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_OTG_FS, ENABLE);
110+
#endif
111+
112+
tud_init(rhport);
113+
}
114+
115+
void TinyUSB_Port_EnterDFU(void) {
116+
// Reset to Bootloader
117+
// enterSerialDfu();
118+
}
119+
120+
uint8_t TinyUSB_Port_GetSerialNumber(uint8_t serial_id[16]) {
121+
volatile uint32_t *ch32_uuid = ((volatile uint32_t *)0x1FFFF7E8UL);
122+
uint32_t *serial_32 = (uint32_t *)serial_id;
123+
serial_32[0] = ch32_uuid[0]; // TODO maybe __builtin_bswap32()
124+
serial_32[1] = ch32_uuid[1];
125+
serial_32[2] = ch32_uuid[2];
126+
127+
return 12;
128+
}
129+
130+
#endif
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
/*
2+
* The MIT License (MIT)
3+
*
4+
* Copyright (c) 2018, hathach for Adafruit
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*/
24+
25+
#ifndef TUSB_CONFIG_CH32_H_
26+
#define TUSB_CONFIG_CH32_H_
27+
28+
#ifdef __cplusplus
29+
extern "C" {
30+
#endif
31+
32+
//--------------------------------------------------------------------
33+
// COMMON CONFIGURATION
34+
//--------------------------------------------------------------------
35+
#if defined(CH32V20x)
36+
#define CFG_TUSB_MCU OPT_MCU_CH32V20X
37+
#define CFG_TUD_WCH_USBIP_FSDEV 1 // use USBD
38+
#elif defined(CH32V30x)
39+
#define CFG_TUSB_MCU OPT_MCU_CH32V307
40+
#endif
41+
42+
#define CFG_TUSB_OS OPT_OS_NONE
43+
44+
#ifndef CFG_TUSB_DEBUG
45+
#define CFG_TUSB_DEBUG 0
46+
#endif
47+
48+
// For selectively disable device log (when > CFG_TUSB_DEBUG)
49+
// #define CFG_TUD_LOG_LEVEL 3
50+
// #define CFG_TUH_LOG_LEVEL 3
51+
52+
#define CFG_TUSB_MEM_SECTION
53+
#define CFG_TUSB_MEM_ALIGN __attribute__((aligned(4)))
54+
55+
#define CFG_TUD_ENABLED 1
56+
57+
// #ifdef USE_TINYUSB
58+
//// Enable device stack
59+
// #define CFG_TUD_ENABLED 1
60+
//
61+
//// Enable host stack with MAX3421E (host shield)
62+
// #define CFG_TUH_ENABLED 1
63+
// #define CFG_TUH_MAX3421 1
64+
//
65+
// #else
66+
// #define CFG_TUD_ENABLED 0
67+
// #define CFG_TUH_ENABLED 0
68+
// #endif
69+
70+
//--------------------------------------------------------------------
71+
// DEVICE CONFIGURATION
72+
//--------------------------------------------------------------------
73+
74+
#define CFG_TUD_ENDPOINT0_SIZE 64
75+
76+
//------------- CLASS -------------//
77+
#ifndef CFG_TUD_CDC
78+
#define CFG_TUD_CDC 1
79+
#endif
80+
81+
#ifndef CFG_TUD_MSC
82+
#define CFG_TUD_MSC 1
83+
#endif
84+
85+
#ifndef CFG_TUD_HID
86+
#define CFG_TUD_HID 2
87+
#endif
88+
89+
#ifndef CFG_TUD_MIDI
90+
#define CFG_TUD_MIDI 1
91+
#endif
92+
93+
#ifndef CFG_TUD_VENDOR
94+
#define CFG_TUD_VENDOR 1
95+
#endif
96+
97+
#ifndef CFG_TUD_VIDEO
98+
#define CFG_TUD_VIDEO 1 // number of video control interfaces
99+
#endif
100+
101+
#ifndef CFG_TUD_VIDEO_STREAMING
102+
#define CFG_TUD_VIDEO_STREAMING 1 // number of video streaming interfaces
103+
#endif
104+
105+
// video streaming endpoint buffer size
106+
#define CFG_TUD_VIDEO_STREAMING_EP_BUFSIZE 256
107+
108+
// CDC FIFO size of TX and RX
109+
#define CFG_TUD_CDC_RX_BUFSIZE 256
110+
#define CFG_TUD_CDC_TX_BUFSIZE 256
111+
112+
// MSC Buffer size of Device Mass storage
113+
#define CFG_TUD_MSC_EP_BUFSIZE 512
114+
115+
// HID buffer size Should be sufficient to hold ID (if any) + Data
116+
#define CFG_TUD_HID_EP_BUFSIZE 64
117+
118+
// MIDI FIFO size of TX and RX
119+
#define CFG_TUD_MIDI_RX_BUFSIZE 128
120+
#define CFG_TUD_MIDI_TX_BUFSIZE 128
121+
122+
// Vendor FIFO size of TX and RX
123+
#ifndef CFG_TUD_VENDOR_RX_BUFSIZE
124+
#define CFG_TUD_VENDOR_RX_BUFSIZE 64
125+
#endif
126+
127+
#ifndef CFG_TUD_VENDOR_TX_BUFSIZE
128+
#define CFG_TUD_VENDOR_TX_BUFSIZE 64
129+
#endif
130+
131+
//--------------------------------------------------------------------
132+
// Host Configuration
133+
//--------------------------------------------------------------------
134+
135+
// Size of buffer to hold descriptors and other data used for enumeration
136+
#define CFG_TUH_ENUMERATION_BUFSIZE 256
137+
138+
// Number of hub devices
139+
#define CFG_TUH_HUB 1
140+
141+
// max device support (excluding hub device): 1 hub typically has 4 ports
142+
#define CFG_TUH_DEVICE_MAX (3 * CFG_TUH_HUB + 1)
143+
144+
// Enable tuh_edpt_xfer() API
145+
// #define CFG_TUH_API_EDPT_XFER 1
146+
147+
// Number of mass storage
148+
#define CFG_TUH_MSC 1
149+
150+
// Number of HIDs
151+
// typical keyboard + mouse device can have 3,4 HID interfaces
152+
#define CFG_TUH_HID (3 * CFG_TUH_DEVICE_MAX)
153+
154+
// Number of CDC interfaces
155+
// FTDI and CP210x are not part of CDC class, only to re-use CDC driver API
156+
#define CFG_TUH_CDC 1
157+
#define CFG_TUH_CDC_FTDI 1
158+
#define CFG_TUH_CDC_CP210X 1
159+
#define CFG_TUH_CDC_CH34X 1
160+
161+
// RX & TX fifo size
162+
#define CFG_TUH_CDC_RX_BUFSIZE 64
163+
#define CFG_TUH_CDC_TX_BUFSIZE 64
164+
165+
// Set Line Control state on enumeration/mounted:
166+
// DTR ( bit 0), RTS (bit 1)
167+
#define CFG_TUH_CDC_LINE_CONTROL_ON_ENUM 0x03
168+
169+
// Set Line Coding on enumeration/mounted, value for cdc_line_coding_t
170+
// bit rate = 115200, 1 stop bit, no parity, 8 bit data width
171+
// This need Pico-PIO-USB at least 0.5.1
172+
#define CFG_TUH_CDC_LINE_CODING_ON_ENUM \
173+
{ 115200, CDC_LINE_CONDING_STOP_BITS_1, CDC_LINE_CODING_PARITY_NONE, 8 }
174+
175+
#ifdef __cplusplus
176+
}
177+
#endif
178+
179+
#endif

0 commit comments

Comments
 (0)