| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- #include "chipflash.h"
- #include "string.h"
- #include <stdalign.h>
- //H523 扇区大小为8K Byte
- // 算出目标地址在哪个扇区
- static uint32_t bsp_get_sector(uint32_t Addr)
- {
- uint32_t sector = 0;
- sector = (Addr - CPU_FLASH_BASE_ADDR) / SECTOR_SIZE;
- return sector;
- }
- // 读取目标地址范围FLASH内容
- static uint8_t bsp_read_cpu_flash(uint32_t ulFlashAddr, uint8_t *ucpDst, uint32_t ulSize)
- {
- uint32_t i;
- if (ulFlashAddr + ulSize > CPU_FLASH_BASE_ADDR + CPU_FLASH_SIZE)
- {
- return 1;
- }
- if (ulSize == 0) // 长度为0时返回,否则起始地址为奇数地址会出错
- {
- return 1;
- }
- for (i = 0; i < ulSize; i++)
- {
- *ucpDst++ = *(uint8_t *)ulFlashAddr++;
- }
- return 0;
- }
- // 比较FLASH 指定地址的数据是否一致
- static uint8_t bsp_cmp_cpu_flash(uint32_t ulFlashAddr, uint8_t *ucpBuf, uint32_t ulSize)
- {
- uint32_t i;
- uint8_t ucIsEqu; // 相等标志位
- uint8_t ucByte;
- // 如果偏移地址超过芯片容量,则不改写输出缓冲区
- if (ulFlashAddr + ulSize > CPU_FLASH_BASE_ADDR + CPU_FLASH_SIZE)
- {
- return FLASH_PARAM_ERR;
- }
- if (ulSize == 0)
- {
- return FLASH_IS_EQU; // FLASH内容与待写入数据相等
- }
- ucIsEqu = 1; // 假设所有字节和待写入的数据相等,如果遇到任何一个不相等,则设置为0
- for (i = 0; i < ulSize; i++)
- {
- ucByte = *(uint8_t *)ulFlashAddr; // 取1字节出来作比较
- if (ucByte != *ucpBuf) // 不一致
- {
- if (ucByte != 0xFF) // 且不等于默认
- {
- return FLASH_REQ_ERASE;
- }
- else
- {
- ucIsEqu = 0; // 标志位置0,不一致,需要写
- }
- }
- ulFlashAddr++;
- ucpBuf++;
- }
- if (ucIsEqu == 1)
- {
- return FLASH_IS_EQU; // 一致
- }
- else
- {
- return FLASH_REQ_WRITE; // 直接写
- }
- }
- // 16字节整倍数写,不支持跨扇区,扇区8KB,长度不是8字节整数倍,最后几个字节末尾补0写入
- static uint8_t bsp_write_cpu_flash(uint32_t ulFlashAddr, uint8_t *ucpSrc, uint32_t ulSize)
- {
- uint32_t i;
- uint8_t ucRet;
- if (ulFlashAddr + ulSize > CPU_FLASH_BASE_ADDR + CPU_FLASH_SIZE || ulFlashAddr < CPU_FLASH_BASE_ADDR)
- {
- return 1;
- }
- if (ulSize == 0)
- {
- return 0;
- }
- //地址必须16字节对齐
- if (ulFlashAddr & 15 )
- return 1;
- ucRet = bsp_cmp_cpu_flash(ulFlashAddr, ucpSrc, ulSize);
- if (ucRet == FLASH_IS_EQU)
- {
- return 0;
- }
- __set_PRIMASK(1);
- HAL_FLASH_Unlock();
- for (i = 0; i < ulSize / 16; i++)
- {
- __ALIGNED(4) uint8_t FlashQuadWord[16] = {0};
- memcpy( FlashQuadWord, ucpSrc, 16);
- ucpSrc += 16;
- if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD, ulFlashAddr, (uint32_t)&FlashQuadWord[0]) == HAL_OK) // 双字64bit
- {
- ulFlashAddr = ulFlashAddr + 16; // 递增128bit
- }
- else
- {
- goto err;
- }
- }
- if (ulSize & 15) // 剩余的部分,如果不是16字节整数倍,剩余部分都是0
- {
- __ALIGNED(4) uint8_t FlashWord[16] = {0};
- memcpy(FlashWord, ucpSrc, ulSize & 15);
- uint32_t ptr = (uint32_t)(&FlashWord[0]);
- if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD, ulFlashAddr, (uint32_t)(&FlashWord[0])) != HAL_OK)
- {
- goto err;
- }
- }
- if( HAL_FLASH_Lock() != HAL_OK)
- {
- goto err;
- }
- __set_PRIMASK(0);
- return 0;
- err:
- HAL_FLASH_Lock();
- __set_PRIMASK(0);
- return 1;
- }
- static uint8_t bsp_erase_cpu_flash(uint32_t ulFlashAddr, uint32_t u2FlashAddr)
- {
- uint32_t FirstSector = 0, NumofSectors = 0, FinishSector = 0;
- FLASH_EraseInitTypeDef EraseInitStruct;
- uint32_t SECTOR_ERR = 0;
- uint8_t ret;
- __set_PRIMASK(1);
- HAL_FLASH_Unlock();
- // 获取此地址所在的扇区
- FirstSector = bsp_get_sector(ulFlashAddr);
- FinishSector = bsp_get_sector(u2FlashAddr);
- // 固定1个扇区
- NumofSectors =
- (FinishSector - FirstSector > 0) ? (FinishSector - FirstSector) : 1;
- // 擦除扇区配置
- EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
- EraseInitStruct.Banks = FLASH_BANK_1;
- EraseInitStruct.Sector = FirstSector;
- EraseInitStruct.NbSectors = NumofSectors;
- // 扇区擦除
- ret = HAL_FLASHEx_Erase(&EraseInitStruct, &SECTOR_ERR);
- HAL_FLASH_Lock();
- __set_PRIMASK(0);
- return ret;
- }
- // _CHIP_INFO chip_info;
- // static void get_chip_info(void)
- // {
- // chip_info.ChipUniqueID[0] = *(__IO uint32_t*)(ChipUniqueID_HIGH);
- // chip_info.ChipUniqueID[1] = *(__IO uint32_t*)(ChipUniqueID_MEDIUM);
- // chip_info.ChipUniqueID[2] = *(__IO uint32_t*)(ChipUniqueID_LOW);
- // chip_info.ChipFlashSize = *(__IO uint16_t*)(CHIPFLASHSIZE);
- // chip_info.ChipMCUID = *(__IO uint32_t*)(CHIPMCUID);
- // }
- __FLASH_OPS _flash_ops = {
- .Read_Flash = bsp_read_cpu_flash,
- .Write_Flash = bsp_write_cpu_flash,
- .Erase_Flash = bsp_erase_cpu_flash,
- };
- __FLASH_OPS *flash_ops = &_flash_ops;
|