123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454 |
- /*
- * Lib(X)SVF - A library for implementing SVF and XSVF JTAG players
- *
- * Copyright (C) 2009 RIEGL Research ForschungsGmbH
- * Copyright (C) 2009 Clifford Wolf <clifford@clifford.at>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
- #include <sys/time.h>
- #include <unistd.h>
- #include <string.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <errno.h>
- #include <stdint.h>
- #include <Arduino.h>
- #include "libxsvf.h"
- #define PIN_TDI 33
- #define PIN_TDO 32
- #define PIN_TCK 27
- #define PIN_TMS 26
- static uint8_t TDI = PIN_TDI;
- static uint8_t TDO = PIN_TDO;
- static uint8_t TCK = PIN_TCK;
- static uint8_t TMS = PIN_TMS;
- /** BEGIN: Low-Level I/O Implementation **/
- static void io_setup(void)
- {
- pinMode(TCK, OUTPUT);
- pinMode(TMS, OUTPUT);
- pinMode(TDI, OUTPUT);
- pinMode(TDO, INPUT);
- }
- static void io_shutdown(void)
- {
- pinMode(TCK, INPUT);
- pinMode(TMS, INPUT);
- pinMode(TDO, INPUT);
- pinMode(TDI, INPUT);
- }
- static inline void io_tms(int val)
- {
- digitalWrite(TMS, val);
- }
- static inline void io_tdi(int val)
- {
- digitalWrite(TDI, val);
- }
- static inline void io_tck(int val)
- {
- digitalWrite(TCK, val);
- }
- static inline void io_sck(int val)
- {
- }
- static inline void io_trst(int val)
- {
- }
- static inline int io_tdo()
- {
- return digitalRead(TDO);
- }
- /** END: Low-Level I/O Implementation **/
- struct udata_s {
- int (*file_getbyte)();
- int line;
- int verbose;
- int clockcount;
- int bitcount_tdi;
- int bitcount_tdo;
- int retval_i;
- int retval[256];
- char report[256];
- uint32_t idcode;
- };
- static int h_setup(struct libxsvf_host *h)
- {
- struct udata_s *u = h->user_data;
- if (u->verbose >= 2) {
- printf("[SETUP]\n");
- }
- io_setup();
- return 0;
- }
- static int h_shutdown(struct libxsvf_host *h)
- {
- struct udata_s *u = h->user_data;
- if (u->verbose >= 2) {
- printf("[SHUTDOWN]\n");
- }
- io_shutdown();
- return 0;
- }
- static void h_udelay(struct libxsvf_host *h, long usecs, int tms, long num_tck)
- {
- struct udata_s *u = h->user_data;
- if (u->verbose >= 3) {
- printf("[DELAY:%ld, TMS:%d, NUM_TCK:%ld]\n", usecs, tms, num_tck);
- }
- if (num_tck > 0) {
- struct timeval tv1, tv2;
- gettimeofday(&tv1, NULL);
- io_tms(tms);
- while (num_tck > 0) {
- io_tck(0);
- io_tck(1);
- num_tck--;
- }
- gettimeofday(&tv2, NULL);
- if (tv2.tv_sec > tv1.tv_sec) {
- usecs -= (1000000 - tv1.tv_usec) + (tv2.tv_sec - tv1.tv_sec - 1) * 1000000;
- tv1.tv_usec = 0;
- }
- usecs -= tv2.tv_usec - tv1.tv_usec;
- if (u->verbose >= 3) {
- printf("[DELAY_AFTER_TCK:%ld]\n", usecs > 0 ? usecs : 0);
- }
- }
- if (usecs > 0) {
- delayMicroseconds(usecs);
- }
- }
- static int h_getbyte(struct libxsvf_host *h)
- {
- struct udata_s *u = h->user_data;
- int retval = u->file_getbyte();
- if(retval == '\n')
- u->line++;
- return retval; // returns same as fgetc()
- }
- static int h_pulse_tck(struct libxsvf_host *h, int tms, int tdi, int tdo, int rmask, int sync)
- {
- struct udata_s *u = h->user_data;
- io_tms(tms);
- if (tdi >= 0) {
- u->bitcount_tdi++;
- io_tdi(tdi);
- }
- io_tck(0);
- io_tck(1);
- int line_tdo = io_tdo();
- int rc = line_tdo >= 0 ? line_tdo : 0;
- if (rmask == 1 && u->retval_i < 256)
- u->retval[u->retval_i++] = line_tdo;
- if (tdo >= 0 && line_tdo >= 0) {
- u->bitcount_tdo++;
- if (tdo != line_tdo)
- rc = -1;
- }
- if (u->verbose >= 4) {
- printf("[TMS:%d, TDI:%d, TDO_ARG:%d, TDO_LINE:%d, RMASK:%d, RC:%d]\n", tms, tdi, tdo, line_tdo, rmask, rc);
- }
- u->clockcount++;
- return rc;
- }
- static void h_pulse_sck(struct libxsvf_host *h)
- {
- struct udata_s *u = h->user_data;
- if (u->verbose >= 4) {
- printf("[SCK]\n");
- }
- io_sck(0);
- io_sck(1);
- }
- static void h_set_trst(struct libxsvf_host *h, int v)
- {
- struct udata_s *u = h->user_data;
- if (u->verbose >= 4) {
- printf("[TRST:%d]\n", v);
- }
- io_trst(v);
- }
- static int h_set_frequency(struct libxsvf_host *h, int v)
- {
- //printf("WARNING: Setting JTAG clock frequency to %d ignored!\n", v);
- return 0;
- }
- static void h_report_tapstate(struct libxsvf_host *h)
- {
- struct udata_s *u = h->user_data;
- if (u->verbose >= 3) {
- printf("[%s]\n", libxsvf_state2str(h->tap_state));
- }
- }
- static void h_report_device(struct libxsvf_host *h, unsigned long idcode)
- {
- struct udata_s *u = h->user_data;
- u->idcode = idcode;
- // printf("idcode=0x%08lx, revision=0x%01lx, part=0x%04lx, manufactor=0x%03lx\n", idcode,
- // (idcode >> 28) & 0xf, (idcode >> 12) & 0xffff, (idcode >> 1) & 0x7ff);
- }
- static void h_report_status(struct libxsvf_host *h, const char *message)
- {
- struct udata_s *u = h->user_data;
- if (u->verbose >= 2) {
- printf("[STATUS] %s\n", message);
- }
- }
- static void h_report_error(struct libxsvf_host *h, const char *file, int line, const char *message)
- {
- struct udata_s *u = h->user_data;
- // snprintf(u->report, 256, "[%s:%d] %s", file, line, message);
- snprintf(u->report, 256, "line %d: %s", u->line, message);
- puts(u->report);
- // printf("[%s:%d] %s\n", file, line, message);
- }
- static int realloc_maxsize[LIBXSVF_MEM_NUM];
- static void *h_realloc(struct libxsvf_host *h, void *ptr, int size, enum libxsvf_mem which)
- {
- struct udata_s *u = h->user_data;
- if (size > realloc_maxsize[which])
- realloc_maxsize[which] = size;
- if (u->verbose >= 3) {
- printf("[REALLOC:%s:%d]\n", libxsvf_mem2str(which), size);
- }
- return realloc(ptr, size);
- }
- static struct udata_s u;
- static struct libxsvf_host h = {
- .udelay = h_udelay,
- .setup = h_setup,
- .shutdown = h_shutdown,
- .getbyte = h_getbyte,
- .pulse_tck = h_pulse_tck,
- .pulse_sck = h_pulse_sck,
- .set_trst = h_set_trst,
- .set_frequency = h_set_frequency,
- .report_tapstate = h_report_tapstate,
- .report_device = h_report_device,
- .report_status = h_report_status,
- .report_error = h_report_error,
- .realloc = h_realloc,
- .user_data = &u
- };
- #if 0
- int main(int argc, char **argv)
- {
- int rc = 0;
- int gotaction = 0;
- int hex_mode = 0;
- const char *realloc_name = NULL;
- int opt, i, j;
- progname = argc >= 1 ? argv[0] : "xvsftool";
- while ((opt = getopt(argc, argv, "r:vLBx:s:c")) != -1)
- {
- switch (opt)
- {
- case 'r':
- realloc_name = optarg;
- break;
- case 'v':
- copyleft();
- u.verbose++;
- break;
- case 'x':
- case 's':
- gotaction = 1;
- if (u.verbose)
- fprintf(stderr, "Playing %s file `%s'.\n", opt == 's' ? "SVF" : "XSVF", optarg);
- if (!strcmp(optarg, "-"))
- u.f = stdin;
- else
- u.f = fopen(optarg, "rb");
- if (u.f == NULL) {
- fprintf(stderr, "Can't open %s file `%s': %s\n", opt == 's' ? "SVF" : "XSVF", optarg, strerror(errno));
- rc = 1;
- break;
- }
- if (libxsvf_play(&h, opt == 's' ? LIBXSVF_MODE_SVF : LIBXSVF_MODE_XSVF) < 0) {
- fprintf(stderr, "Error while playing %s file `%s'.\n", opt == 's' ? "SVF" : "XSVF", optarg);
- rc = 1;
- }
- if (strcmp(optarg, "-"))
- fclose(u.f);
- break;
- case 'c':
- gotaction = 1;
- if (libxsvf_play(&h, LIBXSVF_MODE_SCAN) < 0) {
- fprintf(stderr, "Error while scanning JTAG chain.\n");
- rc = 1;
- }
- break;
- case 'L':
- hex_mode = 1;
- break;
- case 'B':
- hex_mode = 2;
- break;
- default:
- help();
- break;
- }
- }
- if (!gotaction)
- help();
- if (u.verbose) {
- fprintf(stderr, "Total number of clock cycles: %d\n", u.clockcount);
- fprintf(stderr, "Number of significant TDI bits: %d\n", u.bitcount_tdi);
- fprintf(stderr, "Number of significant TDO bits: %d\n", u.bitcount_tdo);
- if (rc == 0) {
- fprintf(stderr, "Finished without errors.\n");
- } else {
- fprintf(stderr, "Finished with errors!\n");
- }
- }
- if (u.retval_i) {
- if (hex_mode) {
- printf("0x");
- for (i=0; i < u.retval_i; i+=4) {
- int val = 0;
- for (j=i; j<i+4; j++)
- val = val << 1 | u.retval[hex_mode > 1 ? j : u.retval_i - j - 1];
- printf("%x", val);
- }
- } else {
- printf("%d rmask bits:", u.retval_i);
- for (i=0; i < u.retval_i; i++)
- printf(" %d", u.retval[i]);
- }
- printf("\n");
- }
- if (realloc_name) {
- int num = 0;
- for (i = 0; i < LIBXSVF_MEM_NUM; i++) {
- if (realloc_maxsize[i] > 0)
- num = i+1;
- }
- printf("void *%s(void *h, void *ptr, int size, int which) {\n", realloc_name);
- for (i = 0; i < num; i++) {
- if (realloc_maxsize[i] > 0)
- printf("\tstatic unsigned char buf_%s[%d];\n", libxsvf_mem2str(i), realloc_maxsize[i]);
- }
- printf("\tstatic unsigned char *buflist[%d] = {", num);
- for (i = 0; i < num; i++) {
- if (realloc_maxsize[i] > 0)
- printf("%sbuf_%s", i ? ", " : " ", libxsvf_mem2str(i));
- else
- printf("%s(void*)0", i ? ", " : " ");
- }
- printf(" };\n\tstatic int sizelist[%d] = {", num);
- for (i = 0; i < num; i++) {
- if (realloc_maxsize[i] > 0)
- printf("%ssizeof(buf_%s)", i ? ", " : " ", libxsvf_mem2str(i));
- else
- printf("%s0", i ? ", " : " ");
- }
- printf(" };\n");
- printf("\treturn which < %d && size <= sizelist[which] ? buflist[which] : (void*)0;\n", num);
- printf("};\n");
- }
- return rc;
- }
- #endif
- int xsvftool_esp_scan(void)
- {
- u.idcode = 0; // clear previous scan result
- return libxsvf_play(&h, LIBXSVF_MODE_SCAN);
- }
- // return scan result (idcode)
- uint32_t xsvftool_esp_id(void)
- {
- return u.idcode;
- }
- int xsvftool_esp_program(int (*file_getbyte)(), int x)
- {
- u.file_getbyte = file_getbyte;
- if(u.file_getbyte)
- return libxsvf_play(&h, x ? LIBXSVF_MODE_XSVF : LIBXSVF_MODE_SVF);
- return -1; // NULL file_getbyte pointer supplied
- }
- int xsvftool_esp_svf_packet(int (*packet_getbyte)(), int index, int final, char *report)
- {
- u.verbose = 0;
- u.file_getbyte = packet_getbyte;
- if(u.file_getbyte)
- {
- if(index == 0)
- u.line = 1;
- int retval = libxsvf_svf_packet(&h, index, final);
- strcpy(report, u.report);
- return retval;
- }
- return -1; // NULL file_getbyte pointer supplied
- }
- void xsvftool_esp_set_pins(uint8_t tdi, uint8_t tdo, uint8_t tck, uint8_t tms)
- {
- TDI = tdi;
- TDO = tdo;
- TCK = tck;
- TMS = tms;
- }
|