blob: 4804d30cfca992f6d12cd7458446f96f969f17c2 [file] [log] [blame]
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07001/*
2 * Copyright (c) 2015 Wind River Systems, Inc.
3 *
David B. Kinderac74d8b2017-01-18 17:01:01 -08004 * SPDX-License-Identifier: Apache-2.0
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07005 */
6
Rodrigo Caballero8a454e62016-02-07 15:04:32 -06007/**
8 * @file
9 * @brief Public APIs for UART drivers
10 */
11
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070012#ifndef __INCuarth
13#define __INCuarth
14
Anas Nashif75482aa2015-10-26 06:18:44 -040015/**
16 * @brief UART Interface
17 * @defgroup uart_interface UART Interface
18 * @ingroup io_interfaces
19 * @{
20 */
21
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070022#ifdef __cplusplus
23extern "C" {
24#endif
25
Andre Guedes245e1402016-03-09 14:54:42 -030026#include <errno.h>
Daniel Leungef252382015-12-03 09:35:43 -080027#include <stddef.h>
28
Daniel Leung1ad2a562015-08-05 12:13:36 -070029#include <device.h>
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070030
Tomasz Bursztyka1e39d622015-08-27 11:06:15 +030031#ifdef CONFIG_PCI
Andrew Boieb0b1a8b2016-08-12 12:24:37 -070032#include <drivers/pci/pci.h>
33#include <drivers/pci/pci_mgr.h>
Tomasz Bursztyka1e39d622015-08-27 11:06:15 +030034#endif
Rodrigo Caballero8a454e62016-02-07 15:04:32 -060035/**
36 * @brief Options for @a UART initialization.
37 */
Adrian Pochiu70603a52015-07-31 06:57:00 -040038#define UART_OPTION_AFCE 0x01
Tomasz Bursztyka1e39d622015-08-27 11:06:15 +030039
Rodrigo Caballero8a454e62016-02-07 15:04:32 -060040/** Common line controls for UART.*/
Daniel Leung64cba6d2016-01-06 09:17:03 -080041#define LINE_CTRL_BAUD_RATE (1 << 0)
42#define LINE_CTRL_RTS (1 << 1)
43#define LINE_CTRL_DTR (1 << 2)
Adrian Bradianu3d8b28b2016-06-01 14:21:11 +030044#define LINE_CTRL_DCD (1 << 3)
45#define LINE_CTRL_DSR (1 << 4)
Daniel Leung64cba6d2016-01-06 09:17:03 -080046
Rodrigo Caballero8a454e62016-02-07 15:04:32 -060047/* Common communication errors for UART.*/
48
49/** @brief Overrun error */
50#define UART_ERROR_OVERRUN (1 << 0)
51
52/** @brief Parity error */
53#define UART_ERROR_PARITY (1 << 1)
54
55/** @brief Framing error */
56#define UART_ERROR_FRAMING (1 << 2)
57
58/**
59 * @brief Break interrupt error:
60 *
61 * A break interrupt was received. This happens when the serial input is
62 * held at a logic '0' state for longer than the sum of start time + data bits
63 * + parity + stop bits.
Fabien Chereau01d42182016-01-18 14:30:21 +010064 */
65#define UART_ERROR_BREAK (1 << 3)
66
Daniel Leunge643ced2016-03-03 10:14:50 -080067/**
Inaky Perez-Gonzalez05180632016-06-15 14:18:38 -070068 * @typedef uart_irq_callback_t
Daniel Leunge643ced2016-03-03 10:14:50 -080069 * @brief Define the application callback function signature for UART.
70 *
71 * @param port Device struct for the UART device.
72 */
73typedef void (*uart_irq_callback_t)(struct device *port);
74
Inaky Perez-Gonzalez05180632016-06-15 14:18:38 -070075/**
76 * @typedef uart_irq_config_func_t
77 * @brief For configuring IRQ on each individual UART device.
78 *
79 * @internal
80 */
Daniel Leunge643ced2016-03-03 10:14:50 -080081typedef void (*uart_irq_config_func_t)(struct device *port);
82
Inaky Perez-Gonzalezecc4c762016-06-16 14:52:44 -070083/**
84 * @brief UART device configuration.
85 *
86 * @param port Base port number
87 * @param base Memory mapped base address
88 * @param regs Register address
89 * @param sys_clk_freq System clock frequency in Hz
90 */
Dan Kalowsky7ed1abf2015-10-29 14:05:16 -070091struct uart_device_config {
Inaky Perez-Gonzalezda544622016-06-30 13:16:48 -070092 union {
Kumar Galacc334c72017-04-21 10:55:34 -050093 u32_t port;
94 u8_t *base;
95 u32_t regs;
Daniel Leung1ad2a562015-08-05 12:13:36 -070096 };
Daniel Leung2fd29e22015-08-10 15:02:04 -070097
Kumar Galacc334c72017-04-21 10:55:34 -050098 u32_t sys_clk_freq;
Daniel Leung846f5f42015-12-01 08:42:19 -080099
Tomasz Bursztyka1e39d622015-08-27 11:06:15 +0300100#ifdef CONFIG_PCI
101 struct pci_dev_info pci_dev;
102#endif /* CONFIG_PCI */
Daniel Leunge643ced2016-03-03 10:14:50 -0800103
104#ifdef CONFIG_UART_INTERRUPT_DRIVEN
105 uart_irq_config_func_t irq_config_func;
106#endif
Daniel Leung1ad2a562015-08-05 12:13:36 -0700107};
108
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600109/** @brief Driver API structure. */
Daniel Leung40147442015-08-13 09:51:10 -0700110struct uart_driver_api {
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600111 /** Console I/O function */
Daniel Leung40147442015-08-13 09:51:10 -0700112 int (*poll_in)(struct device *dev, unsigned char *p_char);
113 unsigned char (*poll_out)(struct device *dev, unsigned char out_char);
Fabien Chereaufdc08ce2016-01-18 14:15:57 +0100114
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600115 /** Console I/O function */
Fabien Chereau01d42182016-01-18 14:30:21 +0100116 int (*err_check)(struct device *dev);
Daniel Leung1ad2a562015-08-05 12:13:36 -0700117
118#ifdef CONFIG_UART_INTERRUPT_DRIVEN
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700119
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600120 /** Interrupt driven FIFO fill function */
Kumar Galacc334c72017-04-21 10:55:34 -0500121 int (*fifo_fill)(struct device *dev, const u8_t *tx_data, int len);
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600122
123 /** Interrupt driven FIFO read function */
Kumar Galacc334c72017-04-21 10:55:34 -0500124 int (*fifo_read)(struct device *dev, u8_t *rx_data, const int size);
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600125
126 /** Interrupt driven transfer enabling function */
Daniel Leung40147442015-08-13 09:51:10 -0700127 void (*irq_tx_enable)(struct device *dev);
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600128
129 /** Interrupt driven transfer disabling function */
Daniel Leung40147442015-08-13 09:51:10 -0700130 void (*irq_tx_disable)(struct device *dev);
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600131
132 /** Interrupt driven transfer ready function */
Daniel Leung40147442015-08-13 09:51:10 -0700133 int (*irq_tx_ready)(struct device *dev);
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600134
135 /** Interrupt driven receiver enabling function */
Daniel Leung40147442015-08-13 09:51:10 -0700136 void (*irq_rx_enable)(struct device *dev);
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600137
138 /** Interrupt driven receiver disabling function */
Daniel Leung40147442015-08-13 09:51:10 -0700139 void (*irq_rx_disable)(struct device *dev);
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600140
Paul Sokolovsky0fdc9b52017-05-11 17:57:29 +0300141 /** Interrupt driven transfer complete function */
142 int (*irq_tx_complete)(struct device *dev);
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600143
144 /** Interrupt driven receiver ready function */
Daniel Leung40147442015-08-13 09:51:10 -0700145 int (*irq_rx_ready)(struct device *dev);
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600146
147 /** Interrupt driven error enabling function */
Daniel Leung40147442015-08-13 09:51:10 -0700148 void (*irq_err_enable)(struct device *dev);
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600149
150 /** Interrupt driven error disabling function */
Daniel Leung40147442015-08-13 09:51:10 -0700151 void (*irq_err_disable)(struct device *dev);
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600152
153 /** Interrupt driven pending status function */
Daniel Leung40147442015-08-13 09:51:10 -0700154 int (*irq_is_pending)(struct device *dev);
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600155
156 /** Interrupt driven interrupt update function */
Daniel Leung40147442015-08-13 09:51:10 -0700157 int (*irq_update)(struct device *dev);
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600158
Daniel Leunge643ced2016-03-03 10:14:50 -0800159 /** Set the callback function */
160 void (*irq_callback_set)(struct device *dev, uart_irq_callback_t cb);
161
Daniel Leung40147442015-08-13 09:51:10 -0700162#endif
Daniel Leung64cba6d2016-01-06 09:17:03 -0800163
164#ifdef CONFIG_UART_LINE_CTRL
Kumar Galacc334c72017-04-21 10:55:34 -0500165 int (*line_ctrl_set)(struct device *dev, u32_t ctrl, u32_t val);
166 int (*line_ctrl_get)(struct device *dev, u32_t ctrl, u32_t *val);
Daniel Leung64cba6d2016-01-06 09:17:03 -0800167#endif
168
169#ifdef CONFIG_UART_DRV_CMD
Kumar Galacc334c72017-04-21 10:55:34 -0500170 int (*drv_cmd)(struct device *dev, u32_t cmd, u32_t p);
Daniel Leung64cba6d2016-01-06 09:17:03 -0800171#endif
172
Daniel Leung40147442015-08-13 09:51:10 -0700173};
174
Daniel Leung40147442015-08-13 09:51:10 -0700175/**
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600176 * @brief Check whether an error was detected.
Fabien Chereau01d42182016-01-18 14:30:21 +0100177 *
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600178 * @param dev UART device structure.
Fabien Chereau01d42182016-01-18 14:30:21 +0100179 *
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600180 * @retval UART_ERROR_OVERRUN if an overrun error was detected.
181 * @retval UART_ERROR_PARITY if a parity error was detected.
182 * @retval UART_ERROR_FRAMING if a framing error was detected.
183 * @retval UART_ERROR_BREAK if a break error was detected.
184 * @retval 0 Otherwise.
Fabien Chereau01d42182016-01-18 14:30:21 +0100185 */
Andrew Boieb93f59e2017-10-26 13:24:34 -0700186__syscall int uart_err_check(struct device *dev);
187
188static inline int _impl_uart_err_check(struct device *dev)
Fabien Chereau01d42182016-01-18 14:30:21 +0100189{
Marcus Shawcroft571c3a82016-10-22 10:05:14 +0100190 const struct uart_driver_api *api = dev->driver_api;
Fabien Chereau01d42182016-01-18 14:30:21 +0100191
Daniel Leung32571932016-04-05 15:08:05 -0700192 if (api->err_check) {
Fabien Chereau01d42182016-01-18 14:30:21 +0100193 return api->err_check(dev);
194 }
195 return 0;
196}
197
198
199/**
Daniel Leung40147442015-08-13 09:51:10 -0700200 * @brief Poll the device for input.
201 *
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600202 * @param dev UART device structure.
203 * @param p_char Pointer to character.
Daniel Leung40147442015-08-13 09:51:10 -0700204 *
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600205 * @retval 0 If a character arrived.
Marti Bolivarf7576222016-11-16 16:47:27 -0500206 * @retval -1 If no character was available to read (i.e., the UART
207 * input buffer was empty).
Andre Guedes245e1402016-03-09 14:54:42 -0300208 * @retval -ENOTSUP If the operation is not supported.
Daniel Leung40147442015-08-13 09:51:10 -0700209 */
Andrew Boieb93f59e2017-10-26 13:24:34 -0700210__syscall int uart_poll_in(struct device *dev, unsigned char *p_char);
211
212static inline int _impl_uart_poll_in(struct device *dev, unsigned char *p_char)
Daniel Leung40147442015-08-13 09:51:10 -0700213{
Marcus Shawcroft571c3a82016-10-22 10:05:14 +0100214 const struct uart_driver_api *api = dev->driver_api;
Daniel Leung40147442015-08-13 09:51:10 -0700215
Daniel Leung75515622015-10-08 11:10:22 -0700216 return api->poll_in(dev, p_char);
Daniel Leung40147442015-08-13 09:51:10 -0700217}
218
219/**
220 * @brief Output a character in polled mode.
221 *
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600222 * This routine checks if the transmitter is empty.
223 * When the transmitter is empty, it writes a character to the data
224 * register.
Daniel Leung40147442015-08-13 09:51:10 -0700225 *
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600226 * To send a character when hardware flow control is enabled, the handshake
227 * signal CTS must be asserted.
Daniel Leung40147442015-08-13 09:51:10 -0700228 *
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600229 * @param dev UART device structure.
230 * @param out_char Character to send.
Daniel Leung40147442015-08-13 09:51:10 -0700231 *
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600232 * @retval char Sent character.
Daniel Leung40147442015-08-13 09:51:10 -0700233 */
Andrew Boieb93f59e2017-10-26 13:24:34 -0700234__syscall unsigned char uart_poll_out(struct device *dev,
235 unsigned char out_char);
236
237static inline unsigned char _impl_uart_poll_out(struct device *dev,
238 unsigned char out_char)
Daniel Leung40147442015-08-13 09:51:10 -0700239{
Marcus Shawcroft571c3a82016-10-22 10:05:14 +0100240 const struct uart_driver_api *api = dev->driver_api;
Daniel Leung40147442015-08-13 09:51:10 -0700241
Daniel Leung75515622015-10-08 11:10:22 -0700242 return api->poll_out(dev, out_char);
Daniel Leung40147442015-08-13 09:51:10 -0700243}
244
245
246#ifdef CONFIG_UART_INTERRUPT_DRIVEN
247
248/**
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600249 * @brief Fill FIFO with data.
Daniel Leung40147442015-08-13 09:51:10 -0700250 *
Paul Sokolovsky38f78e82017-05-22 20:00:03 +0300251 * @details This function is expected to be called from UART
252 * interrupt handler (ISR), if uart_irq_tx_ready() returns true.
253 * Result of calling this function not from an ISR is undefined
254 * (hardware-dependent). Likewise, *not* calling this function
255 * from an ISR if uart_irq_tx_ready() returns true may lead to
256 * undefined behavior, e.g. infinite interrupt loops. It's
257 * mandatory to test return value of this function, as different
258 * hardware has different FIFO depth (oftentimes just 1).
259 *
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600260 * @param dev UART device structure.
261 * @param tx_data Data to transmit.
262 * @param size Number of bytes to send.
Daniel Leung40147442015-08-13 09:51:10 -0700263 *
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600264 * @return Number of bytes sent.
Daniel Leung40147442015-08-13 09:51:10 -0700265 */
Kumar Galacc334c72017-04-21 10:55:34 -0500266static inline int uart_fifo_fill(struct device *dev, const u8_t *tx_data,
Daniel Leung94718c72015-08-24 09:51:47 -0700267 int size)
Daniel Leung40147442015-08-13 09:51:10 -0700268{
Marcus Shawcroft571c3a82016-10-22 10:05:14 +0100269 const struct uart_driver_api *api = dev->driver_api;
Daniel Leung40147442015-08-13 09:51:10 -0700270
Daniel Leung32571932016-04-05 15:08:05 -0700271 if (api->fifo_fill) {
Daniel Leung40147442015-08-13 09:51:10 -0700272 return api->fifo_fill(dev, tx_data, size);
273 }
274
275 return 0;
276}
277
278/**
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600279 * @brief Read data from FIFO.
Daniel Leung40147442015-08-13 09:51:10 -0700280 *
Paul Sokolovsky38f78e82017-05-22 20:00:03 +0300281 * @details This function is expected to be called from UART
282 * interrupt handler (ISR), if uart_irq_rx_ready() returns true.
283 * Result of calling this function not from an ISR is undefined
284 * (hardware-dependent). It's unspecified whether "RX ready"
285 * condition as returned by uart_irq_rx_ready() is level- or
286 * edge- triggered. That means that once uart_irq_rx_ready() is
287 * detected, uart_fifo_read() must be called until it reads all
288 * available data in the FIFO (i.e. until it returns less data
289 * than was requested).
290 *
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600291 * @param dev UART device structure.
292 * @param rx_data Data container.
293 * @param size Container size.
Daniel Leung40147442015-08-13 09:51:10 -0700294 *
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600295 * @return Number of bytes read.
Daniel Leung40147442015-08-13 09:51:10 -0700296 */
Kumar Galacc334c72017-04-21 10:55:34 -0500297static inline int uart_fifo_read(struct device *dev, u8_t *rx_data,
Daniel Leung94718c72015-08-24 09:51:47 -0700298 const int size)
Daniel Leung40147442015-08-13 09:51:10 -0700299{
Marcus Shawcroft571c3a82016-10-22 10:05:14 +0100300 const struct uart_driver_api *api = dev->driver_api;
Daniel Leung40147442015-08-13 09:51:10 -0700301
Daniel Leung32571932016-04-05 15:08:05 -0700302 if (api->fifo_read) {
Daniel Leung40147442015-08-13 09:51:10 -0700303 return api->fifo_read(dev, rx_data, size);
304 }
305
306 return 0;
307}
308
309/**
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600310 * @brief Enable TX interrupt in IER.
Daniel Leung40147442015-08-13 09:51:10 -0700311 *
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600312 * @param dev UART device structure.
Daniel Leung40147442015-08-13 09:51:10 -0700313 *
314 * @return N/A
315 */
Andrew Boieb93f59e2017-10-26 13:24:34 -0700316__syscall void uart_irq_tx_enable(struct device *dev);
317
318static inline void _impl_uart_irq_tx_enable(struct device *dev)
Daniel Leung40147442015-08-13 09:51:10 -0700319{
Marcus Shawcroft571c3a82016-10-22 10:05:14 +0100320 const struct uart_driver_api *api = dev->driver_api;
Daniel Leung40147442015-08-13 09:51:10 -0700321
Daniel Leung32571932016-04-05 15:08:05 -0700322 if (api->irq_tx_enable) {
Daniel Leung40147442015-08-13 09:51:10 -0700323 api->irq_tx_enable(dev);
324 }
325}
326/**
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600327 * @brief Disable TX interrupt in IER.
Daniel Leung40147442015-08-13 09:51:10 -0700328 *
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600329 * @param dev UART device structure.
Daniel Leung40147442015-08-13 09:51:10 -0700330 *
331 * @return N/A
332 */
Andrew Boieb93f59e2017-10-26 13:24:34 -0700333__syscall void uart_irq_tx_disable(struct device *dev);
334
335static inline void _impl_uart_irq_tx_disable(struct device *dev)
Daniel Leung40147442015-08-13 09:51:10 -0700336{
Marcus Shawcroft571c3a82016-10-22 10:05:14 +0100337 const struct uart_driver_api *api = dev->driver_api;
Daniel Leung40147442015-08-13 09:51:10 -0700338
Daniel Leung32571932016-04-05 15:08:05 -0700339 if (api->irq_tx_disable) {
Daniel Leung40147442015-08-13 09:51:10 -0700340 api->irq_tx_disable(dev);
341 }
342}
343
344/**
Paul Sokolovsky0fdc9b52017-05-11 17:57:29 +0300345 * @brief Check if UART TX buffer can accept a new char
346 *
347 * @details Check if UART TX buffer can accept at least one character
348 * for transmission (i.e. uart_fifo_fill() will succeed and return
349 * non-zero). This function must be called in a UART interrupt
350 * handler, or its result is undefined. Before calling this function
351 * in the interrupt handler, uart_irq_update() must be called once per
352 * the handler invocation.
Daniel Leung40147442015-08-13 09:51:10 -0700353 *
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600354 * @param dev UART device structure.
Daniel Leung40147442015-08-13 09:51:10 -0700355 *
Paul Sokolovsky0fdc9b52017-05-11 17:57:29 +0300356 * @retval 1 If at least one char can be written to UART.
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600357 * @retval 0 Otherwise.
Daniel Leung40147442015-08-13 09:51:10 -0700358 */
Daniel Leung94718c72015-08-24 09:51:47 -0700359static inline int uart_irq_tx_ready(struct device *dev)
Daniel Leung40147442015-08-13 09:51:10 -0700360{
Marcus Shawcroft571c3a82016-10-22 10:05:14 +0100361 const struct uart_driver_api *api = dev->driver_api;
Daniel Leung40147442015-08-13 09:51:10 -0700362
Daniel Leung32571932016-04-05 15:08:05 -0700363 if (api->irq_tx_ready) {
Daniel Leung40147442015-08-13 09:51:10 -0700364 return api->irq_tx_ready(dev);
365 }
366
367 return 0;
368}
369
370/**
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600371 * @brief Enable RX interrupt in IER.
Daniel Leung40147442015-08-13 09:51:10 -0700372 *
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600373 * @param dev UART device structure.
Daniel Leung40147442015-08-13 09:51:10 -0700374 *
375 * @return N/A
376 */
Andrew Boieb93f59e2017-10-26 13:24:34 -0700377__syscall void uart_irq_rx_enable(struct device *dev);
378
379static inline void _impl_uart_irq_rx_enable(struct device *dev)
Daniel Leung40147442015-08-13 09:51:10 -0700380{
Marcus Shawcroft571c3a82016-10-22 10:05:14 +0100381 const struct uart_driver_api *api = dev->driver_api;
Daniel Leung40147442015-08-13 09:51:10 -0700382
Daniel Leung32571932016-04-05 15:08:05 -0700383 if (api->irq_rx_enable) {
Daniel Leung40147442015-08-13 09:51:10 -0700384 api->irq_rx_enable(dev);
385 }
386}
387
388/**
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600389 * @brief Disable RX interrupt in IER.
Daniel Leung40147442015-08-13 09:51:10 -0700390 *
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600391 * @param dev UART device structure.
Daniel Leung40147442015-08-13 09:51:10 -0700392 *
393 * @return N/A
394 */
Andrew Boieb93f59e2017-10-26 13:24:34 -0700395__syscall void uart_irq_rx_disable(struct device *dev);
396
397static inline void _impl_uart_irq_rx_disable(struct device *dev)
Daniel Leung40147442015-08-13 09:51:10 -0700398{
Marcus Shawcroft571c3a82016-10-22 10:05:14 +0100399 const struct uart_driver_api *api = dev->driver_api;
Daniel Leung40147442015-08-13 09:51:10 -0700400
Jeremie GARCIA36c19492016-06-20 10:35:51 +0200401 if (api->irq_rx_disable) {
402 api->irq_rx_disable(dev);
Daniel Leung40147442015-08-13 09:51:10 -0700403 }
404}
405
406/**
Paul Sokolovsky0fdc9b52017-05-11 17:57:29 +0300407 * @brief Check if UART TX block finished transmission
408 *
409 * @details Check if any outgoing data buffered in UART TX block was
410 * fully transmitted and TX block is idle. When this condition is
411 * true, UART device (or whole system) can be power off. Note that
412 * this function is *not* useful to check if UART TX can accept more
413 * data, use uart_irq_tx_ready() for that. This function must be called
414 * in a UART interrupt handler, or its result is undefined. Before
415 * calling this function in the interrupt handler, uart_irq_update()
416 * must be called once per the handler invocation.
Fabien Chereaufdc08ce2016-01-18 14:15:57 +0100417 *
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600418 * @param dev UART device structure.
Fabien Chereaufdc08ce2016-01-18 14:15:57 +0100419 *
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600420 * @retval 1 If nothing remains to be transmitted.
421 * @retval 0 Otherwise.
Fabien Chereaufdc08ce2016-01-18 14:15:57 +0100422 */
Paul Sokolovsky0fdc9b52017-05-11 17:57:29 +0300423static inline int uart_irq_tx_complete(struct device *dev)
Fabien Chereaufdc08ce2016-01-18 14:15:57 +0100424{
Marcus Shawcroft571c3a82016-10-22 10:05:14 +0100425 const struct uart_driver_api *api = dev->driver_api;
Fabien Chereaufdc08ce2016-01-18 14:15:57 +0100426
Paul Sokolovsky0fdc9b52017-05-11 17:57:29 +0300427 if (api->irq_tx_complete) {
428 return api->irq_tx_complete(dev);
Fabien Chereaufdc08ce2016-01-18 14:15:57 +0100429 }
430
431 return 0;
432}
433
434/**
Paul Sokolovsky0fdc9b52017-05-11 17:57:29 +0300435 * @deprecated This API is deprecated.
436 */
437static inline int __deprecated uart_irq_tx_empty(struct device *dev)
438{
439 return uart_irq_tx_complete(dev);
440}
441
442/**
Paul Sokolovsky38f78e82017-05-22 20:00:03 +0300443 * @brief Check if UART RX buffer has a received char
Paul Sokolovsky0fdc9b52017-05-11 17:57:29 +0300444 *
Paul Sokolovsky38f78e82017-05-22 20:00:03 +0300445 * @details Check if UART RX buffer has at least one pending character
Paul Sokolovsky0fdc9b52017-05-11 17:57:29 +0300446 * (i.e. uart_fifo_read() will succeed and return non-zero). This function
447 * must be called in a UART interrupt handler, or its result is undefined.
448 * Before calling this function in the interrupt handler, uart_irq_update()
Paul Sokolovsky38f78e82017-05-22 20:00:03 +0300449 * must be called once per the handler invocation. It's unspecified whether
450 * condition as returned by this function is level- or edge- triggered (i.e.
451 * if this function returns true when RX FIFO is non-empty, or when a new
452 * char was received since last call to it). See description of
453 * uart_fifo_read() for implication of this.
Daniel Leung40147442015-08-13 09:51:10 -0700454 *
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600455 * @param dev UART device structure.
Daniel Leung40147442015-08-13 09:51:10 -0700456 *
Paul Sokolovsky38f78e82017-05-22 20:00:03 +0300457 * @retval 1 If a received char is ready.
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600458 * @retval 0 Otherwise.
Daniel Leung40147442015-08-13 09:51:10 -0700459 */
Daniel Leung94718c72015-08-24 09:51:47 -0700460static inline int uart_irq_rx_ready(struct device *dev)
Daniel Leung40147442015-08-13 09:51:10 -0700461{
Marcus Shawcroft571c3a82016-10-22 10:05:14 +0100462 const struct uart_driver_api *api = dev->driver_api;
Daniel Leung40147442015-08-13 09:51:10 -0700463
Daniel Leung32571932016-04-05 15:08:05 -0700464 if (api->irq_rx_ready) {
Daniel Leung40147442015-08-13 09:51:10 -0700465 return api->irq_rx_ready(dev);
466 }
467
468 return 0;
469}
470/**
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600471 * @brief Enable error interrupt in IER.
Daniel Leung40147442015-08-13 09:51:10 -0700472 *
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600473 * @param dev UART device structure.
Daniel Leung40147442015-08-13 09:51:10 -0700474 *
475 * @return N/A
476 */
Andrew Boieb93f59e2017-10-26 13:24:34 -0700477__syscall void uart_irq_err_enable(struct device *dev);
478
479static inline void _impl_uart_irq_err_enable(struct device *dev)
Daniel Leung40147442015-08-13 09:51:10 -0700480{
Marcus Shawcroft571c3a82016-10-22 10:05:14 +0100481 const struct uart_driver_api *api = dev->driver_api;
Daniel Leung40147442015-08-13 09:51:10 -0700482
Daniel Leung32571932016-04-05 15:08:05 -0700483 if (api->irq_err_enable) {
Daniel Leung40147442015-08-13 09:51:10 -0700484 api->irq_err_enable(dev);
485 }
486}
487
488/**
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600489 * @brief Disable error interrupt in IER.
Daniel Leung40147442015-08-13 09:51:10 -0700490 *
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600491 * @param dev UART device structure.
Daniel Leung40147442015-08-13 09:51:10 -0700492 *
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600493 * @retval 1 If an IRQ is ready.
494 * @retval 0 Otherwise.
Daniel Leung40147442015-08-13 09:51:10 -0700495 */
Andrew Boieb93f59e2017-10-26 13:24:34 -0700496__syscall void uart_irq_err_disable(struct device *dev);
497
498static inline void _impl_uart_irq_err_disable(struct device *dev)
Daniel Leung40147442015-08-13 09:51:10 -0700499{
Marcus Shawcroft571c3a82016-10-22 10:05:14 +0100500 const struct uart_driver_api *api = dev->driver_api;
Daniel Leung40147442015-08-13 09:51:10 -0700501
Daniel Leung32571932016-04-05 15:08:05 -0700502 if (api->irq_err_disable) {
Daniel Leung40147442015-08-13 09:51:10 -0700503 api->irq_err_disable(dev);
504 }
505}
506
507/**
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600508 * @brief Check if any IRQs is pending.
Daniel Leung40147442015-08-13 09:51:10 -0700509 *
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600510 * @param dev UART device structure.
Daniel Leung40147442015-08-13 09:51:10 -0700511 *
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600512 * @retval 1 If an IRQ is pending.
513 * @retval 0 Otherwise.
Daniel Leung40147442015-08-13 09:51:10 -0700514 */
Andrew Boieb93f59e2017-10-26 13:24:34 -0700515__syscall int uart_irq_is_pending(struct device *dev);
Daniel Leung40147442015-08-13 09:51:10 -0700516
Andrew Boieb93f59e2017-10-26 13:24:34 -0700517static inline int _impl_uart_irq_is_pending(struct device *dev)
Daniel Leung40147442015-08-13 09:51:10 -0700518{
Marcus Shawcroft571c3a82016-10-22 10:05:14 +0100519 const struct uart_driver_api *api = dev->driver_api;
Daniel Leung40147442015-08-13 09:51:10 -0700520
Daniel Leung32571932016-04-05 15:08:05 -0700521 if (api->irq_is_pending) {
Daniel Leung40147442015-08-13 09:51:10 -0700522 return api->irq_is_pending(dev);
523 }
524
525 return 0;
526}
527
528/**
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600529 * @brief Update cached contents of IIR.
Daniel Leung40147442015-08-13 09:51:10 -0700530 *
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600531 * @param dev UART device structure.
Daniel Leung40147442015-08-13 09:51:10 -0700532 *
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600533 * @retval 1 Always.
Daniel Leung40147442015-08-13 09:51:10 -0700534 */
Andrew Boieb93f59e2017-10-26 13:24:34 -0700535__syscall int uart_irq_update(struct device *dev);
536
537static inline int _impl_uart_irq_update(struct device *dev)
Daniel Leung40147442015-08-13 09:51:10 -0700538{
Marcus Shawcroft571c3a82016-10-22 10:05:14 +0100539 const struct uart_driver_api *api = dev->driver_api;
Daniel Leung40147442015-08-13 09:51:10 -0700540
Daniel Leung32571932016-04-05 15:08:05 -0700541 if (api->irq_update) {
Daniel Leung40147442015-08-13 09:51:10 -0700542 return api->irq_update(dev);
543 }
544
545 return 0;
546}
547
548/**
Daniel Leunge643ced2016-03-03 10:14:50 -0800549 * @brief Set the IRQ callback function pointer.
550 *
551 * This sets up the callback for IRQ. When an IRQ is triggered,
552 * the specified function will be called.
553 *
554 * @param dev UART device structure.
555 * @param cb Pointer to the callback function.
556 *
557 * @return N/A
558 */
559static inline void uart_irq_callback_set(struct device *dev,
560 uart_irq_callback_t cb)
561{
Marcus Shawcroft571c3a82016-10-22 10:05:14 +0100562 const struct uart_driver_api *api = dev->driver_api;
Daniel Leunge643ced2016-03-03 10:14:50 -0800563
564 if ((api != NULL) && (api->irq_callback_set != NULL)) {
565 api->irq_callback_set(dev, cb);
566 }
567}
568
Daniel Leung1ad2a562015-08-05 12:13:36 -0700569#endif
570
Daniel Leung64cba6d2016-01-06 09:17:03 -0800571#ifdef CONFIG_UART_LINE_CTRL
572
573/**
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600574 * @brief Manipulate line control for UART.
Daniel Leung64cba6d2016-01-06 09:17:03 -0800575 *
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600576 * @param dev UART device structure.
577 * @param ctrl The line control to manipulate.
578 * @param val Value to set to the line control.
Daniel Leung64cba6d2016-01-06 09:17:03 -0800579 *
Andre Guedes024cfe72016-03-09 14:01:20 -0300580 * @retval 0 If successful.
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600581 * @retval failed Otherwise.
Daniel Leung64cba6d2016-01-06 09:17:03 -0800582 */
Andrew Boieb93f59e2017-10-26 13:24:34 -0700583__syscall int uart_line_ctrl_set(struct device *dev,
584 u32_t ctrl, u32_t val);
585
586static inline int _impl_uart_line_ctrl_set(struct device *dev,
587 u32_t ctrl, u32_t val)
Daniel Leung64cba6d2016-01-06 09:17:03 -0800588{
Marcus Shawcroft571c3a82016-10-22 10:05:14 +0100589 const struct uart_driver_api *api = dev->driver_api;
Daniel Leung64cba6d2016-01-06 09:17:03 -0800590
Daniel Leung32571932016-04-05 15:08:05 -0700591 if (api->line_ctrl_set) {
Daniel Leung64cba6d2016-01-06 09:17:03 -0800592 return api->line_ctrl_set(dev, ctrl, val);
593 }
594
Andre Guedes245e1402016-03-09 14:54:42 -0300595 return -ENOTSUP;
Daniel Leung64cba6d2016-01-06 09:17:03 -0800596}
597
Adrian Bradianu3d8b28b2016-06-01 14:21:11 +0300598/**
599 * @brief Retrieve line control for UART.
600 *
601 * @param dev UART device structure.
602 * @param ctrl The line control to manipulate.
603 * @param val Value to get for the line control.
604 *
605 * @retval 0 If successful.
606 * @retval failed Otherwise.
607 */
Andrew Boieb93f59e2017-10-26 13:24:34 -0700608__syscall int uart_line_ctrl_get(struct device *dev, u32_t ctrl, u32_t *val);
609
610static inline int _impl_uart_line_ctrl_get(struct device *dev,
611 u32_t ctrl, u32_t *val)
Adrian Bradianu3d8b28b2016-06-01 14:21:11 +0300612{
Marcus Shawcroft571c3a82016-10-22 10:05:14 +0100613 const struct uart_driver_api *api = dev->driver_api;
Adrian Bradianu3d8b28b2016-06-01 14:21:11 +0300614
615 if (api && api->line_ctrl_get) {
616 return api->line_ctrl_get(dev, ctrl, val);
617 }
618
619 return -ENOTSUP;
620}
621
Daniel Leung64cba6d2016-01-06 09:17:03 -0800622#endif /* CONFIG_UART_LINE_CTRL */
623
624#ifdef CONFIG_UART_DRV_CMD
625
626/**
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600627 * @brief Send extra command to driver.
Daniel Leung64cba6d2016-01-06 09:17:03 -0800628 *
629 * Implementation and accepted commands are driver specific.
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600630 * Refer to the drivers for more information.
Daniel Leung64cba6d2016-01-06 09:17:03 -0800631 *
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600632 * @param dev UART device structure.
633 * @param cmd Command to driver.
634 * @param p Parameter to the command.
Daniel Leung64cba6d2016-01-06 09:17:03 -0800635 *
Andre Guedes024cfe72016-03-09 14:01:20 -0300636 * @retval 0 If successful.
Rodrigo Caballero8a454e62016-02-07 15:04:32 -0600637 * @retval failed Otherwise.
Daniel Leung64cba6d2016-01-06 09:17:03 -0800638 */
Andrew Boieb93f59e2017-10-26 13:24:34 -0700639__syscall int uart_drv_cmd(struct device *dev, u32_t cmd, u32_t p);
640
641static inline int _impl_uart_drv_cmd(struct device *dev, u32_t cmd, u32_t p)
Daniel Leung64cba6d2016-01-06 09:17:03 -0800642{
Marcus Shawcroft571c3a82016-10-22 10:05:14 +0100643 const struct uart_driver_api *api = dev->driver_api;
Daniel Leung64cba6d2016-01-06 09:17:03 -0800644
Daniel Leung32571932016-04-05 15:08:05 -0700645 if (api->drv_cmd) {
Daniel Leung64cba6d2016-01-06 09:17:03 -0800646 return api->drv_cmd(dev, cmd, p);
647 }
648
Andre Guedes245e1402016-03-09 14:54:42 -0300649 return -ENOTSUP;
Daniel Leung64cba6d2016-01-06 09:17:03 -0800650}
651
652#endif /* CONFIG_UART_DRV_CMD */
653
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700654#ifdef __cplusplus
655}
656#endif
657
Anas Nashif75482aa2015-10-26 06:18:44 -0400658/**
659 * @}
660 */
661
Andrew Boieb93f59e2017-10-26 13:24:34 -0700662#include <syscalls/uart.h>
663
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700664#endif /* __INCuarth */