1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

cpu/esp32: add stdio_usb_serial_jtag

This commit is contained in:
Benjamin Valentin 2022-12-29 00:35:41 +01:00 committed by Benjamin Valentin
parent 4f1bb12720
commit 55b5c47bc8
9 changed files with 177 additions and 14 deletions

View File

@ -25,6 +25,10 @@ ifneq (, $(filter esp_freertos, $(USEMODULE)))
DIRS += freertos
endif
ifneq (, $(filter stdio_usb_serial_jtag, $(USEMODULE)))
DIRS += stdio_usb_serial_jtag
endif
ifneq (,$(filter esp_wifi% esp_eth, $(USEMODULE)))
SRC += esp_ztimer.c
endif

View File

@ -166,6 +166,17 @@ ifneq (,$(filter shell,$(USEMODULE)))
USEMODULE += ps
endif
ifneq (,$(filter stdio_usb_serial_jtag, $(USEMODULE)))
USEMODULE += tsrb
ifneq (,$(filter stdin,$(USEMODULE)))
USEMODULE += stdio_usb_serial_jtag_rx
endif
endif
ifneq (,$(filter stdio_usb_serial_jtag_rx, $(USEMODULE)))
USEMODULE += isrpipe
USEMODULE += stdio_available
endif
ifneq (,$(filter tinyusb_portable_espressif,$(USEMODULE)))
USEMODULE += esp_idf_usb
endif

View File

@ -50,6 +50,7 @@ PSEUDOMODULES += esp_rtc_timer_32k
PSEUDOMODULES += esp_spi_ram
PSEUDOMODULES += esp_spi_oct
PSEUDOMODULES += esp_wifi_enterprise
PSEUDOMODULES += stdio_usb_serial_jtag_rx
INCLUDES += -I$(RIOTCPU)/$(CPU)/esp-idf/include
INCLUDES += -I$(RIOTCPU)/$(CPU)/esp-idf/include/log

View File

@ -36,20 +36,21 @@ extern "C" {
*
* @{
*/
#define CPU_INUM_GPIO 2 /**< Level interrupt with low priority 1 */
#define CPU_INUM_CAN 3 /**< Level interrupt with low priority 1 */
#define CPU_INUM_UART 4 /**< Level interrupt with low priority 1 */
#define CPU_INUM_USB 8 /**< Level interrupt with low priority 1 */
#define CPU_INUM_RTT 9 /**< Level interrupt with low priority 1 */
#define CPU_INUM_I2C 12 /**< Level interrupt with low priority 1 */
#define CPU_INUM_WDT 13 /**< Level interrupt with low priority 1 */
#define CPU_INUM_SOFTWARE 17 /**< Level interrupt with low priority 1 */
#define CPU_INUM_ETH 18 /**< Level interrupt with low priority 1 */
#define CPU_INUM_TIMER 19 /**< Level interrupt with medium priority 2 */
#define CPU_INUM_FRC2 20 /**< Level interrupt with medium priority 2 */
#define CPU_INUM_SYSTIMER 20 /**< Level interrupt with medium priority 2 */
#define CPU_INUM_BLE 21 /**< Level interrupt with medium priority 2 */
#define CPU_INUM_CACHEERR 25 /**< Level interrupt with high priority 4 */
#define CPU_INUM_GPIO 2 /**< Level interrupt with low priority 1 */
#define CPU_INUM_CAN 3 /**< Level interrupt with low priority 1 */
#define CPU_INUM_UART 4 /**< Level interrupt with low priority 1 */
#define CPU_INUM_USB 8 /**< Level interrupt with low priority 1 */
#define CPU_INUM_RTT 9 /**< Level interrupt with low priority 1 */
#define CPU_INUM_SERIAL_JTAG 10 /**< Level interrupt with low priority 1 */
#define CPU_INUM_I2C 12 /**< Level interrupt with low priority 1 */
#define CPU_INUM_WDT 13 /**< Level interrupt with low priority 1 */
#define CPU_INUM_SOFTWARE 17 /**< Level interrupt with low priority 1 */
#define CPU_INUM_ETH 18 /**< Level interrupt with low priority 1 */
#define CPU_INUM_TIMER 19 /**< Level interrupt with medium priority 2 */
#define CPU_INUM_FRC2 20 /**< Level interrupt with medium priority 2 */
#define CPU_INUM_SYSTIMER 20 /**< Level interrupt with medium priority 2 */
#define CPU_INUM_BLE 21 /**< Level interrupt with medium priority 2 */
#define CPU_INUM_CACHEERR 25 /**< Level interrupt with high priority 4 */
/** @} */
/**

View File

@ -83,6 +83,9 @@ static const struct intr_handle_data_t _irq_data_table[] = {
#if defined(CPU_FAM_ESP32S2) || defined(CPU_FAM_ESP32S3)
{ ETS_USB_INTR_SOURCE, CPU_INUM_USB, 1 },
#endif
#if defined(ETS_USB_SERIAL_JTAG_INTR_SOURCE)
{ ETS_USB_SERIAL_JTAG_INTR_SOURCE, CPU_INUM_SERIAL_JTAG, 1 },
#endif
};
#define IRQ_DATA_TABLE_SIZE ARRAY_SIZE(_irq_data_table)

View File

@ -0,0 +1 @@
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,126 @@
/*
* Copyright (C) 2023 Benjamin Valentin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @defgroup cpu_esp32_usb_serial_jtag ESP32 USB Serial/JTAG interface
* @ingroup cpu_esp32
* @{
*
* @file
* @brief stdio via USB Serial JTAG debug interface
*
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com>
*/
#include <stdint.h>
#include <stddef.h>
#include <errno.h>
#include <sys/types.h>
#include "isrpipe.h"
#include "tsrb.h"
#include "irq_arch.h"
#include "esp_attr.h"
#include "hal/interrupt_controller_types.h"
#include "hal/interrupt_controller_ll.h"
#include "hal/usb_serial_jtag_ll.h"
#include "soc/periph_defs.h"
#include "rom/ets_sys.h"
static uint8_t _rx_buf_mem[USB_SERIAL_JTAG_PACKET_SZ_BYTES];
static isrpipe_t stdio_serial_isrpipe = ISRPIPE_INIT(_rx_buf_mem);
static tsrb_t serial_tx_rb;
static uint8_t serial_tx_rb_buf[USB_SERIAL_JTAG_PACKET_SZ_BYTES];
#define IRQ_MASK (USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY | \
(IS_USED(MODULE_STDIO_USB_SERIAL_JTAG_RX) * USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT))
ssize_t stdio_write(const void *buffer, size_t len)
{
tsrb_add(&serial_tx_rb, buffer, len);
USB_SERIAL_JTAG.int_ena.val = IRQ_MASK;
return len;
}
ssize_t stdio_read(void* buffer, size_t count)
{
if (IS_USED(MODULE_STDIO_USB_SERIAL_JTAG_RX)) {
return (ssize_t)isrpipe_read(&stdio_serial_isrpipe, buffer, count);
}
return -ENOTSUP;
}
int stdio_available(void)
{
if (IS_USED(MODULE_STDIO_AVAILABLE)) {
return tsrb_avail(&stdio_serial_isrpipe.tsrb);
}
return -ENOTSUP;
}
IRAM_ATTR
static void _serial_intr_handler(void *arg)
{
(void)arg;
irq_isr_enter();
uint32_t mask = usb_serial_jtag_ll_get_intsts_mask();
/* read data if available */
while (IS_USED(MODULE_STDIO_USB_SERIAL_JTAG_RX) &&
usb_serial_jtag_ll_rxfifo_data_available()) {
isrpipe_write_one(&stdio_serial_isrpipe, USB_SERIAL_JTAG.ep1.rdwr_byte);
}
/* write data if there is a free stop */
if (mask & USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY) {
while (usb_serial_jtag_ll_txfifo_writable()) {
int c = tsrb_get_one(&serial_tx_rb);
if (c < 0) {
/* no more data to send - disable interrupt */
USB_SERIAL_JTAG.int_ena.val = IRQ_MASK & ~USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY;
break;
}
USB_SERIAL_JTAG.ep1.rdwr_byte = c;
}
usb_serial_jtag_ll_txfifo_flush();
}
/* clear all interrupt flags */
usb_serial_jtag_ll_clr_intsts_mask(mask);
irq_isr_exit();
}
void stdio_init(void)
{
tsrb_init(&serial_tx_rb, serial_tx_rb_buf, sizeof(serial_tx_rb_buf));
/* enable RX interrupt */
if (IS_USED(MODULE_STDIO_USB_SERIAL_JTAG_RX)) {
USB_SERIAL_JTAG.int_ena.val = USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT;
}
/* clear all interrupt flags */
usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_LL_INTR_MASK);
/* route all UART interrupt sources to same the CPU interrupt */
intr_matrix_set(PRO_CPU_NUM, ETS_USB_SERIAL_JTAG_INTR_SOURCE, CPU_INUM_SERIAL_JTAG);
/* we have to enable therefore the CPU interrupt here */
intr_cntrl_ll_set_int_handler(CPU_INUM_SERIAL_JTAG, _serial_intr_handler, NULL);
intr_cntrl_ll_enable_interrupts(BIT(CPU_INUM_SERIAL_JTAG));
}
/**@}*/

View File

@ -10,6 +10,7 @@ STDIO_MODULES = \
stdio_uart \
stdio_telnet \
stdio_tinyusb_cdc_acm \
stdio_usb_serial_jtag \
#
# select stdio_uart if no other stdio module is slected

View File

@ -49,6 +49,12 @@ config MODULE_STDIO_ETHOS
select MODULE_ETHOS_STDIO
select USE_STDOUT_BUFFERED
config MODULE_STDIO_USB_SERIAL_JTAG
bool "STDIO via ESP32 Debug USB Serial/JTAG interface"
depends on TEST_KCONFIG
depends on CPU_FAM_ESP32C3 || CPU_FAM_ESP32S3
select MODULE_TSRB
endchoice
config MODULE_STDIN
@ -63,6 +69,15 @@ config MODULE_STDIO_UART_RX
help
Reception when using UART-based STDIO needs to be enabled.
config MODULE_STDIO_USB_SERIAL_JTAG_RX
bool
depends on MODULE_STDIO_USB_SERIAL_JTAG
select MODULE_ISRPIPE
select MODULE_STDIO_AVAILABLE
default y if MODULE_STDIN
help
Reception when using ESP32 USB Serial/JTAG STDIO needs to be enabled.
config MODULE_STDIO_AVAILABLE
bool
help