Bootload from SD card to sector 0, and jump to sector 24 where new firmware resides
Fork of Panel-Controller-Bootloader by
flash.c@2:0fa89ba8f6fe, 2015-04-22 (annotated)
- Committer:
- bonchenko
- Date:
- Wed Apr 22 10:18:55 2015 +0000
- Revision:
- 2:0fa89ba8f6fe
- Parent:
- 0:c3a652eff606
Bootloader from SD card works perfectly. Compiled with offset in EmBlocks, ADE cannot print readings - but its happened without bootloader too. The problem is Emblocks compiler settings
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
bonchenko | 0:c3a652eff606 | 1 | #include "flash.h" |
bonchenko | 0:c3a652eff606 | 2 | #include "usart.h" |
bonchenko | 0:c3a652eff606 | 3 | #include "rtc.h" |
bonchenko | 0:c3a652eff606 | 4 | #include "main.h" |
bonchenko | 0:c3a652eff606 | 5 | |
bonchenko | 0:c3a652eff606 | 6 | uint32_t BlockNbr = 0; |
bonchenko | 0:c3a652eff606 | 7 | uint32_t UserMemoryMask = 0; |
bonchenko | 0:c3a652eff606 | 8 | |
bonchenko | 0:c3a652eff606 | 9 | FLASH_RESULT FlashFirmware(void) |
bonchenko | 0:c3a652eff606 | 10 | { |
bonchenko | 0:c3a652eff606 | 11 | USART_SendString("Flashing...\r\n"); |
bonchenko | 0:c3a652eff606 | 12 | /* Get the number of block (4 or 2 pages) from where the user program will be loaded */ |
bonchenko | 0:c3a652eff606 | 13 | BlockNbr = (ApplicationAddress - 0x08000000) >> 12; |
bonchenko | 0:c3a652eff606 | 14 | UserMemoryMask = ((uint32_t)~((1 << BlockNbr) - 1)); |
bonchenko | 0:c3a652eff606 | 15 | |
bonchenko | 0:c3a652eff606 | 16 | if ((FLASH_GetWriteProtectionOptionByte() & UserMemoryMask) != UserMemoryMask) |
bonchenko | 0:c3a652eff606 | 17 | { |
bonchenko | 0:c3a652eff606 | 18 | FLASH_DisableWriteProtectionPages(); |
bonchenko | 0:c3a652eff606 | 19 | } |
bonchenko | 0:c3a652eff606 | 20 | |
bonchenko | 0:c3a652eff606 | 21 | FATFS fatfs; |
bonchenko | 0:c3a652eff606 | 22 | FIL file; |
bonchenko | 0:c3a652eff606 | 23 | u8 buffer[1024]; |
bonchenko | 0:c3a652eff606 | 24 | UINT btr = 1024; |
bonchenko | 0:c3a652eff606 | 25 | UINT br = 0; |
bonchenko | 0:c3a652eff606 | 26 | UINT index = 0; |
bonchenko | 0:c3a652eff606 | 27 | |
bonchenko | 0:c3a652eff606 | 28 | USART_SendString("F_Mount\r\n"); |
bonchenko | 0:c3a652eff606 | 29 | FRESULT result = f_mount(0, &fatfs); |
bonchenko | 0:c3a652eff606 | 30 | USART_SendString("F_Mount finished\r\n"); |
bonchenko | 0:c3a652eff606 | 31 | |
bonchenko | 0:c3a652eff606 | 32 | if(result == FR_OK) |
bonchenko | 0:c3a652eff606 | 33 | { |
bonchenko | 0:c3a652eff606 | 34 | USART_SendString("FR OK\r\n"); |
bonchenko | 0:c3a652eff606 | 35 | TCHAR filename[13] = "firmware.bin"; |
bonchenko | 0:c3a652eff606 | 36 | |
bonchenko | 0:c3a652eff606 | 37 | USART_SendString("Opening file...\r\n"); |
bonchenko | 0:c3a652eff606 | 38 | result = f_open(&file, (TCHAR*)filename, FA_READ); |
bonchenko | 0:c3a652eff606 | 39 | USART_SendString("Opening file finished\r\n"); |
bonchenko | 0:c3a652eff606 | 40 | |
bonchenko | 0:c3a652eff606 | 41 | if(result == FR_OK) |
bonchenko | 0:c3a652eff606 | 42 | { |
bonchenko | 0:c3a652eff606 | 43 | USART_SendString("FR Opened\r\n"); |
bonchenko | 0:c3a652eff606 | 44 | FLASH_Unlock(); |
bonchenko | 0:c3a652eff606 | 45 | FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR | FLASH_FLAG_BANK1_PGERR | FLASH_FLAG_BANK1_BSY | FLASH_FLAG_BANK1_EOP | FLASH_FLAG_BANK1_WRPRTERR); |
bonchenko | 0:c3a652eff606 | 46 | |
bonchenko | 0:c3a652eff606 | 47 | FLASH_Status FLASHStatus = FLASH_COMPLETE; |
bonchenko | 0:c3a652eff606 | 48 | uint32_t eraseCounter = 0; |
bonchenko | 0:c3a652eff606 | 49 | uint32_t writeAddress = ApplicationAddress; |
bonchenko | 0:c3a652eff606 | 50 | uint32_t flashValue = 0; |
bonchenko | 0:c3a652eff606 | 51 | |
bonchenko | 0:c3a652eff606 | 52 | // Calculate how many flash pages to erase |
bonchenko | 0:c3a652eff606 | 53 | uint32_t pages = FLASH_PagesMask(file.fsize) + 1; |
bonchenko | 0:c3a652eff606 | 54 | |
bonchenko | 0:c3a652eff606 | 55 | USART_SendString("Erasing flash...\r\n"); |
bonchenko | 0:c3a652eff606 | 56 | // Erase the flash pages |
bonchenko | 0:c3a652eff606 | 57 | for (eraseCounter = 0; (eraseCounter < pages) && (FLASHStatus == FLASH_COMPLETE); eraseCounter++) |
bonchenko | 0:c3a652eff606 | 58 | { |
bonchenko | 0:c3a652eff606 | 59 | FLASHStatus = FLASH_ErasePage(ApplicationAddress + (PAGE_SIZE * eraseCounter)); |
bonchenko | 0:c3a652eff606 | 60 | } |
bonchenko | 0:c3a652eff606 | 61 | |
bonchenko | 0:c3a652eff606 | 62 | USART_SendString("Writing flash...\r\n"); |
bonchenko | 0:c3a652eff606 | 63 | do |
bonchenko | 0:c3a652eff606 | 64 | { |
bonchenko | 0:c3a652eff606 | 65 | //Read the data from the file |
bonchenko | 0:c3a652eff606 | 66 | result = f_read(&file, &buffer, btr, &br); |
bonchenko | 0:c3a652eff606 | 67 | |
bonchenko | 0:c3a652eff606 | 68 | if(result == FR_OK) |
bonchenko | 0:c3a652eff606 | 69 | { |
bonchenko | 0:c3a652eff606 | 70 | // Led1On(); |
bonchenko | 0:c3a652eff606 | 71 | |
bonchenko | 0:c3a652eff606 | 72 | for(index = 0; index < br; index = index + 4) |
bonchenko | 0:c3a652eff606 | 73 | { |
bonchenko | 0:c3a652eff606 | 74 | //Flash Data |
bonchenko | 0:c3a652eff606 | 75 | flashValue = buffer[index + 3] << 24; |
bonchenko | 0:c3a652eff606 | 76 | flashValue += buffer[index + 2] << 16; |
bonchenko | 0:c3a652eff606 | 77 | flashValue += buffer[index + 1] << 8; |
bonchenko | 0:c3a652eff606 | 78 | flashValue += buffer[index]; |
bonchenko | 0:c3a652eff606 | 79 | |
bonchenko | 0:c3a652eff606 | 80 | FLASHStatus = FLASH_ProgramWord(writeAddress, flashValue); |
bonchenko | 0:c3a652eff606 | 81 | |
bonchenko | 0:c3a652eff606 | 82 | if (*(uint32_t*)writeAddress != flashValue) |
bonchenko | 0:c3a652eff606 | 83 | { |
bonchenko | 0:c3a652eff606 | 84 | return FLASH_MEMORY_MISMATCH; |
bonchenko | 0:c3a652eff606 | 85 | } |
bonchenko | 0:c3a652eff606 | 86 | |
bonchenko | 0:c3a652eff606 | 87 | writeAddress += 4; |
bonchenko | 0:c3a652eff606 | 88 | } |
bonchenko | 0:c3a652eff606 | 89 | } |
bonchenko | 0:c3a652eff606 | 90 | else |
bonchenko | 0:c3a652eff606 | 91 | { |
bonchenko | 0:c3a652eff606 | 92 | return FLASH_DISK_ERR; |
bonchenko | 0:c3a652eff606 | 93 | } |
bonchenko | 0:c3a652eff606 | 94 | } |
bonchenko | 0:c3a652eff606 | 95 | while(br == btr); |
bonchenko | 0:c3a652eff606 | 96 | |
bonchenko | 0:c3a652eff606 | 97 | USART_SendString("Closing file\r\n"); |
bonchenko | 0:c3a652eff606 | 98 | // Close the file |
bonchenko | 0:c3a652eff606 | 99 | result = f_close(&file); |
bonchenko | 0:c3a652eff606 | 100 | |
bonchenko | 0:c3a652eff606 | 101 | USART_SendString("Deleting file\r\n"); |
bonchenko | 0:c3a652eff606 | 102 | // Delete the file |
bonchenko | 0:c3a652eff606 | 103 | result = f_unlink((TCHAR*)filename); |
bonchenko | 0:c3a652eff606 | 104 | |
bonchenko | 0:c3a652eff606 | 105 | // Led1Flash(3, 2000); |
bonchenko | 0:c3a652eff606 | 106 | } |
bonchenko | 0:c3a652eff606 | 107 | else |
bonchenko | 0:c3a652eff606 | 108 | { |
bonchenko | 0:c3a652eff606 | 109 | USART_SendString("No File...\r\n"); |
bonchenko | 0:c3a652eff606 | 110 | return FLASH_NO_FILE; |
bonchenko | 0:c3a652eff606 | 111 | } |
bonchenko | 0:c3a652eff606 | 112 | } |
bonchenko | 0:c3a652eff606 | 113 | else |
bonchenko | 0:c3a652eff606 | 114 | { |
bonchenko | 0:c3a652eff606 | 115 | return FLASH_NO_SD_CARD; |
bonchenko | 0:c3a652eff606 | 116 | } |
bonchenko | 0:c3a652eff606 | 117 | |
bonchenko | 0:c3a652eff606 | 118 | return FLASH_OK; |
bonchenko | 0:c3a652eff606 | 119 | } |
bonchenko | 0:c3a652eff606 | 120 | |
bonchenko | 0:c3a652eff606 | 121 | uint32_t CheckFirmware(FIL *file) |
bonchenko | 0:c3a652eff606 | 122 | { |
bonchenko | 0:c3a652eff606 | 123 | |
bonchenko | 0:c3a652eff606 | 124 | return 1; |
bonchenko | 0:c3a652eff606 | 125 | } |
bonchenko | 0:c3a652eff606 | 126 | |
bonchenko | 0:c3a652eff606 | 127 | uint32_t FLASH_PagesMask(__IO uint32_t Size) |
bonchenko | 0:c3a652eff606 | 128 | { |
bonchenko | 0:c3a652eff606 | 129 | uint32_t pagenumber = 0x0; |
bonchenko | 0:c3a652eff606 | 130 | uint32_t size = Size; |
bonchenko | 0:c3a652eff606 | 131 | |
bonchenko | 0:c3a652eff606 | 132 | if ((size % PAGE_SIZE) != 0) |
bonchenko | 0:c3a652eff606 | 133 | { |
bonchenko | 0:c3a652eff606 | 134 | pagenumber = (size / PAGE_SIZE) + 1; |
bonchenko | 0:c3a652eff606 | 135 | } |
bonchenko | 0:c3a652eff606 | 136 | else |
bonchenko | 0:c3a652eff606 | 137 | { |
bonchenko | 0:c3a652eff606 | 138 | pagenumber = size / PAGE_SIZE; |
bonchenko | 0:c3a652eff606 | 139 | } |
bonchenko | 0:c3a652eff606 | 140 | |
bonchenko | 0:c3a652eff606 | 141 | return pagenumber; |
bonchenko | 0:c3a652eff606 | 142 | } |
bonchenko | 0:c3a652eff606 | 143 | |
bonchenko | 0:c3a652eff606 | 144 | void FLASH_DisableWriteProtectionPages(void) |
bonchenko | 0:c3a652eff606 | 145 | { |
bonchenko | 0:c3a652eff606 | 146 | uint32_t useroptionbyte = 0, WRPR = 0; |
bonchenko | 0:c3a652eff606 | 147 | uint16_t var1 = OB_IWDG_SW, var2 = OB_STOP_NoRST, var3 = OB_STDBY_NoRST; |
bonchenko | 0:c3a652eff606 | 148 | FLASH_Status status = FLASH_BUSY; |
bonchenko | 0:c3a652eff606 | 149 | |
bonchenko | 0:c3a652eff606 | 150 | WRPR = FLASH_GetWriteProtectionOptionByte(); |
bonchenko | 0:c3a652eff606 | 151 | |
bonchenko | 0:c3a652eff606 | 152 | /* Test if user memory is write protected */ |
bonchenko | 0:c3a652eff606 | 153 | if ((WRPR & UserMemoryMask) != UserMemoryMask) |
bonchenko | 0:c3a652eff606 | 154 | { |
bonchenko | 0:c3a652eff606 | 155 | useroptionbyte = FLASH_GetUserOptionByte(); |
bonchenko | 0:c3a652eff606 | 156 | |
bonchenko | 0:c3a652eff606 | 157 | UserMemoryMask |= WRPR; |
bonchenko | 0:c3a652eff606 | 158 | |
bonchenko | 0:c3a652eff606 | 159 | status = FLASH_EraseOptionBytes(); |
bonchenko | 0:c3a652eff606 | 160 | |
bonchenko | 0:c3a652eff606 | 161 | if (UserMemoryMask != 0xFFFFFFFF) |
bonchenko | 0:c3a652eff606 | 162 | { |
bonchenko | 0:c3a652eff606 | 163 | status = FLASH_EnableWriteProtection((uint32_t)~UserMemoryMask); |
bonchenko | 0:c3a652eff606 | 164 | } |
bonchenko | 0:c3a652eff606 | 165 | |
bonchenko | 0:c3a652eff606 | 166 | /* Test if user Option Bytes are programmed */ |
bonchenko | 0:c3a652eff606 | 167 | if ((useroptionbyte & 0x07) != 0x07) |
bonchenko | 0:c3a652eff606 | 168 | { |
bonchenko | 0:c3a652eff606 | 169 | /* Restore user Option Bytes */ |
bonchenko | 0:c3a652eff606 | 170 | if ((useroptionbyte & 0x01) == 0x0) |
bonchenko | 0:c3a652eff606 | 171 | { |
bonchenko | 0:c3a652eff606 | 172 | var1 = OB_IWDG_HW; |
bonchenko | 0:c3a652eff606 | 173 | } |
bonchenko | 0:c3a652eff606 | 174 | if ((useroptionbyte & 0x02) == 0x0) |
bonchenko | 0:c3a652eff606 | 175 | { |
bonchenko | 0:c3a652eff606 | 176 | var2 = OB_STOP_RST; |
bonchenko | 0:c3a652eff606 | 177 | } |
bonchenko | 0:c3a652eff606 | 178 | if ((useroptionbyte & 0x04) == 0x0) |
bonchenko | 0:c3a652eff606 | 179 | { |
bonchenko | 0:c3a652eff606 | 180 | var3 = OB_STDBY_RST; |
bonchenko | 0:c3a652eff606 | 181 | } |
bonchenko | 0:c3a652eff606 | 182 | |
bonchenko | 0:c3a652eff606 | 183 | FLASH_UserOptionByteConfig(var1, var2, var3); |
bonchenko | 0:c3a652eff606 | 184 | } |
bonchenko | 0:c3a652eff606 | 185 | |
bonchenko | 0:c3a652eff606 | 186 | if (status == FLASH_COMPLETE) |
bonchenko | 0:c3a652eff606 | 187 | { |
bonchenko | 0:c3a652eff606 | 188 | /* Generate System Reset to load the new option byte values */ |
bonchenko | 0:c3a652eff606 | 189 | NVIC_SystemReset(); |
bonchenko | 0:c3a652eff606 | 190 | } |
bonchenko | 0:c3a652eff606 | 191 | } |
bonchenko | 0:c3a652eff606 | 192 | } |