mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-30 02:20:48 +00:00
cr50: export AP and EC UART through USB
Add support for exporting the EC and AP UARTs to USB. BUG=chrome-os-partner:50702 BRANCH=none TEST=Verify the EC and AP UARTs are forwarded to the EC and AP endpoints Change-Id: Icaeb7929dbaaf71a40f0752aa6cb5a2319373651 Signed-off-by: Mary Ruthven <mruthven@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/336317 Tested-by: Bill Richardson <wfrichar@chromium.org> Reviewed-by: Bill Richardson <wfrichar@chromium.org>
This commit is contained in:
@@ -116,6 +116,8 @@ const void * const usb_strings[] = {
|
||||
[USB_STR_CONSOLE_NAME] = USB_STRING_DESC("Shell"),
|
||||
[USB_STR_BLOB_NAME] = USB_STRING_DESC("Blob"),
|
||||
[USB_STR_HID_NAME] = USB_STRING_DESC("PokeyPokey"),
|
||||
[USB_STR_AP_NAME] = USB_STRING_DESC("AP"),
|
||||
[USB_STR_EC_NAME] = USB_STRING_DESC("EC"),
|
||||
};
|
||||
BUILD_ASSERT(ARRAY_SIZE(usb_strings) == USB_STR_COUNT);
|
||||
#endif
|
||||
|
||||
@@ -70,6 +70,8 @@ enum usb_strings {
|
||||
USB_STR_CONSOLE_NAME,
|
||||
USB_STR_BLOB_NAME,
|
||||
USB_STR_HID_NAME,
|
||||
USB_STR_AP_NAME,
|
||||
USB_STR_EC_NAME,
|
||||
|
||||
USB_STR_COUNT
|
||||
};
|
||||
@@ -89,8 +91,6 @@ enum usb_strings {
|
||||
|
||||
/* UART indexes (use define rather than enum to expand them) */
|
||||
#define UART_CR50 0
|
||||
#define UART_AP 1
|
||||
#define UART_EC 2
|
||||
|
||||
#define UARTN UART_CR50
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ chip-$(CONFIG_USB_CONSOLE)+=usb_console.o
|
||||
chip-$(CONFIG_USB_HID)+=usb_hid.o
|
||||
chip-$(CONFIG_USB_BLOB)+=blob.o
|
||||
chip-$(CONFIG_STREAM_USB)+=usb-stream.o
|
||||
chip-$(CONFIG_STREAM_USART)+=usart.o
|
||||
|
||||
chip-$(CONFIG_LOW_POWER_IDLE)+=idle.o
|
||||
|
||||
|
||||
@@ -111,9 +111,11 @@ void uart_init(void)
|
||||
/* Initialize the Cr50 UART */
|
||||
uartn_init(UARTN);
|
||||
|
||||
#if USE_UART_INTERRUPTS
|
||||
/* Enable interrupts for UART0 only */
|
||||
uart_enable_interrupt();
|
||||
#ifdef UART_AP
|
||||
uartn_init(UART_AP);
|
||||
#endif
|
||||
#ifdef UART_EC
|
||||
uartn_init(UART_EC);
|
||||
#endif
|
||||
|
||||
done_uart_init_yet = 1;
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
#include "uart.h"
|
||||
#include "util.h"
|
||||
|
||||
#define USE_UART_INTERRUPTS (!(defined(CONFIG_CUSTOMIZED_RO) && \
|
||||
defined(SECTION_IS_RO)))
|
||||
|
||||
struct uartn_interrupts {
|
||||
int tx_int;
|
||||
int rx_int;
|
||||
@@ -134,4 +137,9 @@ void uartn_init(int uart)
|
||||
/* Note: doesn't do anything unless turned on in NVIC */
|
||||
GR_UART_ICTRL(uart) = 0x02;
|
||||
|
||||
#if USE_UART_INTERRUPTS
|
||||
/* Enable interrupts for UART */
|
||||
uartn_enable_interrupt(uart);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
125
chip/g/usart.c
Normal file
125
chip/g/usart.c
Normal file
@@ -0,0 +1,125 @@
|
||||
/* 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 "queue.h"
|
||||
#include "queue_policies.h"
|
||||
#include "uartn.h"
|
||||
#include "usart.h"
|
||||
#include "usb-stream.h"
|
||||
|
||||
#define USE_UART_INTERRUPTS (!(defined(CONFIG_CUSTOMIZED_RO) && \
|
||||
defined(SECTION_IS_RO)))
|
||||
#define QUEUE_SIZE 64
|
||||
|
||||
struct usb_stream_config const ap_usb;
|
||||
struct usart_config const ap_uart;
|
||||
|
||||
struct usb_stream_config const ec_usb;
|
||||
struct usart_config const ec_uart;
|
||||
|
||||
static struct queue const ap_uart_to_usb =
|
||||
QUEUE_DIRECT(QUEUE_SIZE, uint8_t, ap_uart.producer, ap_usb.consumer);
|
||||
static struct queue const ap_usb_to_uart =
|
||||
QUEUE_DIRECT(QUEUE_SIZE, uint8_t, ap_usb.producer, ap_uart.consumer);
|
||||
|
||||
static struct queue const ec_uart_to_usb =
|
||||
QUEUE_DIRECT(QUEUE_SIZE, uint8_t, ec_uart.producer, ec_usb.consumer);
|
||||
static struct queue const ec_usb_to_uart =
|
||||
QUEUE_DIRECT(QUEUE_SIZE, uint8_t, ec_usb.producer, ec_uart.consumer);
|
||||
|
||||
struct usart_config const ap_uart = USART_CONFIG(UART_AP,
|
||||
ap_uart_to_usb,
|
||||
ap_usb_to_uart);
|
||||
struct usart_config const ec_uart = USART_CONFIG(UART_EC,
|
||||
ec_uart_to_usb,
|
||||
ec_usb_to_uart);
|
||||
USB_STREAM_CONFIG(ap_usb,
|
||||
USB_IFACE_AP,
|
||||
USB_STR_AP_NAME,
|
||||
USB_EP_AP,
|
||||
USB_MAX_PACKET_SIZE,
|
||||
USB_MAX_PACKET_SIZE,
|
||||
ap_usb_to_uart,
|
||||
ap_uart_to_usb)
|
||||
USB_STREAM_CONFIG(ec_usb,
|
||||
USB_IFACE_EC,
|
||||
USB_STR_EC_NAME,
|
||||
USB_EP_EC,
|
||||
USB_MAX_PACKET_SIZE,
|
||||
USB_MAX_PACKET_SIZE,
|
||||
ec_usb_to_uart,
|
||||
ec_uart_to_usb)
|
||||
|
||||
void get_data_from_usb(struct usart_config const *config)
|
||||
{
|
||||
struct queue const *uart_out = config->consumer.queue;
|
||||
int c;
|
||||
|
||||
/* Copy output from buffer until TX fifo full or output buffer empty */
|
||||
while (queue_count(uart_out) && QUEUE_REMOVE_UNITS(uart_out, &c, 1))
|
||||
uartn_write_char(config->uart, c);
|
||||
|
||||
/* If output buffer is empty, disable transmit interrupt */
|
||||
if (!queue_count(uart_out))
|
||||
uartn_tx_stop(config->uart);
|
||||
}
|
||||
|
||||
void send_data_to_usb(struct usart_config const *config)
|
||||
{
|
||||
struct queue const *uart_in = config->producer.queue;
|
||||
|
||||
/* Copy input from buffer until RX fifo empty or the queue is full */
|
||||
while (uartn_rx_available(config->uart) && queue_space(uart_in)) {
|
||||
int c = uartn_read_char(config->uart);
|
||||
|
||||
QUEUE_ADD_UNITS(uart_in, &c, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void uart_read(struct producer const *producer, size_t count)
|
||||
{
|
||||
}
|
||||
|
||||
static void uart_written(struct consumer const *consumer, size_t count)
|
||||
{
|
||||
struct usart_config const *config =
|
||||
DOWNCAST(consumer, struct usart_config, consumer);
|
||||
|
||||
if (uartn_tx_ready(config->uart), queue_count(consumer->queue))
|
||||
uartn_tx_start(config->uart);
|
||||
}
|
||||
|
||||
static void uart_flush(struct consumer const *consumer)
|
||||
{
|
||||
struct usart_config const *config =
|
||||
DOWNCAST(consumer, struct usart_config, consumer);
|
||||
|
||||
uartn_tx_flush(config->uart);
|
||||
}
|
||||
|
||||
struct producer_ops const uart_producer_ops = {
|
||||
.read = uart_read,
|
||||
};
|
||||
|
||||
struct consumer_ops const uart_consumer_ops = {
|
||||
.written = uart_written,
|
||||
.flush = uart_flush,
|
||||
};
|
||||
|
||||
#if USE_UART_INTERRUPTS
|
||||
/*
|
||||
* Interrupt handlers for UART1
|
||||
*/
|
||||
CONFIGURE_INTERRUPTS(ap_uart,
|
||||
GC_IRQNUM_UART1_RXINT,
|
||||
GC_IRQNUM_UART1_TXINT)
|
||||
|
||||
/*
|
||||
* Interrupt handlers for UART2
|
||||
*/
|
||||
CONFIGURE_INTERRUPTS(ec_uart,
|
||||
GC_IRQNUM_UART2_RXINT,
|
||||
GC_IRQNUM_UART2_TXINT)
|
||||
#endif
|
||||
69
chip/g/usart.h
Normal file
69
chip/g/usart.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/* 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 "consumer.h"
|
||||
#include "producer.h"
|
||||
#include "registers.h"
|
||||
#include "task.h"
|
||||
|
||||
#ifndef __CROS_FORWARD_UART_H
|
||||
#define __CROS_FORWARD_UART_H
|
||||
|
||||
struct usart_config {
|
||||
int uart;
|
||||
|
||||
struct producer const producer;
|
||||
struct consumer const consumer;
|
||||
};
|
||||
|
||||
extern struct consumer_ops const uart_consumer_ops;
|
||||
extern struct producer_ops const uart_producer_ops;
|
||||
#define CONFIGURE_INTERRUPTS(NAME, \
|
||||
RXINT, \
|
||||
TXINT) \
|
||||
void CONCAT2(NAME, _rx_int_)(void); \
|
||||
void CONCAT2(NAME, _tx_int_)(void); \
|
||||
DECLARE_IRQ(RXINT, CONCAT2(NAME, _rx_int_), 1); \
|
||||
DECLARE_IRQ(TXINT, CONCAT2(NAME, _tx_int_), 1); \
|
||||
void CONCAT2(NAME, _tx_int_)(void) \
|
||||
{ \
|
||||
/* Clear transmit interrupt status */ \
|
||||
GR_UART_ISTATECLR(NAME.uart) = \
|
||||
GC_UART_ISTATECLR_TX_MASK; \
|
||||
/* Fill output FIFO */ \
|
||||
get_data_from_usb(&NAME); \
|
||||
} \
|
||||
void CONCAT2(NAME, _rx_int_)(void) \
|
||||
{ \
|
||||
/* Clear receive interrupt status */ \
|
||||
GR_UART_ISTATECLR(NAME.uart) = \
|
||||
GC_UART_ISTATECLR_RX_MASK; \
|
||||
/* Read input FIFO until empty */ \
|
||||
send_data_to_usb(&NAME); \
|
||||
}
|
||||
|
||||
|
||||
#define USART_CONFIG(UART, \
|
||||
RX_QUEUE, \
|
||||
TX_QUEUE) \
|
||||
((struct usart_config const) { \
|
||||
.uart = UART, \
|
||||
.consumer = { \
|
||||
.queue = &TX_QUEUE, \
|
||||
.ops = &uart_consumer_ops, \
|
||||
}, \
|
||||
.producer = { \
|
||||
.queue = &RX_QUEUE, \
|
||||
.ops = &uart_producer_ops, \
|
||||
}, \
|
||||
})
|
||||
|
||||
|
||||
/* Read data from UART and add it to the producer queue */
|
||||
void send_data_to_usb(struct usart_config const *config);
|
||||
|
||||
/* Read data from the consumer queue and send it to the UART */
|
||||
void get_data_from_usb(struct usart_config const *config);
|
||||
#endif /* __CROS_FORWARD_UART_H */
|
||||
Reference in New Issue
Block a user