1 /*
2  *  SPDX-License-Identifier: BSD-3-Clause
3  *  SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
4  *
5  */
6 
7 #ifndef __DRIVER_USART_RPI_H__
8 #define __DRIVER_USART_RPI_H__
9 
10 #include "Driver_USART.h"
11 #include "hardware/gpio.h"
12 #include "hardware/uart.h"
13 
14 #ifdef TFM_MULTI_CORE_TOPOLOGY
15 #include "platform_multicore.h"
16 #include "hardware/structs/sio.h"
17 #endif
18 
19 #ifndef ARG_UNUSED
20 #define ARG_UNUSED(arg)  (void)arg
21 #endif
22 
23 #define ARM_USART_DRV_VERSION    ARM_DRIVER_VERSION_MAJOR_MINOR(1, 0)  /* driver version */
24 
25 /* Driver Version */
26 static const ARM_DRIVER_VERSION DriverVersion = {
27     ARM_USART_API_VERSION,
28     ARM_USART_DRV_VERSION
29 };
30 
31 /* Driver Capabilities */
32 static const ARM_USART_CAPABILITIES DriverCapabilities = {
33     1, /* supports UART (Asynchronous) mode */
34     0, /* supports Synchronous Master mode */
35     0, /* supports Synchronous Slave mode */
36     0, /* supports UART Single-wire mode */
37     0, /* supports UART IrDA mode */
38     0, /* supports UART Smart Card mode */
39     0, /* Smart Card Clock generator available */
40     0, /* RTS Flow Control available */
41     0, /* CTS Flow Control available */
42     0, /* Transmit completed event: \ref ARM_USART_EVENT_TX_COMPLETE */
43     0, /* Signal receive character timeout event: \ref ARM_USART_EVENT_RX_TIMEOUT */
44     0, /* RTS Line: 0=not available, 1=available */
45     0, /* CTS Line: 0=not available, 1=available */
46     0, /* DTR Line: 0=not available, 1=available */
47     0, /* DSR Line: 0=not available, 1=available */
48     0, /* DCD Line: 0=not available, 1=available */
49     0, /* RI Line: 0=not available, 1=available */
50     0, /* Signal CTS change event: \ref ARM_USART_EVENT_CTS */
51     0, /* Signal DSR change event: \ref ARM_USART_EVENT_DSR */
52     0, /* Signal DCD change event: \ref ARM_USART_EVENT_DCD */
53     0, /* Signal RI change event: \ref ARM_USART_EVENT_RI */
54     0  /* Reserved (must be zero) */
55 };
56 
57 
58 typedef struct {
59     uart_inst_t *dev;                   /* UART device */
60     uint32_t tx_nbr_bytes;              /* Number of bytes transfered */
61     uint32_t rx_nbr_bytes;              /* Number of bytes recevied */
62     uint32_t default_baudrate;          /* UART default baudrate */
63     uint8_t rx_pin_num;                 /* RX pin number for GPIO config */
64     uint8_t tx_pin_num;                 /* TX pin number for GPIO config */
65     ARM_USART_SignalEvent_t cb_event;   /* Callback function for events */
66 } UARTx_Resources;
67 //
68 //   Functions
69 //
70 
71 #ifdef TFM_MULTI_CORE_TOPOLOGY
spinlock_claim()72 static inline void spinlock_claim()
73 {
74     /* Reading a spinlock register attempts to claim it, returning nonzero
75         * if the claim was successful and 0 if unsuccessful */
76     while(!*UART_SPINLOCK);
77 }
78 
spinlock_release()79 static inline void spinlock_release()
80 {
81     /* Writing to a spinlock register releases it */
82     *UART_SPINLOCK = 0x1u;
83 }
84 #endif
85 
ARM_USART_GetVersion(void)86 static ARM_DRIVER_VERSION ARM_USART_GetVersion(void)
87 {
88   return DriverVersion;
89 }
90 
ARM_USART_GetCapabilities(void)91 static ARM_USART_CAPABILITIES ARM_USART_GetCapabilities(void)
92 {
93   return DriverCapabilities;
94 }
95 
ARM_USARTx_Initialize(UARTx_Resources * uart_dev)96 static inline int32_t ARM_USARTx_Initialize(UARTx_Resources *uart_dev)
97 {
98     gpio_set_function(uart_dev->rx_pin_num, GPIO_FUNC_UART);
99     gpio_set_function(uart_dev->tx_pin_num, GPIO_FUNC_UART);
100     uart_init(uart_dev->dev, uart_dev->default_baudrate);
101 
102     return ARM_DRIVER_OK;
103 }
104 
ARM_USARTx_Uninitialize(UARTx_Resources * uart_dev)105 static inline int32_t ARM_USARTx_Uninitialize(UARTx_Resources *uart_dev)
106 {
107     uart_deinit(uart_dev->dev);
108 
109     return ARM_DRIVER_OK;
110 }
111 
ARM_USARTx_PowerControl(UARTx_Resources * uart_dev,ARM_POWER_STATE state)112 static int32_t ARM_USARTx_PowerControl(UARTx_Resources *uart_dev, ARM_POWER_STATE state)
113 {
114     ARG_UNUSED(uart_dev);
115 
116     switch (state) {
117     case ARM_POWER_OFF:
118     case ARM_POWER_LOW:
119         return ARM_DRIVER_ERROR_UNSUPPORTED;
120     case ARM_POWER_FULL:
121         /* Nothing to be done */
122         return ARM_DRIVER_OK;
123     /* default:  The default is not defined intentionally to force the
124      *           compiler to check that all the enumeration values are
125      *           covered in the switch.*/
126     }
127 }
128 
ARM_USARTx_Send(UARTx_Resources * uart_dev,const void * data,uint32_t num)129 static inline int32_t ARM_USARTx_Send(UARTx_Resources *uart_dev,
130                                       const void *data,
131                                       uint32_t num)
132 {
133     const uint8_t *p_data;
134 
135     if ((data == NULL) || (num == 0U)) {
136         /* Invalid parameters */
137         return ARM_DRIVER_ERROR_PARAMETER;
138     }
139 
140 #ifdef TFM_MULTI_CORE_TOPOLOGY
141     spinlock_claim();
142 #endif
143 
144     p_data = (const uint8_t *)data;
145 
146     /* Resets previous TX counter */
147     uart_dev->tx_nbr_bytes = 0;
148 
149     while (uart_dev->tx_nbr_bytes != num) {
150         /* Waits until UART is ready to transmit */
151         while (!uart_is_writable(uart_dev->dev)) {
152         }
153         /* As UART is ready to transmit at this point, the write function can
154             * not return any transmit error */
155         uart_putc(uart_dev->dev, *p_data);
156 
157         uart_dev->tx_nbr_bytes++;
158         p_data++;
159     }
160     uart_tx_wait_blocking(uart_dev->dev);
161 
162     if (uart_dev->cb_event != NULL) {
163         uart_dev->cb_event(ARM_USART_EVENT_SEND_COMPLETE);
164     }
165 #ifdef TFM_MULTI_CORE_TOPOLOGY
166     spinlock_release();
167 #endif
168 
169     return ARM_DRIVER_OK;
170 }
171 
ARM_USARTx_Receive(UARTx_Resources * uart_dev,void * data,uint32_t num)172 static inline int32_t ARM_USARTx_Receive(UARTx_Resources *uart_dev,
173                                          void *data, uint32_t num)
174 {
175     uint8_t *p_data;
176 
177     if ((data == NULL) || (num == 0U)) {
178         // Invalid parameters
179         return ARM_DRIVER_ERROR_PARAMETER;
180     }
181 #ifdef TFM_MULTI_CORE_TOPOLOGY
182     spinlock_claim();
183 #endif
184 
185     p_data = (uint8_t *)data;
186 
187     /* Resets previous RX counter */
188     uart_dev->rx_nbr_bytes = 0;
189 
190     while (uart_dev->rx_nbr_bytes != num) {
191         /* Waits until one character is received */
192         while (uart_is_readable(uart_dev->dev)) {
193             *p_data = uart_getc(uart_dev->dev);
194 
195             uart_dev->rx_nbr_bytes++;
196             p_data++;
197         }
198     }
199 
200     if (uart_dev->cb_event != NULL) {
201         uart_dev->cb_event(ARM_USART_EVENT_RECEIVE_COMPLETE);
202     }
203 #ifdef TFM_MULTI_CORE_TOPOLOGY
204     spinlock_release();
205 #endif
206     return ARM_DRIVER_OK;
207 }
208 
ARM_USARTx_GetTxCount(UARTx_Resources * uart_dev)209 static inline uint32_t ARM_USARTx_GetTxCount(UARTx_Resources *uart_dev)
210 {
211     return uart_dev->tx_nbr_bytes;
212 }
213 
ARM_USARTx_GetRxCount(UARTx_Resources * uart_dev)214 static inline uint32_t ARM_USARTx_GetRxCount(UARTx_Resources *uart_dev)
215 {
216     return uart_dev->rx_nbr_bytes;
217 }
218 
ARM_USARTx_Control(UARTx_Resources * uart_dev,uint32_t control,uint32_t arg)219 static inline int32_t ARM_USARTx_Control(UARTx_Resources *uart_dev,
220                                          uint32_t control,
221                                          uint32_t arg)
222 {
223     switch (control & ARM_USART_CONTROL_Msk) {
224 #ifdef UART_TX_RX_CONTROL_ENABLED
225         case ARM_USART_CONTROL_TX:
226             if (arg == 0) {
227                 uart_get_hw(uart)->cr &= ~UART_UARTCR_TXE_BITS;
228             } else if (arg == 1) {
229                 uart_get_hw(uart)->cr |= UART_UARTCR_TXE_BITS;
230             } else {
231                 return ARM_DRIVER_ERROR_PARAMETER;
232             }
233             break;
234         case ARM_USART_CONTROL_RX:
235             if (arg == 0) {
236                 uart_get_hw(uart)->cr &= ~UART_UARTCR_RXE_BITS;
237             } else if (arg == 1) {
238                 uart_get_hw(uart)->cr |= UART_UARTCR_RXE_BITS;
239             } else {
240                 return ARM_DRIVER_ERROR_PARAMETER;
241             }
242             break;
243 #endif
244         case ARM_USART_MODE_ASYNCHRONOUS:
245             uart_set_baudrate(uart_dev->dev, arg);
246             break;
247         /* Unsupported command */
248         default:
249             return ARM_DRIVER_ERROR_UNSUPPORTED;
250     }
251 
252     /* UART Data bits */
253     if (control & ARM_USART_DATA_BITS_Msk) {
254         /* Data bit is not configurable */
255         return ARM_DRIVER_ERROR_UNSUPPORTED;
256     }
257 
258     /* UART Parity */
259     if (control & ARM_USART_PARITY_Msk) {
260         /* Parity is not configurable */
261         return ARM_USART_ERROR_PARITY;
262     }
263 
264     /* USART Stop bits */
265     if (control & ARM_USART_STOP_BITS_Msk) {
266         /* Stop bit is not configurable */
267         return ARM_USART_ERROR_STOP_BITS;
268     }
269 
270     return ARM_DRIVER_OK;
271 }
272 
273 /*
274  * \brief Macro for USART Driver
275  *
276  * \param[in]  USART_DEV          uart_inst_t pointer
277  * \param[out] USART_DRIVER_NAME  Resulting Driver name
278  */
279 #define ARM_DRIVER_USART_RP2350(USART_DEV, USART_DRIVER_NAME, RX_PIN, TX_PIN)   \
280 static UARTx_Resources USART_DRIVER_NAME##_DEV = {                            \
281     .dev = USART_DEV,                                                         \
282     .default_baudrate = 115200,                                               \
283     .tx_nbr_bytes = 0,                                                        \
284     .rx_nbr_bytes = 0,                                                        \
285     .rx_pin_num = RX_PIN,                                                     \
286     .tx_pin_num = TX_PIN,                                                     \
287     .cb_event = NULL,                                                         \
288 };                                                                            \
289                                                                               \
290 static int32_t USART_DRIVER_NAME##_Initialize(                                \
291                                         ARM_USART_SignalEvent_t cb_event)     \
292 {                                                                             \
293     USART_DRIVER_NAME##_DEV.cb_event = cb_event;                              \
294                                                                               \
295     return ARM_USARTx_Initialize(&USART_DRIVER_NAME##_DEV);                   \
296 }                                                                             \
297                                                                               \
298 static int32_t USART_DRIVER_NAME##_Uninitialize(void)                         \
299 {                                                                             \
300     return ARM_USARTx_Uninitialize(&USART_DRIVER_NAME##_DEV);                 \
301 }                                                                             \
302                                                                               \
303 static int32_t USART_DRIVER_NAME##_PowerControl(ARM_POWER_STATE state)        \
304 {                                                                             \
305     return ARM_USARTx_PowerControl(&USART_DRIVER_NAME##_DEV, state);          \
306 }                                                                             \
307                                                                               \
308 static int32_t USART_DRIVER_NAME##_Send(const void *data, uint32_t num)       \
309 {                                                                             \
310     return ARM_USARTx_Send(&USART_DRIVER_NAME##_DEV, data, num);              \
311 }                                                                             \
312                                                                               \
313 static int32_t USART_DRIVER_NAME##_Receive(void *data, uint32_t num)          \
314 {                                                                             \
315     return ARM_USARTx_Receive(&USART_DRIVER_NAME##_DEV, data, num);           \
316 }                                                                             \
317                                                                               \
318 static int32_t USART_DRIVER_NAME##_Transfer(const void *data_out,             \
319                                             void *data_in,                    \
320                                             uint32_t num)                     \
321 {                                                                             \
322     ARG_UNUSED(data_out);                                                     \
323     ARG_UNUSED(data_in);                                                      \
324     ARG_UNUSED(num);                                                          \
325                                                                               \
326     return ARM_DRIVER_ERROR_UNSUPPORTED;                                      \
327 }                                                                             \
328                                                                               \
329 static uint32_t USART_DRIVER_NAME##_GetTxCount(void)                          \
330 {                                                                             \
331     return ARM_USARTx_GetTxCount(&USART_DRIVER_NAME##_DEV);                   \
332 }                                                                             \
333                                                                               \
334 static uint32_t USART_DRIVER_NAME##_GetRxCount(void)                          \
335 {                                                                             \
336     return ARM_USARTx_GetRxCount(&USART_DRIVER_NAME##_DEV);                   \
337 }                                                                             \
338 static int32_t USART_DRIVER_NAME##_Control(uint32_t control, uint32_t arg)    \
339 {                                                                             \
340     return ARM_USARTx_Control(&USART_DRIVER_NAME##_DEV, control, arg);        \
341 }                                                                             \
342                                                                               \
343 static ARM_USART_STATUS USART_DRIVER_NAME##_GetStatus(void)                   \
344 {                                                                             \
345     ARM_USART_STATUS status = {0, 0, 0, 0, 0, 0, 0, 0};                       \
346     return status;                                                            \
347 }                                                                             \
348                                                                               \
349 static int32_t USART_DRIVER_NAME##_SetModemControl(                           \
350                                              ARM_USART_MODEM_CONTROL control) \
351 {                                                                             \
352     ARG_UNUSED(control);                                                      \
353     return ARM_DRIVER_ERROR_UNSUPPORTED;                                      \
354 }                                                                             \
355                                                                               \
356 static ARM_USART_MODEM_STATUS USART_DRIVER_NAME##_GetModemStatus(void)        \
357 {                                                                             \
358     ARM_USART_MODEM_STATUS modem_status = {0, 0, 0, 0, 0};                    \
359     return modem_status;                                                      \
360 }                                                                             \
361                                                                               \
362 extern ARM_DRIVER_USART USART_DRIVER_NAME;                                    \
363 ARM_DRIVER_USART USART_DRIVER_NAME   = {                                      \
364     ARM_USART_GetVersion,                                                     \
365     ARM_USART_GetCapabilities,                                                \
366     USART_DRIVER_NAME##_Initialize,                                           \
367     USART_DRIVER_NAME##_Uninitialize,                                         \
368     USART_DRIVER_NAME##_PowerControl,                                         \
369     USART_DRIVER_NAME##_Send,                                                 \
370     USART_DRIVER_NAME##_Receive,                                              \
371     USART_DRIVER_NAME##_Transfer,                                             \
372     USART_DRIVER_NAME##_GetTxCount,                                           \
373     USART_DRIVER_NAME##_GetRxCount,                                           \
374     USART_DRIVER_NAME##_Control,                                              \
375     USART_DRIVER_NAME##_GetStatus,                                            \
376     USART_DRIVER_NAME##_SetModemControl,                                      \
377     USART_DRIVER_NAME##_GetModemStatus                                        \
378 }
379 
380 #endif  /* __DRIVER_USART_RPI_H__ */
381