diff --git a/firmware/bootloader/bootloader.mk b/firmware/bootloader/bootloader.mk index d8dbd5af08..843d5abf75 100644 --- a/firmware/bootloader/bootloader.mk +++ b/firmware/bootloader/bootloader.mk @@ -5,9 +5,7 @@ ifeq ($(BOOTLOADERINC),) BOOTLOADERINC=$(PROJECT_DIR)/bootloader endif -ifeq ($(LDSCRIPT),) - LDSCRIPT= config/stm32f4ems/STM32F407xG_CCM_bootloader.ld -endif +USE_OPT += -Wl,--defsym=BOOTLOADER=1 # Add bootloader code to the firmware DDEFS += -DEFI_BOOTLOADER_INCLUDE_CODE=TRUE diff --git a/firmware/bootloader/bootloader_generated.hxx b/firmware/bootloader/bootloader_generated.hxx index 6031ce4aec..9e62fb623b 100644 --- a/firmware/bootloader/bootloader_generated.hxx +++ b/firmware/bootloader/bootloader_generated.hxx @@ -1,5 +1,5 @@ // This file was generated by Bin2Header -// Wed May 31 01:05:18 EEST 2017 +// Sun Jun 04 21:58:31 EEST 2017 #ifndef BOOTLOADER_GENERATED_HXX_ #define BOOTLOADER_GENERATED_HXX_ @@ -32,7 +32,7 @@ static const volatile uint8_t bootloader_code[] BOOTLOADER_SECTION = { 0xf1, 0x04, 0x00, 0x08, 0xf1, 0x04, 0x00, 0x08, 0xf1, 0x04, 0x00, 0x08, 0xf1, 0x04, 0x00, 0x08, 0xf1, 0x04, 0x00, 0x08, 0xf1, 0x04, 0x00, 0x08, 0xf1, 0x04, 0x00, 0x08, 0xf1, 0x04, 0x00, 0x08, 0xf1, 0x04, 0x00, 0x08, 0xf1, 0x04, 0x00, 0x08, 0xf1, 0x04, 0x00, 0x08, 0xf1, 0x04, 0x00, 0x08, - 0x31, 0x27, 0x00, 0x08, 0x61, 0x28, 0x00, 0x08, 0x61, 0x29, 0x00, 0x08, 0x51, 0x2f, 0x00, 0x08, + 0x11, 0x27, 0x00, 0x08, 0x41, 0x28, 0x00, 0x08, 0x41, 0x29, 0x00, 0x08, 0x71, 0x2f, 0x00, 0x08, 0x72, 0xb6, 0x34, 0x48, 0x80, 0xf3, 0x09, 0x88, 0x40, 0xf2, 0x00, 0x00, 0xcc, 0xf2, 0x00, 0x00, 0x4e, 0xf6, 0x34, 0x71, 0xce, 0xf2, 0x00, 0x01, 0x08, 0x60, 0xbf, 0xf3, 0x4f, 0x8f, 0xbf, 0xf3, 0x6f, 0x8f, 0x40, 0xf2, 0x00, 0x00, 0xc0, 0xf2, 0xf0, 0x00, 0x4e, 0xf6, 0x88, 0x51, 0xce, 0xf2, @@ -44,10 +44,10 @@ static const volatile uint8_t bootloader_code[] BOOTLOADER_SECTION = { 0x18, 0x49, 0x19, 0x4a, 0x19, 0x4b, 0x9a, 0x42, 0x3e, 0xbf, 0x51, 0xf8, 0x04, 0x0b, 0x42, 0xf8, 0x04, 0x0b, 0xf8, 0xe7, 0x00, 0x20, 0x16, 0x49, 0x16, 0x4a, 0x91, 0x42, 0x3c, 0xbf, 0x41, 0xf8, 0x04, 0x0b, 0xfa, 0xe7, 0x00, 0xf0, 0x0c, 0xf9, 0x00, 0xf0, 0xfa, 0xf8, 0x12, 0x4c, 0x13, 0x4d, - 0xac, 0x42, 0x03, 0xda, 0x54, 0xf8, 0x04, 0x1b, 0x88, 0x47, 0xf9, 0xe7, 0x02, 0xf0, 0x38, 0xfe, + 0xac, 0x42, 0x03, 0xda, 0x54, 0xf8, 0x04, 0x1b, 0x88, 0x47, 0xf9, 0xe7, 0x02, 0xf0, 0x48, 0xfe, 0x0f, 0x4c, 0x10, 0x4d, 0xac, 0x42, 0x03, 0xda, 0x54, 0xf8, 0x04, 0x1b, 0x88, 0x47, 0xf9, 0xe7, 0x00, 0xf0, 0xee, 0xb8, 0x00, 0x16, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0x20, - 0x00, 0x10, 0x00, 0x20, 0x58, 0x37, 0x00, 0x08, 0x00, 0x16, 0x00, 0x20, 0x18, 0x16, 0x00, 0x20, + 0x00, 0x10, 0x00, 0x20, 0x78, 0x37, 0x00, 0x08, 0x00, 0x16, 0x00, 0x20, 0x18, 0x16, 0x00, 0x20, 0x18, 0x16, 0x00, 0x20, 0xec, 0x79, 0x00, 0x20, 0xc0, 0x01, 0x00, 0x08, 0xd0, 0x01, 0x00, 0x08, 0xd0, 0x01, 0x00, 0x08, 0xd0, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0xe9, 0xf0, 0x4f, 0x2d, 0xed, 0x10, 0x8a, 0xc1, 0xf8, 0x0c, 0xd0, 0xc3, 0x68, 0x9d, 0x46, @@ -81,8 +81,8 @@ static const volatile uint8_t bootloader_code[] BOOTLOADER_SECTION = { 0x00, 0x26, 0x9c, 0x42, 0x11, 0xd9, 0x04, 0x39, 0x1a, 0x46, 0x51, 0xf8, 0x04, 0x0f, 0x42, 0xf8, 0x04, 0x0b, 0x94, 0x42, 0xf9, 0xd8, 0xda, 0x43, 0x14, 0x44, 0x24, 0xf0, 0x03, 0x04, 0x04, 0x34, 0x23, 0x44, 0x9d, 0x42, 0x03, 0xd9, 0x43, 0xf8, 0x04, 0x6b, 0x9d, 0x42, 0xfb, 0xd8, 0x10, 0x37, - 0x77, 0x45, 0x02, 0xd2, 0x97, 0xe8, 0x3a, 0x00, 0xe3, 0xe7, 0xf0, 0xbd, 0x00, 0x30, 0x00, 0x08, - 0xec, 0x79, 0x00, 0x20, 0xec, 0x79, 0x00, 0x20, 0xec, 0x79, 0x00, 0x20, 0x70, 0x37, 0x00, 0x08, + 0x77, 0x45, 0x02, 0xd2, 0x97, 0xe8, 0x3a, 0x00, 0xe3, 0xe7, 0xf0, 0xbd, 0x20, 0x30, 0x00, 0x08, + 0xec, 0x79, 0x00, 0x20, 0xec, 0x79, 0x00, 0x20, 0xec, 0x79, 0x00, 0x20, 0x90, 0x37, 0x00, 0x08, 0xfe, 0xe7, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xe7, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x4b, 0x22, 0x4a, 0x22, 0x48, 0xf0, 0xb5, 0x00, 0x24, 0x9c, 0x60, 0xd9, 0x68, 0x21, 0x4e, @@ -94,10 +94,10 @@ static const volatile uint8_t bootloader_code[] BOOTLOADER_SECTION = { 0x7f, 0xf8, 0x84, 0xf3, 0x11, 0x88, 0x62, 0xb6, 0xbb, 0x69, 0x0c, 0x4a, 0x9a, 0x61, 0x05, 0xf1, 0x50, 0x00, 0x32, 0x46, 0x00, 0x94, 0x0a, 0x4b, 0x40, 0xf6, 0x18, 0x01, 0x00, 0xf0, 0x28, 0xfb, 0x08, 0x4b, 0x83, 0x61, 0x03, 0xb0, 0xf0, 0xbd, 0x00, 0xed, 0x00, 0xe0, 0x00, 0x03, 0xfa, 0x05, - 0x00, 0x10, 0x00, 0xe0, 0xf0, 0xed, 0x00, 0xe0, 0x50, 0x16, 0x00, 0x20, 0xf0, 0x31, 0x00, 0x08, - 0x01, 0x05, 0x00, 0x08, 0xa0, 0x30, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0xb5, 0x04, 0x46, 0x72, 0xb6, 0xb1, 0x22, 0x02, 0x49, 0x02, 0xf0, 0xd1, 0xf9, 0x02, 0x4b, - 0xdc, 0x62, 0xfe, 0xe7, 0x80, 0x30, 0x00, 0x08, 0x18, 0x16, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0xe0, 0xf0, 0xed, 0x00, 0xe0, 0x50, 0x16, 0x00, 0x20, 0x10, 0x32, 0x00, 0x08, + 0x01, 0x05, 0x00, 0x08, 0xc0, 0x30, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0xb5, 0x04, 0x46, 0x72, 0xb6, 0xb1, 0x22, 0x02, 0x49, 0x02, 0xf0, 0xc1, 0xf9, 0x02, 0x4b, + 0xdc, 0x62, 0xfe, 0xe7, 0xa0, 0x30, 0x00, 0x08, 0x18, 0x16, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x2d, 0xe9, 0xf8, 0x43, 0x16, 0x4e, 0x00, 0xf0, 0xe3, 0xf8, 0xb2, 0x69, 0x93, 0x7f, 0x0b, 0xb1, 0x01, 0x3b, 0x93, 0x77, 0x00, 0xf0, 0xdc, 0xf8, 0x12, 0x4f, 0xb3, 0x6a, 0xf4, 0x69, 0x01, 0x33, 0xbc, 0x42, 0xb3, 0x62, 0x19, 0xd0, 0xa5, 0x68, 0x01, 0x3d, 0xa5, 0x60, 0xad, 0xb9, 0x4f, 0xf0, @@ -106,31 +106,31 @@ static const volatile uint8_t bootloader_code[] BOOTLOADER_SECTION = { 0x57, 0xf8, 0xf4, 0x69, 0xa3, 0x68, 0x00, 0x2b, 0xeb, 0xd0, 0xbd, 0xe8, 0xf8, 0x83, 0x00, 0xbf, 0x18, 0x16, 0x00, 0x20, 0x34, 0x16, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x4b, 0x1a, 0x6b, 0x0a, 0xb9, 0x5b, 0x6b, 0x13, 0xb1, 0x03, 0x48, 0xff, 0xf7, 0xb0, 0xbf, - 0x70, 0x47, 0x00, 0xbf, 0x18, 0x16, 0x00, 0x20, 0xb0, 0x30, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x70, 0x47, 0x00, 0xbf, 0x18, 0x16, 0x00, 0x20, 0xd0, 0x30, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x04, 0x4b, 0x1a, 0x6b, 0x0a, 0xb9, 0x5b, 0x6b, 0x13, 0xb1, 0x03, 0x48, 0xff, 0xf7, 0xa0, 0xbf, - 0x70, 0x47, 0x00, 0xbf, 0x18, 0x16, 0x00, 0x20, 0xc0, 0x30, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x70, 0x47, 0x00, 0xbf, 0x18, 0x16, 0x00, 0x20, 0xe0, 0x30, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x10, 0xb5, 0x05, 0x4c, 0x23, 0x6b, 0x0b, 0xb9, 0x63, 0x6b, 0x13, 0xb1, 0x03, 0x48, 0xff, 0xf7, - 0x8f, 0xff, 0x01, 0x23, 0x63, 0x63, 0x10, 0xbd, 0x18, 0x16, 0x00, 0x20, 0xf0, 0x30, 0x00, 0x08, + 0x8f, 0xff, 0x01, 0x23, 0x63, 0x63, 0x10, 0xbd, 0x18, 0x16, 0x00, 0x20, 0x10, 0x31, 0x00, 0x08, 0x10, 0xb5, 0x07, 0x4c, 0x23, 0x6b, 0x2b, 0xb9, 0x63, 0x6b, 0x00, 0x2b, 0x02, 0xdd, 0x00, 0x23, 0x63, 0x63, 0x10, 0xbd, 0x03, 0x48, 0xff, 0xf7, 0x7b, 0xff, 0x00, 0x23, 0x63, 0x63, 0x10, 0xbd, - 0x18, 0x16, 0x00, 0x20, 0x40, 0x31, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x16, 0x00, 0x20, 0x60, 0x31, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xb5, 0x06, 0x4c, 0x23, 0x6b, 0x00, 0x2b, 0x01, 0xdd, 0x63, 0x6b, 0x13, 0xb1, 0x04, 0x48, 0xff, 0xf7, 0x66, 0xff, 0x01, 0x23, 0x63, 0x63, 0x10, 0xbd, 0x00, 0xbf, 0x18, 0x16, 0x00, 0x20, - 0x10, 0x31, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x31, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xb5, 0x08, 0x4c, 0x23, 0x6b, 0x00, 0x2b, 0x05, 0xdd, 0x63, 0x6b, 0x00, 0x2b, 0x02, 0xdd, 0x00, 0x23, 0x63, 0x63, 0x10, 0xbd, 0x04, 0x48, 0xff, 0xf7, 0x4a, 0xff, 0x00, 0x23, 0x63, 0x63, - 0x10, 0xbd, 0x00, 0xbf, 0x18, 0x16, 0x00, 0x20, 0x50, 0x31, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xbd, 0x00, 0xbf, 0x18, 0x16, 0x00, 0x20, 0x70, 0x31, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x10, 0xb5, 0x20, 0x23, 0x83, 0xf3, 0x11, 0x88, 0x0a, 0x4c, 0x23, 0x6b, 0x00, 0x2b, 0x01, 0xdb, 0x62, 0x6b, 0x1a, 0xb1, 0x08, 0x48, 0xff, 0xf7, 0x33, 0xff, 0x23, 0x6b, 0x07, 0x4a, 0x11, 0x68, 0x01, 0x33, 0x8b, 0x42, 0x23, 0x63, 0xc8, 0xbf, 0x13, 0x60, 0x00, 0x23, 0x83, 0xf3, 0x11, 0x88, - 0x10, 0xbd, 0x00, 0xbf, 0x18, 0x16, 0x00, 0x20, 0xd0, 0x30, 0x00, 0x08, 0x88, 0x31, 0x00, 0x20, + 0x10, 0xbd, 0x00, 0xbf, 0x18, 0x16, 0x00, 0x20, 0xf0, 0x30, 0x00, 0x08, 0x88, 0x31, 0x00, 0x20, 0x10, 0xb5, 0x20, 0x23, 0x83, 0xf3, 0x11, 0x88, 0x07, 0x4c, 0x23, 0x6b, 0x00, 0x2b, 0x01, 0xdd, 0x62, 0x6b, 0x1a, 0xb1, 0x05, 0x48, 0xff, 0xf7, 0x13, 0xff, 0x23, 0x6b, 0x01, 0x3b, 0x23, 0x63, - 0x00, 0x23, 0x83, 0xf3, 0x11, 0x88, 0x10, 0xbd, 0x18, 0x16, 0x00, 0x20, 0xe0, 0x30, 0x00, 0x08, + 0x00, 0x23, 0x83, 0xf3, 0x11, 0x88, 0x10, 0xbd, 0x18, 0x16, 0x00, 0x20, 0x00, 0x31, 0x00, 0x08, 0x05, 0x4b, 0x1a, 0x6b, 0x00, 0x2a, 0x03, 0xdb, 0x5b, 0x6b, 0x00, 0x2b, 0x00, 0xdd, 0x70, 0x47, - 0x02, 0x48, 0xff, 0xf7, 0xfd, 0xbe, 0x00, 0xbf, 0x18, 0x16, 0x00, 0x20, 0x60, 0x31, 0x00, 0x08, + 0x02, 0x48, 0xff, 0xf7, 0xfd, 0xbe, 0x00, 0xbf, 0x18, 0x16, 0x00, 0x20, 0x80, 0x31, 0x00, 0x08, 0x04, 0x4b, 0x1a, 0x6b, 0x1a, 0xb9, 0x5b, 0x6b, 0x00, 0x2b, 0x00, 0xdd, 0x70, 0x47, 0x02, 0x48, - 0xff, 0xf7, 0xee, 0xbe, 0x18, 0x16, 0x00, 0x20, 0x90, 0x31, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xf7, 0xee, 0xbe, 0x18, 0x16, 0x00, 0x20, 0xb0, 0x31, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x05, 0x4b, 0x4f, 0xf0, 0xff, 0x30, 0x03, 0xf1, 0x1c, 0x02, 0x00, 0x21, 0x58, 0x62, 0x99, 0x62, 0xda, 0x61, 0x1a, 0x62, 0x70, 0x47, 0x00, 0xbf, 0x18, 0x16, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb5, 0x05, 0x46, 0x0c, 0x46, 0x16, 0x46, 0x1f, 0x46, 0xff, 0xf7, 0xc9, 0xff, 0xd5, 0xb1, @@ -138,17 +138,17 @@ static const volatile uint8_t bootloader_code[] BOOTLOADER_SECTION = { 0x04, 0xd9, 0x1b, 0x68, 0xa4, 0x1a, 0x9a, 0x68, 0xa2, 0x42, 0xfa, 0xd3, 0x5a, 0x68, 0x6a, 0x60, 0x2b, 0x60, 0x15, 0x60, 0x5d, 0x60, 0xac, 0x60, 0x99, 0x68, 0x4f, 0xf0, 0xff, 0x32, 0x09, 0x1b, 0x99, 0x60, 0x42, 0x62, 0xf8, 0xbd, 0x03, 0x48, 0xff, 0xf7, 0xb2, 0xfe, 0xe2, 0xe7, 0x00, 0xbf, - 0x18, 0x16, 0x00, 0x20, 0xa0, 0x31, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x16, 0x00, 0x20, 0xc0, 0x31, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0xb5, 0x04, 0x46, 0xff, 0xf7, 0x9c, 0xff, 0x7c, 0xb1, 0x23, 0x68, 0xa5, 0x68, 0x9a, 0x68, 0x61, 0x68, 0x08, 0x48, 0x2a, 0x44, 0x9a, 0x60, 0x0b, 0x60, 0x25, 0x68, 0x00, 0x22, 0x4f, 0xf0, 0xff, 0x33, 0x69, 0x60, 0xe2, 0x60, 0x43, 0x62, 0x38, 0xbd, 0x03, 0x48, 0xff, 0xf7, 0x90, 0xfe, - 0xeb, 0xe7, 0x00, 0xbf, 0x18, 0x16, 0x00, 0x20, 0xb0, 0x31, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0xeb, 0xe7, 0x00, 0xbf, 0x18, 0x16, 0x00, 0x20, 0xd0, 0x31, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x03, 0x4b, 0x00, 0x22, 0x1b, 0x60, 0x5b, 0x60, 0x1b, 0x61, 0x5b, 0x61, 0x9a, 0x60, 0x70, 0x47, 0x18, 0x16, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xb5, 0x04, 0x46, 0xff, 0xf7, 0x6c, 0xff, 0x74, 0xb1, 0x00, 0x22, 0xa1, 0x68, 0x08, 0x4b, 0x22, 0x77, 0x1b, 0x68, 0x9a, 0x68, 0x8a, 0x42, 0xfb, 0xd2, 0x5a, 0x68, 0x62, 0x60, 0x23, 0x60, 0x20, 0x46, 0x14, 0x60, 0x5c, 0x60, 0x10, 0xbd, 0x02, 0x48, 0xff, 0xf7, 0x61, 0xfe, 0xec, 0xe7, - 0x18, 0x16, 0x00, 0x20, 0xc0, 0x31, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x16, 0x00, 0x20, 0xe0, 0x31, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0xb5, 0x04, 0x46, 0x20, 0x23, 0x83, 0xf3, 0x11, 0x88, 0xff, 0xf7, 0xe1, 0xfe, 0x23, 0x7f, 0x07, 0x2b, 0x10, 0xd8, 0xdf, 0xe8, 0x03, 0xf0, 0x15, 0x0f, 0x0f, 0x1b, 0x0a, 0x04, 0x0f, 0x0a, 0x25, 0x6a, 0xff, 0xf7, 0x3d, 0xff, 0xab, 0x68, 0x01, 0x33, 0xab, 0x60, 0x94, 0xe8, 0x0c, 0x00, @@ -192,7 +192,7 @@ static const volatile uint8_t bootloader_code[] BOOTLOADER_SECTION = { 0xa0, 0x77, 0x04, 0xf1, 0x24, 0x01, 0x25, 0x77, 0x63, 0x77, 0xc4, 0xf8, 0x08, 0x80, 0x27, 0x61, 0x66, 0x61, 0xc4, 0xf8, 0x3c, 0x80, 0xa3, 0x63, 0x63, 0x63, 0xa3, 0x61, 0x20, 0x46, 0x34, 0x61, 0x7c, 0x61, 0x61, 0x62, 0xa2, 0x62, 0xe2, 0x62, 0xbd, 0xe8, 0xf8, 0x83, 0xb8, 0xf1, 0x7f, 0x0f, - 0xd2, 0xd8, 0xb9, 0xf1, 0x00, 0x0f, 0xd2, 0xd1, 0xce, 0xe7, 0x00, 0xbf, 0xd0, 0x31, 0x00, 0x08, + 0xd2, 0xd8, 0xb9, 0xf1, 0x00, 0x0f, 0xd2, 0xd1, 0xce, 0xe7, 0x00, 0xbf, 0xf0, 0x31, 0x00, 0x08, 0x18, 0x16, 0x00, 0x20, 0xf9, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0xe9, 0xf0, 0x41, 0x82, 0xb0, 0x98, 0x46, 0x04, 0x46, 0x0d, 0x46, 0x16, 0x46, 0x08, 0x9f, 0x20, 0x23, 0x83, 0xf3, 0x11, 0x88, 0xff, 0xf7, 0x4b, 0xfd, 0x43, 0x46, 0x32, 0x46, 0x29, 0x46, @@ -209,7 +209,7 @@ static const volatile uint8_t bootloader_code[] BOOTLOADER_SECTION = { 0x23, 0x7f, 0x0f, 0x2b, 0x07, 0xd0, 0x0a, 0x4b, 0x62, 0x6a, 0x9b, 0x69, 0x09, 0x20, 0x1a, 0x60, 0x63, 0x62, 0xff, 0xf7, 0x65, 0xfe, 0x24, 0x6a, 0xff, 0xf7, 0xfa, 0xfc, 0x00, 0x23, 0x83, 0xf3, 0x11, 0x88, 0x20, 0x46, 0x10, 0xbd, 0x03, 0x48, 0xff, 0xf7, 0x7a, 0xfc, 0xe3, 0xe7, 0x00, 0xbf, - 0x18, 0x16, 0x00, 0x20, 0xe0, 0x31, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x16, 0x00, 0x20, 0x00, 0x32, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0xb1, 0x08, 0x4b, 0x10, 0xb4, 0x02, 0x46, 0x44, 0x68, 0x9b, 0x69, 0x04, 0x20, 0x83, 0xe8, 0x14, 0x00, 0x23, 0x60, 0x53, 0x60, 0x5d, 0xf8, 0x04, 0x4b, 0xff, 0xf7, 0x59, 0xbe, 0x4f, 0xf0, 0xff, 0x30, 0x70, 0x47, 0x18, 0x16, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -226,16 +226,16 @@ static const volatile uint8_t bootloader_code[] BOOTLOADER_SECTION = { 0x04, 0x67, 0xff, 0xf7, 0xbd, 0xff, 0x68, 0x46, 0xff, 0xf7, 0xc2, 0xff, 0x02, 0x9b, 0xc4, 0xf8, 0x80, 0x30, 0x06, 0xb0, 0xd0, 0xbd, 0x00, 0xbf, 0x18, 0x16, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10, 0xb5, 0x04, 0x46, 0x20, 0xb1, 0x00, 0x23, 0x24, 0x60, 0x64, 0x60, 0xa3, 0x60, 0x10, 0xbd, - 0x01, 0x48, 0xff, 0xf7, 0xed, 0xfb, 0xf6, 0xe7, 0x10, 0x32, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x48, 0xff, 0xf7, 0xed, 0xfb, 0xf6, 0xe7, 0x30, 0x32, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x38, 0xb5, 0x04, 0x46, 0x0d, 0x46, 0xff, 0xf7, 0xdb, 0xfc, 0xb4, 0xb1, 0x61, 0x6b, 0x23, 0x7f, 0x29, 0x43, 0x0a, 0x2b, 0x61, 0x63, 0x0c, 0xd0, 0x0b, 0x2b, 0x00, 0xd0, 0x38, 0xbd, 0x23, 0x6a, 0x8b, 0x43, 0xfb, 0xd1, 0x00, 0x23, 0x23, 0x62, 0x20, 0x46, 0xbd, 0xe8, 0x38, 0x40, 0xff, 0xf7, 0x57, 0xbd, 0x23, 0x6a, 0x19, 0x42, 0xf5, 0xd1, 0x38, 0xbd, 0x02, 0x48, 0xff, 0xf7, 0xc8, 0xfb, - 0xe4, 0xe7, 0x00, 0xbf, 0x40, 0x32, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe4, 0xe7, 0x00, 0xbf, 0x60, 0x32, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xb5, 0x06, 0x46, 0x0d, 0x46, 0xff, 0xf7, 0xb3, 0xfc, 0x8e, 0xb1, 0x34, 0x68, 0xa6, 0x42, 0x0d, 0xd0, 0xe3, 0x68, 0x2b, 0x43, 0xe3, 0x60, 0x15, 0xb1, 0x22, 0x69, 0x13, 0x42, 0x03, 0xd0, 0xa1, 0x68, 0x60, 0x68, 0xff, 0xf7, 0xc4, 0xff, 0x24, 0x68, 0xa6, 0x42, 0xf1, 0xd1, 0x70, 0xbd, - 0x01, 0x48, 0xff, 0xf7, 0xa5, 0xfb, 0xe9, 0xe7, 0x20, 0x32, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x48, 0xff, 0xf7, 0xa5, 0xfb, 0xe9, 0xe7, 0x40, 0x32, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x30, 0xb4, 0x02, 0x9c, 0x04, 0x62, 0x00, 0x25, 0x0a, 0x44, 0x85, 0x60, 0x02, 0x61, 0x00, 0x60, 0x40, 0x60, 0xc1, 0x60, 0x81, 0x61, 0x41, 0x61, 0xc3, 0x61, 0x30, 0xbc, 0x70, 0x47, 0x00, 0xbf, 0x38, 0xb5, 0x04, 0x46, 0x0d, 0x46, 0xff, 0xf7, 0x83, 0xfc, 0xff, 0xf7, 0x81, 0xfc, 0x63, 0x69, @@ -259,7 +259,7 @@ static const volatile uint8_t bootloader_code[] BOOTLOADER_SECTION = { 0xe3, 0x68, 0xa3, 0x61, 0xff, 0xf7, 0x74, 0xfb, 0x8b, 0xf3, 0x11, 0x88, 0x01, 0x36, 0xb2, 0x45, 0x09, 0xd0, 0x01, 0x9b, 0x83, 0xf3, 0x11, 0x88, 0xff, 0xf7, 0x5a, 0xfb, 0xd3, 0xe7, 0xff, 0xf7, 0x67, 0xfb, 0x87, 0xf3, 0x11, 0x88, 0x30, 0x46, 0x03, 0xb0, 0xbd, 0xe8, 0xf0, 0x8f, 0x02, 0x48, - 0xff, 0xf7, 0xe6, 0xfa, 0xbf, 0xe7, 0x00, 0xbf, 0x50, 0x32, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xf7, 0xe6, 0xfa, 0xbf, 0xe7, 0x00, 0xbf, 0x70, 0x32, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x30, 0xb4, 0x02, 0x9c, 0x04, 0x62, 0x8d, 0x18, 0x05, 0x61, 0x00, 0x60, 0x40, 0x60, 0x82, 0x60, 0xc1, 0x60, 0x81, 0x61, 0x41, 0x61, 0xc3, 0x61, 0x30, 0xbc, 0x70, 0x47, 0x00, 0x00, 0x00, 0x00, 0x2d, 0xe9, 0xf0, 0x41, 0x20, 0x23, 0x04, 0x46, 0x88, 0x46, 0x17, 0x46, 0x83, 0xf3, 0x11, 0x88, @@ -284,7 +284,7 @@ static const volatile uint8_t bootloader_code[] BOOTLOADER_SECTION = { 0xff, 0xf7, 0x2e, 0xfb, 0xa3, 0x68, 0x3d, 0x46, 0x6f, 0x1c, 0x20, 0x46, 0x00, 0x2b, 0xd9, 0xd1, 0x01, 0x99, 0x00, 0x93, 0x20, 0x46, 0xff, 0xf7, 0xbb, 0xfd, 0x00, 0x28, 0xcc, 0xd0, 0xff, 0xf7, 0x9f, 0xfa, 0x00, 0x9b, 0x83, 0xf3, 0x11, 0x88, 0x40, 0x46, 0x03, 0xb0, 0xbd, 0xe8, 0xf0, 0x8f, - 0x01, 0x48, 0xff, 0xf7, 0x1d, 0xfa, 0xb6, 0xe7, 0x60, 0x32, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x48, 0xff, 0xf7, 0x1d, 0xfa, 0xb6, 0xe7, 0x80, 0x32, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x03, 0x4b, 0x04, 0x49, 0x04, 0x4a, 0x0b, 0x60, 0x03, 0xf5, 0x00, 0x63, 0x13, 0x60, 0x70, 0x47, 0xb8, 0x1e, 0x00, 0x20, 0xbc, 0x26, 0x00, 0x20, 0xb8, 0x26, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10, 0xb5, 0x20, 0x23, 0x04, 0x46, 0x83, 0xf3, 0x11, 0x88, 0xff, 0xf7, 0x69, 0xfa, 0xff, 0xf7, @@ -305,7 +305,7 @@ static const volatile uint8_t bootloader_code[] BOOTLOADER_SECTION = { 0x00, 0xed, 0x00, 0xe0, 0x30, 0xef, 0x00, 0xe0, 0x0d, 0x03, 0x00, 0x08, 0x18, 0x03, 0x00, 0x08, 0x08, 0xb5, 0x00, 0xf0, 0x2d, 0xf9, 0x08, 0x48, 0x00, 0xf0, 0xea, 0xfb, 0x00, 0xf0, 0x58, 0xf8, 0x00, 0xf0, 0xce, 0xf8, 0x00, 0xf0, 0x0c, 0xf8, 0x00, 0xf0, 0xe2, 0xf8, 0x00, 0xf0, 0x28, 0xff, - 0xbd, 0xe8, 0x08, 0x40, 0x00, 0xf0, 0xd4, 0xb8, 0xb0, 0x33, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0xbd, 0xe8, 0x08, 0x40, 0x00, 0xf0, 0xd4, 0xb8, 0xd0, 0x33, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x70, 0x47, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0xff, 0xf7, 0x35, 0xbe, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x4f, 0xf0, 0xff, 0x33, 0xff, 0xf7, 0x2b, 0xbe, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, @@ -319,17 +319,17 @@ static const volatile uint8_t bootloader_code[] BOOTLOADER_SECTION = { 0x70, 0xb5, 0x0e, 0x4b, 0x04, 0x46, 0x82, 0xb0, 0x40, 0xf8, 0x04, 0x3b, 0x01, 0x26, 0x00, 0x94, 0x15, 0x46, 0x0b, 0x46, 0x60, 0x60, 0x04, 0xf1, 0x54, 0x01, 0x04, 0xf1, 0x0c, 0x00, 0x26, 0x72, 0x10, 0x22, 0xff, 0xf7, 0x6d, 0xfd, 0x00, 0x94, 0x2b, 0x46, 0x04, 0xf1, 0x64, 0x01, 0x04, 0xf1, - 0x30, 0x00, 0x10, 0x22, 0xff, 0xf7, 0x24, 0xfe, 0x02, 0xb0, 0x70, 0xbd, 0xa0, 0x32, 0x00, 0x08, + 0x30, 0x00, 0x10, 0x22, 0xff, 0xf7, 0x24, 0xfe, 0x02, 0xb0, 0x70, 0xbd, 0xc0, 0x32, 0x00, 0x08, 0x38, 0xb5, 0x0d, 0x46, 0x04, 0x46, 0x80, 0xb1, 0x20, 0x23, 0x83, 0xf3, 0x11, 0x88, 0xff, 0xf7, 0x5f, 0xf9, 0x29, 0x46, 0x20, 0x46, 0x00, 0xf0, 0x2b, 0xfe, 0x02, 0x23, 0x23, 0x72, 0xff, 0xf7, 0x67, 0xf9, 0x00, 0x23, 0x83, 0xf3, 0x11, 0x88, 0x38, 0xbd, 0x02, 0x48, 0xff, 0xf7, 0xe8, 0xf8, - 0xea, 0xe7, 0x00, 0xbf, 0x80, 0x32, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xea, 0xe7, 0x00, 0xbf, 0xa0, 0x32, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0xb5, 0x04, 0x46, 0x0d, 0x46, 0xff, 0xf7, 0xd3, 0xf9, 0xe4, 0xb1, 0xff, 0xf7, 0xd0, 0xf9, 0x63, 0x69, 0x3b, 0xb1, 0x29, 0x46, 0x04, 0xf1, 0x0c, 0x00, 0xff, 0xf7, 0x41, 0xfd, 0x00, 0x28, 0x0b, 0xdb, 0x38, 0xbd, 0x04, 0x21, 0x60, 0x18, 0xff, 0xf7, 0x0a, 0xfd, 0x29, 0x46, 0x04, 0xf1, 0x0c, 0x00, 0xff, 0xf7, 0x35, 0xfd, 0x00, 0x28, 0xf3, 0xda, 0x20, 0x1d, 0x80, 0x21, 0xbd, 0xe8, 0x38, 0x40, 0xff, 0xf7, 0xfd, 0xbc, 0x02, 0x48, 0xff, 0xf7, 0xba, 0xf8, 0xde, 0xe7, 0x00, 0xbf, - 0x90, 0x32, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xb0, 0x32, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x56, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x01, 0x22, 0x02, 0x70, 0x43, 0x60, 0x83, 0x60, 0x0c, 0x30, 0xff, 0xf7, 0xa8, 0xbc, 0x00, 0xf0, 0xae, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -340,7 +340,7 @@ static const volatile uint8_t bootloader_code[] BOOTLOADER_SECTION = { 0x18, 0x60, 0x70, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x28, 0x38, 0xb5, 0x04, 0x46, 0x0d, 0x46, 0x02, 0xd9, 0x05, 0x48, 0xff, 0xf7, 0x68, 0xf8, 0x04, 0xf1, 0x60, 0x40, 0x00, 0xf5, 0x6d, 0x40, 0x2d, 0x01, 0xed, 0xb2, 0x05, 0x76, 0x38, 0xbd, - 0xc0, 0x32, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x32, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x4b, 0x4f, 0xf0, 0xff, 0x31, 0x1a, 0x69, 0x00, 0x22, 0x10, 0xb4, 0x19, 0x61, 0x1a, 0x61, 0x58, 0x69, 0x59, 0x61, 0x5a, 0x61, 0x18, 0x6a, 0x12, 0x4c, 0x60, 0xf0, 0x80, 0x50, 0x18, 0x62, 0x1a, 0x62, 0x58, 0x6a, 0x59, 0x62, 0x5a, 0x62, 0x19, 0x6c, 0x41, 0xf0, 0x80, 0x51, 0x19, 0x64, @@ -427,7 +427,7 @@ static const volatile uint8_t bootloader_code[] BOOTLOADER_SECTION = { 0x01, 0xe0, 0x52, 0xf8, 0x0c, 0x0c, 0x01, 0x60, 0x44, 0xf8, 0x33, 0x10, 0x01, 0x33, 0x10, 0x2b, 0x02, 0xf1, 0x0c, 0x02, 0xf5, 0xd1, 0x09, 0x49, 0x09, 0x4a, 0x5d, 0xf8, 0x04, 0x4b, 0x4f, 0xf0, 0xff, 0x33, 0x8b, 0x60, 0xcb, 0x60, 0x93, 0x60, 0xd3, 0x60, 0x70, 0x47, 0x60, 0x27, 0x00, 0x20, - 0xec, 0x32, 0x00, 0x08, 0x10, 0x60, 0x02, 0x40, 0xe0, 0x26, 0x00, 0x20, 0x00, 0x60, 0x02, 0x40, + 0x0c, 0x33, 0x00, 0x08, 0x10, 0x60, 0x02, 0x40, 0xe0, 0x26, 0x00, 0x20, 0x00, 0x60, 0x02, 0x40, 0x00, 0x64, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb5, 0x65, 0x4d, 0x65, 0x4c, 0x2f, 0x6b, 0x65, 0x49, 0x66, 0x4a, 0x66, 0x4b, 0x40, 0xf2, 0xff, 0x1e, 0x47, 0xea, 0x0e, 0x07, 0x2f, 0x63, 0x2e, 0x6d, 0x46, 0xea, 0x0e, 0x06, 0x2e, 0x65, @@ -476,7 +476,7 @@ static const volatile uint8_t bootloader_code[] BOOTLOADER_SECTION = { 0x3c, 0x02, 0xa4, 0xf1, 0x30, 0x03, 0x28, 0x46, 0x32, 0x62, 0x73, 0x62, 0xc6, 0xf8, 0x28, 0x80, 0xf7, 0x62, 0xff, 0xf7, 0x85, 0xfb, 0xa4, 0xf1, 0x60, 0x03, 0x0f, 0x4a, 0xc5, 0xf8, 0x28, 0x80, 0x0c, 0x3c, 0xef, 0x62, 0xea, 0x61, 0x2b, 0x62, 0x6c, 0x62, 0xbd, 0xe8, 0xf0, 0x81, 0x00, 0xbf, - 0x64, 0x27, 0x00, 0x20, 0xf4, 0x27, 0x00, 0x20, 0x40, 0x33, 0x00, 0x08, 0x94, 0x27, 0x00, 0x20, + 0x64, 0x27, 0x00, 0x20, 0xf4, 0x27, 0x00, 0x20, 0x60, 0x33, 0x00, 0x08, 0x94, 0x27, 0x00, 0x20, 0xc4, 0x27, 0x00, 0x20, 0x00, 0x30, 0x01, 0x40, 0x16, 0x00, 0x01, 0x06, 0x46, 0x00, 0x01, 0x06, 0x00, 0x38, 0x00, 0x40, 0x46, 0x00, 0x01, 0x00, 0x00, 0x3c, 0x00, 0x40, 0x16, 0x00, 0x01, 0x00, 0x08, 0xb5, 0xfe, 0xf7, 0xc5, 0xfc, 0x20, 0x23, 0x83, 0xf3, 0x11, 0x88, 0xfe, 0xf7, 0x90, 0xfc, @@ -530,7 +530,7 @@ static const volatile uint8_t bootloader_code[] BOOTLOADER_SECTION = { 0x13, 0x4a, 0xb2, 0xfb, 0xf1, 0xf2, 0x9a, 0x60, 0xd0, 0xe7, 0x10, 0x4a, 0x53, 0x6c, 0x43, 0xf0, 0x10, 0x03, 0x53, 0x64, 0x06, 0x21, 0x25, 0x20, 0xff, 0xf7, 0xea, 0xf9, 0xb9, 0xe7, 0x0b, 0x4a, 0x13, 0x6c, 0x43, 0xf4, 0x00, 0x33, 0x13, 0x64, 0x06, 0x21, 0x26, 0x20, 0xff, 0xf7, 0xe0, 0xf9, - 0xaf, 0xe7, 0x00, 0xbf, 0xa0, 0x33, 0x00, 0x08, 0x00, 0x10, 0x01, 0x40, 0x80, 0xde, 0x80, 0x02, + 0xaf, 0xe7, 0x00, 0xbf, 0xc0, 0x33, 0x00, 0x08, 0x00, 0x10, 0x01, 0x40, 0x80, 0xde, 0x80, 0x02, 0xf8, 0x27, 0x00, 0x20, 0x70, 0x28, 0x00, 0x20, 0xe8, 0x28, 0x00, 0x20, 0x00, 0x38, 0x02, 0x40, 0x00, 0xbd, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf7, 0x36, 0xba, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -579,21 +579,19 @@ static const volatile uint8_t bootloader_code[] BOOTLOADER_SECTION = { 0x1b, 0x69, 0x00, 0x2b, 0xbf, 0xf6, 0x7e, 0xaf, 0x4f, 0xf0, 0xff, 0x30, 0xb5, 0xe7, 0x00, 0xbf, 0x00, 0x3c, 0x02, 0x40, 0x23, 0x01, 0x67, 0x45, 0xab, 0x89, 0xef, 0xcd, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb5, 0x16, 0x4d, 0x2b, 0x68, 0x93, 0xf8, 0x79, 0x31, 0x13, 0xf0, 0x01, 0x03, 0x01, 0xd1, - 0x03, 0x60, 0xf8, 0xbd, 0x12, 0x4f, 0x13, 0x4e, 0x04, 0x46, 0x13, 0x48, 0x00, 0xf0, 0xc0, 0xfa, - 0x3b, 0x68, 0x12, 0x48, 0xd3, 0xf8, 0x90, 0x17, 0x40, 0xf2, 0x82, 0x32, 0x00, 0xf0, 0xe0, 0xf9, - 0x3b, 0x68, 0x0f, 0x48, 0xd3, 0xf8, 0x8c, 0x17, 0x40, 0xf2, 0x82, 0x32, 0x00, 0xf0, 0xd8, 0xf9, - 0x0c, 0x48, 0x00, 0xf0, 0xad, 0xfa, 0x2b, 0x68, 0x0b, 0x49, 0xd3, 0xf8, 0x44, 0x31, 0x0b, 0x60, - 0x30, 0x46, 0xfe, 0xf7, 0xc5, 0xff, 0x26, 0x60, 0xf8, 0xbd, 0x00, 0xbf, 0x10, 0x16, 0x00, 0x20, - 0x14, 0x16, 0x00, 0x20, 0xe8, 0x28, 0x00, 0x20, 0xb0, 0x34, 0x00, 0x08, 0xc8, 0x34, 0x00, 0x08, - 0xd8, 0x34, 0x00, 0x08, 0xe8, 0x34, 0x00, 0x08, 0x00, 0x16, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x60, 0xf8, 0xbd, 0x12, 0x4f, 0x13, 0x4e, 0x04, 0x46, 0x13, 0x48, 0x00, 0xf0, 0xb0, 0xfa, + 0x3b, 0x68, 0x12, 0x48, 0xd3, 0xf8, 0x90, 0x17, 0x40, 0xf2, 0x82, 0x32, 0x00, 0xf0, 0xd0, 0xf9, + 0x3b, 0x68, 0x0f, 0x48, 0xd3, 0xf8, 0x8c, 0x17, 0x40, 0xf2, 0x82, 0x32, 0x00, 0xf0, 0xc8, 0xf9, + 0x0c, 0x48, 0x00, 0xf0, 0x9d, 0xfa, 0x2b, 0x68, 0x0b, 0x49, 0xd3, 0xf8, 0x44, 0x31, 0x0b, 0x60, + 0x30, 0x46, 0xfe, 0xf7, 0xc5, 0xff, 0x26, 0x60, 0xf8, 0xbd, 0x00, 0xbf, 0x0c, 0x16, 0x00, 0x20, + 0x10, 0x16, 0x00, 0x20, 0xe8, 0x28, 0x00, 0x20, 0xd0, 0x34, 0x00, 0x08, 0xe8, 0x34, 0x00, 0x08, + 0xf8, 0x34, 0x00, 0x08, 0x08, 0x35, 0x00, 0x08, 0x00, 0x16, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x88, 0xb1, 0x03, 0x68, 0x70, 0xb5, 0x9d, 0x69, 0x4f, 0xf4, 0x7a, 0x73, 0x14, 0x46, 0xa8, 0x47, 0x84, 0x42, 0x07, 0xd0, 0x23, 0x46, 0x02, 0x46, 0x04, 0x49, 0x04, 0x48, 0xbd, 0xe8, - 0x70, 0x40, 0x00, 0xf0, 0x85, 0xba, 0x70, 0xbd, 0x70, 0x47, 0x00, 0xbf, 0x00, 0x35, 0x00, 0x08, + 0x70, 0x40, 0x00, 0xf0, 0x75, 0xba, 0x70, 0xbd, 0x70, 0x47, 0x00, 0xbf, 0x20, 0x35, 0x00, 0x08, 0xe8, 0x78, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x30, 0xb1, 0x10, 0xb4, 0x04, 0x68, 0xe4, 0x69, 0xa4, 0x46, 0x5d, 0xf8, 0x04, 0x4b, 0x60, 0x47, 0x70, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x68, 0x40, 0xb1, 0x03, 0x68, 0x10, 0xb4, 0xdc, 0x69, 0x4f, 0xf4, 0x7a, 0x73, 0xa4, 0x46, - 0x5d, 0xf8, 0x04, 0x4b, 0x60, 0x47, 0x70, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x6a, 0x49, 0x03, 0x60, 0xf0, 0xb4, 0xff, 0x25, 0x03, 0x71, 0xc3, 0x60, 0x03, 0x74, 0x83, 0x61, 0x03, 0x77, 0x43, 0x62, 0x80, 0xf8, 0x28, 0x30, 0x03, 0x63, 0x80, 0xf8, 0x34, 0x30, 0xc3, 0x63, 0x80, 0xf8, 0x40, 0x30, 0x83, 0x64, 0x80, 0xf8, 0x4c, 0x30, 0x43, 0x65, 0x80, 0xf8, @@ -621,43 +619,43 @@ static const volatile uint8_t bootloader_code[] BOOTLOADER_SECTION = { 0xc2, 0xf8, 0x2c, 0x13, 0x18, 0x32, 0xaa, 0x42, 0xf8, 0xd1, 0x0e, 0x4c, 0x0e, 0x49, 0x00, 0x22, 0x01, 0xe0, 0x54, 0xf8, 0x04, 0x1f, 0x83, 0xf8, 0xb8, 0x21, 0x01, 0x32, 0x0c, 0x2a, 0xc3, 0xf8, 0xac, 0x11, 0x03, 0xf1, 0x20, 0x03, 0xf4, 0xd1, 0xf0, 0xbc, 0x70, 0x47, 0x60, 0x29, 0x00, 0x20, - 0x68, 0x29, 0x00, 0x20, 0xc8, 0x35, 0x00, 0x08, 0xd0, 0x35, 0x00, 0x08, 0x60, 0x35, 0x00, 0x08, - 0xc0, 0x35, 0x00, 0x08, 0x90, 0x35, 0x00, 0x08, 0xc4, 0x35, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x29, 0x00, 0x20, 0xe8, 0x35, 0x00, 0x08, 0xf0, 0x35, 0x00, 0x08, 0x80, 0x35, 0x00, 0x08, + 0xe0, 0x35, 0x00, 0x08, 0xb0, 0x35, 0x00, 0x08, 0xe4, 0x35, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x15, 0x4b, 0x98, 0x42, 0x1b, 0xd0, 0x03, 0xf5, 0x80, 0x63, 0x98, 0x42, 0x19, 0xd0, 0x03, 0xf5, 0x80, 0x63, 0x98, 0x42, 0x17, 0xd0, 0x03, 0xf5, 0x80, 0x63, 0x98, 0x42, 0x15, 0xd0, 0x03, 0xf5, 0x80, 0x63, 0x98, 0x42, 0x13, 0xd0, 0x03, 0xf5, 0x40, 0x63, 0x98, 0x42, 0x11, 0xd0, 0x0b, 0x49, 0x0b, 0x4b, 0x0c, 0x4a, 0x88, 0x42, 0x0c, 0xbf, 0x18, 0x46, 0x10, 0x46, 0x70, 0x47, 0x0a, 0x48, 0x70, 0x47, 0x0a, 0x48, 0x70, 0x47, 0x0a, 0x48, 0x70, 0x47, 0x0a, 0x48, 0x70, 0x47, 0x0a, 0x48, 0x70, 0x47, 0x0a, 0x48, 0x70, 0x47, 0x00, 0xbf, 0x00, 0x00, 0x02, 0x40, 0x00, 0x14, 0x02, 0x40, - 0x48, 0x35, 0x00, 0x08, 0x4c, 0x35, 0x00, 0x08, 0x30, 0x35, 0x00, 0x08, 0x34, 0x35, 0x00, 0x08, - 0x38, 0x35, 0x00, 0x08, 0x3c, 0x35, 0x00, 0x08, 0x40, 0x35, 0x00, 0x08, 0x44, 0x35, 0x00, 0x08, + 0x68, 0x35, 0x00, 0x08, 0x6c, 0x35, 0x00, 0x08, 0x50, 0x35, 0x00, 0x08, 0x54, 0x35, 0x00, 0x08, + 0x58, 0x35, 0x00, 0x08, 0x5c, 0x35, 0x00, 0x08, 0x60, 0x35, 0x00, 0x08, 0x64, 0x35, 0x00, 0x08, 0x01, 0x48, 0xff, 0xf7, 0xd5, 0xbe, 0x00, 0xbf, 0x68, 0x29, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x30, 0xb4, 0x0f, 0x4b, 0x0f, 0x49, 0x1a, 0x68, 0x92, 0xf8, 0x79, 0x31, 0x43, 0xf0, 0x21, 0x03, 0x82, 0xf8, 0x79, 0x31, 0x0b, 0x68, 0x2a, 0x20, 0x2b, 0x21, 0x4f, 0xf4, 0x16, 0x45, 0x4f, 0xf4, 0xe1, 0x34, 0xc3, 0xf8, 0x8c, 0x07, 0xc3, 0xf8, 0x94, 0x07, 0xc3, 0xf8, 0x90, 0x17, 0xc3, 0xf8, - 0x98, 0x17, 0xc2, 0xf8, 0x44, 0x51, 0xc3, 0xf8, 0xb4, 0x48, 0x30, 0xbc, 0xff, 0xf7, 0xd8, 0xbc, - 0x10, 0x16, 0x00, 0x20, 0x14, 0x16, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x98, 0x17, 0xc2, 0xf8, 0x44, 0x51, 0xc3, 0xf8, 0xb4, 0x48, 0x30, 0xbc, 0xff, 0xf7, 0xe8, 0xbc, + 0x0c, 0x16, 0x00, 0x20, 0x10, 0x16, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x4b, 0x0c, 0x4a, 0x1b, 0x68, 0x11, 0x68, 0x93, 0xf8, 0x78, 0x21, 0x03, 0x20, 0x42, 0xf0, 0x04, 0x02, 0x83, 0xf8, 0x78, 0x21, 0xc1, 0xf8, 0x10, 0x0b, 0x93, 0xf8, 0x78, 0x21, 0x34, 0x21, - 0x42, 0xf0, 0x08, 0x02, 0xc3, 0xf8, 0x3c, 0x11, 0x83, 0xf8, 0x78, 0x21, 0xff, 0xf7, 0xc0, 0xbc, - 0x10, 0x16, 0x00, 0x20, 0x14, 0x16, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0xf0, 0x08, 0x02, 0xc3, 0xf8, 0x3c, 0x11, 0x83, 0xf8, 0x78, 0x21, 0xff, 0xf7, 0xd0, 0xbc, + 0x0c, 0x16, 0x00, 0x20, 0x10, 0x16, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x29, 0x36, 0xd0, 0xf0, 0xb5, 0x17, 0x46, 0x83, 0xb0, 0x05, 0x46, 0x0c, 0x46, 0x21, 0xd8, 0x18, 0x4b, 0x0a, 0x11, 0x01, 0xf0, 0x0f, 0x04, 0x53, 0xf8, 0x22, 0x60, 0x7e, 0xb1, 0x30, 0x46, 0xff, 0xf7, 0x5e, 0xff, 0x2a, 0x46, 0x03, 0x46, 0x13, 0x49, 0x14, 0x48, 0x00, 0x94, 0x00, 0xf0, 0xc7, 0xf8, 0x2a, 0x46, 0x21, 0x46, 0x30, 0x46, 0x00, 0xf0, 0x6a, 0xf8, 0x08, 0xb1, 0x03, 0xb0, 0xf0, 0xbd, 0x01, 0x21, 0x3a, 0x46, 0x30, 0x46, 0xa1, 0x40, 0x03, 0xb0, 0xbd, 0xe8, 0xf0, 0x40, - 0xff, 0xf7, 0x0e, 0xba, 0x0a, 0x46, 0x41, 0xf2, 0xf2, 0x70, 0x09, 0x49, 0x00, 0xf0, 0xb8, 0xf8, + 0xff, 0xf7, 0x1e, 0xba, 0x0a, 0x46, 0x41, 0xf2, 0xf2, 0x70, 0x09, 0x49, 0x00, 0xf0, 0xb8, 0xf8, 0x07, 0x49, 0x22, 0x46, 0x41, 0xf2, 0xf2, 0x70, 0x03, 0xb0, 0xbd, 0xe8, 0xf0, 0x40, 0x00, 0xf0, - 0xaf, 0xb8, 0x70, 0x47, 0x70, 0x36, 0x00, 0x08, 0x90, 0x36, 0x00, 0x08, 0xb8, 0x2d, 0x00, 0x20, - 0x50, 0x36, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x49, 0x02, 0x48, 0x00, 0xf0, 0xa4, 0xb8, 0x40, 0x36, 0x00, 0x08, 0xb8, 0x2d, 0x00, 0x20, + 0xaf, 0xb8, 0x70, 0x47, 0x90, 0x36, 0x00, 0x08, 0xb0, 0x36, 0x00, 0x08, 0xb8, 0x2d, 0x00, 0x20, + 0x70, 0x36, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x49, 0x02, 0x48, 0x00, 0xf0, 0xa4, 0xb8, 0x60, 0x36, 0x00, 0x08, 0xb8, 0x2d, 0x00, 0x20, 0x08, 0xb5, 0x18, 0x4b, 0x98, 0x42, 0x1f, 0xd0, 0x03, 0xf5, 0x80, 0x63, 0x98, 0x42, 0x1d, 0xd0, 0x03, 0xf5, 0x80, 0x63, 0x98, 0x42, 0x11, 0xd0, 0x03, 0xf5, 0x80, 0x63, 0x98, 0x42, 0x0f, 0xd0, 0x03, 0xf5, 0x80, 0x63, 0x98, 0x42, 0x0d, 0xd0, 0x03, 0xf5, 0x80, 0x63, 0x98, 0x42, 0x0f, 0xd0, 0x03, 0xf5, 0x00, 0x63, 0x98, 0x42, 0x0d, 0xd1, 0x06, 0x20, 0x08, 0xbd, 0x02, 0x20, 0x08, 0xbd, 0x03, 0x20, 0x08, 0xbd, 0x04, 0x20, 0x08, 0xbd, 0x00, 0x20, 0x08, 0xbd, 0x01, 0x20, 0x08, 0xbd, 0x05, 0x20, 0x08, 0xbd, 0x04, 0x49, 0x41, 0xf2, 0xf4, 0x70, 0x00, 0xf0, 0x69, 0xf8, 0x4f, 0xf0, - 0xff, 0x30, 0x08, 0xbd, 0x00, 0x00, 0x02, 0x40, 0xf0, 0x36, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0xff, 0x30, 0x08, 0xbd, 0x00, 0x00, 0x02, 0x40, 0x10, 0x37, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x2d, 0xe9, 0xf0, 0x41, 0x19, 0x4b, 0x1c, 0x68, 0x82, 0xb0, 0x2c, 0xb3, 0x0d, 0x46, 0x17, 0x46, 0x80, 0x46, 0xff, 0xf7, 0xbd, 0xff, 0x16, 0x4c, 0x05, 0xeb, 0x00, 0x16, 0x54, 0xf8, 0x26, 0x00, 0x88, 0xb1, 0x40, 0x46, 0xff, 0xf7, 0xd4, 0xfe, 0x54, 0xf8, 0x26, 0x30, 0x01, 0x93, 0x02, 0x46, @@ -665,103 +663,107 @@ static const volatile uint8_t bootloader_code[] BOOTLOADER_SECTION = { 0x02, 0xb0, 0xbd, 0xe8, 0xf0, 0x81, 0x0c, 0x4a, 0x44, 0xf8, 0x26, 0x70, 0x13, 0x68, 0x01, 0x33, 0x13, 0x60, 0x02, 0xb0, 0xbd, 0xe8, 0xf0, 0x81, 0x08, 0x49, 0x41, 0xf2, 0xf3, 0x70, 0x00, 0xf0, 0x2f, 0xf8, 0x20, 0x46, 0x02, 0xb0, 0xbd, 0xe8, 0xf0, 0x81, 0x00, 0xbf, 0x7c, 0x30, 0x00, 0x20, - 0xbc, 0x2e, 0x00, 0x20, 0xcc, 0x36, 0x00, 0x08, 0x80, 0x30, 0x00, 0x20, 0xb0, 0x36, 0x00, 0x08, - 0x01, 0x49, 0x02, 0x48, 0x00, 0xf0, 0x24, 0xb8, 0xa0, 0x36, 0x00, 0x08, 0x84, 0x30, 0x00, 0x20, + 0xbc, 0x2e, 0x00, 0x20, 0xec, 0x36, 0x00, 0x08, 0x80, 0x30, 0x00, 0x20, 0xd0, 0x36, 0x00, 0x08, + 0x01, 0x49, 0x02, 0x48, 0x00, 0xf0, 0x24, 0xb8, 0xc0, 0x36, 0x00, 0x08, 0x84, 0x30, 0x00, 0x20, 0x70, 0x47, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xb4, 0x04, 0xb0, 0x70, 0x47, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb4, 0x03, 0xb0, 0x70, 0x47, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xb4, 0x03, 0xb0, 0x70, 0x47, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x47, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x30, 0xb5, 0x83, 0xb0, 0x04, 0x46, 0x05, 0x22, 0x69, 0x46, 0x13, 0x48, 0xff, 0xf7, 0x78, 0xfd, - 0x05, 0x28, 0x02, 0xd0, 0x00, 0x20, 0x03, 0xb0, 0x30, 0xbd, 0x9d, 0xf8, 0x00, 0x30, 0x9d, 0xf8, - 0x01, 0x50, 0x9d, 0xf8, 0x02, 0x00, 0x9d, 0xf8, 0x03, 0x10, 0x9d, 0xf8, 0x04, 0x20, 0x6b, 0x40, - 0x43, 0x40, 0x4b, 0x40, 0x9a, 0x42, 0xed, 0xd1, 0x00, 0x9b, 0x1b, 0xba, 0x03, 0xf1, 0x78, 0x42, - 0xb2, 0xf5, 0x80, 0x4f, 0x38, 0xbf, 0x05, 0x4a, 0x4f, 0xf0, 0x01, 0x00, 0x38, 0xbf, 0x9b, 0x18, - 0x23, 0x60, 0x03, 0xb0, 0x30, 0xbd, 0x00, 0xbf, 0x8c, 0x31, 0x00, 0x20, 0x48, 0x33, 0x00, 0x18, - 0x98, 0xb5, 0x04, 0x46, 0x00, 0xaf, 0x72, 0xb6, 0xfd, 0xf7, 0x12, 0xfe, 0x0f, 0x4a, 0x60, 0x68, + 0x30, 0xb5, 0x16, 0x4b, 0x83, 0xb0, 0x04, 0x46, 0x1b, 0x68, 0x15, 0x48, 0x05, 0x22, 0x69, 0x46, + 0xff, 0xf7, 0x76, 0xfd, 0x05, 0x28, 0x02, 0xd0, 0x00, 0x20, 0x03, 0xb0, 0x30, 0xbd, 0x9d, 0xf8, + 0x00, 0x30, 0x9d, 0xf8, 0x01, 0x50, 0x9d, 0xf8, 0x02, 0x00, 0x9d, 0xf8, 0x03, 0x10, 0x9d, 0xf8, + 0x04, 0x20, 0x6b, 0x40, 0x43, 0x40, 0x4b, 0x40, 0x9a, 0x42, 0xed, 0xd1, 0x00, 0x9b, 0x1b, 0xba, + 0x03, 0xf1, 0x78, 0x42, 0xb2, 0xf5, 0x80, 0x4f, 0x38, 0xbf, 0x06, 0x4a, 0x4f, 0xf0, 0x01, 0x00, + 0x38, 0xbf, 0x9b, 0x18, 0x23, 0x60, 0x03, 0xb0, 0x30, 0xbd, 0x00, 0xbf, 0x14, 0x16, 0x00, 0x20, + 0x8c, 0x31, 0x00, 0x20, 0x48, 0x33, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x98, 0xb5, 0x04, 0x46, 0x00, 0xaf, 0x72, 0xb6, 0xfd, 0xf7, 0x1a, 0xfe, 0x0f, 0x4a, 0x60, 0x68, 0x53, 0x68, 0x23, 0xf0, 0x80, 0x53, 0x53, 0x60, 0x00, 0x22, 0x93, 0x00, 0x03, 0xf1, 0x60, 0x43, 0x03, 0xf5, 0x61, 0x43, 0x01, 0x32, 0xd3, 0xf8, 0x00, 0x12, 0xc3, 0xf8, 0x80, 0x10, 0x08, 0x2a, 0xf3, 0xd1, 0x00, 0x23, 0x83, 0xf3, 0x14, 0x88, 0x23, 0x68, 0x83, 0xf3, 0x08, 0x88, 0x80, 0x47, - 0x03, 0x48, 0xbd, 0x46, 0xbd, 0xe8, 0x98, 0x40, 0xfd, 0xf7, 0xaa, 0xbd, 0x00, 0xed, 0x00, 0xe0, - 0x00, 0x37, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x2d, 0xe9, 0xf0, 0x4f, 0x89, 0xb0, 0x08, 0xa9, 0x79, 0x23, 0xbb, 0x48, 0xdf, 0xf8, 0xfc, 0x82, - 0x01, 0xf8, 0x1b, 0x3d, 0x01, 0x22, 0x04, 0x46, 0xff, 0xf7, 0xe2, 0xfc, 0x4f, 0xf4, 0x80, 0x42, - 0x4f, 0xf0, 0x00, 0x61, 0x40, 0x46, 0xfd, 0xf7, 0x3b, 0xfc, 0xb4, 0x4d, 0xb4, 0x4f, 0x4f, 0xf0, - 0x00, 0x09, 0x2b, 0x68, 0x01, 0x22, 0x0d, 0xf1, 0x02, 0x01, 0x20, 0x46, 0xff, 0xf7, 0xf0, 0xfc, - 0x01, 0x28, 0x40, 0xd0, 0xb9, 0xf1, 0x00, 0x0f, 0x4a, 0xd0, 0x0d, 0xf1, 0x03, 0x06, 0x2b, 0x68, - 0x01, 0x22, 0x0d, 0xf1, 0x02, 0x01, 0x20, 0x46, 0xff, 0xf7, 0xe2, 0xfc, 0x01, 0x28, 0xf6, 0xd1, - 0x02, 0x46, 0x2b, 0x68, 0x31, 0x46, 0x20, 0x46, 0xff, 0xf7, 0xda, 0xfc, 0x01, 0x28, 0x18, 0xd0, - 0x08, 0xa9, 0x1f, 0x23, 0x01, 0xf8, 0x1a, 0x3d, 0x01, 0x22, 0x20, 0x46, 0xff, 0xf7, 0xb0, 0xfc, - 0x2b, 0x68, 0x01, 0x22, 0x0d, 0xf1, 0x02, 0x01, 0x20, 0x46, 0xff, 0xf7, 0xc9, 0xfc, 0x01, 0x28, - 0xdd, 0xd1, 0x2b, 0x68, 0x01, 0x22, 0x31, 0x46, 0x20, 0x46, 0xff, 0xf7, 0xc1, 0xfc, 0x01, 0x28, - 0xe6, 0xd1, 0x81, 0x46, 0x9d, 0xf8, 0x02, 0x30, 0x9d, 0xf8, 0x03, 0x20, 0xdb, 0x43, 0xdb, 0xb2, - 0x9a, 0x42, 0x08, 0xa9, 0x18, 0xd0, 0x1f, 0x23, 0x01, 0xf8, 0x19, 0x3d, 0x01, 0x22, 0x20, 0x46, - 0xff, 0xf7, 0x8e, 0xfc, 0xb5, 0xe7, 0x0d, 0xf1, 0x03, 0x06, 0x02, 0x46, 0x31, 0x46, 0x2b, 0x68, - 0x20, 0x46, 0xff, 0xf7, 0xa5, 0xfc, 0x01, 0x28, 0xe4, 0xd0, 0xb9, 0xf1, 0x00, 0x0f, 0xc7, 0xd1, - 0x00, 0x20, 0x09, 0xb0, 0xbd, 0xe8, 0xf0, 0x8f, 0x4f, 0xf0, 0x79, 0x09, 0x01, 0x22, 0x01, 0xf8, - 0x18, 0x9d, 0x20, 0x46, 0xff, 0xf7, 0x74, 0xfc, 0x9d, 0xf8, 0x02, 0x20, 0x4f, 0xf4, 0x7a, 0x73, - 0x11, 0x2a, 0x2b, 0x60, 0x6f, 0xd0, 0x08, 0xd9, 0x31, 0x2a, 0x63, 0xd0, 0x44, 0x2a, 0x78, 0xd0, - 0x21, 0x2a, 0x35, 0xd0, 0x4f, 0xf4, 0x7a, 0x73, 0xb3, 0xe7, 0x00, 0x2a, 0x3b, 0xd0, 0x02, 0x2a, - 0xf8, 0xd1, 0x78, 0x4b, 0x08, 0xa9, 0x4f, 0xf0, 0x01, 0x0a, 0x1b, 0x68, 0x01, 0xf8, 0x11, 0xad, - 0x52, 0x46, 0x20, 0x46, 0xc3, 0xf3, 0x0b, 0x0b, 0xff, 0xf7, 0x52, 0xfc, 0x08, 0xa9, 0x4f, 0xea, - 0x1b, 0x23, 0x01, 0xf8, 0x12, 0x3d, 0x52, 0x46, 0x20, 0x46, 0xff, 0xf7, 0x49, 0xfc, 0x08, 0xa9, - 0x52, 0x46, 0x01, 0xf8, 0x13, 0xbd, 0x20, 0x46, 0xff, 0xf7, 0x42, 0xfc, 0x08, 0xa9, 0x52, 0x46, - 0x01, 0xf8, 0x14, 0x9d, 0x20, 0x46, 0xff, 0xf7, 0x3b, 0xfc, 0x52, 0x46, 0x2b, 0x68, 0x0d, 0xf1, - 0x02, 0x01, 0x20, 0x46, 0xff, 0xf7, 0x54, 0xfc, 0x50, 0x45, 0x7f, 0xf4, 0x68, 0xaf, 0x88, 0xe7, - 0x07, 0xa8, 0xff, 0xf7, 0xdd, 0xfe, 0x08, 0xa9, 0x00, 0x28, 0x40, 0xf0, 0x81, 0x80, 0x1f, 0x23, - 0x01, 0xf8, 0x10, 0x3d, 0x70, 0xe7, 0x08, 0xa9, 0x06, 0x23, 0xdf, 0xf8, 0x74, 0x91, 0x01, 0xf8, - 0x17, 0x3d, 0x01, 0x22, 0x20, 0x46, 0xff, 0xf7, 0x1b, 0xfc, 0x09, 0xf1, 0x06, 0x0a, 0x31, 0x23, - 0x01, 0xe0, 0x19, 0xf8, 0x01, 0x3b, 0x8d, 0xf8, 0x0a, 0x30, 0x01, 0x22, 0x0d, 0xf1, 0x0a, 0x01, - 0x20, 0x46, 0xff, 0xf7, 0x0d, 0xfc, 0xca, 0x45, 0xf3, 0xd1, 0x08, 0xa9, 0x79, 0x23, 0x01, 0xf8, - 0x15, 0x3d, 0x51, 0xe7, 0x07, 0xa8, 0xff, 0xf7, 0xb3, 0xfe, 0x08, 0xa9, 0x30, 0xbb, 0x1f, 0x23, - 0x01, 0xf8, 0x0a, 0x3d, 0x48, 0xe7, 0x07, 0xa8, 0xff, 0xf7, 0xaa, 0xfe, 0x08, 0xa9, 0x00, 0x28, - 0x58, 0xd1, 0x1f, 0x23, 0x01, 0xf8, 0x0e, 0x3d, 0x01, 0x22, 0x20, 0x46, 0xff, 0xf7, 0xf0, 0xfb, - 0x3e, 0xe7, 0x01, 0x22, 0x3e, 0x49, 0x20, 0x46, 0xff, 0xf7, 0x0a, 0xfc, 0x01, 0x28, 0x81, 0x46, - 0x7f, 0xf4, 0x36, 0xaf, 0x02, 0x46, 0x2b, 0x68, 0x3b, 0x49, 0x20, 0x46, 0xff, 0xf7, 0x00, 0xfc, - 0x01, 0x28, 0x02, 0x46, 0x76, 0xd0, 0x4a, 0x46, 0x2b, 0x68, 0x2b, 0xe7, 0x01, 0xf8, 0x09, 0x9d, - 0x01, 0x22, 0x20, 0x46, 0xff, 0xf7, 0xd4, 0xfb, 0x2b, 0x68, 0x31, 0x49, 0x01, 0x22, 0x20, 0x46, - 0xff, 0xf7, 0xee, 0xfb, 0x01, 0x28, 0x81, 0x46, 0x7f, 0xf4, 0x1a, 0xaf, 0x97, 0xf8, 0x00, 0xa0, - 0x2d, 0x49, 0x0a, 0xf1, 0x02, 0x0b, 0x5a, 0x46, 0x20, 0x46, 0xff, 0xf7, 0xf1, 0xfb, 0x83, 0x45, - 0xe1, 0xd1, 0x5f, 0xfa, 0x8b, 0xf1, 0x01, 0x29, 0x3a, 0x78, 0x07, 0xdd, 0x4b, 0x46, 0xf8, 0x5c, - 0x01, 0x33, 0xdb, 0xb2, 0x8b, 0x42, 0x82, 0xea, 0x00, 0x02, 0xf8, 0xdb, 0x17, 0xf8, 0x0b, 0x30, - 0x93, 0x42, 0x00, 0xf0, 0xab, 0x80, 0x08, 0xa9, 0x1f, 0x23, 0x01, 0xf8, 0x08, 0x3d, 0xf3, 0xe6, - 0x20, 0x46, 0x01, 0x22, 0x01, 0xf8, 0x0f, 0x9d, 0xff, 0xf7, 0xa2, 0xfb, 0x07, 0x98, 0xff, 0xf7, - 0x7f, 0xfe, 0xed, 0xe6, 0x01, 0x22, 0x01, 0xf8, 0x0d, 0x9d, 0x20, 0x46, 0xff, 0xf7, 0x98, 0xfb, - 0x01, 0x22, 0x2b, 0x68, 0x01, 0xa9, 0x20, 0x46, 0xff, 0xf7, 0xb2, 0xfb, 0x01, 0x28, 0x02, 0x46, - 0x7f, 0xf4, 0xde, 0xae, 0x2b, 0x68, 0x31, 0x46, 0x20, 0x46, 0xff, 0xf7, 0xa9, 0xfb, 0x01, 0x28, - 0x02, 0x46, 0x7f, 0xf4, 0xd5, 0xae, 0x9d, 0xf8, 0x04, 0x30, 0x9d, 0xf8, 0x03, 0x00, 0xd9, 0x43, - 0xc9, 0xb2, 0x88, 0x42, 0x08, 0xa9, 0x62, 0xd0, 0x1f, 0x23, 0x01, 0xf8, 0x0c, 0x3d, 0x20, 0x46, - 0xff, 0xf7, 0x76, 0xfb, 0xc4, 0xe6, 0x00, 0xbf, 0x8c, 0x31, 0x00, 0x20, 0x0c, 0x16, 0x00, 0x20, - 0x48, 0x73, 0x00, 0x20, 0x00, 0x20, 0x04, 0xe0, 0x49, 0x73, 0x00, 0x20, 0x48, 0x33, 0x00, 0x20, - 0x21, 0x37, 0x00, 0x08, 0x39, 0x78, 0x7b, 0x78, 0x43, 0xea, 0x01, 0x23, 0x4f, 0xf6, 0xff, 0x71, - 0x8b, 0x42, 0x7f, 0xd0, 0x01, 0x33, 0x4f, 0xea, 0x43, 0x0a, 0x0a, 0xf1, 0x01, 0x09, 0x4a, 0x46, - 0x43, 0x49, 0x20, 0x46, 0xff, 0xf7, 0x84, 0xfb, 0x81, 0x45, 0x7f, 0xf4, 0xa1, 0xae, 0x09, 0xf1, - 0x01, 0x01, 0xc9, 0xb2, 0x01, 0x29, 0x3b, 0x78, 0x0a, 0xf1, 0x02, 0x0a, 0x07, 0xd9, 0x01, 0x22, - 0xb8, 0x5c, 0x01, 0x32, 0xd2, 0xb2, 0x8a, 0x42, 0x83, 0xea, 0x00, 0x03, 0xf8, 0xdb, 0x17, 0xf8, - 0x0a, 0x20, 0x9a, 0x42, 0x59, 0xd1, 0xb9, 0xf1, 0x01, 0x0f, 0x51, 0xdd, 0xa9, 0xf1, 0x02, 0x09, - 0x29, 0xf0, 0x01, 0x09, 0x09, 0xf1, 0x02, 0x09, 0xdf, 0xf8, 0xd0, 0xa0, 0xb9, 0x44, 0x05, 0xe0, - 0x00, 0xf0, 0xae, 0xf8, 0x0a, 0xf1, 0x02, 0x0a, 0xd1, 0x45, 0x41, 0xd0, 0x9a, 0xf8, 0x02, 0x20, - 0x9a, 0xf8, 0x03, 0x30, 0x43, 0xea, 0x02, 0x23, 0x1b, 0xb2, 0x4f, 0xf4, 0x80, 0x42, 0xff, 0x21, - 0x40, 0x46, 0x00, 0x2b, 0xec, 0xd0, 0xd8, 0xb2, 0xff, 0xf7, 0xa2, 0xf9, 0xea, 0xe7, 0x01, 0xf8, - 0x0b, 0x9d, 0x20, 0x46, 0x03, 0xf1, 0x01, 0x09, 0xff, 0xf7, 0x12, 0xfb, 0x07, 0x99, 0x41, 0x45, - 0x1c, 0xd3, 0x20, 0x4b, 0x99, 0x42, 0x19, 0xd2, 0x4a, 0x46, 0x38, 0x46, 0xfd, 0xf7, 0x68, 0xfa, - 0x4a, 0x46, 0x39, 0x46, 0x20, 0x46, 0xff, 0xf7, 0x03, 0xfb, 0x51, 0xe6, 0x07, 0x98, 0x40, 0x45, - 0x0a, 0xf1, 0x01, 0x02, 0x10, 0xd3, 0x17, 0x4b, 0x98, 0x42, 0x0d, 0xd2, 0x16, 0x49, 0xfd, 0xf7, - 0x57, 0xfa, 0x08, 0xa9, 0x79, 0x23, 0x01, 0xf8, 0x07, 0x3d, 0x3d, 0xe6, 0x08, 0x46, 0x4a, 0x46, - 0x39, 0x46, 0xff, 0xf7, 0x0d, 0xfa, 0xe3, 0xe7, 0x0f, 0x49, 0xff, 0xf7, 0x11, 0xfa, 0xf0, 0xe7, - 0x08, 0xa9, 0x79, 0x23, 0x01, 0xf8, 0x05, 0x3d, 0x2e, 0xe6, 0x08, 0xa9, 0x1f, 0x23, 0x01, 0xf8, - 0x06, 0x3d, 0x29, 0xe6, 0x06, 0x49, 0x20, 0x46, 0xff, 0xf7, 0x0a, 0xfb, 0x01, 0x28, 0x81, 0x46, - 0x7f, 0xf4, 0x26, 0xae, 0x3b, 0x78, 0x7a, 0x78, 0x4f, 0xf0, 0x02, 0x0a, 0x53, 0x40, 0x8e, 0xe7, - 0x4a, 0x73, 0x00, 0x20, 0x48, 0x73, 0x00, 0x20, 0x49, 0x73, 0x00, 0x20, 0x48, 0x73, 0x00, 0x20, + 0x03, 0x48, 0xbd, 0x46, 0xbd, 0xe8, 0x98, 0x40, 0xfd, 0xf7, 0xb2, 0xbd, 0x00, 0xed, 0x00, 0xe0, + 0x20, 0x37, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2d, 0xe9, 0xf0, 0x4f, 0x89, 0xb0, 0x08, 0xa9, 0xc6, 0x48, 0xc7, 0x4d, 0xdf, 0xf8, 0x28, 0x83, + 0xc6, 0x4f, 0x79, 0x23, 0x01, 0xf8, 0x1d, 0x3d, 0x01, 0x22, 0x64, 0x23, 0x04, 0x46, 0x2b, 0x60, + 0xff, 0xf7, 0xe6, 0xfc, 0x4f, 0xf4, 0x80, 0x42, 0x4f, 0xf0, 0x00, 0x61, 0x40, 0x46, 0xfd, 0xf7, + 0x3f, 0xfc, 0x4f, 0xf0, 0x00, 0x09, 0x01, 0x22, 0x2b, 0x68, 0x0d, 0xeb, 0x02, 0x01, 0x20, 0x46, + 0xff, 0xf7, 0xf6, 0xfc, 0x01, 0x28, 0x40, 0xd0, 0xb9, 0xf1, 0x00, 0x0f, 0x4a, 0xd0, 0x0d, 0xf1, + 0x02, 0x06, 0x01, 0x22, 0x2b, 0x68, 0x0d, 0xeb, 0x02, 0x01, 0x20, 0x46, 0xff, 0xf7, 0xe8, 0xfc, + 0x01, 0x28, 0xf6, 0xd1, 0x02, 0x46, 0x2b, 0x68, 0x31, 0x46, 0x20, 0x46, 0xff, 0xf7, 0xe0, 0xfc, + 0x01, 0x28, 0x18, 0xd0, 0x08, 0xa9, 0x1f, 0x23, 0x01, 0xf8, 0x1c, 0x3d, 0x01, 0x22, 0x20, 0x46, + 0xff, 0xf7, 0xb6, 0xfc, 0x2b, 0x68, 0x01, 0x22, 0x0d, 0xeb, 0x02, 0x01, 0x20, 0x46, 0xff, 0xf7, + 0xcf, 0xfc, 0x01, 0x28, 0xdd, 0xd1, 0x2b, 0x68, 0x01, 0x22, 0x31, 0x46, 0x20, 0x46, 0xff, 0xf7, + 0xc7, 0xfc, 0x01, 0x28, 0xe6, 0xd1, 0x81, 0x46, 0x9d, 0xf8, 0x01, 0x30, 0x9d, 0xf8, 0x02, 0x20, + 0xdb, 0x43, 0xdb, 0xb2, 0x9a, 0x42, 0x08, 0xa9, 0x18, 0xd0, 0x1f, 0x23, 0x01, 0xf8, 0x1b, 0x3d, + 0x01, 0x22, 0x20, 0x46, 0xff, 0xf7, 0x94, 0xfc, 0xb5, 0xe7, 0x0d, 0xf1, 0x02, 0x06, 0x02, 0x46, + 0x31, 0x46, 0x2b, 0x68, 0x20, 0x46, 0xff, 0xf7, 0xab, 0xfc, 0x01, 0x28, 0xe4, 0xd0, 0xb9, 0xf1, + 0x00, 0x0f, 0xc7, 0xd1, 0x00, 0x20, 0x09, 0xb0, 0xbd, 0xe8, 0xf0, 0x8f, 0x4f, 0xf0, 0x79, 0x09, + 0x01, 0x22, 0x01, 0xf8, 0x1a, 0x9d, 0x20, 0x46, 0xff, 0xf7, 0x7a, 0xfc, 0x9d, 0xf8, 0x01, 0x20, + 0x4f, 0xf4, 0x7a, 0x73, 0x11, 0x2a, 0x2b, 0x60, 0x7a, 0xd0, 0x09, 0xd9, 0x31, 0x2a, 0x6a, 0xd0, + 0x44, 0x2a, 0x00, 0xf0, 0x83, 0x80, 0x21, 0x2a, 0x35, 0xd0, 0x4f, 0xf4, 0x7a, 0x73, 0xb2, 0xe7, + 0x00, 0x2a, 0x41, 0xd0, 0x02, 0x2a, 0xf8, 0xd1, 0x81, 0x4b, 0x08, 0xa9, 0x4f, 0xf0, 0x01, 0x0a, + 0x1b, 0x68, 0x01, 0xf8, 0x16, 0xad, 0x52, 0x46, 0x20, 0x46, 0xc3, 0xf3, 0x0b, 0x0b, 0xff, 0xf7, + 0x57, 0xfc, 0x08, 0xa9, 0x4f, 0xea, 0x1b, 0x23, 0x01, 0xf8, 0x15, 0x3d, 0x52, 0x46, 0x20, 0x46, + 0xff, 0xf7, 0x4e, 0xfc, 0x08, 0xa9, 0x52, 0x46, 0x01, 0xf8, 0x14, 0xbd, 0x20, 0x46, 0xff, 0xf7, + 0x47, 0xfc, 0x08, 0xa9, 0x52, 0x46, 0x01, 0xf8, 0x13, 0x9d, 0x20, 0x46, 0xff, 0xf7, 0x40, 0xfc, + 0x52, 0x46, 0x2b, 0x68, 0x0d, 0xeb, 0x0a, 0x01, 0x20, 0x46, 0xff, 0xf7, 0x59, 0xfc, 0x50, 0x45, + 0x7f, 0xf4, 0x67, 0xaf, 0x87, 0xe7, 0x07, 0xa8, 0xff, 0xf7, 0xd2, 0xfe, 0x08, 0xa9, 0x00, 0x28, + 0x00, 0xf0, 0xc3, 0x80, 0x20, 0x46, 0x01, 0x22, 0x01, 0xf8, 0x12, 0x9d, 0xff, 0xf7, 0x28, 0xfc, + 0x07, 0x98, 0xff, 0xf7, 0xfd, 0xfe, 0x6d, 0xe7, 0x08, 0xa9, 0x06, 0x23, 0xdf, 0xf8, 0x8c, 0x91, + 0x01, 0xf8, 0x18, 0x3d, 0x01, 0x22, 0x20, 0x46, 0xff, 0xf7, 0x1a, 0xfc, 0x09, 0xf1, 0x06, 0x0a, + 0x31, 0x23, 0x01, 0xe0, 0x19, 0xf8, 0x01, 0x3b, 0x8d, 0xf8, 0x09, 0x30, 0x01, 0x22, 0x0d, 0xf1, + 0x09, 0x01, 0x20, 0x46, 0xff, 0xf7, 0x0c, 0xfc, 0xd1, 0x45, 0xf3, 0xd1, 0x08, 0xa9, 0x79, 0x23, + 0x01, 0xf8, 0x19, 0x3d, 0x4a, 0xe7, 0x07, 0xa8, 0xff, 0xf7, 0xa2, 0xfe, 0x08, 0xa9, 0x90, 0xbb, + 0x1f, 0x23, 0x01, 0xf8, 0x07, 0x3d, 0x01, 0x22, 0x20, 0x46, 0xff, 0xf7, 0xf9, 0xfb, 0x41, 0xe7, + 0x07, 0xa8, 0xff, 0xf7, 0x95, 0xfe, 0x08, 0xa9, 0x00, 0x28, 0x5c, 0xd1, 0x1f, 0x23, 0x01, 0xf8, + 0x0b, 0x3d, 0x01, 0x22, 0x20, 0x46, 0xff, 0xf7, 0xeb, 0xfb, 0x33, 0xe7, 0x01, 0x22, 0x43, 0x49, + 0x20, 0x46, 0xff, 0xf7, 0x05, 0xfc, 0x01, 0x28, 0x81, 0x46, 0x7f, 0xf4, 0x2b, 0xaf, 0x02, 0x46, + 0x2b, 0x68, 0x40, 0x49, 0x20, 0x46, 0xff, 0xf7, 0xfb, 0xfb, 0x01, 0x28, 0x02, 0x46, 0x7f, 0xd0, + 0x4a, 0x46, 0x2b, 0x68, 0x0d, 0xf1, 0x01, 0x01, 0x20, 0x46, 0xff, 0xf7, 0xf1, 0xfb, 0x01, 0x28, + 0x7f, 0xf4, 0xff, 0xae, 0x1f, 0xe7, 0x01, 0x22, 0x01, 0xf8, 0x08, 0x9d, 0x20, 0x46, 0xff, 0xf7, + 0xc7, 0xfb, 0x2b, 0x68, 0x31, 0x49, 0x01, 0x22, 0x20, 0x46, 0xff, 0xf7, 0xe1, 0xfb, 0x01, 0x28, + 0x83, 0x46, 0x7f, 0xf4, 0x07, 0xaf, 0x97, 0xf8, 0x00, 0x90, 0x2b, 0x68, 0x2d, 0x49, 0x09, 0xf1, + 0x02, 0x0a, 0x52, 0x46, 0x20, 0x46, 0xff, 0xf7, 0xd3, 0xfb, 0x82, 0x45, 0x7f, 0xf4, 0xfa, 0xae, + 0x5f, 0xfa, 0x8a, 0xf1, 0x01, 0x29, 0x3a, 0x78, 0x07, 0xdd, 0x5b, 0x46, 0xf8, 0x5c, 0x01, 0x33, + 0xdb, 0xb2, 0x99, 0x42, 0x82, 0xea, 0x00, 0x02, 0xf8, 0xdc, 0x17, 0xf8, 0x0a, 0x30, 0x93, 0x42, + 0x00, 0xf0, 0xa8, 0x80, 0x08, 0xa9, 0x1f, 0x23, 0x01, 0xf8, 0x09, 0x3d, 0x01, 0x22, 0x20, 0x46, + 0xff, 0xf7, 0x96, 0xfb, 0xde, 0xe6, 0x01, 0x22, 0x01, 0xf8, 0x0c, 0x9d, 0x20, 0x46, 0xff, 0xf7, + 0x8f, 0xfb, 0x01, 0x22, 0x2b, 0x68, 0x04, 0xa9, 0x20, 0x46, 0xff, 0xf7, 0xa9, 0xfb, 0x01, 0x28, + 0x02, 0x46, 0x7f, 0xf4, 0xcf, 0xae, 0x2b, 0x68, 0x0d, 0xf1, 0x11, 0x01, 0x20, 0x46, 0xff, 0xf7, + 0x9f, 0xfb, 0x01, 0x28, 0x02, 0x46, 0x7f, 0xf4, 0xc5, 0xae, 0x9d, 0xf8, 0x10, 0x30, 0x9d, 0xf8, + 0x11, 0x00, 0xd9, 0x43, 0xc9, 0xb2, 0x88, 0x42, 0x08, 0xa9, 0x67, 0xd0, 0x1f, 0x23, 0x01, 0xf8, + 0x0d, 0x3d, 0x20, 0x46, 0xff, 0xf7, 0x6c, 0xfb, 0xb4, 0xe6, 0x1f, 0x23, 0x01, 0xf8, 0x11, 0x3d, + 0xac, 0xe6, 0x00, 0xbf, 0x8c, 0x31, 0x00, 0x20, 0x14, 0x16, 0x00, 0x20, 0x48, 0x73, 0x00, 0x20, + 0x00, 0x20, 0x04, 0xe0, 0x49, 0x73, 0x00, 0x20, 0x48, 0x33, 0x00, 0x20, 0x41, 0x37, 0x00, 0x08, + 0x39, 0x78, 0x7b, 0x78, 0x43, 0xea, 0x01, 0x23, 0x4f, 0xf6, 0xff, 0x71, 0x8b, 0x42, 0x7d, 0xd0, + 0x01, 0x33, 0x4f, 0xea, 0x43, 0x0a, 0x0a, 0xf1, 0x01, 0x09, 0x4a, 0x46, 0x2b, 0x68, 0x43, 0x49, + 0x20, 0x46, 0xff, 0xf7, 0x65, 0xfb, 0x81, 0x45, 0x7f, 0xf4, 0x8c, 0xae, 0x09, 0xf1, 0x01, 0x01, + 0xc9, 0xb2, 0x01, 0x29, 0x3b, 0x78, 0x0a, 0xf1, 0x02, 0x0a, 0x07, 0xd9, 0x01, 0x22, 0xb8, 0x5c, + 0x01, 0x32, 0xd2, 0xb2, 0x8a, 0x42, 0x83, 0xea, 0x00, 0x03, 0xf8, 0xdb, 0x17, 0xf8, 0x0a, 0x20, + 0x9a, 0x42, 0x56, 0xd1, 0xb9, 0xf1, 0x01, 0x0f, 0x4e, 0xdd, 0xa9, 0xf1, 0x02, 0x09, 0x29, 0xf0, + 0x01, 0x09, 0x09, 0xf1, 0x02, 0x09, 0xdf, 0xf8, 0xd0, 0xa0, 0xb9, 0x44, 0x05, 0xe0, 0xff, 0xf7, + 0xa7, 0xf9, 0x0a, 0xf1, 0x02, 0x0a, 0xd1, 0x45, 0x3e, 0xd0, 0x9a, 0xf8, 0x02, 0x20, 0x9a, 0xf8, + 0x03, 0x30, 0x43, 0xea, 0x02, 0x23, 0x1b, 0xb2, 0xd8, 0xb2, 0x00, 0x2b, 0xef, 0xd1, 0x4f, 0xf4, + 0x80, 0x42, 0xff, 0x21, 0x40, 0x46, 0x00, 0xf0, 0x9b, 0xf8, 0xea, 0xe7, 0x01, 0xf8, 0x0e, 0x9d, + 0x20, 0x46, 0x03, 0xf1, 0x01, 0x09, 0xff, 0xf7, 0x03, 0xfb, 0x07, 0x99, 0x41, 0x45, 0x19, 0xd3, + 0x1f, 0x4b, 0x99, 0x42, 0x16, 0xd2, 0x4a, 0x46, 0x38, 0x46, 0xfd, 0xf7, 0x59, 0xfa, 0x4a, 0x46, + 0x39, 0x46, 0x3c, 0xe6, 0x07, 0x98, 0x40, 0x45, 0x09, 0xf1, 0x01, 0x02, 0x10, 0xd3, 0x18, 0x4b, + 0x98, 0x42, 0x0d, 0xd2, 0x17, 0x49, 0xfd, 0xf7, 0x4b, 0xfa, 0x08, 0xa9, 0x79, 0x23, 0x01, 0xf8, + 0x0a, 0x3d, 0x2b, 0xe6, 0x08, 0x46, 0x4a, 0x46, 0x39, 0x46, 0xff, 0xf7, 0x01, 0xfa, 0xe6, 0xe7, + 0x10, 0x49, 0xff, 0xf7, 0x05, 0xfa, 0xf0, 0xe7, 0x08, 0xa9, 0x79, 0x23, 0x01, 0xf8, 0x06, 0x3d, + 0x1c, 0xe6, 0x08, 0xa9, 0x1f, 0x23, 0x01, 0xf8, 0x05, 0x3d, 0x17, 0xe6, 0x2b, 0x68, 0x07, 0x49, + 0x20, 0x46, 0xff, 0xf7, 0xed, 0xfa, 0x01, 0x28, 0x81, 0x46, 0x7f, 0xf4, 0x13, 0xae, 0x3b, 0x78, + 0x7a, 0x78, 0x4f, 0xf0, 0x02, 0x0a, 0x53, 0x40, 0x90, 0xe7, 0x00, 0xbf, 0x4a, 0x73, 0x00, 0x20, + 0x48, 0x73, 0x00, 0x20, 0x49, 0x73, 0x00, 0x20, 0x48, 0x73, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x70, 0x47, 0x8c, 0x31, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0xb5, 0x05, 0x4b, 0x05, 0x4a, 0x9b, 0x69, 0x9a, 0x61, 0xff, 0xf7, 0xc9, 0xfd, 0x00, 0x20, - 0xbd, 0xe8, 0x08, 0x40, 0xfd, 0xf7, 0xbc, 0xbe, 0x18, 0x16, 0x00, 0x20, 0x40, 0x37, 0x00, 0x08, - 0x10, 0xb5, 0x82, 0xb0, 0xfe, 0xf7, 0xd4, 0xf9, 0x00, 0x24, 0xfd, 0xf7, 0x01, 0xfb, 0xff, 0xf7, - 0x17, 0xfc, 0xff, 0xf7, 0x3d, 0xfc, 0xff, 0xf7, 0xdb, 0xff, 0xff, 0xf7, 0x61, 0xfa, 0x08, 0x4b, - 0x00, 0x94, 0x40, 0x22, 0x4f, 0xf4, 0x93, 0x61, 0x06, 0x48, 0xfd, 0xf7, 0x59, 0xfe, 0xfd, 0xf7, - 0xaf, 0xfe, 0x05, 0x48, 0xff, 0xf7, 0x74, 0xfd, 0x20, 0x46, 0x02, 0xb0, 0x10, 0xbd, 0x00, 0xbf, - 0xe1, 0x2e, 0x00, 0x08, 0x50, 0x74, 0x00, 0x20, 0x00, 0x80, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x49, 0x02, 0x48, 0xff, 0xf7, 0x2c, 0xbd, 0x30, 0x37, 0x00, 0x08, 0xe8, 0x78, 0x00, 0x20, + 0x08, 0xb5, 0x05, 0x4b, 0x05, 0x4a, 0x9b, 0x69, 0x9a, 0x61, 0xff, 0xf7, 0xb1, 0xfd, 0x00, 0x20, + 0xbd, 0xe8, 0x08, 0x40, 0xfd, 0xf7, 0xac, 0xbe, 0x18, 0x16, 0x00, 0x20, 0x60, 0x37, 0x00, 0x08, + 0x10, 0xb5, 0x82, 0xb0, 0xfe, 0xf7, 0xc4, 0xf9, 0x00, 0x24, 0xfd, 0xf7, 0xf1, 0xfa, 0xff, 0xf7, + 0xf7, 0xfb, 0xff, 0xf7, 0x1d, 0xfc, 0xff, 0xf7, 0xdb, 0xff, 0xff, 0xf7, 0x51, 0xfa, 0x08, 0x4b, + 0x00, 0x94, 0x40, 0x22, 0x4f, 0xf4, 0x93, 0x61, 0x06, 0x48, 0xfd, 0xf7, 0x49, 0xfe, 0xfd, 0xf7, + 0x9f, 0xfe, 0x05, 0x48, 0xff, 0xf7, 0x5c, 0xfd, 0x20, 0x46, 0x02, 0xb0, 0x10, 0xbd, 0x00, 0xbf, + 0x01, 0x2f, 0x00, 0x08, 0x50, 0x74, 0x00, 0x20, 0x00, 0x80, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x49, 0x02, 0x48, 0xff, 0xf7, 0x0c, 0xbd, 0x50, 0x37, 0x00, 0x08, 0xe8, 0x78, 0x00, 0x20, 0x70, 0xb4, 0x86, 0x07, 0x46, 0xd0, 0x54, 0x1e, 0x00, 0x2a, 0x41, 0xd0, 0xca, 0xb2, 0x03, 0x46, 0x02, 0xe0, 0x14, 0xf1, 0xff, 0x34, 0x3b, 0xd3, 0x03, 0xf8, 0x01, 0x2b, 0x9d, 0x07, 0xf8, 0xd1, 0x03, 0x2c, 0x2e, 0xd9, 0xcd, 0xb2, 0x45, 0xea, 0x05, 0x25, 0x0f, 0x2c, 0x45, 0xea, 0x05, 0x45, @@ -772,14 +774,14 @@ static const volatile uint8_t bootloader_code[] BOOTLOADER_SECTION = { 0x04, 0x5b, 0xfa, 0xd8, 0x22, 0x1f, 0x22, 0xf0, 0x03, 0x02, 0x04, 0x32, 0x13, 0x44, 0x04, 0xf0, 0x03, 0x04, 0x2c, 0xb1, 0xc9, 0xb2, 0x1c, 0x44, 0x03, 0xf8, 0x01, 0x1b, 0x9c, 0x42, 0xfb, 0xd1, 0x70, 0xbc, 0x70, 0x47, 0x14, 0x46, 0x03, 0x46, 0xc2, 0xe7, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, - 0x70, 0x37, 0x00, 0x08, 0xec, 0x79, 0x00, 0x20, 0xec, 0x79, 0x00, 0x20, 0xec, 0x79, 0x00, 0x20, - 0x70, 0x37, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, - 0x70, 0x37, 0x00, 0x08, 0x00, 0xc0, 0x01, 0x20, 0x00, 0xc0, 0x01, 0x20, 0x00, 0xc0, 0x01, 0x20, - 0x70, 0x37, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x70, 0x37, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, - 0x70, 0x37, 0x00, 0x08, 0x00, 0x40, 0x02, 0x40, 0x00, 0x40, 0x02, 0x40, 0x00, 0x40, 0x02, 0x40, - 0x70, 0x37, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x70, 0x37, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x90, 0x37, 0x00, 0x08, 0xec, 0x79, 0x00, 0x20, 0xec, 0x79, 0x00, 0x20, 0xec, 0x79, 0x00, 0x20, + 0x90, 0x37, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, + 0x90, 0x37, 0x00, 0x08, 0x00, 0xc0, 0x01, 0x20, 0x00, 0xc0, 0x01, 0x20, 0x00, 0xc0, 0x01, 0x20, + 0x90, 0x37, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x90, 0x37, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, + 0x90, 0x37, 0x00, 0x08, 0x00, 0x40, 0x02, 0x40, 0x00, 0x40, 0x02, 0x40, 0x00, 0x40, 0x02, 0x40, + 0x90, 0x37, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x90, 0x37, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x2e, 0x2f, 0x43, 0x68, 0x69, 0x62, 0x69, 0x4f, 0x53, 0x33, 0x2f, 0x6f, 0x73, 0x2f, 0x72, 0x74, 0x2f, 0x73, 0x72, 0x63, 0x2f, 0x63, 0x68, 0x73, 0x79, 0x73, 0x2e, 0x63, 0x00, 0x00, 0x00, 0x69, 0x64, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -858,12 +860,12 @@ static const volatile uint8_t bootloader_code[] BOOTLOADER_SECTION = { 0x50, 0x41, 0x00, 0x00, 0x50, 0x42, 0x00, 0x00, 0x50, 0x43, 0x00, 0x00, 0x50, 0x44, 0x00, 0x00, 0x50, 0x45, 0x00, 0x00, 0x50, 0x48, 0x00, 0x00, 0x50, 0x46, 0x00, 0x00, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc0, 0x35, 0x00, 0x08, 0x0c, 0x36, 0x00, 0x08, 0x10, 0x36, 0x00, 0x08, 0x14, 0x36, 0x00, 0x08, - 0x18, 0x36, 0x00, 0x08, 0x1c, 0x36, 0x00, 0x08, 0x20, 0x36, 0x00, 0x08, 0x24, 0x36, 0x00, 0x08, - 0x28, 0x36, 0x00, 0x08, 0x2c, 0x36, 0x00, 0x08, 0x30, 0x36, 0x00, 0x08, 0x34, 0x36, 0x00, 0x08, - 0xc4, 0x35, 0x00, 0x08, 0xe0, 0x35, 0x00, 0x08, 0xe4, 0x35, 0x00, 0x08, 0xe8, 0x35, 0x00, 0x08, - 0xec, 0x35, 0x00, 0x08, 0xf0, 0x35, 0x00, 0x08, 0xf4, 0x35, 0x00, 0x08, 0xf8, 0x35, 0x00, 0x08, - 0xfc, 0x35, 0x00, 0x08, 0x00, 0x36, 0x00, 0x08, 0x04, 0x36, 0x00, 0x08, 0x08, 0x36, 0x00, 0x08, + 0xe0, 0x35, 0x00, 0x08, 0x2c, 0x36, 0x00, 0x08, 0x30, 0x36, 0x00, 0x08, 0x34, 0x36, 0x00, 0x08, + 0x38, 0x36, 0x00, 0x08, 0x3c, 0x36, 0x00, 0x08, 0x40, 0x36, 0x00, 0x08, 0x44, 0x36, 0x00, 0x08, + 0x48, 0x36, 0x00, 0x08, 0x4c, 0x36, 0x00, 0x08, 0x50, 0x36, 0x00, 0x08, 0x54, 0x36, 0x00, 0x08, + 0xe4, 0x35, 0x00, 0x08, 0x00, 0x36, 0x00, 0x08, 0x04, 0x36, 0x00, 0x08, 0x08, 0x36, 0x00, 0x08, + 0x0c, 0x36, 0x00, 0x08, 0x10, 0x36, 0x00, 0x08, 0x14, 0x36, 0x00, 0x08, 0x18, 0x36, 0x00, 0x08, + 0x1c, 0x36, 0x00, 0x08, 0x20, 0x36, 0x00, 0x08, 0x24, 0x36, 0x00, 0x08, 0x28, 0x36, 0x00, 0x08, 0x63, 0x31, 0x00, 0x00, 0x69, 0x31, 0x00, 0x00, 0x64, 0x69, 0x7a, 0x7a, 0x79, 0x00, 0x00, 0x00, 0x74, 0x61, 0x63, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x32, 0x00, 0x00, 0x69, 0x33, 0x00, 0x00, 0x69, 0x34, 0x00, 0x00, 0x69, 0x35, 0x00, 0x00, @@ -890,7 +892,7 @@ static const volatile uint8_t bootloader_code[] BOOTLOADER_SECTION = { 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x6f, 0x6f, 0x74, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x53, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x78, 0x02, 0x00, 0x10, 0x08, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x78, 0x02, 0x00, 0x10, 0x08, 0x00, 0x00, 0x10, 0x64, 0x00, 0x00, 0x00, }; #endif /* BOOTLOADER_GENERATED_HXX_ */ diff --git a/firmware/bootloader/bootloader_storage.c b/firmware/bootloader/bootloader_storage.c index bab371bb71..a19ebdd251 100644 --- a/firmware/bootloader/bootloader_storage.c +++ b/firmware/bootloader/bootloader_storage.c @@ -14,6 +14,9 @@ int initBootloader(void) { // just make sure we use 'bootloader_code' array + // We're forcing the array to be included into the linked binary. + // The first 4 bytes contain a 32-bit address in RAM, which always starts from 0x20000000 for STM32. + // So the bootloader_code[3] is the most significant byte of the address which equals to 0x20. return (bootloader_code[3] == 0x20) ? 0 : 1; /* todo: should always be 0x20? */ } diff --git a/firmware/bootloader/src/Makefile b/firmware/bootloader/src/Makefile index 915a2bcb91..1b30764e98 100644 --- a/firmware/bootloader/src/Makefile +++ b/firmware/bootloader/src/Makefile @@ -181,6 +181,7 @@ CPPSRC = $(CHCPPSRC) \ $(PROJECT_DIR)/console/binary/tunerstudio_io.cpp \ $(PROJECT_DIR)/controllers/system/efiGpio.cpp \ $(PROJECT_DIR)/controllers/algo/engine_configuration.cpp \ + $(PROJECT_DIR)/controllers/persistent_store.cpp \ $(PROJECT_DIR)/hw_layer/io_pins.cpp \ $(PROJECT_DIR)/hw_layer/pin_repository.cpp \ src/rusefi_stubs.cpp \ diff --git a/firmware/bootloader/src/dfu.cpp b/firmware/bootloader/src/dfu.cpp index 153610cf04..ddeb69f7cf 100644 --- a/firmware/bootloader/src/dfu.cpp +++ b/firmware/bootloader/src/dfu.cpp @@ -48,7 +48,8 @@ static bool isInVirtualPageBuffer(uint32_t addr) { return addr >= (uint32_t)bootloaderVirtualPageBuffer && addr < (uint32_t)bootloaderVirtualPageBuffer + sizeof(bootloaderVirtualPageBuffer); } -// read 32-bit address and 8-bit checksum +// Read 32-bit address and 8-bit checksum. +// Returns true if all 5 bytes are received and checksum is correct, and false otherwise. static bool readAddress(uint32_t *addr) { uint8_t buf[5]; // 4 bytes+checksum if (sr5ReadDataTimeout(&blTsChannel, buf, 5, sr5Timeout) != 5) @@ -74,6 +75,20 @@ static uint16_t bufToInt16(uint8_t *buf) { return (buf[0] << 8) | buf[1]; } +static void prepareInterruptsForJump(void) { +#ifdef STM32F4 + // interrupt control + SCB->ICSR &= ~SCB_ICSR_PENDSVSET_Msk; + // set interrupt vectors + for(int i = 0; i < 8; i++) + NVIC->ICER[i] = NVIC->IABR[i]; + __set_CONTROL(0); +#else +// todo: add support for other MCUs +#error "Unsupported MCU configuration!" +#endif +} + // some weird STM32 magic... void dfuJumpToApp(uint32_t addr) { typedef void (*pFunction)(void); @@ -84,12 +99,7 @@ void dfuJumpToApp(uint32_t addr) { // get jump addr uint32_t jumpAddress = *((uint32_t *)(addr + 4)); pFunction jump = (pFunction) jumpAddress; - // interrupt control - SCB->ICSR &= ~SCB_ICSR_PENDSVSET_Msk; - // set interrupt vectors - for(int i = 0; i < 8; i++) - NVIC->ICER[i] = NVIC->IABR[i]; - __set_CONTROL(0); + prepareInterruptsForJump(); // set stack pointer __set_MSP(*(uint32_t *)addr); @@ -100,10 +110,139 @@ void dfuJumpToApp(uint32_t addr) { chSysHalt("dfuJumpToApp FAIL"); } +static void dfuHandleGetList(void) { + static const uint8_t cmdsInfo[] = { DFU_VERSION_NUMBER, DFU_GET_LIST_CMD, DFU_DEVICE_ID_CMD, DFU_READ_CMD, DFU_GO_CMD, + DFU_WRITE_CMD, DFU_ERASE_CMD }; + size_t numBytes = sizeof(cmdsInfo); + sendByte(numBytes - 1); // number of commands + for (size_t i = 0; i < numBytes; i++) + sendByte(cmdsInfo[i]); + sendByte(DFU_ACK_BYTE); +} + +static void dfuHandleDeviceId(void) { + uint32_t mcuRev = getMcuRevision(); + sendByte(0x01); // the number of bytes to be send - 1 + // send 12 bit MCU revision + sendByte((uint8_t)((mcuRev >> 8) & 0xf)); + sendByte((uint8_t)(mcuRev & 0xff)); + sendByte(DFU_ACK_BYTE); +} + +static void dfuHandleGo(void) { + uint32_t addr; + + if (!readAddress(&addr)) { + sendByte(DFU_NACK_BYTE); + return; + } + // todo: check if the address is valid + sendByte(DFU_ACK_BYTE); + dfuJumpToApp(addr); +} + +static void dfuHandleRead(void) { + uint32_t addr; + + if (!readAddress(&addr)) { + sendByte(DFU_NACK_BYTE); + return; + } + sendByte(DFU_ACK_BYTE); + uint8_t byte, complement; + if (!getByte(&byte)) + return; + if (!getByte(&complement)) + return; + // check if we have a correct byte received + if (complement != complementByte(byte)) { + sendByte(DFU_NACK_BYTE); + return; + } + int numBytes = (int)byte + 1; + sendByte(DFU_ACK_BYTE); + + // read flash or virtual RAM buffer (don't transmit directly from flash) + if (isInVirtualPageBuffer(addr)) + memcpy(buffer, (uint8_t *)addr, numBytes); + else + flashRead(addr, (char *)buffer, numBytes); + + // transmit data + sr5WriteData(&blTsChannel, (uint8_t *)buffer, numBytes); +} + +static void dfuHandleWrite(void) { + uint32_t addr; + + if (!readAddress(&addr)) { + sendByte(DFU_NACK_BYTE); + return; + } + sendByte(DFU_ACK_BYTE); + if (!getByte(buffer)) + return; + + int numBytes = buffer[0] + 1; + int numBytesAndChecksum = numBytes + 1; // +1 byte of checkSum + // receive data + if (sr5ReadDataTimeout(&blTsChannel, buffer + 1, numBytesAndChecksum, sr5Timeout) != numBytesAndChecksum) + return; + // don't write corrupted data! + if (dfuCalcChecksum(buffer, numBytesAndChecksum) != buffer[numBytesAndChecksum]) { + sendByte(DFU_NACK_BYTE); + return; + } + + // now write to flash (or to the virtual RAM buffer) + if (isInVirtualPageBuffer(addr)) + memcpy((uint8_t *)addr, (buffer + 1), numBytes); + else + flashWrite(addr, (const char *)(buffer + 1), numBytes); + + // we're done! + sendByte(DFU_ACK_BYTE); +} + +static void dfuHandleErase(void) { + int numSectors; + if (!getByte(buffer)) + return; + if (!getByte(buffer + 1)) + return; + numSectors = bufToInt16(buffer); + int numSectorData; + if (numSectors == 0xffff) // erase all chip + numSectorData = 1; + else + numSectorData = (numSectors + 1) * 2 + 1; + uint8_t *sectorList = buffer + 2; + // read sector data & checksum + if (sr5ReadDataTimeout(&blTsChannel, sectorList, numSectorData, sr5Timeout) != numSectorData) + return; + // verify checksum + if (dfuCalcChecksum(buffer, 2 + numSectorData - 1) != buffer[2 + numSectorData - 1]) { + sendByte(DFU_NACK_BYTE); + return; + } + // Erase the chosen sectors, sector by sector + for (int i = 0; i < numSectorData - 1; i += 2) { + int sectorIdx = bufToInt16(sectorList + i); + if (sectorIdx < BOOTLOADER_NUM_SECTORS) { // skip first sectors where our bootloader is + // imitate flash erase by writing '0xff' + memset(bootloaderVirtualPageBuffer, 0xff, BOOTLOADER_SIZE); + continue; + } + // erase sector + flashSectorErase(sectorIdx); + } + + sendByte(DFU_ACK_BYTE); +} + bool dfuStartLoop(void) { bool wasCommand = false; uint8_t command, complement; - uint32_t addr; sr5Timeout = DFU_SR5_TIMEOUT_FIRST; @@ -147,133 +286,24 @@ bool dfuStartLoop(void) { switch (command) { case DFU_UART_CHECK: break; - case DFU_GET_LIST_CMD: { - static const uint8_t cmdsInfo[] = { DFU_VERSION_NUMBER, DFU_GET_LIST_CMD, DFU_DEVICE_ID_CMD, DFU_READ_CMD, DFU_GO_CMD, - DFU_WRITE_CMD, DFU_ERASE_CMD }; - size_t numBytes = sizeof(cmdsInfo); - sendByte(numBytes - 1); // number of commands - for (size_t i = 0; i < numBytes; i++) - sendByte(cmdsInfo[i]); - sendByte(DFU_ACK_BYTE); - break; - } - - case DFU_DEVICE_ID_CMD: { - uint32_t mcuRev = getMcuRevision(); - sendByte(0x01); // the number of bytes to be send - 1 - // send 12 bit MCU revision - sendByte((uint8_t)((mcuRev >> 8) & 0xf)); - sendByte((uint8_t)(mcuRev & 0xff)); - sendByte(DFU_ACK_BYTE); + case DFU_GET_LIST_CMD: + dfuHandleGetList(); + break; + case DFU_DEVICE_ID_CMD: + dfuHandleDeviceId(); break; - } - case DFU_GO_CMD: { - if (!readAddress(&addr)) { - sendByte(DFU_NACK_BYTE); - break; - } - // todo: check if the address is valid - sendByte(DFU_ACK_BYTE); - dfuJumpToApp(addr); + case DFU_GO_CMD: + dfuHandleGo(); break; - } - - case DFU_READ_CMD: { - if (!readAddress(&addr)) { - sendByte(DFU_NACK_BYTE); - break; - } - sendByte(DFU_ACK_BYTE); - uint8_t byte; - if (!getByte(&byte)) - break; - if (!getByte(&complement)) - break; - // check if we have a correct byte received - if (complement != complementByte(byte)) { - sendByte(DFU_NACK_BYTE); - break; - } - int numBytes = (int)byte + 1; - sendByte(DFU_ACK_BYTE); - - // read flash or virtual RAM buffer (don't transmit directly from flash) - if (isInVirtualPageBuffer(addr)) - memcpy(buffer, (uint8_t *)addr, numBytes); - else - flashRead(addr, (char *)buffer, numBytes); - - // transmit data - sr5WriteData(&blTsChannel, (uint8_t *)buffer, numBytes); + case DFU_READ_CMD: + dfuHandleRead(); break; - } - case DFU_WRITE_CMD: { - if (!readAddress(&addr)) { - sendByte(DFU_NACK_BYTE); - break; - } - sendByte(DFU_ACK_BYTE); - if (!getByte(buffer)) - break; - int numBytes = buffer[0] + 1; - int numBytesAndChecksum = numBytes + 1; // +1 byte of checkSum - // receive data - if (sr5ReadDataTimeout(&blTsChannel, buffer + 1, numBytesAndChecksum, sr5Timeout) != numBytesAndChecksum) - break; - // don't write corrupted data! - if (dfuCalcChecksum(buffer, numBytesAndChecksum) != buffer[numBytesAndChecksum]) { - sendByte(DFU_NACK_BYTE); - break; - } - - // now write to flash (or to the virtual RAM buffer) - if (isInVirtualPageBuffer(addr)) - memcpy((uint8_t *)addr, (buffer + 1), numBytes); - else - flashWrite(addr, (const char *)(buffer + 1), numBytes); - - // we're done! - sendByte(DFU_ACK_BYTE); + case DFU_WRITE_CMD: + dfuHandleWrite(); break; - } - - case DFU_ERASE_CMD: { - int numSectors; - if (!getByte(buffer)) - break; - if (!getByte(buffer + 1)) - break; - numSectors = bufToInt16(buffer); - int numSectorData; - if (numSectors == 0xffff) // erase all chip - numSectorData = 1; - else - numSectorData = (numSectors + 1) * 2 + 1; - uint8_t *sectorList = buffer + 2; - // read sector data & checksum - if (sr5ReadDataTimeout(&blTsChannel, sectorList, numSectorData, sr5Timeout) != numSectorData) - break; - // verify checksum - if (dfuCalcChecksum(buffer, 2 + numSectorData - 1) != buffer[2 + numSectorData - 1]) { - sendByte(DFU_NACK_BYTE); - break; - } - // Erase the chosen sectors, sector by sector - for (int i = 0; i < numSectorData - 1; i += 2) { - int sectorIdx = bufToInt16(sectorList + i); - if (sectorIdx < BOOTLOADER_NUM_SECTORS) { // skip first sectors where our bootloader is - // imitate flash erase by writing '0xff' - memset(bootloaderVirtualPageBuffer, 0xff, BOOTLOADER_SIZE); - continue; - } - // erase sector - flashSectorErase(sectorIdx); - } - - sendByte(DFU_ACK_BYTE); + case DFU_ERASE_CMD: + dfuHandleErase(); break; - } - default: break; } /* End switch */ diff --git a/firmware/bootloader/src/main.cpp b/firmware/bootloader/src/main.cpp index 21a3ba866a..e6b429395e 100644 --- a/firmware/bootloader/src/main.cpp +++ b/firmware/bootloader/src/main.cpp @@ -19,11 +19,6 @@ extern "C" #include "dfu.h" -persistent_config_container_s persistentState CCM_OPTIONAL; -const persistent_config_s *config = &persistentState.persistentConfiguration; -const engine_configuration_s *engineConfiguration = &persistentState.persistentConfiguration.engineConfiguration; -const board_configuration_s *boardConfiguration = &persistentState.persistentConfiguration.engineConfiguration.bc; - LoggingWithStorage tsLogger("binary"); static bool wasCommand = false; diff --git a/firmware/bootloader/src/rusefi_stubs.cpp b/firmware/bootloader/src/rusefi_stubs.cpp index 6f6498d5e8..9a2a95c108 100644 --- a/firmware/bootloader/src/rusefi_stubs.cpp +++ b/firmware/bootloader/src/rusefi_stubs.cpp @@ -3,6 +3,12 @@ #include "efiGpio.h" #include "global.h" +/* + * We need only a small portion of code from rusEFI codebase in the bootloader. + * Mostly it's tunerstudio_io.cpp. And other files like efiGpio.cpp etc. needed only to make it work. + * And stubs needed just to settle down compiler errors. + * The whole idea of bootloader is to make it as small as possible. And reasonably independent. +*/ int maxNesting = 0; diff --git a/firmware/config/stm32f4ems/STM32F407xG_CCM.ld b/firmware/config/stm32f4ems/STM32F407xG_CCM.ld index d1a5fc1ffa..7842e7bd2b 100644 --- a/firmware/config/stm32f4ems/STM32F407xG_CCM.ld +++ b/firmware/config/stm32f4ems/STM32F407xG_CCM.ld @@ -20,7 +20,8 @@ */ MEMORY { - flash : org = 0x08000000, len = 896k + bl : org = 0x08000000, len = 16k /* bootloader section */ + flash : org = DEFINED(BOOTLOADER) ? 0x08008000 : 0x08000000, len = DEFINED(BOOTLOADER) ? 864k : 896k /* change address & length if bootloader */ ram0 : org = 0x20000000, len = 128k /* SRAM1 + SRAM2 */ ram1 : org = 0x20000000, len = 112k /* SRAM1 */ ram2 : org = 0x2001C000, len = 16k /* SRAM2 */ @@ -48,4 +49,16 @@ REGION_ALIAS("BSS_RAM", ram0); /* RAM region to be used for the default heap.*/ REGION_ALIAS("HEAP_RAM", ram0); +/* Bootloader section */ +SECTIONS +{ +.bl : ALIGN(4) + { + . = ALIGN(4); + *(.bl) + *(.bl.*) + . = ALIGN(4); + } > bl AT > bl +} + INCLUDE rules.ld diff --git a/firmware/config/stm32f4ems/STM32F407xG_CCM_bootloader.ld b/firmware/config/stm32f4ems/STM32F407xG_CCM_bootloader.ld deleted file mode 100644 index f0c267dbbc..0000000000 --- a/firmware/config/stm32f4ems/STM32F407xG_CCM_bootloader.ld +++ /dev/null @@ -1,64 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -/* - * STM32F407xG memory setup. - * Note: Use of ram1 and ram2 is mutually exclusive with use of ram0. - */ -MEMORY -{ - bl : org = 0x08000000, len = 16k - flash : org = 0x08008000, len = 864k - ram0 : org = 0x20000000, len = 128k /* SRAM1 + SRAM2 */ - ram1 : org = 0x20000000, len = 112k /* SRAM1 */ - ram2 : org = 0x2001C000, len = 16k /* SRAM2 */ - ram3 : org = 0x00000000, len = 0 - ram4 : org = 0x10000000, len = 64k /* CCM SRAM */ - ram5 : org = 0x40024000, len = 4k /* BCKP SRAM */ - ram6 : org = 0x00000000, len = 0 - ram7 : org = 0x00000000, len = 0 -} - -/* RAM region to be used for Main stack. This stack accommodates the processing - of all exceptions and interrupts*/ -REGION_ALIAS("MAIN_STACK_RAM", ram0); - -/* RAM region to be used for the process stack. This is the stack used by - the main() function.*/ -REGION_ALIAS("PROCESS_STACK_RAM", ram0); - -/* RAM region to be used for data segment.*/ -REGION_ALIAS("DATA_RAM", ram0); - -/* RAM region to be used for BSS segment.*/ -REGION_ALIAS("BSS_RAM", ram0); - -/* RAM region to be used for the default heap.*/ -REGION_ALIAS("HEAP_RAM", ram0); - -/* Bootloader section */ -SECTIONS -{ -.bl : ALIGN(4) - { - . = ALIGN(4); - *(.bl) - *(.bl.*) - . = ALIGN(4); - } > bl AT > bl -} - -INCLUDE rules.ld diff --git a/firmware/controllers/controllers.mk b/firmware/controllers/controllers.mk index 83abd27cae..d4d0708602 100644 --- a/firmware/controllers/controllers.mk +++ b/firmware/controllers/controllers.mk @@ -14,4 +14,5 @@ CONTROLLERS_SRC_CPP = $(PROJECT_DIR)/controllers/settings.cpp \ $(PROJECT_DIR)/controllers/alternatorController.cpp \ $(PROJECT_DIR)/controllers/lcd_controller.cpp \ $(PROJECT_DIR)/controllers/tachometer.cpp \ - $(PROJECT_DIR)/controllers/engine_controller.cpp + $(PROJECT_DIR)/controllers/engine_controller.cpp \ + $(PROJECT_DIR)/controllers/persistent_store.cpp diff --git a/firmware/controllers/engine_controller.cpp b/firmware/controllers/engine_controller.cpp index 89a6126d9f..14180fb71b 100644 --- a/firmware/controllers/engine_controller.cpp +++ b/firmware/controllers/engine_controller.cpp @@ -70,17 +70,8 @@ extern bool hasFirmwareErrorFlag; extern EnginePins enginePins; -persistent_config_container_s persistentState CCM_OPTIONAL; +EXTERN_ENGINE; -const persistent_config_s *config = &persistentState.persistentConfiguration; - -/** - * todo: it really looks like these fields should become 'static', i.e. private - * the whole 'extern ...' pattern is less then perfect, I guess the 'God object' Engine - * would be a smaller evil. Whatever is needed should be passed into methods/modules/files as an explicit parameter. - */ -const engine_configuration_s *engineConfiguration = &persistentState.persistentConfiguration.engineConfiguration; -const board_configuration_s *boardConfiguration = &persistentState.persistentConfiguration.engineConfiguration.bc; /** * CH_FREQUENCY is the number of system ticks in a second