1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- #include "hal_flash.h"
- #include "hc32_ll.h"
- #define HC32_FLASH_BASE 0x00
- #define HC32_SECTOR_SIZE 0x2000//8kb
- static uint8_t internal_flash_data[HC32_SECTOR_SIZE];//最多是2K字节
-
- int32_t hc32_flash_read(uint32_t u32Addr, uint8_t *pu8Buff, uint32_t u32Len)
- {
- return EFM_ReadByte(u32Addr,pu8Buff, u32Len);
- }
-
- int32_t hc32_flash_read_sector(uint32_t u32Addr)
- {
- return EFM_ReadByte(u32Addr,internal_flash_data,sizeof(internal_flash_data));//读取一个扇区的数据/8kb
- }
-
-
-
- int32_t hc32_flash_write(uint32_t write_addr,uint8_t *buffer,uint32_t number)
- {
- uint32_t i;
- uint32_t sector_page = write_addr/HC32_SECTOR_SIZE;
- uint32_t secpos; //扇区地址
- uint32_t secoff; //扇区内偏移地址
- uint32_t secremain; //扇区内剩余地址
- uint32_t offaddr; //去掉0X08000000后的地址
-
- offaddr = write_addr-HC32_FLASH_BASE; //实际偏移地址.
- secpos = offaddr/HC32_SECTOR_SIZE; //扇区地址 0~32 for HC32F448MTCI
- secoff = (offaddr%HC32_SECTOR_SIZE); //在扇区内的偏移
- secremain = HC32_SECTOR_SIZE-secoff; //扇区剩余空间大小
- if(number<=secremain)secremain=number; //不大于该扇区范围
-
- LL_PERIPH_WE(LL_PERIPH_GPIO | LL_PERIPH_FCG | LL_PERIPH_PWC_CLK_RMU | LL_PERIPH_EFM | LL_PERIPH_SRAM);
- EFM_FWMC_Cmd(ENABLE);
-
- while(1)
- {
- /*读取当前扇区的数据*/
- hc32_flash_read(secpos*HC32_SECTOR_SIZE+HC32_FLASH_BASE,internal_flash_data,sizeof(internal_flash_data));
-
- for(i = 0;i < HC32_SECTOR_SIZE;i++)
- {
- if(internal_flash_data[i]!=0xff)
- break;
- }
- if(i < secremain)
- {
- EFM_SingleSectorOperateCmd(sector_page, ENABLE);//解除写保护
-
- EFM_SectorErase(secpos*HC32_SECTOR_SIZE+HC32_FLASH_BASE);
-
- for(i=0;i<secremain;i++)//复制
- {
- internal_flash_data[secoff+i]=buffer[i];
- }
-
- EFM_Program(secpos*HC32_SECTOR_SIZE+HC32_FLASH_BASE, internal_flash_data, sizeof(internal_flash_data));
- EFM_SingleSectorOperateCmd(sector_page, DISABLE);
-
- }
- else
- {
- EFM_SingleSectorOperateCmd(sector_page, ENABLE);//解除写保护
- EFM_Program(write_addr,buffer,secremain);
- EFM_SingleSectorOperateCmd(sector_page, DISABLE);
- }
- if(number==secremain) break; //写入完成
- else
- {
- secpos++; //扇区地址增1
- secoff=0; //偏移位置为0
- buffer+=secremain; //指针偏移
- write_addr+=secremain;//写地址偏移
- number-=secremain; //字节(16位)数递减
- if(number>(HC32_SECTOR_SIZE))
- secremain=HC32_SECTOR_SIZE;//下一个扇区还是写不完
- else
- secremain=number;//下一个扇区可以写完了
- }
- }
-
-
- EFM_FWMC_Cmd(DISABLE);
- LL_PERIPH_WP(LL_PERIPH_GPIO | LL_PERIPH_FCG | LL_PERIPH_PWC_CLK_RMU | LL_PERIPH_EFM | LL_PERIPH_SRAM);
- }
-
|