Skip to content

Add support for a debug console, such as ST-Link VCP. #2837

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,9 @@ int __attribute__((used)) main(void) {
// displays init after filesystem, since they could share the flash SPI
board_init();

// Start the debug serial
serial_early_init();

// Reset everything and prep MicroPython to run boot.py.
reset_port();
reset_board();
Expand Down
3 changes: 2 additions & 1 deletion ports/atmel-samd/common-hal/busio/UART.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
const mcu_pin_obj_t * rts, const mcu_pin_obj_t * cts,
const mcu_pin_obj_t * rs485_dir, bool rs485_invert,
uint32_t baudrate, uint8_t bits, uart_parity_t parity, uint8_t stop,
mp_float_t timeout, uint16_t receiver_buffer_size) {
mp_float_t timeout, uint16_t receiver_buffer_size, byte* receiver_buffer,
bool sigint_enabled) {

Sercom* sercom = NULL;
uint8_t sercom_index = 255; // Unset index
Expand Down
3 changes: 2 additions & 1 deletion ports/cxd56/common-hal/busio/UART.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
const mcu_pin_obj_t * rts, const mcu_pin_obj_t * cts,
const mcu_pin_obj_t * rs485_dir, bool rs485_invert,
uint32_t baudrate, uint8_t bits, uart_parity_t parity, uint8_t stop,
mp_float_t timeout, uint16_t receiver_buffer_size) {
mp_float_t timeout, uint16_t receiver_buffer_size, byte* receiver_buffer,
bool sigint_enabled) {
struct termios tio;

if ((rts != NULL) || (cts != NULL) || (rs485_dir != NULL) || (rs485_invert)) {
Expand Down
3 changes: 2 additions & 1 deletion ports/mimxrt10xx/common-hal/busio/UART.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
const mcu_pin_obj_t * rts, const mcu_pin_obj_t * cts,
const mcu_pin_obj_t * rs485_dir, bool rs485_invert,
uint32_t baudrate, uint8_t bits, uart_parity_t parity, uint8_t stop,
mp_float_t timeout, uint16_t receiver_buffer_size) {
mp_float_t timeout, uint16_t receiver_buffer_size, byte* receiver_buffer,
bool sigint_enabled) {

// TODO: Allow none rx or tx

Expand Down
3 changes: 2 additions & 1 deletion ports/nrf/common-hal/busio/UART.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
const mcu_pin_obj_t * rts, const mcu_pin_obj_t * cts,
const mcu_pin_obj_t * rs485_dir, bool rs485_invert,
uint32_t baudrate, uint8_t bits, uart_parity_t parity, uint8_t stop,
mp_float_t timeout, uint16_t receiver_buffer_size) {
mp_float_t timeout, uint16_t receiver_buffer_size, byte* receiver_buffer,
bool sigint_enabled) {

if ((rts != NULL) || (cts != NULL) || (rs485_dir != NULL) || (rs485_invert)) {
mp_raise_ValueError(translate("RTS/CTS/RS485 Not yet supported on this device"));
Expand Down
3 changes: 3 additions & 0 deletions ports/stm/boards/nucleo_f746zg/mpconfigboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,6 @@
#define FLASH_PAGE_SIZE (0x4000)

#define BOARD_OSC_DIV (8)

#define DEBUG_UART_TX (&pin_PD08)
#define DEBUG_UART_RX (&pin_PD09)
5 changes: 3 additions & 2 deletions ports/stm/boards/nucleo_f746zg/pins.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,9 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_USB_ID), MP_ROM_PTR(&pin_PA10) },
{ MP_ROM_QSTR(MP_QSTR_USB_DM), MP_ROM_PTR(&pin_PA11) },
{ MP_ROM_QSTR(MP_QSTR_USB_DP), MP_ROM_PTR(&pin_PA12) },
{ MP_ROM_QSTR(MP_QSTR_VCP_TX), MP_ROM_PTR(&pin_PD08) },
{ MP_ROM_QSTR(MP_QSTR_VCP_RX), MP_ROM_PTR(&pin_PD09) },
// As we use these for the debug_console, we won't enable them here.
// { MP_ROM_QSTR(MP_QSTR_VCP_TX), MP_ROM_PTR(&pin_PD08) },
// { MP_ROM_QSTR(MP_QSTR_VCP_RX), MP_ROM_PTR(&pin_PD09) },
{ MP_ROM_QSTR(MP_QSTR_UART2_TX), MP_ROM_PTR(&pin_PD05) },
{ MP_ROM_QSTR(MP_QSTR_UART2_RX), MP_ROM_PTR(&pin_PD06) },
{ MP_ROM_QSTR(MP_QSTR_UART2_RTS), MP_ROM_PTR(&pin_PD04) },
Expand Down
52 changes: 45 additions & 7 deletions ports/stm/common-hal/busio/UART.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "shared-bindings/busio/UART.h"

#include "mpconfigport.h"
#include "lib/mp-readline/readline.h"
#include "lib/utils/interrupt_char.h"
#include "py/gc.h"
#include "py/mperrno.h"
Expand All @@ -39,6 +40,7 @@

//arrays use 0 based numbering: UART1 is stored at index 0
STATIC bool reserved_uart[MAX_UART];
STATIC bool never_reset_uart[MAX_UART];
int errflag; //Used to restart read halts

STATIC void uart_clock_enable(uint16_t mask);
Expand All @@ -61,19 +63,25 @@ STATIC USART_TypeDef * assign_uart_or_throw(busio_uart_obj_t* self, bool pin_eva
}

void uart_reset(void) {
uint16_t never_reset_mask = 0x00;
for (uint8_t i = 0; i < MAX_UART; i++) {
reserved_uart[i] = false;
MP_STATE_PORT(cpy_uart_obj_all)[i] = NULL;
if (!never_reset_uart[i]) {
reserved_uart[i] = false;
MP_STATE_PORT(cpy_uart_obj_all)[i] = NULL;
} else {
never_reset_mask |= 1 << i;
}
}
uart_clock_disable(ALL_UARTS);
uart_clock_disable(ALL_UARTS & ~(never_reset_mask));
}

void common_hal_busio_uart_construct(busio_uart_obj_t *self,
const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx,
const mcu_pin_obj_t * rts, const mcu_pin_obj_t * cts,
const mcu_pin_obj_t * rs485_dir, bool rs485_invert,
uint32_t baudrate, uint8_t bits, uart_parity_t parity, uint8_t stop,
mp_float_t timeout, uint16_t receiver_buffer_size) {
mp_float_t timeout, uint16_t receiver_buffer_size, byte* receiver_buffer,
bool sigint_enabled) {

//match pins to UART objects
USART_TypeDef * USARTx;
Expand Down Expand Up @@ -209,8 +217,12 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,

// Init buffer for rx and claim pins
if (self->rx != NULL) {
if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) {
mp_raise_ValueError(translate("UART Buffer allocation error"));
if (receiver_buffer != NULL) {
self->ringbuf = (ringbuf_t){ receiver_buffer, receiver_buffer_size };
} else {
if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) {
mp_raise_ValueError(translate("UART Buffer allocation error"));
}
}
claim_pin(rx);
}
Expand All @@ -219,6 +231,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
}
self->baudrate = baudrate;
self->timeout_ms = timeout * 1000;
self->sigint_enabled = sigint_enabled;

//start the interrupt series
if ((HAL_UART_GetState(&self->handle) & HAL_UART_STATE_BUSY_RX) == HAL_UART_STATE_BUSY_RX) {
Expand All @@ -234,13 +247,31 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
errflag = HAL_OK;
}

void common_hal_busio_uart_never_reset(busio_uart_obj_t *self) {
for (size_t i = 0; i < MP_ARRAY_SIZE(mcu_uart_banks); i++) {
if (mcu_uart_banks[i] == self->handle.Instance) {
never_reset_uart[i] = true;
never_reset_pin_number(self->tx->pin->port, self->tx->pin->number);
never_reset_pin_number(self->rx->pin->port, self->rx->pin->number);
break;
}
}
}

bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) {
return self->tx->pin == NULL;
}

void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
if (common_hal_busio_uart_deinited(self)) return;

for (size_t i = 0; i < MP_ARRAY_SIZE(mcu_uart_banks); i++) {
if (mcu_uart_banks[i] == self->handle.Instance) {
never_reset_uart[i] = false;
break;
}
}

reset_pin_number(self->tx->pin->port,self->tx->pin->number);
reset_pin_number(self->rx->pin->port,self->rx->pin->number);
self->tx = NULL;
Expand Down Expand Up @@ -289,7 +320,8 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data,
bool write_err = false; //write error shouldn't disable interrupts

HAL_NVIC_DisableIRQ(self->irq);
if (HAL_UART_Transmit(&self->handle, (uint8_t*)data, len, HAL_MAX_DELAY) != HAL_OK) {
HAL_StatusTypeDef ret = HAL_UART_Transmit(&self->handle, (uint8_t*)data, len, HAL_MAX_DELAY);
if (ret != HAL_OK) {
write_err = true;
}
HAL_UART_Receive_IT(&self->handle, &self->rx_char, 1);
Expand All @@ -313,6 +345,12 @@ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *handle)
}
ringbuf_put_n(&context->ringbuf, &context->rx_char, 1);
errflag = HAL_UART_Receive_IT(handle, &context->rx_char, 1);
if (context->sigint_enabled) {
if (context->rx_char == CHAR_CTRL_C) {
common_hal_busio_uart_clear_rx_buffer(context);
mp_keyboard_interrupt();
}
}

return;
}
Expand Down
2 changes: 2 additions & 0 deletions ports/stm/common-hal/busio/UART.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ typedef struct {

uint32_t baudrate;
uint32_t timeout_ms;

bool sigint_enabled;
} busio_uart_obj_t;

void uart_reset(void);
Expand Down
2 changes: 1 addition & 1 deletion shared-bindings/busio/UART.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, co

common_hal_busio_uart_construct(self, tx, rx, rts, cts, rs485_dir, rs485_invert,
args[ARG_baudrate].u_int, bits, parity, stop, timeout,
args[ARG_receiver_buffer_size].u_int);
args[ARG_receiver_buffer_size].u_int, NULL, false);
return (mp_obj_t)self;
}

Expand Down
6 changes: 5 additions & 1 deletion shared-bindings/busio/UART.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

#include "common-hal/microcontroller/Pin.h"
#include "common-hal/busio/UART.h"
#include "py/ringbuf.h"

extern const mp_obj_type_t busio_uart_type;

Expand All @@ -44,7 +45,8 @@ extern void common_hal_busio_uart_construct(busio_uart_obj_t *self,
const mcu_pin_obj_t * rts, const mcu_pin_obj_t * cts,
const mcu_pin_obj_t * rs485_dir, bool rs485_invert,
uint32_t baudrate, uint8_t bits, uart_parity_t parity, uint8_t stop,
mp_float_t timeout, uint16_t receiver_buffer_size);
mp_float_t timeout, uint16_t receiver_buffer_size, byte* receiver_buffer,
bool sigint_enabled);

extern void common_hal_busio_uart_deinit(busio_uart_obj_t *self);
extern bool common_hal_busio_uart_deinited(busio_uart_obj_t *self);
Expand All @@ -66,4 +68,6 @@ extern uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *
extern void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self);
extern bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self);

extern void common_hal_busio_uart_never_reset(busio_uart_obj_t *self);

#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_UART_H
2 changes: 1 addition & 1 deletion shared-module/board/__init__.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ mp_obj_t common_hal_board_create_uart(void) {
#endif

common_hal_busio_uart_construct(self, tx, rx, rts, cts, rs485_dir, rs485_invert,
9600, 8, PARITY_NONE, 1, 1.0f, 64);
9600, 8, PARITY_NONE, 1, 1.0f, 64, NULL, false);
MP_STATE_VM(shared_uart_bus) = MP_OBJ_FROM_PTR(self);
return MP_STATE_VM(shared_uart_bus);
}
Expand Down
1 change: 1 addition & 0 deletions supervisor/serial.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
FIL* boot_output_file;
#endif

void serial_early_init(void);
void serial_init(void);
void serial_write(const char* text);
// Only writes up to given length. Does not check for null termination at all.
Expand Down
52 changes: 52 additions & 0 deletions supervisor/shared/serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,26 +32,73 @@
#include "shared-bindings/terminalio/Terminal.h"
#include "supervisor/serial.h"
#include "supervisor/usb.h"
#include "shared-bindings/microcontroller/Pin.h"

#include "tusb.h"

/*
* Note: DEBUG_UART currently only works on STM32,
* enabling on another platform will cause a crash.
*/

#if defined(DEBUG_UART_TX) && defined(DEBUG_UART_RX)
#include "shared-bindings/busio/UART.h"
busio_uart_obj_t debug_uart;
byte buf_array[64];
#endif

void serial_early_init(void) {
#if defined(DEBUG_UART_TX) && defined(DEBUG_UART_RX)
debug_uart.base.type = &busio_uart_type;

const mcu_pin_obj_t* rx = MP_OBJ_TO_PTR(DEBUG_UART_RX);
const mcu_pin_obj_t* tx = MP_OBJ_TO_PTR(DEBUG_UART_TX);

common_hal_busio_uart_construct(&debug_uart, tx, rx, NULL, NULL, NULL,
false, 115200, 8, PARITY_NONE, 1, 1.0f, 64,
buf_array, true);
common_hal_busio_uart_never_reset(&debug_uart);
#endif
}

void serial_init(void) {
usb_init();
}

bool serial_connected(void) {
#if defined(DEBUG_UART_TX) && defined(DEBUG_UART_RX)
return true;
#else
return tud_cdc_connected();
#endif
}

char serial_read(void) {
#if defined(DEBUG_UART_TX) && defined(DEBUG_UART_RX)
if (tud_cdc_connected() && tud_cdc_available() > 0) {
return (char) tud_cdc_read_char();
}
int uart_errcode;
char text;
common_hal_busio_uart_read(&debug_uart, (uint8_t*) &text, 1, &uart_errcode);
return text;
#else
return (char) tud_cdc_read_char();
#endif
}

bool serial_bytes_available(void) {
#if defined(DEBUG_UART_TX) && defined(DEBUG_UART_RX)
return common_hal_busio_uart_rx_characters_available(&debug_uart) || (tud_cdc_available() > 0);
#else
return tud_cdc_available() > 0;
#endif
}

void serial_write_substring(const char* text, uint32_t length) {
if (length == 0) {
return;
}
#if CIRCUITPY_DISPLAYIO
int errcode;
common_hal_terminalio_terminal_write(&supervisor_terminal, (const uint8_t*) text, length, &errcode);
Expand All @@ -62,6 +109,11 @@ void serial_write_substring(const char* text, uint32_t length) {
count += tud_cdc_write(text + count, length - count);
usb_background();
}

#if defined(DEBUG_UART_TX) && defined(DEBUG_UART_RX)
int uart_errcode;
common_hal_busio_uart_write(&debug_uart, (const uint8_t*) text, length, &uart_errcode);
#endif
}

void serial_write(const char* text) {
Expand Down
4 changes: 4 additions & 0 deletions supervisor/stub/serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@

#include "supervisor/serial.h"

void serial_early_init(void) {

}

void serial_init(void) {

}
Expand Down