diff --git a/ports/raspberrypi/Makefile b/ports/raspberrypi/Makefile index b75d542325166..728a517480eb2 100644 --- a/ports/raspberrypi/Makefile +++ b/ports/raspberrypi/Makefile @@ -549,6 +549,7 @@ SRC_C += \ ifeq ($(CIRCUITPY_USB_HOST), 1) SRC_C += \ lib/tinyusb/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c \ + lib/tinyusb/src/portable/raspberrypi/rp2040/hcd_rp2040.c \ lib/Pico-PIO-USB/src/pio_usb.c \ lib/Pico-PIO-USB/src/pio_usb_host.c \ lib/Pico-PIO-USB/src/usb_crc.c \ diff --git a/ports/raspberrypi/boards/olimex_rp2350pc/board.c b/ports/raspberrypi/boards/olimex_rp2350pc/board.c new file mode 100644 index 0000000000000..f94a4cb3c3211 --- /dev/null +++ b/ports/raspberrypi/boards/olimex_rp2350pc/board.c @@ -0,0 +1,45 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "common-hal/microcontroller/Pin.h" +#include "hardware/gpio.h" +#include "shared-bindings/usb_host/Port.h" +#include "supervisor/board.h" + +#include "common-hal/picodvi/__init__.h" + +bool board_reset_pin_number(uint8_t pin_number) { + #if defined(DEFAULT_USB_HOST_5V_POWER) + if (pin_number == DEFAULT_USB_HOST_5V_POWER->number) { + // doing this (rather than gpio_init) in this specific order ensures no + // glitch if pin was already configured as a high output. gpio_init() temporarily + // configures the pin as an input, so the power enable value would potentially + // glitch. + gpio_put(pin_number, 1); + gpio_set_dir(pin_number, GPIO_OUT); + gpio_set_function(pin_number, GPIO_FUNC_SIO); + + return true; + } + #endif + // Set I2S out of reset. + /* + if (pin_number == I2S_RESET_PIN_NUMBER) { + gpio_put(pin_number, 1); + gpio_set_dir(pin_number, GPIO_OUT); + gpio_set_function(pin_number, GPIO_FUNC_SIO); + + return true; + } + */ + + return false; +} + +void board_init(void) { + common_hal_usb_host_port_construct(0, 0); + picodvi_autoconstruct(); +} diff --git a/ports/raspberrypi/boards/olimex_rp2350pc/mpconfigboard.h b/ports/raspberrypi/boards/olimex_rp2350pc/mpconfigboard.h new file mode 100644 index 0000000000000..3c1e516a28fc8 --- /dev/null +++ b/ports/raspberrypi/boards/olimex_rp2350pc/mpconfigboard.h @@ -0,0 +1,46 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#define MICROPY_HW_BOARD_NAME "Olimex RP2350pc" +#define MICROPY_HW_MCU_NAME "rp2350b" + +#define MICROPY_HW_LED_STATUS (&pin_GPIO25) + +// Internal I2C bus (DVI, I2S), no user connection pins +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO33) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO32) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO6) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO7) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO4) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO1) +#define DEFAULT_UART_BUS_TX (&pin_GPIO0) + +#define CIRCUITPY_CONSOLE_UART_RX DEFAULT_UART_BUS_RX +#define CIRCUITPY_CONSOLE_UART_TX DEFAULT_UART_BUS_TX + +#define CIRCUITPY_PSRAM_CHIP_SELECT (&pin_GPIO8) + +#define DEFAULT_DVI_BUS_CLK_DN (&pin_GPIO15) +#define DEFAULT_DVI_BUS_CLK_DP (&pin_GPIO14) +#define DEFAULT_DVI_BUS_RED_DN (&pin_GPIO13) +#define DEFAULT_DVI_BUS_RED_DP (&pin_GPIO12) +#define DEFAULT_DVI_BUS_GREEN_DN (&pin_GPIO19) +#define DEFAULT_DVI_BUS_GREEN_DP (&pin_GPIO18) +#define DEFAULT_DVI_BUS_BLUE_DN (&pin_GPIO17) +#define DEFAULT_DVI_BUS_BLUE_DP (&pin_GPIO16) + +#define DEFAULT_SD_SCK (&pin_GPIO10) +#define DEFAULT_SD_MOSI (&pin_GPIO11) +#define DEFAULT_SD_MISO (&pin_GPIO24) +#define DEFAULT_SD_CS (&pin_GPIO9) +#define DEFAULT_SD_CARD_DETECT (&pin_GPIO41) +#define DEFAULT_SD_CARD_INSERTED true + +#define CIRCUITPY_DEBUG_TINYUSB 1 + +// #define CIRCUITPY_SAVES_PARTITION_SIZE (2 * 1024 * 1024) diff --git a/ports/raspberrypi/boards/olimex_rp2350pc/mpconfigboard.mk b/ports/raspberrypi/boards/olimex_rp2350pc/mpconfigboard.mk new file mode 100644 index 0000000000000..aa16b8c471c20 --- /dev/null +++ b/ports/raspberrypi/boards/olimex_rp2350pc/mpconfigboard.mk @@ -0,0 +1,28 @@ +#USB_VID = 0x15BA +#USB_PID = 0x0054 +CIRCUITPY_CREATOR_ID = 0x000c15BA +CIRCUITPY_CREATION_ID = 0x00000054 +USB_PRODUCT = "RP2350pc" +USB_MANUFACTURER = "Olimex" + +CHIP_VARIANT = RP2350 +CHIP_PACKAGE = B +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q128JVxQ, P25Q16H" + +CIRCUITPY_USB_DEVICE=0 +CIRCUITPY_USB_IDENTIFICATION = 0 +CIRCUITPY_USB_VIDEO=0 +#CIRCUITPY_USB_MIDI=0 +#CIRCUITPY_USB_CDC = 0 +#CIRCUITPY_USB_HID = 0 +#CIRCUITPY_USB_MSC = 0 + +CIRCUITPY_USB_HOST=1 +#CIRCUITPY_TINYUSB_HOST=1 +#CIRCUITPY_USB_HOST_INSTANCE = 0 + +CIRCUITPY_BUILD_EXTENSIONS = uf2 +UF2_BOOTLOADER = 1 +#OPTIMIZATION_FLAGS = -Os diff --git a/ports/raspberrypi/boards/olimex_rp2350pc/pico-sdk-configboard.h b/ports/raspberrypi/boards/olimex_rp2350pc/pico-sdk-configboard.h new file mode 100644 index 0000000000000..2d9283a9192f2 --- /dev/null +++ b/ports/raspberrypi/boards/olimex_rp2350pc/pico-sdk-configboard.h @@ -0,0 +1,10 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +// Put board-specific pico-sdk definitions here. This file must exist. + +// Allow extra time for xosc to start. +#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 diff --git a/ports/raspberrypi/boards/olimex_rp2350pc/pins.c b/ports/raspberrypi/boards/olimex_rp2350pc/pins.c new file mode 100644 index 0000000000000..d60b1c4f1ee3a --- /dev/null +++ b/ports/raspberrypi/boards/olimex_rp2350pc/pins.c @@ -0,0 +1,78 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // UEXT2 HEADER Pin 1 - 3.3V, 2 - Gnd + { MP_OBJ_NEW_QSTR(MP_QSTR_D36), MP_ROM_PTR(&pin_GPIO36) }, // PIN 6 + { MP_OBJ_NEW_QSTR(MP_QSTR_D37), MP_ROM_PTR(&pin_GPIO37) }, // 5 + { MP_OBJ_NEW_QSTR(MP_QSTR_D38), MP_ROM_PTR(&pin_GPIO38) }, // 3 + { MP_OBJ_NEW_QSTR(MP_QSTR_D39), MP_ROM_PTR(&pin_GPIO39) }, // 4 + { MP_OBJ_NEW_QSTR(MP_QSTR_D42), MP_ROM_PTR(&pin_GPIO42) }, // 9 + { MP_OBJ_NEW_QSTR(MP_QSTR_D43), MP_ROM_PTR(&pin_GPIO43) }, // 8 + { MP_OBJ_NEW_QSTR(MP_QSTR_D44), MP_ROM_PTR(&pin_GPIO44) }, // 7 + { MP_OBJ_NEW_QSTR(MP_QSTR_D45), MP_ROM_PTR(&pin_GPIO45) }, // 10 + +// { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO32) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA0), MP_ROM_PTR(&pin_GPIO36) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D36), MP_ROM_PTR(&pin_GPIO36) }, +// { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO33) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL0), MP_ROM_PTR(&pin_GPIO37) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D37), MP_ROM_PTR(&pin_GPIO37) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA1), MP_ROM_PTR(&pin_GPIO2) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL1), MP_ROM_PTR(&pin_GPIO3) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_GPIO24) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CARD_DETECT), MP_ROM_PTR(&pin_GPIO41) }, + + { MP_ROM_QSTR(MP_QSTR_CKN), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_CKP), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_D0N), MP_ROM_PTR(&pin_GPIO13) }, // Red + { MP_ROM_QSTR(MP_QSTR_D0P), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_D1N), MP_ROM_PTR(&pin_GPIO19) }, // Green + { MP_ROM_QSTR(MP_QSTR_D1P), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_D2N), MP_ROM_PTR(&pin_GPIO17) }, // Blue + { MP_ROM_QSTR(MP_QSTR_D2P), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO25) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_PWM_SPK_L), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_PWM_SPK_R), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_I2S_PWR), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_I2S_DIN), MP_ROM_PTR(&pin_GPIO31) }, + { MP_ROM_QSTR(MP_QSTR_I2S_MCLK), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_I2S_BCLK), MP_ROM_PTR(&pin_GPIO30) }, + { MP_ROM_QSTR(MP_QSTR_I2S_WS), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_I2S_ASDOUT), MP_ROM_PTR(&pin_GPIO28) }, + + // AMP_VOL must be set high and AMP_SHDN set low to enable the PAM8003 amplifier + // There is an unpopulated potentiometer but without it AMP_VOL is only off/on + { MP_ROM_QSTR(MP_QSTR_AMP_VOL), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_AMP_SHDN), MP_ROM_PTR(&pin_GPIO35) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/common-hal/usb_host/Port.c b/ports/raspberrypi/common-hal/usb_host/Port.c index b8a49725030ea..53bfeef8314db 100644 --- a/ports/raspberrypi/common-hal/usb_host/Port.c +++ b/ports/raspberrypi/common-hal/usb_host/Port.c @@ -32,6 +32,7 @@ usb_host_port_obj_t usb_host_instance; +#if CIRCUITPY_USB_DEVICE volatile bool _core1_ready = false; static void __not_in_flash_func(core1_main)(void) { @@ -109,16 +110,19 @@ static size_t get_usb_pio(void) { } mp_raise_RuntimeError(MP_ERROR_TEXT("All state machines in use")); } - +#endif usb_host_port_obj_t *common_hal_usb_host_port_construct(const mcu_pin_obj_t *dp, const mcu_pin_obj_t *dm) { + #if CIRCUITPY_USB_DEVICE if ((dp->number + 1 != dm->number) && (dp->number - 1 != dm->number)) { raise_ValueError_invalid_pins(); } + #endif usb_host_port_obj_t *self = &usb_host_instance; // Return the singleton if given the same pins. + #if CIRCUITPY_USB_DEVICE if (self->dp != NULL) { if (self->dp != dp || self->dm != dm) { mp_raise_msg_varg(&mp_type_RuntimeError, MP_ERROR_TEXT("%q in use"), MP_QSTR_usb_host); @@ -170,6 +174,18 @@ usb_host_port_obj_t *common_hal_usb_host_port_construct(const mcu_pin_obj_t *dp, tuh_configure(TUH_OPT_RHPORT, TUH_CFGID_RPI_PIO_USB_CONFIGURATION, &pio_cfg); tuh_init(TUH_OPT_RHPORT); + #else + #if CIRCUITPY_USB_HOST + // init host stack on configured roothub port + tusb_rhport_init_t host_init = { + .role = TUSB_ROLE_HOST, + .speed = TUSB_SPEED_AUTO + }; + tusb_init(0, &host_init); + + // tuh_init(0); + #endif + #endif return self; } diff --git a/ports/raspberrypi/supervisor/port.c b/ports/raspberrypi/supervisor/port.c index 66e63248c4810..48dcea6688791 100644 --- a/ports/raspberrypi/supervisor/port.c +++ b/ports/raspberrypi/supervisor/port.c @@ -552,10 +552,15 @@ void port_interrupt_after_ticks(uint32_t ticks) { void port_idle_until_interrupt(void) { #ifdef PICO_RP2040 common_hal_mcu_disable_interrupts(); - #if CIRCUITPY_USB_HOST + #if CIRCUITPY_USB_HOST && CIRCUITPY_USB_DEVICE if (!background_callback_pending() && !tud_task_event_ready() && !tuh_task_event_ready() && !_woken_up) { #else + #if CIRCUITPY_USB_HOST + if (!background_callback_pending() && !tuh_task_event_ready() && !_woken_up) { + #endif + #if CIRCUITPY_USB_DEVICE if (!background_callback_pending() && !tud_task_event_ready() && !_woken_up) { + #endif #endif __DSB(); __WFI(); @@ -571,10 +576,15 @@ void port_idle_until_interrupt(void) { uint32_t oldBasePri = __get_BASEPRI(); __set_BASEPRI(0); __isb(); - #if CIRCUITPY_USB_HOST + #if CIRCUITPY_USB_HOST && CIRCUITPY_USB_DEVICE if (!background_callback_pending() && !tud_task_event_ready() && !tuh_task_event_ready() && !_woken_up) { #else + #if CIRCUITPY_USB_HOST + if (!background_callback_pending() && !tuh_task_event_ready() && !_woken_up) { + #endif + #if CIRCUITPY_USB_DEVICE if (!background_callback_pending() && !tud_task_event_ready() && !_woken_up) { + #endif #endif __DSB(); __WFI(); diff --git a/supervisor/shared/usb/tusb_config.h b/supervisor/shared/usb/tusb_config.h index ac2fd9f4f258c..babd9c87ac3e9 100644 --- a/supervisor/shared/usb/tusb_config.h +++ b/supervisor/shared/usb/tusb_config.h @@ -150,9 +150,9 @@ extern "C" { #if CIRCUITPY_USB_HOST || CIRCUITPY_MAX3421E #define CFG_TUH_ENABLED 1 -// Always use PIO to do host on RP2. -#if !CIRCUITPY_MAX3421E -#define CFG_TUH_RPI_PIO_USB 1 +// Don't use RP2 PIO to do host on MAX3421E or when USB device is disabled +#if CIRCUITPY_MAX3421E || (CIRCUITPY_USB_HOST && !CIRCUITPY_USB_DEVICE) +#define CFG_TUH_RPI_PIO_USB 0 #else #define CFG_TUH_RPI_PIO_USB 1 #endif diff --git a/supervisor/shared/usb/usb.c b/supervisor/shared/usb/usb.c index e67c15d022cc9..b56a650180e01 100644 --- a/supervisor/shared/usb/usb.c +++ b/supervisor/shared/usb/usb.c @@ -117,9 +117,11 @@ void usb_init(void) { usb_hid_build_report_descriptor(); #endif + #if CIRCUITPY_USB_DEVICE // Only init device. Host gets inited by the `usb_host` module common-hal. tud_init(TUD_OPT_RHPORT); #endif + #endif post_usb_init(); @@ -181,7 +183,9 @@ void usb_setup_with_vm(void) { void usb_background(void) { if (usb_enabled()) { #if CFG_TUSB_OS == OPT_OS_NONE || CFG_TUSB_OS == OPT_OS_PICO + #if CIRCUITPY_USB_DEVICE tud_task(); + #endif #if CIRCUITPY_USB_HOST || CIRCUITPY_MAX3421E tuh_task(); #endif