spifi
This commit is contained in:
parent
9a527ad3ed
commit
fd74d0b625
@ -178,3 +178,4 @@ CHIP_CSRCS += lpc43_usb0dev.c
|
||||
endif
|
||||
endif
|
||||
|
||||
include chip/spifi/src/Make.defs
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
* isn’t 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;
|
||||
|
175
arch/arm/src/lpc43xx/spifi/.cproject
Normal file
175
arch/arm/src/lpc43xx/spifi/.cproject
Normal 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 "lib${BuildArtifactFileName}" ; # arm-none-eabi-objdump -h -S "lib${BuildArtifactFileName}" >"${BuildArtifactFileBaseName}.lss"">
|
||||
<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=""${workspace_loc:/${ProjName}/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc}/../../inc""/>
|
||||
</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=""${workspace_loc:/${ProjName}/inc}""/>
|
||||
</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 "lib${BuildArtifactFileName}" ; if [ ! -f ../src/spifilib_dev_common.c ] ; then cp lib${BuildArtifactFileName} ../../../../lib/lpcxpresso/. ; fi ; # arm-none-eabi-objdump -h -S "lib${BuildArtifactFileName}" >"${BuildArtifactFileBaseName}.lss"">
|
||||
<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=""${workspace_loc:/${ProjName}/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc}/../../inc""/>
|
||||
</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=""${workspace_loc:/${ProjName}/inc}""/>
|
||||
</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><?xml version="1.0" encoding="UTF-8"?>
|
||||
<TargetConfig>
|
||||
<Properties property_0="" property_3="NXP" property_4="Generic-M4" property_count="5" version="70200"/>
|
||||
<infoList vendor="NXP"><info chip="Generic-M4" match_id="0x0" name="Generic-M4" stub="crt_emu_cm3_gen"><chip><name>Generic-M4</name>
|
||||
<family>Generic-M4</family>
|
||||
<vendor>NXP (formerly Philips)</vendor>
|
||||
<reset board="None" core="Real" sys="Real"/>
|
||||
<clock changeable="TRUE" freq="12MHz" is_accurate="TRUE"/>
|
||||
<memory can_program="true" id="Flash" is_ro="true" type="Flash"/>
|
||||
<memory id="RAM" type="RAM"/>
|
||||
<memory id="Periph" is_volatile="true" type="Peripheral"/>
|
||||
<memoryInstance derived_from="RAM" id="RamLoc" location="0x0" size="0x4000"/>
|
||||
<peripheralInstance derived_from="V7M_MPU" determined="infoFile" id="MPU" location="0xe000ed90"/>
|
||||
<peripheralInstance derived_from="V7M_NVIC" determined="infoFile" id="NVIC" location="0xe000e000"/>
|
||||
<peripheralInstance derived_from="V7M_DCR" determined="infoFile" id="DCR" location="0xe000edf0"/>
|
||||
<peripheralInstance derived_from="V7M_ITM" determined="infoFile" id="ITM" location="0xe0000000"/>
|
||||
</chip>
|
||||
<processor><name gcc_name="cortex-m4">Cortex-M4</name>
|
||||
<family>Cortex-M</family>
|
||||
</processor>
|
||||
<link href="CM3_peripheral.xme" show="embed" type="simple"/>
|
||||
</info>
|
||||
</infoList>
|
||||
</TargetConfig></projectStorage>
|
||||
</storageModule>
|
||||
<storageModule moduleId="refreshScope"/>
|
||||
</cproject>
|
58
arch/arm/src/lpc43xx/spifi/.project
Normal file
58
arch/arm/src/lpc43xx/spifi/.project
Normal 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>
|
135
arch/arm/src/lpc43xx/spifi/changelog.txt
Normal file
135
arch/arm/src/lpc43xx/spifi/changelog.txt
Normal 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.
|
349
arch/arm/src/lpc43xx/spifi/inc/private/spifilib_chiphw.h
Normal file
349
arch/arm/src/lpc43xx/spifi/inc/private/spifilib_chiphw.h
Normal 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_ */
|
438
arch/arm/src/lpc43xx/spifi/inc/spifilib_api.h
Normal file
438
arch/arm/src/lpc43xx/spifi/inc/spifilib_api.h
Normal 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_ */
|
416
arch/arm/src/lpc43xx/spifi/inc/spifilib_dev.h
Normal file
416
arch/arm/src/lpc43xx/spifi/inc/spifilib_dev.h
Normal 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_ */
|
32
arch/arm/src/lpc43xx/spifi/liblinks.xml
Normal file
32
arch/arm/src/lpc43xx/spifi/liblinks.xml
Normal 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>
|
||||
|
39
arch/arm/src/lpc43xx/spifi/src/Make.defs
Normal file
39
arch/arm/src/lpc43xx/spifi/src/Make.defs
Normal 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
|
864
arch/arm/src/lpc43xx/spifi/src/spifilib_dev_common.c
Normal file
864
arch/arm/src/lpc43xx/spifi/src/spifilib_dev_common.c
Normal 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;
|
||||
}
|
1866
arch/arm/src/lpc43xx/spifi/src/spifilib_fam_standard_cmd.c
Normal file
1866
arch/arm/src/lpc43xx/spifi/src/spifilib_fam_standard_cmd.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user