hal_flash.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. #include "hal_flash.h"
  2. #include "hc32_ll.h"
  3. #include "string.h"
  4. #define HC32_FLASH_BASE 0x00
  5. #define HC32_SECTOR_SIZE 0x2000//8kb
  6. static uint8_t internal_flash_data[HC32_SECTOR_SIZE];//最多是2K字节
  7. int32_t hc32_flash_read(uint32_t u32Addr, uint8_t *pu8Buff, uint32_t u32Len)
  8. {
  9. return EFM_ReadByte(u32Addr,pu8Buff, u32Len);
  10. }
  11. int32_t hc32_flash_read_sector(uint32_t u32Addr)
  12. {
  13. return EFM_ReadByte(u32Addr,internal_flash_data,sizeof(internal_flash_data));//读取一个扇区的数据/8kb
  14. }
  15. int32_t hc32_flash_write(uint32_t write_addr,uint8_t *buffer,uint32_t number)
  16. {
  17. uint32_t i;
  18. uint32_t sector_page = write_addr/HC32_SECTOR_SIZE;
  19. uint32_t secpos; //扇区地址
  20. uint32_t secoff; //扇区内偏移地址
  21. uint32_t secremain; //扇区内剩余地址
  22. uint32_t offaddr; //去掉0X08000000后的地址
  23. offaddr = write_addr-HC32_FLASH_BASE; //实际偏移地址.
  24. secpos = offaddr/HC32_SECTOR_SIZE; //扇区地址 0~32 for HC32F448MTCI
  25. secoff = (offaddr%HC32_SECTOR_SIZE); //在扇区内的偏移
  26. secremain = HC32_SECTOR_SIZE-secoff; //扇区剩余空间大小
  27. if(number<=secremain)
  28. secremain=number; //不大于该扇区范围
  29. LL_PERIPH_WE(LL_PERIPH_GPIO | LL_PERIPH_FCG | LL_PERIPH_PWC_CLK_RMU | LL_PERIPH_EFM | LL_PERIPH_SRAM);
  30. EFM_FWMC_Cmd(ENABLE);
  31. #if 1
  32. while(1)
  33. {
  34. /*读取当前扇区的数据*/
  35. hc32_flash_read(secpos*HC32_SECTOR_SIZE+HC32_FLASH_BASE,internal_flash_data,sizeof(internal_flash_data));
  36. for(i = 0;i < HC32_SECTOR_SIZE;i++)
  37. {
  38. if(internal_flash_data[i]!=0xff)
  39. break;
  40. }
  41. if(i < secremain)
  42. {
  43. EFM_SingleSectorOperateCmd(sector_page, ENABLE);//解除写保护
  44. EFM_SectorErase(secpos*HC32_SECTOR_SIZE+HC32_FLASH_BASE);
  45. #if 0
  46. for(i=0;i<secremain;i++)//复制
  47. {
  48. internal_flash_data[secoff+i]=buffer[i];
  49. }
  50. #else
  51. memcpy(internal_flash_data + secoff, buffer, secremain);
  52. #endif
  53. EFM_Program(secpos*HC32_SECTOR_SIZE+HC32_FLASH_BASE, internal_flash_data, sizeof(internal_flash_data));
  54. EFM_SingleSectorOperateCmd(sector_page, DISABLE);
  55. }
  56. else
  57. {
  58. EFM_SingleSectorOperateCmd(sector_page, ENABLE);//解除写保护
  59. EFM_Program(write_addr,buffer,secremain);
  60. EFM_SingleSectorOperateCmd(sector_page, DISABLE);
  61. }
  62. if(number==secremain) break; //写入完成
  63. else
  64. {
  65. secpos++; //扇区地址增1
  66. secoff=0; //偏移位置为0
  67. buffer+=secremain; //指针偏移
  68. write_addr+=secremain;//写地址偏移
  69. number-=secremain; //字节(16位)数递减
  70. if(number>(HC32_SECTOR_SIZE))
  71. secremain=HC32_SECTOR_SIZE;//下一个扇区还是写不完
  72. else
  73. secremain=number;//下一个扇区可以写完了
  74. }
  75. }
  76. #endif
  77. EFM_FWMC_Cmd(DISABLE);
  78. LL_PERIPH_WP(LL_PERIPH_GPIO | LL_PERIPH_FCG | LL_PERIPH_PWC_CLK_RMU | LL_PERIPH_EFM | LL_PERIPH_SRAM);
  79. }