在线时间215 小时
UID329220
注册时间2016-3-7
NXP金币0
TA的每日心情 | 开心 2018-6-6 08:45 |
---|
签到天数: 328 天 连续签到: 1 天 [LV.8]以坛为家I
金牌会员
 
- 积分
- 2006
- 最后登录
- 2019-5-1
|
本帖最后由 anobodykey 于 2017-8-30 21:58 编辑
根据LPC54608的外部FLASH编程算法工程修改而来,放入到keil5\ARM\Flash目录下即可,编译后生成LPC54114_W25P80.FLM,测试可用,欢迎下载测试。
放一些知识点:
LPC54114板卡资源是片上256KB的FLASH,以及192KB的SRAM,平时我们在编辑代码生成的固件一般都是直接下载到片内256KB的FLASH中,但有时我们想要把一些数据放到外部FLASH中以便节省内部FLASH空间,即把代码和数据分开存储,这里就是实现该功能。平时我们是如何把代码通过调试器下载到片内FLASH中呢?在Debug Setting中有一个FLASH Download选项卡,如下:
其中下面的编程算法中我们加载的是LPC5411x_IAP 256KB Flash算法,该算法由MDK的DFP包提供,具体在以下路径中
其中有算法文件FLM以及算法的相应源文件,正是由于该算法的存在,才使得我们能够通过调试器把代码下载到板卡中。
现在我们需要把数据烧录到外部FLASH中,同样需要这样一个算法文件,但很可惜MDK并没有给出LPC54114板卡的烧录外部FLASH算法文件,但是有一个LPC54608板卡的外部FLASH算法文件,如下:
其中LPC5460x_MT25QL128 SPIFI即是。不要意外上面的LPC54114 W25P80 SPI算法文件是我们自己生成的。在MDK的安装目录中有一个Flash路径,存放了各种FLASH的算法文件,我们只需要找到跟我们板卡 相近的工程文件修改一下即可,这里就是使用的LPC5460x_MT25QL128工程文件,拷贝一份该工程并命名为LPC54114 W25P80,并把其中跟LPC54608相关的宏都替换成LPC54114,并从LPC54114的SDK中拷贝出我们需要的库文件
由于LPC54114SDK中有spi flash的相关代码,这里我直接拷贝的driver_examples\spi\polling_flash工程中的mx25r_flash.c/h文件,我们需要关注的核心文件只有两个:FlashDev.c以及FlashPrg.c,前者定义了外部FLASH的相关信息,如下:
- #include "..\FlashOS.H" // FlashOS Structures
- #ifdef W25P80
- struct FlashDevice const FlashDevice = {
- FLASH_DRV_VERS, // Driver Version, do not modify!
- "LPC54114 W25P80 SPI", // Device Name
- EXTSPI, // Device Type
- 0x10000000, // Device Start Address
- 0x00100000, // Device Size (1MB)
- 256, // Programming Page Size
- 0, // Reserved, must be 0
- 0xFF, // Initial Content of Erased Memory
- 300, // Program Page Timeout 300 mSec
- 3000, // Erase Sector Timeout 3000 mSec
- // Specify Size and Address of Sectors
- 0x010000, 0x000000, // Sector Size 64kB (16 Sectors)
- SECTOR_END
- };
- #endif
复制代码 其中flashos.h头文件是ARM提供的,其定义了编程flash的相关接口,以及flash的定义。该结构体所需要的相关信息都可以从W25P80手册中找到,设备的起始地址由我们随意指定,但不能和片内FLASH地址冲突,这里定义的是0x10000000,大小为0x00100000,页大小为256字节,扇区大小为64KB。再来看flashprg.c文件,该文件实现了flashos.h定义的相关接口,我们需要实现以下接口
- // 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);
复制代码 在FlashPrg.c文件中我们直接调用mx25r_flash的相关接口即可。
- /* -----------------------------------------------------------------------------
- * 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: 29. August 2017
- * $Revision: V1.0.0
- *
- * Project: Flash Device Algorithm for
- * NXP LPC54114 W25P80 SPI Flash
- * --------------------------------------------------------------------------- */
- #include "..\FlashOS.H" // FlashOS Structures
- #include "fsl_iocon.h"
- #include "fsl_spi.h"
- #include "mx25r_flash.h"
- #define SECTOR_ADDR 0
- #define SECTOR_SIZE 65536
- #define FLASH_SPI_SSEL 3
- #define EXAMPLE_SPI_MASTER SPI2
- #define EXAMPLE_SPI_MASTER_CLK_SRC kCLOCK_Flexcomm2
- #define EXAMPLE_SPI_MASTER_CLK_FREQ 12000000
- unsigned long base_adr;
- unsigned char chk_buf[256];
- struct mx25r_instance mx25r;
- void SPI_InitPins(void) {
- CLOCK_EnableClock(kCLOCK_Iocon); /* enable clock for IOCON */
-
- /* SPI pins */
- IOCON_PinMuxSet(IOCON, 0, 8, (IOCON_FUNC1 | IOCON_MODE_PULLUP | IOCON_DIGITAL_EN)); /* SPI_MOSI */
- IOCON_PinMuxSet(IOCON, 0, 9, (IOCON_FUNC1 | IOCON_MODE_PULLUP | IOCON_DIGITAL_EN)); /* SPI_MISO */
- IOCON_PinMuxSet(IOCON, 0, 10, (IOCON_FUNC1 | IOCON_MODE_PULLUP | IOCON_DIGITAL_EN)); /* SPI_SCK */
- IOCON_PinMuxSet(IOCON, 0, 2, (IOCON_FUNC2 | IOCON_MODE_PULLUP | IOCON_DIGITAL_EN)); /* SPI_CSN */
- }
- int flash_transfer_cb(void *transfer_prv, uint8_t *tx_data, uint8_t *rx_data, size_t dataSize, bool eof)
- {
- spi_transfer_t xfer = {0};
- xfer.txData = tx_data;
- xfer.rxData = rx_data;
- xfer.dataSize = dataSize;
- /* terminate frame */
- if (eof)
- {
- xfer.configFlags |= kSPI_FrameAssert;
- }
- SPI_MasterTransferBlocking((SPI_Type *)transfer_prv, &xfer);
- return 0;
- }
- int flash_init(void)
- {
- spi_master_config_t masterConfig = {0};
- SPI_MasterGetDefaultConfig(&masterConfig);
- masterConfig.direction = kSPI_MsbFirst;
- masterConfig.polarity = kSPI_ClockPolarityActiveHigh;
- masterConfig.phase = kSPI_ClockPhaseFirstEdge;
- masterConfig.baudRate_Bps = 1000000;
- masterConfig.sselNum = (spi_ssel_t)FLASH_SPI_SSEL;
- SPI_MasterInit(EXAMPLE_SPI_MASTER, &masterConfig, EXAMPLE_SPI_MASTER_CLK_FREQ);
- mx25r_init(&mx25r, flash_transfer_cb, EXAMPLE_SPI_MASTER);
- return mx25r_err_ok;
- }
- /*
- * 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
- */
- int Init (unsigned long adr, unsigned long clk, unsigned long fnc) {
-
- SYSCON->FXCOMCLKSEL[2] = 0;
- /* reset FLEXCOMM for SPI */
- SYSCON->PRESETCTRLSET[1] = (uint32_t)(1<<13);
- SYSCON->PRESETCTRLCLR[1] = (uint32_t)(1<<13);
-
- SPI_InitPins();
- flash_init();
- base_adr = adr;
- return (0);
- }
- /*
- * De-Initialize Flash Programming Functions
- * Parameter: fnc: Function Code (1 - Erase, 2 - Program, 3 - Verify)
- * Return Value: 0 - OK, 1 - Failed
- */
- int UnInit (unsigned long fnc) {
- return (0);
- }
- /*
- * Erase complete Flash Memory
- * Return Value: 0 - OK, 1 - Failed
- */
- int EraseChip (void) {
- mx25r_cmd_chip_erase(&mx25r);
- 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) {
- mx25r_cmd_sector_erase(&mx25r,adr-base_adr);
- 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) {
-
- mx25r_cmd_write(&mx25r,adr-base_adr,buf,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
- */
- unsigned long Verify (unsigned long adr, unsigned long sz, unsigned char *buf)
- {
- int i = 0;
- mx25r_cmd_read(&mx25r,adr-base_adr,chk_buf,sz);
- for(i = 0; i < sz; i++)
- {
- if(buf[i] != chk_buf[i])
- {
- return (adr+i);
- }
- }
- return (adr+sz);
- }
复制代码 为了避免使用过多的库文件,时钟那块直接使用的寄存器操作。整个实现还是很简单的。编译工程即可生成我们所需的LPC54114 W25P80 FLASH算法文件,下面我们来测试一下该算法文件是否起作用,在polling flash工程的基础上增加一小段代码来测试,如下:
- const uint8_t extFlash[] __attribute__ ((at(0x10000000))) =
- {'N','X','P','I','C'};
复制代码 指定extFlash数组存放在0x10000000地址,该地址就是我们之前定义的外部FLASH的起始地址,其他地方无需改动,在debug选项卡中添加我们生成的算法文件,如下:
点击下载,本以为就此成功了,结果弹出框框说下载失败,说无法加载算法文件,MDK输出信息:Insufficient RAM for Flash Algorithms !,经过百度说是RAM空间分配不够,上图默认的4KB RAM,于是乎改成8KB。
再来下载即可成功,赶紧打开串口终端,
可以看到已经读取出了我们之前存放的‘NXPIC’字符信息。测试成功!
|
|