1,目前做了spiflash的stm32f103芯片 可以进行flash的读写 使用STM32CubeProgrammer +stlink 来实现spiflash的读写 目前只支持st的芯片
2,打算做一个mdk的spiflash 读写算法
3,目前已经做好一个H750的spiflash和qspi的烧录算法 支持jlink的软件 j-flash的软件上进行读写外挂spiflash和qspiflash 也支持mdk软件烧录算法
stlink的H750的算法
#include "Dev_Inf.h"
/* This structure containes information used by ST-LINK Utility to program and erase the device */
#if defined (__ICCARM__)
__root struct StorageInfo const StorageInfo = {
#else
struct StorageInfo const StorageInfo = {
#endif
"VT_CORE_W25Q256_H750", // Device Name + EVAL Borad name
NOR_FLASH, // Device Type
QSPI_ADDR_BASE, // Device Start Address
32*1024*1024, // Device Size in Bytes (32MBytes)
0x100, // Programming Page Size 256Bytes
0xFF, // Initial Content of Erased Memory
// Specify Size and Address of Sectors (view example below)
0x00002000, 0x00001000, // Sector Num : 8192 ,Sector Size: 4KBytes
0x00000000, 0x00000000,
};
#include <stdint.h>
#include "sys.h"
#include "w25qxx.h"
#include "qspi.h"
#include "usart.h"
#include "string.h"
#include "Dev_Inf.h"
/*
*********************************************************************************************************
*********************************************************************************************************
*/
#define PAGE_SIZE 4096
/*
*********************************************************************************************************
*********************************************************************************************************
*/
#define DEBUG_BAUD_RATE (921600)
/*
*********************************************************************************************************
*********************************************************************************************************
*/
//
#if defined (__GNUC__) /* GNU Compiler */
volatile uint8_t aux_buf[PAGE_SIZE] __attribute__ ((aligned (32)));
volatile uint32_t base_adr __attribute__ ((aligned (32)));
volatile uint32_t write_flag __attribute__ ((aligned (32)));
#elif defined (__ICCARM__) /* IAR Compiler */
_Pragma("data_alignment=32") volatile uint8_t aux_buf[PAGE_SIZE];
_Pragma("data_alignment=32") volatile uint32_t base_adr;
_Pragma("data_alignment=32") volatile uint32_t write_flag;
#elif defined (__CC_ARM) /* ARM Compiler */
volatile uint8_t aux_buf[PAGE_SIZE] __attribute__ ((aligned (32)));
volatile uint32_t base_adr __attribute__ ((aligned (32)));
volatile uint32_t write_flag __attribute__ ((aligned (32)));
#endif
/*
*********************************************************************************************************
*********************************************************************************************************
*/
void qspi_sys_init(void)
{
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
//串口初始化
uart_init(400,DEBUG_BAUD_RATE);
//
QSPI_W25QXX_Init(); //初始化W25QXX
//
base_adr = QSPI_ADDR_BASE;
//
}
/*******************************************************************************
Description :
System initialization
Inputs :
None
outputs :
"1" : Operation succeeded
"0" : Operation failure
********************************************************************************/
int Init (void)
{
//
qspi_sys_init();
//
debug_log("start qspi \r\n");
//
write_flag=0;
//
return 1;
}
/*******************************************************************************
Description :
Write data to the device
Inputs :
Address : Write location
Size : Length in bytes
buffer : Address where to get the data to write
outputs :
"1" : Operation succeeded
Info :
Note : Mandatory for all types except SRAM and PSRAM
********************************************************************************/
int Write (uint32_t Address, uint32_t Size, uint8_t* buffer)
{
uint32_t result=0;
uint32_t size_shi=0;
uint32_t size_ge=0;
uint32_t i=0;
uint8_t *pbuf=(uint8_t *)buffer;
//
size_shi=Size/PAGE_SIZE;
//
size_ge =Size%PAGE_SIZE;
//
qspi_sys_init();
//
SCB_CleanInvalidateDCache();
//
SCB_CleanDCache();
//
usr_printf("ProgramPage adr:0x%x ,sz: %d ,buf :0x%x \r\n",(uint32_t)Address,Size,(uint32_t)pbuf);
//
if(Address>=base_adr)
{
if(size_shi>0)
{
for(i=0;i<size_shi;i++)
{
QSPI_W25QXX_Write((pbuf+i*PAGE_SIZE),(Address-base_adr)+i*PAGE_SIZE,PAGE_SIZE);
}
}
//
if(size_ge>0)
{
QSPI_W25QXX_Write((pbuf+size_shi*PAGE_SIZE), (Address-base_adr)+size_shi*PAGE_SIZE, size_ge);
}
//
}
return 1;
}
/*******************************************************************************
Description :
Erase a full sector in the device
Inputs :
SectrorAddress : Start of sector
outputs :
"1" : Operation succeeded
"0" : Operation failure
Note : Not Mandatory for SRAM PSRAM and NOR_FLASH
********************************************************************************/
int SectorErase (uint32_t EraseStartAddress ,uint32_t EraseEndAddress)
{
uint32_t SectorAddr;
uint32_t Sector_start;
//
qspi_sys_init();
//
debug_log("ease:%x,ram:%x \r\n",EraseStartAddress,(uint32_t)EraseEndAddress);
//
Sector_start = (EraseStartAddress - (EraseStartAddress % 0x1000));
//
while (EraseEndAddress>=Sector_start)
{
SectorAddr = Sector_start & 0x0FFFFFFF;
//
QSPI_W25QXX_Erase_Sector( SectorAddr);
//
Sector_start += 0x1000;
}
return 1;
}
/*******************************************************************************
Description :
Read data from the device
Inputs :
Address : Write location
Size : Length in bytes
buffer : Address where to get the data to write
outputs :
"1" : Operation succeeded
"0" : Operation failure
Note : Not Mandatory
********************************************************************************/
int Read (uint32_t Address, uint32_t Size, uint8_t* Buffer)
{
//
qspi_sys_init();
//
debug_log("read:%x,ram:%x,size:%d \r\n",Address,(uint32_t)Buffer,Size);
//
if(Address>=base_adr)
{
QSPI_W25QXX_Read((uint8_t*)Buffer, (Address-base_adr), Size);
}
//
return 1;
}
/*******************************************************************************
Description :
Verify the data
Inputs :
MemoryAddr : Write location
RAMBufferAddr : RAM Address
Size : Length in bytes
outputs :
"0" : Operation succeeded
Note : Not Mandatory
********************************************************************************/
int Verify (uint32_t MemoryAddr, uint32_t RAMBufferAddr, uint32_t Size)
{
volatile unsigned char *psrc=(volatile unsigned char *)RAMBufferAddr;
volatile unsigned long i;
uint32_t size_shi=0;
uint32_t size_ge=0;
uint32_t j=0;
uint8_t *pbuf=(uint8_t *)aux_buf;
//
size_shi=Size/PAGE_SIZE;
//
size_ge =Size%PAGE_SIZE;
//
qspi_sys_init();
//
printf("start verify :0x%x ,0x%x,%d ,0x%x\r\n",(uint32_t)MemoryAddr,(uint32_t)Size,(uint32_t)Size,(uint32_t)RAMBufferAddr);
//
SCB_CleanInvalidateDCache();
//
SCB_CleanDCache();
//
if((Size> 0)&&(MemoryAddr>=base_adr))
{
//
if(size_shi>0)
{
for(i=0;i<size_shi;i++)
{
//
memset((uint8_t*)pbuf,0,PAGE_SIZE);
//
QSPI_W25QXX_Read((pbuf),(MemoryAddr-base_adr)+i*PAGE_SIZE,PAGE_SIZE);
//
for(j = 0; j< PAGE_SIZE; j++)
{
if(aux_buf[j] != psrc[j+i*PAGE_SIZE])
{
//
debug_log("erroffset:%d base addr:%x addr:%x data--read:%x write:%x\r\n",
(uint32_t)(j+i*PAGE_SIZE),base_adr,MemoryAddr,aux_buf[j],psrc[j+i*PAGE_SIZE]);
//
return (MemoryAddr+j+i*PAGE_SIZE);
}
}
}
}
//
if(size_ge>0)
{
//
memset((uint8_t*)pbuf,0,PAGE_SIZE);
//
QSPI_W25QXX_Read((pbuf+size_shi*PAGE_SIZE), (MemoryAddr-base_adr)+size_shi*PAGE_SIZE, size_ge);
//
for(j = 0; j< size_ge; j++)
{
if(aux_buf[j] != psrc[j+size_shi*PAGE_SIZE])
{
//
debug_log("erroffset:%d base addr:%x addr:%x data--read:%x write:%x\r\n",
(uint32_t)(j+size_shi*PAGE_SIZE),base_adr,MemoryAddr,aux_buf[j],psrc[j+size_shi*PAGE_SIZE]);
//
return (MemoryAddr+j+size_shi*PAGE_SIZE);
}
}
}
//
return (MemoryAddr+Size);
}
else
{
return (MemoryAddr);
}
}
#define MCU_FLASH 1
#define NAND_FLASH 2
#define NOR_FLASH 3
#define SRAM 4
#define PSRAM 5
#define PC_CARD 6
#define SPI_FLASH 7
#define I2C_FLASH 8
#define SDRAM 9
#define I2C_EEPROM 10
//
#define QSPI_ADDR_BASE (0x90000000)
//
#define SECTOR_NUM 10 // Max Number of Sector types
struct DeviceSectors
{
unsigned long SectorNum; // Number of Sectors
unsigned long SectorSize; // Sector Size in Bytes
};
struct StorageInfo
{
char DeviceName[100]; // Device Name and Description
unsigned short DeviceType; // Device Type: ONCHIP, EXT8BIT, EXT16BIT, ...
unsigned long DeviceStartAddress; // Default Device Start Address
unsigned long DeviceSize; // Total Size of Device
unsigned long PageSize; // Programming Page Size
unsigned char EraseValue; // Content of Erased Memory
struct DeviceSectors sectors[SECTOR_NUM];
};
jlink的H750的算法
/**************************************************************************//**
* @file FlashOS.h
* @brief Data structures and entries Functions
* @version V1.0.0
* @date 10. October 2018
******************************************************************************/
/*
* Copyright (c) 2010-2018 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define USE_SEGGER_LINK_EN 0//表示 jlink烧录器算法 0表示mdk 烧录算法
//
#define QSPI_ADDR_BASE (0x90000000)
//
#if (USE_SEGGER_LINK_EN>0)
//
#define U8 unsigned char
#define U16 unsigned short
#define U32 unsigned long
#define I8 signed char
#define I16 signed short
#define I32 signed long
#define ONCHIP (1) // On-chip Flash Memory
#define MAX_NUM_SECTORS (512) // Max. number of sectors, must not be modified.
#define ALGO_VERSION (0x0101) // Algo version, must not be modified.
struct SECTOR_INFO {
U32 SectorSize; // Sector Size in bytes
U32 SectorStartAddr; // Start address of the sector area (relative to the "BaseAddr" of the flash)
};
struct FlashDevice {
U16 AlgoVer; // Algo version number
U8 Name[128]; // Flash device name
U16 Type; // Flash device type
U32 BaseAddr; // Flash base address
U32 TotalSize; // Total flash device size in Bytes (256 KB)
U32 PageSize; // Page Size (number of bytes that will be passed to ProgramPage(). MinAlig is 8 byte
U32 Reserved; // Reserved, should be 0
U8 ErasedVal; // Flash erased value
U32 TimeoutProg; // Program page timeout in ms; 0: use default timeout
// el xxxx Multi Sector program:
U32 TimeoutErase; // Erase sector timeout in ms 0: Use default timeout
// el xxxx Multi Sector erase:
struct SECTOR_INFO SectorInfo[MAX_NUM_SECTORS]; // Flash sector layout definition
};
//
#define SECTOR_END 0xFFFFFFFF, 0xFFFFFFFF
//
// Flash module functions
//
extern int Init (U32 Addr, U32 Freq, U32 Func );
extern int UnInit (U32 Func );
extern int BlankCheck (U32 Addr, U32 NumBytes, U8 BlankData );
extern int EraseChip (void );
extern int EraseSector (U32 SectorAddr );
extern int ProgramPage (U32 DestAddr, U32 NumBytes, U8 *pSrcBuff );
extern U32 Verify (U32 Addr, U32 NumBytes, U8 *pSrcBuff );
//
// SEGGER defined functions
//
extern int SEGGER_OPEN_Read (U32 Addr, U32 NumBytes, U8 *pDestBuff );
extern int SEGGER_OPEN_Program (U32 DestAddr, U32 NumBytes, U8 *pSrcBuff );
extern int SEGGER_OPEN_Erase (U32 SectorAddr, U32 SectorIndex, U32 NumSectors );
//
#else
//
#define VERS 1 // Interface Version 1.01
#define UNKNOWN 0 // Unknown
#define ONCHIP 1 // On-chip Flash Memory
#define EXT8BIT 2 // External Flash Device on 8-bit Bus
#define EXT16BIT 3 // External Flash Device on 16-bit Bus
#define EXT32BIT 4 // External Flash Device on 32-bit Bus
#define EXTSPI 5 // External Flash Device on SPI
#define SECTOR_NUM 512 // Max Number of Sector Items
#define PAGE_MAX 65536 // Max Page Size for Programming
struct FlashSectors {
unsigned long szSector; // Sector Size in Bytes
unsigned long AddrSector; // Address of Sector
};
#define SECTOR_END 0xFFFFFFFF, 0xFFFFFFFF
struct FlashDevice {
unsigned short Vers; // Version Number and Architecture
char DevName[128]; // Device Name and Description
unsigned short DevType; // Device Type: ONCHIP, EXT8BIT, EXT16BIT, ...
unsigned long DevAdr; // Default Device Start Address
unsigned long szDev; // Total Size of Device
unsigned long szPage; // Programming Page Size
unsigned long Res; // Reserved for future Extension
unsigned char valEmpty; // Content of Erased Memory
unsigned long toProg; // Time Out of Program Page Function
unsigned long toErase; // Time Out of Erase Sector Function
struct FlashSectors sectors[SECTOR_NUM];
};
#define FLASH_DRV_VERS (0x0100+VERS) // Driver Version, do not modify!
// Flash Programming Functions (Called by FlashOS)
extern int Init (unsigned long adr, // Initialize Flash
unsigned long clk,
unsigned long fnc);
extern int UnInit (unsigned long fnc); // De-initialize Flash
extern int BlankCheck (unsigned long adr, // Blank Check
unsigned long sz,
unsigned char pat);
extern int EraseChip (void); // Erase complete Device
extern int EraseSector (unsigned long adr); // Erase Sector Function
extern int ProgramPage (unsigned long adr, // Program Page Function
unsigned long sz,
unsigned char *buf);
extern unsigned long Verify (unsigned long adr, // Verify Function
unsigned long sz,
unsigned char *buf);
//
extern int SEGGER_OPEN_Read (unsigned long Addr, unsigned long NumBytes, unsigned char *pDestBuff );
extern int SEGGER_OPEN_Program (unsigned long DestAddr, unsigned long NumBytes, unsigned char *pSrcBuff );
extern int SEGGER_OPEN_Erase (unsigned long SectorAddr, unsigned long SectorIndex, unsigned long NumSectors );
//
#endif
/* -----------------------------------------------------------------------------
* 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
* STM32H750_FMC100 W25Q256 SPIFI Flash
* --------------------------------------------------------------------------- */
#include "..\FlashOS.H" // FlashOS Structures
//
#if (USE_SEGGER_LINK_EN>0)
//
#ifdef W25Q64FV
//
struct FlashDevice const FlashDevice __attribute__ ((section ("DevDscr"))) = {
ALGO_VERSION, // Algo version
"VT_CORE_H7_V01_JLINK_W25Q64", // Flash device name
ONCHIP, // Flash device type
QSPI_ADDR_BASE, // Flash base address
0x00800000, // Total flash device size in Bytes (256 KB)
4096, // Page Size (number of bytes that will be passed to ProgramPage(). MinAlig is 8 byte
0, // Reserved, should be 0
0xFF, // Flash erased value
1000, // Program page timeout in ms
6000, // Erase sector timeout in ms
//
// Flash sector layout definition
0x001000, 0x000000, // Sector Size 4kB (8192 Sectors)
SECTOR_END
};
//
#endif
//
#else
//
#ifdef W25Q256FV
//
//4Kbytes为一个Sector
//16个扇区为1个Block
//W25Q256
//容量为32M字节,共有512个Block,8192个Sector
//
struct FlashDevice const FlashDevice =
{
FLASH_DRV_VERS, // Driver Version, do not modify!
"VT_CORE_H7_V01_W25Q256", // Device Name
EXTSPI, // Device Type
QSPI_ADDR_BASE, // Device Start Address
0x02000000, // Device Size (32MB)
4096, // Programming Page Size
0, // Reserved, must be 0
0xFF, // Initial Content of Erased Memory
10000, // Program Page Timeout 300 mSec
30000, // Erase Sector Timeout 3000 mSec
// Specify Size and Address of Sectors
0x001000, 0x000000, // Sector Size 4kB (8192 Sectors)
SECTOR_END
};
#endif
#ifdef W25Q128FV
struct FlashDevice const FlashDevice =
{
FLASH_DRV_VERS, // Driver Version, do not modify!
"VT_CORE_H7_V01_W25Q128", // Device Name
EXTSPI, // Device Type
QSPI_ADDR_BASE, // Device Start Address
0x01000000, // Device Size (16MB)
4096, // Programming Page Size
0, // Reserved, must be 0
0xFF, // Initial Content of Erased Memory
10000, // Program Page Timeout 300 mSec
30000, // Erase Sector Timeout 3000 mSec
// Specify Size and Address of Sectors
0x001000, 0x000000, // Sector Size 4kB (8192 Sectors)
SECTOR_END
};
#endif
#ifdef W25Q64FV
struct FlashDevice const FlashDevice =
{
FLASH_DRV_VERS, // Driver Version, do not modify!
"VT_CORE_H7_V01_W25Q64", // Device Name
EXTSPI, // Device Type
QSPI_ADDR_BASE, // Device Start Address
0x00800000, // Device Size (8MB)
4096, // Programming Page Size
0, // Reserved, must be 0
0xFF, // Initial Content of Erased Memory
10000, // Program Page Timeout 300 mSec
30000, // Erase Sector Timeout 3000 mSec
// Specify Size and Address of Sectors
0x001000, 0x000000, // Sector Size 4kB (8192 Sectors)
SECTOR_END
};
#endif
//
#endif
//
/* -----------------------------------------------------------------------------
* 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 "sys.h"
#include "w25qxx.h"
#include "qspi.h"
#include "usart.h"
#include "string.h"
/*
*********************************************************************************************************
*********************************************************************************************************
*/
#define EN_MDK_FLM_VERIFY 1//不开启校验
#define EN_MDK_FLM_MAP 0//
#define BlankCheck_EN 0//
#define PROG_READ_WRITE_EN 0//
#define MDK_FLM_INIT_EN 1//保证稳定性每次都初始化
//
#define PAGE_SIZE 4096
//
#define DEBUG_BAUD_RATE (921600)
//
#define FLM_VER_Main (1)
//
#define FLM_VER_SUB1 (0)
//
#define FLM_VER_SUB2 (14)
/*
*********************************************************************************************************
*********************************************************************************************************
*/
#if ((PROG_READ_WRITE_EN>0)||(EN_MDK_FLM_VERIFY>0))
__IO uint8_t aux_buf[PAGE_SIZE] __attribute__((aligned(32)));
#endif
__IO uint32_t base_adr __attribute__((aligned(32)));
__IO uint32_t write_flag __attribute__((aligned(32)));
/*
*********************************************************************************************************
*********************************************************************************************************
*/
#if (USE_SEGGER_LINK_EN>0)
/*
*********************************************************************************************************
*********************************************************************************************************
*/
int Init(U32 Addr,U32 Freq,U32 Func)
{
uint32_t result=0;
//
SystemInit();
//
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
//串口初始化
uart_init(400,DEBUG_BAUD_RATE);
//
QSPI_W25QXX_Init(); //初始化W25QXX
//
base_adr = Addr;
//
if(write_flag==0)
{
FLASH_Erase_APP_FLAG(APP_FLAG_Offset);
FLASH_Write_APP_FLAG(APP_FLAG_Offset,0xA5A5);
}
//
usr_printf("h750 flm ver: %d.%d.%d VERIFY:%d,MAP:%d,BLANK:%d,PROG_WR:%d,FLM_INIT:%d\r\n",
FLM_VER_Main,FLM_VER_SUB1,FLM_VER_SUB2,
EN_MDK_FLM_VERIFY,EN_MDK_FLM_MAP,
BlankCheck_EN,PROG_READ_WRITE_EN,
MDK_FLM_INIT_EN );
//
#if (EN_MDK_FLM_MAP>0)
// 内存映射
result = QSPI_EnableMemoryMappedMode();
if(result != 0)
{
//
usr_printf("Init :%X\r\n",result);
//
return 1;
}
#endif
//
write_flag=0;
return (0);
}
/*
*********************************************************************************************************
*********************************************************************************************************
*/
int UnInit(U32 Func)
{
#if (EN_MDK_FLM_MAP>0)
uint32_t result=0;
//
#if (EN_MDK_FLM_MAP>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#else
QSPI_W25QXX_Init(); //初始化W25QXX
#endif
// 内存映射
result = QSPI_EnableMemoryMappedMode();
if(result != 0)
{
//
usr_printf("UnInit :%X\r\n",result);
//
return 1;
}
#endif
//
return (0);
}
/*
*********************************************************************************************************
*********************************************************************************************************
*/
#if (BlankCheck_EN>0)
//
int BlankCheck(U32 Addr,U32 NumBytes,U8 BlankData)
{
U8* pData;
pData = (U8 *)Addr;
do
{
if(*pData++ != BlankData)
{
return 1;
}
}
while(--NumBytes);
return 0;
}
#else
//
int BlankCheck(unsigned long adr, unsigned long sz, unsigned char pat)
{
uint32_t size_shi=0;
uint32_t size_ge=0;
uint32_t i=0;
uint32_t j=0;
//
usr_printf("BlankCheck adr:0x%x ,sz: 0x%x ,pat :0x%x \r\n",(uint32_t)adr,(uint32_t)sz,pat);
//
size_shi=sz/PAGE_SIZE;
//
size_ge =sz%PAGE_SIZE;
//
if(size_shi>0)
{
for(i=0;i<size_shi;i++)
{
QSPI_W25QXX_Read((uint8_t*)aux_buf, (adr-base_adr)+i*PAGE_SIZE, PAGE_SIZE);
//
for(j=0;j<PAGE_SIZE;j++)
{
if(aux_buf[j] != pat)
{
return 1;
}
}
}
}
//
if(size_ge>0)
{
QSPI_W25QXX_Read((uint8_t*)aux_buf, (adr-base_adr)+size_shi*PAGE_SIZE, size_ge);
//
for(j=0;j<size_ge;j++)
{
if(aux_buf[j] != pat)
{
return 1;
}
}
}
return 0;
}
//
#endif
/*
*********************************************************************************************************
*********************************************************************************************************
*/
int EraseChip(void)
{
uint32_t result=0;
//
#if (EN_MDK_FLM_MAP>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#else
QSPI_W25QXX_Init(); //初始化W25QXX
#endif
//
QSPI_W25QXX_Erase_Chip();
// 内存映射
#if (EN_MDK_FLM_MAP>0)
result = QSPI_EnableMemoryMappedMode();
if(result != 0)
{
//
usr_printf("EraseChip :%X\r\n",result);
//
return 1;
}
#endif
//
return (0);
}
/*
*********************************************************************************************************
*********************************************************************************************************
*/
int EraseSector(U32 SectorAddr)
{
uint32_t result=0;
//
#if (EN_MDK_FLM_MAP>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#else
QSPI_W25QXX_Init(); //初始化W25QXX
#endif
//
if(SectorAddr>=base_adr)
{
QSPI_W25QXX_Erase_Sector(SectorAddr-base_adr);
}
// 内存映射
#if (EN_MDK_FLM_MAP>0)
result = QSPI_EnableMemoryMappedMode();
if(result != 0)
{
//
usr_printf("EraseSector :%X\r\n",result);
//
return 1;
}
#endif
return (0);
}
/*
*********************************************************************************************************
*********************************************************************************************************
*/
int ProgramPage(U32 DestAddr, U32 NumBytes, U8 *pSrcBuff)
{
uint32_t result=0;
uint32_t size_shi=0;
uint32_t size_ge=0;
uint32_t i=0;
uint8_t *pbuf=(uint8_t *)pSrcBuff;
//
size_shi=NumBytes/PAGE_SIZE;
//
size_ge =NumBytes%PAGE_SIZE;
//
#if (EN_MDK_FLM_MAP>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#else
QSPI_W25QXX_Init(); //初始化W25QXX
#endif
//
SCB_CleanInvalidateDCache();
//
SCB_CleanDCache();
//
usr_printf("ProgramPage adr:0x%x ,sz: %ld ,buf :0x%x \r\n",(uint32_t)DestAddr,NumBytes,(uint32_t)pbuf);
//
if(DestAddr>=base_adr)
{
if(size_shi>0)
{
for(i=0;i<size_shi;i++)
{
QSPI_W25QXX_Write((pbuf+i*PAGE_SIZE),(DestAddr-base_adr)+i*PAGE_SIZE,PAGE_SIZE);
}
}
//
if(size_ge>0)
{
QSPI_W25QXX_Write((pbuf+size_shi*PAGE_SIZE), (DestAddr-base_adr)+size_shi*PAGE_SIZE, size_ge);
}
//
}
// 内存映射
#if (EN_MDK_FLM_MAP>0)
result = QSPI_EnableMemoryMappedMode();
if(result != 0)
{
//
usr_printf("ProgramPage :%X\r\n",result);
//
return 1;
}
#endif
return (0);
}
/*
*********************************************************************************************************
*********************************************************************************************************
*/
#if (EN_MDK_FLM_VERIFY>0)
//
U32 Verify(U32 Addr, U32 NumBytes, U8 *pSrcBuff)
{
volatile unsigned char *psrc=pSrcBuff;
volatile unsigned long i;
uint32_t result=0;
uint32_t size_shi=0;
uint32_t size_ge=0;
uint32_t j=0;
uint8_t *pbuf=(uint8_t *)aux_buf;
//
size_shi=NumBytes/PAGE_SIZE;
//
size_ge =NumBytes%PAGE_SIZE;
//
#if (EN_MDK_FLM_MAP>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#else
QSPI_W25QXX_Init(); //初始化W25QXX
#endif
//
printf("start verify :0x%x ,0x%x,%d ,0x%x\r\n",(uint32_t)Addr,(uint32_t)NumBytes,(uint32_t)NumBytes,(uint32_t)pbuf);
//
SCB_CleanInvalidateDCache();
//
SCB_CleanDCache();
//
if((NumBytes> 0)&&(Addr>=base_adr))
{
//
if(size_shi>0)
{
for(i=0;i<size_shi;i++)
{
//
memset((uint8_t*)pbuf,0,PAGE_SIZE);
//
QSPI_W25QXX_Read((pbuf),(Addr-base_adr)+i*PAGE_SIZE,PAGE_SIZE);
//
for(j = 0; j< PAGE_SIZE; j++)
{
if(aux_buf[j] != psrc[j+i*PAGE_SIZE])
{
//
debug_log("erroffset:%d base addr:%x addr:%lx data--read:%x write:%x\r\n",
(uint32_t)(j+i*PAGE_SIZE),base_adr,Addr,aux_buf[j],psrc[j+i*PAGE_SIZE]);
//
return (Addr+j+i*PAGE_SIZE);
}
}
}
}
//
if(size_ge>0)
{
//
memset((uint8_t*)pbuf,0,PAGE_SIZE);
//
QSPI_W25QXX_Read((pbuf+size_shi*PAGE_SIZE), (Addr-base_adr)+size_shi*PAGE_SIZE, size_ge);
//
for(j = 0; j< size_ge; j++)
{
if(aux_buf[j] != psrc[j+size_shi*PAGE_SIZE])
{
//
debug_log("erroffset:%d base addr:%x addr:%lx data--read:%x write:%x\r\n",
(uint32_t)(j+size_shi*PAGE_SIZE),base_adr,Addr,aux_buf[j],psrc[j+size_shi*PAGE_SIZE]);
//
return (Addr+j+size_shi*PAGE_SIZE);
}
}
}
//
return (Addr+NumBytes);
}
else
{
// 内存映射
#if (EN_MDK_FLM_MAP>0)
result = QSPI_EnableMemoryMappedMode();
if(result != 0)
{
//
usr_printf("Verify3 :%X\r\n",result);
//
return (Addr);
}
#endif
return (Addr);
}
}
//
#endif
/*
*********************************************************************************************************
*********************************************************************************************************
*/
//
// SEGGER defined functions
//
int SEGGER_OPEN_Read(U32 Addr, U32 NumBytes, U8 *pDestBuff)
{
uint32_t result=0;
//
#if (EN_MDK_FLM_MAP>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#else
QSPI_W25QXX_Init(); //初始化W25QXX
#endif
//
SCB_CleanInvalidateDCache();
//
SCB_CleanDCache();
//
usr_printf("SEGGER_OPEN_Read adr:0x%x ,sz: 0x%x ,buf :0x%x \r\n",(uint32_t)Addr,NumBytes,(uint32_t)pDestBuff);
//
if(Addr>=base_adr)
{
QSPI_W25QXX_Read(pDestBuff,(Addr-base_adr),NumBytes);
}
// 内存映射
#if (EN_MDK_FLM_MAP>0)
result = QSPI_EnableMemoryMappedMode();
if(result != 0)
{
//
usr_printf("SEGGER_OPEN_Read :%X\r\n",result);
//
return 0;
}
#endif
return NumBytes;
}
/*
*********************************************************************************************************
*********************************************************************************************************
*/
int SEGGER_OPEN_Program(U32 DestAddr, U32 NumBytes, U8 *pSrcBuff)
{
uint32_t result=0;
uint32_t size_shi=0;
uint32_t size_ge=0;
uint32_t i=0;
uint8_t *pbuf=(uint8_t *)pSrcBuff;
//
size_shi=NumBytes/PAGE_SIZE;
//
size_ge =NumBytes%PAGE_SIZE;
//
#if (EN_MDK_FLM_MAP>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#else
QSPI_W25QXX_Init(); //初始化W25QXX
#endif
//
SCB_CleanInvalidateDCache();
//
SCB_CleanDCache();
//
usr_printf("SEGGER_OPEN_Program adr:0x%x ,sz: %ld ,buf :0x%x \r\n",(uint32_t)DestAddr,NumBytes,(uint32_t)pSrcBuff);
//
if(DestAddr>=base_adr)
{
if(size_shi>0)
{
for(i=0;i<size_shi;i++)
{
QSPI_W25QXX_Write((pbuf+i*PAGE_SIZE),(DestAddr-base_adr)+i*PAGE_SIZE,PAGE_SIZE);
}
}
//
if(size_ge>0)
{
QSPI_W25QXX_Write((pbuf+size_shi*PAGE_SIZE), (DestAddr-base_adr)+size_shi*PAGE_SIZE, size_ge);
}
//
}
// 内存映射
#if (EN_MDK_FLM_MAP>0)
result = QSPI_EnableMemoryMappedMode();
if(result != 0)
{
//
usr_printf("SEGGER_OPEN_Program :%X\r\n",result);
//
return 1;
}
#endif
return (0);
}
/*
*********************************************************************************************************
*********************************************************************************************************
*/
int SEGGER_OPEN_Erase(U32 SectorAddr, U32 SectorIndex, U32 NumSectors)
{
uint32_t result=0;
//
#if (EN_MDK_FLM_MAP>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#else
QSPI_W25QXX_Init(); //初始化W25QXX
#endif
//
usr_printf("SEGGER_OPEN_Erase adr:0x%x ,SectorIndex: %ld ,NumSectors :%d \r\n",(uint32_t)SectorAddr,SectorIndex,(uint32_t)NumSectors);
//
do{
//
if(SectorAddr>=base_adr)
{
QSPI_W25QXX_Erase_Sector(SectorAddr-base_adr);
}
//
SectorAddr += QSPI_SECTOR_SIZE;
//
SectorIndex++;
//
} while (--NumSectors);
//
// 内存映射
#if (EN_MDK_FLM_MAP>0)
result = QSPI_EnableMemoryMappedMode();
if(result != 0)
{
//
usr_printf("EraseSector :%X\r\n",result);
//
return 1;
}
#endif
return (0);
}
/*
*********************************************************************************************************
*********************************************************************************************************
*/
#else
/*
*********************************************************************************************************
*********************************************************************************************************
*/
/*
* 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
*/
//这个函数在keil下载后,在擦除、编程都会重新调用一次此函数,而且在调用此函数之前keil会复位单片机,相当于单片机跑起来的初始化功能要在擦除、编程时都要初始化一遍
int Init(unsigned long adr, unsigned long clk, unsigned long fnc)
{
uint32_t result=0;
//
SystemInit();
//
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
//串口初始化
uart_init(400,DEBUG_BAUD_RATE);
//
QSPI_W25QXX_Init(); //初始化W25QXX
//
base_adr = QSPI_ADDR_BASE;
//
usr_printf("base addr:%x \r\n",base_adr);
usr_printf("h750 flm ver: %d.%d.%d VERIFY:%d,MAP:%d,BLANK:%d,PROG_WR:%d,FLM_INIT:%d\r\n",
FLM_VER_Main,FLM_VER_SUB1,FLM_VER_SUB2,
EN_MDK_FLM_VERIFY,EN_MDK_FLM_MAP,
BlankCheck_EN,PROG_READ_WRITE_EN,
MDK_FLM_INIT_EN );
//
#if (EN_MDK_FLM_MAP>0)
// 内存映射
result = QSPI_EnableMemoryMappedMode();
if(result != 0)
{
//
usr_printf("Init :%X\r\n",result);
//
return 1;
}
#endif
//
write_flag=0;
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)
{
#if (EN_MDK_FLM_MAP>0)
uint32_t result=0;
//
#if (EN_MDK_FLM_MAP>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#else
QSPI_W25QXX_Init(); //初始化W25QXX
#endif
// 内存映射
result = QSPI_EnableMemoryMappedMode();
if(result != 0)
{
//
usr_printf("UnInit :%X\r\n",result);
//
return 1;
}
#endif
//
return (0);
}
/*
* Erase complete Flash Memory
* Return Value: 0 - OK, 1 - Failed
*/
int EraseChip(void)
{
uint32_t result=0;
//
#if (EN_MDK_FLM_MAP>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#else
QSPI_W25QXX_Init(); //初始化W25QXX
#endif
//
QSPI_W25QXX_Erase_Chip();
// 内存映射
#if (EN_MDK_FLM_MAP>0)
result = QSPI_EnableMemoryMappedMode();
if(result != 0)
{
//
usr_printf("EraseChip :%X\r\n",result);
//
return 1;
}
#endif
//
return (0);
}
/*
* Erase Sector in Flash Memory
* Parameter: adr: Sector Address
* Return Value: 0 - OK, 1 - Failed
*/
int EraseSector(unsigned long adr)
{
uint32_t result=0;
//
#if (EN_MDK_FLM_MAP>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#else
QSPI_W25QXX_Init(); //初始化W25QXX
#endif
//
if(adr>=base_adr)
{
QSPI_W25QXX_Erase_Sector(adr-base_adr);
}
// 内存映射
#if (EN_MDK_FLM_MAP>0)
result = QSPI_EnableMemoryMappedMode();
if(result != 0)
{
//
usr_printf("EraseSector :%X\r\n",result);
//
return 1;
}
#endif
return (0);
}
/*
* 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
*/
#if (BlankCheck_EN>0)
int BlankCheck(unsigned long adr, unsigned long sz, unsigned char pat)
{
uint8_t* pData;
pData = (uint8_t *)adr;
do
{
if(*pData++ != pat)
{
return 1;
}
}
while(--sz);
return 0;
}
#else
//
int BlankCheck(unsigned long adr, unsigned long sz, unsigned char pat)
{
uint32_t size_shi=0;
uint32_t size_ge=0;
uint32_t i=0;
uint32_t j=0;
//
usr_printf("BlankCheck adr:0x%x ,sz: 0x%x ,pat :0x%x \r\n",(uint32_t)adr,(uint32_t)sz,pat);
//
size_shi=sz/PAGE_SIZE;
//
size_ge =sz%PAGE_SIZE;
//
if(size_shi>0)
{
for(i=0;i<size_shi;i++)
{
QSPI_W25QXX_Read((uint8_t*)aux_buf, (adr-base_adr)+i*PAGE_SIZE, PAGE_SIZE);
//
for(j=0;j<PAGE_SIZE;j++)
{
if(aux_buf[j] != pat)
{
return 1;
}
}
}
}
//
if(size_ge>0)
{
QSPI_W25QXX_Read((uint8_t*)aux_buf, (adr-base_adr)+size_shi*PAGE_SIZE, size_ge);
//
for(j=0;j<size_ge;j++)
{
if(aux_buf[j] != pat)
{
return 1;
}
}
}
return 0;
}
//
#endif
/*
* 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)
{
uint32_t result=0;
uint32_t size_shi=0;
uint32_t size_ge=0;
uint32_t i=0;
uint8_t *pbuf=(uint8_t *)buf;
//
size_shi=sz/PAGE_SIZE;
//
size_ge =sz%PAGE_SIZE;
//
#if (EN_MDK_FLM_MAP>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#else
QSPI_W25QXX_Init(); //初始化W25QXX
#endif
//
SCB_CleanInvalidateDCache();
//
SCB_CleanDCache();
//
usr_printf("ProgramPage adr:0x%x ,sz: %ld ,buf :0x%x \r\n",(uint32_t)adr,sz,(uint32_t)pbuf);
//
if(adr>=base_adr)
{
if(size_shi>0)
{
for(i=0;i<size_shi;i++)
{
QSPI_W25QXX_Write((pbuf+i*PAGE_SIZE),(adr-base_adr)+i*PAGE_SIZE,PAGE_SIZE);
}
}
//
if(size_ge>0)
{
QSPI_W25QXX_Write((pbuf+size_shi*PAGE_SIZE), (adr-base_adr)+size_shi*PAGE_SIZE, size_ge);
}
//
}
// 内存映射
#if (EN_MDK_FLM_MAP>0)
result = QSPI_EnableMemoryMappedMode();
if(result != 0)
{
//
usr_printf("ProgramPage :%X\r\n",result);
//
return 1;
}
#endif
return (0);
}
/*
* Verify Flash Contents
* Parameter: adr: Start Address
* sz: Size (in bytes)
* buf: Data
* Return Value: (adr+sz) - OK, Failed Address
*/
#if (EN_MDK_FLM_VERIFY>0)
//
unsigned long Verify(unsigned long adr, unsigned long sz, unsigned char *buf)
{
volatile unsigned char *psrc=buf;
volatile unsigned long i;
uint32_t result=0;
uint32_t size_shi=0;
uint32_t size_ge=0;
uint32_t j=0;
uint8_t *pbuf=(uint8_t *)aux_buf;
//
size_shi=sz/PAGE_SIZE;
//
size_ge =sz%PAGE_SIZE;
//
#if (EN_MDK_FLM_MAP>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#else
QSPI_W25QXX_Init(); //初始化W25QXX
#endif
//
printf("start verify :0x%x ,0x%x,%d ,0x%x\r\n",(uint32_t)adr,(uint32_t)sz,(uint32_t)sz,(uint32_t)buf);
//
SCB_CleanInvalidateDCache();
//
SCB_CleanDCache();
//
if((sz> 0)&&(adr>=base_adr))
{
//
if(size_shi>0)
{
for(i=0;i<size_shi;i++)
{
//
memset((uint8_t*)pbuf,0,PAGE_SIZE);
//
QSPI_W25QXX_Read((pbuf),(adr-base_adr)+i*PAGE_SIZE,PAGE_SIZE);
//
for(j = 0; j< PAGE_SIZE; j++)
{
if(aux_buf[j] != psrc[j+i*PAGE_SIZE])
{
//
debug_log("erroffset:%d base addr:%x addr:%lx data--read:%x write:%x\r\n",
(uint32_t)(j+i*PAGE_SIZE),base_adr,adr,aux_buf[j],psrc[j+i*PAGE_SIZE]);
//
return (adr+j+i*PAGE_SIZE);
}
}
}
}
//
if(size_ge>0)
{
//
memset((uint8_t*)pbuf,0,PAGE_SIZE);
//
QSPI_W25QXX_Read((pbuf+size_shi*PAGE_SIZE), (adr-base_adr)+size_shi*PAGE_SIZE, size_ge);
//
for(j = 0; j< size_ge; j++)
{
if(aux_buf[j] != psrc[j+size_shi*PAGE_SIZE])
{
//
debug_log("erroffset:%d base addr:%x addr:%lx data--read:%x write:%x\r\n",
(uint32_t)(j+size_shi*PAGE_SIZE),base_adr,adr,aux_buf[j],psrc[j+size_shi*PAGE_SIZE]);
//
return (adr+j+size_shi*PAGE_SIZE);
}
}
}
//
return (adr+sz);
}
else
{
// 内存映射
#if (EN_MDK_FLM_MAP>0)
result = QSPI_EnableMemoryMappedMode();
if(result != 0)
{
//
usr_printf("Verify3 :%X\r\n",result);
//
return (adr);
}
#endif
return (adr);
}
}
//
#endif
/*
*********************************************************************************************************
*********************************************************************************************************
*/
//
// SEGGER defined functions
//
int SEGGER_OPEN_Read(unsigned long Addr, unsigned long NumBytes, unsigned char *pDestBuff)
{
uint32_t result=0;
//
#if (EN_MDK_FLM_MAP>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#else
QSPI_W25QXX_Init(); //初始化W25QXX
#endif
//
SCB_CleanInvalidateDCache();
//
SCB_CleanDCache();
//
usr_printf("SEGGER_OPEN_Read adr:0x%x ,sz: 0x%x ,buf :0x%x \r\n",(uint32_t)Addr,NumBytes,(uint32_t)pDestBuff);
//
if(Addr>=base_adr)
{
QSPI_W25QXX_Read(pDestBuff,(Addr-base_adr),NumBytes);
}
// 内存映射
#if (EN_MDK_FLM_MAP>0)
result = QSPI_EnableMemoryMappedMode();
if(result != 0)
{
//
usr_printf("SEGGER_OPEN_Read :%X\r\n",result);
//
return 0;
}
#endif
return NumBytes;
}
/*
*********************************************************************************************************
*********************************************************************************************************
*/
int SEGGER_OPEN_Program(unsigned long DestAddr, unsigned long NumBytes, unsigned char *pSrcBuff)
{
uint32_t result=0;
uint32_t size_shi=0;
uint32_t size_ge=0;
uint32_t i=0;
uint8_t *pbuf=(uint8_t *)pSrcBuff;
//
size_shi=NumBytes/PAGE_SIZE;
//
size_ge =NumBytes%PAGE_SIZE;
//
#if (EN_MDK_FLM_MAP>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#else
QSPI_W25QXX_Init(); //初始化W25QXX
#endif
//
SCB_CleanInvalidateDCache();
//
SCB_CleanDCache();
//
usr_printf("SEGGER_OPEN_Program adr:0x%x ,sz: %ld ,buf :0x%x \r\n",(uint32_t)DestAddr,NumBytes,(uint32_t)pbuf);
//
if(DestAddr>=base_adr)
{
if(size_shi>0)
{
for(i=0;i<size_shi;i++)
{
QSPI_W25QXX_Write((pbuf+i*PAGE_SIZE),(DestAddr-base_adr)+i*PAGE_SIZE,PAGE_SIZE);
}
}
//
if(size_ge>0)
{
QSPI_W25QXX_Write((pbuf+size_shi*PAGE_SIZE), (DestAddr-base_adr)+size_shi*PAGE_SIZE, size_ge);
}
//
}
//
usr_printf("\r\nSEGGER_OPEN_Program finish \r\n");
//
// 内存映射
#if (EN_MDK_FLM_MAP>0)
result = QSPI_EnableMemoryMappedMode();
if(result != 0)
{
//
usr_printf("SEGGER_OPEN_Program :%X\r\n",result);
//
return 1;
}
#endif
return (0);
}
/*
*********************************************************************************************************
*********************************************************************************************************
*/
int SEGGER_OPEN_Erase(unsigned long SectorAddr, unsigned long SectorIndex, unsigned long NumSectors)
{
uint32_t result=0;
//
#if (EN_MDK_FLM_MAP>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)
Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhz
uart_init(400,DEBUG_BAUD_RATE);
QSPI_W25QXX_Init(); //初始化W25QXX
#else
QSPI_W25QXX_Init(); //初始化W25QXX
#endif
//
usr_printf("SEGGER_OPEN_Erase adr:0x%x ,SectorIndex: %ld ,NumSectors :%d \r\n",(uint32_t)SectorAddr,SectorIndex,(uint32_t)NumSectors);
//
do{
//
if(SectorAddr>=base_adr)
{
QSPI_W25QXX_Erase_Sector(SectorAddr-base_adr);
}
//
SectorAddr += QSPI_SECTOR_SIZE;
//
SectorIndex++;
//
} while (--NumSectors);
//
// 内存映射
#if (EN_MDK_FLM_MAP>0)
result = QSPI_EnableMemoryMappedMode();
if(result != 0)
{
//
usr_printf("EraseSector :%X\r\n",result);
//
return 1;
}
#endif
return (0);
}
/*
*********************************************************************************************************
*********************************************************************************************************
*/
#endif
/*
*********************************************************************************************************
*********************************************************************************************************
*/