flash.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688
  1. /******************************************************************************
  2. *Copyright(C)2018, Huada Semiconductor Co.,Ltd All rights reserved.
  3. *
  4. * This software is owned and published by:
  5. * Huada Semiconductor Co.,Ltd("HDSC").
  6. *
  7. * BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
  8. * BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
  9. *
  10. * This software contains source code for use with HDSC
  11. * components. This software is licensed by HDSC to be adapted only
  12. * for use in systems utilizing HDSC components. HDSC shall not be
  13. * responsible for misuse or illegal use of this software for devices not
  14. * supported herein. HDSC is providing this software "AS IS" and will
  15. * not be responsible for issues arising from incorrect user implementation
  16. * of the software.
  17. *
  18. * Disclaimer:
  19. * HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
  20. * REGARDING THE SOFTWARE (INCLUDING ANY ACOOMPANYING WRITTEN MATERIALS),
  21. * ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
  22. * WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
  23. * WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
  24. * WARRANTY OF NONINFRINGEMENT.
  25. * HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
  26. * NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
  27. * LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
  28. * LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
  29. * INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
  30. * INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
  31. * SAVINGS OR PROFITS,
  32. * EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
  33. * YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
  34. * INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
  35. * FROM, THE SOFTWARE.
  36. *
  37. * This software may be replicated in part or whole for the licensed use,
  38. * with the restriction that this Disclaimer and Copyright notice must be
  39. * included with each copy of this software, whether used in part or whole,
  40. * at all times.
  41. */
  42. /** \file flash.c
  43. **
  44. ** Common API of flash.
  45. ** @link flashGroup Some description @endlink
  46. **
  47. ** - 2018-05-08
  48. **
  49. ******************************************************************************/
  50. /*******************************************************************************
  51. * Include files
  52. ******************************************************************************/
  53. #include "flash.h"
  54. /**
  55. *******************************************************************************
  56. ** \addtogroup FlashGroup
  57. ******************************************************************************/
  58. //@{
  59. /*******************************************************************************
  60. * Local pre-processor symbols/macros ('#define')
  61. ******************************************************************************/
  62. #define FLASH_END_ADDR (0x0000FFFFu)
  63. #define FLASH_BYPASS() M0P_FLASH->BYPASS_f.BYSEQ = 0x5A5A;\
  64. M0P_FLASH->BYPASS_f.BYSEQ = 0xA5A5;
  65. #define FLASH_IE_TRUE (0x03)
  66. #define FLASH_IE_FALSE (0x00)
  67. /*******************************************************************************
  68. * Global variable definitions (declared in header file with 'extern')
  69. ******************************************************************************/
  70. /*******************************************************************************
  71. * Local type definitions ('typedef')
  72. ******************************************************************************/
  73. /**
  74. ******************************************************************************
  75. ** \brief FLASH OP
  76. **
  77. ** Flash 操作控制数据类型重定义
  78. ******************************************************************************/
  79. typedef enum en_flash_op
  80. {
  81. Read = 0u, ///<读配置值
  82. Program = 1u, ///<编程配置值
  83. SectorErase = 2u, ///<扇区擦除配置值
  84. ChipErase = 3u, ///<全片擦除配置值
  85. } en_flash_op_t;
  86. /**
  87. ******************************************************************************
  88. ** \brief FLASH LOCK
  89. **
  90. ** Flash 加解锁数据类型重定义
  91. ******************************************************************************/
  92. typedef enum en_flash_lock
  93. {
  94. LockAll = 0x00000000u, ///<全片加锁
  95. UnlockAll = (int)0xFFFFFFFFu, ///<全片解锁
  96. } en_flash_lock_t;
  97. /**
  98. ******************************************************************************
  99. ** \brief FLASH 编程时间参数配置
  100. **
  101. ** FLASH编程时间参数配置数据类型重定义 (4MHz)
  102. ******************************************************************************/
  103. typedef enum en_flash_prgtimer
  104. {
  105. Tnvs = 0x20u,
  106. Tpgs = 0x17u,
  107. Tprog = 0x1Bu,
  108. Tserase = 0x4650u,
  109. Tmerase = 0x222E0u,
  110. Tprcv = 0x18u,
  111. Tsrcv = 0xF0u,
  112. Tmrcv = 0x3E8u,
  113. } en_flash_prgtimer_t;
  114. /*******************************************************************************
  115. * Local variable definitions ('static')
  116. ******************************************************************************/
  117. /*******************************************************************************
  118. * Local function prototypes ('static')
  119. ******************************************************************************/
  120. static func_ptr_t pfnFlashCallback = NULL;
  121. /*******************************************************************************
  122. * Function implementation - global ('extern') and local ('static')
  123. ******************************************************************************/
  124. /**
  125. *****************************************************************************
  126. ** \brief Flash中断服务函数
  127. **
  128. **
  129. ** \param [in] u8Param == 0
  130. **
  131. *****************************************************************************/
  132. void EfRam_IRQHandler(uint8_t u8Param)
  133. {
  134. if(NULL != pfnFlashCallback)
  135. {
  136. pfnFlashCallback();
  137. }
  138. }
  139. /**
  140. *****************************************************************************
  141. ** \brief Flash中断标志获取
  142. **
  143. **
  144. ** \param [in] enFlashIntType Flash中断类型
  145. **
  146. ** \retval TRUE or FALSE
  147. *****************************************************************************/
  148. boolean_t Flash_GetIntFlag(en_flash_int_type_t enFlashIntType)
  149. {
  150. boolean_t bRetVal = FALSE;
  151. switch (enFlashIntType)
  152. {
  153. case FlashPCInt:
  154. bRetVal = M0P_FLASH->IFR_f.IF0 ? TRUE : FALSE;
  155. break;
  156. case FlashSlockInt:
  157. bRetVal = M0P_FLASH->IFR_f.IF1 ? TRUE : FALSE;
  158. break;
  159. default:
  160. bRetVal = FALSE;
  161. break;
  162. }
  163. return bRetVal;
  164. }
  165. /**
  166. *****************************************************************************
  167. ** \brief Flash中断标志清除
  168. **
  169. **
  170. ** \param [in] enFlashIntType Flash中断类型
  171. **
  172. ** \retval Ok or Error
  173. *****************************************************************************/
  174. en_result_t Flash_ClearIntFlag(en_flash_int_type_t enFlashIntType)
  175. {
  176. en_result_t enResult = Error;
  177. switch (enFlashIntType)
  178. {
  179. case FlashPCInt:
  180. FLASH_BYPASS();
  181. M0P_FLASH->ICLR_f.ICLR0 = FALSE;
  182. enResult = Ok;
  183. break;
  184. case FlashSlockInt:
  185. FLASH_BYPASS();
  186. M0P_FLASH->ICLR_f.ICLR1 = FALSE;
  187. enResult = Ok;
  188. break;
  189. default:
  190. enResult = Error;
  191. break;
  192. }
  193. return enResult;
  194. }
  195. /**
  196. *****************************************************************************
  197. ** \brief Flash中断使能
  198. **
  199. **
  200. ** \param [in] enFlashIntType Flash中断类型
  201. **
  202. ** \retval Ok or Error
  203. *****************************************************************************/
  204. en_result_t Flash_EnableIrq (en_flash_int_type_t enFlashIntType)
  205. {
  206. en_result_t enResult = Error;
  207. switch (enFlashIntType)
  208. {
  209. case FlashPCInt:
  210. FLASH_BYPASS();
  211. M0P_FLASH->CR_f.IE |= 0x01;
  212. enResult = Ok;
  213. break;
  214. case FlashSlockInt:
  215. FLASH_BYPASS();
  216. M0P_FLASH->CR_f.IE |= 0x02;
  217. enResult = Ok;
  218. break;
  219. default:
  220. enResult = Error;
  221. break;
  222. }
  223. return enResult;
  224. }
  225. /**
  226. *****************************************************************************
  227. ** \brief Flash中断禁止
  228. **
  229. **
  230. ** \param [in] enFlashIntType Flash中断类型
  231. **
  232. ** \retval Ok or Error
  233. *****************************************************************************/
  234. en_result_t Flash_DisableIrq(en_flash_int_type_t enFlashIntType)
  235. {
  236. en_result_t enResult = Error;
  237. switch (enFlashIntType)
  238. {
  239. case FlashSlockInt:
  240. FLASH_BYPASS();
  241. M0P_FLASH->CR_f.IE &= ~0x02u;
  242. enResult = Ok;
  243. break;
  244. case FlashPCInt:
  245. FLASH_BYPASS();
  246. M0P_FLASH->CR_f.IE &= ~0x01u;
  247. enResult = Ok;
  248. break;
  249. default:
  250. enResult = Error;
  251. break;
  252. }
  253. return enResult;
  254. }
  255. /**
  256. *****************************************************************************
  257. ** \brief FLASH 初始化函数——中断服务程序、编程时间配置及低功耗模式
  258. **
  259. ** 该函数用于配置中断服务函数、低功耗模式、根据系统时钟配置FLASH编程时间相关寄存器.
  260. **
  261. ** \param [in] pfnFlashCb Flash中断服务回调函数[void function(void)]
  262. ** \param [in] u8FreqCfg FLASH编程时钟频率配置(根据HCLK的频率选择配置值):
  263. ** 1 - (0,4]MHz;
  264. ** 2 - (4,8]MHz;
  265. ** 4 - (8,16]MHz;
  266. ** 6 - (16,24]MHz;
  267. ** 8 - (24,32]MHz(该配置会设置插入1个FLASH等待周期);
  268. ** 12 - (32,48]MHz(该配置会设置插入1个FLASH等待周期);
  269. ** other - 无效值
  270. ** \param [in] bDpstbEn TRUE - 当系统进入DeepSleep模式,FLASH进入低功耗模式;
  271. ** FALSE - 当系统进入DeepSleep模式,FLASH不进入低功耗模式;
  272. **
  273. ** \retval Ok 操作成功.
  274. ** \retval ErrorInvalidParameter 参数无效.
  275. **
  276. *****************************************************************************/
  277. en_result_t Flash_Init(func_ptr_t pfnFlashCb, uint8_t u8FreqCfg, boolean_t bDpstbEn)
  278. {
  279. en_result_t enResult = Ok;
  280. if ((1 != u8FreqCfg) &&
  281. (2 != u8FreqCfg) &&
  282. (4 != u8FreqCfg) &&
  283. (6 != u8FreqCfg) &&
  284. (8 != u8FreqCfg) &&
  285. (12 != u8FreqCfg))
  286. {
  287. enResult = ErrorInvalidParameter;
  288. return (enResult);
  289. }
  290. //当系统进入DeepSleep模式时,FLASH模式配置
  291. FLASH_BYPASS();
  292. M0P_FLASH->CR_f.DPSTB_EN = bDpstbEn;
  293. //flash时间参数寄存器配置
  294. FLASH_BYPASS();
  295. M0P_FLASH->TNVS_f.TNVS = Tnvs * u8FreqCfg;
  296. FLASH_BYPASS();
  297. M0P_FLASH->TPGS_f.TPGS = Tpgs * u8FreqCfg;
  298. FLASH_BYPASS();
  299. M0P_FLASH->TPROG_f.TPROG = Tprog * u8FreqCfg;
  300. FLASH_BYPASS();
  301. M0P_FLASH->TSERASE_f.TSERASE = Tserase * u8FreqCfg;
  302. FLASH_BYPASS();
  303. M0P_FLASH->TMERASE_f.TMERASE = Tmerase * u8FreqCfg;
  304. FLASH_BYPASS();
  305. M0P_FLASH->TPRCV_f.TPRCV = Tprcv * u8FreqCfg;
  306. FLASH_BYPASS();
  307. M0P_FLASH->TSRCV_f.TSRCV = Tsrcv * u8FreqCfg;
  308. FLASH_BYPASS();
  309. M0P_FLASH->TMRCV_f.TMRCV = Tmrcv * u8FreqCfg;
  310. //开启读FLASH等待周期
  311. if (8 == u8FreqCfg)
  312. {
  313. FLASH_BYPASS();
  314. M0P_FLASH->CR_f.WAIT = 0x01;
  315. }
  316. else if(12 == u8FreqCfg)
  317. {
  318. FLASH_BYPASS();
  319. M0P_FLASH->CR_f.WAIT = 0x01;
  320. }
  321. else
  322. {
  323. FLASH_BYPASS();
  324. M0P_FLASH->CR_f.WAIT = 0x00;
  325. }
  326. pfnFlashCallback = pfnFlashCb;
  327. return (enResult);
  328. }
  329. /**
  330. *****************************************************************************
  331. ** \brief FLASH 字节写
  332. **
  333. ** 用于向FLASH写入1字节数据.
  334. **
  335. ** \param [in] u32Addr Flash地址
  336. ** \param [in] u8Data 1字节数据
  337. **
  338. ** \retval Ok 写入成功.
  339. ** \retval ErrorInvalidParameter FLASH地址无效
  340. *****************************************************************************/
  341. en_result_t Flash_WriteByte(uint32_t u32Addr, uint8_t u8Data)
  342. {
  343. en_result_t enResult = Ok;
  344. if (FLASH_END_ADDR < u32Addr)
  345. {
  346. enResult = ErrorInvalidParameter;
  347. return (enResult);
  348. }
  349. //unlock flash
  350. FLASH_BYPASS();
  351. M0P_FLASH->SLOCK_f.SLOCK = (uint32_t)UnlockAll;
  352. //busy?
  353. while (TRUE == M0P_FLASH->CR_f.BUSY)
  354. {
  355. ;
  356. }
  357. //set OP
  358. FLASH_BYPASS();
  359. M0P_FLASH->CR_f.OP = Program;
  360. //write data
  361. *((volatile uint8_t*)u32Addr) = u8Data;
  362. //busy?
  363. while (TRUE == M0P_FLASH->CR_f.BUSY)
  364. {
  365. ;
  366. }
  367. //lock flash
  368. FLASH_BYPASS();
  369. M0P_FLASH->SLOCK_f.SLOCK = (uint32_t)LockAll;
  370. return (enResult);
  371. }
  372. /**
  373. *****************************************************************************
  374. ** \brief FLASH 半字写
  375. **
  376. ** 用于向FLASH写入半字(2字节)数据.
  377. **
  378. ** \param [in] u32Addr Flash地址
  379. ** \param [in] u16Data 半字(2字节)数据
  380. **
  381. ** \retval Ok 写入成功.
  382. ** \retval ErrorInvalidParameter FLASH地址无效
  383. *****************************************************************************/
  384. en_result_t Flash_WriteHalfWord(uint32_t u32Addr, uint16_t u16Data)
  385. {
  386. en_result_t enResult = Ok;
  387. if ((FLASH_END_ADDR < u32Addr) || (u32Addr % 2))
  388. {
  389. enResult = ErrorInvalidParameter;
  390. return (enResult);
  391. }
  392. //unlock flash
  393. FLASH_BYPASS();
  394. M0P_FLASH->SLOCK_f.SLOCK = (uint32_t)UnlockAll;
  395. //busy?
  396. while (TRUE == M0P_FLASH->CR_f.BUSY)
  397. {
  398. ;
  399. }
  400. //set OP
  401. FLASH_BYPASS();
  402. M0P_FLASH->CR_f.OP = Program;
  403. //write data
  404. *((volatile uint16_t*)u32Addr) = u16Data;
  405. //busy?
  406. while (TRUE == M0P_FLASH->CR_f.BUSY)
  407. {
  408. ;
  409. }
  410. //lock flash
  411. FLASH_BYPASS();
  412. M0P_FLASH->SLOCK_f.SLOCK = (uint32_t)LockAll;
  413. return (enResult);
  414. }
  415. /**
  416. *****************************************************************************
  417. ** \brief FLASH 字写
  418. **
  419. ** 用于向FLASH写入1个字的数据.
  420. **
  421. ** \param [in] u32Addr Flash地址
  422. ** \param [in] u32Data 1个字数据
  423. **
  424. ** \retval Ok 写入成功.
  425. ** \retval ErrorInvalidParameter FLASH地址无效
  426. *****************************************************************************/
  427. en_result_t Flash_WriteWord(uint32_t u32Addr, uint32_t u32Data)
  428. {
  429. en_result_t enResult = Ok;
  430. if ((FLASH_END_ADDR < u32Addr) || (u32Addr % 4))
  431. {
  432. enResult = ErrorInvalidParameter;
  433. return (enResult);
  434. }
  435. //unlock flash
  436. FLASH_BYPASS();
  437. M0P_FLASH->SLOCK_f.SLOCK = (uint32_t)UnlockAll;
  438. //busy?
  439. while (TRUE == M0P_FLASH->CR_f.BUSY)
  440. {
  441. ;
  442. }
  443. //set OP
  444. FLASH_BYPASS();
  445. M0P_FLASH->CR_f.OP = Program;
  446. //write data
  447. *((volatile uint32_t*)u32Addr) = u32Data;
  448. //busy?
  449. while (TRUE == M0P_FLASH->CR_f.BUSY)
  450. {
  451. ;
  452. }
  453. //lock flash
  454. FLASH_BYPASS();
  455. M0P_FLASH->SLOCK_f.SLOCK = LockAll;
  456. return (enResult);
  457. }
  458. /**
  459. *****************************************************************************
  460. ** \brief FLASH 扇区擦除
  461. **
  462. ** FLASH 扇区擦除.
  463. **
  464. ** \param [in] u32SectorAddr 所擦除扇区内的地址
  465. **
  466. ** \retval Ok 擦除成功.
  467. ** \retval ErrorInvalidParameter FLASH地址无效
  468. *****************************************************************************/
  469. en_result_t Flash_SectorErase(uint32_t u32SectorAddr)
  470. {
  471. en_result_t enResult = Ok;
  472. if (FLASH_END_ADDR < u32SectorAddr)
  473. {
  474. enResult = ErrorInvalidParameter;
  475. return (enResult);
  476. }
  477. //unlock flash
  478. FLASH_BYPASS();
  479. M0P_FLASH->SLOCK_f.SLOCK = (uint32_t)UnlockAll;
  480. //busy?
  481. while (TRUE == M0P_FLASH->CR_f.BUSY)
  482. {
  483. ;
  484. }
  485. //set OP
  486. FLASH_BYPASS();
  487. M0P_FLASH->CR_f.OP = SectorErase;
  488. //write data
  489. *((volatile uint8_t*)u32SectorAddr) = 0;
  490. //busy?
  491. while (TRUE == M0P_FLASH->CR_f.BUSY)
  492. {
  493. ;
  494. }
  495. //lock flash
  496. FLASH_BYPASS();
  497. M0P_FLASH->SLOCK_f.SLOCK = LockAll;
  498. return (enResult);
  499. }
  500. /**
  501. *****************************************************************************
  502. ** \brief FLASH 全片擦除
  503. **
  504. ** FLASH 全片擦除.
  505. **
  506. **
  507. ** \retval Ok 擦除成功.
  508. **
  509. *****************************************************************************/
  510. en_result_t Flash_ChipErase(void)
  511. {
  512. en_result_t enResult = Ok;
  513. //unlock flash
  514. FLASH_BYPASS();
  515. M0P_FLASH->SLOCK_f.SLOCK = (uint32_t)UnlockAll;
  516. //busy?
  517. while (TRUE == M0P_FLASH->CR_f.BUSY)
  518. {
  519. ;
  520. }
  521. //set OP
  522. FLASH_BYPASS();
  523. M0P_FLASH->CR_f.OP = ChipErase;
  524. //write data
  525. *((volatile uint8_t*)0) = 0;
  526. //busy?
  527. while (TRUE == M0P_FLASH->CR_f.BUSY)
  528. {
  529. ;
  530. }
  531. //lock flash
  532. FLASH_BYPASS();
  533. M0P_FLASH->SLOCK_f.SLOCK = LockAll;
  534. return (enResult);
  535. }
  536. /**
  537. *****************************************************************************
  538. ** \brief FLASH 编程保护加锁
  539. **
  540. ** \param [in] enFlashSector 加锁范围选择枚举
  541. **
  542. ** \retval Ok 加锁成功
  543. ** \retval ErrorInvalidParameter 参数错误
  544. *****************************************************************************/
  545. en_result_t Flash_Lock(en_flash_sector_lock_t enFlashSector)
  546. {
  547. en_result_t enResult = Ok;
  548. FLASH_BYPASS();
  549. M0P_FLASH->SLOCK_f.SLOCK |= (uint32_t)enFlashSector;
  550. return enResult;
  551. }
  552. /**
  553. *****************************************************************************
  554. ** \brief FLASH 编程保护解锁
  555. **
  556. ** \param [in] enFlashSector 解锁范围选择枚举
  557. **
  558. ** \retval Ok 解锁成功
  559. ** \retval ErrorInvalidParameter 参数错误
  560. *****************************************************************************/
  561. en_result_t Flash_Unlock(en_flash_sector_lock_t enFlashSector)
  562. {
  563. en_result_t enResult = Ok;
  564. FLASH_BYPASS();
  565. M0P_FLASH->SLOCK_f.SLOCK &= ~(uint32_t)enFlashSector;
  566. return enResult;
  567. }
  568. /**
  569. *****************************************************************************
  570. ** \brief FLASH 读等待周期设置
  571. **
  572. ** \param [in] enWaitCycle 插入FLASH读等待周期数枚举类型
  573. **
  574. ** \retval Ok 解锁成功
  575. ** \retval ErrorInvalidParameter 参数错误
  576. *****************************************************************************/
  577. en_result_t Flash_WaitCycle(en_flash_waitcycle_t enWaitCycle)
  578. {
  579. en_result_t enResult = Ok;
  580. //插入FLASH读等待周期
  581. M0P_SYSCTRL->PERI_CLKEN_f.FLASH = 1;
  582. M0P_FLASH->BYPASS_f.BYSEQ = 0x5A5A;
  583. M0P_FLASH->BYPASS_f.BYSEQ = 0xA5A5;
  584. if (0 == enWaitCycle)
  585. {
  586. M0P_FLASH->CR_f.WAIT = 0;
  587. }
  588. else if(1 == enWaitCycle)
  589. {
  590. M0P_FLASH->CR_f.WAIT = 1;
  591. }
  592. else
  593. {
  594. M0P_FLASH->CR_f.WAIT = 2;
  595. }
  596. return enResult;
  597. }
  598. //@} // FlashGroup
  599. /*******************************************************************************
  600. * EOF (not truncated)
  601. ******************************************************************************/