Skip to content

Commit

Permalink
cpu/esp32: add stdio_usb_serial_jtag
Browse files Browse the repository at this point in the history
  • Loading branch information
benpicco committed Jan 5, 2023
1 parent eeb03f1 commit 618f6da
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 0 deletions.
4 changes: 4 additions & 0 deletions cpu/esp32/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 7 additions & 0 deletions cpu/esp32/Makefile.dep
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,13 @@ ifneq (,$(filter shell,$(USEMODULE)))
USEMODULE += ps
endif

ifneq (,$(filter stdio_usb_serial_jtag, $(USEMODULE)))
USEMODULE += tsrb
endif
ifneq (,$(filter stdio_usb_serial_jtag_rx, $(USEMODULE)))
USEMODULE += isrpipe
endif

ifneq (,$(filter tinyusb_portable_espressif,$(USEMODULE)))
USEMODULE += esp_idf_usb
endif
Expand Down
1 change: 1 addition & 0 deletions cpu/esp32/include/irq_arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ extern "C" {
#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_SERIAL_JTAG 26 /**< Level interrupt with low priority 1 */
/** @} */

/**
Expand Down
3 changes: 3 additions & 0 deletions cpu/esp32/irq_arch.c
Original file line number Diff line number Diff line change
Expand Up @@ -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(CPU_INUM_SERIAL_JTAG)
{ ETS_USB_SERIAL_JTAG_INTR_SOURCE, CPU_INUM_SERIAL_JTAG, 1 },
#endif
};

#define IRQ_DATA_TABLE_SIZE ARRAY_SIZE(_irq_data_table)
Expand Down
1 change: 1 addition & 0 deletions cpu/esp32/stdio_usb_serial_jtag/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include $(RIOTBASE)/Makefile.base
115 changes: 115 additions & 0 deletions cpu/esp32/stdio_usb_serial_jtag/usb_serial_jtag.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/*
* 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 "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;
}

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));
}
/**@}*/
1 change: 1 addition & 0 deletions makefiles/pseudomodules.inc.mk
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,7 @@ PSEUDOMODULES += stdio_telnet
PSEUDOMODULES += stdio_uart_onlcr
## @}
PSEUDOMODULES += stdio_uart_rx
PSEUDOMODULES += stdio_usb_serial_jtag_rx
PSEUDOMODULES += stm32_eth
PSEUDOMODULES += stm32_eth_auto
PSEUDOMODULES += stm32_eth_link_up
Expand Down
4 changes: 4 additions & 0 deletions makefiles/stdio.inc.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -52,6 +53,9 @@ ifneq (,$(filter stdin,$(USEMODULE)))
ifneq (,$(filter stdio_uart,$(USEMODULE)))
USEMODULE += stdio_uart_rx
endif
ifneq (,$(filter stdio_usb_serial_jtag,$(USEMODULE)))
USEMODULE += stdio_usb_serial_jtag_rx
endif
endif

ifneq (,$(filter stdio_uart_rx,$(USEMODULE)))
Expand Down

0 comments on commit 618f6da

Please sign in to comment.