UART.c
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) 47 extern 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) 52 static uint8_t UartTransport = DAP_UART_TRANSPORT_USB_COM_PORT; 53 #else 54 static uint8_t UartTransport = DAP_UART_TRANSPORT_NONE; 55 #endif 56 57 // UART Flags 58 static uint8_t UartConfigured = 0U; 59 static uint8_t UartReceiveEnabled = 0U; 60 static uint8_t UartTransmitEnabled = 0U; 61 static uint8_t UartTransmitActive = 0U; 62 63 // UART TX Buffer 64 static uint8_t UartTxBuf[DAP_UART_TX_BUFFER_SIZE]; 65 static volatile uint32_t UartTxIndexI = 0U; 66 static volatile uint32_t UartTxIndexO = 0U; 67 68 // UART RX Buffer 69 static uint8_t UartRxBuf[DAP_UART_RX_BUFFER_SIZE]; 70 static volatile uint32_t UartRxIndexI = 0U; 71 static volatile uint32_t UartRxIndexO = 0U; 72 73 // Uart Errors 74 static volatile uint8_t UartErrorRxDataLost = 0U; 75 static volatile uint8_t UartErrorFraming = 0U; 76 static volatile uint8_t UartErrorParity = 0U; 77 78 // UART Transmit 79 static uint32_t UartTxNum = 0U; 80 81 // Function prototypes 82 static uint8_t UART_Init (void); 83 static void UART_Uninit (void); 84 static uint8_t UART_Get_Status (void); 85 static uint8_t UART_Receive_Enable (void); 86 static uint8_t UART_Transmit_Enable (void); 87 static void UART_Receive_Disable (void); 88 static void UART_Transmit_Disable (void); 89 static void UART_Receive_Flush (void); 90 static void UART_Transmit_Flush (void); 91 static void UART_Receive (void); 92 static void UART_Transmit (void); 93 94 95 // USART Driver Callback function 96 // event: event mask 97 static 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 120 static 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 149 static 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 158 static 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 185 static 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 209 static 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 233 static 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 242 static 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 252 static 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 262 static 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 271 static 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 279 static 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) 302 uint32_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) 393 uint32_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) 458 uint32_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) 515 uint32_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) 563 uint32_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 */