Add support for the USB CDC Serial JTAG console
This commit is contained in:
parent
a3712ac990
commit
384aff1d09
|
@ -12,6 +12,14 @@
|
|||
#include "task/task.h"
|
||||
#include "linput.h"
|
||||
|
||||
#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
|
||||
#include "driver/usb_serial_jtag.h"
|
||||
#include "esp_vfs_usb_serial_jtag.h"
|
||||
#include "esp_vfs_dev.h"
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
int platform_init (void)
|
||||
{
|
||||
platform_ws2812_init();
|
||||
|
@ -34,6 +42,16 @@ int platform_gpio_output_exists( unsigned gpio ) { return GPIO_IS_VALID_OUTPUT_G
|
|||
#define PLATFORM_UART_EVENT_RX (UART_EVENT_MAX + 3)
|
||||
#define PLATFORM_UART_EVENT_BREAK (UART_EVENT_MAX + 4)
|
||||
|
||||
#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
|
||||
#define ADJUST_IDR(id,retval) if (id-- == 0) return retval
|
||||
#define ADJUST_ID(id) if (id-- == 0) return
|
||||
#define UNADJUST_ID(id) id++
|
||||
#else
|
||||
#define ADJUST_IDR(id, retval)
|
||||
#define ADJUST_ID(id)
|
||||
#define UNADJUST_ID(id)
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
unsigned rx_buf_sz;
|
||||
unsigned tx_buf_sz;
|
||||
|
@ -65,23 +83,22 @@ uart_status_t uart_status[NUM_UART];
|
|||
task_handle_t uart_event_task_id = 0;
|
||||
SemaphoreHandle_t sem = NULL;
|
||||
|
||||
#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
|
||||
task_handle_t usbcdc_event_task_id = 0;
|
||||
static uart_status_t usbcdc_status;
|
||||
SemaphoreHandle_t usbcdc_sem = NULL;
|
||||
#endif
|
||||
|
||||
extern bool uart_on_data_cb(unsigned id, const char *buf, size_t len);
|
||||
extern bool uart_on_error_cb(unsigned id, const char *buf, size_t len);
|
||||
|
||||
void uart_event_task( task_param_t param, task_prio_t prio ) {
|
||||
uart_event_post_t *post = (uart_event_post_t *)param;
|
||||
unsigned id = post->id;
|
||||
uart_status_t *us = &uart_status[id];
|
||||
xSemaphoreGive(sem);
|
||||
if(post->type == PLATFORM_UART_EVENT_DATA) {
|
||||
static void handle_uart_data(unsigned int id, uart_event_post_t *post, uart_status_t *us) {
|
||||
size_t i = 0;
|
||||
while (i < post->size)
|
||||
{
|
||||
while (i < post->size) {
|
||||
if (id == CONFIG_ESP_CONSOLE_UART_NUM && run_input) {
|
||||
unsigned used = feed_lua_input(post->data + i, post->size - i);
|
||||
i += used;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
char ch = post->data[i];
|
||||
us->line_buffer[us->line_position] = ch;
|
||||
us->line_position++;
|
||||
|
@ -100,10 +117,25 @@ void uart_event_task( task_param_t param, task_prio_t prio ) {
|
|||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void uart_event_task(task_param_t param, task_prio_t prio)
|
||||
{
|
||||
uart_event_post_t *post = (uart_event_post_t *)param;
|
||||
unsigned id = post->id;
|
||||
uart_status_t *us = &uart_status[id];
|
||||
UNADJUST_ID(id);
|
||||
xSemaphoreGive(sem);
|
||||
if (post->type == PLATFORM_UART_EVENT_DATA)
|
||||
{
|
||||
handle_uart_data(id, post, us);
|
||||
free(post->data);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *err;
|
||||
switch(post->type) {
|
||||
switch (post->type)
|
||||
{
|
||||
case PLATFORM_UART_EVENT_OOM:
|
||||
err = "out_of_memory";
|
||||
break;
|
||||
|
@ -119,6 +151,57 @@ void uart_event_task( task_param_t param, task_prio_t prio ) {
|
|||
free(post);
|
||||
}
|
||||
|
||||
#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
|
||||
void usbcdc_event_task(task_param_t param, task_prio_t prio)
|
||||
{
|
||||
uart_event_post_t *post = (uart_event_post_t *)param;
|
||||
xSemaphoreGive(usbcdc_sem);
|
||||
handle_uart_data(0, post, &usbcdc_status);
|
||||
free(post);
|
||||
}
|
||||
|
||||
static void task_usbcdc(void *pvParameters) {
|
||||
// 4 chosen as a number smaller than the number of nodemcu task slots
|
||||
// available, to make it unlikely we encounter a task_post failing
|
||||
if (usbcdc_sem == NULL)
|
||||
usbcdc_sem = xSemaphoreCreateCounting(4, 4);
|
||||
|
||||
uart_event_post_t *post = NULL;
|
||||
|
||||
for (;;) {
|
||||
if (post == NULL) {
|
||||
post = (uart_event_post_t *)malloc(sizeof(uart_event_post_t) + 64 * sizeof(char));
|
||||
if (post == NULL) {
|
||||
ESP_LOGE(UART_TAG, "Can not alloc memory in task_usbcdc()");
|
||||
// reboot here?
|
||||
continue;
|
||||
}
|
||||
post->data = (void *)(post + 1);
|
||||
post->type = PLATFORM_UART_EVENT_DATA;
|
||||
}
|
||||
|
||||
int len = usb_serial_jtag_read_bytes(post->data, 64, portMAX_DELAY);
|
||||
|
||||
if (len > 0) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (post->data[i] == '\r') {
|
||||
post->data[i] = '\n';
|
||||
}
|
||||
}
|
||||
post->size = len;
|
||||
xSemaphoreTake(usbcdc_sem, portMAX_DELAY);
|
||||
if (!task_post_medium(usbcdc_event_task_id, (task_param_t)post))
|
||||
{
|
||||
ESP_LOGE(UART_TAG, "Task event overrun in task_usbcdc()");
|
||||
xSemaphoreGive(usbcdc_sem);
|
||||
} else {
|
||||
post = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void task_uart( void *pvParameters ){
|
||||
unsigned id = (unsigned)pvParameters;
|
||||
|
||||
|
@ -207,6 +290,7 @@ static void task_uart( void *pvParameters ){
|
|||
// pins must not be null for non-console uart
|
||||
uint32_t platform_uart_setup( unsigned id, uint32_t baud, int databits, int parity, int stopbits, uart_pins_t* pins )
|
||||
{
|
||||
ADJUST_IDR(id, baud);
|
||||
int flow_control = UART_HW_FLOWCTRL_DISABLE;
|
||||
if(pins->flow_control & PLATFORM_UART_FLOW_CTS) flow_control |= UART_HW_FLOWCTRL_CTS;
|
||||
if(pins->flow_control & PLATFORM_UART_FLOW_RTS) flow_control |= UART_HW_FLOWCTRL_RTS;
|
||||
|
@ -260,6 +344,8 @@ void platform_uart_setmode(unsigned id, unsigned mode)
|
|||
{
|
||||
uart_mode_t uartMode;
|
||||
|
||||
ADJUST_IDR(id,);
|
||||
|
||||
switch(mode)
|
||||
{
|
||||
case PLATFORM_UART_MODE_IRDA:
|
||||
|
@ -285,6 +371,7 @@ void platform_uart_send_multi( unsigned id, const char *data, size_t len )
|
|||
putchar (data[ i ]);
|
||||
}
|
||||
} else {
|
||||
ADJUST_ID(id);
|
||||
uart_write_bytes(id, data, len);
|
||||
}
|
||||
}
|
||||
|
@ -293,17 +380,21 @@ void platform_uart_send( unsigned id, uint8_t data )
|
|||
{
|
||||
if (id == CONFIG_ESP_CONSOLE_UART_NUM)
|
||||
putchar (data);
|
||||
else
|
||||
else {
|
||||
ADJUST_ID(id);
|
||||
uart_write_bytes(id, (const char *)&data, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void platform_uart_flush( unsigned id )
|
||||
{
|
||||
if (id == CONFIG_ESP_CONSOLE_UART_NUM)
|
||||
fflush (stdout);
|
||||
else
|
||||
else {
|
||||
ADJUST_ID(id);
|
||||
uart_tx_flush(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int platform_uart_start( unsigned id )
|
||||
|
@ -311,6 +402,57 @@ int platform_uart_start( unsigned id )
|
|||
if(uart_event_task_id == 0)
|
||||
uart_event_task_id = task_get_id( uart_event_task );
|
||||
|
||||
#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
|
||||
if (id == 0) {
|
||||
if (usbcdc_event_task_id == 0) {
|
||||
usbcdc_event_task_id = task_get_id(usbcdc_event_task);
|
||||
|
||||
|
||||
/* Disable buffering on stdin */
|
||||
setvbuf(stdin, NULL, _IONBF, 0);
|
||||
|
||||
/* Minicom, screen, idf_monitor send CR when ENTER key is pressed */
|
||||
esp_vfs_dev_usb_serial_jtag_set_rx_line_endings(ESP_LINE_ENDINGS_CR);
|
||||
/* Move the caret to the beginning of the next line on '\n' */
|
||||
esp_vfs_dev_usb_serial_jtag_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF);
|
||||
|
||||
/* Enable blocking mode on stdin and stdout */
|
||||
fcntl(fileno(stdout), F_SETFL, 0);
|
||||
fcntl(fileno(stdin), F_SETFL, 0);
|
||||
|
||||
usb_serial_jtag_driver_config_t usb_serial_jtag_config;
|
||||
usb_serial_jtag_config.rx_buffer_size = 1024;
|
||||
usb_serial_jtag_config.tx_buffer_size = 1024;
|
||||
|
||||
esp_err_t ret = ESP_OK;
|
||||
/* Install USB-SERIAL-JTAG driver for interrupt-driven reads and writes */
|
||||
ret = usb_serial_jtag_driver_install(&usb_serial_jtag_config);
|
||||
if (ret != ESP_OK)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Tell vfs to use usb-serial-jtag driver */
|
||||
esp_vfs_usb_serial_jtag_use_driver();
|
||||
}
|
||||
usbcdc_status.line_buffer = malloc(LUA_MAXINPUT);
|
||||
usbcdc_status.line_position = 0;
|
||||
if(usbcdc_status.line_buffer == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *pcName = "usbcdc";
|
||||
if(xTaskCreate(task_usbcdc, pcName, 4096, (void*)id, ESP_TASK_MAIN_PRIO + 1, &usbcdc_status.taskHandle) != pdPASS) {
|
||||
free(usbcdc_status.line_buffer);
|
||||
usbcdc_status.line_buffer = NULL;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
ADJUST_IDR(id, -1);
|
||||
|
||||
uart_status_t *us = & uart_status[id];
|
||||
|
||||
esp_err_t ret = uart_driver_install(id, uart_buf_sz_cfg[id].rx_buf_sz, uart_buf_sz_cfg[id].tx_buf_sz, 3, & us->queue, 0);
|
||||
|
@ -342,6 +484,7 @@ void platform_uart_stop( unsigned id )
|
|||
if (id == CONFIG_ESP_CONSOLE_UART_NUM)
|
||||
;
|
||||
else {
|
||||
ADJUST_IDR(id,);
|
||||
uart_status_t *us = & uart_status[id];
|
||||
uart_driver_delete(id);
|
||||
if(us->line_buffer) free(us->line_buffer);
|
||||
|
@ -354,6 +497,19 @@ void platform_uart_stop( unsigned id )
|
|||
int platform_uart_get_config(unsigned id, uint32_t *baudp, uint32_t *databitsp, uint32_t *parityp, uint32_t *stopbitsp) {
|
||||
int err;
|
||||
|
||||
#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
|
||||
if (id == 0) {
|
||||
// Return dummy values
|
||||
*baudp = 115200;
|
||||
*databitsp = 8;
|
||||
*parityp = PLATFORM_UART_PARITY_NONE;
|
||||
*stopbitsp = PLATFORM_UART_STOPBITS_1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
ADJUST_IDR(id, -1);
|
||||
|
||||
err = uart_get_baudrate(id, baudp);
|
||||
if (err != ESP_OK) return -1;
|
||||
*baudp &= 0xFFFFFFFE; // round down
|
||||
|
@ -403,6 +559,7 @@ int platform_uart_get_config(unsigned id, uint32_t *baudp, uint32_t *databitsp,
|
|||
|
||||
int platform_uart_set_wakeup_threshold(unsigned id, unsigned threshold)
|
||||
{
|
||||
ADJUST_IDR(id, 0);
|
||||
esp_err_t err = uart_set_wakeup_threshold(id, threshold);
|
||||
return (err == ESP_OK) ? 0 : -1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue