| /* 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); |
| |
| /* |
| * Trigger tx interrupt to process tx data. Calling this function will set |
| * TXIEIE of USART HW instance and trigger associated IRQ. |
| */ |
| void usart_tx_start(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); |
| |
| /* |
| * This usart_tx structure contains function pointer to interrupt |
| * handler implemented to send host response. Generic queue based |
| * interrupt handler is not used for usart host transport. |
| */ |
| extern struct usart_tx const usart_host_command_tx_interrupt; |
| |
| #endif /* __CROS_EC_USART_H */ |