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

📄 jtagfunc.c

📁 msp430的jtag程序下载的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*==========================================================================*\
|                                                                            |
| JTAGfunc.c                                                                 |
|                                                                            |
| JTAG Control Sequences for Erasing / Programming / Fuse Burning            |
|----------------------------------------------------------------------------|
| Project:              JTAG Functions                                       |
| Developed using:      IAR Embedded Workbench 3.40B [Kickstart]             |
|----------------------------------------------------------------------------|
| Author:               STO                                                  |
| Version:              1.6                                                  |
| Initial Version:      04-17-02                                             |
| Last Change:          07-31-06                                             |
|----------------------------------------------------------------------------|
| Version history:                                                           |
| 1.0 04/02 FRGR        Initial version.                                     |
| 1.1 04/02 ALB2        Formatting changes, added comments.                  |
| 1.2 08/02 ALB2        Initial code release with Lit# SLAA149.              |
| 1.3 09/05 JDI         'ResetTAP': added SetTDI for fuse check              |
|                       search for F2xxx to find respective modifications in |
|                       'SetPC', 'HaltCPU', 'VerifyPSA', 'EraseFLASH'        |
|                       'WriteFLASH'                                         |
|           SUN1        Software delays redesigned to use TimerA harware;    |
|                       see MsDelay() routine.                               |
| 1.4 01/06 STO         Added entry sequence for SpyBiWire devices           |
|                       Minor cosmetic changes                               |
| 1.5 03/06 STO         BlowFuse() make correct fuse check after blowing.    |
| 1.6 07/06 STO         Loop in WriteFLASH() changed.                        |
|----------------------------------------------------------------------------|
| Designed 2002 by Texas Instruments Germany                                 |
\*==========================================================================*/

#include "JTAGfunc.h"
#include "LowLevelFunc.h"
#include "Devices.h"

/****************************************************************************/
/* Low level routines for accessing the target device via JTAG:             */
/****************************************************************************/

//----------------------------------------------------------------------------
/* Function for shifting a given 16-bit word into the JTAG data register
   through TDI.
   Arguments: word data (16-bit data, MSB first)
   Result:    word (value is shifted out via TDO simultaneously)
*/
word DR_Shift16(word data)
{
    // JTAG FSM state = Run-Test/Idle
    SetTMS();
    ClrTCK();
    SetTCK();

    // JTAG FSM state = Select DR-Scan
    ClrTMS();
    ClrTCK();
    SetTCK();
    // JTAG FSM state = Capture-DR
    ClrTCK();
    SetTCK();

    // JTAG FSM state = Shift-DR, Shift in TDI (16-bit)
    return(Shift(F_WORD, data));
    // JTAG FSM state = Run-Test/Idle
}

//----------------------------------------------------------------------------
/* 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
    SetTMS();
    ClrTCK();
    SetTCK();
    // JTAG FSM state = Select DR-Scan
    ClrTCK();
    SetTCK();

    // JTAG FSM state = Select IR-Scan
    ClrTMS();
    ClrTCK();
    SetTCK();
    // JTAG FSM state = Capture-IR
    ClrTCK();
    SetTCK();

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

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

    // process TDI first to settle fuse current
    SetTDI();
    SetTMS();
    SetTCK();

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

    // Perform fuse check
    ClrTMS();
    SetTMS();
    ClrTMS();
    SetTMS();
}

//----------------------------------------------------------------------------
/* 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;

    // Perform Reset
    IR_Shift(IR_CNTRL_SIG_16BIT);
    DR_Shift16(0x2C01);                 // Apply Reset
    DR_Shift16(0x2401);                 // Remove Reset
    ClrTCLK();
    SetTCLK();
    ClrTCLK();
    SetTCLK();
    ClrTCLK();
    JtagVersion = IR_Shift(IR_ADDR_CAPTURE); // read JTAG ID, checked at function end
    SetTCLK();

    WriteMem(F_WORD, 0x0120, 0x5A80);   // Disable Watchdog on target device

    if (JtagVersion != JTAG_ID)
    {
        return(STATUS_ERROR);
    }
    return(STATUS_OK);
}

//----------------------------------------------------------------------------
/* 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--)
    {
        if (DR_Shift16(0x0000) & 0x0080)
        {
            return(STATUS_OK);
        }
        ClrTCLK();
        SetTCLK();
    }
    return(STATUS_ERROR);
}

//----------------------------------------------------------------------------
/* 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
    ClrTCLK();
    SetTCLK();                    // F2xxx
    DR_Shift16(Addr);             // "mov #addr,PC" instruction
    ClrTCLK();
    IR_Shift(IR_ADDR_CAPTURE);
    SetTCLK();
    ClrTCLK();                    // Now the PC should be on Addr
    IR_Shift(IR_CNTRL_SIG_16BIT);
    DR_Shift16(0x2401);           // JTAG has control of RW & BYTE.
}

//----------------------------------------------------------------------------
/* Function to set the CPU into a controlled stop state
*/
void HaltCPU(void)
{
    SetInstrFetch();              // Set CPU into instruction fetch mode

    IR_Shift(IR_DATA_16BIT);
    DR_Shift16(0x3FFF);           // Send JMP $ instruction
    ClrTCLK();
    IR_Shift(IR_CNTRL_SIG_16BIT);
    DR_Shift16(0x2409);           // Set JTAG_HALT bit
    SetTCLK();
}

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

//----------------------------------------------------------------------------
/* This function compares the computed PSA (Pseudo Signature Analysis) value
   to the PSA value shifted out from the target device.
   It is used for very fast data block write or erasure verification.
   Arguments: word StartAddr (Start address of data block to be checked)
              word Length (Number of words within data block)
              word *DataArray (Pointer to array with the data, 0 for Erase Check)
   Result:    word (STATUS_OK if comparison was successful, STATUS_ERROR otherwise)
*/
word VerifyPSA(word StartAddr, word Length, word *DataArray)
{
    word TDOword, i;
    word POLY = 0x0805;           // Polynom value for PSA calculation
    word PSA_CRC = StartAddr-2;   // Start value for PSA calculation

    ExecutePUC();

    if(DeviceHas_EnhVerify())
    {
        SetPC(StartAddr-4);
        HaltCPU();
        ClrTCLK();
        IR_Shift(IR_DATA_16BIT);
        DR_Shift16(StartAddr-2);
    }
    else
    {
        SetPC(StartAddr-2);
        SetTCLK();
        ClrTCLK();
    }
    IR_Shift(IR_DATA_PSA);
    for (i = 0; i < Length; i++)
    {
        // Calculate the PSA (Pseudo Signature Analysis) value
        if ((PSA_CRC & 0x8000) == 0x8000)
        {
            PSA_CRC ^= POLY;
            PSA_CRC <<= 1;
            PSA_CRC |= 0x0001;
        }
        else
        {
            PSA_CRC <<= 1;
        }
        // if pointer is 0 then use erase check mask, otherwise data
        &DataArray[0] == 0 ? (PSA_CRC ^= 0xFFFF) : (PSA_CRC ^= DataArray[i]);

        // Clock through the PSA
        SetTCLK();
        ClrTCLK();           // set here -> Fixes problem with F123 PSA in RAM

        ClrTCK();

        SetTMS();
        SetTCK();            // Select DR scan
        ClrTCK();
        ClrTMS();

        SetTCK();            // Capture DR
        ClrTCK();

        SetTCK();            // Shift DR
        ClrTCK();

        SetTMS();
        SetTCK();            // Exit DR
        ClrTCK();
        SetTCK();
        ClrTMS();
        ClrTCK();
        SetTCK();
    }
    IR_Shift(IR_SHIFT_OUT_PSA);
    TDOword = DR_Shift16(0x0000);     // Read out the PSA value
    SetTCLK();

    if(DeviceHas_EnhVerify())
    {
        ReleaseCPU();
    }
    ExecutePUC();
    return((TDOword == PSA_CRC) ? STATUS_OK : STATUS_ERROR);
}


/****************************************************************************/
/* High level routines for accessing the target device via JTAG:            */
/*                                                                          */
/* From the following, the user is relieved from coding anything.           */
/* To provide better understanding and clearness, some functionality is     */
/* coded generously. (Code and speed optimization enhancements may          */
/* be desired)                                                              */
/****************************************************************************/


//----------------------------------------------------------------------------
/* Function to take target device under JTAG control. Disables the target
   watchdog. Sets the Device index as read from the target device.
   Arguments: None
   Result:    word (STATUS_ERROR if fuse is blown, incorrect JTAG ID or
                    synchronizing time-out; STATUS_OK otherwise)
*/
word GetDevice(void)
{
    word i;

    if (bJtag4Sbw)
    {
        //entry JTAG4 sequence
        ClrRST();
        usDelay(1);         //delay 1 uS

        ClrTST();
        MsDelay(5);

        SetRST();
        SetTST();
        usDelay(8);         // 8us delay

        ClrRST();
        usDelay(8);         // 8us delay

        ClrTST();
        usDelay(3);         // 2us delay

        SetTST();
        SetRST();
        MsDelay(10);
        ReleaseRST();
        //JTAG4 mode is entered!
    }

    ResetTAP();                          // Reset JTAG state machine, check fuse HW

    if (IsFuseBlown())                   // Stop here if fuse is already blown
    {
        return(STATUS_FUSEBLOWN);
    }
    IR_Shift(IR_CNTRL_SIG_16BIT);
    DR_Shift16(0x2401);                  // Set device into JTAG mode + read
    if (IR_Shift(IR_CNTRL_SIG_CAPTURE) != JTAG_ID)
    {
        return(STATUS_ERROR);
    }

    // Wait until CPU is synchronized, timeout after a limited # of attempts
    for (i = 50; i > 0; i--)
    {
        if (DR_Shift16(0x0000) & 0x0200)
        {
            word DeviceId;
            DeviceId = ReadMem(F_WORD, 0x0FF0);// Get target device type
                                               //(bytes are interchanged)
            DeviceId = (DeviceId << 8) + (DeviceId >> 8); // swop bytes
            //Set Device index, which is used by functions in Device.c
            SetDevice(DeviceId);
            break;
        }
        else
        {
            if (i == 1)
            {
                return(STATUS_ERROR);      // Timeout reached, return false
            }
        }
    }
    if (!ExecutePUC())                     // Perform PUC, Includes
    {
        return(STATUS_ERROR);              // target Watchdog disable.
    }
    return(STATUS_OK);
}


//----------------------------------------------------------------------------
/* Function to release the target device from JTAG control
   Argument: word Addr (0xFFFE: Perform Reset, means Load Reset Vector into PC,

⌨️ 快捷键说明

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