Bootload from SD card to sector 0, and jump to sector 24 where new firmware resides

Dependencies:   FatFS mbed

Fork of Panel-Controller-Bootloader by Emma

Revision:
0:c3a652eff606
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flash.c	Tue Apr 21 09:30:11 2015 +0000
@@ -0,0 +1,192 @@
+#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();
+    }
+  }
+}