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 nameNOR_FLASH,                                     // Device TypeQSPI_ADDR_BASE,                                       // Device Start Address32*1024*1024,                                        // Device Size in Bytes (32MBytes)0x100,                                            // Programming Page Size 256Bytes0xFF,                                              // Initial Content of Erased Memory
// Specify Size and Address of Sectors (view example below)0x00002000, 0x00001000,                          // Sector Num : 8192 ,Sector Size: 4KBytes0x00000000, 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 typesstruct DeviceSectors
{unsigned long      SectorNum;     // Number of Sectorsunsigned long        SectorSize;    // Sector Size in Bytes
};struct StorageInfo
{char           DeviceName[100];            // Device Name and Descriptionunsigned short DeviceType;                // Device Type: ONCHIP, EXT8BIT, EXT16BIT, ...unsigned long  DeviceStartAddress;        // Default Device Start Addressunsigned long  DeviceSize;               // Total Size of Deviceunsigned long  PageSize;                 // Programming Page Sizeunsigned char  EraseValue;              // Content of Erased Memorystruct     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 bytesU32 SectorStartAddr;  // Start address of the sector area (relative to the "BaseAddr" of the flash)
};struct FlashDevice {U16 AlgoVer;       // Algo version numberU8  Name[128];     // Flash device nameU16 Type;          // Flash device typeU32 BaseAddr;      // Flash base addressU32 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 byteU32 Reserved;      // Reserved, should be 0U8  ErasedVal;     // Flash erased valueU32 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 Programmingstruct FlashSectors  {unsigned long   szSector;    // Sector Size in Bytesunsigned long AddrSector;    // Address of Sector
};#define SECTOR_END 0xFFFFFFFF, 0xFFFFFFFFstruct FlashDevice  {unsigned short     Vers;    // Version Number and Architecturechar       DevName[128];    // Device Name and Descriptionunsigned short  DevType;    // Device Type: ONCHIP, EXT8BIT, EXT16BIT, ...unsigned long    DevAdr;    // Default Device Start Addressunsigned long     szDev;    // Total Size of Deviceunsigned long    szPage;    // Programming Page Sizeunsigned long       Res;    // Reserved for future Extensionunsigned char  valEmpty;    // Content of Erased Memoryunsigned long    toProg;    // Time Out of Program Page Functionunsigned long   toErase;    // Time Out of Erase Sector Functionstruct 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 Flashunsigned long clk,unsigned long fnc);
extern          int  UnInit      (unsigned long fnc);  // De-initialize Flash
extern          int  BlankCheck  (unsigned long adr,   // Blank Checkunsigned 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 Functionunsigned long sz,unsigned char *buf);
extern unsigned long Verify      (unsigned long adr,   // Verify Functionunsigned 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 nameONCHIP,                   // Flash device typeQSPI_ADDR_BASE,               // Flash base address0x00800000,               // Total flash device size in Bytes (256 KB)4096,                     // Page Size (number of bytes that will be passed to ProgramPage(). MinAlig is 8 byte0,                        // Reserved, should be 00xFF,                     // Flash erased value1000,                    // Program page timeout in ms6000,                    // Erase sector timeout in ms//// Flash sector layout definition0x001000, 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 NameEXTSPI,                     // Device TypeQSPI_ADDR_BASE,                 // Device Start Address0x02000000,                 // Device Size (32MB)4096,                       // Programming Page Size0,                          // Reserved, must be 00xFF,                       // Initial Content of Erased Memory10000,                       // Program Page Timeout 300 mSec30000,                       // Erase Sector Timeout 3000 mSec// Specify Size and Address of Sectors0x001000, 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 NameEXTSPI,                     // Device TypeQSPI_ADDR_BASE,                 // Device Start Address0x01000000,                 // Device Size (16MB)4096,                       // Programming Page Size0,                          // Reserved, must be 00xFF,                       // Initial Content of Erased Memory10000,                       // Program Page Timeout 300 mSec30000,                       // Erase Sector Timeout 3000 mSec// Specify Size and Address of Sectors0x001000, 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 NameEXTSPI,                     // Device TypeQSPI_ADDR_BASE,                 // Device Start Address0x00800000,                 // Device Size (8MB)4096,                       // Programming Page Size0,                          // Reserved, must be 00xFF,                       // Initial Content of Erased Memory10000,                       // Program Page Timeout 300 mSec30000,                       // Erase Sector Timeout 3000 mSec// Specify Size and Address of Sectors0x001000, 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);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elseQSPI_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);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elseQSPI_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);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elseQSPI_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;}
#endifreturn (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);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elseQSPI_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;}
#endifreturn (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);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elseQSPI_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);}
#endifreturn (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);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elseQSPI_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;}
#endifreturn 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);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elseQSPI_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;}
#endifreturn (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);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elseQSPI_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;}
#endifreturn (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);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elseQSPI_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);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elseQSPI_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);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elseQSPI_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;}
#endifreturn (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);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elseQSPI_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;}
#endifreturn (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);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elseQSPI_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);}
#endifreturn (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);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elseQSPI_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;}
#endifreturn 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);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elseQSPI_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;}
#endifreturn (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);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elif (MDK_FLM_INIT_EN>0)Stm32_Clock_Init(5,160,2,2,2);//设置时钟,400Mhzuart_init(400,DEBUG_BAUD_RATE);QSPI_W25QXX_Init();                 //初始化W25QXX
#elseQSPI_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;}
#endifreturn (0);
}
/*
******************************************************************************************************************************************************************************************************************
*/
#endif
/*
******************************************************************************************************************************************************************************************************************
*/

stm32外挂spiflash的烧录算法相关推荐

  1. STM32外挂FLASH模拟U盘(基于HAL库)

    STM32外挂FLASH模拟U盘(基于HAL库) 1.背景 1.1这篇文章能给你带来什么 1.2根据你要解决的问题,精确快速跳转到相应位置 1.3我在做完这个后还有不明白的地方,希望能有大触解答困惑 ...

  2. 单片机搭建环境烧录方法_万物互联-stm32单片机简介、烧录、编程及其项目环境搭建...

    万物互联-stm32单片机简介.烧录.编程 前言:stm32单片机这里给出简单介绍,给不了解的朋友普及下硬件端的基本知识,叙述的较为简单,想深入研究的朋友可以去一些官方网站.论坛.博客汲取知识.最下端 ...

  3. STM32用SWD口烧录程序导致锁死

    STM32用SWD口烧录程序导致锁死 SWD接口是四根线VCC,GND,SCK,DIO SCK是PA14 DIO是PA13 我在程序中用到了PA13,导致程序第一次能烧录进去,第二次就不可以烧录. 解 ...

  4. 我的第一篇文章——stm32的ADC+DMA+滤波算法

    stm32的ADC+DMA+滤波算法 一 工程目的 (1)外设配置 (2)源码 头文件 主文件 二 调试过程遇到的问题 1 如果打开中断 2 无法打开ADC 3 变量无法赋值 三 参考资料 四 写在最 ...

  5. 单片机 stm32 差分升级 增量升级算法源码, 纯c编写跨平因为是程序源码

    单片机 stm32 差分升级 增量升级算法源码, 纯c编写跨平因为是程序源码 IAP升级 OTA升级 物联网 车联网 适用 YID:83500653978935134Deflag

  6. 单片机 stm32 差分升级 增量升级算法源码,纯c编写跨平因为是程序源码

    单片机 stm32 差分升级 增量升级算法源码,纯c编写跨平因为是程序源码 IAP升级 OTA升级 物联网 车联网 适用 现有:69500653978935134Deflag

  7. 单片机 stm32 差分升级 增量升级算法源码,提供移植 纯c编写跨平因为是程序源码

    单片机 stm32 差分升级 增量升级算法源码,提供移植 纯c编写跨平因为是程序源码 IAP升级 OTA升级 物联网 车联网 适用 YID:83500653978935134Deflag

  8. 单片机 stm32 差分升级 增量升级算法源码

    单片机 stm32 差分升级 增量升级算法源码,提供移植 纯c编写跨平因为是程序源码 IAP升级 OTA升级 物联网 车联网 适用 YID:83500653978935134Deflag

  9. STM32 STM8 GD32 脱机烧录器 ,

    stm32 SWD模式脱机烧录器,有需要的看看 https://download.csdn.net/download/li880wert/11119094 用的STM32F103C8T6  或STLI ...

最新文章

  1. R语言使用ggplot2包和ggQC包可视化帕累托图(Pareto chart)
  2. 「行业趋势」人工智能凭什么“教育”人
  3. 第8章 基本UDP套接口编程
  4. c语言 元组顺序随机化,为什么关系中的元组没有先后顺序且不允许有重复元组?...
  5. matchers依赖_Hamcrest Matchers,Guava谓词和Builder设计模式
  6. 用户输入一个字符串,将下标为偶数的字符提出来合并成一个新的字符串A,再将下标为奇数的字符提出来合并成一个新的字符串B,再将字符串A和B连接起来并输出。
  7. 【华为云技术分享】GitHub联合开发
  8. wps二次开发无法创建对象wps.application的解决方案
  9. 主板没有rgb接口怎么接灯_电脑硬件第六期,关于主板的那点破事。
  10. java简单小程序 生日快乐,微信生日祝福小程序,要一个祝朋友生日快乐的VB小程序。...
  11. NotifyIcon的属性、事件、方法
  12. java两个字符串的重复率检查
  13. threejs的点光源+环境光
  14. P7369 [COCI2018-2019#4] Elder 题解
  15. 不用刷新,用 dfuse 流式搜索提供即时用户体验
  16. treeset可以重复吗_买了好几份意外险,可以重复理赔吗?
  17. Java笔试面试(社招版)
  18. 安装PHPStudy(小皮)V8.1最详细安装教程
  19. java 高内聚低耦合_高内聚低耦合法则实例解析
  20. PCI - PCI概述

热门文章

  1. 2018百度之星大赛游记
  2. 提高个税起征点可增加工薪层可支配收入
  3. ROOK-01 集群简单搭建和卸载
  4. 物联网主流技术及其应用场景分析
  5. cmos和ccd区别对比
  6. android10全面屏手势 操作图,全面屏手势浪潮来临?安卓Q测试版新发现,手势操作十分便捷...
  7. 粗识 HTML5 video 标签和MSE媒体源扩展
  8. 51单片机wr和rd的作用
  9. 用批处理删除指定字符之前或之后的所有内容(FOR /F 中的Delims和Tokens总结)
  10. 程序员学英语——In November the English learning summary