diff options
author | Anton Staaf <robotboy@chromium.org> | 2015-07-15 15:03:40 -0700 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2015-07-21 18:30:40 +0000 |
commit | 1e3d00ff7ae32d58ac9c27ef09b22df58e48b1c4 (patch) | |
tree | 190ad8a9e3b463fb7acc6068b1cf73f0286baadd /chip/stm32/usart_tx_dma.h | |
parent | ff9934264163dd0d7e795f32144c6c1082fdf040 (diff) | |
download | chrome-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.h | 90 |
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 */ |