static int presto_flush(void) { if (presto->buff_out_pos == 0) return ERROR_OK; if (presto->retval < 0) { 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_open_libftdi(char *req_serial) { uint8_t presto_data; LOG_DEBUG("searching for PRESTO using libftdi"); /* initialize FTDI context structure */ if (ftdi_init(&presto->ftdic) < 0) { LOG_ERROR("unable to init libftdi: %s", presto->ftdic.error_str); return ERROR_JTAG_DEVICE_ERROR; } /* context, vendor id, product id */ if (ftdi_usb_open_desc(&presto->ftdic, PRESTO_VID, PRESTO_PID, NULL, req_serial) < 0) { LOG_ERROR("unable to open PRESTO: %s", presto->ftdic.error_str); return ERROR_JTAG_DEVICE_ERROR; } if (ftdi_usb_reset(&presto->ftdic) < 0) { LOG_ERROR("unable to reset PRESTO device"); return ERROR_JTAG_DEVICE_ERROR; } if (ftdi_set_latency_timer(&presto->ftdic, 1) < 0) { LOG_ERROR("unable to set latency timer"); return ERROR_JTAG_DEVICE_ERROR; } if (ftdi_usb_purge_buffers(&presto->ftdic) < 0) { LOG_ERROR("unable to purge PRESTO buffers"); return ERROR_JTAG_DEVICE_ERROR; } presto_data = 0xD0; if (presto_write(&presto_data, 1) != ERROR_OK) { LOG_ERROR("error writing to PRESTO"); return ERROR_JTAG_DEVICE_ERROR; } if (presto_read(&presto_data, 1) != ERROR_OK) { LOG_DEBUG("no response from PRESTO, retrying"); if (ftdi_usb_purge_buffers(&presto->ftdic) < 0) return ERROR_JTAG_DEVICE_ERROR; presto_data = 0xD0; if (presto_write(&presto_data, 1) != ERROR_OK) return ERROR_JTAG_DEVICE_ERROR; if (presto_read(&presto_data, 1) != ERROR_OK) { LOG_ERROR("no response from PRESTO, giving up"); return ERROR_JTAG_DEVICE_ERROR; } } if (presto_write(presto_init_seq, sizeof(presto_init_seq)) != ERROR_OK) { LOG_ERROR("error writing PRESTO init sequence"); return ERROR_JTAG_DEVICE_ERROR; } return ERROR_OK; }
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; }