tao_z
2022-05-29 fa8669b0092240642af78e84c0e89f596444fdad
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
/**
 ******************************************************************************
 * @file     xl_flash.c
 * @author   xu.wang
 * @version  4.5.2
 * @date     Fri Mar 26 17:29:12 2021
 * @brief    This file provide function about FLASH firmware program
 ******************************************************************************
 * @attention
 *
 * 2019 by Chipways Communications,Inc. All Rights Reserved.
 * This software is supplied under the terms of a license
 * agreement or non-disclosure agreement with Chipways.
 * Passing on and copying of this document,and communication
 * of its contents is not permitted without prior written
 * authorization.
 *
 * <h2><center>&copy; COPYRIGHT 2019 Chipways</center></h2>
 ******************************************************************************
 */
#if defined(__cplusplus)
extern "C"
{
#endif /* __cplusplus */
 
/* Includes ---------------------------------------------------------------*/
#include "xl_flash.h"
    /** @addtogroup XL6600_StdPeriph_Driver
     * @{
     */
 
    /** @defgroup FLASH FLASH Module
     * @brief FLASH Driver Modules Library
     * @{
     */
 
    /* Private typedef -----------------------------------------------------------*/
    /* Private define ------------------------------------------------------------*/
    /* Private macro -------------------------------------------------------------*/
    /* Private variables ---------------------------------------------------------*/
    /* Private function prototypes -----------------------------------------------*/
    /* Private functions ---------------------------------------------------------*/
 
    /** @defgroup FMC_Private_Functions
     * @{
     */
 
    /**
     * @brief FLASH³õʼ»¯.
     * @param BusClock:µ±Ç°FlashʱÖÓ
     * @retval ·µ»ØFLASH״̬.
     *        Õâ¸ö²ÎÊý¿ÉÒÔÈ¡ÏÂÃæµÄÖµ:
     *            @arg FLASH_ERR_INIT_CCIF£º¼ÓÔØÃüÁîδÍê³É
     *            @arg FLASH_ERR_INIT_CLK1M£ºCLK1M´íÎó
     */
    uint16_t FLASH_Init(uint8_t BusClockMhz)
    {
        uint16_t errorstatus;
        uint32_t clk1M = (uint32_t)BusClockMhz - 1u;
        uint32_t fcpco;
 
        errorstatus = FLASH_ERR_SUCCESS;
 
        if ((FMC->FSTAT & FMC_FSTAT_CCIF_MASK) != FMC_FSTAT_CCIF_MASK)
        {
            errorstatus |= (uint16_t)FLASH_ERR_INIT_CCIF;
        }
        else
        {
            fcpco = FMC->FCPC0;
            if (BusClockMhz > 48u)
            {
                /* high speed ,>48Mhz  */
                fcpco |= FMC_FCPC0_HSMD_MASK;
            }
            else
            {
                /* low speed ,<=48Mhz  */
                fcpco &= ~FMC_FCPC0_HSMD_MASK;
            }
            /* clk1m is not locked  */
            if ((fcpco & FMC_FCPC0_CLK1MLCK_MASK) != FMC_FCPC0_CLK1MLCK_MASK)
            {
                /* first clear the clk1M bit */
                fcpco &= ~FMC_FCPC0_CLK1M_MASK;
 
                fcpco |= (clk1M << FMC_FCPC0_CLK1M_SHIFT);
 
                FMC->FCPC0 = fcpco;
            }
            else
            {
                /* clk1m is locked  */
                if ((fcpco & FMC_FCPC0_CLK1M_MASK) != (clk1M << FMC_FCPC0_CLK1M_SHIFT))
                {
                    /* clk1m locked is wrong  */
                    errorstatus |= (uint16_t)FLASH_ERR_INIT_CLKIM;
                }
            }
        }
        return errorstatus;
    }
 
    /**
     * @brief flash±£»¤ÅäÖÃ
     * @param FLASH_ProtectType:±£»¤²ÎÊýÅäÖýṹÌå
     * @retval None
     */
    void FLASH_ProtecConfig(const FLASH_ProtectTypeDef *FLASH_ProtectType)
    {
        uint32_t temp;
 
        temp = FMC->FOSP;
        /* first clear the protection bits */
        temp &= ~(uint32_t)FLASH_PROTECT_MASK;
        /* set the protection bits */
        temp |= ((uint32_t)FLASH_ProtectType->FLASH_POPEN << FMC_FOSP_FPOPEN_SHIFT) | ((uint32_t)FLASH_ProtectType->FLASH_FPHDIS << FMC_FOSP_FPHDIS_SHIFT) |
                ((uint32_t)FLASH_ProtectType->FLASH_FPHS << FMC_FOSP_FPHS_SHIFT) | ((uint32_t)FLASH_ProtectType->FLASH_FPLDIS << FMC_FOSP_FPLDIS_SHIFT) |
                ((uint32_t)FLASH_ProtectType->FLASH_FPLS << FMC_FOSP_FPLS_SHIFT);
        FMC->FOSP = temp;
    }
 
    /**
     * @brief flashÃüÁîÍê³ÉÖжÏʹÄÜ.
     * @param  NewState£ºÑ¡ÔñÊÇ·ñʹÄÜ
     *        Õâ¸ö²ÎÊý¿ÉÒÔÈ¡ÏÂÃæµÄÖµ:
     *            @arg ENABLE £ºÊ¹ÄÜ
     *            @arg DISABLE £ºÊ§ÄÜ
     * @retval None
     */
    void FLASH_CCIEnableCmd(FunctionalState NewState)
    {
        if (NewState != DISABLE)
        {
            /* Enable the FLASH Command Complete interrupt */
            FMC->FCNFG |= FMC_FCNFG_CCIE_MASK;
        }
        else
        {
            /* Disable the FLASH Command Complete interrupt */
            FMC->FCNFG &= ~FMC_FCNFG_CCIE_MASK;
        }
    }
 
    /**
     * @brief flash¹Ø±ÕECC¹¦ÄÜ
     * @param  ecc_area£ºÑ¡ÔñµÄÇøÓò£¬´ÓFlashµÄ×î´óµØÖ·ÍùÉϼÆÊý
     *        Õâ¸ö²ÎÊý¿ÉÒÔÈ¡ÏÂÃæµÄÖµ:
     *            @arg FLASH_ECC_DISABLE_AREA_0KB  £º0KbµÄÇø¼ä
     *            @arg FLASH_ECC_DISABLE_AREA_1KB  £º1KbµÄÇø¼ä
     *            @arg FLASH_ECC_DISABLE_AREA_2KB  £º2KbµÄÇø¼ä
     *            @arg FLASH_ECC_DISABLE_AREA_4KB  £º4KbµÄÇø¼ä
     *            @arg FLASH_ECC_DISABLE_AREA_8KB  £º8KbµÄÇø¼ä
     *            @arg FLASH_ECC_DISABLE_AREA_16KB £º16KbµÄÇø¼ä
     *            @arg FLASH_ECC_DISABLE_AREA_32KB £º32KbµÄÇø¼ä
     *            @arg FLASH_ECC_DISABLE_AREA_64KB £º64KbµÄÇø¼ä
     * @retval None
     */
    void FLASH_DisableECCArea(uint8_t ecc_area)
    {
        FMC->FCNFG |= (uint32_t)ecc_area;
    }
 
    /**
     * @brief flash  »º´æÊÇÄÜ
     * @param  NewState£ºÑ¡ÔñÊÇ·ñʹÄÜ
     *        Õâ¸ö²ÎÊý¿ÉÒÔÈ¡ÏÂÃæµÄÖµ:
     *            @arg ENABLE £ºÊ¹ÄÜ
     *            @arg DISABLE £ºÊ§ÄÜ
     * @retval None
     */
    void FLASH_CacheCmd(FunctionalState NewState)
    {
        if (NewState != DISABLE)
        {
            /* Enable the cache */
            FMC->FCPC0 |= FMC_FCPC0_CEN_MASK;
        }
        else
        {
            /* Disable the cache */
            FMC->FCPC0 &= ~FMC_FCPC0_CEN_MASK;
        }
    }
    /**
     * @brief flashÔÚstopģʽϽøÈëÐÝÃßģʽ
     * @param  NewState£ºÑ¡ÔñÊÇ·ñʹÄÜ״̬.
     *        Õâ¸ö²ÎÊý¿ÉÒÔÈ¡ÏÂÃæµÄÖµ:
     *            @arg ENABLE £ºÊ¹ÄÜ
     *            @arg DISABLE £ºÊ§ÄÜ
     * @retval None
     */
    void FLASH_SleepInStopCmd(FunctionalState NewState)
    {
        if (NewState != DISABLE)
        {
            /* alow to enter sleep mode in stop mode */
            FMC->FCPC0 |= FMC_FCPC0_DPSTB_MASK;
        }
        else
        {
            /* Can not enter sleep mode in stop mode */
            FMC->FCPC0 &= ~FMC_FCPC0_DPSTB_MASK;
        }
    }
 
    /**
     * @brief CLK1MËø¶¨¿ØÖÆÊ¹ÄÜ
     * @param  NewState£ºÑ¡ÔñÊÇ·ñʹÄÜ״̬.
     *        Õâ¸ö²ÎÊý¿ÉÒÔÈ¡ÏÂÃæµÄÖµ:
     *            @arg ENABLE £ºÊ¹ÄÜ
     *            @arg DISABLE £ºÊ§ÄÜ
     * @retval None
     */
    void FLASH_LockClk1MCmd(FunctionalState NewState)
    {
        if (NewState != DISABLE)
        {
            /* alow to enter sleep mode in stop mode */
            FMC->FCPC0 |= FMC_FCPC0_CLK1MLCK_MASK;
        }
        else
        {
            /* Can not enter sleep mode in stop mode */
            FMC->FCPC0 &= ~FMC_FCPC0_CLK1MLCK_MASK;
        }
    }
 
    /**
     * @brief ÉèÖÃflash¶ÁÈ¡µÈ´ýÖÜÆÚ.
     * @param ReadWatiCycle:¶ÁÈ¡µÈ´ýÖÜÆÚ.
     * @retval None
     */
    void FLASH_SetReadWait(FLASH_ReadWaitCycleDef ReadWaitCycle)
    {
        uint32_t temp;
        /* Check the parameters */
        temp = FMC->FCPC0;
        /* first clear the RWC bit */
        temp &= ~FMC_FCPC0_RWC_MASK;
        /* set the RWC bit */
        temp |= ((uint32_t)ReadWaitCycle << FMC_FCPC0_RWC_SHIFT);
        FMC->FCPC0 = temp;
    }
 
    /**
     * @brief flashµÃµ½ÃüÁîÍê³ÉÖжϱêÖ¾
     * @param None
     * @retval ÖжÏ״̬±êÖ¾
     *        Õâ¸ö²ÎÊý¿ÉÒÔÈ¡ÏÂÃæµÄÖµ:
     *            @arg 0 £ºÉÁ´æÃüÁîÕýÔÚ½øÐÐÖÐ
     *            @arg 1 £ºÉÁ´æÃüÁîÍê³É
     */
    uint8_t FLASH_GetCmdFinshFlag(void)
    {
        uint8_t sta;
        if ((FMC->FSTAT & FMC_FSTAT_CCIF_MASK) == FMC_FSTAT_CCIF_MASK)
        {
            sta = 1;
        }
        else
        {
            sta = 0;
        }
        return sta;
    }
 
    /**
     * @brief »ñÈ¡´æ´¢Æ÷¿ØÖÆÃ¦±êÖ¾
     * @param None
     * @retval ´æ´¢Æ÷¿ØÖÆÃ¦±êÖ¾(Set or Reset)
     */
    uint8_t FLASH_GetControllerBusyFlag(void)
    {
        uint8_t sta;
        if ((FMC->FSTAT & FMC_FSTAT_MGBUSY_MASK) == FMC_FSTAT_MGBUSY_MASK)
        {
            sta = 1;
        }
        else
        {
            sta = 0;
        }
        return sta;
    }
 
    /**
     * @brief  flashÇå³ýÉÁ´æÃüÁîÖжϱêÖ¾
     * @param None
     * @retval None
     */
    void FLASH_LaunchCMD(void)
    {
        /* Launch a command */
        FMC->FSTAT |= 0x80000000u;
    }
 
    /**
     * @brief flash¼ì²â´íÎó״̬.
     * @param None
     * @retval ·µ»ØFLASH״̬.
     *        Õâ¸ö²ÎÊý¿ÉÒÔÈ¡ÏÂÃæµÄÖµ:
     *            @arg FLASH_ERR_ACCESS £ºflash·ÃÎÊ´íÎó±êÖ¾
     *            @arg FLASH_ERR_PROTECTION £ºflash±£»¤Î¥·´±êÖ¾
     *            @arg FLASH_ERR_ECC £ºECCУÑé´íÎó
     *            @arg FLASH_ERR_ERASEVERIFY £º²Á³ýÑéÖ¤´íÎó
     */
    uint16_t FLASH_CheckErrStatus(void)
    {
 
        uint16_t Errstatus;
 
        Errstatus = FLASH_ERR_SUCCESS;
 
        /* Access Error */
        if ((FMC->FSTAT & FMC_FSTAT_ACCERR_MASK) == FMC_FSTAT_ACCERR_MASK)
        {
            Errstatus |= (uint16_t)FLASH_ERR_ACCESS;
        }
 
        /* Flash Protection Violation */
        if ((FMC->FSTAT & FMC_FSTAT_FPVIOL_MASK) == FMC_FSTAT_FPVIOL_MASK)
        {
            Errstatus |= (uint16_t)FLASH_ERR_PROTECTION;
        }
 
        /* ECC error */
        if ((FMC->FSTAT & FMC_FSTAT_MGSTAT_MASK) == FLASH_FSTAT_MGSTAT0_MASK)
        {
            Errstatus |= (uint16_t)FLASH_ERR_ECC;
        }
 
        /* erase verify error */
        if ((FMC->FSTAT & FMC_FSTAT_MGSTAT_MASK) == FLASH_FSTAT_MGSTAT1_MASK)
        {
            Errstatus |= (uint16_t)FLASH_ERR_ERASEVERIFY;
        }
        return (Errstatus);
    }
 
    /**
     *
     * @brief flash±à³ÌÁ½¸ö×ÖÊý¾Ý
     * @param TargetAddress£º Ð´ÈëflashµÄµØÖ·
     *        Õâ¸ö²ÎÊý¿ÉÒÔÈ¡ÏÂÃæµÄÖµ:
     *        DwData0£ºÐ´ÈëÊý¾Ý¸ß×Ö
     *        DwData1£ºÐ´ÈëÊý¾ÝµÍ×Ö
     * @return ·µ»Øflash error״̬.
     */
    uint16_t FLASH_Program2LongWord(uint32_t TargetAddress, uint32_t DwData0, uint32_t DwData1)
    {
 
        uint16_t errorstatus;
 
        errorstatus = FLASH_ERR_SUCCESS;
 
        if ((TargetAddress & 0x03u) == 0x03u)
        {
            errorstatus = FLASH_ERR_INVALID_PARAM;
        }
        else
        {
            // Clear error flags
            FMC->FSTAT = FMC_FSTAT_FPVIOL_MASK | FMC_FSTAT_ACCERR_MASK;
 
            /* Write to specify the command code to be loaded */
            FMC->FCCOBF0 = (((uint32_t)FLASH_CMD_PROGRAM << FMC_FCCOBF0_FCMD_SHIFT) | (TargetAddress));
 
            /* Write to specify the Longword 0 program value to be loaded    */
            FMC->FCCOBF1 = DwData0;
 
            /* Write to specify the Longword 0 program value to be loaded    */
            FMC->FCCOBF2 = DwData1;
        }
 
        return (errorstatus);
    }
    /**
     * @brief Flash¶ÁË«×ÖÊý¾Ý
     * @param TargetAddress£º Ð´ÈëflashµÄµØÖ·
     * @retval ¶Á³öµÄÊý¾Ý
     */
 
    uint64_t FLASH_ReadLongWord(const uint32_t *TargetAddress)
    {
        uint32_t rdata1, rdata2;
        uint64_t data;
 
        rdata1 = TargetAddress[0];
        rdata2 = TargetAddress[1];
 
        data = ((uint64_t)rdata2 << 32) | (uint64_t)rdata1;
 
        return data;
    }
 
    void FLASH_ReadLongWordCmd(uint32_t TargetAddress)
    {
 
        FMC->FCCOBF0 = ((uint32_t)FLASH_CMD_READ << FMC_FCCOBF0_FCMD_SHIFT) | (TargetAddress);
 
        FLASH_LaunchCMD();
    }
 
    /**
     * @brief ²Á³ýÕû¸öflash
     * @param None
     * @retval ·µ»ØFLASH״̬.
     */
    void FLASH_EraseChip(void)
    {
 
        FMC->FSTAT = FMC_FSTAT_FPVIOL_MASK | FMC_FSTAT_ACCERR_MASK;
 
        /* Write to specify the command code to be loaded */
        FMC->FCCOBF0 = ((uint32_t)FLASH_CMD_ERASE_CHIP << FMC_FCCOBF0_FCMD_SHIFT);
    }
 
    /**
     * @brief FlashÉÈÇø²Á³ý
     * @param  TargetAddress: ²Á³ýÉÈÇøµÄµØÖ·
     * @retval ·µ»ØFLASH״̬.
     */
    uint16_t FLASH_EraseSector(uint32_t TargetAddress)
    {
        uint16_t errorstatus;
 
        errorstatus = FLASH_ERR_SUCCESS;
 
        if ((TargetAddress & 0x03u) == 0x03u)
        {
            errorstatus = FLASH_ERR_INVALID_PARAM;
        }
        else
        {
            // Clear error flags
            FMC->FSTAT = FMC_FSTAT_FPVIOL_MASK | FMC_FSTAT_ACCERR_MASK;
 
            /* Write to specify the command code to be loaded */
            FMC->FCCOBF0 = (((uint32_t)FLASH_CMD_ERASE_SECTOR << FMC_FCCOBF0_FCMD_SHIFT) | (TargetAddress));
        }
 
        return (errorstatus);
    }
 
    /**
     * @brief flashÖØÆô
     * @param None
     * @retval ·µ»ØFLASH״̬.
     */
    void FLASH_PowerOnReset(void)
    {
 
        FMC->FSTAT = FMC_FSTAT_FPVIOL_MASK | FMC_FSTAT_ACCERR_MASK;
 
        /* Write to specify the command code to be loaded */
        FMC->FCCOBF0 = ((uint32_t)FLASH_CMD_POWER_ON_RESET << FMC_FCCOBF0_FCMD_SHIFT);
 
        /* Launch the command */
        FLASH_LaunchCMD();
    }
 
    /**
     * @brief Ìṩ²Á³ýÉÈÇø½ÌÑÐ
     * @param  TargetAddress:²Á³ýÉÈÇøµÄµØÖ·
     * @retval ·µ»ØFLASH²Ù×÷µÄ½á¹û
     */
    uint16_t FLASH_EraseVerifySector(uint32_t TargetAddress)
    {
        uint16_t errorstatus = FLASH_ERR_SUCCESS;
 
        if ((TargetAddress & 0x03u) == 0x03u)
        {
            errorstatus = FLASH_ERR_INVALID_PARAM;
        }
        else
        {
            // Clear error flags
            FMC->FSTAT = FMC_FSTAT_FPVIOL_MASK | FMC_FSTAT_ACCERR_MASK;
 
            /* Write to specify the command code to be loaded */
            FMC->FCCOBF0 = ((uint32_t)FLASH_CMD_ERASE_VERIFY_SECTOR << FMC_FCCOBF0_FCMD_SHIFT) | (TargetAddress);
        }
        return (errorstatus);
    }
 
    /**
     * @brief Flash ²Á³ýоƬ²Ù×÷»á²Á³ýÕû¸öflash¼ÇÒäÊý¾Ý.
     * @param None
     * @retval ·µ»ØFLASH״̬.
     */
    void FLASH_EraseVerifyChip(void)
    {
        //    uint16_t errorstatus;
 
        // Clear error flags
        FMC->FSTAT = FMC_FSTAT_FPVIOL_MASK | FMC_FSTAT_ACCERR_MASK;
 
        /* Write to specify the command code to be loaded */
        FMC->FCCOBF0 = ((uint32_t)FLASH_CMD_ERASE_VERIFY_CHIP << FMC_FCCOBF0_FCMD_SHIFT);
 
        /* Launch the command */
        FLASH_LaunchCMD();
    }
 
    /**
     * @brief Flash´ÓмÓÔØ
     * @param None
     * @retval ·µ»ØFLASH״̬.
     */
    void FLASH_ConfigReload(void)
    {
        //    uint16_t errorstatus ;
 
        // Clear error flags
        FMC->FSTAT = FMC_FSTAT_FPVIOL_MASK | FMC_FSTAT_ACCERR_MASK;
 
        /* Write to specify the command code to be loaded */
        FMC->FRLD = FMC_FRLD_FRLD_MASK;
 
        /* Launch the command */
        FLASH_LaunchCMD();
    }
 
    /**
     * @brief flash°²È«ÅäÖÃ.
     * @param None
     * @retval ·µ»ØFLASH°²È«ÅäÖÃ.
     */
    uint8_t FLASH_GetFlashSecurity(void)
    {
        uint8_t flashsecurity;
 
        /* Get the flash security configuration. */
        flashsecurity = (uint8_t)((FMC->FSTAT & FMC_FSTAT_SEC_MASK) >> FMC_FSTAT_SEC_SHIFT);
 
        return flashsecurity;
    }
 
    /**
     * @brief flash±£»¤ÅäÖÃ.
     * @param None
     * @retval ·µ»ØFLASH±£»¤ÅäÖÃ.
     */
    uint8_t FLASH_GetFlashProtection(void)
    {
        uint8_t flashprotection;
 
        /* Get the flash protection configuration. */
        flashprotection = (uint8_t)((FMC->FOSP & FLASH_PROTECT_MASK) >> 8u);
 
        return flashprotection;
    }
 
    /**
     * @brief flashÑ¡ÏîÅäÖÃ.
     * @param None
     * @retval ·µ»ØFLASHÑ¡ÏîÅäÖÃ.
     */
    uint8_t FLASH_GetFlashOption(void)
    {
        uint8_t flashoption;
 
        /* Get the flash option configuration. */
        flashoption = (uint8_t)((FMC->FOSP & FMC_FOSP_FOPT_MASK) >> FMC_FOSP_FOPT_SHIFT);
 
        return flashoption;
    }
 
    /**
     * @brief  ºóÃÅÃØÔ¿½âËø.
     * @param  KeyHigh:ºóÃÅÃØÔ¿¸ß32λ.
     * @param  Keylow:ºóÃÅÃØÔ¿µÍ32λ.
     * @retval None.
     */
    void FLASH_BackdoorUnlockFlash(uint32_t KeyHigh, uint32_t Keylow)
    {
        FMC->KEYLOW = Keylow;
        FMC->KEYHIGH = (KeyHigh | FMC_FOSP_BACKDOOR_EN_MASK);
    }
 
    /**
     * @}
     */
 
    /**
     * @}
     */
 
    /**
     * @}
     */
 
#ifdef __cplusplus
}
#endif /* __cplusplus */