Skip to content

Commit 60b0b69

Browse files
committed
nrf: Add tinyusb support for nrf52840.
Add nrf-port finyusb driver files. USB CDC can be activated by board configuration files using the MICROPY_HW_USB_CDC. Updating BLE driver, Makefile, nrfx-glue and main.c to plug in the tinyusb stack.
1 parent 1571120 commit 60b0b69

File tree

10 files changed

+485
-1
lines changed

10 files changed

+485
-1
lines changed

ports/nrf/Makefile

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ INC += -I../../lib/nrfx/drivers
6666
INC += -I../../lib/nrfx/drivers/include
6767
INC += -I../../lib/nrfx/mdk
6868
INC += -I../../lib/nrfx/hal
69+
INC += -I../../lib/nrfx/drivers/src/
6970

7071
MCU_VARIANT_UPPER = $(shell echo $(MCU_VARIANT) | tr '[:lower:]' '[:upper:]')
7172
MCU_SUB_VARIANT_UPPER = $(shell echo $(MCU_SUB_VARIANT) | tr '[:lower:]' '[:upper:]')
@@ -183,6 +184,8 @@ SRC_NRFX += $(addprefix lib/nrfx/drivers/src/,\
183184
nrfx_pwm.c \
184185
nrfx_gpiote.c \
185186
nrfx_nvmc.c \
187+
nrfx_power.c \
188+
nrfx_clock.c \
186189
)
187190

188191
SRC_C += \
@@ -198,6 +201,34 @@ SRC_C += \
198201
drivers/bluetooth/ble_drv.c \
199202
drivers/bluetooth/ble_uart.c \
200203

204+
ifeq ($(MCU_SUB_VARIANT), nrf52840)
205+
206+
INC += -I./drivers/usb
207+
INC += -I../../lib/tinyusb/src
208+
209+
210+
# If SoftDevice is selected.
211+
ifneq ($(SD), )
212+
# For external tinyusb drivers to enable SoftDevice mode.
213+
CFLAGS += -DSOFTDEVICE_PRESENT
214+
endif
215+
216+
SRC_C += $(addprefix drivers/usb/,\
217+
usb_cdc.c \
218+
usb_descriptors.c \
219+
)
220+
221+
SRC_C += $(addprefix lib/tinyusb/src/,\
222+
common/tusb_fifo.c \
223+
device/usbd.c \
224+
device/usbd_control.c \
225+
class/cdc/cdc_device.c \
226+
tusb.c \
227+
portable/nordic/nrf5x/dcd_nrf5x.c \
228+
portable/nordic/nrf5x/hal_nrf5x.c \
229+
)
230+
endif
231+
201232
DRIVERS_SRC_C += $(addprefix modules/,\
202233
machine/modmachine.c \
203234
machine/uart.c \

ports/nrf/drivers/bluetooth/ble_drv.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@
4040
#include "mphalport.h"
4141

4242

43+
#if MICROPY_HW_USB_CDC
44+
#include "usb_cdc.h"
45+
#endif
46+
4347
#define BLE_DRIVER_VERBOSE 0
4448

4549
#if BLE_DRIVER_VERBOSE
@@ -952,6 +956,10 @@ static void sd_evt_handler(uint32_t evt_id) {
952956
// unhandled event!
953957
break;
954958
}
959+
#if MICROPY_HW_USB_CDC
960+
// Farward SOC events to USB CDC driver.
961+
usb_cdc_sd_event_handler(evt_id);
962+
#endif
955963
}
956964

957965
static void ble_evt_handler(ble_evt_t * p_ble_evt) {

ports/nrf/drivers/usb/tusb_config.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2019 Damien P. George
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
#ifndef MICROPY_INCLUDED_NRF_TUSB_CONFIG_H
27+
#define MICROPY_INCLUDED_NRF_TUSB_CONFIG_H
28+
29+
// Common configuration
30+
31+
#define CFG_TUSB_MCU OPT_MCU_NRF5X
32+
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE
33+
34+
#define CFG_TUSB_MEM_SECTION
35+
#define CFG_TUSB_MEM_ALIGN TU_ATTR_ALIGNED(4)
36+
37+
// Device configuration
38+
39+
#define CFG_TUD_ENDOINT0_SIZE (64)
40+
#define CFG_TUD_CDC (1)
41+
#define CFG_TUD_CDC_RX_BUFSIZE (64)
42+
#define CFG_TUD_CDC_TX_BUFSIZE (64)
43+
44+
#endif // MICROPY_INCLUDED_NRF_TUSB_CONFIG_H

ports/nrf/drivers/usb/usb_cdc.c

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
/*
2+
* The MIT License (MIT)
3+
*
4+
* Copyright (c) 2019 Ha Thach (tinyusb.org)
5+
* Copyright (c) 2019 Glenn Ruben Bakke
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
* THE SOFTWARE.
24+
*
25+
* This file is part of the TinyUSB stack.
26+
*/
27+
28+
#include "py/mphal.h"
29+
30+
#if MICROPY_HW_USB_CDC
31+
32+
#include "tusb.h"
33+
#include "nrfx.h"
34+
#include "nrfx_power.h"
35+
#include "nrfx_uart.h"
36+
#include "py/ringbuf.h"
37+
38+
#ifdef BLUETOOTH_SD
39+
#include "nrf_sdm.h"
40+
#include "nrf_soc.h"
41+
#include "ble_drv.h"
42+
#endif
43+
44+
extern void tusb_hal_nrf_power_event(uint32_t event);
45+
46+
static void cdc_task(void);
47+
48+
static uint8_t rx_ringbuf_array[1024];
49+
static uint8_t tx_ringbuf_array[1024];
50+
static volatile ringbuf_t rx_ringbuf;
51+
static volatile ringbuf_t tx_ringbuf;
52+
53+
static void board_init(void) {
54+
// Config clock source.
55+
#ifndef BLUETOOTH_SD
56+
NRF_CLOCK->LFCLKSRC = (uint32_t)((CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos) & CLOCK_LFCLKSRC_SRC_Msk);
57+
NRF_CLOCK->TASKS_LFCLKSTART = 1UL;
58+
#endif
59+
60+
// Priorities 0, 1, 4 (nRF52) are reserved for SoftDevice
61+
// 2 is highest for application
62+
NRFX_IRQ_PRIORITY_SET(USBD_IRQn, 2);
63+
64+
// USB power may already be ready at this time -> no event generated
65+
// We need to invoke the handler based on the status initially
66+
uint32_t usb_reg;
67+
68+
#ifdef BLUETOOTH_SD
69+
uint8_t sd_en = false;
70+
sd_softdevice_is_enabled(&sd_en);
71+
72+
if (sd_en) {
73+
sd_power_usbdetected_enable(true);
74+
sd_power_usbpwrrdy_enable(true);
75+
sd_power_usbremoved_enable(true);
76+
77+
sd_power_usbregstatus_get(&usb_reg);
78+
} else
79+
#endif
80+
{
81+
// Power module init
82+
const nrfx_power_config_t pwr_cfg = { 0 };
83+
nrfx_power_init(&pwr_cfg);
84+
85+
// Register tusb function as USB power handler
86+
const nrfx_power_usbevt_config_t config = { .handler = (nrfx_power_usb_event_handler_t) tusb_hal_nrf_power_event };
87+
nrfx_power_usbevt_init(&config);
88+
89+
nrfx_power_usbevt_enable();
90+
91+
usb_reg = NRF_POWER->USBREGSTATUS;
92+
}
93+
94+
if (usb_reg & POWER_USBREGSTATUS_VBUSDETECT_Msk) {
95+
tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_DETECTED);
96+
}
97+
98+
#ifndef BLUETOOTH_SD
99+
if (usb_reg & POWER_USBREGSTATUS_OUTPUTRDY_Msk) {
100+
tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_READY);
101+
}
102+
#endif
103+
}
104+
105+
static bool cdc_rx_any(void) {
106+
return rx_ringbuf.iput != rx_ringbuf.iget;
107+
}
108+
109+
static int cdc_rx_char(void) {
110+
return ringbuf_get((ringbuf_t*)&rx_ringbuf);
111+
}
112+
113+
static bool cdc_tx_any(void) {
114+
return tx_ringbuf.iput != tx_ringbuf.iget;
115+
}
116+
117+
static int cdc_tx_char(void) {
118+
return ringbuf_get((ringbuf_t*)&tx_ringbuf);
119+
}
120+
121+
static void cdc_task(void)
122+
{
123+
if ( tud_cdc_connected() ) {
124+
// connected and there are data available
125+
while (tud_cdc_available()) {
126+
int c;
127+
uint32_t count = tud_cdc_read(&c, 1);
128+
(void)count;
129+
ringbuf_put((ringbuf_t*)&rx_ringbuf, c);
130+
}
131+
132+
int chars = 0;
133+
while (cdc_tx_any()) {
134+
if (chars < 64) {
135+
tud_cdc_write_char(cdc_tx_char());
136+
chars++;
137+
} else {
138+
chars = 0;
139+
tud_cdc_write_flush();
140+
}
141+
}
142+
143+
tud_cdc_write_flush();
144+
}
145+
}
146+
147+
static void usb_cdc_loop(void) {
148+
tud_task();
149+
cdc_task();
150+
}
151+
152+
int usb_cdc_init(void)
153+
{
154+
static bool initialized = false;
155+
if (!initialized) {
156+
157+
#if BLUETOOTH_SD
158+
// Initialize the clock and BLE stack.
159+
ble_drv_stack_enable();
160+
#endif
161+
162+
board_init();
163+
initialized = true;
164+
}
165+
166+
rx_ringbuf.buf = rx_ringbuf_array;
167+
rx_ringbuf.size = sizeof(rx_ringbuf_array);
168+
rx_ringbuf.iget = 0;
169+
rx_ringbuf.iput = 0;
170+
171+
tx_ringbuf.buf = tx_ringbuf_array;
172+
tx_ringbuf.size = sizeof(tx_ringbuf_array);
173+
tx_ringbuf.iget = 0;
174+
tx_ringbuf.iput = 0;
175+
176+
tusb_init();
177+
178+
return 0;
179+
}
180+
181+
#ifdef BLUETOOTH_SD
182+
// process SOC event from SD
183+
void usb_cdc_sd_event_handler(uint32_t soc_evt) {
184+
/*------------- usb power event handler -------------*/
185+
int32_t usbevt = (soc_evt == NRF_EVT_POWER_USB_DETECTED ) ? NRFX_POWER_USB_EVT_DETECTED:
186+
(soc_evt == NRF_EVT_POWER_USB_POWER_READY) ? NRFX_POWER_USB_EVT_READY :
187+
(soc_evt == NRF_EVT_POWER_USB_REMOVED ) ? NRFX_POWER_USB_EVT_REMOVED : -1;
188+
189+
if (usbevt >= 0) {
190+
tusb_hal_nrf_power_event(usbevt);
191+
}
192+
}
193+
#endif
194+
195+
int mp_hal_stdin_rx_chr(void) {
196+
for (;;) {
197+
usb_cdc_loop();
198+
if (cdc_rx_any()) {
199+
return cdc_rx_char();
200+
}
201+
}
202+
203+
return 0;
204+
}
205+
206+
void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {
207+
208+
for (const char *top = str + len; str < top; str++) {
209+
ringbuf_put((ringbuf_t*)&tx_ringbuf, *str);
210+
usb_cdc_loop();
211+
}
212+
}
213+
214+
void mp_hal_stdout_tx_strn_cooked(const char *str, mp_uint_t len) {
215+
216+
for (const char *top = str + len; str < top; str++) {
217+
if (*str == '\n') {
218+
ringbuf_put((ringbuf_t*)&tx_ringbuf, '\r');
219+
usb_cdc_loop();
220+
}
221+
ringbuf_put((ringbuf_t*)&tx_ringbuf, *str);
222+
usb_cdc_loop();
223+
}
224+
}
225+
226+
#endif // MICROPY_HW_USB_CDC

ports/nrf/drivers/usb/usb_cdc.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2019 Glenn Ruben Bakke
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#ifndef NRF_DRIVERS_USB_CDC_H__
28+
#define NRF_DRIVERS_USB_CDC_H__
29+
30+
#include "tusb.h"
31+
32+
void usb_cdc_init(void);
33+
34+
void usb_cdc_loop(void);
35+
int usb_cdc_read_char(void);
36+
void usb_cdc_write_char(char c);
37+
38+
void usb_cdc_sd_event_handler(uint32_t soc_evt);
39+
40+
#endif // NRF_DRIVERS_USB_CDC_H__

0 commit comments

Comments
 (0)