SW_DP.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. /*
  2. * Copyright (c) 2013-2016 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. * http://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: 20. May 2015
  21. * $Revision: V1.10
  22. *
  23. * Project: CMSIS-DAP Source
  24. * Title: SW_DP.c CMSIS-DAP SW DP I/O
  25. *
  26. *---------------------------------------------------------------------------*/
  27. #include "DAP_config.h"
  28. #include "DAP.h"
  29. // SW Macros
  30. #define PIN_SWCLK_SET PIN_SWCLK_TCK_SET
  31. #define PIN_SWCLK_CLR PIN_SWCLK_TCK_CLR
  32. #define SW_CLOCK_CYCLE() \
  33. PIN_SWCLK_CLR(); \
  34. PIN_DELAY(); \
  35. PIN_SWCLK_SET(); \
  36. PIN_DELAY()
  37. #define SW_WRITE_BIT(bit) \
  38. PIN_SWDIO_OUT(bit); \
  39. PIN_SWCLK_CLR(); \
  40. PIN_DELAY(); \
  41. PIN_SWCLK_SET(); \
  42. PIN_DELAY()
  43. #define SW_READ_BIT(bit) \
  44. PIN_SWCLK_CLR(); \
  45. PIN_DELAY(); \
  46. bit = PIN_SWDIO_IN(); \
  47. PIN_SWCLK_SET(); \
  48. PIN_DELAY()
  49. #define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)
  50. // Generate SWJ Sequence
  51. // count: sequence bit count
  52. // data: pointer to sequence bit data
  53. // return: none
  54. #if ((DAP_SWD != 0) || (DAP_JTAG != 0))
  55. void SWJ_Sequence (uint32_t count, const uint8_t *data) {
  56. uint32_t val;
  57. uint32_t n;
  58. val = 0U;
  59. n = 0U;
  60. while (count--) {
  61. if (n == 0U) {
  62. val = *data++;
  63. n = 8U;
  64. }
  65. if (val & 1U) {
  66. PIN_SWDIO_TMS_SET();
  67. } else {
  68. PIN_SWDIO_TMS_CLR();
  69. }
  70. SW_CLOCK_CYCLE();
  71. val >>= 1;
  72. n--;
  73. }
  74. }
  75. #endif
  76. #if (DAP_SWD != 0)
  77. // SWD Transfer I/O
  78. // request: A[3:2] RnW APnDP
  79. // data: DATA[31:0]
  80. // return: ACK[2:0]
  81. #define SWD_TransferFunction(speed) /**/ \
  82. uint8_t SWD_Transfer##speed (uint32_t request, uint32_t *data) { \
  83. uint32_t ack; \
  84. uint32_t bit; \
  85. uint32_t val; \
  86. uint32_t parity; \
  87. \
  88. uint32_t n; \
  89. \
  90. /* Packet Request */ \
  91. parity = 0U; \
  92. SW_WRITE_BIT(1U); /* Start Bit */ \
  93. bit = request >> 0; \
  94. SW_WRITE_BIT(bit); /* APnDP Bit */ \
  95. parity += bit; \
  96. bit = request >> 1; \
  97. SW_WRITE_BIT(bit); /* RnW Bit */ \
  98. parity += bit; \
  99. bit = request >> 2; \
  100. SW_WRITE_BIT(bit); /* A2 Bit */ \
  101. parity += bit; \
  102. bit = request >> 3; \
  103. SW_WRITE_BIT(bit); /* A3 Bit */ \
  104. parity += bit; \
  105. SW_WRITE_BIT(parity); /* Parity Bit */ \
  106. SW_WRITE_BIT(0U); /* Stop Bit */ \
  107. SW_WRITE_BIT(1U); /* Park Bit */ \
  108. \
  109. /* Turnaround */ \
  110. PIN_SWDIO_OUT_DISABLE(); \
  111. for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
  112. SW_CLOCK_CYCLE(); \
  113. } \
  114. \
  115. /* Acknowledge response */ \
  116. SW_READ_BIT(bit); \
  117. ack = bit << 0; \
  118. SW_READ_BIT(bit); \
  119. ack |= bit << 1; \
  120. SW_READ_BIT(bit); \
  121. ack |= bit << 2; \
  122. \
  123. if (ack == DAP_TRANSFER_OK) { /* OK response */ \
  124. /* Data transfer */ \
  125. if (request & DAP_TRANSFER_RnW) { \
  126. /* Read data */ \
  127. val = 0U; \
  128. parity = 0U; \
  129. for (n = 32U; n; n--) { \
  130. SW_READ_BIT(bit); /* Read RDATA[0:31] */ \
  131. parity += bit; \
  132. val >>= 1; \
  133. val |= bit << 31; \
  134. } \
  135. SW_READ_BIT(bit); /* Read Parity */ \
  136. if ((parity ^ bit) & 1U) { \
  137. ack = DAP_TRANSFER_ERROR; \
  138. } \
  139. if (data) { *data = val; } \
  140. /* Turnaround */ \
  141. for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
  142. SW_CLOCK_CYCLE(); \
  143. } \
  144. PIN_SWDIO_OUT_ENABLE(); \
  145. } else { \
  146. /* Turnaround */ \
  147. for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
  148. SW_CLOCK_CYCLE(); \
  149. } \
  150. PIN_SWDIO_OUT_ENABLE(); \
  151. /* Write data */ \
  152. val = *data; \
  153. parity = 0U; \
  154. for (n = 32U; n; n--) { \
  155. SW_WRITE_BIT(val); /* Write WDATA[0:31] */ \
  156. parity += val; \
  157. val >>= 1; \
  158. } \
  159. SW_WRITE_BIT(parity); /* Write Parity Bit */ \
  160. } \
  161. /* Idle cycles */ \
  162. n = DAP_Data.transfer.idle_cycles; \
  163. if (n) { \
  164. PIN_SWDIO_OUT(0U); \
  165. for (; n; n--) { \
  166. SW_CLOCK_CYCLE(); \
  167. } \
  168. } \
  169. PIN_SWDIO_OUT(1U); \
  170. return ((uint8_t)ack); \
  171. } \
  172. \
  173. if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) { \
  174. /* WAIT or FAULT response */ \
  175. if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) != 0U)) { \
  176. for (n = 32U+1U; n; n--) { \
  177. SW_CLOCK_CYCLE(); /* Dummy Read RDATA[0:31] + Parity */ \
  178. } \
  179. } \
  180. /* Turnaround */ \
  181. for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
  182. SW_CLOCK_CYCLE(); \
  183. } \
  184. PIN_SWDIO_OUT_ENABLE(); \
  185. if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) == 0U)) { \
  186. PIN_SWDIO_OUT(0U); \
  187. for (n = 32U+1U; n; n--) { \
  188. SW_CLOCK_CYCLE(); /* Dummy Write WDATA[0:31] + Parity */ \
  189. } \
  190. } \
  191. PIN_SWDIO_OUT(1U); \
  192. return ((uint8_t)ack); \
  193. } \
  194. \
  195. /* Protocol error */ \
  196. for (n = DAP_Data.swd_conf.turnaround + 32U + 1U; n; n--) { \
  197. SW_CLOCK_CYCLE(); /* Back off data phase */ \
  198. } \
  199. PIN_SWDIO_OUT_ENABLE(); \
  200. PIN_SWDIO_OUT(1U); \
  201. return ((uint8_t)ack); \
  202. }
  203. #undef PIN_DELAY
  204. #define PIN_DELAY() PIN_DELAY_FAST()
  205. SWD_TransferFunction(Fast);
  206. #undef PIN_DELAY
  207. #define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)
  208. SWD_TransferFunction(Slow);
  209. // SWD Transfer I/O
  210. // request: A[3:2] RnW APnDP
  211. // data: DATA[31:0]
  212. // return: ACK[2:0]
  213. uint8_t SWD_Transfer(uint32_t request, uint32_t *data) {
  214. if (DAP_Data.fast_clock) {
  215. return SWD_TransferFast(request, data);
  216. } else {
  217. return SWD_TransferSlow(request, data);
  218. }
  219. }
  220. #endif /* (DAP_SWD != 0) */