/ Drivers / CMSIS / DAP / Firmware / Source / SWO.c
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)) */