From 46bb98d9dc0806f5aae346bc5e96c1fef978fe39 Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Fri, 10 May 2013 17:48:52 +0200 Subject: Shrink the size of the Printer class bootloader by refactoring the page flush code into a static function. --- Bootloaders/Printer/BootloaderPrinter.c | 60 ++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/Bootloaders/Printer/BootloaderPrinter.c b/Bootloaders/Printer/BootloaderPrinter.c index b80c08284..1e60cdd6d 100644 --- a/Bootloaders/Printer/BootloaderPrinter.c +++ b/Bootloaders/Printer/BootloaderPrinter.c @@ -92,17 +92,13 @@ struct uint32_t CurrBaseAddress; /** Current 32-bit byte address in FLASH being targeted. */ uint32_t CurrAddress; -} HEXParser = - { - .ParserState = HEX_PARSE_STATE_WAIT_LINE - }; +} HEXParser; /** Indicates if there is data waiting to be written to a physical page of * memory in FLASH. */ static bool PageDirty = false; - /** Flag to indicate if the bootloader should be running, or should exit and allow the application code to run * via a soft reset. When cleared, the bootloader will abort, the USB interface will shut down and the application * started via a forced watchdog reset. @@ -153,6 +149,31 @@ static int8_t HexToDecimal(const char Byte) return -1; } +/** + * Flushes a partially written page of data to physical FLASH, if a page + * boundary has been crossed. + * + * \note If a page flush occurs the global HEX parser state is updated. + */ +static void FlushPageIfRequired(void) +{ + /* Abort if no data has been buffered for writing to the current page */ + if (!PageDirty) + return; + + /* Flush the FLASH page to physical memory if we are crossing a page boundary */ + uint32_t NewPageStartAddress = (HEXParser.CurrAddress & ~(SPM_PAGESIZE - 1)); + if (HEXParser.PageStartAddress != NewPageStartAddress) + { + boot_page_write(HEXParser.PageStartAddress); + boot_spm_busy_wait(); + + HEXParser.PageStartAddress = NewPageStartAddress; + + PageDirty = false; + } +} + /** * Parses an input Intel HEX formatted stream one character at a time, loading * the data contents into the device's internal FLASH memory. @@ -241,9 +262,7 @@ static void ParseIntelHEXByte(const char ReadCharacter) switch (HEXParser.RecordType) { case HEX_RECORD_TYPE_Data: - /* If we are writing to a new page, we need to erase it - * first - */ + /* If we are writing to a new page, we need to erase it first */ if (!(PageDirty)) { boot_page_erase(HEXParser.PageStartAddress); @@ -257,16 +276,7 @@ static void ParseIntelHEXByte(const char ReadCharacter) HEXParser.CurrAddress += 2; /* Flush the FLASH page to physical memory if we are crossing a page boundary */ - uint32_t NewPageStartAddress = (HEXParser.CurrAddress & ~(SPM_PAGESIZE - 1)); - if (PageDirty && (HEXParser.PageStartAddress != NewPageStartAddress)) - { - boot_page_write(HEXParser.PageStartAddress); - boot_spm_busy_wait(); - - HEXParser.PageStartAddress = NewPageStartAddress; - - PageDirty = false; - } + FlushPageIfRequired(); break; case HEX_RECORD_TYPE_ExtendedSegmentAddress: @@ -290,16 +300,7 @@ static void ParseIntelHEXByte(const char ReadCharacter) break; /* Flush the FLASH page to physical memory if we are crossing a page boundary */ - uint32_t NewPageStartAddress = (HEXParser.CurrAddress & ~(SPM_PAGESIZE - 1)); - if (PageDirty && (HEXParser.PageStartAddress != NewPageStartAddress)) - { - boot_page_write(HEXParser.PageStartAddress); - boot_spm_busy_wait(); - - HEXParser.PageStartAddress = NewPageStartAddress; - - PageDirty = false; - } + FlushPageIfRequired(); /* If end of the HEX file reached, the bootloader should exit at next opportunity */ if (HEXParser.RecordType == HEX_RECORD_TYPE_EndOfFile) @@ -413,6 +414,9 @@ void EVENT_USB_Device_ConfigurationChanged(void) /* Setup Printer Data Endpoints */ ConfigSuccess &= PRNT_Device_ConfigureEndpoints(&TextOnly_Printer_Interface); + /* Reset the HEX parser upon successful connection to a host */ + HEXParser.ParserState = HEX_PARSE_STATE_WAIT_LINE; + /* Indicate endpoint configuration success or failure */ LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR); } -- cgit v1.2.3