Bootload from SD card to sector 0, and jump to sector 24 where new firmware resides
Fork of Panel-Controller-Bootloader by
flash.c
- Committer:
- bonchenko
- Date:
- 2015-04-22
- Revision:
- 2:0fa89ba8f6fe
- Parent:
- 0:c3a652eff606
File content as of revision 2:0fa89ba8f6fe:
#include "flash.h" #include "usart.h" #include "rtc.h" #include "main.h" uint32_t BlockNbr = 0; uint32_t UserMemoryMask = 0; FLASH_RESULT FlashFirmware(void) { USART_SendString("Flashing...\r\n"); /* Get the number of block (4 or 2 pages) from where the user program will be loaded */ BlockNbr = (ApplicationAddress - 0x08000000) >> 12; UserMemoryMask = ((uint32_t)~((1 << BlockNbr) - 1)); if ((FLASH_GetWriteProtectionOptionByte() & UserMemoryMask) != UserMemoryMask) { FLASH_DisableWriteProtectionPages(); } FATFS fatfs; FIL file; u8 buffer[1024]; UINT btr = 1024; UINT br = 0; UINT index = 0; USART_SendString("F_Mount\r\n"); FRESULT result = f_mount(0, &fatfs); USART_SendString("F_Mount finished\r\n"); if(result == FR_OK) { USART_SendString("FR OK\r\n"); TCHAR filename[13] = "firmware.bin"; USART_SendString("Opening file...\r\n"); result = f_open(&file, (TCHAR*)filename, FA_READ); USART_SendString("Opening file finished\r\n"); if(result == FR_OK) { USART_SendString("FR Opened\r\n"); FLASH_Unlock(); 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); FLASH_Status FLASHStatus = FLASH_COMPLETE; uint32_t eraseCounter = 0; uint32_t writeAddress = ApplicationAddress; uint32_t flashValue = 0; // Calculate how many flash pages to erase uint32_t pages = FLASH_PagesMask(file.fsize) + 1; USART_SendString("Erasing flash...\r\n"); // Erase the flash pages for (eraseCounter = 0; (eraseCounter < pages) && (FLASHStatus == FLASH_COMPLETE); eraseCounter++) { FLASHStatus = FLASH_ErasePage(ApplicationAddress + (PAGE_SIZE * eraseCounter)); } USART_SendString("Writing flash...\r\n"); do { //Read the data from the file result = f_read(&file, &buffer, btr, &br); if(result == FR_OK) { // Led1On(); for(index = 0; index < br; index = index + 4) { //Flash Data flashValue = buffer[index + 3] << 24; flashValue += buffer[index + 2] << 16; flashValue += buffer[index + 1] << 8; flashValue += buffer[index]; FLASHStatus = FLASH_ProgramWord(writeAddress, flashValue); if (*(uint32_t*)writeAddress != flashValue) { return FLASH_MEMORY_MISMATCH; } writeAddress += 4; } } else { return FLASH_DISK_ERR; } } while(br == btr); USART_SendString("Closing file\r\n"); // Close the file result = f_close(&file); USART_SendString("Deleting file\r\n"); // Delete the file result = f_unlink((TCHAR*)filename); // Led1Flash(3, 2000); } else { USART_SendString("No File...\r\n"); return FLASH_NO_FILE; } } else { return FLASH_NO_SD_CARD; } return FLASH_OK; } uint32_t CheckFirmware(FIL *file) { return 1; } uint32_t FLASH_PagesMask(__IO uint32_t Size) { uint32_t pagenumber = 0x0; uint32_t size = Size; if ((size % PAGE_SIZE) != 0) { pagenumber = (size / PAGE_SIZE) + 1; } else { pagenumber = size / PAGE_SIZE; } return pagenumber; } void FLASH_DisableWriteProtectionPages(void) { uint32_t useroptionbyte = 0, WRPR = 0; uint16_t var1 = OB_IWDG_SW, var2 = OB_STOP_NoRST, var3 = OB_STDBY_NoRST; FLASH_Status status = FLASH_BUSY; WRPR = FLASH_GetWriteProtectionOptionByte(); /* Test if user memory is write protected */ if ((WRPR & UserMemoryMask) != UserMemoryMask) { useroptionbyte = FLASH_GetUserOptionByte(); UserMemoryMask |= WRPR; status = FLASH_EraseOptionBytes(); if (UserMemoryMask != 0xFFFFFFFF) { status = FLASH_EnableWriteProtection((uint32_t)~UserMemoryMask); } /* Test if user Option Bytes are programmed */ if ((useroptionbyte & 0x07) != 0x07) { /* Restore user Option Bytes */ if ((useroptionbyte & 0x01) == 0x0) { var1 = OB_IWDG_HW; } if ((useroptionbyte & 0x02) == 0x0) { var2 = OB_STOP_RST; } if ((useroptionbyte & 0x04) == 0x0) { var3 = OB_STDBY_RST; } FLASH_UserOptionByteConfig(var1, var2, var3); } if (status == FLASH_COMPLETE) { /* Generate System Reset to load the new option byte values */ NVIC_SystemReset(); } } }