⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ft2232.c

📁 UrJTAG package is free software, covered by the GNU General Public License, and you are welcome to
💻 C
📖 第 1 页 / 共 4 页
字号:
  cx_cmd_push( cmd_root, SET_BITS_LOW );  cx_cmd_push( cmd_root, BITMASK_SIGNALYZER_nTRST | BITMASK_SIGNALYZER_nSRST );  cx_cmd_push( cmd_root, 0 );  /* Set Data Bits High Byte     disable output drivers */  cx_cmd_push( cmd_root, SET_BITS_HIGH );  cx_cmd_push( cmd_root, BITMASK_SIGNALYZER_nTRST | BITMASK_SIGNALYZER_nSRST );  cx_cmd_push( cmd_root, BITMASK_SIGNALYZER_nTRST | BITMASK_SIGNALYZER_nSRST );  /* Set Data Bits High Byte     set all to input */  cx_cmd_push( cmd_root, SET_BITS_HIGH );  cx_cmd_push( cmd_root, 0 );  cx_cmd_push( cmd_root, 0 );  cx_xfer( cmd_root, &imm_cmd, cable, COMPLETELY );  generic_usbconn_done( cable );}static voidft2232_clock_schedule( cable_t *cable, int tms, int tdi, int n ){  params_t *params = (params_t *)cable->params;  cx_cmd_root_t *cmd_root = &(params->cmd_root);  tms = tms ? 0x7f : 0;  tdi = tdi ? 1 << 7 : 0;  cx_cmd_queue( cmd_root, 0 );  while (n > 0)  {    /* Clock Data to TMS/CS Pin (no Read) */    cx_cmd_push( cmd_root, MPSSE_WRITE_TMS |                 MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG );    if (n <= 7)    {      cx_cmd_push( cmd_root, n-1 );      n = 0;    }    else    {      cx_cmd_push( cmd_root, 7-1 );      n -= 7;    }    cx_cmd_push( cmd_root, tdi | tms );  }}static voidft2232_clock( cable_t *cable, int tms, int tdi, int n ){  params_t *params = (params_t *)cable->params;  ft2232_clock_schedule( cable, tms, tdi, n );  cx_xfer( &(params->cmd_root), &imm_cmd, cable, COMPLETELY );  params->last_tdo_valid = 0;}static voidft2232_get_tdo_schedule( cable_t *cable ){  params_t *params = (params_t *)cable->params;  cx_cmd_root_t *cmd_root = &(params->cmd_root);  /* Read Data Bits Low Byte */  cx_cmd_queue( cmd_root, 1 );  cx_cmd_push( cmd_root, GET_BITS_LOW );}static intft2232_get_tdo_finish( cable_t *cable ){  params_t *params = (params_t *)cable->params;  int value;  value = ( cx_xfer_recv( cable ) & BITMASK_TDO) ? 1 : 0;  params->last_tdo = value;  params->last_tdo_valid = 1;  return value;}static intft2232_get_tdo( cable_t *cable ){  params_t *params = (params_t *)cable->params;  ft2232_get_tdo_schedule( cable );  cx_xfer( &(params->cmd_root), &imm_cmd, cable, COMPLETELY );  return ft2232_get_tdo_finish( cable );}static voidft2232_set_trst_schedule( params_t *params, int trst ){  cx_cmd_root_t *cmd_root = &(params->cmd_root);  cx_cmd_queue( cmd_root, 0 );  cx_cmd_push( cmd_root, SET_BITS_HIGH );  cx_cmd_push( cmd_root,               trst == 0 ? params->high_byte_value_trst_active : params->high_byte_value_trst_inactive );  cx_cmd_push( cmd_root, params->high_byte_dir );}static intft2232_set_trst( cable_t *cable, int trst ){  params_t *params = (params_t *)cable->params;  ft2232_set_trst_schedule( params, trst );  cx_xfer( &(params->cmd_root), &imm_cmd, cable, COMPLETELY );  params->last_tdo_valid = 0;  return trst;}static voidft2232_transfer_schedule( cable_t *cable, int len, char *in, char *out ){  params_t *params = (params_t *)cable->params;  cx_cmd_root_t *cmd_root = &(params->cmd_root);  int in_offset = 0;  int bitwise_len;  int chunkbytes;  /* Set Data Bits Low Byte to lower TMS for transfer     TCK = 0, TMS = 0, TDI = 0, nOE = 0 */  cx_cmd_queue( cmd_root, 0 );  cx_cmd_push( cmd_root, SET_BITS_LOW );  cx_cmd_push( cmd_root, params->low_byte_value | 0 );  cx_cmd_push( cmd_root, params->low_byte_dir | BITMASK_TCK | BITMASK_TDI | BITMASK_TMS );  chunkbytes = len >> 3;  while (chunkbytes > 0)  {    int byte_idx;    /* reduce chunkbytes to the maximum amount we can receive in one step */    if (out && chunkbytes > FTDX_MAXRECV)      chunkbytes = FTDX_MAXRECV;    /* restrict chunkbytes to the maximum amount that can be transferred       for one single operation */    if (chunkbytes > (1 << 16))      chunkbytes = 1 << 16;    /***********************************************************************     * Step 1:     * Determine data shifting command (bytewise).     * Either with or without read     ***********************************************************************/    if (out)    {      cx_cmd_queue( cmd_root, chunkbytes );      /* Clock Data Bytes In and Out LSB First         out on negative edge, in on positive edge */      cx_cmd_push( cmd_root, MPSSE_DO_READ | MPSSE_DO_WRITE |                   MPSSE_LSB | MPSSE_WRITE_NEG );    }    else    {      cx_cmd_queue( cmd_root, 0 );      /* Clock Data Bytes Out on -ve Clock Edge LSB First (no Read) */      cx_cmd_push( cmd_root, MPSSE_DO_WRITE |                   MPSSE_LSB | MPSSE_WRITE_NEG );    }    /* set byte count */    cx_cmd_push( cmd_root, (chunkbytes - 1) & 0xff );    cx_cmd_push( cmd_root, ((chunkbytes - 1) >> 8) & 0xff );    /*********************************************************************     * Step 2:     * Write TDI data in bundles of 8 bits.     *********************************************************************/    for (byte_idx = 0; byte_idx < chunkbytes; byte_idx++)    {      int bit_idx;      unsigned char b = 0;      for (bit_idx = 1; bit_idx < 256; bit_idx <<= 1)        if (in[in_offset++])          b |= bit_idx;      cx_cmd_push( cmd_root, b );    }    /* recalc chunkbytes for next round */    chunkbytes = (len - in_offset) >> 3;  }  /* determine bitwise shift amount */  bitwise_len = (len - in_offset) % 8;  if (bitwise_len > 0)  {    /***********************************************************************     * Step 3:     * Determine data shifting command (bitwise).     * Either with or without read     ***********************************************************************/    if (out)    {      cx_cmd_queue( cmd_root, 1 );      /* Clock Data Bytes In and Out LSB First         out on negative edge, in on positive edge */      cx_cmd_push( cmd_root, MPSSE_DO_READ | MPSSE_DO_WRITE |                   MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG );    }    else    {      cx_cmd_queue( cmd_root, 0 );      /* Clock Data Bytes Out on -ve Clock Edge LSB First (no Read) */      cx_cmd_push( cmd_root, MPSSE_DO_WRITE |                   MPSSE_LSB | MPSSE_BITMODE | MPSSE_WRITE_NEG );    }    /* determine bit count */    cx_cmd_push( cmd_root, bitwise_len - 1 );    /***********************************************************************     * Step 4:     * Write TDI data bitwise     ***********************************************************************/    {      int bit_idx;      unsigned char b = 0;      for (bit_idx = 1; bit_idx <= 1 << bitwise_len; bit_idx <<= 1)      {        if (in[in_offset++])          b |= bit_idx;      }      cx_cmd_push( cmd_root, b );    }  }  if (out)  {    /* Read Data Bits Low Byte to get current TDO,       Do this only if we'll read out data nonetheless */    cx_cmd_queue( cmd_root, 1 );    cx_cmd_push( cmd_root, GET_BITS_LOW );    params->last_tdo_valid = 1;  }  else    params->last_tdo_valid = 0;}static intft2232_transfer_finish( cable_t *cable, int len, char *out ){  params_t *params = (params_t *)cable->params;  int bitwise_len;  int chunkbytes;  int out_offset = 0;  chunkbytes = len >> 3;  bitwise_len = len % 8;  if (out)  {    if (chunkbytes > 0)    {      uint32_t xferred;      /*********************************************************************       * Step 5:       * Read TDO data in bundles of 8 bits if read is requested.       *********************************************************************/      xferred = chunkbytes;      for (; xferred > 0; xferred--)      {        int bit_idx;        unsigned char b;        b = cx_xfer_recv( cable );        for (bit_idx = 1; bit_idx < 256; bit_idx <<= 1)          out[out_offset++] = (b & bit_idx) ? 1 : 0;      }    }    if (bitwise_len > 0)    {      /***********************************************************************       * Step 6:       * Read TDO data bitwise if read is requested.       ***********************************************************************/      int bit_idx;      unsigned char b;      b = cx_xfer_recv( cable );      for (bit_idx = (1 << (8 - bitwise_len)); bit_idx < 256; bit_idx <<= 1)        out[out_offset++] = (b & bit_idx) ? 1 : 0;    }    /* gather current TDO */    params->last_tdo = ( cx_xfer_recv( cable ) & BITMASK_TDO) ? 1 : 0;    params->last_tdo_valid = 1;  }  else    params->last_tdo_valid = 0;  return 0;}static intft2232_transfer( cable_t *cable, int len, char *in, char *out ){  params_t *params = (params_t *)cable->params;  ft2232_transfer_schedule( cable, len, in, out );  cx_xfer( &(params->cmd_root), &imm_cmd, cable, COMPLETELY );  return ft2232_transfer_finish( cable, len, out );}static voidft2232_flush( cable_t *cable, cable_flush_amount_t how_much ){  params_t *params = (params_t *)cable->params;  if (how_much == OPTIONALLY) return;  if (cable->todo.num_items == 0)    cx_xfer( &(params->cmd_root), &imm_cmd, cable, how_much );  while (cable->todo.num_items > 0)  {    int i, j, n;    int last_tdo_valid_schedule = params->last_tdo_valid;    int last_tdo_valid_finish = params->last_tdo_valid;    for (j = i = cable->todo.next_item, n = 0; n < cable->todo.num_items; n++)    {      switch (cable->todo.data[i].action)      {      case CABLE_CLOCK:        ft2232_clock_schedule( cable,                               cable->todo.data[i].arg.clock.tms,                               cable->todo.data[i].arg.clock.tdi,                               cable->todo.data[i].arg.clock.n );        last_tdo_valid_schedule = 0;        break;      case CABLE_GET_TDO:        if (!last_tdo_valid_schedule)        {          ft2232_get_tdo_schedule( cable );          last_tdo_valid_schedule = 1;        }        break;      case CABLE_SET_TRST:        ft2232_set_trst_schedule( params, cable->todo.data[i].arg.value.trst );        last_tdo_valid_schedule = 0;        break;      case CABLE_TRANSFER:        ft2232_transfer_schedule( cable,                                  cable->todo.data[i].arg.transfer.len,                                  cable->todo.data[i].arg.transfer.in,                                  cable->todo.data[i].arg.transfer.out );        last_tdo_valid_schedule = params->last_tdo_valid;        break;      default:        break;      }      i++;      if (i >= cable->todo.max_items)        i = 0;    }    cx_xfer( &(params->cmd_root), &imm_cmd, cable, how_much );    while (j != i)    {      switch (cable->todo.data[j].action)      {      case CABLE_CLOCK:        params->last_tdo_valid = last_tdo_valid_finish = 0;        break;      case CABLE_GET_TDO:        {          int tdo;          int m;          if (last_tdo_valid_finish)            tdo = params->last_tdo;          else            tdo = ft2232_get_tdo_finish( cable );          last_tdo_valid_finish = params->last_tdo_valid;          m = cable_add_queue_item( cable, &(cable->done) );          cable->done.data[m].action = CABLE_GET_TDO;          cable->done.data[m].arg.value.tdo = tdo;          break;        }      case CABLE_SET_TRST:        {          int m = cable_add_queue_item( cable, &(cable->done) );          cable->done.data[m].action = CABLE_SET_TRST;          cable->done.data[m].arg.value.trst = cable->done.data[j].arg.value.trst;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -