📄 jtagfunc430x.c
字号:
*/
void ReleaseDevice_430X(unsigned long Addr)
{
if (Addr == V_RESET)
{
IR_Shift(IR_CNTRL_SIG_16BIT);
DR_Shift16(0x2C01); // Perform a reset
DR_Shift16(0x2401);
}
else
{
SetPC_430X(Addr); // Set target CPU's PC
}
IR_Shift(IR_CNTRL_SIG_RELEASE);
}
//----------------------------------------------------------------------------
/* 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_430X(word Format, unsigned long Addr, word Data)
{
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_Shift20(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_430X(unsigned long StartAddr, unsigned long Length, word *DataArray)
{
unsigned long i;
// Initialize writing:
SetPC_430X(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_430X(unsigned long StartAddr, unsigned long Length, word *DataArray)
{
word i; // Loop counter
unsigned long 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_Shift20(0x0128); // FCTL1 register
IR_Shift(IR_DATA_TO_ADDR);
DR_Shift16(0xA540); // Enable FLASH write
SetTCLK();
ClrTCLK();
IR_Shift(IR_ADDR_16BIT);
DR_Shift20(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_Shift20(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_Shift20(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_Shift20(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_Shift20(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_430X(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_430X(CodeArray[p], CodeArray[p+1], &CodeArray[p+2]);
if (!VerifyMem_430X(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_430X(word Format, unsigned long 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_Shift20(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_430X(unsigned long StartAddr, unsigned long Length, word *DataArray)
{
unsigned long i;
// Initialize reading:
SetPC_430X(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_430X(word EraseMode, unsigned long EraseAddr)
{
word StrobeAmount = 4820; // default for Segment Erase
volatile 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) ||
(EraseMode == ERASE_ALLMAIN) ||
(EraseMode == ERASE_GLOB)
)
{
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_Shift20(0x0128); // FCTL1 address
IR_Shift(IR_DATA_TO_ADDR);
DR_Shift16(EraseMode); // Enable erase mode
SetTCLK();
ClrTCLK();
IR_Shift(IR_ADDR_16BIT);
DR_Shift20(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_Shift20(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_Shift20(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_Shift20(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_Shift20(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_430X(unsigned long StartAddr, unsigned long Length)
{
return (VerifyPSA_430X(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_430X(unsigned long StartAddr, unsigned long Length, word *DataArray)
{
return (VerifyPSA_430X(StartAddr, Length, DataArray));
}
//------------------------------------------------------------------------
/* This function blows the security fuse.
Arguments: None
Result: word (TRUE if burn was successful, FALSE otherwise)
*/
word BlowFuse(void)
{
word mode = VPP_ON_TEST; // Devices with TEST pin: VPP to TEST
if(!DeviceHas_TestPin())
{
// Devices without TEST pin
IR_Shift(IR_CNTRL_SIG_16BIT);// TDO becomes TDI functionality
DR_Shift16(0x7201);
TDOisInput();
mode = VPP_ON_TDI; // Enable VPP on TDI
}
IR_Shift(IR_PREPARE_BLOW); // Initialize fuse blowing
MsDelay(1);
VPPon(mode); // Switch VPP onto selected pin
MsDelay(5);
IR_Shift(IR_EX_BLOW); // Execute fuse blowing
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(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 + -