gd32f10x_fmc.c 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166
  1. /**
  2. ******************************************************************************
  3. * @brief FMC functions of the firmware library.
  4. ******************************************************************************/
  5. /* Includes ------------------------------------------------------------------*/
  6. #include "gd32f10x_fmc.h"
  7. /** @addtogroup GD32F10x_Firmware
  8. * @{
  9. */
  10. /** @defgroup FMC
  11. * @brief FMC driver modules
  12. * @{
  13. */
  14. /** @defgroup FMC_Private_Functions
  15. * @{
  16. */
  17. /** @defgroup FMC_Group1 FMC Memory Programming functions
  18. * @brief FMC Memory Programming functions
  19. *
  20. @verbatim
  21. ===============================================================================
  22. ##### FMC Memory Programming functions #####
  23. ===============================================================================
  24. [..] The FMC Memory Programming functions, includes the following functions:
  25. (+) void FMC_Unlock(void);
  26. (+) void FMC_UnlockBank1(void);
  27. (+) void FMC_UnlockBank2(void);
  28. (+) void FMC_Lock(void);
  29. (+) void FMC_LockBank1(void)
  30. (+) void FMC_LockBank2(void)
  31. (+) FMC_State FMC_ErasePage(uint32_t Page_Address);
  32. (+) FMC_State FMC_MassErase(void);
  33. (+) FMC_State FMC_MassBank1Erase(void)
  34. (+) FMC_State FMC_MassBank2Erase(void)
  35. (+) FMC_State FMC_ProgramWord(uint32_t Address, uint32_t Data);
  36. [..] Any operation of erase or program should follow these steps:
  37. (#) Call the FMC_Unlock() function to unlock the FMC operation
  38. (#) Call erase or program data
  39. (#) Call the FMC_Lock() to lock the FMC operation
  40. @endverbatim
  41. * @{
  42. */
  43. /**
  44. * @brief Unlock the main FMC operation.
  45. * @param None
  46. * @retval None
  47. */
  48. void FMC_Unlock(void)
  49. {
  50. if ((FMC->CMR & FMC_CMR_LK) != RESET) {
  51. /* Write the FMC key */
  52. FMC->UKEYR = FMC_KEY1;
  53. FMC->UKEYR = FMC_KEY2;
  54. }
  55. if (FMC_SIZE > FMC_BANK1_SIZE) {
  56. /* Authorize the FPEC of Bank2 Access */
  57. if ((FMC->CMR2 & FMC_CMR_LK) != RESET) {
  58. FMC->UKEYR2 = FMC_KEY1;
  59. FMC->UKEYR2 = FMC_KEY2;
  60. }
  61. }
  62. }
  63. /**
  64. * @brief Unlocks the FMC Bank1 Program Erase Controller.
  65. * @note This function can be used for all GD32F10x devices.
  66. * - For GD32F10X_XD and GD32F10X_CL devices this function unlocks Bank1.
  67. * - For all other devices it unlocks Bank1 and it is
  68. * equivalent to FLASH_Unlock function.
  69. * @param None
  70. * @retval None
  71. */
  72. void FMC_UnlockB1(void)
  73. {
  74. /* Authorize the FPEC of Bank1 Access */
  75. if ((FMC->CMR & FMC_CMR_LK) != RESET) {
  76. FMC->UKEYR = FMC_KEY1;
  77. FMC->UKEYR = FMC_KEY2;
  78. }
  79. }
  80. /**
  81. * @brief Unlocks the FMC Bank2 Program Erase Controller.
  82. * @note This function can be used for GD32F10X_XD and GD32F10X_CL density devices.
  83. * @param None
  84. * @retval None
  85. */
  86. #if defined GD32F10X_XD || defined GD32F10X_CL
  87. void FMC_UnlockB2(void)
  88. {
  89. /* Authorize the FPEC of Bank2 Access */
  90. if ((FMC->CMR2 & FMC_CMR_LK) != RESET) {
  91. FMC->UKEYR2 = FMC_KEY1;
  92. FMC->UKEYR2 = FMC_KEY2;
  93. }
  94. }
  95. #endif /* GD32F10X_XD and GD32F10X_CL */
  96. /**
  97. * @brief Lock the main FMC operation.
  98. * @param None
  99. * @retval None
  100. */
  101. void FMC_Lock(void)
  102. {
  103. /* Set the LOCK bit*/
  104. FMC->CMR |= FMC_CMR_LK;
  105. if (FMC_SIZE > FMC_BANK1_SIZE) {
  106. /* Set the Lock Bit to lock the FPEC and the CR of Bank2 */
  107. FMC->CMR2 |= FMC_CMR_LK;
  108. }
  109. }
  110. /**
  111. * @brief Locks the FMC Bank1 Program Erase Controller.
  112. * @note this function can be used for all GD32F10X devices.
  113. * - For GD32F10X_XD and GD32F10X_CL devices this function Locks Bank1.
  114. * - For all other devices it Locks Bank1 and it is equivalent
  115. * to FMC_Lock function.
  116. * @param None
  117. * @retval None
  118. */
  119. void FMC_LockB1(void)
  120. {
  121. /* Set the Lock Bit to lock the FPEC and the CMR of Bank1 */
  122. FMC->CMR |= FMC_CMR_LK;
  123. }
  124. /**
  125. * @brief Locks the FMC Bank2 Program Erase Controller.
  126. * @note This function can be used for GD32F10X_XD and GD32F10X_CL density devices.
  127. * @param None
  128. * @retval None
  129. */
  130. #if defined GD32F10X_XD || defined GD32F10X_CL
  131. void FMC_LockB2(void)
  132. {
  133. /* Set the Lock Bit to lock the FPEC and the CMR of Bank2 */
  134. FMC->CMR2 |= FMC_CMR_LK;
  135. }
  136. #endif
  137. /**
  138. * @brief Erase a page.
  139. * @param Page_Address: The page address to be erased.
  140. * @retval FMC state: FMC_READY, FMC_BSY, FMC_WRPERR, FMC_PGERR or FMC_TIMEOUT_ERR.
  141. */
  142. FMC_State FMC_ErasePage(uint32_t Page_Address)
  143. {
  144. if (FMC_SIZE > FMC_BANK1_SIZE) {
  145. FMC_State temp_state = FMC_B1_WaitReady(FMC_TIMEOUT_COUNT);
  146. if (Page_Address < FMC_B1_END_ADDRESS) {
  147. /* Wait for last operation to be completed */
  148. FMC_State temp_state = FMC_B1_WaitReady(FMC_TIMEOUT_COUNT);
  149. if (temp_state == FMC_READY) {
  150. FMC->CMR |= FMC_CMR_PE;
  151. FMC->AR = Page_Address;
  152. FMC->CMR |= FMC_CMR_START;
  153. /* Wait for the FMC ready */
  154. temp_state = FMC_B1_WaitReady(FMC_TIMEOUT_COUNT);
  155. /* Reset the PE bit */
  156. FMC->CMR &= ~FMC_CMR_PE;
  157. }
  158. } else {
  159. /* Wait for last operation to be completed */
  160. FMC_State temp_state = FMC_B2_WaitReady(FMC_TIMEOUT_COUNT);
  161. if (temp_state == FMC_READY) {
  162. FMC->CMR2 |= FMC_CMR_PE;
  163. FMC->AR2 = Page_Address;
  164. if (FMC->OPTR & FMC_OPTR_PLEVEL1) {
  165. FMC->AR = Page_Address;
  166. }
  167. FMC->CMR2 |= FMC_CMR_START;
  168. /* Wait for the FMC ready */
  169. temp_state = FMC_B2_WaitReady(FMC_TIMEOUT_COUNT);
  170. /* Reset the PE bit */
  171. FMC->CMR2 &= ~FMC_CMR_PE;
  172. }
  173. }
  174. /* Return the FMC state */
  175. return temp_state;
  176. }
  177. else {
  178. FMC_State temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT);
  179. if (temp_state == FMC_READY) {
  180. /* Start page erase */
  181. FMC->CMR |= FMC_CMR_PE;
  182. FMC->AR = Page_Address;
  183. FMC->CMR |= FMC_CMR_START;
  184. /* Wait for the FMC ready */
  185. temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT);
  186. /* Reset the PE bit */
  187. FMC->CMR &= ~FMC_CMR_PE;
  188. }
  189. /* Return the FMC state */
  190. return temp_state;
  191. }
  192. }
  193. /**
  194. * @brief Erase all main FMC.
  195. * @param None
  196. * @retval FMC state: FMC_READY, FMC_BSY, FMC_WRPERR, FMC_PGERR or FMC_TIMEOUT_ERR.
  197. */
  198. FMC_State FMC_MassErase(void)
  199. {
  200. if (FMC_SIZE > FMC_BANK1_SIZE) {
  201. /* Wait for last operation to be completed */
  202. FMC_State temp_state = FMC_B1_WaitReady(FMC_TIMEOUT_COUNT);
  203. if (temp_state == FMC_READY) {
  204. /* Start chip erase */
  205. FMC->CMR |= FMC_CMR_ME;
  206. FMC->CMR |= FMC_CMR_START;
  207. /* Wait for the FMC ready */
  208. temp_state = FMC_B1_WaitReady(FMC_TIMEOUT_COUNT);
  209. /* Reset the MER bit */
  210. FMC->CMR &= ~FMC_CMR_ME;
  211. }
  212. temp_state = FMC_B2_WaitReady(FMC_TIMEOUT_COUNT);
  213. if (temp_state == FMC_READY) {
  214. /* Start chip erase */
  215. FMC->CMR2 |= FMC_CMR_ME;
  216. FMC->CMR2 |= FMC_CMR_START;
  217. /* Wait for the FMC ready */
  218. temp_state = FMC_B2_WaitReady(FMC_TIMEOUT_COUNT);
  219. /* Reset the MER bit */
  220. FMC->CMR2 &= ~FMC_CMR_ME;
  221. }
  222. /* Return the FMC state */
  223. return temp_state;
  224. } else {
  225. FMC_State temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT);
  226. if (temp_state == FMC_READY) {
  227. /* Start chip erase */
  228. FMC->CMR |= FMC_CMR_ME;
  229. FMC->CMR |= FMC_CMR_START;
  230. /* Wait for the FMC ready */
  231. temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT);
  232. /* Reset the MER bit */
  233. FMC->CMR &= ~FMC_CMR_ME;
  234. }
  235. /* Return the FMC state */
  236. return temp_state;
  237. }
  238. }
  239. /**
  240. * @brief Erases all Bank1 FMC pages.
  241. * @note This function can be used for all GD32F10x devices.
  242. * - For GD32F10X_XD and GD32F10X_CL devices this function erases all Bank1 pages.
  243. * - For all other devices it erases all Bank1 pages and it is equivalent
  244. * to FLASH_EraseAllPages function.
  245. * @param None
  246. * @retval FLASH Status: FMC state: FMC_READY, FMC_BSY, FMC_WRPERR, FMC_PGERR or FMC_TIMEOUT_ERR.
  247. */
  248. FMC_State FMC_MassB1Erase(void)
  249. {
  250. FMC_State temp_state = FMC_B1_WaitReady(FMC_TIMEOUT_COUNT);
  251. if (temp_state == FMC_READY) {
  252. /* Start chip erase */
  253. FMC->CMR |= FMC_CMR_ME;
  254. FMC->CMR |= FMC_CMR_START;
  255. /* Wait for the FMC ready */
  256. temp_state = FMC_B1_WaitReady(FMC_TIMEOUT_COUNT);
  257. /* Reset the MER bit */
  258. FMC->CMR &= ~FMC_CMR_ME;
  259. }
  260. /* Return the Erase Status */
  261. return temp_state;
  262. }
  263. /**
  264. * @brief Erases all Bank2 FMC pages.
  265. * @note This function can be used for GD32F10X_XD and GD32F10X_CL density devices.
  266. * @param None
  267. * @retval FMC Status: FMC state: FMC_READY, FMC_BSY, FMC_WRPERR, FMC_PGERR or FMC_TIMEOUT_ERR.
  268. */
  269. FMC_State FMC_MassB2Erase(void)
  270. {
  271. FMC_State temp_state = FMC_B2_WaitReady(FMC_TIMEOUT_COUNT);
  272. if (temp_state == FMC_READY) {
  273. /* Start chip erase */
  274. FMC->CMR2 |= FMC_CMR_ME;
  275. FMC->CMR2 |= FMC_CMR_START;
  276. /* Wait for the FMC ready */
  277. temp_state = FMC_B2_WaitReady(FMC_TIMEOUT_COUNT);
  278. /* Reset the MER bit */
  279. FMC->CMR2 &= ~FMC_CMR_ME;
  280. }
  281. /* Return the Erase Status */
  282. return temp_state;
  283. }
  284. /**
  285. * @brief Program a word at the corresponding address.
  286. * @param Address: The address to be programmed.
  287. * @param Data: The data to be programmed.
  288. * @retval FMC state: FMC_READY, FMC_BSY, FMC_WRPERR, FMC_PGERR or FMC_TIMEOUT_ERR.
  289. */
  290. FMC_State FMC_ProgramWord(uint32_t Address, uint32_t Data)
  291. {
  292. if (FMC_SIZE > FMC_BANK1_SIZE) {
  293. FMC_State temp_state = FMC_B1_WaitReady(FMC_TIMEOUT_COUNT);
  294. if (Address < FMC_B1_END_ADDRESS) {
  295. FMC_State temp_state = FMC_B1_WaitReady(FMC_TIMEOUT_COUNT);
  296. if (temp_state == FMC_READY) {
  297. /* Set the PG bit to start program */
  298. FMC->CMR |= FMC_CMR_PG;
  299. *(__IO uint32_t *)Address = Data;
  300. /* Wait for the FMC ready */
  301. temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT);
  302. /* Reset the PG bit */
  303. FMC->CMR &= ~FMC_CMR_PG;
  304. }
  305. } else {
  306. FMC_State temp_state = FMC_B2_WaitReady(FMC_TIMEOUT_COUNT);
  307. if (temp_state == FMC_READY) {
  308. /* Set the PG bit to start program */
  309. FMC->CMR2 |= FMC_CMR_PG;
  310. *(__IO uint32_t *)Address = Data;
  311. /* Wait for the FMC ready */
  312. temp_state = FMC_B2_WaitReady(FMC_TIMEOUT_COUNT);
  313. /* Reset the PG bit */
  314. FMC->CMR2 &= ~FMC_CMR_PG;
  315. }
  316. }
  317. /* Return the FMC state */
  318. return temp_state;
  319. } else {
  320. FMC_State temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT);
  321. if (temp_state == FMC_READY) {
  322. /* Set the PG bit to start program */
  323. FMC->CMR |= FMC_CMR_PG;
  324. *(__IO uint32_t *)Address = Data;
  325. /* Wait for the FMC ready */
  326. temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT);
  327. /* Reset the PG bit */
  328. FMC->CMR &= ~FMC_CMR_PG;
  329. }
  330. /* Return the FMC state */
  331. return temp_state;
  332. }
  333. }
  334. /**
  335. * @}
  336. */
  337. /** @defgroup FMC_Group2 Option Bytes Programming functions
  338. * @brief Option Bytes Programming functions
  339. *
  340. @verbatim
  341. ===============================================================================
  342. ##### Option Bytes Programming functions #####
  343. ===============================================================================
  344. [..] The FMC_Option Bytes Programming_functions, includes the following functions:
  345. (+) void FMC_OB_Unlock(void);
  346. (+) void FMC_OB_Lock(void);
  347. (+) void FMC_OB_Reset(void);
  348. (+) FMC_State FMC_OB_Erase(void);
  349. (+) FMC_State FMC_OB_WRPConfig(uint32_t OB_WRP);
  350. (+) FMC_State FMC_OB_RDPConfig(uint8_t OB_RDP);
  351. (+) FMC_State FMC_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_DEEPSLEEP, uint8_t OB_STDBY);
  352. (+) FMC_State FMC_OB_BOOTConfig(uint8_t OB_BOOT);
  353. (+) FMC_State FMC_OB_WriteUser(uint8_t OB_USER);
  354. (+) FMC_ProgramOptionByteData(uint32_t Address, uint8_t Data);
  355. (+) uint8_t FMC_OB_GetUser(void);
  356. (+) uint32_t FMC_OB_GetWRP(void);
  357. (+) FlagStatus FMC_OB_GetRDP(void);
  358. [..] Any operation of erase or program should follow these steps:
  359. (#) Call the FMC_OB_Unlock() function to enable the Option Bytes registers access
  360. (#) Call one or several functions to program the desired option bytes
  361. (++) FMC_State FMC_OB_RDPConfig(uint8_t OB_RDP) => to set the desired read Protection Level
  362. (++) FMC_State FMC_OB_WRPConfig(uint32_t OB_WRP, FunctionalState NewState)
  363. => to Enable/Disable the desired sector write protection
  364. (++) FMC_State FMC_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_DEEPSLEEP, uint8_t OB_STDBY)
  365. => to configure the user option Bytes: IWDG, DEEPSLEEP and the Standby.
  366. (++) FMC_State FMC_OB_BOOTConfig(uint8_t OB_BOOT1)
  367. => to set or reset BOOT1
  368. (++) FMC_State FMC_OB_VDDAConfig(uint8_t OB_VDDA_ANALOG)
  369. => to enable or disable the VDDA Analog Monitoring
  370. (++) You can write all User Options bytes at once using a single function
  371. by calling FMC_State FMC_OB_WriteUser(uint8_t OB_USER)
  372. (++) FMC_ProgramOptionByteData(uint32_t Address, uint8_t Data) to program the
  373. two half word in the option bytes
  374. (#) Once all needed option bytes to be programmed are correctly written, call the
  375. FMC_OB_Launch(void) function to launch the Option Bytes programming process.
  376. (#) Call the FMC_OB_Lock() to disable the Option Bytes registers access (recommended
  377. to protect the option Bytes against possible unwanted operations)
  378. @endverbatim
  379. * @{
  380. */
  381. /**
  382. * @brief Unlock the option byte operation
  383. * @param None
  384. * @retval None
  385. */
  386. void FMC_OB_Unlock(void)
  387. {
  388. if ((FMC->CMR & FMC_CMR_OBWE) == RESET) {
  389. /* Write the FMC key */
  390. FMC->OBKEYR = FMC_KEY1;
  391. FMC->OBKEYR = FMC_KEY2;
  392. }
  393. }
  394. /**
  395. * @brief Lock the option byte operation.
  396. * @param None
  397. * @retval None
  398. */
  399. void FMC_OB_Lock(void)
  400. {
  401. /* Reset the OBWE bit */
  402. FMC->CMR &= ~FMC_CMR_OBWE;
  403. }
  404. /**
  405. * @brief Generate a system reset to reload the option byte.
  406. * @param None
  407. * @retval None
  408. */
  409. void FMC_OB_Reset(void)
  410. {
  411. /* Set the OPTR bit */
  412. FMC->CMR |= FMC_CMR_OPTR;
  413. }
  414. /**
  415. * @brief Erase the FMC option byte.
  416. * @param None
  417. * @retval FMC state: FMC_READY, FMC_BSY, FMC_WRPERR, FMC_PGERR or FMC_TIMEOUT_ERR.
  418. */
  419. FMC_State FMC_OB_Erase(void)
  420. {
  421. uint16_t temp_rdp = RDP_LEVEL_0;
  422. FMC_State temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT);
  423. /* Check the ReadOut Protection Option Byte */
  424. if (FMC_OB_GetRDP() != RESET) {
  425. temp_rdp = 0x00;
  426. }
  427. if (temp_state == FMC_READY) {
  428. /* Start erase the option byte */
  429. FMC->CMR |= FMC_CMR_OBER;
  430. FMC->CMR |= FMC_CMR_START;
  431. /* Wait for the FMC ready */
  432. temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT);
  433. if (temp_state == FMC_READY) {
  434. /* Reset the OPER bit */
  435. FMC->CMR &= ~FMC_CMR_OBER;
  436. /* Set the OBPG bit */
  437. FMC->CMR |= FMC_CMR_OBPG;
  438. /* Set default RDP level */
  439. OB->RDP = (uint16_t)temp_rdp;
  440. /* Wait for the FMC ready */
  441. temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT);
  442. if (temp_state != FMC_TIMEOUT_ERR) {
  443. /* Reset the OBPG bit */
  444. FMC->CMR &= ~FMC_CMR_OBPG;
  445. }
  446. } else {
  447. if (temp_state != FMC_TIMEOUT_ERR) {
  448. /* Reset the OBPG bit */
  449. FMC->CMR &= ~FMC_CMR_OBPG;
  450. }
  451. }
  452. }
  453. /* Return the FMC state */
  454. return temp_state;
  455. }
  456. /**
  457. * @brief Program Write protect Byte
  458. * @param OB_WRP: specify the address of the pages to be write protected.
  459. * The legal parameter can be:
  460. * @arg WRP_SECTOR0 ... WRP_SECTOR31
  461. * @arg WRP_ALLSECTORS
  462. * @retval FMC state: FMC_READY, FMC_BSY, FMC_WRPERR, FMC_PGERR or FMC_TIMEOUT_ERR.
  463. */
  464. FMC_State FMC_OB_EnableWRP(uint32_t OB_WRP)
  465. {
  466. uint16_t temp_WRP0, temp_WRP1, temp_WRP2, temp_WRP3;
  467. FMC_State temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT);
  468. OB_WRP = (uint32_t)(~OB_WRP);
  469. temp_WRP0 = (uint16_t)(OB_WRP & OB_WRP0_WRP0);
  470. temp_WRP1 = (uint16_t)((OB_WRP & OB_WRP0_nWRP0) >> 8);
  471. temp_WRP2 = (uint16_t)((OB_WRP & OB_WRP1_WRP1) >> 16);
  472. temp_WRP3 = (uint16_t)((OB_WRP & OB_WRP1_nWRP1) >> 24);
  473. if (temp_state == FMC_READY) {
  474. FMC->OBKEYR = FMC_KEY1;
  475. FMC->OBKEYR = FMC_KEY2;
  476. /* Set the OBPG bit*/
  477. FMC->CMR |= FMC_CMR_OBPG;
  478. if (temp_WRP0 != 0xFF) {
  479. OB->WRP0 = temp_WRP0;
  480. /* Wait for the FMC ready */
  481. temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT);
  482. }
  483. if ((temp_state == FMC_READY) && (temp_WRP1 != 0xFF)) {
  484. OB->WRP1 = temp_WRP1;
  485. /* Wait for the FMC ready */
  486. temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT);
  487. }
  488. if ((temp_state == FMC_READY) && (temp_WRP2 != 0xFF)) {
  489. OB->WRP2 = temp_WRP2;
  490. /* Wait for the FMC ready */
  491. temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT);
  492. }
  493. if ((temp_state == FMC_READY) && (temp_WRP3 != 0xFF)) {
  494. OB->WRP3 = temp_WRP3;
  495. /* Wait for the FMC ready */
  496. temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT);
  497. }
  498. if (temp_state != FMC_TIMEOUT_ERR) {
  499. /* Reset the OBPG bit */
  500. FMC->CMR &= ~FMC_CMR_OBPG;
  501. }
  502. }
  503. /* Return the FMC state */
  504. return temp_state;
  505. }
  506. /**
  507. * @brief Enable or disable the read out protection,this function erases all option bytes.
  508. * @param NewValue: ENABLE or DISABLE.
  509. * @retval FMC state: FMC_READY, FMC_WRPERR, FMC_PGERR or FMC_TIMEOUT_ERR.
  510. */
  511. FMC_State FMC_ReadOutProtection(TypeState NewValue)
  512. {
  513. FMC_State temp_state = FMC_READY;
  514. /* Wait for the FMC ready */
  515. temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT);
  516. if (temp_state == FMC_READY) {
  517. /* Unlock option bytes */
  518. FMC->OBKEYR = FMC_KEY1;
  519. FMC->OBKEYR = FMC_KEY2;
  520. while ((FMC->CMR & FMC_CMR_OBWE) != FMC_CMR_OBWE)
  521. {}
  522. FMC->CMR |= FMC_CMR_OBER;
  523. FMC->CMR |= FMC_CMR_START;
  524. /* Wait for the FMC ready */
  525. temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT);
  526. if (temp_state == FMC_READY) {
  527. /* Disable the OBER Bit */
  528. FMC->CMR &= ~FMC_CMR_OBER ;
  529. /* Enable the OBPG Bit */
  530. FMC->CMR |= FMC_CMR_OBPG;
  531. if (NewValue != DISABLE) {
  532. OB->RDP = 0x00;
  533. } else {
  534. OB->RDP = RDP_LEVEL_0;
  535. }
  536. /* Wait for the FMC ready */
  537. temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT);
  538. if (temp_state != FMC_TIMEOUT_ERR) {
  539. /* Enable the OBPG Bit */
  540. FMC->CMR &= ~FMC_CMR_OBPG ;
  541. }
  542. } else {
  543. if (temp_state != FMC_TIMEOUT_ERR) {
  544. /* Disable the OBER Bit */
  545. FMC->CMR &= ~FMC_CMR_OBER ;
  546. }
  547. }
  548. }
  549. /* Return the FMC state */
  550. return temp_state;
  551. }
  552. /**
  553. * @brief Config the Read Out Protection bit.
  554. * @param FMC_ReadProtection_Level: The Read Out Protection level.
  555. * This parameter can be:
  556. * @arg RDP_LEVEL_0: No protection
  557. * @arg RDP_LEVEL_1: Read Outprotection of the memory
  558. * @retval FMC state: FMC_READY, FMC_BSY, FMC_WRPERR, FMC_PGERR or FMC_TIMEOUT_ERR.
  559. */
  560. FMC_State FMC_OB_RDPConfig(uint8_t OB_RDP)
  561. {
  562. FMC_State temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT);
  563. if (temp_state == FMC_READY) {
  564. FMC->CMR |= FMC_CMR_OBER;
  565. FMC->CMR |= FMC_CMR_START;
  566. /* Wait for the FMC ready */
  567. temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT);
  568. if (temp_state == FMC_READY) {
  569. /* Reset the OBER bit */
  570. FMC->CMR &= ~FMC_CMR_OBER;
  571. /* Start the Option Bytes Programming */
  572. FMC->CMR |= FMC_CMR_OBPG;
  573. OB->RDP = OB_RDP;
  574. /* Wait for the FMC ready */
  575. temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT);
  576. if (temp_state != FMC_TIMEOUT_ERR) {
  577. /* Reset the OBPG bit */
  578. FMC->CMR &= ~FMC_CMR_OBPG;
  579. }
  580. } else {
  581. if (temp_state != FMC_TIMEOUT_ERR) {
  582. /* Reset the OBER Bit */
  583. FMC->CMR &= ~FMC_CMR_OBER;
  584. }
  585. }
  586. }
  587. /* Return the FMC state */
  588. return temp_state;
  589. }
  590. /**
  591. * @brief Program the FMC User Option Byte: IWDG_SW / RST_DEEPSLEEP / RST_STDBY.
  592. * @param OB_IWDG: Config the WDG mode
  593. * @arg OB_IWDG_SW: Software WDG selected
  594. * @arg OB_IWDG_HW: Hardware WDG selected
  595. * @param OB_DEEPSLEEP: Config Reset event when entering DEEPSLEEP mode.
  596. * @arg OB_DEEPSLEEP_NORST: No reset generated when entering in DEEPSLEEP
  597. * @arg OB_DEEPSLEEP_RST: Reset generated when entering in DEEPSLEEP
  598. * @param OB_STDBY: Config Reset event when entering Standby mode.
  599. * @arg OB_STDBY_NORST: No reset generated when entering in STANDBY
  600. * @arg OB_STDBY_RST: Reset generated when entering in STANDBY
  601. * @retval FMC state: FMC_READY, FMC_BSY, FMC_WRPERR, FMC_PGERR or FMC_TIMEOUT_ERR.
  602. */
  603. FMC_State FMC_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_DEEPSLEEP, uint8_t OB_STDBY)
  604. {
  605. FMC_State temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT);
  606. if (temp_state == FMC_READY) {
  607. /* Set the OBPG bit*/
  608. FMC->CMR |= FMC_CMR_OBPG;
  609. OB->USER = (uint16_t)((uint16_t)(OB_IWDG | OB_DEEPSLEEP) | (uint16_t)(OB_STDBY | 0xF8));
  610. /* Wait for the FMC ready */
  611. temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT);
  612. if (temp_state != FMC_TIMEOUT_ERR) {
  613. /* Reset the OBPG bit */
  614. FMC->CMR &= ~FMC_CMR_OBPG;
  615. }
  616. }
  617. /* Return the FMC state */
  618. return temp_state;
  619. }
  620. /**
  621. * @brief Program the BOOT option bit.
  622. * @param OB_BOOT: The legal parameter can be one of the following value:
  623. * @arg OB_BOOT_B1:Start up from Bank1
  624. * @arg OB_BOOT_B2:Start up from Bank2
  625. * @retval FMC state: FMC_READY, FMC_BSY, FMC_WRPERR, FMC_PGERR or FMC_TIMEOUT_ERR.
  626. */
  627. FMC_State FMC_OB_BOOTConfig(uint8_t OB_BOOT)
  628. {
  629. FMC_State temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT);
  630. FMC->OBKEYR = FMC_KEY1;
  631. FMC->OBKEYR = FMC_KEY2;
  632. if (temp_state == FMC_READY) {
  633. /* Set the OBPG bit*/
  634. FMC->CMR |= FMC_CMR_OBPG;
  635. if (OB_BOOT == OB_BOOT_B1) {
  636. OB->USER |= OB_USER_BFB2;
  637. } else {
  638. OB->USER &= (uint16_t)(~(uint16_t)(OB_USER_BFB2));
  639. }
  640. /* Wait for the FMC ready */
  641. temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT);
  642. if (temp_state != FMC_TIMEOUT_ERR) {
  643. /* Reset the OBPG bit */
  644. FMC->CMR &= ~FMC_CMR_OBPG;
  645. }
  646. }
  647. /* Return the FMC state */
  648. return temp_state;
  649. }
  650. /**
  651. * @brief Program the FMC User Option Byte.
  652. * @param OB_USER: Select all user option byte
  653. * The legal parameter is one of the following values:
  654. * @arg OB_IWDG_SW
  655. * @arg OB_IWDG_HW
  656. * @arg OB_DEEPSLEEP_NORST
  657. * @arg OB_DEEPSLEEP_RST
  658. * @arg OB_STDBY_NORST
  659. * @arg OB_STDBY_RST
  660. * @arg OB_BOOT_B1
  661. * @arg OB_BOOT_B2
  662. * @retval FMC state: FMC_READY, FMC_BSY, FMC_WRPERR, FMC_PGERR or FMC_TIMEOUT_ERR.
  663. */
  664. FMC_State FMC_OB_WriteUser(uint8_t OB_USER)
  665. {
  666. FMC_State temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT);
  667. if (temp_state == FMC_READY) {
  668. /* Set the OBPG bit */
  669. FMC->CMR |= FMC_CMR_OBPG;
  670. OB->USER = OB_USER | 0xf0;
  671. /* Wait for the FMC ready */
  672. temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT);
  673. if (temp_state != FMC_TIMEOUT_ERR) {
  674. /* Reset the OBPG bit */
  675. FMC->CMR &= ~FMC_CMR_OBPG;
  676. }
  677. }
  678. /* Return the FMC state */
  679. return temp_state;
  680. }
  681. /**
  682. * @brief Program Option Byte Data.
  683. * @param Address: The Option Byte address to be programmed.
  684. * The legal parameter can be 0x1FFFF804 or 0x1FFFF806.
  685. * @param Data: The Byte to be programmed.
  686. * @retval FMC state: FMC_READY, FMC_BSY, FMC_WRPERR, FMC_PGERR or FMC_TIMEOUT_ERR.
  687. */
  688. FMC_State FMC_ProgramOptionByteData(uint32_t Address, uint8_t Data)
  689. {
  690. FMC_State temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT);
  691. if (temp_state == FMC_READY) {
  692. /* SET the OPTPG bit */
  693. FMC->CMR |= FMC_CMR_OBPG;
  694. *(__IO uint16_t *)Address = Data;
  695. /* Wait for the FMC ready */
  696. temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT);
  697. if (temp_state != FMC_TIMEOUT_ERR) {
  698. /* Reset the OPTPG bit */
  699. FMC->CMR &= ~FMC_CMR_OBPG;
  700. }
  701. }
  702. /* Return the FMC state */
  703. return temp_state;
  704. }
  705. /**
  706. * @brief Get the FMC User Option Byte.
  707. * @param None
  708. * @retval The FMC User Option Byte.
  709. */
  710. uint8_t FMC_OB_GetUser(void)
  711. {
  712. return (uint8_t)(FMC->OPTR >> 8);
  713. }
  714. /**
  715. * @brief Get the FMC Write Protection Option Byte.
  716. * @param None
  717. * @retval The FMC Write Protection Option Byte
  718. */
  719. uint32_t FMC_OB_GetWRP(void)
  720. {
  721. return (uint32_t)(FMC->WPR);
  722. }
  723. /**
  724. * @brief Check whether the FMC Read out Protection Status is SET or RESET.
  725. * @param None
  726. * @retval FMC ReadOut Protection state
  727. */
  728. TypeState FMC_OB_GetRDP(void)
  729. {
  730. TypeState RDPState = RESET;
  731. if ((uint8_t)(FMC->OPTR & (FMC_OPTR_PLEVEL1)) != RESET) {
  732. RDPState = SET;
  733. } else {
  734. RDPState = RESET;
  735. }
  736. return RDPState;
  737. }
  738. /**
  739. * @}
  740. */
  741. /** @defgroup FMC_Group3 Interrupts and flags management functions
  742. * @brief Interrupts and flags management functions
  743. *
  744. @verbatim
  745. ===============================================================================
  746. ##### Interrupts and flags management functions #####
  747. ===============================================================================
  748. @endverbatim
  749. * @{
  750. */
  751. /**
  752. * @brief Enable or disable the corresponding FMC interrupt source.
  753. * @param FMC_INT: The FMC interrupt source to be enabled or disabled.
  754. * This parameter can be any combination of the following values:
  755. * @arg FMC_INT_EOP: FMC end of programming Interrupt
  756. * @arg FMC_INT_ERR: FMC Error Interrupt
  757. * @arg FMC_INT_B2_EOP: FMC end of programming Interrupt
  758. * @arg FMC_INT_B2_ERR: FMC Error Interrupt
  759. * @param NewValue: ENABLE or DISABLE.
  760. * @retval None
  761. */
  762. void FMC_INTConfig(uint32_t FMC_INT, TypeState NewValue)
  763. {
  764. if (FMC_SIZE > FMC_BANK1_SIZE) {
  765. if ((FMC_INT & 0x80000000) != 0x0) {
  766. if (NewValue != DISABLE) {
  767. /* Enable the interrupt sources */
  768. FMC->CMR2 |= (FMC_INT & 0x7fffffff);
  769. } else {
  770. /* Disable the interrupt sources */
  771. FMC->CMR2 &= ~(uint32_t)(FMC_INT & 0x7fffffff);
  772. }
  773. } else {
  774. if (NewValue != DISABLE) {
  775. /* Enable the interrupt sources */
  776. FMC->CMR |= FMC_INT;
  777. } else {
  778. /* Disable the interrupt sources */
  779. FMC->CMR &= ~(uint32_t)FMC_INT;
  780. }
  781. }
  782. } else {
  783. if (NewValue != DISABLE) {
  784. /* Enable the interrupt sources */
  785. FMC->CMR |= FMC_INT;
  786. } else {
  787. /* Disable the interrupt sources */
  788. FMC->CMR &= ~(uint32_t)FMC_INT;
  789. }
  790. }
  791. }
  792. /**
  793. * @brief Checks whether the FMC flag is SET or RESET.
  794. * @param FMC_FLAG: the corresponding FMC flag.
  795. * the legal parameter can be:
  796. * @arg FMC_FLAG_BSY: FMC BUSY flag
  797. * @arg FMC_FLAG_PERR: FMC Programming error flag flag
  798. * @arg FMC_FLAG_WERR: FMC Write protection error flag
  799. * @arg FMC_FLAG_EOP: FMC End of Programming flag
  800. * @arg FMC_FLAG_OPTER: FMC option byte error flag
  801. * @retval The state of the FMC flag.
  802. */
  803. TypeState FMC_GetBitState(uint32_t FMC_FLAG)
  804. {
  805. if (FMC_SIZE > FMC_BANK1_SIZE) {
  806. /* Check the parameters */
  807. if (FMC_FLAG == FMC_FLAG_OPTERR) {
  808. if ((FMC->OPTR & FMC_FLAG_OPTERR) != (uint32_t)RESET) {
  809. return SET;
  810. } else {
  811. return RESET;
  812. }
  813. } else {
  814. if ((FMC_FLAG & 0x80000000) != 0x0) {
  815. if ((FMC->CSR2 & FMC_FLAG) != (uint32_t)RESET) {
  816. return SET;
  817. } else {
  818. return RESET;
  819. }
  820. } else {
  821. if ((FMC->CSR & FMC_FLAG) != (uint32_t)RESET) {
  822. return SET;
  823. } else {
  824. return RESET;
  825. }
  826. }
  827. }
  828. } else {
  829. if (FMC_FLAG == FMC_FLAG_OPTERR) {
  830. if ((FMC->OPTR & FMC_FLAG_OPTERR) != (uint32_t)RESET) {
  831. return SET;
  832. } else {
  833. return RESET;
  834. }
  835. } else {
  836. if ((FMC->CSR & FMC_FLAG) != (uint32_t)RESET) {
  837. return SET;
  838. }
  839. /* Return the state of corresponding FMC flag */
  840. else {
  841. return RESET;
  842. }
  843. }
  844. }
  845. }
  846. /**
  847. * @brief Clear the FMC pending flag.
  848. * @param FMC_FLAG: clear the corresponding FMC flag.
  849. * @arg FMC_FLAG_PERR: Programming error flag flag
  850. * @arg FMC_FLAG_WERR: Write protection error flag
  851. * @arg FMC_FLAG_EOP: End of Programming flag
  852. * @retval None
  853. */
  854. void FMC_ClearBitState(uint32_t FMC_FLAG)
  855. {
  856. if (FMC_SIZE > FMC_BANK1_SIZE) {
  857. if ((FMC_FLAG & 0x80000000) != 0x0) {
  858. /* Clear the flags */
  859. FMC->CSR2 = FMC_FLAG;
  860. } else {
  861. /* Clear the flags */
  862. FMC->CSR = FMC_FLAG;
  863. }
  864. } else {
  865. FMC->CSR = FMC_FLAG;
  866. }
  867. }
  868. /**
  869. * @brief Return the FMC state.
  870. * @param None
  871. * @retval FMC state: FMC_READY, FMC_BSY, FMC_WRPERR, or FMC_PGERR
  872. */
  873. FMC_State FMC_GetState(void)
  874. {
  875. FMC_State temp_state = FMC_READY;
  876. if ((FMC->CSR & FMC_CSR_BUSY) == FMC_CSR_BUSY) {
  877. temp_state = FMC_BSY;
  878. } else {
  879. if ((FMC->CSR & (uint32_t)FMC_CSR_WPEF) != (uint32_t)0x00) {
  880. temp_state = FMC_WRPERR;
  881. } else {
  882. if ((FMC->CSR & (uint32_t)(FMC_CSR_PGEF)) != (uint32_t)0x00) {
  883. temp_state = FMC_PGERR;
  884. } else {
  885. temp_state = FMC_READY;
  886. }
  887. }
  888. }
  889. /* Return the FMC state */
  890. return temp_state;
  891. }
  892. /**
  893. * @brief Return the FMC bak1 state.
  894. * @param None
  895. * @retval FMC state: FMC_READY, FMC_BSY, FMC_WRPERR, or FMC_PGERR
  896. */
  897. FMC_State FMC_GetB1State(void)
  898. {
  899. FMC_State temp_state = FMC_READY;
  900. if ((FMC->CSR & FMC_CSR_BUSY) == FMC_CSR_BUSY) {
  901. temp_state = FMC_BSY;
  902. } else {
  903. if ((FMC->CSR & (uint32_t)FMC_CSR_WPEF) != (uint32_t)0x00) {
  904. temp_state = FMC_WRPERR;
  905. } else {
  906. if ((FMC->CSR & (uint32_t)(FMC_CSR_PGEF)) != (uint32_t)0x00) {
  907. temp_state = FMC_PGERR;
  908. } else {
  909. temp_state = FMC_READY;
  910. }
  911. }
  912. }
  913. return temp_state;
  914. }
  915. /**
  916. * @brief Return the FMC bak2 state.
  917. * @param None
  918. * @retval FMC state: FMC_READY, FMC_BSY, FMC_WRPERR, or FMC_PGERR
  919. */
  920. FMC_State FMC_GetB2State(void)
  921. {
  922. FMC_State temp_state = FMC_READY;
  923. if ((FMC->CSR2 & FMC_CSR2_BUSY & 0x7fffffff) == (FMC_CSR2_BUSY & 0x7fffffff)) {
  924. temp_state = FMC_BSY;
  925. } else {
  926. if ((FMC->CSR2 & FMC_CSR2_WPEF & 0x7fffffff) != (uint32_t)0x00) {
  927. temp_state = FMC_WRPERR;
  928. } else {
  929. if ((FMC->CSR2 & FMC_CSR2_PGEF & 0x7fffffff) != (uint32_t)0x00) {
  930. temp_state = FMC_PGERR;
  931. } else {
  932. temp_state = FMC_READY;
  933. }
  934. }
  935. }
  936. /* Return the FMC state */
  937. return temp_state;
  938. }
  939. /**
  940. * @brief Check whether FMC is ready or not.
  941. * @param Timeout: Count of loop
  942. * @retval FMC state: FMC_READY, FMC_BSY, FMC_WRPERR, FMC_PGERR or FMC_TIMEOUT_ERR.
  943. */
  944. FMC_State FMC_WaitReady(uint32_t uCount)
  945. {
  946. FMC_State temp_state = FMC_BSY;
  947. /* Wait for FMC ready */
  948. do {
  949. /* Get FMC state */
  950. temp_state = FMC_GetState();
  951. uCount--;
  952. } while ((temp_state == FMC_BSY) && (uCount != 0x00));
  953. if (temp_state == FMC_BSY) {
  954. temp_state = FMC_TIMEOUT_ERR;
  955. }
  956. /* Return the FMC state */
  957. return temp_state;
  958. }
  959. /**
  960. * @brief Check whether FMC Bank1 is ready or not.
  961. * @param Timeout: Count of loop
  962. * @retval FMC state: FMC_READY, FMC_BSY, FMC_WRPERR, FMC_PGERR or FMC_TIMEOUT_ERR.
  963. */
  964. FMC_State FMC_B1_WaitReady(uint32_t uCount)
  965. {
  966. FMC_State temp_state = FMC_BSY;
  967. /* Wait for FMC ready */
  968. do {
  969. /* Get FMC state */
  970. temp_state = FMC_GetB1State();
  971. uCount--;
  972. } while ((temp_state == FMC_BSY) && (uCount != 0x00));
  973. if (temp_state == FMC_BSY) {
  974. temp_state = FMC_TIMEOUT_ERR;
  975. }
  976. /* Return the FMC state */
  977. return temp_state;
  978. }
  979. /**
  980. * @brief Check whether FMC Bank2 is ready or not.
  981. * @param Timeout: Count of loop
  982. * @retval FMC state: FMC_READY, FMC_BSY, FMC_WRPERR, FMC_PGERR or FMC_TIMEOUT_ERR.
  983. */
  984. FMC_State FMC_B2_WaitReady(uint32_t uCount)
  985. {
  986. FMC_State temp_state = FMC_BSY;
  987. /* Wait for FMC ready */
  988. do {
  989. /* Get FMC state */
  990. temp_state = FMC_GetB2State();
  991. uCount--;
  992. } while ((temp_state == (FMC_BSY && 0x7FFFFFFF)) && (uCount != 0x00));
  993. if (temp_state == FMC_BSY) {
  994. temp_state = FMC_TIMEOUT_ERR;
  995. }
  996. /* Return the FMC state */
  997. return temp_state;
  998. }
  999. /**
  1000. * @}
  1001. */
  1002. /**
  1003. * @}
  1004. */
  1005. /**
  1006. * @}
  1007. */
  1008. /**
  1009. * @}
  1010. */