32
32
#include " hardware/watchdog.h"
33
33
#include " pico/unique_id.h"
34
34
35
+ #ifndef DISABLE_USB_SERIAL
36
+ // Ensure we are installed in the USB chain
37
+ void __USBInstallSerial () { /* noop */ }
38
+ #endif
39
+
35
40
// SerialEvent functions are weak, so when the user doesn't define them,
36
41
// the linker just sets their address to 0 (which is checked below).
37
42
// The Serialx_available is just a wrapper around Serialx.available(),
38
43
// but we can refer to it weakly so we don't pull in the entire
39
44
// HardwareSerial instance if the user doesn't also refer to it.
40
45
extern void serialEvent () __attribute__((weak));
41
46
42
- #define PICO_STDIO_USB_TASK_INTERVAL_US 1000
43
- #define PICO_STDIO_USB_LOW_PRIORITY_IRQ 31
44
-
45
- #define USBD_VID (0x2E8A ) // Raspberry Pi
46
-
47
- #ifdef SERIALUSB_PID
48
- #define USBD_PID (SERIALUSB_PID)
49
- #else
50
- #define USBD_PID (0x000a ) // Raspberry Pi Pico SDK CDC
51
- #endif
52
-
53
- #define USBD_DESC_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN)
54
- #define USBD_MAX_POWER_MA (250 )
55
-
56
- #define USBD_ITF_CDC (0 ) // needs 2 interfaces
57
- #define USBD_ITF_MAX (2 )
58
-
59
- #define USBD_CDC_EP_CMD (0x81 )
60
- #define USBD_CDC_EP_OUT (0x02 )
61
- #define USBD_CDC_EP_IN (0x82 )
62
- #define USBD_CDC_CMD_MAX_SIZE (8 )
63
- #define USBD_CDC_IN_OUT_MAX_SIZE (64 )
64
-
65
- #define USBD_STR_0 (0x00 )
66
- #define USBD_STR_MANUF (0x01 )
67
- #define USBD_STR_PRODUCT (0x02 )
68
- #define USBD_STR_SERIAL (0x03 )
69
- #define USBD_STR_CDC (0x04 )
70
-
71
- // Note: descriptors returned from callbacks must exist long enough for transfer to complete
72
-
73
- static const tusb_desc_device_t usbd_desc_device = {
74
- .bLength = sizeof (tusb_desc_device_t ),
75
- .bDescriptorType = TUSB_DESC_DEVICE,
76
- .bcdUSB = 0x0200 ,
77
- .bDeviceClass = TUSB_CLASS_CDC,
78
- .bDeviceSubClass = MISC_SUBCLASS_COMMON,
79
- .bDeviceProtocol = MISC_PROTOCOL_IAD,
80
- .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
81
- .idVendor = USBD_VID,
82
- .idProduct = USBD_PID,
83
- .bcdDevice = 0x0100 ,
84
- .iManufacturer = USBD_STR_MANUF,
85
- .iProduct = USBD_STR_PRODUCT,
86
- .iSerialNumber = USBD_STR_SERIAL,
87
- .bNumConfigurations = 1 ,
88
- };
89
-
90
- static const uint8_t usbd_desc_cfg[USBD_DESC_LEN] = {
91
- TUD_CONFIG_DESCRIPTOR (1 , USBD_ITF_MAX, USBD_STR_0, USBD_DESC_LEN,
92
- TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, USBD_MAX_POWER_MA),
93
-
94
- TUD_CDC_DESCRIPTOR (USBD_ITF_CDC, USBD_STR_CDC, USBD_CDC_EP_CMD,
95
- USBD_CDC_CMD_MAX_SIZE, USBD_CDC_EP_OUT, USBD_CDC_EP_IN, USBD_CDC_IN_OUT_MAX_SIZE),
96
- };
97
-
98
- static char _idString[PICO_UNIQUE_BOARD_ID_SIZE_BYTES * 2 + 1 ];
99
-
100
- static const char *const usbd_desc_str[] = {
101
- [USBD_STR_0] = " " ,
102
- [USBD_STR_MANUF] = " Raspberry Pi" ,
103
- [USBD_STR_PRODUCT] = " PicoArduino" ,
104
- [USBD_STR_SERIAL] = _idString,
105
- [USBD_STR_CDC] = " Board CDC" ,
106
- };
107
-
108
- const uint8_t *tud_descriptor_device_cb (void ) {
109
- return (const uint8_t *)&usbd_desc_device;
110
- }
111
-
112
- const uint8_t *tud_descriptor_configuration_cb (uint8_t index) {
113
- (void )index;
114
- return usbd_desc_cfg;
115
- }
116
-
117
- const uint16_t *tud_descriptor_string_cb (uint8_t index, uint16_t langid) {
118
- #define DESC_STR_MAX (20 )
119
- static uint16_t desc_str[DESC_STR_MAX];
120
-
121
- uint8_t len;
122
- if (index == 0 ) {
123
- desc_str[1 ] = 0x0409 ; // supported language is English
124
- len = 1 ;
125
- } else {
126
- if (index >= sizeof (usbd_desc_str) / sizeof (usbd_desc_str[0 ])) {
127
- return NULL ;
128
- }
129
- const char *str = usbd_desc_str[index];
130
- for (len = 0 ; len < DESC_STR_MAX - 1 && str[len]; ++len) {
131
- desc_str[1 + len] = str[len];
132
- }
133
- }
134
-
135
- // first byte is length (including header), second byte is string type
136
- desc_str[0 ] = (TUSB_DESC_STRING << 8 ) | (2 * len + 2 );
137
47
138
- return desc_str;
139
- }
140
-
141
- static mutex_t usb_mutex;
142
-
143
- static void low_priority_worker_irq () {
144
- // if the mutex is already owned, then we are in user code
145
- // in this file which will do a tud_task itself, so we'll just do nothing
146
- // until the next tick; we won't starve
147
- if (mutex_try_enter (&usb_mutex, NULL )) {
148
- tud_task ();
149
- mutex_exit (&usb_mutex);
150
- }
151
- }
152
-
153
- static int64_t timer_task (__unused alarm_id_t id, __unused void *user_data) {
154
- irq_set_pending (PICO_STDIO_USB_LOW_PRIORITY_IRQ);
155
- return PICO_STDIO_USB_TASK_INTERVAL_US;
156
- }
48
+ extern mutex_t __usb_mutex;
157
49
158
50
void SerialUSB::begin (unsigned long baud) {
159
51
(void ) baud; // ignored
@@ -162,24 +54,6 @@ void SerialUSB::begin(unsigned long baud) {
162
54
return ;
163
55
}
164
56
165
- // Get ID string into human readable serial number
166
- pico_unique_board_id_t id;
167
- pico_get_unique_board_id (&id);
168
- _idString[0 ] = 0 ;
169
- for (auto i = 0 ; i < PICO_UNIQUE_BOARD_ID_SIZE_BYTES; i++) {
170
- char hx[3 ];
171
- sprintf (hx, " %02X" , id.id [i]);
172
- strcat (_idString, hx);
173
- }
174
-
175
- tusb_init ();
176
-
177
- irq_set_exclusive_handler (PICO_STDIO_USB_LOW_PRIORITY_IRQ, low_priority_worker_irq);
178
- irq_set_enabled (PICO_STDIO_USB_LOW_PRIORITY_IRQ, true );
179
-
180
- mutex_init (&usb_mutex);
181
- add_alarm_in_us (PICO_STDIO_USB_TASK_INTERVAL_US, timer_task, NULL , true );
182
-
183
57
_running = true ;
184
58
}
185
59
@@ -188,7 +62,7 @@ void SerialUSB::end() {
188
62
}
189
63
190
64
int SerialUSB::peek () {
191
- CoreMutex m (&usb_mutex );
65
+ CoreMutex m (&__usb_mutex );
192
66
if (!_running || !m) {
193
67
return 0 ;
194
68
}
@@ -198,7 +72,7 @@ int SerialUSB::peek() {
198
72
}
199
73
200
74
int SerialUSB::read () {
201
- CoreMutex m (&usb_mutex );
75
+ CoreMutex m (&__usb_mutex );
202
76
if (!_running || !m) {
203
77
return -1 ;
204
78
}
@@ -210,7 +84,7 @@ int SerialUSB::read() {
210
84
}
211
85
212
86
int SerialUSB::available () {
213
- CoreMutex m (&usb_mutex );
87
+ CoreMutex m (&__usb_mutex );
214
88
if (!_running || !m) {
215
89
return 0 ;
216
90
}
@@ -219,7 +93,7 @@ int SerialUSB::available() {
219
93
}
220
94
221
95
int SerialUSB::availableForWrite () {
222
- CoreMutex m (&usb_mutex );
96
+ CoreMutex m (&__usb_mutex );
223
97
if (!_running || !m) {
224
98
return 0 ;
225
99
}
@@ -228,7 +102,7 @@ int SerialUSB::availableForWrite() {
228
102
}
229
103
230
104
void SerialUSB::flush () {
231
- CoreMutex m (&usb_mutex );
105
+ CoreMutex m (&__usb_mutex );
232
106
if (!_running || !m) {
233
107
return ;
234
108
}
@@ -241,7 +115,7 @@ size_t SerialUSB::write(uint8_t c) {
241
115
}
242
116
243
117
size_t SerialUSB::write (const uint8_t *buf, size_t length) {
244
- CoreMutex m (&usb_mutex );
118
+ CoreMutex m (&__usb_mutex );
245
119
if (!_running || !m) {
246
120
return 0 ;
247
121
}
@@ -276,7 +150,7 @@ size_t SerialUSB::write(const uint8_t *buf, size_t length) {
276
150
}
277
151
278
152
SerialUSB::operator bool () {
279
- CoreMutex m (&usb_mutex );
153
+ CoreMutex m (&__usb_mutex );
280
154
if (!_running || !m) {
281
155
return false ;
282
156
}
0 commit comments