/* * Bootloader.c * * Created: 03.03.2019 09:55:52 * Author : Jens */ #include "machine.h" #include #include #include #include #include #include "uart.h" #include "srec.h" 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 0x7FUL inline void bootloader_enter() { /* Interrupt Vektoren verbiegen */ char sregtemp = SREG; char temp = MCUCR; MCUCR = temp | (1< write to flash if (start == SPM_PAGESIZE) { page_is_dirty = 0; write_page(page_addr, page_buffer); 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 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; } state = state_next; } } while (!leave_loop); // After flash update: Without RWW section enable, jump to app will fail boot_rww_enable(); } bootloader_exit(); /* Return to address 0x0000 */ startApplication(); } void erase_page(uint16_t page_addr) { 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; boot_spm_busy_wait (); /* Wait until the memory is erased. */ for (i=0; i