/* ********************************************************************************************************* * IAR Development Kits * on the * * M451 * * Filename : fmc_flash.h * Version : V1.00 * Programmer(s) : Qian Xianghong ********************************************************************************************************* */ /* ********************************************************************************************************* * INCLUDE FILES ********************************************************************************************************* */ #include "includes.h" // 读Flash全局缓冲 uint8_t Flash_rdBuf[FLASH_ERASE_SIZE]; // 将地址按4字节对齐 #define ALIGN_DWORD_SIZE(addr) ((addr) & 0xFFFFFFFCul) /* Base address of the Flash sectors */ #define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base address of Sector 0, 16 Kbytes */ #define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08004000) /* Base address of Sector 1, 16 Kbytes */ #define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08008000) /* Base address of Sector 2, 16 Kbytes */ #define ADDR_FLASH_SECTOR_3 ((uint32_t)0x0800C000) /* Base address of Sector 3, 16 Kbytes */ #define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08010000) /* Base address of Sector 4, 64 Kbytes */ #define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08020000) /* Base address of Sector 5, 128 Kbytes */ #define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08040000) /* Base address of Sector 6, 128 Kbytes */ #define ADDR_FLASH_SECTOR_7 ((uint32_t)0x08060000) /* Base address of Sector 7, 128 Kbytes */ #define ADDR_FLASH_SECTOR_8 ((uint32_t)0x08080000) /* Base address of Sector 8, 128 Kbytes */ #define ADDR_FLASH_SECTOR_9 ((uint32_t)0x080A0000) /* Base address of Sector 9, 128 Kbytes */ #define ADDR_FLASH_SECTOR_10 ((uint32_t)0x080C0000) /* Base address of Sector10, 128 Kbytes */ #define ADDR_FLASH_SECTOR_11 ((uint32_t)0x080E0000) /* Base address of Sector11, 128 Kbytes */ #define ADDR_FLASH_SECTOR_12 ((uint32_t)0x08100000) /* Base address of Sector12, 128 Kbytes */ #define ADDR_FLASH_SECTOR_13 ((uint32_t)0x08120000) /* Base address of Sector13, 128 Kbytes */ #define ADDR_FLASH_SECTOR_14 ((uint32_t)0x08140000) /* Base address of Sector14, 128 Kbytes */ #define ADDR_FLASH_SECTOR_15 ((uint32_t)0x08160000) /* Base address of Sector15, 128 Kbytes */ /** * @brief Gets the sector of a given address * @param None * @retval The sector of a given address */ static uint32_t GetSector(uint32_t Address) { uint32_t sector = 0; if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0)) { sector = FLASH_SECTOR_0; } else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1)) { sector = FLASH_SECTOR_1; } else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2)) { sector = FLASH_SECTOR_2; } else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3)) { sector = FLASH_SECTOR_3; } else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4)) { sector = FLASH_SECTOR_4; } else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5)) { sector = FLASH_SECTOR_5; } else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6)) { sector = FLASH_SECTOR_6; } else /* (Address < FLASH_END_ADDR) && (Address >= ADDR_FLASH_SECTOR_7) */ { sector = FLASH_SECTOR_7; } return sector; } /** * @brief Gets sector Size * @param None * @retval The size of a given sector */ static uint32_t GetSectorSize(uint32_t Sector) { uint32_t sectorsize = 0x00; if((Sector == FLASH_SECTOR_0) || (Sector == FLASH_SECTOR_1) || (Sector == FLASH_SECTOR_2) || (Sector == FLASH_SECTOR_3)) { sectorsize = 16 * 1024; } else if(Sector == FLASH_SECTOR_4) { sectorsize = 64 * 1024; } else { sectorsize = 128 * 1024; } return sectorsize; } /** * @brief Gets sector start Address * @param None * @retval The start address of a given sector */ static uint32_t GetSectorAddr(uint32_t Sector) { uint32_t sectoraddr = 0x00; if((Sector == FLASH_SECTOR_0) || (Sector == FLASH_SECTOR_1) || (Sector == FLASH_SECTOR_2) || (Sector == FLASH_SECTOR_3)) { sectoraddr = ADDR_FLASH_SECTOR_0 + 16 * 1024 * (Sector - FLASH_SECTOR_0); } else if(Sector == FLASH_SECTOR_4) { sectoraddr = ADDR_FLASH_SECTOR_0 + 64 * 1024; } else { sectoraddr = ADDR_FLASH_SECTOR_0 + 128 * 1024 * (Sector - FLASH_SECTOR_5); } return sectoraddr; } // 校验flash内容 uint8_t Flash_BufferVerify(uint32_t Addr, uint8_t *buf, uint32_t nbytes) { // 将地址按4字节对齐 uint32_t Addr4Start = ALIGN_DWORD_SIZE(Addr); uint32_t Addr4End = ALIGN_DWORD_SIZE(Addr + nbytes + 3); uint32_t u32Data, i, j = 0; for(i = Addr4Start; i < Addr4End; i += 4) { u32Data = *(__IO uint32_t *)(i); if(i >= Addr && i < Addr + nbytes && buf[j++] != (u32Data & 0xFF)) return 0; if(i + 1 >= Addr && i + 1 < Addr + nbytes && buf[j++] != ((u32Data >> 8) & 0xFF)) return 0; if(i + 2 >= Addr && i + 2 < Addr + nbytes && buf[j++] != ((u32Data >> 16) & 0xFF)) return 0; if(i + 3 >= Addr && i + 3 < Addr + nbytes && buf[j++] != (u32Data >> 24)) return 0; } return 1; } // 将flash内容读入缓冲区 void Flash_BufferRead(uint32_t Addr, uint8_t *buf, uint32_t nbytes) { // 将地址按4字节对齐 uint32_t Addr4Start = ALIGN_DWORD_SIZE(Addr); uint32_t Addr4End = ALIGN_DWORD_SIZE(Addr + nbytes + 3); uint32_t u32Data, i, j = 0; for(i = Addr4Start; i < Addr4End; i += 4) { u32Data = *(__IO uint32_t *)(i); if(i >= Addr && i < Addr + nbytes) buf[j++] = (u32Data & 0xFF); if(i + 1 >= Addr && i + 1 < Addr + nbytes) buf[j++] = ((u32Data >> 8) & 0xFF); if(i + 2 >= Addr && i + 2 < Addr + nbytes) buf[j++] = ((u32Data >> 16) & 0xFF); if(i + 3 >= Addr && i + 3 < Addr + nbytes) buf[j++] = (u32Data >> 24); } } // 擦除一页 void Flash_EraseSector(uint32_t Addr) { static FLASH_EraseInitTypeDef EraseInitStruct; uint32_t PAGEError = 0; EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS; EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3; EraseInitStruct.Sector = GetSector(Addr); EraseInitStruct.NbSectors = 1; HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError); } // 写入一页,Addr为首地址 void Flash_SectorWrite(uint32_t Addr, uint8_t *buf, uint32_t count) { unsigned long *buf32 = (unsigned long *) buf; uint32_t i = 0; while(i < count) { HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Addr + i, *buf32++); i += 4; } } void Flash_BufferWrite(uint32_t Addr, uint8_t *buf, uint32_t nbytes) { uint32_t count, offset; uint32_t sector, sectorSize, sectorAddr; // 第1页(Bootloader)不允许擦除 static uint8_t sectorErased[16] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; while(nbytes > 0) { sector = GetSector(Addr); sectorSize = GetSectorSize(sector); sectorAddr = GetSectorAddr(sector); // 计算页内偏移(只有第一页有可能非0) offset = Addr - sectorAddr; // 计算一页内写入字节数 count = sectorSize - offset; if(count > nbytes) count = nbytes; // 如果第一次写入某个扇区,则擦除 if(!sectorErased[sector]) { // 擦除本页 Flash_EraseSector(Addr); sectorErased[sector] = 1; } // 写入本页数据 Flash_SectorWrite(Addr, buf, count); // 计算下一页 Addr += count; buf += count; nbytes -= count; } }