blob: 33a97395ad1be97698ea4f4a1db1be1233016549 [file] [log] [blame]
/* 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, \
.info = NULL, \
}, \
\
.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 initialize 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 */