Switch to port_serial_* hooks

This makes it easier to integrate port specific serial alongside
the common approaches.
This commit is contained in:
Scott Shawcroft 2022-03-22 19:40:33 -07:00
parent 110857c12e
commit f5d90fc84f
No known key found for this signature in database
GPG Key ID: 0DFD512649C052DA
7 changed files with 70 additions and 214 deletions

View File

@ -24,104 +24,20 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
// This file will only be used when CIRCUITPY_USB is 0. See
// supervisor/supervisor.mk for the rule that applies.
#include <stdarg.h>
#include <string.h>
#include "py/mpconfig.h" #include "py/mpconfig.h"
#include "supervisor/shared/cpu.h"
#include "supervisor/shared/display.h"
#include "shared-bindings/terminalio/Terminal.h"
#include "supervisor/serial.h" #include "supervisor/serial.h"
#include "shared-bindings/microcontroller/Pin.h"
#if CIRCUITPY_SERIAL_BLE
#include "supervisor/shared/bluetooth/serial.h"
#endif
#if defined(CIRCUITPY_DEBUG_UART_TX) || defined(CIRCUITPY_DEBUG_UART_RX)
#include "py/mpprint.h"
#include "shared-bindings/busio/UART.h"
busio_uart_obj_t debug_uart;
byte buf_array[64];
#endif
#if CIRCUITPY_ESP_USB_SERIAL_JTAG #if CIRCUITPY_ESP_USB_SERIAL_JTAG
#include "supervisor/usb_serial_jtag.h" #include "supervisor/usb_serial_jtag.h"
#endif #endif
#if defined(CIRCUITPY_DEBUG_UART_TX) void port_serial_init(void) {
STATIC void debug_uart_print_strn(void *env, const char *str, size_t len) {
(void)env;
int uart_errcode;
common_hal_busio_uart_write(&debug_uart, (const uint8_t *)str, len, &uart_errcode);
}
const mp_print_t debug_uart_print = {NULL, debug_uart_print_strn};
#endif
int debug_uart_printf(const char *fmt, ...) {
#if defined(CIRCUITPY_DEBUG_UART_TX)
// Skip prints that occur before debug serial is started. It's better than
// crashing.
if (common_hal_busio_uart_deinited(&debug_uart)) {
return 0;
}
va_list ap;
va_start(ap, fmt);
int ret = mp_vprintf(&debug_uart_print, fmt, ap);
va_end(ap);
return ret;
#else
return 0;
#endif
}
void serial_early_init(void) {
#if defined(CIRCUITPY_DEBUG_UART_TX) || defined(CIRCUITPY_DEBUG_UART_RX)
debug_uart.base.type = &busio_uart_type;
#if defined(CIRCUITPY_DEBUG_UART_RX)
const mcu_pin_obj_t *rx = MP_OBJ_TO_PTR(CIRCUITPY_DEBUG_UART_RX);
#else
const mcu_pin_obj_t *rx = NULL;
#endif
#if defined(CIRCUITPY_DEBUG_UART_TX)
const mcu_pin_obj_t *tx = MP_OBJ_TO_PTR(CIRCUITPY_DEBUG_UART_TX);
#else
const mcu_pin_obj_t *tx = NULL;
#endif
common_hal_busio_uart_construct(&debug_uart, tx, rx, NULL, NULL, NULL,
false, 115200, 8, BUSIO_UART_PARITY_NONE, 1, 1.0f, 64,
buf_array, true);
common_hal_busio_uart_never_reset(&debug_uart);
// Do an initial print so that we can confirm the serial output is working.
debug_uart_printf("Serial debug setup\r\n");
#endif
}
void serial_init(void) {
#if CIRCUITPY_ESP_USB_SERIAL_JTAG #if CIRCUITPY_ESP_USB_SERIAL_JTAG
usb_serial_jtag_init(); usb_serial_jtag_init();
#endif #endif
} }
bool serial_connected(void) { bool port_serial_connected(void) {
#if defined(CIRCUITPY_DEBUG_UART_TX) && defined(CIRCUITPY_DEBUG_UART_RX)
return true;
#endif
#if CIRCUITPY_SERIAL_BLE
if (ble_serial_connected()) {
return true;
}
#endif
#if CIRCUITPY_ESP_USB_SERIAL_JTAG #if CIRCUITPY_ESP_USB_SERIAL_JTAG
if (usb_serial_jtag_connected()) { if (usb_serial_jtag_connected()) {
return true; return true;
@ -131,23 +47,7 @@ bool serial_connected(void) {
return false; return false;
} }
char serial_read(void) { char port_serial_read(void) {
#if defined(CIRCUITPY_DEBUG_UART_RX)
if (common_hal_busio_uart_rx_characters_available(&debug_uart)) {
int uart_errcode;
char text;
common_hal_busio_uart_read(&debug_uart, (uint8_t *)&text, 1, &uart_errcode);
return text;
}
#endif
#if CIRCUITPY_SERIAL_BLE
if (ble_serial_available() > 0) {
return ble_serial_read_char();
}
#endif
#if CIRCUITPY_ESP_USB_SERIAL_JTAG #if CIRCUITPY_ESP_USB_SERIAL_JTAG
if (usb_serial_jtag_bytes_available() > 0) { if (usb_serial_jtag_bytes_available() > 0) {
return usb_serial_jtag_read_char(); return usb_serial_jtag_read_char();
@ -156,19 +56,7 @@ char serial_read(void) {
return -1; return -1;
} }
bool serial_bytes_available(void) { bool port_serial_bytes_available(void) {
#if defined(CIRCUITPY_DEBUG_UART_RX)
if (common_hal_busio_uart_rx_characters_available(&debug_uart)) {
return true;
}
#endif
#if CIRCUITPY_SERIAL_BLE
if (ble_serial_available()) {
return true;
}
#endif
#if CIRCUITPY_ESP_USB_SERIAL_JTAG #if CIRCUITPY_ESP_USB_SERIAL_JTAG
if (usb_serial_jtag_bytes_available()) { if (usb_serial_jtag_bytes_available()) {
return true; return true;
@ -178,30 +66,8 @@ bool serial_bytes_available(void) {
return false; return false;
} }
void serial_write_substring(const char *text, uint32_t length) { void port_serial_write_substring(const char *text, uint32_t length) {
if (length == 0) {
return;
}
#if CIRCUITPY_TERMINALIO
int errcode;
common_hal_terminalio_terminal_write(&supervisor_terminal, (const uint8_t *)text, length, &errcode);
#endif
#if defined(CIRCUITPY_DEBUG_UART_TX)
int uart_errcode;
common_hal_busio_uart_write(&debug_uart, (const uint8_t *)text, length, &uart_errcode);
#endif
#if CIRCUITPY_SERIAL_BLE
ble_serial_write(text, length);
#endif
#if CIRCUITPY_ESP_USB_SERIAL_JTAG #if CIRCUITPY_ESP_USB_SERIAL_JTAG
usb_serial_jtag_write(text, length); usb_serial_jtag_write(text, length);
#endif #endif
} }
void serial_write(const char *text) {
serial_write_substring(text, strlen(text));
}

View File

@ -1,43 +0,0 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2020 Scott Shawcroft for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdbool.h>
#include "py/mpconfig.h"
#include "supervisor/serial.h"
#include "supervisor/workflow.h"
#include "supervisor/shared/workflow.h"
void supervisor_workflow_reset(void) {
}
bool supervisor_workflow_connecting(void) {
return false;
}
// Return true if host has completed connection to us (such as USB enumeration).
bool supervisor_workflow_active(void) {
return serial_connected();
}

View File

@ -33,6 +33,8 @@
#include "fsl_clock.h" #include "fsl_clock.h"
#include "fsl_lpuart.h" #include "fsl_lpuart.h"
// TODO: Switch this to using DEBUG_UART.
// static LPUART_Type *uart_instance = LPUART1; // evk // static LPUART_Type *uart_instance = LPUART1; // evk
static LPUART_Type *uart_instance = LPUART4; // feather 1011 static LPUART_Type *uart_instance = LPUART4; // feather 1011
// static LPUART_Type *uart_instance = LPUART2; // feather 1062 // static LPUART_Type *uart_instance = LPUART2; // feather 1062
@ -52,7 +54,7 @@ static uint32_t UartSrcFreq(void) {
return freq; return freq;
} }
void serial_init(void) { void port_serial_init(void) {
lpuart_config_t config; lpuart_config_t config;
LPUART_GetDefaultConfig(&config); LPUART_GetDefaultConfig(&config);
@ -63,11 +65,11 @@ void serial_init(void) {
LPUART_Init(uart_instance, &config, UartSrcFreq()); LPUART_Init(uart_instance, &config, UartSrcFreq());
} }
bool serial_connected(void) { bool port_serial_connected(void) {
return true; return true;
} }
char serial_read(void) { char port_serial_read(void) {
uint8_t data; uint8_t data;
LPUART_ReadBlocking(uart_instance, &data, sizeof(data)); LPUART_ReadBlocking(uart_instance, &data, sizeof(data));
@ -75,15 +77,11 @@ char serial_read(void) {
return data; return data;
} }
bool serial_bytes_available(void) { bool port_serial_bytes_available(void) {
return LPUART_GetStatusFlags(uart_instance) & kLPUART_RxDataRegFullFlag; return LPUART_GetStatusFlags(uart_instance) & kLPUART_RxDataRegFullFlag;
} }
void serial_write(const char *text) { void port_serial_write_substring(const char *text, uint32_t len) {
LPUART_WriteBlocking(uart_instance, (uint8_t *)text, strlen(text));
}
void serial_write_substring(const char *text, uint32_t len) {
if (len == 0) { if (len == 0) {
return; return;
} }

View File

@ -31,9 +31,11 @@
#include "stm32f4xx_hal.h" #include "stm32f4xx_hal.h"
#include "stm32f4/gpio.h" #include "stm32f4/gpio.h"
// TODO: Switch this to using DEBUG_UART.
UART_HandleTypeDef huart2; UART_HandleTypeDef huart2;
void serial_init(void) { void port_serial_init(void) {
huart2.Instance = USART2; huart2.Instance = USART2;
huart2.Init.BaudRate = 115200; huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.WordLength = UART_WORDLENGTH_8B;
@ -47,25 +49,21 @@ void serial_init(void) {
} }
} }
bool serial_connected(void) { bool port_serial_connected(void) {
return true; return true;
} }
char serial_read(void) { char port_serial_read(void) {
uint8_t data; uint8_t data;
HAL_UART_Receive(&huart2, &data, 1,500); HAL_UART_Receive(&huart2, &data, 1,500);
return data; return data;
} }
bool serial_bytes_available(void) { bool port_serial_bytes_available(void) {
return __HAL_UART_GET_FLAG(&huart2, UART_FLAG_RXNE); return __HAL_UART_GET_FLAG(&huart2, UART_FLAG_RXNE);
} }
void serial_write(const char *text) { void port_serial_write_substring(const char *text, uint32_t len) {
serial_write_substring(text, strlen(text));
}
void serial_write_substring(const char *text, uint32_t len) {
if (len == 0) { if (len == 0) {
return; return;
} }

View File

@ -39,6 +39,7 @@
extern vstr_t *boot_output; extern vstr_t *boot_output;
#endif #endif
void serial_early_init(void); void serial_early_init(void);
void serial_init(void); void serial_init(void);
void serial_write(const char *text); void serial_write(const char *text);
@ -48,6 +49,14 @@ char serial_read(void);
bool serial_bytes_available(void); bool serial_bytes_available(void);
bool serial_connected(void); bool serial_connected(void);
// These have no-op versions that are weak and the port can override. They work
// in tandem with the cross-port mechanics like USB and BLE.
void port_serial_init(void);
bool port_serial_connected(void);
char port_serial_read(void);
bool port_serial_bytes_available(void);
void port_serial_write_substring(const char *text, uint32_t length);
int debug_uart_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); int debug_uart_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
#endif // MICROPY_INCLUDED_SUPERVISOR_SERIAL_H #endif // MICROPY_INCLUDED_SUPERVISOR_SERIAL_H

View File

@ -88,6 +88,26 @@ int debug_uart_printf(const char *fmt, ...) {
#endif #endif
} }
MP_WEAK void port_serial_init(void) {
}
MP_WEAK bool port_serial_connected(void) {
return false;
}
MP_WEAK char port_serial_read(void) {
return -1;
}
MP_WEAK bool port_serial_bytes_available(void) {
return false;
}
MP_WEAK void port_serial_write_substring(const char *text, uint32_t length) {
(void)text;
(void)length;
}
void serial_early_init(void) { void serial_early_init(void) {
#if defined(CIRCUITPY_DEBUG_UART_TX) || defined(CIRCUITPY_DEBUG_UART_RX) #if defined(CIRCUITPY_DEBUG_UART_TX) || defined(CIRCUITPY_DEBUG_UART_RX)
debug_uart.base.type = &busio_uart_type; debug_uart.base.type = &busio_uart_type;
@ -115,7 +135,7 @@ void serial_early_init(void) {
} }
void serial_init(void) { void serial_init(void) {
// USB serial is set up separately. port_serial_init();
} }
bool serial_connected(void) { bool serial_connected(void) {
@ -144,6 +164,10 @@ bool serial_connected(void) {
return true; return true;
} }
#endif #endif
if (port_serial_connected()) {
return true;
}
return false; return false;
} }
@ -179,6 +203,10 @@ char serial_read(void) {
#if CIRCUITPY_USB #if CIRCUITPY_USB
return (char)tud_cdc_read_char(); return (char)tud_cdc_read_char();
#endif #endif
if (port_serial_bytes_available() > 0) {
return port_serial_read();
}
return -1; return -1;
} }
@ -211,6 +239,10 @@ bool serial_bytes_available(void) {
return true; return true;
} }
#endif #endif
if (port_serial_bytes_available() > 0) {
return true;
}
return false; return false;
} }
@ -256,6 +288,8 @@ void serial_write_substring(const char *text, uint32_t length) {
usb_background(); usb_background();
} }
#endif #endif
port_serial_write_substring(text, length);
} }
void serial_write(const char *text) { void serial_write(const char *text) {

View File

@ -10,11 +10,13 @@ SRC_SUPERVISOR = \
supervisor/shared/micropython.c \ supervisor/shared/micropython.c \
supervisor/shared/reload.c \ supervisor/shared/reload.c \
supervisor/shared/safe_mode.c \ supervisor/shared/safe_mode.c \
supervisor/shared/serial.c \
supervisor/shared/stack.c \ supervisor/shared/stack.c \
supervisor/shared/status_leds.c \ supervisor/shared/status_leds.c \
supervisor/shared/tick.c \ supervisor/shared/tick.c \
supervisor/shared/traceback.c \ supervisor/shared/traceback.c \
supervisor/shared/translate.c supervisor/shared/translate.c \
supervisor/shared/workflow.c
ifeq ($(DISABLE_FILESYSTEM),1) ifeq ($(DISABLE_FILESYSTEM),1)
SRC_SUPERVISOR += supervisor/stub/filesystem.c SRC_SUPERVISOR += supervisor/stub/filesystem.c
@ -76,25 +78,17 @@ $(BUILD)/supervisor/shared/external_flash/external_flash.o: $(HEADER_BUILD)/devi
endif endif
ifeq ($(CIRCUITPY_USB),0) ifneq ($(wildcard supervisor/serial.c),)
ifeq ($(wildcard supervisor/serial.c),) SRC_SUPERVISOR += supervisor/serial.c
SRC_SUPERVISOR += supervisor/shared/serial.c \ endif
supervisor/shared/workflow.c \
else ifeq ($(CIRCUITPY_USB),1)
SRC_SUPERVISOR += supervisor/serial.c \
supervisor/workflow.c \
endif
else
SRC_SUPERVISOR += \ SRC_SUPERVISOR += \
lib/tinyusb/src/class/cdc/cdc_device.c \ lib/tinyusb/src/class/cdc/cdc_device.c \
lib/tinyusb/src/common/tusb_fifo.c \ lib/tinyusb/src/common/tusb_fifo.c \
lib/tinyusb/src/device/usbd.c \ lib/tinyusb/src/device/usbd.c \
lib/tinyusb/src/device/usbd_control.c \ lib/tinyusb/src/device/usbd_control.c \
lib/tinyusb/src/tusb.c \ lib/tinyusb/src/tusb.c \
supervisor/shared/serial.c \
supervisor/shared/workflow.c \
supervisor/usb.c \ supervisor/usb.c \
supervisor/shared/usb/usb_desc.c \ supervisor/shared/usb/usb_desc.c \
supervisor/shared/usb/usb.c \ supervisor/shared/usb/usb.c \