Skip to content

Commit 64e4145

Browse files
committed
Basic USB host support and keyboard workflow
Connects up read, write and ctrl_transfer to TinyUSB. USB Host support is available on iMX RT and RP2040. Fixes micropython#6527 (imx) and fixes micropython#5986 (rp2).
1 parent 95535a8 commit 64e4145

File tree

32 files changed

+812
-63
lines changed

32 files changed

+812
-63
lines changed

.gitmodules

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,3 +341,7 @@
341341
[submodule "frozen/Adafruit_CircuitPython_Wave"]
342342
path = frozen/Adafruit_CircuitPython_Wave
343343
url = http://github.com/adafruit/Adafruit_CircuitPython_Wave.git
344+
[submodule "ports/raspberrypi/lib/Pico-PIO-USB"]
345+
path = ports/raspberrypi/lib/Pico-PIO-USB
346+
url = https://github.com/tannewt/Pico-PIO-USB.git
347+
branch = circuitpython_usb_host

lib/tinyusb

Submodule tinyusb updated 462 files

locale/circuitpython.pot

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -471,12 +471,17 @@ msgstr ""
471471
msgid "All channels in use"
472472
msgstr ""
473473

474+
#: ports/raspberrypi/common-hal/usb_host/Port.c
475+
msgid "All dma channels in use"
476+
msgstr ""
477+
474478
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
475479
msgid "All event channels in use"
476480
msgstr ""
477481

478482
#: ports/raspberrypi/common-hal/picodvi/Framebuffer.c
479483
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
484+
#: ports/raspberrypi/common-hal/usb_host/Port.c
480485
msgid "All state machines in use"
481486
msgstr ""
482487

@@ -1950,10 +1955,6 @@ msgstr ""
19501955
msgid "Size not supported"
19511956
msgstr ""
19521957

1953-
#: ports/raspberrypi/common-hal/alarm/SleepMemory.c
1954-
msgid "Sleep Memory not available"
1955-
msgstr ""
1956-
19571958
#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c
19581959
#: shared-bindings/nvm/ByteArray.c
19591960
msgid "Slice and value different lengths."

ports/mimxrt10xx/Makefile

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -229,12 +229,19 @@ include $(TOP)/py/mkrules.mk
229229
print-%:
230230
@echo $* = $($*)
231231

232-
ifeq ($(CHIP_FAMILY), MIMXRT1062)
233-
PYOCD_TARGET = mimxrt1060
234-
endif
235-
236-
# Flash using pyocd
237-
PYOCD_OPTION ?=
238-
flash: $(BUILD)/firmware.hex
239-
pyocd flash -t $(PYOCD_TARGET) $(PYOCD_OPTION) $<
240-
pyocd reset -t $(PYOCD_TARGET)
232+
# Flash using jlink
233+
define jlink_script
234+
halt
235+
loadfile $^
236+
r
237+
go
238+
exit
239+
endef
240+
export jlink_script
241+
242+
JLINKEXE = JLinkExe
243+
flash-jlink: $(BUILD)/firmware.elf
244+
@echo "$$jlink_script" > $(BUILD)/firmware.jlink
245+
$(JLINKEXE) -device $(CHIP_FAMILY)xxx5A -if swd -JTAGConf -1,-1 -speed auto -CommandFile $(BUILD)/firmware.jlink
246+
247+
flash: flash-jlink

ports/mimxrt10xx/boards/imxrt1060_evk/mpconfigboard.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,5 @@
2121

2222
// Put host on the first USB so that right angle OTG adapters can fit. This is
2323
// the right port when looking at the board.
24-
#define CIRCUITPY_USB_DEVICE_INSTANCE 1
25-
#define CIRCUITPY_USB_HOST_INSTANCE 0
24+
#define CIRCUITPY_USB_DEVICE_INSTANCE 0
25+
#define CIRCUITPY_USB_HOST_INSTANCE 1

ports/mimxrt10xx/linking/common.ld

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ SECTIONS
7272
*(EXCLUDE_FILE(
7373
*fsl_flexspi.o
7474
*dcd_ci_hs.o
75+
*ehci.o
7576
*tusb_fifo.o
7677
*usbd.o
7778
*string0.o
@@ -88,6 +89,11 @@ SECTIONS
8889
We try to only keep USB interrupt related functions. */
8990
*dcd_ci_hs.o(.text.process_*_request .text.dcd_edpt* .text.dcd_init .text.dcd_set_address)
9091
*usbd.o(.text.process_*_request .text.process_[gs]et* .text.tud_* .text.usbd_* .text.configuration_reset .text.invoke_*)
92+
*ehci.o(.text.hcd_edpt* .text.hcd_setup* .text.ehci_init* .text.hcd_port* .text.hcd_device* .text.qtd_init* .text.list_remove*)
93+
94+
/* Less critical portions of the runtime. */
95+
*runtime.o(.text.mp_import* .text.mp_resume* .text.mp_make_raise* .text.mp_init)
96+
*gc.o(.text.gc_never_free .text.gc_make_long_lived)
9197

9298
/* Anything marked cold/unlikely should be in flash. */
9399
*(.text.unlikely.*)
@@ -146,6 +152,7 @@ SECTIONS
146152
*(.itcm.*)
147153
*fsl_flexspi.o(.text*)
148154
*dcd_ci_hs.o(.text*)
155+
*ehci.o(.text*)
149156
*tusb_fifo.o(.text*)
150157
*py/objboundmeth.o(.text*)
151158
*py/objtype.o(.text*)

ports/raspberrypi/Makefile

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ INC += \
148148
CFLAGS += -DRASPBERRYPI -DPICO_ON_DEVICE=1 -DPICO_NO_BINARY_INFO=0 -DPICO_TIME_DEFAULT_ALARM_POOL_DISABLED=0 -DPICO_DIVIDER_CALL_IDIV0=0 -DPICO_DIVIDER_CALL_LDIV0=0 -DPICO_DIVIDER_HARDWARE=1 -DPICO_DOUBLE_ROM=1 -DPICO_FLOAT_ROM=1 -DPICO_MULTICORE=1 -DPICO_BITS_IN_RAM=0 -DPICO_DIVIDER_IN_RAM=0 -DPICO_DOUBLE_PROPAGATE_NANS=0 -DPICO_DOUBLE_IN_RAM=0 -DPICO_MEM_IN_RAM=0 -DPICO_FLOAT_IN_RAM=0 -DPICO_FLOAT_PROPAGATE_NANS=1 -DPICO_NO_FLASH=0 -DPICO_COPY_TO_RAM=0 -DPICO_DISABLE_SHARED_IRQ_HANDLERS=0 -DPICO_NO_BI_BOOTSEL_VIA_DOUBLE_RESET=0 -DDVI_1BPP_BIT_REVERSE=0
149149
OPTIMIZATION_FLAGS ?= -O3
150150
# TinyUSB defines
151-
CFLAGS += -DTUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX=1 -DCFG_TUSB_MCU=OPT_MCU_RP2040 -DCFG_TUD_MIDI_RX_BUFSIZE=128 -DCFG_TUD_CDC_RX_BUFSIZE=256 -DCFG_TUD_MIDI_TX_BUFSIZE=128 -DCFG_TUD_CDC_TX_BUFSIZE=256 -DCFG_TUD_MSC_BUFSIZE=1024
151+
CFLAGS += -DCFG_TUSB_OS=OPT_OS_PICO -DTUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX=1 -DCFG_TUSB_MCU=OPT_MCU_RP2040 -DCFG_TUD_MIDI_RX_BUFSIZE=128 -DCFG_TUD_CDC_RX_BUFSIZE=256 -DCFG_TUD_MIDI_TX_BUFSIZE=128 -DCFG_TUD_CDC_TX_BUFSIZE=256 -DCFG_TUD_MSC_BUFSIZE=1024
152152

153153
# option to override default optimization level, set in boards/$(BOARD)/mpconfigboard.mk
154154
CFLAGS += $(OPTIMIZATION_FLAGS)
@@ -258,6 +258,18 @@ SRC_C += \
258258
$(SRC_CYW43) \
259259
$(SRC_LWIP) \
260260

261+
262+
ifeq ($(CIRCUITPY_USB_HOST), 1)
263+
SRC_C += \
264+
lib/tinyusb/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c \
265+
lib/Pico-PIO-USB/src/pio_usb.c \
266+
lib/Pico-PIO-USB/src/pio_usb_host.c \
267+
lib/Pico-PIO-USB/src/usb_crc.c \
268+
269+
INC += \
270+
-isystem lib/Pico-PIO-USB/src
271+
endif
272+
261273
ifeq ($(CIRCUITPY_PICODVI),1)
262274
SRC_C += \
263275
bindings/picodvi/__init__.c \

ports/raspberrypi/boards/adafruit_feather_rp2040_usb_host/board.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,18 @@
2626

2727
#include "supervisor/board.h"
2828

29+
#include "shared-bindings/digitalio/DigitalInOut.h"
30+
#include "shared-bindings/usb_host/Port.h"
31+
2932
// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here.
33+
34+
usb_host_port_obj_t _host_port;
35+
digitalio_digitalinout_obj_t _host_power;
36+
37+
void board_init(void) {
38+
common_hal_digitalio_digitalinout_construct(&_host_power, &pin_GPIO18);
39+
common_hal_digitalio_digitalinout_never_reset(&_host_power);
40+
common_hal_digitalio_digitalinout_switch_to_output(&_host_power, true, DRIVE_MODE_PUSH_PULL);
41+
42+
common_hal_usb_host_port_construct(&_host_port, &pin_GPIO16, &pin_GPIO17);
43+
}

ports/raspberrypi/boards/adafruit_feather_rp2040_usb_host/mpconfigboard.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,8 @@
1212

1313
#define DEFAULT_UART_BUS_RX (&pin_GPIO1)
1414
#define DEFAULT_UART_BUS_TX (&pin_GPIO0)
15+
16+
#define CIRCUITPY_CONSOLE_UART_RX DEFAULT_UART_BUS_RX
17+
#define CIRCUITPY_CONSOLE_UART_TX DEFAULT_UART_BUS_TX
18+
19+
#define CIRCUITPY_USB_HOST_INSTANCE 1

ports/raspberrypi/common-hal/rp2pio/StateMachine.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ void rp2pio_statemachine_dma_complete(rp2pio_statemachine_obj_t *self, int chann
9898
void rp2pio_statemachine_reset_ok(PIO pio, int sm);
9999
void rp2pio_statemachine_never_reset(PIO pio, int sm);
100100

101+
uint8_t rp2pio_statemachine_find_pio(int program_size, int sm_count);
102+
101103
extern const mp_obj_type_t rp2pio_statemachine_type;
102104

103105
#endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_RP2PIO_STATEMACHINE_H

0 commit comments

Comments
 (0)