📄 jtagfuncsbw.c
字号:
{
HaltCPU();
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
SetTCLK();
ReleaseCPU();
}
//----------------------------------------------------------------------------
/* This function writes an array of words into the target memory.
Arguments: word StartAddr (Start address of target memory)
word Length (Number of words to be programmed)
word *DataArray (Pointer to array with the data)
Result: None
*/
void WriteMemQuick(word StartAddr, word Length, word *DataArray)
{
word i;
// Initialize writing:
SetPC((word)(StartAddr-4));
HaltCPU();
ClrTCLK();
IR_Shift(IR_CNTRL_SIG_16BIT);
DR_Shift16(0x2408); // Set RW to write
IR_Shift(IR_DATA_QUICK);
for (i = 0; i < Length; i++)
{
DR_Shift16(DataArray[i]); // Shift in the write data
SetTCLK();
ClrTCLK(); // Increment PC by 2
}
ReleaseCPU();
}
//----------------------------------------------------------------------------
/* This function programs/verifies an array of words into an FLASH by
using the FLASH controller.
Arguments: word StartAddr (Start address of FLASH memory)
word Length (Number of words to be programmed)
word *DataArray (Pointer to array with the data)
Result: None
*/
void WriteFLASH(word StartAddr, word Length, word *DataArray)
{
word i; // Loop counter
word addr = StartAddr; // Address counter
word FCTL3_val = 0xA500; // ok for all devices; if Info-Seg. A on F2xxx should not be programmed
// word FCTL3_val = 0xA540; // only if Info-Seg. A on F2xxx should be programmed
HaltCPU();
ClrTCLK();
IR_Shift(IR_CNTRL_SIG_16BIT);
DR_Shift16(0x2408); // Set RW to write
IR_Shift(IR_ADDR_16BIT);
DR_Shift16(0x0128); // FCTL1 register
IR_Shift(IR_DATA_TO_ADDR);
DR_Shift16(0xA540); // Enable FLASH write
SetTCLK();
ClrTCLK();
IR_Shift(IR_ADDR_16BIT);
DR_Shift16(0x012A); // FCTL2 register
IR_Shift(IR_DATA_TO_ADDR);
DR_Shift16(0xA540); // Select MCLK as source, DIV=1
SetTCLK();
ClrTCLK();
IR_Shift(IR_ADDR_16BIT);
DR_Shift16(0x012C); // FCTL3 register
IR_Shift(IR_DATA_TO_ADDR);
DR_Shift16(FCTL3_val); // Clear FCTL3; F2xxx: Unlock Info-Seg.
// A by toggling LOCKA-Bit if required,
SetTCLK();
ClrTCLK();
IR_Shift(IR_CNTRL_SIG_16BIT);
for (i = 0; i < Length; i++, addr += 2)
{
DR_Shift16(0x2408); // Set RW to write
IR_Shift(IR_ADDR_16BIT);
DR_Shift16(addr); // Set address
IR_Shift(IR_DATA_TO_ADDR);
DR_Shift16(DataArray[i]); // Set data
SetTCLK();
ClrTCLK();
IR_Shift(IR_CNTRL_SIG_16BIT);
DR_Shift16(0x2409); // Set RW to read
TCLKstrobes(35); // Provide TCLKs, min. 33 for F149 and F449
// F2xxx: 29 are ok
}
IR_Shift(IR_CNTRL_SIG_16BIT);
DR_Shift16(0x2408); // Set RW to write
IR_Shift(IR_ADDR_16BIT);
DR_Shift16(0x0128); // FCTL1 register
IR_Shift(IR_DATA_TO_ADDR);
DR_Shift16(0xA500); // Disable FLASH write
SetTCLK();
// set LOCK-Bits again
ClrTCLK();
IR_Shift(IR_ADDR_16BIT);
DR_Shift16(0x012C); // FCTL3 address
IR_Shift(IR_DATA_TO_ADDR);
DR_Shift16(FCTL3_val); // Lock Inf-Seg. A by toggling LOCKA and set LOCK again
SetTCLK();
ReleaseCPU();
}
//----------------------------------------------------------------------------
/* This function programs/verifies a set of data arrays of words into a FLASH
memory by using the "WriteFLASH()" function. It conforms with the
"CodeArray" structure convention of file "Target_Code.s43".
Arguments: word *DataArray (Pointer to array with the data)
Result: word (STATUS_OK if verification was successful,
STATUS_ERROR otherwise)
*/
word WriteFLASHallSections(word *CodeArray)
{
word s; // Number of sections
word p; // Pointer to data
for (s = CodeArray[0], p = 1; s > 0; s--)
{
// Write/Verify(PSA) one FLASH section
WriteFLASH(CodeArray[p], CodeArray[p+1], &CodeArray[p+2]);
if (!VerifyMem(CodeArray[p], CodeArray[p+1], &CodeArray[p+2]))
{
return(STATUS_ERROR);
}
// pointer of next section = old pointer + 2 + length of actual section
p += CodeArray[p+1] + 2;
}
return(STATUS_OK);
}
//----------------------------------------------------------------------------
/* 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();
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);
SetTCLK();
ClrTCLK();
TDOword = DR_Shift16(0x0000); // Shift out 16 bits
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);
HaltCPU();
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++)
{
SetTCLK();
ClrTCLK();
DataArray[i] = DR_Shift16(0x0000); // Shift out the data
// from the target.
}
ReleaseCPU();
}
//----------------------------------------------------------------------------
/* This function performs a mass erase (with and w/o info memory) or a segment
erase of a FLASH module specified by the given mode and address.
Large memory devices get additional mass erase operations to meet the spec.
Arguments: word Mode (could be ERASE_MASS or ERASE_MAIN or ERASE_SGMT)
word Addr (any address within the selected segment)
Result: None
Remark: Could be extended with erase check via PSA.
*/
void EraseFLASH(word EraseMode, word EraseAddr)
{
word StrobeAmount = 4820; // default for Segment Erase
word i, loopcount = 1; // erase cycle repeating for Mass Erase
word FCTL3_val = 0xA500; // ok for all devices; if Info-Seg. A on F2xxx should not be erased
// word FCTL3_val = 0xA540; // only if Info-Seg. A on F2xxx should be erased
if ((EraseMode == ERASE_MASS) || (EraseMode == ERASE_MAIN))
{
if(DeviceHas_FastFlash())
{
StrobeAmount = 10600; // Larger Flash memories require
}
else
{
StrobeAmount = 5300; // Larger Flash memories require
loopcount = 19; // additional cycles for erase.
}
}
HaltCPU();
for (i = loopcount; i > 0; i--)
{
ClrTCLK();
IR_Shift(IR_CNTRL_SIG_16BIT);
DR_Shift16(0x2408); // set RW to write
IR_Shift(IR_ADDR_16BIT);
DR_Shift16(0x0128); // FCTL1 address
IR_Shift(IR_DATA_TO_ADDR);
DR_Shift16(EraseMode); // Enable erase mode
SetTCLK();
ClrTCLK();
IR_Shift(IR_ADDR_16BIT);
DR_Shift16(0x012A); // FCTL2 address
IR_Shift(IR_DATA_TO_ADDR);
DR_Shift16(0xA540); // MCLK is source, DIV=1
SetTCLK();
ClrTCLK();
IR_Shift(IR_ADDR_16BIT);
DR_Shift16(0x012C); // FCTL3 address
IR_Shift(IR_DATA_TO_ADDR);
DR_Shift16(FCTL3_val); // Clear FCTL3; F2xxx: Unlock Info-Seg. A by toggling LOCKA-Bit if required,
SetTCLK();
ClrTCLK();
IR_Shift(IR_ADDR_16BIT);
DR_Shift16(EraseAddr); // Set erase address
IR_Shift(IR_DATA_TO_ADDR);
DR_Shift16(0x55AA); // Dummy write to start erase
SetTCLK();
ClrTCLK();
IR_Shift(IR_CNTRL_SIG_16BIT);
DR_Shift16(0x2409); // Set RW to read
TCLKstrobes(StrobeAmount); // Provide TCLKs
IR_Shift(IR_CNTRL_SIG_16BIT);
DR_Shift16(0x2408); // Set RW to write
IR_Shift(IR_ADDR_16BIT);
DR_Shift16(0x0128); // FCTL1 address
IR_Shift(IR_DATA_TO_ADDR);
DR_Shift16(0xA500); // Disable erase
SetTCLK();
}
// set LOCK-Bits again
ClrTCLK();
IR_Shift(IR_ADDR_16BIT);
DR_Shift16(0x012C); // FCTL3 address
IR_Shift(IR_DATA_TO_ADDR);
DR_Shift16(FCTL3_val); // Lock Inf-Seg. A by toggling LOCKA (F2xxx) and set LOCK again
SetTCLK();
ReleaseCPU();
}
//----------------------------------------------------------------------------
/* This function performs an Erase Check over the given memory range
Arguments: word StartAddr (Start address of memory to be checked)
word Length (Number of words to be checked)
Result: word (STATUS_OK if erase check was successful, STATUS_ERROR otherwise)
*/
word EraseCheck(word StartAddr, word Length)
{
return (VerifyPSA(StartAddr, Length, 0));
}
//----------------------------------------------------------------------------
/* This function performs a Verification over the given memory range
Arguments: word StartAddr (Start address of memory to be verified)
word Length (Number of words to be verified)
word *DataArray (Pointer to array with the data)
Result: word (STATUS_OK if verification was successful, STATUS_ERROR otherwise)
*/
word VerifyMem(word StartAddr, word Length, word *DataArray)
{
return (VerifyPSA(StartAddr, Length, DataArray));
}
//------------------------------------------------------------------------
/* This function blows the security fuse.
Arguments: None
Result: word (TRUE if burn was successful, FALSE otherwise)
*/
word BlowFuse(void)
{
//the function can not be adapted for SBW because:
// The TTCK pin (SBW clock) is connected to TEST pin (High voltage) on the FET.
// The TTCK pin connected to MSP430 port directly,
// so it can demage the CPU if you try the fuse burning.
word i;
word Data = IR_EX_BLOW;
word MSB = 0x80;
word mode = VPP_ON_TEST; // Devices with TEST pin: VPP to TEST
IR_Shift(IR_PREPARE_BLOW); // initialize fuse blowing
// perform IR_EX_BLOW instruction shift
if (TCLK_saved & SBWDATO)
{
TMSH_TDIH();
}
else
{
TMSH_TDIL();
}
TMSH_TDIH();
TMSL_TDIH();
TMSL_TDIH();
for (i = F_BYTE; i > 0; i--)
{
if (i == 1) // last bit requires TMS=1; TDO one bit before TDI
{
((Data & MSB) == 0) ? TMSH_TDIL() : TMSH_TDIH();
}
else
{
((Data & MSB) == 0) ? TMSL_TDIL() : TMSL_TDIH();
}
Data <<= 1;
}
// SBWTDIO must be low on exit!
TMSH_TDIL();
TMSL_TDIL();
// instruction shift done!
TMSL // go to TDI-slot via TMS-slot
// now in TDI-slot to blow fuse
VPPon(mode); // switch VPP onto selected pin
MsDelay(1); // slow photo-MOS relay
JTAGOUT |= SBWDATO; // TDI=1: executes blow
MsDelay(1);
// Switch off power to target and wait
ReleaseTarget(); // switch VPP and VCC target off
MsDelay(200);
// Check fuse: switch power on, simulate an initial JTAG entry
InitTarget(); // Supply and preset Target Board
// Return result of "is fuse blown?"
return(GetDevice() == STATUS_FUSEBLOWN);
}
//------------------------------------------------------------------------
/* 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_sbw(0xAAAA) == 0x5555)
return(STATUS_OK); // Fuse is blown
}
return(STATUS_ERROR); // fuse is not blown
}
/****************************************************************************/
/* END OF SOURCE FILE */
/****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -