drv_chipFlash.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. #include "drv_chipFlash.h"
  2. #include "stm32f1xx.h"
  3. //#include "stm32f103xb.h"
  4. #include "stm32f1xx_hal_flash.h"
  5. #include "drv_IAP.h"
  6. //#define TEST
  7. //unsigned short ipaFlag = 0;
  8. //BASE_CONFIG base_config;
  9. Cclient_info client_info;
  10. //从指定地址开始读取多个数据
  11. int FLASH_ReadMoreData(uint32_t startAddress, uint32_t *readData, uint32_t countToRead){
  12. #ifdef TEST
  13. //解锁
  14. HAL_FLASH_Unlock();
  15. uint32_t offsetAddress = startAddress - FLASH_BASE; //计算实际偏移地址
  16. uint32_t sectorPosition = offsetAddress / SECTOR_SIZE; //计算扇区位置
  17. uint32_t sectorStartAddress = sectorPosition * SECTOR_SIZE + FLASH_BASE; //计算扇区起始地址
  18. if(FLASH_ErasePage(sectorStartAddress, 1) != 0){
  19. //写操作上锁
  20. HAL_FLASH_Lock();
  21. return -1;
  22. }
  23. HAL_FLASH_Lock();
  24. #endif
  25. //数据大小必须双字节对齐
  26. if(countToRead % 2 != 0 )
  27. return -1;
  28. uint16_t dataIndex = 0;
  29. for(dataIndex = 0; dataIndex < (countToRead / 2); dataIndex++){
  30. readData[dataIndex] = FLASH_ReadHalfWord(startAddress + dataIndex * 2);
  31. }
  32. return 0;
  33. }
  34. //读取指定地址的半字(16位数据)
  35. uint16_t FLASH_ReadHalfWord(uint32_t address){
  36. return *(volatile uint16_t *)address;
  37. }
  38. //读取指定地址的全字(32位数据)
  39. static uint32_t FLASH_ReadWord(uint32_t address){
  40. uint32_t temp1 = 0, temp2 = 0;
  41. temp1 = *(volatile uint16_t *)address;
  42. temp2 = *(volatile uint16_t *)(address + 2);
  43. return (temp2 << 16) | temp1;
  44. }
  45. //擦除指定地址的扇区
  46. int FLASH_ErasePage(uint32_t ErasePageAddr, uint32_t PageNumber){
  47. FLASH_EraseInitTypeDef eraseInit = {0};
  48. uint32_t PageError = 0;
  49. eraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
  50. eraseInit.PageAddress = ErasePageAddr;
  51. eraseInit.NbPages = PageNumber;
  52. //关闭中断
  53. __disable_irq();
  54. //HAL_NVIC_DisableIRQ(SysTick_IRQn);
  55. if(HAL_FLASHEx_Erase(&eraseInit, &PageError) != HAL_OK){
  56. //恢复中断
  57. __enable_irq();
  58. //HAL_NVIC_EnableIRQ(SysTick_IRQn);
  59. return -1;
  60. }
  61. //恢复中断
  62. __enable_irq();
  63. //HAL_NVIC_EnableIRQ(SysTick_IRQn);
  64. return 0;
  65. }
  66. //从指定地址开始写入多个数据
  67. int FLASH_WriteMoreData(uint32_t startAddress, uint32_t *writeData, uint32_t countToWrite){
  68. //非法地址
  69. if(startAddress < FLASH_BASE || ((startAddress + countToWrite) >= (FLASH_BASE + 1024 * CHIPFLASH_SIZE)))
  70. return -1;
  71. //数据大小必须双字节对齐
  72. if(countToWrite % 2!= 0 )
  73. return -1;
  74. //解锁
  75. HAL_FLASH_Unlock();
  76. //计算扇区信息
  77. uint32_t offsetAddress = startAddress - FLASH_BASE; //计算实际偏移地址
  78. uint32_t sectorPosition = offsetAddress / SECTOR_SIZE; //计算扇区位置
  79. uint32_t sectorStartAddress = sectorPosition * SECTOR_SIZE + FLASH_BASE; //计算扇区起始地址
  80. //启用扇区擦除
  81. if(FLASH_ErasePage(sectorStartAddress, 1) != 0){
  82. //写操作上锁
  83. HAL_FLASH_Lock();
  84. return -1;
  85. }
  86. uint16_t dataIndex = 0;
  87. for(dataIndex = 0; dataIndex < (countToWrite / 2); dataIndex++){
  88. __disable_irq();
  89. if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, startAddress + dataIndex * 2
  90. , writeData[dataIndex]) != HAL_OK){
  91. __enable_irq();
  92. //写操作上锁
  93. HAL_FLASH_Lock();
  94. return -1;
  95. }
  96. }
  97. __enable_irq();
  98. //写操作上锁
  99. HAL_FLASH_Lock();
  100. return 0;
  101. }
  102. int FLASH_INFO_SetFlag(void){
  103. #ifdef FUNC
  104. uint8_t *p = (uint8_t *)&client_info;
  105. int i;
  106. int count = 0;
  107. for(i = 0; i < sizeof(client_info); i++){
  108. if(p[i] != 0xFF){
  109. count = 0;
  110. }
  111. if(p[i] == 0xFF){
  112. count++;
  113. }
  114. }
  115. if(count == sizeof(client_info)){
  116. return -1;
  117. }
  118. #endif
  119. if(client_info._init_flag == 1){
  120. return 0;
  121. }
  122. return -1;
  123. }
  124. void erasure_bin_flash(void){
  125. HAL_FLASH_Unlock();
  126. __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_BSY
  127. | FLASH_FLAG_WRPERR | FLASH_FLAG_OPTVERR );
  128. //获取APP开始地址所在扇区
  129. uint32_t UserStartSector = (APPLICATION_ADDRESS - FLASH_BASE) / SECTOR_SIZE;
  130. //获取APP结束地址所在扇区
  131. uint32_t UserEndSector = UserStartSector + (iap_bin_Size + SECTOR_SIZE - 1) / SECTOR_SIZE;
  132. // 如果结束地址错误。APP地址从FLASH_Sector_4开始
  133. if(UserEndSector < UserStartSector){
  134. while(1){
  135. send_mavlink_bootloader_status(BOOTLOADER_STATUS_FLASH_ERASOR_ERROR);
  136. HAL_Delay(600);
  137. }
  138. }
  139. // 擦写到FLASH_Sector_7需要3.5s时间
  140. for(uint32_t i = UserStartSector; i <= UserEndSector; i++){
  141. //驱动电压在[2.7V to 3.6V]范围内,擦除操作将按字擦除
  142. if(FLASH_ErasePage(FLASH_BASE + i * SECTOR_SIZE, 1)!= 0){
  143. HAL_FLASH_Lock();
  144. while(1){
  145. //擦除失败
  146. send_mavlink_bootloader_status(BOOTLOADER_STATUS_FLASH_ERASOR_ERROR);
  147. HAL_Delay(600);
  148. }
  149. }
  150. }
  151. }
  152. int FLASH_Write(volatile uint32_t FlashAddress, uint32_t *WriteData, uint32_t DataLength){
  153. uint32_t i =0;
  154. //解锁
  155. HAL_FLASH_Unlock();
  156. for(i = 0; (i < DataLength) && (FlashAddress <= (USER_FLASH_END_ADDR - 4)); i++){
  157. __disable_irq();
  158. //if(FLASH_WriteMoreData(FlashAddress, (uint32_t *)(WriteData + i), 4) == 0)
  159. if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, FlashAddress, *(uint32_t*)(WriteData + i))== HAL_OK)
  160. {
  161. __enable_irq();
  162. if(*(uint32_t *)FlashAddress != *(uint32_t*)(WriteData + i)){
  163. //FLASH中数据与SRAM中内容不一致
  164. //写操作上锁
  165. HAL_FLASH_Lock();
  166. return -1;
  167. }
  168. FlashAddress += 4;
  169. }
  170. else{
  171. __enable_irq();
  172. //写操作上锁
  173. HAL_FLASH_Lock();
  174. //编程Flash memory时发生错误
  175. return -1;
  176. }
  177. }
  178. __enable_irq();
  179. //写操作上锁
  180. HAL_FLASH_Lock();
  181. cur_address = FlashAddress;
  182. return 0;
  183. }
  184. int FLASH_Write_HalfWord(volatile uint32_t FlashAddress, uint16_t *WriteData, uint16_t DataLength){
  185. //解锁
  186. HAL_FLASH_Unlock();
  187. uint32_t i =0;
  188. for(i = 0; (i < DataLength) && (FlashAddress <= (USER_FLASH_END_ADDR - 2)); i++)
  189. {
  190. __disable_irq();
  191. if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, FlashAddress, *(uint16_t*)(WriteData + i)) == HAL_OK)
  192. {
  193. __enable_irq();
  194. if(*(uint16_t *)FlashAddress!= *(uint16_t*)(WriteData + i)){
  195. //FLASH中数据与SRAM中内容不一致
  196. //写操作上锁
  197. HAL_FLASH_Lock();
  198. return -1;
  199. }
  200. FlashAddress += 2;
  201. }
  202. else{
  203. __enable_irq();
  204. //写操作上锁
  205. HAL_FLASH_Lock();
  206. //编程Flash memory时发生错误
  207. return -1;
  208. }
  209. }
  210. __enable_irq();
  211. //写操作上锁
  212. HAL_FLASH_Lock();
  213. cur_address = FlashAddress;
  214. return 0;
  215. }