📄 jtag_flash_f02x.c
字号:
//------------------------------------------------------------------------------------
// JTAG_Flash_F02x.c
//------------------------------------------------------------------------------------
// This program contains some primitive routines which read, write, and erase the FLASH
// through the JTAG port on a C8051Fxxx device under test (DUT). The JTAG pins on the
// DUT are connected to port pins on the C8051F02x 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
//------------------------------------------------------------------------------------
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
// GPIO pins connecting to JTAG pins on device to be programmed (DUT)
sbit TCK = P3^7; // JTAG Test Clock
sbit TMS = P3^6; // JTAG Mode Select
sbit TDI = P3^5; // JTAG Data Input
sbit TDO = P3^4; // JTAG Data Output
#define TRUE 1
#define FALSE 0
// JTAG Instruction Register Addresses
#define INST_LENGTH 16 // number of bits in the Instruction Register
#define BYPASS 0xffff
#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
//------------------------------------------------------------------------------------
// Function PROTOTYPES
//------------------------------------------------------------------------------------
void SYSCLK_Init (void);
void PORT_Init (void);
void JTAG_StrobeTCK (void);
void JTAG_Reset (void);
unsigned int JTAG_IR_Scan (unsigned int instruction, int num_bits);
unsigned long JTAG_DR_Scan (unsigned long dat, int 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) {
unsigned long id;
unsigned char dest;
int pass;
id = 0x12345678L;
WDTCN = 0xde; // disable watchdog timer
WDTCN = 0xad;
PORT_Init (); // initialize crossbar and GPIO
SYSCLK_Init (); // initialize oscillator
JTAG_Reset (); // Reset the JTAG state machine on DUT
JTAG_IR_Scan (RESET, INST_LENGTH); // Reset the DUT
JTAG_IR_Scan (IDCODE, INST_LENGTH); // load IDCODE into IR and HALT the DUT
id = JTAG_DR_Scan (0x0L, IDCODE_LEN); // read the IDCODE
// IDCODE should = 0x10000243 for
// C8051F000 rev D device
// here we erase the FLASH page 0x1000 - 0x11ff, read 0x1000 (it's an 0xff),
// write a 0x66 to 0x1000, and read 0x1000 again (it's changed to an 0x66).
while (1) {
pass = FLASH_PageErase (0x7c00); // erase page prior to writing...
while (!pass); // handle Write Lock condition
dest = 0x5a; // set test variable to non-0xff value
pass = FLASH_ByteRead (0x7c00, &dest); // dest should return 0xff
while (!pass); // handle Read Lock condition
dest = 0x66;
pass = FLASH_ByteWrite (0x7c00, dest); // store 0x66 at 0x1000
while (!pass); // handle Read Lock condition
pass = FLASH_ByteRead (0x7c00, &dest); // dest should return 0x66
while (!pass); // handle Read Lock condition
pass = FLASH_PageErase (0x7c00);
while (!pass);
pass = FLASH_ByteRead (0x7c00, &dest);
while (!pass);
}
}
//------------------------------------------------------------------------------------
// Functions and Procedures
//------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// 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
}
//------------------------------------------------------------------------------------
// JTAG_StrobeTCK
//------------------------------------------------------------------------------------
// This routine strobes the TCK pin (brings high then back low again)
// on the target system.
//
void JTAG_StrobeTCK (void) {
TCK = 1;
TCK = 0;
}
//------------------------------------------------------------------------------------
// JTAG_Reset
//------------------------------------------------------------------------------------
// This routine places the JTAG state machine on the target system in
// the Test Logic Reset state by strobing TCK 5 times while leaving
// TMS high. Leaves the JTAG state machine in the Run_Test/Idle state.
//
void JTAG_Reset (void) {
TMS = 1;
JTAG_StrobeTCK (); // move to Test Logic Reset state
JTAG_StrobeTCK ();
JTAG_StrobeTCK ();
JTAG_StrobeTCK ();
JTAG_StrobeTCK ();
TMS = 0;
JTAG_StrobeTCK (); // move to Run_Test/Idle state
}
//------------------------------------------------------------------------------------
// JTAG_IR_Scan
//------------------------------------------------------------------------------------
// This routine loads the supplied <instruction> of <num_bits> length into the JTAG
// Instruction Register on the target system. Leaves in the Run_Test/Idle state.
// The return value is the n-bit value read from the IR.
// Assumes the JTAG state machine starts in the Run_Test/Idle state.
//
unsigned int JTAG_IR_Scan (unsigned int instruction, int num_bits) {
unsigned int retval; // JTAG instruction read
int i; // JTAG IR bit counter
retval = 0x0;
TMS = 1;
JTAG_StrobeTCK (); // move to SelectDR
TMS = 1;
JTAG_StrobeTCK (); // move to SelectIR
TMS = 0;
JTAG_StrobeTCK (); // move to Capture_IR
TMS = 0;
JTAG_StrobeTCK (); // move to Shift_IR state
for (i=0; i < num_bits; i++) {
TDI = (instruction & 0x01); // shift IR, LSB-first
instruction = instruction >> 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -