Files
OpenCellular/chip/g/usart.h
Marius Schilder 0059070b22 g: tweak usart queuing for stream signing
Guarded by CONFIG_STREAM_SIGNING
Comes at 10K cost in SRAM
Used by nm50

Signed-off-by: mschilder@google.com
BRANCH=cr50
BUG=none
TEST=sign nm50 target dump_state 115200 output w/o overruns

Change-Id: I4db2dec4de8afbeba68d1bc72f43a91fc134ff85
Reviewed-on: https://chromium-review.googlesource.com/823264
Commit-Ready: Marius Schilder <mschilder@chromium.org>
Tested-by: Marius Schilder <mschilder@chromium.org>
Reviewed-by: Marius Schilder <mschilder@chromium.org>
Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
2017-12-13 17:26:11 -08:00

92 lines
2.6 KiB
C

/* 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"
#include "board.h"
#ifndef __CROS_FORWARD_UART_H
#define __CROS_FORWARD_UART_H
#ifdef CONFIG_STREAM_SIGNATURE
/*
* When configured for signing over streaming data, call the consumer handler
* directly to help avoid incoming uart overruns.
* Note this will run under interrupt handler so consumer beware.
*/
#define CONFIGURE_INTERRUPTS__rx_int(NAME) send_data_to_usb(&NAME)
#else
#define CONFIGURE_INTERRUPTS__rx_int(NAME) hook_call_deferred(NAME.deferred, 0)
#endif
struct usart_config {
int uart;
struct producer const producer;
struct consumer const consumer;
const struct deferred_data *deferred;
};
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 */ \
CONFIGURE_INTERRUPTS__rx_int(NAME); \
}
#define USART_CONFIG(NAME, \
UART, \
RX_QUEUE, \
TX_QUEUE) \
static void CONCAT2(NAME, _deferred_)(void); \
DECLARE_DEFERRED(CONCAT2(NAME, _deferred_)); \
struct usart_config const NAME = { \
.uart = UART, \
.consumer = { \
.queue = &TX_QUEUE, \
.ops = &uart_consumer_ops, \
}, \
.producer = { \
.queue = &RX_QUEUE, \
.ops = &uart_producer_ops, \
}, \
.deferred = &CONCAT2(NAME, _deferred__data), \
}; \
static void CONCAT2(NAME, _deferred_)(void) \
{ \
send_data_to_usb(&NAME); \
} \
/* 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 */