主机环境:Windows 10 64bit
开发环境:MDK 5.23
目标板:LPC54114
之前在NXP社区得到一块LPC54114的板卡,是由万利制作的,LPC54114是一款双核MCU,包含了一颗M4主核和一颗M0+从核,利用该板卡学习了一下双核MCU的开发流程,板卡中提供了一颗W25P80FLASH,之前拥有的板卡都没有挂外部FLASH,刚好之前利用LPC54608学习TouchGFX时可以把图片资源下载到外部FLASH中,因此借此机会来学习一下如何把数据下载到外部FLASH。
平时烧录代码我们都是烧录到MCU内部的FLASH中,如下图:
可以看到下载的时片上256KB的FLASH,该算法文件是由DFP包提供的,具体可以在keil5的安装目录下找到,如下:
加载到内部FLASH的算法有了,但加载到外部FLASH的算法还没得。keil5中提供了LPC54608板卡的外部FLASH算法,LPC54114的外部FLASH算法就需要我们自己实现了,而且我们的板卡不是NXP官方的板卡,更不可能提供外部FLASH的加载算法了。。。
进入到keil的FLASH目录,如下:
拷贝LPC5460x_MT25QL128文件夹到LPC54114_W25P80文件夹,并把其中有关信息全部替换成LPC54114相关信息。keil中提供了FlashOS.h头文件,定义了烧录到外部FLASH的相关接口,很简单,如下:
这就是本次我们需要实现的相关接口,修改的关键文件只有两个:FlashDev.c以及FlashPrg.c,首先看FlashDev.c文件,该文件定义了外部Flash的相关信息,经过简单修改就可以使用了,如下:
- #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
- /* -----------------------------------------------------------------------------
- * 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的SDK中的polling_flash工程中加入一段测试数据,如下:
- const uint8_t extFlash[] __attribute__ ((at(0x10000000))) =
- {'N','X','P','I','C'};
下载该代码,本以为就此成功了,结果弹出一个框框,说无法加载FLASH编程算法,
MDK中的输出信息如下:Insufficient RAM for Flash Algorithms !,百度搜索了一下说是为该算法分配的RAM空间小了,默认的是0x1000,4KB大小,这里加大了已被改成了8KB,如下:
再次下载,很顺畅地下载成功了,赶紧打开串口助手查看测试结果:
成功地从外部FLASH读取到了我们定义的‘NXPIC’字符,测试成功!大家一起来测试一下吧!
工程文件:http://download.csdn.net/download/key123zhangxing/9956278