27
27
#if defined ARDUINO_ARCH_RP2040 & TUSB_OPT_DEVICE_ENABLED
28
28
29
29
#include " Arduino.h"
30
- #include " arduino/Adafruit_USBD_Device.h"
31
-
32
30
#include " pico/bootrom.h"
31
+ #include " pico/time.h"
32
+ #include " hardware/irq.h"
33
+ #include " pico/mutex.h"
33
34
#include " pico/unique_id.h"
34
35
36
+ #include " tusb.h"
37
+ #include " arduino/Adafruit_TinyUSB_API.h"
38
+
35
39
// --------------------------------------------------------------------+
36
40
// Forward USB interrupt events to TinyUSB IRQ Handler
37
41
// rp2040 implementation will install approriate handler when initializing
42
46
// Porting API
43
47
// --------------------------------------------------------------------+
44
48
49
+ // USB processing will be a periodic timer task
50
+ #define USB_TASK_INTERVAL 1000
51
+ #define USB_TASK_IRQ 31
52
+
53
+ // Big, global USB mutex, shared with all USB devices to make sure we don't
54
+ // have multiple cores updating the TUSB state in parallel
55
+ mutex_t __usb_mutex;
56
+
57
+ static void usb_irq () {
58
+ // if the mutex is already owned, then we are in user code
59
+ // in this file which will do a tud_task itself, so we'll just do nothing
60
+ // until the next tick; we won't starve
61
+ if (mutex_try_enter (&__usb_mutex, NULL )) {
62
+ tud_task ();
63
+ mutex_exit (&__usb_mutex);
64
+ }
65
+ }
66
+
67
+ static int64_t timer_task (__unused alarm_id_t id, __unused void *user_data) {
68
+ irq_set_pending (USB_TASK_IRQ);
69
+ return USB_TASK_INTERVAL;
70
+ }
71
+
45
72
void TinyUSB_Port_InitDevice (uint8_t rhport)
46
73
{
47
74
(void ) rhport;
48
75
49
- // no specific hardware initialization
50
- // TOOD maybe set up sdtio usb
76
+ mutex_init (&__usb_mutex);
77
+ tusb_init ();
78
+
79
+ irq_set_exclusive_handler (USB_TASK_IRQ, usb_irq);
80
+ irq_set_enabled (USB_TASK_IRQ, true );
81
+
82
+ add_alarm_in_us (USB_TASK_INTERVAL, timer_task, NULL , true );
51
83
}
52
84
53
85
void TinyUSB_Port_EnterDFU (void )
@@ -62,4 +94,25 @@ uint8_t TinyUSB_Port_GetSerialNumber(uint8_t serial_id[16])
62
94
return PICO_UNIQUE_BOARD_ID_SIZE_BYTES;
63
95
}
64
96
97
+ // --------------------------------------------------------------------+
98
+ // Core API
99
+ // Implement Core API since rp2040 need mutex for calling tud_task in
100
+ // IRQ context
101
+ // --------------------------------------------------------------------+
102
+
103
+ extern " C"
104
+ {
105
+
106
+ void TinyUSB_Device_Task (void )
107
+ {
108
+ // Since tud_task() is also invoked in ISR, we need to get the mutex first
109
+ if (mutex_try_enter (&__usb_mutex, NULL ))
110
+ {
111
+ tud_task ();
112
+ mutex_exit (&__usb_mutex);
113
+ }
114
+ }
115
+
116
+ }
117
+
65
118
#endif // USE_TINYUSB
0 commit comments