gd32f4xx_fmc.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824
  1. /*!
  2. \file gd32f4xx_fmc.c
  3. \brief FMC driver
  4. */
  5. /*
  6. Copyright (C) 2016 GigaDevice
  7. 2016-08-15, V1.0.0, firmware for GD32F4xx
  8. */
  9. #include "gd32f4xx_fmc.h"
  10. /*!
  11. \brief set the wait state counter value
  12. \param[in] wscnt£ºwait state counter value
  13. \arg WS_WSCNT_0: FMC 0 wait
  14. \arg WS_WSCNT_1: FMC 1 wait
  15. \arg WS_WSCNT_2: FMC 2 wait
  16. \arg WS_WSCNT_3: FMC 3 wait
  17. \arg WS_WSCNT_4: FMC 4 wait
  18. \arg WS_WSCNT_5: FMC 5 wait
  19. \arg WS_WSCNT_6: FMC 6 wait
  20. \arg WS_WSCNT_7: FMC 7 wait
  21. \arg WS_WSCNT_8: FMC 8 wait
  22. \arg WS_WSCNT_9: FMC 9 wait
  23. \arg WS_WSCNT_10: FMC 10 wait
  24. \arg WS_WSCNT_11: FMC 11 wait
  25. \arg WS_WSCNT_12: FMC 12 wait
  26. \arg WS_WSCNT_13: FMC 13 wait
  27. \arg WS_WSCNT_14: FMC 14 wait
  28. \arg WS_WSCNT_15: FMC 15 wait
  29. \param[out] none
  30. \retval none
  31. */
  32. void fmc_wscnt_set(uint32_t wscnt)
  33. {
  34. uint32_t reg;
  35. reg = FMC_WS;
  36. /* set the wait state counter value */
  37. reg &= ~FMC_WC_WSCNT;
  38. FMC_WS = (reg | wscnt);
  39. }
  40. /*!
  41. \brief unlock the main FMC operation
  42. \param[in] none
  43. \param[out] none
  44. \retval none
  45. */
  46. void fmc_unlock(void)
  47. {
  48. if((RESET != (FMC_CTL & FMC_CTL_LK))){
  49. /* write the FMC key */
  50. FMC_KEY = UNLOCK_KEY0;
  51. FMC_KEY = UNLOCK_KEY1;
  52. }
  53. }
  54. /*!
  55. \brief lock the main FMC operation
  56. \param[in] none
  57. \param[out] none
  58. \retval none
  59. */
  60. void fmc_lock(void)
  61. {
  62. /* set the LK bit*/
  63. FMC_CTL |= FMC_CTL_LK;
  64. }
  65. /*!
  66. \brief erase sector
  67. \param[in] fmc_sector: select the sector to erase
  68. \arg CTL_SECTOR_NUMBER_0: sector 0
  69. \arg CTL_SECTOR_NUMBER_1: sector 1
  70. \arg CTL_SECTOR_NUMBER_2: sector 2
  71. \arg CTL_SECTOR_NUMBER_3: sector 3
  72. \arg CTL_SECTOR_NUMBER_4: sector 4
  73. \arg CTL_SECTOR_NUMBER_5: sector 5
  74. \arg CTL_SECTOR_NUMBER_6: sector 6
  75. \arg CTL_SECTOR_NUMBER_7: sector 7
  76. \arg CTL_SECTOR_NUMBER_8: sector 8
  77. \arg CTL_SECTOR_NUMBER_9: sector 9
  78. \arg CTL_SECTOR_NUMBER_10: sector 10
  79. \arg CTL_SECTOR_NUMBER_11: sector 11
  80. \arg CTL_SECTOR_NUMBER_12: sector 12
  81. \arg CTL_SECTOR_NUMBER_13: sector 13
  82. \arg CTL_SECTOR_NUMBER_14: sector 14
  83. \arg CTL_SECTOR_NUMBER_15: sector 15
  84. \arg CTL_SECTOR_NUMBER_16: sector 16
  85. \arg CTL_SECTOR_NUMBER_17: sector 17
  86. \arg CTL_SECTOR_NUMBER_18: sector 18
  87. \arg CTL_SECTOR_NUMBER_19: sector 19
  88. \arg CTL_SECTOR_NUMBER_20: sector 20
  89. \arg CTL_SECTOR_NUMBER_21: sector 21
  90. \arg CTL_SECTOR_NUMBER_22: sector 22
  91. \arg CTL_SECTOR_NUMBER_23: sector 23
  92. \arg CTL_SECTOR_NUMBER_24: sector 24
  93. \arg CTL_SECTOR_NUMBER_25: sector 25
  94. \arg CTL_SECTOR_NUMBER_26: sector 26
  95. \arg CTL_SECTOR_NUMBER_27: sector 27
  96. \arg CTL_SECTOR_NUMBER_28: sector 28
  97. \arg CTL_SECTOR_NUMBER_29: sector 29
  98. \arg CTL_SECTOR_NUMBER_30: sector 30
  99. \param[out] none
  100. \retval fmc_state_enum
  101. */
  102. fmc_state_enum fmc_sector_erase(uint32_t fmc_sector)
  103. {
  104. fmc_state_enum fmc_state = FMC_READY;
  105. /* wait for the FMC ready */
  106. fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
  107. if(FMC_READY == fmc_state){
  108. /* start sector erase */
  109. FMC_CTL &= ~FMC_CTL_SN;
  110. FMC_CTL |= (FMC_CTL_SER | fmc_sector);
  111. FMC_CTL |= FMC_CTL_START;
  112. /* wait for the FMC ready */
  113. fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
  114. /* reset the SER bit */
  115. FMC_CTL &= (~FMC_CTL_SER);
  116. FMC_CTL &= ~FMC_CTL_SN;
  117. }
  118. /* return the FMC state */
  119. return fmc_state;
  120. }
  121. /*!
  122. \brief erase whole chip
  123. \param[in] none
  124. \param[out] none
  125. \retval fmc_state_enum
  126. */
  127. fmc_state_enum fmc_mass_erase(void)
  128. {
  129. fmc_state_enum fmc_state = FMC_READY;
  130. /* wait for the FMC ready */
  131. fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
  132. if(FMC_READY == fmc_state){
  133. /* start whole chip erase */
  134. FMC_CTL |= (FMC_CTL_MER0 | FMC_CTL_MER1);
  135. FMC_CTL |= FMC_CTL_START;
  136. /* wait for the FMC ready */
  137. fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
  138. /* reset the MER bits */
  139. FMC_CTL &= ~(FMC_CTL_MER0 | FMC_CTL_MER1);
  140. }
  141. /* return the fmc state */
  142. return fmc_state;
  143. }
  144. /*!
  145. \brief erase all FMC sectors in bank0
  146. \param[in] none
  147. \param[out] none
  148. \retval fmc_state_enum
  149. */
  150. fmc_state_enum fmc_bank0_erase(void)
  151. {
  152. fmc_state_enum fmc_state = FMC_READY;
  153. /* wait for the FMC ready */
  154. fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
  155. if(FMC_READY == fmc_state){
  156. /* start FMC bank0 erase */
  157. FMC_CTL |= FMC_CTL_MER0;
  158. FMC_CTL |= FMC_CTL_START;
  159. /* wait for the FMC ready */
  160. fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
  161. /* reset the MER0 bit */
  162. FMC_CTL &= (~FMC_CTL_MER0);
  163. }
  164. /* return the fmc state */
  165. return fmc_state;
  166. }
  167. /*!
  168. \brief erase all FMC sectors in bank1
  169. \param[in] none
  170. \param[out] none
  171. \retval fmc_state_enum
  172. */
  173. fmc_state_enum fmc_bank1_erase(void)
  174. {
  175. fmc_state_enum fmc_state = FMC_READY;
  176. /* wait for the FMC ready */
  177. fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
  178. if(FMC_READY == fmc_state){
  179. /* start FMC bank1 erase */
  180. FMC_CTL |= FMC_CTL_MER1;
  181. FMC_CTL |= FMC_CTL_START;
  182. /* wait for the FMC ready */
  183. fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
  184. /* reset the MER1 bit */
  185. FMC_CTL &= (~FMC_CTL_MER1);
  186. }
  187. /* return the fmc state */
  188. return fmc_state;
  189. }
  190. /*!
  191. \brief program a word at the corresponding address
  192. \param[in] address: address to program
  193. \param[in] data: word to program
  194. \param[out] none
  195. \retval fmc_state_enum
  196. */
  197. fmc_state_enum fmc_word_program(uint32_t address, uint32_t data)
  198. {
  199. fmc_state_enum fmc_state = FMC_READY;
  200. /* wait for the FMC ready */
  201. fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
  202. if(FMC_READY == fmc_state){
  203. /* set the PG bit to start program */
  204. FMC_CTL &= ~FMC_CTL_PSZ;
  205. FMC_CTL |= CTL_PSZ_WORD;
  206. FMC_CTL |= FMC_CTL_PG;
  207. REG32(address) = data;
  208. /* wait for the FMC ready */
  209. fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
  210. /* reset the PG bit */
  211. FMC_CTL &= ~FMC_CTL_PG;
  212. }
  213. /* return the FMC state */
  214. return fmc_state;
  215. }
  216. /*!
  217. \brief program a half word at the corresponding address
  218. \param[in] address: address to program
  219. \param[in] data: halfword to program
  220. \param[out] none
  221. \retval fmc_state_enum
  222. */
  223. fmc_state_enum fmc_halfword_program(uint32_t address, uint16_t data)
  224. {
  225. fmc_state_enum fmc_state = FMC_READY;
  226. /* wait for the FMC ready */
  227. fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
  228. if(FMC_READY == fmc_state){
  229. /* set the PG bit to start program */
  230. FMC_CTL &= ~FMC_CTL_PSZ;
  231. FMC_CTL |= CTL_PSZ_HALF_WORD;
  232. FMC_CTL |= FMC_CTL_PG;
  233. REG16(address) = data;
  234. /* wait for the FMC ready */
  235. fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
  236. /* reset the PG bit */
  237. FMC_CTL &= ~FMC_CTL_PG;
  238. }
  239. /* return the FMC state */
  240. return fmc_state;
  241. }
  242. /*!
  243. \brief program a byte at the corresponding address
  244. \param[in] address: address to program
  245. \param[in] data: byte to program
  246. \param[out] none
  247. \retval fmc_state_enum
  248. */
  249. fmc_state_enum fmc_byte_program(uint32_t address, uint8_t data)
  250. {
  251. fmc_state_enum fmc_state = FMC_READY;
  252. /* wait for the FMC ready */
  253. fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
  254. if(FMC_READY == fmc_state){
  255. /* set the PG bit to start program */
  256. FMC_CTL &= ~FMC_CTL_PSZ;
  257. FMC_CTL |= CTL_PSZ_BYTE;
  258. FMC_CTL |= FMC_CTL_PG;
  259. REG8(address) = data;
  260. /* wait for the FMC ready */
  261. fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
  262. /* reset the PG bit */
  263. FMC_CTL &= ~FMC_CTL_PG;
  264. }
  265. /* return the FMC state */
  266. return fmc_state;
  267. }
  268. /*!
  269. \brief unlock the option byte operation
  270. \param[in] none
  271. \param[out] none
  272. \retval none
  273. */
  274. void ob_unlock(void)
  275. {
  276. if(RESET != (FMC_OBCTL0 & FMC_OBCTL0_OB_LK)){
  277. /* write the FMC key */
  278. FMC_OBKEY = OB_UNLOCK_KEY0;
  279. FMC_OBKEY = OB_UNLOCK_KEY1;
  280. }
  281. }
  282. /*!
  283. \brief lock the option byte operation
  284. \param[in] none
  285. \param[out] none
  286. \retval none
  287. */
  288. void ob_lock(void)
  289. {
  290. /* reset the OB_LK bit */
  291. FMC_OBCTL0 &= ~FMC_OBCTL0_OB_LK;
  292. }
  293. /*!
  294. \brief send option byte change command
  295. \param[in] none
  296. \param[out] none
  297. \retval none
  298. */
  299. void ob_start(void)
  300. {
  301. /* set the OB_START bit in OBCTL0 register */
  302. FMC_OBCTL0 |= FMC_OBCTL0_OB_START;
  303. }
  304. /*!
  305. \brief enable write protection
  306. \param[in] ob_wp: specify sector to be write protected
  307. \arg OB_WPx(x=0..11): write protect specify sector
  308. \arg OB_WP_ALL: write protect all sector
  309. \param[out] none
  310. \retval none
  311. */
  312. void ob_write_protection0_enable(uint32_t ob_wp)
  313. {
  314. fmc_state_enum fmc_state = FMC_READY;
  315. /* wait for the FMC ready */
  316. fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
  317. if(FMC_READY == fmc_state){
  318. FMC_OBCTL0 &= (~((uint32_t)ob_wp << 16));
  319. }
  320. }
  321. /*!
  322. \brief disable write protection
  323. \param[in] ob_wp: specify sector to be write protected
  324. \arg OB_WPx(x=0..11): write protect specify sector
  325. \arg OB_WP_ALL: write protect all sector
  326. \param[out] none
  327. \retval none
  328. */
  329. void ob_write_protection0_disable(uint32_t ob_wp)
  330. {
  331. fmc_state_enum fmc_state = FMC_READY;
  332. /* wait for the FMC ready */
  333. fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
  334. if(FMC_READY == fmc_state){
  335. FMC_OBCTL0 |= ((uint32_t)ob_wp << 16);
  336. }
  337. }
  338. /*!
  339. \brief enable write protection
  340. \param[in] ob_wp: specify sector to be write protected
  341. \arg OB_WPx(x=12..30): write protect specify sector
  342. \arg OB_WP_ALL: write protect all sector
  343. \param[out] none
  344. \retval none
  345. */
  346. void ob_write_protection1_enable(uint32_t ob_wp)
  347. {
  348. fmc_state_enum fmc_state = FMC_READY;
  349. /* wait for the FMC ready */
  350. fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
  351. if(FMC_READY == fmc_state){
  352. FMC_OBCTL1 &= (~((uint32_t)ob_wp << 16));
  353. }
  354. }
  355. /*!
  356. \brief disable write protection
  357. \param[in] ob_wp: specify sector to be write protected
  358. \arg OB_WPx(x=12..30): write protect specify sector
  359. \arg OB_WP_ALL: write protect all sector
  360. \param[out] none
  361. \retval none
  362. */
  363. void ob_write_protection1_disable(uint32_t ob_wp)
  364. {
  365. fmc_state_enum fmc_state = FMC_READY;
  366. /* wait for the FMC ready */
  367. fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
  368. if(FMC_READY == fmc_state){
  369. FMC_OBCTL1 |= ((uint32_t)ob_wp << 16);
  370. }
  371. }
  372. /*!
  373. \brief configure the protection mode
  374. \param[in] ob_drp: configure the protection mode of WPx bits
  375. \arg OB_DRP_DISABLE: the WPx bits used as erase/program protection of each sector
  376. \arg OB_DRP_ENABLE: the WPx bits used as erase/program protection and D-bus read protection of each sector
  377. \param[out] none
  378. \retval none
  379. */
  380. void ob_drp_config(uint32_t ob_drp)
  381. {
  382. FMC_OBCTL0 &= ~FMC_OBCTL0_DRP;
  383. FMC_OBCTL0 |= ob_drp;
  384. }
  385. /*!
  386. \brief enable erase/program protection and D-bus read protection
  387. \param[in] ob_drp: enable the WPx bits used as erase/program protection and D-bus read protection of each sector
  388. \arg OB_DRPx(x=0..11): erase/program protection and D-bus read protection of specify sector
  389. \arg OB_DRP_ALL: erase/program protection and D-bus read protection of all sector
  390. \param[out] none
  391. \retval none
  392. */
  393. void ob_drp0_enable(uint32_t ob_drp)
  394. {
  395. fmc_state_enum fmc_state = FMC_READY;
  396. /* wait for the FMC ready */
  397. fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
  398. if(FMC_READY == fmc_state){
  399. FMC_OBCTL0 |= ((uint32_t)ob_drp << 16);
  400. }
  401. }
  402. /*!
  403. \brief disable erase/program protection and D-bus read protection
  404. \param[in] ob_drp: disable the WPx bits used as erase/program protection and D-bus read protection of each sector
  405. \arg OB_DRPx(x=0..11): erase/program protection and D-bus read protection of specify sector
  406. \arg OB_DRP_ALL: erase/program protection and D-bus read protection of all sector
  407. \param[out] none
  408. \retval none
  409. */
  410. void ob_drp0_disable(uint32_t ob_drp)
  411. {
  412. fmc_state_enum fmc_state = FMC_READY;
  413. /* wait for the FMC ready */
  414. fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
  415. if(FMC_READY == fmc_state){
  416. FMC_OBCTL0 &= (~((uint32_t)ob_drp << 16));
  417. }
  418. }
  419. /*!
  420. \brief enable erase/program protection and D-bus read protection
  421. \param[in] ob_drp: enable the WPx bits used as erase/program protection and D-bus read protection of each sector
  422. \arg OB_DRPx(x=12..30): erase/program protection and D-bus read protection of specify sector
  423. \arg OB_DRP_ALL: erase/program protection and D-bus read protection of all sector
  424. \param[out] none
  425. \retval none
  426. */
  427. void ob_drp1_enable(uint32_t ob_drp)
  428. {
  429. fmc_state_enum fmc_state = FMC_READY;
  430. /* wait for the FMC ready */
  431. fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
  432. if(FMC_READY == fmc_state){
  433. FMC_OBCTL1 |= ((uint32_t)ob_drp << 16);
  434. }
  435. }
  436. /*!
  437. \brief disable erase/program protection and D-bus read protection
  438. \param[in] ob_drp: disable the WPx bits used as erase/program protection and D-bus read protection of each sector
  439. \arg OB_DRPx(x=12..30): erase/program protection and D-bus read protection of specify sector
  440. \arg OB_DRP_ALL: erase/program protection and D-bus read protection of all sector
  441. \param[out] none
  442. \retval none
  443. */
  444. void ob_drp1_disable(uint32_t ob_drp)
  445. {
  446. fmc_state_enum fmc_state = FMC_READY;
  447. /* wait for the FMC ready */
  448. fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
  449. if(FMC_READY == fmc_state){
  450. FMC_OBCTL1 &= (~((uint32_t)ob_drp << 16));
  451. }
  452. }
  453. /*!
  454. \brief configure security protection level
  455. \param[in] ob_spc: specify security protection level
  456. \arg FMC_NSPC: no security protection
  457. \arg FMC_LSPC: low security protection
  458. \arg FMC_HSPC: high security protection
  459. \param[out] none
  460. \retval none
  461. */
  462. void ob_security_protection_config(uint8_t ob_spc)
  463. {
  464. fmc_state_enum fmc_state = FMC_READY;
  465. /* wait for the FMC ready */
  466. fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
  467. if(FMC_READY == fmc_state){
  468. uint32_t reg;
  469. reg = FMC_OBCTL0;
  470. /* reset the OBCTL0_SPC, set according to ob_spc */
  471. reg &= ~FMC_OBCTL0_SPC;
  472. FMC_OBCTL0 |= ((uint32_t)ob_spc << 8);
  473. }
  474. }
  475. /*!
  476. \brief program the FMC user option byte
  477. \param[in] ob_fwdgt: option byte watchdog value
  478. \arg OB_FWDGT_SW: software free watchdog
  479. \arg OB_FWDGT_HW: hardware free watchdog
  480. \param[in] ob_deepsleep: option byte deepsleep reset value
  481. \arg OB_DEEPSLEEP_NRST: no reset when entering deepsleep mode
  482. \arg OB_DEEPSLEEP_RST: generate a reset instead of entering deepsleep mode
  483. \param[in] ob_stdby:option byte standby reset value
  484. \arg OB_STDBY_NRST: no reset when entering standby mode
  485. \arg OB_STDBY_RST: generate a reset instead of entering standby mode
  486. \param[out] none
  487. \retval none
  488. */
  489. void ob_user_write(uint32_t ob_fwdgt, uint32_t ob_deepsleep, uint32_t ob_stdby)
  490. {
  491. fmc_state_enum fmc_state = FMC_READY;
  492. /* wait for the FMC ready */
  493. fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
  494. if(FMC_READY == fmc_state){
  495. uint32_t reg;
  496. reg = FMC_OBCTL0;
  497. /* reset the OB_FWDGT, OB_DEEPSLEEP and OB_STDBY, set according to ob_fwdgt ,ob_deepsleep and ob_stdby */
  498. reg &= ~(FMC_OBCTL0_NWDG_HW | FMC_OBCTL0_NRST_DPSLP | FMC_OBCTL0_NRST_STDBY);
  499. FMC_OBCTL0 = (reg | ob_fwdgt | ob_deepsleep | ob_stdby);
  500. }
  501. }
  502. /*!
  503. \brief program the option byte BOR threshold value
  504. \param[in] ob_bor_th: user option byte
  505. \arg OB_BOR_TH_VALUE3: BOR threshold value 3
  506. \arg OB_BOR_TH_VALUE2: BOR threshold value 2
  507. \arg OB_BOR_TH_VALUE1: BOR threshold value 1
  508. \arg OB_BOR_TH_OFF: no BOR function.
  509. \param[out] none
  510. \retval none
  511. */
  512. void ob_user_bor_threshold(uint32_t ob_bor_th)
  513. {
  514. uint32_t reg;
  515. reg = FMC_OBCTL0;
  516. /* set the BOR level */
  517. reg &= ~FMC_OBCTL0_BOR_TH;
  518. FMC_OBCTL0 = (reg | ob_bor_th);
  519. }
  520. /*!
  521. \brief configure the option byte boot bank value
  522. \param[in] boot_mode: specifies the option byte boot bank value
  523. \arg OB_BB_DISABLE: boot from bank0
  524. \arg OB_BB_ENABLE: boot from bank1 or bank0 if bank1 is void
  525. \param[out] none
  526. \retval none
  527. */
  528. void ob_boot_mode_config(uint32_t boot_mode)
  529. {
  530. uint32_t reg;
  531. reg = FMC_OBCTL0;
  532. /* set option byte boot bank value */
  533. reg &= ~FMC_OBCTL0_BB;
  534. FMC_OBCTL0 = (reg | boot_mode);
  535. }
  536. /*!
  537. \brief get the FMC user option byte
  538. \param[in] none
  539. \param[out] none
  540. \retval the FMC user option byte values: ob_fwdgt(Bit0), ob_deepsleep(Bit1), ob_stdby(Bit2).
  541. */
  542. uint8_t ob_user_get(void)
  543. {
  544. return (uint8_t)((uint8_t)(FMC_OBCTL0 >> 5) & (uint8_t)0x07);
  545. }
  546. /*!
  547. \brief get the FMC option byte write protection
  548. \param[in] none
  549. \param[out] none
  550. \retval the FMC write protection option byte value
  551. */
  552. uint16_t ob_write_protection0_get(void)
  553. {
  554. /* return the FMC write protection option byte value */
  555. return (uint16_t)(((uint16_t)(FMC_OBCTL0 >> 16)) & (uint16_t)0x0FFF);
  556. }
  557. /*!
  558. \brief get the FMC option byte write protection
  559. \param[in] none
  560. \param[out] none
  561. \retval the FMC write protection option byte value
  562. */
  563. uint16_t ob_write_protection1_get(void)
  564. {
  565. /* return the the FMC write protection option byte value */
  566. return (uint16_t)(((uint16_t)(FMC_OBCTL1 >> 16)) & (uint16_t)0x0FFF);
  567. }
  568. /*!
  569. \brief get the FMC D-bus read protection protection
  570. \param[in] none
  571. \param[out] none
  572. \retval the FMC erase/program protection and D-bus read protection option bytes value
  573. */
  574. uint16_t ob_drp0_get(void)
  575. {
  576. /* return the FMC erase/program protection and D-bus read protection option bytes value */
  577. return (uint16_t)(((uint16_t)(FMC_OBCTL0 >> 16)) & (uint16_t)0x0FFF);
  578. }
  579. /*!
  580. \brief get the FMC D-bus read protection protection
  581. \param[in] none
  582. \param[out] none
  583. \retval the FMC erase/program protection and D-bus read protection option bytes value
  584. */
  585. uint16_t ob_drp1_get(void)
  586. {
  587. /* return the FMC erase/program protection and D-bus read protection option bytes value */
  588. return (uint16_t)(((uint16_t)(FMC_OBCTL1 >> 16)) & (uint16_t)0x0FFF);
  589. }
  590. /*!
  591. \brief get the FMC option byte security protection
  592. \param[in] none
  593. \param[out] none
  594. \retval FlagStatus: SET or RESET
  595. */
  596. FlagStatus ob_spc_get(void)
  597. {
  598. FlagStatus spc_state = RESET;
  599. if (((uint8_t)(FMC_OBCTL0 >> 8)) != (uint8_t)FMC_NSPC){
  600. spc_state = SET;
  601. }else{
  602. spc_state = RESET;
  603. }
  604. return spc_state;
  605. }
  606. /*!
  607. \brief get the FMC option byte BOR threshold value
  608. \param[in] none
  609. \param[out] none
  610. \retval the FMC BOR threshold value:OB_BOR_TH_OFF,OB_BOR_TH_VALUE1,OB_BOR_TH_VALUE2,OB_BOR_TH_VALUE3
  611. */
  612. uint8_t ob_user_bor_threshold_get(void)
  613. {
  614. /* return the FMC BOR threshold value */
  615. return (uint8_t)((uint8_t)FMC_OBCTL0 & (uint8_t)0x0C);
  616. }
  617. /*!
  618. \brief enable FMC interrupt
  619. \param[in] the FMC interrupt source
  620. \arg FMC_INTEN_END: enable FMC end of program interrupt
  621. \arg FMC_INTEN_ERR: enable FMC error interrupt
  622. \param[out] none
  623. \retval none
  624. */
  625. void fmc_interrupt_enable(uint32_t fmc_int)
  626. {
  627. FMC_CTL |= fmc_int;
  628. }
  629. /*!
  630. \brief disable FMC interrupt
  631. \param[in] the FMC interrupt source
  632. \arg FMC_INTEN_END: disable FMC end of program interrupt
  633. \arg FMC_INTEN_ERR: disable FMC error interrupt
  634. \param[out] none
  635. \retval none
  636. */
  637. void fmc_interrupt_disable(uint32_t fmc_int)
  638. {
  639. FMC_CTL &= ~(uint32_t)fmc_int;
  640. }
  641. /*!
  642. \brief get flag set or reset
  643. \param[in] fmc_flag: check FMC flag
  644. \arg FMC_FLAG_BUSY: FMC busy flag
  645. \arg FMC_FLAG_RDDERR: FMC read D-bus protection error flag bit
  646. \arg FMC_FLAG_PGSERR: FMC program sequence error flag bit
  647. \arg FMC_FLAG_PGMERR: FMC program size not match error flag bit
  648. \arg FMC_FLAG_WPERR: FMC Erase/Program protection error flag bit
  649. \arg FMC_FLAG_OPERR: FMC operation error flag bit
  650. \arg FMC_FLAG_END: FMC end of operation flag bit
  651. \param[out] none
  652. \retval FlagStatus: SET or RESET
  653. */
  654. FlagStatus fmc_flag_get(uint32_t fmc_flag)
  655. {
  656. if(FMC_STAT & fmc_flag){
  657. return SET;
  658. }
  659. /* return the state of corresponding FMC flag */
  660. return RESET;
  661. }
  662. /*!
  663. \brief clear the FMC pending flag
  664. \param[in] FMC_flag: clear FMC flag
  665. \arg FMC_FLAG_RDDERR: FMC read D-bus protection error flag bit
  666. \arg FMC_FLAG_PGSERR: FMC program sequence error flag bit
  667. \arg FMC_FLAG_PGMERR: FMC program size not match error flag bit
  668. \arg FMC_FLAG_WPERR: FMC erase/program protection error flag bit
  669. \arg FMC_FLAG_OPERR: FMC operation error flag bit
  670. \arg FMC_FLAG_END: FMC end of operation flag bit
  671. \param[out] none
  672. \retval none
  673. */
  674. void fmc_flag_clear(uint32_t fmc_flag)
  675. {
  676. /* clear the flags */
  677. FMC_STAT = fmc_flag;
  678. }
  679. /*!
  680. \brief get the FMC state
  681. \param[in] none
  682. \param[out] none
  683. \retval fmc_state_enum
  684. */
  685. fmc_state_enum fmc_state_get(void)
  686. {
  687. fmc_state_enum fmc_state = FMC_READY;
  688. if((FMC_STAT & FMC_FLAG_BUSY) == FMC_FLAG_BUSY){
  689. fmc_state = FMC_BUSY;
  690. }else{
  691. if((FMC_STAT & FMC_FLAG_WPERR) != (uint32_t)0x00){
  692. fmc_state = FMC_WPERR;
  693. }else{
  694. if((FMC_STAT & FMC_FLAG_RDDERR) != (uint32_t)0x00){
  695. fmc_state = FMC_RDDERR;
  696. }else{
  697. if((FMC_STAT & (uint32_t)0xEF) != (uint32_t)0x00){
  698. fmc_state = FMC_PGERR;
  699. }else{
  700. if((FMC_STAT & FMC_FLAG_OPERR) != (uint32_t)0x00){
  701. fmc_state = FMC_OPERR;
  702. }else{
  703. fmc_state = FMC_READY;
  704. }
  705. }
  706. }
  707. }
  708. }
  709. /* return the FMC state */
  710. return fmc_state;
  711. }
  712. /*!
  713. \brief check whether FMC is ready or not
  714. \param[in] count: FMC_TIMEOUT_COUNT
  715. \param[out] none
  716. \retval fmc_state_enum
  717. */
  718. fmc_state_enum fmc_ready_wait(uint32_t count)
  719. {
  720. fmc_state_enum fmc_state = FMC_BUSY;
  721. /* wait for FMC ready */
  722. do{
  723. /* get FMC state */
  724. fmc_state = fmc_state_get();
  725. count--;
  726. }while((FMC_BUSY == fmc_state) && ((uint32_t)RESET != count));
  727. if(FMC_BUSY == fmc_state){
  728. fmc_state = FMC_TOERR;
  729. }
  730. /* return the FMC state */
  731. return fmc_state;
  732. }