1 /*
2  * Copyright (c) 2016-2022 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 CMSDK UART.
20  *      Features of the driver:
21  *          1. Initialize UART
22  *          2. Set/Get UART baudrate
23  *          3. Set system clock
24  *          4. Read/Write UART data
25  *          5. Enable/Disable TX interrupt
26  *          6. Enable/Disable RX interrupt
27  *          7. Clear interrupts
28  *          8. Verifies if RX has data
29  *          9. Verifies if TX is ready to send more data
30  */
31 
32 #ifndef __UART_CMSDK_DRV_H__
33 #define __UART_CMSDK_DRV_H__
34 
35 #include <stdint.h>
36 
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 
41 /* ARM UART device configuration structure */
42 struct uart_cmsdk_dev_cfg_t {
43     const uint32_t base;              /*!< UART base address */
44     const uint32_t default_baudrate;  /*!< Default baudrate */
45 };
46 
47 /* ARM UART device data structure */
48 struct uart_cmsdk_dev_data_t {
49     uint32_t state;       /*!< Indicates if the uart driver
50                            *   is initialized and enabled
51                            */
52     uint32_t system_clk;  /*!< System clock */
53     uint32_t baudrate;    /*!< Baudrate */
54 };
55 
56 /* ARM UART device structure */
57 struct uart_cmsdk_dev_t {
58     const struct uart_cmsdk_dev_cfg_t* const cfg;  /*!< UART configuration */
59     struct uart_cmsdk_dev_data_t* const data;      /*!< UART data */
60 };
61 
62 /* ARM UART enumeration types */
63 enum uart_cmsdk_error_t {
64     UART_CMSDK_ERR_NONE = 0,      /*!< No error */
65     UART_CMSDK_ERR_INVALID_ARG,   /*!< Error invalid input argument */
66     UART_CMSDK_ERR_INVALID_BAUD,  /*!< Invalid baudrate */
67     UART_CMSDK_ERR_NOT_INIT,      /*!< Error UART not initialized */
68     UART_CMSDK_ERR_NOT_READY,     /*!< Error UART not ready */
69 };
70 
71 enum uart_cmsdk_irq_t {
72     UART_CMSDK_IRQ_RX,       /*!< RX interrupt source */
73     UART_CMSDK_IRQ_TX,       /*!< TX interrupt source */
74     UART_CMSDK_IRQ_COMBINED  /*!< RX-TX combined interrupt source */
75 };
76 
77 /**
78  * \brief Initializes UART. It uses the default baudrate to configure
79  * the peripheral at this point.
80  *
81  * \param[in] dev         UART device struct \ref uart_cmsdk_dev_t
82  * \param[in] system_clk  System clock used by the device.
83  *
84  * \return Returns error code as specified in \ref uart_cmsdk_error_t
85  *
86  * \note This function doesn't check if dev is NULL.
87  */
88 enum uart_cmsdk_error_t uart_cmsdk_init(struct uart_cmsdk_dev_t* dev,
89                                     uint32_t system_clk);
90 
91 /**
92  * \brief Sets the UART baudrate.
93  *
94  * \param[in] dev       UART device struct \ref uart_cmsdk_dev_t
95  * \param[in] baudrate  New baudrate.
96  *
97  * \return Returns error code as specified in \ref uart_cmsdk_error_t
98  *
99  * \note This function doesn't check if dev is NULL.
100  */
101 enum uart_cmsdk_error_t uart_cmsdk_set_baudrate(struct uart_cmsdk_dev_t* dev,
102                                             uint32_t baudrate);
103 
104 /**
105  * \brief Gets the UART baudrate.
106  *
107  * \param[in] dev  UART device struct \ref uart_cmsdk_dev_t
108  *
109  * \return Returns the UART baudrate.
110  *
111  * \note This function doesn't check if dev is NULL.
112  */
113 uint32_t uart_cmsdk_get_baudrate(struct uart_cmsdk_dev_t* dev);
114 
115 /**
116  * \brief Sets system clock.
117  *
118  * \param[in] dev         UART device struct \ref uart_cmsdk_dev_t
119  * \param[in] system_clk  System clock used by the device.
120  *
121  * \return Returns error code as specified in \ref uart_cmsdk_error_t
122  *
123  * \note This function doesn't check if dev is NULL.
124  */
125 enum uart_cmsdk_error_t uart_cmsdk_set_clock(struct uart_cmsdk_dev_t* dev,
126                                          uint32_t system_clk);
127 /**
128  * \brief Reads one byte from UART dev.
129  *
130  * \param[in] dev   UART device struct \ref uart_cmsdk_dev_t
131  * \param[in] byte  Pointer to byte.
132  *
133  * \return Returns error code as specified in \ref uart_cmsdk_error_t
134  *
135  * \note For better performance, this function doesn't check if dev and byte
136  * pointer are NULL, and if the driver is initialized.
137  */
138 enum uart_cmsdk_error_t uart_cmsdk_read(struct uart_cmsdk_dev_t* dev,
139                                                                 uint8_t* byte);
140 
141 /**
142  * \brief Writes a byte to UART dev.
143  *
144  * \param[in] dev   UART device struct \ref uart_cmsdk_dev_t
145  * \param[in] byte  Byte to write.
146  *
147  * \return Returns error code as specified in \ref uart_cmsdk_error_t
148  *
149  * \note For better performance, this function doesn't check if dev is NULL and
150  * if the driver is initialized to have better performance.
151  */
152 enum uart_cmsdk_error_t uart_cmsdk_write(struct uart_cmsdk_dev_t* dev,
153                                                                  uint8_t byte);
154 
155 /**
156  * \brief Enables TX interrupt.
157  *
158  * \param[in] dev  UART device struct \ref uart_cmsdk_dev_t
159  *
160  * \return Returns error code as specified in \ref uart_cmsdk_error_t
161  *
162  * \note This function doesn't check if dev is NULL.
163  */
164 enum uart_cmsdk_error_t uart_cmsdk_irq_tx_enable(struct uart_cmsdk_dev_t* dev);
165 
166 /**
167  * \brief Disables TX interrupt.
168  *
169  * \param[in] dev  UART device struct \ref uart_cmsdk_dev_t
170  *
171  * \note This function doesn't check if dev is NULL.
172  */
173 void uart_cmsdk_irq_tx_disable(struct uart_cmsdk_dev_t* dev);
174 
175 /**
176  * \brief  Verifies if Tx is ready to send more data.
177  *
178  * \param[in] dev  UART device struct \ref uart_cmsdk_dev_t
179  *
180  * \return  1 if TX is ready, 0 otherwise.
181  *
182  * \note This function doesn't check if dev is NULL.
183  */
184 uint32_t uart_cmsdk_tx_ready(struct uart_cmsdk_dev_t* dev);
185 
186 /**
187  * \brief Enables RX interrupt.
188  *
189  * \param[in] dev  UART device struct \ref uart_cmsdk_dev_t
190  *
191  * \return Returns error code as specified in \ref uart_cmsdk_error_t
192  *
193  * \note This function doesn't check if dev is NULL.
194  */
195 enum uart_cmsdk_error_t uart_cmsdk_irq_rx_enable(struct uart_cmsdk_dev_t* dev);
196 
197 /**
198  * \brief Disables RX interrupt
199  *
200  * \param[in] dev  UART device struct \ref uart_cmsdk_dev_t
201  *
202  * \note This function doesn't check if dev is NULL.
203  */
204 void uart_cmsdk_irq_rx_disable(struct uart_cmsdk_dev_t* dev);
205 
206 /**
207  * \brief Verifies if Rx has data.
208  *
209  * \param[in] dev  UART device struct \ref uart_cmsdk_dev_t
210  *
211  * \return 1 if RX has data, 0 otherwise.
212  *
213  * \note This function doesn't check if dev is NULL.
214  */
215 uint32_t uart_cmsdk_rx_ready(struct uart_cmsdk_dev_t* dev);
216 
217 /**
218  * \brief Clears UART interrupt.
219  *
220  * \param[in] dev  UART device struct \ref uart_cmsdk_dev_t
221  * \param[in] irq  IRQ source to clean \ref uart_cmsdk_irq_t
222  *
223  * \note This function doesn't check if dev is NULL.
224  */
225 void uart_cmsdk_clear_interrupt(struct uart_cmsdk_dev_t* dev,
226                               enum uart_cmsdk_irq_t irq);
227 
228 /**
229  * \brief Enables TX
230  *
231  * \param[in] dev  UART device struct \ref uart_cmsdk_dev_t
232  *
233  * \return Returns error code as specified in \ref uart_cmsdk_error_t
234  *
235  * \note This function doesn't check if dev is NULL.
236  */
237 enum uart_cmsdk_error_t uart_cmsdk_tx_enable(struct uart_cmsdk_dev_t* dev);
238 
239 /**
240  * \brief Disables TX
241  *
242  * \param[in] dev  UART device struct \ref uart_cmsdk_dev_t
243  *
244  * \note This function doesn't check if dev is NULL.
245  */
246 void uart_cmsdk_tx_disable(struct uart_cmsdk_dev_t* dev);
247 
248 /**
249  * \brief Enables RX
250  *
251  * \param[in] dev  UART device struct \ref uart_cmsdk_dev_t
252  *
253  * \return Returns error code as specified in \ref uart_cmsdk_error_t
254  *
255  * \note This function doesn't check if dev is NULL.
256  */
257 enum uart_cmsdk_error_t uart_cmsdk_rx_enable(struct uart_cmsdk_dev_t* dev);
258 
259 /**
260  * \brief Disables RX
261  *
262  * \param[in] dev  UART device struct \ref uart_cmsdk_dev_t
263  *
264  * \note This function doesn't check if dev is NULL.
265  */
266 void uart_cmsdk_rx_disable(struct uart_cmsdk_dev_t* dev);
267 
268 #ifdef __cplusplus
269 }
270 #endif
271 #endif /* __UART_CMSDK_DRV_H__ */
272