diff --git a/Control/firmware/Bootloader/Bootloader/Bootloader.cproj b/Control/firmware/Bootloader/Bootloader/Bootloader.cproj
index c214e4c..6b65d49 100644
--- a/Control/firmware/Bootloader/Bootloader/Bootloader.cproj
+++ b/Control/firmware/Bootloader/Bootloader/Bootloader.cproj
@@ -4,7 +4,7 @@
2.0
7.0
com.Atmel.AVRGCC8.C
- dce6c7e3-ee26-4d79-826b-08594b9ad897
+ {c77f8c5d-b585-42ee-bf03-003a6350cd7a}
ATmega328P
none
Executable
@@ -58,91 +58,91 @@
- -mmcu=atmega328p -B "%24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\gcc\dev\atmega328p"
- True
- True
- True
- True
- False
- True
- True
-
-
- NDEBUG
- ARDUINO_NANO=1
-
-
-
-
- %24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\include
-
-
- Optimize for size (-Os)
- True
- True
- True
-
-
- libm
-
-
-
-
- .text=0x3C00
-
-
-
-
- %24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\include
-
-
-
+ -mmcu=atmega328p -B "%24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\gcc\dev\atmega328p"
+ True
+ True
+ True
+ True
+ False
+ True
+ True
+
+
+ NDEBUG
+ ARDUINO_NANO=1
+
+
+
+
+ %24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\include
+
+
+ Optimize for size (-Os)
+ True
+ True
+ True
+
+
+ libm
+
+
+
+
+ .text=0x3800
+
+
+
+
+ %24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\include
+
+
+
- -mmcu=atmega328p -B "%24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\gcc\dev\atmega328p"
- True
- True
- True
- True
- False
- True
- True
-
-
- DEBUG
- ARDUINO_NANO=1
-
-
-
-
- %24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\include
-
-
- Optimize debugging experience (-Og)
- True
- True
- Default (-g2)
- True
-
-
- libm
-
-
-
-
- .text=0x3C00
-
-
-
-
- %24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\include
-
-
- Default (-Wa,-g)
-
+ -mmcu=atmega328p -B "%24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\gcc\dev\atmega328p"
+ True
+ True
+ True
+ True
+ False
+ True
+ True
+
+
+ DEBUG
+ ARDUINO_NANO=1
+
+
+
+
+ %24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\include
+
+
+ Optimize debugging experience (-Og)
+ True
+ True
+ Default (-g2)
+ True
+
+
+ libm
+
+
+
+
+ .text=0x3800
+
+
+
+
+ %24(PackRepoDir)\atmel\ATmega_DFP\1.2.209\include
+
+
+ Default (-Wa,-g)
+
diff --git a/Control/firmware/Bootloader/Bootloader/main.c b/Control/firmware/Bootloader/Bootloader/main.c
index 7ceedfb..6a08626 100644
--- a/Control/firmware/Bootloader/Bootloader/main.c
+++ b/Control/firmware/Bootloader/Bootloader/main.c
@@ -15,8 +15,11 @@
#include "uart.h"
#include "srec.h"
-void (*startApplication)( void ) = 0x0000; /* Funktionspointer auf 0x0000 */
-void (*startBootloader)( void ) = 0x7800; /* Funktionspointer auf 0x0000 */
+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
inline void bootloader_enter()
{
@@ -35,9 +38,6 @@ inline void bootloader_exit()
char temp = MCUCR;
MCUCR = temp | (1< image_size)
- image_size = srec.addr + srec.size;
+ uint16_t next_page_addr = srec.addr & ~SPM_PAGESIZE_MASK;
+ int withinPage = (page_addr == next_page_addr);
+ if (!withinPage)
+ {
+ if (!page_isEmpty)
+ {
+ write_page(page_addr, page_buffer);
+ page_isEmpty = 1;
+ }
+ }
if (page_isEmpty)
{
+ // Begin new page
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;
case srec_rec:
break;
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;
case srec_err:
startBootloader();
@@ -138,16 +172,33 @@ int main(void)
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;
- uart_putc(c);
}
- }
- uart_puts("Exit bootloader!\n");
+ } while (!leave_loop);
+
+ uart_puts("Exit bootloader!\n\n");
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