286 lines
6.3 KiB
C
286 lines
6.3 KiB
C
|
//
|
|||
|
// Created by hu123456 on 2024/5/22.
|
|||
|
//
|
|||
|
|
|||
|
#include "stm32h7_flash.h"
|
|||
|
|
|||
|
uint32_t GetSector(uint32_t Address)
|
|||
|
{
|
|||
|
uint32_t sector = 0;
|
|||
|
|
|||
|
if (((Address < ADDR_FLASH_SECTOR_1_BANK1) && (Address >= ADDR_FLASH_SECTOR_0_BANK1)) || \
|
|||
|
((Address < ADDR_FLASH_SECTOR_1_BANK2) && (Address >= ADDR_FLASH_SECTOR_0_BANK2)))
|
|||
|
{
|
|||
|
sector = FLASH_SECTOR_0;
|
|||
|
}
|
|||
|
else if (((Address < ADDR_FLASH_SECTOR_2_BANK1) && (Address >= ADDR_FLASH_SECTOR_1_BANK1)) || \
|
|||
|
((Address < ADDR_FLASH_SECTOR_2_BANK2) && (Address >= ADDR_FLASH_SECTOR_1_BANK2)))
|
|||
|
{
|
|||
|
sector = FLASH_SECTOR_1;
|
|||
|
}
|
|||
|
else if (((Address < ADDR_FLASH_SECTOR_3_BANK1) && (Address >= ADDR_FLASH_SECTOR_2_BANK1)) || \
|
|||
|
((Address < ADDR_FLASH_SECTOR_3_BANK2) && (Address >= ADDR_FLASH_SECTOR_2_BANK2)))
|
|||
|
{
|
|||
|
sector = FLASH_SECTOR_2;
|
|||
|
}
|
|||
|
else if (((Address < ADDR_FLASH_SECTOR_4_BANK1) && (Address >= ADDR_FLASH_SECTOR_3_BANK1)) || \
|
|||
|
((Address < ADDR_FLASH_SECTOR_4_BANK2) && (Address >= ADDR_FLASH_SECTOR_3_BANK2)))
|
|||
|
{
|
|||
|
sector = FLASH_SECTOR_3;
|
|||
|
}
|
|||
|
else if (((Address < ADDR_FLASH_SECTOR_5_BANK1) && (Address >= ADDR_FLASH_SECTOR_4_BANK1)) || \
|
|||
|
((Address < ADDR_FLASH_SECTOR_5_BANK2) && (Address >= ADDR_FLASH_SECTOR_4_BANK2)))
|
|||
|
{
|
|||
|
sector = FLASH_SECTOR_4;
|
|||
|
}
|
|||
|
else if (((Address < ADDR_FLASH_SECTOR_6_BANK1) && (Address >= ADDR_FLASH_SECTOR_5_BANK1)) || \
|
|||
|
((Address < ADDR_FLASH_SECTOR_6_BANK2) && (Address >= ADDR_FLASH_SECTOR_5_BANK2)))
|
|||
|
{
|
|||
|
sector = FLASH_SECTOR_5;
|
|||
|
}
|
|||
|
else if (((Address < ADDR_FLASH_SECTOR_7_BANK1) && (Address >= ADDR_FLASH_SECTOR_6_BANK1)) || \
|
|||
|
((Address < ADDR_FLASH_SECTOR_7_BANK2) && (Address >= ADDR_FLASH_SECTOR_6_BANK2)))
|
|||
|
{
|
|||
|
sector = FLASH_SECTOR_6;
|
|||
|
}
|
|||
|
else if (((Address < ADDR_FLASH_SECTOR_0_BANK2) && (Address >= ADDR_FLASH_SECTOR_7_BANK1)) || \
|
|||
|
((Address < CPU_FLASH_END_ADDR) && (Address >= ADDR_FLASH_SECTOR_7_BANK2)))
|
|||
|
{
|
|||
|
sector = FLASH_SECTOR_7;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
sector = FLASH_SECTOR_7;
|
|||
|
}
|
|||
|
|
|||
|
return sector;
|
|||
|
}
|
|||
|
/*
|
|||
|
***************************************************************************************************
|
|||
|
*?? ??????flash????
|
|||
|
*?? ?<EFBFBD><EFBFBD>?_ulFlashAddr????????flash???
|
|||
|
* _ucpDst ????????
|
|||
|
* _ulSize ???????<EFBFBD><EFBFBD>,??<EFBFBD><EFBFBD>????
|
|||
|
* ?? ?? ???0??? 1?????????? 2<EFBFBD><EFBFBD>?????
|
|||
|
***************************************************************************************************
|
|||
|
*/
|
|||
|
uint8_t stm32h7_read_flash(uint32_t _ulFlashAddr, uint8_t *_ucpDst, uint32_t _ulSize)
|
|||
|
{
|
|||
|
uint32_t i;
|
|||
|
|
|||
|
if (_ulFlashAddr + _ulSize > CPU_FLASH_BASE_ADDR + CPU_FLASH_SIZE)
|
|||
|
{
|
|||
|
return 1;
|
|||
|
}
|
|||
|
|
|||
|
if (_ulSize == 0)
|
|||
|
{
|
|||
|
return 1;
|
|||
|
}
|
|||
|
|
|||
|
for (i = 0; i < _ulSize; i++)
|
|||
|
{
|
|||
|
*_ucpDst++ = *(uint8_t *)_ulFlashAddr++;
|
|||
|
}
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
/*
|
|||
|
//???flash???????
|
|||
|
?????: 0 <EFBFBD><EFBFBD>???????flash??????? ???<EFBFBD><EFBFBD>???
|
|||
|
1 ????????????<EFBFBD><EFBFBD>
|
|||
|
2 ??????????<EFBFBD><EFBFBD>
|
|||
|
3 ????????
|
|||
|
*/
|
|||
|
uint8_t cmp_flash(uint32_t _ulFlashAddr, uint8_t *_ucpBuf, uint32_t _ulSize)
|
|||
|
{
|
|||
|
uint32_t i;
|
|||
|
uint8_t ucIsEqu;
|
|||
|
uint8_t ucByte;
|
|||
|
|
|||
|
if (_ulFlashAddr + _ulSize > CPU_FLASH_BASE_ADDR + CPU_FLASH_SIZE)
|
|||
|
{
|
|||
|
return FLASH_PARAM_ERR;
|
|||
|
}
|
|||
|
|
|||
|
if (_ulSize == 0)
|
|||
|
{
|
|||
|
return FLASH_IS_EQU;
|
|||
|
}
|
|||
|
|
|||
|
ucIsEqu = 1;
|
|||
|
for (i = 0; i < _ulSize; i++)
|
|||
|
{
|
|||
|
ucByte = *(uint8_t *)_ulFlashAddr;
|
|||
|
|
|||
|
if (ucByte != *_ucpBuf)
|
|||
|
{
|
|||
|
if (ucByte != 0xFF)
|
|||
|
{
|
|||
|
return FLASH_REQ_ERASE;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
ucIsEqu = 0;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
_ulFlashAddr++;
|
|||
|
_ucpBuf++;
|
|||
|
}
|
|||
|
|
|||
|
if (ucIsEqu == 1)
|
|||
|
{
|
|||
|
return FLASH_IS_EQU;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return FLASH_REQ_WRITE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
uint8_t erase_flash(uint32_t _ulFlashAddr)
|
|||
|
{
|
|||
|
uint32_t FirstSector = 0, NbOfSectors = 0;
|
|||
|
FLASH_EraseInitTypeDef EraseInitStruct;
|
|||
|
uint32_t SECTORError = 0;
|
|||
|
uint8_t re;
|
|||
|
|
|||
|
HAL_FLASH_Unlock();
|
|||
|
|
|||
|
FirstSector = GetSector(_ulFlashAddr);
|
|||
|
|
|||
|
NbOfSectors = 1;
|
|||
|
|
|||
|
EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
|
|||
|
EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
|
|||
|
|
|||
|
if (_ulFlashAddr >= ADDR_FLASH_SECTOR_0_BANK2)
|
|||
|
{
|
|||
|
EraseInitStruct.Banks = FLASH_BANK_2;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
EraseInitStruct.Banks = FLASH_BANK_1;
|
|||
|
}
|
|||
|
|
|||
|
EraseInitStruct.Sector = FirstSector;
|
|||
|
EraseInitStruct.NbSectors = NbOfSectors;
|
|||
|
|
|||
|
re = HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError);
|
|||
|
|
|||
|
HAL_FLASH_Lock();
|
|||
|
|
|||
|
return re;
|
|||
|
}
|
|||
|
/*
|
|||
|
***************************************************************************************************
|
|||
|
*?? ?????????<EFBFBD><EFBFBD>??flash??????32?????????<EFBFBD><EFBFBD>?????????????
|
|||
|
*?? ?<EFBFBD><EFBFBD>?_ulFlashAddr??flash ???
|
|||
|
* _ucpSrc ??<EFBFBD><EFBFBD>????????
|
|||
|
* _ulSize ???????<EFBFBD><EFBFBD>,??<EFBFBD><EFBFBD>??????????32???????????
|
|||
|
* ?? ?? ???0??? 1?????????? 2<EFBFBD><EFBFBD>?????
|
|||
|
***************************************************************************************************
|
|||
|
*/
|
|||
|
uint8_t stm32h7_write_flash(uint32_t _ulFlashAddr, uint8_t *_ucpSrc, uint32_t _ulSize)
|
|||
|
{
|
|||
|
uint32_t i;
|
|||
|
uint8_t ucRet;
|
|||
|
|
|||
|
if (_ulFlashAddr + _ulSize > CPU_FLASH_BASE_ADDR + CPU_FLASH_SIZE)
|
|||
|
{
|
|||
|
return 1;
|
|||
|
}
|
|||
|
|
|||
|
if (_ulSize == 0)
|
|||
|
{
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
ucRet = cmp_flash(_ulFlashAddr, _ucpSrc, _ulSize);
|
|||
|
|
|||
|
if (ucRet == FLASH_IS_EQU)
|
|||
|
{
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
__set_PRIMASK(1);//???<3F><>?
|
|||
|
erase_flash(_ulFlashAddr);
|
|||
|
|
|||
|
HAL_FLASH_Unlock();
|
|||
|
|
|||
|
for (i = 0; i < _ulSize / 32; i++)
|
|||
|
{
|
|||
|
uint64_t FlashWord[4];
|
|||
|
|
|||
|
memcpy((char *)FlashWord, _ucpSrc, 32);
|
|||
|
_ucpSrc += 32;
|
|||
|
|
|||
|
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, _ulFlashAddr, (uint64_t)((uint32_t)FlashWord)) == HAL_OK)
|
|||
|
{
|
|||
|
_ulFlashAddr = _ulFlashAddr + 32;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
goto err;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (_ulSize % 32)
|
|||
|
{
|
|||
|
uint64_t FlashWord[4];
|
|||
|
|
|||
|
FlashWord[0] = 0;
|
|||
|
FlashWord[1] = 0;
|
|||
|
FlashWord[2] = 0;
|
|||
|
FlashWord[3] = 0;
|
|||
|
memcpy((char *)FlashWord, _ucpSrc, _ulSize % 32);
|
|||
|
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, _ulFlashAddr, (uint64_t)((uint32_t)FlashWord)) == HAL_OK)
|
|||
|
{
|
|||
|
; // _ulFlashAddr = _ulFlashAddr + 32;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
goto err;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
HAL_FLASH_Lock();
|
|||
|
|
|||
|
__set_PRIMASK(0);
|
|||
|
|
|||
|
return 0;
|
|||
|
|
|||
|
err:
|
|||
|
HAL_FLASH_Lock();
|
|||
|
|
|||
|
__set_PRIMASK(0);
|
|||
|
|
|||
|
return 1;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|