From d9c05c52e57bedc4c249144fa315884133e5531f Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 17 Dec 2024 16:09:33 -0500 Subject: [PATCH] CP console over UART doesn't work --- .gitmodules | 3 - boards/pca10056/mpconfigboard.h | 5 +- main.c | 5 +- ports/nordic/common-hal/busio/I2C.c | 1 - ports/nordic/common-hal/busio/SPI.c | 27 ++++----- ports/nordic/common-hal/busio/UART.c | 41 +++++++++---- ports/nordic/common-hal/microcontroller/Pin.c | 1 - ports/nordic/nrfx | 1 - ports/nordic/peripherals/nrf/pins.h | 2 + prj.conf | 7 ++- supervisor/shared/serial.c | 1 + supervisor/zephyr/flash.c | 6 ++ supervisor/zephyr/serial.c | 59 +------------------ tools/cpbuild/build_circuitpython.py | 17 +++++- 14 files changed, 81 insertions(+), 95 deletions(-) delete mode 160000 ports/nordic/nrfx diff --git a/.gitmodules b/.gitmodules index 3707b3d7ed68..a77461d5638a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -63,9 +63,6 @@ [submodule "frozen/Adafruit_CircuitPython_Crickit"] path = frozen/Adafruit_CircuitPython_Crickit url = https://github.com/adafruit/Adafruit_CircuitPython_Crickit -[submodule "ports/nordic/nrfx"] - path = ports/nordic/nrfx - url = https://github.com/adafruit/nrfx.git [submodule "lib/tinyusb"] path = lib/tinyusb url = https://github.com/hathach/tinyusb.git diff --git a/boards/pca10056/mpconfigboard.h b/boards/pca10056/mpconfigboard.h index 4be1f0aa05f0..f678b0f88083 100644 --- a/boards/pca10056/mpconfigboard.h +++ b/boards/pca10056/mpconfigboard.h @@ -6,8 +6,6 @@ #pragma once -#include "nrfx/hal/nrf_gpio.h" - #define MICROPY_HW_BOARD_NAME "PCA10056 nRF52840-DK" #define MICROPY_HW_MCU_NAME "nRF52840" @@ -23,6 +21,9 @@ #define DEFAULT_UART_BUS_RX (&pin_P1_01) #define DEFAULT_UART_BUS_TX (&pin_P1_02) +#define CIRCUITPY_CONSOLE_UART_TX (&pin_P0_06) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_P0_08) + // Flash operation mode is determined by MICROPY_QSPI_DATAn pin configuration. // A pin config is valid if it is defined and its value is not 0xFF. // Quad mode: If all DATA0 --> DATA3 are valid diff --git a/main.c b/main.c index 90f44e333316..5659919887dd 100644 --- a/main.c +++ b/main.c @@ -997,20 +997,19 @@ int __attribute__((used)) main(void) { common_hal_nvm_bytearray_set_bytes(&common_hal_mcu_nvm_obj, 0, &value_out, 1); #endif + printk("serial_early_init\r\n"); + // Start the debug serial serial_early_init(); - console_write(NULL, "serial_early_init\r\n", strlen("serial_early_init\r\n")); mp_hal_stdout_tx_str(line_clear); // Wait briefly to give a reset window where we'll enter safe mode after the reset. if (get_safe_mode() == SAFE_MODE_NONE) { - console_write(NULL, "wait_for_safe_mode_reset\r\n", strlen("wait_for_safe_mode_reset\r\n")); set_safe_mode(wait_for_safe_mode_reset()); } printk("safe_mode: %d\r\n", get_safe_mode()); - console_write(NULL, "stack_init\r\n", strlen("stack_init\r\n")); stack_init(); diff --git a/ports/nordic/common-hal/busio/I2C.c b/ports/nordic/common-hal/busio/I2C.c index 3558fad165ba..0b011fc8539f 100644 --- a/ports/nordic/common-hal/busio/I2C.c +++ b/ports/nordic/common-hal/busio/I2C.c @@ -16,7 +16,6 @@ #include "nrfx_twim.h" #include "nrfx_spim.h" -#include "nrf_gpio.h" // all TWI instances have the same max size // 16 bits for 840, 10 bits for 810, 8 bits for 832 diff --git a/ports/nordic/common-hal/busio/SPI.c b/ports/nordic/common-hal/busio/SPI.c index 8af4c5f4e83f..e3e24703ab3d 100644 --- a/ports/nordic/common-hal/busio/SPI.c +++ b/ports/nordic/common-hal/busio/SPI.c @@ -12,7 +12,6 @@ #include "py/runtime.h" #include "nrfx_spim.h" -#include "nrf_gpio.h" #ifndef NRFX_SPIM3_ENABLED #define NRFX_SPIM3_ENABLED (0) @@ -63,7 +62,7 @@ static bool never_reset[MP_ARRAY_SIZE(spim_peripherals)]; // Separate RAM area for SPIM3 transmit buffer to avoid SPIM3 hardware errata. // https://infocenter.nordicsemi.com/index.jsp?topic=%2Ferrata_nRF52840_Rev2%2FERR%2FnRF52840%2FRev2%2Flatest%2Fanomaly_840_198.html -static uint8_t *spim3_transmit_buffer = (uint8_t *)SPIM3_BUFFER_RAM_START_ADDR; +// static uint8_t *spim3_transmit_buffer = (uint8_t *)SPIM3_BUFFER_RAM_START_ADDR; void spi_reset(void) { for (size_t i = 0; i < MP_ARRAY_SIZE(spim_peripherals); i++) { @@ -142,8 +141,8 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t * mp_raise_ValueError(MP_ERROR_TEXT("All SPI peripherals are in use")); } - nrfx_spim_config_t config = NRFX_SPIM_DEFAULT_CONFIG(NRFX_SPIM_PIN_NOT_USED, NRFX_SPIM_PIN_NOT_USED, - NRFX_SPIM_PIN_NOT_USED, NRFX_SPIM_PIN_NOT_USED); + nrfx_spim_config_t config = NRFX_SPIM_DEFAULT_CONFIG(NRF_SPIM_PIN_NOT_CONNECTED, NRF_SPIM_PIN_NOT_CONNECTED, + NRF_SPIM_PIN_NOT_CONNECTED, NRF_SPIM_PIN_NOT_CONNECTED); config.frequency = baudrate_to_spim_frequency(self->spim_peripheral->max_frequency); @@ -241,11 +240,11 @@ bool common_hal_busio_spi_write(busio_spi_obj_t *self, const uint8_t *data, size while (len > 0) { size_t chunk_size = MIN(len, self->spim_peripheral->max_xfer_size); uint8_t *chunk = next_chunk; - if (is_spim3) { - // If SPIM3, copy into unused RAM block, and do DMA from there. - memcpy(spim3_transmit_buffer, chunk, chunk_size); - chunk = spim3_transmit_buffer; - } + // if (is_spim3) { + // // If SPIM3, copy into unused RAM block, and do DMA from there. + // memcpy(spim3_transmit_buffer, chunk, chunk_size); + // chunk = spim3_transmit_buffer; + // } const nrfx_spim_xfer_desc_t xfer = NRFX_SPIM_XFER_TX(chunk, chunk_size); if (nrfx_spim_xfer(&self->spim_peripheral->spim, &xfer, 0) != NRFX_SUCCESS) { return false; @@ -269,11 +268,11 @@ bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, const uint8_t *data_ou while (len > 0) { const uint8_t *chunk_out = next_chunk_out; size_t chunk_size = MIN(len, self->spim_peripheral->max_xfer_size); - if (is_spim3) { - // If SPIM3, copy into unused RAM block, and do DMA from there. - memcpy(spim3_transmit_buffer, chunk_out, chunk_size); - chunk_out = spim3_transmit_buffer; - } + // if (is_spim3) { + // // If SPIM3, copy into unused RAM block, and do DMA from there. + // memcpy(spim3_transmit_buffer, chunk_out, chunk_size); + // chunk_out = spim3_transmit_buffer; + // } const nrfx_spim_xfer_desc_t xfer = NRFX_SPIM_SINGLE_XFER(next_chunk_out, chunk_size, next_chunk_in, chunk_size); diff --git a/ports/nordic/common-hal/busio/UART.c b/ports/nordic/common-hal/busio/UART.c index c9b0024db921..f0b82c07d7f8 100644 --- a/ports/nordic/common-hal/busio/UART.c +++ b/ports/nordic/common-hal/busio/UART.c @@ -15,14 +15,14 @@ #include "py/stream.h" #include "nrfx_uarte.h" -#include "nrf_gpio.h" +#include #include // expression to examine, and return value in case of failing #define _VERIFY_ERR(_exp) \ do { \ uint32_t _err = (_exp); \ - if (NRFX_SUCCESS != _err) { \ + while (NRFX_SUCCESS != _err) { \ mp_raise_msg_varg(&mp_type_RuntimeError, MP_ERROR_TEXT("error = 0x%08lX"), _err); \ } \ } while (0) @@ -36,6 +36,17 @@ static nrfx_uarte_t nrfx_uartes[] = { #endif }; +static void *irq_handlers[] = { + #if NRFX_CHECK(NRFX_UARTE0_ENABLED) + NRFX_UARTE_INST_HANDLER_GET(0), + #endif + #if NRFX_CHECK(NRFX_UARTE1_ENABLED) + NRFX_UARTE_INST_HANDLER_GET(1), + #endif +}; + + + static bool never_reset[NRFX_UARTE0_ENABLED + NRFX_UARTE1_ENABLED]; static uint32_t get_nrf_baud(uint32_t baudrate) { @@ -80,8 +91,8 @@ static void uart_callback_irq(const nrfx_uarte_event_t *event, void *context) { switch (event->type) { case NRFX_UARTE_EVT_RX_DONE: - if (ringbuf_num_empty(&self->ringbuf) >= event->data.rxtx.bytes) { - ringbuf_put_n(&self->ringbuf, event->data.rxtx.p_data, event->data.rxtx.bytes); + if (ringbuf_num_empty(&self->ringbuf) >= event->data.rx.length) { + ringbuf_put_n(&self->ringbuf, event->data.rx.p_buffer, event->data.rx.length); // keep receiving (void)nrfx_uarte_rx(self->uarte, &self->rx_char, 1); } else { @@ -100,7 +111,7 @@ static void uart_callback_irq(const nrfx_uarte_event_t *event, void *context) { // Possible Error source is Overrun, Parity, Framing, Break // uint32_t errsrc = event->data.error.error_mask; - ringbuf_put_n(&self->ringbuf, event->data.error.rxtx.p_data, event->data.error.rxtx.bytes); + ringbuf_put_n(&self->ringbuf, event->data.error.rx.p_buffer, event->data.error.rx.length); // Keep receiving (void)nrfx_uarte_rx(self->uarte, &self->rx_char, 1); @@ -151,9 +162,11 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, // Find a free UART peripheral. self->uarte = NULL; + void *handler = NULL; for (size_t i = 0; i < MP_ARRAY_SIZE(nrfx_uartes); i++) { if ((nrfx_uartes[i].p_reg->ENABLE & UARTE_ENABLE_ENABLE_Msk) == 0) { self->uarte = &nrfx_uartes[i]; + handler = irq_handlers[i]; break; } } @@ -173,19 +186,25 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, bool hwfc = rts != NULL || cts != NULL; nrfx_uarte_config_t config = { - .pseltxd = (tx == NULL) ? NRF_UARTE_PSEL_DISCONNECTED : tx->number, - .pselrxd = (rx == NULL) ? NRF_UARTE_PSEL_DISCONNECTED : rx->number, - .pselcts = (cts == NULL) ? NRF_UARTE_PSEL_DISCONNECTED : cts->number, - .pselrts = (rts == NULL) ? NRF_UARTE_PSEL_DISCONNECTED : rts->number, + .txd_pin = (tx == NULL) ? NRF_UARTE_PSEL_DISCONNECTED : tx->number, + .rxd_pin = (rx == NULL) ? NRF_UARTE_PSEL_DISCONNECTED : rx->number, + .cts_pin = (cts == NULL) ? NRF_UARTE_PSEL_DISCONNECTED : cts->number, + .rts_pin = (rts == NULL) ? NRF_UARTE_PSEL_DISCONNECTED : rts->number, + .skip_gpio_cfg = false, + .skip_psel_cfg = false, .p_context = self, .baudrate = get_nrf_baud(baudrate), .interrupt_priority = NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY, - .hal_cfg = { + .config = { .hwfc = hwfc ? NRF_UARTE_HWFC_ENABLED : NRF_UARTE_HWFC_DISABLED, .parity = (parity == BUSIO_UART_PARITY_NONE) ? NRF_UARTE_PARITY_EXCLUDED : NRF_UARTE_PARITY_INCLUDED } }; + // Manually connect the UART IRQ through Zephyr. + irq_connect_dynamic(nrfx_get_irq_number(self->uarte->p_reg), NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY, + nrfx_isr, handler, 0); + _VERIFY_ERR(nrfx_uarte_init(self->uarte, &config, uart_callback_irq)); // Init buffer for rx @@ -337,7 +356,7 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, RUN_BACKGROUND_TASKS; } - (*errcode) = nrfx_uarte_tx(self->uarte, tx_buf, len); + (*errcode) = nrfx_uarte_tx(self->uarte, tx_buf, len, 0); _VERIFY_ERR(*errcode); (*errcode) = 0; diff --git a/ports/nordic/common-hal/microcontroller/Pin.c b/ports/nordic/common-hal/microcontroller/Pin.c index 2574083007be..c1fdfb209a6a 100644 --- a/ports/nordic/common-hal/microcontroller/Pin.c +++ b/ports/nordic/common-hal/microcontroller/Pin.c @@ -7,7 +7,6 @@ #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/digitalio/DigitalInOut.h" -#include "nrf_gpio.h" #include "py/mphal.h" #include "nrf/pins.h" diff --git a/ports/nordic/nrfx b/ports/nordic/nrfx deleted file mode 160000 index ab21106ea57b..000000000000 --- a/ports/nordic/nrfx +++ /dev/null @@ -1 +0,0 @@ -Subproject commit ab21106ea57b63d97b757a9f17201ddf298ffab0 diff --git a/ports/nordic/peripherals/nrf/pins.h b/ports/nordic/peripherals/nrf/pins.h index a964e6536878..4230930225fc 100644 --- a/ports/nordic/peripherals/nrf/pins.h +++ b/ports/nordic/peripherals/nrf/pins.h @@ -12,6 +12,8 @@ #include #include +#include + typedef struct { mp_obj_base_t base; // These could be squeezed to fewer bits if more fields are needed. diff --git a/prj.conf b/prj.conf index 3ea26a39870d..090e5fdc8d0d 100644 --- a/prj.conf +++ b/prj.conf @@ -1,6 +1,9 @@ CONFIG_HEAP_MEM_POOL_SIZE=65536 -CONFIG_CONSOLE_SUBSYS=y -CONFIG_CONSOLE_GETCHAR=y CONFIG_LOG=y +CONFIG_FLASH=y +CONFIG_FLASH_MAP=y CONFIG_RING_BUFFER=y +CONFIG_NRFX_UARTE0=y +CONFIG_NRFX_UARTE1=y +CONFIG_DYNAMIC_INTERRUPTS=y diff --git a/supervisor/shared/serial.c b/supervisor/shared/serial.c index a3354d4b9905..17bd98382e50 100644 --- a/supervisor/shared/serial.c +++ b/supervisor/shared/serial.c @@ -152,6 +152,7 @@ void serial_early_init(void) { // Do an initial print so that we can confirm the serial output is working. console_uart_printf("Serial console setup\r\n"); + printk("Serial console setup\r\n"); #endif board_serial_early_init(); diff --git a/supervisor/zephyr/flash.c b/supervisor/zephyr/flash.c index ab3aff58f82f..5be7dd8f1a5f 100644 --- a/supervisor/zephyr/flash.c +++ b/supervisor/zephyr/flash.c @@ -15,7 +15,12 @@ #include "py/runtime.h" #include "lib/oofatfs/ff.h" +#include + +static struct flash_area *filesystem_area = NULL; + void supervisor_flash_init(void) { + flash_area_open(FIXED_PARTITION_ID(storage_partition), &filesystem_area); } uint32_t supervisor_flash_get_block_size(void) { @@ -27,6 +32,7 @@ uint32_t supervisor_flash_get_block_count(void) { } mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) { + flash_area_read(filesystem_area, block * 512, dest, num_blocks * 512); return 0; // success } diff --git a/supervisor/zephyr/serial.c b/supervisor/zephyr/serial.c index 08d8c063bd60..4806ebb8f0e9 100644 --- a/supervisor/zephyr/serial.c +++ b/supervisor/zephyr/serial.c @@ -5,77 +5,24 @@ // SPDX-License-Identifier: MIT #include "supervisor/shared/serial.h" -#include "py/ringbuf.h" - -#include - -// #if defined(CONFIG_CONSOLE_SUBSYS) - -#include -#include - -// init the console ourselves so we can set the timeout to zero. -static struct tty_serial console_serial; - -static uint8_t console_rxbuf[CONFIG_CONSOLE_GETCHAR_BUFSIZE]; -static uint8_t console_txbuf[CONFIG_CONSOLE_PUTCHAR_BUFSIZE]; void port_serial_early_init(void) { - const struct device *uart_dev; - int ret; - - uart_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_console)); - if (!device_is_ready(uart_dev)) { - return -ENODEV; - } - - ret = tty_init(&console_serial, uart_dev); - - if (ret) { - return ret; - } - - /* Checks device driver supports for interrupt driven data transfers. */ - if (CONFIG_CONSOLE_GETCHAR_BUFSIZE + CONFIG_CONSOLE_PUTCHAR_BUFSIZE) { - const struct uart_driver_api *api = - (const struct uart_driver_api *)uart_dev->api; - if (!api->irq_callback_set) { - return -ENOTSUP; - } - } - - tty_set_tx_buf(&console_serial, console_txbuf, sizeof(console_txbuf)); - tty_set_rx_buf(&console_serial, console_rxbuf, sizeof(console_rxbuf)); - - printk("port_serial_early_init done"); } void port_serial_init(void) { } bool port_serial_connected(void) { - return true; + return false; } char port_serial_read(void) { - char buf[1]; - ssize_t read = tty_read(&console_serial, buf, 1); - if (read == 0) { - return -1; - } - return buf[0]; + return -1; } uint32_t port_serial_bytes_available(void) { - _fill_ring_buf(); - return ring_buf_size_get(&rb); + return 0; } void port_serial_write_substring(const char *text, uint32_t length) { - uint32_t total_written = 0; - while (total_written < length) { - total_written += tty_write(NULL, text + total_written, length - total_written); - } } - -// #endif diff --git a/tools/cpbuild/build_circuitpython.py b/tools/cpbuild/build_circuitpython.py index d45b9bef5c37..5cef7f5b79c1 100644 --- a/tools/cpbuild/build_circuitpython.py +++ b/tools/cpbuild/build_circuitpython.py @@ -173,6 +173,7 @@ async def build_circuitpython(): circuitpython_flags.extend(("-I", srcdir / "supervisor/shared/usb")) circuitpython_flags.extend(("-I", builddir)) circuitpython_flags.extend(("-I", srcdir / "ports" / port)) + circuitpython_flags.extend(("-I", srcdir / "ports" / port / "peripherals")) circuitpython_flags.extend(("-I", srcdir / "boards" / board)) # circuitpython_flags.extend(("-I", build_path / board_id)) @@ -198,6 +199,7 @@ async def build_circuitpython(): "lib/tlsf/tlsf.c", f"ports/{port}/background.c", f"ports/{port}/common-hal/microcontroller/__init__.c", + f"ports/{port}/common-hal/microcontroller/Pin.c", f"ports/{port}/common-hal/microcontroller/Processor.c", f"ports/{port}/common-hal/os/__init__.c", "supervisor/stub/misc.c", @@ -206,10 +208,14 @@ async def build_circuitpython(): "shared/runtime/interrupt_char.c", "shared/runtime/stdout_helpers.c", "shared/runtime/sys_stdio_mphal.c", + "shared-bindings/board/__init__.c", "shared-bindings/supervisor/Runtime.c", + "shared-bindings/microcontroller/Pin.c", + "shared-module/board/__init__.c", "extmod/vfs_reader.c", "extmod/vfs_blockdev.c", "extmod/vfs_fat_file.c", + f"boards/{board}/pins.c", ] top = srcdir supervisor_source = [pathlib.Path(p) for p in supervisor_source] @@ -220,6 +226,7 @@ async def build_circuitpython(): # Load the toml settings kwargs = {} + kwargs["busio"] = True with open(srcdir / "boards" / board / "mpconfigboard.toml", "rb") as f: mpconfigboard = tomllib.load(f) if usb_num_endpoint_pairs > 0: @@ -251,19 +258,26 @@ async def build_circuitpython(): # if flash_filesystem == "external": # supervisor_source.extend(top.glob("supervisor/shared/usb/*.c")) # Make sure all modules have a setting by filling in defaults. + hal_source = [] for module in top.glob("shared-bindings/*"): if not module.is_dir(): continue enabled = kwargs.get(module.name, module.name in DEFAULT_MODULES) kwargs[module.name] = enabled + print(f"Module {module.name} enabled: {enabled}") circuitpython_flags.append( f"-DCIRCUITPY_{module.name.upper()}={1 if kwargs[module.name] else 0}" ) + if enabled: + hal_source.extend(top.glob(f"ports/{port}/common-hal/{module.name}/*.c")) + hal_source.extend(top.glob(f"shared-bindings/{module.name}/*.c")) + for mpflag in MPCONFIG_FLAGS: circuitpython_flags.append(f"-DCIRCUITPY_{mpflag.upper()}=0") - source_files = supervisor_source + ["extmod/vfs.c"] + print(hal_source) + source_files = supervisor_source + hal_source + ["extmod/vfs.c"] for file in top.glob("py/*.c"): source_files.append(file) qstr_flags = "-DNO_QSTR" @@ -304,6 +318,7 @@ async def build_circuitpython(): source_files.append(srcdir / "shared-module/time/__init__.c") source_files.append(srcdir / "shared-module/os/__init__.c") source_files.append(srcdir / "shared-module/supervisor/__init__.c") + source_files.append(srcdir / "ports" / port / "peripherals" / "nrf" / "nrf52840" / "pins.c") assembly_files = [] assembly_files.append(srcdir / "ports/nordic/supervisor/cpu.s")