drv_chipFlash.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. #include "drv_chipFlash.h"
  2. #include "stm32l4xx.h"
  3. #include "stm32l4xx_hal_flash.h"
  4. #include "drv_IAP.h"
  5. //#define TEST
  6. //unsigned short ipaFlag = 0;
  7. //BASE_CONFIG base_config;
  8. //从指定地址开始读取多个数据
  9. int FLASH_ReadMoreData(uint32_t startAddress, uint64_t *readData, uint32_t countToRead){
  10. //数据大小必须双字节对齐
  11. if(countToRead % 8 != 0 )
  12. return -1;
  13. uint16_t dataIndex = 0;
  14. for(dataIndex = 0; dataIndex < (countToRead / 8); dataIndex++){
  15. readData[dataIndex] = FLASH_ReadDoubleWord(startAddress + dataIndex * 8);
  16. }
  17. return 0;
  18. }
  19. //读取指定地址的半字(16位数据)
  20. uint16_t FLASH_ReadHalfWord(uint32_t address){
  21. return *(volatile uint16_t *)address;
  22. }
  23. //读取指定地址的双字(64位数据)
  24. uint64_t FLASH_ReadDoubleWord(uint32_t address){
  25. return *(volatile uint64_t *)address;
  26. }
  27. //擦除指定地址的扇区
  28. int FLASH_ErasePage(uint32_t StartPage, uint32_t PageNumber){
  29. FLASH_EraseInitTypeDef eraseInit = {0};
  30. uint32_t PageError = 0;
  31. eraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
  32. eraseInit.Page = StartPage;
  33. eraseInit.NbPages = PageNumber;
  34. //关闭中断
  35. __disable_irq();
  36. //HAL_NVIC_DisableIRQ(SysTick_IRQn);
  37. if(HAL_FLASHEx_Erase(&eraseInit, &PageError) != HAL_OK){
  38. //恢复中断
  39. __enable_irq();
  40. //HAL_NVIC_EnableIRQ(SysTick_IRQn);
  41. return -1;
  42. }
  43. //恢复中断
  44. __enable_irq();
  45. //HAL_NVIC_EnableIRQ(SysTick_IRQn);
  46. return 0;
  47. }
  48. void erasure_bin_flash(void){
  49. HAL_FLASH_Unlock();
  50. __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_PGSERR | FLASH_FLAG_PROGERR | FLASH_FLAG_BSY
  51. | FLASH_FLAG_WRPERR | FLASH_FLAG_OPTVERR );
  52. //获取APP开始地址所在扇区
  53. uint32_t UserStartSector = (APPLICATION_ADDRESS - FLASH_BASE) / SECTOR_SIZE;
  54. //获取APP结束地址所在扇区
  55. uint32_t UserEndSector = UserStartSector + (iap_bin_Size + SECTOR_SIZE - 1) / SECTOR_SIZE;
  56. // 如果结束地址错误。APP地址从FLASH_Sector_4开始
  57. if(UserEndSector < UserStartSector){
  58. while(1){
  59. send_mavlink_bootloader_status(BOOTLOADER_STATUS_FLASH_ERASOR_ERROR);
  60. HAL_Delay(600);
  61. }
  62. }
  63. // 擦写到FLASH_Sector_7需要3.5s时间
  64. for(uint32_t i = UserStartSector; i <= UserEndSector; i++){
  65. //驱动电压在[2.7V to 3.6V]范围内,擦除操作将按字擦除
  66. if(FLASH_ErasePage(i, 1)!= 0){
  67. HAL_FLASH_Lock();
  68. while(1){
  69. //擦除失败
  70. send_mavlink_bootloader_status(BOOTLOADER_STATUS_FLASH_ERASOR_ERROR);
  71. HAL_Delay(600);
  72. }
  73. }
  74. }
  75. }
  76. // int FLASH_Write(volatile uint32_t FlashAddress, uint32_t *WriteData, uint32_t DataLength){
  77. // uint32_t i =0;
  78. // //解锁
  79. // HAL_FLASH_Unlock();
  80. // for(i = 0; (i < DataLength) && (FlashAddress <= (USER_FLASH_END_ADDR - 4)); i++){
  81. // __disable_irq();
  82. // //if(FLASH_WriteMoreData(FlashAddress, (uint32_t *)(WriteData + i), 4) == 0)
  83. // if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, FlashAddress, *(uint32_t*)(WriteData + i))== HAL_OK)
  84. // {
  85. // __enable_irq();
  86. // if(*(uint32_t *)FlashAddress != *(uint32_t*)(WriteData + i)){
  87. // //FLASH中数据与SRAM中内容不一致
  88. // //写操作上锁
  89. // HAL_FLASH_Lock();
  90. // return -1;
  91. // }
  92. // FlashAddress += 4;
  93. // }
  94. // else{
  95. // __enable_irq();
  96. // //写操作上锁
  97. // HAL_FLASH_Lock();
  98. // //编程Flash memory时发生错误
  99. // return -1;
  100. // }
  101. // }
  102. // __enable_irq();
  103. // //写操作上锁
  104. // HAL_FLASH_Lock();
  105. // cur_address = FlashAddress;
  106. // return 0;
  107. // }
  108. // int FLASH_Write_HalfWord(volatile uint32_t FlashAddress, uint16_t *WriteData, uint16_t DataLength){
  109. // //解锁
  110. // HAL_FLASH_Unlock();
  111. // uint32_t i =0;
  112. // for(i = 0; (i < DataLength) && (FlashAddress <= (USER_FLASH_END_ADDR - 2)); i++)
  113. // {
  114. // __disable_irq();
  115. // if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, FlashAddress, *(uint16_t*)(WriteData + i)) == HAL_OK)
  116. // {
  117. // __enable_irq();
  118. // if(*(uint16_t *)FlashAddress!= *(uint16_t*)(WriteData + i)){
  119. // //FLASH中数据与SRAM中内容不一致
  120. // //写操作上锁
  121. // HAL_FLASH_Lock();
  122. // return -1;
  123. // }
  124. // FlashAddress += 2;
  125. // }
  126. // else{
  127. // __enable_irq();
  128. // //写操作上锁
  129. // HAL_FLASH_Lock();
  130. // //编程Flash memory时发生错误
  131. // return -1;
  132. // }
  133. // }
  134. // __enable_irq();
  135. // //写操作上锁
  136. // HAL_FLASH_Lock();
  137. // cur_address = FlashAddress;
  138. // return 0;
  139. // }
  140. int FLASH_Write_DoubleWord(volatile uint32_t FlashAddress, uint64_t *WriteData, uint16_t DataLength){
  141. //解锁
  142. HAL_FLASH_Unlock();
  143. uint32_t i =0;
  144. for(i = 0; (i < DataLength) && (FlashAddress <= (USER_FLASH_END_ADDR - 2)); i++)
  145. {
  146. __disable_irq();
  147. if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, FlashAddress, *(uint64_t*)(WriteData + i)) == HAL_OK)
  148. {
  149. __enable_irq();
  150. if(*(uint64_t *)FlashAddress!= *(uint64_t*)(WriteData + i)){
  151. //FLASH中数据与SRAM中内容不一致
  152. //写操作上锁
  153. HAL_FLASH_Lock();
  154. return -1;
  155. }
  156. FlashAddress += 8;
  157. }
  158. else{
  159. __enable_irq();
  160. //写操作上锁
  161. HAL_FLASH_Lock();
  162. //编程Flash memory时发生错误
  163. return -1;
  164. }
  165. }
  166. __enable_irq();
  167. //写操作上锁
  168. HAL_FLASH_Lock();
  169. cur_address = FlashAddress;
  170. return 0;
  171. }