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