259 lines
7.3 KiB
C
259 lines
7.3 KiB
C
/* Copyright 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.
|
|
*/
|
|
#ifndef __CROS_EC_USART_H
|
|
#define __CROS_EC_USART_H
|
|
|
|
/* STM32 USART driver for Chrome EC */
|
|
|
|
#include "common.h"
|
|
#include "consumer.h"
|
|
#include "producer.h"
|
|
#include "queue.h"
|
|
|
|
#include <stdint.h>
|
|
|
|
/*
|
|
* Per-USART state stored in RAM. This structure will be zero initialized by
|
|
* BSS init.
|
|
*/
|
|
struct usart_state {
|
|
/*
|
|
* Counter of bytes received and then dropped because of lack of space
|
|
* in the RX queue.
|
|
*/
|
|
uint32_t rx_dropped;
|
|
|
|
/*
|
|
* Counter of the number of times an receive overrun condition is
|
|
* detected. This will not usually be a count of the number of bytes
|
|
* that were lost due to overrun conditions.
|
|
*/
|
|
uint32_t rx_overrun;
|
|
};
|
|
|
|
struct usart_config;
|
|
|
|
struct usart_hw_ops {
|
|
/*
|
|
* The generic USART initialization code calls this function to allow
|
|
* the variant HW specific code to perform any initialization. This
|
|
* function is called before the USART is enabled, and should among
|
|
* other things enable the USARTs interrupt.
|
|
*/
|
|
void (*enable)(struct usart_config const *config);
|
|
|
|
/*
|
|
* The generic USART shutdown code calls this function, allowing the
|
|
* variant specific code an opportunity to do any variant specific
|
|
* shutdown tasks.
|
|
*/
|
|
void (*disable)(struct usart_config const *config);
|
|
};
|
|
|
|
/*
|
|
* The usart_rx/usart_tx structures contain functions pointers for the
|
|
* interrupt handler and producer/consumer operations required to implement a
|
|
* particular RX/TX strategy.
|
|
*
|
|
* These structures are defined by the various RX/TX implementations, and are
|
|
* used to initialize the usart_config structure to configure the USART driver
|
|
* for interrupt or DMA based transfer.
|
|
*/
|
|
struct usart_rx {
|
|
void (*init)(struct usart_config const *config);
|
|
void (*interrupt)(struct usart_config const *config);
|
|
|
|
/*
|
|
* Print to the console any per-strategy diagnostic information, this
|
|
* is used by the usart_info command. This can be NULL if there is
|
|
* nothing interesting to display.
|
|
*/
|
|
void (*info)(struct usart_config const *config);
|
|
|
|
struct producer_ops producer_ops;
|
|
};
|
|
|
|
struct usart_tx {
|
|
void (*init)(struct usart_config const *config);
|
|
void (*interrupt)(struct usart_config const *config);
|
|
|
|
/*
|
|
* Print to the console any per-strategy diagnostic information, this
|
|
* is used by the usart_info command. This can be NULL if there is
|
|
* nothing interesting to display.
|
|
*/
|
|
void (*info)(struct usart_config const *config);
|
|
|
|
struct consumer_ops consumer_ops;
|
|
};
|
|
|
|
extern struct usart_rx const usart_rx_interrupt;
|
|
extern struct usart_tx const usart_tx_interrupt;
|
|
|
|
/*
|
|
* Per-USART hardware configuration stored in flash. Instances of this
|
|
* structure are provided by each variants driver, one per physical USART.
|
|
*/
|
|
struct usart_hw_config {
|
|
int index;
|
|
intptr_t base;
|
|
int irq;
|
|
|
|
uint32_t volatile *clock_register;
|
|
uint32_t clock_enable;
|
|
|
|
struct usart_hw_ops const *ops;
|
|
};
|
|
|
|
/*
|
|
* Compile time Per-USART configuration stored in flash. Instances of this
|
|
* structure are provided by the user of the USART. This structure binds
|
|
* together all information required to operate a USART.
|
|
*/
|
|
struct usart_config {
|
|
/*
|
|
* Pointer to USART HW configuration. There is one HW configuration
|
|
* per physical USART.
|
|
*/
|
|
struct usart_hw_config const *hw;
|
|
|
|
struct usart_rx const *rx;
|
|
struct usart_tx const *tx;
|
|
|
|
/*
|
|
* Pointer to USART state structure. The state structure maintains per
|
|
* USART information.
|
|
*/
|
|
struct usart_state volatile *state;
|
|
|
|
/*
|
|
* Baud rate for USART.
|
|
*/
|
|
int baud;
|
|
|
|
/* Other flags (rx/tx inversion, half-duplex). */
|
|
#define USART_CONFIG_FLAG_RX_INV BIT(0)
|
|
#define USART_CONFIG_FLAG_TX_INV BIT(1)
|
|
#define USART_CONFIG_FLAG_HDSEL BIT(2)
|
|
unsigned int flags;
|
|
|
|
struct consumer consumer;
|
|
struct producer producer;
|
|
};
|
|
|
|
/*
|
|
* Convenience macro for defining USARTs and their associated state and buffers.
|
|
* NAME is used to construct the names of the usart_state struct, and
|
|
* usart_config struct, the latter is just called NAME.
|
|
*
|
|
* HW is the name of the usart_hw_config provided by the variant specific code.
|
|
*
|
|
* RX_QUEUE and TX_QUEUE are the names of the RX and TX queues that this USART
|
|
* should write to and read from respectively.
|
|
*/
|
|
/*
|
|
* The following assertions can not be made because they require access to
|
|
* non-const fields, but should be kept in mind.
|
|
*
|
|
* BUILD_ASSERT(RX_QUEUE.unit_bytes == 1);
|
|
* BUILD_ASSERT(TX_QUEUE.unit_bytes == 1);
|
|
*/
|
|
#define USART_CONFIG(HW, RX, TX, BAUD, FLAGS, RX_QUEUE, TX_QUEUE) \
|
|
((struct usart_config const) { \
|
|
.hw = &HW, \
|
|
.rx = &RX, \
|
|
.tx = &TX, \
|
|
.state = &((struct usart_state){}), \
|
|
.baud = BAUD, \
|
|
.flags = FLAGS, \
|
|
.consumer = { \
|
|
.queue = &TX_QUEUE, \
|
|
.ops = &TX.consumer_ops, \
|
|
}, \
|
|
.producer = { \
|
|
.queue = &RX_QUEUE, \
|
|
.ops = &RX.producer_ops, \
|
|
}, \
|
|
})
|
|
|
|
/*
|
|
* Initialize the given USART. Once init is finished the USART streams are
|
|
* available for operating on.
|
|
*/
|
|
void usart_init(struct usart_config const *config);
|
|
|
|
/*
|
|
* Shutdown the given USART.
|
|
*/
|
|
void usart_shutdown(struct usart_config const *config);
|
|
|
|
/*
|
|
* Handle a USART interrupt. The per-variant USART code creates bindings
|
|
* for the variants interrupts to call this generic USART interrupt handler
|
|
* with the appropriate usart_config.
|
|
*/
|
|
void usart_interrupt(struct usart_config const *config);
|
|
|
|
/*
|
|
* These are HW specific baud rate calculation and setting functions that the
|
|
* peripheral variant code uses during initialization and clock frequency
|
|
* change. The baud rate divisor input frequency is passed in Hertz.
|
|
*/
|
|
void usart_set_baud_f0_l(struct usart_config const *config, int baud,
|
|
int frequency_hz);
|
|
void usart_set_baud_f(struct usart_config const *config, int baud,
|
|
int frequency_hz);
|
|
|
|
/*
|
|
* Allow specification of parity for this usart.
|
|
* parity is 0: none, 1: odd, 2: even.
|
|
*/
|
|
void usart_set_parity(struct usart_config const *config, int parity);
|
|
|
|
/*
|
|
* Check parity for this usart.
|
|
* parity is 0: none, 1: odd, 2: even.
|
|
*/
|
|
int usart_get_parity(struct usart_config const *config);
|
|
|
|
/*
|
|
* Set baud rate for this usart. Note that baud rate will get reset on
|
|
* core frequency change, so this only makes sense if the board never
|
|
* goes to deep idle.
|
|
*/
|
|
void usart_set_baud(struct usart_config const *config, int baud);
|
|
|
|
/*
|
|
* Different families provide different ways of clearing the transmit complete
|
|
* flag. This function will be provided by the family specific implementation.
|
|
*/
|
|
void usart_clear_tc(struct usart_config const *config);
|
|
|
|
/*
|
|
* Each family implementation provides the usart_get_configs function to access
|
|
* a read only list of the configs that are currently enabled.
|
|
*/
|
|
struct usart_configs {
|
|
/*
|
|
* The family's usart_config array, entries in the array for disabled
|
|
* configs will be NULL, enabled configs will point to the usart_config
|
|
* that was enabled. And the following will be true:
|
|
*
|
|
* configs[i]->hw->index == i;
|
|
*/
|
|
struct usart_config const * const *configs;
|
|
|
|
/*
|
|
* The total possible number of configs that this family supports.
|
|
* This will be the same as the number of usart_hw structs that the
|
|
* family provides in its family specific usart header.
|
|
*/
|
|
size_t count;
|
|
};
|
|
|
|
struct usart_configs usart_get_configs(void);
|
|
|
|
#endif /* __CROS_EC_USART_H */
|