flash.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  1. /**
  2. ******************************************************************************
  3. * @file FLASH.c
  4. * @author
  5. * @brief program the STM32F4xx FLASH.
  6. ******************************************************************************
  7. *
  8. ******************************************************************************
  9. */
  10. /* Includes ------------------------------------------------------------------*/
  11. #include "main.h"
  12. #include "flash.h"
  13. /* Private typedef -----------------------------------------------------------*/
  14. /* Private define ------------------------------------------------------------*/
  15. /* Private macro -------------------------------------------------------------*/
  16. /* Private variables ---------------------------------------------------------*/
  17. /*Variable used for Erase procedure*/
  18. uint8_t flashBuf[FLASH_BUFFER_SIZE] = {0};
  19. /* Private function prototypes -----------------------------------------------*/
  20. static uint32_t GetSector(uint32_t Address);
  21. static uint32_t GetSectorSize(uint32_t Sector);
  22. /* Private functions ---------------------------------------------------------*/
  23. /**
  24. * @brief program
  25. * @param None
  26. * @retval None
  27. */
  28. #if 0
  29. int ProgramFlashPage(uint32_t startAddress, uint32_t endAddress, uint32_t data)
  30. {
  31. uint32_t FirstSector = 0, NbOfSectors = 0, Address = 0;
  32. uint32_t SectorError = 0;
  33. __IO uint32_t data32 = 0 , MemoryProgramStatus = 0;
  34. FLASH_EraseInitTypeDef EraseInitStruct;
  35. int retval=0;
  36. /* Unlock the Flash to enable the flash control register access *************/
  37. HAL_FLASH_Unlock();
  38. /* Get the 1st sector to erase */
  39. FirstSector = GetSector(startAddress);
  40. /* Get the number of sector to erase from 1st sector*/
  41. NbOfSectors = GetSector(endAddress) - FirstSector + 1;
  42. /* Fill EraseInit structure*/
  43. EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
  44. EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
  45. EraseInitStruct.Sector = FirstSector;
  46. EraseInitStruct.NbSectors = NbOfSectors;
  47. if(HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK)
  48. {
  49. /*
  50. Error occurred while sector erase.
  51. User can add here some code to deal with this error.
  52. SectorError will contain the faulty sector and then to know the code error on this sector,
  53. user can call function 'HAL_FLASH_GetError()'
  54. */
  55. retval = -1;
  56. }
  57. else
  58. {
  59. /* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
  60. you have to make sure that these data are rewritten before they are accessed during code
  61. execution. If this cannot be done safely, it is recommended to flush the caches by setting the
  62. DCRST and ICRST bits in the FLASH_CR register. */
  63. __HAL_FLASH_DATA_CACHE_DISABLE();
  64. __HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
  65. __HAL_FLASH_DATA_CACHE_RESET();
  66. __HAL_FLASH_INSTRUCTION_CACHE_RESET();
  67. __HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
  68. __HAL_FLASH_DATA_CACHE_ENABLE();
  69. /* Program the user Flash area word by word ***********/
  70. Address = startAddress;
  71. while (Address < endAddress)
  72. {
  73. if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Address, data) == HAL_OK)
  74. {
  75. Address = Address + 4;
  76. }
  77. else
  78. {
  79. /* Error occurred while writing data in Flash memory.
  80. User can add here some code to deal with this error */
  81. retval = -2;
  82. }
  83. }
  84. }
  85. /* Lock the Flash to disable the flash control register access (recommended
  86. to protect the FLASH memory against possible unwanted operation) *********/
  87. HAL_FLASH_Lock();
  88. if(retval==0)
  89. {
  90. /* Check if the programmed data is OK
  91. MemoryProgramStatus = 0: data programmed correctly
  92. MemoryProgramStatus != 0: number of words not programmed correctly ******/
  93. Address = startAddress;
  94. MemoryProgramStatus = 0;
  95. while (Address < endAddress)
  96. {
  97. data32 = *(__IO uint32_t*)Address;
  98. if (data32 != data)
  99. {
  100. MemoryProgramStatus++;
  101. }
  102. Address = Address + 4;
  103. }
  104. }
  105. /* Check if there is an issue to program data */
  106. if (MemoryProgramStatus == 0)
  107. {
  108. }
  109. else
  110. {
  111. retval = -3;
  112. }
  113. return retval;
  114. }
  115. #else
  116. int ProgramFlashPage(uint32_t startAddress, const uint8_t* data, uint32_t len)
  117. {
  118. uint32_t FirstSector = 0, NbOfSectors = 0, Address = 0, endAddress = 0;
  119. uint32_t SectorError = 0;
  120. __IO uint32_t data32 = 0 , MemoryProgramStatus = 0;
  121. uint32_t* pData = 0;
  122. FLASH_EraseInitTypeDef EraseInitStruct;
  123. int retval=0;
  124. HAL_StatusTypeDef status;
  125. Address = startAddress & (uint32_t)(~(FLASH_USER_PAGE_SIZE - 1));
  126. endAddress = (startAddress + len + sizeof(uint64_t) -1) & (uint32_t)(~(sizeof(uint64_t)-1));
  127. if( endAddress >= Address + FLASH_USER_PAGE_SIZE || FLASH_BUFFER_SIZE < len)//
  128. {
  129. return -1;
  130. }
  131. memcpy((void*)flashBuf, (void const*)Address, FLASH_BUFFER_SIZE);
  132. memcpy((void*)(flashBuf + (startAddress - Address)), (void const*)data, len);
  133. /* Unlock the Flash to enable the flash control register access *************/
  134. ClearFlashWriteProtect();
  135. HAL_FLASH_Unlock();
  136. /* Get the 1st sector to erase */
  137. FirstSector = GetSector(startAddress);
  138. /* Get the number of sector to erase from 1st sector*/
  139. //NbOfSectors = GetSector(endAddress) - FirstSector + 1;
  140. NbOfSectors = 1;
  141. /* Fill EraseInit structure*/
  142. EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
  143. EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
  144. EraseInitStruct.Sector = FirstSector;
  145. EraseInitStruct.NbSectors = NbOfSectors;
  146. status = HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError);
  147. if(status != HAL_OK)
  148. {
  149. /*
  150. Error occurred while sector erase.
  151. User can add here some code to deal with this error.
  152. SectorError will contain the faulty sector and then to know the code error on this sector,
  153. user can call function 'HAL_FLASH_GetError()'
  154. */
  155. retval = -1;
  156. }
  157. else
  158. {
  159. /* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
  160. you have to make sure that these data are rewritten before they are accessed during code
  161. execution. If this cannot be done safely, it is recommended to flush the caches by setting the
  162. DCRST and ICRST bits in the FLASH_CR register. */
  163. __HAL_FLASH_DATA_CACHE_DISABLE();
  164. __HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
  165. __HAL_FLASH_DATA_CACHE_RESET();
  166. __HAL_FLASH_INSTRUCTION_CACHE_RESET();
  167. __HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
  168. __HAL_FLASH_DATA_CACHE_ENABLE();
  169. /* Program the user Flash area word by word ***********/
  170. Address = FLASH_USER_START_ADDR;
  171. endAddress = Address + FLASH_BUFFER_SIZE;
  172. pData = (uint32_t*)flashBuf;
  173. while (Address < endAddress)
  174. {
  175. status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Address, *pData);
  176. if (status == HAL_OK)
  177. {
  178. Address = Address + 4;
  179. pData++;
  180. }
  181. else
  182. {
  183. /* Error occurred while writing data in Flash memory.
  184. User can add here some code to deal with this error */
  185. retval = -2;
  186. break;
  187. }
  188. }
  189. }
  190. /* Lock the Flash to disable the flash control register access (recommended
  191. to protect the FLASH memory against possible unwanted operation) *********/
  192. SetFlashWriteProtect();
  193. if(retval==0)
  194. {
  195. /* Check if the programmed data is OK
  196. MemoryProgramStatus = 0: data programmed correctly
  197. MemoryProgramStatus != 0: number of words not programmed correctly ******/
  198. Address = FLASH_USER_START_ADDR;
  199. pData = (uint32_t*)flashBuf;
  200. MemoryProgramStatus = 0;
  201. while (Address < endAddress)
  202. {
  203. data32 = *(__IO uint32_t*)Address;
  204. if (data32 != *pData)
  205. {
  206. MemoryProgramStatus++;
  207. }
  208. Address = Address + 4;
  209. pData++;
  210. }
  211. /* Check if there is an issue to program data */
  212. if (MemoryProgramStatus == 0)
  213. {
  214. retval = 0;
  215. }
  216. else
  217. {
  218. retval = -3;
  219. }
  220. }
  221. return retval;
  222. }
  223. #endif
  224. int EraseFlashProgram(uint32_t startAddress, uint32_t length)
  225. {
  226. uint32_t FirstSector = 0, NbOfSectors = 0;
  227. uint32_t SectorError = 0,endAddress=0;
  228. FLASH_EraseInitTypeDef EraseInitStruct;
  229. int retval=0;
  230. HAL_StatusTypeDef status;
  231. /* Unlock the Flash to enable the flash control register access *************/
  232. HAL_FLASH_Unlock();
  233. /* Get the 1st sector to erase */
  234. FirstSector = GetSector(startAddress);
  235. /* Get the number of sector to erase from 1st sector*/
  236. endAddress = startAddress + length;
  237. NbOfSectors = GetSector(endAddress) - FirstSector + 1;
  238. /* Fill EraseInit structure*/
  239. EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
  240. EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
  241. EraseInitStruct.Sector = FirstSector;
  242. EraseInitStruct.NbSectors = NbOfSectors;
  243. status = HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError);
  244. if(HAL_OK != status)
  245. {
  246. /*
  247. Error occurred while sector erase.
  248. User can add here some code to deal with this error.
  249. SectorError will contain the faulty sector and then to know the code error on this sector,
  250. user can call function 'HAL_FLASH_GetError()'
  251. */
  252. retval = -1;
  253. }
  254. else
  255. {
  256. retval = 1;
  257. }
  258. return retval;
  259. }
  260. int WriteData2FlashProgram(uint32_t startAddress, const uint8_t* data, uint32_t length)
  261. {
  262. int retval = 1;
  263. uint32_t endAddress = startAddress + length, curAddress = startAddress;
  264. uint32_t* pData = (uint32_t*)data;
  265. /* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
  266. you have to make sure that these data are rewritten before they are accessed during code
  267. execution. If this cannot be done safely, it is recommended to flush the caches by setting the
  268. DCRST and ICRST bits in the FLASH_CR register. */
  269. __HAL_FLASH_DATA_CACHE_DISABLE();
  270. __HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
  271. __HAL_FLASH_DATA_CACHE_RESET();
  272. __HAL_FLASH_INSTRUCTION_CACHE_RESET();
  273. __HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
  274. __HAL_FLASH_DATA_CACHE_ENABLE();
  275. /* Program the user Flash area word by word ***********/
  276. while (curAddress < endAddress)
  277. {
  278. if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, curAddress, *pData) == HAL_OK)
  279. {
  280. curAddress += sizeof(uint32_t);
  281. pData++;
  282. }
  283. else
  284. {
  285. /* Error occurred while writing data in Flash memory.
  286. User can add here some code to deal with this error */
  287. retval = -2;
  288. }
  289. }
  290. return retval;;
  291. }
  292. int FinishFlashProgram(uint32_t startAddress, uint32_t length)
  293. {
  294. int retval = 1;
  295. /* Lock the Flash to disable the flash control register access (recommended
  296. to protect the FLASH memory against possible unwanted operation) *********/
  297. HAL_FLASH_Lock();
  298. return retval;
  299. }
  300. /**
  301. * @brief Gets the sector of a given address
  302. * @param None
  303. * @retval The sector of a given address
  304. */
  305. static uint32_t GetSector(uint32_t Address)
  306. {
  307. uint32_t sector = 0;
  308. if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0))
  309. {
  310. sector = FLASH_SECTOR_0;
  311. }
  312. else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1))
  313. {
  314. sector = FLASH_SECTOR_1;
  315. }
  316. else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2))
  317. {
  318. sector = FLASH_SECTOR_2;
  319. }
  320. else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3))
  321. {
  322. sector = FLASH_SECTOR_3;
  323. }
  324. else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4))
  325. {
  326. sector = FLASH_SECTOR_4;
  327. }
  328. else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5))
  329. {
  330. sector = FLASH_SECTOR_5;
  331. }
  332. else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6))
  333. {
  334. sector = FLASH_SECTOR_6;
  335. }
  336. else if((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7))
  337. {
  338. sector = FLASH_SECTOR_7;
  339. }
  340. else if((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8))
  341. {
  342. sector = FLASH_SECTOR_8;
  343. }
  344. else if((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9))
  345. {
  346. sector = FLASH_SECTOR_9;
  347. }
  348. else if((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10))
  349. {
  350. sector = FLASH_SECTOR_10;
  351. }
  352. else /* (Address < FLASH_END_ADDR) && (Address >= ADDR_FLASH_SECTOR_11) */
  353. {
  354. sector = FLASH_SECTOR_11;
  355. }
  356. return sector;
  357. }
  358. /**
  359. * @brief Gets sector Size
  360. * @param None
  361. * @retval The size of a given sector
  362. */
  363. static uint32_t GetSectorSize(uint32_t Sector)
  364. {
  365. uint32_t sectorsize = 0x00;
  366. if((Sector == FLASH_SECTOR_0) || (Sector == FLASH_SECTOR_1) || (Sector == FLASH_SECTOR_2) || (Sector == FLASH_SECTOR_3))
  367. {
  368. sectorsize = 16 * 1024;
  369. }
  370. else if(Sector == FLASH_SECTOR_4)
  371. {
  372. sectorsize = 64 * 1024;
  373. }
  374. else
  375. {
  376. sectorsize = 128 * 1024;
  377. }
  378. return sectorsize;
  379. }
  380. void SetFlashReadProtect(void)
  381. {
  382. FLASH_OBProgramInitTypeDef OBInit={0};
  383. HAL_FLASHEx_OBGetConfig(&OBInit);
  384. if(OB_RDP_LEVEL_0 == OBInit.RDPLevel)
  385. {
  386. OBInit.OptionType = OPTIONBYTE_RDP;
  387. OBInit.RDPLevel = OB_RDP_LEVEL_1;
  388. /* Allow Access to option bytes sector */
  389. HAL_FLASH_OB_Unlock();
  390. /* Allow Access to Flash control registers and user Flash */
  391. HAL_FLASH_Unlock();
  392. HAL_FLASHEx_OBProgram(&OBInit);
  393. /* Prevent Access to option bytes sector */
  394. HAL_FLASH_OB_Lock();
  395. /* Disable the Flash option control register access (recommended to protect
  396. the option Bytes against possible unwanted operations) */
  397. HAL_FLASH_Lock();
  398. }
  399. }
  400. void SetFlashWriteProtect(void)
  401. {
  402. FLASH_OBProgramInitTypeDef OBInit={0};
  403. HAL_FLASHEx_OBGetConfig(&OBInit);
  404. if(OB_WRPSTATE_DISABLE == OBInit.WRPState || OB_WRP_SECTOR_All != OBInit.WRPSector)
  405. {
  406. OBInit.OptionType = OPTIONBYTE_WRP;
  407. OBInit.WRPState = OB_WRPSTATE_ENABLE;
  408. OBInit.WRPSector = OB_WRP_SECTOR_All;
  409. OBInit.Banks = FLASH_BANK_1;
  410. /* Allow Access to option bytes sector */
  411. HAL_FLASH_OB_Unlock();
  412. /* Allow Access to Flash control registers and user Flash */
  413. HAL_FLASH_Unlock();
  414. HAL_StatusTypeDef status = HAL_FLASHEx_OBProgram(&OBInit);
  415. /* Prevent Access to option bytes sector */
  416. HAL_FLASH_OB_Lock();
  417. /* Disable the Flash option control register access (recommended to protect
  418. the option Bytes against possible unwanted operations) */
  419. HAL_FLASH_Lock();
  420. if(HAL_OK != status)
  421. {
  422. return;
  423. }
  424. }
  425. }
  426. void ClearFlashWriteProtect(void)
  427. {
  428. FLASH_OBProgramInitTypeDef OBInit={0};
  429. HAL_FLASHEx_OBGetConfig(&OBInit);
  430. //if(OB_WRPSTATE_ENABLE == OBInit.WRPState)
  431. {
  432. OBInit.OptionType = OPTIONBYTE_WRP;
  433. OBInit.WRPState = OB_WRPSTATE_DISABLE;
  434. OBInit.WRPSector = OB_WRP_SECTOR_All;
  435. OBInit.Banks = FLASH_BANK_1;
  436. /* Allow Access to option bytes sector */
  437. HAL_FLASH_OB_Unlock();
  438. /* Allow Access to Flash control registers and user Flash */
  439. HAL_FLASH_Unlock();
  440. HAL_StatusTypeDef status = HAL_FLASHEx_OBProgram(&OBInit);
  441. /* Prevent Access to option bytes sector */
  442. HAL_FLASH_OB_Lock();
  443. /* Disable the Flash option control register access (recommended to protect
  444. the option Bytes against possible unwanted operations) */
  445. HAL_FLASH_Lock();
  446. if(HAL_OK != status)
  447. {
  448. return;
  449. }
  450. }
  451. }
  452. void SetBORLevel(void)
  453. {
  454. FLASH_OBProgramInitTypeDef OBInit={0};
  455. HAL_FLASHEx_OBGetConfig(&OBInit);
  456. if(OB_BOR_LEVEL3 != OBInit.BORLevel)
  457. {
  458. OBInit.OptionType = OPTIONBYTE_BOR;
  459. OBInit.BORLevel = OB_BOR_LEVEL3;
  460. /* Allow Access to option bytes sector */
  461. HAL_FLASH_OB_Unlock();
  462. /* Allow Access to Flash control registers and user Flash */
  463. HAL_FLASH_Unlock();
  464. HAL_FLASHEx_OBProgram(&OBInit);
  465. /* Prevent Access to option bytes sector */
  466. HAL_FLASH_OB_Lock();
  467. /* Disable the Flash option control register access (recommended to protect
  468. the option Bytes against possible unwanted operations) */
  469. HAL_FLASH_Lock();
  470. }
  471. }
  472. /*********************************END OF FILE**********************************/