[bootloader]
- reduce memory footprint - bugfix writing last page git-svn-id: http://moon:8086/svn/projects/HendiControl@56 fda53097-d464-4ada-af97-ba876c37ca34
This commit is contained in:
@@ -19,7 +19,7 @@ typedef void(fp_t)(void);
|
||||
fp_t *startApplication = (fp_t*)0x0000; /* Funktionspointer auf 0x0000 */
|
||||
fp_t *startBootloader = (fp_t*)0x7000; /* Funktionspointer auf 0x7000 */
|
||||
|
||||
#define SPM_PAGESIZE_MASK 0x7F
|
||||
#define SPM_PAGESIZE_MASK 0x7FUL
|
||||
|
||||
inline void bootloader_enter()
|
||||
{
|
||||
@@ -46,6 +46,7 @@ typedef enum _eState
|
||||
StateHex,
|
||||
} State;
|
||||
|
||||
void erase_page(uint16_t page_addr);
|
||||
void write_page(uint16_t page_addr, uint8_t *buf);
|
||||
void program_page (uint32_t page, uint8_t *buf);
|
||||
|
||||
@@ -69,13 +70,13 @@ int main(void)
|
||||
|
||||
uart_init(9600);
|
||||
|
||||
uart_puts("Hendi-Control Bootloader\n");
|
||||
uart_puts("Hendi-Control Bootloader v1.1\n");
|
||||
size_t image_size = 0;
|
||||
uint16_t page_addr = 0xFFFF;
|
||||
int page_isEmpty = 1;
|
||||
size_t hex_buffer_size = 0;
|
||||
int leave_loop = 0;
|
||||
|
||||
int page_is_dirty = 0;
|
||||
int force_page_erase = 1;
|
||||
do
|
||||
{
|
||||
char c;
|
||||
@@ -117,48 +118,50 @@ int main(void)
|
||||
{
|
||||
case srec_sob:
|
||||
image_size = 0;
|
||||
page_isEmpty = 1;
|
||||
init_page(page_buffer, SPM_PAGESIZE);
|
||||
page_is_dirty = 0;
|
||||
break;
|
||||
|
||||
case srec_data:
|
||||
{
|
||||
uint16_t new_page_addr = srec.addr & ~SPM_PAGESIZE_MASK;
|
||||
if (new_page_addr != page_addr)
|
||||
if ((new_page_addr != page_addr) || force_page_erase)
|
||||
{
|
||||
eeprom_busy_wait ();
|
||||
boot_spm_busy_wait ();
|
||||
boot_page_erase (new_page_addr);
|
||||
page_addr = new_page_addr;
|
||||
force_page_erase = 0;
|
||||
erase_page(page_addr);
|
||||
}
|
||||
page_addr = new_page_addr;
|
||||
|
||||
if (page_isEmpty)
|
||||
{
|
||||
// Begin new page
|
||||
page_isEmpty = 0;
|
||||
init_page(page_buffer, SPM_PAGESIZE);
|
||||
}
|
||||
int start = srec.addr & SPM_PAGESIZE_MASK;
|
||||
int i = 0;
|
||||
int to_write = srec.size;
|
||||
if ((start + to_write) > SPM_PAGESIZE)
|
||||
{
|
||||
to_write = SPM_PAGESIZE - start;
|
||||
}
|
||||
for (; i < to_write; i++)
|
||||
uint16_t start = srec.addr & SPM_PAGESIZE_MASK;
|
||||
uint16_t i = 0;
|
||||
for (; i < srec.size; i++)
|
||||
{
|
||||
if (start == SPM_PAGESIZE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
page_is_dirty = 1;
|
||||
page_buffer[start++] = srec.data[i];
|
||||
}
|
||||
// Page buffer is complete -> write to flash
|
||||
if ((start + i) >= SPM_PAGESIZE)
|
||||
if (start == SPM_PAGESIZE)
|
||||
{
|
||||
page_is_dirty = 0;
|
||||
write_page(page_addr, page_buffer);
|
||||
page_isEmpty = 1;
|
||||
init_page(page_buffer, SPM_PAGESIZE);
|
||||
}
|
||||
|
||||
if (i < srec.size)
|
||||
{
|
||||
page_addr += SPM_PAGESIZE;
|
||||
page_is_dirty = 1;
|
||||
force_page_erase = 1;
|
||||
start=0;
|
||||
}
|
||||
|
||||
// Copy remaining data to start of page buffer
|
||||
start=0;
|
||||
for (; i < srec.size; i++)
|
||||
{
|
||||
page_isEmpty = 0;
|
||||
page_buffer[start++] = srec.data[i];
|
||||
}
|
||||
image_size += srec.size;
|
||||
@@ -169,10 +172,14 @@ int main(void)
|
||||
break;
|
||||
case srec_eob:
|
||||
state_next = StateIdle;
|
||||
if (!page_isEmpty)
|
||||
if (page_is_dirty)
|
||||
{
|
||||
if (force_page_erase)
|
||||
{
|
||||
erase_page(page_addr);
|
||||
}
|
||||
write_page(page_addr, page_buffer);
|
||||
page_isEmpty = 1;
|
||||
page_is_dirty = 0;
|
||||
}
|
||||
uart_puts("\nImage size: 0x"); print_word(image_size); uart_puts("\n");
|
||||
/* Reenable RWW-section again. We need this if we want to jump back */
|
||||
@@ -202,6 +209,14 @@ int main(void)
|
||||
startApplication();
|
||||
}
|
||||
|
||||
void erase_page(uint16_t page_addr)
|
||||
{
|
||||
// uart_puts("ErasePage: "); print_word(page_addr); uart_puts("\n");
|
||||
eeprom_busy_wait ();
|
||||
boot_spm_busy_wait ();
|
||||
boot_page_erase (page_addr);
|
||||
|
||||
}
|
||||
void write_page(uint16_t page_addr, uint8_t *pPageBuffer)
|
||||
{
|
||||
uint16_t i;
|
||||
@@ -213,10 +228,10 @@ void write_page(uint16_t page_addr, uint8_t *pPageBuffer)
|
||||
{
|
||||
/* Set up little-endian word. */
|
||||
uint16_t w = *(pPageBuffer++);
|
||||
w += *(pPageBuffer++) << 8;
|
||||
uint16_t v = *(pPageBuffer++);
|
||||
w += v << 8;
|
||||
|
||||
boot_page_fill (page_addr + i, w);
|
||||
}
|
||||
|
||||
boot_page_write (page_addr); /* Store buffer in flash page. */
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user