This commit is contained in:
Lok Tep 2015-12-01 23:09:31 +01:00
parent 9a527ad3ed
commit fd74d0b625
15 changed files with 4404 additions and 35 deletions

View File

@ -178,3 +178,4 @@ CHIP_CSRCS += lpc43_usb0dev.c
endif
endif
include chip/spifi/src/Make.defs

View File

@ -574,28 +574,28 @@
# define BASE_PHYTX_CLKSEL_IDIVD (15 << BASE_PHYTX_CLK_CLKSEL_SHIFT) /* IDIVD */
# define BASE_PHYTX_CLKSEL_IDIVE (16 << BASE_PHYTX_CLK_CLKSEL_SHIFT) /* IDIVE */
/* Bits 29-31: Reserved */
/* Output stage 9 control register (BASE_APB1_CLK) */
/* Output stage 9 control register (BASE_APB1_CLK, BASE_APB3_CLK) */
/* NOTE: Clocks 4-19 are identical */
#define BASE_APB1_CLK_PD (1 << 0) /* Bit 0: Output stage power down */
#define BASE_APB_CLK_PD (1 << 0) /* Bit 0: Output stage power down */
/* Bits 1-10: Reserved */
#define BASE_APB1_CLK_AUTOBLOCK (1 << 11) /* Bit 11: Block clock during frequency change */
#define BASE_APB_CLK_AUTOBLOCK (1 << 11) /* Bit 11: Block clock during frequency change */
/* Bits 12-23: Reserved */
#define BASE_APB1_CLK_CLKSEL_SHIFT (24) /* Bits 24-28: Clock source selection */
#define BASE_APB1_CLK_CLKSEL_MASK (31 << BASE_APB1_CLK_CLKSEL_SHIFT)
# define BASE_APB1_CLKSEL_32KHZOSC (0 << BASE_APB1_CLK_CLKSEL_SHIFT) /* 32 kHz oscillator */
# define BASE_APB1_CLKSEL_IRC (1 << BASE_APB1_CLK_CLKSEL_SHIFT) /* IRC (default) */
# define BASE_APB1_CLKSEL_ENET_RXCLK (2 << BASE_APB1_CLK_CLKSEL_SHIFT) /* ENET_RX_CLK */
# define BASE_APB1_CLKSEL_ENET_TXCLK (3 << BASE_APB1_CLK_CLKSEL_SHIFT) /* ENET_TX_CLK */
# define BASE_APB1_CLKSEL_GPCLKIN (4 << BASE_APB1_CLK_CLKSEL_SHIFT) /* GP_CLKIN */
# define BASE_APB1_CLKSEL_XTAL (6 << BASE_APB1_CLK_CLKSEL_SHIFT) /* Crystal oscillator */
# define BASE_APB1_CLKSEL_PLL0AUDIO (8 << BASE_APB1_CLK_CLKSEL_SHIFT) /* PLL0AUDIO */
# define BASE_APB1_CLKSEL_PLL1 (9 << BASE_APB1_CLK_CLKSEL_SHIFT) /* PLL1 */
# define BASE_APB1_CLKSEL_IDIVA (12 << BASE_APB1_CLK_CLKSEL_SHIFT) /* IDIVA */
# define BASE_APB1_CLKSEL_IDIVB (13 << BASE_APB1_CLK_CLKSEL_SHIFT) /* IDIVB */
# define BASE_APB1_CLKSEL_IDIVC (14 << BASE_APB1_CLK_CLKSEL_SHIFT) /* IDIVC */
# define BASE_APB1_CLKSEL_IDIVD (15 << BASE_APB1_CLK_CLKSEL_SHIFT) /* IDIVD */
# define BASE_APB1_CLKSEL_IDIVE (16 << BASE_APB1_CLK_CLKSEL_SHIFT) /* IDIVE */
#define BASE_APB_CLK_CLKSEL_SHIFT (24) /* Bits 24-28: Clock source selection */
#define BASE_APB_CLK_CLKSEL_MASK (31 << BASE_APB_CLK_CLKSEL_SHIFT)
# define BASE_APB_CLKSEL_32KHZOSC (0 << BASE_APB_CLK_CLKSEL_SHIFT) /* 32 kHz oscillator */
# define BASE_APB_CLKSEL_IRC (1 << BASE_APB_CLK_CLKSEL_SHIFT) /* IRC (default) */
# define BASE_APB_CLKSEL_ENET_RXCLK (2 << BASE_APB_CLK_CLKSEL_SHIFT) /* ENET_RX_CLK */
# define BASE_APB_CLKSEL_ENET_TXCLK (3 << BASE_APB_CLK_CLKSEL_SHIFT) /* ENET_TX_CLK */
# define BASE_APB_CLKSEL_GPCLKIN (4 << BASE_APB_CLK_CLKSEL_SHIFT) /* GP_CLKIN */
# define BASE_APB_CLKSEL_XTAL (6 << BASE_APB_CLK_CLKSEL_SHIFT) /* Crystal oscillator */
# define BASE_APB_CLKSEL_PLL0AUDIO (8 << BASE_APB_CLK_CLKSEL_SHIFT) /* PLL0AUDIO */
# define BASE_APB_CLKSEL_PLL1 (9 << BASE_APB_CLK_CLKSEL_SHIFT) /* PLL1 */
# define BASE_APB_CLKSEL_IDIVA (12 << BASE_APB_CLK_CLKSEL_SHIFT) /* IDIVA */
# define BASE_APB_CLKSEL_IDIVB (13 << BASE_APB_CLK_CLKSEL_SHIFT) /* IDIVB */
# define BASE_APB_CLKSEL_IDIVC (14 << BASE_APB_CLK_CLKSEL_SHIFT) /* IDIVC */
# define BASE_APB_CLKSEL_IDIVD (15 << BASE_APB_CLK_CLKSEL_SHIFT) /* IDIVD */
# define BASE_APB_CLKSEL_IDIVE (16 << BASE_APB_CLK_CLKSEL_SHIFT) /* IDIVE */
/* Bits 29-31: Reserved */
/* Output stage 11 control register (BASE_LCD_CLK) */
/* NOTE: Clocks 4-19 are identical */

View File

@ -44,18 +44,11 @@
#include <nuttx/analog/adc.h>
#include "chip/lpc43_adc.h"
#ifdef CONFIG_LPC43_ADC
#ifdef CONFIG_LPC43_ADC0
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_ADC_CHANLIST
# if !defined(CONFIG_ADC_NCHANNELS)
# error "CONFIG_ADC_CHANLIST must defined in this configuration"
# elif CONFIG_ADC_NCHANNELS < 1
# error "The value of CONFIG_ADC_NCHANNELS is invalid"
# endif
#endif
/****************************************************************************
* Public Types

View File

@ -566,8 +566,8 @@ void lpc43_abp1(void)
/* Set clock source */
regval = getreg32(LPC43_BASE_APB1_CLK);
regval &= ~BASE_APB1_CLK_CLKSEL_MASK;
regval |= BOARD_ABP1_CLKSRC | BASE_APB1_CLK_AUTOBLOCK;
regval &= ~BASE_APB_CLK_CLKSEL_MASK;
regval |= BOARD_ABP1_CLKSRC | BASE_APB_CLK_AUTOBLOCK;
putreg32(regval, LPC43_BASE_APB1_CLK);
}
#endif
@ -580,8 +580,8 @@ void lpc43_abp3(void)
/* Set clock source */
regval = getreg32(LPC43_BASE_APB3_CLK);
regval &= ~BASE_APB3_CLK_CLKSEL_MASK;
regval |= BOARD_ABP3_CLKSRC | BASE_APB3_CLK_AUTOBLOCK;
regval &= ~BASE_APB_CLK_CLKSEL_MASK;
regval |= BOARD_ABP3_CLKSRC | BASE_APB_CLK_AUTOBLOCK;
putreg32(regval, LPC43_BASE_APB3_CLK);
}
#endif

View File

@ -62,8 +62,9 @@
#include "lpc43_cgu.h"
#include "lpc43_spifi.h"
#include "lpc43_pinconfig.h"
#include "spifi/inc/spifilib_api.h"
#ifdef CONFIG_LPC43_SPIFI
#ifdef CONFIG_LPC43_SPIFI_FIXME
/****************************************************************************
* Pre-processor Definitions
@ -145,11 +146,11 @@
priv->spifi->spifi_erase(rom, operands)
#else
# define SPIFI_INIT(priv, rom, cshigh, options, mhz) \
spifi_init(rom, cshigh, options, mhz)
spifiInit(rom, cshigh, options, mhz)
# define SPIFI_PROGRAM(priv, rom, src, operands) \
spifi_program(rom, src, operands)
spifiProgram(rom, src, operands)
# define SPIFI_ERASE(priv, rom, operands) \
spifi_erase(rom, operands)
spifiErase(rom, operands)
#endif
/* 512 byte sector simulation */
@ -244,7 +245,7 @@
* csHigh = ceiling(min CS high / SPIFI clock period) - 1
*
* where ceiling means round up to the next higher integer if the argument
* isnt an integer.
* isn<EFBFBD>t an integer.
*/
#define SPIFI_CSHIGH 9
@ -791,6 +792,7 @@ static ssize_t lpc43_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t
dest = SPIFI_BASE + (startblock << SPIFI_BLKSHIFT);
#if defined(CONFIG_SPIFI_SECTOR512)
/* Write all of the erase blocks to FLASH */
ret = lpc43_pagewrite(priv, dest, buffer, nblocks << SPIFI_512SHIFT);
@ -799,6 +801,7 @@ static ssize_t lpc43_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t
fdbg("ERROR: lpc43_pagewrite failed: %d\n", ret);
return ret;
}
#endif
lpc43_dumpbuffer(__func__, buffer, nblocks << SPIFI_BLKSHIFT)
return nblocks;

View File

@ -0,0 +1,175 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="com.crt.advproject.config.lib.debug.1825680109">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.crt.advproject.config.lib.debug.1825680109" moduleId="org.eclipse.cdt.core.settings" name="Debug">
<externalSettings>
<externalSetting>
<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/spifilib_m4f_hard"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/spifilib_m4f_hard/Debug"/>
<entry flags="RESOLVED" kind="libraryFile" name="spifilib_m4f_hard" srcPrefixMapping="" srcRootPath=""/>
</externalSetting>
</externalSettings>
<extensions>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="a" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.staticLib" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.staticLib" cleanCommand="rm -rf" description="Debug build" errorParsers="org.eclipse.cdt.core.CWDLocator;org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.GASErrorParser" id="com.crt.advproject.config.lib.debug.1825680109" name="Debug" parent="com.crt.advproject.config.lib.debug" postannouncebuildStep="Performing post-build steps" postbuildStep="arm-none-eabi-size &quot;lib${BuildArtifactFileName}&quot; ; # arm-none-eabi-objdump -h -S &quot;lib${BuildArtifactFileName}&quot; &gt;&quot;${BuildArtifactFileBaseName}.lss&quot;">
<folderInfo id="com.crt.advproject.config.lib.debug.1825680109." name="/" resourcePath="">
<toolChain id="com.crt.advproject.toolchain.lib.debug.1140641873" name="Code Red MCU Tools" superClass="com.crt.advproject.toolchain.lib.debug">
<targetPlatform binaryParser="org.eclipse.cdt.core.ELF;org.eclipse.cdt.core.GNU_ELF" id="com.crt.advproject.platform.lib.debug.2005661861" name="ARM-based MCU (Debug)" superClass="com.crt.advproject.platform.lib.debug"/>
<builder buildPath="${workspace_loc:/spifilib_m4f_hard}/Debug" id="com.crt.advproject.builder.lib.debug.883145021" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="com.crt.advproject.builder.lib.debug"/>
<tool id="com.crt.advproject.cpp.lib.debug.2123206095" name="MCU C++ Compiler" superClass="com.crt.advproject.cpp.lib.debug"/>
<tool id="com.crt.advproject.gcc.lib.debug.1823317949" name="MCU C Compiler" superClass="com.crt.advproject.gcc.lib.debug">
<option id="com.crt.advproject.gcc.arch.785649556" name="Architecture" superClass="com.crt.advproject.gcc.arch" value="com.crt.advproject.gcc.target.cm4" valueType="enumerated"/>
<option id="com.crt.advproject.gcc.thumb.1968664041" name="Thumb mode" superClass="com.crt.advproject.gcc.thumb" value="true" valueType="boolean"/>
<option id="gnu.c.compiler.option.preprocessor.def.symbols.1843984343" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="__REDLIB__"/>
<listOptionValue builtIn="false" value="DEBUG"/>
<listOptionValue builtIn="false" value="__CODE_RED"/>
<listOptionValue builtIn="false" value="CORE_M4"/>
<listOptionValue builtIn="false" value="__GENERIC_M4__"/>
</option>
<option id="gnu.c.compiler.option.misc.other.482687371" name="Other flags" superClass="gnu.c.compiler.option.misc.other" value="-c -fmessage-length=0 -fno-builtin -ffunction-sections -fdata-sections -fsingle-precision-constant" valueType="string"/>
<option id="gnu.c.compiler.option.include.paths.1266944767" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc}/../../inc&quot;"/>
</option>
<option id="com.crt.advproject.gcc.fpu.1084014995" name="Floating point" superClass="com.crt.advproject.gcc.fpu" value="com.crt.advproject.gcc.fpu.fpv4.hard" valueType="enumerated"/>
<option id="com.crt.advproject.gcc.hdrlib.900054249" name="Library headers" superClass="com.crt.advproject.gcc.hdrlib" value="Redlib" valueType="enumerated"/>
<inputType id="com.crt.advproject.compiler.input.1797320080" superClass="com.crt.advproject.compiler.input"/>
</tool>
<tool id="com.crt.advproject.gas.lib.debug.1273564729" name="MCU Assembler" superClass="com.crt.advproject.gas.lib.debug">
<option id="com.crt.advproject.gas.arch.1168168301" name="Architecture" superClass="com.crt.advproject.gas.arch" value="com.crt.advproject.gas.target.cm4" valueType="enumerated"/>
<option id="com.crt.advproject.gas.thumb.682537235" name="Thumb mode" superClass="com.crt.advproject.gas.thumb" value="true" valueType="boolean"/>
<option id="gnu.both.asm.option.flags.crt.876403086" name="Assembler flags" superClass="gnu.both.asm.option.flags.crt" value="-c -x assembler-with-cpp -D__REDLIB__ -DDEBUG -D__CODE_RED -DCORE_M4 -D__GENERIC_M4__" valueType="string"/>
<option id="gnu.both.asm.option.include.paths.1728725397" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
</option>
<option id="com.crt.advproject.gas.fpu.1400267278" name="Floating point" superClass="com.crt.advproject.gas.fpu" value="com.crt.advproject.gas.fpu.fpv4.hard" valueType="enumerated"/>
<option id="com.crt.advproject.gas.hdrlib.412316547" name="Library headers" superClass="com.crt.advproject.gas.hdrlib" value="Redlib" valueType="enumerated"/>
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1715036066" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
<inputType id="com.crt.advproject.assembler.input.370519403" name="Additional Assembly Source Files" superClass="com.crt.advproject.assembler.input"/>
</tool>
<tool id="com.crt.advproject.ar.lib.debug.602973900" name="MCU Archiver" superClass="com.crt.advproject.ar.lib.debug"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="inc"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
<cconfiguration id="com.crt.advproject.config.lib.release.289741577">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.crt.advproject.config.lib.release.289741577" moduleId="org.eclipse.cdt.core.settings" name="Release">
<externalSettings>
<externalSetting>
<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/spifilib_m4f_hard"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/spifilib_m4f_hard/Release"/>
<entry flags="RESOLVED" kind="libraryFile" name="spifilib_m4f_hard" srcPrefixMapping="" srcRootPath=""/>
</externalSetting>
</externalSettings>
<extensions>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="a" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.staticLib" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.staticLib" cleanCommand="rm -rf" description="Release build" errorParsers="org.eclipse.cdt.core.CWDLocator;org.eclipse.cdt.core.GmakeErrorParser;org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.GASErrorParser" id="com.crt.advproject.config.lib.release.289741577" name="Release" parent="com.crt.advproject.config.lib.release" postannouncebuildStep="Performing post-build steps" postbuildStep="arm-none-eabi-size &quot;lib${BuildArtifactFileName}&quot; ; if [ ! -f ../src/spifilib_dev_common.c ] ; then cp lib${BuildArtifactFileName} ../../../../lib/lpcxpresso/. ; fi ; # arm-none-eabi-objdump -h -S &quot;lib${BuildArtifactFileName}&quot; &gt;&quot;${BuildArtifactFileBaseName}.lss&quot;">
<folderInfo id="com.crt.advproject.config.lib.release.289741577." name="/" resourcePath="">
<toolChain id="com.crt.advproject.toolchain.lib.release.1396144083" name="Code Red MCU Tools" superClass="com.crt.advproject.toolchain.lib.release">
<targetPlatform binaryParser="org.eclipse.cdt.core.ELF;org.eclipse.cdt.core.GNU_ELF" id="com.crt.advproject.platform.lib.release.933177499" name="ARM-based MCU (Debug)" superClass="com.crt.advproject.platform.lib.release"/>
<builder buildPath="${workspace_loc:/spifilib_m4f_hard}/Release" id="com.crt.advproject.builder.lib.release.1407761972" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="com.crt.advproject.builder.lib.release"/>
<tool id="com.crt.advproject.cpp.lib.release.127947908" name="MCU C++ Compiler" superClass="com.crt.advproject.cpp.lib.release"/>
<tool id="com.crt.advproject.gcc.lib.release.371637005" name="MCU C Compiler" superClass="com.crt.advproject.gcc.lib.release">
<option id="com.crt.advproject.gcc.arch.703913963" name="Architecture" superClass="com.crt.advproject.gcc.arch" value="com.crt.advproject.gcc.target.cm4" valueType="enumerated"/>
<option id="com.crt.advproject.gcc.thumb.2123431566" name="Thumb mode" superClass="com.crt.advproject.gcc.thumb" value="true" valueType="boolean"/>
<option id="gnu.c.compiler.option.preprocessor.def.symbols.1620546070" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="__REDLIB__"/>
<listOptionValue builtIn="false" value="NDEBUG"/>
<listOptionValue builtIn="false" value="__CODE_RED"/>
<listOptionValue builtIn="false" value="CORE_M4"/>
<listOptionValue builtIn="false" value="__GENERIC_M4__"/>
</option>
<option id="gnu.c.compiler.option.misc.other.1056418239" name="Other flags" superClass="gnu.c.compiler.option.misc.other" value="-c -fmessage-length=0 -fno-builtin -ffunction-sections -fdata-sections -fsingle-precision-constant" valueType="string"/>
<option id="gnu.c.compiler.option.include.paths.1744512211" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc}/../../inc&quot;"/>
</option>
<option id="com.crt.advproject.gcc.fpu.1469714694" name="Floating point" superClass="com.crt.advproject.gcc.fpu" value="com.crt.advproject.gcc.fpu.fpv4.hard" valueType="enumerated"/>
<option id="com.crt.advproject.gcc.hdrlib.1478486360" name="Library headers" superClass="com.crt.advproject.gcc.hdrlib" value="com.crt.advproject.gcc.hdrlib.codered" valueType="enumerated"/>
<inputType id="com.crt.advproject.compiler.input.1039388872" superClass="com.crt.advproject.compiler.input"/>
</tool>
<tool id="com.crt.advproject.gas.lib.release.305305716" name="MCU Assembler" superClass="com.crt.advproject.gas.lib.release">
<option id="com.crt.advproject.gas.arch.1706520265" name="Architecture" superClass="com.crt.advproject.gas.arch" value="com.crt.advproject.gas.target.cm4" valueType="enumerated"/>
<option id="com.crt.advproject.gas.thumb.1746256321" name="Thumb mode" superClass="com.crt.advproject.gas.thumb" value="true" valueType="boolean"/>
<option id="gnu.both.asm.option.flags.crt.2138990015" name="Assembler flags" superClass="gnu.both.asm.option.flags.crt" value="-c -x assembler-with-cpp -D__REDLIB__ -DNDEBUG -D__CODE_RED -DCORE_M4 -D__GENERIC_M4__" valueType="string"/>
<option id="gnu.both.asm.option.include.paths.1770185984" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
</option>
<option id="com.crt.advproject.gas.fpu.544639325" name="Floating point" superClass="com.crt.advproject.gas.fpu" value="com.crt.advproject.gas.fpu.fpv4.hard" valueType="enumerated"/>
<option id="com.crt.advproject.gas.hdrlib.1511799236" name="Library headers" superClass="com.crt.advproject.gas.hdrlib" value="com.crt.advproject.gas.hdrlib.codered" valueType="enumerated"/>
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1197878263" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
<inputType id="com.crt.advproject.assembler.input.1716360932" name="Additional Assembly Source Files" superClass="com.crt.advproject.assembler.input"/>
</tool>
<tool id="com.crt.advproject.ar.lib.release.990536372" name="MCU Archiver" superClass="com.crt.advproject.ar.lib.release"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="inc"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="spifilib_m4f_hard.com.crt.advproject.projecttype.lib.1304330378" name="Static Library" projectType="com.crt.advproject.projecttype.lib"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="com.crt.config">
<projectStorage>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;TargetConfig&gt;
&lt;Properties property_0="" property_3="NXP" property_4="Generic-M4" property_count="5" version="70200"/&gt;
&lt;infoList vendor="NXP"&gt;&lt;info chip="Generic-M4" match_id="0x0" name="Generic-M4" stub="crt_emu_cm3_gen"&gt;&lt;chip&gt;&lt;name&gt;Generic-M4&lt;/name&gt;
&lt;family&gt;Generic-M4&lt;/family&gt;
&lt;vendor&gt;NXP (formerly Philips)&lt;/vendor&gt;
&lt;reset board="None" core="Real" sys="Real"/&gt;
&lt;clock changeable="TRUE" freq="12MHz" is_accurate="TRUE"/&gt;
&lt;memory can_program="true" id="Flash" is_ro="true" type="Flash"/&gt;
&lt;memory id="RAM" type="RAM"/&gt;
&lt;memory id="Periph" is_volatile="true" type="Peripheral"/&gt;
&lt;memoryInstance derived_from="RAM" id="RamLoc" location="0x0" size="0x4000"/&gt;
&lt;peripheralInstance derived_from="V7M_MPU" determined="infoFile" id="MPU" location="0xe000ed90"/&gt;
&lt;peripheralInstance derived_from="V7M_NVIC" determined="infoFile" id="NVIC" location="0xe000e000"/&gt;
&lt;peripheralInstance derived_from="V7M_DCR" determined="infoFile" id="DCR" location="0xe000edf0"/&gt;
&lt;peripheralInstance derived_from="V7M_ITM" determined="infoFile" id="ITM" location="0xe0000000"/&gt;
&lt;/chip&gt;
&lt;processor&gt;&lt;name gcc_name="cortex-m4"&gt;Cortex-M4&lt;/name&gt;
&lt;family&gt;Cortex-M&lt;/family&gt;
&lt;/processor&gt;
&lt;link href="CM3_peripheral.xme" show="embed" type="simple"/&gt;
&lt;/info&gt;
&lt;/infoList&gt;
&lt;/TargetConfig&gt;</projectStorage>
</storageModule>
<storageModule moduleId="refreshScope"/>
</cproject>

View File

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>spifilib_m4f_hard</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
<linkedResources>
<link>
<name>changelog.txt</name>
<type>1</type>
<locationURI>PARENT-2-WORKSPACE_LOC/changelog.txt</locationURI>
</link>
<link>
<name>inc/spifilib_api.h</name>
<type>1</type>
<locationURI>PARENT-2-WORKSPACE_LOC/inc/spifilib_api.h</locationURI>
</link>
<link>
<name>inc/spifilib_dev.h</name>
<type>1</type>
<locationURI>PARENT-2-WORKSPACE_LOC/inc/spifilib_dev.h</locationURI>
</link>
<link>
<name>src/spifilib_dev_common.c</name>
<type>1</type>
<locationURI>PARENT-2-WORKSPACE_LOC/src/spifilib_dev_common.c</locationURI>
</link>
<link>
<name>src/spifilib_fam_standard_cmd.c</name>
<type>1</type>
<locationURI>PARENT-2-WORKSPACE_LOC/src/spifilib_fam_standard_cmd.c</locationURI>
</link>
<link>
<name>inc/private/spifilib_chiphw.h</name>
<type>1</type>
<locationURI>PARENT-2-WORKSPACE_LOC/inc/private/spifilib_chiphw.h</locationURI>
</link>
</linkedResources>
</projectDescription>

View File

@ -0,0 +1,135 @@
LPCSpifilib version <1.03>
==========================
Release date <01/19/2015>
1. Corrected id for S25FL256S device.
2. Added 4 Byte address support for large devices (S25FL256S and S25FL512S).
3. Changed directory structure to new v3.xx format.
4. Removed --gnu flag and produced generic lib for use with both IAR and Keil
Known issues: (carried forward)
1. Option SPIFI_CAP_NOBLOCK is not implemented.
2. Will break IAR examples in LPCOpen v2.12 [Libraries in projects must be
renamed from lib_llpcspifi_Mx.a to lib_lpcspifi_Mx.a]
LPCSpifilib version <1.02>
==========================
Release date <12/30/2014>
1. Included pre-build of LPCXpresso M4F and M4F_hard libraries
Known issues: (carried forward)
1. Option SPIFI_CAP_NOBLOCK is not implemented.
2. Will break IAR examples in LPCOpen v2.12 [Libraries in projects must be
renamed from lib_llpcspifi_Mx.a to lib_lpcspifi_Mx.a]
LPCSpifilib version <1.01>
==========================
Release date <12/11/2014>
1. Changed reported device string on S25FL512S from "S25FL512S 256kSec" to "S25FL512S".
2. Changelog update: Added support for MX25L1635E, MX25L6435E, MX25L8035E, S25FL016K, S25FL064P, S25FL128S, S25FL256S,
S25FL512S, W25Q16DV, and W25Q64FV devices.
3. Changelog update: Changed maxRead to 16128 (was 32768).
Known issues: (carried forward)
1. Option SPIFI_CAP_NOBLOCK is not implemented.
2. Will break IAR examples in LPCOpen v2.12 [Libraries in projects must be
renamed from lib_llpcspifi_Mx.a to lib_lpcspifi_Mx.a]
LPCSpifilib version <1.0>
==========================
Release date <12/2/2014>
Change Log:
1. Added support for MX25L1635E, MX25L6435E, MX25L8035E, S25FL016K, S25FL064P, S25FL128P, S25FL256S,
S25FL512S, W25Q16DV, and W25Q64FV devices.
2. Added support for device enumeration.
3. Added support for device base address return.
4. Improved read/write performance by issuing dword access to spifi controller.
5. Changed device structure to use function enum to facilitate adding external devices without recompiling library.
6. Added support for dual read / write.
7. Changed quad command to quad io read (improved performance).
8. Added ability for device to define read / write configuration word on a per
device basis.
9. Changed maxRead to 16383 (was 32768)
10. Removed API spifiDeInit();
11. Renamed spifiDevGetInfo option SPIFI_INFO_MAX_QUADREAD_CLOCK to SPIFI_INFO_MAX_HSREAD_CLOCK
12. Renamed spifiDevGetInfo option SPIFI_INFO_MAX_QUADPROG_CLOCK to SPIFI_INFO_MAX_HSPROG_CLOCK
Known issues: (carried forward)
1. Option SPIFI_CAP_NOBLOCK is not implemented.
2. Will break IAR examples in LPCOpen v2.12 [Libraries in projects must be
renamed from lib_llpcspifi_Mx.a to lib_lpcspifi_Mx.a].
LPCSpifilib version <0.07>
==========================
Release date <9/9/2014>
Change Log:
1. Added support for Winbond W25Q32FV.
2. Added support for Winbond W25Q80BV.
3. Added API's to return max speed for specific functions:
Read, QuadRead, Program, Quad Program.
4. Added prvGetStatus, prvSetStatus and prvSetQuadMode Functions to device definition structure.
5. Added spifiDevGetCount function.
6. Consolidated MX25L3235E and S25FL164K support into spifilib_fam_standard_cmd module
(removed SPIFI_REG_FAMILY_xxx registration functions and replaced with
spifi_REG_FAMILY_StandardCommandSet function).
7. Fixed bug in spifiRegisterFamily where NULL was being returned instead of the
family handle.
8. Removed switch statements and clib calls to memcpy and memset to facilitate running from iRam.
9. Renamed SPIFI_DEV_FAMILY_T to SPIFI_FAM_NODE_T.
10. Moved spifiDevRegister to shared module (spifilib_dev_common.c).
11. Updated documentation to reflect current design.
Known issues: (carried forward)
1. Option SPIFI_CAP_NOBLOCK is not implemented.
2. Will break IAR examples in LPCOpen v2.12 [Libraries in projects must be
renamed from lib_llpcspifi_Mx.a to lib_lpcspifi_Mx.a]
LPCSpifilib version <0.06>
==========================
Release date <6/25/2014>
Change Log:
1. Changed identify to allow dynamic ID bytes per MFG/PART #. Moved to common
module.
2. Added support for S25FL129P (256kB sectors).
3. Verified S25FL129P 64kB sectors variant.
4. Renamed familes to indicate functionality in place of root device.
(This was done to avoid confusion over where devices reside).
5. Family cleanup to aid in comparison.
6. Removed Chip.h dependency.
7. Moved getInfo to common module.
8. Code/Memory optimizations.
9. LPCXpresso XML projects added.
10. M0 Library added.
11. Sub-block erase fixed for devices with full capability.
12. IAR libarary renamed to match Keil library
13. Moved project files into proj directory
Known issues: (carried forward)
1. Option SPIFI_CAP_NOBLOCK is not implemented.
2. Will break IAR examples in LPCOpen v2.12 [Libraries in projects must be
renamed from lib_llpcspifi_Mx.a to lib_lpcspifi_Mx.a]
LPCSpifilib version <0.05>
==========================
Release date <5/15/2014>
Change Log:
1. Comment cleanup.
2. Added support for 40xx series
3. Changed spifiInit() api to include spifi control register address.
4. Changed spifiInitDevice() to include spifi control register address.
Known issues: (carried forward)
1. Option SPIFI_CAP_NOBLOCK is not implemented.
2. Option SPIFI_CAP_SUBBLKERASE is not working.
3. Device S25FL129P is un-tested.
LPCSpifilib version <0.04>
===========================
Release date <4/25/2014>
Change Log:
1. Initial version.
Known issues:
1. Option SPIFI_CAP_NOBLOCK is not implemented.
2. Option SPIFI_CAP_SUBBLKERASE is not working.
3. Device S25FL129P is un-tested.

View File

@ -0,0 +1,349 @@
/*
* @brief LPCSPIFILIB hardware definitions and functions
*
* @note
* Copyright(C) NXP Semiconductors, 2014
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licenser disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __SPIFILIB_CHIPHW_H_
#define __SPIFILIB_CHIPHW_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Define for inline */
#ifndef INLINE
#ifdef __CC_ARM
#define INLINE __inline
#else
#define INLINE inline
#endif /* __CC_ARM */
#endif /* !INLINE */
#ifdef __CC_ARM
#pragma anon_unions
#endif
/** @defgroup LPCSPIFILIB_HW_API LPCSPIFILIB hardware definitions and API functions
* @ingroup LPCSPIFILIB
* @{
*/
/**
* @brief SPIFI controller hardware register structure
*/
typedef struct LPC_SPIFI_CHIPHW {
volatile uint32_t CTRL; /**< SPIFI control register */
volatile uint32_t CMD; /**< SPIFI command register */
volatile uint32_t ADDR; /**< SPIFI address register */
volatile uint32_t DATINTM; /**< SPIFI intermediate data register */
volatile uint32_t CACHELIMIT; /**< SPIFI cache limit register */
union {
volatile uint8_t DAT8; /**< SPIFI 8 bit data */
volatile uint16_t DAT16; /**< SPIFI 16 bit data */
volatile uint32_t DAT32; /**< SPIFI 32 bit data */
};
volatile uint32_t MEMCMD; /**< SPIFI memory command register */
volatile uint32_t STAT; /**< SPIFI status register */
} LPC_SPIFI_CHIPHW_T;
/** @defgroup LPCSPIFILIB_HW_PRIM LPCSPIFILIB primative API functions
* @{
*/
/**
* @brief SPIFI controller control register bit definitions
*/
#define SPIFI_CTRL_TO(t) ((t) << 0) /**< SPIFI timeout */
#define SPIFI_CTRL_CSHI(c) ((c) << 16) /**< SPIFI chip select minimum high time */
#define SPIFI_CTRL_DATA_PREFETCH_DISABLE(d) ((d) << 21) /**< SPIFI memMode prefetch enable*/
#define SPIFI_CTRL_INTEN(i) ((i) << 22) /**< SPIFI cmdComplete irq enable */
#define SPIFI_CTRL_MODE3(m) ((m) << 23) /**< SPIFI mode3 config */
#define SPIFI_CTRL_PREFETCH_DISABLE(d) ((d) << 27) /**< SPIFI cache prefetch enable */
#define SPIFI_CTRL_DUAL(d) ((d) << 28) /**< SPIFI enable dual */
#define SPIFI_CTRL_RFCLK(m) ((m) << 29) /**< SPIFI clock edge config */
#define SPIFI_CTRL_FBCLK(m) ((m) << 30) /**< SPIFI feedback clock select */
#define SPIFI_CTRL_DMAEN(m) ((m) << 31) /**< SPIFI dma enable */
/**
* @brief Write SPIFI controller control register
* @param pSpifi : Base address of SPIFI controller
* @param ctrl : Control value to write
* @return Nothing
*/
static INLINE void spifi_HW_SetCtrl(LPC_SPIFI_CHIPHW_T *pSpifi, uint32_t ctrl)
{
pSpifi->CTRL = ctrl;
}
/**
* @brief Read SPIFI controller control register
* @param pSpifi : Base address of SPIFI controller
* @return Current CTRL register values
*/
static INLINE uint32_t spifi_HW_GetCtrl(LPC_SPIFI_CHIPHW_T *pSpifi)
{
return pSpifi->CTRL;
}
/**
* @brief SPIFI controller status register bit definitions
*/
#define SPIFI_STAT_RESET (1 << 4) /**< SPIFI reset */
#define SPIFI_STAT_INTRQ (1 << 5) /**< SPIFI interrupt request */
#define SPIFI_STAT_CMD (1 << 1) /**< SPIFI command in progress */
#define SPIFI_STAT_MCINIT (1) /**< SPIFI MCINIT */
/**
* @brief Write SPIFI controller status register
* @param pSpifi : Base address of SPIFI controller
* @param stat : Status bits to write
* @return Nothing
*/
static INLINE void spifi_HW_SetStat(LPC_SPIFI_CHIPHW_T *pSpifi, uint32_t stat)
{
pSpifi->STAT = stat;
}
/**
* @brief Read SPIFI controller status register
* @param pSpifi : Base address of SPIFI controller
* @return Current STAT register values
*/
static INLINE uint32_t spifi_HW_GetStat(LPC_SPIFI_CHIPHW_T *pSpifi)
{
return pSpifi->STAT;
}
/**
* @brief SPIFI controller command register bit definitions
*/
#define SPIFI_CMD_DATALEN(l) ((l) << 0) /**< SPIFI bytes to send or receive */
#define SPIFI_CMD_POLLRS(p) ((p) << 14) /**< SPIFI enable poll */
#define SPIFI_CMD_DOUT(d) ((d) << 15) /**< SPIFI data direction is out */
#define SPIFI_CMD_INTER(i) ((i) << 16) /**< SPIFI intermediate bit length */
#define SPIFI_CMD_FIELDFORM(p) ((p) << 19) /**< SPIFI 2 bit data/cmd mode control */
#define SPIFI_CMD_FRAMEFORM(f) ((f) << 21) /**< SPIFI op and adr field config */
#define SPIFI_CMD_OPCODE(o) ((uint32_t) (o) << 24) /**< SPIFI 8-bit command code */
/**
* @brief frame form definitions
*/
typedef enum {
SPIFI_FRAMEFORM_OP = 1,
SPIFI_FRAMEFORM_OP_1ADDRESS = 2,
SPIFI_FRAMEFORM_OP_2ADDRESS = 3,
SPIFI_FRAMEFORM_OP_3ADDRESS = 4,
SPIFI_FRAMEFORM_OP_4ADDRESS = 5,
SPIFI_FRAMEFORM_NOOP_3ADDRESS = 6,
SPIFI_FRAMEFORM_NOOP_4ADDRESS = 7
} SPIFI_FRAMEFORM_T;
/**
* @brief serial type definitions
*/
typedef enum {
SPIFI_FIELDFORM_ALL_SERIAL = 0,
SPIFI_FIELDFORM_SERIAL_OPCODE_ADDRESS = 1,
SPIFI_FIELDFORM_SERIAL_OPCODE = 2,
SPIFI_FIELDFORM_NO_SERIAL = 3
} SPIFI_FIELDFORM_T;
/**
* @brief Read SPIFI controller command register
* @param pSpifi : Base address of SPIFI controller
* @return 32-bit value read from the command register
*/
static INLINE uint32_t spifi_HW_GetCmd(LPC_SPIFI_CHIPHW_T *pSpifi)
{
return pSpifi->CMD;
}
/**
* @brief Write SPIFI controller command register
* @param pSpifi : Base address of SPIFI controller
* @param cmd : Command to write
* @return Nothing
*/
static INLINE void spifi_HW_SetCmd(LPC_SPIFI_CHIPHW_T *pSpifi, uint32_t cmd)
{
pSpifi->CMD = cmd;
}
/**
* @brief Write SPIFI controller address register
* @param pSpifi : Base address of SPIFI controller
* @param addr : address (offset) to write
* @return Nothing
*/
static INLINE void spifi_HW_SetAddr(LPC_SPIFI_CHIPHW_T *pSpifi, uint32_t addr)
{
pSpifi->ADDR = addr;
}
/**
* @brief Read an 8-bit value from the controller data register
* @param pSpifi : Base address of SPIFI controller
* @return 8-bit value read from the data register
*/
static INLINE uint8_t spifi_HW_GetData8(LPC_SPIFI_CHIPHW_T *pSpifi)
{
return pSpifi->DAT8;
}
/**
* @brief Read an 16-bit value from the controller data register
* @param pSpifi : Base address of SPIFI controller
* @return 16-bit value read from the data register
*/
static INLINE uint16_t spifi_HW_GetData16(LPC_SPIFI_CHIPHW_T *pSpifi)
{
return pSpifi->DAT16;
}
/**
* @brief Read an 32-bit value from the controller data register
* @param pSpifi : Base address of SPIFI controller
* @return 32-bit value read from the data register
*/
static INLINE uint32_t spifi_HW_GetData32(LPC_SPIFI_CHIPHW_T *pSpifi)
{
return pSpifi->DAT32;
}
/**
* @brief Write an 8-bit value from the controller data register
* @param pSpifi : Base address of SPIFI controller
* @param data : 8-bit data value to write
* @return Nothing
*/
static INLINE void spifi_HW_SetData8(LPC_SPIFI_CHIPHW_T *pSpifi, uint8_t data)
{
pSpifi->DAT8 = data;
}
/**
* @brief Write an 16-bit value from the controller data register
* @param pSpifi : Base address of SPIFI controller
* @param data : 16-bit data value to write
* @return Nothing
*/
static INLINE void spifi_HW_SetData16(LPC_SPIFI_CHIPHW_T *pSpifi, uint16_t data)
{
pSpifi->DAT16 = data;
}
/**
* @brief Write an 32-bit value from the controller data register
* @param pSpifi : Base address of SPIFI controller
* @param data : 32-bit data value to write
* @return Nothing
*/
static INLINE void spifi_HW_SetData32(LPC_SPIFI_CHIPHW_T *pSpifi, uint32_t data)
{
pSpifi->DAT32 = data;
}
/**
* @brief Write IDATA register
* @param pSpifi : Base address of SPIFI controller
* @param mode : value to write. Used to specify value used for intermediate
data value when enabled.
* @return Nothing
*/
static INLINE void spifi_HW_SetIDATA(LPC_SPIFI_CHIPHW_T *pSpifi, uint32_t mode)
{
pSpifi->DATINTM = mode;
}
/**
* @brief Write MEMCMD register
* @param pSpifi : Base address of SPIFI controller
* @param cmd : Command value to write
* @return Nothing
*/
static INLINE void spifi_HW_SetMEMCMD(LPC_SPIFI_CHIPHW_T *pSpifi, uint32_t cmd)
{
pSpifi->MEMCMD = cmd;
}
/**
* @}
*/
/** @defgroup LPCSPIFILIB_HW_L2 LPCSPIFILIB hardware support API functions
* @{
*/
/**
* @brief Reset SPIFI controller
* @param pSpifi : Base address of SPIFI controller
* @return Nothing
*/
static INLINE void spifi_HW_ResetController(LPC_SPIFI_CHIPHW_T *pSpifi)
{
pSpifi->STAT = SPIFI_STAT_RESET;
while ((pSpifi->STAT & SPIFI_STAT_RESET) != 0) {}
}
/**
* @brief Wait for a command to complete
* @param pSpifi : Base address of SPIFI controller
* @return Nothing
*/
static INLINE void spifi_HW_WaitCMD(LPC_SPIFI_CHIPHW_T *pSpifi)
{
while ((spifi_HW_GetStat(pSpifi) & SPIFI_STAT_CMD) != 0) {}
}
/**
* @brief Wait for a RESET bit to clear
* @param pSpifi : Base address of SPIFI controller
* @return Nothing
*/
static INLINE void spifi_HW_WaitRESET(LPC_SPIFI_CHIPHW_T *pSpifi)
{
while ((spifi_HW_GetStat(pSpifi) & SPIFI_STAT_RESET) != 0) {}
}
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __SPIFILIB_CHIPHW_H_ */

View File

@ -0,0 +1,438 @@
/*
* @brief LPCSPIFILIB driver definitions and functions
*
* @note
* Copyright(C) NXP Semiconductors, 2014
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licenser disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __SPIFILIB_API_H_
#define __SPIFILIB_API_H_
#include "spifilib_dev.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @defgroup LPCSPIFILIB_API LPCSPIFILIB common API functions
* @ingroup LPCSPIFILIB
* These LPCSPIFILIB functions provide an abstracted interface to
* the LPCSPIFILIB functions. The device API is a private API which should
* only used to interface with the LPCSPIFILIB core library.
* @{
*/
/** @defgroup LPCSPIFILIB_CMNAPI LPCSPIFILIB library support functions
* Library support functions are not tied to any specific LPCSPIFILIB device.
* @{
*/
/**
* @brief Report the SPIFILIB version
* @return SPIFI library version in format MMmm where MM is major number
* and mm is minor number.
*/
uint16_t spifiGetLibVersion(void);
/**
* @brief Initialize the SPIFILIB driver
* @param spifiCtrlAddr : Base address of SPIFI controller
* @param reset : true to reset the SPIFI controller, or false to not reset
* @return SPIFI library error code
* @note This function should be called prior to any other SPIFILIB functions.
* In most cases, a reset isn't needed. Before calling this function, all board
* specific functions related to the SPIFI interface must be setup and the SPIFI
* clock must be enabled. If booting from SPIFI FLASH, this will already be done.
* If not booting from SPIFI FLASH, the SPIFI FLASH pin muxing and SPIFI controller
* clock need to be enabled prior to this call.
*/
SPIFI_ERR_T spifiInit(uint32_t spifiCtrlAddr, uint8_t reset);
/**
* @brief Register a SPIFILIB family driver
* @param regFx : A function which returns persistent device specific data structure.
* @return Handle to device specific data structure.
* @note This function should be called prior to calling spifiGetHandleMemSize() or
* spifiInitDevice().
*/
SPIFI_FAM_NODE_T *spifiRegisterFamily(SPIFI_FAM_NODE_T *(*regFx)(void));
/**
* @brief Converts a SPIFILIB error code into a meaningful string
* @param errCode : Error code to get string pointer to
* @return Pointer to string for the passed error code
*/
const char *spifiReturnErrString(SPIFI_ERR_T errCode);
/**
* @brief Return the number of registered device families in this driver
* @return number of registered device families in this driver
*/
uint32_t spifiGetSuppFamilyCount(void);
/**
* @brief Return the driver device family name for a specific index
* @param index : Index (0 - n) where n = number of families returned
* by spifiGetSuppFamilyCount() -1
* @return a string pointer to the generic device name
* @note Can be used with the spifiGetSuppFamilyCount() to get a list of
* device families the library is configured for.
*/
const char *spifiGetSuppFamilyName(uint32_t index);
/**
* @brief Detect and return memory needed for device handle at passed address
* @param spifiCtrlAddr : Base address of SPIFI controller
* @return The size in bytes this device needs for the call to InitDevice().
* If no supported device is detected 0 will be returned.
* @note Selects the first matching device in the library.
*/
uint32_t spifiGetHandleMemSize(uint32_t spifiCtrlAddr);
/**
* @brief Initialize driver and hardware for a specific device
* @param pMem : Pointer to a 32-bit aligned buffer with a size returned from spifiGetHandleMemSize()
* @param sizePMem : Size of the buffer in bytes pass in pMem
* @param spifiCtrlAddr : Base address of SPIFI controller
* @param baseAddr : Base address of device
* @return Returns a pointer to a device handle if successful, or NULL on an error.
*/
SPIFI_HANDLE_T *spifiInitDevice(void *pMem, uint32_t sizePMem, uint32_t spifiCtrlAddr, uint32_t baseAddr);
/**
* @brief Set or unset driver options
* @param pHandle : Pointer to a LPCSPIFILIB device handle
* @param options : Options to set or unset, an OR'ed value of SPIFI_OPT_xxx values
* (example #SPIFI_OPT_USE_QUAD | #SPIFI_OPT_NOBLOCK)
* @param set : true to set the passed options, false to clear them
* @return Nothing
* @note Only options that are supported in the capabilities of the driver can be
* set or unset.
*/
SPIFI_ERR_T spifiDevSetOpts(SPIFI_HANDLE_T *pHandle, uint32_t options, uint8_t set);
/**
* @}
*/
/** @defgroup LPCSPIFILIB_DEVAPI LPCSPIFILIB library device functions
* Device functions are used to perform LPCSPIFILIB device operations.
* @{
*/
/**
* @brief Add device to family driver
* @param pFamily : Pointer to a SPIFI_DEV_FAMILY_T family handle
* @param pDevData : Pointer to a persistent SPIFI_DEV_DATA_T device structure
* @return A SPIFI_ERR_T error code (SPIFI_ERR_NONE for no errors)
* @note This function MUST be called prior to spifiGetHandleMemSize() or spifiInitDevice()
*/
SPIFI_ERR_T spifiDevRegister(const SPIFI_FAM_NODE_T *pFamily, SPIFI_DEV_NODE_T *pDevData);
/**
* @brief Returns the number of supported devices within a family
* @param pFamily : Pointer to a SPIFI_DEV_FAMILY_T family handle
* @return The number of registered devices.
*/
static INLINE uint32_t spifiDevGetCount(const SPIFI_FAM_NODE_T *pFamily)
{
return *(pFamily->pDesc->pDevCount);
}
/**
* @brief Enumerates the friendly names of supported devices
* @param pContext : Pointer to a SPIFI_DEV_ENUMERATOR_T context structure
* @param reset : 0 enumerates next device, 1 resets list to beginning and returns first device
* @return A friendly string representing the device, NULL when list has been exhausted.
*/
const char *spifiDevEnumerateName(SPIFI_DEV_ENUMERATOR_T *pContext, uint8_t reset);
/**
* @brief Initialize a detected LPCSPIFILIB device
* @param pHandle : Pointer to a LPCSPIFILIB device handle
* @return A SPIFI_NO_* error code (SPIFI_ERR_NONE is no errors)
*/
SPIFI_ERR_T spifiDevInit(const SPIFI_HANDLE_T *pHandle);
/**
* @brief De-initialize a detected LPCSPIFILIB device
* @param pHandle : Pointer to a LPCSPIFILIB device handle
* @return A SPIFI_NO_* error code (SPIFI_ERR_NONE is no errors)
*/
SPIFI_ERR_T spifiDevDeInit(const SPIFI_HANDLE_T *pHandle);
/**
* @brief Sets or clears memory mode
* @param pHandle : Pointer to a LPCSPIFILIB device handle
* @param enMMode : true to enable memory mode, false to disable
* @return A SPIFI_NO_* error code (SPIFI_ERR_NONE is no errors)
* @note Enter memory mode to enable direct read access for Execute in
* place code and memory mapped data. Memory mode must be disabled
* for most operations.
*/
SPIFI_ERR_T spifiDevSetMemMode(const SPIFI_HANDLE_T *pHandle, uint8_t enMMode);
/**
* @brief Return status of memory mode
* @param pSpifi : Base address of SPIFI controller
* @return state of memory mode (false = off, true = on)
*/
uint8_t spifiDevGetMemoryMode(const SPIFI_HANDLE_T *pSpifi);
/**
* @brief Full LPCSPIFILIB device unlock
* @param pHandle : Pointer to a LPCSPIFILIB device handle
* @return A SPIFI_NO_* error code (SPIFI_ERR_NONE is no errors)
*/
static INLINE SPIFI_ERR_T spifiDevUnlockDevice(const SPIFI_HANDLE_T *pHandle)
{
return pHandle->pFamFx->lockCmd(pHandle, SPIFI_PCMD_UNLOCK_DEVICE, 0);
}
/**
* @brief Full LPCSPIFILIB device lock
* @param pHandle : Pointer to a LPCSPIFILIB device handle
* @return A SPIFI_NO_* error code (SPIFI_ERR_NONE is no errors)
*/
static INLINE SPIFI_ERR_T spifiDevLockDevice(const SPIFI_HANDLE_T *pHandle)
{
return pHandle->pFamFx->lockCmd(pHandle, SPIFI_PCMD_LOCK_DEVICE, 0);
}
/**
* @brief Unlock a single device block
* @param pHandle : Pointer to a LPCSPIFILIB device handle
* @param block : Block number to unlock
* @return A SPIFI_NO_* error code (SPIFI_ERR_NONE is no errors)
*/
static INLINE SPIFI_ERR_T spifiDevUnlockBlock(const SPIFI_HANDLE_T *pHandle, uint32_t block)
{
return pHandle->pFamFx->lockCmd(pHandle, SPIFI_PCMD_UNLOCK_BLOCK, block);
}
/**
* @brief Lock a single device block
* @param pHandle : Pointer to a LPCSPIFILIB device handle
* @param block : Block number to lock
* @return A SPIFI_NO_* error code (SPIFI_ERR_NONE is no errors)
*/
static INLINE SPIFI_ERR_T spifiDevLockBlock(const SPIFI_HANDLE_T *pHandle, uint32_t block)
{
return pHandle->pFamFx->lockCmd(pHandle, SPIFI_PCMD_LOCK_BLOCK, block);
}
/**
* @brief Full LPCSPIFILIB device erase
* @param pHandle : Pointer to a LPCSPIFILIB device handle
* @return A SPIFI_NO_* error code (SPIFI_ERR_NONE is no errors)
*/
static INLINE SPIFI_ERR_T spifiDevEraseAll(const SPIFI_HANDLE_T *pHandle)
{
return pHandle->pFamFx->eraseAll(pHandle);
}
/**
* @brief Erase a sub-block
* @param pHandle : Pointer to a LPCSPIFILIB device handle
* @param blknum : Sub-block number to erase
* @return A SPIFI_NO_* error code (SPIFI_ERR_NONE is no errors)
*/
static INLINE SPIFI_ERR_T spifiDevEraseSubBlock(const SPIFI_HANDLE_T *pHandle, uint32_t blknum)
{
return pHandle->pFamFx->eraseSubBlock(pHandle, blknum);
}
/**
* @brief Program up to a page of data at an address
* @param pHandle : Pointer to a LPCSPIFILIB device handle
* @param addr : LPCSPIFILIB device address to start write at
* @param writeBuff : Address of buffer to write, must be 32-bit aligned
* @param bytes : Number of bytes to write, must not exceed page length
* @return A SPIFI_NO_* error code (SPIFI_ERR_NONE is no errors)
* @note Only use this function to program data up to the page size.
*/
static INLINE SPIFI_ERR_T spifiDevPageProgram(const SPIFI_HANDLE_T *pHandle,
uint32_t addr,
uint32_t *writeBuff,
uint32_t bytes)
{
return pHandle->pFamFx->pageProgram(pHandle, addr, writeBuff, bytes);
}
/**
* @brief Read data from a LPCSPIFILIB device
* @param pHandle : Pointer to a LPCSPIFILIB device handle
* @param addr : LPCSPIFILIB device address to read from
* @param readBuff : Address of buffer to fill, must be 32-bit aligned
* @param bytes : Number of bytes to read
* @return A SPIFI_NO_* error code (SPIFI_ERR_NONE is no errors)
* @note Maximum read size is limited to the max single read size
*/
static INLINE SPIFI_ERR_T spifiDevRead(const SPIFI_HANDLE_T *pHandle, uint32_t addr, uint32_t *readBuff, uint32_t bytes)
{
return pHandle->pFamFx->read(pHandle, addr, readBuff, bytes);
}
/**
* @brief Reset the device
* @param pHandle : Pointer to a LPCSPIFILIB device handle
* @return Nothing
* @note Will set the device into read mode
*/
static INLINE void spifiDevReset(const SPIFI_HANDLE_T *pHandle)
{
pHandle->pFamFx->reset(pHandle);
}
/**
* @brief Returns a string pointer to the generic device family name
* @param pHandle : Pointer to a LPCSPIFILIB device handle
* @return a string pointer to the generic device family name
*/
static INLINE const char *spifiDevGetDeviceName(const SPIFI_HANDLE_T *pHandle)
{
return pHandle->pInfoData->pDevName;
}
#define spifiDevGetFamilyName spifiDevGetDeviceName /**< Deprecated! Do NOT use for new development */
/**
* @brief Returns information on the device
* @param pHandle : Pointer to a LPCSPIFILIB device handle
* @param infoId : Info to get about the device
* @return Return value varies per selected function
*/
uint32_t spifiDevGetInfo(const SPIFI_HANDLE_T *pHandle, SPIFI_INFO_ID_T infoId);
/**
* @}
*/
/** @defgroup LPCSPIFILIB_HELPAPI LPCSPIFILIB library helper functions
* @{
*/
/**
* @brief Returns the starting address of a block number
* @param pHandle : Pointer to a LPCSPIFILIB device handle
* @param blockNum : Block number fo get starting address for
* @return The starting address for the block, or 0xFFFFFFFF if the block number if invalid
*/
uint32_t spifiGetAddrFromBlock(const SPIFI_HANDLE_T *pHandle, uint32_t blockNum);
/**
* @brief Returns the starting address of a sub-block number
* @param pHandle : Pointer to a LPCSPIFILIB device handle
* @param subBlockNum : Sub-block number fo get starting address for
* @return The starting address for the sub-block, or 0xFFFFFFFF if the block number if invalid
*/
uint32_t spifiGetAddrFromSubBlock(const SPIFI_HANDLE_T *pHandle, uint32_t subBlockNum);
/**
* @brief Returns the block number the passed address is located in
* @param pHandle : Pointer to a LPCSPIFILIB device handle
* @param addr : Address to get block number for
* @return The block number the passed address is in, 0xFFFFFFFF is the address is invalid
*/
uint32_t spifiGetBlockFromAddr(const SPIFI_HANDLE_T *pHandle, uint32_t addr);
/**
* @brief Returns the sub-block number the passed address is located in
* @param pHandle : Pointer to a LPCSPIFILIB device handle
* @param addr : Address to get sub-block number for
* @return The sub-block number the passed address is in, 0xFFFFFFFF is the address is invalid
*/
uint32_t spifiGetSubBlockFromAddr(const SPIFI_HANDLE_T *pHandle, uint32_t addr);
/**
* @brief Returns the first sub-block for a block
* @param pHandle : Pointer to a LPCSPIFILIB device handle
* @param blockNum : Block number to get first sub-block for
* @return The first sub-block number in passed block, 0xFFFFFFFF if the block number if invalid
*/
uint32_t spifiGetSubBlockFromBlock(const SPIFI_HANDLE_T *pHandle, uint32_t blockNum);
/**
* @brief Program the device with the passed buffer
* @param pHandle : Pointer to a LPCSPIFILIB device handle
* @param addr : LPCSPIFILIB device address to start write at
* @param writeBuff : Address of buffer to write, must be 32-bit aligned
* @param bytes : Number of bytes to write
* @return A SPIFI_ERR_xxx error code (SPIFI_ERR_NONE is no errors)
* @note This function has no size limit. This function only works in blocking mode.
*/
SPIFI_ERR_T spifiProgram(const SPIFI_HANDLE_T *pHandle, uint32_t addr, const uint32_t *writeBuff, uint32_t bytes);
/**
* @brief Read the device into the passed buffer
* @param pHandle : Pointer to a LPCSPIFILIB device handle
* @param addr : LPCSPIFILIB device address to start read at
* @param readBuff : Address of buffer to read into, must be 32-bit aligned
* @param bytes : Number of bytes to read
* @return A SPIFI_ERR_xxx error code (SPIFI_ERR_NONE is no errors)
* @note This function has no size limit. Optionally, the device can be placed into memory
* mode and accessed directly via memory mapped reads without using this function. This
* function only works in blocking mode.
*/
SPIFI_ERR_T spifiRead(const SPIFI_HANDLE_T *pHandle, uint32_t addr, uint32_t *readBuff, uint32_t bytes);
/**
* @brief Erase multiple blocks
* @param pHandle : Pointer to a LPCSPIFILIB device handle
* @param firstBlock : First block number to erase
* @param numBlocks : Number of blocks to erase
* @return A SPIFI_ERR_xxx error code (SPIFI_ERR_NONE is no errors)
* @note If any of the specified params are invalid, the operation is aborted
* before any sectors are erased. This function only works in blocking mode.
*/
SPIFI_ERR_T spifiErase(const SPIFI_HANDLE_T *pHandle, uint32_t firstBlock, uint32_t numBlocks);
/**
* @brief Erase multiple blocks by address range
* @param pHandle : Pointer to a LPCSPIFILIB device handle
* @param firstAddr : Starting address range for block erase
* @param lastAddr : Ending address range for block erase
* @return A SPIFI_ERR_xxx error code (SPIFI_ERR_NONE is no errors)
* @note This function will erase blocks inside the passed address
* range if and only if the address range is valid.
* This function only works in blocking mode.
*/
SPIFI_ERR_T spifiEraseByAddr(const SPIFI_HANDLE_T *pHandle, uint32_t firstAddr, uint32_t lastAddr);
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __SPIFILIB_API_H_ */

View File

@ -0,0 +1,416 @@
/*
* @brief LPCSPIFILIB FLASH library device specific functions
*
* @note
* Copyright(C) NXP Semiconductors, 2014
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licenser disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#ifndef __SPIFILIB_DEV_H_
#define __SPIFILIB_DEV_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Define for inline functions */
#ifndef INLINE
#ifdef __CC_ARM
#define INLINE __inline
#else
#define INLINE inline
#endif /* __CC_ARM */
#endif /* !INLINE */
/** @defgroup LPCSPIFILIB_DEV LPCSPIFILIB device driver API functions
* @ingroup LPCSPIFILIB
* @{
*/
/**
* @brief Possible error codes that can be returned from functions
*/
typedef enum {
SPIFI_ERR_NONE = 0, /**< No error */
SPIFI_ERR_BUSY, /**< Device is busy */
SPIFI_ERR_GEN, /**< General error */
SPIFI_ERR_NOTSUPPORTED, /**< Capability not supported */
SPIFI_ERR_ALIGNERR, /**< Attempted to do an operation on an unaligned section of the device */
SPIFI_ERR_LOCKED, /**< Device was locked and a program/erase operation was attempted */
SPIFI_ERR_PROGERR, /**< Error programming device (blocking mode only) */
SPIFI_ERR_ERASEERR, /**< Erase error (blocking mode only) */
SPIFI_ERR_NOTBLANK, /**< Program operation on block that is not blank */
SPIFI_ERR_PAGESIZE, /**< PageProgram write size exceeds page size */
SPIFI_ERR_VAL, /**< Program operation failed validation or readback compare */
SPIFI_ERR_RANGE, /**< Range error, bad block number, address out of range, etc. */
SPIFI_ERR_MEMMODE, /**< Library calls not allowed while in memory mode. */
/** @cond INTERNAL */
SPIFI_ERR_LASTINDEX /* Internal use to count number of errors */
/** @endcond */
} SPIFI_ERR_T;
/**
* @brief Possible device capabilities returned from getInfo()
*/
#define SPIFI_CAP_DUAL_READ (1 << 0) /**< Supports DUAL read mode */
#define SPIFI_CAP_DUAL_WRITE (1 << 1) /**< Supports DUAL write mode */
#define SPIFI_CAP_QUAD_READ (1 << 2) /**< Supports QUAD read mode */
#define SPIFI_CAP_QUAD_WRITE (1 << 3) /**< Supports QUAD write mode */
#define SPIFI_CAP_FULLLOCK (1 << 4) /**< Full device lock supported */
#define SPIFI_CAP_BLOCKLOCK (1 << 5) /**< Individual block device lock supported */
#define SPIFI_CAP_SUBBLKERASE (1 << 6) /**< Sub-block erase supported */
#define SPIFI_CAP_4BYTE_ADDR (1 << 7) /**< Supports 4 Byte addressing */
#define SPIFI_CAP_NOBLOCK (1 << 16) /**< Non-blocking mode supported */
/**
* @brief Possible driver options, may not be supported by all drivers
*/
#define SPIFI_OPT_USE_DUAL (3 << 0) /**< Enable DUAL read / write if option is supported */
#define SPIFI_OPT_USE_QUAD (3 << 2) /**< Enable QUAD read / write if option is supported */
#define SPIFI_OPT_NOBLOCK (1 << 16) /**< Will not block on program and erase operations, poll device status manually */
/**
* @brief Possible device statuses returned from getInfo()
*/
#define SPIFI_STAT_BUSY (1 << 0) /**< Device is busy erasing or programming */
#define SPIFI_STAT_ISWP (1 << 1) /**< Device is write protected (software or hardware) */
#define SPIFI_STAT_FULLLOCK (1 << 2) /**< Device is fully locked */
#define SPIFI_STAT_PARTLOCK (1 << 3) /**< Device is partially locked (device specific) */
#define SPIFI_STAT_PROGERR (1 << 4) /**< Device status shows a program error (non-blocking mode only) */
#define SPIFI_STAT_ERASEERR (1 << 5) /**< Device status shows a erase error (non-blocking mode only) */
/**
* @brief Possible info lookup requests
*/
typedef enum {
SPIFI_INFO_BASE_ADDRESS = 0, /**< Device physical memory address */
SPIFI_INFO_DEVSIZE, /**< Device size in Bytes */
SPIFI_INFO_ERASE_BLOCKS, /**< Number of erase blocks */
SPIFI_INFO_ERASE_BLOCKSIZE, /**< Size of erase blocks */
SPIFI_INFO_ERASE_SUBBLOCKS, /**< Number of erase sub-blocks */
SPIFI_INFO_ERASE_SUBBLOCKSIZE, /**< Size of erase sub-blocks */
SPIFI_INFO_PAGESIZE, /**< Size of a page, page write size limit */
SPIFI_INFO_MAXREADSIZE, /**< Maximum read size, read size limit in bytes */
SPIFI_INFO_MAXCLOCK, /**< Maximum device speed in Hz */
SPIFI_INFO_MAX_READ_CLOCK, /**< Maximum device speed for read cmd in Hz */
SPIFI_INFO_MAX_HSREAD_CLOCK, /**< Maximum device speed for quad / dual read cmd in Hz */
SPIFI_INFO_MAX_PROG_CLOCK, /**< Maximum device speed for program cmd in Hz */
SPIFI_INFO_MAX_HSPROG_CLOCK, /**< Maximum device speed for quad program cmd in Hz */
SPIFI_INFO_CAPS, /**< Device capabilities, OR'ed SPIFI_CAP_* values */
SPIFI_INFO_STATUS, /**< Or'ed SPIFI_STAT_xxx values. Any persistent hardware bits will be cleared */
SPIFI_INFO_STATUS_RETAIN, /**< Or'ed SPIFI_STAT_xxx values. Any persistent hardware bits will be retained */
SPIFI_INFO_OPTIONS, /**< Device capabilities, Or'ed SPIFI_OPT_* values */
SPIFI_INFO_LASTINDEX
} SPIFI_INFO_ID_T;
/**
* @brief SPIFI_INFO_QUADREAD_CLOCK Depricated! Do NOT use for new development
*/
#define SPIFI_INFO_QUADREAD_CLOCK SPIFI_INFO_MAX_HSREAD_CLOCK
/**
* @brief SPIFI_INFO_QUADPROG_CLOCK Depricated! Do NOT use for new development
*/
#define SPIFI_INFO_QUADPROG_CLOCK SPIFI_INFO_MAX_HSPROG_CLOCK
/**
* @brief Possible device specific lock / un-lock commands
*/
typedef enum {
SPIFI_PCMD_UNLOCK_DEVICE = 0, /**< unlock device */
SPIFI_PCMD_LOCK_DEVICE, /**< lock device */
SPIFI_PCMD_UNLOCK_BLOCK, /**< unlock specified block */
SPIFI_PCMD_LOCK_BLOCK /**< lock specified block */
} SPIFI_PCMD_LOCK_UNLOCK_T;
/**
* @brief Possible device specific sub-block commands
*/
typedef enum {
SPIFI_PCMD_ADDR_TO_SUB_BLOCK = 0, /**< Convert address to a sub-block */
SPIFI_PCMD_SUB_BLOCK_TO_ADDR, /**< Convert sub-block to address */
SPIFI_PCMD_BLOCK_TO_SUB_BLOCK /**< Convert block to sub-block */
} SPIFI_PCMD_SUBBLK_T;
/**
* @brief Enumeration of device specific functions.
*/
typedef enum {
FX_spifiDeviceDataInitDeinit = 0, /**< Generic device init / de-init function */
FX_spifiDeviceDataInitDeinitS25FL164K, /**< S25FL164K specific device init / de-init function */
FX_spifiDeviceDataClearStatusNone, /**< General do nothing I.e no status bits to clear */
FX_spifiDeviceDataClearStatusS25FL032P, /**< S25FL032P (and similar) clear status bits function */
FX_spifiDeviceDataGetStatusS25FL032P, /**< S25FL032P (and similar) get status function */
FX_spifiDeviceDataGetStatusS25FL164K, /**< S25FL164K (and similar) get status function */
FX_spifiDeviceDataGetStatusMX25L3235E, /**< MX25L3235E (and similar) get status function */
FX_spifiDeviceDataGetStatusW25Q80BV, /**< W25Q80BV (and similar) get status function */
FX_spifiDeviceDataSetStatusS25FL032P, /**< S25FL032P (and similar) set status function */
FX_spifiDeviceDataSetStatusS25FL164K, /**< S25FL164K (and similar) set status function */
FX_spifiDeviceDataSetStatusMX25L3235E, /**< MX25L3235E (and similar) set sttus function */
FX_spifiDeviceDataSetOptsQuadModeBit9, /**< Set bit 9 when enabling Quad mode */
FX_spifiDeviceDataSetOptsQuadModeBit6, /**< Set bit 6 when enabling Quad mode */
FX_spifiDeviceInitReadCommand, /**< General return cmdReg value for read */
FX_spifiDevice4BInitReadCommand, /**< General return cmdReg value for read w/ 4Byte address */
FX_spifiDeviceInitWriteCommand, /**< General return cmdReg value for write */
FX_spifiDevice4BInitWriteCommand, /**< General return cmdReg value for write w/ 4Byte address */
FX_spifiDeviceInitWriteCommandMacronix /**< Macronix return cmdReg value for write */
} SPIFI_DEVFX_T;
/* Forward type declaration */
struct SPIFI_HANDLE;
struct SPIFI_DEVICE_DATA;
struct SPIFI_FAM_DESC;
struct SPIFI_DEVICE_ID;
/**
* @brief LPCSPIFILIB family data.
*/
typedef struct SPIFI_FAM_NODE {
const struct SPIFI_FAM_DESC *pDesc; /**< Pointer to device descriptor */
struct SPIFI_FAM_NODE *pNext; /**< Reserved list pointer */
} SPIFI_FAM_NODE_T;
/**
* @brief LPCSPIFILIB family descriptor, used to describe devices to non-device specific functions
*/
typedef struct SPIFI_FAM_DESC {
const char *pFamName; /**< (required) Pointer to generic family name */
struct SPIFI_DEV_NODE *pDevList; /**< (required) Pointer to device list */
uint32_t prvContextSize; /**< Number of bytes needed for driver context allocation */
uint32_t *pDevCount; /**< (required) Pointer to device count */
void (*pPrvDevGetID)(uint32_t baseAddr, struct SPIFI_DEVICE_ID *pID); /**< (NULL allowed) Pointer to method that queries deviceID */
SPIFI_ERR_T (*pPrvDevSetup)(struct SPIFI_HANDLE *pHandle, uint32_t spifiCtrlAddr, uint32_t baseAddr); /**< (required) Pointer to device specific device initialization */
} SPIFI_FAM_DESC_T;
/**
* @brief Register device data node
*/
typedef struct SPIFI_DEV_NODE {
const struct SPIFI_DEVICE_DATA *pDevData; /**< (required) Pointer to device specific data */
struct SPIFI_DEV_NODE *pNext; /**< Reserved */
} SPIFI_DEV_NODE_T;
typedef SPIFI_ERR_T (*deviceInitDeInitFx)(const struct SPIFI_HANDLE *, uint32_t); /**< Fx* to handle init / de-init */
typedef void (*devClearStatusFx)(const struct SPIFI_HANDLE *); /**< Fx* to clear status */
typedef uint32_t (*devGetStatusFx)(const struct SPIFI_HANDLE *); /**< Fx* to get status */
typedef void (*devSetStatusFx)(const struct SPIFI_HANDLE *, uint32_t); /**< Fx* to set status */
typedef SPIFI_ERR_T (*devSetOptsFx)(const struct SPIFI_HANDLE *, uint32_t, uint32_t); /**< Fx* to set options */
typedef void (*devGetReadCmdFx)(const struct SPIFI_HANDLE *, uint8_t, uint32_t *, uint32_t *); /**< Fx* to return read commandReg value */
typedef void (*devGetWriteCmdFx)(const struct SPIFI_HANDLE *, uint32_t *); /**< Fx* to return write commandReg value */
/**
* @brief Device specific function pointers
*/
typedef struct SPIFI_FAM_FX {
/* Device init and de-initialization */
SPIFI_ERR_T (*lockCmd)(const struct SPIFI_HANDLE *, SPIFI_PCMD_LOCK_UNLOCK_T, uint32_t); /**< (required) Lock / unlock handler */
SPIFI_ERR_T (*eraseAll)(const struct SPIFI_HANDLE *); /**< (required) Full device erase */
SPIFI_ERR_T (*eraseBlock)(const struct SPIFI_HANDLE *, uint32_t); /**< (required) Erase a block by block number */
SPIFI_ERR_T (*eraseSubBlock)(const struct SPIFI_HANDLE *, uint32_t); /**< (required) Erase a sub-block by block number */
SPIFI_ERR_T (*pageProgram)(const struct SPIFI_HANDLE *, uint32_t, const uint32_t *, uint32_t); /**< (required) Program up to a page of data at an address */
SPIFI_ERR_T (*read)(const struct SPIFI_HANDLE *, uint32_t, uint32_t *, uint32_t); /**< (required) Read an address range */
SPIFI_ERR_T (*reset)(const struct SPIFI_HANDLE *); /**< (required) Reset SPIFI device */
/* Info query functions */
uint32_t (*getStatus)(const struct SPIFI_HANDLE *, uint8_t); /**< (required) Returns device status */
uint32_t (*subBlockCmd)(const struct SPIFI_HANDLE *, SPIFI_PCMD_SUBBLK_T, uint32_t); /**< (NULL allowed) Performs specified cmd */
/* Device specific functions */
deviceInitDeInitFx devInitDeInit; /**< run-time assigned Fx* device init de-init */
devClearStatusFx devClearStatus; /**< run-time assigned Fx* to clear status */
devGetStatusFx devGetStatus; /**< run-time assigned Fx* to get status */
devSetStatusFx devSetStatus; /**< run-time assigned Fx* to set status */
devSetOptsFx devSetOpts; /**< run-time assigned Fx* to set quad mode */
devGetReadCmdFx devGetReadCmd; /**< run-time assigned Fx* to return read cmd */
devGetWriteCmdFx devGetWriteCmd; /**< run-time assigned Fx* to return write cmd */
} SPIFI_FAM_FX_T;
/**
* @brief Device identification data
*/
typedef struct SPIFI_DEVICE_ID {
uint8_t mfgId[3]; /**< JEDEC ID data */
uint8_t extCount; /**< Number of extended bytes to check */
uint8_t extId[8]; /**< extended data */
} SPIFI_DEVICE_ID_T;
/**
* @brief Register device data.
*/
typedef struct SPIFI_DEVICE_DATA {
const char *pDevName; /**< (required) Device friendly name */
SPIFI_DEVICE_ID_T id; /**< Device id structure */
uint32_t caps; /**< capabilities supported */
uint16_t blks; /**< # of blocks */
uint32_t blkSize; /**< size of block */
uint16_t subBlks; /**< # of sub-blocks */
uint16_t subBlkSize; /**< size of sub-block */
uint16_t pageSize; /**< page size */
uint32_t maxReadSize; /**< max read allowed in one operation */
uint8_t maxClkRate; /**< (in Mhz) maximum clock rate (max common speed) */
uint8_t maxReadRate; /**< (in Mhz) max clock rate for read (driver may utilize fast read) */
uint8_t maxHSReadRate; /**< (in Mhz) max clock rate for quad / dual read */
uint8_t maxProgramRate; /**< (in Mhz) max clock rate for program */
uint8_t maxHSProgramRate; /**< (in Mhz) max clock rate for quad program */
uint8_t initDeInitFxId; /**< init/DeInit fx_id */
uint8_t clearStatusFxId; /**< clearStatus fx_id */
uint8_t getStatusFxId; /**< getStatus fx_id */
uint8_t setStatusFxId; /**< setStatus fx_id */
uint8_t setOptionsFxId; /**< setOptions fx_id */
uint8_t getReadCmdFxId; /**< getReadCommand fx_id */
uint8_t getWriteCmdFxId; /**< getWriteCommand fx_id */
} SPIFI_DEVICE_DATA_T;
/**
* @brief LPCSPIFILIB device handle, used with all device and info functions
*/
typedef struct SPIFI_HANDLE {
const struct SPIFI_FAM_FX *pFamFx; /**< (required) Pointer to device specific functions */
struct SPIFI_INFODATA *pInfoData; /**< (required) Pointer to info data area */
void *pDevContext; /**< (NULL allowed) Pointer to device context (used by device functions) */
} SPIFI_HANDLE_T;
/**
* @brief Common data applicable to all devices
*/
typedef struct SPIFI_INFODATA {
uint32_t spifiCtrlAddr; /**< SPIFI controller base address */
uint32_t baseAddr; /**< Physical base address for the device */
uint32_t numBlocks; /**< Number of blocks on the device */
uint32_t blockSize; /**< Size of blocks on the device */
uint32_t numSubBlocks; /**< Number of sub-blocks on the device */
uint32_t subBlockSize; /**< Size of sub-blocks on the device */
uint32_t pageSize; /**< Size of a page, usually denotes maximum write size in bytes for a single write operation */
uint32_t maxReadSize; /**< Maximum read size in bytes for a single read operation */
const struct SPIFI_DEVICE_DATA *pDeviceData; /**< (required) Pointer to device specific data */
uint32_t opts; /**< Device options of values SPIFI_OPT_* */
const char *pDevName; /**< (required) Pointer to device name */
SPIFI_ERR_T lastErr; /**< Last error for the driver */
const SPIFI_DEVICE_ID_T *pId; /**< (required) Device id structure (JEDEC ID etc) */
} SPIFI_INFODATA_T;
/**
* @brief Context for enumerating devices
*/
typedef struct SPIFI_DEV_ENUMERATOR {
SPIFI_FAM_NODE_T *pFamily; /**< pointer to family node */
SPIFI_DEV_NODE_T *pDevice; /**< pointer to device structure */
} SPIFI_DEV_ENUMERATOR_T;
/**
* @}
*/
/** @defgroup LPCSPIFILIB_REGISTERHELPER LPCSPIFILIB family registration functions
* @ingroup LPCSPIFILIB
* @{
*/
/**
* @brief Family registration function
* @return A pointer to a persistent SPIFI_DEV_FAMILY_T initialized for family.
* @note This function constructs and returns a non-volitile SPIFI_DEV_FAMILY_T
* structure that contains family specific information needed to register family.
* This function MUST NOT be called directly and should only be passed to the
* registration function spifiRegisterFamily()
*/
SPIFI_FAM_NODE_T *spifi_REG_FAMILY_CommonCommandSet(void);
/**
* @brief SPIFI_REG_FAMILY_Spansion_2Byte_PStatus Depricated! Do NOT use for new development
*/
#define SPIFI_REG_FAMILY_Spansion_2Byte_PStatus spifi_REG_FAMILY_CommonCommandSet
/**
* @brief SPIFI_REG_FAMILY_Spansion_3Byte_Status Depricated! Do NOT use for new development
*/
#define SPIFI_REG_FAMILY_Spansion_3Byte_Status spifi_REG_FAMILY_CommonCommandSet
/**
* @brief SPIFI_REG_FAMILY_Macronix_2Byte_Status Depricated! Do NOT use for new development
*/
#define SPIFI_REG_FAMILY_Macronix_2Byte_Status spifi_REG_FAMILY_CommonCommandSet
/**
* @brief SPIFI_REG_FAMILY_SpansionS25FLP Depricated! Do NOT use for new development
*/
#define SPIFI_REG_FAMILY_SpansionS25FLP spifi_REG_FAMILY_CommonCommandSet
/**
* @brief SPIFI_REG_FAMILY_SpansionS25FL1 Depricated! Do NOT use for new development
*/
#define SPIFI_REG_FAMILY_SpansionS25FL1 spifi_REG_FAMILY_CommonCommandSet
/**
* @brief SPIFI_REG_FAMILY_MacronixMX25L Depricated! Do NOT use for new development
*/
#define SPIFI_REG_FAMILY_MacronixMX25L spifi_REG_FAMILY_CommonCommandSet
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __SPIFILIB_DEV_H_ */

View File

@ -0,0 +1,32 @@
<!-- liblinks.xml
Code Red Technologies "Smart update wizard" script file
When executed on a particular application project, will
add appropriate links to the specified library project.
Note that this script assumes that the application project
contains the standard 'Debug' and 'Release' build
configurations.
-->
<project name="" update="true">
<setting id="all.compiler.inc">
<value>${workspace_loc:/spifilib_m4f_hard/inc}</value>
</setting>
<setting id="assembler.inc">
<value>${workspace_loc:/spifilib_m4f_hard/inc}</value>
</setting>
<setting id="linker.libs">
<value>spifilib_m4f_hard</value>
</setting>
<setting id="linker.paths" buildType="Debug">
<value>${workspace_loc:/spifilib_m4f_hard/Debug}</value>
</setting>
<setting id="linker.paths" buildType="Release">
<value>${workspace_loc:/spifilib_m4f_hard/Release}</value>
</setting>
<requires msg="Library project `spifilib_m4f_hard` not found">
<value>spifilib_m4f_hard</value>
</requires>
</project>

View File

@ -0,0 +1,39 @@
############################################################################
# configs/lpc4330-xplorer/src/Makefile
#
# Copyright (C) 2015 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name NuttX nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
ifeq ($(CONFIG_SPIFI_LIBRARY),y)
CHIP_CSRCS += spifi/src/spifilib_fam_standard_cmd.c
CHIP_CSRCS += spifi/src/spifilib_dev_common.c
endif

View File

@ -0,0 +1,864 @@
/*
* @brief LPCSPIFILIB driver functions and structures that are not visible
*
* @note
* Copyright(C) NXP Semiconductors, 2014
* All rights reserved.
*
* @par
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products. This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licenser disclaim any and
* all warranties, express or implied, including all implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of
* intellectual property rights. NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
*
* @par
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, under NXP Semiconductors' and its
* licensor's relevant copyrights in the software, without fee, provided that it
* is used in conjunction with NXP Semiconductors microcontrollers. This
* copyright, permission, and disclaimer notice must appear in all copies of
* this code.
*/
#include "spifi/inc/spifilib_api.h"
#include "spifi/inc/private/spifilib_chiphw.h"
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
#ifndef NULL
#define NULL 0L
#endif
/* Declare the version numbers */
#define LIBRARY_VERSION_MAJOR (1)
#define LIBRARY_VERSION_MINOR (03)
/* device node count and linked list header */
static uint32_t famCount = 0;
static SPIFI_FAM_NODE_T famListHead = {0};
/* Generic device OP Codes */
#define SPIFI_OP_CODE_RDID 0x9F
/* Number of supported devices */
#define NUMSUPPDEVS (sizeof(pPrvDevs) / sizeof(SPIFI_DEVDESC_T *))
/* Mapped error strings to error codes */
static const char *spifiErrStrings[SPIFI_ERR_LASTINDEX] = {
"No error",
"Device is busy",
"General error",
"Capability not supported",
"Alignment error",
"Device is locked",
"Program error",
"Erase error",
"Program region not blank",
"Page size exceeded",
"Validation error",
"Range exceeded",
"Not Allowed in Memory Mode"
};
static const char noName[] = "Invalid index";
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
/*****************************************************************************
* Private functions
****************************************************************************/
static uint8_t spifiPrvCheckExtendedMatch(SPIFI_DEV_NODE_T *pNode, SPIFI_DEVICE_ID_T *pID)
{
uint32_t x;
if (pID->extCount != pNode->pDevData->id.extCount) {
return 0;
}
if (pNode->pDevData->id.extCount) {
for (x = 0; x < pID->extCount; ++x) {
if (pNode->pDevData->id.extId[x] != pID->extId[x]) {
return 0;
}
}
}
return 1;
}
static SPIFI_DEV_NODE_T *spifiPrvFindDeviceMatch(SPIFI_DEV_NODE_T *pHead, SPIFI_DEVICE_ID_T *pID, uint8_t checkExtended)
{
SPIFI_DEV_NODE_T *pNode;
/* search the list looking for a match. Skip over head node since
it is a dummy node and NEVER contains data */
for (pNode = pHead->pNext; pNode != NULL; pNode = pNode->pNext) {
/* Manufacturer and part match? */
if ((pID->mfgId[0] == pNode->pDevData->id.mfgId[0]) &&
(pID->mfgId[1] == pNode->pDevData->id.mfgId[1]) &&
(pID->mfgId[2] == pNode->pDevData->id.mfgId[2])) {
/* If extended data check it */
uint8_t matchFound = 1;
if (checkExtended) {
matchFound = spifiPrvCheckExtendedMatch(pNode, pID);
}
/* Match, time to exit */
if (matchFound) {
return pNode;
}
}
}
return NULL;
}
/* Read Identification */
static void spifiPrvDevGetID(uint32_t spifiAddr, SPIFI_DEVICE_ID_T *pID)
{
uint8_t idx;
LPC_SPIFI_CHIPHW_T *pSpifiCtrlAddr = (LPC_SPIFI_CHIPHW_T *) spifiAddr;
/* Read ID command, plus read 3 bytes on data */
spifi_HW_SetCmd(pSpifiCtrlAddr,
(SPIFI_CMD_OPCODE(SPIFI_OP_CODE_RDID) |
SPIFI_CMD_DATALEN(3 + pID->extCount) |
SPIFI_CMD_FIELDFORM(SPIFI_FIELDFORM_ALL_SERIAL) |
SPIFI_CMD_FRAMEFORM(SPIFI_FRAMEFORM_OP)));
/* Get info from the device */
pID->mfgId[0] = spifi_HW_GetData8(pSpifiCtrlAddr); /* Manufacturers ID */
pID->mfgId[1] = spifi_HW_GetData8(pSpifiCtrlAddr); /* Memory Type */
pID->mfgId[2] = spifi_HW_GetData8(pSpifiCtrlAddr); /* Memmory Capacity */
/* Read the specified number of extended bytes */
for (idx = 0; idx < pID->extCount; ++idx) {
pID->extId[idx] = spifi_HW_GetData8(pSpifiCtrlAddr);
}
spifi_HW_WaitCMD(pSpifiCtrlAddr);
}
/* Detect if this device exists at the passed base address, returns 0 if the
device doesn't exist of the required memory allocation size for the device
context if the device exists. */
static SPIFI_DEV_NODE_T *spifiPrvDevDetect(uint32_t spifiCtrlAddr, SPIFI_FAM_NODE_T *familyNode)
{
SPIFI_DEV_NODE_T *devNode;
uint32_t idx;
SPIFI_DEVICE_ID_T id;
SPIFI_DEVICE_ID_T idVerify;
void (*pPrvspifiPrvDevGetID)(uint32_t baseAddr, SPIFI_DEVICE_ID_T *pID) = spifiPrvDevGetID;
/* Do not ask for extended ID information yet */
id.extCount = 0;
idVerify.extCount = 0;
/* If the family has a specific readID routine, use it instead */
if (familyNode->pDesc->pPrvDevGetID) {
pPrvspifiPrvDevGetID = familyNode->pDesc->pPrvDevGetID;
}
/* Read device ID three times to validate. First read on a hard reset isn't reliable */
pPrvspifiPrvDevGetID(spifiCtrlAddr, &id);
pPrvspifiPrvDevGetID(spifiCtrlAddr, &id);
pPrvspifiPrvDevGetID(spifiCtrlAddr, &idVerify);
/* Compare both reads to make sure they match. If any byte doesn't compare, abort. */
for (idx = 0; idx < sizeof(id.mfgId); ++idx) {
if (id.mfgId[idx] != idVerify.mfgId[idx]) {
return NULL;
}
}
/* Find match for 3 bytes. If found, check to see if there is extended id information */
devNode = spifiPrvFindDeviceMatch(familyNode->pDesc->pDevList, &id, 0);
if ((devNode) && (devNode->pDevData->id.extCount)) {
/* read ID + extended ID data */
id.extCount = devNode->pDevData->id.extCount;
pPrvspifiPrvDevGetID(spifiCtrlAddr, &id);
/* Now get the node that matches JEDEC and extended data */
devNode = spifiPrvFindDeviceMatch(familyNode->pDesc->pDevList, &id, 1);
}
return devNode;
}
/* Detect first SPIFI FLASH device at the passed base address */
static SPIFI_FAM_NODE_T *spifiPrvPartDetect(uint32_t spifiCtrlAddr, SPIFI_DEV_NODE_T * *devData)
{
SPIFI_FAM_NODE_T *pNode;
/* Loop through the library and check for detected devices.
skip over head node because it is NEVER used. */
for (pNode = famListHead.pNext; pNode != NULL; pNode = pNode->pNext) {
/* Match at this index */
if ((*devData = spifiPrvDevDetect(spifiCtrlAddr, pNode)) != NULL) {
return pNode;
}
}
return NULL;
}
static uint32_t spifiPrvCalculateHandleSize(SPIFI_FAM_NODE_T *devData)
{
/* This is the size needed for the device context instance by the driver */
return sizeof(SPIFI_HANDLE_T) + sizeof(SPIFI_INFODATA_T) +
devData->pDesc->prvContextSize;
}
static void *spifiPrvMemset(void *bufPtr, uint8_t value, uint32_t count)
{
uint8_t *dest = (uint8_t *) bufPtr;
uint32_t index;
for (index = 0; index < count; ++index) {
dest[index] = value;
}
return bufPtr;
}
static void spifiPrvInitContext(SPIFI_DEV_ENUMERATOR_T *pContext, SPIFI_FAM_NODE_T *pFamily)
{
/* Save the new family passed */
pContext->pFamily = pFamily;
/* Save pointer to device or NULL if No devices */
if (pFamily) {
pContext->pDevice = pFamily->pDesc->pDevList->pNext;
}
else {
pContext->pDevice = NULL;
}
}
/*****************************************************************************
* Public functions
****************************************************************************/
SPIFI_FAM_NODE_T *spifiRegisterFamily(SPIFI_FAM_NODE_T *(*regFx)(void))
{
SPIFI_FAM_NODE_T *pFam;
/* Get the family node from the user */
pFam = regFx();
/* If not a valid family return NULL and don't process */
if (!pFam) {
return NULL;
}
/* Insert the node into the beginning of the list */
pFam->pNext = famListHead.pNext;
famListHead.pNext = pFam;
/* update the count of known families */
++famCount;
/* Return handle */
return pFam;
}
/* register a device (i.e append to the list of known devices) */
SPIFI_ERR_T spifiDevRegister(const SPIFI_FAM_NODE_T *pDevFamily, SPIFI_DEV_NODE_T *pDevData)
{
/* insert into the beginning of the list */
pDevData->pNext = pDevFamily->pDesc->pDevList->pNext;
pDevFamily->pDesc->pDevList->pNext = pDevData;
/* update the number of devices in the list */
(*pDevFamily->pDesc->pDevCount) += 1;
/* Nothing to do here yet */
return SPIFI_ERR_NONE;
}
/* enumerate the friendly names of supported devices */
const char *spifiDevEnumerateName(SPIFI_DEV_ENUMERATOR_T *pContext, uint8_t reset)
{
const char *retValue = NULL;
/* If user requested reset, point back to the beginning of the list */
if (reset) {
/* Initialize the device list from new family */
spifiPrvInitContext(pContext, famListHead.pNext);
}
/* Now get the friendly name of the current device and increment to the next device. */
if (pContext->pDevice) {
/* Retrieve friendly name */
retValue = pContext->pDevice->pDevData->pDevName;
/* Point at next device */
pContext->pDevice = pContext->pDevice->pNext;
/* Point at next family if at end of device list */
if (!pContext->pDevice) {
/* Initialize the device list from new family */
spifiPrvInitContext(pContext, pContext->pFamily->pNext);
}
}
return retValue;
}
/* Report the library version number */
uint16_t spifiGetLibVersion(void)
{
return (LIBRARY_VERSION_MAJOR << 8) | LIBRARY_VERSION_MINOR;
}
/* Initialize the SPIFILIB driver */
SPIFI_ERR_T spifiInit(uint32_t spifiCtrlAddr, uint8_t reset)
{
LPC_SPIFI_CHIPHW_T *pSpifiCtrlAddr = (LPC_SPIFI_CHIPHW_T *) spifiCtrlAddr;
if (reset) {
/* Reset controller */
spifi_HW_ResetController(pSpifiCtrlAddr);
/* Set intermediate data and memcmd registers. */
spifi_HW_SetIDATA(pSpifiCtrlAddr, 0x0);
spifi_HW_SetMEMCMD(pSpifiCtrlAddr, 0);
spifi_HW_ResetController(pSpifiCtrlAddr);
/* Setup SPIFI controller */
spifi_HW_SetCtrl(pSpifiCtrlAddr,
(SPIFI_CTRL_TO(1000) |
SPIFI_CTRL_CSHI(15) |
SPIFI_CTRL_RFCLK(1) |
SPIFI_CTRL_FBCLK(1)));
}
/* Nothing to do here yet */
return SPIFI_ERR_NONE;
}
/* performs device specific initialization */
SPIFI_ERR_T spifiDevInit(const SPIFI_HANDLE_T *pHandle)
{
SPIFI_ERR_T retValue = SPIFI_ERR_NONE;
/* call device specific initialization if provided */
pHandle->pFamFx->devInitDeInit(pHandle, 1);
/* make sure the controller is not in memMode */
spifiDevSetMemMode(pHandle, 0);
return retValue;
}
/* performs device specific de-initialization */
SPIFI_ERR_T spifiDevDeInit(const SPIFI_HANDLE_T *pHandle)
{
SPIFI_ERR_T retValue = SPIFI_ERR_NONE;
/* call device specific de-init if provided */
pHandle->pFamFx->devInitDeInit(pHandle, 0);
/* make sure the controller is in memMode */
spifiDevSetMemMode(pHandle, 1);
return retValue;
}
/* Converts a SPIFILIB error code into a meaningful string */
const char *spifiReturnErrString(SPIFI_ERR_T errCode)
{
if (((unsigned int) errCode) < SPIFI_ERR_LASTINDEX) {
return spifiErrStrings[errCode];
}
return noName;
}
/* Returns information on the device */
uint32_t spifiDevGetInfo(const SPIFI_HANDLE_T *pHandle, SPIFI_INFO_ID_T infoId)
{
uint32_t val = 0;
/* Don't use switch statement to prevent including clib helpers */
if (infoId == SPIFI_INFO_BASE_ADDRESS) {
val = pHandle->pInfoData->baseAddr;
}
else if (infoId == SPIFI_INFO_DEVSIZE) {
val = pHandle->pInfoData->numBlocks * pHandle->pInfoData->blockSize;
}
else if (infoId == SPIFI_INFO_ERASE_BLOCKS) {
val = pHandle->pInfoData->numBlocks;
}
else if (infoId == SPIFI_INFO_ERASE_BLOCKSIZE) {
val = pHandle->pInfoData->blockSize;
}
else if (infoId == SPIFI_INFO_ERASE_SUBBLOCKS) {
val = pHandle->pInfoData->numSubBlocks;
}
else if (infoId == SPIFI_INFO_ERASE_SUBBLOCKSIZE) {
val = pHandle->pInfoData->subBlockSize;
}
else if (infoId == SPIFI_INFO_PAGESIZE) {
val = pHandle->pInfoData->pageSize;
}
else if (infoId == SPIFI_INFO_MAXREADSIZE) {
val = pHandle->pInfoData->maxReadSize;
}
else if (infoId == SPIFI_INFO_MAXCLOCK) {
val = (pHandle->pInfoData->pDeviceData->maxClkRate * 1000000);
}
else if (infoId == SPIFI_INFO_MAX_READ_CLOCK) {
val = (pHandle->pInfoData->pDeviceData->maxReadRate * 1000000);
}
else if (infoId == SPIFI_INFO_MAX_HSREAD_CLOCK) {
val = (pHandle->pInfoData->pDeviceData->maxHSReadRate * 1000000);
}
else if (infoId == SPIFI_INFO_MAX_PROG_CLOCK) {
val = (pHandle->pInfoData->pDeviceData->maxProgramRate * 1000000);
}
else if (infoId == SPIFI_INFO_MAX_HSPROG_CLOCK) {
val = (pHandle->pInfoData->pDeviceData->maxHSProgramRate * 1000000);
}
else if (infoId == SPIFI_INFO_CAPS) {
val = pHandle->pInfoData->pDeviceData->caps;
}
else if (infoId == SPIFI_INFO_STATUS) {
val = pHandle->pFamFx->getStatus(pHandle, 1);
}
else if (infoId == SPIFI_INFO_STATUS_RETAIN) {
val = pHandle->pFamFx->getStatus(pHandle, 0);
}
else if (infoId == SPIFI_INFO_OPTIONS) {
val = pHandle->pInfoData->opts;
}
return val;
}
/* Returns status of memory mode */
uint8_t spifiDevGetMemoryMode(const SPIFI_HANDLE_T *pHandle)
{
LPC_SPIFI_CHIPHW_T *pSpifiCtrlAddr = (LPC_SPIFI_CHIPHW_T *) pHandle->pInfoData->spifiCtrlAddr;
return (spifi_HW_GetStat(pSpifiCtrlAddr) & SPIFI_STAT_MCINIT) != 0;
}
SPIFI_ERR_T spifiDevSetMemMode(const SPIFI_HANDLE_T *pHandle, uint8_t enMMode)
{
uint32_t cmdValue;
uint32_t iDataValue;
uint32_t ctrlReg;
LPC_SPIFI_CHIPHW_T *pSpifiCtrlAddr = (LPC_SPIFI_CHIPHW_T *) pHandle->pInfoData->spifiCtrlAddr;
/* RESET the memMode controller */
spifi_HW_ResetController(pSpifiCtrlAddr);
/* Wait for HW to acknowledge the reset. */
spifi_HW_WaitRESET(pSpifiCtrlAddr);
/* First off set the HW mode based on current option */
ctrlReg = spifi_HW_GetCtrl(pSpifiCtrlAddr);
if (pHandle->pInfoData->opts & SPIFI_CAP_QUAD_READ) {
ctrlReg &= ~(SPIFI_CTRL_DUAL(1));
}
else if (pHandle->pInfoData->opts & SPIFI_CAP_DUAL_READ) {
ctrlReg |= SPIFI_CTRL_DUAL(1);
}
spifi_HW_SetCtrl(pSpifiCtrlAddr, ctrlReg);
if (enMMode) {
/* Get the device specific memory mode command and iData values */
pHandle->pFamFx->devGetReadCmd(pHandle, enMMode, &cmdValue, &iDataValue);
/* Specify the intermediate data byte. */
spifi_HW_SetIDATA(pSpifiCtrlAddr, iDataValue);
/* Set the appropriate values in the command reg. */
spifi_HW_SetCmd(pSpifiCtrlAddr, cmdValue);
spifi_HW_WaitCMD(pSpifiCtrlAddr);
spifi_HW_SetMEMCMD(pSpifiCtrlAddr, cmdValue);
}
else {
spifi_HW_SetIDATA(pSpifiCtrlAddr, 0xFF);
spifi_HW_SetMEMCMD(pSpifiCtrlAddr, 0);
/* RESET the memMode controller */
spifi_HW_ResetController(pSpifiCtrlAddr);
/* Wait for HW to acknowledge the reset. */
spifi_HW_WaitRESET(pSpifiCtrlAddr);
}
return SPIFI_ERR_NONE;
}
/* Return the number of supported device families in this driver */
uint32_t spifiGetSuppFamilyCount(void)
{
/* return number of registered devices */
return famCount;
}
/* Return the driver family name for a specific index */
const char *spifiGetSuppFamilyName(uint32_t index)
{
uint32_t idx;
SPIFI_FAM_NODE_T *pNode;
if (index >= famCount) {
return noName;
}
/* cycle through the list of families skipping over head node since it
is NEVER used. Once we break out of this loop pNode should be
pointing at the correct node. */
pNode = famListHead.pNext;
for (idx = 0; idx < index; ++idx) {
pNode = pNode->pNext;
}
return pNode->pDesc->pFamName;
}
/* Detect and return memory needed for device handle at passed address */
uint32_t spifiGetHandleMemSize(uint32_t spifiCtrlAddr)
{
uint32_t bytesNeeded = 0;
SPIFI_FAM_NODE_T *detectedPart;
SPIFI_DEV_NODE_T *devData;
/* Find first device at the base address */
detectedPart = spifiPrvPartDetect(spifiCtrlAddr, &devData);
if (detectedPart) {
/* This is the size needed for the device context instance by the driver */
bytesNeeded = spifiPrvCalculateHandleSize(detectedPart);
}
return bytesNeeded;
}
/* Initialize driver and hardware for a specific device */
SPIFI_HANDLE_T *spifiInitDevice(void *pMem, uint32_t sizePMem, uint32_t spifiCtrlAddr, uint32_t baseAddr)
{
SPIFI_FAM_NODE_T *detectedPart;
SPIFI_DEV_NODE_T *devData;
SPIFI_HANDLE_T *pSpifiHandle;
uint32_t *pMem32 = (uint32_t *) pMem;
/* Is the passed buffer size aligned on a 32-bit boundary? */
if (((uint32_t) pMem32 & 0x3) != 0) {
return NULL;
}
/* Detect the device at at the base address and abort on error. */
detectedPart = spifiPrvPartDetect(spifiCtrlAddr, &devData);
if (!detectedPart) {
return NULL;
}
/* Is passed memory space big enough? */
if (spifiPrvCalculateHandleSize(detectedPart) > sizePMem) {
return NULL;
}
/* Setup handle */
pSpifiHandle = (SPIFI_HANDLE_T *) pMem;
/* Clear entire device context areas */
spifiPrvMemset(pMem, 0, sizePMem);
/* Setup device info region */
pMem32 += (sizeof(SPIFI_HANDLE_T) / sizeof(uint32_t));
pSpifiHandle->pInfoData = (SPIFI_INFODATA_T *) pMem32;
/* Save ptr to the detected device specific data into the handle */
pSpifiHandle->pInfoData->pId = &devData->pDevData->id;
/* Setup device private data region */
pMem32 += (sizeof(SPIFI_INFODATA_T) / sizeof(uint32_t));
pSpifiHandle->pDevContext = (void *) pMem32;
/* Setup device specific data */
pSpifiHandle->pInfoData->spifiCtrlAddr = spifiCtrlAddr;
pSpifiHandle->pInfoData->baseAddr = baseAddr;
pSpifiHandle->pInfoData->numBlocks = devData->pDevData->blks;
pSpifiHandle->pInfoData->blockSize = devData->pDevData->blkSize;
pSpifiHandle->pInfoData->numSubBlocks = devData->pDevData->subBlks;
pSpifiHandle->pInfoData->subBlockSize = devData->pDevData->subBlkSize;
pSpifiHandle->pInfoData->pageSize = devData->pDevData->pageSize;
pSpifiHandle->pInfoData->maxReadSize = devData->pDevData->maxReadSize;
pSpifiHandle->pInfoData->pDeviceData = devData->pDevData;
pSpifiHandle->pInfoData->pDevName = devData->pDevData->pDevName;
/* Call device setup */
pSpifiHandle->pInfoData->lastErr = detectedPart->pDesc->pPrvDevSetup(pSpifiHandle, spifiCtrlAddr, baseAddr);
if (pSpifiHandle->pInfoData->lastErr != SPIFI_ERR_NONE) {
return NULL;
}
/* Call the device specific init */
pSpifiHandle->pInfoData->lastErr = spifiDevInit(pSpifiHandle);
if (pSpifiHandle->pInfoData->lastErr != SPIFI_ERR_NONE) {
return NULL;
}
return pSpifiHandle;
}
SPIFI_ERR_T spifiDevSetOpts(SPIFI_HANDLE_T *pHandle, uint32_t options, uint8_t set)
{
/* default to not supported */
SPIFI_ERR_T retValue = SPIFI_ERR_NOTSUPPORTED;
/* If changing any of the high speed modes process seperately */
if (options & (SPIFI_CAP_DUAL_READ | SPIFI_CAP_DUAL_WRITE | SPIFI_CAP_QUAD_READ | SPIFI_CAP_QUAD_WRITE)) {
uint32_t hsOptions;
uint8_t memMode;
/* first get the current memory mode */
memMode = spifiDevGetMemoryMode(pHandle);
/* First clear ALL high speed mode options */
pHandle->pInfoData->opts &=
~(SPIFI_CAP_DUAL_READ | SPIFI_CAP_DUAL_WRITE | SPIFI_CAP_QUAD_READ | SPIFI_CAP_QUAD_WRITE);
/* sanitize the change list */
hsOptions = options &
(pHandle->pInfoData->pDeviceData->caps &
(SPIFI_CAP_DUAL_READ | SPIFI_CAP_DUAL_WRITE | SPIFI_CAP_QUAD_READ | SPIFI_CAP_QUAD_WRITE));
/* Now set the high speed options */
if (set) {
pHandle->pInfoData->opts |= hsOptions;
}
/* Perform device specific setup for the option */
retValue = pHandle->pFamFx->devSetOpts(pHandle, hsOptions, set);
/* remove so that it won't be interpreted as an error */
options &= ~(SPIFI_CAP_DUAL_READ | SPIFI_CAP_DUAL_WRITE | SPIFI_CAP_QUAD_READ | SPIFI_CAP_QUAD_WRITE);
/* update memory mode when changing the high speed options */
spifiDevSetMemMode(pHandle, memMode);
}
/* If the remaining options are valid, process them */
if ((options & pHandle->pInfoData->pDeviceData->caps) == options) {
retValue = SPIFI_ERR_NONE;
/* Set the option in the driver so other routines will act accordingly */
if (set) {
pHandle->pInfoData->opts |= options;
}
else {
pHandle->pInfoData->opts &= ~options;
}
/* Perform device specific setup for the option if defined */
if (pHandle->pFamFx->devSetOpts) {
retValue = pHandle->pFamFx->devSetOpts(pHandle, options, set);
}
}
return retValue;
}
/* Returns the address mapped to an block number */
uint32_t spifiGetAddrFromBlock(const SPIFI_HANDLE_T *pHandle, uint32_t blockNum)
{
uint32_t baseAddr = 0xFFFFFFFF;
if (blockNum < pHandle->pInfoData->numBlocks) {
baseAddr = pHandle->pInfoData->baseAddr + (blockNum * pHandle->pInfoData->blockSize);
}
return baseAddr;
}
/* Returns the starting address of a sub-block number */
uint32_t spifiGetAddrFromSubBlock(const SPIFI_HANDLE_T *pHandle, uint32_t subBlockNum)
{
uint32_t baseAddr = ~0UL;
/* If the device provides a specific method for calculating the address use it. */
if (!pHandle->pFamFx->subBlockCmd) {
/* If sub-blocks are not supported (.e numSubBlocks = 0) then return error */
if (subBlockNum < pHandle->pInfoData->numSubBlocks) {
baseAddr = pHandle->pInfoData->baseAddr + (subBlockNum * pHandle->pInfoData->subBlockSize);
}
}
else {
baseAddr = pHandle->pFamFx->subBlockCmd(pHandle, SPIFI_PCMD_SUB_BLOCK_TO_ADDR, subBlockNum);
}
return baseAddr;
}
/* Returns the block number the passedd= address is located in */
uint32_t spifiGetBlockFromAddr(const SPIFI_HANDLE_T *pHandle, uint32_t addr)
{
uint32_t block;
block = (addr - pHandle->pInfoData->baseAddr) / pHandle->pInfoData->blockSize;
if (block >= pHandle->pInfoData->numBlocks) {
return ~0UL;
}
return block;
}
/* Returns the sub-block number the passed address is located in */
uint32_t spifiGetSubBlockFromAddr(const SPIFI_HANDLE_T *pHandle, uint32_t addr)
{
uint32_t subBlock;
/* If device does not support sub-blocks return error */
if (!pHandle->pInfoData->subBlockSize) {
return ~0UL;
}
if (!pHandle->pFamFx->subBlockCmd) {
subBlock = (addr - pHandle->pInfoData->baseAddr) / pHandle->pInfoData->subBlockSize;
if (subBlock >= pHandle->pInfoData->numSubBlocks) {
return ~0UL;
}
}
else {
subBlock = pHandle->pFamFx->subBlockCmd(pHandle, SPIFI_PCMD_ADDR_TO_SUB_BLOCK, addr);
}
return subBlock;
}
/* Returns the first sub-block in hte passed block */
uint32_t spifiGetSubBlockFromBlock(const SPIFI_HANDLE_T *pHandle, uint32_t blockNum)
{
uint32_t subBlock = ~0UL;
if (!pHandle->pFamFx->subBlockCmd) {
/* If the blockNum passed is larger than this device,
or if sub-blocks are not supported report error */
if ((blockNum >= pHandle->pInfoData->numBlocks) ||
(!pHandle->pInfoData->subBlockSize)) {
return subBlock;
}
/* Calculate the sub-block number based on detected params */
subBlock = (blockNum * (pHandle->pInfoData->blockSize / pHandle->pInfoData->subBlockSize));
}
else {
subBlock = pHandle->pFamFx->subBlockCmd(pHandle, SPIFI_PCMD_BLOCK_TO_SUB_BLOCK, blockNum);
}
return subBlock;
}
/* Program the device with the passed buffer */
SPIFI_ERR_T spifiProgram(const SPIFI_HANDLE_T *pHandle, uint32_t addr, const uint32_t *writeBuff, uint32_t bytes)
{
uint32_t sendBytes;
SPIFI_ERR_T err = SPIFI_ERR_NONE;
/* Program using up to page size */
while ((bytes > 0) && (err == SPIFI_ERR_NONE)) {
sendBytes = bytes;
if (sendBytes > pHandle->pInfoData->pageSize) {
sendBytes = pHandle->pInfoData->pageSize;
}
err = pHandle->pFamFx->pageProgram(pHandle, addr, writeBuff, sendBytes);
addr += sendBytes;
writeBuff += (sendBytes >> 2);
bytes -= sendBytes;
}
return err;
}
/* Read the device into the passed buffer */
SPIFI_ERR_T spifiRead(const SPIFI_HANDLE_T *pHandle, uint32_t addr, uint32_t *readBuff, uint32_t bytes)
{
uint32_t readBytes;
SPIFI_ERR_T err = SPIFI_ERR_NONE;
/* Read using up to the maximum read size */
while ((bytes > 0) && (err == SPIFI_ERR_NONE)) {
readBytes = bytes;
if (readBytes > pHandle->pInfoData->maxReadSize) {
readBytes = pHandle->pInfoData->maxReadSize;
}
err = pHandle->pFamFx->read(pHandle, addr, readBuff, readBytes);
addr += readBytes;
readBuff += (readBytes / sizeof(uint32_t));
bytes -= readBytes;
}
return err;
}
/* Erase multiple blocks */
SPIFI_ERR_T spifiErase(const SPIFI_HANDLE_T *pHandle, uint32_t firstBlock, uint32_t numBlocks)
{
SPIFI_ERR_T err = SPIFI_ERR_NONE;
if ((firstBlock + numBlocks) > pHandle->pInfoData->numBlocks) {
return SPIFI_ERR_RANGE;
}
/* Only perform erase if numBlocks is != 0 */
for (; (numBlocks); ++firstBlock, --numBlocks) {
err = pHandle->pFamFx->eraseBlock(pHandle, firstBlock);
if (err != SPIFI_ERR_NONE) {
break;
}
}
return err;
}
/* Erase multiple blocks by address range */
SPIFI_ERR_T spifiEraseByAddr(const SPIFI_HANDLE_T *pHandle, uint32_t firstAddr, uint32_t lastAddr)
{
uint32_t firstBlock, lastBlock;
SPIFI_ERR_T err = SPIFI_ERR_RANGE;
/* Get block numbers for addresses */
firstBlock = spifiGetBlockFromAddr(pHandle, firstAddr);
lastBlock = spifiGetBlockFromAddr(pHandle, lastAddr);
/* Limit to legal address range */
if ((firstBlock != ~0UL) && (lastBlock != ~0UL)) {
err = spifiErase(pHandle, firstBlock, ((lastBlock - firstBlock) + 1));
}
return err;
}

File diff suppressed because it is too large Load Diff