SWO.c
1 /* 2 * Copyright (c) 2013-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: 29. March 2021 21 * $Revision: V2.0.1 22 * 23 * Project: CMSIS-DAP Source 24 * Title: SWO.c CMSIS-DAP SWO I/O 25 * 26 *---------------------------------------------------------------------------*/ 27 28 #include "DAP_config.h" 29 #include "DAP.h" 30 #if (SWO_UART != 0) 31 #include "Driver_USART.h" 32 #endif 33 #if (SWO_STREAM != 0) 34 #include "cmsis_os2.h" 35 #define osObjectsExternal 36 #include "osObjects.h" 37 #endif 38 39 #if (SWO_STREAM != 0) 40 #ifdef DAP_FW_V1 41 #error "SWO Streaming Trace not supported in DAP V1!" 42 #endif 43 #endif 44 45 #if (SWO_UART != 0) 46 47 // USART Driver 48 #define _USART_Driver_(n) Driver_USART##n 49 #define USART_Driver_(n) _USART_Driver_(n) 50 extern ARM_DRIVER_USART USART_Driver_(SWO_UART_DRIVER); 51 #define pUSART (&USART_Driver_(SWO_UART_DRIVER)) 52 53 static uint8_t USART_Ready = 0U; 54 55 #endif /* (SWO_UART != 0) */ 56 57 58 #if ((SWO_UART != 0) || (SWO_MANCHESTER != 0)) 59 60 61 #define SWO_STREAM_TIMEOUT 50U /* Stream timeout in ms */ 62 63 #define USB_BLOCK_SIZE 512U /* USB Block Size */ 64 #define TRACE_BLOCK_SIZE 64U /* Trace Block Size (2^n: 32...512) */ 65 66 // Trace State 67 static uint8_t TraceTransport = 0U; /* Trace Transport */ 68 static uint8_t TraceMode = 0U; /* Trace Mode */ 69 static uint8_t TraceStatus = 0U; /* Trace Status without Errors */ 70 static uint8_t TraceError[2] = {0U, 0U}; /* Trace Error flags (banked) */ 71 static uint8_t TraceError_n = 0U; /* Active Trace Error bank */ 72 73 // Trace Buffer 74 static uint8_t TraceBuf[SWO_BUFFER_SIZE]; /* Trace Buffer (must be 2^n) */ 75 static volatile uint32_t TraceIndexI = 0U; /* Incoming Trace Index */ 76 static volatile uint32_t TraceIndexO = 0U; /* Outgoing Trace Index */ 77 static volatile uint8_t TraceUpdate; /* Trace Update Flag */ 78 static uint32_t TraceBlockSize; /* Current Trace Block Size */ 79 80 #if (TIMESTAMP_CLOCK != 0U) 81 // Trace Timestamp 82 static volatile struct { 83 uint32_t index; 84 uint32_t tick; 85 } TraceTimestamp; 86 #endif 87 88 // Trace Helper functions 89 static void ClearTrace (void); 90 static void ResumeTrace (void); 91 static uint32_t GetTraceCount (void); 92 static uint8_t GetTraceStatus (void); 93 static void SetTraceError (uint8_t flag); 94 95 #if (SWO_STREAM != 0) 96 extern osThreadId_t SWO_ThreadId; 97 static volatile uint8_t TransferBusy = 0U; /* Transfer Busy Flag */ 98 static uint32_t TransferSize; /* Current Transfer Size */ 99 #endif 100 101 102 #if (SWO_UART != 0) 103 104 // USART Driver Callback function 105 // event: event mask 106 static void USART_Callback (uint32_t event) { 107 uint32_t index_i; 108 uint32_t index_o; 109 uint32_t count; 110 uint32_t num; 111 112 if (event & ARM_USART_EVENT_RECEIVE_COMPLETE) { 113 #if (TIMESTAMP_CLOCK != 0U) 114 TraceTimestamp.tick = TIMESTAMP_GET(); 115 #endif 116 index_o = TraceIndexO; 117 index_i = TraceIndexI; 118 index_i += TraceBlockSize; 119 TraceIndexI = index_i; 120 #if (TIMESTAMP_CLOCK != 0U) 121 TraceTimestamp.index = index_i; 122 #endif 123 num = TRACE_BLOCK_SIZE - (index_i & (TRACE_BLOCK_SIZE - 1U)); 124 count = index_i - index_o; 125 if (count <= (SWO_BUFFER_SIZE - num)) { 126 index_i &= SWO_BUFFER_SIZE - 1U; 127 TraceBlockSize = num; 128 pUSART->Receive(&TraceBuf[index_i], num); 129 } else { 130 TraceStatus = DAP_SWO_CAPTURE_ACTIVE | DAP_SWO_CAPTURE_PAUSED; 131 } 132 TraceUpdate = 1U; 133 #if (SWO_STREAM != 0) 134 if (TraceTransport == 2U) { 135 if (count >= (USB_BLOCK_SIZE - (index_o & (USB_BLOCK_SIZE - 1U)))) { 136 osThreadFlagsSet(SWO_ThreadId, 1U); 137 } 138 } 139 #endif 140 } 141 if (event & ARM_USART_EVENT_RX_OVERFLOW) { 142 SetTraceError(DAP_SWO_BUFFER_OVERRUN); 143 } 144 if (event & (ARM_USART_EVENT_RX_BREAK | 145 ARM_USART_EVENT_RX_FRAMING_ERROR | 146 ARM_USART_EVENT_RX_PARITY_ERROR)) { 147 SetTraceError(DAP_SWO_STREAM_ERROR); 148 } 149 } 150 151 // Enable or disable SWO Mode (UART) 152 // enable: enable flag 153 // return: 1 - Success, 0 - Error 154 __WEAK uint32_t SWO_Mode_UART (uint32_t enable) { 155 int32_t status; 156 157 USART_Ready = 0U; 158 159 if (enable != 0U) { 160 status = pUSART->Initialize(USART_Callback); 161 if (status != ARM_DRIVER_OK) { 162 return (0U); 163 } 164 status = pUSART->PowerControl(ARM_POWER_FULL); 165 if (status != ARM_DRIVER_OK) { 166 pUSART->Uninitialize(); 167 return (0U); 168 } 169 } else { 170 pUSART->Control(ARM_USART_CONTROL_RX, 0U); 171 pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U); 172 pUSART->PowerControl(ARM_POWER_OFF); 173 pUSART->Uninitialize(); 174 } 175 return (1U); 176 } 177 178 // Configure SWO Baudrate (UART) 179 // baudrate: requested baudrate 180 // return: actual baudrate or 0 when not configured 181 __WEAK uint32_t SWO_Baudrate_UART (uint32_t baudrate) { 182 int32_t status; 183 uint32_t index; 184 uint32_t num; 185 186 if (baudrate > SWO_UART_MAX_BAUDRATE) { 187 baudrate = SWO_UART_MAX_BAUDRATE; 188 } 189 190 if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) { 191 pUSART->Control(ARM_USART_CONTROL_RX, 0U); 192 if (pUSART->GetStatus().rx_busy) { 193 TraceIndexI += pUSART->GetRxCount(); 194 pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U); 195 } 196 } 197 198 status = pUSART->Control(ARM_USART_MODE_ASYNCHRONOUS | 199 ARM_USART_DATA_BITS_8 | 200 ARM_USART_PARITY_NONE | 201 ARM_USART_STOP_BITS_1, 202 baudrate); 203 204 if (status == ARM_DRIVER_OK) { 205 USART_Ready = 1U; 206 } else { 207 USART_Ready = 0U; 208 return (0U); 209 } 210 211 if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) { 212 if ((TraceStatus & DAP_SWO_CAPTURE_PAUSED) == 0U) { 213 index = TraceIndexI & (SWO_BUFFER_SIZE - 1U); 214 num = TRACE_BLOCK_SIZE - (index & (TRACE_BLOCK_SIZE - 1U)); 215 TraceBlockSize = num; 216 pUSART->Receive(&TraceBuf[index], num); 217 } 218 pUSART->Control(ARM_USART_CONTROL_RX, 1U); 219 } 220 221 return (baudrate); 222 } 223 224 // Control SWO Capture (UART) 225 // active: active flag 226 // return: 1 - Success, 0 - Error 227 __WEAK uint32_t SWO_Control_UART (uint32_t active) { 228 int32_t status; 229 230 if (active) { 231 if (!USART_Ready) { 232 return (0U); 233 } 234 TraceBlockSize = 1U; 235 status = pUSART->Receive(&TraceBuf[0], 1U); 236 if (status != ARM_DRIVER_OK) { 237 return (0U); 238 } 239 status = pUSART->Control(ARM_USART_CONTROL_RX, 1U); 240 if (status != ARM_DRIVER_OK) { 241 return (0U); 242 } 243 } else { 244 pUSART->Control(ARM_USART_CONTROL_RX, 0U); 245 if (pUSART->GetStatus().rx_busy) { 246 TraceIndexI += pUSART->GetRxCount(); 247 pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U); 248 } 249 } 250 return (1U); 251 } 252 253 // Start SWO Capture (UART) 254 // buf: pointer to buffer for capturing 255 // num: number of bytes to capture 256 __WEAK void SWO_Capture_UART (uint8_t *buf, uint32_t num) { 257 TraceBlockSize = num; 258 pUSART->Receive(buf, num); 259 } 260 261 // Get SWO Pending Trace Count (UART) 262 // return: number of pending trace data bytes 263 __WEAK uint32_t SWO_GetCount_UART (void) { 264 uint32_t count; 265 266 if (pUSART->GetStatus().rx_busy) { 267 count = pUSART->GetRxCount(); 268 } else { 269 count = 0U; 270 } 271 return (count); 272 } 273 274 #endif /* (SWO_UART != 0) */ 275 276 277 #if (SWO_MANCHESTER != 0) 278 279 // Enable or disable SWO Mode (Manchester) 280 // enable: enable flag 281 // return: 1 - Success, 0 - Error 282 __WEAK uint32_t SWO_Mode_Manchester (uint32_t enable) { 283 return (0U); 284 } 285 286 // Configure SWO Baudrate (Manchester) 287 // baudrate: requested baudrate 288 // return: actual baudrate or 0 when not configured 289 __WEAK uint32_t SWO_Baudrate_Manchester (uint32_t baudrate) { 290 return (0U); 291 } 292 293 // Control SWO Capture (Manchester) 294 // active: active flag 295 // return: 1 - Success, 0 - Error 296 __WEAK uint32_t SWO_Control_Manchester (uint32_t active) { 297 return (0U); 298 } 299 300 // Start SWO Capture (Manchester) 301 // buf: pointer to buffer for capturing 302 // num: number of bytes to capture 303 __WEAK void SWO_Capture_Manchester (uint8_t *buf, uint32_t num) { 304 } 305 306 // Get SWO Pending Trace Count (Manchester) 307 // return: number of pending trace data bytes 308 __WEAK uint32_t SWO_GetCount_Manchester (void) { 309 } 310 311 #endif /* (SWO_MANCHESTER != 0) */ 312 313 314 // Clear Trace Errors and Data 315 static void ClearTrace (void) { 316 317 #if (SWO_STREAM != 0) 318 if (TraceTransport == 2U) { 319 if (TransferBusy != 0U) { 320 SWO_AbortTransfer(); 321 TransferBusy = 0U; 322 } 323 } 324 #endif 325 326 TraceError[0] = 0U; 327 TraceError[1] = 0U; 328 TraceError_n = 0U; 329 TraceIndexI = 0U; 330 TraceIndexO = 0U; 331 332 #if (TIMESTAMP_CLOCK != 0U) 333 TraceTimestamp.index = 0U; 334 TraceTimestamp.tick = 0U; 335 #endif 336 } 337 338 // Resume Trace Capture 339 static void ResumeTrace (void) { 340 uint32_t index_i; 341 uint32_t index_o; 342 343 if (TraceStatus == (DAP_SWO_CAPTURE_ACTIVE | DAP_SWO_CAPTURE_PAUSED)) { 344 index_i = TraceIndexI; 345 index_o = TraceIndexO; 346 if ((index_i - index_o) < SWO_BUFFER_SIZE) { 347 index_i &= SWO_BUFFER_SIZE - 1U; 348 switch (TraceMode) { 349 #if (SWO_UART != 0) 350 case DAP_SWO_UART: 351 TraceStatus = DAP_SWO_CAPTURE_ACTIVE; 352 SWO_Capture_UART(&TraceBuf[index_i], 1U); 353 break; 354 #endif 355 #if (SWO_MANCHESTER != 0) 356 case DAP_SWO_MANCHESTER: 357 TraceStatus = DAP_SWO_CAPTURE_ACTIVE; 358 SWO_Capture_Manchester(&TraceBuf[index_i], 1U); 359 break; 360 #endif 361 default: 362 break; 363 } 364 } 365 } 366 } 367 368 // Get Trace Count 369 // return: number of available data bytes in trace buffer 370 static uint32_t GetTraceCount (void) { 371 uint32_t count; 372 373 if (TraceStatus == DAP_SWO_CAPTURE_ACTIVE) { 374 do { 375 TraceUpdate = 0U; 376 count = TraceIndexI - TraceIndexO; 377 switch (TraceMode) { 378 #if (SWO_UART != 0) 379 case DAP_SWO_UART: 380 count += SWO_GetCount_UART(); 381 break; 382 #endif 383 #if (SWO_MANCHESTER != 0) 384 case DAP_SWO_MANCHESTER: 385 count += SWO_GetCount_Manchester(); 386 break; 387 #endif 388 default: 389 break; 390 } 391 } while (TraceUpdate != 0U); 392 } else { 393 count = TraceIndexI - TraceIndexO; 394 } 395 396 return (count); 397 } 398 399 // Get Trace Status (clear Error flags) 400 // return: Trace Status (Active flag and Error flags) 401 static uint8_t GetTraceStatus (void) { 402 uint8_t status; 403 uint32_t n; 404 405 n = TraceError_n; 406 TraceError_n ^= 1U; 407 status = TraceStatus | TraceError[n]; 408 TraceError[n] = 0U; 409 410 return (status); 411 } 412 413 // Set Trace Error flag(s) 414 // flag: error flag(s) to set 415 static void SetTraceError (uint8_t flag) { 416 TraceError[TraceError_n] |= flag; 417 } 418 419 420 // Process SWO Transport command and prepare response 421 // request: pointer to request data 422 // response: pointer to response data 423 // return: number of bytes in response (lower 16 bits) 424 // number of bytes in request (upper 16 bits) 425 uint32_t SWO_Transport (const uint8_t *request, uint8_t *response) { 426 uint8_t transport; 427 uint32_t result; 428 429 if ((TraceStatus & DAP_SWO_CAPTURE_ACTIVE) == 0U) { 430 transport = *request; 431 switch (transport) { 432 case 0U: 433 case 1U: 434 #if (SWO_STREAM != 0) 435 case 2U: 436 #endif 437 TraceTransport = transport; 438 result = 1U; 439 break; 440 default: 441 result = 0U; 442 break; 443 } 444 } else { 445 result = 0U; 446 } 447 448 if (result != 0U) { 449 *response = DAP_OK; 450 } else { 451 *response = DAP_ERROR; 452 } 453 454 return ((1U << 16) | 1U); 455 } 456 457 458 // Process SWO Mode command and prepare response 459 // request: pointer to request data 460 // response: pointer to response data 461 // return: number of bytes in response (lower 16 bits) 462 // number of bytes in request (upper 16 bits) 463 uint32_t SWO_Mode (const uint8_t *request, uint8_t *response) { 464 uint8_t mode; 465 uint32_t result; 466 467 mode = *request; 468 469 switch (TraceMode) { 470 #if (SWO_UART != 0) 471 case DAP_SWO_UART: 472 SWO_Mode_UART(0U); 473 break; 474 #endif 475 #if (SWO_MANCHESTER != 0) 476 case DAP_SWO_MANCHESTER: 477 SWO_Mode_Manchester(0U); 478 break; 479 #endif 480 default: 481 break; 482 } 483 484 switch (mode) { 485 case DAP_SWO_OFF: 486 result = 1U; 487 break; 488 #if (SWO_UART != 0) 489 case DAP_SWO_UART: 490 result = SWO_Mode_UART(1U); 491 break; 492 #endif 493 #if (SWO_MANCHESTER != 0) 494 case DAP_SWO_MANCHESTER: 495 result = SWO_Mode_Manchester(1U); 496 break; 497 #endif 498 default: 499 result = 0U; 500 break; 501 } 502 if (result != 0U) { 503 TraceMode = mode; 504 } else { 505 TraceMode = DAP_SWO_OFF; 506 } 507 508 TraceStatus = 0U; 509 510 if (result != 0U) { 511 *response = DAP_OK; 512 } else { 513 *response = DAP_ERROR; 514 } 515 516 return ((1U << 16) | 1U); 517 } 518 519 520 // Process SWO Baudrate command and prepare response 521 // request: pointer to request data 522 // response: pointer to response data 523 // return: number of bytes in response (lower 16 bits) 524 // number of bytes in request (upper 16 bits) 525 uint32_t SWO_Baudrate (const uint8_t *request, uint8_t *response) { 526 uint32_t baudrate; 527 528 baudrate = (uint32_t)(*(request+0) << 0) | 529 (uint32_t)(*(request+1) << 8) | 530 (uint32_t)(*(request+2) << 16) | 531 (uint32_t)(*(request+3) << 24); 532 533 switch (TraceMode) { 534 #if (SWO_UART != 0) 535 case DAP_SWO_UART: 536 baudrate = SWO_Baudrate_UART(baudrate); 537 break; 538 #endif 539 #if (SWO_MANCHESTER != 0) 540 case DAP_SWO_MANCHESTER: 541 baudrate = SWO_Baudrate_Manchester(baudrate); 542 break; 543 #endif 544 default: 545 baudrate = 0U; 546 break; 547 } 548 549 if (baudrate == 0U) { 550 TraceStatus = 0U; 551 } 552 553 *response++ = (uint8_t)(baudrate >> 0); 554 *response++ = (uint8_t)(baudrate >> 8); 555 *response++ = (uint8_t)(baudrate >> 16); 556 *response = (uint8_t)(baudrate >> 24); 557 558 return ((4U << 16) | 4U); 559 } 560 561 562 // Process SWO Control command and prepare response 563 // request: pointer to request data 564 // response: pointer to response data 565 // return: number of bytes in response (lower 16 bits) 566 // number of bytes in request (upper 16 bits) 567 uint32_t SWO_Control (const uint8_t *request, uint8_t *response) { 568 uint8_t active; 569 uint32_t result; 570 571 active = *request & DAP_SWO_CAPTURE_ACTIVE; 572 573 if (active != (TraceStatus & DAP_SWO_CAPTURE_ACTIVE)) { 574 if (active) { 575 ClearTrace(); 576 } 577 switch (TraceMode) { 578 #if (SWO_UART != 0) 579 case DAP_SWO_UART: 580 result = SWO_Control_UART(active); 581 break; 582 #endif 583 #if (SWO_MANCHESTER != 0) 584 case DAP_SWO_MANCHESTER: 585 result = SWO_Control_Manchester(active); 586 break; 587 #endif 588 default: 589 result = 0U; 590 break; 591 } 592 if (result != 0U) { 593 TraceStatus = active; 594 #if (SWO_STREAM != 0) 595 if (TraceTransport == 2U) { 596 osThreadFlagsSet(SWO_ThreadId, 1U); 597 } 598 #endif 599 } 600 } else { 601 result = 1U; 602 } 603 604 if (result != 0U) { 605 *response = DAP_OK; 606 } else { 607 *response = DAP_ERROR; 608 } 609 610 return ((1U << 16) | 1U); 611 } 612 613 614 // Process SWO Status command and prepare response 615 // response: pointer to response data 616 // return: number of bytes in response 617 uint32_t SWO_Status (uint8_t *response) { 618 uint8_t status; 619 uint32_t count; 620 621 status = GetTraceStatus(); 622 count = GetTraceCount(); 623 624 *response++ = status; 625 *response++ = (uint8_t)(count >> 0); 626 *response++ = (uint8_t)(count >> 8); 627 *response++ = (uint8_t)(count >> 16); 628 *response = (uint8_t)(count >> 24); 629 630 return (5U); 631 } 632 633 634 // Process SWO Extended Status command and prepare response 635 // request: pointer to request data 636 // response: pointer to response data 637 // return: number of bytes in response (lower 16 bits) 638 // number of bytes in request (upper 16 bits) 639 uint32_t SWO_ExtendedStatus (const uint8_t *request, uint8_t *response) { 640 uint8_t cmd; 641 uint8_t status; 642 uint32_t count; 643 #if (TIMESTAMP_CLOCK != 0U) 644 uint32_t index; 645 uint32_t tick; 646 #endif 647 uint32_t num; 648 649 num = 0U; 650 cmd = *request; 651 652 if (cmd & 0x01U) { 653 status = GetTraceStatus(); 654 *response++ = status; 655 num += 1U; 656 } 657 658 if (cmd & 0x02U) { 659 count = GetTraceCount(); 660 *response++ = (uint8_t)(count >> 0); 661 *response++ = (uint8_t)(count >> 8); 662 *response++ = (uint8_t)(count >> 16); 663 *response++ = (uint8_t)(count >> 24); 664 num += 4U; 665 } 666 667 #if (TIMESTAMP_CLOCK != 0U) 668 if (cmd & 0x04U) { 669 do { 670 TraceUpdate = 0U; 671 index = TraceTimestamp.index; 672 tick = TraceTimestamp.tick; 673 } while (TraceUpdate != 0U); 674 *response++ = (uint8_t)(index >> 0); 675 *response++ = (uint8_t)(index >> 8); 676 *response++ = (uint8_t)(index >> 16); 677 *response++ = (uint8_t)(index >> 24); 678 *response++ = (uint8_t)(tick >> 0); 679 *response++ = (uint8_t)(tick >> 8); 680 *response++ = (uint8_t)(tick >> 16); 681 *response++ = (uint8_t)(tick >> 24); 682 num += 4U; 683 } 684 #endif 685 686 return ((1U << 16) | num); 687 } 688 689 690 // Process SWO Data command and prepare response 691 // request: pointer to request data 692 // response: pointer to response data 693 // return: number of bytes in response (lower 16 bits) 694 // number of bytes in request (upper 16 bits) 695 uint32_t SWO_Data (const uint8_t *request, uint8_t *response) { 696 uint8_t status; 697 uint32_t count; 698 uint32_t index; 699 uint32_t n, i; 700 701 status = GetTraceStatus(); 702 count = GetTraceCount(); 703 704 if (TraceTransport == 1U) { 705 n = (uint32_t)(*(request+0) << 0) | 706 (uint32_t)(*(request+1) << 8); 707 if (n > (DAP_PACKET_SIZE - 4U)) { 708 n = DAP_PACKET_SIZE - 4U; 709 } 710 if (count > n) { 711 count = n; 712 } 713 } else { 714 count = 0U; 715 } 716 717 *response++ = status; 718 *response++ = (uint8_t)(count >> 0); 719 *response++ = (uint8_t)(count >> 8); 720 721 if (TraceTransport == 1U) { 722 index = TraceIndexO; 723 for (i = index, n = count; n; n--) { 724 i &= SWO_BUFFER_SIZE - 1U; 725 *response++ = TraceBuf[i++]; 726 } 727 TraceIndexO = index + count; 728 ResumeTrace(); 729 } 730 731 return ((2U << 16) | (3U + count)); 732 } 733 734 735 #if (SWO_STREAM != 0) 736 737 // SWO Data Transfer complete callback 738 void SWO_TransferComplete (void) { 739 TraceIndexO += TransferSize; 740 TransferBusy = 0U; 741 ResumeTrace(); 742 osThreadFlagsSet(SWO_ThreadId, 1U); 743 } 744 745 // SWO Thread 746 __NO_RETURN void SWO_Thread (void *argument) { 747 uint32_t timeout; 748 uint32_t flags; 749 uint32_t count; 750 uint32_t index; 751 uint32_t i, n; 752 (void) argument; 753 754 timeout = osWaitForever; 755 756 for (;;) { 757 flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout); 758 if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) { 759 timeout = SWO_STREAM_TIMEOUT; 760 } else { 761 timeout = osWaitForever; 762 flags = osFlagsErrorTimeout; 763 } 764 if (TransferBusy == 0U) { 765 count = GetTraceCount(); 766 if (count != 0U) { 767 index = TraceIndexO & (SWO_BUFFER_SIZE - 1U); 768 n = SWO_BUFFER_SIZE - index; 769 if (count > n) { 770 count = n; 771 } 772 if (flags != osFlagsErrorTimeout) { 773 i = index & (USB_BLOCK_SIZE - 1U); 774 if (i == 0U) { 775 count &= ~(USB_BLOCK_SIZE - 1U); 776 } else { 777 n = USB_BLOCK_SIZE - i; 778 if (count >= n) { 779 count = n; 780 } else { 781 count = 0U; 782 } 783 } 784 } 785 if (count != 0U) { 786 TransferSize = count; 787 TransferBusy = 1U; 788 SWO_QueueTransfer(&TraceBuf[index], count); 789 } 790 } 791 } 792 } 793 } 794 795 #endif /* (SWO_STREAM != 0) */ 796 797 798 #endif /* ((SWO_UART != 0) || (SWO_MANCHESTER != 0)) */