MoistureSoftware/.pack/Keil/STM32F1xx_DFP.2.3.0/Flash/STM32F10x/FlashPrg.c

437 lines
12 KiB
C

/* -----------------------------------------------------------------------------
* Copyright (c) 2014 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: 15. April 2014
* $Revision: V1.00
*
* Project: Flash Programming Functions for ST Microelectronics STM32F10x Flash
* --------------------------------------------------------------------------- */
/* History:
* Version 1.00
* Initial release
*/
#include "FlashOS.H" // FlashOS Structures
typedef volatile unsigned char vu8;
typedef volatile unsigned long vu32;
typedef volatile unsigned short vu16;
#define M8(adr) (*((vu8 *) (adr)))
#define M16(adr) (*((vu16 *) (adr)))
#define M32(adr) (*((vu32 *) (adr)))
// Peripheral Memory Map
#define IWDG_BASE 0x40003000
#define FLASH_BASE 0x40022000
#define IWDG ((IWDG_TypeDef *) IWDG_BASE)
#define FLASH ((FLASH_TypeDef*) FLASH_BASE)
// FLASH BANK size
#define BANK1_SIZE 0x00080000 // Bank1 Size = 512kB
// Independent WATCHDOG
typedef struct {
vu32 KR;
vu32 PR;
vu32 RLR;
vu32 SR;
} IWDG_TypeDef;
// Flash Registers
typedef struct {
vu32 ACR; // offset 0x000
vu32 KEYR; // offset 0x004
vu32 OPTKEYR; // offset 0x008
vu32 SR; // offset 0x00C
vu32 CR; // offset 0x010
vu32 AR; // offset 0x014
vu32 RESERVED0[1];
vu32 OBR; // offset 0x01C
vu32 WRPR; // offset 0x020
#ifdef STM32F10x_1024
vu32 RESERVED1[8];
vu32 KEYR2; // offset 0x044
vu32 RESERVED2[1];
vu32 SR2; // offset 0x04C
vu32 CR2; // offset 0x050
vu32 AR2; // offset 0x054
#endif
} FLASH_TypeDef;
// Flash Keys
#define RDPRT_KEY 0x5AA5
#define FLASH_KEY1 0x45670123
#define FLASH_KEY2 0xCDEF89AB
// Flash Control Register definitions
#define FLASH_PG 0x00000001
#define FLASH_PER 0x00000002
#define FLASH_MER 0x00000004
#define FLASH_OPTPG 0x00000010
#define FLASH_OPTER 0x00000020
#define FLASH_STRT 0x00000040
#define FLASH_LOCK 0x00000080
#define FLASH_OPTWRE 0x00000100
// Flash Status Register definitions
#define FLASH_BSY 0x00000001
#define FLASH_PGERR 0x00000004
#define FLASH_WRPRTERR 0x00000010
#define FLASH_EOP 0x00000020
unsigned long base_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
*/
#ifdef FLASH_MEM
int Init (unsigned long adr, unsigned long clk, unsigned long fnc) {
base_adr = adr & ~(BANK1_SIZE - 1); // Align to Size Boundary
// Zero Wait State
FLASH->ACR = 0x00000000;
// Unlock Flash
FLASH->KEYR = FLASH_KEY1;
FLASH->KEYR = FLASH_KEY2;
#ifdef STM32F10x_1024
FLASH->KEYR2 = FLASH_KEY1; // Flash bank 2
FLASH->KEYR2 = FLASH_KEY2;
#endif
// Test if IWDG is running (IWDG in HW mode)
if ((FLASH->OBR & 0x04) == 0x00) {
// 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 = 4095; // Set reload value to 4095
}
return (0);
}
#endif
#ifdef FLASH_OPT
int Init (unsigned long adr, unsigned long clk, unsigned long fnc) {
// Zero Wait State
FLASH->ACR = 0x00000000;
// Unlock Flash
FLASH->KEYR = FLASH_KEY1;
FLASH->KEYR = FLASH_KEY2;
// Unlock Option Bytes
FLASH->OPTKEYR = FLASH_KEY1;
FLASH->OPTKEYR = FLASH_KEY2;
// Test if IWDG is running (IWDG in HW mode)
if ((FLASH->OBR & 0x04) == 0x00) {
// 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 = 4095; // 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) {
// Lock Flash
FLASH->CR |= FLASH_LOCK;
#ifdef STM32F10x_1024
FLASH->CR2 |= FLASH_LOCK; // Flash bank 2
#endif
return (0);
}
#endif
#ifdef FLASH_OPT
int UnInit (unsigned long fnc) {
// Lock Flash & Option Bytes
FLASH->CR &= ~FLASH_OPTWRE;
FLASH->CR |= FLASH_LOCK;
return (0);
}
#endif
/*
* Erase complete Flash Memory
* Return Value: 0 - OK, 1 - Failed
*/
#ifdef FLASH_MEM
int EraseChip (void) {
FLASH->CR |= FLASH_MER; // Mass Erase Enabled
FLASH->CR |= FLASH_STRT; // Start Erase
while (FLASH->SR & FLASH_BSY) {
IWDG->KR = 0xAAAA; // Reload IWDG
}
FLASH->CR &= ~FLASH_MER; // Mass Erase Disabled
#ifdef STM32F10x_1024 // Flash bank 2
FLASH->CR2 |= FLASH_MER;
FLASH->CR2 |= FLASH_STRT;
while (FLASH->SR2 & FLASH_BSY) {
IWDG->KR = 0xAAAA;
}
FLASH->CR2 &= ~FLASH_MER;
#endif
return (0); // Done
}
#endif
#ifdef FLASH_OPT
int EraseChip (void) {
FLASH->CR |= FLASH_OPTER; // Option Byte Erase Enabled
FLASH->CR |= FLASH_STRT; // Start Erase
while (FLASH->SR & FLASH_BSY) {
IWDG->KR = 0xAAAA; // Reload IWDG
}
FLASH->CR &= ~FLASH_OPTER; // Option Byte Erase Disabled
// Unprotect Flash
FLASH->CR |= FLASH_OPTPG; // Option Byte Programming Enabled
M16(0x1FFFF800) = RDPRT_KEY; // Program Half Word: RDPRT Key
while (FLASH->SR & FLASH_BSY) {
IWDG->KR = 0xAAAA; // Reload IWDG
}
FLASH->CR &= ~FLASH_OPTPG; // Option Byte Programming Disabled
// Check for Errors
if (FLASH->SR & (FLASH_PGERR | FLASH_WRPRTERR)) {
FLASH->SR |= FLASH_PGERR | FLASH_WRPRTERR;
return (1); // Failed
}
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) {
#ifdef STM32F10x_1024
if (adr < (base_adr + BANK1_SIZE)) { // Flash bank 2
#endif
FLASH->CR |= FLASH_PER; // Page Erase Enabled
FLASH->AR = adr; // Page Address
FLASH->CR |= FLASH_STRT; // Start Erase
while (FLASH->SR & FLASH_BSY) {
IWDG->KR = 0xAAAA; // Reload IWDG
}
FLASH->CR &= ~FLASH_PER; // Page Erase Disabled
#ifdef STM32F10x_1024
}
else { // Flash bank 2
FLASH->CR2 |= FLASH_PER;
FLASH->AR2 = adr;
FLASH->CR2 |= FLASH_STRT;
while (FLASH->SR2 & FLASH_BSY) {
IWDG->KR = 0xAAAA;
}
FLASH->CR2 &= ~FLASH_PER;
}
#endif
return (0); // Done
}
#endif
#ifdef FLASH_OPT
int EraseSector (unsigned long adr) {
FLASH->CR |= FLASH_OPTER; // Option Byte Erase Enabled
FLASH->CR |= FLASH_STRT; // Start Erase
while (FLASH->SR & FLASH_BSY) {
IWDG->KR = 0xAAAA; // Reload IWDG
}
FLASH->CR &= ~FLASH_OPTER; // Option Byte Erase Disabled
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
*/
#ifdef FLASH_OPT
int BlankCheck (unsigned long adr, unsigned long sz, unsigned char pat) {
return (1); // Always Force Erase
}
#endif
/*
* 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 + 1) & ~1; // Adjust size for Half Words
#ifdef STM32F10x_1024
if (adr < (base_adr + BANK1_SIZE)) { // Flash bank 2
#endif
while (sz) {
FLASH->CR |= FLASH_PG; // Programming Enabled
M16(adr) = *((unsigned short *)buf); // Program Half Word
while (FLASH->SR & FLASH_BSY);
FLASH->CR &= ~FLASH_PG; // Programming Disabled
// Check for Errors
if (FLASH->SR & (FLASH_PGERR | FLASH_WRPRTERR)) {
FLASH->SR |= FLASH_PGERR | FLASH_WRPRTERR;
return (1); // Failed
}
// Go to next Half Word
adr += 2;
buf += 2;
sz -= 2;
}
#ifdef STM32F10x_1024
}
else { // Flash bank 2
while (sz) {
FLASH->CR2 |= FLASH_PG;
M16(adr) = *((unsigned short *)buf);
while (FLASH->SR2 & FLASH_BSY);
FLASH->CR2 &= ~FLASH_PG;
// Check for Errors
if (FLASH->SR2 & (FLASH_PGERR | FLASH_WRPRTERR)) {
FLASH->SR2 |= FLASH_PGERR | FLASH_WRPRTERR;
return (1);
}
// Go to next Half Word
adr += 2;
buf += 2;
sz -= 2;
}
}
#endif
return (0); // Done
}
#endif
#ifdef FLASH_OPT
int ProgramPage (unsigned long adr, unsigned long sz, unsigned char *buf) {
sz = (sz + 1) & ~1; // Adjust size for Half Words
while (sz) {
FLASH->CR |= FLASH_OPTPG; // Option Byte Programming Enabled
M16(adr) = *((unsigned short *)buf); // Program Half Word
while (FLASH->SR & FLASH_BSY) {
IWDG->KR = 0xAAAA; // Reload IWDG
}
FLASH->CR &= ~FLASH_OPTPG; // Option Byte Programming Disabled
// Check for Errors
if (FLASH->SR & (FLASH_PGERR | FLASH_WRPRTERR)) {
FLASH->SR |= FLASH_PGERR | FLASH_WRPRTERR;
return (1); // Failed
}
// Go to next Half Word
adr += 2;
buf += 2;
sz -= 2;
}
return (0); // Done
}
#endif