summaryrefslogtreecommitdiff
path: root/chip/stm32/usb_dwc_console.c
diff options
context:
space:
mode:
Diffstat (limited to 'chip/stm32/usb_dwc_console.c')
-rw-r--r--chip/stm32/usb_dwc_console.c360
1 files changed, 0 insertions, 360 deletions
diff --git a/chip/stm32/usb_dwc_console.c b/chip/stm32/usb_dwc_console.c
deleted file mode 100644
index 0d1340fb83..0000000000
--- a/chip/stm32/usb_dwc_console.c
+++ /dev/null
@@ -1,360 +0,0 @@
-/* Copyright 2016 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "common.h"
-#include "config.h"
-#include "console.h"
-#include "link_defs.h"
-#include "printf.h"
-#include "queue.h"
-#include "registers.h"
-#include "task.h"
-#include "timer.h"
-#include "util.h"
-#include "usb_descriptor.h"
-#include "usb_hw.h"
-
-/* Console output macro */
-#define CPRINTF(format, args...) cprintf(CC_USB, format, ## args)
-#define USB_CONSOLE_TIMEOUT_US (30 * MSEC)
-
-static int last_tx_ok = 1;
-
-static int is_reset;
-static int is_enabled = 1;
-static int is_readonly;
-
-/* USB-Serial descriptors */
-const struct usb_interface_descriptor USB_IFACE_DESC(USB_IFACE_CONSOLE) = {
- .bLength = USB_DT_INTERFACE_SIZE,
- .bDescriptorType = USB_DT_INTERFACE,
- .bInterfaceNumber = USB_IFACE_CONSOLE,
- .bAlternateSetting = 0,
- .bNumEndpoints = 2,
- .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
- .bInterfaceSubClass = USB_SUBCLASS_GOOGLE_SERIAL,
- .bInterfaceProtocol = USB_PROTOCOL_GOOGLE_SERIAL,
- .iInterface = USB_STR_CONSOLE_NAME,
-};
-const struct usb_endpoint_descriptor USB_EP_DESC(USB_IFACE_CONSOLE, 0) = {
- .bLength = USB_DT_ENDPOINT_SIZE,
- .bDescriptorType = USB_DT_ENDPOINT,
- .bEndpointAddress = 0x80 | USB_EP_CONSOLE,
- .bmAttributes = 0x02 /* Bulk IN */,
- .wMaxPacketSize = USB_MAX_PACKET_SIZE,
- .bInterval = 10,
-};
-const struct usb_endpoint_descriptor USB_EP_DESC(USB_IFACE_CONSOLE, 1) = {
- .bLength = USB_DT_ENDPOINT_SIZE,
- .bDescriptorType = USB_DT_ENDPOINT,
- .bEndpointAddress = USB_EP_CONSOLE,
- .bmAttributes = 0x02 /* Bulk OUT */,
- .wMaxPacketSize = USB_MAX_PACKET_SIZE,
- .bInterval = 0
-};
-
-static uint8_t ep_buf_tx[USB_MAX_PACKET_SIZE];
-static uint8_t ep_buf_rx[USB_MAX_PACKET_SIZE];
-
-static struct queue const tx_q = QUEUE_NULL(256, uint8_t);
-static struct queue const rx_q = QUEUE_NULL(USB_MAX_PACKET_SIZE, uint8_t);
-
-
-struct dwc_usb_ep ep_console_ctl = {
- .max_packet = USB_MAX_PACKET_SIZE,
- .tx_fifo = USB_EP_CONSOLE,
- .out_pending = 0,
- .out_data = 0,
- .out_databuffer = ep_buf_tx,
- .out_databuffer_max = sizeof(ep_buf_tx),
- .in_packets = 0,
- .in_pending = 0,
- .in_data = 0,
- .in_databuffer = ep_buf_rx,
- .in_databuffer_max = sizeof(ep_buf_rx),
-};
-
-
-
-/* Let the USB HW IN-to-host FIFO transmit some bytes */
-static void usb_enable_tx(int len)
-{
- struct dwc_usb_ep *ep = &ep_console_ctl;
-
- ep->in_data = ep->in_databuffer;
- ep->in_packets = 1;
- ep->in_pending = len;
-
- GR_USB_DIEPTSIZ(USB_EP_CONSOLE) = 0;
-
- GR_USB_DIEPTSIZ(USB_EP_CONSOLE) |= DXEPTSIZ_PKTCNT(1);
- GR_USB_DIEPTSIZ(USB_EP_CONSOLE) |= DXEPTSIZ_XFERSIZE(len);
- GR_USB_DIEPDMA(USB_EP_CONSOLE) = (uint32_t)ep->in_data;
-
- GR_USB_DIEPCTL(USB_EP_CONSOLE) |= DXEPCTL_CNAK | DXEPCTL_EPENA;
-}
-
-/* Let the USB HW OUT-from-host FIFO receive some bytes */
-static void usb_enable_rx(int len)
-{
- struct dwc_usb_ep *ep = &ep_console_ctl;
-
- ep->out_data = ep->out_databuffer;
- ep->out_pending = 0;
-
- GR_USB_DOEPTSIZ(USB_EP_CONSOLE) = 0;
- GR_USB_DOEPTSIZ(USB_EP_CONSOLE) |= DXEPTSIZ_PKTCNT(1);
- GR_USB_DOEPTSIZ(USB_EP_CONSOLE) |= DXEPTSIZ_XFERSIZE(len);
- GR_USB_DOEPDMA(USB_EP_CONSOLE) = (uint32_t)ep->out_data;
-
- GR_USB_DOEPCTL(USB_EP_CONSOLE) |= DXEPCTL_CNAK | DXEPCTL_EPENA;
-}
-
-/* True if the HW Rx/OUT FIFO has bytes for us. */
-static inline int rx_fifo_is_ready(void)
-{
- struct dwc_usb_ep *ep = &ep_console_ctl;
-
- return ep->out_pending;
-}
-
-/*
- * This function tries to shove new bytes from the USB host into the queue for
- * consumption elsewhere. It is invoked either by a HW interrupt (telling us we
- * have new bytes from the USB host), or by whoever is reading bytes out of the
- * other end of the queue (telling us that there's now more room in the queue
- * if we still have bytes to shove in there).
- */
-char buffer[65];
-static void rx_fifo_handler(void)
-{
- struct dwc_usb_ep *ep = &ep_console_ctl;
-
- int rx_in_fifo;
- size_t added;
-
- if (!rx_fifo_is_ready())
- return;
-
- rx_in_fifo = ep->out_pending;
- added = QUEUE_ADD_UNITS(&rx_q, ep->out_databuffer, rx_in_fifo);
-
- if (added != rx_in_fifo)
- CPRINTF("DROP CONSOLE: %d/%d process\n", added, rx_in_fifo);
-
- /* wake-up the console task */
- console_has_input();
-
- usb_enable_rx(USB_MAX_PACKET_SIZE);
-}
-DECLARE_DEFERRED(rx_fifo_handler);
-
-/* Rx/OUT interrupt handler */
-static void con_ep_rx(void)
-{
- struct dwc_usb_ep *ep = &ep_console_ctl;
-
- if (GR_USB_DOEPCTL(USB_EP_CONSOLE) & DXEPCTL_EPENA)
- return;
-
- /* Bytes received decrement DOEPTSIZ XFERSIZE */
- if (GR_USB_DOEPINT(USB_EP_CONSOLE) & DOEPINT_XFERCOMPL) {
- ep->out_pending =
- ep->max_packet -
- (GR_USB_DOEPTSIZ(USB_EP_CONSOLE) &
- GC_USB_DOEPTSIZ1_XFERSIZE_MASK);
- }
-
- /* Wake up the Rx FIFO handler */
- hook_call_deferred(&rx_fifo_handler_data, 0);
-
- /* clear the RX/OUT interrupts */
- GR_USB_DOEPINT(USB_EP_CONSOLE) = 0xffffffff;
-}
-
-/* True if the Tx/IN FIFO can take some bytes from us. */
-static inline int tx_fifo_is_ready(void)
-{
- return !(GR_USB_DIEPCTL(USB_EP_CONSOLE) & DXEPCTL_EPENA);
-}
-
-/* Try to send some bytes to the host */
-static void tx_fifo_handler(void)
-{
- struct dwc_usb_ep *ep = &ep_console_ctl;
- size_t count;
-
- if (!is_reset)
- return;
-
- /* If the HW FIFO isn't ready, then we can't do anything right now. */
- if (!tx_fifo_is_ready())
- return;
-
- count = QUEUE_REMOVE_UNITS(&tx_q,
- ep->in_databuffer, USB_MAX_PACKET_SIZE);
- if (count)
- usb_enable_tx(count);
-}
-DECLARE_DEFERRED(tx_fifo_handler);
-
-static void handle_output(void)
-{
- /* Wake up the Tx FIFO handler */
- hook_call_deferred(&tx_fifo_handler_data, 0);
-}
-
-/* Tx/IN interrupt handler */
-static void con_ep_tx(void)
-{
- /* Wake up the Tx FIFO handler */
- hook_call_deferred(&tx_fifo_handler_data, 0);
-
- /* clear the Tx/IN interrupts */
- GR_USB_DIEPINT(USB_EP_CONSOLE) = 0xffffffff;
-}
-
-static void ep_event(enum usb_ep_event evt)
-{
- if (evt != USB_EVENT_RESET)
- return;
-
- epN_reset(USB_EP_CONSOLE);
-
- is_reset = 1;
-
- /* Flush any queued data */
- hook_call_deferred(&tx_fifo_handler_data, 0);
- hook_call_deferred(&rx_fifo_handler_data, 0);
-
- usb_enable_rx(USB_MAX_PACKET_SIZE);
-}
-
-
-USB_DECLARE_EP(USB_EP_CONSOLE, con_ep_tx, con_ep_rx, ep_event);
-
-static int usb_wait_console(void)
-{
- timestamp_t deadline = get_time();
- int wait_time_us = 1;
-
- if (!is_enabled || !tx_fifo_is_ready())
- return EC_SUCCESS;
-
- deadline.val += USB_CONSOLE_TIMEOUT_US;
-
- /*
- * If the USB console is not used, Tx buffer would never free up.
- * In this case, let's drop characters immediately instead of sitting
- * for some time just to time out. On the other hand, if the last
- * Tx is good, it's likely the host is there to receive data, and
- * we should wait so that we don't clobber the buffer.
- */
- if (last_tx_ok) {
- while (queue_space(&tx_q) < USB_MAX_PACKET_SIZE || !is_reset) {
- if (timestamp_expired(deadline, NULL) ||
- in_interrupt_context()) {
- last_tx_ok = 0;
- return EC_ERROR_TIMEOUT;
- }
- if (wait_time_us < MSEC)
- udelay(wait_time_us);
- else
- usleep(wait_time_us);
- wait_time_us *= 2;
- }
-
- return EC_SUCCESS;
- }
-
- last_tx_ok = queue_space(&tx_q);
- return EC_SUCCESS;
-}
-static int __tx_char(void *context, int c)
-{
- struct queue *state =
- (struct queue *) context;
-
- if (c == '\n' && __tx_char(state, '\r'))
- return 1;
-
- QUEUE_ADD_UNITS(state, &c, 1);
- return 0;
-}
-
-/*
- * Public USB console implementation below.
- */
-int usb_getc(void)
-{
- int c;
-
- if (!is_enabled)
- return -1;
-
- if (QUEUE_REMOVE_UNITS(&rx_q, &c, 1))
- return c;
-
- return -1;
-}
-
-int usb_puts(const char *outstr)
-{
- int ret;
- struct queue state;
-
- if (is_readonly)
- return EC_SUCCESS;
-
- ret = usb_wait_console();
- if (ret)
- return ret;
-
- state = tx_q;
- while (*outstr)
- if (__tx_char(&state, *outstr++))
- break;
-
- if (queue_count(&state))
- handle_output();
-
- return *outstr ? EC_ERROR_OVERFLOW : EC_SUCCESS;
-}
-
-int usb_putc(int c)
-{
- char string[2];
-
- string[0] = c;
- string[1] = '\0';
- return usb_puts(string);
-}
-
-int usb_vprintf(const char *format, va_list args)
-{
- int ret;
- struct queue state;
-
- if (is_readonly)
- return EC_SUCCESS;
-
- ret = usb_wait_console();
- if (ret)
- return ret;
-
- state = tx_q;
- ret = vfnprintf(__tx_char, &state, format, args);
-
- if (queue_count(&state))
- handle_output();
-
- return ret;
-}
-
-void usb_console_enable(int enabled, int readonly)
-{
- is_enabled = enabled;
- is_readonly = readonly;
-}