📄 boot.c
字号:
keyTest2 = (((0x557F << 1) + WT_EEDATA) - i/2) + 6;
//initiate write sequence
WriteMem(EE_WORD_WRITE);
writeKey1 += 5; // Modify keys to ensure proper program flow
writeKey2 -= 6;
#else
//initiate write sequence bypasssing runaway protection
WriteMem(EE_WORD_WRITE);
#endif
sourceAddr.Val +=2;
}
responseBytes = 1; //set length of reply
break;
#endif
#ifdef DEV_HAS_CONFIG_BITS
case RD_CONFIG: //Read config memory
//Read length bytes from config memory
while(bytesRead < length)
{
//read flash
temp.Val = ReadLatch(sourceAddr.word.HW, sourceAddr.word.LW);
buffer[bytesRead+5] = temp.v[0]; //put read data onto buffer
bytesRead++;
sourceAddr.Val += 2; //increment addr by 2
}
responseBytes = length + 5;
break;
case WT_CONFIG: //Write Config mem
//Write length bytes of config memory
while(i < length){
temp.byte.LB = buffer[5+i++]; //load data to write
temp.byte.HB = 0;
#ifdef USE_RUNAWAY_PROTECT
writeKey1++;
writeKey2--;
#endif
//Make sure that config write is inside implemented configuration space
if(sourceAddr.Val >= CONFIG_START && sourceAddr.Val <= CONFIG_END)
{
TBLPAG = sourceAddr.byte.UB;
__builtin_tblwtl(sourceAddr.word.LW,temp.Val);
#ifdef USE_RUNAWAY_PROTECT
//setup program flow protection test keys
keyTest1 = (((0x0009 | (WORD)(sourceAddr.Val-i*2)) -
length) + i) - 5;
keyTest2 = (((0x557F << 1) + WT_CONFIG) - i) + 6;
//initiate write sequence
WriteMem(CONFIG_WORD_WRITE);
writeKey1 += 5; // Modify keys to ensure proper program flow
writeKey2 -= 6;
#else
//initiate write sequence bypasssing runaway protection
WriteMem(CONFIG_WORD_WRITE);
#endif
}//end if(sourceAddr.Val...)
sourceAddr.Val +=2;
}//end while(i < length)
responseBytes = 1; //set length of reply
break;
#endif
case VERIFY_OK:
#ifdef USE_RUNAWAY_PROTECT
writeKey1 -= 1; // Modify keys to ensure proper program flow
writeKey2 += Command;
#endif
WriteTimeout();
responseBytes = 1; //set length of reply
break;
default:
break;
}// end switch(Command)
}//end HandleCommand()
/********************************************************************
* Function: void PutResponse()
*
* Precondition: UART Setup, data in buffer
*
* Input: None.
*
* Output: None.
*
* Side Effects: None.
*
* Overview: Transmits responseBytes bytes of data from buffer
with UART as a response to received command.
*
* Note: None.
********************************************************************/
void PutResponse(WORD responseLen)
{
WORD i;
BYTE data;
BYTE checksum;
SET_DT;
U1STAbits.UTXEN = 1; //make sure TX is enabled
PutChar(STX); //Put 2 STX characters
PutChar(STX);
//Output buffer as response packet
checksum = 0;
for(i = 0; i < responseLen; i++){
asm("clrwdt"); //looping code so clear WDT
data = buffer[i]; //get data from response buffer
checksum += data; //accumulate checksum
//if control character, stuff DLE
if(data == STX || data == ETX || data == DLE){
PutChar(DLE);
}
PutChar(data); //send data
}
checksum = ~checksum + 1; //keep track of checksum
//if control character, stuff DLE
if(checksum == STX || checksum == ETX || checksum == DLE){
PutChar(DLE);
}
PutChar(checksum); //put checksum
PutChar(ETX); //put End of text
while(!U1STAbits.TRMT); //wait for transmit to finish
CLR_DT;
}//end PutResponse()
/********************************************************************
* Function: void PutChar(BYTE Char)
*
* Precondition: UART Setup
*
* Input: Char - Character to transmit
*
* Output: None
*
* Side Effects: Puts character into destination pointed to by ptrChar.
*
* Overview: Transmits a character on UART2.
* Waits for an empty spot in TXREG FIFO.
*
* Note: None
********************************************************************/
void PutChar(BYTE txChar)
{
while(U1STAbits.UTXBF); //wait for FIFO space
U1TXREG = txChar; //put character onto UART FIFO to transmit
}//end PutChar(BYTE Char)
/********************************************************************
* Function: void GetChar(BYTE * ptrChar)
*
* PreCondition: UART Setup
*
* Input: ptrChar - pointer to character received
*
* Output:
*
* Side Effects: Puts character into destination pointed to by ptrChar.
* Clear WDT
*
* Overview: Receives a character from UART2.
*
* Note: None
********************************************************************/
void GetChar(BYTE * ptrChar)
{
BYTE dummy;
while(1)
{
asm("clrwdt"); //looping code, so clear WDT
//check for receive errors
if((U1STA & 0x000E) != 0x0000)
{
dummy = UxRXREG; //dummy read to clear FERR/PERR
UxSTAbits.OERR = 0; //clear OERR to keep receiving
}
//get the data
if(U1STAbits.URXDA == 1)
{
* ptrChar = U1RXREG; //get data from UART RX FIFO
break;
}
#ifndef USE_AUTOBAUD
//if timer expired, jump to user code
if(IFS0bits.T3IF == 1){
ResetDevice(userReset.Val);
}
#endif
}//end while(1)
}//end GetChar(BYTE *ptrChar)
/********************************************************************
* Function: void ReadPM(WORD length, DWORD_VAL sourceAddr)
*
* PreCondition: None
*
* Input: length - number of instructions to read
* sourceAddr - address to read from
*
* Output: None
*
* Side Effects: Puts read instructions into buffer.
*
* Overview: Reads from program memory, stores data into buffer.
*
* Note: None
********************************************************************/
void ReadPM(WORD length, DWORD_VAL sourceAddr)
{
WORD bytesRead = 0;
DWORD_VAL temp;
//Read length instructions from flash
while(bytesRead < length*PM_INSTR_SIZE)
{
//read flash
temp.Val = ReadLatch(sourceAddr.word.HW, sourceAddr.word.LW);
buffer[bytesRead+5] = temp.v[0]; //put read data onto
buffer[bytesRead+6] = temp.v[1]; //response buffer
buffer[bytesRead+7] = temp.v[2];
buffer[bytesRead+8] = temp.v[3];
//4 bytes per instruction: low word, high byte, phantom byte
bytesRead+=PM_INSTR_SIZE;
sourceAddr.Val = sourceAddr.Val + 2; //increment addr by 2
}//end while(bytesRead < length*PM_INSTR_SIZE)
}//end ReadPM(WORD length, DWORD_VAL sourceAddr)
/********************************************************************
* Function: void WritePM(WORD length, DWORD_VAL sourceAddr)
*
* PreCondition: Page containing rows to write should be erased.
*
* Input: length - number of rows to write
* sourceAddr - row aligned address to write to
*
* Output: None.
*
* Side Effects: None.
*
* Overview: Writes number of rows indicated from buffer into
* flash memory
*
* Note: None
********************************************************************/
void WritePM(WORD length, DWORD_VAL sourceAddr)
{
WORD bytesWritten;
DWORD_VAL data;
#ifdef USE_RUNAWAY_PROTECT
WORD temp = (WORD)sourceAddr.Val;
#endif
bytesWritten = 0; //first 5 buffer locations are cmd,len,addr
//write length rows to flash
while((bytesWritten) < length*PM_ROW_SIZE)
{
asm("clrwdt");
//get data to write from buffer
data.v[0] = buffer[bytesWritten+5];
data.v[1] = buffer[bytesWritten+6];
data.v[2] = buffer[bytesWritten+7];
data.v[3] = buffer[bytesWritten+8];
//4 bytes per instruction: low word, high byte, phantom byte
bytesWritten+=PM_INSTR_SIZE;
//Flash configuration word handling
#ifndef DEV_HAS_CONFIG_BITS
//Mask of bit 15 of CW1 to ensure it is programmed as 0
//as noted in PIC24FJ datasheets
if(sourceAddr.Val == CONFIG_END){
data.Val &= 0x007FFF;
}
#endif
//Protect the bootloader & reset vector
#ifdef USE_BOOT_PROTECT
//protect BL reset & get user reset
if(sourceAddr.Val == 0x0){
//get user app reset vector lo word
userReset.Val = data.Val & 0xFFFF;
//program low word of BL reset
data.Val = 0x040000 + (0xFFFF & BOOT_ADDR_LOW);
userResetRead = 1;
}
if(sourceAddr.Val == 0x2){
//get user app reset vector hi byte
userReset.Val += (DWORD)(data.Val & 0x00FF)<<16;
//program high byte of BL reset
data.Val = ((DWORD)(BOOT_ADDR_LOW & 0xFF0000))>>16;
userResetRead = 1;
}
#else
//get user app reset vector lo word
if(sourceAddr.Val == 0x0){
userReset.Val = data.Val & 0xFFFF;
userResetRead = 1;
}
//get user app reset vector hi byte
if(sourceAddr.Val == 0x2) {
userReset.Val |= ((DWORD)(data.Val & 0x00FF))<<16;
userResetRead = 1;
}
#endif
//put information from reset vector in user reset vector location
if(sourceAddr.Val == USER_PROG_RESET){
if(userResetRead){ //has reset vector been grabbed from location 0x0?
//if yes, use that reset vector
data.Val = userReset.Val;
}else{
//if no, use the user's indicated reset vector
userReset.Val = data.Val;
}
}
//If address is delay timer location, store data and write empty word
if(sourceAddr.Val == DELAY_TIME_ADDR){
userTimeout.Val = data.Val;
data.Val = 0xFFFFFF;
}
#ifdef USE_BOOT_PROTECT //do not erase bootloader & reset vector
if(sourceAddr.Val < BOOT_ADDR_LOW || sourceAddr.Val > BOOT_ADDR_HI){
#endif
#ifdef USE_CONFIGWORD_PROTECT //do not erase last page
if(sourceAddr.Val < (CONFIG_START & 0xFFFC00)){
#endif
#ifdef USE_VECTOR_PROTECT //do not erase first page
//if(sourceAddr.Val >= PM_PAGE_SIZE/2){
if(sourceAddr.Val >= VECTOR_SECTION){
#endif
//write data into latches
WriteLatch(sourceAddr.word.HW, sourceAddr.word.LW,
data.word.HW, data.word.LW);
#ifdef USE_VECTOR_PROTECT
}//end vectors protect
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -