summaryrefslogtreecommitdiff
path: root/chip/stm32/usart_rx_interrupt.c
diff options
context:
space:
mode:
authorAnton Staaf <robotboy@chromium.org>2015-06-16 10:34:56 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-07-15 21:57:46 +0000
commit137959bb88ef381cba67e24943388bd17ae89357 (patch)
treed4844e76548432b726cf40d57bf0214d92d64634 /chip/stm32/usart_rx_interrupt.c
parent88a1790bb7d82a30e052f1e10a9c7c88fb5c5c36 (diff)
downloadchrome-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.c48
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,
+};