📄 jbijtag.c
字号:
if (jbi_jtag_state == state)
{
/*
* We are already in the desired state. If it is a stable state,
* loop here. Otherwise do nothing (no clock cycles).
*/
if ((state == IDLE) ||
(state == DRSHIFT) ||
(state == DRPAUSE) ||
(state == IRSHIFT) ||
(state == IRPAUSE))
{
jbi_jtag_io(TMS_LOW, TDI_LOW, IGNORE_TDO);
}
else if (state == RESET)
{
jbi_jtag_io(TMS_HIGH, TDI_LOW, IGNORE_TDO);
}
}
else
{
while ((jbi_jtag_state != state) && (count < 9))
{
/*
* Get TMS value to take a step toward desired state
*/
tms = (jbi_jtag_path_map[jbi_jtag_state] & (1 << state)) ?
TMS_HIGH : TMS_LOW;
/*
* Take a step
*/
jbi_jtag_io(tms, TDI_LOW, IGNORE_TDO);
if (tms)
{
jbi_jtag_state =
jbi_jtag_state_transitions[jbi_jtag_state].tms_high;
}
else
{
jbi_jtag_state =
jbi_jtag_state_transitions[jbi_jtag_state].tms_low;
}
++count;
}
}
if (jbi_jtag_state != state)
{
status = JBIC_INTERNAL_ERROR;
}
return (status);
}
/****************************************************************************/
/* */
JBI_RETURN_TYPE jbi_do_wait_cycles
(
long cycles,
JBIE_JTAG_STATE wait_state
)
/* */
/* Description: Causes JTAG hardware to loop in the specified stable */
/* state for the specified number of TCK clock cycles. */
/* */
/* Returns: JBIC_SUCCESS for success, else appropriate error code */
/* */
/****************************************************************************/
{
int tms;
long count;
JBI_RETURN_TYPE status = JBIC_SUCCESS;
if (jbi_jtag_state != wait_state)
{
status = jbi_goto_jtag_state(wait_state);
}
if (status == JBIC_SUCCESS)
{
/*
* Set TMS high to loop in RESET state
* Set TMS low to loop in any other stable state
*/
tms = (wait_state == RESET) ? TMS_HIGH : TMS_LOW;
for (count = 0L; count < cycles; count++)
{
jbi_jtag_io(tms, TDI_LOW, IGNORE_TDO);
}
}
return (status);
}
/****************************************************************************/
/* */
JBI_RETURN_TYPE jbi_do_wait_microseconds
(
long microseconds,
JBIE_JTAG_STATE wait_state
)
/* */
/* Description: Causes JTAG hardware to sit in the specified stable */
/* state for the specified duration of real time. If */
/* no JTAG operations have been performed yet, then only */
/* a delay is performed. This permits the WAIT USECS */
/* statement to be used in VECTOR programs without causing */
/* any JTAG operations. */
/* */
/* Returns: JBIC_SUCCESS for success, else appropriate error code */
/* */
/****************************************************************************/
{
long loop;
JBI_RETURN_TYPE status = JBIC_SUCCESS;
if ((jbi_jtag_state != JBI_ILLEGAL_JTAG_STATE) &&
(jbi_jtag_state != wait_state))
{
status = jbi_goto_jtag_state(wait_state);
}
if (status == JBIC_SUCCESS)
{
/*
* Wait for specified time interval
*/
uwait(microseconds);
}
return (status);
}
/****************************************************************************/
/* */
void jbi_jtag_concatenate_data
(
unsigned char *buffer,
unsigned char *preamble_data,
unsigned int preamble_count,
unsigned char *target_data,
unsigned long start_index,
unsigned int target_count,
unsigned char *postamble_data,
unsigned int postamble_count
)
/* */
/* Description: Copies preamble data, target data, and postamble data */
/* into one buffer for IR or DR scans. */
/* */
/* Returns: nothing */
/* */
/****************************************************************************/
{
unsigned long i;
unsigned long j;
unsigned long k;
for (i = 0L; i < preamble_count; ++i)
{
if (preamble_data[i >> 3L] & (1L << (i & 7L)))
{
buffer[i >> 3L] |= (1L << (i & 7L));
}
else
{
buffer[i >> 3L] &= ~(unsigned int) (1L << (i & 7L));
}
}
j = start_index;
k = preamble_count + target_count;
for (; i < k; ++i, ++j)
{
if (target_data[j >> 3L] & (1L << (j & 7L)))
{
buffer[i >> 3L] |= (1L << (i & 7L));
}
else
{
buffer[i >> 3L] &= ~(unsigned int) (1L << (i & 7L));
}
}
j = 0L;
k = preamble_count + target_count + postamble_count;
for (; i < k; ++i, ++j)
{
if (postamble_data[j >> 3L] & (1L << (j & 7L)))
{
buffer[i >> 3L] |= (1L << (i & 7L));
}
else
{
buffer[i >> 3L] &= ~(unsigned int) (1L << (i & 7L));
}
}
}
int jbi_jtag_drscan
(
int start_state,
int count,
unsigned char *tdi,
unsigned char *tdo
)
{
int i = 0;
int tdo_bit = 0;
int status = 1;
/*
* First go to DRSHIFT state
*/
switch (start_state)
{
case 0: /* IDLE */
jbi_jtag_io(1, 0, 0); /* DRSELECT */
jbi_jtag_io(0, 0, 0); /* DRCAPTURE */
jbi_jtag_io(0, 0, 0); /* DRSHIFT */
break;
case 1: /* DRPAUSE */
jbi_jtag_io(1, 0, 0); /* DREXIT2 */
jbi_jtag_io(0, 0, 0); /* DRSHIFT */
break;
case 2: /* IRPAUSE */
jbi_jtag_io(1, 0, 0); /* IREXIT2 */
jbi_jtag_io(1, 0, 0); /* IRUPDATE */
jbi_jtag_io(1, 0, 0); /* DRSELECT */
jbi_jtag_io(0, 0, 0); /* DRCAPTURE */
jbi_jtag_io(0, 0, 0); /* DRSHIFT */
break;
default:
status = 0;
}
if (status)
{
/* loop in the SHIFT-DR state */
for (i = 0; i < count; i++)
{
tdo_bit = jbi_jtag_io(
(i == count - 1),
tdi[i >> 3] & (1 << (i & 7)),
(tdo != NULL));
if (tdo != NULL)
{
if (tdo_bit)
{
tdo[i >> 3] |= (1 << (i & 7));
}
else
{
tdo[i >> 3] &= ~(unsigned int) (1 << (i & 7));
}
}
}
jbi_jtag_io(0, 0, 0); /* DRPAUSE */
}
return (status);
}
int jbi_jtag_irscan
(
int start_state,
int count,
unsigned char *tdi,
unsigned char *tdo
)
{
int i = 0;
int tdo_bit = 0;
int status = 1;
/*
* First go to IRSHIFT state
*/
switch (start_state)
{
case 0: /* IDLE */
jbi_jtag_io(1, 0, 0); /* DRSELECT */
jbi_jtag_io(1, 0, 0); /* IRSELECT */
jbi_jtag_io(0, 0, 0); /* IRCAPTURE */
jbi_jtag_io(0, 0, 0); /* IRSHIFT */
break;
case 1: /* DRPAUSE */
jbi_jtag_io(1, 0, 0); /* DREXIT2 */
jbi_jtag_io(1, 0, 0); /* DRUPDATE */
jbi_jtag_io(1, 0, 0); /* DRSELECT */
jbi_jtag_io(1, 0, 0); /* IRSELECT */
jbi_jtag_io(0, 0, 0); /* IRCAPTURE */
jbi_jtag_io(0, 0, 0); /* IRSHIFT */
break;
case 2: /* IRPAUSE */
jbi_jtag_io(1, 0, 0); /* IREXIT2 */
jbi_jtag_io(0, 0, 0); /* IRSHIFT */
break;
default:
status = 0;
}
if (status)
{
/* loop in the SHIFT-IR state */
for (i = 0; i < count; i++)
{
tdo_bit = jbi_jtag_io(
(i == count - 1),
tdi[i >> 3] & (1 << (i & 7)),
(tdo != NULL));
if (tdo != NULL)
{
if (tdo_bit)
{
tdo[i >> 3] |= (1 << (i & 7));
}
else
{
tdo[i >> 3] &= ~(unsigned int) (1 << (i & 7));
}
}
}
jbi_jtag_io(0, 0, 0); /* IRPAUSE */
}
return (status);
}
/****************************************************************************/
/* */
void jbi_jtag_extract_target_data
(
unsigned char *buffer,
unsigned char *target_data,
unsigned int start_index,
unsigned int preamble_count,
unsigned int target_count
)
/* */
/* Description: Copies target data from scan buffer, filtering out */
/* preamble and postamble data. */
/* */
/* Returns: nothing */
/* */
/****************************************************************************/
{
unsigned int i;
unsigned int j;
unsigned int k;
j = preamble_count;
k = start_index + target_count;
for (i = start_index; i < k; ++i, ++j)
{
if (buffer[j >> 3] & (1 << (j & 7)))
{
target_data[i >> 3] |= (1 << (i & 7));
}
else
{
target_data[i >> 3] &= ~(unsigned int) (1 << (i & 7));
}
}
}
/****************************************************************************/
/* */
JBI_RETURN_TYPE jbi_do_irscan
(
unsigned int count,
unsigned char *tdi_data,
unsigned int start_index
)
/* */
/* Description: Shifts data into instruction register */
/* */
/* Returns: JBIC_SUCCESS for success, else appropriate error code */
/* */
/****************************************************************************/
{
int start_code = 0;
unsigned int alloc_chars = 0;
unsigned int shift_count = jbi_ir_preamble + count + jbi_ir_postamble;
JBI_RETURN_TYPE status = JBIC_SUCCESS;
JBIE_JTAG_STATE start_state = JBI_ILLEGAL_JTAG_STATE;
switch (jbi_jtag_state)
{
case JBI_ILLEGAL_JTAG_STATE:
case RESET:
case IDLE:
start_code = 0;
start_state = IDLE;
break;
case DRSELECT:
case DRCAPTURE:
case DRSHIFT:
case DREXIT1:
case DRPAUSE:
case DREXIT2:
case DRUPDATE:
start_code = 1;
start_state = DRPAUSE;
break;
case IRSELECT:
case IRCAPTURE:
case IRSHIFT:
case IREXIT1:
case IRPAUSE:
case IREXIT2:
case IRUPDATE:
start_code = 2;
start_state = IRPAUSE;
break;
default:
status = JBIC_INTERNAL_ERROR;
break;
}
if (status == JBIC_SUCCESS)
{
if (jbi_jtag_state != start_state)
{
status = jbi_goto_jtag_state(start_state);
}
}
if (status == JBIC_SUCCESS)
{
if (jbi_workspace != NULL)
{
if (shift_count > JBIC_MAX_JTAG_IR_LENGTH)
{
status = JBIC_OUT_OF_MEMORY;
}
}
else if (shift_count > jbi_ir_length)
{
alloc_chars = (shift_count + 7) >> 3;
jbi_free(jbi_ir_buffer);
jbi_ir_buffer = (unsigned char *) jbi_malloc(alloc_chars);
if (jbi_ir_buffer == NULL)
{
status = JBIC_OUT_OF_MEMORY;
}
else
{
jbi_ir_length = alloc_chars * 8;
}
}
}
if (status == JBIC_SUCCESS)
{
/*
* Copy preamble data, IR data, and postamble data into a buffer
*/
jbi_jtag_concatenate_data
(
jbi_ir_buffer,
jbi_ir_preamble_data,
jbi_ir_preamble,
tdi_data,
start_index,
count,
jbi_ir_postamble_data,
jbi_ir_postamble
);
/*
* Do the IRSCAN
*/
jbi_jtag_irscan
(
start_code,
shift_count,
jbi_ir_buffer,
NULL
);
/* jbi_jtag_irscan() always ends in IRPAUSE state */
jbi_jtag_state = IRPAUSE;
}
if (status == JBIC_SUCCESS)
{
if (jbi_irstop_state != IRPAUSE)
{
status = jbi_goto_jtag_state(jbi_irstop_state);
}
}
return (status);
}
/****************************************************************************/
/* */
JBI_RETURN_TYPE jbi_swap_ir
(
unsigned int count,
unsigned char *in_data,
unsigned int in_index,
unsigned char *out_data,
unsigned int out_index
)
/* */
/* Description: Shifts data into instruction register, capturing output */
/* data */
/* */
/* Returns: JBIC_SUCCESS for success, else appropriate error code */
/* */
/****************************************************************************/
{
int start_code = 0;
unsigned int alloc_chars = 0;
unsigned int shift_count = jbi_ir_preamble + count + jbi_ir_postamble;
JBI_RETURN_TYPE status = JBIC_SUCCESS;
JBIE_JTAG_STATE start_state = JBI_ILLEGAL_JTAG_STATE;
switch (jbi_jtag_state)
{
case JBI_ILLEGAL_JTAG_STATE:
case RESET:
case IDLE:
start_code = 0;
start_state = IDLE;
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -