里飞网
标题:
MDK下载算法-W25Q256
[打印本页]
作者:
阿里兄
时间:
2019-12-25 17:48
标题:
MDK下载算法-W25Q256
本帖最后由 阿里兄 于 2019-12-25 17:50 编辑
MDK下载算法-W25Q256
参考了正点原子
说在前面:
1、下载算法就是把固件通过用户提供的读、写、擦除函数写到指定的地址处。
2、QSPI的映射地址是0x90000000,而W25Q256的地址是从0开始,而下载算法提供的地址是用户工程设置的IROM地址如0x90000000,读、写、擦除函数都要减去此偏移地址。
3、下载完成后需复位W25Q256芯片,在UnInit加入复位函数,如不加,在下载完成后读到全是0x88,也不能在线仿真,需要断电才能正确使用,这个问题坑了我两天。
4、如果下载出现 insufficient RAM for Flash Algorithms.则加大设置的烧写下载设置里面 : Project->Options->Utilities->...Settings->“RAM for Algorithm ” size = 0x8000 <--加大这个。
5、如下载后验证不通过,则取消校验,Project->Options->Utilities->...Settings,取消Verify前面的勾。
6、下载完成后,只是把固件下载到了W25Q256里面,而不能马上运行,这是因为STM32上电或复位后还是跑到0x8000000地址处执行。
7、想在W25Q256上运行程序,需增加Bootloader,即在内部FLASH增加程序跳转,跳转前需把QSPI设置为内存映射模式。
struct FlashDevice const FlashDevice = {
FLASH_DRV_VERS, // Driver Version, do not modify!
"STM32F750_W25Q256_lfly", // Device Name
EXTSPI, // Device Type
0x90000000, // Device Start Address
0x02000000, // Device Size (32MB)
4096, // Programming Page Size
0, // Reserved, must be 0
0xFF, // Initial Content of Erased Memory
1000, // Program Page Timeout 300 mSec
3000, // Erase Sector Timeout 3000 mSec
// Specify Size and Address of Sectors
0x001000, 0x000000, // Sector Size 4kB (8192 Sectors)
SECTOR_END
};
复制代码
/* -----------------------------------------------------------------------------
* 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 "delay.h"
#include "w25qxx.h"
#include "qspi.h"
#include "mpu.h"
#define PAGE_SIZE 4096
/*
* 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
*/
uint8_t aux_buf[PAGE_SIZE];
uint32_t base_adr;
//这个函数在keil下载后,在擦除、编程都会重新调用一次此函数,而且在调用此函数之前keil会复位单片机,相当于单片机跑起来的初始化功能要在擦除、编程时都要初始化一遍
int Init (unsigned long adr, unsigned long clk, unsigned long fnc) {
//MPU_Memory_Protection(); //保护相关存储区域
Stm32_Clock_Init(432,25,2,9);//设置时钟,216Mhz
delay_init(216); //延时初始化
W25QXX_Init(); //初始化W25QXX
base_adr = adr;
return (0);
}
/*
* De-Initialize Flash Programming Functions
* Parameter: fnc: Function Code (1 - Erase, 2 - Program, 3 - Verify)
* Return Value: 0 - OK, 1 - Failed
*/
int UnInit (unsigned long fnc) {
W25QXX_Reset();
return (0);
}
/*
* Erase complete Flash Memory
* Return Value: 0 - OK, 1 - Failed
*/
int EraseChip (void) {
W25QXX_Erase_Chip();
return (0); /* Finished without Errors */
}
/*
* Erase Sector in Flash Memory
* Parameter: adr: Sector Address
* Return Value: 0 - OK, 1 - Failed
*/
int EraseSector (unsigned long adr) {
W25QXX_Erase_Sector((adr-base_adr)/4096);
return (0); /* Finished without Errors */
}
/*
* Blank Check Checks if Memory is Blank
* Parameter: adr: Block Start Address
* sz: Block Size (in bytes)
* pat: Block Pattern
* Return Value: 0 - OK, 1 - Failed
*/
int BlankCheck (unsigned long adr, unsigned long sz, unsigned char pat) {
return (1); /* Always Force Erase */
}
/*
* Program Page in Flash Memory
* Parameter: adr: Page Start Address
* sz: Page Size
* buf: Page Data
* Return Value: 0 - OK, 1 - Failed
*/
int ProgramPage (unsigned long adr, unsigned long sz, unsigned char *buf) {
W25QXX_Write_NoCheck(buf,adr-base_adr,sz);
return (0); /* Finished without Errors */
}
/*
* Verify Flash Contents
* Parameter: adr: Start Address
* sz: Size (in bytes)
* buf: Data
* Return Value: (adr+sz) - OK, Failed Address
*/
/*
Verify function is obsolete because all other function leave
the SPIFI in memory mode so a memory compare could be used.
*/
unsigned long Verify (unsigned long adr, unsigned long sz, unsigned char *buf) {
int i;
W25QXX_Read(aux_buf, adr-base_adr, sz);
for (i = 0; i< PAGE_SIZE; i++)
{
if (aux_buf[i] != buf[i])
return (adr+i); // Verification Failed (return address)
}
return (adr+sz); // Done successfully
}
复制代码
欢迎光临 里飞网 (http://dz.lfly.xyz/)
Powered by Discuz! X3.3