uint8_t Checksum;
/** Starting address of the last addressed FLASH page. */
uint32_t PageStartAddress;
+ /** Current 32-bit byte extended base address in FLASH being targeted. */
+ uint32_t CurrBaseAddress;
/** Current 32-bit byte address in FLASH being targeted. */
uint32_t CurrAddress;
} HEXParser =
*
* \param[in] Byte ASCII byte of data to check
*
- * \return Boolean \c true if the input data is ASCII encoded HEX, false otherwise.
+ * \return Boolean \c true if the input data is ASCII encoded HEX, \c false otherwise.
*/
static bool IsHex(const char Byte)
{
if ((HEXParser.ParserState == HEX_PARSE_STATE_WAIT_LINE) || (ReadCharacter == ':'))
{
HEXParser.Checksum = 0;
- HEXParser.CurrAddress &= ~0xFFFF;
+ HEXParser.CurrAddress = HEXParser.CurrBaseAddress;
HEXParser.ParserState = HEX_PARSE_STATE_WAIT_LINE;
HEXParser.ReadMSB = false;
break;
case HEX_PARSE_STATE_ADDRESS_HIGH:
- HEXParser.CurrAddress |= ((uint16_t)HEXParser.Data << 8);
+ HEXParser.CurrAddress += ((uint16_t)HEXParser.Data << 8);
HEXParser.ParserState = HEX_PARSE_STATE_ADDRESS_LOW;
break;
case HEX_PARSE_STATE_ADDRESS_LOW:
- HEXParser.CurrAddress |= HEXParser.Data;
+ HEXParser.CurrAddress += HEXParser.Data;
HEXParser.ParserState = HEX_PARSE_STATE_RECORD_TYPE;
break;
/* Track the number of read data bytes in the record */
HEXParser.DataRem--;
+ /* Protect the bootloader against being written to */
+ if (HEXParser.CurrAddress >= BOOT_START_ADDR)
+ {
+ HEXParser.ParserState = HEX_PARSE_STATE_WAIT_LINE;
+ PageDirty = false;
+ return;
+ }
+
/* Wait for a machine word (two bytes) of data to be read */
if (HEXParser.DataRem & 0x01)
{
break;
}
+ /* Convert the last two received data bytes into a 16-bit word */
+ uint16_t NewDataWord = ((uint16_t)HEXParser.Data << 8) | HEXParser.PrevData;
+
switch (HEXParser.RecordType)
{
case HEX_RECORD_TYPE_Data:
}
/* Fill the FLASH memory buffer with the new word of data */
- boot_page_fill(HEXParser.CurrAddress, ((uint16_t)HEXParser.Data << 8) | HEXParser.PrevData);
+ boot_page_fill(HEXParser.CurrAddress, NewDataWord);
HEXParser.CurrAddress += 2;
/* Flush the FLASH page to physical memory if we are crossing a page boundary */
}
break;
+ case HEX_RECORD_TYPE_ExtendedSegmentAddress:
+ /* Extended address data - store the upper 12-bits of the new address */
+ HEXParser.CurrBaseAddress = ((uint32_t)NewDataWord << 4);
+ break;
+
case HEX_RECORD_TYPE_ExtendedLinearAddress:
/* Extended address data - store the upper 16-bits of the new address */
- HEXParser.CurrAddress |= (uint32_t)HEXParser.Data << (HEXParser.DataRem ? 24 : 16);
+ HEXParser.CurrBaseAddress = ((uint32_t)NewDataWord << 16);
break;
}
}
/** Configures the board hardware and chip peripherals for the demo's functionality. */
-void SetupHardware(void)
+static void SetupHardware(void)
{
/* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF);
}
/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
- * the status LEDs and stops the Mass Storage management task.
+ * the status LEDs and stops the Printer management task.
*/
void EVENT_USB_Device_Disconnect(void)
{