tapsm.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. /*
  2. * Copyright (C) 2004-2007 by egnite Software GmbH
  3. * Copyright (C) 2008 by egnite GmbH
  4. *
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the distribution.
  16. * 3. Neither the name of the copyright holders nor the names of
  17. * contributors may be used to endorse or promote products derived
  18. * from this software without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  23. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  24. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  25. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  26. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  27. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  28. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  29. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  30. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31. * SUCH DAMAGE.
  32. *
  33. * For additional information see http://www.ethernut.de/
  34. * and Xilinx Application Note XAPP058.
  35. */
  36. /*
  37. * $Log$
  38. * Revision 1.1 2008/10/20 13:10:05 haraldkipp
  39. * Checked in.
  40. *
  41. */
  42. #ifdef _MSC_VER
  43. #include <winsock2.h>
  44. #endif
  45. #include "xsvf.h" /* Error codes. */
  46. #include "host.h" /* Hardware access. */
  47. #include "tapsm.h"
  48. /*!
  49. * \file tapsm.c
  50. * \brief TAP controller state handler.
  51. */
  52. /*!
  53. * \addtogroup xgTAP
  54. */
  55. /*@{*/
  56. /*!
  57. * \brief Current state of the TAP controller.
  58. */
  59. static uint8_t tapState;
  60. /*!
  61. * \brief TAP controller initialization.
  62. *
  63. * Must be called prior any other routine in this module.
  64. */
  65. void TapStateInit(void)
  66. {
  67. tapState = TEST_LOGIC_RESET;
  68. SET_TMS();
  69. }
  70. /*!
  71. * \brief State transition with TMS set to high.
  72. */
  73. static void TmsHighTransition(void)
  74. {
  75. SET_TMS();
  76. CLR_TCK();
  77. SET_TCK();
  78. }
  79. /*!
  80. * \brief State transition with TMS set to low.
  81. */
  82. static void TmsLowTransition(void)
  83. {
  84. CLR_TMS();
  85. CLR_TCK();
  86. SET_TCK();
  87. }
  88. /*!
  89. * \brief Change TAP state.
  90. *
  91. * Moves the TAP (Test Access Port) controller of the target to the
  92. * specified state.
  93. *
  94. * Trying to enter Exit2-DR or Exit2-IR from any other state except
  95. * Pause-DR or Pause-IR resp. will result in an error.
  96. *
  97. * \param state Requested TAP controller state.
  98. *
  99. * \return Zero on success, otherwise an error code is returned.
  100. */
  101. int TapStateChange(uint8_t state)
  102. {
  103. int i;
  104. int rc = 0;
  105. /*
  106. * No state change. However, XSVF expects us to terminate a Pause state.
  107. */
  108. if (state == tapState) {
  109. if (state == PAUSE_DR) {
  110. TmsHighTransition();
  111. tapState = EXIT2_DR;
  112. } else if (state == PAUSE_IR) {
  113. TmsHighTransition();
  114. tapState = EXIT2_IR;
  115. }
  116. }
  117. /*
  118. * Keeping TMS high for 5 or more consecutive state transition will put
  119. * the TAP controller in Test-Logic-Reset state.
  120. */
  121. else if (state == TEST_LOGIC_RESET) {
  122. for (i = 0; i < 5; ++i) {
  123. TmsHighTransition();
  124. }
  125. tapState = TEST_LOGIC_RESET;
  126. }
  127. /*
  128. * Check for illegal state transisiton.
  129. */
  130. else if ((state == EXIT2_DR && tapState != PAUSE_DR) || (state == EXIT2_IR && tapState != PAUSE_IR) ) {
  131. rc = XE_ILLEGALSTATE;
  132. }
  133. else {
  134. /*
  135. * Walk through the state tree until we reach the requested state.
  136. */
  137. while (rc == 0 && state != tapState) {
  138. switch (tapState) {
  139. case TEST_LOGIC_RESET:
  140. TmsLowTransition();
  141. tapState = RUN_TEST_IDLE;
  142. break;
  143. case RUN_TEST_IDLE:
  144. TmsHighTransition();
  145. tapState = SELECT_DR_SCAN;
  146. break;
  147. case SELECT_DR_SCAN:
  148. if (state >= SELECT_IR_SCAN) {
  149. TmsHighTransition();
  150. tapState = SELECT_IR_SCAN;
  151. } else {
  152. TmsLowTransition();
  153. tapState = CAPTURE_DR;
  154. }
  155. break;
  156. case CAPTURE_DR:
  157. if (state == SHIFT_DR) {
  158. TmsLowTransition();
  159. tapState = SHIFT_DR;
  160. } else {
  161. TmsHighTransition();
  162. tapState = EXIT1_DR;
  163. }
  164. break;
  165. case SHIFT_DR:
  166. TmsHighTransition();
  167. tapState = EXIT1_DR;
  168. break;
  169. case EXIT1_DR:
  170. if (state == PAUSE_DR) {
  171. TmsLowTransition();
  172. tapState = PAUSE_DR;
  173. } else {
  174. TmsHighTransition();
  175. tapState = UPDATE_DR;
  176. }
  177. break;
  178. case PAUSE_DR:
  179. TmsHighTransition();
  180. tapState = EXIT2_DR;
  181. break;
  182. case EXIT2_DR:
  183. if (state == SHIFT_DR) {
  184. TmsLowTransition();
  185. tapState = SHIFT_DR;
  186. } else {
  187. TmsHighTransition();
  188. tapState = UPDATE_DR;
  189. }
  190. break;
  191. case UPDATE_DR:
  192. if (state == RUN_TEST_IDLE) {
  193. TmsLowTransition();
  194. tapState = RUN_TEST_IDLE;
  195. } else {
  196. TmsHighTransition();
  197. tapState = SELECT_DR_SCAN;
  198. }
  199. break;
  200. case SELECT_IR_SCAN:
  201. TmsLowTransition();
  202. tapState = CAPTURE_IR;
  203. break;
  204. case CAPTURE_IR:
  205. if (state == SHIFT_IR) {
  206. TmsLowTransition();
  207. tapState = SHIFT_IR;
  208. } else {
  209. TmsHighTransition();
  210. tapState = EXIT1_IR;
  211. }
  212. break;
  213. case SHIFT_IR:
  214. TmsHighTransition();
  215. tapState = EXIT1_IR;
  216. break;
  217. case EXIT1_IR:
  218. if (state == PAUSE_IR) {
  219. TmsLowTransition();
  220. tapState = PAUSE_IR;
  221. } else {
  222. TmsHighTransition();
  223. tapState = UPDATE_IR;
  224. }
  225. break;
  226. case PAUSE_IR:
  227. TmsHighTransition();
  228. tapState = EXIT2_IR;
  229. break;
  230. case EXIT2_IR:
  231. if (state == SHIFT_IR) {
  232. TmsLowTransition();
  233. tapState = SHIFT_IR;
  234. } else {
  235. TmsHighTransition();
  236. tapState = UPDATE_IR;
  237. }
  238. break;
  239. case UPDATE_IR:
  240. if (state == RUN_TEST_IDLE) {
  241. TmsLowTransition();
  242. tapState = RUN_TEST_IDLE;
  243. } else {
  244. TmsHighTransition();
  245. tapState = SELECT_DR_SCAN;
  246. }
  247. break;
  248. default:
  249. rc = XE_ILLEGALSTATE;
  250. break;
  251. }
  252. }
  253. }
  254. return rc;
  255. }
  256. /*!
  257. * \brief Increment the TAP state.
  258. *
  259. * This routine will be used by the caller to update the
  260. * current TAP state, if the last shift included a state
  261. * transition.
  262. */
  263. void TapStateInc(void)
  264. {
  265. tapState++;
  266. }
  267. /*@}*/