source: trunk/firmware_v4/Drivers/CMSIS/DAP/Firmware/Source/UART.c

Last change on this file was 42, checked in by f.jahn, 5 days ago
File size: 17.3 KB
Line 
1/*
2 * Copyright (c) 2021 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 * 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 *
20 * $Date: 1. March 2021
21 * $Revision: V1.0.0
22 *
23 * Project: CMSIS-DAP Source
24 * Title: UART.c CMSIS-DAP UART
25 *
26 *---------------------------------------------------------------------------*/
27
28#include "DAP_config.h"
29#include "DAP.h"
30
31#if (DAP_UART != 0)
32
33#ifdef DAP_FW_V1
34#error "UART Communication Port not supported in DAP V1!"
35#endif
36
37#include "Driver_USART.h"
38
39#include "cmsis_os2.h"
40#include <string.h>
41
42#define UART_RX_BLOCK_SIZE 32U /* Uart Rx Block Size (must be 2^n) */
43
44// USART Driver
45#define _USART_Driver_(n) Driver_USART##n
46#define USART_Driver_(n) _USART_Driver_(n)
47extern ARM_DRIVER_USART USART_Driver_(DAP_UART_DRIVER);
48#define pUSART (&USART_Driver_(DAP_UART_DRIVER))
49
50// UART Configuration
51#if (DAP_UART_USB_COM_PORT != 0)
52static uint8_t UartTransport = DAP_UART_TRANSPORT_USB_COM_PORT;
53#else
54static uint8_t UartTransport = DAP_UART_TRANSPORT_NONE;
55#endif
56
57// UART Flags
58static uint8_t UartConfigured = 0U;
59static uint8_t UartReceiveEnabled = 0U;
60static uint8_t UartTransmitEnabled = 0U;
61static uint8_t UartTransmitActive = 0U;
62
63// UART TX Buffer
64static uint8_t UartTxBuf[DAP_UART_TX_BUFFER_SIZE];
65static volatile uint32_t UartTxIndexI = 0U;
66static volatile uint32_t UartTxIndexO = 0U;
67
68// UART RX Buffer
69static uint8_t UartRxBuf[DAP_UART_RX_BUFFER_SIZE];
70static volatile uint32_t UartRxIndexI = 0U;
71static volatile uint32_t UartRxIndexO = 0U;
72
73// Uart Errors
74static volatile uint8_t UartErrorRxDataLost = 0U;
75static volatile uint8_t UartErrorFraming = 0U;
76static volatile uint8_t UartErrorParity = 0U;
77
78// UART Transmit
79static uint32_t UartTxNum = 0U;
80
81// Function prototypes
82static uint8_t UART_Init (void);
83static void UART_Uninit (void);
84static uint8_t UART_Get_Status (void);
85static uint8_t UART_Receive_Enable (void);
86static uint8_t UART_Transmit_Enable (void);
87static void UART_Receive_Disable (void);
88static void UART_Transmit_Disable (void);
89static void UART_Receive_Flush (void);
90static void UART_Transmit_Flush (void);
91static void UART_Receive (void);
92static void UART_Transmit (void);
93
94
95// USART Driver Callback function
96// event: event mask
97static void USART_Callback (uint32_t event) {
98 if (event & ARM_USART_EVENT_SEND_COMPLETE) {
99 UartTxIndexO += UartTxNum;
100 UartTransmitActive = 0U;
101 UART_Transmit();
102 }
103 if (event & ARM_USART_EVENT_RECEIVE_COMPLETE) {
104 UartRxIndexI += UART_RX_BLOCK_SIZE;
105 UART_Receive();
106 }
107 if (event & ARM_USART_EVENT_RX_OVERFLOW) {
108 UartErrorRxDataLost = 1U;
109 }
110 if (event & ARM_USART_EVENT_RX_FRAMING_ERROR) {
111 UartErrorFraming = 1U;
112 }
113 if (event & ARM_USART_EVENT_RX_PARITY_ERROR) {
114 UartErrorParity = 1U;
115 }
116}
117
118// Init UART
119// return: DAP_OK or DAP_ERROR
120static uint8_t UART_Init (void) {
121 int32_t status;
122 uint8_t ret = DAP_ERROR;
123
124 UartConfigured = 0U;
125 UartReceiveEnabled = 0U;
126 UartTransmitEnabled = 0U;
127 UartTransmitActive = 0U;
128 UartErrorRxDataLost = 0U;
129 UartErrorFraming = 0U;
130 UartErrorParity = 0U;
131 UartTxIndexI = 0U;
132 UartTxIndexO = 0U;
133 UartRxIndexI = 0U;
134 UartRxIndexO = 0U;
135 UartTxNum = 0U;
136
137 status = pUSART->Initialize(USART_Callback);
138 if (status == ARM_DRIVER_OK) {
139 status = pUSART->PowerControl(ARM_POWER_FULL);
140 }
141 if (status == ARM_DRIVER_OK) {
142 ret = DAP_OK;
143 }
144
145 return (ret);
146}
147
148// Un-Init UART
149static void UART_Uninit (void) {
150 UartConfigured = 0U;
151
152 pUSART->PowerControl(ARM_POWER_OFF);
153 pUSART->Uninitialize();
154}
155
156// Get UART Status
157// return: status
158static uint8_t UART_Get_Status (void) {
159 uint8_t status = 0U;
160
161 if (UartReceiveEnabled != 0U) {
162 status |= DAP_UART_STATUS_RX_ENABLED;
163 }
164 if (UartErrorRxDataLost != 0U) {
165 UartErrorRxDataLost = 0U;
166 status |= DAP_UART_STATUS_RX_DATA_LOST;
167 }
168 if (UartErrorFraming != 0U) {
169 UartErrorFraming = 0U;
170 status |= DAP_UART_STATUS_FRAMING_ERROR;
171 }
172 if (UartErrorParity != 0U) {
173 UartErrorParity = 0U;
174 status |= DAP_UART_STATUS_PARITY_ERROR;
175 }
176 if (UartTransmitEnabled != 0U) {
177 status |= DAP_UART_STATUS_TX_ENABLED;
178 }
179
180 return (status);
181}
182
183// Enable UART Receive
184// return: DAP_OK or DAP_ERROR
185static uint8_t UART_Receive_Enable (void) {
186 int32_t status;
187 uint8_t ret = DAP_ERROR;
188
189 if (UartReceiveEnabled == 0U) {
190 // Flush Buffers
191 UartRxIndexI = 0U;
192 UartRxIndexO = 0U;
193
194 UART_Receive();
195 status = pUSART->Control(ARM_USART_CONTROL_RX, 1U);
196 if (status == ARM_DRIVER_OK) {
197 UartReceiveEnabled = 1U;
198 ret = DAP_OK;
199 }
200 } else {
201 ret = DAP_OK;
202 }
203
204 return (ret);
205}
206
207// Enable UART Transmit
208// return: DAP_OK or DAP_ERROR
209static uint8_t UART_Transmit_Enable (void) {
210 int32_t status;
211 uint8_t ret = DAP_ERROR;
212
213 if (UartTransmitEnabled == 0U) {
214 // Flush Buffers
215 UartTransmitActive = 0U;
216 UartTxIndexI = 0U;
217 UartTxIndexO = 0U;
218 UartTxNum = 0U;
219
220 status = pUSART->Control(ARM_USART_CONTROL_TX, 1U);
221 if (status == ARM_DRIVER_OK) {
222 UartTransmitEnabled = 1U;
223 ret = DAP_OK;
224 }
225 } else {
226 ret = DAP_OK;
227 }
228
229 return (ret);
230}
231
232// Disable UART Receive
233static void UART_Receive_Disable (void) {
234 if (UartReceiveEnabled != 0U) {
235 pUSART->Control(ARM_USART_CONTROL_RX, 0U);
236 pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U);
237 UartReceiveEnabled = 0U;
238 }
239}
240
241// Disable UART Transmit
242static void UART_Transmit_Disable (void) {
243 if (UartTransmitEnabled != 0U) {
244 pUSART->Control(ARM_USART_ABORT_SEND, 0U);
245 pUSART->Control(ARM_USART_CONTROL_TX, 0U);
246 UartTransmitActive = 0U;
247 UartTransmitEnabled = 0U;
248 }
249}
250
251// Flush UART Receive buffer
252static void UART_Receive_Flush (void) {
253 pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U);
254 UartRxIndexI = 0U;
255 UartRxIndexO = 0U;
256 if (UartReceiveEnabled != 0U) {
257 UART_Receive();
258 }
259}
260
261// Flush UART Transmit buffer
262static void UART_Transmit_Flush (void) {
263 pUSART->Control(ARM_USART_ABORT_SEND, 0U);
264 UartTransmitActive = 0U;
265 UartTxIndexI = 0U;
266 UartTxIndexO = 0U;
267 UartTxNum = 0U;
268}
269
270// Receive data from target via UART
271static void UART_Receive (void) {
272 uint32_t index;
273
274 index = UartRxIndexI & (DAP_UART_RX_BUFFER_SIZE - 1U);
275 pUSART->Receive(&UartRxBuf[index], UART_RX_BLOCK_SIZE);
276}
277
278// Transmit available data to target via UART
279static void UART_Transmit (void) {
280 uint32_t count;
281 uint32_t index;
282
283 count = UartTxIndexI - UartTxIndexO;
284 index = UartTxIndexO & (DAP_UART_TX_BUFFER_SIZE - 1U);
285
286 if (count != 0U) {
287 if ((index + count) <= DAP_UART_TX_BUFFER_SIZE) {
288 UartTxNum = count;
289 } else {
290 UartTxNum = DAP_UART_TX_BUFFER_SIZE - index;
291 }
292 UartTransmitActive = 1U;
293 pUSART->Send(&UartTxBuf[index], UartTxNum);
294 }
295}
296
297// Process UART Transport command and prepare response
298// request: pointer to request data
299// response: pointer to response data
300// return: number of bytes in response (lower 16 bits)
301// number of bytes in request (upper 16 bits)
302uint32_t UART_Transport (const uint8_t *request, uint8_t *response) {
303 uint8_t transport;
304 uint8_t ret = DAP_ERROR;
305
306 transport = *request;
307 switch (transport) {
308 case DAP_UART_TRANSPORT_NONE:
309 switch (UartTransport) {
310 case DAP_UART_TRANSPORT_NONE:
311 ret = DAP_OK;
312 break;
313 case DAP_UART_TRANSPORT_USB_COM_PORT:
314#if (DAP_UART_USB_COM_PORT != 0)
315 USB_COM_PORT_Activate(0U);
316 UartTransport = DAP_UART_TRANSPORT_NONE;
317 ret = DAP_OK;
318#endif
319 break;
320 case DAP_UART_TRANSPORT_DAP_COMMAND:
321 UART_Receive_Disable();
322 UART_Transmit_Disable();
323 UART_Uninit();
324 UartTransport = DAP_UART_TRANSPORT_NONE;
325 ret= DAP_OK;
326 break;
327 }
328 break;
329 case DAP_UART_TRANSPORT_USB_COM_PORT:
330 switch (UartTransport) {
331 case DAP_UART_TRANSPORT_NONE:
332#if (DAP_UART_USB_COM_PORT != 0)
333 if (USB_COM_PORT_Activate(1U) == 0U) {
334 UartTransport = DAP_UART_TRANSPORT_USB_COM_PORT;
335 ret = DAP_OK;
336 }
337#endif
338 break;
339 case DAP_UART_TRANSPORT_USB_COM_PORT:
340 ret = DAP_OK;
341 break;
342 case DAP_UART_TRANSPORT_DAP_COMMAND:
343 UART_Receive_Disable();
344 UART_Transmit_Disable();
345 UART_Uninit();
346 UartTransport = DAP_UART_TRANSPORT_NONE;
347#if (DAP_UART_USB_COM_PORT != 0)
348 if (USB_COM_PORT_Activate(1U) == 0U) {
349 UartTransport = DAP_UART_TRANSPORT_USB_COM_PORT;
350 ret = DAP_OK;
351 }
352#endif
353 break;
354 }
355 break;
356 case DAP_UART_TRANSPORT_DAP_COMMAND:
357 switch (UartTransport) {
358 case DAP_UART_TRANSPORT_NONE:
359 ret = UART_Init();
360 if (ret == DAP_OK) {
361 UartTransport = DAP_UART_TRANSPORT_DAP_COMMAND;
362 }
363 break;
364 case DAP_UART_TRANSPORT_USB_COM_PORT:
365#if (DAP_UART_USB_COM_PORT != 0)
366 USB_COM_PORT_Activate(0U);
367 UartTransport = DAP_UART_TRANSPORT_NONE;
368#endif
369 ret = UART_Init();
370 if (ret == DAP_OK) {
371 UartTransport = DAP_UART_TRANSPORT_DAP_COMMAND;
372 }
373 break;
374 case DAP_UART_TRANSPORT_DAP_COMMAND:
375 ret = DAP_OK;
376 break;
377 }
378 break;
379 default:
380 break;
381 }
382
383 *response = ret;
384
385 return ((1U << 16) | 1U);
386}
387
388// Process UART Configure command and prepare response
389// request: pointer to request data
390// response: pointer to response data
391// return: number of bytes in response (lower 16 bits)
392// number of bytes in request (upper 16 bits)
393uint32_t UART_Configure (const uint8_t *request, uint8_t *response) {
394 uint8_t control, status;
395 uint32_t baudrate;
396 int32_t result;
397
398 if (UartTransport != DAP_UART_TRANSPORT_DAP_COMMAND) {
399 status = DAP_UART_CFG_ERROR_DATA_BITS |
400 DAP_UART_CFG_ERROR_PARITY |
401 DAP_UART_CFG_ERROR_STOP_BITS;
402 baudrate = 0U; // baudrate error
403 } else {
404
405 status = 0U;
406 control = *request;
407 baudrate = (uint32_t)(*(request+1) << 0) |
408 (uint32_t)(*(request+2) << 8) |
409 (uint32_t)(*(request+3) << 16) |
410 (uint32_t)(*(request+4) << 24);
411
412 result = pUSART->Control(control |
413 ARM_USART_MODE_ASYNCHRONOUS |
414 ARM_USART_FLOW_CONTROL_NONE,
415 baudrate);
416 if (result == ARM_DRIVER_OK) {
417 UartConfigured = 1U;
418 } else {
419 UartConfigured = 0U;
420 switch (result) {
421 case ARM_USART_ERROR_BAUDRATE:
422 status = 0U;
423 baudrate = 0U;
424 break;
425 case ARM_USART_ERROR_DATA_BITS:
426 status = DAP_UART_CFG_ERROR_DATA_BITS;
427 break;
428 case ARM_USART_ERROR_PARITY:
429 status = DAP_UART_CFG_ERROR_PARITY;
430 break;
431 case ARM_USART_ERROR_STOP_BITS:
432 status = DAP_UART_CFG_ERROR_STOP_BITS;
433 break;
434 default:
435 status = DAP_UART_CFG_ERROR_DATA_BITS |
436 DAP_UART_CFG_ERROR_PARITY |
437 DAP_UART_CFG_ERROR_STOP_BITS;
438 baudrate = 0U;
439 break;
440 }
441 }
442 }
443
444 *response++ = status;
445 *response++ = (uint8_t)(baudrate >> 0);
446 *response++ = (uint8_t)(baudrate >> 8);
447 *response++ = (uint8_t)(baudrate >> 16);
448 *response = (uint8_t)(baudrate >> 24);
449
450 return ((5U << 16) | 5U);
451}
452
453// Process UART Control command and prepare response
454// request: pointer to request data
455// response: pointer to response data
456// return: number of bytes in response (lower 16 bits)
457// number of bytes in request (upper 16 bits)
458uint32_t UART_Control (const uint8_t *request, uint8_t *response) {
459 uint8_t control;
460 uint8_t result;
461 uint8_t ret = DAP_OK;
462
463 if (UartTransport != DAP_UART_TRANSPORT_DAP_COMMAND) {
464 ret = DAP_ERROR;
465 } else {
466
467 control = *request;
468
469 if ((control & DAP_UART_CONTROL_RX_DISABLE) != 0U) {
470 // Receive disable
471 UART_Receive_Disable();
472 } else if ((control & DAP_UART_CONTROL_RX_ENABLE) != 0U) {
473 // Receive enable
474 if (UartConfigured != 0U) {
475 result = UART_Receive_Enable();
476 if (result != DAP_OK) {
477 ret = DAP_ERROR;
478 }
479 } else {
480 ret = DAP_ERROR;
481 }
482 }
483 if ((control & DAP_UART_CONTROL_RX_BUF_FLUSH) != 0U) {
484 UART_Receive_Flush();
485 }
486
487 if ((control & DAP_UART_CONTROL_TX_DISABLE) != 0U) {
488 // Transmit disable
489 UART_Transmit_Disable();
490 } else if ((control & DAP_UART_CONTROL_TX_ENABLE) != 0U) {
491 // Transmit enable
492 if (UartConfigured != 0U) {
493 result = UART_Transmit_Enable();
494 if (result != DAP_OK) {
495 ret = DAP_ERROR;
496 }
497 } else {
498 ret = DAP_ERROR;
499 }
500 }
501 if ((control & DAP_UART_CONTROL_TX_BUF_FLUSH) != 0U) {
502 UART_Transmit_Flush();
503 }
504 }
505
506 *response = ret;
507
508 return ((1U << 16) | 1U);
509}
510
511// Process UART Status command and prepare response
512// response: pointer to response data
513// return: number of bytes in response (lower 16 bits)
514// number of bytes in request (upper 16 bits)
515uint32_t UART_Status (uint8_t *response) {
516 uint32_t rx_cnt, tx_cnt;
517 uint32_t cnt;
518 uint8_t status;
519
520 if ((UartTransport != DAP_UART_TRANSPORT_DAP_COMMAND) ||
521 (UartConfigured == 0U)) {
522 rx_cnt = 0U;
523 tx_cnt = 0U;
524 status = 0U;
525 } else {
526
527 rx_cnt = UartRxIndexI - UartRxIndexO;
528 rx_cnt += pUSART->GetRxCount();
529 if (rx_cnt > (DAP_UART_RX_BUFFER_SIZE - (UART_RX_BLOCK_SIZE*2))) {
530 // Overflow
531 UartErrorRxDataLost = 1U;
532 rx_cnt = (DAP_UART_RX_BUFFER_SIZE - (UART_RX_BLOCK_SIZE*2));
533 UartRxIndexO = UartRxIndexI - rx_cnt;
534 }
535
536 tx_cnt = UartTxIndexI - UartTxIndexO;
537 cnt = pUSART->GetTxCount();
538 if (UartTransmitActive != 0U) {
539 tx_cnt -= cnt;
540 }
541
542 status = UART_Get_Status();
543 }
544
545 *response++ = status;
546 *response++ = (uint8_t)(rx_cnt >> 0);
547 *response++ = (uint8_t)(rx_cnt >> 8);
548 *response++ = (uint8_t)(rx_cnt >> 16);
549 *response++ = (uint8_t)(rx_cnt >> 24);
550 *response++ = (uint8_t)(tx_cnt >> 0);
551 *response++ = (uint8_t)(tx_cnt >> 8);
552 *response++ = (uint8_t)(tx_cnt >> 16);
553 *response = (uint8_t)(tx_cnt >> 24);
554
555 return ((0U << 16) | 9U);
556}
557
558// Process UART Transfer command and prepare response
559// request: pointer to request data
560// response: pointer to response data
561// return: number of bytes in response (lower 16 bits)
562// number of bytes in request (upper 16 bits)
563uint32_t UART_Transfer (const uint8_t *request, uint8_t *response) {
564 uint32_t rx_cnt, tx_cnt;
565 uint32_t rx_num, tx_num;
566 uint8_t *rx_data;
567 const
568 uint8_t *tx_data;
569 uint32_t num;
570 uint32_t index;
571 uint8_t status;
572
573 if (UartTransport != DAP_UART_TRANSPORT_DAP_COMMAND) {
574 status = 0U;
575 rx_cnt = 0U;
576 tx_cnt = 0U;
577 } else {
578
579 // RX Data
580 rx_cnt = ((uint32_t)(*(request+0) << 0) |
581 (uint32_t)(*(request+1) << 8));
582
583 if (rx_cnt > (DAP_PACKET_SIZE - 6U)) {
584 rx_cnt = (DAP_PACKET_SIZE - 6U);
585 }
586 rx_num = UartRxIndexI - UartRxIndexO;
587 rx_num += pUSART->GetRxCount();
588 if (rx_num > (DAP_UART_RX_BUFFER_SIZE - (UART_RX_BLOCK_SIZE*2))) {
589 // Overflow
590 UartErrorRxDataLost = 1U;
591 rx_num = (DAP_UART_RX_BUFFER_SIZE - (UART_RX_BLOCK_SIZE*2));
592 UartRxIndexO = UartRxIndexI - rx_num;
593 }
594 if (rx_cnt > rx_num) {
595 rx_cnt = rx_num;
596 }
597
598 rx_data = (response+5);
599 index = UartRxIndexO & (DAP_UART_RX_BUFFER_SIZE - 1U);
600 if ((index + rx_cnt) <= DAP_UART_RX_BUFFER_SIZE) {
601 memcpy( rx_data, &UartRxBuf[index], rx_cnt);
602 } else {
603 num = DAP_UART_RX_BUFFER_SIZE - index;
604 memcpy( rx_data, &UartRxBuf[index], num);
605 memcpy(&rx_data[num], &UartRxBuf[0], rx_cnt - num);
606 }
607 UartRxIndexO += rx_cnt;
608
609 // TX Data
610 tx_cnt = ((uint32_t)(*(request+2) << 0) |
611 (uint32_t)(*(request+3) << 8));
612 tx_data = (request+4);
613
614 if (tx_cnt > (DAP_PACKET_SIZE - 5U)) {
615 tx_cnt = (DAP_PACKET_SIZE - 5U);
616 }
617 tx_num = UartTxIndexI - UartTxIndexO;
618 num = pUSART->GetTxCount();
619 if (UartTransmitActive != 0U) {
620 tx_num -= num;
621 }
622 if (tx_cnt > (DAP_UART_TX_BUFFER_SIZE - tx_num)) {
623 tx_cnt = (DAP_UART_TX_BUFFER_SIZE - tx_num);
624 }
625
626 index = UartTxIndexI & (DAP_UART_TX_BUFFER_SIZE - 1U);
627 if ((index + tx_cnt) <= DAP_UART_TX_BUFFER_SIZE) {
628 memcpy(&UartTxBuf[index], tx_data, tx_cnt);
629 } else {
630 num = DAP_UART_TX_BUFFER_SIZE - index;
631 memcpy(&UartTxBuf[index], tx_data, num);
632 memcpy(&UartTxBuf[0], &tx_data[num], tx_cnt - num);
633 }
634 UartTxIndexI += tx_cnt;
635
636 if (UartTransmitActive == 0U) {
637 UART_Transmit();
638 }
639
640 status = UART_Get_Status();
641 }
642
643 *response++ = status;
644 *response++ = (uint8_t)(tx_cnt >> 0);
645 *response++ = (uint8_t)(tx_cnt >> 8);
646 *response++ = (uint8_t)(rx_cnt >> 0);
647 *response = (uint8_t)(rx_cnt >> 8);
648
649 return (((4U + tx_cnt) << 16) | (5U + rx_cnt));
650}
651
652#endif /* DAP_UART */
Note: See TracBrowser for help on using the repository browser.