mirror of
https://github.com/micropython/micropython.git
synced 2025-07-21 13:01:10 +02:00
nrf: Consolidate all stdio functions.
Consolidate CDC, UART and NUS stdio interfaces into the one handler. Allows any/all of them to be enabled separately. Updates UART REPL to use similar define to other platforms: `MICROPY_HW_ENABLE_UART_REPL`. USB now uses the shared/tinyusb CDC implementation. Signed-off-by: Andrew Leech <andrew@alelec.net>
This commit is contained in:
committed by
Damien George
parent
e1fe62f4fc
commit
19075695da
@@ -80,15 +80,16 @@ INC += -I./modules/music
|
||||
INC += -I./modules/ble
|
||||
INC += -I./modules/board
|
||||
INC += -I./modules/nrf
|
||||
INC += -I../../shared/readline
|
||||
INC += -I./drivers/bluetooth
|
||||
INC += -I./drivers
|
||||
INC += -I./drivers/bluetooth
|
||||
INC += -I./drivers/usb
|
||||
INC += -I../../lib/nrfx/
|
||||
INC += -I../../lib/nrfx/drivers
|
||||
INC += -I../../lib/nrfx/drivers/include
|
||||
INC += -I../../lib/nrfx/mdk
|
||||
INC += -I../../lib/nrfx/hal
|
||||
INC += -I../../lib/nrfx/drivers/src/
|
||||
INC += -I../../shared/readline
|
||||
|
||||
MCU_VARIANT_UPPER = $(shell echo $(MCU_VARIANT) | tr '[:lower:]' '[:upper:]')
|
||||
MCU_SUB_VARIANT_UPPER = $(shell echo $(MCU_SUB_VARIANT) | tr '[:lower:]' '[:upper:]')
|
||||
@@ -183,9 +184,12 @@ SRC_SHARED_C += $(addprefix shared/,\
|
||||
libc/string0.c \
|
||||
readline/readline.c \
|
||||
runtime/pyexec.c \
|
||||
runtime/stdout_helpers.c \
|
||||
runtime/sys_stdio_mphal.c \
|
||||
runtime/interrupt_char.c \
|
||||
tinyusb/mp_usbd.c \
|
||||
tinyusb/mp_usbd_cdc.c \
|
||||
tinyusb/mp_usbd_descriptor.c \
|
||||
timeutils/timeutils.c \
|
||||
)
|
||||
|
||||
@@ -200,13 +204,13 @@ endif
|
||||
SRC_NRFX += $(addprefix lib/nrfx/drivers/src/,\
|
||||
prs/nrfx_prs.c \
|
||||
nrfx_uart.c \
|
||||
nrfx_uarte.c \
|
||||
nrfx_uarte.c \
|
||||
nrfx_adc.c \
|
||||
nrfx_saadc.c \
|
||||
nrfx_temp.c \
|
||||
nrfx_rng.c \
|
||||
nrfx_twi.c \
|
||||
nrfx_twim.c \
|
||||
nrfx_twim.c \
|
||||
nrfx_spi.c \
|
||||
nrfx_spim.c \
|
||||
nrfx_rtc.c \
|
||||
@@ -234,21 +238,17 @@ SRC_C += \
|
||||
$(wildcard $(BOARD_DIR)/*.c) \
|
||||
|
||||
ifeq ($(MCU_SUB_VARIANT), nrf52840)
|
||||
# Add support for USB using TinyUSB.
|
||||
|
||||
INC += -I./drivers/usb
|
||||
INC += -I../../lib/tinyusb/src
|
||||
|
||||
|
||||
# If SoftDevice is selected.
|
||||
ifneq ($(SD), )
|
||||
# For external tinyusb drivers to enable SoftDevice mode.
|
||||
CFLAGS += -DSOFTDEVICE_PRESENT
|
||||
endif
|
||||
|
||||
SRC_C += $(addprefix drivers/usb/,\
|
||||
usb_cdc.c \
|
||||
usb_descriptors.c \
|
||||
)
|
||||
SRC_C += drivers/usb/usb_cdc.c
|
||||
|
||||
SRC_C += $(addprefix lib/tinyusb/src/,\
|
||||
common/tusb_fifo.c \
|
||||
@@ -259,6 +259,7 @@ SRC_C += $(addprefix lib/tinyusb/src/,\
|
||||
portable/nordic/nrf5x/dcd_nrf5x.c \
|
||||
)
|
||||
|
||||
LDFLAGS += -Wl,--wrap=dcd_event_handler
|
||||
endif
|
||||
|
||||
DRIVERS_SRC_C += $(addprefix modules/,\
|
||||
@@ -331,9 +332,9 @@ hex: $(BUILD)/$(OUTPUT_FILENAME).hex
|
||||
$(BUILD)/$(OUTPUT_FILENAME).hex: $(BUILD)/$(OUTPUT_FILENAME).elf
|
||||
$(OBJCOPY) -O ihex $< $@
|
||||
|
||||
FLASHER ?=
|
||||
FLASHER ?= jlink
|
||||
|
||||
ifeq ($(FLASHER),)
|
||||
ifeq ($(FLASHER), jlink)
|
||||
|
||||
ifeq ($(MCU_VARIANT), nrf91)
|
||||
|
||||
|
@@ -3,10 +3,15 @@
|
||||
|
||||
// SD specific configurations.
|
||||
|
||||
#ifndef MICROPY_PY_BLE_NUS
|
||||
// Nordic UART Service
|
||||
// If enabled, REPL will be available on this interface.
|
||||
#define MICROPY_PY_BLE_NUS (0)
|
||||
#endif
|
||||
|
||||
#if (BLUETOOTH_SD == 110)
|
||||
|
||||
#define MICROPY_PY_BLE (1)
|
||||
#define MICROPY_PY_BLE_NUS (0)
|
||||
#define BLUETOOTH_WEBBLUETOOTH_REPL (0)
|
||||
#define MICROPY_PY_UBLUEPY (1)
|
||||
#define MICROPY_PY_UBLUEPY_PERIPHERAL (1)
|
||||
@@ -14,7 +19,6 @@
|
||||
#elif (BLUETOOTH_SD == 132)
|
||||
|
||||
#define MICROPY_PY_BLE (1)
|
||||
#define MICROPY_PY_BLE_NUS (0)
|
||||
#define BLUETOOTH_WEBBLUETOOTH_REPL (0)
|
||||
#define MICROPY_PY_UBLUEPY (1)
|
||||
#define MICROPY_PY_UBLUEPY_PERIPHERAL (1)
|
||||
@@ -23,7 +27,6 @@
|
||||
#elif (BLUETOOTH_SD == 140)
|
||||
|
||||
#define MICROPY_PY_BLE (1)
|
||||
#define MICROPY_PY_BLE_NUS (0)
|
||||
#define BLUETOOTH_WEBBLUETOOTH_REPL (0)
|
||||
#define MICROPY_PY_UBLUEPY (1)
|
||||
#define MICROPY_PY_UBLUEPY_PERIPHERAL (1)
|
||||
@@ -39,8 +42,4 @@
|
||||
#define MICROPY_PY_BLE (0)
|
||||
#endif
|
||||
|
||||
#ifndef MICROPY_PY_BLE_NUS
|
||||
#define MICROPY_PY_BLE_NUS (0)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@@ -18,6 +18,7 @@
|
||||
#define MICROPY_PY_MACHINE_ADC (1)
|
||||
#define MICROPY_PY_MACHINE_TEMP (1)
|
||||
|
||||
#define MICROPY_HW_ENABLE_USBDEV (1)
|
||||
#define MICROPY_HW_USB_CDC (1)
|
||||
#define MICROPY_HW_HAS_LED (1)
|
||||
#define MICROPY_HW_HAS_SWITCH (0)
|
||||
|
@@ -37,6 +37,9 @@
|
||||
|
||||
#define MICROPY_HW_ENABLE_RNG (1)
|
||||
|
||||
#define MICROPY_HW_ENABLE_USBDEV (1)
|
||||
#define MICROPY_HW_USB_CDC (1)
|
||||
|
||||
#define MICROPY_HW_HAS_LED (1)
|
||||
#define MICROPY_HW_LED_COUNT (4)
|
||||
#define MICROPY_HW_LED_PULLUP (1)
|
||||
@@ -47,6 +50,7 @@
|
||||
#define MICROPY_HW_LED4 (16) // LED4
|
||||
|
||||
// UART config
|
||||
#define MICROPY_HW_ENABLE_UART_REPL (1)
|
||||
#define MICROPY_HW_UART1_RX (8)
|
||||
#define MICROPY_HW_UART1_TX (6)
|
||||
#define MICROPY_HW_UART1_CTS (7)
|
||||
|
@@ -9,9 +9,7 @@ ifeq ($(DFU),1)
|
||||
BOOTLOADER=open_bootloader
|
||||
BOOTLOADER_VERSION_MAJOR=1
|
||||
BOOTLOADER_VERSION_MINOR=2
|
||||
FLASHER=nrfutil
|
||||
else
|
||||
FLASHER=segger
|
||||
FLASHER ?= nrfutil
|
||||
endif
|
||||
|
||||
LD_FILES += boards/nrf52840_1M_256k.ld
|
||||
|
@@ -32,6 +32,7 @@
|
||||
#define MICROPY_BOARD_DEINIT XIAO_board_deinit
|
||||
#define MICROPY_BOARD_ENTER_BOOTLOADER(nargs, args) XIAO_board_enter_bootloader()
|
||||
|
||||
#define MICROPY_HW_ENABLE_USBDEV (1)
|
||||
#define MICROPY_HW_USB_CDC (1)
|
||||
#define MICROPY_PY_MACHINE_UART (1)
|
||||
#define MICROPY_PY_MACHINE_HW_PWM (1)
|
||||
|
@@ -39,7 +39,7 @@
|
||||
#include "mphalport.h"
|
||||
|
||||
|
||||
#if MICROPY_HW_USB_CDC
|
||||
#if MICROPY_HW_ENABLE_USBDEV && MICROPY_HW_USB_CDC
|
||||
#include "usb_cdc.h"
|
||||
#endif
|
||||
|
||||
@@ -941,7 +941,7 @@ static void sd_evt_handler(uint32_t evt_id) {
|
||||
// unhandled event!
|
||||
break;
|
||||
}
|
||||
#if MICROPY_HW_USB_CDC
|
||||
#if MICROPY_HW_ENABLE_USBDEV && MICROPY_HW_USB_CDC
|
||||
// Forward SOC events to USB CDC driver.
|
||||
usb_cdc_sd_event_handler(evt_id);
|
||||
#endif
|
||||
|
@@ -97,20 +97,16 @@ static ubluepy_advertise_data_t m_adv_data_uart_service;
|
||||
static ubluepy_advertise_data_t m_adv_data_eddystone_url;
|
||||
#endif // BLUETOOTH_WEBBLUETOOTH_REPL
|
||||
|
||||
int mp_hal_stdin_rx_chr(void) {
|
||||
while (!ble_uart_enabled()) {
|
||||
// wait for connection
|
||||
int mp_ble_uart_stdin_rx_chr(void) {
|
||||
if (ble_uart_enabled() && !isBufferEmpty(mp_rx_ring_buffer)) {
|
||||
uint8_t byte = -1;
|
||||
bufferRead(mp_rx_ring_buffer, byte);
|
||||
return (int)byte;
|
||||
}
|
||||
while (isBufferEmpty(mp_rx_ring_buffer)) {
|
||||
;
|
||||
}
|
||||
|
||||
uint8_t byte;
|
||||
bufferRead(mp_rx_ring_buffer, byte);
|
||||
return (int)byte;
|
||||
return -1;
|
||||
}
|
||||
|
||||
mp_uint_t mp_hal_stdout_tx_strn(const char *str, size_t len) {
|
||||
mp_uint_t mp_ble_uart_stdout_tx_strn(const char *str, size_t len) {
|
||||
// Not connected: drop output
|
||||
if (!ble_uart_enabled()) return 0;
|
||||
|
||||
@@ -150,17 +146,8 @@ void ble_uart_tx_char(char c) {
|
||||
(uint8_t *)&c);
|
||||
}
|
||||
|
||||
void mp_hal_stdout_tx_strn_cooked(const char *str, mp_uint_t len) {
|
||||
for (const char *top = str + len; str < top; str++) {
|
||||
if (*str == '\n') {
|
||||
ble_uart_tx_char('\r');
|
||||
}
|
||||
ble_uart_tx_char(*str);
|
||||
}
|
||||
}
|
||||
|
||||
#if MICROPY_PY_SYS_STDFILES
|
||||
uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) {
|
||||
uintptr_t mp_ble_uart_stdio_poll(uintptr_t poll_flags) {
|
||||
uintptr_t ret = 0;
|
||||
if ((poll_flags & MP_STREAM_POLL_RD) && ble_uart_enabled()
|
||||
&& !isBufferEmpty(mp_rx_ring_buffer)) {
|
||||
|
@@ -37,6 +37,10 @@ void ble_uart_advertise(void);
|
||||
bool ble_uart_connected(void);
|
||||
bool ble_uart_enabled(void);
|
||||
|
||||
uintptr_t mp_ble_uart_stdio_poll(uintptr_t poll_flags);
|
||||
int mp_ble_uart_stdin_rx_chr(void);
|
||||
mp_uint_t mp_ble_uart_stdout_tx_strn(const char *str, size_t len);
|
||||
|
||||
#endif // BLUETOOTH_SD
|
||||
|
||||
#endif // BLUETOOTH_LE_UART_H__
|
||||
|
@@ -26,19 +26,9 @@
|
||||
#ifndef MICROPY_INCLUDED_NRF_TUSB_CONFIG_H
|
||||
#define MICROPY_INCLUDED_NRF_TUSB_CONFIG_H
|
||||
|
||||
// Common configuration
|
||||
|
||||
#define CFG_TUSB_MCU OPT_MCU_NRF5X
|
||||
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE
|
||||
|
||||
#define CFG_TUSB_MEM_SECTION
|
||||
#define CFG_TUSB_MEM_ALIGN TU_ATTR_ALIGNED(4)
|
||||
#include "shared/tinyusb/tusb_config.h"
|
||||
|
||||
// Device configuration
|
||||
|
||||
#define CFG_TUD_ENDOINT0_SIZE (64)
|
||||
#define CFG_TUD_CDC (1)
|
||||
#define CFG_TUD_CDC_RX_BUFSIZE (64)
|
||||
#define CFG_TUD_CDC_TX_BUFSIZE (64)
|
||||
#define CFG_TUSB_MCU OPT_MCU_NRF5X
|
||||
|
||||
#endif // MICROPY_INCLUDED_NRF_TUSB_CONFIG_H
|
||||
|
@@ -27,7 +27,7 @@
|
||||
|
||||
#include "py/mphal.h"
|
||||
|
||||
#if MICROPY_HW_USB_CDC
|
||||
#if MICROPY_HW_ENABLE_USBDEV && MICROPY_HW_USB_CDC
|
||||
|
||||
#include "nrfx.h"
|
||||
#include "nrfx_power.h"
|
||||
@@ -37,6 +37,9 @@
|
||||
#include "py/runtime.h"
|
||||
#include "shared/runtime/interrupt_char.h"
|
||||
#include "shared/tinyusb/mp_usbd.h"
|
||||
#include "shared/tinyusb/mp_usbd_cdc.h"
|
||||
#include "extmod/misc.h"
|
||||
#include <hal/nrf_ficr.h>
|
||||
|
||||
#ifdef BLUETOOTH_SD
|
||||
#include "nrf_sdm.h"
|
||||
@@ -46,13 +49,6 @@
|
||||
|
||||
extern void tusb_hal_nrf_power_event(uint32_t event);
|
||||
|
||||
static void cdc_task(bool tx);
|
||||
|
||||
static uint8_t rx_ringbuf_array[1024];
|
||||
static uint8_t tx_ringbuf_array[1024];
|
||||
static volatile ringbuf_t rx_ringbuf;
|
||||
static volatile ringbuf_t tx_ringbuf;
|
||||
|
||||
static void board_init(void) {
|
||||
// Config clock source.
|
||||
#ifndef BLUETOOTH_SD
|
||||
@@ -105,89 +101,27 @@ static void board_init(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool cdc_rx_any(void) {
|
||||
return rx_ringbuf.iput != rx_ringbuf.iget;
|
||||
}
|
||||
|
||||
static int cdc_rx_char(void) {
|
||||
return ringbuf_get((ringbuf_t*)&rx_ringbuf);
|
||||
}
|
||||
|
||||
static bool cdc_tx_any(void) {
|
||||
return tx_ringbuf.iput != tx_ringbuf.iget;
|
||||
}
|
||||
|
||||
static int cdc_tx_char(void) {
|
||||
return ringbuf_get((ringbuf_t*)&tx_ringbuf);
|
||||
}
|
||||
|
||||
static void cdc_task(bool tx)
|
||||
{
|
||||
if ( tud_cdc_connected() ) {
|
||||
// connected and there are data available
|
||||
while (tud_cdc_available()) {
|
||||
int c = tud_cdc_read_char();
|
||||
if (c == mp_interrupt_char) {
|
||||
rx_ringbuf.iget = 0;
|
||||
rx_ringbuf.iput = 0;
|
||||
mp_sched_keyboard_interrupt();
|
||||
} else {
|
||||
ringbuf_put((ringbuf_t*)&rx_ringbuf, c);
|
||||
}
|
||||
}
|
||||
|
||||
if (tx) {
|
||||
int chars = 0;
|
||||
while (cdc_tx_any()) {
|
||||
if (chars < 64) {
|
||||
tud_cdc_write_char(cdc_tx_char());
|
||||
chars++;
|
||||
} else {
|
||||
chars = 0;
|
||||
tud_cdc_write_flush();
|
||||
}
|
||||
}
|
||||
|
||||
tud_cdc_write_flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void usb_cdc_loop(void) {
|
||||
tud_task();
|
||||
cdc_task(true);
|
||||
}
|
||||
|
||||
void tud_cdc_rx_cb(uint8_t itf) {
|
||||
cdc_task(false);
|
||||
void mp_usbd_port_get_serial_number(char *serial_buf) {
|
||||
uint32_t deviceid[2];
|
||||
deviceid[0] = nrf_ficr_deviceid_get(NRF_FICR, 0);
|
||||
deviceid[1] = nrf_ficr_deviceid_get(NRF_FICR, 1);
|
||||
MP_STATIC_ASSERT(sizeof(deviceid) * 2 <= MICROPY_HW_USB_DESC_STR_MAX);
|
||||
mp_usbd_hex_str(serial_buf, (uint8_t *)deviceid, sizeof(deviceid));
|
||||
}
|
||||
|
||||
int usb_cdc_init(void)
|
||||
{
|
||||
static bool initialized = false;
|
||||
if (!initialized) {
|
||||
|
||||
#if BLUETOOTH_SD
|
||||
#if BLUETOOTH_SD
|
||||
// Initialize the clock and BLE stack.
|
||||
ble_drv_stack_enable();
|
||||
#endif
|
||||
|
||||
#endif
|
||||
board_init();
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
rx_ringbuf.buf = rx_ringbuf_array;
|
||||
rx_ringbuf.size = sizeof(rx_ringbuf_array);
|
||||
rx_ringbuf.iget = 0;
|
||||
rx_ringbuf.iput = 0;
|
||||
|
||||
tx_ringbuf.buf = tx_ringbuf_array;
|
||||
tx_ringbuf.size = sizeof(tx_ringbuf_array);
|
||||
tx_ringbuf.iget = 0;
|
||||
tx_ringbuf.iput = 0;
|
||||
|
||||
mp_usbd_init();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -205,52 +139,6 @@ void usb_cdc_sd_event_handler(uint32_t soc_evt) {
|
||||
}
|
||||
#endif
|
||||
|
||||
uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) {
|
||||
uintptr_t ret = 0;
|
||||
if (poll_flags & MP_STREAM_POLL_RD) {
|
||||
usb_cdc_loop();
|
||||
if (cdc_rx_any()) {
|
||||
ret |= MP_STREAM_POLL_RD;
|
||||
}
|
||||
}
|
||||
if (poll_flags & MP_STREAM_POLL_WR) {
|
||||
ret |= MP_STREAM_POLL_WR;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mp_hal_stdin_rx_chr(void) {
|
||||
for (;;) {
|
||||
usb_cdc_loop();
|
||||
if (cdc_rx_any()) {
|
||||
return cdc_rx_char();
|
||||
}
|
||||
MICROPY_EVENT_POLL_HOOK
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
mp_uint_t mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {
|
||||
for (const char *top = str + len; str < top; str++) {
|
||||
ringbuf_put((ringbuf_t*)&tx_ringbuf, *str);
|
||||
usb_cdc_loop();
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
void mp_hal_stdout_tx_strn_cooked(const char *str, mp_uint_t len) {
|
||||
|
||||
for (const char *top = str + len; str < top; str++) {
|
||||
if (*str == '\n') {
|
||||
ringbuf_put((ringbuf_t*)&tx_ringbuf, '\r');
|
||||
usb_cdc_loop();
|
||||
}
|
||||
ringbuf_put((ringbuf_t*)&tx_ringbuf, *str);
|
||||
usb_cdc_loop();
|
||||
}
|
||||
}
|
||||
|
||||
void USBD_IRQHandler(void) {
|
||||
tud_int_handler(0);
|
||||
}
|
||||
|
@@ -1,117 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "tusb.h"
|
||||
|
||||
#ifndef MICROPY_HW_USB_VID
|
||||
#define MICROPY_HW_USB_VID (0xf055)
|
||||
#define MICROPY_HW_USB_PID (0x9802)
|
||||
#endif
|
||||
|
||||
#define USBD_DESC_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN)
|
||||
#define USBD_MAX_POWER_MA (250)
|
||||
|
||||
#define USBD_ITF_CDC (0) // needs 2 interfaces
|
||||
#define USBD_ITF_MAX (2)
|
||||
|
||||
#define USBD_CDC_EP_CMD (0x81)
|
||||
#define USBD_CDC_EP_OUT (0x02)
|
||||
#define USBD_CDC_EP_IN (0x82)
|
||||
#define USBD_CDC_CMD_MAX_SIZE (8)
|
||||
#define USBD_CDC_IN_OUT_MAX_SIZE (64)
|
||||
|
||||
#define USBD_STR_0 (0x00)
|
||||
#define USBD_STR_MANUF (0x01)
|
||||
#define USBD_STR_PRODUCT (0x02)
|
||||
#define USBD_STR_SERIAL (0x03)
|
||||
#define USBD_STR_CDC (0x04)
|
||||
|
||||
// Note: descriptors returned from callbacks must exist long enough for transfer to complete
|
||||
|
||||
static const tusb_desc_device_t usbd_desc_device = {
|
||||
.bLength = sizeof(tusb_desc_device_t),
|
||||
.bDescriptorType = TUSB_DESC_DEVICE,
|
||||
.bcdUSB = 0x0200,
|
||||
.bDeviceClass = TUSB_CLASS_MISC,
|
||||
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
|
||||
.bDeviceProtocol = MISC_PROTOCOL_IAD,
|
||||
.bMaxPacketSize0 = CFG_TUD_ENDOINT0_SIZE,
|
||||
.idVendor = MICROPY_HW_USB_VID,
|
||||
.idProduct = MICROPY_HW_USB_PID,
|
||||
.bcdDevice = 0x0100,
|
||||
.iManufacturer = USBD_STR_MANUF,
|
||||
.iProduct = USBD_STR_PRODUCT,
|
||||
.iSerialNumber = USBD_STR_SERIAL,
|
||||
.bNumConfigurations = 1,
|
||||
};
|
||||
|
||||
static const uint8_t usbd_desc_cfg[USBD_DESC_LEN] = {
|
||||
TUD_CONFIG_DESCRIPTOR(1, USBD_ITF_MAX, USBD_STR_0, USBD_DESC_LEN,
|
||||
TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, USBD_MAX_POWER_MA),
|
||||
|
||||
TUD_CDC_DESCRIPTOR(USBD_ITF_CDC, USBD_STR_CDC, USBD_CDC_EP_CMD,
|
||||
USBD_CDC_CMD_MAX_SIZE, USBD_CDC_EP_OUT, USBD_CDC_EP_IN, USBD_CDC_IN_OUT_MAX_SIZE),
|
||||
};
|
||||
|
||||
static const char *const usbd_desc_str[] = {
|
||||
[USBD_STR_MANUF] = "MicroPython",
|
||||
[USBD_STR_PRODUCT] = "Board in FS mode",
|
||||
[USBD_STR_SERIAL] = "000000000000", // TODO
|
||||
[USBD_STR_CDC] = "Board CDC",
|
||||
};
|
||||
|
||||
const uint8_t *tud_descriptor_device_cb(void) {
|
||||
return (const uint8_t*)&usbd_desc_device;
|
||||
}
|
||||
|
||||
const uint8_t *tud_descriptor_configuration_cb(uint8_t index) {
|
||||
(void)index;
|
||||
return usbd_desc_cfg;
|
||||
}
|
||||
|
||||
const uint16_t *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
|
||||
#define DESC_STR_MAX (20)
|
||||
static uint16_t desc_str[DESC_STR_MAX];
|
||||
|
||||
uint8_t len;
|
||||
if (index == 0) {
|
||||
desc_str[1] = 0x0409; // supported language is English
|
||||
len = 1;
|
||||
} else {
|
||||
if (index >= sizeof(usbd_desc_str) / sizeof(usbd_desc_str[0])) {
|
||||
return NULL;
|
||||
}
|
||||
const char* str = usbd_desc_str[index];
|
||||
for (len = 0; len < DESC_STR_MAX - 1 && str[len]; ++len) {
|
||||
desc_str[1 + len] = str[len];
|
||||
}
|
||||
}
|
||||
|
||||
// first byte is length (including header), second byte is string type
|
||||
desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2 * len + 2);
|
||||
|
||||
return desc_str;
|
||||
}
|
@@ -73,7 +73,7 @@
|
||||
#include "softpwm.h"
|
||||
#endif
|
||||
|
||||
#if MICROPY_HW_USB_CDC
|
||||
#if MICROPY_HW_ENABLE_USBDEV && MICROPY_HW_USB_CDC
|
||||
#include "usb_cdc.h"
|
||||
#endif
|
||||
|
||||
@@ -165,11 +165,11 @@ soft_reset:
|
||||
uart_init0();
|
||||
#endif
|
||||
|
||||
#if (MICROPY_PY_BLE_NUS == 0) && (MICROPY_HW_USB_CDC == 0)
|
||||
#if MICROPY_HW_ENABLE_UART_REPL
|
||||
{
|
||||
mp_obj_t args[2] = {
|
||||
MP_OBJ_NEW_SMALL_INT(0),
|
||||
MP_OBJ_NEW_SMALL_INT(115200),
|
||||
MP_OBJ_NEW_SMALL_INT(MICROPY_HW_UART_REPL),
|
||||
MP_OBJ_NEW_SMALL_INT(MICROPY_HW_UART_REPL_BAUD),
|
||||
};
|
||||
MP_STATE_VM(dupterm_objs[0]) = MP_OBJ_TYPE_GET_SLOT(&machine_uart_type, make_new)((mp_obj_t)&machine_uart_type, MP_ARRAY_SIZE(args), 0, args);
|
||||
}
|
||||
@@ -265,7 +265,7 @@ soft_reset:
|
||||
ret_code = pyexec_file_if_exists("boot.py");
|
||||
#endif
|
||||
|
||||
#if MICROPY_HW_USB_CDC
|
||||
#if MICROPY_HW_ENABLE_USBDEV && MICROPY_HW_USB_CDC
|
||||
usb_cdc_init();
|
||||
#endif
|
||||
|
||||
|
@@ -158,8 +158,7 @@
|
||||
#define MICROPY_STREAMS_NON_BLOCK (1)
|
||||
#define MICROPY_CAN_OVERRIDE_BUILTINS (1)
|
||||
#define MICROPY_USE_INTERNAL_ERRNO (1)
|
||||
#if MICROPY_HW_USB_CDC_1200BPS_TOUCH
|
||||
#define MICROPY_HW_ENABLE_USBDEV (1)
|
||||
#if MICROPY_HW_ENABLE_USBDEV
|
||||
#define MICROPY_ENABLE_SCHEDULER (1)
|
||||
#define MICROPY_SCHEDULER_STATIC_NODES (1)
|
||||
#endif
|
||||
@@ -297,6 +296,24 @@
|
||||
#define MICROPY_PY_BLE_NUS (0)
|
||||
#endif
|
||||
|
||||
// Whether to enable the REPL on a UART.
|
||||
#ifndef MICROPY_HW_ENABLE_UART_REPL
|
||||
// note: if both uart repl and cdc are enabled, uart hwfc can cause the cdc to lock up.
|
||||
#define MICROPY_HW_ENABLE_UART_REPL (!MICROPY_PY_BLE_NUS && !MICROPY_HW_USB_CDC)
|
||||
#endif
|
||||
|
||||
#if MICROPY_HW_ENABLE_UART_REPL
|
||||
|
||||
#ifndef MICROPY_HW_UART_REPL
|
||||
#define MICROPY_HW_UART_REPL (0)
|
||||
#endif
|
||||
|
||||
#ifndef MICROPY_HW_UART_REPL_BAUD
|
||||
#define MICROPY_HW_UART_REPL_BAUD (115200)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// type definitions for the specific machine
|
||||
|
||||
#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void *)((mp_uint_t)(p) | 1))
|
||||
@@ -331,17 +348,21 @@ long unsigned int rng_generate_random_word(void);
|
||||
|
||||
#define MP_STATE_PORT MP_STATE_VM
|
||||
|
||||
#if MICROPY_HW_USB_CDC
|
||||
#include "device/usbd.h"
|
||||
#define MICROPY_HW_USBDEV_TASK_HOOK extern void tud_task(void); tud_task();
|
||||
#define MICROPY_EXCLUDE_SHARED_TINYUSB_USBD_CDC (1)
|
||||
#else
|
||||
#define MICROPY_HW_USBDEV_TASK_HOOK ;
|
||||
#if MICROPY_HW_ENABLE_USBDEV
|
||||
#ifndef MICROPY_HW_USB_CDC
|
||||
#define MICROPY_HW_USB_CDC (1)
|
||||
#endif
|
||||
|
||||
#ifndef MICROPY_HW_USB_VID
|
||||
#define MICROPY_HW_USB_VID (0xf055)
|
||||
#endif
|
||||
#ifndef MICROPY_HW_USB_PID
|
||||
#define MICROPY_HW_USB_PID (0x9802)
|
||||
#endif
|
||||
#endif // MICROPY_HW_ENABLE_USBDEV
|
||||
|
||||
#define MICROPY_EVENT_POLL_HOOK \
|
||||
do { \
|
||||
MICROPY_HW_USBDEV_TASK_HOOK \
|
||||
extern void mp_handle_pending(bool); \
|
||||
mp_handle_pending(true); \
|
||||
__WFI(); \
|
||||
|
@@ -29,11 +29,15 @@
|
||||
#include "py/mpstate.h"
|
||||
#include "py/mphal.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "py/ringbuf.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/stream.h"
|
||||
#include "extmod/misc.h"
|
||||
#include "uart.h"
|
||||
#include "nrfx_errors.h"
|
||||
#include "nrfx_config.h"
|
||||
#include "drivers/bluetooth/ble_uart.h"
|
||||
#include "shared/tinyusb/mp_usbd_cdc.h"
|
||||
|
||||
#if MICROPY_PY_TIME_TICKS
|
||||
#include "nrfx_rtc.h"
|
||||
@@ -50,6 +54,14 @@
|
||||
#include "soc/nrfx_coredep.h"
|
||||
#endif
|
||||
|
||||
#ifndef MICROPY_HW_STDIN_BUFFER_LEN
|
||||
#define MICROPY_HW_STDIN_BUFFER_LEN 512
|
||||
#endif
|
||||
|
||||
static uint8_t stdin_ringbuf_array[MICROPY_HW_STDIN_BUFFER_LEN];
|
||||
ringbuf_t stdin_ringbuf = { stdin_ringbuf_array, sizeof(stdin_ringbuf_array), 0, 0 };
|
||||
|
||||
|
||||
void mp_nrf_start_lfclk(void) {
|
||||
if (!nrf_clock_lf_start_task_status_get(NRF_CLOCK)) {
|
||||
// Check if the clock was recently stopped but is still running.
|
||||
@@ -200,47 +212,73 @@ void mp_hal_set_interrupt_char(int c) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !MICROPY_PY_BLE_NUS && !MICROPY_HW_USB_CDC
|
||||
uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) {
|
||||
uintptr_t ret = 0;
|
||||
if ((poll_flags & MP_STREAM_POLL_RD) && MP_STATE_VM(dupterm_objs[0]) != MP_OBJ_NULL
|
||||
&& uart_rx_any(MP_STATE_VM(dupterm_objs[0]))) {
|
||||
ret |= MP_STREAM_POLL_RD;
|
||||
}
|
||||
if ((poll_flags & MP_STREAM_POLL_WR) && MP_STATE_VM(dupterm_objs[0]) != MP_OBJ_NULL) {
|
||||
ret |= MP_STREAM_POLL_WR;
|
||||
}
|
||||
#if MICROPY_HW_ENABLE_USBDEV && MICROPY_HW_USB_CDC
|
||||
ret |= mp_usbd_cdc_poll_interfaces(poll_flags);
|
||||
#endif
|
||||
#if MICROPY_PY_BLE_NUS && MICROPY_PY_SYS_STDFILES
|
||||
ret |= mp_ble_uart_stdio_poll(poll_flags);
|
||||
#endif
|
||||
#if MICROPY_PY_OS_DUPTERM
|
||||
ret |= mp_os_dupterm_poll(poll_flags);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mp_hal_stdin_rx_chr(void) {
|
||||
for (;;) {
|
||||
if (MP_STATE_VM(dupterm_objs[0]) != MP_OBJ_NULL && uart_rx_any(MP_STATE_VM(dupterm_objs[0]))) {
|
||||
return uart_rx_char(MP_STATE_VM(dupterm_objs[0]));
|
||||
#if MICROPY_HW_ENABLE_USBDEV && MICROPY_HW_USB_CDC
|
||||
mp_usbd_cdc_poll_interfaces(0);
|
||||
#endif
|
||||
int c = ringbuf_get(&stdin_ringbuf);
|
||||
if (c != -1) {
|
||||
return c;
|
||||
}
|
||||
#if MICROPY_PY_BLE_NUS
|
||||
c = mp_ble_uart_stdin_rx_chr();
|
||||
if (c != -1) {
|
||||
return c;
|
||||
}
|
||||
#endif
|
||||
#if MICROPY_PY_OS_DUPTERM
|
||||
int dupterm_c = mp_os_dupterm_rx_chr();
|
||||
if (dupterm_c >= 0) {
|
||||
return dupterm_c;
|
||||
}
|
||||
#endif
|
||||
MICROPY_EVENT_POLL_HOOK
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Send string of given length
|
||||
mp_uint_t mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {
|
||||
if (MP_STATE_VM(dupterm_objs[0]) != MP_OBJ_NULL) {
|
||||
uart_tx_strn(MP_STATE_VM(dupterm_objs[0]), str, len);
|
||||
return len;
|
||||
mp_uint_t ret = len;
|
||||
bool did_write = false;
|
||||
#if MICROPY_HW_ENABLE_USBDEV && MICROPY_HW_USB_CDC
|
||||
mp_uint_t cdc_res = mp_usbd_cdc_tx_strn(str, len);
|
||||
if (cdc_res > 0) {
|
||||
did_write = true;
|
||||
ret = MIN(cdc_res, ret);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mp_hal_stdout_tx_strn_cooked(const char *str, mp_uint_t len) {
|
||||
if (MP_STATE_VM(dupterm_objs[0]) != MP_OBJ_NULL) {
|
||||
uart_tx_strn_cooked(MP_STATE_VM(dupterm_objs[0]), str, len);
|
||||
#endif
|
||||
#if MICROPY_PY_BLE_NUS
|
||||
mp_uint_t ble_res = mp_ble_uart_stdout_tx_strn(str, len);
|
||||
if (ble_res > 0) {
|
||||
did_write = true;
|
||||
ret = MIN(ble_res, ret);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void mp_hal_stdout_tx_str(const char *str) {
|
||||
mp_hal_stdout_tx_strn(str, strlen(str));
|
||||
#endif
|
||||
#if MICROPY_PY_OS_DUPTERM
|
||||
int dupterm_res = mp_os_dupterm_tx_strn(str, len);
|
||||
if (dupterm_res >= 0) {
|
||||
did_write = true;
|
||||
ret = MIN((mp_uint_t)dupterm_res, ret);
|
||||
}
|
||||
#endif
|
||||
return did_write ? ret : 0;
|
||||
}
|
||||
|
||||
#if MICROPY_PY_TIME_TICKS
|
||||
|
@@ -28,10 +28,12 @@
|
||||
#define __NRF52_HAL
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include "py/ringbuf.h"
|
||||
#include <nrfx.h>
|
||||
#include "pin.h"
|
||||
#include "nrf_gpio.h"
|
||||
#include "nrfx_config.h"
|
||||
#include "shared/runtime/interrupt_char.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
@@ -43,6 +45,8 @@ typedef enum
|
||||
|
||||
extern const unsigned char mp_hal_status_to_errno_table[4];
|
||||
|
||||
extern ringbuf_t stdin_ringbuf;
|
||||
|
||||
NORETURN void mp_hal_raise(HAL_StatusTypeDef status);
|
||||
void mp_hal_set_interrupt_char(int c); // -1 to disable
|
||||
|
||||
|
Reference in New Issue
Block a user