xsvftool-esp.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. /*
  2. * Lib(X)SVF - A library for implementing SVF and XSVF JTAG players
  3. *
  4. * Copyright (C) 2009 RIEGL Research ForschungsGmbH
  5. * Copyright (C) 2009 Clifford Wolf <clifford@clifford.at>
  6. *
  7. * Permission to use, copy, modify, and/or distribute this software for any
  8. * purpose with or without fee is hereby granted, provided that the above
  9. * copyright notice and this permission notice appear in all copies.
  10. *
  11. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  12. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  13. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  14. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  15. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  16. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  17. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  18. *
  19. */
  20. #include <sys/time.h>
  21. #include <unistd.h>
  22. #include <string.h>
  23. #include <stdlib.h>
  24. #include <stdio.h>
  25. #include <errno.h>
  26. #include <stdint.h>
  27. #include <Arduino.h>
  28. #include "libxsvf.h"
  29. #define PIN_TDI 33
  30. #define PIN_TDO 32
  31. #define PIN_TCK 27
  32. #define PIN_TMS 26
  33. static uint8_t TDI = PIN_TDI;
  34. static uint8_t TDO = PIN_TDO;
  35. static uint8_t TCK = PIN_TCK;
  36. static uint8_t TMS = PIN_TMS;
  37. /** BEGIN: Low-Level I/O Implementation **/
  38. static void io_setup(void)
  39. {
  40. pinMode(TCK, OUTPUT);
  41. pinMode(TMS, OUTPUT);
  42. pinMode(TDI, OUTPUT);
  43. pinMode(TDO, INPUT);
  44. }
  45. static void io_shutdown(void)
  46. {
  47. pinMode(TCK, INPUT);
  48. pinMode(TMS, INPUT);
  49. pinMode(TDO, INPUT);
  50. pinMode(TDI, INPUT);
  51. }
  52. static inline void io_tms(int val)
  53. {
  54. digitalWrite(TMS, val);
  55. }
  56. static inline void io_tdi(int val)
  57. {
  58. digitalWrite(TDI, val);
  59. }
  60. static inline void io_tck(int val)
  61. {
  62. digitalWrite(TCK, val);
  63. }
  64. static inline void io_sck(int val)
  65. {
  66. }
  67. static inline void io_trst(int val)
  68. {
  69. }
  70. static inline int io_tdo()
  71. {
  72. return digitalRead(TDO);
  73. }
  74. /** END: Low-Level I/O Implementation **/
  75. struct udata_s {
  76. int (*file_getbyte)();
  77. int line;
  78. int verbose;
  79. int clockcount;
  80. int bitcount_tdi;
  81. int bitcount_tdo;
  82. int retval_i;
  83. int retval[256];
  84. char report[256];
  85. uint32_t idcode;
  86. };
  87. static int h_setup(struct libxsvf_host *h)
  88. {
  89. struct udata_s *u = h->user_data;
  90. if (u->verbose >= 2) {
  91. printf("[SETUP]\n");
  92. }
  93. io_setup();
  94. return 0;
  95. }
  96. static int h_shutdown(struct libxsvf_host *h)
  97. {
  98. struct udata_s *u = h->user_data;
  99. if (u->verbose >= 2) {
  100. printf("[SHUTDOWN]\n");
  101. }
  102. io_shutdown();
  103. return 0;
  104. }
  105. static void h_udelay(struct libxsvf_host *h, long usecs, int tms, long num_tck)
  106. {
  107. struct udata_s *u = h->user_data;
  108. if (u->verbose >= 3) {
  109. printf("[DELAY:%ld, TMS:%d, NUM_TCK:%ld]\n", usecs, tms, num_tck);
  110. }
  111. if (num_tck > 0) {
  112. struct timeval tv1, tv2;
  113. gettimeofday(&tv1, NULL);
  114. io_tms(tms);
  115. while (num_tck > 0) {
  116. io_tck(0);
  117. io_tck(1);
  118. num_tck--;
  119. }
  120. gettimeofday(&tv2, NULL);
  121. if (tv2.tv_sec > tv1.tv_sec) {
  122. usecs -= (1000000 - tv1.tv_usec) + (tv2.tv_sec - tv1.tv_sec - 1) * 1000000;
  123. tv1.tv_usec = 0;
  124. }
  125. usecs -= tv2.tv_usec - tv1.tv_usec;
  126. if (u->verbose >= 3) {
  127. printf("[DELAY_AFTER_TCK:%ld]\n", usecs > 0 ? usecs : 0);
  128. }
  129. }
  130. if (usecs > 0) {
  131. delayMicroseconds(usecs);
  132. }
  133. }
  134. static int h_getbyte(struct libxsvf_host *h)
  135. {
  136. struct udata_s *u = h->user_data;
  137. int retval = u->file_getbyte();
  138. if(retval == '\n')
  139. u->line++;
  140. return retval; // returns same as fgetc()
  141. }
  142. static int h_pulse_tck(struct libxsvf_host *h, int tms, int tdi, int tdo, int rmask, int sync)
  143. {
  144. struct udata_s *u = h->user_data;
  145. io_tms(tms);
  146. if (tdi >= 0) {
  147. u->bitcount_tdi++;
  148. io_tdi(tdi);
  149. }
  150. io_tck(0);
  151. io_tck(1);
  152. int line_tdo = io_tdo();
  153. int rc = line_tdo >= 0 ? line_tdo : 0;
  154. if (rmask == 1 && u->retval_i < 256)
  155. u->retval[u->retval_i++] = line_tdo;
  156. if (tdo >= 0 && line_tdo >= 0) {
  157. u->bitcount_tdo++;
  158. if (tdo != line_tdo)
  159. rc = -1;
  160. }
  161. if (u->verbose >= 4) {
  162. printf("[TMS:%d, TDI:%d, TDO_ARG:%d, TDO_LINE:%d, RMASK:%d, RC:%d]\n", tms, tdi, tdo, line_tdo, rmask, rc);
  163. }
  164. u->clockcount++;
  165. return rc;
  166. }
  167. static void h_pulse_sck(struct libxsvf_host *h)
  168. {
  169. struct udata_s *u = h->user_data;
  170. if (u->verbose >= 4) {
  171. printf("[SCK]\n");
  172. }
  173. io_sck(0);
  174. io_sck(1);
  175. }
  176. static void h_set_trst(struct libxsvf_host *h, int v)
  177. {
  178. struct udata_s *u = h->user_data;
  179. if (u->verbose >= 4) {
  180. printf("[TRST:%d]\n", v);
  181. }
  182. io_trst(v);
  183. }
  184. static int h_set_frequency(struct libxsvf_host *h, int v)
  185. {
  186. //printf("WARNING: Setting JTAG clock frequency to %d ignored!\n", v);
  187. return 0;
  188. }
  189. static void h_report_tapstate(struct libxsvf_host *h)
  190. {
  191. struct udata_s *u = h->user_data;
  192. if (u->verbose >= 3) {
  193. printf("[%s]\n", libxsvf_state2str(h->tap_state));
  194. }
  195. }
  196. static void h_report_device(struct libxsvf_host *h, unsigned long idcode)
  197. {
  198. struct udata_s *u = h->user_data;
  199. u->idcode = idcode;
  200. // printf("idcode=0x%08lx, revision=0x%01lx, part=0x%04lx, manufactor=0x%03lx\n", idcode,
  201. // (idcode >> 28) & 0xf, (idcode >> 12) & 0xffff, (idcode >> 1) & 0x7ff);
  202. }
  203. static void h_report_status(struct libxsvf_host *h, const char *message)
  204. {
  205. struct udata_s *u = h->user_data;
  206. if (u->verbose >= 2) {
  207. printf("[STATUS] %s\n", message);
  208. }
  209. }
  210. static void h_report_error(struct libxsvf_host *h, const char *file, int line, const char *message)
  211. {
  212. struct udata_s *u = h->user_data;
  213. // snprintf(u->report, 256, "[%s:%d] %s", file, line, message);
  214. snprintf(u->report, 256, "line %d: %s", u->line, message);
  215. puts(u->report);
  216. // printf("[%s:%d] %s\n", file, line, message);
  217. }
  218. static int realloc_maxsize[LIBXSVF_MEM_NUM];
  219. static void *h_realloc(struct libxsvf_host *h, void *ptr, int size, enum libxsvf_mem which)
  220. {
  221. struct udata_s *u = h->user_data;
  222. if (size > realloc_maxsize[which])
  223. realloc_maxsize[which] = size;
  224. if (u->verbose >= 3) {
  225. printf("[REALLOC:%s:%d]\n", libxsvf_mem2str(which), size);
  226. }
  227. return realloc(ptr, size);
  228. }
  229. static struct udata_s u;
  230. static struct libxsvf_host h = {
  231. .udelay = h_udelay,
  232. .setup = h_setup,
  233. .shutdown = h_shutdown,
  234. .getbyte = h_getbyte,
  235. .pulse_tck = h_pulse_tck,
  236. .pulse_sck = h_pulse_sck,
  237. .set_trst = h_set_trst,
  238. .set_frequency = h_set_frequency,
  239. .report_tapstate = h_report_tapstate,
  240. .report_device = h_report_device,
  241. .report_status = h_report_status,
  242. .report_error = h_report_error,
  243. .realloc = h_realloc,
  244. .user_data = &u
  245. };
  246. #if 0
  247. int main(int argc, char **argv)
  248. {
  249. int rc = 0;
  250. int gotaction = 0;
  251. int hex_mode = 0;
  252. const char *realloc_name = NULL;
  253. int opt, i, j;
  254. progname = argc >= 1 ? argv[0] : "xvsftool";
  255. while ((opt = getopt(argc, argv, "r:vLBx:s:c")) != -1)
  256. {
  257. switch (opt)
  258. {
  259. case 'r':
  260. realloc_name = optarg;
  261. break;
  262. case 'v':
  263. copyleft();
  264. u.verbose++;
  265. break;
  266. case 'x':
  267. case 's':
  268. gotaction = 1;
  269. if (u.verbose)
  270. fprintf(stderr, "Playing %s file `%s'.\n", opt == 's' ? "SVF" : "XSVF", optarg);
  271. if (!strcmp(optarg, "-"))
  272. u.f = stdin;
  273. else
  274. u.f = fopen(optarg, "rb");
  275. if (u.f == NULL) {
  276. fprintf(stderr, "Can't open %s file `%s': %s\n", opt == 's' ? "SVF" : "XSVF", optarg, strerror(errno));
  277. rc = 1;
  278. break;
  279. }
  280. if (libxsvf_play(&h, opt == 's' ? LIBXSVF_MODE_SVF : LIBXSVF_MODE_XSVF) < 0) {
  281. fprintf(stderr, "Error while playing %s file `%s'.\n", opt == 's' ? "SVF" : "XSVF", optarg);
  282. rc = 1;
  283. }
  284. if (strcmp(optarg, "-"))
  285. fclose(u.f);
  286. break;
  287. case 'c':
  288. gotaction = 1;
  289. if (libxsvf_play(&h, LIBXSVF_MODE_SCAN) < 0) {
  290. fprintf(stderr, "Error while scanning JTAG chain.\n");
  291. rc = 1;
  292. }
  293. break;
  294. case 'L':
  295. hex_mode = 1;
  296. break;
  297. case 'B':
  298. hex_mode = 2;
  299. break;
  300. default:
  301. help();
  302. break;
  303. }
  304. }
  305. if (!gotaction)
  306. help();
  307. if (u.verbose) {
  308. fprintf(stderr, "Total number of clock cycles: %d\n", u.clockcount);
  309. fprintf(stderr, "Number of significant TDI bits: %d\n", u.bitcount_tdi);
  310. fprintf(stderr, "Number of significant TDO bits: %d\n", u.bitcount_tdo);
  311. if (rc == 0) {
  312. fprintf(stderr, "Finished without errors.\n");
  313. } else {
  314. fprintf(stderr, "Finished with errors!\n");
  315. }
  316. }
  317. if (u.retval_i) {
  318. if (hex_mode) {
  319. printf("0x");
  320. for (i=0; i < u.retval_i; i+=4) {
  321. int val = 0;
  322. for (j=i; j<i+4; j++)
  323. val = val << 1 | u.retval[hex_mode > 1 ? j : u.retval_i - j - 1];
  324. printf("%x", val);
  325. }
  326. } else {
  327. printf("%d rmask bits:", u.retval_i);
  328. for (i=0; i < u.retval_i; i++)
  329. printf(" %d", u.retval[i]);
  330. }
  331. printf("\n");
  332. }
  333. if (realloc_name) {
  334. int num = 0;
  335. for (i = 0; i < LIBXSVF_MEM_NUM; i++) {
  336. if (realloc_maxsize[i] > 0)
  337. num = i+1;
  338. }
  339. printf("void *%s(void *h, void *ptr, int size, int which) {\n", realloc_name);
  340. for (i = 0; i < num; i++) {
  341. if (realloc_maxsize[i] > 0)
  342. printf("\tstatic unsigned char buf_%s[%d];\n", libxsvf_mem2str(i), realloc_maxsize[i]);
  343. }
  344. printf("\tstatic unsigned char *buflist[%d] = {", num);
  345. for (i = 0; i < num; i++) {
  346. if (realloc_maxsize[i] > 0)
  347. printf("%sbuf_%s", i ? ", " : " ", libxsvf_mem2str(i));
  348. else
  349. printf("%s(void*)0", i ? ", " : " ");
  350. }
  351. printf(" };\n\tstatic int sizelist[%d] = {", num);
  352. for (i = 0; i < num; i++) {
  353. if (realloc_maxsize[i] > 0)
  354. printf("%ssizeof(buf_%s)", i ? ", " : " ", libxsvf_mem2str(i));
  355. else
  356. printf("%s0", i ? ", " : " ");
  357. }
  358. printf(" };\n");
  359. printf("\treturn which < %d && size <= sizelist[which] ? buflist[which] : (void*)0;\n", num);
  360. printf("};\n");
  361. }
  362. return rc;
  363. }
  364. #endif
  365. int xsvftool_esp_scan(void)
  366. {
  367. u.idcode = 0; // clear previous scan result
  368. return libxsvf_play(&h, LIBXSVF_MODE_SCAN);
  369. }
  370. // return scan result (idcode)
  371. uint32_t xsvftool_esp_id(void)
  372. {
  373. return u.idcode;
  374. }
  375. int xsvftool_esp_program(int (*file_getbyte)(), int x)
  376. {
  377. u.file_getbyte = file_getbyte;
  378. if(u.file_getbyte)
  379. return libxsvf_play(&h, x ? LIBXSVF_MODE_XSVF : LIBXSVF_MODE_SVF);
  380. return -1; // NULL file_getbyte pointer supplied
  381. }
  382. int xsvftool_esp_svf_packet(int (*packet_getbyte)(), int index, int final, char *report)
  383. {
  384. u.verbose = 0;
  385. u.file_getbyte = packet_getbyte;
  386. if(u.file_getbyte)
  387. {
  388. if(index == 0)
  389. u.line = 1;
  390. int retval = libxsvf_svf_packet(&h, index, final);
  391. strcpy(report, u.report);
  392. return retval;
  393. }
  394. return -1; // NULL file_getbyte pointer supplied
  395. }
  396. void xsvftool_esp_set_pins(uint8_t tdi, uint8_t tdo, uint8_t tck, uint8_t tms)
  397. {
  398. TDI = tdi;
  399. TDO = tdo;
  400. TCK = tck;
  401. TMS = tms;
  402. }