chipflash.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. #include "chipflash.h"
  2. #include "string.h"
  3. #include <stdalign.h>
  4. //H523 扇区大小为8K Byte
  5. // 算出目标地址在哪个扇区
  6. static uint32_t bsp_get_sector(uint32_t Addr)
  7. {
  8. uint32_t sector = 0;
  9. sector = (Addr - CPU_FLASH_BASE_ADDR) / SECTOR_SIZE;
  10. return sector;
  11. }
  12. // 读取目标地址范围FLASH内容
  13. static uint8_t bsp_read_cpu_flash(uint32_t ulFlashAddr, uint8_t *ucpDst, uint32_t ulSize)
  14. {
  15. uint32_t i;
  16. if (ulFlashAddr + ulSize > CPU_FLASH_BASE_ADDR + CPU_FLASH_SIZE)
  17. {
  18. return 1;
  19. }
  20. if (ulSize == 0) // 长度为0时返回,否则起始地址为奇数地址会出错
  21. {
  22. return 1;
  23. }
  24. for (i = 0; i < ulSize; i++)
  25. {
  26. *ucpDst++ = *(uint8_t *)ulFlashAddr++;
  27. }
  28. return 0;
  29. }
  30. // 比较FLASH 指定地址的数据是否一致
  31. static uint8_t bsp_cmp_cpu_flash(uint32_t ulFlashAddr, uint8_t *ucpBuf, uint32_t ulSize)
  32. {
  33. uint32_t i;
  34. uint8_t ucIsEqu; // 相等标志位
  35. uint8_t ucByte;
  36. // 如果偏移地址超过芯片容量,则不改写输出缓冲区
  37. if (ulFlashAddr + ulSize > CPU_FLASH_BASE_ADDR + CPU_FLASH_SIZE)
  38. {
  39. return FLASH_PARAM_ERR;
  40. }
  41. if (ulSize == 0)
  42. {
  43. return FLASH_IS_EQU; // FLASH内容与待写入数据相等
  44. }
  45. ucIsEqu = 1; // 假设所有字节和待写入的数据相等,如果遇到任何一个不相等,则设置为0
  46. for (i = 0; i < ulSize; i++)
  47. {
  48. ucByte = *(uint8_t *)ulFlashAddr; // 取1字节出来作比较
  49. if (ucByte != *ucpBuf) // 不一致
  50. {
  51. if (ucByte != 0xFF) // 且不等于默认
  52. {
  53. return FLASH_REQ_ERASE;
  54. }
  55. else
  56. {
  57. ucIsEqu = 0; // 标志位置0,不一致,需要写
  58. }
  59. }
  60. ulFlashAddr++;
  61. ucpBuf++;
  62. }
  63. if (ucIsEqu == 1)
  64. {
  65. return FLASH_IS_EQU; // 一致
  66. }
  67. else
  68. {
  69. return FLASH_REQ_WRITE; // 直接写
  70. }
  71. }
  72. // 16字节整倍数写,不支持跨扇区,扇区8KB,长度不是8字节整数倍,最后几个字节末尾补0写入
  73. static uint8_t bsp_write_cpu_flash(uint32_t ulFlashAddr, uint8_t *ucpSrc, uint32_t ulSize)
  74. {
  75. uint32_t i;
  76. uint8_t ucRet;
  77. if (ulFlashAddr + ulSize > CPU_FLASH_BASE_ADDR + CPU_FLASH_SIZE || ulFlashAddr < CPU_FLASH_BASE_ADDR)
  78. {
  79. return 1;
  80. }
  81. if (ulSize == 0)
  82. {
  83. return 0;
  84. }
  85. //地址必须16字节对齐
  86. if (ulFlashAddr & 15 )
  87. return 1;
  88. ucRet = bsp_cmp_cpu_flash(ulFlashAddr, ucpSrc, ulSize);
  89. if (ucRet == FLASH_IS_EQU)
  90. {
  91. return 0;
  92. }
  93. __set_PRIMASK(1);
  94. HAL_FLASH_Unlock();
  95. for (i = 0; i < ulSize / 16; i++)
  96. {
  97. __ALIGNED(4) uint8_t FlashQuadWord[16] = {0};
  98. memcpy( FlashQuadWord, ucpSrc, 16);
  99. ucpSrc += 16;
  100. if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD, ulFlashAddr, (uint32_t)&FlashQuadWord[0]) == HAL_OK) // 双字64bit
  101. {
  102. ulFlashAddr = ulFlashAddr + 16; // 递增128bit
  103. }
  104. else
  105. {
  106. goto err;
  107. }
  108. }
  109. if (ulSize & 15) // 剩余的部分,如果不是16字节整数倍,剩余部分都是0
  110. {
  111. __ALIGNED(4) uint8_t FlashWord[16] = {0};
  112. memcpy(FlashWord, ucpSrc, ulSize & 15);
  113. uint32_t ptr = (uint32_t)(&FlashWord[0]);
  114. if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD, ulFlashAddr, (uint32_t)(&FlashWord[0])) != HAL_OK)
  115. {
  116. goto err;
  117. }
  118. }
  119. if( HAL_FLASH_Lock() != HAL_OK)
  120. {
  121. goto err;
  122. }
  123. __set_PRIMASK(0);
  124. return 0;
  125. err:
  126. HAL_FLASH_Lock();
  127. __set_PRIMASK(0);
  128. return 1;
  129. }
  130. static uint8_t bsp_erase_cpu_flash(uint32_t ulFlashAddr, uint32_t u2FlashAddr)
  131. {
  132. uint32_t FirstSector = 0, NumofSectors = 0, FinishSector = 0;
  133. FLASH_EraseInitTypeDef EraseInitStruct;
  134. uint32_t SECTOR_ERR = 0;
  135. uint8_t ret;
  136. __set_PRIMASK(1);
  137. HAL_FLASH_Unlock();
  138. // 获取此地址所在的扇区
  139. FirstSector = bsp_get_sector(ulFlashAddr);
  140. FinishSector = bsp_get_sector(u2FlashAddr);
  141. // 固定1个扇区
  142. NumofSectors =
  143. (FinishSector - FirstSector > 0) ? (FinishSector - FirstSector) : 1;
  144. // 擦除扇区配置
  145. EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
  146. EraseInitStruct.Banks = FLASH_BANK_1;
  147. EraseInitStruct.Sector = FirstSector;
  148. EraseInitStruct.NbSectors = NumofSectors;
  149. // 扇区擦除
  150. ret = HAL_FLASHEx_Erase(&EraseInitStruct, &SECTOR_ERR);
  151. HAL_FLASH_Lock();
  152. __set_PRIMASK(0);
  153. return ret;
  154. }
  155. // _CHIP_INFO chip_info;
  156. // static void get_chip_info(void)
  157. // {
  158. // chip_info.ChipUniqueID[0] = *(__IO uint32_t*)(ChipUniqueID_HIGH);
  159. // chip_info.ChipUniqueID[1] = *(__IO uint32_t*)(ChipUniqueID_MEDIUM);
  160. // chip_info.ChipUniqueID[2] = *(__IO uint32_t*)(ChipUniqueID_LOW);
  161. // chip_info.ChipFlashSize = *(__IO uint16_t*)(CHIPFLASHSIZE);
  162. // chip_info.ChipMCUID = *(__IO uint32_t*)(CHIPMCUID);
  163. // }
  164. __FLASH_OPS _flash_ops = {
  165. .Read_Flash = bsp_read_cpu_flash,
  166. .Write_Flash = bsp_write_cpu_flash,
  167. .Erase_Flash = bsp_erase_cpu_flash,
  168. };
  169. __FLASH_OPS *flash_ops = &_flash_ops;