Arrow / Mbed OS DAPLink Reset
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SWO.c Source File

SWO.c

00001 /*
00002  * Copyright (c) 2013-2017 ARM Limited. All rights reserved.
00003  *
00004  * SPDX-License-Identifier: Apache-2.0
00005  *
00006  * Licensed under the Apache License, Version 2.0 (the License); you may
00007  * not use this file except in compliance with the License.
00008  * You may obtain a copy of the License at
00009  *
00010  * www.apache.org/licenses/LICENSE-2.0
00011  *
00012  * Unless required by applicable law or agreed to in writing, software
00013  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
00014  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015  * See the License for the specific language governing permissions and
00016  * limitations under the License.
00017  *
00018  * ----------------------------------------------------------------------
00019  *
00020  * $Date:        1. December 2017
00021  * $Revision:    V2.0.0
00022  *
00023  * Project:      CMSIS-DAP Source
00024  * Title:        SWO.c CMSIS-DAP SWO I/O
00025  *
00026  *---------------------------------------------------------------------------*/
00027 
00028 #include "DAP_config.h"
00029 #include "DAP.h"
00030 #if (SWO_UART != 0)
00031 #include "Driver_USART.h"
00032 #endif
00033 #if (SWO_STREAM != 0)
00034 #include "cmsis_os2.h"
00035 #endif
00036 
00037 #if (SWO_STREAM != 0)
00038 #ifdef DAP_FW_V1
00039 #error "SWO Streaming Trace not supported in DAP V1!"
00040 #endif
00041 #endif
00042 
00043 #if (SWO_UART != 0)
00044 
00045 #ifndef  SWO_USART_PORT
00046 #define  SWO_USART_PORT 0           /* USART Port Number */
00047 #endif
00048 
00049 // USART Driver
00050 #define _USART_Driver_(n)  Driver_USART##n
00051 #define  USART_Driver_(n) _USART_Driver_(n)
00052 extern ARM_DRIVER_USART    USART_Driver_(SWO_USART_PORT);
00053 #define pUSART           (&USART_Driver_(SWO_USART_PORT))
00054 
00055 static uint8_t USART_Ready = 0U;
00056 
00057 #endif  /* (SWO_UART != 0) */
00058 
00059 
00060 #if ((SWO_UART != 0) || (SWO_MANCHESTER != 0))
00061 
00062 
00063 #define SWO_STREAM_TIMEOUT      50U     /* Stream timeout in ms */
00064 
00065 #define USB_BLOCK_SIZE          512U    /* USB Block Size */
00066 #define TRACE_BLOCK_SIZE        64U     /* Trace Block Size (2^n: 32...512) */
00067 
00068 // Trace State
00069 static uint8_t  TraceTransport =  0U;       /* Trace Transport */
00070 static uint8_t  TraceMode      =  0U;       /* Trace Mode */
00071 static uint8_t  TraceStatus    =  0U;       /* Trace Status without Errors */
00072 static uint8_t  TraceError[2]  = {0U, 0U};  /* Trace Error flags (banked) */
00073 static uint8_t  TraceError_n   =  0U;       /* Active Trace Error bank */
00074 
00075 // Trace Buffer
00076 static uint8_t  TraceBuf[SWO_BUFFER_SIZE];  /* Trace Buffer (must be 2^n) */
00077 static volatile uint32_t TraceIndexI  = 0U; /* Incoming Trace Index */
00078 static volatile uint32_t TraceIndexO  = 0U; /* Outgoing Trace Index */
00079 static volatile uint8_t  TraceUpdate;       /* Trace Update Flag */
00080 static          uint32_t TraceBlockSize;    /* Current Trace Block Size */
00081 
00082 #if (TIMESTAMP_CLOCK != 0U) 
00083 // Trace Timestamp
00084 static volatile struct {
00085   uint32_t index;
00086   uint32_t tick;
00087 } TraceTimestamp;
00088 #endif
00089 
00090 // Trace Helper functions
00091 static void     ClearTrace     (void);
00092 static void     ResumeTrace    (void);
00093 static uint32_t GetTraceCount  (void);
00094 static uint8_t  GetTraceStatus (void);
00095 static void     SetTraceError  (uint8_t flag);
00096 
00097 #if (SWO_STREAM != 0)
00098 extern osThreadId_t      SWO_ThreadId;
00099 static volatile uint8_t  TransferBusy = 0U; /* Transfer Busy Flag */
00100 static          uint32_t TransferSize;      /* Current Transfer Size */
00101 #endif
00102 
00103 
00104 #if (SWO_UART != 0)
00105 
00106 // USART Driver Callback function
00107 //   event: event mask
00108 static void USART_Callback (uint32_t event) {
00109   uint32_t index_i;
00110   uint32_t index_o;
00111   uint32_t count;
00112   uint32_t num;
00113 
00114   if (event &  ARM_USART_EVENT_RECEIVE_COMPLETE) {
00115 #if (TIMESTAMP_CLOCK != 0U) 
00116     TraceTimestamp.tick = TIMESTAMP_GET();
00117 #endif
00118     index_o  = TraceIndexO;
00119     index_i  = TraceIndexI;
00120     index_i += TraceBlockSize;
00121     TraceIndexI = index_i;
00122 #if (TIMESTAMP_CLOCK != 0U) 
00123     TraceTimestamp.index = index_i;
00124 #endif
00125     num   = TRACE_BLOCK_SIZE - (index_i & (TRACE_BLOCK_SIZE - 1U));
00126     count = index_i - index_o;
00127     if (count <= (SWO_BUFFER_SIZE - num)) {
00128       index_i &= SWO_BUFFER_SIZE - 1U;
00129       TraceBlockSize = num;
00130       pUSART->Receive(&TraceBuf[index_i], num);
00131     } else {
00132       TraceStatus = DAP_SWO_CAPTURE_ACTIVE | DAP_SWO_CAPTURE_PAUSED;
00133     }
00134     TraceUpdate = 1U;
00135 #if (SWO_STREAM != 0)
00136     if (TraceTransport == 2U) {
00137       if (count >= (USB_BLOCK_SIZE - (index_o & (USB_BLOCK_SIZE - 1U)))) {
00138         osThreadFlagsSet(SWO_ThreadId, 1U);
00139       }
00140     }
00141 #endif
00142   }
00143   if (event &  ARM_USART_EVENT_RX_OVERFLOW) {
00144     SetTraceError(DAP_SWO_BUFFER_OVERRUN);
00145   }
00146   if (event & (ARM_USART_EVENT_RX_BREAK         |
00147                ARM_USART_EVENT_RX_FRAMING_ERROR |
00148                ARM_USART_EVENT_RX_PARITY_ERROR)) {
00149     SetTraceError(DAP_SWO_STREAM_ERROR);
00150   }
00151 }
00152 
00153 // Enable or disable UART SWO Mode
00154 //   enable: enable flag
00155 //   return: 1 - Success, 0 - Error
00156 __WEAK uint32_t UART_SWO_Mode (uint32_t enable) {
00157   int32_t status;
00158 
00159   USART_Ready = 0U;
00160 
00161   if (enable != 0U) {
00162     status = pUSART->Initialize(USART_Callback);
00163     if (status != ARM_DRIVER_OK) {
00164       return (0U);
00165     }
00166     status = pUSART->PowerControl(ARM_POWER_FULL);
00167     if (status != ARM_DRIVER_OK) {
00168       pUSART->Uninitialize();
00169       return (0U);
00170     }
00171   } else {
00172     pUSART->Control(ARM_USART_CONTROL_RX, 0U);
00173     pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U);
00174     pUSART->PowerControl(ARM_POWER_OFF);
00175     pUSART->Uninitialize();
00176   }
00177   return (1U);
00178 }
00179 
00180 // Configure UART SWO Baudrate
00181 //   baudrate: requested baudrate
00182 //   return:   actual baudrate or 0 when not configured
00183 __WEAK uint32_t UART_SWO_Baudrate (uint32_t baudrate) {
00184   int32_t  status;
00185   uint32_t index;
00186   uint32_t num;
00187 
00188   if (baudrate > SWO_UART_MAX_BAUDRATE) {
00189     baudrate = SWO_UART_MAX_BAUDRATE;
00190   }
00191 
00192   if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {
00193     pUSART->Control(ARM_USART_CONTROL_RX, 0U);
00194     if (pUSART->GetStatus().rx_busy) {
00195       TraceIndexI += pUSART->GetRxCount();
00196       pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U);
00197     }
00198   }
00199 
00200   status = pUSART->Control(ARM_USART_MODE_ASYNCHRONOUS |
00201                            ARM_USART_DATA_BITS_8       |
00202                            ARM_USART_PARITY_NONE       |
00203                            ARM_USART_STOP_BITS_1,
00204                            baudrate);
00205 
00206   if (status == ARM_DRIVER_OK) {
00207     USART_Ready = 1U;
00208   } else {
00209     USART_Ready = 0U;
00210     return (0U);
00211   }
00212 
00213   if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {
00214     if ((TraceStatus & DAP_SWO_CAPTURE_PAUSED) == 0U) {
00215       index = TraceIndexI & (SWO_BUFFER_SIZE - 1U);
00216       num = TRACE_BLOCK_SIZE - (index & (TRACE_BLOCK_SIZE - 1U));
00217       TraceBlockSize = num;
00218       pUSART->Receive(&TraceBuf[index], num);
00219     }
00220     pUSART->Control(ARM_USART_CONTROL_RX, 1U);
00221   }
00222 
00223   return (baudrate);
00224 }
00225 
00226 // Control UART SWO Capture
00227 //   active: active flag
00228 //   return: 1 - Success, 0 - Error
00229 __WEAK uint32_t UART_SWO_Control (uint32_t active) {
00230   int32_t status;
00231 
00232   if (active) {
00233     if (!USART_Ready) { 
00234       return (0U);
00235     }
00236     TraceBlockSize = 1U;
00237     status = pUSART->Receive(&TraceBuf[0], 1U);
00238     if (status != ARM_DRIVER_OK) {
00239       return (0U);
00240     }
00241     status = pUSART->Control(ARM_USART_CONTROL_RX, 1U);
00242     if (status != ARM_DRIVER_OK) {
00243       return (0U);
00244     }
00245   } else {
00246     pUSART->Control(ARM_USART_CONTROL_RX, 0U);
00247     if (pUSART->GetStatus().rx_busy) {
00248       TraceIndexI += pUSART->GetRxCount();
00249       pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U);
00250     }
00251   }
00252   return (1U);
00253 }
00254 
00255 // Start UART SWO Capture
00256 //   buf: pointer to buffer for capturing
00257 //   num: number of bytes to capture
00258 __WEAK void UART_SWO_Capture (uint8_t *buf, uint32_t num) {
00259   TraceBlockSize = num;
00260   pUSART->Receive(buf, num);
00261 }
00262 
00263 // Get UART SWO Pending Trace Count
00264 //   return: number of pending trace data bytes
00265 __WEAK uint32_t UART_SWO_GetCount (void) {
00266   uint32_t count;
00267 
00268   if (pUSART->GetStatus().rx_busy) {
00269     count = pUSART->GetRxCount();
00270   } else {
00271     count = 0U;
00272   }
00273   return (count);
00274 }
00275 
00276 #endif  /* (SWO_UART != 0) */
00277 
00278 
00279 #if (SWO_MANCHESTER != 0)
00280 
00281 // Enable or disable Manchester SWO Mode
00282 //   enable: enable flag
00283 //   return: 1 - Success, 0 - Error
00284 __WEAK uint32_t Manchester_SWO_Mode (uint32_t enable) {
00285   return (0U);
00286 }
00287 
00288 // Configure Manchester SWO Baudrate
00289 //   baudrate: requested baudrate
00290 //   return:   actual baudrate or 0 when not configured
00291 __WEAK uint32_t Manchester_SWO_Baudrate (uint32_t baudrate) {
00292   return (0U);
00293 }
00294 
00295 // Control Manchester SWO Capture
00296 //   active: active flag
00297 //   return: 1 - Success, 0 - Error
00298 __WEAK uint32_t Manchester_SWO_Control (uint32_t active) {
00299   return (0U);
00300 }
00301 
00302 // Start Manchester SWO Capture
00303 //   buf: pointer to buffer for capturing
00304 //   num: number of bytes to capture
00305 __WEAK void Manchester_SWO_Capture (uint8_t *buf, uint32_t num) {
00306 }
00307 
00308 // Get Manchester SWO Pending Trace Count
00309 //   return: number of pending trace data bytes
00310 __WEAK uint32_t Manchester_SWO_GetCount (void) {
00311 }
00312 
00313 #endif  /* (SWO_MANCHESTER != 0) */
00314 
00315 
00316 // Clear Trace Errors and Data
00317 static void ClearTrace (void) {
00318 
00319 #if (SWO_STREAM != 0)
00320   if (TraceTransport == 2U) {
00321     if (TransferBusy != 0U) {
00322       SWO_AbortTransfer();
00323       TransferBusy = 0U;
00324     }
00325   }
00326 #endif
00327 
00328   TraceError[0] = 0U;
00329   TraceError[1] = 0U;
00330   TraceError_n  = 0U;
00331   TraceIndexI   = 0U;
00332   TraceIndexO   = 0U;
00333 
00334 #if (TIMESTAMP_CLOCK != 0U) 
00335   TraceTimestamp.index = 0U;
00336   TraceTimestamp.tick  = 0U;
00337 #endif
00338 }
00339 
00340 // Resume Trace Capture
00341 static void ResumeTrace (void) {
00342   uint32_t index_i;
00343   uint32_t index_o;
00344 
00345   if (TraceStatus == (DAP_SWO_CAPTURE_ACTIVE | DAP_SWO_CAPTURE_PAUSED)) {
00346     index_i = TraceIndexI;
00347     index_o = TraceIndexO;
00348     if ((index_i - index_o) < SWO_BUFFER_SIZE) {
00349       index_i &= SWO_BUFFER_SIZE - 1U;
00350       switch (TraceMode) {
00351 #if (SWO_UART != 0)
00352         case DAP_SWO_UART:
00353           TraceStatus = DAP_SWO_CAPTURE_ACTIVE;
00354           UART_SWO_Capture(&TraceBuf[index_i], 1U);
00355           break;
00356 #endif
00357 #if (SWO_MANCHESTER != 0)
00358         case DAP_SWO_MANCHESTER:
00359           TraceStatus = DAP_SWO_CAPTURE_ACTIVE;
00360           Manchester_SWO_Capture(&TraceBuf[index_i], 1U);
00361           break;
00362 #endif
00363         default:
00364           break;
00365       }
00366     }
00367   }
00368 }
00369 
00370 // Get Trace Count
00371 //   return: number of available data bytes in trace buffer
00372 static uint32_t GetTraceCount (void) {
00373   uint32_t count;
00374 
00375   if (TraceStatus == DAP_SWO_CAPTURE_ACTIVE) {
00376     do {
00377       TraceUpdate = 0U;
00378       count = TraceIndexI - TraceIndexO;
00379       switch (TraceMode) {
00380 #if (SWO_UART != 0)
00381         case DAP_SWO_UART:
00382           count += UART_SWO_GetCount();
00383           break;
00384 #endif
00385 #if (SWO_MANCHESTER != 0)
00386         case DAP_SWO_MANCHESTER:
00387           count += Manchester_SWO_GetCount();
00388           break;
00389 #endif
00390         default:
00391           break;
00392       }
00393     } while (TraceUpdate != 0U);
00394   } else {
00395     count = TraceIndexI - TraceIndexO;
00396   }
00397 
00398   return (count);
00399 }
00400 
00401 // Get Trace Status (clear Error flags)
00402 //   return: Trace Status (Active flag and Error flags)
00403 static uint8_t GetTraceStatus (void) {
00404   uint8_t  status;
00405   uint32_t n;
00406 
00407   n = TraceError_n;
00408   TraceError_n ^= 1U;
00409   status = TraceStatus | TraceError[n];
00410   TraceError[n] = 0U;
00411 
00412   return (status);
00413 }
00414 
00415 // Set Trace Error flag(s)
00416 //   flag:  error flag(s) to set
00417 static void SetTraceError (uint8_t flag) {
00418   TraceError[TraceError_n] |= flag;
00419 }
00420 
00421 
00422 // Process SWO Transport command and prepare response
00423 //   request:  pointer to request data
00424 //   response: pointer to response data
00425 //   return:   number of bytes in response (lower 16 bits)
00426 //             number of bytes in request (upper 16 bits)
00427 uint32_t SWO_Transport (const uint8_t *request, uint8_t *response) {
00428   uint8_t  transport;
00429   uint32_t result;
00430 
00431   if ((TraceStatus & DAP_SWO_CAPTURE_ACTIVE) == 0U) {
00432     transport = *request;
00433     switch (transport) {
00434       case 0U:
00435       case 1U:
00436 #if (SWO_STREAM != 0)
00437       case 2U:
00438 #endif
00439         TraceTransport = transport;
00440         result = 1U;
00441         break;
00442       default:
00443         result = 0U;
00444         break;
00445     }
00446   } else {
00447     result = 0U;
00448   }
00449 
00450   if (result != 0U) {
00451     *response = DAP_OK;
00452   } else {
00453     *response = DAP_ERROR;
00454   }
00455 
00456   return ((1U << 16) | 1U);
00457 }
00458 
00459 
00460 // Process SWO Mode command and prepare response
00461 //   request:  pointer to request data
00462 //   response: pointer to response data
00463 //   return:   number of bytes in response (lower 16 bits)
00464 //             number of bytes in request (upper 16 bits)
00465 uint32_t SWO_Mode (const uint8_t *request, uint8_t *response) {
00466   uint8_t  mode;
00467   uint32_t result;
00468 
00469   mode = *request;
00470 
00471   switch (TraceMode) {
00472 #if (SWO_UART != 0)
00473     case DAP_SWO_UART:
00474       UART_SWO_Mode(0U);
00475       break;
00476 #endif
00477 #if (SWO_MANCHESTER != 0)
00478     case DAP_SWO_MANCHESTER:
00479       Manchester_SWO_Mode(0U);
00480       break;
00481 #endif
00482     default:
00483       break;
00484   }
00485 
00486   switch (mode) {
00487     case DAP_SWO_OFF:
00488       result = 1U;
00489       break;
00490 #if (SWO_UART != 0)
00491     case DAP_SWO_UART:
00492       result = UART_SWO_Mode(1U);
00493       break;
00494 #endif
00495 #if (SWO_MANCHESTER != 0)
00496     case DAP_SWO_MANCHESTER:
00497       result = Manchester_SWO_Mode(1U);
00498       break;
00499 #endif
00500     default:
00501       result = 0U;
00502       break;
00503   }
00504   if (result != 0U) {
00505     TraceMode = mode;
00506   } else {
00507     TraceMode = DAP_SWO_OFF;
00508   }
00509 
00510   TraceStatus = 0U;
00511 
00512   if (result != 0U) {
00513     *response = DAP_OK;
00514   } else {
00515     *response = DAP_ERROR;
00516   }
00517 
00518   return ((1U << 16) | 1U);
00519 }
00520 
00521 
00522 // Process SWO Baudrate command and prepare response
00523 //   request:  pointer to request data
00524 //   response: pointer to response data
00525 //   return:   number of bytes in response (lower 16 bits)
00526 //             number of bytes in request (upper 16 bits)
00527 uint32_t SWO_Baudrate (const uint8_t *request, uint8_t *response) {
00528   uint32_t baudrate;
00529 
00530   baudrate = (uint32_t)(*(request+0) <<  0) |
00531              (uint32_t)(*(request+1) <<  8) |
00532              (uint32_t)(*(request+2) << 16) |
00533              (uint32_t)(*(request+3) << 24);
00534 
00535   switch (TraceMode) {
00536 #if (SWO_UART != 0)
00537     case DAP_SWO_UART:
00538       baudrate = UART_SWO_Baudrate(baudrate);
00539       break;
00540 #endif
00541 #if (SWO_MANCHESTER != 0)
00542     case DAP_SWO_MANCHESTER:
00543       baudrate = Manchester_SWO_Baudrate(baudrate);
00544       break;
00545 #endif
00546     default:
00547       baudrate = 0U;
00548       break;
00549   }
00550 
00551   if (baudrate == 0U) {
00552     TraceStatus = 0U;
00553   }
00554 
00555   *response++ = (uint8_t)(baudrate >>  0);
00556   *response++ = (uint8_t)(baudrate >>  8);
00557   *response++ = (uint8_t)(baudrate >> 16);
00558   *response   = (uint8_t)(baudrate >> 24);
00559 
00560   return ((4U << 16) | 4U);
00561 }
00562 
00563 
00564 // Process SWO Control command and prepare response
00565 //   request:  pointer to request data
00566 //   response: pointer to response data
00567 //   return:   number of bytes in response (lower 16 bits)
00568 //             number of bytes in request (upper 16 bits)
00569 uint32_t SWO_Control (const uint8_t *request, uint8_t *response) {
00570   uint8_t  active;
00571   uint32_t result;
00572 
00573   active = *request & DAP_SWO_CAPTURE_ACTIVE;
00574 
00575   if (active != (TraceStatus & DAP_SWO_CAPTURE_ACTIVE)) {
00576     if (active) {
00577       ClearTrace();
00578     }
00579     switch (TraceMode) {
00580 #if (SWO_UART != 0)
00581       case DAP_SWO_UART:
00582         result = UART_SWO_Control(active);
00583         break;
00584 #endif
00585 #if (SWO_MANCHESTER != 0)
00586       case DAP_SWO_MANCHESTER:
00587         result = Manchester_SWO_Control(active);
00588         break;
00589 #endif
00590       default:
00591         result = 0U;
00592         break;
00593     }
00594     if (result != 0U) {
00595       TraceStatus = active;
00596 #if (SWO_STREAM != 0)
00597       if (TraceTransport == 2U) {
00598         osThreadFlagsSet(SWO_ThreadId, 1U);
00599       }
00600 #endif
00601     }
00602   } else {
00603     result = 1U;
00604   }
00605 
00606   if (result != 0U) {
00607     *response = DAP_OK;
00608   } else {
00609     *response = DAP_ERROR;
00610   }
00611 
00612   return ((1U << 16) | 1U);
00613 }
00614 
00615 
00616 // Process SWO Status command and prepare response
00617 //   response: pointer to response data
00618 //   return:   number of bytes in response
00619 uint32_t SWO_Status (uint8_t *response) {
00620   uint8_t  status;
00621   uint32_t count;
00622 
00623   status = GetTraceStatus();
00624   count  = GetTraceCount();
00625 
00626   *response++ = status;
00627   *response++ = (uint8_t)(count >>  0);
00628   *response++ = (uint8_t)(count >>  8);
00629   *response++ = (uint8_t)(count >> 16);
00630   *response   = (uint8_t)(count >> 24);
00631 
00632   return (5U);
00633 }
00634 
00635 
00636 // Process SWO Extended Status command and prepare response
00637 //   request:  pointer to request data
00638 //   response: pointer to response data
00639 //   return:   number of bytes in response (lower 16 bits)
00640 //             number of bytes in request (upper 16 bits)
00641 uint32_t SWO_ExtendedStatus (const uint8_t *request, uint8_t *response) {
00642   uint8_t  cmd;
00643   uint8_t  status;
00644   uint32_t count;
00645 #if (TIMESTAMP_CLOCK != 0U) 
00646   uint32_t index;
00647   uint32_t tick;
00648 #endif
00649   uint32_t num;
00650 
00651   num = 0U;
00652   cmd = *request;
00653 
00654   if (cmd & 0x01U) {
00655     status = GetTraceStatus();
00656     *response++ = status;
00657     num += 1U;
00658   }
00659 
00660   if (cmd & 0x02U) {
00661     count = GetTraceCount();
00662     *response++ = (uint8_t)(count >>  0);
00663     *response++ = (uint8_t)(count >>  8);
00664     *response++ = (uint8_t)(count >> 16);
00665     *response++ = (uint8_t)(count >> 24);
00666     num += 4U;
00667   }
00668 
00669 #if (TIMESTAMP_CLOCK != 0U) 
00670   if (cmd & 0x04U) {
00671     do {
00672       TraceUpdate = 0U;
00673       index = TraceTimestamp.index;
00674       tick  = TraceTimestamp.tick;
00675     } while (TraceUpdate != 0U);
00676     *response++ = (uint8_t)(index >>  0);
00677     *response++ = (uint8_t)(index >>  8);
00678     *response++ = (uint8_t)(index >> 16);
00679     *response++ = (uint8_t)(index >> 24);
00680     *response++ = (uint8_t)(tick  >>  0);
00681     *response++ = (uint8_t)(tick  >>  8);
00682     *response++ = (uint8_t)(tick  >> 16);
00683     *response++ = (uint8_t)(tick  >> 24);
00684     num += 4U;
00685   }
00686 #endif
00687 
00688   return ((1U << 16) | num);
00689 }
00690 
00691 
00692 // Process SWO Data command and prepare response
00693 //   request:  pointer to request data
00694 //   response: pointer to response data
00695 //   return:   number of bytes in response (lower 16 bits)
00696 //             number of bytes in request (upper 16 bits)
00697 uint32_t SWO_Data (const uint8_t *request, uint8_t *response) {
00698   uint8_t  status;
00699   uint32_t count;
00700   uint32_t index;
00701   uint32_t n, i;
00702 
00703   status = GetTraceStatus();
00704   count  = GetTraceCount();
00705 
00706   if (TraceTransport == 1U) {
00707     n = (uint32_t)(*(request+0) << 0) |
00708         (uint32_t)(*(request+1) << 8);
00709     if (n > (DAP_PACKET_SIZE - 4U)) {
00710       n = DAP_PACKET_SIZE - 4U;
00711     }
00712     if (count > n) {
00713       count = n;
00714     }
00715   } else {
00716     count = 0U;
00717   }
00718 
00719   *response++ = status;
00720   *response++ = (uint8_t)(count >> 0);
00721   *response++ = (uint8_t)(count >> 8);
00722 
00723   if (TraceTransport == 1U) {
00724     index = TraceIndexO;
00725     for (i = index, n = count; n; n--) {
00726       i &= SWO_BUFFER_SIZE - 1U;
00727       *response++ = TraceBuf[i++];
00728     }
00729     TraceIndexO = index + count;
00730     ResumeTrace();
00731   }
00732 
00733   return ((2U << 16) | (3U + count));
00734 }
00735 
00736 
00737 #if (SWO_STREAM != 0)
00738 
00739 // SWO Data Transfer complete callback
00740 void SWO_TransferComplete (void) {
00741   TraceIndexO += TransferSize;
00742   TransferBusy = 0U;
00743   ResumeTrace();
00744   osThreadFlagsSet(SWO_ThreadId, 1U);
00745 }
00746 
00747 // SWO Thread
00748 __NO_RETURN void SWO_Thread (void *argument) {
00749   uint32_t timeout;
00750   uint32_t flags;
00751   uint32_t count;
00752   uint32_t index;
00753   uint32_t i, n;
00754   (void)   argument;
00755 
00756   timeout = osWaitForever;
00757 
00758   for (;;) {
00759     flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);
00760     if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {
00761       timeout = SWO_STREAM_TIMEOUT;
00762     } else {
00763       timeout = osWaitForever;
00764       flags   = osFlagsErrorTimeout;
00765     }
00766     if (TransferBusy == 0U) {
00767       count = GetTraceCount();
00768       if (count != 0U) {
00769         index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);
00770         n = SWO_BUFFER_SIZE - index;
00771         if (count > n) {
00772           count = n;
00773         }
00774         if (flags != osFlagsErrorTimeout) {
00775           i = index & (USB_BLOCK_SIZE - 1U);
00776           if (i == 0U) {
00777             count &= ~(USB_BLOCK_SIZE - 1U);
00778           } else {
00779             n = USB_BLOCK_SIZE - i;
00780             if (count >= n) {
00781               count = n;
00782             } else {
00783               count = 0U;
00784             }
00785           }
00786         }
00787         if (count != 0U) {
00788           TransferSize = count;
00789           TransferBusy = 1U;
00790           SWO_QueueTransfer(&TraceBuf[index], count);
00791         }
00792       }
00793     }
00794   }
00795 }
00796 
00797 #endif  /* (SWO_STREAM != 0) */
00798 
00799 
00800 #endif  /* ((SWO_UART != 0) || (SWO_MANCHESTER != 0)) */