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