void discovery( chain_t *chain ) { int irlen; tap_register *ir; tap_register *irz; /* detecting IR size */ jtag_reset( chain ); printf( _("Detecting IR length ... ") ); fflush( stdout ); tap_capture_ir( chain ); irlen = detect_register_size( chain ); printf( _("%d\n"), irlen ); if (irlen < 1) { printf( _("Error: Invalid IR length!\n") ); return; } /* all 1 is BYPASS in all parts, so DR length gives number of parts */ ir = register_fill( register_alloc( irlen ), 1 ); irz = register_duplicate( ir ); if (!ir || !irz) { register_free( ir ); register_free( irz ); printf( _("Error: Out of memory!\n") ); return; } for (;;) { int rs; jtag_reset( chain ); tap_capture_ir( chain ); tap_shift_register( chain, ir, NULL, 1 ); printf( _("Detecting DR length for IR %s ... "), register_get_string( ir ) ); fflush( stdout ); tap_capture_dr( chain ); rs = detect_register_size( chain ); printf( _("%d\n"), rs ); register_inc( ir ); if (register_compare( ir, irz ) == 0) break; } register_free( ir ); register_free( irz ); }
static int jtag_open(struct jtag_state *state) { gpio_export(TDI_GPIO); gpio_export(TMS_GPIO); gpio_export(TCK_GPIO); gpio_export(TDO_GPIO); gpio_set_direction(TDI_GPIO, 0); gpio_set_direction(TMS_GPIO, 1); gpio_set_direction(TCK_GPIO, 1); gpio_set_direction(TDO_GPIO, 1); gpio_set_value(TDO_GPIO, 0); gpio_set_value(TMS_GPIO, 0); gpio_set_value(TCK_GPIO, 0); state->tdi = TDI_GPIO; state->tms = TMS_GPIO; state->tck = TCK_GPIO; state->tdo = TDO_GPIO; jtag_reset(state); return 0; }
/* Reads the ID CODE out of the FPGA * When the state machine is reset, the sequence 0, 1, 0, 0 will move * it to a point where continually reading the TDO line will yield the * ID code. * * This is because by default, the reset command loads the chip's ID * into the data register, so all we have to do is read it out. */ static uint32_t jtag_idcode(struct jtag_state *state) { int i; uint32_t val = 0; /* Reset the state machine */ jtag_reset(state); /* Get into "Run-Test/ Idle" state */ gpio_set_value(state->tms, 0); jtag_tick(state); /* Get into "Select DR-Scan" state */ gpio_set_value(state->tms, 1); jtag_tick(state); /* Get into "Capture DR" state */ gpio_set_value(state->tms, 0); jtag_tick(state); /* Get into "Shift-DR" state */ gpio_set_value(state->tms, 0); jtag_tick(state); /* Read the code out */ for (i=0; i<32; i++) { int ret = gpio_get_value(state->tdi); val |= (ret<<i); jtag_tick(state); } return val; }
int main(int argc, char **argv) { unsigned bits; if (jtag_open() < 0) return -1; if (jtag_reset() < 0) return -1; if (jtag_dr(32, 0, &bits) < 0) return -1; fprintf(stderr,"IDCODE: %08x\n", bits); if (jtag_open_virtual_device(0xffffffff)) return -1; jtag_close(); return 0; }
static int jtag_ioctl(struct cdev *inode, int cmd, void *arg) { int ret = 0; struct jtag_info *info = (struct jtag_info *)inode->priv; int devices = info->devices; struct jtag_cmd *jcmd = (struct jtag_cmd *)arg; struct jtag_platdata *pdata = info->pdata; if (_IOC_TYPE(cmd) != JTAG_IOC_MAGIC) return -ENOTTY; if (_IOC_NR(cmd) > JTAG_IOC_MAXNR) return -ENOTTY; switch (cmd) { case JTAG_GET_DEVICES: /* Returns how many devices found in the chain */ ret = info->devices; break; case JTAG_GET_ID: /* Returns ID register of selected device */ if ((((struct jtag_rd_id *)arg)->device < 0) || (((struct jtag_rd_id *)arg)->device >= devices)) { ret = -EINVAL; break; } jtag_reset(pdata); pulse_tms0(pdata); pulse_tms1(pdata); pulse_tms0(pdata); pulse_tms0(pdata); while (devices-- > 0) { unsigned long id = 0; pulse_tms0(pdata); if (gpio_get_value(pdata->gpio_tdi)) { unsigned long mask; for (id = 1, mask = 0x00000002; (mask != 0); mask <<= 1) { pulse_tms0(pdata); if (gpio_get_value(pdata->gpio_tdi)) id |= mask; } } if (devices == ((struct jtag_rd_id *)arg)->device) { ((struct jtag_rd_id *)arg)->id = id; ret = 0; break; } } jtag_reset(pdata); break; case JTAG_SET_IR_LENGTH: /* Sets up IR length of one device */ if ((jcmd->device >= 0) && (jcmd->device < devices)) info->ir_len[jcmd->device] = jcmd->bitlen; else ret = -EINVAL; break; case JTAG_RESET: /* Resets all JTAG states */ jtag_reset(pdata); break; case JTAG_IR_WR: /* * Writes Instruction Register * If device == -1 writes same Instruction Register in * all devices. * If device >= 0 writes Instruction Register in selected * device and loads BYPASS instruction in all others. */ if ((jcmd->device < -1) || (jcmd->device >= devices)) { ret = -EINVAL; break; } pulse_tms0(pdata); pulse_tms1(pdata); pulse_tms1(pdata); pulse_tms0(pdata); pulse_tms0(pdata); while (devices-- > 0) { if ((jcmd->device == -1) || (jcmd->device == devices)) /* Loads desired instruction */ jtag_output(pdata, jcmd->data, info->ir_len[devices], devices); else /* Loads BYPASS instruction */ jtag_output(pdata, &bypass, info->ir_len[devices], devices); } pulse_tms1(pdata); pulse_tms0(pdata); break; case JTAG_DR_WR: /* * Writes Data Register of all devices * If device == -1 writes same Data Register in all devices. * If device >= 0 writes Data Register in selected device * and loads BYPASS instruction in all others. */ if ((jcmd->device < -1) || (jcmd->device >= devices)) { ret = -EINVAL; break; } pulse_tms0(pdata); pulse_tms1(pdata); pulse_tms0(pdata); pulse_tms0(pdata); while (devices-- > 0) { if ((jcmd->device == -1) || (devices == jcmd->device)) /* Loads desired data */ jtag_output(pdata, jcmd->data, jcmd->bitlen, devices); else /* Loads 1 dummy bit in BYPASS data register */ jtag_output(pdata, &bypass, 1, devices); } pulse_tms1(pdata); pulse_tms0(pdata); break; case JTAG_DR_RD: /* Reads data register of selected device */ if ((jcmd->device < 0) || (jcmd->device >= devices)) ret = -EINVAL; else { unsigned long mask; int bitlen = jcmd->bitlen; unsigned long *data = jcmd->data; pulse_tms0(pdata); pulse_tms1(pdata); pulse_tms0(pdata); pulse_tms0(pdata); devices -= (jcmd->device + 1); while (devices-- > 0) pulse_tms0(pdata); while (bitlen > 0) { for (*data = 0, mask = 0x00000001; (mask != 0) && (bitlen > 0); mask <<= 1, bitlen--) { if (bitlen == 1) pulse_tms1(pdata); else pulse_tms0(pdata); if (gpio_get_value(pdata->gpio_tdi)) *data |= mask; } data++; } pulse_tms1(pdata); pulse_tms0(pdata); } break; case JTAG_CLK: /* Generates arg clock pulses */ gpio_set_value(pdata->gpio_tms, 0); while ((*(unsigned int *) arg)--) { gpio_set_value(pdata->gpio_tclk, 0); gpio_set_value(pdata->gpio_tclk, 1); } break; default: ret = -EFAULT; } return ret; }
static int jtag_probe(struct device_d *pdev) { int i, ret; struct jtag_info *info; struct jtag_platdata *pdata = pdev->platform_data; /* Setup gpio pins */ gpio_direction_output(pdata->gpio_tms, 0); gpio_direction_output(pdata->gpio_tclk, 1); gpio_direction_output(pdata->gpio_tdo, 0); gpio_direction_input(pdata->gpio_tdi); if (pdata->use_gpio_trst) { /* * Keep fixed at 1 because some devices in the chain could * not use it, to reset chain use jtag_reset() */ gpio_direction_output(pdata->gpio_trst, 1); } /* Find how many devices in chain */ jtag_reset(pdata); pulse_tms0(pdata); pulse_tms1(pdata); pulse_tms1(pdata); pulse_tms0(pdata); pulse_tms0(pdata); gpio_set_value(pdata->gpio_tdo, 1); /* Fills all IR with bypass instruction */ for (i = 0; i < 32 * MAX_DEVICES; i++) pulse_tms0(pdata); pulse_tms1(pdata); pulse_tms1(pdata); pulse_tms1(pdata); pulse_tms0(pdata); pulse_tms0(pdata); gpio_set_value(pdata->gpio_tdo, 0); /* Fills all 1-bit bypass register with 0 */ for (i = 0; i < MAX_DEVICES + 2; i++) pulse_tms0(pdata); gpio_set_value(pdata->gpio_tdo, 1); /* Counts chain's bit length */ for (i = 0; i < MAX_DEVICES + 1; i++) { pulse_tms0(pdata); if (gpio_get_value(pdata->gpio_tdi)) break; } dev_notice(pdev, "%d devices found in chain\n", i); /* Allocate structure with chain specific infos */ info = xzalloc(sizeof(struct jtag_info) + sizeof(info->ir_len[0]) * i); info->devices = i; info->pdata = pdata; pdev->priv = info; info->cdev.name = JTAG_NAME; info->cdev.dev = pdev; info->cdev.ops = &jtag_operations; info->cdev.priv = info; ret = devfs_create(&info->cdev); if (ret) goto fail_devfs_create; return 0; fail_devfs_create: pdev->priv = NULL; free(info); return ret; }