STM32H750XB_RT-THREAD/0-下载算法/embedFire-H750-W25Q256/User/FlashAPI/FlashPrg.c
2025-07-21 14:34:29 +08:00

333 lines
9.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* -----------------------------------------------------------------------------
* Copyright (c) 2016 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: 10. October 2018
* $Revision: V1.0.0
*
* Project: Flash Device Description for
* STM32H743 W25Q256 SPIFI Flash
* --------------------------------------------------------------------------- */
#include "FlashOS.H" // FlashOS Structures
#include "stm32h7xx.h"
#include "bsp_qspi_flash.h"
#include "bsp_led.h"
typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;
typedef volatile uint32_t vu32;
typedef volatile uint16_t vu16;
typedef volatile uint8_t vu8;
#define PAGE_SIZE 512
/*
* 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
*/
static void SystemClock_Config(void);
uint8_t aux_buf[PAGE_SIZE];
uint32_t base_adr;
uint32_t Address = 0, SECTORError = 0, Index = 0;
__IO uint64_t data64 = 0;
unsigned int Bootloader_size(void);
extern const unsigned char BootloaderImage[];
uint32_t ISBootloadrOK(void)
{
__IO uint32_t MemoryProgramStatus = 0;
/* <20><><EFBFBD><EFBFBD>BootLoader<65>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>
MemoryProgramStatus = 0: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
MemoryProgramStatus != 0: <20><><EFBFBD><EFBFBD>ȱʧ */
Address = 0x08000000;
MemoryProgramStatus = 0x0;
while (Address < 0x08000000+Bootloader_size())
{
data64 = *(uint64_t*)Address;
__DSB();
if(data64 != ((uint64_t*)BootloaderImage)[Index])
{
MemoryProgramStatus++;
}
Address +=8;
Index++;
}
return MemoryProgramStatus;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>keil<69><6C><EFBFBD>غ<EFBFBD><D8BA><EFBFBD><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̶<EFBFBD><CCB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD><C2B5><EFBFBD>һ<EFBFBD>δ˺<CEB4><CBBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5>ô˺<C3B4><CBBA><EFBFBD>֮ǰkeil<69>Ḵλ<E1B8B4><CEBB>Ƭ<EFBFBD><C6AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>Ƭ<EFBFBD><C6AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ij<EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>Ҫ<EFBFBD><D2AA>ʼ<EFBFBD><CABC>һ<EFBFBD><D2BB>
int Init (unsigned long adr, unsigned long clk, unsigned long fnc) {
if(fnc==1)
{/* WORKAROUND for BL: Disable interrupts to avoid SPI/DMA interrupts enabled by BL */
__disable_irq();
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><D0A3><EFBFBD><EFBFBD>Բ<EFBFBD><D4B2><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD>оƬ<D0BE><C6AC><EFBFBD><EFBFBD> */
/* ʹ<><CAB9>ָ<EFBFBD><EFBFBD><EEBBBA> */
// SCB_EnableICache();
/* ʹ<><CAB9><EFBFBD><EFBFBD><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD> */
// SCB_EnableDCache();
/* Init value with the default clock after reset. Needed by HAL drivers */
SystemInit();
HAL_Init();
SystemClock_Config();
LED_GPIO_Config();
/* <20><><EFBFBD><EFBFBD>BootLoader<65><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
if (ISBootloadrOK() != 0)
{
static FLASH_EraseInitTypeDef EraseInitStruct;
/* <20><><EFBFBD><EFBFBD>Flash<73><68><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƼĴ<C6BC><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
HAL_FLASH_Unlock();
/* <20><><EFBFBD>ò<EFBFBD><C3B2><EFBFBD><EFBFBD><EFBFBD><E1B9B9>*/
EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
EraseInitStruct.Banks = FLASH_BANK_1;
EraseInitStruct.Sector = FLASH_SECTOR_0;
EraseInitStruct.NbSectors = 1;
if (HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError) != HAL_OK)
{
return (1);
}
/* <20><><EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD>û<EFBFBD>Flash<73><68><EFBFBD><EFBFBD> */
Address = 0x08000000;
Index =0;
while (Address < 0x08000000+Bootloader_size())
{
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, Address, ((uint32_t)BootloaderImage)+Index) == HAL_OK)
{
Address = Address + 32;
Index = Index + 32;
}
else
{
return (1);
}
}
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƼĴ<C6BC><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʣ<EFBFBD><CAA3><EFBFBD><EFBFBD><EFBFBD><E9B1A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܿ<EFBFBD><DCBF>ܵ<EFBFBD><DCB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>***/
HAL_FLASH_Lock();
}
/*<2A><>ʼ<EFBFBD><CABC>Flash*/
QSPI_FLASH_Init();
}
base_adr = adr;
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) {
return (0);
}
/*
* Erase complete Flash Memory
* Return Value: 0 - OK, 1 - Failed
*/
int EraseChip (void) {
uint8_t res = QSPI_ERROR;
res = BSP_QSPI_Erase_Chip();
if(res != QSPI_OK)
return (1);/* Finished with Errors */
else
return (0);/* Finished without Errors */
}
/*
* Erase Sector in Flash Memory
* Parameter: adr: Sector Address
* Return Value: 0 - OK, 1 - Failed
*/
int EraseSector (unsigned long adr) {
uint8_t res = QSPI_ERROR;
res = BSP_QSPI_Erase_Block(adr-base_adr);
if(res != QSPI_OK)
{
return (1);
} /* Finished with Errors */
else
return (0); /* Finished without Errors */
}
/*
* 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
*/
int ProgramPage (unsigned long adr, unsigned long sz, unsigned char *buf) {
uint8_t res = QSPI_ERROR;
res = BSP_QSPI_Write(buf,adr-base_adr,sz);
if(res != QSPI_OK)
return (1); /* Finished with Errors */
else
return (0); /* Finished without Errors */
}
/*
* Verify Flash Contents
* Parameter: adr: Start Address
* sz: Size (in bytes)
* buf: Data
* Return Value: (adr+sz) - OK, Failed Address
*/
/*
Verify function is obsolete because all other function leave
the SPIFI in memory mode so a memory compare could be used.
*/
unsigned long Verify (unsigned long adr, unsigned long sz, unsigned char *buf) {
int numWR;// ʵ<>ʶ<EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int oriAddr=adr,oriSize=sz;// <20><>¼ԭ<C2BC><D4AD>ַ<EFBFBD>ʹ<EFBFBD>С
uint8_t res = QSPI_ERROR;
while(sz!=0)
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>sz<73><7A><EFBFBD><EFBFBD>PAGE_SIZE<5A><45><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD>ȡ<EFBFBD><C8A1>һ<EFBFBD>ζ<EFBFBD>PAGE_SIZE<5A><45><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>Ϊsz-=numWR<57><52>
if(sz>PAGE_SIZE)
{
numWR=PAGE_SIZE;
sz-=numWR;
}
else
{
numWR=sz;// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>PAGE_SIZE<5A><45>ֱ<EFBFBD>Ӷ<EFBFBD>ȡnumWR<57><52><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD>ʣ<EFBFBD><CAA3><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>szΪ0<CEAA><30>
sz=0;
}
res = BSP_QSPI_FastRead(aux_buf,adr-base_adr,numWR);
if(res == QSPI_OK)
{
for (int i = 0; i< numWR; i++)
{
if (aux_buf[i] != buf[i])
return (adr+i); // Verification Failed (return address)
}
adr+=numWR;// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD>ĵ<EFBFBD>ַ
}
else
{
return (0x0badc0de);// failed
}
}
return (oriAddr+oriSize); // Done successfully
}
static void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Supply configuration update enable
*/
HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
/** Configure the main internal regulator output voltage
*/
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 5;
RCC_OscInitStruct.PLL.PLLN = 192;
RCC_OscInitStruct.PLL.PLLP = 2;
RCC_OscInitStruct.PLL.PLLQ = 2;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2;
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
RCC_OscInitStruct.PLL.PLLFRACN = 0;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
while(1);
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
|RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
{
while(1);
}
}