Add USB to Serial/JTAG support for REPL

Adds Adafruit QT Py C3 board that uses it. Also revamps size
check script to work for S3 and C3 as well.

Fixes #6030
This commit is contained in:
Scott Shawcroft 2022-03-21 13:57:29 -07:00
parent 4465adfe01
commit 6dd9db31b3
No known key found for this signature in database
GPG Key ID: 0DFD512649C052DA
15 changed files with 789 additions and 32 deletions

View File

@ -262,6 +262,11 @@ SRC_C += \
endif endif
endif endif
ifeq ($(IDF_TARGET),esp32c3)
SRC_C += \
supervisor/usb_serial_jtag.c
endif
$(BUILD)/i2s_lcd_esp32s2_driver.o: CFLAGS += -Wno-sign-compare $(BUILD)/i2s_lcd_esp32s2_driver.o: CFLAGS += -Wno-sign-compare
ifneq ($(CIRCUITPY_USB),0) ifneq ($(CIRCUITPY_USB),0)

View File

@ -0,0 +1,49 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2021 microDev
* Copyright (c) 2021 skieast/Bruce Segal
*
* 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 "shared-bindings/microcontroller/Pin.h"
#include "supervisor/board.h"
#include "components/driver/include/driver/gpio.h"
#include "soc/usb_serial_jtag_struct.h"
void board_init(void) {
}
bool board_requests_safe_mode(void) {
return false;
}
bool espressif_board_reset_pin_number(gpio_num_t pin_number) {
return false;
}
void reset_board(void) {
}
void board_deinit(void) {
}

View File

@ -0,0 +1,48 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2021 microDev
* Copyright (c) 2021 skieast/Bruce Segal
*
* 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.
*/
// Board setup
#define MICROPY_HW_BOARD_NAME "Adafruit QT Py ESP32C3"
#define MICROPY_HW_MCU_NAME "ESP32-C3FN4"
// Status LED
#define MICROPY_HW_NEOPIXEL (&pin_GPIO2)
#define CIRCUITPY_BOARD_I2C (1)
#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO6, .sda = &pin_GPIO5}}
#define CIRCUITPY_BOARD_SPI (1)
#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO10, .mosi = &pin_GPIO7, .miso = &pin_GPIO8}}
#define CIRCUITPY_BOARD_UART (1)
#define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO21, .rx = &pin_GPIO20}}
// For entering safe mode
#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO9)
// Explanation of how a user got into safe mode
#define BOARD_USER_SAFE_MODE_ACTION translate("pressing boot button at start up.\n")

View File

@ -0,0 +1,10 @@
CIRCUITPY_CREATOR_ID = 0x0000239A
CIRCUITPY_CREATION_ID = 0x00010001
IDF_TARGET = esp32c3
INTERNAL_FLASH_FILESYSTEM = 1
CIRCUITPY_ESP_FLASH_MODE=dio
CIRCUITPY_ESP_FLASH_FREQ=80m
CIRCUITPY_ESP_FLASH_SIZE=4MB

View File

@ -0,0 +1,85 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2021 microDev
* Copyright (c) 2021 skieast/Bruce Segal
*
* 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 "shared-bindings/board/__init__.h"
#include "shared-bindings/board/__init__.h"
CIRCUITPY_BOARD_BUS_SINGLETON(stemma_i2c, i2c, 1)
STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS
{ MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO9) },
{ MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO9) },
{ MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO9) },
{ MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO4) },
{ MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO4) },
{ MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO3) },
{ MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO3) },
{ MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO1) },
{ MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO1) },
{ MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO0) },
{ MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO0) },
{ MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO5) },
{ MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO5) },
{ MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO5) },
{ MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO6) },
{ MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) },
{ MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO6) },
{ MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO21) },
{ MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO21) },
{ MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_GPIO21) },
{ MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO20) },
{ MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO20) },
{ MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_GPIO20) },
{ MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO7) },
{ MP_ROM_QSTR(MP_QSTR_D35), MP_ROM_PTR(&pin_GPIO7) },
{ MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO10) },
{ MP_ROM_QSTR(MP_QSTR_D36), MP_ROM_PTR(&pin_GPIO10) },
{ MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO8) },
{ MP_ROM_QSTR(MP_QSTR_D37), MP_ROM_PTR(&pin_GPIO8) },
{ MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO2) },
{ MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
{ MP_ROM_QSTR(MP_QSTR_STEMMA_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);

View File

@ -0,0 +1,108 @@
#
# Bootloader config
#
CONFIG_BOOTLOADER_LOG_LEVEL_NONE=y
# CONFIG_BOOTLOADER_LOG_LEVEL_INFO is not set
CONFIG_BOOTLOADER_LOG_LEVEL=0
# end of Bootloader config
# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set
#
# Partition Table
#
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="esp-idf-config/partitions-4MB-no-uf2.csv"
CONFIG_PARTITION_TABLE_FILENAME="esp-idf-config/partitions-4MB-no-uf2.csv"
# end of Partition Table
# CONFIG_COMPILER_SAVE_RESTORE_LIBCALLS is not set
#
# Bluetooth
#
CONFIG_BT_SOC_SUPPORT_5_0=y
# end of Bluetooth
CONFIG_BT_CTRL_HW_CCA_VAL=20
#
# NimBLE Options
#
CONFIG_BT_NIMBLE_PINNED_TO_CORE=0
# end of NimBLE Options
# CONFIG_BLE_MESH is not set
#
# ESP System Settings
#
# CONFIG_ESP_SYSTEM_USE_EH_FRAME is not set
# CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG is not set
CONFIG_ESP_CONSOLE_SECONDARY_NONE=y
# CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG is not set
# CONFIG_ESP_DEBUG_STUBS_ENABLE is not set
# end of ESP System Settings
CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y
#
# LWIP
#
CONFIG_LWIP_LOCAL_HOSTNAME="Adafruit-QTPy-ESP32C3"
# end of LWIP
# CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set
#
# mbedTLS v2.28.x related
#
CONFIG_MBEDTLS_ECDH_LEGACY_CONTEXT=y
# CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set
# CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set
CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y
# end of mbedTLS v2.28.x related
# CONFIG_MBEDTLS_SSL_DTLS_CONNECTION_ID is not set
#
# DTLS-based configurations
#
# CONFIG_MBEDTLS_SSL_DTLS_SRTP is not set
# end of DTLS-based configurations
CONFIG_MBEDTLS_ECP_RESTARTABLE=y
#
# mbedTLS
#
CONFIG_MBEDTLS_CMAC_C=y
# end of mbedTLS
CONFIG_MDNS_MAX_SERVICES=10
#
# mDNS
#
CONFIG_MDNS_TASK_PRIORITY=1
CONFIG_MDNS_TASK_STACK_SIZE=4096
# CONFIG_MDNS_TASK_AFFINITY_NO_AFFINITY is not set
CONFIG_MDNS_TASK_AFFINITY_CPU0=y
CONFIG_MDNS_TASK_AFFINITY=0x0
CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000
# CONFIG_MDNS_STRICT_MODE is not set
CONFIG_MDNS_TIMER_PERIOD_MS=100
# CONFIG_MDNS_NETWORKING_SOCKET is not set
CONFIG_MDNS_MULTIPLE_INSTANCE=y
# end of mDNS
# CONFIG_SPI_FLASH_AUTO_SUSPEND is not set
#
# Auto-detect flash chips
#
CONFIG_SPI_FLASH_SUPPORT_TH_CHIP=y
# end of Auto-detect flash chips
CONFIG_LOG_BOOTLOADER_LEVEL_NONE=y
#
# Deprecated options for backward compatibility
#
# CONFIG_LOG_BOOTLOADER_LEVEL_INFO is not set
CONFIG_LOG_BOOTLOADER_LEVEL=0
# CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG is not set
CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y
CONFIG_ESP32S2_PANIC_PRINT_HALT=y
# CONFIG_ESP32S2_PANIC_SILENT_REBOOT is not set
CONFIG_CONSOLE_UART=y
# CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set
# end of Deprecated options for backward compatibility

View File

@ -78,6 +78,11 @@ STATIC void _reset_pin(gpio_num_t pin_number) {
if (11 <= pin_number && pin_number <= 17) { if (11 <= pin_number && pin_number <= 17) {
return; return;
} }
#if CIRCUITPY_ESP_USB_SERIAL_JTAG
if (pin_number == 18 || pin_number == 19) {
return;
}
#endif
#endif #endif
// Give the board a chance to reset the pin in a particular way. // Give the board a chance to reset the pin in a particular way.

View File

@ -42,8 +42,8 @@ CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT=y
# CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG is not set # CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG is not set
# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set # CONFIG_ESP_CONSOLE_UART_CUSTOM is not set
CONFIG_ESP_CONSOLE_NONE=y CONFIG_ESP_CONSOLE_NONE=y
# CONFIG_ESP_CONSOLE_SECONDARY_NONE is not set CONFIG_ESP_CONSOLE_SECONDARY_NONE=1
CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG=y # CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG is not set
CONFIG_ESP_CONSOLE_MULTIPLE_UART=y CONFIG_ESP_CONSOLE_MULTIPLE_UART=y
CONFIG_ESP_CONSOLE_UART_NUM=-1 CONFIG_ESP_CONSOLE_UART_NUM=-1
# #

View File

@ -73,4 +73,10 @@
#define CIRCUITPY_I2C_ALLOW_INTERNAL_PULL_UP (0) #define CIRCUITPY_I2C_ALLOW_INTERNAL_PULL_UP (0)
#endif #endif
// Define to (1) in mpconfigboard.h if the board uses the internal USB to
// Serial/JTAG to connect do USB.
#ifndef CIRCUITPY_ESP_USB_SERIAL_JTAG
#define CIRCUITPY_ESP_USB_SERIAL_JTAG (0)
#endif
#endif // MICROPY_INCLUDED_ESPRESSIF_MPCONFIGPORT_H #endif // MICROPY_INCLUDED_ESPRESSIF_MPCONFIGPORT_H

View File

@ -0,0 +1,207 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2022 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.
*/
// 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 "supervisor/shared/cpu.h"
#include "supervisor/shared/display.h"
#include "shared-bindings/terminalio/Terminal.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
#include "supervisor/usb_serial_jtag.h"
#endif
#if defined(CIRCUITPY_DEBUG_UART_TX)
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
usb_serial_jtag_init();
#endif
}
bool 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 (usb_serial_jtag_connected()) {
return true;
}
#endif
return false;
}
char 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 (usb_serial_jtag_bytes_available() > 0) {
return usb_serial_jtag_read_char();
}
#endif
return -1;
}
bool 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 (usb_serial_jtag_bytes_available()) {
return true;
}
#endif
return false;
}
void 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
usb_serial_jtag_write(text, length);
#endif
}
void serial_write(const char *text) {
serial_write_substring(text, strlen(text));
}

View File

@ -0,0 +1,111 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2021 Patrick Van Oosterwijck
* Copyright (c) 2022 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 "py/ringbuf.h"
#include "py/runtime.h"
#include "py/mphal.h"
#include "usb_serial_jtag.h"
#include "hal/usb_serial_jtag_ll.h"
#include "esp_intr_alloc.h"
#include "soc/periph_defs.h"
#include "supervisor/esp_port.h"
#define USB_SERIAL_JTAG_BUF_SIZE (64)
STATIC ringbuf_t ringbuf;
STATIC uint8_t buf[128];
STATIC bool connected;
static void usb_serial_jtag_isr_handler(void *arg) {
uint32_t flags = usb_serial_jtag_ll_get_intsts_mask();
if (flags & USB_SERIAL_JTAG_INTR_SOF) {
usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SOF);
}
if (flags & USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT) {
usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT);
size_t req_len = ringbuf_num_empty(&ringbuf);
if (req_len > USB_SERIAL_JTAG_BUF_SIZE) {
req_len = USB_SERIAL_JTAG_BUF_SIZE;
}
uint8_t rx_buf[USB_SERIAL_JTAG_BUF_SIZE];
size_t len = usb_serial_jtag_ll_read_rxfifo(rx_buf, req_len);
for (size_t i = 0; i < len; ++i) {
if (rx_buf[i] == mp_interrupt_char) {
mp_sched_keyboard_interrupt();
} else {
ringbuf_put(&ringbuf, rx_buf[i]);
}
}
vTaskNotifyGiveFromISR(circuitpython_task, NULL);
}
}
void usb_serial_jtag_init(void) {
ringbuf_init(&ringbuf, buf, sizeof(buf));
usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SOF | USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT);
usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SOF | USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT);
ESP_ERROR_CHECK(esp_intr_alloc(ETS_USB_SERIAL_JTAG_INTR_SOURCE, ESP_INTR_FLAG_LEVEL1,
usb_serial_jtag_isr_handler, NULL, NULL));
}
bool usb_serial_jtag_connected(void) {
// Make connected sticky. Otherwise we'll be disconnected every time the SOF
// index is 0. (It's only ~15 bits so it wraps around frequently.)
if (connected) {
return true;
}
connected = USB_SERIAL_JTAG.fram_num.sof_frame_index > 0;
return connected;
}
char usb_serial_jtag_read_char(void) {
if (ringbuf_num_filled(&ringbuf) == 0) {
return -1;
}
return ringbuf_get(&ringbuf);
}
bool usb_serial_jtag_bytes_available(void) {
return ringbuf_num_filled(&ringbuf);
}
void usb_serial_jtag_write(const char *text, uint32_t length) {
if (USB_SERIAL_JTAG.fram_num.sof_frame_index > 0) {
size_t total_written = 0;
uint32_t start_time = supervisor_ticks_ms32();
// Time out after 5 milliseconds in case usb isn't actually reading CDC.
while (total_written < length && start_time - supervisor_ticks_ms32() < 5) {
total_written += usb_serial_jtag_ll_write_txfifo((const uint8_t *)(text + total_written), length - total_written);
RUN_BACKGROUND_TASKS;
}
usb_serial_jtag_ll_txfifo_flush();
}
}

View File

@ -0,0 +1,33 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2022 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.
*/
#pragma once
void usb_serial_jtag_init(void);
bool usb_serial_jtag_connected(void);
char usb_serial_jtag_read_char(void);
bool usb_serial_jtag_bytes_available(void);
void usb_serial_jtag_write(const char *text, uint32_t length);

View File

@ -0,0 +1,43 @@
/*
* 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

@ -5,6 +5,7 @@
# #
# SPDX-License-Identifier: MIT # SPDX-License-Identifier: MIT
import csv
import os import os
import re import re
import sys import sys
@ -13,27 +14,70 @@ from elftools.elf.elffile import ELFFile
print() print()
internal_memory = [ internal_memory = {
"esp32s2": [
# Name, Start, Length # Name, Start, Length
("RTC Fast Memory", (0x3FF9_E000, 0x4007_0000), 8 * 1024), ("RTC Fast Memory", (0x3FF9_E000, 0x4007_0000), 8 * 1024),
("RTC Slow Memory", (0x5000_0000,), 8 * 1024), ("RTC Slow Memory", (0x5000_0000,), 8 * 1024),
("Internal SRAM 0", (0x3FFB_0000, 0x4002_0000), 32 * 1024), ("Internal SRAM 0", (0x3FFB_0000, 0x4002_0000), 32 * 1024),
("Internal SRAM 1", (0x3FFB_8000, 0x4002_8000), 288 * 1024), ("Internal SRAM 1", (0x3FFB_8000, 0x4002_8000), 288 * 1024),
] ],
"esp32s3": [
# Name, Start, Length
def partition_size(arg): ("RTC Fast Memory", (0x600F_E000,), 8 * 1024),
if "4MB" in arg: ("RTC Slow Memory", (0x5000_0000,), 8 * 1024),
return 1408 * 1024 ("Internal SRAM 0", (0x4037_0000,), 32 * 1024),
else: ("Internal SRAM 1", (0x3FC8_0000, 0x4037_8000), 416 * 1024),
return 2048 * 1024 ("Internal SRAM 2", (0x3FCF_0000,), 64 * 1024),
],
"esp32c3": [
# Name, Start, Length
("RTC Fast Memory", (0x5000_0000,), 8 * 1024),
("Internal SRAM 0", (0x4037_C000,), 16 * 1024),
("Internal SRAM 1", (0x3FC8_0000, 0x4038_0000), 384 * 1024),
],
}
def align(n, m): def align(n, m):
return m * ((n + m - 1) // m) return m * ((n + m - 1) // m)
regions = dict((name, 0) for name, _, _ in internal_memory) def find_region(start_address):
for name, starts, length in internal_memory[target]:
for mem_start in starts:
mem_end = mem_start + length
if mem_start <= start_address < mem_end:
return (name, mem_start + length)
target = None
# This file is the sdkconfig
with open(sys.argv[2], "r") as f:
for line in f:
line = line.strip()
if line.startswith("CONFIG_IDF_TARGET="):
target = line.split('"')[1]
elif line.startswith("CONFIG_PARTITION_TABLE_FILENAME"):
partitions_file = line.split('"')[1]
with open(partitions_file, "r") as f:
ota = None
app = None
for partition in csv.reader(f):
if partition[0][0] == "#":
continue
subtype = partition[2].strip()
if subtype == "factory":
app = partition[4].strip()
elif subtype == "ota_0":
ota = partition[4].strip()
size = app if ota is None else ota
if size[-1] not in ("k", "K"):
raise RuntimeError("Unhandled partition size suffix")
firmware_region = int(size[:-1]) * 1024
regions = dict((name, 0) for name, _, _ in internal_memory[target])
# This file is the elf # This file is the elf
with open(sys.argv[1], "rb") as stream: with open(sys.argv[1], "rb") as stream:
@ -44,19 +88,20 @@ with open(sys.argv[1], "rb") as stream:
offset = section["sh_offset"] offset = section["sh_offset"]
if not size or not start: if not size or not start:
continue continue
for name, starts, length in internal_memory: # This handles sections that span two memory regions, not more than that.
for mem_start in starts: # print(start, size, offset, section.name)
mem_end = mem_start + length region = find_region(start)
if start >= mem_start and start < mem_end: if region is None:
regions[name] = max(regions.get(name, 0), size) continue
# print("# putting %s in %s (start=0x%x, size=%d)" % (section.name, name, start, size)) name, region_end = region
region_size = min(size, region_end - start)
# This file is the sdkconfig regions[name] += region_size
with open(sys.argv[2], "r") as f: # print("# putting %s in %s (start=0x%x, size=%d)" % (section.name, name, start, region_size))
for line in f: if region_size < size:
line = line.strip() name, _ = find_region(region_end)
if line.startswith("CONFIG_PARTITION_TABLE_FILENAME"): remaining_size = size - region_size
firmware_region = int(partition_size(line.split("=")[-1])) regions[name] += remaining_size
# print("# putting %s in %s (start=0x%x, size=%d)" % (section.name, name, region_end, remaining_size))
# This file is the bin # This file is the bin
used_flash = os.stat(sys.argv[3]).st_size used_flash = os.stat(sys.argv[3]).st_size
@ -67,7 +112,7 @@ print(
used_flash, free_flash, firmware_region, firmware_region / 1024 used_flash, free_flash, firmware_region, firmware_region / 1024
) )
) )
for name, mem_start, length in internal_memory: for name, mem_start, length in internal_memory[target]:
if name in regions: if name in regions:
print( print(
"{:7} bytes used, {:7} bytes free in '{}' out of {} bytes ({}kB).".format( "{:7} bytes used, {:7} bytes free in '{}' out of {} bytes ({}kB).".format(

View File

@ -82,7 +82,9 @@ ifeq ($(CIRCUITPY_USB),0)
supervisor/shared/workflow.c \ supervisor/shared/workflow.c \
else else
SRC_SUPERVISOR += supervisor/serial.c SRC_SUPERVISOR += supervisor/serial.c \
supervisor/workflow.c \
endif endif
else else
SRC_SUPERVISOR += \ SRC_SUPERVISOR += \