- use fancy short pulse heartbeat led flashing
- bootloader now checks BSEL git-svn-id: http://moon:8086/svn/projects/HendiControl@153 fda53097-d464-4ada-af97-ba876c37ca34
This commit is contained in:
@@ -58,6 +58,14 @@ void init_page(uint8_t *pPageBuffer, size_t size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int port_init()
|
||||||
|
{
|
||||||
|
DDRB = 0x00;
|
||||||
|
DDRD = 0x40;
|
||||||
|
PORTD = 0x00;
|
||||||
|
return (PINB0 == 1);
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
uint8_t page_buffer[SPM_PAGESIZE];
|
uint8_t page_buffer[SPM_PAGESIZE];
|
||||||
@@ -66,142 +74,146 @@ int main(void)
|
|||||||
State state_next;
|
State state_next;
|
||||||
srec_t srec;
|
srec_t srec;
|
||||||
cli();
|
cli();
|
||||||
|
|
||||||
bootloader_enter();
|
bootloader_enter();
|
||||||
|
|
||||||
uart_init(9600);
|
int bsel = port_init();
|
||||||
|
if (bsel)
|
||||||
uart_puts("Hendi-Control Bootloader v1.1\n");
|
{
|
||||||
size_t image_size = 0;
|
uart_init(9600);
|
||||||
uint16_t page_addr = 0xFFFF;
|
uart_puts("Hendi-Control Bootloader v1.1\n");
|
||||||
size_t hex_buffer_size = 0;
|
size_t image_size = 0;
|
||||||
int leave_loop = 0;
|
uint16_t page_addr = 0xFFFF;
|
||||||
int page_is_dirty = 0;
|
size_t hex_buffer_size = 0;
|
||||||
int force_page_erase = 1;
|
int leave_loop = 0;
|
||||||
do
|
int page_is_dirty = 0;
|
||||||
{
|
int force_page_erase = 1;
|
||||||
char c;
|
do
|
||||||
if ((c = uart_getc()))
|
|
||||||
{
|
{
|
||||||
char C = toupper(c);
|
char c;
|
||||||
|
if ((c = uart_getc()))
|
||||||
state_next = state;
|
|
||||||
switch(state)
|
|
||||||
{
|
{
|
||||||
case StateIdle:
|
char C = toupper(c);
|
||||||
if (C == 'S')
|
|
||||||
{
|
|
||||||
hex_buffer_size = 0;
|
|
||||||
state_next = StateHex;
|
|
||||||
hex_buffer[hex_buffer_size++] = C;
|
|
||||||
|
|
||||||
}
|
state_next = state;
|
||||||
if (C == 'R')
|
switch(state)
|
||||||
{
|
{
|
||||||
startBootloader();
|
case StateIdle:
|
||||||
}
|
if (C == 'S')
|
||||||
if (C == 'Q')
|
|
||||||
{
|
|
||||||
leave_loop = 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case StateHex:
|
|
||||||
if(((C != 0x0D) && (C != 0x0A)))
|
|
||||||
{
|
|
||||||
hex_buffer[hex_buffer_size++] = C;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int srec_state = srec_decode(&srec, hex_buffer, hex_buffer_size);
|
|
||||||
hex_buffer_size = 0;
|
|
||||||
switch(srec_state)
|
|
||||||
{
|
{
|
||||||
case srec_sob:
|
hex_buffer_size = 0;
|
||||||
image_size = 0;
|
state_next = StateHex;
|
||||||
init_page(page_buffer, SPM_PAGESIZE);
|
hex_buffer[hex_buffer_size++] = C;
|
||||||
page_is_dirty = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case srec_data:
|
}
|
||||||
|
if (C == 'R')
|
||||||
|
{
|
||||||
|
startBootloader();
|
||||||
|
}
|
||||||
|
if (C == 'Q')
|
||||||
|
{
|
||||||
|
leave_loop = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case StateHex:
|
||||||
|
if(((C != 0x0D) && (C != 0x0A)))
|
||||||
|
{
|
||||||
|
hex_buffer[hex_buffer_size++] = C;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int srec_state = srec_decode(&srec, hex_buffer, hex_buffer_size);
|
||||||
|
hex_buffer_size = 0;
|
||||||
|
switch(srec_state)
|
||||||
{
|
{
|
||||||
uint16_t new_page_addr = srec.addr & ~SPM_PAGESIZE_MASK;
|
case srec_sob:
|
||||||
if ((new_page_addr != page_addr) || force_page_erase)
|
image_size = 0;
|
||||||
{
|
init_page(page_buffer, SPM_PAGESIZE);
|
||||||
page_addr = new_page_addr;
|
page_is_dirty = 0;
|
||||||
force_page_erase = 0;
|
break;
|
||||||
erase_page(page_addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t start = srec.addr & SPM_PAGESIZE_MASK;
|
case srec_data:
|
||||||
uint16_t i = 0;
|
|
||||||
for (; i < srec.size; i++)
|
|
||||||
{
|
{
|
||||||
|
uint16_t new_page_addr = srec.addr & ~SPM_PAGESIZE_MASK;
|
||||||
|
if ((new_page_addr != page_addr) || force_page_erase)
|
||||||
|
{
|
||||||
|
page_addr = new_page_addr;
|
||||||
|
force_page_erase = 0;
|
||||||
|
erase_page(page_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 == SPM_PAGESIZE)
|
if (start == SPM_PAGESIZE)
|
||||||
{
|
{
|
||||||
break;
|
page_is_dirty = 0;
|
||||||
|
write_page(page_addr, page_buffer);
|
||||||
|
init_page(page_buffer, SPM_PAGESIZE);
|
||||||
}
|
}
|
||||||
page_is_dirty = 1;
|
|
||||||
page_buffer[start++] = srec.data[i];
|
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
|
||||||
|
for (; i < srec.size; i++)
|
||||||
|
{
|
||||||
|
page_buffer[start++] = srec.data[i];
|
||||||
|
}
|
||||||
|
image_size += srec.size;
|
||||||
|
uart_putc('.');
|
||||||
}
|
}
|
||||||
// Page buffer is complete -> write to flash
|
break;
|
||||||
if (start == SPM_PAGESIZE)
|
case srec_rec:
|
||||||
|
break;
|
||||||
|
case srec_eob:
|
||||||
|
state_next = StateIdle;
|
||||||
|
if (page_is_dirty)
|
||||||
{
|
{
|
||||||
page_is_dirty = 0;
|
if (force_page_erase)
|
||||||
|
{
|
||||||
|
erase_page(page_addr);
|
||||||
|
}
|
||||||
write_page(page_addr, page_buffer);
|
write_page(page_addr, page_buffer);
|
||||||
init_page(page_buffer, SPM_PAGESIZE);
|
page_is_dirty = 0;
|
||||||
}
|
}
|
||||||
|
uart_puts("\nImage size: 0x"); print_word(image_size); uart_puts("\n");
|
||||||
if (i < srec.size)
|
/* Reenable RWW-section again. We need this if we want to jump back */
|
||||||
{
|
/* to the application after bootloading. */
|
||||||
page_addr += SPM_PAGESIZE;
|
boot_rww_enable ();
|
||||||
page_is_dirty = 1;
|
break;
|
||||||
force_page_erase = 1;
|
case srec_err:
|
||||||
start=0;
|
startBootloader();
|
||||||
}
|
break;
|
||||||
|
|
||||||
// Copy remaining data to start of page buffer
|
|
||||||
for (; i < srec.size; i++)
|
|
||||||
{
|
|
||||||
page_buffer[start++] = srec.data[i];
|
|
||||||
}
|
|
||||||
image_size += srec.size;
|
|
||||||
uart_putc('.');
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case srec_rec:
|
|
||||||
break;
|
|
||||||
case srec_eob:
|
|
||||||
state_next = StateIdle;
|
|
||||||
if (page_is_dirty)
|
|
||||||
{
|
|
||||||
if (force_page_erase)
|
|
||||||
{
|
|
||||||
erase_page(page_addr);
|
|
||||||
}
|
|
||||||
write_page(page_addr, page_buffer);
|
|
||||||
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 */
|
|
||||||
/* to the application after bootloading. */
|
|
||||||
boot_rww_enable ();
|
|
||||||
break;
|
|
||||||
case srec_err:
|
|
||||||
startBootloader();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
state = state_next;
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
state = state_next;
|
} while (!leave_loop);
|
||||||
}
|
|
||||||
} while (!leave_loop);
|
|
||||||
|
|
||||||
uart_puts("Exit bootloader!\n\n");
|
uart_puts("Exit bootloader!\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
bootloader_exit();
|
bootloader_exit();
|
||||||
|
|
||||||
|
|||||||
@@ -206,8 +206,15 @@ int main(void)
|
|||||||
{
|
{
|
||||||
case TIMER_GENERAL:
|
case TIMER_GENERAL:
|
||||||
{
|
{
|
||||||
timer_start(timer_id, TIMER_SW_DELAY_MS(500));
|
|
||||||
hb_state = !hb_state;
|
hb_state = !hb_state;
|
||||||
|
if (hb_state)
|
||||||
|
{
|
||||||
|
timer_start(timer_id, TIMER_SW_DELAY_MS(50));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
timer_start(timer_id, TIMER_SW_DELAY_MS(950));
|
||||||
|
}
|
||||||
portSet(Led_HB, hb_state);
|
portSet(Led_HB, hb_state);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user