static int presto_bitq_reset(int trst, int srst) { presto_tdi_flush(); presto_tck_idle(); /* add a delay after possible TCK transition */ presto_sendbyte(0x80); presto_sendbyte(0x80); presto->jtag_rst = trst || srst; presto_sendbyte((presto->jtag_rst ? 0xEA : 0xE8) | (presto->jtag_tms ? 0x04 : 0)); return 0; }
static int presto_bitq_flush(void) { presto_tdi_flush(); presto_tck_idle(); presto_sendbyte(0xA0); /* LED idicator - JTAG idle */ return presto_flush(); }
static int presto_tck_idle(void) { if (presto->jtag_tck == 1) { presto_sendbyte(0xCA); presto->jtag_tck = 0; } return 0; }
static int presto_tdi_flush(void) { if (presto->jtag_tdi_count == 0) return 0; if (presto->jtag_tck == 0) { LOG_ERROR("BUG: unexpected TAP condition, TCK low"); return -1; } presto->jtag_tdi_data |= (presto->jtag_tdi_count - 1) << 4; presto_sendbyte(presto->jtag_tdi_data); presto->jtag_tdi_count = 0; presto->jtag_tdi_data = 0; return 0; }
static int presto_bitq_sleep(unsigned long us) { long waits; presto_tdi_flush(); presto_tck_idle(); if (us > 100000) { presto_bitq_flush(); jtag_sleep(us); return 0; } waits = us / 170 + 2; while (waits--) presto_sendbyte(0x80); return 0; }
static int presto_bitq_out(int tms, int tdi, int tdo_req) { int i; unsigned char cmd; if (presto->jtag_tck == 0) presto_sendbyte(0xA4); /* LED idicator - JTAG active */ else if (presto->jtag_speed == 0 && !tdo_req && tms == presto->jtag_tms) { presto->jtag_tdi_data |= (tdi != 0) << presto->jtag_tdi_count; if (++presto->jtag_tdi_count == 4) presto_tdi_flush(); return 0; } presto_tdi_flush(); cmd = tdi ? 0xCB : 0xCA; presto_sendbyte(cmd); if (tms != presto->jtag_tms) { presto_sendbyte((tms ? 0xEC : 0xE8) | (presto->jtag_rst ? 0x02 : 0)); presto->jtag_tms = tms; } /* delay with TCK low */ for (i = presto->jtag_speed; i > 1; i--) presto_sendbyte(cmd); cmd |= 0x04; presto_sendbyte(cmd | (tdo_req ? 0x10 : 0)); /* delay with TCK high */ for (i = presto->jtag_speed; i > 1; i--) presto_sendbyte(cmd); presto->jtag_tck = 1; return 0; }
static int presto_flush(void) { if (presto->buff_out_pos == 0) return ERROR_OK; #if BUILD_PRESTO_FTD2XX == 1 if (presto->status != FT_OK) { #elif BUILD_PRESTO_LIBFTDI == 1 if (presto->retval < 0) { #endif LOG_DEBUG("error in previous communication, canceling I/O operation"); return ERROR_JTAG_DEVICE_ERROR; } if (presto_write(presto->buff_out, presto->buff_out_pos) != ERROR_OK) { presto->buff_out_pos = 0; return ERROR_JTAG_DEVICE_ERROR; } presto->total_out += presto->buff_out_pos; presto->buff_out_pos = 0; if (presto->buff_in_exp == 0) return ERROR_OK; presto->buff_in_pos = 0; presto->buff_in_len = 0; if (presto_read(presto->buff_in, presto->buff_in_exp) != ERROR_OK) { presto->buff_in_exp = 0; return ERROR_JTAG_DEVICE_ERROR; } presto->total_in += presto->buff_in_exp; presto->buff_in_len = presto->buff_in_exp; presto->buff_in_exp = 0; return ERROR_OK; } static int presto_sendbyte(int data) { if (data == EOF) return presto_flush(); if (presto->buff_out_pos < BUFFER_SIZE) { presto->buff_out[presto->buff_out_pos++] = (uint8_t)data; if (((data & 0xC0) == 0x40) || ((data & 0xD0) == 0xD0)) presto->buff_in_exp++; } else return ERROR_JTAG_DEVICE_ERROR; #if BUILD_PRESTO_FTD2XX == 1 if (presto->buff_out_pos >= BUFFER_SIZE) #elif BUILD_PRESTO_LIBFTDI == 1 /* libftdi does not do background read, be sure that USB IN buffer does not overflow (128 *bytes only!) */ if (presto->buff_out_pos >= BUFFER_SIZE || presto->buff_in_exp == 128) #endif return presto_flush(); return ERROR_OK; } #if 0 static int presto_getbyte(void) { if (presto->buff_in_pos < presto->buff_in_len) return presto->buff_in[presto->buff_in_pos++]; if (presto->buff_in_exp == 0) return -1; if (presto_flush() != ERROR_OK) return -1; if (presto->buff_in_pos < presto->buff_in_len) return presto->buff_in[presto->buff_in_pos++]; return -1; } #endif /* -------------------------------------------------------------------------- */ static int presto_tdi_flush(void) { if (presto->jtag_tdi_count == 0) return 0; if (presto->jtag_tck == 0) { LOG_ERROR("BUG: unexpected TAP condition, TCK low"); return -1; } presto->jtag_tdi_data |= (presto->jtag_tdi_count - 1) << 4; presto_sendbyte(presto->jtag_tdi_data); presto->jtag_tdi_count = 0; presto->jtag_tdi_data = 0; return 0; } static int presto_tck_idle(void) { if (presto->jtag_tck == 1) { presto_sendbyte(0xCA); presto->jtag_tck = 0; } return 0; } /* -------------------------------------------------------------------------- */ static int presto_bitq_out(int tms, int tdi, int tdo_req) { int i; unsigned char cmd; if (presto->jtag_tck == 0) presto_sendbyte(0xA4); /* LED idicator - JTAG active */ else if (presto->jtag_speed == 0 && !tdo_req && tms == presto->jtag_tms) { presto->jtag_tdi_data |= (tdi != 0) << presto->jtag_tdi_count; if (++presto->jtag_tdi_count == 4) presto_tdi_flush(); return 0; } presto_tdi_flush(); cmd = tdi ? 0xCB : 0xCA; presto_sendbyte(cmd); if (tms != presto->jtag_tms) { presto_sendbyte((tms ? 0xEC : 0xE8) | (presto->jtag_rst ? 0x02 : 0)); presto->jtag_tms = tms; } /* delay with TCK low */ for (i = presto->jtag_speed; i > 1; i--) presto_sendbyte(cmd); cmd |= 0x04; presto_sendbyte(cmd | (tdo_req ? 0x10 : 0)); /* delay with TCK high */ for (i = presto->jtag_speed; i > 1; i--) presto_sendbyte(cmd); presto->jtag_tck = 1; return 0; }