int cable_usbblaster_inout(uint8_t value, uint8_t *in_bit) { int rv; // to catch return values of functions char ret[3] = {0,0,0}; // Two useless bytes (0x31,0x60) always precede the useful byte char out; out = (USBBLASTER_CMD_OE | USBBLASTER_CMD_nCS); // Set output enable (?) and nCS (necessary for byte-shift reads) out |= USBBLASTER_CMD_READ; // Translate to USB blaster protocol // USB-Blaster has no TRST pin if(value & TCLK_BIT) out |= USBBLASTER_CMD_TCK; if(value & TDI_BIT) out |= USBBLASTER_CMD_TDI; if(value & TMS_BIT) out |= USBBLASTER_CMD_TMS; // open the device, if necessary if(h_device == NULL) { rv = cable_usbblaster_open_cable(); if(rv != APP_ERR_NONE) return rv; } // Send a read request rv = usb_bulk_write(h_device, EP2, &out, 1, USB_TIMEOUT); if (rv != 1){ fprintf(stderr, "\nFailed to write a read request to the EP2 FIFO:\n%s", usb_strerror()); cable_usbblaster_close_cable(); return APP_ERR_USB; } // receive the response // Sometimes, we do a read but just get the useless 0x31,0x60 chars... // retry until we get a 3rd byte (with real data), for a reasonable number of retries. int retries = 0; do { rv = usb_bulk_read(h_device, EP1, ret, 3, USB_TIMEOUT); if (rv < 0){ fprintf(stderr, "\nFailed to read from the EP1 FIFO (%i):\n%s", rv, usb_strerror()); cable_usbblaster_close_cable(); return APP_ERR_USB; } // fprintf(stderr, "Read %i bytes: 0x%X, 0x%X, 0x%X\n", rv, ret[0], ret[1], ret[2]); retries++; } while((rv < 3) && (retries < 20)); *in_bit = (ret[2] & 0x01); /* TDO is bit 0. USB-Blaster may also set bit 1. */ return APP_ERR_NONE; }
int cable_usbblaster_read_stream ( const uint32_t * const outstream, uint32_t * const instream, const int len_bits, const int set_last_bit ) { int rv; // to catch return values of functions unsigned int bytes_received = 0, total_bytes_received = 0; unsigned int bytes_to_transfer, leftover_bit_length; uint32_t leftover_bits, leftovers_received = 0; unsigned char i; int bytes_remaining; const char *xfer_ptr; int retval = APP_ERR_NONE; debug("cable_usbblaster_read_stream(0x%X, %d, %i)\n", outstream[0], len_bits, set_last_bit); // This routine must transfer at least 8 bits. Additionally, TMS (the last bit) // cannot be set by 'byte shift mode'. So we need at least 8 bits to transfer, // plus one bit to send along with TMS. bytes_to_transfer = len_bits / 8; leftover_bit_length = len_bits - (bytes_to_transfer * 8); if((!leftover_bit_length) && set_last_bit) { bytes_to_transfer -= 1; leftover_bit_length += 8; } debug("RD bytes_to_transfer: %d. leftover_bit_length: %d\n", bytes_to_transfer, leftover_bit_length); // Not enough bits for high-speed transfer. bit-bang. if(bytes_to_transfer == 0) { return cable_common_read_stream(outstream, instream, len_bits, set_last_bit); } // Bitbang functions leave clock high. USBBlaster assumes clock low at the start of a burst. if(clock_is_high) { // Lower the clock. retval |= cable_usbblaster_out(0); } // Zero the input, since we add new data by logical-OR for(i = 0; i < (len_bits/32); i++) instream[i] = 0; if(len_bits % 32) instream[i] = 0; // Set leftover bits leftover_bits = (outstream[bytes_to_transfer>>2] >> ((bytes_to_transfer & 0x3) * 8)) & 0xFF; debug("leftover_bits: 0x%X\n", leftover_bits); // open the device, if necessary if(h_device == NULL) { rv = cable_usbblaster_open_cable(); if(rv != APP_ERR_NONE) return rv; } // Transfer the data. USBBlaster has a max transfer size of 64 bytes. bytes_remaining = bytes_to_transfer; xfer_ptr = (const char *) outstream; total_bytes_received = 0; while(bytes_remaining > 0) { int bytes_this_xfer = (bytes_remaining > USBBLASTER_MAX_READ) ? USBBLASTER_MAX_READ:bytes_remaining; data_out_scratchpad[0] = USBBLASTER_CMD_BYTESHIFT | USBBLASTER_CMD_READ | (bytes_this_xfer & 0x3F); memcpy(&data_out_scratchpad[1], xfer_ptr, bytes_this_xfer); /* debug("Data packet: "); for(i = 0; i <= bytes_to_transfer; i++) debug("0x%X ", data_out_scratchpad[i]); debug("\n"); */ rv = usb_bulk_write(h_device, EP2, data_out_scratchpad, bytes_this_xfer+1, USB_TIMEOUT); if (rv != (bytes_this_xfer+1)){ fprintf(stderr, "\nFailed to write to the EP2 FIFO (rv = %d):\n%s", rv, usb_strerror()); cable_usbblaster_close_cable(); return APP_ERR_USB; } // receive the response // Sometimes, we do a read but just get the useless 0x31,0x60 chars... // retry until we get at least 3 bytes (with real data), for a reasonable number of retries. int retries = 0; bytes_received = 0; do { debug("stream read, bytes_this_xfer = %i, bytes_received = %i\n", bytes_this_xfer, bytes_received); rv = usb_bulk_read(h_device, EP1, data_in_scratchpad, (bytes_this_xfer-bytes_received)+2, USB_TIMEOUT); if (rv < 0){ fprintf(stderr, "\nFailed to read stream from the EP1 FIFO (%i):\n%s", rv, usb_strerror()); cable_usbblaster_close_cable(); return APP_ERR_USB; } /* debug("Read %i bytes: ", rv); for(i = 0; i < rv; i++) debug("0x%X ", data_in_scratchpad[i]); debug("\n"); */ if(rv > 2) retries = 0; else retries++; /* Put the received bytes into the return stream. Works for either endian. */ for(i = 0; i < (rv-2); i++) { // Do size/type promotion before shift. Must cast to unsigned, else the value may be // sign-extended through the upper 16 bits of the uint32_t. uint32_t tmp = (unsigned char) data_in_scratchpad[2+i]; instream[(total_bytes_received+i)>>2] |= (tmp << ((i & 0x3)*8)); } bytes_received += (rv-2); total_bytes_received += (rv-2); } while((bytes_received < unsigned(bytes_this_xfer)) && (retries < 15)); bytes_remaining -= bytes_this_xfer; xfer_ptr += bytes_this_xfer; } clock_is_high = 0; // if we have a number of bits not divisible by 8 if(leftover_bit_length != 0) { debug("Doing leftovers: (0x%X, %d, %d)\n", leftover_bits, leftover_bit_length, set_last_bit); retval |= cable_common_read_stream(&leftover_bits, &leftovers_received, leftover_bit_length, set_last_bit); instream[bytes_to_transfer>>2] |= (leftovers_received & 0xFF) << (8*(bytes_to_transfer & 0x3)); }