summaryrefslogtreecommitdiff
path: root/chip/stm32/usart_tx_dma.h
diff options
context:
space:
mode:
authorAnton Staaf <robotboy@chromium.org>2015-07-15 15:03:40 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-07-21 18:30:40 +0000
commit1e3d00ff7ae32d58ac9c27ef09b22df58e48b1c4 (patch)
tree190ad8a9e3b463fb7acc6068b1cf73f0286baadd /chip/stm32/usart_tx_dma.h
parentff9934264163dd0d7e795f32144c6c1082fdf040 (diff)
downloadchrome-ec-1e3d00ff7ae32d58ac9c27ef09b22df58e48b1c4.tar.gz
USART: Add DMA based transmitter
This adds a new transmission implementation for the multi UART driver. It is a DMA based transmitter that can directly read from the TX queue with zero copy overhead. The DMA channel used as well as the maximum DMA transmission size are configurable per UART at the board level. This also updates the Ryu AP UART to use DMA transmission. Signed-off-by: Anton Staaf <robotboy@chromium.org> BRANCH=None BUG=None TEST=make buildall -j Manually verify that the AP UART forwarding works Change-Id: I3cb27d0f9015043d75a38c12919388afe90dc4af Reviewed-on: https://chromium-review.googlesource.com/286274 Trybot-Ready: Anton Staaf <robotboy@chromium.org> Tested-by: Anton Staaf <robotboy@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org> Commit-Queue: Anton Staaf <robotboy@chromium.org>
Diffstat (limited to 'chip/stm32/usart_tx_dma.h')
-rw-r--r--chip/stm32/usart_tx_dma.h90
1 files changed, 90 insertions, 0 deletions
diff --git a/chip/stm32/usart_tx_dma.h b/chip/stm32/usart_tx_dma.h
new file mode 100644
index 0000000000..a1e4e0831d
--- /dev/null
+++ b/chip/stm32/usart_tx_dma.h
@@ -0,0 +1,90 @@
+/* Copyright (c) 2015 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.
+ *
+ * DMA based USART TX driver for STM32
+ */
+#ifndef __CROS_EC_USART_TX_DMA_H
+#define __CROS_EC_USART_TX_DMA_H
+
+#include "consumer.h"
+#include "dma.h"
+#include "queue.h"
+#include "usart.h"
+
+/*
+ * Construct a USART TX instance for DMA using the given DMA channel.
+ *
+ * This macro creates a new usart_tx_dma struct, complete with in RAM state,
+ * the contained usart_tx struct can be used in initializing a usart_config
+ * struct.
+ *
+ * CHANNEL is the DMA channel to be used for transmission. This must be a
+ * valid DMA channel for the USART peripheral and any alternate channel
+ * mappings must be handled by the board specific code.
+ *
+ * MAX_BYTES is the maximum size in bytes of a single DMA transfer. This
+ * allows the board to tune how often the TX engine updates the queue state.
+ * A larger number here could cause the queue to appear full for longer than
+ * required because the queue isn't notified that it has been read from until
+ * after the DMA transfer completes.
+ */
+#define USART_TX_DMA(CHANNEL, MAX_BYTES) \
+ ((struct usart_tx_dma const) { \
+ .usart_tx = { \
+ .consumer_ops = { \
+ .written = usart_tx_dma_written,\
+ .flush = usart_tx_dma_flush, \
+ }, \
+ \
+ .init = usart_tx_dma_init, \
+ .interrupt = usart_tx_dma_interrupt, \
+ }, \
+ \
+ .state = &((struct usart_tx_dma_state){}), \
+ .channel = CHANNEL, \
+ .max_bytes = MAX_BYTES, \
+ })
+
+/*
+ * In RAM state required to manage DMA based transmission.
+ */
+struct usart_tx_dma_state {
+ /*
+ * The current chunk of queue buffer being used for transmission. Once
+ * the transfer is complete, this is used to update the TX queue head
+ * pointer as well.
+ */
+ struct queue_chunk chunk;
+
+ /*
+ * Flag indicating whether a DMA transfer is currently active.
+ */
+ int dma_active;
+};
+
+/*
+ * Extension of the usart_tx struct to include required configuration for
+ * DMA based transmission.
+ */
+struct usart_tx_dma {
+ struct usart_tx usart_tx;
+
+ struct usart_tx_dma_state volatile *state;
+
+ enum dma_channel channel;
+
+ size_t max_bytes;
+};
+
+/*
+ * Function pointers needed to intialize a usart_tx struct. These shouldn't
+ * be called in any other context as they assume that the consumer or config
+ * that they are passed was initialized with a complete usart_tx_dma struct.
+ */
+void usart_tx_dma_written(struct consumer const *consumer, size_t count);
+void usart_tx_dma_flush(struct consumer const *consumer);
+void usart_tx_dma_init(struct usart_config const *config);
+void usart_tx_dma_interrupt(struct usart_config const *config);
+
+#endif /* __CROS_EC_USART_TX_DMA_H */