1 /*
2 * Copyright (c) 2023 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 #ifndef __DRIVER_USART_CMSDK_H__
18 #define __DRIVER_USART_CMSDK_H__
19
20 #include "Driver_USART_Common.h"
21 #include "uart_cmsdk_drv.h"
22
23 extern uint32_t PeripheralClock;
24
25 /* Driver Capabilities */
26 static const ARM_USART_CAPABILITIES DriverCapabilities = {
27 1, /* supports UART (Asynchronous) mode */
28 0, /* supports Synchronous Master mode */
29 0, /* supports Synchronous Slave mode */
30 0, /* supports UART Single-wire mode */
31 0, /* supports UART IrDA mode */
32 0, /* supports UART Smart Card mode */
33 0, /* Smart Card Clock generator available */
34 0, /* RTS Flow Control available */
35 0, /* CTS Flow Control available */
36 0, /* Transmit completed event: \ref ARM_USARTx_EVENT_TX_COMPLETE */
37 0, /* Signal receive character timeout event: \ref ARM_USARTx_EVENT_RX_TIMEOUT */
38 0, /* RTS Line: 0=not available, 1=available */
39 0, /* CTS Line: 0=not available, 1=available */
40 0, /* DTR Line: 0=not available, 1=available */
41 0, /* DSR Line: 0=not available, 1=available */
42 0, /* DCD Line: 0=not available, 1=available */
43 0, /* RI Line: 0=not available, 1=available */
44 0, /* Signal CTS change event: \ref ARM_USARTx_EVENT_CTS */
45 0, /* Signal DSR change event: \ref ARM_USARTx_EVENT_DSR */
46 0, /* Signal DCD change event: \ref ARM_USARTx_EVENT_DCD */
47 0, /* Signal RI change event: \ref ARM_USARTx_EVENT_RI */
48 0 /* Reserved */
49 };
50
51 typedef struct {
52 struct uart_cmsdk_dev_t *dev; /* UART device structure */
53 uint32_t tx_nbr_bytes; /* Number of bytes transfered */
54 uint32_t rx_nbr_bytes; /* Number of bytes recevied */
55 ARM_USART_SignalEvent_t cb_event; /* Callback function for events */
56 } UARTx_Resources;
57
ARM_USART_GetCapabilities(void)58 static inline ARM_USART_CAPABILITIES ARM_USART_GetCapabilities(void)
59 {
60 return DriverCapabilities;
61 }
62
ARM_USARTx_Initialize(UARTx_Resources * uart_dev)63 static inline int32_t ARM_USARTx_Initialize(UARTx_Resources *uart_dev)
64 {
65 /* Initializes generic UART driver */
66 uart_cmsdk_init(uart_dev->dev, PeripheralClock);
67
68 return ARM_DRIVER_OK;
69 }
70
ARM_USARTx_PowerControl(UARTx_Resources * uart_dev,ARM_POWER_STATE state)71 static inline int32_t ARM_USARTx_PowerControl(UARTx_Resources *uart_dev,
72 ARM_POWER_STATE state)
73 {
74 ARG_UNUSED(uart_dev);
75
76 switch (state) {
77 case ARM_POWER_OFF:
78 case ARM_POWER_LOW:
79 return ARM_DRIVER_ERROR_UNSUPPORTED;
80 case ARM_POWER_FULL:
81 /* Nothing to be done */
82 return ARM_DRIVER_OK;
83 /* default: The default is not defined intentionally to force the
84 * compiler to check that all the enumeration values are
85 * covered in the switch.*/
86 }
87 }
88
ARM_USARTx_Send(UARTx_Resources * uart_dev,const void * data,uint32_t num)89 static inline int32_t ARM_USARTx_Send(UARTx_Resources *uart_dev,
90 const void *data,
91 uint32_t num)
92 {
93 const uint8_t *p_data = (const uint8_t *)data;
94
95 if ((data == NULL) || (num == 0U)) {
96 /* Invalid parameters */
97 return ARM_DRIVER_ERROR_PARAMETER;
98 }
99
100 /* Resets previous TX counter */
101 uart_dev->tx_nbr_bytes = 0;
102
103 while (uart_dev->tx_nbr_bytes != num) {
104 /* Waits until UART is ready to transmit */
105 while (!uart_cmsdk_tx_ready(uart_dev->dev)) {
106 }
107
108 /* As UART is ready to transmit at this point, the write function can
109 * not return any transmit error */
110 (void)uart_cmsdk_write(uart_dev->dev, *p_data);
111
112 uart_dev->tx_nbr_bytes++;
113 p_data++;
114 }
115
116 if (uart_dev->cb_event != NULL) {
117 uart_dev->cb_event(ARM_USART_EVENT_SEND_COMPLETE);
118 }
119
120 /* Waits until character is transmited */
121 while (!uart_cmsdk_tx_ready(uart_dev->dev)) {
122 }
123
124 return ARM_DRIVER_OK;
125 }
126
ARM_USARTx_Receive(UARTx_Resources * uart_dev,void * data,uint32_t num)127 static inline int32_t ARM_USARTx_Receive(UARTx_Resources *uart_dev,
128 void *data, uint32_t num)
129 {
130 uint8_t *p_data = (uint8_t *)data;
131
132 if ((data == NULL) || (num == 0U)) {
133 // Invalid parameters
134 return ARM_DRIVER_ERROR_PARAMETER;
135 }
136
137 /* Resets previous RX counter */
138 uart_dev->rx_nbr_bytes = 0;
139
140 while (uart_dev->rx_nbr_bytes != num) {
141 /* Waits until one character is received */
142 while (!uart_cmsdk_rx_ready(uart_dev->dev)){
143 }
144
145 /* As UART has received one byte, the read can not
146 * return any receive error at this point */
147 (void)uart_cmsdk_read(uart_dev->dev, p_data);
148
149 uart_dev->rx_nbr_bytes++;
150 p_data++;
151 }
152
153 if (uart_dev->cb_event != NULL) {
154 uart_dev->cb_event(ARM_USART_EVENT_RECEIVE_COMPLETE);
155 }
156
157 return ARM_DRIVER_OK;
158 }
159
ARM_USARTx_GetTxCount(UARTx_Resources * uart_dev)160 static inline uint32_t ARM_USARTx_GetTxCount(UARTx_Resources *uart_dev)
161 {
162 return uart_dev->tx_nbr_bytes;
163 }
164
ARM_USARTx_GetRxCount(UARTx_Resources * uart_dev)165 static inline uint32_t ARM_USARTx_GetRxCount(UARTx_Resources *uart_dev)
166 {
167 return uart_dev->rx_nbr_bytes;
168 }
169
ARM_USARTx_Control(UARTx_Resources * uart_dev,uint32_t control,uint32_t arg)170 static inline int32_t ARM_USARTx_Control(UARTx_Resources *uart_dev,
171 uint32_t control,
172 uint32_t arg)
173 {
174 switch (control & ARM_USART_CONTROL_Msk) {
175 #ifdef UART_TX_RX_CONTROL_ENABLED
176 case ARM_USART_CONTROL_TX:
177 if (arg == 0) {
178 uart_cmsdk_tx_disable(uart_dev->dev);
179 } else if (arg == 1) {
180 if (uart_cmsdk_tx_enable(uart_dev->dev)
181 != UART_CMSDK_ERR_NONE) {
182 return ARM_DRIVER_ERROR;
183 }
184 } else {
185 return ARM_DRIVER_ERROR_PARAMETER;
186 }
187 break;
188 case ARM_USART_CONTROL_RX:
189 if (arg == 0) {
190 uart_cmsdk_rx_disable(uart_dev->dev);
191 } else if (arg == 1) {
192 if (uart_cmsdk_rx_enable(uart_dev->dev)
193 != UART_CMSDK_ERR_NONE) {
194 return ARM_DRIVER_ERROR;
195 }
196 } else {
197 return ARM_DRIVER_ERROR_PARAMETER;
198 }
199 break;
200 #endif
201 case ARM_USART_MODE_ASYNCHRONOUS:
202 if (uart_cmsdk_set_baudrate(uart_dev->dev, arg) != UART_CMSDK_ERR_NONE) {
203 return ARM_USART_ERROR_BAUDRATE;
204 }
205 break;
206 /* Unsupported command */
207 default:
208 return ARM_DRIVER_ERROR_UNSUPPORTED;
209 }
210
211 /* UART Data bits */
212 if (control & ARM_USART_DATA_BITS_Msk) {
213 /* Data bit is not configurable */
214 return ARM_DRIVER_ERROR_UNSUPPORTED;
215 }
216
217 /* UART Parity */
218 if (control & ARM_USART_PARITY_Msk) {
219 /* Parity is not configurable */
220 return ARM_USART_ERROR_PARITY;
221 }
222
223 /* USART Stop bits */
224 if (control & ARM_USART_STOP_BITS_Msk) {
225 /* Stop bit is not configurable */
226 return ARM_USART_ERROR_STOP_BITS;
227 }
228
229 return ARM_DRIVER_OK;
230 }
231
232 /*
233 * \brief Macro for USART CMSDK Driver
234 *
235 * \param[in] USART_DEV Native driver device
236 * \ref uart_cmsdk_dev_t
237 * \param[out] USART_DRIVER_NAME Resulting Driver name
238 */
239 #define ARM_DRIVER_USART_CMSDK(USART_DEV, USART_DRIVER_NAME) \
240 static UARTx_Resources USART_DRIVER_NAME##_DEV = { \
241 .dev = &USART_DEV, \
242 .tx_nbr_bytes = 0, \
243 .rx_nbr_bytes = 0, \
244 .cb_event = NULL, \
245 }; \
246 \
247 static int32_t USART_DRIVER_NAME##_Initialize( \
248 ARM_USART_SignalEvent_t cb_event) \
249 { \
250 USART_DRIVER_NAME##_DEV.cb_event = cb_event; \
251 \
252 return ARM_USARTx_Initialize(&USART_DRIVER_NAME##_DEV); \
253 } \
254 \
255 static int32_t USART_DRIVER_NAME##_Uninitialize(void) \
256 { \
257 /* Nothing to be done */ \
258 return ARM_DRIVER_OK; \
259 } \
260 \
261 static int32_t USART_DRIVER_NAME##_PowerControl(ARM_POWER_STATE state) \
262 { \
263 return ARM_USARTx_PowerControl(&USART_DRIVER_NAME##_DEV, state); \
264 } \
265 \
266 static int32_t USART_DRIVER_NAME##_Send(const void *data, uint32_t num) \
267 { \
268 return ARM_USARTx_Send(&USART_DRIVER_NAME##_DEV, data, num); \
269 } \
270 \
271 static int32_t USART_DRIVER_NAME##_Receive(void *data, uint32_t num) \
272 { \
273 return ARM_USARTx_Receive(&USART_DRIVER_NAME##_DEV, data, num); \
274 } \
275 \
276 static int32_t USART_DRIVER_NAME##_Transfer(const void *data_out, \
277 void *data_in, \
278 uint32_t num) \
279 { \
280 ARG_UNUSED(data_out); \
281 ARG_UNUSED(data_in); \
282 ARG_UNUSED(num); \
283 \
284 return ARM_DRIVER_ERROR_UNSUPPORTED; \
285 } \
286 \
287 static uint32_t USART_DRIVER_NAME##_GetTxCount(void) \
288 { \
289 return ARM_USARTx_GetTxCount(&USART_DRIVER_NAME##_DEV); \
290 } \
291 \
292 static uint32_t USART_DRIVER_NAME##_GetRxCount(void) \
293 { \
294 return ARM_USARTx_GetRxCount(&USART_DRIVER_NAME##_DEV); \
295 } \
296 static int32_t USART_DRIVER_NAME##_Control(uint32_t control, uint32_t arg) \
297 { \
298 return ARM_USARTx_Control(&USART_DRIVER_NAME##_DEV, control, arg); \
299 } \
300 \
301 static ARM_USART_STATUS USART_DRIVER_NAME##_GetStatus(void) \
302 { \
303 ARM_USART_STATUS status = {0, 0, 0, 0, 0, 0, 0, 0}; \
304 return status; \
305 } \
306 \
307 static int32_t USART_DRIVER_NAME##_SetModemControl( \
308 ARM_USART_MODEM_CONTROL control) \
309 { \
310 ARG_UNUSED(control); \
311 return ARM_DRIVER_ERROR_UNSUPPORTED; \
312 } \
313 \
314 static ARM_USART_MODEM_STATUS USART_DRIVER_NAME##_GetModemStatus(void) \
315 { \
316 ARM_USART_MODEM_STATUS modem_status = {0, 0, 0, 0, 0}; \
317 return modem_status; \
318 } \
319 \
320 extern ARM_DRIVER_USART USART_DRIVER_NAME; \
321 ARM_DRIVER_USART USART_DRIVER_NAME = { \
322 ARM_USART_GetVersion, \
323 ARM_USART_GetCapabilities, \
324 USART_DRIVER_NAME##_Initialize, \
325 USART_DRIVER_NAME##_Uninitialize, \
326 USART_DRIVER_NAME##_PowerControl, \
327 USART_DRIVER_NAME##_Send, \
328 USART_DRIVER_NAME##_Receive, \
329 USART_DRIVER_NAME##_Transfer, \
330 USART_DRIVER_NAME##_GetTxCount, \
331 USART_DRIVER_NAME##_GetRxCount, \
332 USART_DRIVER_NAME##_Control, \
333 USART_DRIVER_NAME##_GetStatus, \
334 USART_DRIVER_NAME##_SetModemControl, \
335 USART_DRIVER_NAME##_GetModemStatus \
336 }
337
338 #endif /* __DRIVER_USART_CMSDK_H__ */
339