1 /* Copyright 2018 SiFive, Inc */
2 /* SPDX-License-Identifier: Apache-2.0 */
9 * @brief API for UART serial ports
12 #include <metal/interrupt.h>
17 struct metal_uart_vtable {
18 void (*init)(struct metal_uart *uart, int baud_rate);
19 int (*putc)(struct metal_uart *uart, int c);
20 int (*txready)(struct metal_uart *uart);
21 int (*getc)(struct metal_uart *uart, int *c);
22 int (*get_baud_rate)(struct metal_uart *uart);
23 int (*set_baud_rate)(struct metal_uart *uart, int baud_rate);
24 struct metal_interrupt *(*controller_interrupt)(struct metal_uart *uart);
25 int (*get_interrupt_id)(struct metal_uart *uart);
26 int (*tx_interrupt_enable)(struct metal_uart *uart);
27 int (*tx_interrupt_disable)(struct metal_uart *uart);
28 int (*rx_interrupt_enable)(struct metal_uart *uart);
29 int (*rx_interrupt_disable)(struct metal_uart *uart);
30 int (*set_tx_watermark)(struct metal_uart *uart, size_t length);
31 size_t (*get_tx_watermark)(struct metal_uart *uart);
32 int (*set_rx_watermark)(struct metal_uart *uart, size_t length);
33 size_t (*get_rx_watermark)(struct metal_uart *uart);
37 * @brief Handle for a UART serial device
40 const struct metal_uart_vtable *vtable;
43 /*! @brief Get a handle for a UART device
44 * @param device_num The index of the desired UART device
45 * @return A handle to the UART device, or NULL if the device does not exist*/
46 struct metal_uart *metal_uart_get_device(unsigned int device_num);
49 * @brief Initialize UART device
51 * Initialize the UART device described by the UART handle. This function must
53 * other method on the UART can be invoked. It is invalid to initialize a UART
56 * @param uart The UART device handle
57 * @param baud_rate the baud rate to set the UART to
59 __inline__ void metal_uart_init(struct metal_uart *uart, int baud_rate) {
60 uart->vtable->init(uart, baud_rate);
64 * @brief Output a character over the UART
65 * @param uart The UART device handle
66 * @param c The character to send over the UART
67 * @return 0 upon success
69 __inline__ int metal_uart_putc(struct metal_uart *uart, int c) {
70 return uart->vtable->putc(uart, c);
74 * @brief Test, determine if tx output is blocked(full/busy)
75 * @param uart The UART device handle
76 * @return 0 not blocked
78 __inline__ int metal_uart_txready(struct metal_uart *uart) {
79 return uart->vtable->txready(uart);
83 * @brief Read a character sent over the UART
84 * @param uart The UART device handle
85 * @param c The varible to hold the read character
86 * @return 0 upon success
88 * If "c == -1" no char was ready.
89 * If "c != -1" then C == byte value (0x00 to 0xff)
91 __inline__ int metal_uart_getc(struct metal_uart *uart, int *c) {
92 return uart->vtable->getc(uart, c);
96 * @brief Get the baud rate of the UART peripheral
97 * @param uart The UART device handle
98 * @return The current baud rate of the UART
100 __inline__ int metal_uart_get_baud_rate(struct metal_uart *uart) {
101 return uart->vtable->get_baud_rate(uart);
105 * @brief Set the baud rate of the UART peripheral
106 * @param uart The UART device handle
107 * @param baud_rate The baud rate to configure
108 * @return the new baud rate of the UART
110 __inline__ int metal_uart_set_baud_rate(struct metal_uart *uart,
112 return uart->vtable->set_baud_rate(uart, baud_rate);
116 * @brief Get the interrupt controller of the UART peripheral
118 * Get the interrupt controller for the UART peripheral. The interrupt
119 * controller must be initialized before any interrupts can be registered
120 * or enabled with it.
122 * @param uart The UART device handle
123 * @return The handle for the UART interrupt controller
125 __inline__ struct metal_interrupt *
126 metal_uart_interrupt_controller(struct metal_uart *uart) {
127 return uart->vtable->controller_interrupt(uart);
131 * @brief Get the interrupt ID of the UART controller
132 * @param uart The UART device handle
133 * @return The UART interrupt id
135 __inline__ int metal_uart_get_interrupt_id(struct metal_uart *uart) {
136 return uart->vtable->get_interrupt_id(uart);
140 * @brief Enable the UART transmit interrupt
141 * @param uart The UART device handle
142 * @return 0 upon success
144 __inline__ int metal_uart_transmit_interrupt_enable(struct metal_uart *uart) {
145 return uart->vtable->tx_interrupt_enable(uart);
149 * @brief Disable the UART transmit interrupt
150 * @param uart The UART device handle
151 * @return 0 upon success
153 __inline__ int metal_uart_transmit_interrupt_disable(struct metal_uart *uart) {
154 return uart->vtable->tx_interrupt_disable(uart);
158 * @brief Enable the UART receive interrupt
159 * @param uart The UART device handle
160 * @return 0 upon success
162 __inline__ int metal_uart_receive_interrupt_enable(struct metal_uart *uart) {
163 return uart->vtable->rx_interrupt_enable(uart);
167 * @brief Disable the UART receive interrupt
168 * @param uart The UART device handle
169 * @return 0 upon success
171 __inline__ int metal_uart_receive_interrupt_disable(struct metal_uart *uart) {
172 return uart->vtable->rx_interrupt_disable(uart);
176 * @brief Set the transmit watermark level of the UART controller
177 * @param uart The UART device handle
178 * @param level The UART transmit watermark level
179 * @return 0 upon success
181 __inline__ int metal_uart_set_transmit_watermark(struct metal_uart *uart,
183 return uart->vtable->set_tx_watermark(uart, level);
187 * @brief Get the transmit watermark level of the UART controller
188 * @param uart The UART device handle
189 * @return The UART transmit watermark level
191 __inline__ size_t metal_uart_get_transmit_watermark(struct metal_uart *uart) {
192 return uart->vtable->get_tx_watermark(uart);
196 * @brief Set the receive watermark level of the UART controller
197 * @param uart The UART device handle
198 * @param level The UART transmit watermark level
199 * @return 0 upon success
201 __inline__ int metal_uart_set_receive_watermark(struct metal_uart *uart,
203 return uart->vtable->set_rx_watermark(uart, level);
207 * @brief Get the receive watermark level of the UART controller
208 * @param uart The UART device handle
209 * @return The UART transmit watermark level
211 __inline__ size_t metal_uart_get_receive_watermark(struct metal_uart *uart) {
212 return uart->vtable->get_rx_watermark(uart);