mirror of
				https://github.com/IcedRooibos/py32f0-template.git
				synced 2025-10-31 01:42:04 -07:00 
			
		
		
		
	
		
			
				
	
	
		
			543 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			543 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* -----------------------------------------------------------------------------
 | |
|  * Copyright (c) 2014 - 2019 ARM Ltd.
 | |
|  *
 | |
|  * This software is provided 'as-is', without any express or implied warranty.
 | |
|  * In no event will the authors be held liable for any damages arising from
 | |
|  * the use of this software. Permission is granted to anyone to use this
 | |
|  * software for any purpose, including commercial applications, and to alter
 | |
|  * it and redistribute it freely, subject to the following restrictions:
 | |
|  *
 | |
|  * 1. The origin of this software must not be misrepresented; you must not
 | |
|  *    claim that you wrote the original software. If you use this software in
 | |
|  *    a product, an acknowledgment in the product documentation would be
 | |
|  *    appreciated but is not required.
 | |
|  *
 | |
|  * 2. Altered source versions must be plainly marked as such, and must not be
 | |
|  *    misrepresented as being the original software.
 | |
|  *
 | |
|  * 3. This notice may not be removed or altered from any source distribution.
 | |
|  *
 | |
|  *
 | |
|  * $Date:        2021-7-1
 | |
|  * $Revision:    V1.0.0
 | |
|  *
 | |
|  * Project:      Flash Programming Functions for Puya PY32F0xx Flash
 | |
|  * --------------------------------------------------------------------------- */
 | |
| 
 | |
| /* History:
 | |
|  *  Version 1.0.0
 | |
|  *    Initial release
 | |
|  */
 | |
| 
 | |
| #include "FlashOS.h"        // FlashOS Structures
 | |
| 
 | |
| typedef volatile unsigned char    vu8;
 | |
| typedef          unsigned char     u8;
 | |
| typedef volatile unsigned short   vu16;
 | |
| typedef          unsigned short    u16;
 | |
| typedef volatile unsigned long    vu32;
 | |
| typedef          unsigned long     u32;
 | |
| 
 | |
| #define M8(adr)  (*((vu8  *) (adr)))
 | |
| #define M16(adr) (*((vu16 *) (adr)))
 | |
| #define M32(adr) (*((vu32 *) (adr)))
 | |
| 
 | |
| #define SET_BIT(REG, BIT)     ((REG) |= (BIT))
 | |
| #define CLEAR_BIT(REG, BIT)   ((REG) &= ~(BIT))
 | |
| #define READ_BIT(REG, BIT)    ((REG) & (BIT))
 | |
| #define CLEAR_REG(REG)        ((REG) = (0x0))
 | |
| #define WRITE_REG(REG, VAL)   ((REG) = (VAL))
 | |
| #define READ_REG(REG)         ((REG))
 | |
| #define MODIFY_REG(REG, CLEARMASK, SETMASK)  WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))
 | |
| 
 | |
| // Peripheral Memory Map
 | |
| #define RCC_BASE        0x40021000
 | |
| #define IWDG_BASE       0x40003000
 | |
| #define FLASH_BASE      0x40022000
 | |
| 
 | |
| #define RCC             ((RCC_TypeDef*) RCC_BASE)
 | |
| #define IWDG            ((IWDG_TypeDef *) IWDG_BASE)
 | |
| #define FLASH           ((FLASH_TypeDef*) FLASH_BASE)
 | |
| 
 | |
| typedef struct
 | |
| {
 | |
|   vu32 CR;          /*!< RCC Clock Sources Control Register,                                     Address offset: 0x00 */
 | |
|   vu32 ICSCR;       /*!< RCC Internal Clock Sources Calibration Register,                        Address offset: 0x04 */
 | |
| } RCC_TypeDef;
 | |
| 
 | |
| // Independent WATCHDOG
 | |
| typedef struct {
 | |
|   vu32 KR;          /*!< IWDG Key register,       Address offset: 0x00 */
 | |
|   vu32 PR;          /*!< IWDG Prescaler register, Address offset: 0x04 */
 | |
|   vu32 RLR;         /*!< IWDG Reload register,    Address offset: 0x08 */
 | |
|   vu32 SR;          /*!< IWDG Status register,    Address offset: 0x0C */
 | |
| } IWDG_TypeDef;
 | |
| 
 | |
| // Flash Registers
 | |
| typedef struct {
 | |
|   vu32 ACR;          /*!< FLASH Access Control register,                     Address offset: 0x00 */
 | |
|   vu32 RESERVED1;    /*!< Reserved1,                                         Address offset: 0x04 */
 | |
|   vu32 KEYR;         /*!< FLASH Key register,                                Address offset: 0x08 */
 | |
|   vu32 OPTKEYR;      /*!< FLASH Option Key register,                         Address offset: 0x0C */
 | |
|   vu32 SR;           /*!< FLASH Status register,                             Address offset: 0x10 */
 | |
|   vu32 CR;           /*!< FLASH Control register,                            Address offset: 0x14 */
 | |
|   vu32 RESERVED2[2]; /*!< Reserved2,                                         Address offset: 0x18-0x1C */
 | |
|   vu32 OPTR;         /*!< FLASH Option register,                             Address offset: 0x20 */
 | |
|   vu32 SDKR;         /*!< FLASH SDK address register,                        Address offset: 0x24 */
 | |
|   vu32 RESERVED3;    /*!< Reserved2,                                         Address offset: 0x28 */
 | |
|   vu32 WRPR;         /*!< FLASH WRP address register,                        Address offset: 0x2C */
 | |
|   vu32 RESERVED4[(0x90 - 0x2C) / 4 - 1];
 | |
|   vu32 STCR;         /*!< FLASH sleep time config register,                  Address offset: 0x90 */
 | |
|   vu32 RESERVED5[(0x100 - 0x90) / 4 - 1];
 | |
|   vu32 TS0;          /*!< FLASH TS0 register,                                Address offset: 0x100 */
 | |
|   vu32 TS1;          /*!< FLASH TS1 register,                                Address offset: 0x104 */
 | |
|   vu32 TS2P;         /*!< FLASH TS2P register,                               Address offset: 0x108 */
 | |
|   vu32 TPS3;         /*!< FLASH TPS3 register,                               Address offset: 0x10C */
 | |
|   vu32 TS3;          /*!< FLASH TS3 register,                                Address offset: 0x110 */
 | |
|   vu32 PERTPE;       /*!< FLASH PERTPE register,                             Address offset: 0x114 */
 | |
|   vu32 SMERTPE;      /*!< FLASH SMERTPE register,                            Address offset: 0x118 */
 | |
|   vu32 PRGTPE;       /*!< FLASH PRGTPE register,                             Address offset: 0x11C */
 | |
|   vu32 PRETPE;       /*!< FLASH PRETPE register,                             Address offset: 0x120 */
 | |
| } FLASH_TypeDef;
 | |
| 
 | |
| 
 | |
| // Flash Keys
 | |
| #define FLASH_KEY1              ((unsigned int)0x45670123)
 | |
| #define FLASH_KEY2              ((unsigned int)0xCDEF89AB)
 | |
| #define FLASH_OPTKEY1           ((unsigned int)0x08192A3B)
 | |
| #define FLASH_OPTKEY2           ((unsigned int)0x4C5D6E7F)
 | |
| 
 | |
| // Flash Control Register definitions
 | |
| #define FLASH_CR_PG_Pos                 (0U)
 | |
| #define FLASH_CR_PG_Msk                 (0x1UL << FLASH_CR_PG_Pos)       /*!< 0x00000001 */
 | |
| #define FLASH_CR_PG                     FLASH_CR_PG_Msk
 | |
| #define FLASH_CR_PER_Pos                (1U)
 | |
| #define FLASH_CR_PER_Msk                (0x1UL << FLASH_CR_PER_Pos)      /*!< 0x00000002 */
 | |
| #define FLASH_CR_PER                    FLASH_CR_PER_Msk
 | |
| #define FLASH_CR_MER_Pos                (2U)
 | |
| #define FLASH_CR_MER_Msk                (0x1UL << FLASH_CR_MER_Pos)     /*!< 0x00000004 */
 | |
| #define FLASH_CR_MER                    FLASH_CR_MER_Msk
 | |
| #define FLASH_CR_SER_Pos                (11U)
 | |
| #define FLASH_CR_SER_Msk                (0x1UL << FLASH_CR_SER_Pos)     /*!< 0x00000800 */
 | |
| #define FLASH_CR_SER                    FLASH_CR_SER_Msk
 | |
| #define FLASH_CR_OPTSTRT_Pos            (17U)
 | |
| #define FLASH_CR_OPTSTRT_Msk            (0x1UL << FLASH_CR_OPTSTRT_Pos)  /*!< 0x00020000 */
 | |
| #define FLASH_CR_OPTSTRT                FLASH_CR_OPTSTRT_Msk
 | |
| #define FLASH_CR_PGSTRT_Pos             (19U)
 | |
| #define FLASH_CR_PGSTRT_Msk             (0x1UL << FLASH_CR_PGSTRT_Pos)     /*!< 0x00080000 */
 | |
| #define FLASH_CR_PGSTRT                 FLASH_CR_PGSTRT_Msk
 | |
| #define FLASH_CR_EOPIE_Pos              (24U)
 | |
| #define FLASH_CR_EOPIE_Msk              (0x1UL << FLASH_CR_EOPIE_Pos)    /*!< 0x01000000 */
 | |
| #define FLASH_CR_EOPIE                  FLASH_CR_EOPIE_Msk
 | |
| #define FLASH_CR_ERRIE_Pos              (25U)
 | |
| #define FLASH_CR_ERRIE_Msk              (0x1UL << FLASH_CR_ERRIE_Pos)    /*!< 0x02000000 */
 | |
| #define FLASH_CR_ERRIE                  FLASH_CR_ERRIE_Msk
 | |
| #define FLASH_CR_OBL_LAUNCH_Pos         (27U)
 | |
| #define FLASH_CR_OBL_LAUNCH_Msk         (0x1UL << FLASH_CR_OBL_LAUNCH_Pos) /*!< 0x08000000 */
 | |
| #define FLASH_CR_OBL_LAUNCH             FLASH_CR_OBL_LAUNCH_Msk
 | |
| #define FLASH_CR_OPTLOCK_Pos            (30U)
 | |
| #define FLASH_CR_OPTLOCK_Msk            (0x1UL << FLASH_CR_OPTLOCK_Pos)  /*!< 0x40000000 */
 | |
| #define FLASH_CR_OPTLOCK                FLASH_CR_OPTLOCK_Msk
 | |
| #define FLASH_CR_LOCK_Pos               (31U)
 | |
| #define FLASH_CR_LOCK_Msk               (0x1UL << FLASH_CR_LOCK_Pos)     /*!< 0x80000000 */
 | |
| #define FLASH_CR_LOCK                   FLASH_CR_LOCK_Msk
 | |
| 
 | |
| // Flash Status Register definitions
 | |
| #define FLASH_SR_EOP_Pos                  (0U)
 | |
| #define FLASH_SR_EOP_Msk                  (0x1UL << FLASH_SR_EOP_Pos)      /*!< 0x00000001 */
 | |
| #define FLASH_SR_EOP                      FLASH_SR_EOP_Msk
 | |
| #define FLASH_SR_WRPERR_Pos               (4U)
 | |
| #define FLASH_SR_WRPERR_Msk               (0x1UL << FLASH_SR_WRPERR_Pos)   /*!< 0x00000010 */
 | |
| #define FLASH_SR_WRPERR                   FLASH_SR_WRPERR_Msk
 | |
| #define FLASH_SR_OPTVERR_Pos              (15U)
 | |
| #define FLASH_SR_OPTVERR_Msk              (0x1UL << FLASH_SR_OPTVERR_Pos)  /*!< 0x00008000 */
 | |
| #define FLASH_SR_OPTVERR                  FLASH_SR_OPTVERR_Msk
 | |
| #define FLASH_SR_BSY_Pos                  (16U)
 | |
| #define FLASH_SR_BSY_Msk                  (0x1UL << FLASH_SR_BSY_Pos)     /*!< 0x00010000 */
 | |
| #define FLASH_SR_BSY                      FLASH_SR_BSY_Msk
 | |
| 
 | |
| #define FLASH_OPTR_IWDG_SW_Pos          (12U)
 | |
| #define FLASH_OPTR_IWDG_SW_Msk          (0x1UL << FLASH_OPTR_IWDG_SW_Pos)   /*!< 0x00010000 */
 | |
| #define FLASH_OPTR_IWDG_SW              FLASH_OPTR_IWDG_SW_Msk
 | |
| #define FLASH_OPTR_WWDG_SW_Pos          (13U)
 | |
| #define FLASH_OPTR_WWDG_SW_Msk          (0x1UL << FLASH_OPTR_WWDG_SW_Pos) /*!< 0x00080000 */
 | |
| #define FLASH_OPTR_WWDG_SW              FLASH_OPTR_WWDG_SW_Msk
 | |
| 
 | |
| u32 RCC_ICSCR_HSI_FS_RESTORE;
 | |
| void InitRccAndFlashParam(void);
 | |
| void UnInitRccAndFlashParam(void);
 | |
| 
 | |
| /*
 | |
|  *  Initialize Flash Programming Functions
 | |
|  *    Parameter:      adr:  Device Base Address
 | |
|  *                    clk:  Clock Frequency (Hz)
 | |
|  *                    fnc:  Function Code (1 - Erase, 2 - Program, 3 - Verify)
 | |
|  *    Return Value:   0 - OK,  1 - Failed
 | |
|  */
 | |
| 
 | |
| #ifdef FLASH_MEM
 | |
| int Init(unsigned long adr, unsigned long clk, unsigned long fnc)
 | |
| {
 | |
|   FLASH->KEYR = FLASH_KEY1;                             // Unlock Flash
 | |
|   FLASH->KEYR = FLASH_KEY2;
 | |
|   
 | |
|   InitRccAndFlashParam();
 | |
| 
 | |
|   FLASH->ACR  = 0x00000000;                             // Zero Wait State, no Prefetch
 | |
|   FLASH->SR  |= FLASH_SR_EOP;                              // Reset FLASH_EOP
 | |
| 
 | |
|   if ((FLASH->OPTR & FLASH_OPTR_IWDG_SW) == 0x00)                   // Test if IWDG is running (IWDG in HW mode)
 | |
|   {
 | |
|     // Set IWDG time out to ~32.768 second
 | |
|     IWDG->KR  = 0x5555;                                 // Enable write access to IWDG_PR and IWDG_RLR
 | |
|     IWDG->PR  = 0x06;                                   // Set prescaler to 256
 | |
|     IWDG->RLR = 0xFFF;                                   // Set reload value to 4095
 | |
|   }
 | |
| 
 | |
|   return (0);
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #ifdef FLASH_OPT
 | |
| int Init(unsigned long adr, unsigned long clk, unsigned long fnc)
 | |
| {
 | |
|   FLASH->KEYR = FLASH_KEY1;                             // Unlock Flash
 | |
|   FLASH->KEYR = FLASH_KEY2;
 | |
|   
 | |
|   InitRccAndFlashParam();
 | |
| 
 | |
|   FLASH->OPTKEYR = FLASH_OPTKEY1;                       // Unlock Option Bytes
 | |
|   FLASH->OPTKEYR = FLASH_OPTKEY2;
 | |
| 
 | |
|   FLASH->ACR  = 0x00000000;                             // Zero Wait State, no Prefetch
 | |
|   FLASH->SR  |= FLASH_SR_EOP;                              // Reset FLASH_EOP
 | |
| 
 | |
| 
 | |
|   if ((FLASH->OPTR & 0x1000) == 0x00)                   // Test if IWDG is running (IWDG in HW mode)
 | |
|   {
 | |
|     // Set IWDG time out to ~32.768 second
 | |
|     IWDG->KR  = 0x5555;                                 // Enable write access to IWDG_PR and IWDG_RLR
 | |
|     IWDG->PR  = 0x06;                                   // Set prescaler to 256
 | |
|     IWDG->RLR = 0xFFF;                                  // Set reload value to 4095
 | |
|   }
 | |
| 
 | |
|   return (0);
 | |
| }
 | |
| #endif
 | |
| 
 | |
| 
 | |
| /*
 | |
|  *  De-Initialize Flash Programming Functions
 | |
|  *    Parameter:      fnc:  Function Code (1 - Erase, 2 - Program, 3 - Verify)
 | |
|  *    Return Value:   0 - OK,  1 - Failed
 | |
|  */
 | |
| 
 | |
| #ifdef FLASH_MEM
 | |
| int UnInit(unsigned long fnc)
 | |
| {
 | |
| 
 | |
|   UnInitRccAndFlashParam();
 | |
| 
 | |
|   FLASH->CR    |=  FLASH_CR_LOCK;                          // Lock Flash
 | |
| 
 | |
|   return (0);
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #ifdef FLASH_OPT
 | |
| int UnInit(unsigned long fnc)
 | |
| {
 | |
| 
 | |
|   UnInitRccAndFlashParam();
 | |
| 
 | |
|   FLASH->CR    |=  FLASH_CR_LOCK;                          // Lock Flash
 | |
|   FLASH->CR    |=  FLASH_CR_OPTLOCK;                       // Lock Option Bytes
 | |
| 
 | |
|   return (0);
 | |
| }
 | |
| #endif
 | |
| 
 | |
| /*
 | |
|  *  Erase complete Flash Memory
 | |
|  *    Return Value:   0 - OK,  1 - Failed
 | |
|  */
 | |
| 
 | |
| #ifdef FLASH_MEM
 | |
| int EraseChip(void)
 | |
| {
 | |
| 
 | |
|   FLASH->SR  |= FLASH_SR_EOP;                              // Reset FLASH_EOP
 | |
| 
 | |
|   FLASH->CR |=  FLASH_CR_MER;                              // Mass Erase Enabled
 | |
|   FLASH->CR |=  FLASH_CR_EOPIE;
 | |
|   M32(0x08000000) = 0xFF;
 | |
|   __asm("DSB");
 | |
| 
 | |
|   while (FLASH->SR & FLASH_SR_BSY)
 | |
|   {
 | |
|     IWDG->KR = 0xAAAA;                                  // Reload IWDG
 | |
|   }
 | |
| 
 | |
|   FLASH->CR &= ~FLASH_CR_MER;                              // Mass Erase Disabled
 | |
|   FLASH->CR &= ~FLASH_CR_EOPIE;                            // Reset FLASH_EOPIE
 | |
| 
 | |
|   if (FLASH_SR_EOP != (FLASH->SR & FLASH_SR_EOP))             // Check for FLASH_SR_EOP
 | |
|   {
 | |
|     FLASH->SR |= FLASH_SR_EOP;
 | |
|     return (1);                                         // Failed
 | |
|   }
 | |
| 
 | |
|   return (0);                                           // Done
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #ifdef FLASH_OPT
 | |
| int EraseChip(void)
 | |
| {
 | |
| 
 | |
|   /* erase chip is not needed for
 | |
|      - Flash Option bytes
 | |
|      - Flash One Time Programmable bytes
 | |
|   */
 | |
|   return (0);                                           // Done
 | |
| }
 | |
| #endif
 | |
| 
 | |
| /*
 | |
|  *  Erase Sector in Flash Memory
 | |
|  *    Parameter:      adr:  Sector Address
 | |
|  *    Return Value:   0 - OK,  1 - Failed
 | |
|  */
 | |
| 
 | |
| #ifdef FLASH_MEM
 | |
| int EraseSector(unsigned long adr)
 | |
| {
 | |
| 
 | |
|   FLASH->SR  |= FLASH_SR_EOP;                              // Reset FLASH_EOP
 | |
| 
 | |
|   FLASH->CR  |=  FLASH_CR_SER;                             // Sector Erase Enabled
 | |
|   FLASH->CR  |=  FLASH_CR_EOPIE;
 | |
|   M32(adr) = 0xFF;                                      // Sector Address
 | |
|   __asm("DSB");
 | |
| 
 | |
|   while (FLASH->SR  & FLASH_SR_BSY)
 | |
|   {
 | |
|     IWDG->KR = 0xAAAA;                                  // Reload IWDG
 | |
|   }
 | |
| 
 | |
|   FLASH->CR  &= ~FLASH_CR_SER;                             // Sector Erase Disabled
 | |
|   FLASH->CR  &= ~FLASH_CR_EOPIE;                           // Reset FLASH_EOPIE
 | |
| 
 | |
| //  if (FLASH_EOP != (FLASH->SR & FLASH_EOP)) {           // Check for FLASH_SR_EOP
 | |
| //    FLASH->SR |= FLASH_EOP;
 | |
| //    return (1);                                         // Failed
 | |
| //  }
 | |
| 
 | |
|   return (0);                                           // Done
 | |
| }
 | |
| #endif
 | |
| 
 | |
| 
 | |
| #ifdef FLASH_OPT
 | |
| int EraseSector(unsigned long adr)
 | |
| {
 | |
|   /* erase sector is not needed for
 | |
|      - Flash Option bytes
 | |
|      - Flash One Time Programmable bytes
 | |
|   */
 | |
|   return (0);                                           // Done
 | |
| }
 | |
| #endif
 | |
| 
 | |
| /*
 | |
|  *  Blank Check Checks if Memory is Blank
 | |
|  *    Parameter:      adr:  Block Start Address
 | |
|  *                    sz:   Block Size (in bytes)
 | |
|  *                    pat:  Block Pattern
 | |
|  *    Return Value:   0 - OK,  1 - Failed
 | |
|  */
 | |
| 
 | |
| int BlankCheck(unsigned long adr, unsigned long sz, unsigned char pat)
 | |
| {
 | |
|   return (1);                                            // Always Force Erase
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  *  Program Page in Flash Memory
 | |
|  *    Parameter:      adr:  Page Start Address
 | |
|  *                    sz:   Page Size
 | |
|  *                    buf:  Page Data
 | |
|  *    Return Value:   0 - OK,  1 - Failed
 | |
|  */
 | |
| 
 | |
| #ifdef FLASH_MEM
 | |
| int ProgramPage(unsigned long adr, unsigned long sz, unsigned char *buf)
 | |
| {
 | |
| 
 | |
|   sz = (sz + 127) & ~127;                               // Adjust size for 32 Words
 | |
| 
 | |
|   FLASH->SR  |= FLASH_SR_EOP;                              // Reset FLASH_EOP
 | |
| 
 | |
|   while (sz)
 | |
|   {
 | |
|     FLASH->CR  |=  FLASH_CR_PG;                            // Programming Enabled
 | |
|     FLASH->CR  |=  FLASH_CR_EOPIE;
 | |
| 
 | |
|     for (u8 i = 0; i < 32; i++)
 | |
|     {
 | |
| 
 | |
|       M32(adr + i * 4) = *((u32 *)(buf + i * 4));       // Program the first word of the Double Word
 | |
|       if (i == 30)
 | |
|       {
 | |
|         FLASH->CR  |= FLASH_CR_PGSTRT;
 | |
|       }
 | |
|     }
 | |
|     __asm("DSB");
 | |
| 
 | |
|     while (FLASH->SR & FLASH_SR_BSY)
 | |
|     {
 | |
|       IWDG->KR = 0xAAAA;                                // Reload IWDG
 | |
|     }
 | |
| 
 | |
|     FLASH->CR  &= ~FLASH_CR_PG;                            // Programming Disabled
 | |
|     FLASH->CR  &= ~FLASH_CR_EOPIE;                         // Reset FLASH_EOPIE
 | |
| 
 | |
| //    if (FLASH_EOP != (FLASH->SR & FLASH_EOP)) {         // Check for FLASH_SR_EOP
 | |
| //      FLASH->SR |= FLASH_EOP;
 | |
| //      return (1);                                       // Failed
 | |
| //    }
 | |
| 
 | |
|     adr += 128;                                         // Go to next Page
 | |
|     buf += 128;
 | |
|     sz  -= 128;
 | |
|   }
 | |
| 
 | |
|   return (0);                                           // Done
 | |
| }
 | |
| #endif //  FLASH_MEM
 | |
| 
 | |
| #ifdef FLASH_OPT
 | |
| int ProgramPage(unsigned long adr, unsigned long sz, unsigned char *buf)
 | |
| {
 | |
|   u32 optr;
 | |
|   u32 sdkr;
 | |
|   u32 wrpr;
 | |
| 
 | |
|   optr = *((u32 *)(buf + 0x00));
 | |
|   sdkr = *((u32 *)(buf + 0x04));
 | |
|   wrpr = *((u32 *)(buf + 0x0C));
 | |
| 
 | |
|   FLASH->SR |= FLASH_SR_EOP;                            // Reset FLASH_EOP
 | |
| 
 | |
|   FLASH->OPTR = (optr & 0x0000FFFF);                 // Write OPTR values
 | |
|   FLASH->SDKR = (sdkr & 0x0000FFFF);                 // Write SDKR values
 | |
|   FLASH->WRPR = (wrpr & 0x0000FFFF);                 // Write WRPR values
 | |
| 
 | |
|   FLASH->CR |= FLASH_CR_OPTSTRT;
 | |
|   FLASH->CR |= FLASH_CR_EOPIE;
 | |
|   M32(0x40022080) = 0xFF;
 | |
|   __asm("DSB");
 | |
| 
 | |
|   FLASH->CR  &= ~FLASH_CR_OPTSTRT;                      // Programming Disabled
 | |
|   FLASH->CR  &= ~FLASH_CR_EOPIE;                        // Reset FLASH_EOPIE
 | |
| 
 | |
|   //FLASH->CR |= FLASH_CR_OBL_LAUNCH;
 | |
| 
 | |
|   return (0);                                           // Done
 | |
| }
 | |
| #endif //  FLASH_OPT
 | |
| 
 | |
| 
 | |
| /*
 | |
|  *  Verify Flash Contents
 | |
|  *    Parameter:      adr:  Start Address
 | |
|  *                    sz:   Size (in bytes)
 | |
|  *                    buf:  Data
 | |
|  *    Return Value:   (adr+sz) - OK, Failed Address
 | |
|  */
 | |
| 
 | |
| #ifdef FLASH_OPT
 | |
| unsigned long Verify(unsigned long adr, unsigned long sz, unsigned char *buf)
 | |
| {
 | |
|   u32 optr;
 | |
|   u32 sdkr;
 | |
|   u32 wrpr;
 | |
| 
 | |
|   optr = *((u32 *)(buf +  0x00));
 | |
|   sdkr = *((u32 *)(buf +  0x04));
 | |
|   wrpr = *((u32 *)(buf +  0x0C));
 | |
| 
 | |
|   if (M32(adr + 0x00) != optr)
 | |
|   {
 | |
|     return (adr + 0x00);
 | |
|   }
 | |
|   if (M32(adr + 0x04) != sdkr)
 | |
|   {
 | |
|     return (adr + 0x04);
 | |
|   }
 | |
|   if (M32(adr + 0x0C) != wrpr)
 | |
|   {
 | |
|     return (adr + 0x0C);
 | |
|   }
 | |
| 
 | |
|   return (adr + sz);
 | |
| }
 | |
| #endif // FLASH_OPT
 | |
| 
 | |
| 
 | |
| #define RCC_CR_HSIRDY_Pos                (10U)
 | |
| #define RCC_CR_HSIRDY_Msk                (0x1UL << RCC_CR_HSIRDY_Pos)          /*!< 0x00000400 */
 | |
| #define RCC_CR_HSIRDY                    RCC_CR_HSIRDY_Msk                     /*!< Internal High Speed clock ready flag */
 | |
| #define RCC_ICSCR_HSI_TRIM_Pos            (0U)
 | |
| #define RCC_ICSCR_HSI_TRIM_Msk            (0x1FFFUL << RCC_ICSCR_HSI_TRIM_Pos)   /*!< 0x00001FFF */
 | |
| #define RCC_ICSCR_HSI_TRIM                RCC_ICSCR_HSI_TRIM_Msk                 /*!< HSITRIM[14:8] bits */
 | |
| #define RCC_ICSCR_HSI_FS_Pos              (13U)
 | |
| #define RCC_ICSCR_HSI_FS_Msk              (0x7UL << RCC_ICSCR_HSI_FS_Pos)       /*!< 0x0000E000 */
 | |
| #define RCC_ICSCR_HSI_FS                  RCC_ICSCR_HSI_FS_Msk                 /*!< HSIFS[15:13] bits */
 | |
| #define RCC_ICSCR_HSI_FS_0                (0x01UL << RCC_ICSCR_HSI_FS_Pos)     /*!< 0x00002000 */
 | |
| #define RCC_ICSCR_HSI_FS_1                (0x02UL << RCC_ICSCR_HSI_FS_Pos)     /*!< 0x00004000 */
 | |
| #define RCC_ICSCR_HSI_FS_2                (0x04UL << RCC_ICSCR_HSI_FS_Pos)     /*!< 0x00008000 */
 | |
| 
 | |
| void InitRccAndFlashParam(void)
 | |
| {
 | |
|   RCC_ICSCR_HSI_FS_RESTORE = READ_BIT(RCC->ICSCR, RCC_ICSCR_HSI_FS);
 | |
|   MODIFY_REG(RCC->ICSCR, RCC_ICSCR_HSI_FS, RCC_ICSCR_HSI_FS_2);//HSI_24MHz
 | |
|   MODIFY_REG(RCC->ICSCR, RCC_ICSCR_HSI_TRIM, M32(0x1FFF0F10)&RCC_ICSCR_HSI_TRIM);
 | |
|   while (RCC_CR_HSIRDY != READ_BIT(RCC->CR, RCC_CR_HSIRDY));
 | |
|   
 | |
|   FLASH->TS0 = ((M32(0x1FFF0F1C + 4 * 0x14) >> 0) & 0x000000FF);
 | |
|   FLASH->TS3 = ((M32(0x1FFF0F1C + 4 * 0x14) >> 8) & 0x000000FF);
 | |
|   FLASH->TS1 = ((M32(0x1FFF0F1C + 4 * 0x14) >> 16) & 0x000001FF);
 | |
|   FLASH->TS2P = ((M32(0x1FFF0F20 + 4 * 0x14) >> 0) & 0x000000FF);
 | |
|   FLASH->TPS3 = ((M32(0x1FFF0F20 + 4 * 0x14) >> 16) & 0x000007FF);
 | |
|   FLASH->PERTPE = ((M32(0x1FFF0F24 + 4 * 0x14) >> 0) & 0x0001FFFF);
 | |
|   FLASH->SMERTPE = ((M32(0x1FFF0F28 + 4 * 0x14) >> 0) & 0x0001FFFF);
 | |
|   FLASH->PRGTPE = ((M32(0x1FFF0F2C + 4 * 0x14) >> 0) & 0x0000FFFF);
 | |
|   FLASH->PRETPE = ((M32(0x1FFF0F2C + 4 * 0x14) >> 16) & 0x0000FFFF);
 | |
| }
 | |
| 
 | |
| void UnInitRccAndFlashParam(void)
 | |
| {
 | |
|   MODIFY_REG(RCC->ICSCR, RCC_ICSCR_HSI_FS, RCC_ICSCR_HSI_FS_RESTORE);
 | |
|   switch (RCC_ICSCR_HSI_FS_RESTORE)
 | |
|   {
 | |
|   case RCC_ICSCR_HSI_FS_2://24MHz
 | |
|     MODIFY_REG(RCC->ICSCR, RCC_ICSCR_HSI_TRIM, M32(0x1FFF0F10)&RCC_ICSCR_HSI_TRIM);
 | |
|     break;
 | |
|   case (RCC_ICSCR_HSI_FS_1|RCC_ICSCR_HSI_FS_0)://22.12MHz
 | |
|     MODIFY_REG(RCC->ICSCR, RCC_ICSCR_HSI_TRIM, M32(0x1FFF0F0C)&RCC_ICSCR_HSI_TRIM);
 | |
|     break;
 | |
|   case RCC_ICSCR_HSI_FS_1://16MHz
 | |
|     MODIFY_REG(RCC->ICSCR, RCC_ICSCR_HSI_TRIM, M32(0x1FFF0F08)&RCC_ICSCR_HSI_TRIM);
 | |
|     break;
 | |
|   case RCC_ICSCR_HSI_FS_0://8MHz
 | |
|     MODIFY_REG(RCC->ICSCR, RCC_ICSCR_HSI_TRIM, M32(0x1FFF0F04)&RCC_ICSCR_HSI_TRIM);
 | |
|     break;
 | |
|   default://4MHz
 | |
|     MODIFY_REG(RCC->ICSCR, RCC_ICSCR_HSI_TRIM, M32(0x1FFF0F00)&RCC_ICSCR_HSI_TRIM);
 | |
|     break;
 | |
|   }
 | |
|   while (RCC_CR_HSIRDY != READ_BIT(RCC->CR, RCC_CR_HSIRDY));
 | |
| }
 | 
