1 /*
2  * Copyright (c) 2016-2019 Arm Limited. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /**
18  * \file uart_cmsdk_drv.h
19  * \brief Generic driver for ARM UART.
20  */
21 
22 #ifndef __UART_CMSDK_DRV_H__
23 #define __UART_CMSDK_DRV_H__
24 
25 #include <stdint.h>
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 /* ARM UART device configuration structure */
32 struct uart_cmsdk_dev_cfg_t {
33     const uint32_t base;              /*!< UART base address */
34     const uint32_t default_baudrate;  /*!< Default baudrate */
35 };
36 
37 /* ARM UART device data structure */
38 struct uart_cmsdk_dev_data_t {
39     uint32_t state;       /*!< Indicates if the uart driver
40                            *   is initialized and enabled
41                            */
42     uint32_t system_clk;  /*!< System clock */
43     uint32_t baudrate;    /*!< Baudrate */
44 };
45 
46 /* ARM UART device structure */
47 struct uart_cmsdk_dev_t {
48     const struct uart_cmsdk_dev_cfg_t* const cfg;  /*!< UART configuration */
49     struct uart_cmsdk_dev_data_t* const data;      /*!< UART data */
50 };
51 
52 /* ARM UART enumeration types */
53 enum uart_cmsdk_error_t {
54     UART_CMSDK_ERR_NONE = 0,      /*!< No error */
55     UART_CMSDK_ERR_INVALID_ARG,   /*!< Error invalid input argument */
56     UART_CMSDK_ERR_INVALID_BAUD,  /*!< Invalid baudrate */
57     UART_CMSDK_ERR_NOT_INIT,      /*!< Error UART not initialized */
58     UART_CMSDK_ERR_NOT_READY,     /*!< Error UART not ready */
59 };
60 
61 enum uart_cmsdk_irq_t {
62     UART_CMSDK_IRQ_RX,       /*!< RX interrupt source */
63     UART_CMSDK_IRQ_TX,       /*!< TX interrupt source */
64     UART_CMSDK_IRQ_COMBINED  /*!< RX-TX combined interrupt source */
65 };
66 
67 /**
68  * \brief Initializes UART. It uses the default baudrate to configure
69  * the peripheral at this point.
70  *
71  * \param[in] dev         UART device struct \ref uart_cmsdk_dev_t
72  * \param[in] system_clk  System clock used by the device.
73  *
74  * \return Returns error code as specified in \ref uart_cmsdk_error_t
75  *
76  * \note This function doesn't check if dev is NULL.
77  */
78 enum uart_cmsdk_error_t uart_cmsdk_init(struct uart_cmsdk_dev_t* dev,
79                                     uint32_t system_clk);
80 
81 /**
82  * \brief Sets the UART baudrate.
83  *
84  * \param[in] dev       UART device struct \ref uart_cmsdk_dev_t
85  * \param[in] baudrate  New baudrate.
86  *
87  * \return Returns error code as specified in \ref uart_cmsdk_error_t
88  *
89  * \note This function doesn't check if dev is NULL.
90  */
91 enum uart_cmsdk_error_t uart_cmsdk_set_baudrate(struct uart_cmsdk_dev_t* dev,
92                                             uint32_t baudrate);
93 
94 /**
95  * \brief Gets the UART baudrate.
96  *
97  * \param[in] dev  UART device struct \ref uart_cmsdk_dev_t
98  *
99  * \return Returns the UART baudrate.
100  *
101  * \note This function doesn't check if dev is NULL.
102  */
103 uint32_t uart_cmsdk_get_baudrate(struct uart_cmsdk_dev_t* dev);
104 
105 /**
106  * \brief Sets system clock.
107  *
108  * \param[in] dev         UART device struct \ref uart_cmsdk_dev_t
109  * \param[in] system_clk  System clock used by the device.
110  *
111  * \return Returns error code as specified in \ref uart_cmsdk_error_t
112  *
113  * \note This function doesn't check if dev is NULL.
114  */
115 enum uart_cmsdk_error_t uart_cmsdk_set_clock(struct uart_cmsdk_dev_t* dev,
116                                          uint32_t system_clk);
117 /**
118  * \brief Reads one byte from UART dev.
119  *
120  * \param[in] dev   UART device struct \ref uart_cmsdk_dev_t
121  * \param[in] byte  Pointer to byte.
122  *
123  * \return Returns error code as specified in \ref uart_cmsdk_error_t
124  *
125  * \note For better performance, this function doesn't check if dev and byte
126  * pointer are NULL, and if the driver is initialized.
127  */
128 enum uart_cmsdk_error_t uart_cmsdk_read(struct uart_cmsdk_dev_t* dev,
129                                                                 uint8_t* byte);
130 
131 /**
132  * \brief Writes a byte to UART dev.
133  *
134  * \param[in] dev   UART device struct \ref uart_cmsdk_dev_t
135  * \param[in] byte  Byte to write.
136  *
137  * \return Returns error code as specified in \ref uart_cmsdk_error_t
138  *
139  * \note For better performance, this function doesn't check if dev is NULL and
140  * if the driver is initialized to have better performance.
141  */
142 enum uart_cmsdk_error_t uart_cmsdk_write(struct uart_cmsdk_dev_t* dev,
143                                                                  uint8_t byte);
144 
145 /**
146  * \brief Enables TX interrupt.
147  *
148  * \param[in] dev  UART device struct \ref uart_cmsdk_dev_t
149  *
150  * \return Returns error code as specified in \ref uart_cmsdk_error_t
151  *
152  * \note This function doesn't check if dev is NULL.
153  */
154 enum uart_cmsdk_error_t uart_cmsdk_irq_tx_enable(struct uart_cmsdk_dev_t* dev);
155 
156 /**
157  * \brief Disables TX interrupt.
158  *
159  * \param[in] dev  UART device struct \ref uart_cmsdk_dev_t
160  *
161  * \note This function doesn't check if dev is NULL.
162  */
163 void uart_cmsdk_irq_tx_disable(struct uart_cmsdk_dev_t* dev);
164 
165 /**
166  * \brief  Verifies if Tx is ready to send more data.
167  *
168  * \param[in] dev  UART device struct \ref uart_cmsdk_dev_t
169  *
170  * \return  1 if TX is ready, 0 otherwise.
171  *
172  * \note This function doesn't check if dev is NULL.
173  */
174 uint32_t uart_cmsdk_tx_ready(struct uart_cmsdk_dev_t* dev);
175 
176 /**
177  * \brief Enables RX interrupt.
178  *
179  * \param[in] dev  UART device struct \ref uart_cmsdk_dev_t
180  *
181  * \return Returns error code as specified in \ref uart_cmsdk_error_t
182  *
183  * \note This function doesn't check if dev is NULL.
184  */
185 enum uart_cmsdk_error_t uart_cmsdk_irq_rx_enable(struct uart_cmsdk_dev_t* dev);
186 
187 /**
188  * \brief Disables RX interrupt
189  *
190  * \param[in] dev  UART device struct \ref uart_cmsdk_dev_t
191  *
192  * \note This function doesn't check if dev is NULL.
193  */
194 void uart_cmsdk_irq_rx_disable(struct uart_cmsdk_dev_t* dev);
195 
196 /**
197  * \brief Verifies if Rx has data.
198  *
199  * \param[in] dev  UART device struct \ref uart_cmsdk_dev_t
200  *
201  * \return 1 if RX has data, 0 otherwise.
202  *
203  * \note This function doesn't check if dev is NULL.
204  */
205 uint32_t uart_cmsdk_rx_ready(struct uart_cmsdk_dev_t* dev);
206 
207 /**
208  * \brief Clears UART interrupt.
209  *
210  * \param[in] dev  UART device struct \ref uart_cmsdk_dev_t
211  * \param[in] irq  IRQ source to clean \ref uart_cmsdk_irq_t
212  *
213  * \note This function doesn't check if dev is NULL.
214  */
215 void uart_cmsdk_clear_interrupt(struct uart_cmsdk_dev_t* dev,
216                               enum uart_cmsdk_irq_t irq);
217 
218 #ifdef __cplusplus
219 }
220 #endif
221 #endif /* __UART_CMSDK_DRV_H__ */
222