You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

724 lines
20 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2011 by Martin Schmoelzer *
  3. * <martin.schmoelzer@student.tuwien.ac.at> *
  4. * *
  5. * This program is free software; you can redistribute it and/or modify *
  6. * it under the terms of the GNU General Public License as published by *
  7. * the Free Software Foundation; either version 2 of the License, or *
  8. * (at your option) any later version. *
  9. * *
  10. * This program is distributed in the hope that it will be useful, *
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  13. * GNU General Public License for more details. *
  14. * *
  15. * You should have received a copy of the GNU General Public License *
  16. * along with this program; if not, write to the *
  17. * Free Software Foundation, Inc., *
  18. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  19. ***************************************************************************/
  20. #include "jtag.h"
  21. #include "io.h"
  22. #include "msgtypes.h"
  23. #include "common.h"
  24. #include <stdbool.h>
  25. /** Delay value for SCAN_IN operations with less than maximum TCK frequency */
  26. uint8_t delay_scan_in;
  27. /** Delay value for SCAN_OUT operations with less than maximum TCK frequency */
  28. uint8_t delay_scan_out;
  29. /** Delay value for SCAN_IO operations with less than maximum TCK frequency */
  30. uint8_t delay_scan_io;
  31. /** Delay value for CLOCK_TCK operations with less than maximum frequency */
  32. uint8_t delay_tck;
  33. /** Delay value for CLOCK_TMS operations with less than maximum frequency */
  34. uint8_t delay_tms;
  35. /**
  36. * Perform JTAG SCAN-IN operation at maximum TCK frequency.
  37. *
  38. * Dummy data is shifted into the JTAG chain via TDI, TDO data is sampled and
  39. * stored in the EP2 IN buffer.
  40. *
  41. * Maximum achievable TCK frequency is 182 kHz for ULINK clocked at 24 MHz.
  42. *
  43. * @param out_offset offset in OUT2BUF where payload data starts
  44. */
  45. void jtag_scan_in(uint8_t out_offset, uint8_t in_offset)
  46. {
  47. uint8_t scan_size_bytes, bits_last_byte;
  48. uint8_t tms_count_start, tms_count_end;
  49. uint8_t tms_sequence_start, tms_sequence_end;
  50. uint8_t tdo_data, i, j;
  51. uint8_t outb_buffer;
  52. /* Get parameters from OUT2BUF */
  53. scan_size_bytes = OUT2BUF[out_offset];
  54. bits_last_byte = OUT2BUF[out_offset + 1];
  55. tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;
  56. tms_count_end = OUT2BUF[out_offset + 2] & 0x0F;
  57. tms_sequence_start = OUT2BUF[out_offset + 3];
  58. tms_sequence_end = OUT2BUF[out_offset + 4];
  59. if (tms_count_start > 0)
  60. jtag_clock_tms(tms_count_start, tms_sequence_start);
  61. outb_buffer = OUTB & ~(PIN_TDI | PIN_TCK | PIN_TMS);
  62. /* Shift all bytes except the last byte */
  63. for (i = 0; i < scan_size_bytes - 1; i++) {
  64. tdo_data = 0;
  65. for (j = 0; j < 8; j++) {
  66. OUTB = outb_buffer; /* TCK changes here */
  67. tdo_data = tdo_data >> 1;
  68. OUTB = (outb_buffer | PIN_TCK);
  69. if (GET_TDO())
  70. tdo_data |= 0x80;
  71. }
  72. /* Copy TDO data to IN2BUF */
  73. IN2BUF[i + in_offset] = tdo_data;
  74. }
  75. tdo_data = 0;
  76. /* Shift the last byte */
  77. for (j = 0; j < bits_last_byte; j++) {
  78. /* Assert TMS signal if requested and this is the last bit */
  79. if ((j == bits_last_byte - 1) && (tms_count_end > 0)) {
  80. outb_buffer |= PIN_TMS;
  81. tms_count_end--;
  82. tms_sequence_end = tms_sequence_end >> 1;
  83. }
  84. OUTB = outb_buffer; /* TCK change here */
  85. tdo_data = tdo_data >> 1;
  86. OUTB = (outb_buffer | PIN_TCK);
  87. if (GET_TDO())
  88. tdo_data |= 0x80;
  89. }
  90. tdo_data = tdo_data >> (8 - bits_last_byte);
  91. /* Copy TDO data to IN2BUF */
  92. IN2BUF[i + in_offset] = tdo_data;
  93. /* Move to correct end state */
  94. if (tms_count_end > 0)
  95. jtag_clock_tms(tms_count_end, tms_sequence_end);
  96. }
  97. /**
  98. * Perform JTAG SCAN-IN operation at variable TCK frequency.
  99. *
  100. * Dummy data is shifted into the JTAG chain via TDI, TDO data is sampled and
  101. * stored in the EP2 IN buffer.
  102. *
  103. * Maximum achievable TCK frequency is 113 kHz for ULINK clocked at 24 MHz.
  104. *
  105. * @param out_offset offset in OUT2BUF where payload data starts
  106. */
  107. void jtag_slow_scan_in(uint8_t out_offset, uint8_t in_offset)
  108. {
  109. uint8_t scan_size_bytes, bits_last_byte;
  110. uint8_t tms_count_start, tms_count_end;
  111. uint8_t tms_sequence_start, tms_sequence_end;
  112. uint8_t tdo_data, i, j, k;
  113. uint8_t outb_buffer;
  114. /* Get parameters from OUT2BUF */
  115. scan_size_bytes = OUT2BUF[out_offset];
  116. bits_last_byte = OUT2BUF[out_offset + 1];
  117. tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;
  118. tms_count_end = OUT2BUF[out_offset + 2] & 0x0F;
  119. tms_sequence_start = OUT2BUF[out_offset + 3];
  120. tms_sequence_end = OUT2BUF[out_offset + 4];
  121. if (tms_count_start > 0)
  122. jtag_slow_clock_tms(tms_count_start, tms_sequence_start);
  123. outb_buffer = OUTB & ~(PIN_TDI | PIN_TCK | PIN_TMS);
  124. /* Shift all bytes except the last byte */
  125. for (i = 0; i < scan_size_bytes - 1; i++) {
  126. tdo_data = 0;
  127. for (j = 0; j < 8; j++) {
  128. OUTB = outb_buffer; /* TCK changes here */
  129. for (k = 0; k < delay_scan_in; k++)
  130. ;
  131. tdo_data = tdo_data >> 1;
  132. OUTB = (outb_buffer | PIN_TCK);
  133. for (k = 0; k < delay_scan_in; k++)
  134. ;
  135. if (GET_TDO())
  136. tdo_data |= 0x80;
  137. }
  138. /* Copy TDO data to IN2BUF */
  139. IN2BUF[i + in_offset] = tdo_data;
  140. }
  141. tdo_data = 0;
  142. /* Shift the last byte */
  143. for (j = 0; j < bits_last_byte; j++) {
  144. /* Assert TMS signal if requested and this is the last bit */
  145. if ((j == bits_last_byte - 1) && (tms_count_end > 0)) {
  146. outb_buffer |= PIN_TMS;
  147. tms_count_end--;
  148. tms_sequence_end = tms_sequence_end >> 1;
  149. }
  150. OUTB = outb_buffer; /* TCK change here */
  151. for (k = 0; k < delay_scan_in; k++)
  152. ;
  153. tdo_data = tdo_data >> 1;
  154. OUTB = (outb_buffer | PIN_TCK);
  155. for (k = 0; k < delay_scan_in; k++)
  156. ;
  157. if (GET_TDO())
  158. tdo_data |= 0x80;
  159. }
  160. tdo_data = tdo_data >> (8 - bits_last_byte);
  161. /* Copy TDO data to IN2BUF */
  162. IN2BUF[i + in_offset] = tdo_data;
  163. /* Move to correct end state */
  164. if (tms_count_end > 0)
  165. jtag_slow_clock_tms(tms_count_end, tms_sequence_end);
  166. }
  167. /**
  168. * Perform JTAG SCAN-OUT operation at maximum TCK frequency.
  169. *
  170. * Data stored in EP2 OUT buffer is shifted into the JTAG chain via TDI, TDO
  171. * data is not sampled.
  172. * The TAP-FSM state is alyways left in the PAUSE-DR/PAUSE-IR state.
  173. *
  174. * Maximum achievable TCK frequency is 142 kHz for ULINK clocked at 24 MHz.
  175. *
  176. * @param out_offset offset in OUT2BUF where payload data starts
  177. */
  178. void jtag_scan_out(uint8_t out_offset)
  179. {
  180. uint8_t scan_size_bytes, bits_last_byte;
  181. uint8_t tms_count_start, tms_count_end;
  182. uint8_t tms_sequence_start, tms_sequence_end;
  183. uint8_t tdi_data, i, j;
  184. uint8_t outb_buffer;
  185. /* Get parameters from OUT2BUF */
  186. scan_size_bytes = OUT2BUF[out_offset];
  187. bits_last_byte = OUT2BUF[out_offset + 1];
  188. tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;
  189. tms_count_end = OUT2BUF[out_offset + 2] & 0x0F;
  190. tms_sequence_start = OUT2BUF[out_offset + 3];
  191. tms_sequence_end = OUT2BUF[out_offset + 4];
  192. if (tms_count_start > 0)
  193. jtag_clock_tms(tms_count_start, tms_sequence_start);
  194. outb_buffer = OUTB & ~(PIN_TCK | PIN_TMS);
  195. /* Shift all bytes except the last byte */
  196. for (i = 0; i < scan_size_bytes - 1; i++) {
  197. tdi_data = OUT2BUF[i + out_offset + 5];
  198. for (j = 0; j < 8; j++) {
  199. if (tdi_data & 0x01)
  200. outb_buffer |= PIN_TDI;
  201. else
  202. outb_buffer &= ~PIN_TDI;
  203. OUTB = outb_buffer; /* TDI and TCK change here */
  204. tdi_data = tdi_data >> 1;
  205. OUTB = (outb_buffer | PIN_TCK);
  206. }
  207. }
  208. tdi_data = OUT2BUF[i + out_offset + 5];
  209. /* Shift the last byte */
  210. for (j = 0; j < bits_last_byte; j++) {
  211. if (tdi_data & 0x01)
  212. outb_buffer |= PIN_TDI;
  213. else
  214. outb_buffer &= ~PIN_TDI;
  215. /* Assert TMS signal if requested and this is the last bit */
  216. if ((j == bits_last_byte - 1) && (tms_count_end > 0)) {
  217. outb_buffer |= PIN_TMS;
  218. tms_count_end--;
  219. tms_sequence_end = tms_sequence_end >> 1;
  220. }
  221. OUTB = outb_buffer; /* TDI and TCK change here */
  222. tdi_data = tdi_data >> 1;
  223. OUTB = (outb_buffer | PIN_TCK);
  224. }
  225. /* Move to correct end state */
  226. if (tms_count_end > 0)
  227. jtag_clock_tms(tms_count_end, tms_sequence_end);
  228. }
  229. /**
  230. * Perform JTAG SCAN-OUT operation at maximum TCK frequency.
  231. *
  232. * Data stored in EP2 OUT buffer is shifted into the JTAG chain via TDI, TDO
  233. * data is not sampled.
  234. * The TAP-FSM state is alyways left in the PAUSE-DR/PAUSE-IR state.
  235. *
  236. * Maximum achievable TCK frequency is 97 kHz for ULINK clocked at 24 MHz.
  237. *
  238. * @param out_offset offset in OUT2BUF where payload data starts
  239. */
  240. void jtag_slow_scan_out(uint8_t out_offset)
  241. {
  242. uint8_t scan_size_bytes, bits_last_byte;
  243. uint8_t tms_count_start, tms_count_end;
  244. uint8_t tms_sequence_start, tms_sequence_end;
  245. uint8_t tdi_data, i, j, k;
  246. uint8_t outb_buffer;
  247. /* Get parameters from OUT2BUF */
  248. scan_size_bytes = OUT2BUF[out_offset];
  249. bits_last_byte = OUT2BUF[out_offset + 1];
  250. tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;
  251. tms_count_end = OUT2BUF[out_offset + 2] & 0x0F;
  252. tms_sequence_start = OUT2BUF[out_offset + 3];
  253. tms_sequence_end = OUT2BUF[out_offset + 4];
  254. if (tms_count_start > 0)
  255. jtag_slow_clock_tms(tms_count_start, tms_sequence_start);
  256. outb_buffer = OUTB & ~(PIN_TCK | PIN_TMS);
  257. /* Shift all bytes except the last byte */
  258. for (i = 0; i < scan_size_bytes - 1; i++) {
  259. tdi_data = OUT2BUF[i + out_offset + 5];
  260. for (j = 0; j < 8; j++) {
  261. if (tdi_data & 0x01)
  262. outb_buffer |= PIN_TDI;
  263. else
  264. outb_buffer &= ~PIN_TDI;
  265. OUTB = outb_buffer; /* TDI and TCK change here */
  266. for (k = 0; k < delay_scan_out; k++)
  267. ;
  268. tdi_data = tdi_data >> 1;
  269. OUTB = (outb_buffer | PIN_TCK);
  270. for (k = 0; k < delay_scan_out; k++)
  271. ;
  272. }
  273. }
  274. tdi_data = OUT2BUF[i + out_offset + 5];
  275. /* Shift the last byte */
  276. for (j = 0; j < bits_last_byte; j++) {
  277. if (tdi_data & 0x01)
  278. outb_buffer |= PIN_TDI;
  279. else
  280. outb_buffer &= ~PIN_TDI;
  281. /* Assert TMS signal if requested and this is the last bit */
  282. if ((j == bits_last_byte - 1) && (tms_count_end > 0)) {
  283. outb_buffer |= PIN_TMS;
  284. tms_count_end--;
  285. tms_sequence_end = tms_sequence_end >> 1;
  286. }
  287. OUTB = outb_buffer; /* TDI and TCK change here */
  288. for (k = 0; k < delay_scan_out; k++)
  289. ;
  290. tdi_data = tdi_data >> 1;
  291. OUTB = (outb_buffer | PIN_TCK);
  292. for (k = 0; k < delay_scan_out; k++)
  293. ;
  294. }
  295. /* Move to correct end state */
  296. if (tms_count_end > 0)
  297. jtag_slow_clock_tms(tms_count_end, tms_sequence_end);
  298. }
  299. /**
  300. * Perform bidirectional JTAG SCAN operation at maximum TCK frequency.
  301. *
  302. * Data stored in EP2 OUT buffer is shifted into the JTAG chain via TDI, TDO
  303. * data is sampled and stored in the EP2 IN buffer.
  304. * The TAP-FSM state is alyways left in the PAUSE-DR/PAUSE-IR state.
  305. *
  306. * Maximum achievable TCK frequency is 100 kHz for ULINK clocked at 24 MHz.
  307. *
  308. * @param out_offset offset in OUT2BUF where payload data starts
  309. */
  310. void jtag_scan_io(uint8_t out_offset, uint8_t in_offset)
  311. {
  312. uint8_t scan_size_bytes, bits_last_byte;
  313. uint8_t tms_count_start, tms_count_end;
  314. uint8_t tms_sequence_start, tms_sequence_end;
  315. uint8_t tdi_data, tdo_data, i, j;
  316. uint8_t outb_buffer;
  317. /* Get parameters from OUT2BUF */
  318. scan_size_bytes = OUT2BUF[out_offset];
  319. bits_last_byte = OUT2BUF[out_offset + 1];
  320. tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;
  321. tms_count_end = OUT2BUF[out_offset + 2] & 0x0F;
  322. tms_sequence_start = OUT2BUF[out_offset + 3];
  323. tms_sequence_end = OUT2BUF[out_offset + 4];
  324. if (tms_count_start > 0)
  325. jtag_clock_tms(tms_count_start, tms_sequence_start);
  326. outb_buffer = OUTB & ~(PIN_TCK | PIN_TMS);
  327. /* Shift all bytes except the last byte */
  328. for (i = 0; i < scan_size_bytes - 1; i++) {
  329. tdi_data = OUT2BUF[i + out_offset + 5];
  330. tdo_data = 0;
  331. for (j = 0; j < 8; j++) {
  332. if (tdi_data & 0x01)
  333. outb_buffer |= PIN_TDI;
  334. else
  335. outb_buffer &= ~PIN_TDI;
  336. OUTB = outb_buffer; /* TDI and TCK change here */
  337. tdi_data = tdi_data >> 1;
  338. OUTB = (outb_buffer | PIN_TCK);
  339. tdo_data = tdo_data >> 1;
  340. if (GET_TDO())
  341. tdo_data |= 0x80;
  342. }
  343. /* Copy TDO data to IN2BUF */
  344. IN2BUF[i + in_offset] = tdo_data;
  345. }
  346. tdi_data = OUT2BUF[i + out_offset + 5];
  347. tdo_data = 0;
  348. /* Shift the last byte */
  349. for (j = 0; j < bits_last_byte; j++) {
  350. if (tdi_data & 0x01)
  351. outb_buffer |= PIN_TDI;
  352. else
  353. outb_buffer &= ~PIN_TDI;
  354. /* Assert TMS signal if requested and this is the last bit */
  355. if ((j == bits_last_byte - 1) && (tms_count_end > 0)) {
  356. outb_buffer |= PIN_TMS;
  357. tms_count_end--;
  358. tms_sequence_end = tms_sequence_end >> 1;
  359. }
  360. OUTB = outb_buffer; /* TDI and TCK change here */
  361. tdi_data = tdi_data >> 1;
  362. OUTB = (outb_buffer | PIN_TCK);
  363. tdo_data = tdo_data >> 1;
  364. if (GET_TDO())
  365. tdo_data |= 0x80;
  366. }
  367. tdo_data = tdo_data >> (8 - bits_last_byte);
  368. /* Copy TDO data to IN2BUF */
  369. IN2BUF[i + in_offset] = tdo_data;
  370. /* Move to correct end state */
  371. if (tms_count_end > 0)
  372. jtag_clock_tms(tms_count_end, tms_sequence_end);
  373. }
  374. /**
  375. * Perform bidirectional JTAG SCAN operation at maximum TCK frequency.
  376. *
  377. * Data stored in EP2 OUT buffer is shifted into the JTAG chain via TDI, TDO
  378. * data is sampled and stored in the EP2 IN buffer.
  379. * The TAP-FSM state is alyways left in the PAUSE-DR/PAUSE-IR state.
  380. *
  381. * Maximum achievable TCK frequency is 78 kHz for ULINK clocked at 24 MHz.
  382. *
  383. * @param out_offset offset in OUT2BUF where payload data starts
  384. */
  385. void jtag_slow_scan_io(uint8_t out_offset, uint8_t in_offset)
  386. {
  387. uint8_t scan_size_bytes, bits_last_byte;
  388. uint8_t tms_count_start, tms_count_end;
  389. uint8_t tms_sequence_start, tms_sequence_end;
  390. uint8_t tdi_data, tdo_data, i, j, k;
  391. uint8_t outb_buffer;
  392. /* Get parameters from OUT2BUF */
  393. scan_size_bytes = OUT2BUF[out_offset];
  394. bits_last_byte = OUT2BUF[out_offset + 1];
  395. tms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;
  396. tms_count_end = OUT2BUF[out_offset + 2] & 0x0F;
  397. tms_sequence_start = OUT2BUF[out_offset + 3];
  398. tms_sequence_end = OUT2BUF[out_offset + 4];
  399. if (tms_count_start > 0)
  400. jtag_slow_clock_tms(tms_count_start, tms_sequence_start);
  401. outb_buffer = OUTB & ~(PIN_TCK | PIN_TMS);
  402. /* Shift all bytes except the last byte */
  403. for (i = 0; i < scan_size_bytes - 1; i++) {
  404. tdi_data = OUT2BUF[i + out_offset + 5];
  405. tdo_data = 0;
  406. for (j = 0; j < 8; j++) {
  407. if (tdi_data & 0x01)
  408. outb_buffer |= PIN_TDI;
  409. else
  410. outb_buffer &= ~PIN_TDI;
  411. OUTB = outb_buffer; /* TDI and TCK change here */
  412. for (k = 0; k < delay_scan_io; k++)
  413. ;
  414. tdi_data = tdi_data >> 1;
  415. OUTB = (outb_buffer | PIN_TCK);
  416. for (k = 0; k < delay_scan_io; k++)
  417. ;
  418. tdo_data = tdo_data >> 1;
  419. if (GET_TDO())
  420. tdo_data |= 0x80;
  421. }
  422. /* Copy TDO data to IN2BUF */
  423. IN2BUF[i + in_offset] = tdo_data;
  424. }
  425. tdi_data = OUT2BUF[i + out_offset + 5];
  426. tdo_data = 0;
  427. /* Shift the last byte */
  428. for (j = 0; j < bits_last_byte; j++) {
  429. if (tdi_data & 0x01)
  430. outb_buffer |= PIN_TDI;
  431. else
  432. outb_buffer &= ~PIN_TDI;
  433. /* Assert TMS signal if requested and this is the last bit */
  434. if ((j == bits_last_byte - 1) && (tms_count_end > 0)) {
  435. outb_buffer |= PIN_TMS;
  436. tms_count_end--;
  437. tms_sequence_end = tms_sequence_end >> 1;
  438. }
  439. OUTB = outb_buffer; /* TDI and TCK change here */
  440. for (k = 0; k < delay_scan_io; k++)
  441. ;
  442. tdi_data = tdi_data >> 1;
  443. OUTB = (outb_buffer | PIN_TCK);
  444. for (k = 0; k < delay_scan_io; k++)
  445. ;
  446. tdo_data = tdo_data >> 1;
  447. if (GET_TDO())
  448. tdo_data |= 0x80;
  449. }
  450. tdo_data = tdo_data >> (8 - bits_last_byte);
  451. /* Copy TDO data to IN2BUF */
  452. IN2BUF[i + in_offset] = tdo_data;
  453. /* Move to correct end state */
  454. if (tms_count_end > 0)
  455. jtag_slow_clock_tms(tms_count_end, tms_sequence_end);
  456. }
  457. /**
  458. * Generate TCK clock cycles.
  459. *
  460. * Maximum achievable TCK frequency is 375 kHz for ULINK clocked at 24 MHz.
  461. *
  462. * @param count number of TCK clock cyclces to generate.
  463. */
  464. void jtag_clock_tck(uint16_t count)
  465. {
  466. uint16_t i;
  467. uint8_t outb_buffer = OUTB & ~(PIN_TCK);
  468. for (i = 0; i < count; i++) {
  469. OUTB = outb_buffer;
  470. OUTB = outb_buffer | PIN_TCK;
  471. }
  472. }
  473. /**
  474. * Generate TCK clock cycles at variable frequency.
  475. *
  476. * Maximum achieveable TCK frequency is 166.6 kHz for ULINK clocked at 24 MHz.
  477. *
  478. * @param count number of TCK clock cyclces to generate.
  479. */
  480. void jtag_slow_clock_tck(uint16_t count)
  481. {
  482. uint16_t i;
  483. uint8_t j;
  484. uint8_t outb_buffer = OUTB & ~(PIN_TCK);
  485. for (i = 0; i < count; i++) {
  486. OUTB = outb_buffer;
  487. for (j = 0; j < delay_tck; j++)
  488. ;
  489. OUTB = outb_buffer | PIN_TCK;
  490. for (j = 0; j < delay_tck; j++)
  491. ;
  492. }
  493. }
  494. /**
  495. * Perform TAP FSM state transitions at maximum TCK frequency.
  496. *
  497. * Maximum achievable TCK frequency is 176 kHz for ULINK clocked at 24 MHz.
  498. *
  499. * @param count the number of state transitions to perform.
  500. * @param sequence the TMS pin levels for each state transition, starting with
  501. * the least-significant bit.
  502. */
  503. void jtag_clock_tms(uint8_t count, uint8_t sequence)
  504. {
  505. uint8_t outb_buffer = OUTB & ~(PIN_TCK);
  506. uint8_t i;
  507. for (i = 0; i < count; i++) {
  508. /* Set TMS pin according to sequence parameter */
  509. if (sequence & 0x1)
  510. outb_buffer |= PIN_TMS;
  511. else
  512. outb_buffer &= ~PIN_TMS;
  513. OUTB = outb_buffer;
  514. sequence = sequence >> 1;
  515. OUTB = outb_buffer | PIN_TCK;
  516. }
  517. }
  518. /**
  519. * Perform TAP-FSM state transitions at less than maximum TCK frequency.
  520. *
  521. * Maximum achievable TCK frequency is 117 kHz for ULINK clocked at 24 MHz.
  522. *
  523. * @param count the number of state transitions to perform.
  524. * @param sequence the TMS pin levels for each state transition, starting with
  525. * the least-significant bit.
  526. */
  527. void jtag_slow_clock_tms(uint8_t count, uint8_t sequence)
  528. {
  529. uint8_t outb_buffer = OUTB & ~(PIN_TCK);
  530. uint8_t i, j;
  531. for (i = 0; i < count; i++) {
  532. /* Set TMS pin according to sequence parameter */
  533. if (sequence & 0x1)
  534. outb_buffer |= PIN_TMS;
  535. else
  536. outb_buffer &= ~PIN_TMS;
  537. OUTB = outb_buffer;
  538. for (j = 0; j < delay_tms; j++)
  539. ;
  540. sequence = sequence >> 1;
  541. OUTB = outb_buffer | PIN_TCK;
  542. for (j = 0; j < delay_tms; j++)
  543. ;
  544. }
  545. }
  546. /**
  547. * Get current JTAG signal states.
  548. *
  549. * @return a 16-bit integer where the most-significant byte contains the state
  550. * of the JTAG input signals and the least-significant byte cotains the state
  551. * of the JTAG output signals.
  552. */
  553. uint16_t jtag_get_signals(void)
  554. {
  555. uint8_t input_signal_state, output_signal_state;
  556. input_signal_state = 0;
  557. output_signal_state = 0;
  558. /* Get states of input pins */
  559. if (GET_TDO())
  560. input_signal_state |= SIGNAL_TDO;
  561. if (GET_BRKOUT())
  562. input_signal_state |= SIGNAL_BRKOUT;
  563. if (GET_TRAP())
  564. input_signal_state |= SIGNAL_TRAP;
  565. if (GET_RTCK()) {
  566. /* Using RTCK this way would be extremely slow,
  567. * implemented only for the sake of completeness */
  568. input_signal_state |= SIGNAL_RTCK;
  569. }
  570. /* Get states of output pins */
  571. output_signal_state = PINSB & MASK_PORTB_DIRECTION_OUT;
  572. return ((uint16_t)input_signal_state << 8) | ((uint16_t)output_signal_state);
  573. }
  574. /**
  575. * Set state of JTAG output signals.
  576. *
  577. * @param low signals which should be de-asserted.
  578. * @param high signals which should be asserted.
  579. */
  580. void jtag_set_signals(uint8_t low, uint8_t high)
  581. {
  582. OUTB &= ~(low & MASK_PORTB_DIRECTION_OUT);
  583. OUTB |= (high & MASK_PORTB_DIRECTION_OUT);
  584. }
  585. /**
  586. * Configure TCK delay parameters.
  587. *
  588. * @param scan_in number of delay cycles in scan_in operations.
  589. * @param scan_out number of delay cycles in scan_out operations.
  590. * @param scan_io number of delay cycles in scan_io operations.
  591. * @param tck number of delay cycles in clock_tck operations.
  592. * @param tms number of delay cycles in clock_tms operations.
  593. */
  594. void jtag_configure_tck_delay(uint8_t scan_in, uint8_t scan_out,
  595. uint8_t scan_io, uint8_t tck, uint8_t tms)
  596. {
  597. delay_scan_in = scan_in;
  598. delay_scan_out = scan_out;
  599. delay_scan_io = scan_io;
  600. delay_tck = tck;
  601. delay_tms = tms;
  602. }