⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jtagfunc.cpp

📁 TI MSP430 JTAG program for internal flash upgarde from PC printer port
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>
#include <windows.h>
#include <time.h>
#include <conio.h>
#include "jtagup.h"

extern word DEVICE;
extern byte g_tck;
extern byte g_tms;
extern byte g_tdi;
extern int lpt_address;

void putp1(byte tck, byte tms, byte tdi, byte usX);
int getp1(byte usX);
void error_out(char*);
void TCLKstrobes(word Amount);

//----------------------------------------------------------------------------
/* This function sets the target JTAG state machine (JTAG FSM) back into the 
   Run-Test/Idle state after a shift access.
*/
void PrepTCLK(void)
{
    // JTAG FSM = Exit-DR
    putp1(0,g_tms,g_tdi,1);     //ClrTCK();
    putp1(1,g_tms,g_tdi,1);     //SetTCK();
    // JTAG FSM = Update-DR
    g_tms = 0;                  //ClrTMS();
    putp1(0,g_tms,g_tdi,1);     //ClrTCK();
    putp1(1,g_tms,g_tdi,1);     //SetTCK();
    // JTAG FSM = Run-Test/Idle
}

//----------------------------------------------------------------------------
/*  Shift a value into TDI (MSB first) and simultaneously shift out a value
    from TDO (MSB first).
    Note:      When defining SPI_MODE the embedded SPI is used to speed up by 2.
    Arguments: word Format (number of bits shifted, 8 (F_BYTE) or 16 (F_WORD))
               word Data (data to be shifted into TDI)  
    Result:    word (scanned TDO value)
*/
word Shift(word Format, word Data)
{
    byte tclk;                      //= StoreTCLK();      // Store TCLK state;
    word TDOword = 0x0000;          // Initialize shifted-in word
    word MSB = 0x0000;
    word i;
/*    byte bypassbit;
	
	//bypass PxA
	bypassbit = (Format == F_WORD) ? 1 : 5;     //PxA DR 1 bit(bypass register), IR 5 bits
	g_tdi = (Format == F_WORD) ? 0 : 1;         //DR put low,IR put high (bypass IR = 0x1F)
    for (i = bypassbit; i > 0; i--) {
        putp1(0,g_tms,g_tdi,1);   //ClrTCK();
        putp1(1,g_tms,g_tdi,1);   //SetTCK();
    }
*/
	tclk = g_tdi;             //StoreTCLK();
    (Format == F_WORD) ? (MSB = 0x8000) : (MSB = 0x80);
    for (i = Format; i > 0; i--)  {
        g_tdi = ((Data & MSB) == 0) ? 0 : 1;    //((Data & MSB) == 0) ? ClrTDI() : SetTDI();
        Data <<= 1;
        if (i == 1)                 // Last bit requires TMS=1
            g_tms = 1;              //SetTMS();
        putp1(0,g_tms,g_tdi,1);     //ClrTCK();
        putp1(1,g_tms,g_tdi,1);     //SetTCK();
        TDOword <<= 1;              // TDO could be any port pin
        if (getp1(1) != 0)          //if (ScanTDO() != 0)
            TDOword++;	
    }
    //printf("%x\n",TDOword);
    // common exit
    g_tdi = tclk;           //RestoreTCLK(tclk);            // restore TCLK state
    PrepTCLK();             // Set JTAG FSM back into Run-Test/Idle
    return(TDOword);
}

//----------------------------------------------------------------------------
/* Function for shifting a new instruction into the JTAG instruction 
   register through TDI (MSB first, but with interchanged MSB - LSB, to
   simply use the same shifting function, Shift(), as used in DR_Shift16).
   Arguments: byte Instruction (8bit JTAG instruction, MSB first)
   Result:    word TDOword (value shifted out from TDO = JTAG ID)
*/
word IR_Shift(byte instruction)
{
    // JTAG FSM state = Run-Test/Idle
    g_tms = 1;                  //SetTMS();
    putp1(0,g_tms,g_tdi,1);     //ClrTCK();
    putp1(1,g_tms,g_tdi,1);     //SetTCK();
    // JTAG FSM state = Select DR-Scan
    putp1(0,g_tms,g_tdi,1);     //ClrTCK();
    putp1(1,g_tms,g_tdi,1);     //SetTCK();
  
    // JTAG FSM state = Select IR-Scan
    g_tms = 0;                  //ClrTMS();
    putp1(0,g_tms,g_tdi,1);     //ClrTCK();
    putp1(1,g_tms,g_tdi,1);     //SetTCK();
    // JTAG FSM state = Capture-IR
    putp1(0,g_tms,g_tdi,1);     //ClrTCK();
    putp1(1,g_tms,g_tdi,1);     //SetTCK();

    // JTAG FSM state = Shift-IR, Shift in TDI (8-bit)
    return(Shift(F_BYTE, instruction));
    // JTAG FSM state = Run-Test/Idle
}

word DR_Shift16(word data)
{
    // JTAG FSM state = Run-Test/Idle
    g_tms = 1;                  //SetTMS();
    putp1(0,g_tms,g_tdi,1);     //ClrTCK();
    putp1(1,g_tms,g_tdi,1);     //SetTCK();
  
    // JTAG FSM state = Select DR-Scan
    g_tms = 0;                  //ClrTMS();
    putp1(0,g_tms,g_tdi,1);     //ClrTCK();
    putp1(1,g_tms,g_tdi,1);     //SetTCK();
    // JTAG FSM state = Capture-DR
    putp1(0,g_tms,g_tdi,1);     //ClrTCK();
    putp1(1,g_tms,g_tdi,1);     //SetTCK();
  
    // JTAG FSM state = Shift-DR, Shift in TDI (16-bit)
    return(Shift(F_WORD, data));
    // JTAG FSM state = Run-Test/Idle
}

//----------------------------------------------------------------------------
/* Reset target JTAG interface and perform fuse-HW check.
   Arguments: None
   Result:    None
*/
void ResetTAP(void)
{
    word i;

    g_tms = 1;                  //SetTMS();
    putp1(1,g_tms,g_tdi,1);     //SetTCK();
    // Perform fuse check
    putp1(1,0,1,1);             //ClrTMS();
    putp1(1,1,1,1);             //SetTMS();
    putp1(1,0,1,1);             //ClrTMS();
    putp1(1,1,1,1);             //SetTMS();
    // Now fuse is checked, Reset JTAG FSM
    for (i = 6; i > 0; i--)
    {
        putp1(0,g_tms,0,1);     //ClrTCK();
        putp1(1,g_tms,0,1);     //SetTCK();
    }
    // JTAG FSM is now in Test-Logic-Reset  
    putp1(0,g_tms,g_tdi,1);     //ClrTCK();
    g_tms = 0;                  //ClrTMS();
    putp1(1,g_tms,g_tdi,1);     //SetTCK();
    // JTAG FSM is now in Run-Test/IDLE
}

//----------------------------------------------------------------------------
/* Function to set target CPU JTAG FSM into the instruction fetch state
   Argument: None
   Result:   word (STATUS_OK if instr. fetch was set, STATUS_ERROR otherwise)
*/
word SetInstrFetch(void)
{
    word i;

    IR_Shift(IR_CNTRL_SIG_CAPTURE);
  
    // Wait until CPU is in instr. fetch state, timeout after limited attempts
    for (i = 50; i > 0; i--) {
        putp1(g_tck,g_tms,0,1);   //ClrTCLK();
        putp1(g_tck,g_tms,1,1);   //SetTCLK();
        if ((DR_Shift16(0x0000) & 0x0080) == 0x0080)
	  	    return(STATUS_OK); 
    }
    printf("SetInstrFetch error\n");
    return(STATUS_ERROR); 
}

//----------------------------------------------------------------------------
/* Function to set the CPU into a controlled stop state
*/
void HaltCPU(void)
{
    SetInstrFetch();        // Set CPU into instruction fetch mode
  
    IR_Shift(IR_CNTRL_SIG_16BIT);
    DR_Shift16(0x2401);
    IR_Shift(IR_DATA_16BIT);
    DR_Shift16(0x3FFF);     // Send JMP $ instruction
    putp1(g_tck,g_tms,1,1); //SetTCLK();
    putp1(g_tck,g_tms,0,1); //ClrTCLK();
    IR_Shift(IR_CNTRL_SIG_16BIT);
    DR_Shift16(0x2409);     // Set JTAG_HALT bit
    putp1(g_tck,g_tms,1,1); //SetTCLK();
}

//----------------------------------------------------------------------------
/* Function to release the target CPU from the controlled stop state
*/
void ReleaseCPU(void)
{
    putp1(g_tck,g_tms,0,1); //ClrTCLK();
    IR_Shift(IR_CNTRL_SIG_16BIT);
    DR_Shift16(0x2401);     // Clear the HALT_JTAG bit
    IR_Shift(IR_ADDR_CAPTURE);
    putp1(g_tck,g_tms,1,1); //SetTCLK();
}

//------------------------------------------------------------------------
/* This function checks if the JTAG access security fuse is blown.
   Arguments: None
   Result:    word (STATUS_OK if fuse is blown, STATUS_ERROR otherwise)
*/
word IsFuseBlown(void)
{
    word i;
  
    for (i = 3; i > 0; i--)	{   //  First trial could be wrong
        IR_Shift(IR_CNTRL_SIG_CAPTURE);
  	    if (DR_Shift16(0xAAAA) == 0x5555)
  		    return(STATUS_OK);  // Fuse is blown
    }
    return(STATUS_ERROR);       // fuse is not blown 	
}

//----------------------------------------------------------------------------
/* Load a given address into the target CPU's program counter (PC).
   Argument: word Addr (destination address)
   Result:   None
*/
void SetPC(word Addr)
{
  SetInstrFetch();      // Set CPU into instruction fetch mode, TCLK=1
  
  // Load PC with address
  IR_Shift(IR_CNTRL_SIG_16BIT);
  DR_Shift16(0x3401);       // CPU has control of RW & BYTE.
  IR_Shift(IR_DATA_16BIT);
  DR_Shift16(0x4030);       // "mov #addr,PC" instruction
  putp1(g_tck,g_tms,1,1);   //SetTCLK();
  putp1(g_tck,g_tms,0,1);   //ClrTCLK();        
  DR_Shift16(Addr);	        // Send addr value
  putp1(g_tck,g_tms,1,1);   //SetTCLK();
  putp1(g_tck,g_tms,0,1);   //ClrTCLK(); 
  putp1(g_tck,g_tms,1,1);   //SetTCLK();
  putp1(g_tck,g_tms,0,1);   //ClrTCLK();            // Now the PC should be on Addr
  IR_Shift(IR_CNTRL_SIG_16BIT);
  DR_Shift16(0x2401);       // JTAG has control of RW & BYTE.
}

//----------------------------------------------------------------------------
/* This function reads one byte/word from a given address in memory
   Arguments: word Format (F_BYTE or F_WORD)
              word Addr (address of memory)
   Result:    word (content of the addressed memory location)
*/
word ReadMem(word Format, word Addr)
{
    word TDOword;
  
    HaltCPU();
  
    putp1(g_tck,g_tms,0,1); //ClrTCLK();
    IR_Shift(IR_CNTRL_SIG_16BIT);
    if  (Format == F_WORD)
	    DR_Shift16(0x2409);	// Set word read
    else
  	    DR_Shift16(0x2419);	// Set byte read	
    
    IR_Shift(IR_ADDR_16BIT);
    DR_Shift16(Addr);		// Set address
    IR_Shift(IR_DATA_TO_ADDR);
    putp1(g_tck,g_tms,1,1); //SetTCLK();
  
    putp1(g_tck,g_tms,0,1); //ClrTCLK();
    TDOword = DR_Shift16(0x0000);   // Shift out 16 bits
    putp1(g_tck,g_tms,1,1); //SetTCLK();

    ReleaseCPU();
    return(Format == F_WORD ? TDOword : TDOword & 0x00FF);
}

//----------------------------------------------------------------------------
/* This function reads an array of words from a memory.
   Arguments: word StartAddr (Start address of memory to be read)
              word Length (Number of words to be read)
              word *DataArray (Pointer to array for the data)
   Result:    None
*/
void ReadMemQuick(word StartAddr, word Length, word *DataArray)
{
  word i;
  
  // Initialize reading:
  //SetPC(StartAddr-4);
  SetPC(StartAddr-8); //lucas
  HaltCPU();
  
  putp1(g_tck,g_tms,0,1);   //ClrTCLK();
  IR_Shift(IR_CNTRL_SIG_16BIT);
  DR_Shift16(0x2409);       // Set RW to read
  IR_Shift(IR_DATA_QUICK);
  
  for (i = 0; i < Length; i++)
  {
    putp1(g_tck,g_tms,1,1); //SetTCLK();
    putp1(g_tck,g_tms,0,1); //ClrTCLK();
    DataArray[i] = DR_Shift16(0x0000); // Shift out the data
                                       // from the target.
  }
  putp1(g_tck,g_tms,1,1);   //SetTCLK();
  
  ReleaseCPU();
}

//----------------------------------------------------------------------------
/* This function writes one byte/word at a given address ( <0xA00) 
   Arguments: word Format (F_BYTE or F_WORD)
              word Addr (Address of data to be written)
              word Data (shifted data)  
   Result:    None
*/
void WriteMem(word Format, word Addr, word Data)
{
    HaltCPU();
  
    putp1(g_tck,g_tms,0,1); //ClrTCLK();
    IR_Shift(IR_CNTRL_SIG_16BIT);
    if  (Format == F_WORD)
	    DR_Shift16(0x2408);	// Set word write
    else
  	    DR_Shift16(0x2418);	// Set byte write
  	    
    IR_Shift(IR_ADDR_16BIT);
    DR_Shift16(Addr);		// Set addr
    IR_Shift(IR_DATA_TO_ADDR);
    DR_Shift16(Data);		// Shift in 16 bits
    putp1(g_tck,g_tms,1,1);   //SetTCLK();

    ReleaseCPU();
}

//----------------------------------------------------------------------------
/* Function to execute a Power-Up Clear (PUC) using JTAG CNTRL SIG register
   Arguments: None
   Result:    word (STATUS_OK if JTAG ID is valid, STATUS_ERROR otherwise)
*/
word ExecutePUC(void)
{
    word JTAGVERSION;

    IR_Shift(IR_CNTRL_SIG_16BIT);
    DR_Shift16(0x2C01);         // Apply Reset
    DR_Shift16(0x2401);         // Remove Reset
    putp1(g_tck,g_tms,0,1);     //ClrTCLK();
    putp1(g_tck,g_tms,1,1);     //SetTCLK();
    putp1(g_tck,g_tms,0,1);     //ClrTCLK();
    putp1(g_tck,g_tms,1,1);     //SetTCLK();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -