SWO.c 19 KB

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