* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
*/
/*
};
static struct drvs_map lowlevel_drivers_map[] = {
-#if BUILD_USB_BLASTER_LIBFTDI
+#if BUILD_USB_BLASTER
{ .name = "ftdi", .drv_register = ublast_register_ftdi },
#endif
-#if BUILD_USB_BLASTER_FTD2XX
- { .name = "ftd2xx", .drv_register = ublast_register_ftd2xx },
-#endif
#if BUILD_USB_BLASTER_2
{ .name = "ublast2", .drv_register = ublast2_register_libusb },
#endif
jtag_sleep(us);
}
+static void ublast_initial_wipeout(void)
+{
+ static uint8_t tms_reset = 0xff;
+ uint8_t out_value;
+ uint32_t retlen;
+ int i;
+
+ out_value = ublast_build_out(SCAN_OUT);
+ for (i = 0; i < BUF_LEN; i++)
+ info.buf[i] = out_value | ((i % 2) ? TCK : 0);
+
+ /*
+ * Flush USB-Blaster queue fifos
+ * - empty the write FIFO (128 bytes)
+ * - empty the read FIFO (384 bytes)
+ */
+ ublast_buf_write(info.buf, BUF_LEN, &retlen);
+ /*
+ * Put JTAG in RESET state (five 1 on TMS)
+ */
+ ublast_tms_seq(&tms_reset, 5);
+ tap_set_state(TAP_RESET);
+}
+
static int ublast_execute_queue(void)
{
struct jtag_command *cmd;
+ static int first_call = 1;
int ret = ERROR_OK;
+ if (first_call) {
+ first_call--;
+ ublast_initial_wipeout();
+ }
+
for (cmd = jtag_command_queue; ret == ERROR_OK && cmd != NULL;
cmd = cmd->next) {
switch (cmd->type) {
*
* Initialize the device :
* - open the USB device
- * - empty the write FIFO (128 bytes)
- * - empty the read FIFO (384 bytes)
+ * - pretend it's initialized while actual init is delayed until first jtag command
*
* Returns ERROR_OK if USB device found, error if not.
*/
static int ublast_init(void)
{
- static uint8_t tms_reset = 0xff;
int ret, i;
- if (info.lowlevel_name) {
- for (i = 0; lowlevel_drivers_map[i].name; i++)
- if (!strcmp(lowlevel_drivers_map[i].name, info.lowlevel_name))
+ for (i = 0; lowlevel_drivers_map[i].name; i++) {
+ if (info.lowlevel_name) {
+ if (!strcmp(lowlevel_drivers_map[i].name, info.lowlevel_name)) {
+ info.drv = lowlevel_drivers_map[i].drv_register();
+ if (!info.drv) {
+ LOG_ERROR("Error registering lowlevel driver \"%s\"",
+ info.lowlevel_name);
+ return ERROR_JTAG_DEVICE_ERROR;
+ }
break;
- if (lowlevel_drivers_map[i].name)
- info.drv = lowlevel_drivers_map[i].drv_register();
- if (!info.drv) {
- LOG_ERROR("no lowlevel driver found for %s or lowlevel driver opening error",
- info.lowlevel_name);
- return ERROR_JTAG_DEVICE_ERROR;
- }
- } else {
- LOG_INFO("No lowlevel driver configured, will try them all");
- for (i = 0; !info.drv && lowlevel_drivers_map[i].name; i++)
+ }
+ } else {
info.drv = lowlevel_drivers_map[i].drv_register();
- if (!info.drv) {
- LOG_ERROR("no lowlevel driver found");
- return ERROR_JTAG_DEVICE_ERROR;
+ if (info.drv) {
+ info.lowlevel_name = strdup(lowlevel_drivers_map[i].name);
+ LOG_INFO("No lowlevel driver configured, using %s", info.lowlevel_name);
+ break;
+ }
}
- info.lowlevel_name = strdup(lowlevel_drivers_map[i-1].name);
+ }
+
+ if (!info.drv) {
+ LOG_ERROR("No lowlevel driver available");
+ return ERROR_JTAG_DEVICE_ERROR;
}
/*
info.flags |= info.drv->flags;
ret = info.drv->open(info.drv);
- if (ret == ERROR_OK) {
- /*
- * Flush USB-Blaster queue fifos
- */
- uint32_t retlen;
- ublast_buf_write(info.buf, BUF_LEN, &retlen);
- /*
- * Put JTAG in RESET state (five 1 on TMS)
- */
- ublast_tms_seq(&tms_reset, 5);
- tap_set_state(TAP_RESET);
- }
+
+ /*
+ * Let lie here : the TAP is in an unknown state, but the first
+ * execute_queue() will trigger a ublast_initial_wipeout(), which will
+ * put the TAP in RESET.
+ */
+ tap_set_state(TAP_RESET);
return ret;
}
.name = "usb_blaster_lowlevel_driver",
.handler = ublast_handle_lowlevel_drv_command,
.mode = COMMAND_CONFIG,
- .help = "set the lowlevel access for the USB Blaster (ftdi, ftd2xx, ublast2)",
- .usage = "(ftdi|ftd2xx|ublast2)",
+ .help = "set the lowlevel access for the USB Blaster (ftdi, ublast2)",
+ .usage = "(ftdi|ublast2)",
},
{
.name = "usb_blaster_pin",