📄 jtag_chain_f02x.c
字号:
//************************************************************************************
// JTAG_Chain_F02x.c
//------------------------------------------------------------------------------------
// This program contains some primitive routines which gather information through the
// JTAG port on multiple JTAG compatible devices under test (DUT) connected in a
// chain. The TCK & TMS JTAG pins on the DUT are connected in parallel to port pins on
// the C8051F02x master device and the TDI & TDO pins are connected in
// series.
//
// **NOTE: The first device in the chain (device 0) is the one whose TDO pin is
// connected to the TDO pin of the master device.
//
// Target device: C8051F02x
//
// Tool chain: KEIL Eval 'c'
//************************************************************************************
//------------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------------
#include <c8051f020.h> // SFR declarations
//------------------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F02x
//------------------------------------------------------------------------------------
sfr16 DP = 0x82; // data pointer
sfr16 TMR3RL = 0x92; // Timer3 reload value
sfr16 TMR3 = 0x94; // Timer3 counter
sfr16 ADC0 = 0xbe; // ADC0 data
sfr16 ADC0GT = 0xc4; // ADC0 greater than window
sfr16 ADC0LT = 0xc6; // ADC0 less than window
sfr16 RCAP2 = 0xca; // Timer2 capture/reload
sfr16 T2 = 0xcc; // Timer2
sfr16 RCAP4 = 0xe4; // Timer4 capture/reload
sfr16 T4 = 0xf4; // Timer4
sfr16 DAC0 = 0xd2; // DAC0 data
sfr16 DAC1 = 0xd5; // DAC1 data
//------------------------------------------------------------------------------------
// Global CONSTANTS
//------------------------------------------------------------------------------------
#define MAX_NUM_DEVICES_IN_CHAIN 10
sbit LED = P1^6; // green LED: '1' = ON; '0' = OFF
sbit SW2 = P3^7; // SW2='0' means switch pressed
#define SYSCLK 22118400 // SYSCLK frequency in Hz
sbit TCK = P3^7; // JTAG Test Clock -- Connected to TCK pin on all devices.
sbit TMS = P3^6; // JTAG Mode Select -- Connected to TMS pin on all devices.
sbit TDI = P3^5; // JTAG Data Input(output of master) -- Connected to the
// TDI pin of device n.
sbit TDO = P3^4; // JTAG Data Output (input to master)-- Connected to the
// TDO pin of device 0.
#define TRUE 1
#define FALSE 0
// JTAG Instruction Register Addresses
#define INST_LENGTH 16 // number of bits in the C8051Fxxx
#define BYPASS 0xffff // Instruction Register
#define EXTEST 0x0000
#define SAMPLE 0x0002
#define RESET 0x2fff // System RESET Instruction
#define IDCODE 0x1004 // IDCODE Instruction address/HALT
#define IDCODE_LEN 32 // number of bits in the ID code
#define FLASHCON 0x4082 // FLASH Control Instruction address
#define FLCN_LEN 8 // number of bits in FLASHCON
#define FLASHDAT 0x4083 // FLASH Data Instruction address
#define FLD_RDLEN 10 // number of bits in an FLASHDAT read
#define FLD_WRLEN 8 // number of bits in an FLASHDAT write
#define FLASHADR 0x4084 // FLASH Address Instruction address
#define FLA_LEN 16 // number of bits in FLASHADR
#define FLASHSCL 0x4085 // FLASH Scale Instruction address
#define FLSC_LEN 8 // number of bits in FLASHSCL
//------------------------------------------------------------------------------------
// Global Variable DECLARATIONS
//------------------------------------------------------------------------------------
// The addresses of the following variables are explicitly defined for viewing
// purposes. If the width of the external memory window is 5 bytes, then each
// device will take up exactly one row starting from the second row.
char xdata num_devices _at_ 0x0000;
char xdata num_devices_before _at_ 0x0001; // #devices before and after the isolated
char xdata num_devices_after _at_ 0x0002; // device
char xdata num_IR_bits_before _at_ 0x0003; // #instruction register bits before and
char xdata num_IR_bits_after _at_ 0x0004; // after the isolated device
typedef struct JTAG_Information { // Discovery information
unsigned char IR_length; // Instruction register length
unsigned long id; // Identification code for each device
} JTAG_Information;
// Array: one entry per device in the
// JTAG chain
JTAG_Information xdata JTAG_info[MAX_NUM_DEVICES_IN_CHAIN];
//------------------------------------------------------------------------------------
// Function PROTOTYPES
//------------------------------------------------------------------------------------
void SYSCLK_Init (void);
void PORT_Init (void);
void JTAG_StrobeTCK (void);
void JTAG_Reset (void);
void Blink_Led(void);
void init(void);
void JTAG_Discover(void);
void JTAG_Discover_IR(void);
void JTAG_Discover_DR(void);
void JTAG_Isolate(char index);
unsigned long JTAG_IR_Scan (unsigned long instruction, char num_bits) ;
unsigned long JTAG_DR_Scan (unsigned long dat, char num_bits);
void JTAG_IWrite (unsigned int ireg, unsigned long dat, int num_bits);
unsigned long JTAG_IRead (unsigned int ireg, int num_bits);
int FLASH_ByteRead (unsigned int addr, unsigned char *pdat);
int FLASH_ByteWrite (unsigned int addr, unsigned char dat);
int FLASH_PageErase (unsigned int addr);
//------------------------------------------------------------------------------------
// MAIN Routine
//------------------------------------------------------------------------------------
void main (void)
{
long xdata id;
unsigned char dest;
int pass;
int address;
char device = 0;
WDTCN = 0xde; // disable watchdog timer
WDTCN = 0xad;
PORT_Init (); // initialize crossbar and GPIO
SYSCLK_Init (); // initialize oscillator
LED = 1; // turn on the LED
init(); // initialize JTAG Chain variables
JTAG_Discover(); // IDCODE should = 0x10000243 for
// C8051F000 rev D device
JTAG_Isolate(0); // isolate device 0
JTAG_IR_Scan (IDCODE, INST_LENGTH); // load IDCODE into IR and HALT the DUT
id = JTAG_DR_Scan (0x0L, IDCODE_LEN); // get the ID Code of the isolated device
// comment out this code if you have less than two devices in the chain
JTAG_Isolate(1);
JTAG_IR_Scan (IDCODE, INST_LENGTH); // load IDCODE into IR and HALT the DUT
id = JTAG_DR_Scan (0x0L, IDCODE_LEN); // get the ID Code of the isolated device
// comment out this code if you have less than three devices in the chain
JTAG_Isolate(2);
JTAG_IR_Scan (IDCODE, INST_LENGTH); // load IDCODE into IR and HALT the DUT
id = JTAG_DR_Scan (0x0L, IDCODE_LEN); // get the ID Code of the isolated device
for(device = 0; device < num_devices; device++) {
JTAG_Isolate(device);
//TEST 1 -- ERASE A FLASH PAGE
pass = FLASH_PageErase (0x1000); // erase page prior to writing
while (!pass); // handle Write Lock condition
//Verify that locations 0x1000 - 0x11FF are 0xFF
for(address = 0x1000; address < 0x1200; address++){
pass = FLASH_ByteRead (address, &dest); // dest should return 0xff
if(!pass || dest != 0xFF) Blink_Led();
}
//TEST 2 -- WRITE A PATTERN TO FLASH PAGE
for(address = 0x1000; address < 0x1200; address++){
dest = address & 0x00FF; // strip away upper 8 bits
pass = FLASH_ByteWrite (address, dest);// store LSByte of address at address
while (!pass); // handle Read Lock condition
}
dest = 0x12; // set test variable to non-0xff value
//Verify that locations 0x1000 - 0x11FF are following the pattern
for(address = 0x1000; address < 0x1200; address++){
pass = FLASH_ByteRead (address, &dest);
if(!pass || dest != (address & 0x00FF)) Blink_Led();
}
}
LED = 0; // turn off the led,
// program executed correctly
while(1);
}
//************************************************************************************
// Function and Procedure DEFINITIONS
//************************************************************************************
//-----------------------------------------------------------------------------
// SYSCLK_Init
//-----------------------------------------------------------------------------
//
// This routine initializes the system clock to use an 22.1184MHz crystal
// as its clock source.
//
void SYSCLK_Init (void)
{
int i; // delay counter
OSCXCN = 0x67; // start external oscillator with
// 22.1184MHz crystal
for (i=0; i < 256; i++) ; // XTLVLD blanking interval (>1ms)
while (!(OSCXCN & 0x80)) ; // Wait for crystal osc. to settle
OSCICN = 0x88; // select external oscillator as SYSCLK
// source and enable missing clock
// detector
}
//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Configure the Crossbar and GPIO ports
//
void PORT_Init (void)
{
XBR0 = 0x04; // Enable UART0
XBR1 = 0x00;
XBR2 = 0x40; // Enable crossbar and weak pull-ups
P0MDOUT |= 0x01; // enable TX0 as a push-pull output
P1MDOUT |= 0x40; // enable P1.6 (LED) as push-pull output
P3MDOUT |= 0xe0; // make P3.7-5 push-pull outputs
P3 &= ~0xe0; // TCK, TMS, and TDI all low
}
//------------------------------------------------------------------------------------
// Blink_Led
//------------------------------------------------------------------------------------
// This routine blinks the Green LED forever to indicate an error.
//
void Blink_Led(void)
{
int i; // millisecond counter
int ms = 200; // stay in each state for ms milliseconds
TCON &= ~0x30; // STOP Timer0 and clear overflow flag
TMOD &= ~0x0F; // configure Timer0 to 16-bit mode
TMOD |= 0x01;
CKCON |= 0x08; // Timer0 counts SYSCLKs
while (1){
LED = ~LED;
for (i = 0; i < ms; i++) { // count milliseconds
TR0 = 0; // STOP Timer0
TH0 = (-SYSCLK/1000) >> 8; // SET Timer0 to overflow in 1ms
TL0 = -SYSCLK/1000;
TR0 = 1; // START Timer0
while(TF0 == 0); // wait for overflow
TF0 = 0; // clear overflow indicator
}
}
}
//------------------------------------------------------------------------------------
// init
//------------------------------------------------------------------------------------
// This routine initializes the variables used in a JTAG chain.
//
void init (void)
{
num_devices = 1; // The default number of devices is one.
// JTAG_Discover() does not have to be
// called if only one device is connected.
num_devices_before = 0; // Initializing these variables to zero
num_devices_after = 0; // allows calling the JTAG_IR_Scan() and
num_IR_bits_before = 0; // the JTAG_DR_Scan() without first
num_IR_bits_after = 0; // calling JTAG_Isolate() when there is
// only one device in the chain.
}
//------------------------------------------------------------------------------------
// JTAG_StrobeTCK
//------------------------------------------------------------------------------------
// This routine strobes the TCK pin (brings high then back low again)
// on the target system.
//
void JTAG_StrobeTCK (void)
{
TCK = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -