From fca0add22b93b18f292d1693ca3f59c60256cde3 Mon Sep 17 00:00:00 2001 From: Jithu Joseph Date: Sun, 6 Nov 2016 16:58:14 -0800 Subject: [PATCH] console : usb: USB UART console output support Add support for console output via the USB UART. Note that console input via the USB UART doesnt work. Adds a simulated poll method for UART interface exposed by USB. Jira : ZEP-775 Change-Id: I357827ea52c027eb000baed80225f422df1f3358 Signed-off-by: Jithu Joseph --- .../quark_se/Kconfig.defconfig.series | 3 ++- drivers/console/Kconfig | 14 ++++++++++++++ drivers/console/uart_console.c | 16 +++++++++++++++- subsys/usb/class/cdc_acm.c | 15 ++++++++++++--- 4 files changed, 43 insertions(+), 5 deletions(-) diff --git a/arch/x86/soc/intel_quark/quark_se/Kconfig.defconfig.series b/arch/x86/soc/intel_quark/quark_se/Kconfig.defconfig.series index 50863c6db18..6b8f51ce9e6 100644 --- a/arch/x86/soc/intel_quark/quark_se/Kconfig.defconfig.series +++ b/arch/x86/soc/intel_quark/quark_se/Kconfig.defconfig.series @@ -217,7 +217,8 @@ endif # UART_QMSI if UART_CONSOLE config UART_CONSOLE_ON_DEV_NAME - default "UART_1" + default "UART_1" if USB_UART_CONSOLE = n + default "CDC_ACM" if USB_UART_CONSOLE endif diff --git a/drivers/console/Kconfig b/drivers/console/Kconfig index 269a400432a..9960becf97b 100644 --- a/drivers/console/Kconfig +++ b/drivers/console/Kconfig @@ -95,6 +95,20 @@ config UART_CONSOLE_DEBUG_SERVER_HOOKS they are some sort of control characters, or let the regular console code handle them if they are of no special significance to it. +config USB_UART_CONSOLE + bool + prompt "Use USB port for console outputs" + depends on SERIAL + select CONSOLE_HAS_DRIVER + select USB_CDC_ACM + default n + help + Enable this option to use the USB UART for console output. The output + can be viewed from the USB host via /dev/ttyACM* port. Note that console + inputs from the USB UART are not functional yet. Also since the USB + layer currently doesnt support multiple interfaces, this shouldnt be + selected in conjunction with say USB Mass Storage. + config RAM_CONSOLE bool prompt "Use RAM console" diff --git a/drivers/console/uart_console.c b/drivers/console/uart_console.c index 2181a175049..bc4c8c2cfb0 100644 --- a/drivers/console/uart_console.c +++ b/drivers/console/uart_console.c @@ -493,10 +493,22 @@ void uart_console_hook_install(void) */ static int uart_console_init(struct device *arg) { + + uint32_t dtr = 0; ARG_UNUSED(arg); uart_console_dev = device_get_binding(CONFIG_UART_CONSOLE_ON_DEV_NAME); +#ifdef CONFIG_USB_UART_CONSOLE + while (1) { + uart_line_ctrl_get(uart_console_dev, LINE_CTRL_DTR, &dtr); + if (dtr) { + break; + } + } + sys_thread_busy_wait(1000000); +#endif + uart_console_hook_install(); return 0; @@ -504,7 +516,9 @@ static int uart_console_init(struct device *arg) /* UART console initializes after the UART device itself */ SYS_INIT(uart_console_init, -#if defined(CONFIG_EARLY_CONSOLE) +#if defined(CONFIG_USB_UART_CONSOLE) + APPLICATION, +#elif defined(CONFIG_EARLY_CONSOLE) PRE_KERNEL_1, #else POST_KERNEL, diff --git a/subsys/usb/class/cdc_acm.c b/subsys/usb/class/cdc_acm.c index 05c8ad3ef36..65fc64b220c 100644 --- a/subsys/usb/class/cdc_acm.c +++ b/subsys/usb/class/cdc_acm.c @@ -72,6 +72,8 @@ static struct uart_driver_api cdc_acm_driver_api; struct device *cdc_acm_dev; +static struct nano_sem poll_wait_sem; + /* Device data structure */ struct cdc_acm_dev_data_t { /* USB device status code */ @@ -306,6 +308,7 @@ static void cdc_acm_bulk_in(uint8_t ep, enum usb_dc_ep_cb_status_code ep_status) struct cdc_acm_dev_data_t * const dev_data = DEV_DATA(cdc_acm_dev); dev_data->tx_ready = 1; + nano_sem_give(&poll_wait_sem); /* Call callback only if tx irq ena */ if (dev_data->cb && dev_data->tx_irq_ena) dev_data->cb(cdc_acm_dev); @@ -500,6 +503,7 @@ static int cdc_acm_init(struct device *dev) } dev->driver_api = &cdc_acm_driver_api; + nano_sem_init(&poll_wait_sem); return 0; } @@ -834,13 +838,18 @@ static int cdc_acm_poll_in(struct device *dev, unsigned char *c) /* * @brief Output a character in polled mode. * - * @return 0 Since it is not supported. See the comments of - * cdc_acm_poll_in() for details. Apps should use fifo_fill API instead. + * The UART poll method for USB UART is simulated by waiting till + * we get the next BULK In upcall from the USB device controller or 100 ms. + * + * @return the same character which is sent */ static unsigned char cdc_acm_poll_out(struct device *dev, unsigned char c) { - return 0; + cdc_acm_fifo_fill(dev, &c, 1); + nano_sem_take(&poll_wait_sem, MSEC(100)); + + return c; } static struct uart_driver_api cdc_acm_driver_api = {