Example code


/*
 * Example use of XJAPI.
 * Reads idcodes from the XJDemo board v2/v3 and demonstrates the use of test-reset sequences.
 *
 * Copyright 2009-2024 (c) XJTAG Ltd. All rights reserved.
 * Licensed under the MIT Licence. See Licence.txt for more information.
 */

#include <stdio.h>
#include <stdlib.h>

#define XJAPI_VERSION 0x020300
#include "xjapi.h"

// TCK frequency (10MHz)
#define FREQUENCY (10 * 1000 * 1000)

// Number of devices
#define DEVICECOUNT 2

// A custom pinmap. 
static XJAPI_USER_MAP pinMap = {
	{ XJAPI_HIGH,     XJAPI_DRIVE_HIGH },  // has to be high
	{ XJAPI_DISABLED,                  },  // has to be an input
	{ XJAPI_DISABLED,                  },
	{ XJAPI_LOW,      XJAPI_DRIVE_HIGH },  // has to be low
	{ XJAPI_TDI,      XJAPI_DRIVE_LOW  },  // TDI
	{ XJAPI_LOW,      XJAPI_DRIVE_HIGH },
	{ XJAPI_TMS,      XJAPI_DRIVE_LOW  },  // TMS
	{ XJAPI_LOW,      XJAPI_DRIVE_HIGH },
	{ XJAPI_TCK,      XJAPI_DRIVE_LOW  },  // TCK
	{ XJAPI_LOW,      XJAPI_DRIVE_HIGH },
	{ XJAPI_DISABLED,                  },
	{ XJAPI_LOW,      XJAPI_DRIVE_HIGH },
	{ XJAPI_TDO,                       },  // TDO
	{ XJAPI_LOW,      XJAPI_DRIVE_HIGH },
	{ XJAPI_PIO,      XJAPI_DRIVE_LOW  },  // our TRST pin (15)
	{ XJAPI_LOW,      XJAPI_DRIVE_HIGH },
	{ XJAPI_DISABLED,                  },
	{ XJAPI_LOW,      XJAPI_DRIVE_HIGH },
	{ XJAPI_DISABLED,                  },
	{ XJAPI_LOW,      XJAPI_DRIVE_HIGH },  // has to be low
};

#define PIOPIN 15

/*
 * Error handler.
 */
static void handleError(char *msg)
{
	char text[200];
	XJAPI_GetLastError(text, sizeof(text));
	printf("%s: %s\n", msg, text);
	XJAPI_Shutdown();
	exit(1);
}

int main(int argc, char *argv[])
{
	XJAPI_ERROR ec;
	unsigned int dataIn[DEVICECOUNT] = { 0, };
	unsigned int idCodes[DEVICECOUNT];
	unsigned int trstValues[3];
	unsigned int trstMasks[3];
	int i;

	// hide unused argument warnings
	(void)argc;
	(void)argv;

	XJAPI_Startup();

	// Initialise the hardware
	ec = XJAPI_HardwareSetup(0, FREQUENCY, XJAPI_XJTAG, TRUE);
	if (ec)
		handleError("Failed to execute HardwareSetup");
	
	ec = XJAPI_SetPinMap(XJAPI_USERDEFINED, &pinMap, TRUE);
	if (ec)
		handleError("Failed to execute SetPinMap");
	
	// Set up TRST. The TRST pin is pin 15, we need to pulse it low and then
	// hold it high, which requires 3 steps.
	// Note that this is not actually needed for either the XJDemo v2 or XJDemo v3 board, but is
	// here to demonstrate the use of PIO pins and TRST sequences
	trstValues[0] = 0x1 << (PIOPIN - 1);
	trstValues[1] = 0;
	trstValues[2] = 0x1 << (PIOPIN - 1);

	// TRST is the only pin we want to drive
	trstMasks[0] = trstMasks[1] = trstMasks[2] = 0x1 << (PIOPIN - 1);

	ec = XJAPI_SetTrst(3, trstValues, trstMasks, FALSE);
	if (ec)
		handleError("Failed to set up TRST sequence");

	// Finally, actually perform the TRST before trying to access the JTAG chain
	ec = XJAPI_Trst();
	if (ec)
		handleError("Failed to perform TRST");
	
	// Set TCK frequency to 10MHz (not strictly necessary, since we already
	// specified a frequency to XJAPI_HardwareSetup.
	ec = XJAPI_SetFrequency(FREQUENCY);
	if (ec)
		handleError("Failed to execute SetFrequency");

	// Set up skew control
	ec = XJAPI_AutoSkew();
	if (ec)
		handleError("Failed to execute AutoSkew");

	// Do a TMS Reset
	ec = XJAPI_TmsReset();
	if (ec)
		handleError("Failed to execute TMSReset");
	
	// Scan and check IDCodes (assuming two devices)
	// Since we've already done a Reset the TAP will be in IDCODE instruction
	// or BYPASS (if there is no IDCode)
	ec = XJAPI_Scan(XJAPI_SCAN_DR, 32 * DEVICECOUNT, dataIn, idCodes);
	if (ec)
		handleError("Failed to execute Scan");
		
	// Print out the idcodes we've found (we're assuming all devices in the
	// chain have an idcode)
	printf("Found IDCodes:\n");
	for (i = 0; i < DEVICECOUNT; i++)
		printf("  0x%08x\n", idCodes[i]);

	// Do a TMS Reset
	ec = XJAPI_TmsReset();
	if (ec)
		handleError("Failed to execute TMSReset");

	XJAPI_HardwareRelease();
	XJAPI_Shutdown();
	return 0;
}