1 /*
2  * Copyright (c) 2013-2022 Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Licensed under the Apache License, Version 2.0 (the License); you may
7  * not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #include "Driver_USART.h"
20 
21 #include "cmsis_driver_config.h"
22 #include "RTE_Device.h"
23 
24 #ifndef ARG_UNUSED
25 #define ARG_UNUSED(arg)  (void)arg
26 #endif
27 
28 /* Driver version */
29 #define ARM_USART_DRV_VERSION  ARM_DRIVER_VERSION_MAJOR_MINOR(2, 2)
30 
31 /* Driver Version */
32 static const ARM_DRIVER_VERSION DriverVersion = {
33     ARM_USART_API_VERSION,
34     ARM_USART_DRV_VERSION
35 };
36 
37 /* Driver Capabilities */
38 static const ARM_USART_CAPABILITIES DriverCapabilities = {
39     1, /* supports UART (Asynchronous) mode */
40     0, /* supports Synchronous Master mode */
41     0, /* supports Synchronous Slave mode */
42     0, /* supports UART Single-wire mode */
43     0, /* supports UART IrDA mode */
44     0, /* supports UART Smart Card mode */
45     0, /* Smart Card Clock generator available */
46     0, /* RTS Flow Control available */
47     0, /* CTS Flow Control available */
48     0, /* Transmit completed event: \ref ARM_USARTx_EVENT_TX_COMPLETE */
49     0, /* Signal receive character timeout event:
50         * \ref ARM_USARTx_EVENT_RX_TIMEOUT
51         */
52     0, /* RTS Line: 0=not available, 1=available */
53     0, /* CTS Line: 0=not available, 1=available */
54     0, /* DTR Line: 0=not available, 1=available */
55     0, /* DSR Line: 0=not available, 1=available */
56     0, /* DCD Line: 0=not available, 1=available */
57     0, /* RI Line: 0=not available, 1=available */
58     0, /* Signal CTS change event: \ref ARM_USARTx_EVENT_CTS */
59     0, /* Signal DSR change event: \ref ARM_USARTx_EVENT_DSR */
60     0, /* Signal DCD change event: \ref ARM_USARTx_EVENT_DCD */
61     0, /* Signal RI change event: \ref ARM_USARTx_EVENT_RI */
62     0  /* Reserved */
63 };
64 
ARM_USART_GetVersion(void)65 static ARM_DRIVER_VERSION ARM_USART_GetVersion(void)
66 {
67     return DriverVersion;
68 }
69 
ARM_USART_GetCapabilities(void)70 static ARM_USART_CAPABILITIES ARM_USART_GetCapabilities(void)
71 {
72     return DriverCapabilities;
73 }
74 
75 typedef struct {
76     struct uart_pl011_dev_t* dev;      /* UART device structure */
77     uint32_t tx_nbr_bytes;             /* Number of bytes transfered */
78     uint32_t rx_nbr_bytes;             /* Number of bytes received */
79     ARM_USART_SignalEvent_t cb_event;  /* Callback function for events */
80 } UARTx_Resources;
81 
ARM_USARTx_Initialize(UARTx_Resources * uart_dev)82 static int32_t ARM_USARTx_Initialize(UARTx_Resources* uart_dev)
83 {
84     /* Initializes generic UART driver */
85     uart_pl011_init(uart_dev->dev, PeripheralClock);
86 
87     uart_pl011_enable(uart_dev->dev);
88 
89     return ARM_DRIVER_OK;
90 }
91 
ARM_USARTx_Uninitialize(UARTx_Resources * uart_dev)92 static int32_t ARM_USARTx_Uninitialize(UARTx_Resources* uart_dev)
93 {
94     /* Disables and uninitializes generic UART driver */
95     uart_pl011_uninit(uart_dev->dev);
96 
97     return ARM_DRIVER_OK;
98 }
99 
ARM_USARTx_PowerControl(UARTx_Resources * uart_dev,ARM_POWER_STATE state)100 static int32_t ARM_USARTx_PowerControl(UARTx_Resources* uart_dev,
101                                        ARM_POWER_STATE state)
102 {
103     ARG_UNUSED(uart_dev);
104 
105     switch (state) {
106     case ARM_POWER_OFF:
107     case ARM_POWER_LOW:
108         return ARM_DRIVER_ERROR_UNSUPPORTED;
109     case ARM_POWER_FULL:
110         /* Nothing to be done */
111         return ARM_DRIVER_OK;
112     default:
113         return ARM_DRIVER_ERROR_PARAMETER;
114     }
115 }
116 
ARM_USARTx_Send(UARTx_Resources * uart_dev,const void * data,uint32_t num)117 static int32_t ARM_USARTx_Send(UARTx_Resources* uart_dev, const void *data,
118                                uint32_t num)
119 {
120     const uint8_t* p_data = (const uint8_t*)data;
121 
122     if ((data == NULL) || (num == 0U)) {
123         /* Invalid parameters */
124         return ARM_DRIVER_ERROR_PARAMETER;
125     }
126 
127     /* Resets previous TX counter */
128     uart_dev->tx_nbr_bytes = 0;
129 
130     while(uart_dev->tx_nbr_bytes != num) {
131         /* Waits until UART is ready to transmit */
132         while(!uart_pl011_is_writable(uart_dev->dev)) {};
133 
134         /* As UART is ready to transmit at this point, the write function can
135          * not return any transmit error */
136         (void)uart_pl011_write(uart_dev->dev, *p_data);
137 
138         uart_dev->tx_nbr_bytes++;
139         p_data++;
140     }
141 
142     if (uart_dev->cb_event != NULL) {
143         uart_dev->cb_event(ARM_USART_EVENT_SEND_COMPLETE);
144     }
145 
146     /* Waits until character is transmited */
147     while (!uart_pl011_is_writable(uart_dev->dev)){};
148 
149     return ARM_DRIVER_OK;
150 }
151 
ARM_USARTx_Receive(UARTx_Resources * uart_dev,void * data,uint32_t num)152 static int32_t ARM_USARTx_Receive(UARTx_Resources* uart_dev,
153                                   void *data, uint32_t num)
154 {
155     uint8_t* p_data = (uint8_t*)data;
156 
157     if ((data == NULL) || (num == 0U)) {
158         // Invalid parameters
159         return ARM_DRIVER_ERROR_PARAMETER;
160     }
161 
162     /* Resets previous RX counter */
163     uart_dev->rx_nbr_bytes = 0;
164 
165     while(uart_dev->rx_nbr_bytes != num) {
166         /* Waits until one character is received */
167         while (!uart_pl011_is_readable(uart_dev->dev)){};
168 
169         /* As UART has received one byte, the read can not
170          * return any receive error at this point */
171         (void)uart_pl011_read(uart_dev->dev, p_data);
172 
173         uart_dev->rx_nbr_bytes++;
174         p_data++;
175     }
176 
177     if (uart_dev->cb_event != NULL) {
178         uart_dev->cb_event(ARM_USART_EVENT_RECEIVE_COMPLETE);
179     }
180 
181     return ARM_DRIVER_OK;
182 }
183 
ARM_USARTx_GetTxCount(UARTx_Resources * uart_dev)184 static uint32_t ARM_USARTx_GetTxCount(UARTx_Resources* uart_dev)
185 {
186     return uart_dev->tx_nbr_bytes;
187 }
188 
ARM_USARTx_GetRxCount(UARTx_Resources * uart_dev)189 static uint32_t ARM_USARTx_GetRxCount(UARTx_Resources* uart_dev)
190 {
191     return uart_dev->rx_nbr_bytes;
192 }
193 
ARM_USARTx_Control(UARTx_Resources * uart_dev,uint32_t control,uint32_t arg)194 static int32_t ARM_USARTx_Control(UARTx_Resources* uart_dev, uint32_t control,
195                                   uint32_t arg)
196 {
197     switch (control & ARM_USART_CONTROL_Msk) {
198 #ifdef UART_TX_RX_CONTROL_ENABLED
199         case ARM_USART_CONTROL_TX:
200             if (arg == 0) {
201                 uart_pl011_disable_transmit(uart_dev->dev);
202             } else if (arg == 1) {
203                 uart_pl011_enable_transmit(uart_dev->dev);
204             } else {
205                 return ARM_DRIVER_ERROR_PARAMETER;
206             }
207             break;
208         case ARM_USART_CONTROL_RX:
209             if (arg == 0) {
210                 uart_pl011_disable_receive(uart_dev->dev);
211             } else if (arg == 1) {
212                 uart_pl011_enable_receive(uart_dev->dev);
213             } else {
214                 return ARM_DRIVER_ERROR_PARAMETER;
215             }
216             break;
217 #endif
218         case ARM_USART_MODE_ASYNCHRONOUS:
219             if(uart_pl011_set_baudrate(uart_dev->dev, arg) !=
220                 UART_PL011_ERR_NONE) {
221                 return ARM_USART_ERROR_BAUDRATE;
222             }
223             break;
224         /* Unsupported command */
225         default:
226             return ARM_DRIVER_ERROR_UNSUPPORTED;
227     }
228 
229     /* UART Data bits */
230     if(control & ARM_USART_DATA_BITS_Msk) {
231         /* Data bit is not configurable */
232         return ARM_DRIVER_ERROR_UNSUPPORTED;
233     }
234 
235     /* UART Parity */
236     if(control & ARM_USART_PARITY_Msk) {
237         /* Parity is not configurable */
238         return ARM_USART_ERROR_PARITY;
239     }
240 
241     /* USART Stop bits */
242     if(control & ARM_USART_STOP_BITS_Msk) {
243         /* Stop bit is not configurable */
244         return ARM_USART_ERROR_STOP_BITS;
245     }
246 
247     return ARM_DRIVER_OK;
248 }
249 
250 #if (RTE_USART0)
251 /* USART0 Driver wrapper functions */
252 static UARTx_Resources USART0_DEV = {
253     .dev = &UART0_DEV,
254     .tx_nbr_bytes = 0,
255     .rx_nbr_bytes = 0,
256     .cb_event = NULL,
257 };
258 
ARM_USART0_Initialize(ARM_USART_SignalEvent_t cb_event)259 static int32_t ARM_USART0_Initialize(ARM_USART_SignalEvent_t cb_event)
260 {
261     USART0_DEV.cb_event = cb_event;
262 
263     return ARM_USARTx_Initialize(&USART0_DEV);
264 }
265 
ARM_USART0_Uninitialize(void)266 static int32_t ARM_USART0_Uninitialize(void)
267 {
268     return ARM_USARTx_Uninitialize(&USART0_DEV);
269 }
270 
ARM_USART0_PowerControl(ARM_POWER_STATE state)271 static int32_t ARM_USART0_PowerControl(ARM_POWER_STATE state)
272 {
273     return ARM_USARTx_PowerControl(&USART0_DEV, state);
274 }
275 
ARM_USART0_Send(const void * data,uint32_t num)276 static int32_t ARM_USART0_Send(const void *data, uint32_t num)
277 {
278     return ARM_USARTx_Send(&USART0_DEV, data, num);
279 }
280 
ARM_USART0_Receive(void * data,uint32_t num)281 static int32_t ARM_USART0_Receive(void *data, uint32_t num)
282 {
283     return ARM_USARTx_Receive(&USART0_DEV, data, num);
284 }
285 
ARM_USART0_Transfer(const void * data_out,void * data_in,uint32_t num)286 static int32_t ARM_USART0_Transfer(const void *data_out, void *data_in,
287                                    uint32_t num)
288 {
289     ARG_UNUSED(data_out);
290     ARG_UNUSED(data_in);
291     ARG_UNUSED(num);
292 
293     return ARM_DRIVER_ERROR_UNSUPPORTED;
294 }
295 
ARM_USART0_GetTxCount(void)296 static uint32_t ARM_USART0_GetTxCount(void)
297 {
298     return ARM_USARTx_GetTxCount(&USART0_DEV);
299 }
300 
ARM_USART0_GetRxCount(void)301 static uint32_t ARM_USART0_GetRxCount(void)
302 {
303     return ARM_USARTx_GetRxCount(&USART0_DEV);
304 }
ARM_USART0_Control(uint32_t control,uint32_t arg)305 static int32_t ARM_USART0_Control(uint32_t control, uint32_t arg)
306 {
307     return ARM_USARTx_Control(&USART0_DEV, control, arg);
308 }
309 
ARM_USART0_GetStatus(void)310 static ARM_USART_STATUS ARM_USART0_GetStatus(void)
311 {
312     ARM_USART_STATUS status = {0, 0, 0, 0, 0, 0, 0, 0};
313     return status;
314 }
315 
ARM_USART0_SetModemControl(ARM_USART_MODEM_CONTROL control)316 static int32_t ARM_USART0_SetModemControl(ARM_USART_MODEM_CONTROL control)
317 {
318     ARG_UNUSED(control);
319     return ARM_DRIVER_ERROR_UNSUPPORTED;
320 }
321 
ARM_USART0_GetModemStatus(void)322 static ARM_USART_MODEM_STATUS ARM_USART0_GetModemStatus(void)
323 {
324     ARM_USART_MODEM_STATUS modem_status = {0, 0, 0, 0, 0};
325     return modem_status;
326 }
327 
328 extern ARM_DRIVER_USART Driver_USART0;
329 ARM_DRIVER_USART Driver_USART0 = {
330     ARM_USART_GetVersion,
331     ARM_USART_GetCapabilities,
332     ARM_USART0_Initialize,
333     ARM_USART0_Uninitialize,
334     ARM_USART0_PowerControl,
335     ARM_USART0_Send,
336     ARM_USART0_Receive,
337     ARM_USART0_Transfer,
338     ARM_USART0_GetTxCount,
339     ARM_USART0_GetRxCount,
340     ARM_USART0_Control,
341     ARM_USART0_GetStatus,
342     ARM_USART0_SetModemControl,
343     ARM_USART0_GetModemStatus
344 };
345 #endif /* RTE_USART0 */
346