diff options
author | Anton Staaf <robotboy@chromium.org> | 2015-06-16 10:34:56 -0700 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2015-07-15 21:57:46 +0000 |
commit | 137959bb88ef381cba67e24943388bd17ae89357 (patch) | |
tree | d4844e76548432b726cf40d57bf0214d92d64634 /chip/stm32/usart_rx_interrupt.c | |
parent | 88a1790bb7d82a30e052f1e10a9c7c88fb5c5c36 (diff) | |
download | chrome-ec-137959bb88ef381cba67e24943388bd17ae89357.tar.gz |
USART: Add flexibility needed to support DMA
In order to support DMA transfers in one or both directions the usart
driver needs to be configurable with producer/consumer operations and
interrupt handler functions. These are now packaged up in the usart_rx
and usart_tx structs, and versions for interrupt driven RX and TX are
provided.
Signed-off-by: Anton Staaf <robotboy@chromium.org>
BRANCH=None
BUG=None
TEST=make buildall -j
Change-Id: I3fd14c675c90873e903195b8e20d2070d2eda5ac
Reviewed-on: https://chromium-review.googlesource.com/285023
Trybot-Ready: Anton Staaf <robotboy@chromium.org>
Tested-by: Anton Staaf <robotboy@chromium.org>
Reviewed-by: Todd Broch <tbroch@chromium.org>
Tested-by: Todd Broch <tbroch@chromium.org>
Commit-Queue: Anton Staaf <robotboy@chromium.org>
Diffstat (limited to 'chip/stm32/usart_rx_interrupt.c')
-rw-r--r-- | chip/stm32/usart_rx_interrupt.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/chip/stm32/usart_rx_interrupt.c b/chip/stm32/usart_rx_interrupt.c new file mode 100644 index 0000000000..6a46b3fb11 --- /dev/null +++ b/chip/stm32/usart_rx_interrupt.c @@ -0,0 +1,48 @@ +/* Copyright (c) 2014 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. + */ + +/* Interrupt based USART RX driver for STM32 */ + +#include "usart.h" + +#include "atomic.h" +#include "common.h" +#include "queue.h" +#include "registers.h" + +static void usart_rx_init(struct usart_config const *config) +{ + intptr_t base = config->hw->base; + + STM32_USART_CR1(base) |= STM32_USART_CR1_RXNEIE; + STM32_USART_CR1(base) |= STM32_USART_CR1_RE; +} + +static void usart_rx_interrupt_handler(struct usart_config const *config) +{ + intptr_t base = config->hw->base; + uint8_t byte; + + if (!(STM32_USART_SR(base) & STM32_USART_SR_RXNE)) + return; + + byte = STM32_USART_RDR(base); + + if (!queue_add_unit(config->producer.queue, &byte)) + atomic_add((uint32_t *) &config->state->rx_dropped, 1); +} + +struct usart_rx const usart_rx_interrupt = { + .producer_ops = { + /* + * Nothing to do here, we either had enough space in the queue + * when a character came in or we dropped it already. + */ + .read = NULL, + }, + + .init = usart_rx_init, + .interrupt = usart_rx_interrupt_handler, +}; |