4
4
* SPDX-License-Identifier: BSD-3-Clause
5
5
*/
6
6
7
- #if !defined( LIB_TINYUSB_HOST ) && !defined( LIB_TINYUSB_DEVICE )
7
+ #ifndef LIB_TINYUSB_HOST
8
8
#include "tusb.h"
9
+ #include "pico/stdio_usb.h"
10
+
11
+ // these may not be set if the user is providing tud support (i.e. LIB_TINYUSB_DEVICE is 1 because
12
+ // the user linked in tinyusb_device) but they haven't selected CDC
13
+ #if (CFG_TUD_ENABLED | TUSB_OPT_DEVICE_ENABLED ) && CFG_TUD_CDC
9
14
15
+ #include "pico/binary_info.h"
10
16
#include "pico/time.h"
11
17
#include "pico/stdio/driver.h"
12
- #include "pico/binary_info.h"
13
18
#include "pico/mutex.h"
14
19
#include "hardware/irq.h"
15
20
21
+ static mutex_t stdio_usb_mutex ;
22
+ #ifndef NDEBUG
23
+ static uint8_t stdio_usb_core_num ;
24
+ #endif
25
+
26
+ // when tinyusb_device is explicitly linked we do no background tud processing
27
+ #if !LIB_TINYUSB_DEVICE
16
28
#ifdef PICO_STDIO_USB_LOW_PRIORITY_IRQ
17
29
static_assert (PICO_STDIO_USB_LOW_PRIORITY_IRQ >= NUM_IRQS - NUM_USER_IRQS , "" );
18
30
#define low_priority_irq_num PICO_STDIO_USB_LOW_PRIORITY_IRQ
19
31
#else
20
32
static uint8_t low_priority_irq_num ;
21
33
#endif
22
34
23
- static mutex_t stdio_usb_mutex ;
24
-
25
35
static void low_priority_worker_irq (void ) {
26
36
// if the mutex is already owned, then we are in user code
27
37
// in this file which will do a tud_task itself, so we'll just do nothing
@@ -32,10 +42,16 @@ static void low_priority_worker_irq(void) {
32
42
}
33
43
}
34
44
45
+ static void usb_irq (void ) {
46
+ irq_set_pending (low_priority_irq_num );
47
+ }
48
+
35
49
static int64_t timer_task (__unused alarm_id_t id , __unused void * user_data ) {
50
+ assert (stdio_usb_core_num == get_core_num ()); // if this fails, you have initialized stdio_usb on the wrong core
36
51
irq_set_pending (low_priority_irq_num );
37
52
return PICO_STDIO_USB_TASK_INTERVAL_US ;
38
53
}
54
+ #endif
39
55
40
56
static void stdio_usb_out_chars (const char * buf , int length ) {
41
57
static uint64_t last_avail_time ;
@@ -95,13 +111,23 @@ stdio_driver_t stdio_usb = {
95
111
};
96
112
97
113
bool stdio_usb_init (void ) {
114
+ #ifndef NDEBUG
115
+ stdio_usb_core_num = (uint8_t )get_core_num ();
116
+ #endif
98
117
#if !PICO_NO_BI_STDIO_USB
99
118
bi_decl_if_func_used (bi_program_feature ("USB stdin / stdout" ));
100
119
#endif
101
120
102
- // initialize TinyUSB
121
+ #if !defined(LIB_TINYUSB_DEVICE )
122
+ // initialize TinyUSB, as user hasn't explicitly linked it
103
123
tusb_init ();
124
+ #else
125
+ assert (tud_inited ()); // we expect the caller to have initialized if they are using TinyUSB
126
+ #endif
104
127
128
+ mutex_init (& stdio_usb_mutex );
129
+ bool rc = true;
130
+ #if !LIB_TINYUSB_DEVICE
105
131
#ifdef PICO_STDIO_USB_LOW_PRIORITY_IRQ
106
132
user_irq_claim (PICO_STDIO_USB_LOW_PRIORITY_IRQ );
107
133
#else
@@ -110,8 +136,13 @@ bool stdio_usb_init(void) {
110
136
irq_set_exclusive_handler (low_priority_irq_num , low_priority_worker_irq );
111
137
irq_set_enabled (low_priority_irq_num , true);
112
138
113
- mutex_init (& stdio_usb_mutex );
114
- bool rc = add_alarm_in_us (PICO_STDIO_USB_TASK_INTERVAL_US , timer_task , NULL , true);
139
+ if (irq_has_shared_handler (USBCTRL_IRQ )) {
140
+ // we can use a shared handler to notice when there may be work to do
141
+ irq_add_shared_handler (USBCTRL_IRQ , usb_irq , PICO_SHARED_IRQ_HANDLER_LOWEST_ORDER_PRIORITY );
142
+ } else {
143
+ rc = add_alarm_in_us (PICO_STDIO_USB_TASK_INTERVAL_US , timer_task , NULL , true);
144
+ }
145
+ #endif
115
146
if (rc ) {
116
147
stdio_set_driver_enabled (& stdio_usb , true);
117
148
#if PICO_STDIO_USB_CONNECT_WAIT_TIMEOUT_MS
@@ -138,9 +169,15 @@ bool stdio_usb_connected(void) {
138
169
return tud_cdc_connected ();
139
170
}
140
171
#else
141
- #include "pico/stdio_usb.h"
142
- #warning stdio USB was configured, but is being disabled as TinyUSB is explicitly linked
172
+ #warning stdio USB was configured along with user use of TinyUSB device mode, but CDC is not enabled
143
173
bool stdio_usb_init (void ) {
144
174
return false;
145
175
}
146
- #endif
176
+ #endif // CFG_TUD_ENABLED && CFG_TUD_CDC
177
+ #else
178
+ #warning stdio USB was configured, but is being disabled as TinyUSB host is explicitly linked
179
+ bool stdio_usb_init (void ) {
180
+ return false;
181
+ }
182
+ #endif // !LIB_TINYUSB_HOST
183
+
0 commit comments