diff --git a/ports/esp32/boards/GENERIC_C3_USB/mpconfigboard.cmake b/ports/esp32/boards/GENERIC_C3_USB/mpconfigboard.cmake new file mode 100644 index 0000000000..2b65121b96 --- /dev/null +++ b/ports/esp32/boards/GENERIC_C3_USB/mpconfigboard.cmake @@ -0,0 +1,11 @@ +set(IDF_TARGET esp32c3) + +set(SDKCONFIG_DEFAULTS + boards/sdkconfig.base + boards/sdkconfig.ble + boards/GENERIC_C3_USB/sdkconfig.board +) + +if(NOT MICROPY_FROZEN_MANIFEST) + set(MICROPY_FROZEN_MANIFEST ${MICROPY_PORT_DIR}/boards/manifest.py) +endif() diff --git a/ports/esp32/boards/GENERIC_C3_USB/mpconfigboard.h b/ports/esp32/boards/GENERIC_C3_USB/mpconfigboard.h new file mode 100644 index 0000000000..d403e70e46 --- /dev/null +++ b/ports/esp32/boards/GENERIC_C3_USB/mpconfigboard.h @@ -0,0 +1,8 @@ +// This configuration is for a generic ESP32C3 board with 4MiB (or more) of flash. + +#define MICROPY_HW_BOARD_NAME "ESP32C3 module" +#define MICROPY_HW_MCU_NAME "ESP32C3" + +#define MICROPY_HW_ENABLE_SDCARD (0) +#define MICROPY_PY_MACHINE_DAC (0) +#define MICROPY_PY_MACHINE_I2S (0) diff --git a/ports/esp32/boards/GENERIC_C3_USB/sdkconfig.board b/ports/esp32/boards/GENERIC_C3_USB/sdkconfig.board new file mode 100644 index 0000000000..f0cbad00e4 --- /dev/null +++ b/ports/esp32/boards/GENERIC_C3_USB/sdkconfig.board @@ -0,0 +1,9 @@ +CONFIG_ESP32C3_REV_MIN_3=y +CONFIG_ESP32C3_REV_MIN=3 +CONFIG_ESP32C3_BROWNOUT_DET=y +CONFIG_ESP32C3_BROWNOUT_DET_LVL_SEL_7= +CONFIG_ESP32C3_BROWNOUT_DET_LVL_SEL_4=y +CONFIG_ESP32C3_BROWNOUT_DET_LVL=4 +CONFIG_ESP_CONSOLE_UART_DEFAULT= +CONFIG_ESP_CONSOLE_USB_CDC= +CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y diff --git a/ports/esp32/machine_pin.c b/ports/esp32/machine_pin.c index 181f88b787..6c1e96879f 100644 --- a/ports/esp32/machine_pin.c +++ b/ports/esp32/machine_pin.c @@ -125,12 +125,17 @@ STATIC const machine_pin_obj_t machine_pin_obj[] = { {{&machine_pin_type}, GPIO_NUM_11}, {{&machine_pin_type}, GPIO_NUM_12}, {{&machine_pin_type}, GPIO_NUM_13}, - {{&machine_pin_type}, GPIO_NUM_14}, - {{&machine_pin_type}, GPIO_NUM_15}, - {{&machine_pin_type}, GPIO_NUM_16}, - {{&machine_pin_type}, GPIO_NUM_17}, + {{NULL}, -1}, // 14 FLASH + {{NULL}, -1}, // 15 FLASH + {{NULL}, -1}, // 16 FLASH + {{NULL}, -1}, // 17 FLASH + #if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG + {{NULL}, -1}, // 18 is for native USB D- + {{NULL}, -1}, // 19 is for native USB D+ + #else {{&machine_pin_type}, GPIO_NUM_18}, {{&machine_pin_type}, GPIO_NUM_19}, + #endif {{&machine_pin_type}, GPIO_NUM_20}, {{&machine_pin_type}, GPIO_NUM_21}, diff --git a/ports/esp32/main.c b/ports/esp32/main.c index 0650c8d71d..2ba6136681 100644 --- a/ports/esp32/main.c +++ b/ports/esp32/main.c @@ -58,6 +58,7 @@ #include "shared/runtime/pyexec.h" #include "uart.h" #include "usb.h" +#include "usb_serial_jtag.h" #include "modmachine.h" #include "modnetwork.h" #include "mpthreadport.h" @@ -89,6 +90,8 @@ void mp_task(void *pvParameter) { #endif #if CONFIG_USB_ENABLED usb_init(); + #elif CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG + usb_serial_jtag_init(); #else uart_init(); #endif diff --git a/ports/esp32/main/CMakeLists.txt b/ports/esp32/main/CMakeLists.txt index 0e7d6ff250..057ec02441 100644 --- a/ports/esp32/main/CMakeLists.txt +++ b/ports/esp32/main/CMakeLists.txt @@ -47,6 +47,7 @@ set(MICROPY_SOURCE_PORT ${PROJECT_DIR}/main.c ${PROJECT_DIR}/uart.c ${PROJECT_DIR}/usb.c + ${PROJECT_DIR}/usb_serial_jtag.c ${PROJECT_DIR}/gccollect.c ${PROJECT_DIR}/mphalport.c ${PROJECT_DIR}/fatfs_port.c diff --git a/ports/esp32/mphalport.c b/ports/esp32/mphalport.c index 6e6fd26ef4..de1b173ac4 100644 --- a/ports/esp32/mphalport.c +++ b/ports/esp32/mphalport.c @@ -53,6 +53,7 @@ #include "shared/runtime/pyexec.h" #include "mphalport.h" #include "usb.h" +#include "usb_serial_jtag.h" TaskHandle_t mp_main_task_handle; @@ -118,6 +119,8 @@ void mp_hal_stdout_tx_strn(const char *str, size_t len) { } #if CONFIG_USB_ENABLED usb_tx_strn(str, len); + #elif CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG + usb_serial_jtag_tx_strn(str, len); #else for (uint32_t i = 0; i < len; ++i) { uart_tx_one_char(str[i]); diff --git a/ports/esp32/usb_serial_jtag.c b/ports/esp32/usb_serial_jtag.c new file mode 100644 index 0000000000..a7d06a355a --- /dev/null +++ b/ports/esp32/usb_serial_jtag.c @@ -0,0 +1,98 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Patrick Van Oosterwijck + * + * 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/runtime.h" +#include "py/mphal.h" +#include "usb_serial_jtag.h" + +#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG + +#include "hal/usb_serial_jtag_ll.h" +#include "esp_intr_alloc.h" +#include "soc/periph_defs.h" + +#define USB_SERIAL_JTAG_BUF_SIZE (64) + +static uint8_t rx_buf[USB_SERIAL_JTAG_BUF_SIZE]; +static volatile bool terminal_connected = false; + +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_free(&stdin_ringbuf); + if (req_len > USB_SERIAL_JTAG_BUF_SIZE) { + req_len = 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(&stdin_ringbuf, rx_buf[i]); + } + } + mp_hal_wake_main_task_from_isr(); + } +} + +void usb_serial_jtag_init(void) { + usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT | + USB_SERIAL_JTAG_INTR_SOF); + usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT | + USB_SERIAL_JTAG_INTR_SOF); + ESP_ERROR_CHECK(esp_intr_alloc(ETS_USB_SERIAL_JTAG_INTR_SOURCE, ESP_INTR_FLAG_LEVEL1, + usb_serial_jtag_isr_handler, NULL, NULL)); +} + +void usb_serial_jtag_tx_strn(const char *str, size_t len) { + while (len) { + size_t l = len; + if (l > USB_SERIAL_JTAG_PACKET_SZ_BYTES) { + l = USB_SERIAL_JTAG_PACKET_SZ_BYTES; + } + portTickType start_tick = xTaskGetTickCount(); + while (!usb_serial_jtag_ll_txfifo_writable()) { + portTickType now_tick = xTaskGetTickCount(); + if (!terminal_connected || now_tick > (start_tick + pdMS_TO_TICKS(200))) { + terminal_connected = false; + return; + } + } + terminal_connected = true; + l = usb_serial_jtag_ll_write_txfifo((const uint8_t *)str, l); + usb_serial_jtag_ll_txfifo_flush(); + str += l; + len -= l; + } +} + +#endif // CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG diff --git a/ports/esp32/usb_serial_jtag.h b/ports/esp32/usb_serial_jtag.h new file mode 100644 index 0000000000..4eebb19e4b --- /dev/null +++ b/ports/esp32/usb_serial_jtag.h @@ -0,0 +1,32 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Patrick Van Oosterwijck + * + * 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. + */ +#ifndef MICROPY_INCLUDED_ESP32_USB_SERIAL_JTAG_H +#define MICROPY_INCLUDED_ESP32_USB_SERIAL_JTAG_H + +void usb_serial_jtag_init(void); +void usb_serial_jtag_tx_strn(const char *str, size_t len); + +#endif // MICROPY_INCLUDED_ESP32_USB_SERIAL_JTAG_H