📄 stk500boot.c
字号:
checksum ^= c;
if ( i == msgLength )
{
msgParseState = ST_GET_CHECK;
}
break;
case ST_GET_CHECK:
if( c == checksum )
{
msgParseState = ST_PROCESS;
}
else
{
msgParseState = ST_START;
}
break;
}//switch
}//while(msgParseState)
/*
* Now process the STK500 commands, see Atmel Appnote AVR068
*/
switch (msgBuffer[0])
{
#ifndef REMOVE_CMD_SPI_MULTI
case CMD_SPI_MULTI:
{
unsigned char answerByte;
unsigned char flag=0;
if ( msgBuffer[4]== 0x30 )
{
unsigned char signatureIndex = msgBuffer[6];
if ( signatureIndex == 0 )
answerByte = (SIGNATURE_BYTES >>16) & 0x000000FF;
else if ( signatureIndex == 1 )
answerByte = (SIGNATURE_BYTES >> 8) & 0x000000FF;
else
answerByte = SIGNATURE_BYTES & 0x000000FF;
}
else if ( msgBuffer[4] & 0x50 )
{
answerByte = 0; //read fuse/lock bits not implemented, return dummy value
}
else
{
flag = 1;
}
if ( !flag )
{
msgLength = 7;
msgBuffer[1] = STATUS_CMD_OK;
msgBuffer[2] = 0;
msgBuffer[3] = msgBuffer[4];
msgBuffer[4] = 0;
msgBuffer[5] = answerByte;
msgBuffer[6] = STATUS_CMD_OK;
}
}
break;
#endif
case CMD_SIGN_ON:
msgLength = 11;
msgBuffer[1] = STATUS_CMD_OK;
msgBuffer[2] = 8;
msgBuffer[3] = 'A';
msgBuffer[4] = 'V';
msgBuffer[5] = 'R';
msgBuffer[6] = 'I';
msgBuffer[7] = 'S';
msgBuffer[8] = 'P';
msgBuffer[9] = '_';
msgBuffer[10] = '2';
break;
case CMD_GET_PARAMETER:
{
unsigned char value;
switch(msgBuffer[1])
{
case PARAM_BUILD_NUMBER_LOW:
value = CONFIG_PARAM_BUILD_NUMBER_LOW;
break;
case PARAM_BUILD_NUMBER_HIGH:
value = CONFIG_PARAM_BUILD_NUMBER_HIGH;
break;
case PARAM_HW_VER:
value = CONFIG_PARAM_HW_VER;
break;
case PARAM_SW_MAJOR:
value = CONFIG_PARAM_SW_MAJOR;
break;
case PARAM_SW_MINOR:
value = CONFIG_PARAM_SW_MINOR;
break;
default:
value = 0;
break;
}
msgLength = 3;
msgBuffer[1] = STATUS_CMD_OK;
msgBuffer[2] = value;
}
break;
case CMD_SET_PARAMETER:
case CMD_ENTER_PROGMODE_ISP:
case CMD_LEAVE_PROGMODE_ISP:
msgLength = 2;
msgBuffer[1] = STATUS_CMD_OK;
break;
case CMD_READ_SIGNATURE_ISP:
{
unsigned char signatureIndex = msgBuffer[4];
unsigned char signature;
if ( signatureIndex == 0 )
signature = (SIGNATURE_BYTES >>16) & 0x000000FF;
else if ( signatureIndex == 1 )
signature = (SIGNATURE_BYTES >> 8) & 0x000000FF;
else
signature = SIGNATURE_BYTES & 0x000000FF;
msgLength = 4;
msgBuffer[1] = STATUS_CMD_OK;
msgBuffer[2] = signature;
msgBuffer[3] = STATUS_CMD_OK;
}
break;
case CMD_READ_LOCK_ISP:
msgLength = 4;
msgBuffer[1] = STATUS_CMD_OK;
msgBuffer[2] = boot_lock_fuse_bits_get( GET_LOCK_BITS );
msgBuffer[3] = STATUS_CMD_OK;
break;
case CMD_READ_FUSE_ISP:
{
unsigned char fuseBits;
if ( msgBuffer[2] == 0x50 )
{
if ( msgBuffer[3] == 0x08 )
fuseBits = boot_lock_fuse_bits_get( GET_EXTENDED_FUSE_BITS );
else
fuseBits = boot_lock_fuse_bits_get( GET_LOW_FUSE_BITS );
}
else
{
fuseBits = boot_lock_fuse_bits_get( GET_HIGH_FUSE_BITS );
}
msgLength = 4;
msgBuffer[1] = STATUS_CMD_OK;
msgBuffer[2] = fuseBits;
msgBuffer[3] = STATUS_CMD_OK;
}
break;
#ifndef REMOVE_PROGRAM_LOCK_BIT_SUPPORT
case CMD_PROGRAM_LOCK_ISP:
{
unsigned char lockBits = msgBuffer[4];
lockBits = (~lockBits) & 0x3C; // mask BLBxx bits
boot_lock_bits_set(lockBits); // and program it
boot_spm_busy_wait();
msgLength = 3;
msgBuffer[1] = STATUS_CMD_OK;
msgBuffer[2] = STATUS_CMD_OK;
}
break;
#endif
case CMD_CHIP_ERASE_ISP:
eraseAddress = 0;
msgLength = 2;
msgBuffer[1] = STATUS_CMD_OK;
break;
case CMD_LOAD_ADDRESS:
#if defined(RAMPZ)
address = ( ((address_t)(msgBuffer[1])<<24)|((address_t)(msgBuffer[2])<<16)|((address_t)(msgBuffer[3])<<8)|(msgBuffer[4]) )<<1;
#else
address = ( ((msgBuffer[3])<<8)|(msgBuffer[4]) )<<1; //convert word to byte address
#endif
msgLength = 2;
msgBuffer[1] = STATUS_CMD_OK;
break;
case CMD_PROGRAM_FLASH_ISP:
case CMD_PROGRAM_EEPROM_ISP:
{
unsigned int size = ((msgBuffer[1])<<8) | msgBuffer[2];
unsigned char *p = msgBuffer+10;
unsigned int data;
unsigned char highByte, lowByte;
address_t tempaddress = address;
if ( msgBuffer[0] == CMD_PROGRAM_FLASH_ISP )
{
// erase only main section (bootloader protection)
if ( eraseAddress < APP_END )
{
boot_page_erase(eraseAddress); // Perform page erase
boot_spm_busy_wait(); // Wait until the memory is erased.
eraseAddress += SPM_PAGESIZE; // point to next page to be erase
}
/* Write FLASH */
do {
lowByte = *p++;
highByte = *p++;
data = (highByte << 8) | lowByte;
boot_page_fill(address,data);
address = address + 2; // Select next word in memory
size -= 2; // Reduce number of bytes to write by two
} while(size); // Loop until all bytes written
boot_page_write(tempaddress);
boot_spm_busy_wait();
boot_rww_enable(); // Re-enable the RWW section
}
else
{
/* write EEPROM */
do {
EEARL = address; // Setup EEPROM address
EEARH = (address >> 8);
address++; // Select next EEPROM byte
EEDR= *p++; // get byte from buffer
EECR |= (1<<EEMWE); // Write data into EEPROM
EECR |= (1<<EEWE);
while (EECR & (1<<EEWE)); // Wait for write operation to finish
size--; // Decrease number of bytes to write
} while(size); // Loop until all bytes written
}
msgLength = 2;
msgBuffer[1] = STATUS_CMD_OK;
}
break;
case CMD_READ_FLASH_ISP:
case CMD_READ_EEPROM_ISP:
{
unsigned int size = ((msgBuffer[1])<<8) | msgBuffer[2];
unsigned char *p = msgBuffer+1;
msgLength = size+3;
*p++ = STATUS_CMD_OK;
if (msgBuffer[0] == CMD_READ_FLASH_ISP )
{
unsigned int data;
// Read FLASH
do {
#if defined(RAMPZ)
data = pgm_read_word_far(address);
#else
data = pgm_read_word_near(address);
#endif
*p++ = (unsigned char)data; //LSB
*p++ = (unsigned char)(data >> 8); //MSB
address += 2; // Select next word in memory
size -= 2;
}while (size);
}
else
{
/* Read EEPROM */
do {
EEARL = address; // Setup EEPROM address
EEARH = ((address >> 8));
address++; // Select next EEPROM byte
EECR |= (1<<EERE); // Read EEPROM
*p++ = EEDR; // Send EEPROM data
size--;
}while(size);
}
*p++ = STATUS_CMD_OK;
}
break;
default:
msgLength = 2;
msgBuffer[1] = STATUS_CMD_FAILED;
break;
}
/*
* Now send answer message back
*/
sendchar(MESSAGE_START);
checksum = MESSAGE_START^0;
sendchar(seqNum);
checksum ^= seqNum;
c = ((msgLength>>8)&0xFF);
sendchar(c);
checksum ^= c;
c = msgLength&0x00FF;
sendchar(c);
checksum ^= c;
sendchar(TOKEN);
checksum ^= TOKEN;
p = msgBuffer;
while ( msgLength )
{
c = *p++;
sendchar(c);
checksum ^=c;
msgLength--;
}
sendchar(checksum);
seqNum++;
}//for
#ifndef REMOVE_BOOTLOADER_LED
PROGLED_DDR &= ~(1<<PROGLED_PIN); // set to default
#endif
}
/*
* Now leave bootloader
*/
#ifndef REMOVE_PROG_PIN_PULLUP
PROG_PORT &= ~(1<<PROG_PIN); // set to default
#endif
boot_rww_enable(); // enable application section
asm volatile ( "push r1" "\n\t" // Jump to Reset vector in Application Section
"push r1" "\n\t"
"ret" "\n\t"
::);
/*
* Never return to stop GCC to generate exit return code
* Actually we will never reach this point, but the compiler doesn't
* understand this
*/
for(;;);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -