#include "stm32g4xx_ll_flash.h"
//*****************************************************************************
//功能: 解锁
//说明:
//*****************************************************************************
uint8_t FLASH_Unlock(void)
{
if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0U)
{
WRITE_REG(FLASH->KEYR, FLASH_KEY1);
WRITE_REG(FLASH->KEYR, FLASH_KEY2);
if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0U)
return ERROR;
}
return SUCCESS;
}
//*****************************************************************************
//功能: 上锁
//说明:
//*****************************************************************************
void FLASH_Lock(void)
{
SET_BIT(FLASH->CR, FLASH_CR_LOCK);
}
//*****************************************************************************
//功能: 操作开始动作
//说明:
//操作: 擦除,写入
//*****************************************************************************
void Flash_ActionStart(void)
{
__disable_irq(); // 全局中断关闭
FLASH_Unlock(); // Flash解锁
FLASH_INSTRUCTION_CACHE_DISABLE;// 关闭指令缓存
FLASH_DATA_CACHE_DISABLE; // 关闭数据缓存
}
//*****************************************************************************
//功能: 操作结束动作
//操作: 擦除,写入
//*****************************************************************************
void Flash_ActionEnd(void)
{
FLASH_INSTRUCTION_CACHE_RESET;
FLASH_INSTRUCTION_CACHE_ENABLE;
FLASH_DATA_CACHE_RESET;
FLASH_DATA_CACHE_ENABLE;
FLASH_Lock();
__enable_irq();
}
//*****************************************************************************
//功能: 等待不忙
//说明:
//*****************************************************************************
ErrorStatus FLASH_WaitForLastOperation(void)
{
uint32_t delay = 600000U;
uint32_t error;
while(FLASH_GET_FLAG(FLASH_FLAG_BSY))
{
if(delay > 0)
delay--;
else
return ERROR;
}
// 检查错误
error = (FLASH->SR & FLASH_FLAG_SR_ERRORS);
if (error != 0u)
{
FLASH_CLEAR_FLAG(error);
return ERROR;
}
// 检查操作完成
if(FLASH_GET_FLAG(FLASH_FLAG_EOP))
{
FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
}
return SUCCESS;
}
//*****************************************************************************
//功能: 写入最小单元
//说明: 8字节
//*****************************************************************************
ErrorStatus FLASH_Program_DoubleWord(uint8_t Bank, uint32_t Address, uint64_t Data)
{
if(FLASH_WaitForLastOperation() == ERROR)
return ERROR;
// 选择BANK
if (READ_BIT(FLASH->OPTR, FLASH_OPTR_DBANK) == 0U)
{
CLEAR_BIT(FLASH->CR, FLASH_CR_BKER);
}
else
{
if(Bank == FLASH_BANK2)
SET_BIT(FLASH->CR, FLASH_CR_BKER);
else
CLEAR_BIT(FLASH->CR, FLASH_CR_BKER);
}
SET_BIT(FLASH->CR, FLASH_CR_PG);
// 写第一个字
*(uint32_t *)Address = (uint32_t)Data;
// 确保2步执行
__ISB();
// 写第二个字
*(uint32_t *)(Address + 4U) = (uint32_t)(Data >> 32U);
if(FLASH_WaitForLastOperation() == ERROR)
return ERROR;
CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
return SUCCESS;
}
//*****************************************************************************
//功能: 擦除 FLASH_CR_BKER
//说明: 1页2K字节
//*****************************************************************************
ErrorStatus FLASH_PageEarse(uint8_t Bank, uint32_t Page)
{
if(FLASH_WaitForLastOperation() == ERROR)
return ERROR;
// 选择BANK
if (READ_BIT(FLASH->OPTR, FLASH_OPTR_DBANK) == 0U)
{
CLEAR_BIT(FLASH->CR, FLASH_CR_BKER);
}
else
{
if(Bank == FLASH_BANK2)
SET_BIT(FLASH->CR, FLASH_CR_BKER);
else
CLEAR_BIT(FLASH->CR, FLASH_CR_BKER);
}
MODIFY_REG(FLASH->CR, FLASH_CR_PNB, ((Page & 0xFFU) << FLASH_CR_PNB_Pos));
SET_BIT(FLASH->CR, FLASH_CR_PER);
SET_BIT(FLASH->CR, FLASH_CR_STRT);
if(FLASH_WaitForLastOperation() == ERROR)
return ERROR;
CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
return SUCCESS;
}
//*****************************************************************************
//功能: 读取
//说明:
//*****************************************************************************
void Flash_ReadBuff(uint8_t Bank, uint32_t Addr, uint8_t *Buff, uint16_t Length)
{
uint16_t i = 0;
// 选择BANK
if(Bank == FLASH_BANK2)
SET_BIT(FLASH->CR, FLASH_CR_BKER);
else
CLEAR_BIT(FLASH->CR, FLASH_CR_BKER);
for(i = 0; i < Length; i++)
{
Buff[i] = *(uint8_t *)(Addr + i);
}
}
//*****************************************************************************
//功能: 存储写入
//说明: 最小64位写入
//*****************************************************************************
uint8_t Flash_WriteBuff(uint8_t Bank, uint32_t Addr, uint64_t *Buff, uint16_t Length)
{
uint16_t i = 0;
uint32_t addr = Addr;
Flash_ActionStart();
for(i = 0; i < Length; i++)
{
if(FLASH_Program_DoubleWord(Bank, addr, Buff[i]) == SUCCESS)
addr += 8;
else
return 0;
}
Flash_ActionEnd();
return 1;
}
//*****************************************************************************
//功能: 擦除
//说明:
//*****************************************************************************
uint8_t Flash_EraseUnits(uint8_t Bank, uint32_t UnitStart, uint8_t Units)
{
uint8_t i = 0;
Flash_ActionStart();
for(i = 0; i < Units; i++)
{
if(FLASH_PageEarse(Bank, UnitStart + i) == ERROR)
return 0;
}
Flash_ActionEnd();
return 1;
}