| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656 |
- /* -----------------------------------------------------------------------------
- * 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 FLASH_BASE (0x08000000UL) /*!< FLASH base address */
- #define FLASH_END (0x0800FFFFUL) /*!< FLASH end address */
- #define FLASH_SIZE (FLASH_END - FLASH_BASE + 1)
- #define FLASH_PAGE_SIZE 0x00000080U /*!< FLASH Page Size, 128 Bytes */
- #define FLASH_PAGE_NB (FLASH_SIZE / FLASH_PAGE_SIZE)
- #define FLASH_SECTOR_SIZE 0x00001000U /*!< FLASH Sector Size, 4096 Bytes */
- #define FLASH_SECTOR_NB (FLASH_SIZE / FLASH_SECTOR_SIZE)
- #define SRAM_BASE (0x20000000UL) /*!< SRAM base address */
- #define SRAM_END (0x20001FFFUL) /*!< SRAM end address */
- #define FLASH_USERDATA_BASE (0x1FFF0D00UL) /*!< Base address of : (up to 128 Bytes) embedded FLASH Userdata Area */
- #define FLASH_USERDATA_END (0x1FFF0D7FUL) /*!< End address of : (up to 128 Bytes) embedded FLASH Userdata Area */
- #define RCC_BASE 0x40021000
- #define WWDG_BASE 0x40002C00
- #define IWDG_BASE 0x40003000
- #define FLASH_R_BASE 0x40022000
- #define OB_BASE 0x1FFF0E80UL /*!< FLASH Option Bytes base address */
- #define FLASHSIZE_BASE 0x1FFF0FFCUL /*!< FLASH Size register base address */
- #define RCC ((RCC_TypeDef *)RCC_BASE)
- #define IWDG ((IWDG_TypeDef *)IWDG_BASE)
- #define WWDG ((WWDG_TypeDef *) WWDG_BASE)
- #define FLASH ((FLASH_TypeDef *)FLASH_R_BASE)
- #define OB ((OB_TypeDef *) OB_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;
- typedef struct
- {
- vu32 CR; /*!< WWDG Control register, Address offset: 0x00 */
- vu32 CFR; /*!< WWDG Configuration register, Address offset: 0x04 */
- vu32 SR; /*!< WWDG Status register, Address offset: 0x08 */
- } WWDG_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;
- /******************* Bits definition for FLASH_ACR register *****************/
- #define FLASH_ACR_LATENCY_Pos (0U)
- #define FLASH_ACR_LATENCY_Msk (0x3UL << FLASH_ACR_LATENCY_Pos) /*!< 0x00000003 */
- #define FLASH_ACR_LATENCY FLASH_ACR_LATENCY_Msk
- /* 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_UPG_Pos (3U)
- #define FLASH_CR_UPG_Msk (0x1UL << FLASH_CR_UPG_Pos) /*!< 0x00000008 */
- #define FLASH_CR_UPG FLASH_CR_UPG_Msk
- #define FLASH_CR_UPER_Pos (4U)
- #define FLASH_CR_UPER_Msk (0x1UL << FLASH_CR_UPER_Pos) /*!< 0x00000010 */
- #define FLASH_CR_UPER FLASH_CR_UPER_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_UPGSTRT_Pos (18U)
- #define FLASH_CR_UPGSTRT_Msk (0x1UL << FLASH_CR_UPGSTRT_Pos) /*!< 0x00040000 */
- #define FLASH_CR_UPGSTRT FLASH_CR_UPGSTRT_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
- #define WWDG_CR_T_Pos (0U)
- #define WWDG_CR_T_Msk (0x7FUL << WWDG_CR_T_Pos) /*!< 0x0000007F */
- #define WWDG_CR_T WWDG_CR_T_Msk /*!<T[6:0] bits (7-Bit counter (MSB to LSB)) */
- #define WWDG_CFR_W_Pos (0U)
- #define WWDG_CFR_W_Msk (0x7FUL << WWDG_CFR_W_Pos) /*!< 0x0000007F */
- #define WWDG_CFR_W WWDG_CFR_W_Msk /*!<W[6:0] bits (7-bit window value) */
- #define WWDG_CFR_WDGTB_Pos (7U)
- #define WWDG_CFR_WDGTB_Msk (0x3UL << WWDG_CFR_WDGTB_Pos) /*!< 0x00000180 */
- #define WWDG_CFR_WDGTB WWDG_CFR_WDGTB_Msk /*!<WDGTB[1:0] bits (Timer Base) */
- u32 gdw_HSI_FS;
- void InitRccAndFlashParam(void);
- void UnInitRccAndFlashParam(void);
- int ErasePage(unsigned long adr);
- /*
- * 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
- */
- int Init(unsigned long adr, unsigned long clk, unsigned long fnc)
- {
- FLASH->KEYR = FLASH_KEY1; /* Unlock Flash */
- FLASH->KEYR = FLASH_KEY2;
- InitRccAndFlashParam();
- #ifdef FLASH_OB
- FLASH->OPTKEYR = FLASH_OPTKEY1; /* Unlock Option Bytes */
- FLASH->OPTKEYR = FLASH_OPTKEY2;
- #endif
- FLASH->ACR &= ~FLASH_ACR_LATENCY; /* Zero Wait State, no Prefetch */
- FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
- while (FLASH->SR & FLASH_SR_BSY); /* Check FLASH_SR_BSY */
- 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 = 0xAAAA; /* Reload IWDG */
- 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 */
- }
- if (FLASH_OPTR_WWDG_SW != READ_BIT(FLASH->OPTR, FLASH_OPTR_WWDG_SW)) /* Test if WWDG is running (WWDG in HW mode) */
- {
- /* Set WWDG time out to maximum */
- SET_BIT(WWDG->CFR, WWDG_CFR_WDGTB); /* Set prescaler to maximum */
- SET_BIT(WWDG->CR, WWDG_CR_T); /* Reload WWDG */
- }
- return (0);
- }
- /*
- * De-Initialize Flash Programming Functions
- * Parameter: fnc: Function Code (1 - Erase, 2 - Program, 3 - Verify)
- * Return Value: 0 - OK, 1 - Failed
- */
- int UnInit(unsigned long fnc)
- {
- UnInitRccAndFlashParam();
- FLASH->CR |= FLASH_CR_LOCK; /* Lock Flash */
- #ifdef FLASH_OB
- FLASH->CR |= FLASH_CR_OPTLOCK; /* Lock Option Bytes */
- #endif
- return (0);
- }
- /*
- * Erase complete Flash Memory
- * Return Value: 0 - OK, 1 - Failed
- */
- int EraseChip(void)
- {
- #ifdef FLASH_OTP
- ErasePage(FLASH_USERDATA_BASE);
- #endif /* FLASH_OTP */
- #if FLASH_MEM || FLASH_PE
- FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
- FLASH->CR |= FLASH_CR_MER; /* Mass Erase Enabled */
- FLASH->CR |= FLASH_CR_EOPIE;
- M32(FLASH_BASE) = 0xFF;
- __asm("DSB");
- while (FLASH->SR & FLASH_SR_BSY)
- {
- SET_BIT(WWDG->CR, WWDG_CR_T); /* Reload WWDG */
- IWDG->KR = 0xAAAA; /* Reload IWDG */
- }
- if (FLASH_SR_EOP != (FLASH->SR & FLASH_SR_EOP)) /* Check for FLASH_SR_EOP */
- {
- FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
- return (1); /* Failed */
- }
- FLASH->CR &= ~FLASH_CR_MER; /* Mass Erase Disabled */
- FLASH->CR &= ~FLASH_CR_EOPIE; /* Reset FLASH_EOPIE */
- #endif
- return (0); /* Done */
- }
- /*
- * Erase Sector in Flash Memory
- * Parameter: adr: Sector Address
- * Return Value: 0 - OK, 1 - Failed
- */
- int EraseSector(unsigned long adr)
- {
- #ifdef FLASH_OTP
- ErasePage(FLASH_USERDATA_BASE);
- #endif
- #ifdef FLASH_MEM
- 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)
- {
- SET_BIT(WWDG->CR, WWDG_CR_T); /* Reload WWDG */
- IWDG->KR = 0xAAAA; /* Reload IWDG */
- }
- if (FLASH_SR_EOP != (FLASH->SR & FLASH_SR_EOP)) /* Check for FLASH_SR_EOP */
- {
- FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
- return (1); /* Failed */
- }
- FLASH->CR &= ~FLASH_CR_SER; /* Sector Erase Disabled */
- FLASH->CR &= ~FLASH_CR_EOPIE; /* Reset FLASH_EOPIE */
- #endif
- #ifdef FLASH_PE
- FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
- FLASH->CR |= FLASH_CR_PER; /* page Erase Enabled */
- FLASH->CR |= FLASH_CR_EOPIE;
- M32(adr) = 0xFF; /* Sector Address */
- __asm("DSB");
- while (FLASH->SR & FLASH_SR_BSY)
- {
- SET_BIT(WWDG->CR, WWDG_CR_T); /* Reload WWDG */
- IWDG->KR = 0xAAAA; /* Reload IWDG */
- }
- if (FLASH_SR_EOP != (FLASH->SR & FLASH_SR_EOP)) /* Check for FLASH_SR_EOP */
- {
- FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
- return (1); /* Failed */
- }
- FLASH->CR &= ~FLASH_CR_PER; /* page Erase Disabled */
- FLASH->CR &= ~FLASH_CR_EOPIE; /* Reset FLASH_EOPIE */
- #endif
- return (0); /* Done */
- }
- #ifdef FLASH_OTP
- int ErasePage(unsigned long adr)
- {
- FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
- FLASH->CR |= FLASH_CR_UPER; /* Mass Erase Enabled */
- FLASH->CR |= FLASH_CR_EOPIE;
- M32(FLASH_USERDATA_BASE) = 0xFF;
- __asm("DSB");
- while (FLASH->SR & FLASH_SR_BSY)
- {
- SET_BIT(WWDG->CR, WWDG_CR_T); /* Reload WWDG */
- IWDG->KR = 0xAAAA; /* Reload IWDG */
- }
- if (FLASH_SR_EOP != (FLASH->SR & FLASH_SR_EOP)) /* Check for FLASH_SR_EOP */
- {
- FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
- return (1); /* Failed */
- }
- FLASH->CR &= ~FLASH_CR_UPER; /* Mass Erase Disabled */
- FLASH->CR &= ~FLASH_CR_EOPIE; /* Reset FLASH_EOPIE */
- 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
- */
- #if FLASH_MEM || FLASH_PE
- int ProgramPage(unsigned long adr, unsigned long sz, unsigned char *buf)
- {
- sz = (sz + (FLASH_PAGE_SIZE - 1)) & ~(FLASH_PAGE_SIZE - 1); /* 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 < (FLASH_PAGE_SIZE / 4); i++)
- {
- M32(adr + i * 4) = *((u32 *)(buf + i * 4)); /* Program the first word of the Double Word */
- if (i == (FLASH_PAGE_SIZE / 4) - 2)
- {
- FLASH->CR |= FLASH_CR_PGSTRT;
- }
- }
- __asm("DSB");
- while (FLASH->SR & FLASH_SR_BSY)
- {
- SET_BIT(WWDG->CR, WWDG_CR_T); /* Reload WWDG */
- IWDG->KR = 0xAAAA; /* Reload IWDG */
- }
- if (FLASH_SR_EOP != (FLASH->SR & FLASH_SR_EOP)) /* Check for FLASH_SR_EOP */
- {
- FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
- return (1); /* Failed */
- }
- FLASH->CR &= ~FLASH_CR_PG; /* Programming Disabled */
- FLASH->CR &= ~FLASH_CR_EOPIE; /* Reset FLASH_EOPIE */
- adr += FLASH_PAGE_SIZE; /* Go to next Page */
- buf += FLASH_PAGE_SIZE;
- sz -= FLASH_PAGE_SIZE;
- }
- return (0); /* Done */
- }
- #endif /* FLASH_MEM */
- #ifdef FLASH_OB
- int ProgramPage(unsigned long adr, unsigned long sz, unsigned char *buf)
- {
- u32 optr;
- u32 sdkr;
- u32 wrpr;
- u32 bor;
- optr = *((u32 *)(buf + 0x00)) & 0xFFFF;
- bor = *((u32 *)(buf + 0x04)) & 0xF;
- optr = optr | (bor << 16);
- sdkr = *((u32 *)(buf + 0x08)) & 0xFFFF;
- wrpr = *((u32 *)(buf + 0x0C)) & 0xFFFF;
- FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
- FLASH->OPTR = (optr & 0xFFFFF); /* Write OPTR values */
- FLASH->SDKR = (sdkr & 0xFFFF); /* Write SDKR values */
- FLASH->WRPR = (wrpr & 0xFFFF); /* Write WRPR values */
- FLASH->CR |= FLASH_CR_OPTSTRT;
- FLASH->CR |= FLASH_CR_EOPIE;
- M32(0x1FFF0E80) = 0xFF; /*Address Write Date*/
- __asm("DSB");
- while (FLASH->SR & FLASH_SR_BSY)
- {
- SET_BIT(WWDG->CR, WWDG_CR_T); /* Reload WWDG */
- WRITE_REG(IWDG->KR, 0x0000AAAAU); /* Reload IWDG */
- }
- if (FLASH_SR_EOP != (FLASH->SR & FLASH_SR_EOP)) /* Check for FLASH_SR_EOP */
- {
- FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
- return (1); /* Failed */
- }
- FLASH->CR &= ~FLASH_CR_OPTSTRT; /* Programming Disabled */
- FLASH->CR &= ~FLASH_CR_EOPIE; /* Reset FLASH_EOPIE */
- return (0); /* Done */
- }
- #endif /* FLASH_OB */
- #ifdef FLASH_OTP
- int ProgramPage(unsigned long adr, unsigned long sz, unsigned char *buf)
- {
- sz = (sz + (FLASH_PAGE_SIZE - 1)) & ~(FLASH_PAGE_SIZE - 1); /* Adjust size for 32 Words */
- FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
- FLASH->CR |= FLASH_CR_UPG; /* Programming Enabled */
- FLASH->CR |= FLASH_CR_EOPIE;
- for (u8 i = 0; i < (FLASH_PAGE_SIZE / 4); i++)
- {
- M32(FLASH_USERDATA_BASE + i * 4) = *((u32 *)(buf + i * 4));
- if (i == (FLASH_PAGE_SIZE / 4 - 2))
- {
- FLASH->CR |= FLASH_CR_UPGSTRT;
- }
- }
- __asm("DSB");
- while (FLASH->SR & FLASH_SR_BSY)
- {
- SET_BIT(WWDG->CR, WWDG_CR_T); /* Reload WWDG */
- IWDG->KR = 0xAAAA; /* Reload IWDG */
- }
- if (FLASH_SR_EOP != (FLASH->SR & FLASH_SR_EOP)) /* Check for FLASH_SR_EOP */
- {
- FLASH->SR |= FLASH_SR_EOP; /* Reset FLASH_EOP */
- return (1); /* Failed */
- }
- FLASH->CR &= ~FLASH_CR_UPG; /* Programming Disabled */
- FLASH->CR &= ~FLASH_CR_EOPIE; /* Reset FLASH_EOPIE */
- return (0); /* Done */
- }
- #endif /* FLASH_OTP */
- /*
- * Verify Flash Contents
- * Parameter: adr: Start Address
- * sz: Size (in bytes)
- * buf: Data
- * Return Value: (adr+sz) - OK, Failed Address
- */
- #ifdef FLASH_OB
- unsigned long Verify(unsigned long adr, unsigned long sz, unsigned char *buf)
- {
- u32 optr;
- u32 sdkr;
- u32 wrpr;
- u32 bor;
- optr = *((u32 *)(buf + 0x00));
- bor = *((u32 *)(buf + 0x04));
- sdkr = *((u32 *)(buf + 0x08));
- wrpr = *((u32 *)(buf + 0x0C));
- if (M32(adr + 0x00) != optr)
- {
- return (adr + 0x00);
- }
- if (M32(adr + 0x04) != bor)
- {
- return (adr + 0x04);
- }
- if (M32(adr + 0x08) != sdkr)
- {
- return (adr + 0x08);
- }
- if (M32(adr + 0x0C) != wrpr)
- {
- return (adr + 0x0C);
- }
- return (adr + sz);
- }
- #endif /* FLASH_OB */
- #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)
- {
- gdw_HSI_FS = READ_BIT(RCC->ICSCR, RCC_ICSCR_HSI_FS);
- MODIFY_REG(RCC->ICSCR, (RCC_ICSCR_HSI_FS | RCC_ICSCR_HSI_TRIM), M32(0x1FFF0F10)); // HSI_24MHz
- 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)
- {
- switch (gdw_HSI_FS)
- {
- case RCC_ICSCR_HSI_FS_2: // 24MHz
- MODIFY_REG(RCC->ICSCR, (RCC_ICSCR_HSI_FS | RCC_ICSCR_HSI_TRIM), M32(0x1FFF0F10));
- break;
- case (RCC_ICSCR_HSI_FS_1 | RCC_ICSCR_HSI_FS_0): // 22.12MHz
- MODIFY_REG(RCC->ICSCR, (RCC_ICSCR_HSI_FS | RCC_ICSCR_HSI_TRIM), M32(0x1FFF0F0C));
- break;
- case RCC_ICSCR_HSI_FS_1: // 16MHz
- MODIFY_REG(RCC->ICSCR, (RCC_ICSCR_HSI_FS | RCC_ICSCR_HSI_TRIM), M32(0x1FFF0F08));
- break;
- case RCC_ICSCR_HSI_FS_0: // 8MHz
- MODIFY_REG(RCC->ICSCR, (RCC_ICSCR_HSI_FS | RCC_ICSCR_HSI_TRIM), M32(0x1FFF0F04));
- break;
- default: // 4MHz
- MODIFY_REG(RCC->ICSCR, (RCC_ICSCR_HSI_FS | RCC_ICSCR_HSI_TRIM), M32(0x1FFF0F00));
- break;
- }
- while (RCC_CR_HSIRDY != READ_BIT(RCC->CR, RCC_CR_HSIRDY))
- ;
- }
|