-bootloader is flashing

git-svn-id: http://moon:8086/svn/projects/HendiControl@52 fda53097-d464-4ada-af97-ba876c37ca34
This commit is contained in:
2019-03-03 15:24:44 +00:00
parent 2c6927ff43
commit fda682f386
4 changed files with 162 additions and 109 deletions
@@ -4,7 +4,7 @@
<SchemaVersion>2.0</SchemaVersion> <SchemaVersion>2.0</SchemaVersion>
<ProjectVersion>7.0</ProjectVersion> <ProjectVersion>7.0</ProjectVersion>
<ToolchainName>com.Atmel.AVRGCC8.C</ToolchainName> <ToolchainName>com.Atmel.AVRGCC8.C</ToolchainName>
<ProjectGuid>dce6c7e3-ee26-4d79-826b-08594b9ad897</ProjectGuid> <ProjectGuid>{c77f8c5d-b585-42ee-bf03-003a6350cd7a}</ProjectGuid>
<avrdevice>ATmega328P</avrdevice> <avrdevice>ATmega328P</avrdevice>
<avrdeviceseries>none</avrdeviceseries> <avrdeviceseries>none</avrdeviceseries>
<OutputType>Executable</OutputType> <OutputType>Executable</OutputType>
@@ -88,7 +88,7 @@
</avrgcc.linker.libraries.Libraries> </avrgcc.linker.libraries.Libraries>
<avrgcc.linker.memorysettings.Flash> <avrgcc.linker.memorysettings.Flash>
<ListValues> <ListValues>
<Value>.text=0x3C00</Value> <Value>.text=0x3800</Value>
</ListValues> </ListValues>
</avrgcc.linker.memorysettings.Flash> </avrgcc.linker.memorysettings.Flash>
<avrgcc.assembler.general.IncludePaths> <avrgcc.assembler.general.IncludePaths>
@@ -96,7 +96,7 @@
<Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\include</Value> <Value>%24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\include</Value>
</ListValues> </ListValues>
</avrgcc.assembler.general.IncludePaths> </avrgcc.assembler.general.IncludePaths>
</AvrGcc> </AvrGcc>
</ToolchainSettings> </ToolchainSettings>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
@@ -133,7 +133,7 @@
</avrgcc.linker.libraries.Libraries> </avrgcc.linker.libraries.Libraries>
<avrgcc.linker.memorysettings.Flash> <avrgcc.linker.memorysettings.Flash>
<ListValues> <ListValues>
<Value>.text=0x3C00</Value> <Value>.text=0x3800</Value>
</ListValues> </ListValues>
</avrgcc.linker.memorysettings.Flash> </avrgcc.linker.memorysettings.Flash>
<avrgcc.assembler.general.IncludePaths> <avrgcc.assembler.general.IncludePaths>
@@ -142,7 +142,7 @@
</ListValues> </ListValues>
</avrgcc.assembler.general.IncludePaths> </avrgcc.assembler.general.IncludePaths>
<avrgcc.assembler.debugging.DebugLevel>Default (-Wa,-g)</avrgcc.assembler.debugging.DebugLevel> <avrgcc.assembler.debugging.DebugLevel>Default (-Wa,-g)</avrgcc.assembler.debugging.DebugLevel>
</AvrGcc> </AvrGcc>
</ToolchainSettings> </ToolchainSettings>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
+75 -24
View File
@@ -15,8 +15,11 @@
#include "uart.h" #include "uart.h"
#include "srec.h" #include "srec.h"
void (*startApplication)( void ) = 0x0000; /* Funktionspointer auf 0x0000 */ typedef void(fp_t)(void);
void (*startBootloader)( void ) = 0x7800; /* Funktionspointer auf 0x0000 */ fp_t *startApplication = (fp_t*)0x0000; /* Funktionspointer auf 0x0000 */
fp_t *startBootloader = (fp_t*)0x7000; /* Funktionspointer auf 0x7000 */
#define SPM_PAGESIZE_MASK 0x7F
inline void bootloader_enter() inline void bootloader_enter()
{ {
@@ -35,9 +38,6 @@ inline void bootloader_exit()
char temp = MCUCR; char temp = MCUCR;
MCUCR = temp | (1<<IVCE); MCUCR = temp | (1<<IVCE);
MCUCR = temp & ~(1<<IVSEL); MCUCR = temp & ~(1<<IVSEL);
/* Return to address 0x0000 */
startApplication();
} }
typedef enum _eState typedef enum _eState
@@ -46,8 +46,9 @@ typedef enum _eState
StateHex, StateHex,
} State; } State;
const char *stateStr[2] = {"Idle", "Hex"}; void write_page(uint16_t page_addr, uint8_t *buf);
const char *srecStr[] = {"srec_err", "srec_sob", "srec_data", "srec_rec", "srec_eob"}; void program_page (uint32_t page, uint8_t *buf);
int main(void) int main(void)
{ {
uint8_t page_buffer[SPM_PAGESIZE]; uint8_t page_buffer[SPM_PAGESIZE];
@@ -58,15 +59,16 @@ int main(void)
cli(); cli();
bootloader_enter(); bootloader_enter();
uart_init(115200); uart_init(9600);
uart_puts("Hallo, Welt!\n"); uart_puts("Hendi-Control Bootloader\n");
size_t image_size = 0; size_t image_size = 0;
uint16_t page_addr = 0; uint16_t page_addr = 0xFFFF;
int page_isEmpty = 1; int page_isEmpty = 1;
size_t hex_buffer_size = 0; size_t hex_buffer_size = 0;
int leave_loop = 0;
while (1) do
{ {
char c; char c;
if ((c = uart_getc())) if ((c = uart_getc()))
@@ -90,7 +92,7 @@ int main(void)
} }
if (C == 'Q') if (C == 'Q')
{ {
startApplication(); leave_loop = 1;
} }
break; break;
@@ -102,7 +104,6 @@ int main(void)
else else
{ {
int srec_state = srec_decode(&srec, hex_buffer, hex_buffer_size); int srec_state = srec_decode(&srec, hex_buffer, hex_buffer_size);
uart_puts(" : "); uart_puts(srecStr[srec_state]); uart_puts("\n");
hex_buffer_size = 0; hex_buffer_size = 0;
switch(srec_state) switch(srec_state)
{ {
@@ -112,20 +113,53 @@ int main(void)
break; break;
case srec_data: case srec_data:
{ {
if ((srec.addr + srec.size) > image_size) uint16_t next_page_addr = srec.addr & ~SPM_PAGESIZE_MASK;
image_size = srec.addr + srec.size; int withinPage = (page_addr == next_page_addr);
if (!withinPage)
{
if (!page_isEmpty)
{
write_page(page_addr, page_buffer);
page_isEmpty = 1;
}
}
if (page_isEmpty) if (page_isEmpty)
{ {
// Begin new page
page_isEmpty = 0; page_isEmpty = 0;
page_addr = srec.addr; page_addr = srec.addr & ~SPM_PAGESIZE_MASK;
for (int i=0; i < SPM_PAGESIZE; i++)
{
page_buffer[i] = 0xFF;
} }
uart_puts("SREC.ADDR: "); print_word(srec.addr); uart_puts("\n"); eeprom_busy_wait ();
boot_spm_busy_wait ();
boot_page_erase (page_addr);
uart_putc('.');
}
int start = srec.addr & SPM_PAGESIZE_MASK;
for (int i=0; i < srec.size; i++)
{
page_buffer[start + i] = srec.data[i];
}
image_size += srec.size;
} }
break; break;
case srec_rec: case srec_rec:
break; break;
case srec_eob: case srec_eob:
state_next = StateIdle;
if (!page_isEmpty)
{
write_page(page_addr, page_buffer);
page_isEmpty = 1;
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; break;
case srec_err: case srec_err:
startBootloader(); startBootloader();
@@ -138,16 +172,33 @@ int main(void)
break; break;
} }
if (state_next != state)
{
uart_puts("State: "); uart_puts(stateStr[state]); uart_puts(" => "); uart_puts(stateStr[state_next]); uart_puts("\n");
}
state = state_next; state = state_next;
uart_putc(c);
} }
} } while (!leave_loop);
uart_puts("Exit bootloader!\n");
uart_puts("Exit bootloader!\n\n");
bootloader_exit(); bootloader_exit();
/* Return to address 0x0000 */
startApplication();
} }
void write_page(uint16_t page_addr, uint8_t *pPageBuffer)
{
uint16_t i;
// uart_puts("Write page 0x"); print_word(page_addr); uart_puts("\n");
boot_spm_busy_wait (); /* Wait until the memory is erased. */
for (i=0; i<SPM_PAGESIZE; i+=2)
{
/* Set up little-endian word. */
uint16_t w = *(pPageBuffer++);
w += *(pPageBuffer++) << 8;
boot_page_fill (page_addr + i, w);
}
boot_page_write (page_addr); /* Store buffer in flash page. */
}
@@ -11,6 +11,8 @@
#include "machine.h" #include "machine.h"
#define XON 17 /* XON Zeichen */
#define XOFF 19 /* XOFF Zeichen */
#define UART_PRESCALE(baudrate, smpPerBit) ((5+ 10*F_CPU / (baudrate*smpPerBit) - 1)/10) #define UART_PRESCALE(baudrate, smpPerBit) ((5+ 10*F_CPU / (baudrate*smpPerBit) - 1)/10)
void uart_init(uint32_t baudrate); void uart_init(uint32_t baudrate);