📄 flash.c
字号:
/******************** (C) COPYRIGHT 2003 STMicroelectronics ********************
* File Name : flash.c
* Author : MCD Application Team
* Date First Issued : 28/07/2003
* Description : This file provides all the Flash software functions
********************************************************************************
* History:
** 28/07/2003 : Created
* 13/07/2004 : Rename FLASH_EraseSector,FLASH_EraseBank,FLASH_EraseModule functions
* to FLASH_SectorErase,FLASH_BankErase,FLASH_ModuleErase
*******************************************************************************/
#include "flash.h"
/*******************************************************************************
* Function Name : FLASH_Init
* Description : Initialise the Flash
* Input : None
* Return : None
*******************************************************************************/
void FLASH_Init(void)
{
// Reset Flash Control Registers
FLASHR->CR0 = 0x00000000;
FLASHR->CR1 = 0x00000000;
// Reset Flash Data Registers
FLASHR->DR0 = 0xFFFFFFFF;
FLASHR->DR1 = 0xFFFFFFFF;
// Reset Flash Error Register
FLASHR->ER = 0x00000000;
}
/*******************************************************************************
* Function Name : FLASH_WordWrite
* Description : Writes a Word to the Flash
* Input 1 : Address of the Destination
* Input 2 : Word To program
* Return : None
*******************************************************************************/
void FLASH_WordWrite(u32 XtargetAdd, u32 Xdata)
{
WaitForLastTask(FLASH_BANK0);
WaitForLastTask(FLASH_BANK1);
// set the Word Programming bit 'WPG' in the CR0 Reg
FLASHR->CR0 |= FLASH_WPG_Mask;
// Load the destination address in AR
FLASHR->AR = XtargetAdd;
// Load DATA to be programmed in DR0
FLASHR->DR0 = Xdata;
// Set the Write Mode Start bit 'WMS' in the CR0 Reg to Start Write Operation
FLASHR->CR0 |= FLASH_WMS_Mask;
}
/*******************************************************************************
* Function Name : FLASH_DWordWrite
* Description : Writes Double Word to the Flash
* Input 1 : Address of the Destination
* Input 2 : Word 1 To program
* Input 3 : Word 2 To program
* Return : None
*******************************************************************************/
void FLASH_DWordWrite(u32 XtargetAdd, u32 Xdata0, u32 Xdata1)
{
WaitForLastTask(FLASH_BANK0);
WaitForLastTask(FLASH_BANK1);
// set the Double Word Programming bit 'DWPG' in the CR0 Reg
FLASHR->CR0 |= FLASH_DWPG_Mask;
// Load the destination address in AR
FLASHR->AR = XtargetAdd;
// Load DATA0 in DR0 Reg
FLASHR->DR0 = Xdata0;
// Load DATA1 in DR1 Reg
FLASHR->DR1 = Xdata1;
// Set the Write Mode Start bit 'WMS' in the CR0 Reg to Start Write Operation
FLASHR->CR0 |= FLASH_WMS_Mask;
}
/*******************************************************************************
* Function Name : FLASH_WriteBlock
* Description : Writes Data To the Flash
* Input 1 : Address of the Data source
* Input 2 : Address of the Destination
* Input 3 : Nbr of words to be stored
* Return : None
*******************************************************************************/
void FLASH_BlockWrite(u32 XsourceAdd, u32 XtargetAdd, u32 XdataLength)
{
u32 TmpAddrS, TmpAddrD;
u32 NbrW, NbrDW;
u32 TmpData0, TmpData1;
// Get The Source Address
TmpAddrS = XsourceAdd;
// Get The Destination Address
TmpAddrD = XtargetAdd;
// Get Number of Double Words
NbrDW = XdataLength >> 1;
// Get Number of single Words
NbrW = XdataLength & 0x00000001;
// Programming Double Words
while (NbrDW > 0)
{
// Get The First 32 bits
TmpData0 = *(u32 *)TmpAddrS;
// Increment The Source Address
TmpAddrS += 4;
// Get The Second 32 bits
TmpData1 = *(u32 *)TmpAddrS;
// Increment The Source Address
TmpAddrS += 4;
// Use The FLASH_DWordWrite function to program the 64 bits
FLASH_DWordWrite(TmpAddrD, TmpData0, TmpData1);
// Decrease number of Double word
NbrDW--;
// Increment The destination Address
TmpAddrD += 8;
// Waits for the data to be programmed
FLASH_Delay();
}
if (NbrW > 0)
{
// Get The First 32 bits
TmpData1 = *(u32 *)TmpAddrS;
// Use The FLASH_WordWrite function to program the 32 bits
FLASH_WordWrite(TmpAddrD, TmpData1);
// Waits for the data to be programmed
FLASH_Delay();
}
}
/*******************************************************************************
* Function Name : FLASH_EraseSector
* Description : Erases a Flash sector
* Input 1 : Sectors to be Erased
* Return : None
*******************************************************************************/
void FLASH_SectorErase(u32 Xsectors)
{
WaitForLastTask(FLASH_BANK0);
WaitForLastTask(FLASH_BANK1);
// Set the Sector Erase flag 'SER' in the FCRO reg
FLASHR->CR0 |= FLASH_SER_Mask;
// Select the Sectors to be erased in the CR1 register
FLASHR->CR1 |= Xsectors;
// Set the Write Mode Start bit 'WMS' in the CR0 Reg to Start Erase Operation
FLASHR->CR0 |= FLASH_WMS_Mask;
}
/*******************************************************************************
* Function Name : FLASH_EraseModule
* Description : Erases a flash module
* Input : None
* Return : None
*******************************************************************************/
void FLASH_ModuleErase(void)
{
WaitForLastTask(FLASH_BANK0);
FLASH_BankErase(FLASH_BANK0);
WaitForLastTask(FLASH_BANK1);
FLASH_BankErase(FLASH_BANK1);
// waits for the end of the write operation on both banks
WaitForLastTask(FLASH_BANK0);
WaitForLastTask(FLASH_BANK1);
}
/*******************************************************************************
* Function Name : FLASH_Delay
* Description : Add the delay required for the Flash Write & Erase operation
* Input 1 : None
* Return : None
*******************************************************************************/
void FLASH_Delay(void)
{
u8 Xdelay;
for(Xdelay = 0; Xdelay < 0xFE; Xdelay ++);
}
/*******************************************************************************
* Function Name : FLASH_Suspend
* Description : Suspends the current program or erase operation
* Input 1 : None
* Return : None
*******************************************************************************/
void FLASH_Suspend(void)
{
// Set The suspend Bit 'SUSP' in the CR0 register
FLASHR->CR0 |= FLASH_SUSP_Mask;
}
/*******************************************************************************
* Function Name : FLASH_Resume
* Description : Resume a Suspended program or erase operation
* Input 1 : None
* Return : None
*******************************************************************************/
void FLASH_Resume(void)
{
// Reset The suspend Bit 'SUSP' in the FRC0 register
FLASHR->CR0 &= ~FLASH_SUSP_Mask;
// Set write mode bit
FLASHR->CR0 |= FLASH_WMS_Mask;
}
/*******************************************************************************
* Function Name : FLASH_ReadWord
* Description : Read a single word of the flash
* Input 1 : Source Address
* Return : Word
*******************************************************************************/
u32 FLASH_WordRead(u32 SourceAdd)
{
WaitForLastTask(FLASH_BANK0);
WaitForLastTask(FLASH_BANK1);
// Waits for the flash to be unlocked
while((FLASH_FlagStatus(FLASH_LOCK))== SET);
// Reads the data from the specified Address
return *(u32 *)(SourceAdd + 0x40000000);
}
/*******************************************************************************
* Function Name : FLASH_ReadBlock -> Block Read
* Description : Block Read from the flash
* Input 1 : Destination Address where the Data will be Stored
* Input 2 : Data Source Address
* Input 3 : Nbr of word to be Read
* Return : Word
*******************************************************************************/
void FLASH_BlockRead(u32 DestAdd, u32 SourceAdd, u32 NbrData)
{
u32 TmpaddrD,TmpaddrS,TmpNbrData;
// Number of data to be Read from the Flash
TmpNbrData = NbrData;
// Source Address
TmpaddrS = SourceAdd;
// Destination Address
TmpaddrD = DestAdd;
WaitForLastTask(FLASH_BANK0);
WaitForLastTask(FLASH_BANK1);
while(TmpNbrData > 0)
{
*(u32 *)TmpaddrD = FLASH_WordRead(TmpaddrS);
// Increase the Source Address
TmpaddrS += 4;
// Increase the Destination Address
TmpaddrD += 4;
// Decrease the Number of data to be read
TmpNbrData --;
}
}
/*******************************************************************************
* Function Name : FLASH_WritePrConfig
* Description : Configures The Write Protection Bits
* Input 1 : Flash Bank
* Input 2 : Enable Or disable Protection
* Return : None
*******************************************************************************/
void FLASH_WritePrConfig(u32 Xsectors, FunctionalState NewState)
{
u32 TmpProtection;
TmpProtection = FLASHPR->NVWPAR;
WaitForLastTask(FLASH_BANK0);
WaitForLastTask(FLASH_BANK1);
if (NewState == DISABLE) TmpProtection |= Xsectors;
else TmpProtection &= ~Xsectors;
// Set the Set protection Bit
FLASHR->CR0 |= FLASH_SPR_Mask;
// Set the Register Address
FLASHR->AR = 0x4010DFB0;
// Data To be Programmed to the Protection Register
FLASHR->DR0 = TmpProtection;
// Set the WMS bit to Start the Sequence
FLASHR->CR0 |= FLASH_WMS_Mask;
}
/*******************************************************************************
* Function Name : FLASH_DebugPrConfig
* Description : Configures The Debug Protection Bits
* Input 1 : ENABLE or DISABLE
* Return : Word
*******************************************************************************/
void FLASH_DebugPrConfig(FunctionalState NewState)
{
u16 TmpPEN, TmpPDS, TmpProtection;
TmpPEN = (FLASHPR->NVAPR1 & 0xFFFF0000) >> 16;
TmpPDS = (FLASHPR->NVAPR1 & 0x0000FFFF);
if (NewState == ENABLE)
{
// If the First Protection Reset the DBGP bit
if ((FLASHPR->NVAPR0 & 0x2)==0x02) FLASHPR->NVAPR0 &= ~FLASH_DBGP_Mask;
else FLASHPR->NVAPR1 = ResetBit(FLASHPR->NVAPR1, ProtectionLevel(TmpPEN) + 16);
// FLASHPR->NVAPR1 = TmpPDS |((TmpPEN & ~(1<<ProtectionLevel(TmpPEN)))<< 16);
}
else
{
// Test wether the Protection is already Enabled
if ((FLASHPR->NVAPR0 & 0x2) == 0x0) FLASHPR->NVAPR1 = ResetBit(FLASHPR->NVAPR1, ProtectionLevel(TmpPDS));
// FLASHPR->NVAPR1 =(TmpPEN << 16)|(TmpPDS &~(1 << ProtectionLevel(TmpPDS)));
}
// Set the Set protection Bit
FLASHR->CR0 |= FLASH_SPR_Mask;
// Set the Register Address
FLASHR->AR = 0x4010DFB0;
// Data To be Programmed to the Protection Register
FLASHR->DR0 = TmpProtection;
// Set the WMS bit to Start the Sequence
FLASHR->CR0 |= FLASH_WMS_Mask;
}
/*******************************************************************************
* Function Name : FLASH_FlagStatus
* Description : Returns the NewState of Flash flags
* Input 1 : Flash Flag
* Return : flagstate
*******************************************************************************/
FlagStatus FLASH_FlagStatus(flashflags Xflag)
{
FlagStatus TmpResult;
u8 TmpReg, TmpPos;
// get the Register Index
TmpReg = (Xflag & FLASH_Reg_Mask) >> 5;
// get the Flag Index
TmpPos = (Xflag & FLASH_Flag_Mask);
switch(TmpReg)
{
case 0 : // CR0
{
// Returns the status of the CR0[TmpPos] flag
TmpResult = (FLASHR->CR0 & (1<<TmpPos))==0 ? RESET : SET;
break;
}
case 1 : // CR1
{
// Returns the status of the CR1[TmpPos] flag
TmpResult = (FLASHR->CR1 & (1<<TmpPos))==0 ? RESET : SET;
break;
}
case 5 : // ER
{
// Returns the status of the ER[TmpPos] flag
TmpResult = (FLASHR->ER & (1<<TmpPos))==0 ? RESET : SET;
break;
}
}
return(TmpResult);
}
/*******************************************************************************
* Function Name : FLASH_FlagClear
* Description : Clears a flash flag
* Input 1 : Flash Flag
* Return : None
*******************************************************************************/
void FLASH_FlagClear(flashflags Xflag)
{
u8 TmpReg, TmpPos;
TmpReg = (Xflag & FLASH_Reg_Mask) >> 5;
TmpPos = (Xflag & FLASH_Flag_Mask);
switch(TmpReg)
{
case 0 : // CR0
{
// Clears the status of the CR0[TmpPos] flag
FLASHR->CR0 &= ~(1<<TmpPos);
break;
}
case 1 : // CR1
{
// Clears the status of the CR1[TmpPos] flag
FLASHR->CR1 &= ~(1<<TmpPos);
break;
}
case 5 : // ER
{
// Clears the status of the ER[TmpPos] flag
FLASHR->ER &= ~(1<<TmpPos);
break;
}
}
}
/*******************************************************************************
* Function Name : ProtectionLevel
* Description : Returns the Index of the Last bit used to Enable / Disable the
* Permanent protection.
* Input 1 : None
* Return : None
*******************************************************************************/
u16 ProtectionLevel(u16 ProtectionRegs)
{
u16 TmpBitIndex = 0;
while ((ProtectionRegs & 0x1) == 0 && TmpBitIndex < 16)
{
ProtectionRegs>>=1;
TmpBitIndex++;
}
return TmpBitIndex;
}
/*******************************************************************************
* Function Name : Wait For Last Task
* Description : Waits for the end of last task on a Flash Bank
* Input 1 : Bank number.
* Return : The value passed in parameter with the bit (Bitindex) reset
*******************************************************************************/
void WaitForLastTask(flashbanks Xbank)
{
if (Xbank == FLASH_BANK0) while (FLASH_FlagStatus(FLASH_BSY0) == SET);
else while (FLASH_FlagStatus(FLASH_BSY1) == SET);
}
/*******************(C)COPYRIGHT 2003 STMicroelectronics *****END OF FILE****/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -