Skip to content

Commit

Permalink
CP console over UART doesn't work
Browse files Browse the repository at this point in the history
  • Loading branch information
tannewt committed Dec 17, 2024
1 parent 88e50b8 commit d9c05c5
Show file tree
Hide file tree
Showing 14 changed files with 81 additions and 95 deletions.
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 3 additions & 2 deletions boards/pca10056/mpconfigboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -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
Expand Down
5 changes: 2 additions & 3 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
1 change: 0 additions & 1 deletion ports/nordic/common-hal/busio/I2C.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
27 changes: 13 additions & 14 deletions ports/nordic/common-hal/busio/SPI.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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++) {
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand Down
41 changes: 30 additions & 11 deletions ports/nordic/common-hal/busio/UART.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@
#include "py/stream.h"

#include "nrfx_uarte.h"
#include "nrf_gpio.h"
#include <stdatomic.h>
#include <string.h>

// 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)
Expand All @@ -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) {
Expand Down Expand Up @@ -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 {
Expand All @@ -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);
Expand Down Expand Up @@ -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;
}
}
Expand All @@ -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
Expand Down Expand Up @@ -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;

Expand Down
1 change: 0 additions & 1 deletion ports/nordic/common-hal/microcontroller/Pin.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
1 change: 0 additions & 1 deletion ports/nordic/nrfx
Submodule nrfx deleted from ab2110
2 changes: 2 additions & 0 deletions ports/nordic/peripherals/nrf/pins.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include <stdint.h>
#include <stdbool.h>

#include <hal/nrf_gpio.h>

typedef struct {
mp_obj_base_t base;
// These could be squeezed to fewer bits if more fields are needed.
Expand Down
7 changes: 5 additions & 2 deletions prj.conf
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions supervisor/shared/serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
6 changes: 6 additions & 0 deletions supervisor/zephyr/flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@
#include "py/runtime.h"
#include "lib/oofatfs/ff.h"

#include <zephyr/storage/flash_map.h>

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) {
Expand All @@ -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
}

Expand Down
59 changes: 3 additions & 56 deletions supervisor/zephyr/serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,77 +5,24 @@
// SPDX-License-Identifier: MIT

#include "supervisor/shared/serial.h"
#include "py/ringbuf.h"

#include <zephyr/autoconf.h>

// #if defined(CONFIG_CONSOLE_SUBSYS)

#include <zephyr/console/console.h>
#include <zephyr/sys/ring_buffer.h>

// 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
Loading

0 comments on commit d9c05c5

Please sign in to comment.