-bootloader is flashing
git-svn-id: http://moon:8086/svn/projects/HendiControl@52 fda53097-d464-4ada-af97-ba876c37ca34
This commit is contained in:
@@ -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>
|
||||||
@@ -58,91 +58,91 @@
|
|||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||||
<ToolchainSettings>
|
<ToolchainSettings>
|
||||||
<AvrGcc>
|
<AvrGcc>
|
||||||
<avrgcc.common.Device>-mmcu=atmega328p -B "%24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\gcc\dev\atmega328p"</avrgcc.common.Device>
|
<avrgcc.common.Device>-mmcu=atmega328p -B "%24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\gcc\dev\atmega328p"</avrgcc.common.Device>
|
||||||
<avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
|
<avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
|
||||||
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
|
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
|
||||||
<avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
|
<avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
|
||||||
<avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec>
|
<avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec>
|
||||||
<avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures>
|
<avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures>
|
||||||
<avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
|
<avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
|
||||||
<avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
|
<avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
|
||||||
<avrgcc.compiler.symbols.DefSymbols>
|
<avrgcc.compiler.symbols.DefSymbols>
|
||||||
<ListValues>
|
<ListValues>
|
||||||
<Value>NDEBUG</Value>
|
<Value>NDEBUG</Value>
|
||||||
<Value>ARDUINO_NANO=1</Value>
|
<Value>ARDUINO_NANO=1</Value>
|
||||||
</ListValues>
|
</ListValues>
|
||||||
</avrgcc.compiler.symbols.DefSymbols>
|
</avrgcc.compiler.symbols.DefSymbols>
|
||||||
<avrgcc.compiler.directories.IncludePaths>
|
<avrgcc.compiler.directories.IncludePaths>
|
||||||
<ListValues>
|
<ListValues>
|
||||||
<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.compiler.directories.IncludePaths>
|
</avrgcc.compiler.directories.IncludePaths>
|
||||||
<avrgcc.compiler.optimization.level>Optimize for size (-Os)</avrgcc.compiler.optimization.level>
|
<avrgcc.compiler.optimization.level>Optimize for size (-Os)</avrgcc.compiler.optimization.level>
|
||||||
<avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
|
<avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
|
||||||
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
|
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
|
||||||
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
|
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
|
||||||
<avrgcc.linker.libraries.Libraries>
|
<avrgcc.linker.libraries.Libraries>
|
||||||
<ListValues>
|
<ListValues>
|
||||||
<Value>libm</Value>
|
<Value>libm</Value>
|
||||||
</ListValues>
|
</ListValues>
|
||||||
</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>
|
||||||
<ListValues>
|
<ListValues>
|
||||||
<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' ">
|
||||||
<ToolchainSettings>
|
<ToolchainSettings>
|
||||||
<AvrGcc>
|
<AvrGcc>
|
||||||
<avrgcc.common.Device>-mmcu=atmega328p -B "%24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\gcc\dev\atmega328p"</avrgcc.common.Device>
|
<avrgcc.common.Device>-mmcu=atmega328p -B "%24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\gcc\dev\atmega328p"</avrgcc.common.Device>
|
||||||
<avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
|
<avrgcc.common.outputfiles.hex>True</avrgcc.common.outputfiles.hex>
|
||||||
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
|
<avrgcc.common.outputfiles.lss>True</avrgcc.common.outputfiles.lss>
|
||||||
<avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
|
<avrgcc.common.outputfiles.eep>True</avrgcc.common.outputfiles.eep>
|
||||||
<avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec>
|
<avrgcc.common.outputfiles.srec>True</avrgcc.common.outputfiles.srec>
|
||||||
<avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures>
|
<avrgcc.common.outputfiles.usersignatures>False</avrgcc.common.outputfiles.usersignatures>
|
||||||
<avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
|
<avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</avrgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
|
||||||
<avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
|
<avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>True</avrgcc.compiler.general.ChangeDefaultBitFieldUnsigned>
|
||||||
<avrgcc.compiler.symbols.DefSymbols>
|
<avrgcc.compiler.symbols.DefSymbols>
|
||||||
<ListValues>
|
<ListValues>
|
||||||
<Value>DEBUG</Value>
|
<Value>DEBUG</Value>
|
||||||
<Value>ARDUINO_NANO=1</Value>
|
<Value>ARDUINO_NANO=1</Value>
|
||||||
</ListValues>
|
</ListValues>
|
||||||
</avrgcc.compiler.symbols.DefSymbols>
|
</avrgcc.compiler.symbols.DefSymbols>
|
||||||
<avrgcc.compiler.directories.IncludePaths>
|
<avrgcc.compiler.directories.IncludePaths>
|
||||||
<ListValues>
|
<ListValues>
|
||||||
<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.compiler.directories.IncludePaths>
|
</avrgcc.compiler.directories.IncludePaths>
|
||||||
<avrgcc.compiler.optimization.level>Optimize debugging experience (-Og)</avrgcc.compiler.optimization.level>
|
<avrgcc.compiler.optimization.level>Optimize debugging experience (-Og)</avrgcc.compiler.optimization.level>
|
||||||
<avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
|
<avrgcc.compiler.optimization.PackStructureMembers>True</avrgcc.compiler.optimization.PackStructureMembers>
|
||||||
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
|
<avrgcc.compiler.optimization.AllocateBytesNeededForEnum>True</avrgcc.compiler.optimization.AllocateBytesNeededForEnum>
|
||||||
<avrgcc.compiler.optimization.DebugLevel>Default (-g2)</avrgcc.compiler.optimization.DebugLevel>
|
<avrgcc.compiler.optimization.DebugLevel>Default (-g2)</avrgcc.compiler.optimization.DebugLevel>
|
||||||
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
|
<avrgcc.compiler.warnings.AllWarnings>True</avrgcc.compiler.warnings.AllWarnings>
|
||||||
<avrgcc.linker.libraries.Libraries>
|
<avrgcc.linker.libraries.Libraries>
|
||||||
<ListValues>
|
<ListValues>
|
||||||
<Value>libm</Value>
|
<Value>libm</Value>
|
||||||
</ListValues>
|
</ListValues>
|
||||||
</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>
|
||||||
<ListValues>
|
<ListValues>
|
||||||
<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.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>
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
eeprom_busy_wait ();
|
||||||
|
boot_spm_busy_wait ();
|
||||||
|
boot_page_erase (page_addr);
|
||||||
|
|
||||||
|
uart_putc('.');
|
||||||
}
|
}
|
||||||
uart_puts("SREC.ADDR: "); print_word(srec.addr); uart_puts("\n");
|
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. */
|
||||||
|
}
|
||||||
|
|||||||
@@ -48,10 +48,10 @@ void uart_putc(char c)
|
|||||||
|
|
||||||
char uart_getc()
|
char uart_getc()
|
||||||
{
|
{
|
||||||
while ((UCSR0A & (1 << RXC0)) == 0)
|
while ((UCSR0A & (1 << RXC0)) == 0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
return UDR0;
|
return UDR0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void uart_puts(char const *str)
|
void uart_puts(char const *str)
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user