SWO.c 19 KB

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