OpenCores
URL https://opencores.org/ocsvn/jtag_stapl_player/jtag_stapl_player/trunk

Subversion Repositories jtag_stapl_player

[/] [jtag_stapl_player/] [trunk/] [jamjtag.c] - Rev 2

Compare with Previous | Blame | View Log

/****************************************************************************/
/*																			*/
/*	Module:			jamjtag.c												*/
/*																			*/
/*					Copyright (C) Altera Corporation 1997					*/
/*																			*/
/*	Description:	Contains array management functions, including			*/
/*					functions for reading array initialization data in		*/
/*					compressed formats.										*/
/*																			*/
/*	Revisions:		1.1 allow WAIT USECS without using JTAG hardware if		*/
/*					JTAG hardware has not yet been initialized -- this is	*/
/*					needed to create delays in VECTOR (non-JTAG) programs	*/
/*																			*/
/****************************************************************************/
 
/****************************************************************************/
/*																			*/
/*	Actel version 1.1             May 2003									*/
/*																			*/
/****************************************************************************/
 
#include "jamexprt.h"
#include "jamdefs.h"
#include "jamsym.h"
#include "jamstack.h"
#include "jamutil.h"
#include "jamjtag.h"
 
//&RA
#include <stdio.h>
extern long verbose;
/*
*	Global variable to store the current JTAG state
*/
JAME_JTAG_STATE jam_jtag_state = JAM_ILLEGAL_JTAG_STATE;
 
/*
*	Store current stop-state for DR and IR scan commands
*/
JAME_JTAG_STATE jam_drstop_state = IDLE;
JAME_JTAG_STATE jam_irstop_state = IDLE;
 
/*
*	Store current padding values
*/
int jam_dr_preamble  = 0;
int jam_dr_postamble = 0;
int jam_ir_preamble  = 0;
int jam_ir_postamble = 0;
int jam_dr_length    = 0;
int jam_ir_length    = 0;
long *jam_dr_preamble_data  = NULL;
long *jam_dr_postamble_data = NULL;
long *jam_ir_preamble_data  = NULL;
long *jam_ir_postamble_data = NULL;
char *jam_dr_buffer         = NULL;
char *jam_ir_buffer         = NULL;
 
/*
*	Table of JTAG state names
*/
struct JAMS_JTAG_MAP
{
	JAME_JTAG_STATE state;
	char string[JAMC_MAX_JTAG_STATE_LENGTH + 1];
} jam_jtag_state_table[] =
{
	{ RESET,     "RESET"     },
	{ IDLE,      "IDLE"      },
	{ DRSELECT,  "DRSELECT"  },
	{ DRCAPTURE, "DRCAPTURE" },
	{ DRSHIFT,   "DRSHIFT"   },
	{ DREXIT1,   "DREXIT1"   },
	{ DRPAUSE,   "DRPAUSE"   },
	{ DREXIT2,   "DREXIT2"   },
	{ DRUPDATE,  "DRUPDATE"  },
	{ IRSELECT,  "IRSELECT"  },
	{ IRCAPTURE, "IRCAPTURE" },
	{ IRSHIFT,   "IRSHIFT"   },
	{ IREXIT1,   "IREXIT1"   },
	{ IRPAUSE,   "IRPAUSE"   },
	{ IREXIT2,   "IREXIT2"   },
	{ IRUPDATE,  "IRUPDATE"  }
};
 
#define JAMC_JTAG_STATE_COUNT \
  (sizeof(jam_jtag_state_table) / sizeof(jam_jtag_state_table[0]))
 
/*
*	This structure shows, for each JTAG state, which state is reached after
*	a single TCK clock cycle with TMS high or TMS low, respectively.  This
*	describes all possible state transitions in the JTAG state machine.
*/
struct JAMS_JTAG_MACHINE
{
	JAME_JTAG_STATE tms_high;
	JAME_JTAG_STATE tms_low;
} jam_jtag_state_transitions[] =
{
/* RESET     */	{ RESET,	IDLE },
/* IDLE      */	{ DRSELECT,	IDLE },
/* DRSELECT  */	{ IRSELECT,	DRCAPTURE },
/* DRCAPTURE */	{ DREXIT1,	DRSHIFT },
/* DRSHIFT   */	{ DREXIT1,	DRSHIFT },
/* DREXIT1   */	{ DRUPDATE,	DRPAUSE },
/* DRPAUSE   */	{ DREXIT2,	DRPAUSE },
/* DREXIT2   */	{ DRUPDATE,	DRSHIFT },
/* DRUPDATE  */	{ DRSELECT,	IDLE },
/* IRSELECT  */	{ RESET,	IRCAPTURE },
/* IRCAPTURE */	{ IREXIT1,	IRSHIFT },
/* IRSHIFT   */	{ IREXIT1,	IRSHIFT },
/* IREXIT1   */	{ IRUPDATE,	IRPAUSE },
/* IRPAUSE   */	{ IREXIT2,	IRPAUSE },
/* IREXIT2   */	{ IRUPDATE,	IRSHIFT },
/* IRUPDATE  */	{ DRSELECT,	IDLE }
};
 
/*
*	This table contains the TMS value to be used to take the NEXT STEP on
*	the path to the desired state.  The array index is the current state,
*	and the bit position is the desired endstate.  To find out which state
*	is used as the intermediate state, look up the TMS value in the
*	jam_jtag_state_transitions[] table.
*/
unsigned short jam_jtag_path_map[16] =
{
	0x0001, 0xFFFD, 0xFE01, 0xFFE7, 0xFFEF, 0xFF0F, 0xFFBF, 0xFF0F,
	0xFEFD, 0x0001, 0xF3FF, 0xF7FF, 0x87FF, 0xDFFF, 0x87FF, 0x7FFD
};
 
/*
*	Flag bits for jam_jtag_io() function
*/
#define TMS_HIGH   1
#define TMS_LOW    0
#define TDI_HIGH   1
#define TDI_LOW    0
#define READ_TDO   1
#define IGNORE_TDO 0
 
/****************************************************************************/
/*																			*/
 
JAM_RETURN_TYPE jam_init_jtag(void)
 
/*																			*/
/****************************************************************************/
{
	void **symbol_table = NULL;
	JAMS_STACK_RECORD *stack = NULL;
 
	/* initial JTAG state is unknown */
	jam_jtag_state = JAM_ILLEGAL_JTAG_STATE;
 
	/* initialize global variables to default state */
	jam_drstop_state = IDLE;
	jam_irstop_state = IDLE;
 
	/*&RA
	jam_dr_preamble  = 0;
	jam_dr_postamble = 0;
	jam_ir_preamble  = 0;
	jam_ir_postamble = 0;
	*/
	jam_dr_length    = 0;
	jam_ir_length    = 0;
 
	if (jam_workspace != NULL)
	{
		symbol_table = (void **) jam_workspace;
		stack = (JAMS_STACK_RECORD *) &symbol_table[JAMC_MAX_SYMBOL_COUNT];
		jam_dr_preamble_data = (long *) &stack[JAMC_MAX_NESTING_DEPTH];
		jam_dr_postamble_data = &jam_dr_preamble_data[JAMC_MAX_JTAG_DR_PREAMBLE / 32];
		jam_ir_preamble_data = &jam_dr_postamble_data[JAMC_MAX_JTAG_DR_POSTAMBLE / 32];
		jam_ir_postamble_data = &jam_ir_preamble_data[JAMC_MAX_JTAG_IR_PREAMBLE / 32];
		jam_dr_buffer = (char * )&jam_ir_postamble_data[JAMC_MAX_JTAG_IR_POSTAMBLE / 32];
		jam_ir_buffer = &jam_dr_buffer[JAMC_MAX_JTAG_DR_LENGTH / 8];
	}
	/*&RA
	else
	{
		jam_dr_preamble_data  = NULL;
		jam_dr_postamble_data = NULL;
		jam_ir_preamble_data  = NULL;
		jam_ir_postamble_data = NULL;
		jam_dr_buffer         = NULL;
		jam_ir_buffer         = NULL;
	}
	*/
	if(verbose&8) printf("jam_init_jtag workspace %lx chain parameters PREIR/DR, POSTIR/DR =%d/%d, %d/%d\n",
		(unsigned long)jam_workspace,jam_ir_preamble,jam_dr_preamble,jam_ir_postamble,jam_dr_postamble); 
	return (JAMC_SUCCESS);
}
 
/****************************************************************************/
/*																			*/
 
JAM_RETURN_TYPE jam_set_drstop_state
(
	JAME_JTAG_STATE state
)
 
/*																			*/
/****************************************************************************/
{
	jam_drstop_state = state;
 
	return (JAMC_SUCCESS);
}
 
/****************************************************************************/
/*																			*/
 
JAM_RETURN_TYPE jam_set_irstop_state
(
	JAME_JTAG_STATE state
)
 
/*																			*/
/****************************************************************************/
{
	jam_irstop_state = state;
 
	return (JAMC_SUCCESS);
}
 
/****************************************************************************/
/*																			*/
 
JAM_RETURN_TYPE jam_set_dr_preamble
(
	int count,
	int start_index,
	long *data
)
 
/*																			*/
/****************************************************************************/
{
	JAM_RETURN_TYPE status = JAMC_SUCCESS;
	int alloc_longs = 0;
	int i = 0;
	int bit = 0;
 
	if (count >= 0)
	{
		if (jam_workspace != NULL)
		{
			if (count > JAMC_MAX_JTAG_DR_PREAMBLE)
			{
				status = JAMC_OUT_OF_MEMORY;
			}
			else
			{
				jam_dr_preamble = count;
			}
		}
		else
		{
			if (count > jam_dr_preamble)
			{
				alloc_longs = (count + 31) >> 5;
				jam_free(jam_dr_preamble_data);
				jam_dr_preamble_data = (long *) jam_malloc(
					alloc_longs * sizeof(long));
 
				if (jam_dr_preamble_data == NULL)
				{
					status = JAMC_OUT_OF_MEMORY;
				}
				else
				{
					jam_dr_preamble = count;
				}
			}
			else
			{
				jam_dr_preamble = count;
			}
		}
 
		if (status == JAMC_SUCCESS)
		{
			for (i = 0; i < count; ++i)
			{
				bit = i + start_index;
 
				if (data == NULL)
				{
					jam_dr_preamble_data[i >> 5] |= (1L << (bit & 0x1f));
				}
				else
				{
					if (data[bit >> 5] & (1L << (bit & 0x1f)))
					{
						jam_dr_preamble_data[i >> 5] |= (1L << (bit & 0x1f));
					}
					else
					{
						jam_dr_preamble_data[i >> 5] &=
							~(unsigned long) (1L << (bit & 0x1f));
					}
				}
			}
		}
	}
 
	return (status);
}
 
/****************************************************************************/
/*																			*/
 
JAM_RETURN_TYPE jam_set_ir_preamble
(
	int count,
	int start_index,
	long *data
)
 
/*																			*/
/****************************************************************************/
{
	JAM_RETURN_TYPE status = JAMC_SUCCESS;
	int alloc_longs = 0;
	int i = 0;
	int bit = 0;
 
	if (count >= 0)
	{
		if (jam_workspace != NULL)
		{
			if (count > JAMC_MAX_JTAG_IR_PREAMBLE)
			{
				status = JAMC_OUT_OF_MEMORY;
			}
			else
			{
				jam_ir_preamble = count;
			}
		}
		else
		{
			if (count > jam_ir_preamble)
			{
				alloc_longs = (count + 31) >> 5;
				jam_free(jam_ir_preamble_data);
				jam_ir_preamble_data = (long *) jam_malloc(
					alloc_longs * sizeof(long));
 
				if (jam_ir_preamble_data == NULL)
				{
					status = JAMC_OUT_OF_MEMORY;
				}
				else
				{
					jam_ir_preamble = count;
				}
			}
			else
			{
				jam_ir_preamble = count;
			}
		}
 
		if (status == JAMC_SUCCESS)
		{
			for (i = 0; i < count; ++i)
			{
				bit = i + start_index;
 
				if (data == NULL)
				{
					jam_ir_preamble_data[i >> 5] |= (1L << (bit & 0x1f));
				}
				else
				{
					if (data[bit >> 5] & (1L << (bit & 0x1f)))
					{
						jam_ir_preamble_data[i >> 5] |= (1L << (bit & 0x1f));
					}
					else
					{
						jam_ir_preamble_data[i >> 5] &=
							~(unsigned long) (1L << (bit & 0x1f));
					}
				}
			}
		}
	}
	if(verbose&8) printf("jam_ir_preamble=%d\n",jam_ir_preamble);
	return (status);
}
 
/****************************************************************************/
/*																			*/
 
JAM_RETURN_TYPE jam_set_dr_postamble
(
	int count,
	int start_index,
	long *data
)
 
/*																			*/
/****************************************************************************/
{
	JAM_RETURN_TYPE status = JAMC_SUCCESS;
	int alloc_longs = 0;
	int i = 0;
	int bit = 0;
 
	if (count >= 0)
	{
		if (jam_workspace != NULL)
		{
			if (count > JAMC_MAX_JTAG_DR_POSTAMBLE)
			{
				status = JAMC_OUT_OF_MEMORY;
			}
			else
			{
				jam_dr_postamble = count;
			}
		}
		else
		{
			if (count > jam_dr_postamble)
			{
				alloc_longs = (count + 31) >> 5;
				jam_free(jam_dr_postamble_data);
				jam_dr_postamble_data = (long *) jam_malloc(
					alloc_longs * sizeof(long));
 
				if (jam_dr_postamble_data == NULL)
				{
					status = JAMC_OUT_OF_MEMORY;
				}
				else
				{
					jam_dr_postamble = count;
				}
			}
			else
			{
				jam_dr_postamble = count;
			}
		}
 
		if (status == JAMC_SUCCESS)
		{
			for (i = 0; i < count; ++i)
			{
				bit = i + start_index;
 
				if (data == NULL)
				{
					jam_dr_postamble_data[i >> 5] |= (1L << (bit & 0x1f));
				}
				else
				{
					if (data[bit >> 5] & (1L << (bit & 0x1f)))
					{
						jam_dr_postamble_data[i >> 5] |= (1L << (bit & 0x1f));
					}
					else
					{
						jam_dr_postamble_data[i >> 5] &=
							~(unsigned long) (1L << (bit & 0x1f));
					}
				}
			}
		}
	}
 
	return (status);
}
 
/****************************************************************************/
/*																			*/
 
JAM_RETURN_TYPE jam_set_ir_postamble
(
	int count,
	int start_index,
	long *data
)
 
/*																			*/
/****************************************************************************/
{
	JAM_RETURN_TYPE status = JAMC_SUCCESS;
	int alloc_longs = 0;
	int i = 0;
	int bit = 0;
 
	if (count >= 0)
	{
		if (jam_workspace != NULL)
		{
			if (count > JAMC_MAX_JTAG_IR_POSTAMBLE)
			{
				status = JAMC_OUT_OF_MEMORY;
			}
			else
			{
				jam_ir_postamble = count;
			}
		}
		else
		{
			if (count > jam_ir_postamble)
			{
				alloc_longs = (count + 31) >> 5;
				jam_free(jam_ir_postamble_data);
				jam_ir_postamble_data = (long *) jam_malloc(
					alloc_longs * sizeof(long));
 
				if (jam_ir_postamble_data == NULL)
				{
					status = JAMC_OUT_OF_MEMORY;
				}
				else
				{
					jam_ir_postamble = count;
				}
			}
			else
			{
				jam_ir_postamble = count;
			}
		}
 
		if (status == JAMC_SUCCESS)
		{
			for (i = 0; i < count; ++i)
			{
				bit = i + start_index;
 
				if (data == NULL)
				{
					jam_ir_postamble_data[i >> 5] |= (1L << (bit & 0x1f));
				}
				else
				{
					if (data[bit >> 5] & (1L << (bit & 0x1f)))
					{
						jam_ir_postamble_data[i >> 5] |= (1L << (bit & 0x1f));
					}
					else
					{
						jam_ir_postamble_data[i >> 5] &=
							~(unsigned long) (1L << (bit & 0x1f));
					}
				}
			}
		}
	}
 
	return (status);
}
 
/****************************************************************************/
/*																			*/
 
void jam_jtag_reset_idle(void)
 
/*																			*/
/****************************************************************************/
{
	int i = 0;
 
	/*
	*	Go to Test Logic Reset (no matter what the starting state may be)
	*/
	for (i = 0; i < 5; ++i)
	{
		jam_jtag_io(TMS_HIGH, TDI_LOW, IGNORE_TDO);
	}
 
	/*
	*	Now step to Run Test / Idle
	*/
	jam_jtag_io(TMS_LOW, TDI_LOW, IGNORE_TDO);
 
	jam_jtag_state = IDLE;
}
 
/****************************************************************************/
/*																			*/
 
JAM_RETURN_TYPE jam_goto_jtag_state
(
	JAME_JTAG_STATE state
)
 
/*																			*/
/****************************************************************************/
{
	int tms = 0;
	int count = 0;
	JAM_RETURN_TYPE status = JAMC_SUCCESS;
 
	if (jam_jtag_state == JAM_ILLEGAL_JTAG_STATE)
	{
		/* initialize JTAG chain to known state */
		jam_jtag_reset_idle();
	}
 
	if (jam_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))
		{
			jam_jtag_io(TMS_LOW, TDI_LOW, IGNORE_TDO);
		}
		else if (state == RESET)
		{
			jam_jtag_io(TMS_HIGH, TDI_LOW, IGNORE_TDO);
		}
	}
	else
	{
		while ((jam_jtag_state != state) && (count < 9))
		{
			/*
			*	Get TMS value to take a step toward desired state
			*/
			tms = (jam_jtag_path_map[jam_jtag_state] & (1 << state)) ?
				TMS_HIGH : TMS_LOW;
 
			/*
			*	Take a step
			*/
			jam_jtag_io(tms, TDI_LOW, IGNORE_TDO);
 
			if (tms)
			{
				jam_jtag_state =
					jam_jtag_state_transitions[jam_jtag_state].tms_high;
			}
			else
			{
				jam_jtag_state =
					jam_jtag_state_transitions[jam_jtag_state].tms_low;
			}
 
			++count;
		}
	}
 
	if (jam_jtag_state != state)
	{
		status = JAMC_INTERNAL_ERROR;
	}
 
	return (status);
}
 
/****************************************************************************/
/*																			*/
 
JAME_JTAG_STATE jam_get_jtag_state_from_name
(
	char *name
)
 
/*																			*/
/*	Description:	Finds JTAG state code corresponding to name of state	*/
/*					supplied as a string									*/
/*																			*/
/*	Returns:		JTAG state code, or JAM_ILLEGAL_JTAG_STATE if string	*/
/*					does not match any valid state name						*/
/*																			*/
/****************************************************************************/
{
	int i = 0;
	JAME_JTAG_STATE jtag_state = JAM_ILLEGAL_JTAG_STATE;
 
	for (i = 0; (jtag_state == JAM_ILLEGAL_JTAG_STATE) &&
		(i < (int) JAMC_JTAG_STATE_COUNT); ++i)
	{
		if (jam_strcmp(name, jam_jtag_state_table[i].string) == 0)
		{
			jtag_state = jam_jtag_state_table[i].state;
		}
	}
 
	return (jtag_state);
}
 
/****************************************************************************/
/*																			*/
 
JAM_RETURN_TYPE jam_do_wait_cycles
(
	long cycles,
	JAME_JTAG_STATE wait_state
)
 
/*																			*/
/*	Description:	Causes JTAG hardware to loop in the specified stable	*/
/*					state for the specified number of TCK clock cycles.		*/
/*																			*/
/*	Returns:		JAMC_SUCCESS for success, else appropriate error code	*/
/*																			*/
/****************************************************************************/
{
	int tms = 0;
	long count = 0L;
	JAM_RETURN_TYPE status = JAMC_SUCCESS;
 
	if (jam_jtag_state != wait_state)
	{
		status = jam_goto_jtag_state(wait_state);
	}
 
	if (status == JAMC_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++)
		{
			jam_jtag_io(tms, TDI_LOW, IGNORE_TDO);
		}
	}
 
	return (status);
}
 
/****************************************************************************/
/*																			*/
 
JAM_RETURN_TYPE jam_do_wait_microseconds
(
	long microseconds,
	JAME_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:		JAMC_SUCCESS for success, else appropriate error code	*/
/*																			*/
/****************************************************************************/
{
	JAM_RETURN_TYPE status = JAMC_SUCCESS;
 
	if ((jam_jtag_state != JAM_ILLEGAL_JTAG_STATE) &&
		(jam_jtag_state != wait_state))
	{
		status = jam_goto_jtag_state(wait_state);
	}
 
	if (status == JAMC_SUCCESS)
	{
		/*
		*	Wait for specified time interval
		*/
		jam_delay(microseconds);
	}
 
	return (status);
}
 
/****************************************************************************/
/*																			*/
 
void jam_jtag_concatenate_data
(
	char *buffer,
	long *preamble_data,
	long preamble_count,
	long *target_data,
	long start_index,
	long target_count,
	long *postamble_data,
	long postamble_count
)
 
/*																			*/
/*	Description:	Copies preamble data, target data, and postamble data	*/
/*					into one buffer for IR or DR scans.  Note that buffer	*/
/*					is an array of char, while other arrays are of long		*/
/*																			*/
/*	Returns:		nothing													*/
/*																			*/
/****************************************************************************/
{
	long i = 0L;
	long j = 0L;
	long k = 0L;
 
	for (i = 0L; i < preamble_count; ++i)
	{
		if (preamble_data[i >> 5] & (1L << (i & 0x1f)))
		{
			buffer[i >> 3] |= (1 << (i & 7));
		}
		else
		{
			buffer[i >> 3] &= ~(unsigned int) (1 << (i & 7));
		}
	}
 
	j = start_index;
	k = preamble_count + target_count;
	for (; i < k; ++i, ++j)
	{
		if (target_data[j >> 5] & (1L << (j & 0x1f)))
		{
			buffer[i >> 3] |= (1 << (i & 7));
		}
		else
		{
			buffer[i >> 3] &= ~(unsigned int) (1 << (i & 7));
		}
	}
 
	j = 0L;
	k = preamble_count + target_count + postamble_count;
	for (; i < k; ++i, ++j)
	{
		if (postamble_data[j >> 5] & (1L << (j & 0x1f)))
		{
			buffer[i >> 3] |= (1 << (i & 7));
		}
		else
		{
			buffer[i >> 3] &= ~(unsigned int) (1 << (i & 7));
		}
	}
}
 
/****************************************************************************/
/*																			*/
 
void jam_jtag_extract_target_data
(
	char *buffer,
	long *target_data,
	long start_index,
	long preamble_count,
	long target_count
)
 
/*																			*/
/*	Description:	Copies target data from scan buffer, filtering out		*/
/*					preamble and postamble data.   Note that buffer is an	*/
/*					array of char, while target_data is an array of long	*/
/*																			*/
/*	Returns:		nothing													*/
/*																			*/
/****************************************************************************/
{
	long i = 0L;
	long j = 0L;
	long k = 0L;
 
	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 >> 5] |= (1L << (i & 0x1f));
		}
		else
		{
			target_data[i >> 5] &= ~(unsigned long) (1L << (i & 0x1f));
		}
	}
}
 
int jam_jtag_drscan
(
	int start_state,
	int count,
	char *tdi,
	char *tdo
)
{
	int i = 0;
	int tdo_bit = 0;
	int status = 1;
 
	/*
	*	First go to DRSHIFT state
	*/
	switch (start_state)
	{
	case 0:						/* IDLE */
		jam_jtag_io(1, 0, 0);	/* DRSELECT */
		jam_jtag_io(0, 0, 0);	/* DRCAPTURE */
		jam_jtag_io(0, 0, 0);	/* DRSHIFT */
		break;
 
	case 1:						/* DRPAUSE */
		jam_jtag_io(1, 0, 0);	/* DREXIT2 */
		jam_jtag_io(0, 0, 0);	/* DRSHIFT */
		break;
 
	case 2:						/* IRPAUSE */
		jam_jtag_io(1, 0, 0);	/* IREXIT2 */
		jam_jtag_io(1, 0, 0);	/* IRUPDATE */
		jam_jtag_io(1, 0, 0);	/* DRSELECT */
		jam_jtag_io(0, 0, 0);	/* DRCAPTURE */
		jam_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 = jam_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));
				}
			}
		}
 
		jam_jtag_io(0, 0, 0);	/* DRPAUSE */
	}
 
	return (status);
}
 
int jam_jtag_irscan
(
	int start_state,
	int count,
	char *tdi,
	char *tdo
)
{
	int i = 0;
	int tdo_bit = 0;
	int status = 1;
 
	/*
	*	First go to IRSHIFT state
	*/
	switch (start_state)
	{
	case 0:						/* IDLE */
		jam_jtag_io(1, 0, 0);	/* DRSELECT */
		jam_jtag_io(1, 0, 0);	/* IRSELECT */
		jam_jtag_io(0, 0, 0);	/* IRCAPTURE */
		jam_jtag_io(0, 0, 0);	/* IRSHIFT */
		break;
 
	case 1:						/* DRPAUSE */
		jam_jtag_io(1, 0, 0);	/* DREXIT2 */
		jam_jtag_io(1, 0, 0);	/* DRUPDATE */
		jam_jtag_io(1, 0, 0);	/* DRSELECT */
		jam_jtag_io(1, 0, 0);	/* IRSELECT */
		jam_jtag_io(0, 0, 0);	/* IRCAPTURE */
		jam_jtag_io(0, 0, 0);	/* IRSHIFT */
		break;
 
	case 2:						/* IRPAUSE */
		jam_jtag_io(1, 0, 0);	/* IREXIT2 */
		jam_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 = jam_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));
				}
			}
		}
 
		jam_jtag_io(0, 0, 0);	/* IRPAUSE */
	}
 
	return (status);
}
 
/****************************************************************************/
/*																			*/
 
JAM_RETURN_TYPE jam_do_irscan
(
	long count,
	long *data,
	long start_index
)
 
/*																			*/
/*	Description:	Shifts data into instruction register					*/
/*																			*/
/*	Returns:		JAMC_SUCCESS for success, else appropriate error code	*/
/*																			*/
/****************************************************************************/
{
	int start_code = 0;
	int alloc_chars = 0;
	int shift_count = (int) (jam_ir_preamble + count + jam_ir_postamble);
	JAM_RETURN_TYPE status = JAMC_SUCCESS;
	JAME_JTAG_STATE start_state = JAM_ILLEGAL_JTAG_STATE;
 
	switch (jam_jtag_state)
	{
	case JAM_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 = JAMC_INTERNAL_ERROR;
		break;
	}
 
	if (status == JAMC_SUCCESS)
	{
		if (jam_jtag_state != start_state)
		{
			status = jam_goto_jtag_state(start_state);
		}
	}
 
	if (status == JAMC_SUCCESS)
	{
		if (jam_workspace != NULL)
		{
			if (shift_count > JAMC_MAX_JTAG_IR_LENGTH)
			{
				status = JAMC_OUT_OF_MEMORY;
			}
		}
		else if (shift_count > jam_ir_length)
		{
			alloc_chars = (shift_count + 7) >> 3;
			jam_free(jam_ir_buffer);
			jam_ir_buffer = (char *) jam_malloc(alloc_chars);
 
			if (jam_ir_buffer == NULL)
			{
				status = JAMC_OUT_OF_MEMORY;
			}
			else
			{
				jam_ir_length = alloc_chars * 8;
			}
		}
	}
 
	if (status == JAMC_SUCCESS)
	{
		/*
		*	Copy preamble data, IR data, and postamble data into a buffer
		*/
		jam_jtag_concatenate_data
		(
			jam_ir_buffer,
			jam_ir_preamble_data,
			jam_ir_preamble,
			data,
			start_index,
			count,
			jam_ir_postamble_data,
			jam_ir_postamble
		);
 
		/*
		*	Do the IRSCAN
		*/
		if(verbose&8) printf("jam_do_irscan jam_ir_preamble=%d\n",jam_ir_preamble);
		jam_jtag_irscan
		(
			start_code,
			shift_count,
			jam_ir_buffer,
			NULL
		);
 
		/* jam_jtag_irscan() always ends in IRPAUSE state */
		jam_jtag_state = IRPAUSE;
	}
 
	if (status == JAMC_SUCCESS)
	{
		if (jam_irstop_state != IRPAUSE)
		{
			status = jam_goto_jtag_state(jam_irstop_state);
		}
	}
 
	return (status);
}
 
/****************************************************************************/
/*																			*/
 
JAM_RETURN_TYPE jam_swap_ir
(
	long count,
	long *in_data,
	long in_index,
	long *out_data,
	long out_index
)
 
/*																			*/
/*	Description:	Shifts data into instruction register, capturing output	*/
/*					data													*/
/*																			*/
/*	Returns:		JAMC_SUCCESS for success, else appropriate error code	*/
/*																			*/
/****************************************************************************/
{
	int start_code = 0;
	int alloc_chars = 0;
	int shift_count = (int) (jam_ir_preamble + count + jam_ir_postamble);
	JAM_RETURN_TYPE status = JAMC_SUCCESS;
	JAME_JTAG_STATE start_state = JAM_ILLEGAL_JTAG_STATE;
 
	switch (jam_jtag_state)
	{
	case JAM_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 = JAMC_INTERNAL_ERROR;
		break;
	}
 
	if (status == JAMC_SUCCESS)
	{
		if (jam_jtag_state != start_state)
		{
			status = jam_goto_jtag_state(start_state);
		}
	}
 
	if (status == JAMC_SUCCESS)
	{
		if (jam_workspace != NULL)
		{
			if (shift_count > JAMC_MAX_JTAG_IR_LENGTH)
			{
				status = JAMC_OUT_OF_MEMORY;
			}
		}
		else if (shift_count > jam_ir_length)
		{
			alloc_chars = (shift_count + 7) >> 3;
			jam_free(jam_ir_buffer);
			jam_ir_buffer = (char *) jam_malloc(alloc_chars);
 
			if (jam_ir_buffer == NULL)
			{
				status = JAMC_OUT_OF_MEMORY;
			}
			else
			{
				jam_ir_length = alloc_chars * 8;
			}
		}
	}
 
	if (status == JAMC_SUCCESS)
	{
		/*
		*	Copy preamble data, IR data, and postamble data into a buffer
		*/
		jam_jtag_concatenate_data
		(
			jam_ir_buffer,
			jam_ir_preamble_data,
			jam_ir_preamble,
			in_data,
			in_index,
			count,
			jam_ir_postamble_data,
			jam_ir_postamble
		);
 
		/*
		*	Do the IRSCAN
		*/
        if(verbose&8) printf("jam_swap_ir jam_ir_preamble=%d\n",jam_ir_preamble);
		jam_jtag_irscan
		(
			start_code,
			shift_count,
			jam_ir_buffer,
			jam_ir_buffer
		);
 
		/* jam_jtag_irscan() always ends in IRPAUSE state */
		jam_jtag_state = IRPAUSE;
	}
 
	if (status == JAMC_SUCCESS)
	{
		if (jam_irstop_state != IRPAUSE)
		{
			status = jam_goto_jtag_state(jam_irstop_state);
		}
	}
 
	if (status == JAMC_SUCCESS)
	{
		/*
		*	Now extract the returned data from the buffer
		*/
		jam_jtag_extract_target_data
		(
			jam_ir_buffer,
			out_data,
			out_index,
			jam_ir_preamble,
			count
		);
	}
 
	return (status);
}
 
/****************************************************************************/
/*																			*/
 
JAM_RETURN_TYPE jam_do_drscan
(
	long count,
	long *data,
	long start_index
)
 
/*																			*/
/*	Description:	Shifts data into data register (ignoring output data)	*/
/*																			*/
/*	Returns:		JAMC_SUCCESS for success, else appropriate error code	*/
/*																			*/
/****************************************************************************/
{
	int start_code = 0;
	int alloc_chars = 0;
	int shift_count = (int) (jam_dr_preamble + count + jam_dr_postamble);
	JAM_RETURN_TYPE status = JAMC_SUCCESS;
	JAME_JTAG_STATE start_state = JAM_ILLEGAL_JTAG_STATE;
 
	switch (jam_jtag_state)
	{
	case JAM_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 = JAMC_INTERNAL_ERROR;
		break;
	}
 
	if (status == JAMC_SUCCESS)
	{
		if (jam_jtag_state != start_state)
		{
			status = jam_goto_jtag_state(start_state);
		}
	}
 
	if (status == JAMC_SUCCESS)
	{
		if (jam_workspace != NULL)
		{
			if (shift_count > JAMC_MAX_JTAG_DR_LENGTH)
			{
				status = JAMC_OUT_OF_MEMORY;
			}
		}
		else if (shift_count > jam_dr_length)
		{
			alloc_chars = (shift_count + 7) >> 3;
			jam_free(jam_dr_buffer);
			jam_dr_buffer = (char *) jam_malloc(alloc_chars);
 
			if (jam_dr_buffer == NULL)
			{
				status = JAMC_OUT_OF_MEMORY;
			}
			else
			{
				jam_dr_length = alloc_chars * 8;
			}
		}
	}
 
	if (status == JAMC_SUCCESS)
	{
		/*
		*	Copy preamble data, DR data, and postamble data into a buffer
		*/
		jam_jtag_concatenate_data
		(
			jam_dr_buffer,
			jam_dr_preamble_data,
			jam_dr_preamble,
			data,
			start_index,
			count,
			jam_dr_postamble_data,
			jam_dr_postamble
		);
 
		/*
		*	Do the DRSCAN
		*/
		jam_jtag_drscan
		(
			start_code,
			shift_count,
			jam_dr_buffer,
			NULL
		);
 
		/* jam_jtag_drscan() always ends in DRPAUSE state */
		jam_jtag_state = DRPAUSE;
	}
 
	if (status == JAMC_SUCCESS)
	{
		if (jam_drstop_state != DRPAUSE)
		{
			status = jam_goto_jtag_state(jam_drstop_state);
		}
	}
 
	return (status);
}
 
/****************************************************************************/
/*																			*/
 
JAM_RETURN_TYPE jam_swap_dr
(
	long count,
	long *in_data,
	long in_index,
	long *out_data,
	long out_index
)
 
/*																			*/
/*	Description:	Shifts data into data register, capturing output data	*/
/*																			*/
/*	Returns:		JAMC_SUCCESS for success, else appropriate error code	*/
/*																			*/
/****************************************************************************/
{
	int start_code = 0;
	int alloc_chars = 0;
	int shift_count = (int) (jam_dr_preamble + count + jam_dr_postamble);
	JAM_RETURN_TYPE status = JAMC_SUCCESS;
	JAME_JTAG_STATE start_state = JAM_ILLEGAL_JTAG_STATE;
 
	switch (jam_jtag_state)
	{
	case JAM_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 = JAMC_INTERNAL_ERROR;
		break;
	}
 
	if (status == JAMC_SUCCESS)
	{
		if (jam_jtag_state != start_state)
		{
			status = jam_goto_jtag_state(start_state);
		}
	}
 
	if (status == JAMC_SUCCESS)
	{
		if (jam_workspace != NULL)
		{
			if (shift_count > JAMC_MAX_JTAG_DR_LENGTH)
			{
				status = JAMC_OUT_OF_MEMORY;
			}
		}
		else if (shift_count > jam_dr_length)
		{
			alloc_chars = (shift_count + 7) >> 3;
			jam_free(jam_dr_buffer);
			jam_dr_buffer = (char *) jam_malloc(alloc_chars);
 
			if (jam_dr_buffer == NULL)
			{
				status = JAMC_OUT_OF_MEMORY;
			}
			else
			{
				jam_dr_length = alloc_chars * 8;
			}
		}
	}
 
	if (status == JAMC_SUCCESS)
	{
		/*
		*	Copy preamble data, DR data, and postamble data into a buffer
		*/
		jam_jtag_concatenate_data
		(
			jam_dr_buffer,
			jam_dr_preamble_data,
			jam_dr_preamble,
			in_data,
			in_index,
			count,
			jam_dr_postamble_data,
			jam_dr_postamble
		);
 
		/*
		*	Do the DRSCAN
		*/
		jam_jtag_drscan
		(
			start_code,
			shift_count,
			jam_dr_buffer,
			jam_dr_buffer
		);
 
		/* jam_jtag_drscan() always ends in DRPAUSE state */
		jam_jtag_state = DRPAUSE;
	}
 
	if (status == JAMC_SUCCESS)
	{
		if (jam_drstop_state != DRPAUSE)
		{
			status = jam_goto_jtag_state(jam_drstop_state);
		}
	}
 
	if (status == JAMC_SUCCESS)
	{
		/*
		*	Now extract the returned data from the buffer
		*/
		jam_jtag_extract_target_data
		(
			jam_dr_buffer,
			out_data,
			out_index,
			jam_dr_preamble,
			count
		);
	}
 
	return (status);
}
 
/****************************************************************************/
/*																			*/
 
void jam_free_jtag_padding_buffers(int reset_jtag)
 
/*																			*/
/*	Description:	Frees memory allocated for JTAG IR and DR buffers		*/
/*																			*/
/*	Returns:		nothing													*/
/*																			*/
/****************************************************************************/
{
	/*
	*	If the JTAG interface was used, reset it to TLR
	*/
	if (reset_jtag && (jam_jtag_state != JAM_ILLEGAL_JTAG_STATE))
	{
		jam_jtag_reset_idle();
	}
 
	if (jam_workspace == NULL)
	{
		if (jam_dr_preamble_data != NULL)
		{
			jam_free(jam_dr_preamble_data);
			jam_dr_preamble_data = NULL;
		}
 
		if (jam_dr_postamble_data != NULL)
		{
			jam_free(jam_dr_postamble_data);
			jam_dr_postamble_data = NULL;
		}
 
		if (jam_dr_buffer != NULL)
		{
			jam_free(jam_dr_buffer);
			jam_dr_buffer = NULL;
		}
 
		if (jam_ir_preamble_data != NULL)
		{
			jam_free(jam_ir_preamble_data);
			jam_ir_preamble_data = NULL;
		}
 
		if (jam_ir_postamble_data != NULL)
		{
			jam_free(jam_ir_postamble_data);
			jam_ir_postamble_data = NULL;
		}
 
		if (jam_ir_buffer != NULL)
		{
			jam_free(jam_ir_buffer);
			jam_ir_buffer = NULL;
		}
	}
}
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.