mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
Add SmartFusion2 demo for the SmartFustion2 development kit.
This commit is contained in:
parent
063c05ccad
commit
4d966adc8b
|
@ -0,0 +1,65 @@
|
|||
REM This file should be executed from the command line prior to the first
|
||||
REM build. It will be necessary to refresh the Eclipse project once the
|
||||
REM .bat file has been executed (normally just press F5 to refresh).
|
||||
|
||||
REM Copies all the required files from their location within the standard
|
||||
REM FreeRTOS directory structure to under the Eclipse project directory.
|
||||
REM This permits the Eclipse project to be used in 'managed' mode and without
|
||||
REM having to setup any linked resources.
|
||||
|
||||
REM Standard paths
|
||||
SET FREERTOS_SOURCE=..\..\Source
|
||||
SET COMMON_SOURCE=..\Common\minimal
|
||||
SET COMMON_INCLUDE=..\Common\include
|
||||
SET CLI_SOURCE=..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-CLI
|
||||
SET FAT_SOURCE=..\..\..\FreeRTOS-Plus\Source\FreeRTOS-Plus-FAT-SL
|
||||
|
||||
REM Have the files already been copied?
|
||||
IF EXIST RTOSDemo\FreeRTOS-Source Goto END
|
||||
|
||||
REM Create the required directory structure.
|
||||
MD RTOSDemo\FreeRTOS-Source
|
||||
MD RTOSDemo\FreeRTOS-Source\include
|
||||
MD RTOSDemo\FreeRTOS-Source\portable
|
||||
MD RTOSDemo\FreeRTOS-Source\portable\GCC
|
||||
MD RTOSDemo\FreeRTOS-Source\portable\GCC\ARM_CM3
|
||||
MD RTOSDemo\FreeRTOS-Source\portable\MemMang
|
||||
|
||||
REM Copy the core kernel files into the project directory
|
||||
copy %FREERTOS_SOURCE%\tasks.c RTOSDemo\FreeRTOS-Source
|
||||
copy %FREERTOS_SOURCE%\queue.c RTOSDemo\FreeRTOS-Source
|
||||
copy %FREERTOS_SOURCE%\list.c RTOSDemo\FreeRTOS-Source
|
||||
copy %FREERTOS_SOURCE%\timers.c RTOSDemo\FreeRTOS-Source
|
||||
|
||||
REM Copy the common header files into the project directory
|
||||
copy %FREERTOS_SOURCE%\include\*.* RTOSDemo\FreeRTOS-Source\include
|
||||
|
||||
REM Copy the portable layer files into the project directory
|
||||
copy %FREERTOS_SOURCE%\portable\GCC\ARM_CM3\*.* RTOSDemo\FreeRTOS-Source\portable\GCC\ARM_CM3
|
||||
|
||||
REM Copy the memory allocation files into the project directory
|
||||
copy %FREERTOS_SOURCE%\portable\MemMang\heap_4.c RTOSDemo\FreeRTOS-Source\portable\MemMang
|
||||
|
||||
REM Copy the files that define the common demo tasks.
|
||||
copy %COMMON_SOURCE%\dynamic.c RTOSDemo\Full-Demo\Common-Demo-Source
|
||||
copy %COMMON_SOURCE%\BlockQ.c RTOSDemo\Full-Demo\Common-Demo-Source
|
||||
copy %COMMON_SOURCE%\flash_timer.c RTOSDemo\Full-Demo\Common-Demo-Source
|
||||
copy %COMMON_SOURCE%\death.c RTOSDemo\Full-Demo\Common-Demo-Source
|
||||
copy %COMMON_SOURCE%\blocktim.c RTOSDemo\Full-Demo\Common-Demo-Source
|
||||
copy %COMMON_SOURCE%\semtest.c RTOSDemo\Full-Demo\Common-Demo-Source
|
||||
copy %COMMON_SOURCE%\PollQ.c RTOSDemo\Full-Demo\Common-Demo-Source
|
||||
copy %COMMON_SOURCE%\GenQTest.c RTOSDemo\Full-Demo\Common-Demo-Source
|
||||
copy %COMMON_SOURCE%\recmutex.c RTOSDemo\Full-Demo\Common-Demo-Source
|
||||
copy %COMMON_SOURCE%\countsem.c RTOSDemo\Full-Demo\Common-Demo-Source
|
||||
copy %COMMON_SOURCE%\integer.c RTOSDemo\Full-Demo\Common-Demo-Source
|
||||
|
||||
REM Copy the common demo file headers.
|
||||
copy %COMMON_INCLUDE%\*.h RTOSDemo\Full-Demo\Common-Demo-Source\include
|
||||
|
||||
REM Copy the FreeRTOS+CLI source.
|
||||
copy %CLI_SOURCE%\*.* RTOSDemo\Full-Demo\FreeRTOS-Plus-CLI-Source
|
||||
|
||||
REM Copy the FreeRTOS+FAT SL source.
|
||||
xcopy %FAT_SOURCE%\*.* RTOSDemo\Full-Demo\FreeRTOS-Plus-FAT-SL-Source /S
|
||||
|
||||
: END
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,462 @@
|
|||
<?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="cdt.managedbuild.config.gnu.cross.cortexm3.exe.debug.437611960">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.cross.cortexm3.exe.debug.437611960" moduleId="org.eclipse.cdt.core.settings" name="Debug">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.MakeErrorParser" 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"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactName="RTOSDemo" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.cortexm3.exe.debug.437611960" name="Debug" parent="cdt.managedbuild.config.gnu.cross.cortexm3.exe.debug">
|
||||
<folderInfo id="cdt.managedbuild.config.gnu.cross.cortexm3.exe.debug.437611960." name="/" resourcePath="">
|
||||
<toolChain id="cdt.managedbuild.toolchain.gnu.cross.cortexm3.exe.debug.1648156965" name="Microsemi Cortex-M3 Tools" superClass="cdt.managedbuild.toolchain.gnu.cross.cortexm3.exe.debug">
|
||||
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.cross.cortexm3.exe.debug.775451197" name="Debug Platform" osList="all" superClass="cdt.managedbuild.target.gnu.platform.cross.cortexm3.exe.debug"/>
|
||||
<builder buildPath="${workspace_loc:/RTOSDemo/Debug}" id="cdt.managedbuild.target.gnu.builder.cross.cortexm3.exe.debug.1204461106" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.cross.cortexm3.exe.debug"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.compiler.cross.cortexm3.exe.debug.503663152" name="GNU C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.cross.cortexm3.exe.debug">
|
||||
<option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.cross.cortexm3.exe.debug.option.optimization.level.1584838985" name="Optimization Level" superClass="gnu.c.compiler.cross.cortexm3.exe.debug.option.optimization.level" value="gnu.c.optimization.level.none" valueType="enumerated"/>
|
||||
<option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.cross.cortexm3.exe.debug.option.debugging.level.749310406" name="Debug Level" superClass="gnu.c.compiler.cross.cortexm3.exe.debug.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
|
||||
<option id="gnu.c.compiler.option.include.paths.237389139" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/}"/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/RTOSDemo/Full-Demo}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/RTOSDemo/Full-Demo/FreeRTOS-Plus-CLI-Source}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/RTOSDemo/Full-Demo/FreeRTOS-Plus-FAT-SL-Source/api}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/RTOSDemo/Full-Demo/Common-Demo-Source/include}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/RTOSDemo/FreeRTOS-Source/include}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/RTOSDemo/FreeRTOS-Source/portable/GCC/ARM_CM3}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/RTOSDemo}""/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/CMSIS}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/CMSIS/startup_gcc}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/drivers}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/drivers/mss_gpio}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/drivers/mss_hpdma}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/drivers/mss_nvm}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/drivers/mss_rtc}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/drivers/mss_sys_services}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/drivers/mss_timer}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/drivers/mss_uart}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/drivers_config}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/drivers_config/sys_config}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/hal}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/hal/CortexM3}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/hal/CortexM3/GNU}"/>
|
||||
</option>
|
||||
<option id="gnu.c.compiler.option.misc.verbose.1351799799" name="Verbose (-v)" superClass="gnu.c.compiler.option.misc.verbose" value="true" valueType="boolean"/>
|
||||
<option id="gnu.c.compiler.option.optimization.flags.435998408" name="Other optimization flags" superClass="gnu.c.compiler.option.optimization.flags" value="-ffunction-sections -fdata-sections" valueType="string"/>
|
||||
<option id="gnu.c.compiler.option.misc.other.1001754914" name="Other flags" superClass="gnu.c.compiler.option.misc.other" value="-c -fmessage-length=0 -Wextra" valueType="string"/>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.2036217646" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.cross.cortexm3.exe.debug.612642130" name="GNU C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.cross.cortexm3.exe.debug">
|
||||
<option id="gnu.cpp.compiler.cross.cortexm3.exe.debug.option.optimization.level.141468934" name="Optimization Level" superClass="gnu.cpp.compiler.cross.cortexm3.exe.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
|
||||
<option id="gnu.cpp.compiler.cross.cortexm3.exe.debug.option.debugging.level.1870407154" name="Debug Level" superClass="gnu.cpp.compiler.cross.cortexm3.exe.debug.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
|
||||
</tool>
|
||||
<tool command="arm-none-eabi-gcc -mthumb -mcpu=cortex-m3 " id="cdt.managedbuild.tool.gnu.c.linker.cross.cortexm3.exe.debug.2105782767" name="GNU C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.cross.cortexm3.exe.debug">
|
||||
<option id="gnu.c.link.option.libs.259558666" name="Libraries (-l)" superClass="gnu.c.link.option.libs" valueType="libs">
|
||||
<listOptionValue builtIn="false" value="RTOSDemo_Hardware_Platform"/>
|
||||
</option>
|
||||
<option id="gnu.c.link.option.paths.71294329" name="Library search path (-L)" superClass="gnu.c.link.option.paths" valueType="libPaths">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/RTOSDemo_Hardware_Platform/Debug}""/>
|
||||
</option>
|
||||
<option id="gnu.c.link.option.ldflags.988543446" name="Linker flags" superClass="gnu.c.link.option.ldflags" value="-T../../RTOSDemo_Hardware_Platform/CMSIS/startup_gcc/debug-in-microsemi-smartfusion2-envm.ld" valueType="string"/>
|
||||
<option id="gnu.c.link.option.userobjs.1227465178" name="Other objects" superClass="gnu.c.link.option.userobjs" valueType="userObjs">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/RTOSDemo_Hardware_Platform/Debug/CMSIS/startup_gcc/startup_m2sxxx.o}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/RTOSDemo_Hardware_Platform/Debug/CMSIS/startup_gcc/newlib_stubs.o}""/>
|
||||
</option>
|
||||
<option id="gnu.c.link.option.other.737278809" name="Other options (-Xlinker [option])" superClass="gnu.c.link.option.other" valueType="stringList">
|
||||
<listOptionValue builtIn="false" value="-gc-sections"/>
|
||||
</option>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.1749893941" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
</inputType>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.cross.cortexm3.exe.debug.1302116748" name="GNU C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.cross.cortexm3.exe.debug"/>
|
||||
<tool command="arm-none-eabi-gcc -c -mthumb -mcpu=cortex-m3" id="cdt.managedbuild.tool.gnu.assembler.cross.cortexm3.exe.debug.1231704524" name="GNU Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.cross.cortexm3.exe.debug">
|
||||
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.2060018502" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
||||
</tool>
|
||||
<tool id="com.actel.softconsole.memory-map.gen.cross.cortexm3.xml.debug.1514572064" name="Memory map generator" superClass="com.actel.softconsole.memory-map.gen.cross.cortexm3.xml.debug"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.objcopy.cross.cortexm3.ihex.debug.1835740717" name="GNU Intel Hex File Generator" superClass="cdt.managedbuild.tool.gnu.objcopy.cross.cortexm3.ihex.debug"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.objcopy.cross.cortexm3.srec.debug.460443486" name="GNU S-Record Generator" superClass="cdt.managedbuild.tool.gnu.objcopy.cross.cortexm3.srec.debug"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.objdump.cross.cortexm3.lst.debug.541279749" name="GNU Listing Generator" superClass="cdt.managedbuild.tool.gnu.objdump.cross.cortexm3.lst.debug"/>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
<sourceEntries>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
||||
</sourceEntries>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile"/>
|
||||
<profile id="com.actel.softconsole.arm.ActelARMManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="arm-none-eabi-gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="com.actel.softconsole.core8051s.SDCCManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="false" filePath=""/>
|
||||
<parser enabled="false"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-V -E -Wp -P -dD ${plugin_state_location}/${specs_file}" command="sdcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="com.actel.softconsole.cortexm1.ActelCortexM1ManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="arm-none-eabi-gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="com.actel.softconsole.cortexm3.ActelCortexM3ManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="arm-none-eabi-gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="makefileGenerator">
|
||||
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/${specs_file}"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'g++ -E -P -v -dD "${plugin_state_location}/specs.cpp"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/specs.c"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cross.cortexm3.exe.debug.437611960;cdt.managedbuild.config.gnu.cross.cortexm3.exe.debug.437611960.">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.actel.softconsole.cortexm3.ActelCortexM3ManagedMakePerProjectProfile"/>
|
||||
<profile id="com.actel.softconsole.arm.ActelARMManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="arm-none-eabi-gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="com.actel.softconsole.cortexm1.ActelCortexM1ManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="arm-none-eabi-gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="com.actel.softconsole.cortexm3.ActelCortexM3ManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="arm-none-eabi-gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="makefileGenerator">
|
||||
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/${specs_file}"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'g++ -E -P -v -dD "${plugin_state_location}/specs.cpp"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/specs.c"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cross.cortexm3.exe.release.1586788319;cdt.managedbuild.config.gnu.cross.cortexm3.exe.release.1586788319.">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.actel.softconsole.cortexm3.ActelCortexM3ManagedMakePerProjectProfile"/>
|
||||
<profile id="com.actel.softconsole.arm.ActelARMManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="arm-none-eabi-gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="com.actel.softconsole.core8051s.SDCCManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="false" filePath=""/>
|
||||
<parser enabled="false"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-V -E -Wp -P -dD ${plugin_state_location}/${specs_file}" command="sdcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="com.actel.softconsole.cortexm1.ActelCortexM1ManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="arm-none-eabi-gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="com.actel.softconsole.cortexm3.ActelCortexM3ManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="arm-none-eabi-gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="makefileGenerator">
|
||||
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/${specs_file}"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'g++ -E -P -v -dD "${plugin_state_location}/specs.cpp"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/specs.c"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
</scannerConfigBuildInfo>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
|
||||
</cconfiguration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<project id="RTOSDemo.cdt.managedbuild.target.gnu.cross.cortexm3.exe.340201866" name="Executable (Managed Make)" projectType="cdt.managedbuild.target.gnu.cross.cortexm3.exe"/>
|
||||
</storageModule>
|
||||
</cproject>
|
|
@ -0,0 +1,81 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>RTOSDemo</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
<project> RTOSDemo_Hardware_Platform </project>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>?name?</key>
|
||||
<value></value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.append_environment</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.autoBuildTarget</key>
|
||||
<value>all</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildArguments</key>
|
||||
<value></value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildCommand</key>
|
||||
<value>make</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildLocation</key>
|
||||
<value>${workspace_loc:/RTOSDemo/Debug}</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
|
||||
<value>clean</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.contents</key>
|
||||
<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableFullBuild</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.fullBuildTarget</key>
|
||||
<value>all</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.stopOnError</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||
<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>
|
||||
</projectDescription>
|
|
@ -0,0 +1,245 @@
|
|||
/*
|
||||
FreeRTOS V7.4.2 - Copyright (C) 2013 Real Time Engineers Ltd.
|
||||
|
||||
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||
* Complete, revised, and edited pdf reference manuals are also *
|
||||
* available. *
|
||||
* *
|
||||
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||
* ensuring you get running as quickly as possible and with an *
|
||||
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||
* the FreeRTOS project to continue with its mission of providing *
|
||||
* professional grade, cross platform, de facto standard solutions *
|
||||
* for microcontrollers - completely free of charge! *
|
||||
* *
|
||||
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||
* *
|
||||
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||
|
||||
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to
|
||||
distribute a combined work that includes FreeRTOS without being obliged to
|
||||
provide the source code for proprietary components outside of the FreeRTOS
|
||||
kernel.
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details. You should have received a copy of the GNU General Public License
|
||||
and the FreeRTOS license exception along with FreeRTOS; if not it can be
|
||||
viewed here: http://www.freertos.org/a00114.html and also obtained by
|
||||
writing to Real Time Engineers Ltd., contact details for whom are available
|
||||
on the FreeRTOS WEB site.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* Having a problem? Start by reading the FAQ "My application does *
|
||||
* not run, what could be wrong?" *
|
||||
* *
|
||||
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
|
||||
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||
license and Real Time Engineers Ltd. contact details.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, and our new
|
||||
fully thread aware and reentrant UDP/IP stack.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||
Integrity Systems, who sell the code with commercial support,
|
||||
indemnification and middleware, under the OpenRTOS brand.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* NOTE 1: This project provides two demo applications. A simple blinky style
|
||||
* project, and a more comprehensive test and demo application. The
|
||||
* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select
|
||||
* between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY
|
||||
* in main.c. This file implements the simply blinky style version.
|
||||
*
|
||||
* NOTE 2: This file only contains the source code that is specific to the
|
||||
* basic demo. Generic functions, such FreeRTOS hook functions, and functions
|
||||
* required to configure the hardware, are defined in main.c.
|
||||
******************************************************************************
|
||||
*
|
||||
* main_blinky() creates one queue, and two tasks. It then starts the
|
||||
* scheduler.
|
||||
*
|
||||
* The Queue Send Task:
|
||||
* The queue send task is implemented by the prvQueueSendTask() function in
|
||||
* this file. prvQueueSendTask() sits in a loop that causes it to repeatedly
|
||||
* block for 200 milliseconds, before sending the value 100 to the queue that
|
||||
* was created within main_blinky(). Once the value is sent, the task loops
|
||||
* back around to block for another 200 milliseconds.
|
||||
*
|
||||
* The Queue Receive Task:
|
||||
* The queue receive task is implemented by the prvQueueReceiveTask() function
|
||||
* in this file. prvQueueReceiveTask() sits in a loop where it repeatedly
|
||||
* blocks on attempts to read data from the queue that was created within
|
||||
* main_blinky(). When data is received, the task checks the value of the
|
||||
* data, and if the value equals the expected 100, toggles the LED. The 'block
|
||||
* time' parameter passed to the queue receive function specifies that the
|
||||
* task should be held in the Blocked state indefinitely to wait for data to
|
||||
* be available on the queue. The queue receive task will only leave the
|
||||
* Blocked state when the queue send task writes to the queue. As the queue
|
||||
* send task writes to the queue every 200 milliseconds, the queue receive
|
||||
* task leaves the Blocked state every 200 milliseconds, and therefore toggles
|
||||
* the LED every 200 milliseconds.
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdio.h>
|
||||
|
||||
/* Kernel includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "semphr.h"
|
||||
|
||||
/* Common demo includes. */
|
||||
#include "partest.h"
|
||||
|
||||
/* Priorities at which the tasks are created. */
|
||||
#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
|
||||
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
|
||||
|
||||
/* The rate at which data is sent to the queue. The 200ms value is converted
|
||||
to ticks using the portTICK_RATE_MS constant. */
|
||||
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_RATE_MS )
|
||||
|
||||
/* The number of items the queue can hold. This is 1 as the receive task
|
||||
will remove items as they are added, meaning the send task should always find
|
||||
the queue empty. */
|
||||
#define mainQUEUE_LENGTH ( 1 )
|
||||
|
||||
/* Values passed to the two tasks just to check the task parameter
|
||||
functionality. */
|
||||
#define mainQUEUE_SEND_PARAMETER ( 0x1111UL )
|
||||
#define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* The tasks as described in the comments at the top of this file.
|
||||
*/
|
||||
static void prvQueueReceiveTask( void *pvParameters );
|
||||
static void prvQueueSendTask( void *pvParameters );
|
||||
|
||||
/*
|
||||
* Called by main() to create the simply blinky style application if
|
||||
* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1.
|
||||
*/
|
||||
void main_blinky( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* The queue used by both tasks. */
|
||||
static xQueueHandle xQueue = NULL;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void main_blinky( void )
|
||||
{
|
||||
/* Create the queue. */
|
||||
xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) );
|
||||
|
||||
if( xQueue != NULL )
|
||||
{
|
||||
/* Start the two tasks as described in the comments at the top of this
|
||||
file. */
|
||||
xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
|
||||
( signed char * ) "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
|
||||
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
|
||||
( void * ) mainQUEUE_RECEIVE_PARAMETER, /* The parameter passed to the task - just to check the functionality. */
|
||||
mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */
|
||||
NULL ); /* The task handle is not required, so NULL is passed. */
|
||||
|
||||
xTaskCreate( prvQueueSendTask, ( signed char * ) "TX", configMINIMAL_STACK_SIZE, ( void * ) mainQUEUE_SEND_PARAMETER, mainQUEUE_SEND_TASK_PRIORITY, NULL );
|
||||
|
||||
/* Start the tasks and timer running. */
|
||||
vTaskStartScheduler();
|
||||
}
|
||||
|
||||
/* If all is well, the scheduler will now be running, and the following
|
||||
line will never be reached. If the following line does execute, then
|
||||
there was insufficient FreeRTOS heap memory available for the idle and/or
|
||||
timer tasks to be created. See the memory management section on the
|
||||
FreeRTOS web site for more details. */
|
||||
for( ;; );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvQueueSendTask( void *pvParameters )
|
||||
{
|
||||
portTickType xNextWakeTime;
|
||||
const unsigned long ulValueToSend = 100UL;
|
||||
|
||||
/* Check the task parameter is as expected. */
|
||||
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER );
|
||||
|
||||
/* Initialise xNextWakeTime - this only needs to be done once. */
|
||||
xNextWakeTime = xTaskGetTickCount();
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
/* Place this task in the blocked state until it is time to run again.
|
||||
The block time is specified in ticks, the constant used converts ticks
|
||||
to ms. While in the Blocked state this task will not consume any CPU
|
||||
time. */
|
||||
vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
|
||||
|
||||
/* Send to the queue - causing the queue receive task to unblock and
|
||||
toggle the LED. 0 is used as the block time so the sending operation
|
||||
will not block - it shouldn't need to block as the queue should always
|
||||
be empty at this point in the code. */
|
||||
xQueueSend( xQueue, &ulValueToSend, 0U );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvQueueReceiveTask( void *pvParameters )
|
||||
{
|
||||
unsigned long ulReceivedValue;
|
||||
|
||||
/* Check the task parameter is as expected. */
|
||||
configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
/* Wait until something arrives in the queue - this task will block
|
||||
indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
|
||||
FreeRTOSConfig.h. */
|
||||
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
|
||||
|
||||
/* To get here something must have been received from the queue, but
|
||||
is it the expected value? If it is, toggle the LED. */
|
||||
if( ulReceivedValue == 100UL )
|
||||
{
|
||||
vParTestToggleLED( 0 );
|
||||
ulReceivedValue = 0U;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
FreeRTOS V7.4.2 - Copyright (C) 2013 Real Time Engineers Ltd.
|
||||
|
||||
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||
* Complete, revised, and edited pdf reference manuals are also *
|
||||
* available. *
|
||||
* *
|
||||
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||
* ensuring you get running as quickly as possible and with an *
|
||||
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||
* the FreeRTOS project to continue with its mission of providing *
|
||||
* professional grade, cross platform, de facto standard solutions *
|
||||
* for microcontrollers - completely free of charge! *
|
||||
* *
|
||||
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||
* *
|
||||
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||
|
||||
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to
|
||||
distribute a combined work that includes FreeRTOS without being obliged to
|
||||
provide the source code for proprietary components outside of the FreeRTOS
|
||||
kernel.
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details. You should have received a copy of the GNU General Public License
|
||||
and the FreeRTOS license exception along with FreeRTOS; if not it can be
|
||||
viewed here: http://www.freertos.org/a00114.html and also obtained by
|
||||
writing to Real Time Engineers Ltd., contact details for whom are available
|
||||
on the FreeRTOS WEB site.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* Having a problem? Start by reading the FAQ "My application does *
|
||||
* not run, what could be wrong?" *
|
||||
* *
|
||||
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
|
||||
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||
license and Real Time Engineers Ltd. contact details.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, and our new
|
||||
fully thread aware and reentrant UDP/IP stack.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||
Integrity Systems, who sell the code with commercial support,
|
||||
indemnification and middleware, under the OpenRTOS brand.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef FREERTOS_CONFIG_H
|
||||
#define FREERTOS_CONFIG_H
|
||||
|
||||
/*
|
||||
* The following #error directive is to remind users that a batch file must be
|
||||
* executed prior to this project being built. Once it has been executed
|
||||
* remove the #error line below.
|
||||
*/
|
||||
//#error Ensure CreateProjectDirectoryStructure.bat has been executed before building. See comment immediately above.
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Application specific definitions.
|
||||
*
|
||||
* These definitions should be adjusted for your particular hardware and
|
||||
* application requirements.
|
||||
*
|
||||
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
|
||||
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
|
||||
*
|
||||
* See http://www.freertos.org/a00110.html.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
#include <stdint.h>
|
||||
extern uint32_t SystemCoreClock;
|
||||
|
||||
#define configUSE_PREEMPTION 1
|
||||
#define configUSE_IDLE_HOOK 1
|
||||
#define configUSE_TICK_HOOK 0
|
||||
#define configCPU_CLOCK_HZ ( SystemCoreClock )
|
||||
#define configTICK_RATE_HZ ( ( portTickType ) 1000 )
|
||||
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 )
|
||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 80 )
|
||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 25000 ) )
|
||||
#define configMAX_TASK_NAME_LEN ( 10 )
|
||||
#define configUSE_TRACE_FACILITY 1
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
#define configIDLE_SHOULD_YIELD 1
|
||||
#define configUSE_MUTEXES 1
|
||||
#define configQUEUE_REGISTRY_SIZE 0
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||
#define configUSE_RECURSIVE_MUTEXES 1
|
||||
#define configUSE_MALLOC_FAILED_HOOK 1
|
||||
#define configUSE_APPLICATION_TASK_TAG 0
|
||||
#define configUSE_COUNTING_SEMAPHORES 1
|
||||
|
||||
/* Co-routine definitions. */
|
||||
#define configUSE_CO_ROUTINES 0
|
||||
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
|
||||
|
||||
/* Software timer definitions. */
|
||||
#define configUSE_TIMERS 1
|
||||
#define configTIMER_TASK_PRIORITY ( 2 )
|
||||
#define configTIMER_QUEUE_LENGTH 5
|
||||
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
|
||||
|
||||
/* Run time stats gathering definitions. */
|
||||
void vConfigureTimerForRunTimeStats( void );
|
||||
uint32_t ulGetRunTimeCounterValue( void );
|
||||
#define configGENERATE_RUN_TIME_STATS 1
|
||||
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats()
|
||||
#define portGET_RUN_TIME_COUNTER_VALUE() ulGetRunTimeCounterValue()
|
||||
|
||||
/* Set the following definitions to 1 to include the API function, or zero
|
||||
to exclude the API function. */
|
||||
#define INCLUDE_vTaskPrioritySet 1
|
||||
#define INCLUDE_uxTaskPriorityGet 1
|
||||
#define INCLUDE_vTaskDelete 1
|
||||
#define INCLUDE_vTaskCleanUpResources 1
|
||||
#define INCLUDE_vTaskSuspend 1
|
||||
#define INCLUDE_vTaskDelayUntil 1
|
||||
#define INCLUDE_vTaskDelay 1
|
||||
|
||||
/* The size of the global output buffer that is available for use when there
|
||||
are multiple command interpreters running at once (for example, one on a UART
|
||||
and one on TCP/IP). This is done to prevent an output buffer being defined by
|
||||
each implementation - which would waste RAM. In this case, there is only one
|
||||
command interpreter running. */
|
||||
#define configCOMMAND_INT_MAX_OUTPUT_SIZE 2048
|
||||
|
||||
/* Cortex-M specific definitions. */
|
||||
#ifdef __NVIC_PRIO_BITS
|
||||
/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
|
||||
#define configPRIO_BITS __NVIC_PRIO_BITS
|
||||
#else
|
||||
#define configPRIO_BITS 4 /* 15 priority levels */
|
||||
#endif
|
||||
|
||||
/* The lowest interrupt priority that can be used in a call to a "set priority"
|
||||
function. */
|
||||
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x0f
|
||||
|
||||
/* The highest interrupt priority that can be used by any interrupt service
|
||||
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
|
||||
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
|
||||
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
|
||||
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 10
|
||||
|
||||
/* Interrupt priorities used by the kernel port layer itself. These are generic
|
||||
to all Cortex-M ports, and do not rely on any particular library functions. */
|
||||
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
||||
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
|
||||
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
|
||||
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
||||
|
||||
/* Normal assert() semantics without relying on the provision of an assert.h
|
||||
header file. */
|
||||
#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }
|
||||
|
||||
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
|
||||
standard names. */
|
||||
#define vPortSVCHandler SVC_Handler
|
||||
#define xPortPendSVHandler PendSV_Handler
|
||||
#define xPortSysTickHandler SysTick_Handler
|
||||
|
||||
#endif /* FREERTOS_CONFIG_H */
|
||||
|
|
@ -0,0 +1 @@
|
|||
Run the CreateProjectDirectoryStructure.bat batch file to populate this directory before building the demo.
|
|
@ -0,0 +1 @@
|
|||
Run the CreateProjectDirectoryStructure.bat batch file to populate this directory before building the demo.
|
|
@ -0,0 +1,575 @@
|
|||
/*
|
||||
FreeRTOS V7.4.2 - Copyright (C) 2013 Real Time Engineers Ltd.
|
||||
|
||||
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||
* Complete, revised, and edited pdf reference manuals are also *
|
||||
* available. *
|
||||
* *
|
||||
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||
* ensuring you get running as quickly as possible and with an *
|
||||
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||
* the FreeRTOS project to continue with its mission of providing *
|
||||
* professional grade, cross platform, de facto standard solutions *
|
||||
* for microcontrollers - completely free of charge! *
|
||||
* *
|
||||
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||
* *
|
||||
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||
|
||||
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to
|
||||
distribute a combined work that includes FreeRTOS without being obliged to
|
||||
provide the source code for proprietary components outside of the FreeRTOS
|
||||
kernel.
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details. You should have received a copy of the GNU General Public License
|
||||
and the FreeRTOS license exception along with FreeRTOS; if not itcan be
|
||||
viewed here: http://www.freertos.org/a00114.html and also obtained by
|
||||
writing to Real Time Engineers Ltd., contact details for whom are available
|
||||
on the FreeRTOS WEB site.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* Having a problem? Start by reading the FAQ "My application does *
|
||||
* not run, what could be wrong?" *
|
||||
* *
|
||||
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
|
||||
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||
license and Real Time Engineers Ltd. contact details.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, and our new
|
||||
fully thread aware and reentrant UDP/IP stack.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||
Integrity Systems, who sell the code with commercial support,
|
||||
indemnification and middleware, under the OpenRTOS brand.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
*/
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* FreeRTOS+CLI includes. */
|
||||
#include "FreeRTOS_CLI.h"
|
||||
|
||||
/* File system includes. */
|
||||
#include "fat_sl.h"
|
||||
#include "api_mdriver_ram.h"
|
||||
|
||||
#ifdef _WINDOWS_
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
#define cliNEW_LINE "\r\n"
|
||||
|
||||
/*******************************************************************************
|
||||
* See the URL in the comments within main.c for the location of the online
|
||||
* documentation.
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
* Print out information on a single file.
|
||||
*/
|
||||
static void prvCreateFileInfoString( int8_t *pcBuffer, F_FIND *pxFindStruct );
|
||||
|
||||
/*
|
||||
* Copies an existing file into a newly created file.
|
||||
*/
|
||||
static portBASE_TYPE prvPerformCopy( int8_t *pcSourceFile,
|
||||
int32_t lSourceFileLength,
|
||||
int8_t *pcDestinationFile,
|
||||
int8_t *pxWriteBuffer,
|
||||
size_t xWriteBufferLen );
|
||||
|
||||
/*
|
||||
* Implements the DIR command.
|
||||
*/
|
||||
static portBASE_TYPE prvDIRCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );
|
||||
|
||||
/*
|
||||
* Implements the CD command.
|
||||
*/
|
||||
static portBASE_TYPE prvCDCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );
|
||||
|
||||
/*
|
||||
* Implements the DEL command.
|
||||
*/
|
||||
static portBASE_TYPE prvDELCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );
|
||||
|
||||
/*
|
||||
* Implements the TYPE command.
|
||||
*/
|
||||
static portBASE_TYPE prvTYPECommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );
|
||||
|
||||
/*
|
||||
* Implements the COPY command.
|
||||
*/
|
||||
static portBASE_TYPE prvCOPYCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );
|
||||
|
||||
/* Structure that defines the DIR command line command, which lists all the
|
||||
files in the current directory. */
|
||||
static const CLI_Command_Definition_t xDIR =
|
||||
{
|
||||
( const int8_t * const ) "dir", /* The command string to type. */
|
||||
( const int8_t * const ) "\r\ndir:\r\n Lists the files in the current directory\r\n",
|
||||
prvDIRCommand, /* The function to run. */
|
||||
0 /* No parameters are expected. */
|
||||
};
|
||||
|
||||
/* Structure that defines the CD command line command, which changes the
|
||||
working directory. */
|
||||
static const CLI_Command_Definition_t xCD =
|
||||
{
|
||||
( const int8_t * const ) "cd", /* The command string to type. */
|
||||
( const int8_t * const ) "\r\ncd <dir name>:\r\n Changes the working directory\r\n",
|
||||
prvCDCommand, /* The function to run. */
|
||||
1 /* One parameter is expected. */
|
||||
};
|
||||
|
||||
/* Structure that defines the TYPE command line command, which prints the
|
||||
contents of a file to the console. */
|
||||
static const CLI_Command_Definition_t xTYPE =
|
||||
{
|
||||
( const int8_t * const ) "type", /* The command string to type. */
|
||||
( const int8_t * const ) "\r\ntype <filename>:\r\n Prints file contents to the terminal\r\n",
|
||||
prvTYPECommand, /* The function to run. */
|
||||
1 /* One parameter is expected. */
|
||||
};
|
||||
|
||||
/* Structure that defines the DEL command line command, which deletes a file. */
|
||||
static const CLI_Command_Definition_t xDEL =
|
||||
{
|
||||
( const int8_t * const ) "del", /* The command string to type. */
|
||||
( const int8_t * const ) "\r\ndel <filename>:\r\n deletes a file or directory\r\n",
|
||||
prvDELCommand, /* The function to run. */
|
||||
1 /* One parameter is expected. */
|
||||
};
|
||||
|
||||
/* Structure that defines the COPY command line command, which deletes a file. */
|
||||
static const CLI_Command_Definition_t xCOPY =
|
||||
{
|
||||
( const int8_t * const ) "copy", /* The command string to type. */
|
||||
( const int8_t * const ) "\r\ncopy <source file> <dest file>:\r\n Copies <source file> to <dest file>\r\n",
|
||||
prvCOPYCommand, /* The function to run. */
|
||||
2 /* Two parameters are expected. */
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vRegisterFileSystemCLICommands( void )
|
||||
{
|
||||
/* Register all the command line commands defined immediately above. */
|
||||
FreeRTOS_CLIRegisterCommand( &xDIR );
|
||||
FreeRTOS_CLIRegisterCommand( &xCD );
|
||||
FreeRTOS_CLIRegisterCommand( &xTYPE );
|
||||
FreeRTOS_CLIRegisterCommand( &xDEL );
|
||||
FreeRTOS_CLIRegisterCommand( &xCOPY );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static portBASE_TYPE prvTYPECommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )
|
||||
{
|
||||
int8_t *pcParameter;
|
||||
portBASE_TYPE xParameterStringLength, xReturn = pdTRUE;
|
||||
static F_FILE *pxFile = NULL;
|
||||
int iChar;
|
||||
size_t xByte;
|
||||
size_t xColumns = 50U;
|
||||
|
||||
/* Ensure there is always a null terminator after each character written. */
|
||||
memset( pcWriteBuffer, 0x00, xWriteBufferLen );
|
||||
|
||||
/* Ensure the buffer leaves space for the \r\n. */
|
||||
configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) );
|
||||
xWriteBufferLen -= strlen( cliNEW_LINE );
|
||||
|
||||
if( xWriteBufferLen < xColumns )
|
||||
{
|
||||
/* Ensure the loop that uses xColumns as an end condition does not
|
||||
write off the end of the buffer. */
|
||||
xColumns = xWriteBufferLen;
|
||||
}
|
||||
|
||||
if( pxFile == NULL )
|
||||
{
|
||||
/* The file has not been opened yet. Find the file name. */
|
||||
pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter
|
||||
(
|
||||
pcCommandString, /* The command string itself. */
|
||||
1, /* Return the first parameter. */
|
||||
&xParameterStringLength /* Store the parameter string length. */
|
||||
);
|
||||
|
||||
/* Sanity check something was returned. */
|
||||
configASSERT( pcParameter );
|
||||
|
||||
/* Attempt to open the requested file. */
|
||||
pxFile = f_open( ( const char * ) pcParameter, "r" );
|
||||
}
|
||||
|
||||
if( pxFile != NULL )
|
||||
{
|
||||
/* Read the next chunk of data from the file. */
|
||||
for( xByte = 0; xByte < xColumns; xByte++ )
|
||||
{
|
||||
iChar = f_getc( pxFile );
|
||||
|
||||
if( iChar == -1 )
|
||||
{
|
||||
/* No more characters to return. */
|
||||
f_close( pxFile );
|
||||
pxFile = NULL;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
pcWriteBuffer[ xByte ] = ( int8_t ) iChar;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( pxFile == NULL )
|
||||
{
|
||||
/* Either the file was not opened, or all the data from the file has
|
||||
been returned and the file is now closed. */
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
|
||||
strcat( ( char * ) pcWriteBuffer, cliNEW_LINE );
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static portBASE_TYPE prvCDCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )
|
||||
{
|
||||
int8_t *pcParameter;
|
||||
portBASE_TYPE xParameterStringLength;
|
||||
unsigned char ucReturned;
|
||||
size_t xStringLength;
|
||||
|
||||
/* Obtain the parameter string. */
|
||||
pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter
|
||||
(
|
||||
pcCommandString, /* The command string itself. */
|
||||
1, /* Return the first parameter. */
|
||||
&xParameterStringLength /* Store the parameter string length. */
|
||||
);
|
||||
|
||||
/* Sanity check something was returned. */
|
||||
configASSERT( pcParameter );
|
||||
|
||||
/* Attempt to move to the requested directory. */
|
||||
ucReturned = f_chdir( ( char * ) pcParameter );
|
||||
|
||||
if( ucReturned == F_NO_ERROR )
|
||||
{
|
||||
sprintf( ( char * ) pcWriteBuffer, "In: " );
|
||||
xStringLength = strlen( ( const char * ) pcWriteBuffer );
|
||||
f_getcwd( ( char * ) &( pcWriteBuffer[ xStringLength ] ), ( unsigned char ) ( xWriteBufferLen - xStringLength ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( ( char * ) pcWriteBuffer, "Error" );
|
||||
}
|
||||
|
||||
strcat( ( char * ) pcWriteBuffer, cliNEW_LINE );
|
||||
|
||||
return pdFALSE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static portBASE_TYPE prvDIRCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )
|
||||
{
|
||||
static F_FIND *pxFindStruct = NULL;
|
||||
unsigned char ucReturned;
|
||||
portBASE_TYPE xReturn = pdFALSE;
|
||||
|
||||
/* This assumes pcWriteBuffer is long enough. */
|
||||
( void ) pcCommandString;
|
||||
|
||||
/* Ensure the buffer leaves space for the \r\n. */
|
||||
configASSERT( xWriteBufferLen > ( strlen( cliNEW_LINE ) * 2 ) );
|
||||
xWriteBufferLen -= strlen( cliNEW_LINE );
|
||||
|
||||
if( pxFindStruct == NULL )
|
||||
{
|
||||
/* This is the first time this function has been executed since the Dir
|
||||
command was run. Create the find structure. */
|
||||
pxFindStruct = ( F_FIND * ) pvPortMalloc( sizeof( F_FIND ) );
|
||||
|
||||
if( pxFindStruct != NULL )
|
||||
{
|
||||
ucReturned = f_findfirst( "*.*", pxFindStruct );
|
||||
|
||||
if( ucReturned == F_NO_ERROR )
|
||||
{
|
||||
prvCreateFileInfoString( pcWriteBuffer, pxFindStruct );
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf( ( char * ) pcWriteBuffer, xWriteBufferLen, "Error: f_findfirst() failed." );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf( ( char * ) pcWriteBuffer, xWriteBufferLen, "Failed to allocate RAM (using heap_4.c will prevent fragmentation)." );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The find struct has already been created. Find the next file in
|
||||
the directory. */
|
||||
ucReturned = f_findnext( pxFindStruct );
|
||||
|
||||
if( ucReturned == F_NO_ERROR )
|
||||
{
|
||||
prvCreateFileInfoString( pcWriteBuffer, pxFindStruct );
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* There are no more files. Free the find structure. */
|
||||
vPortFree( pxFindStruct );
|
||||
pxFindStruct = NULL;
|
||||
|
||||
/* No string to return. */
|
||||
pcWriteBuffer[ 0 ] = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
strcat( ( char * ) pcWriteBuffer, cliNEW_LINE );
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static portBASE_TYPE prvDELCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )
|
||||
{
|
||||
int8_t *pcParameter;
|
||||
portBASE_TYPE xParameterStringLength;
|
||||
unsigned char ucReturned;
|
||||
|
||||
/* This function assumes xWriteBufferLen is large enough! */
|
||||
( void ) xWriteBufferLen;
|
||||
|
||||
/* Obtain the parameter string. */
|
||||
pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter
|
||||
(
|
||||
pcCommandString, /* The command string itself. */
|
||||
1, /* Return the first parameter. */
|
||||
&xParameterStringLength /* Store the parameter string length. */
|
||||
);
|
||||
|
||||
/* Sanity check something was returned. */
|
||||
configASSERT( pcParameter );
|
||||
|
||||
/* Attempt to delete the file. */
|
||||
ucReturned = f_delete( ( const char * ) pcParameter );
|
||||
|
||||
if( ucReturned == F_NO_ERROR )
|
||||
{
|
||||
sprintf( ( char * ) pcWriteBuffer, "%s was deleted", pcParameter );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( ( char * ) pcWriteBuffer, "Error" );
|
||||
}
|
||||
|
||||
strcat( ( char * ) pcWriteBuffer, cliNEW_LINE );
|
||||
|
||||
return pdFALSE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static portBASE_TYPE prvCOPYCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )
|
||||
{
|
||||
int8_t *pcSourceFile, *pcDestinationFile;
|
||||
portBASE_TYPE xParameterStringLength;
|
||||
long lSourceLength, lDestinationLength = 0;
|
||||
|
||||
/* Obtain the name of the destination file. */
|
||||
pcDestinationFile = ( int8_t * ) FreeRTOS_CLIGetParameter
|
||||
(
|
||||
pcCommandString, /* The command string itself. */
|
||||
2, /* Return the second parameter. */
|
||||
&xParameterStringLength /* Store the parameter string length. */
|
||||
);
|
||||
|
||||
/* Sanity check something was returned. */
|
||||
configASSERT( pcDestinationFile );
|
||||
|
||||
/* Obtain the name of the source file. */
|
||||
pcSourceFile = ( int8_t * ) FreeRTOS_CLIGetParameter
|
||||
(
|
||||
pcCommandString, /* The command string itself. */
|
||||
1, /* Return the first parameter. */
|
||||
&xParameterStringLength /* Store the parameter string length. */
|
||||
);
|
||||
|
||||
/* Sanity check something was returned. */
|
||||
configASSERT( pcSourceFile );
|
||||
|
||||
/* Terminate the string. */
|
||||
pcSourceFile[ xParameterStringLength ] = 0x00;
|
||||
|
||||
/* See if the source file exists, obtain its length if it does. */
|
||||
lSourceLength = f_filelength( ( const char * ) pcSourceFile );
|
||||
|
||||
if( lSourceLength == 0 )
|
||||
{
|
||||
sprintf( ( char * ) pcWriteBuffer, "Source file does not exist" );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* See if the destination file exists. */
|
||||
lDestinationLength = f_filelength( ( const char * ) pcDestinationFile );
|
||||
|
||||
if( lDestinationLength != 0 )
|
||||
{
|
||||
sprintf( ( char * ) pcWriteBuffer, "Error: Destination file already exists" );
|
||||
}
|
||||
}
|
||||
|
||||
/* Continue only if the source file exists and the destination file does
|
||||
not exist. */
|
||||
if( ( lSourceLength != 0 ) && ( lDestinationLength == 0 ) )
|
||||
{
|
||||
if( prvPerformCopy( pcSourceFile, lSourceLength, pcDestinationFile, pcWriteBuffer, xWriteBufferLen ) == pdPASS )
|
||||
{
|
||||
sprintf( ( char * ) pcWriteBuffer, "Copy made" );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( ( char * ) pcWriteBuffer, "Error during copy" );
|
||||
}
|
||||
}
|
||||
|
||||
strcat( ( char * ) pcWriteBuffer, cliNEW_LINE );
|
||||
|
||||
return pdFALSE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static portBASE_TYPE prvPerformCopy( int8_t *pcSourceFile,
|
||||
int32_t lSourceFileLength,
|
||||
int8_t *pcDestinationFile,
|
||||
int8_t *pxWriteBuffer,
|
||||
size_t xWriteBufferLen )
|
||||
{
|
||||
int32_t lBytesRead = 0, lBytesToRead, lBytesRemaining;
|
||||
F_FILE *pxFile;
|
||||
portBASE_TYPE xReturn = pdPASS;
|
||||
|
||||
/* NOTE: Error handling has been omitted for clarity. */
|
||||
|
||||
while( lBytesRead < lSourceFileLength )
|
||||
{
|
||||
/* How many bytes are left? */
|
||||
lBytesRemaining = lSourceFileLength - lBytesRead;
|
||||
|
||||
/* How many bytes should be read this time around the loop. Can't
|
||||
read more bytes than will fit into the buffer. */
|
||||
if( lBytesRemaining > ( long ) xWriteBufferLen )
|
||||
{
|
||||
lBytesToRead = ( long ) xWriteBufferLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
lBytesToRead = lBytesRemaining;
|
||||
}
|
||||
|
||||
/* Open the source file, seek past the data that has already been
|
||||
read from the file, read the next block of data, then close the
|
||||
file again so the destination file can be opened. */
|
||||
pxFile = f_open( ( const char * ) pcSourceFile, "r" );
|
||||
if( pxFile != NULL )
|
||||
{
|
||||
f_seek( pxFile, lBytesRead, F_SEEK_SET );
|
||||
f_read( pxWriteBuffer, lBytesToRead, 1, pxFile );
|
||||
f_close( pxFile );
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = pdFAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Open the destination file and write the block of data to the end of
|
||||
the file. */
|
||||
pxFile = f_open( ( const char * ) pcDestinationFile, "a" );
|
||||
if( pxFile != NULL )
|
||||
{
|
||||
f_write( pxWriteBuffer, lBytesToRead, 1, pxFile );
|
||||
f_close( pxFile );
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = pdFAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
lBytesRead += lBytesToRead;
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvCreateFileInfoString( int8_t *pcBuffer, F_FIND *pxFindStruct )
|
||||
{
|
||||
const char *pcWritableFile = "writable file", *pcReadOnlyFile = "read only file", *pcDirectory = "directory";
|
||||
const char * pcAttrib;
|
||||
|
||||
/* Point pcAttrib to a string that describes the file. */
|
||||
if( ( pxFindStruct->attr & F_ATTR_DIR ) != 0 )
|
||||
{
|
||||
pcAttrib = pcDirectory;
|
||||
}
|
||||
else if( pxFindStruct->attr & F_ATTR_READONLY )
|
||||
{
|
||||
pcAttrib = pcReadOnlyFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
pcAttrib = pcWritableFile;
|
||||
}
|
||||
|
||||
/* Create a string that includes the file name, the file size and the
|
||||
attributes string. */
|
||||
sprintf( ( char * ) pcBuffer, "%s [%s] [size=%d]", pxFindStruct->filename, pcAttrib, ( int ) pxFindStruct->filesize );
|
||||
}
|
|
@ -0,0 +1,384 @@
|
|||
/*
|
||||
FreeRTOS V7.4.2 - Copyright (C) 2013 Real Time Engineers Ltd.
|
||||
|
||||
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||
* Complete, revised, and edited pdf reference manuals are also *
|
||||
* available. *
|
||||
* *
|
||||
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||
* ensuring you get running as quickly as possible and with an *
|
||||
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||
* the FreeRTOS project to continue with its mission of providing *
|
||||
* professional grade, cross platform, de facto standard solutions *
|
||||
* for microcontrollers - completely free of charge! *
|
||||
* *
|
||||
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||
* *
|
||||
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||
|
||||
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to
|
||||
distribute a combined work that includes FreeRTOS without being obliged to
|
||||
provide the source code for proprietary components outside of the FreeRTOS
|
||||
kernel.
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details. You should have received a copy of the GNU General Public License
|
||||
and the FreeRTOS license exception along with FreeRTOS; if not itcan be
|
||||
viewed here: http://www.freertos.org/a00114.html and also obtained by
|
||||
writing to Real Time Engineers Ltd., contact details for whom are available
|
||||
on the FreeRTOS WEB site.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* Having a problem? Start by reading the FAQ "My application does *
|
||||
* not run, what could be wrong?" *
|
||||
* *
|
||||
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
|
||||
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||
license and Real Time Engineers Ltd. contact details.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, and our new
|
||||
fully thread aware and reentrant UDP/IP stack.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||
Integrity Systems, who sell the code with commercial support,
|
||||
indemnification and middleware, under the OpenRTOS brand.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* See the URL in the comments within main.c for the location of the online
|
||||
* documentation.
|
||||
******************************************************************************/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* File system includes. */
|
||||
#include "fat_sl.h"
|
||||
#include "api_mdriver_ram.h"
|
||||
|
||||
/* 8.3 format, plus null terminator. */
|
||||
#define fsMAX_FILE_NAME_LEN 13
|
||||
|
||||
/* The number of bytes read/written to the example files at a time. */
|
||||
#define fsRAM_BUFFER_SIZE 200
|
||||
|
||||
/* The number of bytes written to the file that uses f_putc() and f_getc(). */
|
||||
#define fsPUTC_FILE_SIZE 100
|
||||
|
||||
/* The number of files created in root. */
|
||||
#define fsROOT_FILES 3
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Creates and verifies different files on the volume, demonstrating the use of
|
||||
* various different API functions.
|
||||
*/
|
||||
void vCreateAndVerifySampleFiles( void );
|
||||
|
||||
/*
|
||||
* Create a set of example files in the root directory of the volume using
|
||||
* f_write().
|
||||
*/
|
||||
static void prvCreateDemoFilesUsing_f_write( void );
|
||||
|
||||
/*
|
||||
* Use f_read() to read back and verify the files that were created by
|
||||
* prvCreateDemoFilesUsing_f_write().
|
||||
*/
|
||||
static void prvVerifyDemoFileUsing_f_read( void );
|
||||
|
||||
/*
|
||||
* Create an example file in a sub-directory using f_putc().
|
||||
*/
|
||||
static void prvCreateDemoFileUsing_f_putc( void );
|
||||
|
||||
/*
|
||||
* Use f_getc() to read back and verify the file that was created by
|
||||
* prvCreateDemoFileUsing_f_putc().
|
||||
*/
|
||||
static void prvVerifyDemoFileUsing_f_getc( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* A buffer used to both create content to write to disk, and read content back
|
||||
from a disk. Note there is no mutual exclusion on this buffer. */
|
||||
static char cRAMBuffer[ fsRAM_BUFFER_SIZE ];
|
||||
|
||||
/* Names of directories that are created. */
|
||||
static const char *pcRoot = "/", *pcDirectory1 = "SUB1", *pcDirectory2 = "SUB2", *pcFullPath = "/SUB1/SUB2";
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vCreateAndVerifySampleFiles( void )
|
||||
{
|
||||
unsigned char ucStatus;
|
||||
|
||||
/* First create the volume. */
|
||||
ucStatus = f_initvolume( ram_initfunc );
|
||||
|
||||
/* It is expected that the volume is not formatted. */
|
||||
if( ucStatus == F_ERR_NOTFORMATTED )
|
||||
{
|
||||
/* Format the created volume. */
|
||||
ucStatus = f_format( F_FAT12_MEDIA );
|
||||
}
|
||||
|
||||
if( ucStatus == F_NO_ERROR )
|
||||
{
|
||||
/* Create a set of files using f_write(). */
|
||||
prvCreateDemoFilesUsing_f_write();
|
||||
|
||||
/* Read back and verify the files that were created using f_write(). */
|
||||
prvVerifyDemoFileUsing_f_read();
|
||||
|
||||
/* Create sub directories two deep then create a file using putc. */
|
||||
prvCreateDemoFileUsing_f_putc();
|
||||
|
||||
/* Read back and verify the file created by
|
||||
prvCreateDemoFileUsing_f_putc(). */
|
||||
prvVerifyDemoFileUsing_f_getc();
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvCreateDemoFilesUsing_f_write( void )
|
||||
{
|
||||
portBASE_TYPE xFileNumber, xWriteNumber;
|
||||
char cFileName[ fsMAX_FILE_NAME_LEN ];
|
||||
long lItemsWritten;
|
||||
F_FILE *pxFile;
|
||||
|
||||
/* Create fsROOT_FILES files. Each created file will be
|
||||
( xFileNumber * fsRAM_BUFFER_SIZE ) bytes in length, and filled
|
||||
with a different repeating character. */
|
||||
for( xFileNumber = 1; xFileNumber <= fsROOT_FILES; xFileNumber++ )
|
||||
{
|
||||
/* Generate a file name. */
|
||||
sprintf( cFileName, "root%03d.txt", ( int ) xFileNumber );
|
||||
|
||||
/* Obtain the current working directory and print out the file name and
|
||||
the directory into which the file is being written. */
|
||||
f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );
|
||||
printf( "Creating file %s in %s\r\n", cFileName, cRAMBuffer );
|
||||
|
||||
/* Open the file, creating the file if it does not already exist. */
|
||||
pxFile = f_open( cFileName, "w" );
|
||||
configASSERT( pxFile );
|
||||
|
||||
/* Fill the RAM buffer with data that will be written to the file. This
|
||||
is just a repeating ascii character that indicates the file number. */
|
||||
memset( cRAMBuffer, ( int ) ( '0' + xFileNumber ), fsRAM_BUFFER_SIZE );
|
||||
|
||||
/* Write the RAM buffer to the opened file a number of times. The
|
||||
number of times the RAM buffer is written to the file depends on the
|
||||
file number, so the length of each created file will be different. */
|
||||
for( xWriteNumber = 0; xWriteNumber < xFileNumber; xWriteNumber++ )
|
||||
{
|
||||
lItemsWritten = f_write( cRAMBuffer, fsRAM_BUFFER_SIZE, 1, pxFile );
|
||||
configASSERT( lItemsWritten == 1 );
|
||||
}
|
||||
|
||||
/* Close the file so another file can be created. */
|
||||
f_close( pxFile );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvVerifyDemoFileUsing_f_read( void )
|
||||
{
|
||||
portBASE_TYPE xFileNumber, xReadNumber;
|
||||
char cFileName[ fsMAX_FILE_NAME_LEN ];
|
||||
long lItemsRead, lChar;
|
||||
F_FILE *pxFile;
|
||||
|
||||
/* Read back the files that were created by
|
||||
prvCreateDemoFilesUsing_f_write(). */
|
||||
for( xFileNumber = 1; xFileNumber <= fsROOT_FILES; xFileNumber++ )
|
||||
{
|
||||
/* Generate the file name. */
|
||||
sprintf( cFileName, "root%03d.txt", ( int ) xFileNumber );
|
||||
|
||||
/* Obtain the current working directory and print out the file name and
|
||||
the directory from which the file is being read. */
|
||||
f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );
|
||||
printf( "Reading file %s from %s\r\n", cFileName, cRAMBuffer );
|
||||
|
||||
/* Open the file for reading. */
|
||||
pxFile = f_open( cFileName, "r" );
|
||||
configASSERT( pxFile );
|
||||
|
||||
/* Read the file into the RAM buffer, checking the file contents are as
|
||||
expected. The size of the file depends on the file number. */
|
||||
for( xReadNumber = 0; xReadNumber < xFileNumber; xReadNumber++ )
|
||||
{
|
||||
/* Start with the RAM buffer clear. */
|
||||
memset( cRAMBuffer, 0x00, fsRAM_BUFFER_SIZE );
|
||||
|
||||
lItemsRead = f_read( cRAMBuffer, fsRAM_BUFFER_SIZE, 1, pxFile );
|
||||
configASSERT( lItemsRead == 1 );
|
||||
|
||||
/* Check the RAM buffer is filled with the expected data. Each
|
||||
file contains a different repeating ascii character that indicates
|
||||
the number of the file. */
|
||||
for( lChar = 0; lChar < fsRAM_BUFFER_SIZE; lChar++ )
|
||||
{
|
||||
configASSERT( cRAMBuffer[ lChar ] == ( '0' + ( char ) xFileNumber ) );
|
||||
}
|
||||
}
|
||||
|
||||
/* Close the file. */
|
||||
f_close( pxFile );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvCreateDemoFileUsing_f_putc( void )
|
||||
{
|
||||
unsigned char ucReturn;
|
||||
int iByte, iReturned;
|
||||
F_FILE *pxFile;
|
||||
char cFileName[ fsMAX_FILE_NAME_LEN ];
|
||||
|
||||
/* Obtain and print out the working directory. */
|
||||
f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );
|
||||
printf( "In directory %s\r\n", cRAMBuffer );
|
||||
|
||||
/* Create a sub directory. */
|
||||
ucReturn = f_mkdir( pcDirectory1 );
|
||||
configASSERT( ucReturn == F_NO_ERROR );
|
||||
|
||||
/* Move into the created sub-directory. */
|
||||
ucReturn = f_chdir( pcDirectory1 );
|
||||
configASSERT( ucReturn == F_NO_ERROR );
|
||||
|
||||
/* Obtain and print out the working directory. */
|
||||
f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );
|
||||
printf( "In directory %s\r\n", cRAMBuffer );
|
||||
|
||||
/* Create a subdirectory in the new directory. */
|
||||
ucReturn = f_mkdir( pcDirectory2 );
|
||||
configASSERT( ucReturn == F_NO_ERROR );
|
||||
|
||||
/* Move into the directory just created - now two directories down from
|
||||
the root. */
|
||||
ucReturn = f_chdir( pcDirectory2 );
|
||||
configASSERT( ucReturn == F_NO_ERROR );
|
||||
|
||||
/* Obtain and print out the working directory. */
|
||||
f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );
|
||||
printf( "In directory %s\r\n", cRAMBuffer );
|
||||
configASSERT( strcmp( ( const char * ) cRAMBuffer, pcFullPath ) == 0 );
|
||||
|
||||
/* Generate the file name. */
|
||||
sprintf( cFileName, "%s.txt", pcDirectory2 );
|
||||
|
||||
/* Print out the file name and the directory into which the file is being
|
||||
written. */
|
||||
printf( "Writing file %s in %s\r\n", cFileName, cRAMBuffer );
|
||||
|
||||
pxFile = f_open( cFileName, "w" );
|
||||
|
||||
/* Create a file 1 byte at a time. The file is filled with incrementing
|
||||
ascii characters starting from '0'. */
|
||||
for( iByte = 0; iByte < fsPUTC_FILE_SIZE; iByte++ )
|
||||
{
|
||||
iReturned = f_putc( ( ( int ) '0' + iByte ), pxFile );
|
||||
configASSERT( iReturned == ( ( int ) '0' + iByte ) );
|
||||
}
|
||||
|
||||
/* Finished so close the file. */
|
||||
f_close( pxFile );
|
||||
|
||||
/* Move back to the root directory. */
|
||||
ucReturn = f_chdir( "../.." );
|
||||
configASSERT( ucReturn == F_NO_ERROR );
|
||||
|
||||
/* Obtain and print out the working directory. */
|
||||
f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );
|
||||
printf( "Back in root directory %s\r\n", cRAMBuffer );
|
||||
configASSERT( strcmp( ( const char * ) cRAMBuffer, pcRoot ) == 0 );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvVerifyDemoFileUsing_f_getc( void )
|
||||
{
|
||||
unsigned char ucReturn;
|
||||
int iByte, iReturned;
|
||||
F_FILE *pxFile;
|
||||
char cFileName[ fsMAX_FILE_NAME_LEN ];
|
||||
|
||||
/* Move into the directory in which the file was created. */
|
||||
ucReturn = f_chdir( pcFullPath );
|
||||
configASSERT( ucReturn == F_NO_ERROR );
|
||||
|
||||
/* Obtain and print out the working directory. */
|
||||
f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );
|
||||
printf( "Back in directory %s\r\n", cRAMBuffer );
|
||||
configASSERT( strcmp( ( const char * ) cRAMBuffer, pcFullPath ) == 0 );
|
||||
|
||||
/* Generate the file name. */
|
||||
sprintf( cFileName, "%s.txt", pcDirectory2 );
|
||||
|
||||
/* Print out the file name and the directory from which the file is being
|
||||
read. */
|
||||
printf( "Reading file %s in %s\r\n", cFileName, cRAMBuffer );
|
||||
|
||||
/* This time the file is opened for reading. */
|
||||
pxFile = f_open( cFileName, "r" );
|
||||
|
||||
/* Read the file 1 byte at a time. */
|
||||
for( iByte = 0; iByte < fsPUTC_FILE_SIZE; iByte++ )
|
||||
{
|
||||
iReturned = f_getc( pxFile );
|
||||
configASSERT( iReturned == ( ( int ) '0' + iByte ) );
|
||||
}
|
||||
|
||||
/* Finished so close the file. */
|
||||
f_close( pxFile );
|
||||
|
||||
/* Move back to the root directory. */
|
||||
ucReturn = f_chdir( "../.." );
|
||||
configASSERT( ucReturn == F_NO_ERROR );
|
||||
|
||||
/* Obtain and print out the working directory. */
|
||||
f_getcwd( cRAMBuffer, fsRAM_BUFFER_SIZE );
|
||||
printf( "Back in root directory %s\r\n", cRAMBuffer );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
Run the CreateProjectDirectoryStructure.bat batch file to populate this directory before building the demo.
|
|
@ -0,0 +1 @@
|
|||
Run the CreateProjectDirectoryStructure.bat batch file to populate this directory before building the demo.
|
|
@ -0,0 +1,426 @@
|
|||
/*
|
||||
FreeRTOS V7.4.2 - Copyright (C) 2013 Real Time Engineers Ltd.
|
||||
|
||||
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||
* Complete, revised, and edited pdf reference manuals are also *
|
||||
* available. *
|
||||
* *
|
||||
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||
* ensuring you get running as quickly as possible and with an *
|
||||
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||
* the FreeRTOS project to continue with its mission of providing *
|
||||
* professional grade, cross platform, de facto standard solutions *
|
||||
* for microcontrollers - completely free of charge! *
|
||||
* *
|
||||
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||
* *
|
||||
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||
|
||||
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to
|
||||
distribute a combined work that includes FreeRTOS without being obliged to
|
||||
provide the source code for proprietary components outside of the FreeRTOS
|
||||
kernel.
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details. You should have received a copy of the GNU General Public License
|
||||
and the FreeRTOS license exception along with FreeRTOS; if not itcan be
|
||||
viewed here: http://www.freertos.org/a00114.html and also obtained by
|
||||
writing to Real Time Engineers Ltd., contact details for whom are available
|
||||
on the FreeRTOS WEB site.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* Having a problem? Start by reading the FAQ "My application does *
|
||||
* not run, what could be wrong?" *
|
||||
* *
|
||||
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
|
||||
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||
license and Real Time Engineers Ltd. contact details.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, and our new
|
||||
fully thread aware and reentrant UDP/IP stack.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||
Integrity Systems, who sell the code with commercial support,
|
||||
indemnification and middleware, under the OpenRTOS brand.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* See the following URL for information on the commands defined in this file:
|
||||
* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Ethernet_Examples/Ethernet_Related_CLI_Commands.shtml
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* FreeRTOS+CLI includes. */
|
||||
#include "FreeRTOS_CLI.h"
|
||||
|
||||
#ifndef configINCLUDE_TRACE_RELATED_CLI_COMMANDS
|
||||
#define configINCLUDE_TRACE_RELATED_CLI_COMMANDS 0
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Implements the run-time-stats command.
|
||||
*/
|
||||
static portBASE_TYPE prvTaskStatsCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );
|
||||
|
||||
/*
|
||||
* Implements the task-stats command.
|
||||
*/
|
||||
static portBASE_TYPE prvRunTimeStatsCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );
|
||||
|
||||
/*
|
||||
* Implements the echo-three-parameters command.
|
||||
*/
|
||||
static portBASE_TYPE prvThreeParameterEchoCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );
|
||||
|
||||
/*
|
||||
* Implements the echo-parameters command.
|
||||
*/
|
||||
static portBASE_TYPE prvParameterEchoCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );
|
||||
|
||||
/*
|
||||
* Implements the "trace start" and "trace stop" commands;
|
||||
*/
|
||||
#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1
|
||||
static portBASE_TYPE prvStartStopTraceCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString );
|
||||
#endif
|
||||
|
||||
/* Structure that defines the "run-time-stats" command line command. This
|
||||
generates a table that shows how much run time each task has */
|
||||
static const CLI_Command_Definition_t xRunTimeStats =
|
||||
{
|
||||
( const int8_t * const ) "run-time-stats", /* The command string to type. */
|
||||
( const int8_t * const ) "\r\nrun-time-stats:\r\n Displays a table showing how much processing time each FreeRTOS task has used\r\n",
|
||||
prvRunTimeStatsCommand, /* The function to run. */
|
||||
0 /* No parameters are expected. */
|
||||
};
|
||||
|
||||
/* Structure that defines the "task-stats" command line command. This generates
|
||||
a table that gives information on each task in the system. */
|
||||
static const CLI_Command_Definition_t xTaskStats =
|
||||
{
|
||||
( const int8_t * const ) "task-stats", /* The command string to type. */
|
||||
( const int8_t * const ) "\r\ntask-stats:\r\n Displays a table showing the state of each FreeRTOS task\r\n",
|
||||
prvTaskStatsCommand, /* The function to run. */
|
||||
0 /* No parameters are expected. */
|
||||
};
|
||||
|
||||
/* Structure that defines the "echo_3_parameters" command line command. This
|
||||
takes exactly three parameters that the command simply echos back one at a
|
||||
time. */
|
||||
static const CLI_Command_Definition_t xThreeParameterEcho =
|
||||
{
|
||||
( const int8_t * const ) "echo-3-parameters",
|
||||
( const int8_t * const ) "\r\necho-3-parameters <param1> <param2> <param3>:\r\n Expects three parameters, echos each in turn\r\n",
|
||||
prvThreeParameterEchoCommand, /* The function to run. */
|
||||
3 /* Three parameters are expected, which can take any value. */
|
||||
};
|
||||
|
||||
/* Structure that defines the "echo_parameters" command line command. This
|
||||
takes a variable number of parameters that the command simply echos back one at
|
||||
a time. */
|
||||
static const CLI_Command_Definition_t xParameterEcho =
|
||||
{
|
||||
( const int8_t * const ) "echo-parameters",
|
||||
( const int8_t * const ) "\r\necho-parameters <...>:\r\n Take variable number of parameters, echos each in turn\r\n",
|
||||
prvParameterEchoCommand, /* The function to run. */
|
||||
-1 /* The user can enter any number of commands. */
|
||||
};
|
||||
|
||||
#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1
|
||||
/* Structure that defines the "trace" command line command. This takes a single
|
||||
parameter, which can be either "start" or "stop". */
|
||||
static const CLI_Command_Definition_t xStartStopTrace =
|
||||
{
|
||||
( const int8_t * const ) "trace",
|
||||
( const int8_t * const ) "\r\ntrace [start | stop]:\r\n Starts or stops a trace recording for viewing in FreeRTOS+Trace\r\n",
|
||||
prvStartStopTraceCommand, /* The function to run. */
|
||||
1 /* One parameter is expected. Valid values are "start" and "stop". */
|
||||
};
|
||||
#endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vRegisterSampleCLICommands( void )
|
||||
{
|
||||
/* Register all the command line commands defined immediately above. */
|
||||
FreeRTOS_CLIRegisterCommand( &xTaskStats );
|
||||
FreeRTOS_CLIRegisterCommand( &xRunTimeStats );
|
||||
FreeRTOS_CLIRegisterCommand( &xThreeParameterEcho );
|
||||
FreeRTOS_CLIRegisterCommand( &xParameterEcho );
|
||||
|
||||
#if( configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1 )
|
||||
{
|
||||
FreeRTOS_CLIRegisterCommand( & xStartStopTrace );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static portBASE_TYPE prvTaskStatsCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )
|
||||
{
|
||||
const int8_t *const pcHeader = ( int8_t * ) "Task State Priority Stack #\r\n************************************************\r\n";
|
||||
|
||||
/* Remove compile time warnings about unused parameters, and check the
|
||||
write buffer is not NULL. NOTE - for simplicity, this example assumes the
|
||||
write buffer length is adequate, so does not check for buffer overflows. */
|
||||
( void ) pcCommandString;
|
||||
( void ) xWriteBufferLen;
|
||||
configASSERT( pcWriteBuffer );
|
||||
|
||||
/* Generate a table of task stats. */
|
||||
strcpy( ( char * ) pcWriteBuffer, ( char * ) pcHeader );
|
||||
vTaskList( pcWriteBuffer + strlen( ( char * ) pcHeader ) );
|
||||
|
||||
/* There is no more data to return after this single string, so return
|
||||
pdFALSE. */
|
||||
return pdFALSE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static portBASE_TYPE prvRunTimeStatsCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )
|
||||
{
|
||||
const int8_t * const pcHeader = ( int8_t * ) "Task Abs Time % Time\r\n****************************************\r\n";
|
||||
|
||||
/* Remove compile time warnings about unused parameters, and check the
|
||||
write buffer is not NULL. NOTE - for simplicity, this example assumes the
|
||||
write buffer length is adequate, so does not check for buffer overflows. */
|
||||
( void ) pcCommandString;
|
||||
( void ) xWriteBufferLen;
|
||||
configASSERT( pcWriteBuffer );
|
||||
|
||||
/* Generate a table of task stats. */
|
||||
strcpy( ( char * ) pcWriteBuffer, ( char * ) pcHeader );
|
||||
vTaskGetRunTimeStats( pcWriteBuffer + strlen( ( char * ) pcHeader ) );
|
||||
|
||||
/* There is no more data to return after this single string, so return
|
||||
pdFALSE. */
|
||||
return pdFALSE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static portBASE_TYPE prvThreeParameterEchoCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )
|
||||
{
|
||||
int8_t *pcParameter;
|
||||
portBASE_TYPE xParameterStringLength, xReturn;
|
||||
static portBASE_TYPE lParameterNumber = 0;
|
||||
|
||||
/* Remove compile time warnings about unused parameters, and check the
|
||||
write buffer is not NULL. NOTE - for simplicity, this example assumes the
|
||||
write buffer length is adequate, so does not check for buffer overflows. */
|
||||
( void ) pcCommandString;
|
||||
( void ) xWriteBufferLen;
|
||||
configASSERT( pcWriteBuffer );
|
||||
|
||||
if( lParameterNumber == 0 )
|
||||
{
|
||||
/* The first time the function is called after the command has been
|
||||
entered just a header string is returned. */
|
||||
sprintf( ( char * ) pcWriteBuffer, "The three parameters were:\r\n" );
|
||||
|
||||
/* Next time the function is called the first parameter will be echoed
|
||||
back. */
|
||||
lParameterNumber = 1L;
|
||||
|
||||
/* There is more data to be returned as no parameters have been echoed
|
||||
back yet. */
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Obtain the parameter string. */
|
||||
pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter
|
||||
(
|
||||
pcCommandString, /* The command string itself. */
|
||||
lParameterNumber, /* Return the next parameter. */
|
||||
&xParameterStringLength /* Store the parameter string length. */
|
||||
);
|
||||
|
||||
/* Sanity check something was returned. */
|
||||
configASSERT( pcParameter );
|
||||
|
||||
/* Return the parameter string. */
|
||||
memset( pcWriteBuffer, 0x00, xWriteBufferLen );
|
||||
sprintf( ( char * ) pcWriteBuffer, "%d: ", ( int ) lParameterNumber );
|
||||
strncat( ( char * ) pcWriteBuffer, ( const char * ) pcParameter, xParameterStringLength );
|
||||
strncat( ( char * ) pcWriteBuffer, "\r\n", strlen( "\r\n" ) );
|
||||
|
||||
/* If this is the last of the three parameters then there are no more
|
||||
strings to return after this one. */
|
||||
if( lParameterNumber == 3L )
|
||||
{
|
||||
/* If this is the last of the three parameters then there are no more
|
||||
strings to return after this one. */
|
||||
xReturn = pdFALSE;
|
||||
lParameterNumber = 0L;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* There are more parameters to return after this one. */
|
||||
xReturn = pdTRUE;
|
||||
lParameterNumber++;
|
||||
}
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static portBASE_TYPE prvParameterEchoCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )
|
||||
{
|
||||
int8_t *pcParameter;
|
||||
portBASE_TYPE xParameterStringLength, xReturn;
|
||||
static portBASE_TYPE lParameterNumber = 0;
|
||||
|
||||
/* Remove compile time warnings about unused parameters, and check the
|
||||
write buffer is not NULL. NOTE - for simplicity, this example assumes the
|
||||
write buffer length is adequate, so does not check for buffer overflows. */
|
||||
( void ) pcCommandString;
|
||||
( void ) xWriteBufferLen;
|
||||
configASSERT( pcWriteBuffer );
|
||||
|
||||
if( lParameterNumber == 0 )
|
||||
{
|
||||
/* The first time the function is called after the command has been
|
||||
entered just a header string is returned. */
|
||||
sprintf( ( char * ) pcWriteBuffer, "The parameters were:\r\n" );
|
||||
|
||||
/* Next time the function is called the first parameter will be echoed
|
||||
back. */
|
||||
lParameterNumber = 1L;
|
||||
|
||||
/* There is more data to be returned as no parameters have been echoed
|
||||
back yet. */
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Obtain the parameter string. */
|
||||
pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter
|
||||
(
|
||||
pcCommandString, /* The command string itself. */
|
||||
lParameterNumber, /* Return the next parameter. */
|
||||
&xParameterStringLength /* Store the parameter string length. */
|
||||
);
|
||||
|
||||
if( pcParameter != NULL )
|
||||
{
|
||||
/* Return the parameter string. */
|
||||
memset( pcWriteBuffer, 0x00, xWriteBufferLen );
|
||||
sprintf( ( char * ) pcWriteBuffer, "%d: ", ( int ) lParameterNumber );
|
||||
strncat( ( char * ) pcWriteBuffer, ( const char * ) pcParameter, xParameterStringLength );
|
||||
strncat( ( char * ) pcWriteBuffer, "\r\n", strlen( "\r\n" ) );
|
||||
|
||||
/* There might be more parameters to return after this one. */
|
||||
xReturn = pdTRUE;
|
||||
lParameterNumber++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No more parameters were found. Make sure the write buffer does
|
||||
not contain a valid string. */
|
||||
pcWriteBuffer[ 0 ] = 0x00;
|
||||
|
||||
/* No more data to return. */
|
||||
xReturn = pdFALSE;
|
||||
|
||||
/* Start over the next time this command is executed. */
|
||||
lParameterNumber = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if configINCLUDE_TRACE_RELATED_CLI_COMMANDS == 1
|
||||
|
||||
static portBASE_TYPE prvStartStopTraceCommand( int8_t *pcWriteBuffer, size_t xWriteBufferLen, const int8_t *pcCommandString )
|
||||
{
|
||||
int8_t *pcParameter;
|
||||
portBASE_TYPE lParameterStringLength;
|
||||
|
||||
/* Remove compile time warnings about unused parameters, and check the
|
||||
write buffer is not NULL. NOTE - for simplicity, this example assumes the
|
||||
write buffer length is adequate, so does not check for buffer overflows. */
|
||||
( void ) pcCommandString;
|
||||
( void ) xWriteBufferLen;
|
||||
configASSERT( pcWriteBuffer );
|
||||
|
||||
/* Obtain the parameter string. */
|
||||
pcParameter = ( int8_t * ) FreeRTOS_CLIGetParameter
|
||||
(
|
||||
pcCommandString, /* The command string itself. */
|
||||
1, /* Return the first parameter. */
|
||||
&lParameterStringLength /* Store the parameter string length. */
|
||||
);
|
||||
|
||||
/* Sanity check something was returned. */
|
||||
configASSERT( pcParameter );
|
||||
|
||||
/* There are only two valid parameter values. */
|
||||
if( strncmp( ( const char * ) pcParameter, "start", strlen( "start" ) ) == 0 )
|
||||
{
|
||||
/* Start or restart the trace. */
|
||||
vTraceStop();
|
||||
vTraceClear();
|
||||
vTraceStart();
|
||||
|
||||
sprintf( ( char * ) pcWriteBuffer, "Trace recording (re)started.\r\n" );
|
||||
}
|
||||
else if( strncmp( ( const char * ) pcParameter, "stop", strlen( "stop" ) ) == 0 )
|
||||
{
|
||||
/* End the trace, if one is running. */
|
||||
vTraceStop();
|
||||
sprintf( ( char * ) pcWriteBuffer, "Stopping trace recording.\r\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( ( char * ) pcWriteBuffer, "Valid parameters are 'start' and 'stop'.\r\n" );
|
||||
}
|
||||
|
||||
/* There is no more data to return after this single string, so return
|
||||
pdFALSE. */
|
||||
return pdFALSE;
|
||||
}
|
||||
|
||||
#endif /* configINCLUDE_TRACE_RELATED_CLI_COMMANDS */
|
|
@ -0,0 +1,290 @@
|
|||
/*
|
||||
FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd.
|
||||
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||
* Complete, revised, and edited pdf reference manuals are also *
|
||||
* available. *
|
||||
* *
|
||||
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||
* ensuring you get running as quickly as possible and with an *
|
||||
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||
* the FreeRTOS project to continue with its mission of providing *
|
||||
* professional grade, cross platform, de facto standard solutions *
|
||||
* for microcontrollers - completely free of charge! *
|
||||
* *
|
||||
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||
* *
|
||||
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||
distribute a combined work that includes FreeRTOS without being obliged to
|
||||
provide the source code for proprietary components outside of the FreeRTOS
|
||||
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
more details. You should have received a copy of the GNU General Public
|
||||
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||
by writing to Richard Barry, contact details for whom are available on the
|
||||
FreeRTOS WEB site.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
|
||||
http://www.FreeRTOS.org - Documentation, latest information, license and
|
||||
contact details.
|
||||
|
||||
http://www.SafeRTOS.com - A version that is certified for use in safety
|
||||
critical systems.
|
||||
|
||||
http://www.OpenRTOS.com - Commercial support, development, porting,
|
||||
licensing and training services.
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include "string.h"
|
||||
#include "stdio.h"
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
|
||||
/* Driver includes. */
|
||||
#include "drivers/mss_uart/mss_uart.h"
|
||||
|
||||
/* Example includes. */
|
||||
#include "FreeRTOS_CLI.h"
|
||||
#include "UARTCommandConsole.h"
|
||||
|
||||
/* Dimensions the buffer into which input characters are placed. */
|
||||
#define cmdMAX_INPUT_SIZE 50
|
||||
|
||||
/* The maximum time in ticks to wait for the UART access mutex. */
|
||||
#define cmdMAX_MUTEX_WAIT ( 200 / portTICK_RATE_MS )
|
||||
|
||||
/* Characters are only ever received slowly on the CLI so it is ok to pass
|
||||
received characters from the UART interrupt to the task on a queue. This sets
|
||||
the length of the queue used for that purpose. */
|
||||
#define cmdRXED_CHARS_QUEUE_LENGTH ( 10 )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* The task that implements the command console processing.
|
||||
*/
|
||||
static void prvUARTCommandConsoleTask( void *pvParameters );
|
||||
|
||||
/*
|
||||
* Ensure a previous interrupt driven Tx has completed before sending the next
|
||||
* data block to the UART.
|
||||
*/
|
||||
static void prvSendBuffer( const uint8_t * pcBuffer, size_t xBufferLength );
|
||||
|
||||
/*
|
||||
* A UART is used for printf() output and CLI input and output. Configure the
|
||||
* UART and register prvUARTRxNotificationHandler() to handle UART Rx events.
|
||||
*/
|
||||
static void prvConfigureUART( void );
|
||||
static void prvUARTRxNotificationHandler( mss_uart_instance_t * this_uart );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Const messages output by the command console. */
|
||||
static const uint8_t * const pcWelcomeMessage = ( uint8_t * ) "\r\n\r\nFreeRTOS command server.\r\nType Help to view a list of registered commands.\r\n\r\n>";
|
||||
static const uint8_t * const pcEndOfOutputMessage = ( uint8_t * ) "\r\n[Press ENTER to execute the previous command again]\r\n>";
|
||||
static const uint8_t * const pcNewLine = ( uint8_t * ) "\r\n";
|
||||
|
||||
/* The UART used by the CLI. */
|
||||
static const mss_uart_instance_t * const pxUART = &g_mss_uart1;
|
||||
static const IRQn_Type xUART_IRQ = UART1_IRQn;
|
||||
|
||||
/* Because characters are received slowly (at the speed somebody can type) then
|
||||
it is ok to pass received characters from the Rx interrupt to the task on a
|
||||
queue. This is the queue used for that purpose. */
|
||||
static xQueueHandle xRxedChars = NULL;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vUARTCommandConsoleStart( uint16_t usStackSize, unsigned portBASE_TYPE uxPriority )
|
||||
{
|
||||
/* A UART is used for printf() output and CLI input and output. Note there
|
||||
is no mutual exclusion on the UART, but the demo as it stands does not
|
||||
require mutual exclusion. */
|
||||
prvConfigureUART();
|
||||
|
||||
/* Create that task that handles the console itself. */
|
||||
xTaskCreate( prvUARTCommandConsoleTask, /* The task that implements the command console. */
|
||||
( const int8_t * const ) "CLI", /* Text name assigned to the task. This is just to assist debugging. The kernel does not use this name itself. */
|
||||
usStackSize, /* The size of the stack allocated to the task. */
|
||||
NULL, /* The parameter is not used, so NULL is passed. */
|
||||
uxPriority, /* The priority allocated to the task. */
|
||||
NULL ); /* A handle is not required, so just pass NULL. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvUARTCommandConsoleTask( void *pvParameters )
|
||||
{
|
||||
int8_t cRxedChar, cInputIndex = 0, *pcOutputString;
|
||||
static int8_t cInputString[ cmdMAX_INPUT_SIZE ], cLastInputString[ cmdMAX_INPUT_SIZE ];
|
||||
portBASE_TYPE xReturned;
|
||||
|
||||
( void ) pvParameters;
|
||||
|
||||
/* Obtain the address of the output buffer. Note there is no mutual
|
||||
exclusion on this buffer as it is assumed only one command console
|
||||
interface will be used at any one time. */
|
||||
pcOutputString = FreeRTOS_CLIGetOutputBuffer();
|
||||
|
||||
/* Send the welcome message. */
|
||||
prvSendBuffer( pcWelcomeMessage, strlen( ( char * ) pcWelcomeMessage ) );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
/* Wait for the next character to arrive. */
|
||||
if( xQueueReceive( xRxedChars, &cRxedChar, portMAX_DELAY ) == pdPASS )
|
||||
{
|
||||
/* Echo the character back. */
|
||||
prvSendBuffer( ( uint8_t * ) &cRxedChar, sizeof( cRxedChar ) );
|
||||
|
||||
/* Was it the end of the line? */
|
||||
if( cRxedChar == '\n' || cRxedChar == '\r' )
|
||||
{
|
||||
/* Just to space the output from the input. */
|
||||
prvSendBuffer( ( uint8_t * ) pcNewLine, strlen( ( char * ) pcNewLine ) );
|
||||
|
||||
/* See if the command is empty, indicating that the last command is
|
||||
to be executed again. */
|
||||
if( cInputIndex == 0 )
|
||||
{
|
||||
/* Copy the last command back into the input string. */
|
||||
strcpy( ( char * ) cInputString, ( char * ) cLastInputString );
|
||||
}
|
||||
|
||||
/* Pass the received command to the command interpreter. The
|
||||
command interpreter is called repeatedly until it returns pdFALSE
|
||||
(indicating there is no more output) as it might generate more than
|
||||
one string. */
|
||||
do
|
||||
{
|
||||
/* Get the next output string from the command interpreter. */
|
||||
xReturned = FreeRTOS_CLIProcessCommand( cInputString, pcOutputString, configCOMMAND_INT_MAX_OUTPUT_SIZE );
|
||||
|
||||
/* Write the generated string to the UART. */
|
||||
prvSendBuffer( ( uint8_t * ) pcOutputString, strlen( ( char * ) pcOutputString ) );
|
||||
|
||||
} while( xReturned != pdFALSE );
|
||||
|
||||
/* All the strings generated by the input command have been sent.
|
||||
Clear the input string ready to receive the next command. Remember
|
||||
the command that was just processed first in case it is to be
|
||||
processed again. */
|
||||
strcpy( ( char * ) cLastInputString, ( char * ) cInputString );
|
||||
cInputIndex = 0;
|
||||
memset( cInputString, 0x00, cmdMAX_INPUT_SIZE );
|
||||
|
||||
prvSendBuffer( ( uint8_t * ) pcEndOfOutputMessage, strlen( ( char * ) pcEndOfOutputMessage ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( cRxedChar == '\r' )
|
||||
{
|
||||
/* Ignore the character. */
|
||||
}
|
||||
else if( cRxedChar == '\b' )
|
||||
{
|
||||
/* Backspace was pressed. Erase the last character in the
|
||||
string - if any. */
|
||||
if( cInputIndex > 0 )
|
||||
{
|
||||
cInputIndex--;
|
||||
cInputString[ cInputIndex ] = '\0';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* A character was entered. Add it to the string
|
||||
entered so far. When a \n is entered the complete
|
||||
string will be passed to the command interpreter. */
|
||||
if( ( cRxedChar >= ' ' ) && ( cRxedChar <= '~' ) )
|
||||
{
|
||||
if( cInputIndex < cmdMAX_INPUT_SIZE )
|
||||
{
|
||||
cInputString[ cInputIndex ] = cRxedChar;
|
||||
cInputIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvSendBuffer( const uint8_t * pcBuffer, size_t xBufferLength )
|
||||
{
|
||||
const portTickType xVeryShortDelay = 2UL;
|
||||
|
||||
MSS_UART_irq_tx( ( mss_uart_instance_t * ) pxUART, pcBuffer, xBufferLength );
|
||||
|
||||
/* Ensure any previous transmissions have completed. The default UART
|
||||
interrupt does not provide an event based method of signally the end of a Tx
|
||||
- this is therefore a crude poll of the Tx end status. Replacing the
|
||||
default UART handler with one that 'gives' a semaphore when the Tx is
|
||||
complete would allow this poll loop to be replaced by a simple semaphore
|
||||
block. */
|
||||
while( MSS_UART_tx_complete( ( mss_uart_instance_t * ) pxUART ) == pdFALSE )
|
||||
{
|
||||
vTaskDelay( xVeryShortDelay );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvConfigureUART( void )
|
||||
{
|
||||
/* Initialise the UART which is used for printf() and CLI IO. */
|
||||
MSS_UART_init( ( mss_uart_instance_t * ) pxUART, MSS_UART_115200_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT );
|
||||
|
||||
/* Characters are only ever received slowly on the CLI so it is ok to pass
|
||||
received characters from the UART interrupt to the task on a queue. Create
|
||||
the queue used for that purpose. */
|
||||
xRxedChars = xQueueCreate( cmdRXED_CHARS_QUEUE_LENGTH, sizeof( char ) );
|
||||
|
||||
/* The interrupt handler makes use of FreeRTOS API functions, so its
|
||||
priority must be at or below the configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY
|
||||
setting (the higher the numeric priority, the lower the logical priority). */
|
||||
NVIC_SetPriority( xUART_IRQ, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
|
||||
|
||||
/* Set the UART Rx notification function. */
|
||||
MSS_UART_set_rx_handler( ( mss_uart_instance_t * ) pxUART, prvUARTRxNotificationHandler, MSS_UART_FIFO_SINGLE_BYTE );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvUARTRxNotificationHandler( mss_uart_instance_t * pxUART )
|
||||
{
|
||||
uint8_t cRxed;
|
||||
portBASE_TYPE xHigherPriorityTaskWoken;
|
||||
|
||||
/* The command console receives data very slowly (at the speed of somebody
|
||||
typing), therefore it is ok to just handle one character at a time and use
|
||||
a queue to send the characters to the task. */
|
||||
if( MSS_UART_get_rx( pxUART, &cRxed, sizeof( cRxed ) ) == sizeof( cRxed ) )
|
||||
{
|
||||
xHigherPriorityTaskWoken = pdFALSE;
|
||||
xQueueSendFromISR( xRxedChars, &cRxed, &xHigherPriorityTaskWoken );
|
||||
|
||||
/* portEND_SWITCHING_ISR() or portYIELD_FROM_ISR() can be used here. */
|
||||
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
FreeRTOS V7.4.2 - Copyright (C) 2013 Real Time Engineers Ltd.
|
||||
|
||||
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||
* Complete, revised, and edited pdf reference manuals are also *
|
||||
* available. *
|
||||
* *
|
||||
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||
* ensuring you get running as quickly as possible and with an *
|
||||
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||
* the FreeRTOS project to continue with its mission of providing *
|
||||
* professional grade, cross platform, de facto standard solutions *
|
||||
* for microcontrollers - completely free of charge! *
|
||||
* *
|
||||
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||
* *
|
||||
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||
|
||||
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to
|
||||
distribute a combined work that includes FreeRTOS without being obliged to
|
||||
provide the source code for proprietary components outside of the FreeRTOS
|
||||
kernel.
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details. You should have received a copy of the GNU General Public License
|
||||
and the FreeRTOS license exception along with FreeRTOS; if not it can be
|
||||
viewed here: http://www.freertos.org/a00114.html and also obtained by
|
||||
writing to Real Time Engineers Ltd., contact details for whom are available
|
||||
on the FreeRTOS WEB site.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* Having a problem? Start by reading the FAQ "My application does *
|
||||
* not run, what could be wrong?" *
|
||||
* *
|
||||
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
|
||||
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||
license and Real Time Engineers Ltd. contact details.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, and our new
|
||||
fully thread aware and reentrant UDP/IP stack.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||
Integrity Systems, who sell the code with commercial support,
|
||||
indemnification and middleware, under the OpenRTOS brand.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
*/
|
||||
|
||||
#ifndef UART_COMMAND_CONSOLE_H
|
||||
#define UART_COMMAND_CONSOLE_H
|
||||
|
||||
/*
|
||||
* Create the task that implements a command console using the USB virtual com
|
||||
* port driver for intput and output.
|
||||
*/
|
||||
void vUARTCommandConsoleStart( uint16_t usStackSize, unsigned portBASE_TYPE uxPriority );
|
||||
|
||||
#endif /* UART_COMMAND_CONSOLE_H */
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded
|
||||
*
|
||||
* FreeRTOS+FAT SL is an complementary component provided to Real Time Engineers
|
||||
* Ltd. by HCC Embedded for use with FreeRTOS. It is not, in itself, part of
|
||||
* the FreeRTOS kernel. FreeRTOS+FAT SL is licensed separately from FreeRTOS,
|
||||
* and uses a different license to FreeRTOS. FreeRTOS+FAT SL uses a dual
|
||||
* license model, information on which is provided below:
|
||||
*
|
||||
* - Open source licensing -
|
||||
* FreeRTOS+FAT SL is a free download and may be used, modified and distributed
|
||||
* without charge provided the user adheres to version two of the GNU General
|
||||
* Public license (GPL) and does not remove the copyright notice or this text.
|
||||
* The GPL V2 text is available on the gnu.org web site, and on the following
|
||||
* URL: http://www.FreeRTOS.org/gpl-2.0.txt
|
||||
*
|
||||
* - Commercial licensing -
|
||||
* Businesses and individuals who wish to incorporate FreeRTOS+FAT SL into
|
||||
* proprietary software for redistribution in any form must first obtain a
|
||||
* commercial license - and in-so-doing support the maintenance, support and
|
||||
* further development of the FreeRTOS+FAT SL product. Commercial licenses can
|
||||
* be obtained from http://shop.freertos.org and do not require any source files
|
||||
* to be changed.
|
||||
*
|
||||
* FreeRTOS+FAT SL is distributed in the hope that it will be useful. You
|
||||
* cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as
|
||||
* is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the
|
||||
* implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all
|
||||
* conditions and terms, be they implied, expressed, or statutory.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://www.FreeRTOS.org/FreeRTOS-Plus
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CONFIG_FAT_SL_H
|
||||
#define _CONFIG_FAT_SL_H
|
||||
|
||||
#include "../version/ver_fat_sl.h"
|
||||
#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2
|
||||
#error Incompatible FAT_SL version number!
|
||||
#endif
|
||||
|
||||
#include "../api/api_mdriver.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
**
|
||||
** FAT SL user settings
|
||||
**
|
||||
**************************************************************************/
|
||||
#define F_SECTOR_SIZE 512u /* Disk sector size. */
|
||||
#define F_FS_THREAD_AWARE 1 /* Set to one if the file system will be access from more than one task. */
|
||||
#define F_MAXPATH 64 /* Maximum length a file name (including its full path) can be. */
|
||||
#define F_MAX_LOCK_WAIT_TICKS 20 /* The maximum number of RTOS ticks to wait when attempting to obtain a lock on the file system when F_FS_THREAD_AWARE is set to 1. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _CONFIG_FAT_SL_H */
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded
|
||||
*
|
||||
* FreeRTOS+FAT SL is an complementary component provided to Real Time Engineers
|
||||
* Ltd. by HCC Embedded for use with FreeRTOS. It is not, in itself, part of
|
||||
* the FreeRTOS kernel. FreeRTOS+FAT SL is licensed separately from FreeRTOS,
|
||||
* and uses a different license to FreeRTOS. FreeRTOS+FAT SL uses a dual
|
||||
* license model, information on which is provided below:
|
||||
*
|
||||
* - Open source licensing -
|
||||
* FreeRTOS+FAT SL is a free download and may be used, modified and distributed
|
||||
* without charge provided the user adheres to version two of the GNU General
|
||||
* Public license (GPL) and does not remove the copyright notice or this text.
|
||||
* The GPL V2 text is available on the gnu.org web site, and on the following
|
||||
* URL: http://www.FreeRTOS.org/gpl-2.0.txt
|
||||
*
|
||||
* - Commercial licensing -
|
||||
* Businesses and individuals who wish to incorporate FreeRTOS+FAT SL into
|
||||
* proprietary software for redistribution in any form must first obtain a
|
||||
* commercial license - and in-so-doing support the maintenance, support and
|
||||
* further development of the FreeRTOS+FAT SL product. Commercial licenses can
|
||||
* be obtained from http://shop.freertos.org and do not require any source files
|
||||
* to be changed.
|
||||
*
|
||||
* FreeRTOS+FAT SL is distributed in the hope that it will be useful. You
|
||||
* cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as
|
||||
* is'. FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the
|
||||
* implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all
|
||||
* conditions and terms, be they implied, expressed, or statutory.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://www.FreeRTOS.org/FreeRTOS-Plus
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CONFIG_MDRIVER_RAM_H_
|
||||
#define _CONFIG_MDRIVER_RAM_H_
|
||||
|
||||
#include "../version/ver_mdriver_ram.h"
|
||||
#if VER_MDRIVER_RAM_MAJOR != 1 || VER_MDRIVER_RAM_MINOR != 2
|
||||
#error Incompatible MDRIVER_RAM version number!
|
||||
#endif
|
||||
|
||||
#define MDRIVER_RAM_SECTOR_SIZE 512 /* Sector size */
|
||||
|
||||
#define MDRIVER_RAM_VOLUME0_SIZE (28 * 1024) /* defintion for size of ramdrive0 */
|
||||
|
||||
#define MDRIVER_MEM_LONG_ACCESS 1 /* set this value to 1 if 32bit access available */
|
||||
|
||||
#endif /* ifndef _CONFIG_MDRIVER_RAM_H_ */
|
||||
|
|
@ -0,0 +1,367 @@
|
|||
/*
|
||||
FreeRTOS V7.4.2 - Copyright (C) 2013 Real Time Engineers Ltd.
|
||||
|
||||
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||
* Complete, revised, and edited pdf reference manuals are also *
|
||||
* available. *
|
||||
* *
|
||||
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||
* ensuring you get running as quickly as possible and with an *
|
||||
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||
* the FreeRTOS project to continue with its mission of providing *
|
||||
* professional grade, cross platform, de facto standard solutions *
|
||||
* for microcontrollers - completely free of charge! *
|
||||
* *
|
||||
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||
* *
|
||||
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||
|
||||
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to
|
||||
distribute a combined work that includes FreeRTOS without being obliged to
|
||||
provide the source code for proprietary components outside of the FreeRTOS
|
||||
kernel.
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details. You should have received a copy of the GNU General Public License
|
||||
and the FreeRTOS license exception along with FreeRTOS; if not it can be
|
||||
viewed here: http://www.freertos.org/a00114.html and also obtained by
|
||||
writing to Real Time Engineers Ltd., contact details for whom are available
|
||||
on the FreeRTOS WEB site.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* Having a problem? Start by reading the FAQ "My application does *
|
||||
* not run, what could be wrong?" *
|
||||
* *
|
||||
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
|
||||
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||
license and Real Time Engineers Ltd. contact details.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, and our new
|
||||
fully thread aware and reentrant UDP/IP stack.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||
Integrity Systems, who sell the code with commercial support,
|
||||
indemnification and middleware, under the OpenRTOS brand.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* NOTE 1: This project provides two demo applications. A simple blinky style
|
||||
* project, and a more comprehensive test and demo application. The
|
||||
* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select
|
||||
* between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY
|
||||
* in main.c. This file implements the comprehensive test and demo version.
|
||||
*
|
||||
* NOTE 2: This file only contains the source code that is specific to the
|
||||
* full demo. Generic functions, such FreeRTOS hook functions, and functions
|
||||
* required to configure the hardware, are defined in main.c.
|
||||
******************************************************************************
|
||||
*
|
||||
* main_full() creates all the demo application tasks and a software timer, then
|
||||
* starts the scheduler. The web documentation provides more details of the
|
||||
* standard demo application tasks, which provide no particular functionality,
|
||||
* but do provide a good example of how to use the FreeRTOS API.
|
||||
*
|
||||
* In addition to the standard demo tasks, the following tasks and tests are
|
||||
* defined and/or created within this file:
|
||||
*
|
||||
* "Check" timer - The check software timer period is initially set to three
|
||||
* seconds. The callback function associated with the check software timer
|
||||
* checks that all the standard demo tasks are not only still executing, but
|
||||
* are executing without reporting any errors. If the check software timer
|
||||
* discovers that a task has either stalled, or reported an error, then it
|
||||
* changes its own execution period from the initial three seconds, to just
|
||||
* 200ms. The check software timer callback function also toggles the green
|
||||
* LED each time it is called. This provides a visual indication of the system
|
||||
* status: If the green LED toggles every three seconds, then no issues have
|
||||
* been discovered. If the green LED toggles every 200ms, then an issue has
|
||||
* been discovered with at least one task.
|
||||
*
|
||||
* FreeRTOS+CLI command console. The command console is access through UART0
|
||||
* using 115200 baud and the Microsemi MSS UART drivers. Type "help" to see a
|
||||
* list of registered commands, which include some basic file system commands
|
||||
* (see FreeRTOS+FAT SL comments below). The FreeRTOS+CLI license is different
|
||||
* to the FreeRTOS license, see http://www.FreeRTOS.org/cli for license and
|
||||
* usage details.
|
||||
*
|
||||
* FreeRTOS+FAT SL. FreeRTOS+FAT SL is demonstrated using a RAM disk. [At the
|
||||
* time of writing] The functionality of the file system demo is identical to
|
||||
* the functionality of the FreeRTOS Win32 simulator file system demo with the
|
||||
* command console being accessed via the UART (as described above) instead of
|
||||
* a network terminal. The FreeRTOS+FAT SL license is different to the FreeRTOS
|
||||
* license, see http://www.FreeRTOS.org/fat_sl for license and usage details,
|
||||
* and a description of the file system demo functionality.
|
||||
*
|
||||
* See the documentation page for this demo on the FreeRTOS.org web site for
|
||||
* full information, including hardware setup requirements.
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdio.h>
|
||||
|
||||
/* Kernel includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "timers.h"
|
||||
#include "queue.h"
|
||||
|
||||
/* Standard demo application includes. */
|
||||
#include "integer.h"
|
||||
#include "PollQ.h"
|
||||
#include "semtest.h"
|
||||
#include "dynamic.h"
|
||||
#include "BlockQ.h"
|
||||
#include "blocktim.h"
|
||||
#include "countsem.h"
|
||||
#include "GenQTest.h"
|
||||
#include "recmutex.h"
|
||||
#include "death.h"
|
||||
#include "flash_timer.h"
|
||||
#include "partest.h"
|
||||
#include "UARTCommandConsole.h"
|
||||
|
||||
/* Priorities for the demo application tasks. */
|
||||
#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2UL )
|
||||
#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1UL )
|
||||
#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2UL )
|
||||
#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3UL )
|
||||
#define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY )
|
||||
|
||||
/* A block time of zero simply means "don't block". */
|
||||
#define mainDONT_BLOCK ( 0UL )
|
||||
|
||||
/* The period after which the check timer will expire, in ms, provided no errors
|
||||
have been reported by any of the standard demo tasks. ms are converted to the
|
||||
equivalent in ticks using the portTICK_RATE_MS constant. */
|
||||
#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_RATE_MS )
|
||||
|
||||
/* The period at which the check timer will expire, in ms, if an error has been
|
||||
reported in one of the standard demo tasks. ms are converted to the equivalent
|
||||
in ticks using the portTICK_RATE_MS constant. */
|
||||
#define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_RATE_MS )
|
||||
|
||||
/* The standard demo flash timers can be used to flash any number of LEDs. In
|
||||
this case, because only three LEDs are available, and one is in use by the
|
||||
check timer, only two are used by the flash timers. */
|
||||
#define mainNUMBER_OF_FLASH_TIMERS_LEDS ( 1 )
|
||||
|
||||
/* The LED toggled by the check timer. The first two LEDs are toggle by the
|
||||
standard demo flash timers. */
|
||||
#define mainCHECK_LED ( 1 )
|
||||
|
||||
/* The size of the stack and the priority used by the UART command console
|
||||
task. */
|
||||
#define mainUART_COMMAND_CONSOLE_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 )
|
||||
#define mainUART_COMMAND_CONSOLE_TASK_PRIORITY ( tskIDLE_PRIORITY )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* The check timer callback function, as described at the top of this file.
|
||||
*/
|
||||
static void prvCheckTimerCallback( xTimerHandle xTimer );
|
||||
|
||||
/*
|
||||
* Register commands that can be used with FreeRTOS+CLI. The commands are
|
||||
* defined in CLI-Commands.c and File-Related-CLI-Command.c respectively.
|
||||
*/
|
||||
extern void vRegisterSampleCLICommands( void );
|
||||
extern void vRegisterFileSystemCLICommands( void );
|
||||
|
||||
/* Prepare to run the full demo: Configure the IO, register the CLI
|
||||
* commands, and depending on configuration, generate a set of sample files on
|
||||
* a RAM disk.
|
||||
*/
|
||||
static void prvPrepareForFullDemo( void );
|
||||
|
||||
/*
|
||||
* Creates and verifies different files on the volume, demonstrating the use of
|
||||
* various different API functions.
|
||||
*/
|
||||
extern void vCreateAndVerifySampleFiles( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void main_full( void )
|
||||
{
|
||||
xTimerHandle xCheckTimer = NULL;
|
||||
|
||||
/* Prepare to run the full demo: Configure the IO, register the CLI
|
||||
commands, and depending on configuration, generate a set of sample files on
|
||||
a RAM disk. */
|
||||
prvPrepareForFullDemo();
|
||||
|
||||
/* Start all the other standard demo/test tasks. The have not particular
|
||||
functionality, but do demonstrate how to use the FreeRTOS API and test the
|
||||
kernel port. */
|
||||
vStartIntegerMathTasks( tskIDLE_PRIORITY );
|
||||
vStartDynamicPriorityTasks();
|
||||
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
|
||||
vCreateBlockTimeTasks();
|
||||
vStartCountingSemaphoreTasks();
|
||||
vStartGenericQueueTasks( tskIDLE_PRIORITY );
|
||||
vStartRecursiveMutexTasks();
|
||||
vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );
|
||||
vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );
|
||||
vStartLEDFlashTimers( mainNUMBER_OF_FLASH_TIMERS_LEDS );
|
||||
|
||||
/* Start the tasks that implements the command console on the UART, as
|
||||
described above. */
|
||||
vUARTCommandConsoleStart( mainUART_COMMAND_CONSOLE_STACK_SIZE, mainUART_COMMAND_CONSOLE_TASK_PRIORITY );
|
||||
|
||||
/* Create the software timer that performs the 'check' functionality,
|
||||
as described at the top of this file. */
|
||||
xCheckTimer = xTimerCreate( ( const signed char * ) "CheckTimer",/* A text name, purely to help debugging. */
|
||||
( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
|
||||
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
|
||||
( void * ) 0, /* The ID is not used, so can be set to anything. */
|
||||
prvCheckTimerCallback /* The callback function that inspects the status of all the other tasks. */
|
||||
);
|
||||
|
||||
if( xCheckTimer != NULL )
|
||||
{
|
||||
xTimerStart( xCheckTimer, mainDONT_BLOCK );
|
||||
}
|
||||
|
||||
/* The set of tasks created by the following function call have to be
|
||||
created last as they keep account of the number of tasks they expect to see
|
||||
running. */
|
||||
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
|
||||
|
||||
/* Start the scheduler. */
|
||||
vTaskStartScheduler();
|
||||
|
||||
/* If all is well, the scheduler will now be running, and the following line
|
||||
will never be reached. If the following line does execute, then there was
|
||||
insufficient FreeRTOS heap memory available for the idle and/or timer tasks
|
||||
to be created. See the memory management section on the FreeRTOS web site
|
||||
for more details. */
|
||||
for( ;; );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvCheckTimerCallback( xTimerHandle xTimer )
|
||||
{
|
||||
static long lChangedTimerPeriodAlready = pdFALSE;
|
||||
unsigned long ulErrorFound = pdFALSE;
|
||||
|
||||
/* Check all the demo tasks (other than the flash tasks) to ensure
|
||||
they are all still running, and that none have detected an error. */
|
||||
if( xAreIntegerMathsTaskStillRunning() != pdTRUE )
|
||||
{
|
||||
ulErrorFound = pdTRUE;
|
||||
}
|
||||
|
||||
if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )
|
||||
{
|
||||
ulErrorFound = pdTRUE;
|
||||
}
|
||||
|
||||
if( xAreBlockingQueuesStillRunning() != pdTRUE )
|
||||
{
|
||||
ulErrorFound = pdTRUE;
|
||||
}
|
||||
|
||||
if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
|
||||
{
|
||||
ulErrorFound = pdTRUE;
|
||||
}
|
||||
|
||||
if ( xAreGenericQueueTasksStillRunning() != pdTRUE )
|
||||
{
|
||||
ulErrorFound = pdTRUE;
|
||||
}
|
||||
|
||||
if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE )
|
||||
{
|
||||
ulErrorFound = pdTRUE;
|
||||
}
|
||||
|
||||
if( xIsCreateTaskStillRunning() != pdTRUE )
|
||||
{
|
||||
ulErrorFound = pdTRUE;
|
||||
}
|
||||
|
||||
if( xArePollingQueuesStillRunning() != pdTRUE )
|
||||
{
|
||||
ulErrorFound = pdTRUE;
|
||||
}
|
||||
|
||||
if( xAreSemaphoreTasksStillRunning() != pdTRUE )
|
||||
{
|
||||
ulErrorFound = pdTRUE;
|
||||
}
|
||||
|
||||
/* Toggle the check LED to give an indication of the system status. If
|
||||
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
|
||||
everything is ok. A faster toggle indicates an error. */
|
||||
vParTestToggleLED( mainCHECK_LED );
|
||||
|
||||
/* Have any errors been latch in ulErrorFound? If so, shorten the
|
||||
period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds.
|
||||
This will result in an increase in the rate at which mainCHECK_LED
|
||||
toggles. */
|
||||
if( ulErrorFound != pdFALSE )
|
||||
{
|
||||
if( lChangedTimerPeriodAlready == pdFALSE )
|
||||
{
|
||||
lChangedTimerPeriodAlready = pdTRUE;
|
||||
|
||||
/* This call to xTimerChangePeriod() uses a zero block time.
|
||||
Functions called from inside of a timer callback function must
|
||||
*never* attempt to block. */
|
||||
xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvPrepareForFullDemo( void )
|
||||
{
|
||||
/* If the file system is only going to be accessed from one task then
|
||||
F_FS_THREAD_AWARE can be set to 0 and the set of example files are created
|
||||
before the RTOS scheduler is started. If the file system is going to be
|
||||
access from more than one task then F_FS_THREAD_AWARE must be set to 1 and
|
||||
the set of sample files are created from the idle task hook function
|
||||
vApplicationIdleHook() - which is defined in this file. */
|
||||
#if F_FS_THREAD_AWARE == 0
|
||||
{
|
||||
/* Initialise the drive and file system, then create a few example
|
||||
files. The output from this function just goes to the stdout window,
|
||||
allowing the output to be viewed when the UDP command console is not
|
||||
connected. */
|
||||
vCreateAndVerifySampleFiles();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Register both the standard and file system related CLI commands. */
|
||||
vRegisterSampleCLICommands();
|
||||
vRegisterFileSystemCLICommands();
|
||||
}
|
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
FreeRTOS V7.4.2 - Copyright (C) 2013 Real Time Engineers Ltd.
|
||||
|
||||
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||
* Complete, revised, and edited pdf reference manuals are also *
|
||||
* available. *
|
||||
* *
|
||||
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||
* ensuring you get running as quickly as possible and with an *
|
||||
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||
* the FreeRTOS project to continue with its mission of providing *
|
||||
* professional grade, cross platform, de facto standard solutions *
|
||||
* for microcontrollers - completely free of charge! *
|
||||
* *
|
||||
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||
* *
|
||||
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||
|
||||
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to
|
||||
distribute a combined work that includes FreeRTOS without being obliged to
|
||||
provide the source code for proprietary components outside of the FreeRTOS
|
||||
kernel.
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details. You should have received a copy of the GNU General Public License
|
||||
and the FreeRTOS license exception along with FreeRTOS; if not it can be
|
||||
viewed here: http://www.freertos.org/a00114.html and also obtained by
|
||||
writing to Real Time Engineers Ltd., contact details for whom are available
|
||||
on the FreeRTOS WEB site.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* Having a problem? Start by reading the FAQ "My application does *
|
||||
* not run, what could be wrong?" *
|
||||
* *
|
||||
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
|
||||
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||
license and Real Time Engineers Ltd. contact details.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, and our new
|
||||
fully thread aware and reentrant UDP/IP stack.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||
Integrity Systems, who sell the code with commercial support,
|
||||
indemnification and middleware, under the OpenRTOS brand.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Simple IO routines to control the LEDs.
|
||||
* This file is called ParTest.c for historic reasons. Originally it stood for
|
||||
* PARallel port TEST.
|
||||
*-----------------------------------------------------------*/
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Demo includes. */
|
||||
#include "partest.h"
|
||||
|
||||
/* Library includes. */
|
||||
#include "drivers/mss_gpio/mss_gpio.h"
|
||||
#include "CMSIS/system_m2sxxx.h"
|
||||
|
||||
#define partstNUM_LEDS 2
|
||||
|
||||
/* Remember the state of the outputs for easy toggling. */
|
||||
static unsigned char ucPortState = 0;
|
||||
|
||||
static const mss_gpio_id_t ucLEDs[ partstNUM_LEDS ] = { MSS_GPIO_14, MSS_GPIO_15 };
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vParTestInitialise( void )
|
||||
{
|
||||
long x;
|
||||
|
||||
/* Initialise MSS GPIOs. */
|
||||
MSS_GPIO_init();
|
||||
|
||||
/* Ensure the LEDs are outputs and off to start. */
|
||||
for( x = 0; x < partstNUM_LEDS; x++ )
|
||||
{
|
||||
MSS_GPIO_config( ucLEDs[ x ], MSS_GPIO_OUTPUT_MODE );
|
||||
vParTestSetLED( x, pdFALSE );
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vParTestSetLED( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue )
|
||||
{
|
||||
if( uxLED < partstNUM_LEDS )
|
||||
{
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
MSS_GPIO_set_output( ucLEDs[ uxLED ], xValue );
|
||||
|
||||
/* Remember the new output state. */
|
||||
if( xValue == 0 )
|
||||
{
|
||||
ucPortState &= ~( 1 << uxLED );
|
||||
}
|
||||
else
|
||||
{
|
||||
ucPortState |= ( 1 << uxLED );
|
||||
}
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vParTestToggleLED( unsigned portBASE_TYPE uxLED )
|
||||
{
|
||||
if( uxLED < partstNUM_LEDS )
|
||||
{
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
vParTestSetLED( uxLED, !( ucPortState & ( 1 << uxLED ) ) );
|
||||
}
|
||||
taskEXIT_CRITICAL();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
FreeRTOS V7.4.2 - Copyright (C) 2013 Real Time Engineers Ltd.
|
||||
|
||||
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||
* Complete, revised, and edited pdf reference manuals are also *
|
||||
* available. *
|
||||
* *
|
||||
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||
* ensuring you get running as quickly as possible and with an *
|
||||
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||
* the FreeRTOS project to continue with its mission of providing *
|
||||
* professional grade, cross platform, de facto standard solutions *
|
||||
* for microcontrollers - completely free of charge! *
|
||||
* *
|
||||
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||
* *
|
||||
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||
|
||||
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to
|
||||
distribute a combined work that includes FreeRTOS without being obliged to
|
||||
provide the source code for proprietary components outside of the FreeRTOS
|
||||
kernel.
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details. You should have received a copy of the GNU General Public License
|
||||
and the FreeRTOS license exception along with FreeRTOS; if not it can be
|
||||
viewed here: http://www.freertos.org/a00114.html and also obtained by
|
||||
writing to Real Time Engineers Ltd., contact details for whom are available
|
||||
on the FreeRTOS WEB site.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* Having a problem? Start by reading the FAQ "My application does *
|
||||
* not run, what could be wrong?" *
|
||||
* *
|
||||
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
|
||||
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||
license and Real Time Engineers Ltd. contact details.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, and our new
|
||||
fully thread aware and reentrant UDP/IP stack.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||
Integrity Systems, who sell the code with commercial support,
|
||||
indemnification and middleware, under the OpenRTOS brand.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
*/
|
||||
|
||||
/* FreeRTOS includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Utility functions to implement run time stats on Cortex-M CPUs. The collected
|
||||
run time data can be viewed through the CLI interface. See the following URL for
|
||||
more information on run time stats:
|
||||
http://www.freertos.org/rtos-run-time-stats.html */
|
||||
|
||||
/* Used in the run time stats calculations. */
|
||||
static uint32_t ulClocksPer10thOfAMilliSecond = 0UL;
|
||||
|
||||
|
||||
void vConfigureTimerForRunTimeStats( void )
|
||||
{
|
||||
/* How many clocks are there per tenth of a millisecond? */
|
||||
ulClocksPer10thOfAMilliSecond = configCPU_CLOCK_HZ / 10000UL;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
uint32_t ulGetRunTimeCounterValue( void )
|
||||
{
|
||||
uint32_t ulSysTickCounts, ulTickCount, ulReturn;
|
||||
const uint32_t ulSysTickReloadValue = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
|
||||
volatile uint32_t * const pulCurrentSysTickCount = ( ( volatile uint32_t *) 0xe000e018 );
|
||||
volatile uint32_t * const pulInterruptCTRLState = ( ( volatile uint32_t *) 0xe000ed04 );
|
||||
const uint32_t ulSysTickPendingBit = 0x04000000UL;
|
||||
|
||||
/* NOTE: There are potentially race conditions here. However, it is used
|
||||
anyway to keep the examples simple, and to avoid reliance on a separate
|
||||
timer peripheral. */
|
||||
|
||||
|
||||
/* The SysTick is a down counter. How many clocks have passed since it was
|
||||
last reloaded? */
|
||||
ulSysTickCounts = ulSysTickReloadValue - *pulCurrentSysTickCount;
|
||||
|
||||
/* How many times has it overflowed? */
|
||||
ulTickCount = xTaskGetTickCountFromISR();
|
||||
|
||||
/* Is there a SysTick interrupt pending? */
|
||||
if( ( *pulInterruptCTRLState & ulSysTickPendingBit ) != 0UL )
|
||||
{
|
||||
/* There is a SysTick interrupt pending, so the SysTick has overflowed
|
||||
but the tick count not yet incremented. */
|
||||
ulTickCount++;
|
||||
|
||||
/* Read the SysTick again, as the overflow might have occurred since
|
||||
it was read last. */
|
||||
ulSysTickCounts = ulSysTickReloadValue - *pulCurrentSysTickCount;
|
||||
}
|
||||
|
||||
/* Convert the tick count into tenths of a millisecond. THIS ASSUMES
|
||||
configTICK_RATE_HZ is 1000! */
|
||||
ulReturn = ( ulTickCount * 10UL ) ;
|
||||
|
||||
/* Add on the number of tenths of a millisecond that have passed since the
|
||||
tick count last got updated. */
|
||||
ulReturn += ( ulSysTickCounts / ulClocksPer10thOfAMilliSecond );
|
||||
|
||||
return ulReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
|
@ -0,0 +1,233 @@
|
|||
/*
|
||||
FreeRTOS V7.4.2 - Copyright (C) 2013 Real Time Engineers Ltd.
|
||||
|
||||
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||
* Complete, revised, and edited pdf reference manuals are also *
|
||||
* available. *
|
||||
* *
|
||||
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||
* ensuring you get running as quickly as possible and with an *
|
||||
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||
* the FreeRTOS project to continue with its mission of providing *
|
||||
* professional grade, cross platform, de facto standard solutions *
|
||||
* for microcontrollers - completely free of charge! *
|
||||
* *
|
||||
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||
* *
|
||||
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||
|
||||
>>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to
|
||||
distribute a combined work that includes FreeRTOS without being obliged to
|
||||
provide the source code for proprietary components outside of the FreeRTOS
|
||||
kernel.
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details. You should have received a copy of the GNU General Public License
|
||||
and the FreeRTOS license exception along with FreeRTOS; if not it can be
|
||||
viewed here: http://www.freertos.org/a00114.html and also obtained by
|
||||
writing to Real Time Engineers Ltd., contact details for whom are available
|
||||
on the FreeRTOS WEB site.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* Having a problem? Start by reading the FAQ "My application does *
|
||||
* not run, what could be wrong?" *
|
||||
* *
|
||||
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
|
||||
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||
license and Real Time Engineers Ltd. contact details.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, and our new
|
||||
fully thread aware and reentrant UDP/IP stack.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||
Integrity Systems, who sell the code with commercial support,
|
||||
indemnification and middleware, under the OpenRTOS brand.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* This project provides two demo applications. A simple blinky style project,
|
||||
* and a more comprehensive test and demo application. The
|
||||
* mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting (defined in this file) is used to
|
||||
* select between the two. The simply blinky demo is implemented and described
|
||||
* in main_blinky.c. The more comprehensive test and demo application is
|
||||
* implemented and described in main_full.c.
|
||||
*
|
||||
* This file implements the code that is not demo specific, including the
|
||||
* hardware setup and FreeRTOS hook functions.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdio.h>
|
||||
|
||||
/* Kernel includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Standard demo includes - just needed for the LED (ParTest) initialisation
|
||||
function. */
|
||||
#include "partest.h"
|
||||
|
||||
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
|
||||
or 0 to run the more comprehensive test and demo application. */
|
||||
#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0
|
||||
|
||||
/*
|
||||
* Set up the hardware ready to run this demo.
|
||||
*/
|
||||
static void prvSetupHardware( void );
|
||||
|
||||
/*
|
||||
* main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1.
|
||||
* main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0.
|
||||
*/
|
||||
extern void main_blinky( void );
|
||||
extern void main_full( void );
|
||||
|
||||
/* Prototypes for the standard FreeRTOS callback/hook functions implemented
|
||||
within this file. */
|
||||
void vApplicationMallocFailedHook( void );
|
||||
void vApplicationIdleHook( void );
|
||||
void vApplicationStackOverflowHook( xTaskHandle pxTask, signed char *pcTaskName );
|
||||
void vApplicationTickHook( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
/* See the documentation page for this demo on the FreeRTOS.org web site for
|
||||
full information - including hardware setup requirements. */
|
||||
|
||||
int main( void )
|
||||
{
|
||||
/* Prepare the hardware to run this demo. */
|
||||
prvSetupHardware();
|
||||
|
||||
/* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
|
||||
of this file. */
|
||||
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1
|
||||
{
|
||||
main_blinky();
|
||||
}
|
||||
#else
|
||||
{
|
||||
main_full();
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvSetupHardware( void )
|
||||
{
|
||||
/* Perform any configuration necessary to use the ParTest LED output
|
||||
functions. The name ParTest is now somewhat obsolete - originally it
|
||||
stood for PARallel port Test. */
|
||||
vParTestInitialise();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vApplicationMallocFailedHook( void )
|
||||
{
|
||||
/* vApplicationMallocFailedHook() will only be called if
|
||||
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
|
||||
function that will get called if a call to pvPortMalloc() fails.
|
||||
pvPortMalloc() is called internally by the kernel whenever a task, queue,
|
||||
timer or semaphore is created. It is also called by various parts of the
|
||||
demo application. If heap_1.c or heap_2.c are used, then the size of the
|
||||
heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
|
||||
FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
|
||||
to query the size of free heap space that remains (although it does not
|
||||
provide information on how the remaining heap might be fragmented). */
|
||||
taskDISABLE_INTERRUPTS();
|
||||
for( ;; );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vApplicationIdleHook( void )
|
||||
{
|
||||
/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
|
||||
to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
|
||||
task. It is essential that code added to this hook function never attempts
|
||||
to block in any way (for example, call xQueueReceive() with a block time
|
||||
specified, or call vTaskDelay()). If the application makes use of the
|
||||
vTaskDelete() API function (as this demo application does) then it is also
|
||||
important that vApplicationIdleHook() is permitted to return to its calling
|
||||
function, because it is the responsibility of the idle task to clean up
|
||||
memory allocated by the kernel to any task that has since been deleted. */
|
||||
|
||||
#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY != 1
|
||||
{
|
||||
/* If the file system is only going to be accessed from one task then
|
||||
F_FS_THREAD_AWARE can be set to 0 and the set of example files is created
|
||||
before the RTOS scheduler is started. If the file system is going to be
|
||||
access from more than one task then F_FS_THREAD_AWARE must be set to 1 and
|
||||
the set of sample files are created from the idle task hook function. */
|
||||
#if F_FS_THREAD_AWARE == 1
|
||||
{
|
||||
static portBASE_TYPE xCreatedSampleFiles = pdFALSE;
|
||||
|
||||
/* Initialise the drive and file system, then create a few example
|
||||
files. The output from this function just goes to the stdout window,
|
||||
allowing the output to be viewed when the UDP command console is not
|
||||
connected. */
|
||||
if( xCreatedSampleFiles == pdFALSE )
|
||||
{
|
||||
vCreateAndVerifySampleFiles();
|
||||
xCreatedSampleFiles = pdTRUE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vApplicationStackOverflowHook( xTaskHandle pxTask, signed char *pcTaskName )
|
||||
{
|
||||
( void ) pcTaskName;
|
||||
( void ) pxTask;
|
||||
|
||||
/* Run time stack overflow checking is performed if
|
||||
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
|
||||
function is called if a stack overflow is detected. */
|
||||
taskDISABLE_INTERRUPTS();
|
||||
for( ;; );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vApplicationTickHook( void )
|
||||
{
|
||||
/* This function will be called by each tick interrupt if
|
||||
configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be
|
||||
added here, but the tick hook is called from an interrupt context, so
|
||||
code must not attempt to block, and only the interrupt safe FreeRTOS API
|
||||
functions can be used (those that end in FromISR()). */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
|
@ -0,0 +1,289 @@
|
|||
/*
|
||||
Copyright 2001, 2002 Georges Menie (www.menie.org)
|
||||
stdarg version contributed by Christian Ettinger
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
putchar is the only external dependency for this file,
|
||||
if you have a working putchar, leave it commented out.
|
||||
If not, uncomment the define below and
|
||||
replace outbyte(c) by your own function call.
|
||||
|
||||
*/
|
||||
#include "FreeRTOS.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static void printchar(char **str, int c)
|
||||
{
|
||||
if (str) {
|
||||
**str = (char)c;
|
||||
++(*str);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Output char here. */
|
||||
}
|
||||
}
|
||||
|
||||
#define PAD_RIGHT 1
|
||||
#define PAD_ZERO 2
|
||||
|
||||
static int prints(char **out, const char *string, int width, int pad)
|
||||
{
|
||||
register int pc = 0, padchar = ' ';
|
||||
|
||||
if (width > 0) {
|
||||
register int len = 0;
|
||||
register const char *ptr;
|
||||
for (ptr = string; *ptr; ++ptr) ++len;
|
||||
if (len >= width) width = 0;
|
||||
else width -= len;
|
||||
if (pad & PAD_ZERO) padchar = '0';
|
||||
}
|
||||
if (!(pad & PAD_RIGHT)) {
|
||||
for ( ; width > 0; --width) {
|
||||
printchar (out, padchar);
|
||||
++pc;
|
||||
}
|
||||
}
|
||||
for ( ; *string ; ++string) {
|
||||
printchar (out, *string);
|
||||
++pc;
|
||||
}
|
||||
for ( ; width > 0; --width) {
|
||||
printchar (out, padchar);
|
||||
++pc;
|
||||
}
|
||||
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* the following should be enough for 32 bit int */
|
||||
#define PRINT_BUF_LEN 12
|
||||
|
||||
static int printi(char **out, int i, int b, int sg, int width, int pad, int letbase)
|
||||
{
|
||||
char print_buf[PRINT_BUF_LEN];
|
||||
register char *s;
|
||||
register int t, neg = 0, pc = 0;
|
||||
register unsigned int u = (unsigned int)i;
|
||||
|
||||
if (i == 0) {
|
||||
print_buf[0] = '0';
|
||||
print_buf[1] = '\0';
|
||||
return prints (out, print_buf, width, pad);
|
||||
}
|
||||
|
||||
if (sg && b == 10 && i < 0) {
|
||||
neg = 1;
|
||||
u = (unsigned int)-i;
|
||||
}
|
||||
|
||||
s = print_buf + PRINT_BUF_LEN-1;
|
||||
*s = '\0';
|
||||
|
||||
while (u) {
|
||||
t = (unsigned int)u % b;
|
||||
if( t >= 10 )
|
||||
t += letbase - '0' - 10;
|
||||
*--s = (char)(t + '0');
|
||||
u /= b;
|
||||
}
|
||||
|
||||
if (neg) {
|
||||
if( width && (pad & PAD_ZERO) ) {
|
||||
printchar (out, '-');
|
||||
++pc;
|
||||
--width;
|
||||
}
|
||||
else {
|
||||
*--s = '-';
|
||||
}
|
||||
}
|
||||
|
||||
return pc + prints (out, s, width, pad);
|
||||
}
|
||||
|
||||
static int print( char **out, const char *format, va_list args )
|
||||
{
|
||||
register int width, pad;
|
||||
register int pc = 0;
|
||||
char scr[2];
|
||||
|
||||
for (; *format != 0; ++format) {
|
||||
if (*format == '%') {
|
||||
++format;
|
||||
width = pad = 0;
|
||||
if (*format == '\0') break;
|
||||
if (*format == '%') goto out;
|
||||
if (*format == '-') {
|
||||
++format;
|
||||
pad = PAD_RIGHT;
|
||||
}
|
||||
while (*format == '0') {
|
||||
++format;
|
||||
pad |= PAD_ZERO;
|
||||
}
|
||||
for ( ; *format >= '0' && *format <= '9'; ++format) {
|
||||
width *= 10;
|
||||
width += *format - '0';
|
||||
}
|
||||
if( *format == 's' ) {
|
||||
register char *s = (char *)va_arg( args, int );
|
||||
pc += prints (out, s?s:"(null)", width, pad);
|
||||
continue;
|
||||
}
|
||||
if( *format == 'd' || *format == 'i' ) {
|
||||
pc += printi (out, va_arg( args, int ), 10, 1, width, pad, 'a');
|
||||
continue;
|
||||
}
|
||||
if( *format == 'x' ) {
|
||||
pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'a');
|
||||
continue;
|
||||
}
|
||||
if( *format == 'X' ) {
|
||||
pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'A');
|
||||
continue;
|
||||
}
|
||||
if( *format == 'u' ) {
|
||||
pc += printi (out, va_arg( args, int ), 10, 0, width, pad, 'a');
|
||||
continue;
|
||||
}
|
||||
if( *format == 'c' ) {
|
||||
/* char are converted to int then pushed on the stack */
|
||||
scr[0] = (char)va_arg( args, int );
|
||||
scr[1] = '\0';
|
||||
pc += prints (out, scr, width, pad);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
out:
|
||||
printchar (out, *format);
|
||||
++pc;
|
||||
}
|
||||
}
|
||||
if (out) **out = '\0';
|
||||
va_end( args );
|
||||
return pc;
|
||||
}
|
||||
|
||||
int printf(const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start( args, format );
|
||||
return print( 0, format, args );
|
||||
}
|
||||
|
||||
int sprintf(char *out, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start( args, format );
|
||||
return print( &out, format, args );
|
||||
}
|
||||
|
||||
|
||||
int snprintf( char *buf, unsigned int count, const char *format, ... )
|
||||
{
|
||||
va_list args;
|
||||
|
||||
( void ) count;
|
||||
|
||||
va_start( args, format );
|
||||
return print( &buf, format, args );
|
||||
}
|
||||
|
||||
#ifdef TEST_PRINTF
|
||||
int main(void)
|
||||
{
|
||||
char *ptr = "Hello world!";
|
||||
char *np = 0;
|
||||
int i = 5;
|
||||
unsigned int bs = sizeof(int)*8;
|
||||
int mi;
|
||||
char buf[80];
|
||||
|
||||
mi = (1 << (bs-1)) + 1;
|
||||
printf("%s\n", ptr);
|
||||
printf("printf test\n");
|
||||
printf("%s is null pointer\n", np);
|
||||
printf("%d = 5\n", i);
|
||||
printf("%d = - max int\n", mi);
|
||||
printf("char %c = 'a'\n", 'a');
|
||||
printf("hex %x = ff\n", 0xff);
|
||||
printf("hex %02x = 00\n", 0);
|
||||
printf("signed %d = unsigned %u = hex %x\n", -3, -3, -3);
|
||||
printf("%d %s(s)%", 0, "message");
|
||||
printf("\n");
|
||||
printf("%d %s(s) with %%\n", 0, "message");
|
||||
sprintf(buf, "justif: \"%-10s\"\n", "left"); printf("%s", buf);
|
||||
sprintf(buf, "justif: \"%10s\"\n", "right"); printf("%s", buf);
|
||||
sprintf(buf, " 3: %04d zero padded\n", 3); printf("%s", buf);
|
||||
sprintf(buf, " 3: %-4d left justif.\n", 3); printf("%s", buf);
|
||||
sprintf(buf, " 3: %4d right justif.\n", 3); printf("%s", buf);
|
||||
sprintf(buf, "-3: %04d zero padded\n", -3); printf("%s", buf);
|
||||
sprintf(buf, "-3: %-4d left justif.\n", -3); printf("%s", buf);
|
||||
sprintf(buf, "-3: %4d right justif.\n", -3); printf("%s", buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* if you compile this file with
|
||||
* gcc -Wall $(YOUR_C_OPTIONS) -DTEST_PRINTF -c printf.c
|
||||
* you will get a normal warning:
|
||||
* printf.c:214: warning: spurious trailing `%' in format
|
||||
* this line is testing an invalid % at the end of the format string.
|
||||
*
|
||||
* this should display (on 32bit int machine) :
|
||||
*
|
||||
* Hello world!
|
||||
* printf test
|
||||
* (null) is null pointer
|
||||
* 5 = 5
|
||||
* -2147483647 = - max int
|
||||
* char a = 'a'
|
||||
* hex ff = ff
|
||||
* hex 00 = 00
|
||||
* signed -3 = unsigned 4294967293 = hex fffffffd
|
||||
* 0 message(s)
|
||||
* 0 message(s) with %
|
||||
* justif: "left "
|
||||
* justif: " right"
|
||||
* 3: 0003 zero padded
|
||||
* 3: 3 left justif.
|
||||
* 3: 3 right justif.
|
||||
* -3: -003 zero padded
|
||||
* -3: -3 left justif.
|
||||
* -3: -3 right justif.
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* To keep linker happy. */
|
||||
int write( int i, char* c, int n)
|
||||
{
|
||||
(void)i;
|
||||
(void)n;
|
||||
(void)c;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,320 @@
|
|||
<?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="cdt.managedbuild.config.gnu.cross.cortexm3.lib.debug.1468565853">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.cross.cortexm3.lib.debug.1468565853" moduleId="org.eclipse.cdt.core.settings" name="Debug">
|
||||
<externalSettings>
|
||||
<externalSetting>
|
||||
<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/RTOSDemo_Hardware_Platform"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/RTOSDemo_Hardware_Platform/Debug"/>
|
||||
</externalSetting>
|
||||
</externalSettings>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.MakeErrorParser" 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"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactExtension="a" artifactName="RTOSDemo_Hardware_Platform" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.staticLib" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.staticLib" cleanCommand="rm -rf" description="" errorParsers="org.eclipse.cdt.core.MakeErrorParser;org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.GASErrorParser" id="cdt.managedbuild.config.gnu.cross.cortexm3.lib.debug.1468565853" name="Debug" parent="cdt.managedbuild.config.gnu.cross.cortexm3.lib.debug">
|
||||
<folderInfo id="cdt.managedbuild.config.gnu.cross.cortexm3.lib.debug.1468565853." name="/" resourcePath="">
|
||||
<toolChain id="cdt.managedbuild.toolchain.gnu.cross.cortexm3.lib.debug.409640005" name="Microsemi Cortex-M3 Tools" superClass="cdt.managedbuild.toolchain.gnu.cross.cortexm3.lib.debug">
|
||||
<targetPlatform id="cdt.managedbuild.target.gnu.platform.cross.cortexm3.lib.debug.328970973" name="%PlatformName.Dbg" superClass="cdt.managedbuild.target.gnu.platform.cross.cortexm3.lib.debug"/>
|
||||
<builder buildPath="${workspace_loc:/RTOSDemo_Hardware_Platform/Debug}" id="cdt.managedbuild.target.gnu.builder.cross.cortexm3.lib.debug.568072199" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.cross.cortexm3.lib.debug"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.compiler.cross.cortexm3.lib.debug.2065819927" name="GNU C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.cross.cortexm3.lib.debug">
|
||||
<option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.cross.cortexm3.lib.debug.option.optimization.level.681489611" name="Optimization Level" superClass="gnu.c.compiler.cross.cortexm3.lib.debug.option.optimization.level" valueType="enumerated"/>
|
||||
<option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.cross.cortexm3.lib.debug.option.debugging.level.1682080951" name="Debug Level" superClass="gnu.c.compiler.cross.cortexm3.lib.debug.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
|
||||
<option id="gnu.c.compiler.option.include.paths.1398648520" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/CMSIS}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/CMSIS/startup_gcc}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/drivers}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/drivers/mss_gpio}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/drivers/mss_hpdma}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/drivers/mss_nvm}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/drivers/mss_rtc}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/drivers/mss_sys_services}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/drivers/mss_timer}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/drivers/mss_uart}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/drivers_config}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/drivers_config/sys_config}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/hal}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/hal/CortexM3}"/>
|
||||
<listOptionValue builtIn="false" value="${workspace_loc:/RTOSDemo_Hardware_Platform/hal/CortexM3/GNU}"/>
|
||||
</option>
|
||||
<option id="gnu.c.compiler.option.optimization.flags.224943415" name="Other optimization flags" superClass="gnu.c.compiler.option.optimization.flags" value="-ffunction-sections -fdata-sections" valueType="string"/>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.916892465" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.cross.cortexm3.lib.debug.395470401" name="GNU C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.cross.cortexm3.lib.debug">
|
||||
<option id="gnu.cpp.compiler.cross.cortexm3.lib.debug.option.optimization.level.1205883536" name="Optimization Level" superClass="gnu.cpp.compiler.cross.cortexm3.lib.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
|
||||
<option id="gnu.cpp.compiler.cross.cortexm3.lib.debug.option.debugging.level.121193510" name="Debug Level" superClass="gnu.cpp.compiler.cross.cortexm3.lib.debug.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.archiver.cross.cortexm3.lib.debug.223490042" name="GNU Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.cross.cortexm3.lib.debug">
|
||||
<outputType id="cdt.managedbuild.tool.gnu.archiver.output.882723846" outputPrefix="lib" superClass="cdt.managedbuild.tool.gnu.archiver.output"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.assembler.cross.cortexm3.lib.debug.1647173666" name="GNU Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.cross.cortexm3.lib.debug">
|
||||
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1769880125" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
||||
</tool>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile"/>
|
||||
<profile id="com.actel.softconsole.arm.ActelARMManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="arm-none-eabi-gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="com.actel.softconsole.core8051s.SDCCManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="false" filePath=""/>
|
||||
<parser enabled="false"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-V -E -Wp -P -dD ${plugin_state_location}/${specs_file}" command="sdcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="com.actel.softconsole.cortexm1.ActelCortexM1ManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="arm-none-eabi-gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="com.actel.softconsole.cortexm3.ActelCortexM3ManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="arm-none-eabi-gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="makefileGenerator">
|
||||
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/${specs_file}"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'g++ -E -P -v -dD "${plugin_state_location}/specs.cpp"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/specs.c"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cross.cortexm3.lib.debug.1468565853;cdt.managedbuild.config.gnu.cross.cortexm3.lib.debug.1468565853.">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.actel.softconsole.cortexm3.ActelCortexM3ManagedMakePerProjectProfile"/>
|
||||
<profile id="com.actel.softconsole.arm.ActelARMManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="arm-none-eabi-gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="com.actel.softconsole.core8051s.SDCCManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="false" filePath=""/>
|
||||
<parser enabled="false"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-V -E -Wp -P -dD ${plugin_state_location}/${specs_file}" command="sdcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="com.actel.softconsole.cortexm1.ActelCortexM1ManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="arm-none-eabi-gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="com.actel.softconsole.cortexm3.ActelCortexM3ManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="arm-none-eabi-gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="makefileGenerator">
|
||||
<runAction arguments="-f ${project_name}_scd.mk" command="make" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/${specs_file}"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'g++ -E -P -v -dD "${plugin_state_location}/specs.cpp"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/specs.c"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
</scannerConfigBuildInfo>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
|
||||
</cconfiguration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<project id="RTOSDemo_Hardware_Platform.cdt.managedbuild.target.gnu.cross.cortexm3.lib.597503304" name="Static Library" projectType="cdt.managedbuild.target.gnu.cross.cortexm3.lib"/>
|
||||
</storageModule>
|
||||
</cproject>
|
|
@ -0,0 +1,80 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>RTOSDemo_Hardware_Platform</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>?name?</key>
|
||||
<value></value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.append_environment</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.autoBuildTarget</key>
|
||||
<value>all</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildArguments</key>
|
||||
<value></value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildCommand</key>
|
||||
<value>make</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildLocation</key>
|
||||
<value>${workspace_loc:/RTOSDemo_Hardware_Platform/Debug}</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
|
||||
<value>clean</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.contents</key>
|
||||
<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableFullBuild</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.fullBuildTarget</key>
|
||||
<value>all</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.stopOnError</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||
<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>
|
||||
</projectDescription>
|
|
@ -0,0 +1,113 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2011-2013 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* SmartFusion2 Cortex Microcontroller Software Interface - Peripheral
|
||||
* Access Layer.
|
||||
*
|
||||
* This file provides interfaces to perform register and register bit level
|
||||
* read / write operations. These interfaces support bit-banding in case of
|
||||
* Cortex-M3 CPU.
|
||||
*
|
||||
* SVN $Revision: 5263 $
|
||||
* SVN $Date: 2013-03-21 14:44:58 +0000 (Thu, 21 Mar 2013) $
|
||||
*/
|
||||
|
||||
#ifndef HW_REG_IO_H_
|
||||
#define HW_REG_IO_H_
|
||||
|
||||
#include <stdint.h> /* Include standard types */
|
||||
|
||||
#if defined ( __CC_ARM )
|
||||
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
|
||||
|
||||
#elif defined ( __ICCARM__ )
|
||||
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */
|
||||
|
||||
#elif defined ( __GNUC__ )
|
||||
#define __INLINE inline /*!< inline keyword for GNU Compiler */
|
||||
#endif
|
||||
|
||||
/*****************************************************************************************
|
||||
* Definitions for register access
|
||||
*/
|
||||
|
||||
#define HW_REG(addr) (*((volatile uint32_t *) (addr)))
|
||||
|
||||
static __INLINE void write_reg32(volatile uint32_t * reg, uint32_t val)
|
||||
{
|
||||
HW_REG(reg) = val;
|
||||
}
|
||||
static __INLINE void write_reg16(volatile uint16_t * reg, uint16_t val)
|
||||
{
|
||||
HW_REG(reg) = val;
|
||||
}
|
||||
static __INLINE void write_reg8(volatile uint8_t * reg, uint8_t val)
|
||||
{
|
||||
HW_REG(reg) = val;
|
||||
}
|
||||
|
||||
static __INLINE uint32_t read_reg32(volatile uint32_t * reg)
|
||||
{
|
||||
return ( HW_REG(reg) );
|
||||
}
|
||||
static __INLINE uint16_t read_reg16(volatile uint16_t * reg)
|
||||
{
|
||||
return ( HW_REG(reg) );
|
||||
}
|
||||
static __INLINE uint8_t read_reg8(volatile uint8_t * reg)
|
||||
{
|
||||
return ( HW_REG(reg) );
|
||||
}
|
||||
/*****************************************************************************************
|
||||
* Definitions for register bits access using bit-band aliases for Cortex-M3
|
||||
*/
|
||||
#define BITBAND(addr,bitnum) (((uint32_t)addr & 0xF0000000)+0x02000000+(((uint32_t)addr & 0xFFFFF)<<5)+(bitnum<<2))
|
||||
#define HW_REG_BIT(reg,bitnum) (*(volatile unsigned int *)((BITBAND(reg,bitnum))))
|
||||
|
||||
/*****************************************************************************************
|
||||
* Functions to set a bit field in Cortex-M3
|
||||
*/
|
||||
static __INLINE void set_bit_reg32(volatile uint32_t * reg, uint8_t bit)
|
||||
{
|
||||
HW_REG_BIT(reg,bit) = 0x1;
|
||||
}
|
||||
static __INLINE void set_bit_reg16(volatile uint16_t * reg, uint8_t bit)
|
||||
{
|
||||
HW_REG_BIT(reg,bit) = 0x1;
|
||||
}
|
||||
static __INLINE void set_bit_reg8(volatile uint8_t * reg, uint8_t bit)
|
||||
{
|
||||
HW_REG_BIT(reg,bit) = 0x1;
|
||||
}
|
||||
/*****************************************************************************************
|
||||
* Functions to clear a bit field in Cortex-M3
|
||||
*/
|
||||
static __INLINE void clear_bit_reg32(volatile uint32_t * reg, uint8_t bit)
|
||||
{
|
||||
HW_REG_BIT(reg,bit) = 0x0;
|
||||
}
|
||||
static __INLINE void clear_bit_reg16(volatile uint16_t * reg, uint8_t bit)
|
||||
{
|
||||
HW_REG_BIT(reg,bit) = 0x0;
|
||||
}
|
||||
static __INLINE void clear_bit_reg8(volatile uint8_t * reg, uint8_t bit)
|
||||
{
|
||||
HW_REG_BIT(reg,bit) = 0x0;
|
||||
}
|
||||
/*****************************************************************************************
|
||||
* Functions to read a bit field in Cortex-M3
|
||||
*/
|
||||
static __INLINE uint8_t read_bit_reg32(volatile uint32_t * reg, uint8_t bit)
|
||||
{
|
||||
return (HW_REG_BIT(reg,bit));
|
||||
}
|
||||
static __INLINE uint8_t read_bit_reg16(volatile uint16_t * reg, uint8_t bit)
|
||||
{
|
||||
return (HW_REG_BIT(reg,bit));
|
||||
}
|
||||
static __INLINE uint8_t read_bit_reg8(volatile uint8_t * reg, uint8_t bit)
|
||||
{
|
||||
return (HW_REG_BIT(reg,bit));
|
||||
}
|
||||
|
||||
#endif /* HW_REG_IO_H_ */
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,61 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2009-2013 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* Assertion implementation.
|
||||
*
|
||||
* This file provides the implementation of the ASSERT macro. This file can be
|
||||
* modified to cater for project specific requirements regarding the way
|
||||
* assertions are handled.
|
||||
*
|
||||
* SVN $Revision: 5279 $
|
||||
* SVN $Date: 2013-03-22 20:48:38 +0000 (Fri, 22 Mar 2013) $
|
||||
*/
|
||||
#ifndef __MSS_ASSERT_H_
|
||||
#define __MSS_ASSERT_H_
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#if defined ( __GNUC__ )
|
||||
|
||||
#if defined(NDEBUG)
|
||||
|
||||
#define ASSERT(CHECK)
|
||||
|
||||
#else /* NDEBUG */
|
||||
/*
|
||||
* SoftConsole assertion handling
|
||||
*/
|
||||
#define ASSERT(CHECK) \
|
||||
do { \
|
||||
if (!(CHECK)) \
|
||||
{ \
|
||||
__asm volatile ("BKPT\n\t"); \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
#endif /* NDEBUG */
|
||||
|
||||
#elif defined ( __ICCARM__ )
|
||||
/*
|
||||
* IAR Embedded Workbench assertion handling.
|
||||
* Call C library assert function which should result in error message
|
||||
* displayed in debugger.
|
||||
*/
|
||||
#define ASSERT(X) assert(X)
|
||||
|
||||
#else
|
||||
/*
|
||||
* Keil assertion handling.
|
||||
* Call C library assert function which should result in error message
|
||||
* displayed in debugger.
|
||||
*/
|
||||
|
||||
#ifndef __MICROLIB
|
||||
#define ASSERT(X) assert(X)
|
||||
#else
|
||||
#define ASSERT(X)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __MSS_ASSERT_H_ */
|
|
@ -0,0 +1,186 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2012-2013 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* SmartFusion2 Cortex-M3 linker script for creating a SoftConsole downloadable
|
||||
* debug image executing in SmartFusion2 development board external RAM.
|
||||
*
|
||||
* SVN $Revision: 5269 $
|
||||
* SVN $Date: 2013-03-21 20:53:38 +0000 (Thu, 21 Mar 2013) $
|
||||
*/
|
||||
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
|
||||
"elf32-littlearm")
|
||||
GROUP(-lc -lgcc -lm)
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(Reset_Handler)
|
||||
SEARCH_DIR(.)
|
||||
__DYNAMIC = 0;
|
||||
|
||||
/*******************************************************************************
|
||||
* Start of board customization.
|
||||
*******************************************************************************/
|
||||
MEMORY
|
||||
{
|
||||
/* SmartFusion2 internal eSRAM */
|
||||
esram (rwx) : ORIGIN = 0x20000000, LENGTH = 64k
|
||||
|
||||
/* SmartFusion2 development board external RAM */
|
||||
external_ram (rwx) : ORIGIN = 0x70000000, LENGTH = 2M
|
||||
}
|
||||
|
||||
RAM_START_ADDRESS = 0x70000000; /* Must be the same value MEMORY region ram ORIGIN above. */
|
||||
RAM_SIZE = 64k; /* Must be the same value MEMORY region ram LENGTH above. */
|
||||
MAIN_STACK_SIZE = 8k; /* Cortex main stack size. */
|
||||
PROCESS_STACK_SIZE = 4k; /* Cortex process stack size (only available with OS extensions).*/
|
||||
|
||||
/*******************************************************************************
|
||||
* End of board customization.
|
||||
*******************************************************************************/
|
||||
|
||||
PROVIDE (__main_stack_start = RAM_START_ADDRESS + RAM_SIZE);
|
||||
PROVIDE (__process_stack_start = __main_stack_start - MAIN_STACK_SIZE);
|
||||
PROVIDE (_estack = __main_stack_start);
|
||||
PROVIDE (__mirrored_nvm = 0); /* Indicate to startup code that NVM is not mirrored to VMA address .text copy is required. */
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.init :
|
||||
{
|
||||
__vector_table_vma_base_address = .;
|
||||
*(.isr_vector)
|
||||
. = ALIGN(0x4);
|
||||
} >esram
|
||||
|
||||
.text :
|
||||
{
|
||||
CREATE_OBJECT_SYMBOLS
|
||||
__text_load = LOADADDR(.text);
|
||||
__text_start = .;
|
||||
*(.text .text.* .gnu.linkonce.t.*)
|
||||
*(.plt)
|
||||
*(.gnu.warning)
|
||||
*(.glue_7t) *(.glue_7) *(.vfp11_veneer)
|
||||
|
||||
. = ALIGN(0x4);
|
||||
/* These are for running static constructors and destructors under ELF. */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*crtend.o(.ctors))
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*crtend.o(.dtors))
|
||||
|
||||
*(.rodata .rodata.* .gnu.linkonce.r.*)
|
||||
|
||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||
*(.gcc_except_table)
|
||||
*(.eh_frame_hdr)
|
||||
*(.eh_frame)
|
||||
|
||||
KEEP (*(.init))
|
||||
KEEP (*(.fini))
|
||||
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(.fini_array))
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
} >external_ram
|
||||
/* .ARM.exidx is sorted, so has to go in its own output section. */
|
||||
__exidx_start = .;
|
||||
.ARM.exidx :
|
||||
{
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
} >external_ram
|
||||
__exidx_end = .;
|
||||
_etext = .;
|
||||
PROVIDE(__text_end = .);
|
||||
|
||||
.data :
|
||||
{
|
||||
__data_load = LOADADDR (.data);
|
||||
_sidata = LOADADDR (.data);
|
||||
__data_start = .;
|
||||
_sdata = .;
|
||||
KEEP(*(.jcr))
|
||||
*(.got.plt) *(.got)
|
||||
*(.shdata)
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
. = ALIGN (4);
|
||||
_edata = .;
|
||||
} >external_ram
|
||||
|
||||
.bss :
|
||||
{
|
||||
__bss_start__ = . ;
|
||||
_sbss = .;
|
||||
*(.shbss)
|
||||
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
. = ALIGN (8);
|
||||
__bss_end__ = .;
|
||||
_end = .;
|
||||
__end = _end;
|
||||
_ebss = .;
|
||||
PROVIDE(end = .);
|
||||
} >external_ram
|
||||
|
||||
/*
|
||||
* The .stack section is only specified here in order for the linker to generate
|
||||
* an error if the esram is full.
|
||||
*/
|
||||
.stack :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
. += PROCESS_STACK_SIZE;
|
||||
. = ALIGN(4);
|
||||
. += MAIN_STACK_SIZE;
|
||||
. = ALIGN(4);
|
||||
} >external_ram
|
||||
|
||||
.stab 0 (NOLOAD) :
|
||||
{
|
||||
*(.stab)
|
||||
}
|
||||
|
||||
.stabstr 0 (NOLOAD) :
|
||||
{
|
||||
*(.stabstr)
|
||||
}
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
|
||||
.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
|
||||
/DISCARD/ : { *(.note.GNU-stack) *(.isr_vector) }
|
||||
}
|
|
@ -0,0 +1,184 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2012-2013 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* SmartFusion2 Cortex-M3 linker script for creating a SoftConsole downloadable
|
||||
* debug image executing in SmartFusion2 internal eNVM.
|
||||
*
|
||||
* SVN $Revision: 5269 $
|
||||
* SVN $Date: 2013-03-21 20:53:38 +0000 (Thu, 21 Mar 2013) $
|
||||
*/
|
||||
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
|
||||
"elf32-littlearm")
|
||||
GROUP(-lc -lgcc -lm)
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(Reset_Handler)
|
||||
SEARCH_DIR(.)
|
||||
__DYNAMIC = 0;
|
||||
|
||||
/*******************************************************************************
|
||||
* Start of board customization.
|
||||
*******************************************************************************/
|
||||
MEMORY
|
||||
{
|
||||
/*
|
||||
* WARNING: The words "SOFTCONSOLE", "FLASH", and "USE", the colon ":", and
|
||||
* the name of the type of flash memory are all in a specific order.
|
||||
* Please do not modify that comment line, in order to ensure
|
||||
* debugging of your application will use the flash memory correctly.
|
||||
*/
|
||||
|
||||
/* SOFTCONSOLE FLASH USE: microsemi-smartfusion2-envm */
|
||||
rom (rx) : ORIGIN = 0x60000000, LENGTH = 256k
|
||||
|
||||
/* SmartFusion2 internal eNVM mirrored to 0x00000000 */
|
||||
romMirror (rx) : ORIGIN = 0x00000000, LENGTH = 256k
|
||||
|
||||
/* SmartFusion2 internal eSRAM */
|
||||
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64k
|
||||
}
|
||||
|
||||
RAM_START_ADDRESS = 0x20000000; /* Must be the same value MEMORY region ram ORIGIN above. */
|
||||
RAM_SIZE = 64k; /* Must be the same value MEMORY region ram LENGTH above. */
|
||||
MAIN_STACK_SIZE = 8k; /* Cortex main stack size. */
|
||||
PROCESS_STACK_SIZE = 4k; /* Cortex process stack size (only available with OS extensions).*/
|
||||
|
||||
/*******************************************************************************
|
||||
* End of board customization.
|
||||
*******************************************************************************/
|
||||
|
||||
PROVIDE (__main_stack_start = RAM_START_ADDRESS + RAM_SIZE);
|
||||
PROVIDE (__process_stack_start = __main_stack_start - MAIN_STACK_SIZE);
|
||||
PROVIDE (_estack = __main_stack_start);
|
||||
PROVIDE (__mirrored_nvm = 1); /* Indicate to startup code that NVM is mirrored to VMA address and no text copy is required. */
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.init :
|
||||
{
|
||||
__vector_table_vma_base_address = .;
|
||||
*(.isr_vector)
|
||||
. = ALIGN(0x4);
|
||||
} >romMirror AT>rom
|
||||
|
||||
.text :
|
||||
{
|
||||
CREATE_OBJECT_SYMBOLS
|
||||
__text_load = LOADADDR(.text);
|
||||
__text_start = .;
|
||||
|
||||
*(.text .text.* .gnu.linkonce.t.*)
|
||||
*(.plt)
|
||||
*(.gnu.warning)
|
||||
*(.glue_7t) *(.glue_7) *(.vfp11_veneer)
|
||||
|
||||
. = ALIGN(0x4);
|
||||
/* These are for running static constructors and destructors under ELF. */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*crtend.o(.ctors))
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*crtend.o(.dtors))
|
||||
|
||||
*(.rodata .rodata.* .gnu.linkonce.r.*)
|
||||
|
||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||
*(.gcc_except_table)
|
||||
*(.eh_frame_hdr)
|
||||
*(.eh_frame)
|
||||
|
||||
KEEP (*(.init))
|
||||
KEEP (*(.fini))
|
||||
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(.fini_array))
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
} >romMirror AT>rom
|
||||
|
||||
/* .ARM.exidx is sorted, so has to go in its own output section. */
|
||||
__exidx_start = .;
|
||||
.ARM.exidx :
|
||||
{
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
} >ram AT>rom
|
||||
__exidx_end = .;
|
||||
_etext = .;
|
||||
|
||||
.data :
|
||||
{
|
||||
__data_load = LOADADDR(.data);
|
||||
_sidata = LOADADDR (.data);
|
||||
__data_start = .;
|
||||
_sdata = .;
|
||||
KEEP(*(.jcr))
|
||||
*(.got.plt) *(.got)
|
||||
*(.shdata)
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
. = ALIGN (4);
|
||||
_edata = .;
|
||||
} >ram AT>rom
|
||||
|
||||
.bss :
|
||||
{
|
||||
__bss_start__ = . ;
|
||||
_sbss = .;
|
||||
*(.shbss)
|
||||
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
. = ALIGN (8);
|
||||
__bss_end__ = .;
|
||||
_end = .;
|
||||
__end = _end;
|
||||
_ebss = .;
|
||||
PROVIDE(end = .);
|
||||
} >ram AT>rom
|
||||
|
||||
.stab 0 (NOLOAD) :
|
||||
{
|
||||
*(.stab)
|
||||
}
|
||||
|
||||
.stabstr 0 (NOLOAD) :
|
||||
{
|
||||
*(.stabstr)
|
||||
}
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
|
||||
.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
|
||||
/DISCARD/ : { *(.note.GNU-stack) }
|
||||
}
|
|
@ -0,0 +1,178 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2012-2013 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* SmartFusion2 Cortex-M3 linker script for creating a SoftConsole downloadable
|
||||
* debug image executing in SmartFusion2 internal eSRAM.
|
||||
*
|
||||
* SVN $Revision: 5269 $
|
||||
* SVN $Date: 2013-03-21 20:53:38 +0000 (Thu, 21 Mar 2013) $
|
||||
*/
|
||||
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
|
||||
"elf32-littlearm")
|
||||
GROUP(-lc -lgcc -lm)
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(Reset_Handler)
|
||||
SEARCH_DIR(.)
|
||||
__DYNAMIC = 0;
|
||||
|
||||
/*******************************************************************************
|
||||
* Start of board customization.
|
||||
*******************************************************************************/
|
||||
MEMORY
|
||||
{
|
||||
/* SmartFusion2 internal eSRAM */
|
||||
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64k
|
||||
}
|
||||
|
||||
RAM_START_ADDRESS = 0x20000000; /* Must be the same value MEMORY region ram ORIGIN above. */
|
||||
RAM_SIZE = 64k; /* Must be the same value MEMORY region ram LENGTH above. */
|
||||
MAIN_STACK_SIZE = 1k; /* Cortex main stack size. */
|
||||
PROCESS_STACK_SIZE = 0k; /* Cortex process stack size (only available with OS extensions).*/
|
||||
|
||||
/*******************************************************************************
|
||||
* End of board customization.
|
||||
*******************************************************************************/
|
||||
|
||||
PROVIDE (__main_stack_start = RAM_START_ADDRESS + RAM_SIZE);
|
||||
PROVIDE (__process_stack_start = __main_stack_start - MAIN_STACK_SIZE);
|
||||
PROVIDE (_estack = __main_stack_start);
|
||||
PROVIDE (__mirrored_nvm = 0); /* Indicate to startup code that NVM is not mirrored to VMA address .text copy is required. */
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
CREATE_OBJECT_SYMBOLS
|
||||
__text_load = LOADADDR(.text);
|
||||
__text_start = .;
|
||||
__vector_table_vma_base_address = .;
|
||||
*(.isr_vector)
|
||||
*(.text .text.* .gnu.linkonce.t.*)
|
||||
*(.plt)
|
||||
*(.gnu.warning)
|
||||
*(.glue_7t) *(.glue_7) *(.vfp11_veneer)
|
||||
|
||||
. = ALIGN(0x4);
|
||||
/* These are for running static constructors and destructors under ELF. */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*crtend.o(.ctors))
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*crtend.o(.dtors))
|
||||
|
||||
*(.rodata .rodata.* .gnu.linkonce.r.*)
|
||||
|
||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||
*(.gcc_except_table)
|
||||
*(.eh_frame_hdr)
|
||||
*(.eh_frame)
|
||||
|
||||
KEEP (*(.init))
|
||||
KEEP (*(.fini))
|
||||
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(.fini_array))
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
} >ram
|
||||
/* .ARM.exidx is sorted, so has to go in its own output section. */
|
||||
__exidx_start = .;
|
||||
.ARM.exidx :
|
||||
{
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
} >ram
|
||||
__exidx_end = .;
|
||||
_etext = .;
|
||||
PROVIDE(__text_end = .);
|
||||
|
||||
.data :
|
||||
{
|
||||
__data_load = LOADADDR (.data);
|
||||
_sidata = LOADADDR (.data);
|
||||
__data_start = .;
|
||||
_sdata = .;
|
||||
KEEP(*(.jcr))
|
||||
*(.got.plt) *(.got)
|
||||
*(.shdata)
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
. = ALIGN (4);
|
||||
_edata = .;
|
||||
} >ram
|
||||
|
||||
.bss :
|
||||
{
|
||||
__bss_start__ = . ;
|
||||
_sbss = .;
|
||||
*(.shbss)
|
||||
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
. = ALIGN (8);
|
||||
__bss_end__ = .;
|
||||
_end = .;
|
||||
__end = _end;
|
||||
_ebss = .;
|
||||
PROVIDE(end = .);
|
||||
} >ram
|
||||
|
||||
/*
|
||||
* The .stack section is only specified here in order for the linker to generate
|
||||
* an error if the ram is full.
|
||||
*/
|
||||
.stack :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
. += PROCESS_STACK_SIZE;
|
||||
. = ALIGN(4);
|
||||
. += MAIN_STACK_SIZE;
|
||||
. = ALIGN(4);
|
||||
} >ram
|
||||
|
||||
.stab 0 (NOLOAD) :
|
||||
{
|
||||
*(.stab)
|
||||
}
|
||||
|
||||
.stabstr 0 (NOLOAD) :
|
||||
{
|
||||
*(.stabstr)
|
||||
}
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
|
||||
.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
|
||||
/DISCARD/ : { *(.note.GNU-stack) *(.isr_vector) }
|
||||
}
|
|
@ -0,0 +1,273 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2009-2013 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* Stubs for Newlib system calls.
|
||||
*
|
||||
* SVN $Revision: 5269 $
|
||||
* SVN $Date: 2013-03-21 20:53:38 +0000 (Thu, 21 Mar 2013) $
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/times.h>
|
||||
#include <errno.h>
|
||||
|
||||
/*==============================================================================
|
||||
* Redirection of standard output to a SmartFusion2 MSS UART.
|
||||
*------------------------------------------------------------------------------
|
||||
* A default implementation for the redirection of the output of printf() to a
|
||||
* UART is provided at the bottom of this file. This redirection is enabled by
|
||||
* adding the symbol/define MICROSEMI_STDIO_THRU_MMUART0 or
|
||||
* MICROSEMI_STDIO_THRU_MMUART0 to your project settings and specifying the baud
|
||||
* rate using the MICROSEMI_STDIO_BAUD_RATE define.
|
||||
*/
|
||||
#ifdef MICROSEMI_STDIO_THRU_MMUART0
|
||||
#ifndef MICROSEMI_STDIO_THRU_UART
|
||||
#define MICROSEMI_STDIO_THRU_UART
|
||||
#endif
|
||||
#endif /* MICROSEMI_STDIO_THRU_MMUART0 */
|
||||
|
||||
#ifdef MICROSEMI_STDIO_THRU_MMUART1
|
||||
#ifndef MICROSEMI_STDIO_THRU_UART
|
||||
#define MICROSEMI_STDIO_THRU_UART
|
||||
#endif
|
||||
#endif /* MICROSEMI_STDIO_THRU_MMUART1 */
|
||||
|
||||
/*
|
||||
* Select which MMUART will be used for stdio and what baud rate will be used.
|
||||
* Default to 57600 baud if no baud rate is specified using the
|
||||
* MICROSEMI_STDIO_BAUD_RATE #define.
|
||||
*/
|
||||
#ifdef MICROSEMI_STDIO_THRU_UART
|
||||
#include "../../drivers/mss_uart/mss_uart.h"
|
||||
|
||||
#ifndef MICROSEMI_STDIO_BAUD_RATE
|
||||
#define MICROSEMI_STDIO_BAUD_RATE MSS_UART_57600_BAUD
|
||||
#endif
|
||||
|
||||
#ifdef MICROSEMI_STDIO_THRU_MMUART0
|
||||
static mss_uart_instance_t * const gp_my_uart = &g_mss_uart0;
|
||||
#else
|
||||
static mss_uart_instance_t * const gp_my_uart = &g_mss_uart1;
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Global flag used to indicate if the UART driver needs to be initialized.
|
||||
*/
|
||||
static int g_stdio_uart_init_done = 0;
|
||||
|
||||
#endif /* MICROSEMI_STDIO_THRU_UART */
|
||||
|
||||
/*==============================================================================
|
||||
* Environment variables.
|
||||
* A pointer to a list of environment variables and their values. For a minimal
|
||||
* environment, this empty list is adequate:
|
||||
*/
|
||||
char *__env[1] = { 0 };
|
||||
char **environ = __env;
|
||||
|
||||
/*==============================================================================
|
||||
* Close a file.
|
||||
*/
|
||||
int _close(int file)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* Transfer control to a new process.
|
||||
*/
|
||||
int _execve(char *name, char **argv, char **env)
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* Exit a program without cleaning up files.
|
||||
*/
|
||||
void _exit( int code )
|
||||
{
|
||||
/* Should we force a system reset? */
|
||||
while( 1 )
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* Create a new process.
|
||||
*/
|
||||
int _fork(void)
|
||||
{
|
||||
errno = EAGAIN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* Status of an open file.
|
||||
*/
|
||||
int _fstat(int file, struct stat *st)
|
||||
{
|
||||
st->st_mode = S_IFCHR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* Process-ID
|
||||
*/
|
||||
int _getpid(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* Query whether output stream is a terminal.
|
||||
*/
|
||||
int _isatty(int file)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* Send a signal.
|
||||
*/
|
||||
int _kill(int pid, int sig)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* Establish a new name for an existing file.
|
||||
*/
|
||||
int _link(char *old, char *new)
|
||||
{
|
||||
errno = EMLINK;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* Set position in a file.
|
||||
*/
|
||||
int _lseek(int file, int ptr, int dir)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* Open a file.
|
||||
*/
|
||||
int _open(const char *name, int flags, int mode)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* Read from a file.
|
||||
*/
|
||||
int _read(int file, char *ptr, int len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* Write to a file. libc subroutines will use this system routine for output to
|
||||
* all files, including stdout—so if you need to generate any output, for
|
||||
* example to a serial port for debugging, you should make your minimal write
|
||||
* capable of doing this.
|
||||
*/
|
||||
int _write_r( void * reent, int file, char * ptr, int len )
|
||||
{
|
||||
#ifdef MICROSEMI_STDIO_THRU_UART
|
||||
/*--------------------------------------------------------------------------
|
||||
* Initialize the UART driver if it is the first time this function is
|
||||
* called.
|
||||
*/
|
||||
if(!g_stdio_uart_init_done)
|
||||
{
|
||||
MSS_UART_init(gp_my_uart,
|
||||
MICROSEMI_STDIO_BAUD_RATE,
|
||||
MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY);
|
||||
|
||||
g_stdio_uart_init_done = 1;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* Output text to the UART.
|
||||
*/
|
||||
MSS_UART_polled_tx(gp_my_uart, (uint8_t *)ptr, len);
|
||||
|
||||
return len;
|
||||
#else /* MICROSEMI_STDIO_THRU_UART */
|
||||
return 0;
|
||||
#endif /* MICROSEMI_STDIO_THRU_UART */
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* Increase program data space. As malloc and related functions depend on this,
|
||||
* it is useful to have a working implementation. The following suffices for a
|
||||
* standalone system; it exploits the symbol _end automatically defined by the
|
||||
* GNU linker.
|
||||
*/
|
||||
caddr_t _sbrk(int incr)
|
||||
{
|
||||
extern char _end; /* Defined by the linker */
|
||||
static char *heap_end;
|
||||
char *prev_heap_end;
|
||||
char * stack_ptr;
|
||||
|
||||
if (heap_end == 0)
|
||||
{
|
||||
heap_end = &_end;
|
||||
}
|
||||
|
||||
prev_heap_end = heap_end;
|
||||
asm volatile ("MRS %0, msp" : "=r" (stack_ptr) );
|
||||
if (heap_end + incr > stack_ptr)
|
||||
{
|
||||
_write_r ((void *)0, 1, "Heap and stack collision\n", 25);
|
||||
_exit (1);
|
||||
}
|
||||
|
||||
heap_end += incr;
|
||||
return (caddr_t) prev_heap_end;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* Status of a file (by name).
|
||||
*/
|
||||
int _stat(char *file, struct stat *st)
|
||||
{
|
||||
st->st_mode = S_IFCHR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* Timing information for current process.
|
||||
*/
|
||||
int _times(struct tms *buf)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* Remove a file's directory entry.
|
||||
*/
|
||||
int _unlink(char *name)
|
||||
{
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* Wait for a child process.
|
||||
*/
|
||||
int _wait(int *status)
|
||||
{
|
||||
errno = ECHILD;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2009-2013 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* SmartFusion2 Cortex-M3 linker script creating an executable image for use in
|
||||
* the Libero flow for executing code in place in internal eNVM.
|
||||
*
|
||||
* SVN $Revision: 5269 $
|
||||
* SVN $Date: 2013-03-21 20:53:38 +0000 (Thu, 21 Mar 2013) $
|
||||
*/
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
|
||||
"elf32-littlearm")
|
||||
GROUP(-lc -lgcc -lm)
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(Reset_Handler)
|
||||
SEARCH_DIR(.)
|
||||
__DYNAMIC = 0;
|
||||
|
||||
/*******************************************************************************
|
||||
* Start of board customization.
|
||||
*******************************************************************************/
|
||||
MEMORY
|
||||
{
|
||||
/* SmartFusion2 internal eNVM */
|
||||
rom (rx) : ORIGIN = 0, LENGTH = 256k
|
||||
|
||||
/* SmartFusion2 internal eSRAM */
|
||||
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64k
|
||||
}
|
||||
|
||||
RAM_START_ADDRESS = 0x20000000; /* Must be the same value as MEMORY region ram ORIGIN above. */
|
||||
RAM_SIZE = 64k; /* Must be the same value as MEMORY region ram LENGTH above. */
|
||||
MAIN_STACK_SIZE = 8k; /* Cortex main stack size. */
|
||||
PROCESS_STACK_SIZE = 4k; /* Cortex process stack size (only available with OS extensions).*/
|
||||
|
||||
/*******************************************************************************
|
||||
* End of board customization.
|
||||
*******************************************************************************/
|
||||
|
||||
PROVIDE (__main_stack_start = RAM_START_ADDRESS + RAM_SIZE);
|
||||
PROVIDE (__process_stack_start = __main_stack_start - MAIN_STACK_SIZE);
|
||||
PROVIDE (_estack = __main_stack_start);
|
||||
PROVIDE (__mirrored_nvm = 0); /* Indicate to startup code that NVM is not mirrored to VMA address .text copy is required. */
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.reset :
|
||||
{
|
||||
__vector_table_vma_base_address = .;
|
||||
*(.isr_vector)
|
||||
. = ALIGN(0x4);
|
||||
} >rom
|
||||
|
||||
.text :
|
||||
{
|
||||
CREATE_OBJECT_SYMBOLS
|
||||
__text_load = LOADADDR(.text);
|
||||
__text_start = .;
|
||||
|
||||
*(.text .text.* .gnu.linkonce.t.*)
|
||||
*(.plt)
|
||||
*(.gnu.warning)
|
||||
*(.glue_7t) *(.glue_7) *(.vfp11_veneer)
|
||||
|
||||
. = ALIGN(0x4);
|
||||
/* These are for running static constructors and destructors under ELF. */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*crtend.o(.ctors))
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*crtend.o(.dtors))
|
||||
|
||||
*(.rodata .rodata.* .gnu.linkonce.r.*)
|
||||
|
||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||
*(.gcc_except_table)
|
||||
*(.eh_frame_hdr)
|
||||
*(.eh_frame)
|
||||
|
||||
KEEP (*(.init))
|
||||
KEEP (*(.fini))
|
||||
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(.fini_array))
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
} >rom
|
||||
/* .ARM.exidx is sorted, so has to go in its own output section. */
|
||||
__exidx_start = .;
|
||||
.ARM.exidx :
|
||||
{
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
} >rom
|
||||
__exidx_end = .;
|
||||
_etext = .;
|
||||
|
||||
.data :
|
||||
{
|
||||
__data_load = LOADADDR(.data);
|
||||
_sidata = LOADADDR (.data);
|
||||
__data_start = .;
|
||||
_sdata = .;
|
||||
KEEP(*(.jcr))
|
||||
*(.got.plt) *(.got)
|
||||
*(.shdata)
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
. = ALIGN (4);
|
||||
_edata = .;
|
||||
} >ram AT>rom
|
||||
|
||||
.bss :
|
||||
{
|
||||
__bss_start__ = . ;
|
||||
_sbss = .;
|
||||
*(.shbss)
|
||||
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
. = ALIGN (8);
|
||||
__bss_end__ = .;
|
||||
_end = .;
|
||||
__end = _end;
|
||||
_ebss = .;
|
||||
PROVIDE(end = .);
|
||||
} >ram AT>rom
|
||||
|
||||
.stab 0 (NOLOAD) :
|
||||
{
|
||||
*(.stab)
|
||||
}
|
||||
|
||||
.stabstr 0 (NOLOAD) :
|
||||
{
|
||||
*(.stabstr)
|
||||
}
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
|
||||
.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
|
||||
/DISCARD/ : { *(.note.GNU-stack) }
|
||||
}
|
|
@ -0,0 +1,178 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2009-2013 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* SmartFusion2 Cortex-M3 linker script creating an executable image for use in
|
||||
* the Libero flow for relocating executable from internal eNVM to external RAM
|
||||
* before starting execution.
|
||||
*
|
||||
* SVN $Revision: 5269 $
|
||||
* SVN $Date: 2013-03-21 20:53:38 +0000 (Thu, 21 Mar 2013) $
|
||||
*/
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
|
||||
"elf32-littlearm")
|
||||
GROUP(-lc -lgcc -lm)
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(Reset_Handler)
|
||||
SEARCH_DIR(.)
|
||||
__DYNAMIC = 0;
|
||||
|
||||
/*******************************************************************************
|
||||
* Start of board customization.
|
||||
*******************************************************************************/
|
||||
MEMORY
|
||||
{
|
||||
/* SmartFusion2 internal eNVM */
|
||||
rom (rx) : ORIGIN = 0, LENGTH = 256k
|
||||
|
||||
/* SmartFusion2 internal eSRAM */
|
||||
esram (rwx) : ORIGIN = 0x20000000, LENGTH = 64k
|
||||
|
||||
/* SmartFusion2 development board external RAM */
|
||||
external_ram (rwx) : ORIGIN = 0x70000000, LENGTH = 2M
|
||||
}
|
||||
|
||||
RAM_START_ADDRESS = 0x20000000; /* Must be the same value as MEMORY region esram ORIGIN above. */
|
||||
RAM_SIZE = 64k; /* Must be the same value as MEMORY region esram LENGTH above. */
|
||||
MAIN_STACK_SIZE = 8k; /* Cortex main stack size. */
|
||||
PROCESS_STACK_SIZE = 4k; /* Cortex process stack size (only available with OS extensions).*/
|
||||
|
||||
/*******************************************************************************
|
||||
* End of board customization.
|
||||
*******************************************************************************/
|
||||
|
||||
PROVIDE (__main_stack_start = RAM_START_ADDRESS + RAM_SIZE);
|
||||
PROVIDE (__process_stack_start = __main_stack_start - MAIN_STACK_SIZE);
|
||||
PROVIDE (_estack = __main_stack_start);
|
||||
PROVIDE (__mirrored_nvm = 0); /* Indicate to startup code that NVM is not mirrored to VMA address .text copy is required. */
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.reset :
|
||||
{
|
||||
__vector_table_vma_base_address = .;
|
||||
*(.isr_vector)
|
||||
/* SystemInit() is called before relocation to RAM so keep in ROM */
|
||||
*system_m2sxxx.o(.text*)
|
||||
. = ALIGN(0x4);
|
||||
} >rom
|
||||
|
||||
.text :
|
||||
{
|
||||
CREATE_OBJECT_SYMBOLS
|
||||
__text_load = LOADADDR(.text);
|
||||
__text_start = .;
|
||||
|
||||
*(.text .text.* .gnu.linkonce.t.*)
|
||||
*(.plt)
|
||||
*(.gnu.warning)
|
||||
*(.glue_7t) *(.glue_7) *(.vfp11_veneer)
|
||||
|
||||
. = ALIGN(0x4);
|
||||
/* These are for running static constructors and destructors under ELF. */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*crtend.o(.ctors))
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*crtend.o(.dtors))
|
||||
|
||||
*(.rodata .rodata.* .gnu.linkonce.r.*)
|
||||
|
||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||
*(.gcc_except_table)
|
||||
*(.eh_frame_hdr)
|
||||
*(.eh_frame)
|
||||
|
||||
KEEP (*(.init))
|
||||
KEEP (*(.fini))
|
||||
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(.fini_array))
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
} >external_ram AT>rom
|
||||
/* .ARM.exidx is sorted, so has to go in its own output section. */
|
||||
__exidx_start = .;
|
||||
.ARM.exidx :
|
||||
{
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
} >external_ram AT>rom
|
||||
__exidx_end = .;
|
||||
_etext = .;
|
||||
|
||||
.data :
|
||||
{
|
||||
__data_load = LOADADDR(.data);
|
||||
_sidata = LOADADDR (.data);
|
||||
__data_start = .;
|
||||
_sdata = .;
|
||||
KEEP(*(.jcr))
|
||||
*(.got.plt) *(.got)
|
||||
*(.shdata)
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
. = ALIGN (4);
|
||||
_edata = .;
|
||||
} >esram AT>rom
|
||||
|
||||
.bss :
|
||||
{
|
||||
__bss_start__ = . ;
|
||||
_sbss = .;
|
||||
*(.shbss)
|
||||
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
. = ALIGN (8);
|
||||
__bss_end__ = .;
|
||||
_end = .;
|
||||
__end = _end;
|
||||
_ebss = .;
|
||||
PROVIDE(end = .);
|
||||
} >esram AT>rom
|
||||
|
||||
.stab 0 (NOLOAD) :
|
||||
{
|
||||
*(.stab)
|
||||
}
|
||||
|
||||
.stabstr 0 (NOLOAD) :
|
||||
{
|
||||
*(.stabstr)
|
||||
}
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
|
||||
.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
|
||||
/DISCARD/ : { *(.note.GNU-stack) }
|
||||
}
|
|
@ -0,0 +1,951 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2012-2013 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* SmartFusion2 vector table and startup code for CodeSourcery G++.
|
||||
*
|
||||
* SVN $Revision: 5269 $
|
||||
* SVN $Date: 2013-03-21 20:53:38 +0000 (Thu, 21 Mar 2013) $
|
||||
*/
|
||||
|
||||
.syntax unified
|
||||
.cpu cortex-m3
|
||||
.thumb
|
||||
|
||||
|
||||
/*==============================================================================
|
||||
* Vector table
|
||||
*/
|
||||
.global g_pfnVectors
|
||||
.section .isr_vector,"a",%progbits
|
||||
.type g_pfnVectors, %object
|
||||
.size g_pfnVectors, .-g_pfnVectors
|
||||
|
||||
g_pfnVectors:
|
||||
.word _estack
|
||||
.word Reset_Handler
|
||||
.word NMI_Handler
|
||||
.word HardFault_Handler
|
||||
.word MemManage_Handler
|
||||
.word BusFault_Handler
|
||||
.word UsageFault_Handler
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word SVC_Handler
|
||||
.word DebugMon_Handler
|
||||
.word 0
|
||||
.word PendSV_Handler
|
||||
.word SysTick_Handler
|
||||
.word WdogWakeup_IRQHandler
|
||||
.word RTC_Wakeup_IRQHandler
|
||||
.word SPI0_IRQHandler
|
||||
.word SPI1_IRQHandler
|
||||
.word I2C0_IRQHandler
|
||||
.word I2C0_SMBAlert_IRQHandler
|
||||
.word I2C0_SMBus_IRQHandler
|
||||
.word I2C1_IRQHandler
|
||||
.word I2C1_SMBAlert_IRQHandler
|
||||
.word I2C1_SMBus_IRQHandler
|
||||
.word UART0_IRQHandler
|
||||
.word UART1_IRQHandler
|
||||
.word EthernetMAC_IRQHandler
|
||||
.word DMA_IRQHandler
|
||||
.word Timer1_IRQHandler
|
||||
.word Timer2_IRQHandler
|
||||
.word CAN_IRQHandler
|
||||
.word ENVM0_IRQHandler
|
||||
.word ENVM1_IRQHandler
|
||||
.word ComBlk_IRQHandler
|
||||
.word USB_IRQHandler
|
||||
.word USB_DMA_IRQHandler
|
||||
.word PLL_Lock_IRQHandler
|
||||
.word PLL_LockLost_IRQHandler
|
||||
.word CommSwitchError_IRQHandler
|
||||
.word CacheError_IRQHandler
|
||||
.word DDR_IRQHandler
|
||||
.word HPDMA_Complete_IRQHandler
|
||||
.word HPDMA_Error_IRQHandler
|
||||
.word ECC_Error_IRQHandler
|
||||
.word MDDR_IOCalib_IRQHandler
|
||||
.word FAB_PLL_Lock_IRQHandler
|
||||
.word FAB_PLL_LockLost_IRQHandler
|
||||
.word FIC64_IRQHandler
|
||||
.word FabricIrq0_IRQHandler
|
||||
.word FabricIrq1_IRQHandler
|
||||
.word FabricIrq2_IRQHandler
|
||||
.word FabricIrq3_IRQHandler
|
||||
.word FabricIrq4_IRQHandler
|
||||
.word FabricIrq5_IRQHandler
|
||||
.word FabricIrq6_IRQHandler
|
||||
.word FabricIrq7_IRQHandler
|
||||
.word FabricIrq8_IRQHandler
|
||||
.word FabricIrq9_IRQHandler
|
||||
.word FabricIrq10_IRQHandler
|
||||
.word FabricIrq11_IRQHandler
|
||||
.word FabricIrq12_IRQHandler
|
||||
.word FabricIrq13_IRQHandler
|
||||
.word FabricIrq14_IRQHandler
|
||||
.word FabricIrq15_IRQHandler
|
||||
.word GPIO0_IRQHandler
|
||||
.word GPIO1_IRQHandler
|
||||
.word GPIO2_IRQHandler
|
||||
.word GPIO3_IRQHandler
|
||||
.word GPIO4_IRQHandler
|
||||
.word GPIO5_IRQHandler
|
||||
.word GPIO6_IRQHandler
|
||||
.word GPIO7_IRQHandler
|
||||
.word GPIO8_IRQHandler
|
||||
.word GPIO9_IRQHandler
|
||||
.word GPIO10_IRQHandler
|
||||
.word GPIO11_IRQHandler
|
||||
.word GPIO12_IRQHandler
|
||||
.word GPIO13_IRQHandler
|
||||
.word GPIO14_IRQHandler
|
||||
.word GPIO15_IRQHandler
|
||||
.word GPIO16_IRQHandler
|
||||
.word GPIO17_IRQHandler
|
||||
.word GPIO18_IRQHandler
|
||||
.word GPIO19_IRQHandler
|
||||
.word GPIO20_IRQHandler
|
||||
.word GPIO21_IRQHandler
|
||||
.word GPIO22_IRQHandler
|
||||
.word GPIO23_IRQHandler
|
||||
.word GPIO24_IRQHandler
|
||||
.word GPIO25_IRQHandler
|
||||
.word GPIO26_IRQHandler
|
||||
.word GPIO27_IRQHandler
|
||||
.word GPIO28_IRQHandler
|
||||
.word GPIO29_IRQHandler
|
||||
.word GPIO30_IRQHandler
|
||||
.word GPIO31_IRQHandler
|
||||
|
||||
|
||||
/*==============================================================================
|
||||
* Reset_Handler
|
||||
*/
|
||||
.global Reset_Handler
|
||||
.type Reset_Handler, %function
|
||||
Reset_Handler:
|
||||
_start:
|
||||
/*------------------------------------------------------------------------------
|
||||
* Call CMSIS system init function.
|
||||
*/
|
||||
ldr r0, =SystemInit
|
||||
blx r0
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Check if the executable is built for NVM LMA mirrored to VMA address.
|
||||
* This is done for debugging executables running out of eNVM with SoftConsole.
|
||||
* The .text section should not be copied in this case since both the LMA and
|
||||
* VMA point at the eNVM despite the LMA and VMa having different values.
|
||||
*/
|
||||
ldr r0, =__mirrored_nvm
|
||||
cmp r0, #0
|
||||
bne copy_data
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Copy code section.
|
||||
*/
|
||||
ldr r0, =__text_load
|
||||
ldr r1, =__text_start
|
||||
ldr r2, =_etext
|
||||
cmp r0, r1
|
||||
beq copy_data
|
||||
copy_code_loop:
|
||||
cmp r1, r2
|
||||
itt ne
|
||||
ldrne r3, [r0], #4
|
||||
strne r3, [r1], #4
|
||||
bne copy_code_loop
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Copy data section.
|
||||
*/
|
||||
copy_data:
|
||||
ldr r0, =__data_load
|
||||
ldr r1, =__data_start
|
||||
ldr r2, =_edata
|
||||
cmp r0, r1
|
||||
beq clear_bss
|
||||
copy_data_loop:
|
||||
cmp r1, r2
|
||||
itt ne
|
||||
ldrne r3, [r0], #4
|
||||
strne r3, [r1], #4
|
||||
bne copy_data_loop
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Clear .bss
|
||||
*/
|
||||
clear_bss:
|
||||
ldr r0, =0
|
||||
ldr r1, =__bss_start__
|
||||
ldr r2, =__bss_end__
|
||||
clear_bss_loop:
|
||||
cmp r1, r2
|
||||
it ne
|
||||
strne r0, [r1], #4
|
||||
bne clear_bss_loop
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Call global constructors
|
||||
*/
|
||||
/*
|
||||
* Align to word and use 32-bits LDR instruction to ensure the ADD instruction
|
||||
* taking PC as argument is aligned on a word boundary.
|
||||
*/
|
||||
.align 4
|
||||
call_glob_ctor:
|
||||
ldr.w r0, =__libc_init_array
|
||||
add lr, pc, #3
|
||||
bx r0
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* branch to main.
|
||||
*/
|
||||
branch_to_main:
|
||||
mov r0, #0 /* no arguments */
|
||||
mov r1, #0 /* no argv either */
|
||||
ldr pc, =main
|
||||
|
||||
ExitLoop:
|
||||
B ExitLoop
|
||||
|
||||
/*==============================================================================
|
||||
* NMI_Handler
|
||||
*/
|
||||
.weak NMI_Handler
|
||||
.type NMI_Handler, %function
|
||||
NMI_Handler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* HardFault_Handler
|
||||
*/
|
||||
.weak HardFault_Handler
|
||||
.type HardFault_Handler, %function
|
||||
HardFault_Handler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* MemManage_Handler
|
||||
*/
|
||||
.weak MemManage_Handler
|
||||
.type MemManage_Handler, %function
|
||||
MemManage_Handler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* BusFault_Handler
|
||||
*/
|
||||
.weak BusFault_Handler
|
||||
.type BusFault_Handler, %function
|
||||
BusFault_Handler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* UsageFault_Handler
|
||||
*/
|
||||
.weak UsageFault_Handler
|
||||
.type UsageFault_Handler, %function
|
||||
UsageFault_Handler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* SVC_Handler
|
||||
*/
|
||||
.weak SVC_Handler
|
||||
.type SVC_Handler, %function
|
||||
SVC_Handler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* DebugMon_Handler
|
||||
*/
|
||||
.weak DebugMon_Handler
|
||||
.type DebugMon_Handler, %function
|
||||
DebugMon_Handler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* PendSV_Handler
|
||||
*/
|
||||
.weak PendSV_Handler
|
||||
.type PendSV_Handler, %function
|
||||
PendSV_Handler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* SysTick_Handler
|
||||
*/
|
||||
.weak SysTick_Handler
|
||||
.type SysTick_Handler, %function
|
||||
SysTick_Handler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* WdogWakeup_IRQHandler
|
||||
*/
|
||||
.weak WdogWakeup_IRQHandler
|
||||
.type WdogWakeup_IRQHandler, %function
|
||||
WdogWakeup_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* RTC_Wakeup_IRQHandler
|
||||
*/
|
||||
.weak RTC_Wakeup_IRQHandler
|
||||
.type RTC_Wakeup_IRQHandler, %function
|
||||
RTC_Wakeup_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* SPI0_IRQHandler
|
||||
*/
|
||||
.weak SPI0_IRQHandler
|
||||
.type SPI0_IRQHandler, %function
|
||||
SPI0_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* SPI1_IRQHandler
|
||||
*/
|
||||
.weak SPI1_IRQHandler
|
||||
.type SPI1_IRQHandler, %function
|
||||
SPI1_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* I2C0_IRQHandler
|
||||
*/
|
||||
.weak I2C0_IRQHandler
|
||||
.type I2C0_IRQHandler, %function
|
||||
I2C0_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* I2C0_SMBAlert_IRQHandler
|
||||
*/
|
||||
.weak I2C0_SMBAlert_IRQHandler
|
||||
.type I2C0_SMBAlert_IRQHandler, %function
|
||||
I2C0_SMBAlert_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* I2C0_SMBus_IRQHandler
|
||||
*/
|
||||
.weak I2C0_SMBus_IRQHandler
|
||||
.type I2C0_SMBus_IRQHandler, %function
|
||||
I2C0_SMBus_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* I2C1_IRQHandler
|
||||
*/
|
||||
.weak I2C1_IRQHandler
|
||||
.type I2C1_IRQHandler, %function
|
||||
I2C1_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* I2C1_SMBAlert_IRQHandler
|
||||
*/
|
||||
.weak I2C1_SMBAlert_IRQHandler
|
||||
.type I2C1_SMBAlert_IRQHandler, %function
|
||||
I2C1_SMBAlert_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* I2C1_SMBus_IRQHandler
|
||||
*/
|
||||
.weak I2C1_SMBus_IRQHandler
|
||||
.type I2C1_SMBus_IRQHandler, %function
|
||||
I2C1_SMBus_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* UART0_IRQHandler
|
||||
*/
|
||||
.weak UART0_IRQHandler
|
||||
.type UART0_IRQHandler, %function
|
||||
UART0_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* UART1_IRQHandler
|
||||
*/
|
||||
.weak UART1_IRQHandler
|
||||
.type UART1_IRQHandler, %function
|
||||
UART1_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* EthernetMAC_IRQHandler
|
||||
*/
|
||||
.weak EthernetMAC_IRQHandler
|
||||
.type EthernetMAC_IRQHandler, %function
|
||||
EthernetMAC_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* DMA_IRQHandler
|
||||
*/
|
||||
.weak DMA_IRQHandler
|
||||
.type DMA_IRQHandler, %function
|
||||
DMA_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* Timer1_IRQHandler
|
||||
*/
|
||||
.weak Timer1_IRQHandler
|
||||
.type Timer1_IRQHandler, %function
|
||||
Timer1_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* Timer2_IRQHandler
|
||||
*/
|
||||
.weak Timer2_IRQHandler
|
||||
.type Timer2_IRQHandler, %function
|
||||
Timer2_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* CAN_IRQHandler
|
||||
*/
|
||||
.weak CAN_IRQHandler
|
||||
.type CAN_IRQHandler, %function
|
||||
CAN_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* ENVM0_IRQHandler
|
||||
*/
|
||||
.weak ENVM0_IRQHandler
|
||||
.type ENVM0_IRQHandler, %function
|
||||
ENVM0_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* ENVM1_IRQHandler
|
||||
*/
|
||||
.weak ENVM1_IRQHandler
|
||||
.type ENVM1_IRQHandler, %function
|
||||
ENVM1_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* ComBlk_IRQHandler
|
||||
*/
|
||||
.weak ComBlk_IRQHandler
|
||||
.type ComBlk_IRQHandler, %function
|
||||
ComBlk_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* USB_IRQHandler
|
||||
*/
|
||||
.weak USB_IRQHandler
|
||||
.type USB_IRQHandler, %function
|
||||
USB_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* USB_DMA_IRQHandler
|
||||
*/
|
||||
.weak USB_DMA_IRQHandler
|
||||
.type USB_DMA_IRQHandler, %function
|
||||
USB_DMA_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* PLL_Lock_IRQHandler
|
||||
*/
|
||||
.weak PLL_Lock_IRQHandler
|
||||
.type PLL_Lock_IRQHandler, %function
|
||||
PLL_Lock_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* PLL_LockLost_IRQHandler
|
||||
*/
|
||||
.weak PLL_LockLost_IRQHandler
|
||||
.type PLL_LockLost_IRQHandler, %function
|
||||
PLL_LockLost_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* CommSwitchError_IRQHandler
|
||||
*/
|
||||
.weak CommSwitchError_IRQHandler
|
||||
.type CommSwitchError_IRQHandler, %function
|
||||
CommSwitchError_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* CacheError_IRQHandler
|
||||
*/
|
||||
.weak CacheError_IRQHandler
|
||||
.type CacheError_IRQHandler, %function
|
||||
CacheError_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* DDR_IRQHandler
|
||||
*/
|
||||
.weak DDR_IRQHandler
|
||||
.type DDR_IRQHandler, %function
|
||||
DDR_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* HPDMA_Complete_IRQHandler
|
||||
*/
|
||||
.weak HPDMA_Complete_IRQHandler
|
||||
.type HPDMA_Complete_IRQHandler, %function
|
||||
HPDMA_Complete_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* HPDMA_Error_IRQHandler
|
||||
*/
|
||||
.weak HPDMA_Error_IRQHandler
|
||||
.type HPDMA_Error_IRQHandler, %function
|
||||
HPDMA_Error_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* ECC_Error_IRQHandler
|
||||
*/
|
||||
.weak ECC_Error_IRQHandler
|
||||
.type ECC_Error_IRQHandler, %function
|
||||
ECC_Error_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* MDDR_IOCalib_IRQHandler
|
||||
*/
|
||||
.weak MDDR_IOCalib_IRQHandler
|
||||
.type MDDR_IOCalib_IRQHandler, %function
|
||||
MDDR_IOCalib_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* FAB_PLL_Lock_IRQHandler
|
||||
*/
|
||||
.weak FAB_PLL_Lock_IRQHandler
|
||||
.type FAB_PLL_Lock_IRQHandler, %function
|
||||
FAB_PLL_Lock_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* FAB_PLL_LockLost_IRQHandler
|
||||
*/
|
||||
.weak FAB_PLL_LockLost_IRQHandler
|
||||
.type FAB_PLL_LockLost_IRQHandler, %function
|
||||
FAB_PLL_LockLost_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* FIC64_IRQHandler
|
||||
*/
|
||||
.weak FIC64_IRQHandler
|
||||
.type FIC64_IRQHandler, %function
|
||||
FIC64_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* FabricIrq0_IRQHandler
|
||||
*/
|
||||
.weak FabricIrq0_IRQHandler
|
||||
.type FabricIrq0_IRQHandler, %function
|
||||
FabricIrq0_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* FabricIrq1_IRQHandler
|
||||
*/
|
||||
.weak FabricIrq1_IRQHandler
|
||||
.type FabricIrq1_IRQHandler, %function
|
||||
FabricIrq1_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* FabricIrq2_IRQHandler
|
||||
*/
|
||||
.weak FabricIrq2_IRQHandler
|
||||
.type FabricIrq2_IRQHandler, %function
|
||||
FabricIrq2_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* FabricIrq3_IRQHandler
|
||||
*/
|
||||
.weak FabricIrq3_IRQHandler
|
||||
.type FabricIrq3_IRQHandler, %function
|
||||
FabricIrq3_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* FabricIrq4_IRQHandler
|
||||
*/
|
||||
.weak FabricIrq4_IRQHandler
|
||||
.type FabricIrq4_IRQHandler, %function
|
||||
FabricIrq4_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* FabricIrq5_IRQHandler
|
||||
*/
|
||||
.weak FabricIrq5_IRQHandler
|
||||
.type FabricIrq5_IRQHandler, %function
|
||||
FabricIrq5_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* FabricIrq6_IRQHandler
|
||||
*/
|
||||
.weak FabricIrq6_IRQHandler
|
||||
.type FabricIrq6_IRQHandler, %function
|
||||
FabricIrq6_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* FabricIrq7_IRQHandler
|
||||
*/
|
||||
.weak FabricIrq7_IRQHandler
|
||||
.type FabricIrq7_IRQHandler, %function
|
||||
FabricIrq7_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* FabricIrq8_IRQHandler
|
||||
*/
|
||||
.weak FabricIrq8_IRQHandler
|
||||
.type FabricIrq8_IRQHandler, %function
|
||||
FabricIrq8_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* FabricIrq9_IRQHandler
|
||||
*/
|
||||
.weak FabricIrq9_IRQHandler
|
||||
.type FabricIrq9_IRQHandler, %function
|
||||
FabricIrq9_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* FabricIrq10_IRQHandler
|
||||
*/
|
||||
.weak FabricIrq10_IRQHandler
|
||||
.type FabricIrq10_IRQHandler, %function
|
||||
FabricIrq10_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* FabricIrq11_IRQHandler
|
||||
*/
|
||||
.weak FabricIrq11_IRQHandler
|
||||
.type FabricIrq11_IRQHandler, %function
|
||||
FabricIrq11_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* FabricIrq12_IRQHandler
|
||||
*/
|
||||
.weak FabricIrq12_IRQHandler
|
||||
.type FabricIrq12_IRQHandler, %function
|
||||
FabricIrq12_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* FabricIrq13_IRQHandler
|
||||
*/
|
||||
.weak FabricIrq13_IRQHandler
|
||||
.type FabricIrq13_IRQHandler, %function
|
||||
FabricIrq13_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* FabricIrq14_IRQHandler
|
||||
*/
|
||||
.weak FabricIrq14_IRQHandler
|
||||
.type FabricIrq14_IRQHandler, %function
|
||||
FabricIrq14_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* FabricIrq15_IRQHandler
|
||||
*/
|
||||
.weak FabricIrq15_IRQHandler
|
||||
.type FabricIrq15_IRQHandler, %function
|
||||
FabricIrq15_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO0_IRQHandler
|
||||
*/
|
||||
.weak GPIO0_IRQHandler
|
||||
.type GPIO0_IRQHandler, %function
|
||||
GPIO0_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO1_IRQHandler
|
||||
*/
|
||||
.weak GPIO1_IRQHandler
|
||||
.type GPIO1_IRQHandler, %function
|
||||
GPIO1_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO2_IRQHandler
|
||||
*/
|
||||
.weak GPIO2_IRQHandler
|
||||
.type GPIO2_IRQHandler, %function
|
||||
GPIO2_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO3_IRQHandler
|
||||
*/
|
||||
.weak GPIO3_IRQHandler
|
||||
.type GPIO3_IRQHandler, %function
|
||||
GPIO3_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO4_IRQHandler
|
||||
*/
|
||||
.weak GPIO4_IRQHandler
|
||||
.type GPIO4_IRQHandler, %function
|
||||
GPIO4_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO5_IRQHandler
|
||||
*/
|
||||
.weak GPIO5_IRQHandler
|
||||
.type GPIO5_IRQHandler, %function
|
||||
GPIO5_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO6_IRQHandler
|
||||
*/
|
||||
.weak GPIO6_IRQHandler
|
||||
.type GPIO6_IRQHandler, %function
|
||||
GPIO6_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO7_IRQHandler
|
||||
*/
|
||||
.weak GPIO7_IRQHandler
|
||||
.type GPIO7_IRQHandler, %function
|
||||
GPIO7_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO8_IRQHandler
|
||||
*/
|
||||
.weak GPIO8_IRQHandler
|
||||
.type GPIO8_IRQHandler, %function
|
||||
GPIO8_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO9_IRQHandler
|
||||
*/
|
||||
.weak GPIO9_IRQHandler
|
||||
.type GPIO9_IRQHandler, %function
|
||||
GPIO9_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO10_IRQHandler
|
||||
*/
|
||||
.weak GPIO10_IRQHandler
|
||||
.type GPIO10_IRQHandler, %function
|
||||
GPIO10_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO11_IRQHandler
|
||||
*/
|
||||
.weak GPIO11_IRQHandler
|
||||
.type GPIO11_IRQHandler, %function
|
||||
GPIO11_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO12_IRQHandler
|
||||
*/
|
||||
.weak GPIO12_IRQHandler
|
||||
.type GPIO12_IRQHandler, %function
|
||||
GPIO12_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO13_IRQHandler
|
||||
*/
|
||||
.weak GPIO13_IRQHandler
|
||||
.type GPIO13_IRQHandler, %function
|
||||
GPIO13_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO14_IRQHandler
|
||||
*/
|
||||
.weak GPIO14_IRQHandler
|
||||
.type GPIO14_IRQHandler, %function
|
||||
GPIO14_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO15_IRQHandler
|
||||
*/
|
||||
.weak GPIO15_IRQHandler
|
||||
.type GPIO15_IRQHandler, %function
|
||||
GPIO15_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO16_IRQHandler
|
||||
*/
|
||||
.weak GPIO16_IRQHandler
|
||||
.type GPIO16_IRQHandler, %function
|
||||
GPIO16_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO17_IRQHandler
|
||||
*/
|
||||
.weak GPIO17_IRQHandler
|
||||
.type GPIO17_IRQHandler, %function
|
||||
GPIO17_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO18_IRQHandler
|
||||
*/
|
||||
.weak GPIO18_IRQHandler
|
||||
.type GPIO18_IRQHandler, %function
|
||||
GPIO18_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO19_IRQHandler
|
||||
*/
|
||||
.weak GPIO19_IRQHandler
|
||||
.type GPIO19_IRQHandler, %function
|
||||
GPIO19_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO20_IRQHandler
|
||||
*/
|
||||
.weak GPIO20_IRQHandler
|
||||
.type GPIO20_IRQHandler, %function
|
||||
GPIO20_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO21_IRQHandler
|
||||
*/
|
||||
.weak GPIO21_IRQHandler
|
||||
.type GPIO21_IRQHandler, %function
|
||||
GPIO21_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO22_IRQHandler
|
||||
*/
|
||||
.weak GPIO22_IRQHandler
|
||||
.type GPIO22_IRQHandler, %function
|
||||
GPIO22_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO23_IRQHandler
|
||||
*/
|
||||
.weak GPIO23_IRQHandler
|
||||
.type GPIO23_IRQHandler, %function
|
||||
GPIO23_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO24_IRQHandler
|
||||
*/
|
||||
.weak GPIO24_IRQHandler
|
||||
.type GPIO24_IRQHandler, %function
|
||||
GPIO24_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO25_IRQHandler
|
||||
*/
|
||||
.weak GPIO25_IRQHandler
|
||||
.type GPIO25_IRQHandler, %function
|
||||
GPIO25_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO26_IRQHandler
|
||||
*/
|
||||
.weak GPIO26_IRQHandler
|
||||
.type GPIO26_IRQHandler, %function
|
||||
GPIO26_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO27_IRQHandler
|
||||
*/
|
||||
.weak GPIO27_IRQHandler
|
||||
.type GPIO27_IRQHandler, %function
|
||||
GPIO27_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO28_IRQHandler
|
||||
*/
|
||||
.weak GPIO28_IRQHandler
|
||||
.type GPIO28_IRQHandler, %function
|
||||
GPIO28_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO29_IRQHandler
|
||||
*/
|
||||
.weak GPIO29_IRQHandler
|
||||
.type GPIO29_IRQHandler, %function
|
||||
GPIO29_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO30_IRQHandler
|
||||
*/
|
||||
.weak GPIO30_IRQHandler
|
||||
.type GPIO30_IRQHandler, %function
|
||||
GPIO30_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* GPIO31_IRQHandler
|
||||
*/
|
||||
.weak GPIO31_IRQHandler
|
||||
.type GPIO31_IRQHandler, %function
|
||||
GPIO31_IRQHandler:
|
||||
B .
|
||||
|
||||
/*==============================================================================
|
||||
* mscc_post_hw_cfg_init
|
||||
*/
|
||||
.weak mscc_post_hw_cfg_init
|
||||
.type mscc_post_hw_cfg_init, %function
|
||||
mscc_post_hw_cfg_init:
|
||||
BX LR
|
||||
|
||||
.end
|
|
@ -0,0 +1,212 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2012 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
*
|
||||
*
|
||||
* SVN $Revision: 4410 $
|
||||
* SVN $Date: 2012-07-16 14:36:17 +0100 (Mon, 16 Jul 2012) $
|
||||
*/
|
||||
|
||||
#ifndef SYSTEM_INIT_CFG_TYPES_H_
|
||||
#define SYSTEM_INIT_CFG_TYPES_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*============================================================================*/
|
||||
/* DDR Configuration */
|
||||
/*============================================================================*/
|
||||
typedef struct
|
||||
{
|
||||
/*--------------------------------------------------------------------------
|
||||
* DDR Controller registers.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
uint16_t DYN_SOFT_RESET_CR;
|
||||
uint16_t RESERVED0;
|
||||
uint16_t DYN_REFRESH_1_CR;
|
||||
uint16_t DYN_REFRESH_2_CR;
|
||||
uint16_t DYN_POWERDOWN_CR;
|
||||
uint16_t DYN_DEBUG_CR;
|
||||
uint16_t MODE_CR;
|
||||
uint16_t ADDR_MAP_BANK_CR;
|
||||
uint16_t ECC_DATA_MASK_CR;
|
||||
uint16_t ADDR_MAP_COL_1_CR;
|
||||
uint16_t ADDR_MAP_COL_2_CR;
|
||||
uint16_t ADDR_MAP_ROW_1_CR;
|
||||
uint16_t ADDR_MAP_ROW_2_CR;
|
||||
uint16_t INIT_1_CR;
|
||||
uint16_t CKE_RSTN_CYCLES_1_CR;
|
||||
uint16_t CKE_RSTN_CYCLES_2_CR;
|
||||
uint16_t INIT_MR_CR;
|
||||
uint16_t INIT_EMR_CR;
|
||||
uint16_t INIT_EMR2_CR;
|
||||
uint16_t INIT_EMR3_CR;
|
||||
uint16_t DRAM_BANK_TIMING_PARAM_CR;
|
||||
uint16_t DRAM_RD_WR_LATENCY_CR;
|
||||
uint16_t DRAM_RD_WR_PRE_CR;
|
||||
uint16_t DRAM_MR_TIMING_PARAM_CR;
|
||||
uint16_t DRAM_RAS_TIMING_CR;
|
||||
uint16_t DRAM_RD_WR_TRNARND_TIME_CR;
|
||||
uint16_t DRAM_T_PD_CR;
|
||||
uint16_t DRAM_BANK_ACT_TIMING_CR;
|
||||
uint16_t ODT_PARAM_1_CR;
|
||||
uint16_t ODT_PARAM_2_CR;
|
||||
uint16_t ADDR_MAP_COL_3_CR;
|
||||
uint16_t MODE_REG_RD_WR_CR;
|
||||
uint16_t MODE_REG_DATA_CR;
|
||||
uint16_t PWR_SAVE_1_CR;
|
||||
uint16_t PWR_SAVE_2_CR;
|
||||
uint16_t ZQ_LONG_TIME_CR;
|
||||
uint16_t ZQ_SHORT_TIME_CR;
|
||||
uint16_t ZQ_SHORT_INT_REFRESH_MARGIN_1_CR;
|
||||
uint16_t ZQ_SHORT_INT_REFRESH_MARGIN_2_CR;
|
||||
uint16_t PERF_PARAM_1_CR;
|
||||
uint16_t HPR_QUEUE_PARAM_1_CR;
|
||||
uint16_t HPR_QUEUE_PARAM_2_CR;
|
||||
uint16_t LPR_QUEUE_PARAM_1_CR;
|
||||
uint16_t LPR_QUEUE_PARAM_2_CR;
|
||||
uint16_t WR_QUEUE_PARAM_CR;
|
||||
uint16_t PERF_PARAM_2_CR;
|
||||
uint16_t PERF_PARAM_3_CR;
|
||||
uint16_t DFI_RDDATA_EN_CR;
|
||||
uint16_t DFI_MIN_CTRLUPD_TIMING_CR;
|
||||
uint16_t DFI_MAX_CTRLUPD_TIMING_CR;
|
||||
uint16_t DFI_WR_LVL_CONTROL_1_CR;
|
||||
uint16_t DFI_WR_LVL_CONTROL_2_CR;
|
||||
uint16_t DFI_RD_LVL_CONTROL_1_CR;
|
||||
uint16_t DFI_RD_LVL_CONTROL_2_CR;
|
||||
uint16_t DFI_CTRLUPD_TIME_INTERVAL_CR;
|
||||
uint16_t DYN_SOFT_RESET_CR2;
|
||||
uint16_t AXI_FABRIC_PRI_ID_CR;
|
||||
} ddrc;
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* DDR PHY configuration registers
|
||||
*/
|
||||
struct
|
||||
{
|
||||
uint16_t LOOPBACK_TEST_CR;
|
||||
uint16_t BOARD_LOOPBACK_CR;
|
||||
uint16_t CTRL_SLAVE_RATIO_CR;
|
||||
uint16_t CTRL_SLAVE_FORCE_CR;
|
||||
uint16_t CTRL_SLAVE_DELAY_CR;
|
||||
uint16_t DATA_SLICE_IN_USE_CR;
|
||||
uint16_t LVL_NUM_OF_DQ0_CR;
|
||||
uint16_t DQ_OFFSET_1_CR;
|
||||
uint16_t DQ_OFFSET_2_CR;
|
||||
uint16_t DQ_OFFSET_3_CR;
|
||||
uint16_t DIS_CALIB_RST_CR;
|
||||
uint16_t DLL_LOCK_DIFF_CR;
|
||||
uint16_t FIFO_WE_IN_DELAY_1_CR;
|
||||
uint16_t FIFO_WE_IN_DELAY_2_CR;
|
||||
uint16_t FIFO_WE_IN_DELAY_3_CR;
|
||||
uint16_t FIFO_WE_IN_FORCE_CR;
|
||||
uint16_t FIFO_WE_SLAVE_RATIO_1_CR;
|
||||
uint16_t FIFO_WE_SLAVE_RATIO_2_CR;
|
||||
uint16_t FIFO_WE_SLAVE_RATIO_3_CR;
|
||||
uint16_t FIFO_WE_SLAVE_RATIO_4_CR;
|
||||
uint16_t GATELVL_INIT_MODE_CR;
|
||||
uint16_t GATELVL_INIT_RATIO_1_CR;
|
||||
uint16_t GATELVL_INIT_RATIO_2_CR;
|
||||
uint16_t GATELVL_INIT_RATIO_3_CR;
|
||||
uint16_t GATELVL_INIT_RATIO_4_CR;
|
||||
uint16_t LOCAL_ODT_CR;
|
||||
uint16_t INVERT_CLKOUT_CR;
|
||||
uint16_t RD_DQS_SLAVE_DELAY_1_CR;
|
||||
uint16_t RD_DQS_SLAVE_DELAY_2_CR;
|
||||
uint16_t RD_DQS_SLAVE_DELAY_3_CR;
|
||||
uint16_t RD_DQS_SLAVE_FORCE_CR;
|
||||
uint16_t RD_DQS_SLAVE_RATIO_1_CR;
|
||||
uint16_t RD_DQS_SLAVE_RATIO_2_CR;
|
||||
uint16_t RD_DQS_SLAVE_RATIO_3_CR;
|
||||
uint16_t RD_DQS_SLAVE_RATIO_4_CR;
|
||||
uint16_t WR_DQS_SLAVE_DELAY_1_CR;
|
||||
uint16_t WR_DQS_SLAVE_DELAY_2_CR;
|
||||
uint16_t WR_DQS_SLAVE_DELAY_3_CR;
|
||||
uint16_t WR_DQS_SLAVE_FORCE_CR;
|
||||
uint16_t WR_DQS_SLAVE_RATIO_1_CR;
|
||||
uint16_t WR_DQS_SLAVE_RATIO_2_CR;
|
||||
uint16_t WR_DQS_SLAVE_RATIO_3_CR;
|
||||
uint16_t WR_DQS_SLAVE_RATIO_4_CR;
|
||||
uint16_t WR_DATA_SLAVE_DELAY_1_CR;
|
||||
uint16_t WR_DATA_SLAVE_DELAY_2_CR;
|
||||
uint16_t WR_DATA_SLAVE_DELAY_3_CR;
|
||||
uint16_t WR_DATA_SLAVE_FORCE_CR;
|
||||
uint16_t WR_DATA_SLAVE_RATIO_1_CR;
|
||||
uint16_t WR_DATA_SLAVE_RATIO_2_CR;
|
||||
uint16_t WR_DATA_SLAVE_RATIO_3_CR;
|
||||
uint16_t WR_DATA_SLAVE_RATIO_4_CR;
|
||||
uint16_t WRLVL_INIT_MODE_CR;
|
||||
uint16_t WRLVL_INIT_RATIO_1_CR;
|
||||
uint16_t WRLVL_INIT_RATIO_2_CR;
|
||||
uint16_t WRLVL_INIT_RATIO_3_CR;
|
||||
uint16_t WRLVL_INIT_RATIO_4_CR;
|
||||
uint16_t WR_RD_RL_CR;
|
||||
uint16_t RDC_FIFO_RST_ERRCNTCLR_CR;
|
||||
uint16_t RDC_WE_TO_RE_DELAY_CR;
|
||||
uint16_t USE_FIXED_RE_CR;
|
||||
uint16_t USE_RANK0_DELAYS_CR;
|
||||
uint16_t USE_LVL_TRNG_LEVEL_CR;
|
||||
uint16_t CONFIG_CR;
|
||||
uint16_t RD_WR_GATE_LVL_CR;
|
||||
uint16_t DYN_RESET_CR;
|
||||
} phy;
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* FIC-64 registers
|
||||
* These registers are 16-bit wide and 32-bit aligned.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
uint16_t NB_ADDR_CR;
|
||||
uint16_t NBRWB_SIZE_CR;
|
||||
uint16_t WB_TIMEOUT_CR;
|
||||
uint16_t HPD_SW_RW_EN_CR;
|
||||
uint16_t HPD_SW_RW_INVAL_CR;
|
||||
uint16_t SW_WR_ERCLR_CR;
|
||||
uint16_t ERR_INT_ENABLE_CR;
|
||||
uint16_t NUM_AHB_MASTERS_CR;
|
||||
uint16_t LOCK_TIMEOUTVAL_1_CR;
|
||||
uint16_t LOCK_TIMEOUTVAL_2_CR;
|
||||
uint16_t LOCK_TIMEOUT_EN_CR;
|
||||
} fic;
|
||||
} ddr_subsys_cfg_t;
|
||||
|
||||
/*============================================================================*/
|
||||
/* FDDR Configuration */
|
||||
/*============================================================================*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t PLL_CONFIG_LOW_1;
|
||||
uint16_t PLL_CONFIG_LOW_2;
|
||||
uint16_t PLL_CONFIG_HIGH;
|
||||
uint16_t FACC_CLK_EN;
|
||||
uint16_t FACC_MUX_CONFIG;
|
||||
uint16_t FACC_DIVISOR_RATIO;
|
||||
uint16_t PLL_DELAY_LINE_SEL;
|
||||
uint16_t SOFT_RESET;
|
||||
uint16_t IO_CALIB;
|
||||
uint16_t INTERRUPT_ENABLE;
|
||||
uint16_t AXI_AHB_MODE_SEL;
|
||||
uint16_t PHY_SELF_REF_EN;
|
||||
} fddr_sysreg_t;
|
||||
|
||||
/*============================================================================*/
|
||||
/* PCI Express Bridge IP Core configuration. */
|
||||
/*============================================================================*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t * p_reg;
|
||||
uint32_t value;
|
||||
} cfg_addr_value_pair_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SYSTEM_INIT_CFG_TYPES_H_ */
|
|
@ -0,0 +1,560 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2012-2013 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* SmartFusion2 CMSIS system initialization.
|
||||
*
|
||||
* SVN $Revision: 5280 $
|
||||
* SVN $Date: 2013-03-22 20:51:50 +0000 (Fri, 22 Mar 2013) $
|
||||
*/
|
||||
#include "m2sxxx.h"
|
||||
#include "../drivers_config/sys_config/sys_config.h"
|
||||
#include "sys_init_cfg_types.h"
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
Silicon revisions.
|
||||
*/
|
||||
#define UNKNOWN_SILICON_REV 0
|
||||
#define M2S050_REV_A_SILICON 1
|
||||
#define M2S050_REV_B_SILICON 2
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void mscc_post_hw_cfg_init(void);
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* System registers of interest.
|
||||
*/
|
||||
/*
|
||||
* MSSDDR_FACC1_CR register masks:
|
||||
*/
|
||||
#define DDR_CLK_EN_SHIFT 8u
|
||||
#define FACC_GLMUX_SEL_MASK 0x00001000u
|
||||
#define CONTROLLER_PLL_INIT_MASK 0x04000000u
|
||||
#define RCOSC_DIV2_MASK 0x00000004u
|
||||
|
||||
/*
|
||||
* MSSDDR_PLL_STATUS register masks:
|
||||
*/
|
||||
#define FAB_PLL_LOCK_MASK 0x00000001u
|
||||
#define MPLL_LOCK_MASK 0x00000002u
|
||||
|
||||
/*
|
||||
* MSSDDR_PLL_STATUS_HIGH_CR register masks:
|
||||
*/
|
||||
#define FACC_PLL_BYPASS_MASK 0x00000001u
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Standard CMSIS global variables.
|
||||
*/
|
||||
uint32_t SystemCoreClock = MSS_SYS_M3_CLK_FREQ; /*!< System Clock Frequency (Core Clock) */
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* SmartFusion2 specific clocks.
|
||||
*/
|
||||
uint32_t g_FrequencyPCLK0 = MSS_SYS_APB_0_CLK_FREQ; /*!< Clock frequency of APB bus 0. */
|
||||
uint32_t g_FrequencyPCLK1 = MSS_SYS_APB_1_CLK_FREQ; /*!< Clock frequency of APB bus 1. */
|
||||
uint32_t g_FrequencyPCLK2 = MSS_SYS_APB_2_CLK_FREQ; /*!< Clock frequency of APB bus 2. */
|
||||
uint32_t g_FrequencyFIC0 = MSS_SYS_FIC_0_CLK_FREQ; /*!< Clock frequecny of FPGA fabric interface controller 1. */
|
||||
uint32_t g_FrequencyFIC1 = MSS_SYS_FIC_1_CLK_FREQ; /*!< Clock frequecny of FPGA fabric inteface controller 2. */
|
||||
uint32_t g_FrequencyFIC64 = MSS_SYS_FIC64_CLK_FREQ; /*!< Clock frequecny of 64-bit FPGA fabric interface controller. */
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* System configuration tables generated by Libero.
|
||||
*/
|
||||
#if MSS_SYS_MDDR_CONFIG_BY_CORTEX
|
||||
extern MDDR_TypeDef * const g_m2s_mddr_addr;
|
||||
extern const ddr_subsys_cfg_t g_m2s_mddr_subsys_config;
|
||||
#endif
|
||||
|
||||
#if MSS_SYS_FDDR_CONFIG_BY_CORTEX
|
||||
extern FDDR_TypeDef * const g_m2s_fddr_addr;
|
||||
extern const ddr_subsys_cfg_t g_m2s_fddr_subsys_config;
|
||||
#endif
|
||||
|
||||
#define MSS_SYS_SERDES_CONFIG_BY_CORTEX (MSS_SYS_SERDES_0_CONFIG_BY_CORTEX || MSS_SYS_SERDES_1_CONFIG_BY_CORTEX || MSS_SYS_SERDES_2_CONFIG_BY_CORTEX || MSS_SYS_SERDES_3_CONFIG_BY_CORTEX)
|
||||
|
||||
#if MSS_SYS_SERDES_0_CONFIG_BY_CORTEX
|
||||
extern const cfg_addr_value_pair_t g_m2s_serdes_0_config[SERDES_0_CFG_NB_OF_PAIRS];
|
||||
#endif
|
||||
|
||||
#if MSS_SYS_SERDES_1_CONFIG_BY_CORTEX
|
||||
extern const cfg_addr_value_pair_t g_m2s_serdes_1_config[SERDES_1_CFG_NB_OF_PAIRS];
|
||||
#endif
|
||||
|
||||
#if MSS_SYS_SERDES_2_CONFIG_BY_CORTEX
|
||||
extern const cfg_addr_value_pair_t g_m2s_serdes_2_config[SERDES_2_CFG_NB_OF_PAIRS];
|
||||
#endif
|
||||
|
||||
#if MSS_SYS_SERDES_3_CONFIG_BY_CORTEX
|
||||
extern const cfg_addr_value_pair_t g_m2s_serdes_3_config[SERDES_3_CFG_NB_OF_PAIRS];
|
||||
#endif
|
||||
|
||||
#define MSS_SYS_CORESF2RESET_USED (MSS_SYS_MDDR_CONFIG_BY_CORTEX || MSS_SYS_FDDR_CONFIG_BY_CORTEX || MSS_SYS_SERDES_CONFIG_BY_CORTEX)
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Local functions:
|
||||
*/
|
||||
static uint32_t get_silicon_revision(void);
|
||||
static void silicon_workarounds(void);
|
||||
static void m2s050_rev_a_workarounds(void);
|
||||
|
||||
#if (MSS_SYS_FACC_INIT_BY_CORTEX == 1)
|
||||
static void complete_clock_config(void);
|
||||
#endif
|
||||
|
||||
#if MSS_SYS_SERDES_CONFIG_BY_CORTEX
|
||||
static void configure_serdes_intf(void);
|
||||
#endif
|
||||
|
||||
#if (MSS_SYS_MDDR_CONFIG_BY_CORTEX || MSS_SYS_FDDR_CONFIG_BY_CORTEX)
|
||||
static void config_ddr_subsys
|
||||
(
|
||||
const ddr_subsys_cfg_t * p_ddr_subsys_cfg,
|
||||
DDRCore_TypeDef * p_ddr_subsys_regs
|
||||
);
|
||||
#endif
|
||||
|
||||
#if MSS_SYS_SERDES_CONFIG_BY_CORTEX
|
||||
static void config_by_addr_value
|
||||
(
|
||||
const cfg_addr_value_pair_t * p_addr_value_pair,
|
||||
uint32_t nb_of_cfg_pairs
|
||||
);
|
||||
#endif
|
||||
|
||||
static uint32_t get_rcosc_25_50mhz_frequency(void);
|
||||
static void set_clock_frequency_globals(uint32_t fclk);
|
||||
|
||||
/***************************************************************************//**
|
||||
* See system_m2sxxx.h for details.
|
||||
*/
|
||||
void SystemInit(void)
|
||||
{
|
||||
/*
|
||||
* Do not make use of global variables or make any asumptions regarding
|
||||
* memory content if modifying this function. The memory content has not been
|
||||
* initialised by the time this function is called by the start-up code.
|
||||
*/
|
||||
#if (MSS_SYS_FACC_INIT_BY_CORTEX == 1)
|
||||
complete_clock_config();
|
||||
#endif
|
||||
|
||||
silicon_workarounds();
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* Set STKALIGN to ensure exception stacking starts on 8 bytes address
|
||||
* boundary. This ensures compliance with the "Procedure Call Standards for
|
||||
* the ARM Architecture" (AAPCS).
|
||||
*/
|
||||
SCB->CCR |= SCB_CCR_STKALIGN_Msk;
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* MDDR configuration
|
||||
*/
|
||||
#if MSS_SYS_MDDR_CONFIG_BY_CORTEX
|
||||
config_ddr_subsys(&g_m2s_mddr_subsys_config, &g_m2s_mddr_addr->core);
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* MDDR configuration
|
||||
*/
|
||||
#if MSS_SYS_FDDR_CONFIG_BY_CORTEX
|
||||
config_ddr_subsys(&g_m2s_fddr_subsys_config, &g_m2s_fddr_addr->core);
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* SERDES interfaces configuration.
|
||||
*/
|
||||
#if MSS_SYS_SERDES_CONFIG_BY_CORTEX
|
||||
configure_serdes_intf();
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* Call user defined configuration function.
|
||||
*/
|
||||
mscc_post_hw_cfg_init();
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* Synchronize with CoreSF2Reset controlling resets from the fabric.
|
||||
*/
|
||||
#if MSS_SYS_CORESF2RESET_USED
|
||||
CORE_SF2_CFG->CONFIG_DONE = 1u; /* Signal to CoreSF2Reset that peripheral
|
||||
configuration registers have been written.*/
|
||||
while(!CORE_SF2_CFG->INIT_DONE)
|
||||
{
|
||||
; /* Wait for INIT_DONE from CoreSF2Reset. */
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* SystemCoreClockUpdate()
|
||||
*/
|
||||
#define RCOSC_25_50MHZ_CLK_SRC 0u
|
||||
#define CLK_XTAL_CLK_SRC 1u
|
||||
#define RCOSC_1_MHZ_CLK_SRC 2u
|
||||
#define CCC2ASCI_CLK_SRC 3u
|
||||
|
||||
#define FACC_STANDBY_SHIFT 6u
|
||||
#define FACC_STANDBY_SEL_MASK 0x00000007u
|
||||
|
||||
#define FREQ_32KHZ 32768u
|
||||
#define FREQ_1MHZ 1000000u
|
||||
#define FREQ_25MHZ 25000000u
|
||||
#define FREQ_50MHZ 50000000u
|
||||
|
||||
void SystemCoreClockUpdate(void)
|
||||
{
|
||||
#if 1
|
||||
uint32_t controller_pll_init;
|
||||
uint32_t clk_src;
|
||||
|
||||
controller_pll_init = SYSREG->MSSDDR_FACC1_CR & CONTROLLER_PLL_INIT_MASK;
|
||||
|
||||
if(0u == controller_pll_init)
|
||||
{
|
||||
/* Normal operations. */
|
||||
uint32_t global_mux_sel;
|
||||
|
||||
global_mux_sel = SYSREG->MSSDDR_FACC1_CR & FACC_GLMUX_SEL_MASK;
|
||||
if(0u == global_mux_sel)
|
||||
{
|
||||
/* MSS clocked from MSS PLL. Use Libero flow defines. */
|
||||
SystemCoreClock = MSS_SYS_M3_CLK_FREQ;
|
||||
g_FrequencyPCLK0 = MSS_SYS_APB_0_CLK_FREQ;
|
||||
g_FrequencyPCLK1 = MSS_SYS_APB_1_CLK_FREQ;
|
||||
g_FrequencyPCLK2 = MSS_SYS_APB_2_CLK_FREQ;
|
||||
g_FrequencyFIC0 = MSS_SYS_FIC_0_CLK_FREQ;
|
||||
g_FrequencyFIC1 = MSS_SYS_FIC_1_CLK_FREQ;
|
||||
g_FrequencyFIC64 = MSS_SYS_FIC64_CLK_FREQ;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* MSS clocked from standby clock. */
|
||||
const uint8_t standby_clock_lut[8] = { RCOSC_25_50MHZ_CLK_SRC,
|
||||
CLK_XTAL_CLK_SRC,
|
||||
RCOSC_25_50MHZ_CLK_SRC,
|
||||
CLK_XTAL_CLK_SRC,
|
||||
RCOSC_1_MHZ_CLK_SRC,
|
||||
RCOSC_1_MHZ_CLK_SRC,
|
||||
CCC2ASCI_CLK_SRC,
|
||||
CCC2ASCI_CLK_SRC };
|
||||
|
||||
uint32_t standby_sel;
|
||||
uint8_t clock_source;
|
||||
|
||||
standby_sel = (SYSREG->MSSDDR_FACC2_CR >> FACC_STANDBY_SHIFT) & FACC_STANDBY_SEL_MASK;
|
||||
clock_source = standby_clock_lut[standby_sel];
|
||||
switch(clock_source)
|
||||
{
|
||||
case RCOSC_25_50MHZ_CLK_SRC:
|
||||
clk_src = get_rcosc_25_50mhz_frequency();
|
||||
set_clock_frequency_globals(clk_src);
|
||||
break;
|
||||
|
||||
case CLK_XTAL_CLK_SRC:
|
||||
set_clock_frequency_globals(FREQ_32KHZ);
|
||||
break;
|
||||
|
||||
case RCOSC_1_MHZ_CLK_SRC:
|
||||
set_clock_frequency_globals(FREQ_1MHZ);
|
||||
break;
|
||||
|
||||
case CCC2ASCI_CLK_SRC:
|
||||
/* Fall through. */
|
||||
default:
|
||||
set_clock_frequency_globals(FREQ_1MHZ);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* PLL initialization mode. Running from 25/50MHZ RC oscillator. */
|
||||
clk_src = get_rcosc_25_50mhz_frequency();
|
||||
set_clock_frequency_globals(clk_src);
|
||||
}
|
||||
|
||||
#else
|
||||
/*
|
||||
* Reset the clock frequency global variables to the values delected in the
|
||||
* Libero flow.
|
||||
*/
|
||||
SystemCoreClock = MSS_SYS_M3_CLK_FREQ;
|
||||
g_FrequencyPCLK0 = MSS_SYS_APB_0_CLK_FREQ;
|
||||
g_FrequencyPCLK1 = MSS_SYS_APB_1_CLK_FREQ;
|
||||
g_FrequencyPCLK2 = MSS_SYS_APB_2_CLK_FREQ;
|
||||
g_FrequencyFIC0 = MSS_SYS_FIC_0_CLK_FREQ;
|
||||
g_FrequencyFIC1 = MSS_SYS_FIC_1_CLK_FREQ;
|
||||
g_FrequencyFIC64 = MSS_SYS_FIC64_CLK_FREQ;
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Find out frequency generated by the 25_50mhz RC osciallator.
|
||||
*/
|
||||
static uint32_t get_rcosc_25_50mhz_frequency(void)
|
||||
{
|
||||
uint32_t rcosc_div2;
|
||||
uint32_t rcosc_frequency;
|
||||
|
||||
rcosc_div2 = SYSREG->MSSDDR_PLL_STATUS & RCOSC_DIV2_MASK;
|
||||
if(0u == rcosc_div2)
|
||||
{
|
||||
/* 25_50mhz oscillator is configured for 25 MHz operations. */
|
||||
rcosc_frequency = FREQ_25MHZ;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 25_50mhz oscillator is configured for 50 MHz operations. */
|
||||
rcosc_frequency = FREQ_50MHZ;
|
||||
}
|
||||
|
||||
return rcosc_frequency;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
Set the value of the clock frequency global variables based on the value of
|
||||
standby_clk passed as parameter.
|
||||
The following global variables are set by this function:
|
||||
- SystemCoreClock
|
||||
- g_FrequencyPCLK0
|
||||
- g_FrequencyPCLK1
|
||||
- g_FrequencyPCLK2
|
||||
- g_FrequencyFIC0
|
||||
- g_FrequencyFIC1
|
||||
- g_FrequencyFIC64
|
||||
*/
|
||||
static void set_clock_frequency_globals(uint32_t standby_clk)
|
||||
{
|
||||
SystemCoreClock = standby_clk;
|
||||
g_FrequencyPCLK0 = standby_clk;
|
||||
g_FrequencyPCLK1 = standby_clk;
|
||||
g_FrequencyPCLK2 = MSS_SYS_APB_2_CLK_FREQ;
|
||||
g_FrequencyFIC0 = standby_clk;
|
||||
g_FrequencyFIC1 = standby_clk;
|
||||
g_FrequencyFIC64 = standby_clk;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Write 16-bit configuration values into 32-bit word aligned registers.
|
||||
*/
|
||||
#if (MSS_SYS_MDDR_CONFIG_BY_CORTEX || MSS_SYS_FDDR_CONFIG_BY_CORTEX)
|
||||
static void copy_cfg16_to_regs
|
||||
(
|
||||
volatile uint32_t * p_regs,
|
||||
const uint16_t * p_cfg,
|
||||
uint32_t nb_16bit_words
|
||||
)
|
||||
{
|
||||
uint32_t inc;
|
||||
|
||||
for(inc = 0u; inc < nb_16bit_words; ++inc)
|
||||
{
|
||||
p_regs[inc] = p_cfg[inc];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* Configure peripheral using register address and register value pairs.
|
||||
*/
|
||||
#if MSS_SYS_SERDES_CONFIG_BY_CORTEX
|
||||
static void config_by_addr_value
|
||||
(
|
||||
const cfg_addr_value_pair_t * p_addr_value_pair,
|
||||
uint32_t nb_of_cfg_pairs
|
||||
)
|
||||
{
|
||||
uint32_t inc;
|
||||
|
||||
for(inc = 0u; inc < nb_of_cfg_pairs; ++inc)
|
||||
{
|
||||
*p_addr_value_pair[inc].p_reg = p_addr_value_pair[inc].value;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* DDR subsystem configuration.
|
||||
*/
|
||||
#if (MSS_SYS_MDDR_CONFIG_BY_CORTEX || MSS_SYS_FDDR_CONFIG_BY_CORTEX)
|
||||
|
||||
#define NB_OF_DDRC_REGS_TO_CONFIG 57u
|
||||
#define NB_OF_DDR_PHY_REGS_TO_CONFIG 65u
|
||||
|
||||
static void config_ddr_subsys
|
||||
(
|
||||
const ddr_subsys_cfg_t * p_ddr_subsys_cfg,
|
||||
DDRCore_TypeDef * p_ddr_subsys_regs
|
||||
)
|
||||
{
|
||||
volatile uint32_t * p_regs;
|
||||
const uint16_t * p_cfg;
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* Configure DDR controller part of the MDDR subsystem.
|
||||
*/
|
||||
p_cfg = &p_ddr_subsys_cfg->ddrc.DYN_SOFT_RESET_CR;
|
||||
p_regs = &p_ddr_subsys_regs->ddrc.DYN_SOFT_RESET_CR;
|
||||
|
||||
copy_cfg16_to_regs(p_regs, p_cfg, NB_OF_DDRC_REGS_TO_CONFIG);
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* Configure DDR PHY.
|
||||
*/
|
||||
p_cfg = &p_ddr_subsys_cfg->phy.LOOPBACK_TEST_CR;
|
||||
p_regs = &p_ddr_subsys_regs->phy.LOOPBACK_TEST_CR;
|
||||
|
||||
copy_cfg16_to_regs(p_regs, p_cfg, NB_OF_DDR_PHY_REGS_TO_CONFIG);
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* Configure DDR FIC.
|
||||
*/
|
||||
p_ddr_subsys_regs->fic.NB_ADDR_CR = p_ddr_subsys_cfg->fic.NB_ADDR_CR;
|
||||
p_ddr_subsys_regs->fic.NBRWB_SIZE_CR = p_ddr_subsys_cfg->fic.NBRWB_SIZE_CR;
|
||||
p_ddr_subsys_regs->fic.WB_TIMEOUT_CR = p_ddr_subsys_cfg->fic.WB_TIMEOUT_CR;
|
||||
p_ddr_subsys_regs->fic.HPD_SW_RW_EN_CR = p_ddr_subsys_cfg->fic.HPD_SW_RW_EN_CR;
|
||||
p_ddr_subsys_regs->fic.HPD_SW_RW_INVAL_CR = p_ddr_subsys_cfg->fic.HPD_SW_RW_INVAL_CR;
|
||||
p_ddr_subsys_regs->fic.SW_WR_ERCLR_CR = p_ddr_subsys_cfg->fic.SW_WR_ERCLR_CR;
|
||||
p_ddr_subsys_regs->fic.ERR_INT_ENABLE_CR = p_ddr_subsys_cfg->fic.ERR_INT_ENABLE_CR;
|
||||
p_ddr_subsys_regs->fic.NUM_AHB_MASTERS_CR = p_ddr_subsys_cfg->fic.NUM_AHB_MASTERS_CR;
|
||||
p_ddr_subsys_regs->fic.LOCK_TIMEOUTVAL_CR[0] = p_ddr_subsys_cfg->fic.LOCK_TIMEOUTVAL_1_CR;
|
||||
p_ddr_subsys_regs->fic.LOCK_TIMEOUTVAL_CR[1] = p_ddr_subsys_cfg->fic.LOCK_TIMEOUTVAL_2_CR;
|
||||
p_ddr_subsys_regs->fic.LOCK_TIMEOUT_EN_CR = p_ddr_subsys_cfg->fic.LOCK_TIMEOUT_EN_CR;
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* Enable DDR.
|
||||
*/
|
||||
p_ddr_subsys_regs->ddrc.DYN_SOFT_RESET_CR = 0x01u;
|
||||
|
||||
while(0x0000u == p_ddr_subsys_regs->ddrc.DDRC_SR)
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* Configure SERDES interfaces.
|
||||
*/
|
||||
#if MSS_SYS_SERDES_CONFIG_BY_CORTEX
|
||||
|
||||
static void configure_serdes_intf(void)
|
||||
{
|
||||
#if MSS_SYS_SERDES_0_CONFIG_BY_CORTEX
|
||||
config_by_addr_value(g_m2s_serdes_0_config, SERDES_0_CFG_NB_OF_PAIRS);
|
||||
#endif
|
||||
|
||||
#if MSS_SYS_SERDES_1_CONFIG_BY_CORTEX
|
||||
config_by_addr_value(g_m2s_serdes_1_config, SERDES_1_CFG_NB_OF_PAIRS);
|
||||
#endif
|
||||
|
||||
#if MSS_SYS_SERDES_2_CONFIG_BY_CORTEX
|
||||
config_by_addr_value(g_m2s_serdes_2_config, SERDES_2_CFG_NB_OF_PAIRS);
|
||||
#endif
|
||||
|
||||
#if MSS_SYS_SERDES_3_CONFIG_BY_CORTEX
|
||||
config_by_addr_value(g_m2s_serdes_3_config, SERDES_3_CFG_NB_OF_PAIRS);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
Retrieve silicon revision from system registers.
|
||||
*/
|
||||
static uint32_t get_silicon_revision(void)
|
||||
{
|
||||
uint32_t silicon_revision;
|
||||
uint32_t device_version;
|
||||
|
||||
device_version = SYSREG->DEVICE_VERSION;
|
||||
switch(device_version)
|
||||
{
|
||||
case 0x0000F802:
|
||||
silicon_revision = M2S050_REV_A_SILICON;
|
||||
break;
|
||||
|
||||
case 0x0001F802:
|
||||
silicon_revision = M2S050_REV_B_SILICON;
|
||||
break;
|
||||
|
||||
default:
|
||||
silicon_revision = UNKNOWN_SILICON_REV;
|
||||
break;
|
||||
}
|
||||
|
||||
return silicon_revision;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
Workarounds for various silicon versions.
|
||||
*/
|
||||
static void silicon_workarounds(void)
|
||||
{
|
||||
uint32_t silicon_revision;
|
||||
|
||||
silicon_revision = get_silicon_revision();
|
||||
|
||||
switch(silicon_revision)
|
||||
{
|
||||
case M2S050_REV_A_SILICON:
|
||||
m2s050_rev_a_workarounds();
|
||||
break;
|
||||
|
||||
case M2S050_REV_B_SILICON:
|
||||
/* Fall through. */
|
||||
case UNKNOWN_SILICON_REV:
|
||||
/* Fall through. */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
Silicon workarounds for M2S050 rev A.
|
||||
*/
|
||||
static void m2s050_rev_a_workarounds(void)
|
||||
{
|
||||
/*--------------------------------------------------------------------------
|
||||
* Work around a couple of silicon issues:
|
||||
*/
|
||||
/* DDR_CLK_EN <- 1 */
|
||||
SYSREG->MSSDDR_FACC1_CR |= (uint32_t)1 << DDR_CLK_EN_SHIFT;
|
||||
|
||||
/* CONTROLLER_PLL_INIT <- 0 */
|
||||
SYSREG->MSSDDR_FACC1_CR = SYSREG->MSSDDR_FACC1_CR & ~CONTROLLER_PLL_INIT_MASK;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
Complete clock configuration if requested by Libero.
|
||||
*/
|
||||
#if (MSS_SYS_FACC_INIT_BY_CORTEX == 1)
|
||||
static void complete_clock_config(void)
|
||||
{
|
||||
uint32_t pll_locked;
|
||||
|
||||
/* Wait for fabric PLL to lock. */
|
||||
do {
|
||||
pll_locked = SYSREG->MSSDDR_PLL_STATUS & FAB_PLL_LOCK_MASK;
|
||||
} while(!pll_locked);
|
||||
|
||||
/* Negate MPLL bypass. */
|
||||
SYSREG->MSSDDR_PLL_STATUS_HIGH_CR &= ~FACC_PLL_BYPASS_MASK;
|
||||
|
||||
/* Wait for MPLL to lock. */
|
||||
do {
|
||||
pll_locked = SYSREG->MSSDDR_PLL_STATUS & MPLL_LOCK_MASK;
|
||||
} while(!pll_locked);
|
||||
|
||||
/* Switch FACC from standby to run mode. */
|
||||
SYSREG->MSSDDR_FACC1_CR &= ~FACC_GLMUX_SEL_MASK;
|
||||
|
||||
/* Negate FPGA_SOFTRESET to de-assert MSS_RESET_N_M2F in the fabric */
|
||||
SYSREG->SOFT_RST_CR &= ~SYSREG_FPGA_SOFTRESET_MASK;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2012-2013 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* SmartFusion2 CMSIS system initialization.
|
||||
*
|
||||
* SVN $Revision: 5280 $
|
||||
* SVN $Date: 2013-03-22 20:51:50 +0000 (Fri, 22 Mar 2013) $
|
||||
*/
|
||||
|
||||
#ifndef SYSTEM_M2SXXX_H
|
||||
#define SYSTEM_M2SXXX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Standard CMSIS global variables. */
|
||||
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
|
||||
|
||||
/* SmartFusion2 specific clocks. */
|
||||
extern uint32_t g_FrequencyPCLK0; /*!< Clock frequency of APB bus 0. */
|
||||
extern uint32_t g_FrequencyPCLK1; /*!< Clock frequency of APB bus 1. */
|
||||
extern uint32_t g_FrequencyPCLK2; /*!< Clock frequency of APB bus 2. */
|
||||
extern uint32_t g_FrequencyFIC0; /*!< Clock frequecny of FPGA fabric interface controller 1. */
|
||||
extern uint32_t g_FrequencyFIC1; /*!< Clock frequecny of FPGA fabric inteface controller 2. */
|
||||
extern uint32_t g_FrequencyFIC64; /*!< Clock frequecny of 64-bit FPGA fabric interface controller. */
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* The SystemInit() is a standard CMSIS function called during system startup.
|
||||
* It is meant to perform low level hardware setup such as configuring DDR and
|
||||
* SERDES controllers.
|
||||
*/
|
||||
void SystemInit(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* The SystemCoreClockUpdate() is a standard CMSIS function which can be called
|
||||
* by the application in order to ensure that the SystemCoreClock global
|
||||
* variable contains the up to date Cortex-M3 core frequency. Calling this
|
||||
* function also updates the global variables containing the frequencies of the
|
||||
* APB busses connecting the peripherals.
|
||||
*/
|
||||
void SystemCoreClockUpdate(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef RTOSDemo_HW_PLATFORM_H_
|
||||
#define RTOSDemo_HW_PLATFORM_H_
|
||||
/*****************************************************************************
|
||||
*
|
||||
*Created by Actel SmartDesign Sun May 05 13:23:22 2013
|
||||
*
|
||||
*Memory map specification for peripherals in RTOSDemo
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* CM3 subsystem memory map
|
||||
* Master(s) for this subsystem: CM3
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#endif /* RTOSDemo_HW_PLATFORM_H_*/
|
|
@ -0,0 +1,296 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2008-2013 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* SmartFusion2 microcontroller subsystem GPIO bare metal driver implementation.
|
||||
*
|
||||
* SVN $Revision: 5394 $
|
||||
* SVN $Date: 2013-03-27 20:56:36 +0000 (Wed, 27 Mar 2013) $
|
||||
*/
|
||||
#include "mss_gpio.h"
|
||||
#include "../../CMSIS/mss_assert.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* Defines.
|
||||
*/
|
||||
#define GPIO_INT_ENABLE_MASK ((uint32_t)0x00000008uL)
|
||||
#define OUTPUT_BUFFER_ENABLE_MASK 0x00000004u
|
||||
|
||||
#define NB_OF_GPIO ((uint32_t)32)
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* Lookup table of GPIO configuration registers address indexed on GPIO ID.
|
||||
*/
|
||||
static uint32_t volatile * const g_config_reg_lut[NB_OF_GPIO] =
|
||||
{
|
||||
&(GPIO->GPIO_0_CFG),
|
||||
&(GPIO->GPIO_1_CFG),
|
||||
&(GPIO->GPIO_2_CFG),
|
||||
&(GPIO->GPIO_3_CFG),
|
||||
&(GPIO->GPIO_4_CFG),
|
||||
&(GPIO->GPIO_5_CFG),
|
||||
&(GPIO->GPIO_6_CFG),
|
||||
&(GPIO->GPIO_7_CFG),
|
||||
&(GPIO->GPIO_8_CFG),
|
||||
&(GPIO->GPIO_9_CFG),
|
||||
&(GPIO->GPIO_10_CFG),
|
||||
&(GPIO->GPIO_11_CFG),
|
||||
&(GPIO->GPIO_12_CFG),
|
||||
&(GPIO->GPIO_13_CFG),
|
||||
&(GPIO->GPIO_14_CFG),
|
||||
&(GPIO->GPIO_15_CFG),
|
||||
&(GPIO->GPIO_16_CFG),
|
||||
&(GPIO->GPIO_17_CFG),
|
||||
&(GPIO->GPIO_18_CFG),
|
||||
&(GPIO->GPIO_19_CFG),
|
||||
&(GPIO->GPIO_20_CFG),
|
||||
&(GPIO->GPIO_21_CFG),
|
||||
&(GPIO->GPIO_22_CFG),
|
||||
&(GPIO->GPIO_23_CFG),
|
||||
&(GPIO->GPIO_24_CFG),
|
||||
&(GPIO->GPIO_25_CFG),
|
||||
&(GPIO->GPIO_26_CFG),
|
||||
&(GPIO->GPIO_27_CFG),
|
||||
&(GPIO->GPIO_28_CFG),
|
||||
&(GPIO->GPIO_29_CFG),
|
||||
&(GPIO->GPIO_30_CFG),
|
||||
&(GPIO->GPIO_31_CFG)
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* Lookup table of Cortex-M3 GPIO interrupt number indexed on GPIO ID.
|
||||
*/
|
||||
static const IRQn_Type g_gpio_irqn_lut[NB_OF_GPIO] =
|
||||
{
|
||||
GPIO0_IRQn,
|
||||
GPIO1_IRQn,
|
||||
GPIO2_IRQn,
|
||||
GPIO3_IRQn,
|
||||
GPIO4_IRQn,
|
||||
GPIO5_IRQn,
|
||||
GPIO6_IRQn,
|
||||
GPIO7_IRQn,
|
||||
GPIO8_IRQn,
|
||||
GPIO9_IRQn,
|
||||
GPIO10_IRQn,
|
||||
GPIO11_IRQn,
|
||||
GPIO12_IRQn,
|
||||
GPIO13_IRQn,
|
||||
GPIO14_IRQn,
|
||||
GPIO15_IRQn,
|
||||
GPIO16_IRQn,
|
||||
GPIO17_IRQn,
|
||||
GPIO18_IRQn,
|
||||
GPIO19_IRQn,
|
||||
GPIO20_IRQn,
|
||||
GPIO21_IRQn,
|
||||
GPIO22_IRQn,
|
||||
GPIO23_IRQn,
|
||||
GPIO24_IRQn,
|
||||
GPIO25_IRQn,
|
||||
GPIO26_IRQn,
|
||||
GPIO27_IRQn,
|
||||
GPIO28_IRQn,
|
||||
GPIO29_IRQn,
|
||||
GPIO30_IRQn,
|
||||
GPIO31_IRQn
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* MSS_GPIO_init
|
||||
* See "mss_gpio.h" for details of how to use this function.
|
||||
*/
|
||||
void MSS_GPIO_init( void )
|
||||
{
|
||||
uint32_t inc;
|
||||
|
||||
/* reset MSS GPIO hardware */
|
||||
SYSREG->SOFT_RST_CR |= SYSREG_GPIO_SOFTRESET_MASK;
|
||||
SYSREG->SOFT_RST_CR |= (SYSREG_GPIO_7_0_SOFTRESET_MASK |
|
||||
SYSREG_GPIO_15_8_SOFTRESET_MASK |
|
||||
SYSREG_GPIO_23_16_SOFTRESET_MASK |
|
||||
SYSREG_GPIO_31_24_SOFTRESET_MASK);
|
||||
|
||||
/* Clear any previously pended MSS GPIO interrupt */
|
||||
for(inc = 0U; inc < NB_OF_GPIO; ++inc)
|
||||
{
|
||||
NVIC_DisableIRQ(g_gpio_irqn_lut[inc]);
|
||||
NVIC_ClearPendingIRQ(g_gpio_irqn_lut[inc]);
|
||||
}
|
||||
/* Take MSS GPIO hardware out of reset. */
|
||||
SYSREG->SOFT_RST_CR &= ~(SYSREG_GPIO_7_0_SOFTRESET_MASK |
|
||||
SYSREG_GPIO_15_8_SOFTRESET_MASK |
|
||||
SYSREG_GPIO_23_16_SOFTRESET_MASK |
|
||||
SYSREG_GPIO_31_24_SOFTRESET_MASK);
|
||||
SYSREG->SOFT_RST_CR &= ~SYSREG_GPIO_SOFTRESET_MASK;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* MSS_GPIO_config
|
||||
* See "mss_gpio.h" for details of how to use this function.
|
||||
*/
|
||||
void MSS_GPIO_config
|
||||
(
|
||||
mss_gpio_id_t port_id,
|
||||
uint32_t config
|
||||
)
|
||||
{
|
||||
uint32_t gpio_idx = (uint32_t)port_id;
|
||||
|
||||
ASSERT(gpio_idx < NB_OF_GPIO);
|
||||
|
||||
if(gpio_idx < NB_OF_GPIO)
|
||||
{
|
||||
*(g_config_reg_lut[gpio_idx]) = config;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* MSS_GPIO_set_output
|
||||
* See "mss_gpio.h" for details of how to use this function.
|
||||
*/
|
||||
void MSS_GPIO_set_output
|
||||
(
|
||||
mss_gpio_id_t port_id,
|
||||
uint8_t value
|
||||
)
|
||||
{
|
||||
uint32_t gpio_setting;
|
||||
uint32_t gpio_idx = (uint32_t)port_id;
|
||||
|
||||
ASSERT(gpio_idx < NB_OF_GPIO);
|
||||
|
||||
if(gpio_idx < NB_OF_GPIO)
|
||||
{
|
||||
gpio_setting = GPIO->GPIO_OUT;
|
||||
gpio_setting &= ~((uint32_t)0x01u << gpio_idx);
|
||||
gpio_setting |= ((uint32_t)value & 0x01u) << gpio_idx;
|
||||
GPIO->GPIO_OUT = gpio_setting;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* MSS_GPIO_drive_inout
|
||||
* See "mss_gpio.h" for details of how to use this function.
|
||||
*/
|
||||
void MSS_GPIO_drive_inout
|
||||
(
|
||||
mss_gpio_id_t port_id,
|
||||
mss_gpio_inout_state_t inout_state
|
||||
)
|
||||
{
|
||||
uint32_t outputs_state;
|
||||
uint32_t config;
|
||||
uint32_t gpio_idx = (uint32_t)port_id;
|
||||
|
||||
ASSERT(gpio_idx < NB_OF_GPIO);
|
||||
|
||||
if(gpio_idx < NB_OF_GPIO)
|
||||
{
|
||||
switch(inout_state)
|
||||
{
|
||||
case MSS_GPIO_DRIVE_HIGH:
|
||||
/* Set output high */
|
||||
outputs_state = GPIO->GPIO_OUT;
|
||||
outputs_state |= (uint32_t)1 << gpio_idx;
|
||||
GPIO->GPIO_OUT = outputs_state;
|
||||
/* Enable output buffer */
|
||||
config = *(g_config_reg_lut[gpio_idx]);
|
||||
config |= OUTPUT_BUFFER_ENABLE_MASK;
|
||||
*(g_config_reg_lut[gpio_idx]) = config;
|
||||
break;
|
||||
|
||||
case MSS_GPIO_DRIVE_LOW:
|
||||
/* Set output low */
|
||||
outputs_state = GPIO->GPIO_OUT;
|
||||
outputs_state &= ~((uint32_t)((uint32_t)1 << gpio_idx));
|
||||
GPIO->GPIO_OUT = outputs_state;
|
||||
/* Enable output buffer */
|
||||
config = *(g_config_reg_lut[gpio_idx]);
|
||||
config |= OUTPUT_BUFFER_ENABLE_MASK;
|
||||
*(g_config_reg_lut[gpio_idx]) = config;
|
||||
break;
|
||||
|
||||
case MSS_GPIO_HIGH_Z:
|
||||
/* Disable output buffer */
|
||||
config = *(g_config_reg_lut[gpio_idx]);
|
||||
config &= ~OUTPUT_BUFFER_ENABLE_MASK;
|
||||
*(g_config_reg_lut[gpio_idx]) = config;
|
||||
break;
|
||||
|
||||
default:
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* MSS_GPIO_enable_irq
|
||||
* See "mss_gpio.h" for details of how to use this function.
|
||||
*/
|
||||
void MSS_GPIO_enable_irq
|
||||
(
|
||||
mss_gpio_id_t port_id
|
||||
)
|
||||
{
|
||||
uint32_t cfg_value;
|
||||
uint32_t gpio_idx = (uint32_t)port_id;
|
||||
|
||||
ASSERT(gpio_idx < NB_OF_GPIO);
|
||||
|
||||
if(gpio_idx < NB_OF_GPIO)
|
||||
{
|
||||
cfg_value = *(g_config_reg_lut[gpio_idx]);
|
||||
*(g_config_reg_lut[gpio_idx]) = (cfg_value | GPIO_INT_ENABLE_MASK);
|
||||
NVIC_EnableIRQ(g_gpio_irqn_lut[gpio_idx]);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* MSS_GPIO_disable_irq
|
||||
* See "mss_gpio.h" for details of how to use this function.
|
||||
*/
|
||||
void MSS_GPIO_disable_irq
|
||||
(
|
||||
mss_gpio_id_t port_id
|
||||
)
|
||||
{
|
||||
uint32_t cfg_value;
|
||||
uint32_t gpio_idx = (uint32_t)port_id;
|
||||
|
||||
ASSERT(gpio_idx < NB_OF_GPIO);
|
||||
|
||||
if(gpio_idx < NB_OF_GPIO)
|
||||
{
|
||||
cfg_value = *(g_config_reg_lut[gpio_idx]);
|
||||
*(g_config_reg_lut[gpio_idx]) = (cfg_value & ~GPIO_INT_ENABLE_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* MSS_GPIO_clear_irq
|
||||
* See "mss_gpio.h" for details of how to use this function.
|
||||
*/
|
||||
void MSS_GPIO_clear_irq
|
||||
(
|
||||
mss_gpio_id_t port_id
|
||||
)
|
||||
{
|
||||
uint32_t gpio_idx = (uint32_t)port_id;
|
||||
|
||||
ASSERT(gpio_idx < NB_OF_GPIO);
|
||||
|
||||
if(gpio_idx < NB_OF_GPIO)
|
||||
{
|
||||
GPIO->GPIO_IRQ = ((uint32_t)1) << gpio_idx;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,507 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2008-2013 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* SmartFusion2 Microcontroller Subsystem GPIO bare metal software driver public
|
||||
* API.
|
||||
*
|
||||
* SVN $Revision: 5487 $
|
||||
* SVN $Date: 2013-03-29 15:33:22 +0000 (Fri, 29 Mar 2013) $
|
||||
*/
|
||||
|
||||
/*=========================================================================*//**
|
||||
@mainpage SmartFusion2 MSS GPIO Bare Metal Driver.
|
||||
|
||||
@section intro_sec Introduction
|
||||
The SmartFusion2 Microcontroller Subsystem (MSS) includes a block of 32 general
|
||||
purpose input/outputs (GPIO).
|
||||
This software driver provides a set of functions for controlling the MSS GPIO
|
||||
block as part of a bare metal system where no operating system is available.
|
||||
This driver can be adapted for use as part of an operating system but the
|
||||
implementation of the adaptation layer between this driver and the operating
|
||||
system's driver model is outside the scope of this driver.
|
||||
|
||||
@section hw_dependencies Hardware Flow Dependencies
|
||||
The configuration of all features of the MSS GPIOs is covered by this driver
|
||||
with the exception of the SmartFusion2 IOMUX configuration. SmartFusion2
|
||||
allows multiple non-concurrent uses of some external pins through IOMUX
|
||||
configuration. This feature allows optimization of external pin usage by
|
||||
assigning external pins for use by either the microcontroller subsystem or the
|
||||
FPGA fabric. The MSS GPIOs share SmartFusion2 device external pins with the
|
||||
FPGA fabric and with other MSS peripherals via an IOMUX. The MSS GPIO ports
|
||||
can alternatively be routed to the FPGA fabric through an IOMUX.
|
||||
The IOMUXs are configured using the SmartFusion2 MSS configurator tool. You
|
||||
must ensure that the MSS GPIOs are enabled and configured in the SmartFusion2
|
||||
MSS configurator if you wish to use them. For more information on IOMUXs,
|
||||
refer to the IOMUX section of the SmartFusion2 Microcontroller Subsystem (MSS)
|
||||
User’s Guide.
|
||||
The base address, register addresses and interrupt number assignment for the
|
||||
MSS GPIO block are defined as constants in the SmartFusion2 CMSIS HAL. You
|
||||
must ensure that the latest SmartFusion2 CMSIS HAL is included in the project
|
||||
settings of the software tool chain used to build your project and that it is
|
||||
generated into your project.
|
||||
|
||||
@section theory_op Theory of Operation
|
||||
The MSS GPIO driver functions are grouped into the following categories:
|
||||
- Initialization
|
||||
- Configuration
|
||||
- Reading and setting GPIO state
|
||||
- Interrupt control
|
||||
|
||||
Initialization
|
||||
The MSS GPIO driver is initialized through a call to the MSS_GPIO_init()
|
||||
function. The MSS_GPIO_init() function must be called before any other MSS
|
||||
GPIO driver functions can be called.
|
||||
|
||||
Configuration
|
||||
Each GPIO port is individually configured through a call to the
|
||||
MSS_GPIO_config() function. Configuration includes deciding if a GPIO port
|
||||
will be used as an input, an output or both. GPIO ports configured as inputs
|
||||
can be further configured to generate interrupts based on the input's state.
|
||||
Interrupts can be level or edge sensitive.
|
||||
|
||||
Reading and Setting GPIO State
|
||||
The state of the GPIO ports can be read and set using the following functions:
|
||||
- MSS_GPIO_get_inputs()
|
||||
- MSS_GPIO_get_outputs()
|
||||
- MSS_GPIO_set_outputs()
|
||||
- MSS_GPIO_set_output()
|
||||
- MSS_GPIO_drive_inout()
|
||||
|
||||
Interrupt Control
|
||||
Interrupts generated by GPIO ports configured as inputs are controlled using
|
||||
the following functions:
|
||||
- MSS_GPIO_enable_irq()
|
||||
- MSS_GPIO_disable_irq()
|
||||
- MSS_GPIO_clear_irq()
|
||||
|
||||
*//*=========================================================================*/
|
||||
#ifndef MSS_GPIO_H_
|
||||
#define MSS_GPIO_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../../CMSIS/m2sxxx.h"
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The mss_gpio_id_t enumeration is used to identify individual GPIO ports as an
|
||||
argument to functions:
|
||||
- MSS_GPIO_config()
|
||||
- MSS_GPIO_set_output() and MSS_GPIO_drive_inout()
|
||||
- MSS_GPIO_enable_irq(), MSS_GPIO_disable_irq() and MSS_GPIO_clear_irq()
|
||||
*/
|
||||
typedef enum __mss_gpio_id_t
|
||||
{
|
||||
MSS_GPIO_0 = 0,
|
||||
MSS_GPIO_1 = 1,
|
||||
MSS_GPIO_2 = 2,
|
||||
MSS_GPIO_3 = 3,
|
||||
MSS_GPIO_4 = 4,
|
||||
MSS_GPIO_5 = 5,
|
||||
MSS_GPIO_6 = 6,
|
||||
MSS_GPIO_7 = 7,
|
||||
MSS_GPIO_8 = 8,
|
||||
MSS_GPIO_9 = 9,
|
||||
MSS_GPIO_10 = 10,
|
||||
MSS_GPIO_11 = 11,
|
||||
MSS_GPIO_12 = 12,
|
||||
MSS_GPIO_13 = 13,
|
||||
MSS_GPIO_14 = 14,
|
||||
MSS_GPIO_15 = 15,
|
||||
MSS_GPIO_16 = 16,
|
||||
MSS_GPIO_17 = 17,
|
||||
MSS_GPIO_18 = 18,
|
||||
MSS_GPIO_19 = 19,
|
||||
MSS_GPIO_20 = 20,
|
||||
MSS_GPIO_21 = 21,
|
||||
MSS_GPIO_22 = 22,
|
||||
MSS_GPIO_23 = 23,
|
||||
MSS_GPIO_24 = 24,
|
||||
MSS_GPIO_25 = 25,
|
||||
MSS_GPIO_26 = 26,
|
||||
MSS_GPIO_27 = 27,
|
||||
MSS_GPIO_28 = 28,
|
||||
MSS_GPIO_29 = 29,
|
||||
MSS_GPIO_30 = 30,
|
||||
MSS_GPIO_31 = 31
|
||||
} mss_gpio_id_t;
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
These constant definitions are used as an argument to the
|
||||
MSS_GPIO_set_outputs() function to identify GPIO ports. A logical OR of these
|
||||
constants can be used to specify multiple GPIO ports.
|
||||
These definitions can also be used to identify GPIO ports through logical
|
||||
operations on the return value of the MSS_GPIO_get_inputs() function.
|
||||
*/
|
||||
#define MSS_GPIO_0_MASK 0x00000001uL
|
||||
#define MSS_GPIO_1_MASK 0x00000002uL
|
||||
#define MSS_GPIO_2_MASK 0x00000004uL
|
||||
#define MSS_GPIO_3_MASK 0x00000008uL
|
||||
#define MSS_GPIO_4_MASK 0x00000010uL
|
||||
#define MSS_GPIO_5_MASK 0x00000020uL
|
||||
#define MSS_GPIO_6_MASK 0x00000040uL
|
||||
#define MSS_GPIO_7_MASK 0x00000080uL
|
||||
#define MSS_GPIO_8_MASK 0x00000100uL
|
||||
#define MSS_GPIO_9_MASK 0x00000200uL
|
||||
#define MSS_GPIO_10_MASK 0x00000400uL
|
||||
#define MSS_GPIO_11_MASK 0x00000800uL
|
||||
#define MSS_GPIO_12_MASK 0x00001000uL
|
||||
#define MSS_GPIO_13_MASK 0x00002000uL
|
||||
#define MSS_GPIO_14_MASK 0x00004000uL
|
||||
#define MSS_GPIO_15_MASK 0x00008000uL
|
||||
#define MSS_GPIO_16_MASK 0x00010000uL
|
||||
#define MSS_GPIO_17_MASK 0x00020000uL
|
||||
#define MSS_GPIO_18_MASK 0x00040000uL
|
||||
#define MSS_GPIO_19_MASK 0x00080000uL
|
||||
#define MSS_GPIO_20_MASK 0x00100000uL
|
||||
#define MSS_GPIO_21_MASK 0x00200000uL
|
||||
#define MSS_GPIO_22_MASK 0x00400000uL
|
||||
#define MSS_GPIO_23_MASK 0x00800000uL
|
||||
#define MSS_GPIO_24_MASK 0x01000000uL
|
||||
#define MSS_GPIO_25_MASK 0x02000000uL
|
||||
#define MSS_GPIO_26_MASK 0x04000000uL
|
||||
#define MSS_GPIO_27_MASK 0x08000000uL
|
||||
#define MSS_GPIO_28_MASK 0x10000000uL
|
||||
#define MSS_GPIO_29_MASK 0x20000000uL
|
||||
#define MSS_GPIO_30_MASK 0x40000000uL
|
||||
#define MSS_GPIO_31_MASK 0x80000000uL
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
These constant definitions are used as an argument to the MSS_GPIO_config()
|
||||
function to specify the I/O mode of each GPIO port.
|
||||
*/
|
||||
#define MSS_GPIO_INPUT_MODE 0x0000000002uL
|
||||
#define MSS_GPIO_OUTPUT_MODE 0x0000000005uL
|
||||
#define MSS_GPIO_INOUT_MODE 0x0000000003uL
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
These constant definitions are used as an argument to the MSS_GPIO_config()
|
||||
function to specify the interrupt mode of each GPIO port.
|
||||
*/
|
||||
#define MSS_GPIO_IRQ_LEVEL_HIGH 0x0000000000uL
|
||||
#define MSS_GPIO_IRQ_LEVEL_LOW 0x0000000020uL
|
||||
#define MSS_GPIO_IRQ_EDGE_POSITIVE 0x0000000040uL
|
||||
#define MSS_GPIO_IRQ_EDGE_NEGATIVE 0x0000000060uL
|
||||
#define MSS_GPIO_IRQ_EDGE_BOTH 0x0000000080uL
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The mss_gpio_inout_state_t enumeration is used to specify the output state of
|
||||
an INOUT GPIO port as an argument to the MSS_GPIO_drive_inout() function.
|
||||
*/
|
||||
typedef enum mss_gpio_inout_state
|
||||
{
|
||||
MSS_GPIO_DRIVE_LOW = 0,
|
||||
MSS_GPIO_DRIVE_HIGH,
|
||||
MSS_GPIO_HIGH_Z
|
||||
} mss_gpio_inout_state_t;
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_GPIO_init() function initializes the SmartFusion2 MSS GPIO block. It
|
||||
resets the MSS GPIO hardware block and it also clears any pending MSS GPIO
|
||||
interrupts in the ARM Cortex-M3 interrupt controller. When the function exits,
|
||||
it takes the MSS GPIO block out of reset.
|
||||
|
||||
@param
|
||||
This function has no parameters.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
*/
|
||||
void MSS_GPIO_init( void );
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_GPIO_config() function is used to configure an individual GPIO port.
|
||||
|
||||
@param port_id
|
||||
The port_id parameter identifies the GPIO port to be configured. An
|
||||
enumeration item of the form MSS_GPIO_n, where n is the number of the GPIO
|
||||
port, is used to identify the GPIO port. For example, MSS_GPIO_0 identifies
|
||||
the first GPIO port and MSS_GPIO_31 is the last one.
|
||||
|
||||
@param config
|
||||
The config parameter specifies the configuration to be applied to the GPIO
|
||||
port identified by the port_id parameter. It is a logical OR of the required
|
||||
I/O mode and the required interrupt mode. The interrupt mode is not relevant
|
||||
if the GPIO is configured as an output only.
|
||||
These I/O mode constants are allowed:
|
||||
- MSS_GPIO_INPUT_MODE
|
||||
- MSS_GPIO_OUTPUT_MODE
|
||||
- MSS_GPIO_INOUT_MODE
|
||||
These interrupt mode constants are allowed:
|
||||
- MSS_GPIO_IRQ_LEVEL_HIGH
|
||||
- MSS_GPIO_IRQ_LEVEL_LOW
|
||||
- MSS_GPIO_IRQ_EDGE_POSITIVE
|
||||
- MSS_GPIO_IRQ_EDGE_NEGATIVE
|
||||
- MSS_GPIO_IRQ_EDGE_BOTH
|
||||
|
||||
@return
|
||||
none.
|
||||
|
||||
Example:
|
||||
The following call will configure GPIO 4 as an input generating interrupts on
|
||||
a Low to High transition of the input:
|
||||
@code
|
||||
MSS_GPIO_config( MSS_GPIO_4, MSS_GPIO_INPUT_MODE | MSS_GPIO_IRQ_EDGE_POSITIVE );
|
||||
@endcode
|
||||
*/
|
||||
void MSS_GPIO_config
|
||||
(
|
||||
mss_gpio_id_t port_id,
|
||||
uint32_t config
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_GPIO_set_outputs() function is used to set the state of all GPIO ports
|
||||
configured as outputs.
|
||||
|
||||
@param value
|
||||
The value parameter specifies the state of the GPIO ports configured as
|
||||
outputs. It is a bit mask of the form (MSS_GPIO_n_MASK | MSS_GPIO_m_MASK)
|
||||
where n and m are numbers identifying GPIOs. For example, (MSS_GPIO_0_MASK |
|
||||
MSS_GPIO_1_MASK | MSS_GPIO_2_MASK ) specifies that the first, second and
|
||||
third GPIO outputs must be set High and all other GPIO outputs set Low. The
|
||||
driver provides 32 mask constants, MSS_GPIO_0_MASK to MSS_GPIO_31_MASK
|
||||
inclusive, for this purpose.
|
||||
|
||||
@return
|
||||
none.
|
||||
|
||||
Example 1:
|
||||
Set GPIOs outputs 0 and 8 high and all other GPIO outputs low.
|
||||
@code
|
||||
MSS_GPIO_set_outputs( MSS_GPIO_0_MASK | MSS_GPIO_8_MASK );
|
||||
@endcode
|
||||
|
||||
Example 2:
|
||||
Set GPIOs outputs 2 and 4 low without affecting other GPIO outputs.
|
||||
@code
|
||||
uint32_t gpio_outputs;
|
||||
gpio_outputs = MSS_GPIO_get_outputs();
|
||||
gpio_outputs &= ~( MSS_GPIO_2_MASK | MSS_GPIO_4_MASK );
|
||||
MSS_GPIO_set_outputs( gpio_outputs );
|
||||
@endcode
|
||||
|
||||
@see MSS_GPIO_get_outputs()
|
||||
*/
|
||||
static __INLINE void
|
||||
MSS_GPIO_set_outputs
|
||||
(
|
||||
uint32_t value
|
||||
)
|
||||
{
|
||||
GPIO->GPIO_OUT = value;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_GPIO_set_output() function is used to set the state of a single GPIO
|
||||
port configured as an output.
|
||||
Note: Using bit-band writes might be a better option than this function for
|
||||
performance critical applications where the application code is not
|
||||
intended to be ported to a processor other than the ARM Cortex-M3 in
|
||||
SmartFusion2. The bit-band write equivalent to this function would be:
|
||||
GPIO_BITBAND->GPIO_OUT[port_id] = (uint32_t)value;
|
||||
|
||||
@param port_id
|
||||
The port_id parameter identifies the GPIO port that is to have its output
|
||||
set. An enumeration item of the form MSS_GPIO_n, where n is the number of
|
||||
the GPIO port, is used to identify the GPIO port. For example, MSS_GPIO_0
|
||||
identifies the first GPIO port and MSS_GPIO_31 is the last one.
|
||||
|
||||
@param value
|
||||
The value parameter specifies the desired state for the GPIO output. A value
|
||||
of 0 will set the output Low and a value of 1 will set the output High.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
|
||||
Example:
|
||||
The following call will set GPIO output 12 High, leaving all other GPIO
|
||||
outputs unaffected:
|
||||
@code
|
||||
_GPIO_set_output(MSS_GPIO_12, 1);
|
||||
@endcode
|
||||
*/
|
||||
void MSS_GPIO_set_output
|
||||
(
|
||||
mss_gpio_id_t port_id,
|
||||
uint8_t value
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_GPIO_get_inputs() function is used to read the current state all GPIO
|
||||
ports configured as inputs.
|
||||
|
||||
@return
|
||||
This function returns a 32-bit unsigned integer where each bit represents
|
||||
the state of a GPIO input. The least significant bit represents the state of
|
||||
GPIO input 0 and the most significant bit the state of GPIO input 31.
|
||||
|
||||
Example:
|
||||
Read and assign the current state of the GPIO outputs to a variable.
|
||||
@code
|
||||
uint32_t gpio_inputs;
|
||||
gpio_inputs = MSS_GPIO_get_inputs();
|
||||
@endcode
|
||||
*/
|
||||
static __INLINE uint32_t
|
||||
MSS_GPIO_get_inputs( void )
|
||||
{
|
||||
return GPIO->GPIO_IN;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_GPIO_get_outputs() function is used to read the current state all GPIO
|
||||
ports configured as outputs.
|
||||
|
||||
@return
|
||||
This function returns a 32-bit unsigned integer where each bit represents
|
||||
the state of a GPIO output. The least significant bit represents the state
|
||||
of GPIO output 0 and the most significant bit the state of GPIO output 31.
|
||||
|
||||
Example:
|
||||
Read and assign the current state of the GPIO outputs to a variable.
|
||||
@code
|
||||
uint32_t gpio_outputs;
|
||||
gpio_outputs = MSS_GPIO_get_outputs();
|
||||
@endcode
|
||||
*/
|
||||
static __INLINE uint32_t
|
||||
MSS_GPIO_get_outputs( void )
|
||||
{
|
||||
return GPIO->GPIO_OUT;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_GPIO_drive_inout() function is used to set the output state of a
|
||||
single GPIO port configured as an INOUT. An INOUT GPIO can be in one of three
|
||||
states:
|
||||
- High
|
||||
- Low
|
||||
- High impedance
|
||||
An INOUT output would typically be used where several devices can drive the
|
||||
state of a shared signal line. The High and Low states are equivalent to the
|
||||
High and Low states of a GPIO configured as an output. The High impedance
|
||||
state is used to prevent the GPIO from driving its output state onto the
|
||||
signal line, while at the same time allowing the input state of the GPIO to
|
||||
be read.
|
||||
|
||||
@param port_id
|
||||
The port_id parameter identifies the GPIO port for which you want to change
|
||||
the output state. An enumeration item of the form MSS_GPIO_n, where n is the
|
||||
number of the GPIO port, is used to identify the GPIO port. For example,
|
||||
MSS_GPIO_0 identifies the first GPIO port and MSS_GPIO_31 is the last one.
|
||||
|
||||
@param inout_state
|
||||
The inout_state parameter specifies the state of the GPIO port identified by
|
||||
the port_id parameter. Allowed values of type mss_gpio_inout_state_t are as
|
||||
follows:
|
||||
- MSS_GPIO_DRIVE_HIGH
|
||||
- MSS_GPIO_DRIVE_LOW
|
||||
- MSS_GPIO_HIGH_Z (High impedance)
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
|
||||
Example:
|
||||
The call to MSS_GPIO_drive_inout() below will set the GPIO 7 output to the
|
||||
high impedance state.
|
||||
@code
|
||||
MSS_GPIO_drive_inout( MSS_GPIO_7, MSS_GPIO_HIGH_Z );
|
||||
@endcode
|
||||
*/
|
||||
void MSS_GPIO_drive_inout
|
||||
(
|
||||
mss_gpio_id_t port_id,
|
||||
mss_gpio_inout_state_t inout_state
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_GPIO_enable_irq() function is used to enable interrupt generation for
|
||||
the specified GPIO input. Interrupts are generated based on the state of the
|
||||
GPIO input and the interrupt mode configured for it by MSS_GPIO_config().
|
||||
|
||||
@param port_id
|
||||
The port_id parameter identifies the GPIO port for which you want to enable
|
||||
interrupt generation. An enumeration item of the form MSS_GPIO_n, where n is
|
||||
the number of the GPIO port, is used to identify the GPIO port. For example,
|
||||
MSS_GPIO_0 identifies the first GPIO port and MSS_GPIO_31 is the last one.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
|
||||
Example:
|
||||
The call to MSS_GPIO_enable_irq() below will allow GPIO 8 to generate
|
||||
interrupts.
|
||||
@code
|
||||
MSS_GPIO_enable_irq( MSS_GPIO_8 );
|
||||
@endcode
|
||||
*/
|
||||
void MSS_GPIO_enable_irq
|
||||
(
|
||||
mss_gpio_id_t port_id
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_GPIO_disable_irq() function is used to disable interrupt generation
|
||||
for the specified GPIO input.
|
||||
|
||||
@param port_id
|
||||
The port_id parameter identifies the GPIO port for which you want to disable
|
||||
interrupt generation. An enumeration item of the form MSS_GPIO_n, where n is
|
||||
the number of the GPIO port, is used to identify the GPIO port. For example,
|
||||
MSS_GPIO_0 identifies the first GPIO port and MSS_GPIO_31 is the last one.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
|
||||
Example:
|
||||
The call to MSS_GPIO_disable_irq() below will prevent GPIO 8 from generating
|
||||
interrupts.
|
||||
@code
|
||||
MSS_GPIO_disable_irq( MSS_GPIO_8 );
|
||||
@endcode
|
||||
*/
|
||||
void MSS_GPIO_disable_irq
|
||||
(
|
||||
mss_gpio_id_t port_id
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_GPIO_clear_irq() function is used to clear a pending interrupt from
|
||||
the specified GPIO input.
|
||||
Note: The MSS_GPIO_clear_irq() function must be called as part of any GPIO
|
||||
interrupt service routine (ISR) in order to prevent the same interrupt
|
||||
event retriggering a call to the GPIO ISR.
|
||||
|
||||
@param port_id
|
||||
The port_id parameter identifies the GPIO port for which you want to clear
|
||||
the interrupt. An enumeration item of the form MSS_GPIO_n, where n is the
|
||||
number of the GPIO port, is used to identify the GPIO port. For example,
|
||||
MSS_GPIO_0 identifies the first GPIO port and MSS_GPIO_31 is the last one.
|
||||
|
||||
@return
|
||||
none.
|
||||
|
||||
Example:
|
||||
The example below demonstrates the use of the MSS_GPIO_clear_irq() function
|
||||
as part of the GPIO 9 interrupt service routine.
|
||||
@code
|
||||
void GPIO9_IRQHandler( void )
|
||||
{
|
||||
do_interrupt_processing();
|
||||
|
||||
MSS_GPIO_clear_irq( MSS_GPIO_9 );
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
void MSS_GPIO_clear_irq
|
||||
(
|
||||
mss_gpio_id_t port_id
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MSS_GPIO_H_ */
|
|
@ -0,0 +1,344 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2010-2013 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* SmartFusion2 MSS HPDMA bare metal driver implementation.
|
||||
*
|
||||
* SVN $Revision: 5148 $
|
||||
* SVN $Date: 2013-02-27 16:42:01 +0000 (Wed, 27 Feb 2013) $
|
||||
*/
|
||||
#include "mss_hpdma.h"
|
||||
|
||||
/*==============================================================================
|
||||
* Design Notes
|
||||
*------------------------------------------------------------------------------
|
||||
This SmartFusion2 MSS HPDMA driver only makes use of the first HPDMA
|
||||
descriptor. The rationale for this choice is that the pause and clear bits of
|
||||
each individual descriptor have undocumented side effects to the other
|
||||
descriptors in the HPDMA hardware block. This prevents independent operations
|
||||
of the descriptors in particular when it comes to error handling where error
|
||||
recovery requires clearing a descriptor. An error on one descriptor would
|
||||
result in aborting transfers on the other descriptors. Likewise, it is not
|
||||
possible to pause individual descriptors. Setting the pause bit in one
|
||||
descriptor results in all descriptors being paused.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* Constants
|
||||
*/
|
||||
#define HPDMA_ENABLE 1u
|
||||
#define HPDMA_DISABLE 0u
|
||||
#define NULL_HANDLER ((mss_hpdma_handler_t)0)
|
||||
|
||||
/* 64 K DMA Transfer */
|
||||
#define MAX_SIZE_PER_DMA_XFR 0x10000u
|
||||
|
||||
#define DESC0 0u
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* Mask Constants
|
||||
*/
|
||||
#define HPDMA_SOFT_RESET 0x00020000u
|
||||
#define HPDMA_XFR_SIZE_MASK 0xFFFF0000u
|
||||
|
||||
#define HPDMACR_XFR_CMP_INT_MASK 0x00100000u
|
||||
#define HPDMACR_XFR_ERR_INT_MASK 0x00200000u
|
||||
#define HPDMACR_NON_WORD_INT_MASK 0x00400000u
|
||||
|
||||
#define HPDMACR_ALL_IRQ_ENABLE_MASK (HPDMACR_XFR_CMP_INT_MASK | HPDMACR_XFR_ERR_INT_MASK | HPDMACR_NON_WORD_INT_MASK)
|
||||
|
||||
#define HPDMAICR_CLEAR_ALL_IRQ 0x000000FFu
|
||||
|
||||
#define HPDMAEDR_DCP_ERR_MASK 0x00000100u
|
||||
|
||||
#define HPDMAEDR_NON_WORD_ERR_MASK 0x00001000u
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
Current transfer state information.
|
||||
*/
|
||||
typedef struct hpdma_xfer_info
|
||||
{
|
||||
hpdma_status_t state;
|
||||
mss_hpdma_handler_t completion_handler;
|
||||
uint32_t src_addr;
|
||||
uint32_t des_addr;
|
||||
uint32_t xfr_size;
|
||||
uint8_t xfr_dir;
|
||||
} hpdma_xfer_info_t;
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
Current transfer state information.
|
||||
*/
|
||||
static hpdma_xfer_info_t g_transfer;
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
Interrupt service routines function prototypes.
|
||||
The name of these interrupt service routines must match the name of the ISRs
|
||||
defined in startup_m2sxxx.s distributed as part of the SmartFusion2 CMSIS.
|
||||
*/
|
||||
#if defined(__GNUC__)
|
||||
__attribute__((__interrupt__)) void HPDMA_Complete_IRQHandler(void);
|
||||
#else
|
||||
void HPDMA_Complete_IRQHandler(void);
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
__attribute__((__interrupt__)) void HPDMA_Error_IRQHandler(void);
|
||||
#else
|
||||
void HPDMA_Error_IRQHandler(void);
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* See "mss_hpdma.h" for details of how to use this function.
|
||||
*/
|
||||
void
|
||||
MSS_HPDMA_init
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
/* Reset HPDMA block. */
|
||||
SYSREG->SOFT_RST_CR |= HPDMA_SOFT_RESET;
|
||||
|
||||
/* Take HPDMA controller out of reset. */
|
||||
SYSREG->SOFT_RST_CR &= ~HPDMA_SOFT_RESET;
|
||||
|
||||
/* Initialize data structures. */
|
||||
g_transfer.xfr_size = 0u;
|
||||
g_transfer.completion_handler = NULL_HANDLER;
|
||||
g_transfer.state = HPDMA_COMPLETED;
|
||||
|
||||
/* Disable Interrupt. */
|
||||
HPDMA->Descriptor[DESC0].HPDMACR_REG &= ~HPDMACR_ALL_IRQ_ENABLE_MASK;
|
||||
|
||||
/* Clear any previously pended MSS HPDMA interrupt. */
|
||||
NVIC_ClearPendingIRQ(HPDMA_Error_IRQn);
|
||||
NVIC_ClearPendingIRQ(HPDMA_Complete_IRQn);
|
||||
|
||||
/* Clear all interrupts. */
|
||||
HPDMA->HPDMAICR_REG = HPDMAICR_CLEAR_ALL_IRQ;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* See "mss_hpdma.h" for details of how to use this function.
|
||||
*/
|
||||
void
|
||||
MSS_HPDMA_start
|
||||
(
|
||||
uint32_t src_addr,
|
||||
uint32_t dest_addr,
|
||||
uint32_t transfer_size,
|
||||
uint8_t transfer_dir
|
||||
)
|
||||
{
|
||||
/* Pause transfer. */
|
||||
HPDMA_BITBAND->Descriptor[DESC0].HPDMACR_DCP_PAUSE = HPDMA_ENABLE;
|
||||
|
||||
/*
|
||||
* Disable all interrupts for the current descriptor. Treat this function as a
|
||||
* critical section. Pausing the descriptor transfer is not sufficient in case
|
||||
* of non-aligned errors.
|
||||
*/
|
||||
HPDMA->Descriptor[DESC0].HPDMACR_REG &= ~HPDMACR_ALL_IRQ_ENABLE_MASK;
|
||||
|
||||
/* Set descriptor transfer direction */
|
||||
HPDMA_BITBAND->Descriptor[DESC0].HPDMACR_DCP_XFR_DIR = transfer_dir;
|
||||
|
||||
/* Store Source and destination Address */
|
||||
HPDMA->Descriptor[DESC0].HPDMASAR_REG = src_addr;
|
||||
HPDMA->Descriptor[DESC0].HPDMADAR_REG = dest_addr;
|
||||
|
||||
/* Set the transfer size to 64K */
|
||||
HPDMA->Descriptor[DESC0].HPDMACR_REG &= HPDMA_XFR_SIZE_MASK;
|
||||
|
||||
g_transfer.state = HPDMA_IN_PROGRESS;
|
||||
if(transfer_size <= MAX_SIZE_PER_DMA_XFR)
|
||||
{
|
||||
/* Set descriptor transfer size */
|
||||
HPDMA->Descriptor[DESC0].HPDMACR_REG |= (uint16_t)transfer_size;
|
||||
g_transfer.xfr_size = 0u;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_transfer.xfr_size = transfer_size - MAX_SIZE_PER_DMA_XFR;
|
||||
g_transfer.des_addr = dest_addr + MAX_SIZE_PER_DMA_XFR;
|
||||
g_transfer.src_addr = src_addr + MAX_SIZE_PER_DMA_XFR;
|
||||
g_transfer.xfr_dir = transfer_dir;
|
||||
}
|
||||
|
||||
/* Enable interrupts for the requested descriptor. */
|
||||
HPDMA->Descriptor[DESC0].HPDMACR_REG |= HPDMACR_ALL_IRQ_ENABLE_MASK;
|
||||
NVIC_EnableIRQ(HPDMA_Complete_IRQn);
|
||||
NVIC_EnableIRQ(HPDMA_Error_IRQn);
|
||||
|
||||
/* Set valid descriptor to start transfer */
|
||||
HPDMA_BITBAND->Descriptor[DESC0].HPDMACR_DCP_VALID = HPDMA_ENABLE;
|
||||
|
||||
/* Start transfer */
|
||||
HPDMA_BITBAND->Descriptor[DESC0].HPDMACR_DCP_PAUSE = HPDMA_DISABLE;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* See "mss_hpdma.h" for details of how to use this function.
|
||||
*/
|
||||
void
|
||||
MSS_HPDMA_pause
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
/* Pause transfer */
|
||||
HPDMA_BITBAND->Descriptor[DESC0].HPDMACR_DCP_PAUSE = HPDMA_ENABLE;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* See "mss_hpdma.h" for details of how to use this function.
|
||||
*/
|
||||
void
|
||||
MSS_HPDMA_resume
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
/* Resume transfer */
|
||||
HPDMA_BITBAND->Descriptor[DESC0].HPDMACR_DCP_PAUSE = HPDMA_DISABLE;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* See "mss_hpdma.h" for details of how to use this function.
|
||||
*/
|
||||
void
|
||||
MSS_HPDMA_abort
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
HPDMA_BITBAND->Descriptor[DESC0].HPDMACR_DCP_CLR = HPDMA_ENABLE;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* See "mss_hpdma.h" for details of how to use this function.
|
||||
*/
|
||||
hpdma_status_t
|
||||
MSS_HPDMA_get_transfer_status
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
return g_transfer.state;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* See "mss_hpdma.h" for details of how to use this function.
|
||||
*/
|
||||
void MSS_HPDMA_set_handler
|
||||
(
|
||||
mss_hpdma_handler_t handler
|
||||
)
|
||||
{
|
||||
if(handler == NULL_HANDLER)
|
||||
{
|
||||
g_transfer.completion_handler = NULL_HANDLER;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_transfer.completion_handler = handler;
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
HPDMA Transfer complete service routine.
|
||||
This function will be called as a result of any descriptor transfer
|
||||
is completed by HPDMA controller .
|
||||
*/
|
||||
#if defined(__GNUC__)
|
||||
__attribute__((__interrupt__)) void HPDMA_Complete_IRQHandler(void)
|
||||
#else
|
||||
void HPDMA_Complete_IRQHandler(void)
|
||||
#endif
|
||||
{
|
||||
/* Clear interrupt */
|
||||
HPDMA_BITBAND->HPDMAICR_CLR_XFR_INT[DESC0] = HPDMA_ENABLE;
|
||||
|
||||
if(g_transfer.xfr_size > 0u)
|
||||
{
|
||||
MSS_HPDMA_start(g_transfer.src_addr,
|
||||
g_transfer.des_addr,
|
||||
g_transfer.xfr_size,
|
||||
g_transfer.xfr_dir);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_transfer.state = HPDMA_COMPLETED;
|
||||
if(g_transfer.completion_handler != NULL_HANDLER)
|
||||
{
|
||||
(*(g_transfer.completion_handler))(HPDMA_COMPLETED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
HPDMA Transfer Error service routine.
|
||||
This function will be called as a result of any descriptor transfer
|
||||
has an error condition or it there is non word transfer size error.
|
||||
*/
|
||||
#if defined(__GNUC__)
|
||||
__attribute__((__interrupt__)) void HPDMA_Error_IRQHandler(void)
|
||||
#else
|
||||
void HPDMA_Error_IRQHandler(void)
|
||||
#endif
|
||||
{
|
||||
uint32_t error_bits;
|
||||
|
||||
/*
|
||||
* Handle source/destination errors.
|
||||
*/
|
||||
error_bits = HPDMA->HPDMAEDR_REG & HPDMAEDR_DCP_ERR_MASK;
|
||||
if(error_bits != 0u)
|
||||
{
|
||||
if(g_transfer.completion_handler != NULL_HANDLER)
|
||||
{
|
||||
if(HPDMA_BITBAND->Descriptor[DESC0].HPDMASR_DCP_SERR)
|
||||
{
|
||||
g_transfer.state = HPDMA_SOURCE_ERROR;
|
||||
(*(g_transfer.completion_handler))(HPDMA_SOURCE_ERROR);
|
||||
}
|
||||
|
||||
if(HPDMA_BITBAND->Descriptor[DESC0].HPDMASR_DCP_DERR)
|
||||
{
|
||||
g_transfer.state = HPDMA_DESTINATION_ERROR;
|
||||
(*(g_transfer.completion_handler))(HPDMA_DESTINATION_ERROR);
|
||||
}
|
||||
}
|
||||
/* Abort transfer. */
|
||||
HPDMA_BITBAND->Descriptor[DESC0].HPDMACR_DCP_CLR = HPDMA_ENABLE;
|
||||
/* Clear interrupt. */
|
||||
HPDMA_BITBAND->HPDMAICR_CLR_XFR_INT[DESC0] = HPDMA_ENABLE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle non word aligned errors.
|
||||
*/
|
||||
error_bits = HPDMA->HPDMAEDR_REG & HPDMAEDR_NON_WORD_ERR_MASK;
|
||||
if(error_bits != 0u)
|
||||
{
|
||||
g_transfer.state = HPDMA_WORD_ALIGN_ERROR;
|
||||
/* Call handler. */
|
||||
if(g_transfer.completion_handler != NULL_HANDLER)
|
||||
{
|
||||
(*(g_transfer.completion_handler))(HPDMA_WORD_ALIGN_ERROR);
|
||||
}
|
||||
/* Abort transfer. */
|
||||
HPDMA_BITBAND->Descriptor[DESC0].HPDMACR_DCP_CLR = HPDMA_ENABLE;
|
||||
/* Clear interrupt. */
|
||||
HPDMA_BITBAND->HPDMAICR_NON_WORD_INT[DESC0] = HPDMA_ENABLE;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,361 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2010-2013 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* SmartFusion2 MSS HPDMA bare metal software driver public API.
|
||||
*
|
||||
* SVN $Revision: 5583 $
|
||||
* SVN $Date: 2013-04-04 12:29:18 +0100 (Thu, 04 Apr 2013) $
|
||||
*/
|
||||
|
||||
/*=========================================================================*//**
|
||||
@mainpage SmartFusion2 MSS HPDMA Bare Metal Driver.
|
||||
|
||||
@section intro_sec Introduction
|
||||
The SmartFusion2 Microcontroller Subsystem (MSS) includes a High Performance
|
||||
Direct Memory Access (HPDMA) controller which performs fast data transfer
|
||||
between any MSS memory connected to the AHB bus matrix and MSS DDR-Bridge
|
||||
memory. This software driver provides a set of functions for controlling the
|
||||
MSS HPDMA as part of a bare metal system where no operating system is
|
||||
available. The driver can be adapted for use as part of an operating system
|
||||
but the implementation of the adaptation layer between the driver and the
|
||||
operating system's driver model is outside the scope of the driver.
|
||||
|
||||
@section hw_dependencies Hardware Flow Dependencies
|
||||
The configuration of all features of the MSS HPDMA is covered by this driver.
|
||||
There are no dependencies on the hardware flow when configuring the MSS HPDMA.
|
||||
The base address, register addresses and interrupt number assignment for the
|
||||
MSS HPDMA blocks are defined as constants in the SmartFusion2 CMSIS HAL. You
|
||||
must ensure that the latest SmartFusion2 CMSIS HAL is included in the project
|
||||
settings of the software tool chain used to build your project and that it is
|
||||
generated into your project.
|
||||
|
||||
@section theory_op Theory of Operation
|
||||
The MSS HPDMA driver functions are grouped into the following categories:
|
||||
- Initialization of the MSS HPDMA driver and hardware
|
||||
- Data transfer control
|
||||
- Data transfer status
|
||||
- Interrupt handling
|
||||
|
||||
Initialization
|
||||
The MSS HPDMA driver is initialized through a call to the MSS_HPDMA_init()
|
||||
function. The MSS_HPDMA_init() function must be called before any other MSS
|
||||
HPDMA driver functions can be called.
|
||||
|
||||
Data Transfer Control
|
||||
The driver provides the following functions to control HPDMA data transfers:
|
||||
- MSS_HPDMA_start() – This function starts a HPDMA data transfer. You must
|
||||
provide the source and destination addresses along
|
||||
with transfer size and transfer direction.
|
||||
- MSS_HPDMA_pause() – This function pauses the HPDMA transfer that is
|
||||
currently in progress.
|
||||
- MSS_HPDMA_resume() – This function resumes a HPDMA transfer that was
|
||||
previously paused.
|
||||
- MSS_HPDMA_abort() – This function aborts the HPDMA transfer that is
|
||||
currently in progress.
|
||||
|
||||
Data Transfer Status
|
||||
The status of the HPDMA transfer initiated by the last call to
|
||||
MSS_HPDMA_start() can be retrieved using the MSS_HPDMA_get_transfer_status()
|
||||
function.
|
||||
|
||||
Interrupt Handling
|
||||
The MSS_HPDMA_set_handler() function is used to register a handler function
|
||||
that will be called by the driver when the HPDMA transfer completes. You must
|
||||
create and register a transfer completion handler function to suit your
|
||||
application.
|
||||
|
||||
*//*=========================================================================*/
|
||||
#ifndef MSS_HPDMA_H_
|
||||
#define MSS_HPDMA_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../../CMSIS/m2sxxx.h"
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The HPDMA_TO_DDR constant is used to specify the data transfer direction. It
|
||||
indicates a transfer from memory connected to the AHB bus matrix to MSS
|
||||
DDR-Bridge memory. It is used as a parameter by the MSS_HPDMA_start()
|
||||
function.
|
||||
*/
|
||||
#define HPDMA_TO_DDR 0u
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The HPDMA_FROM_DDR constant is used to specify the data transfer direction. It
|
||||
indicates a transter from MSS DDR-Bridge memory to memory connected to the AHB
|
||||
bus matrix. It is used as a parameter by the MSS_HPDMA_start() function.
|
||||
*/
|
||||
#define HPDMA_FROM_DDR 1u
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The hpdma_status_t type is used to communicate the status of the HPDMA
|
||||
transfer initiated by the most recent call to HPDMA_start(). It indicates if
|
||||
a transfer is still currently in progress or the outcome of the latest
|
||||
transfer. This type is returned by the MSS_HPDMA_get_transfer_status()
|
||||
function and used as parameter to handler functions registered with the MSS
|
||||
HPDMA driver by the application.
|
||||
|
||||
- HPDMA_IN_PROGRESS - A HPDMA transfer is taking place.
|
||||
- HPDMA_COMPLETED - The most recent HPDMA transfer initiated by a call
|
||||
to HPDMA_start() has completed successfully.
|
||||
- HPDMA_SOURCE_ERROR - The most recent HPDMA transfer failed because of a
|
||||
problem with the source address passed to
|
||||
HPDMA_start().
|
||||
- HPDMA_DESTINATION_ERROR - The most recent HPDMA transfer failed because of a
|
||||
problem with the destination address passed to
|
||||
HPDMA_start().
|
||||
- HPDMA_WORD_ALIGN_ERROR - The most recent HPDMA transfer failed because the
|
||||
transfer size was not word aligned. This means
|
||||
that the transfer size passed to HPDMA_start() was
|
||||
not a multiple of four.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
HPDMA_IN_PROGRESS,
|
||||
HPDMA_COMPLETED,
|
||||
HPDMA_SOURCE_ERROR,
|
||||
HPDMA_DESTINATION_ERROR,
|
||||
HPDMA_WORD_ALIGN_ERROR
|
||||
} hpdma_status_t;
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
This type definition specifies the prototype of a function that can be
|
||||
registered with this driver as a HPDMA transfer completion handler function
|
||||
through a call to MSS_HPDMA_set_handler(). The HPDMA transfer completion
|
||||
handler will be called by the driver when a HPDMA transfer completes. The MSS
|
||||
HPDMA driver passes the outcome of the transfer to the completion handler in
|
||||
the form of a hpdma_status_t parameter indicating if the transfer was
|
||||
successful or the type of error that occurred during the transfer.
|
||||
*/
|
||||
typedef void (*mss_hpdma_handler_t)(hpdma_status_t status);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_HPDMA_init() function initializes the MSS HPDMA driver. It resets the
|
||||
HPDMA controller. It clears all pending HPDMA interrupts. It initializes
|
||||
internal data structures used by the MSS HPDMA driver. It disables interrupts
|
||||
related to HPDMA data transfers.
|
||||
|
||||
@param
|
||||
This function has no parameters.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
*/
|
||||
void
|
||||
MSS_HPDMA_init
|
||||
(
|
||||
void
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_HPDMA_start() function starts a HPDMA data transfer. Its parameters
|
||||
specify the source and destination addresses of the transfer as well as its
|
||||
size and direction. HPDMA data transfers always use DDR memory as the source
|
||||
or destination of the transfer. The HPDMA controller transfers data in 32-bit
|
||||
chunks located on 32-bit word aligned address boundaries.
|
||||
|
||||
@param src_addr
|
||||
The parameter src_addr is the address of the data that will be transferred
|
||||
by the HPDMA. This address must be 32-bit word aligned. The memory location
|
||||
specified by this address must be located in DDR memory if the transfer_dir
|
||||
parameter is set to HPDM_FROM_DDR.
|
||||
|
||||
@param dest_addr
|
||||
The parameter dest_addr is the address of the location at which the data
|
||||
will be transferred. This address must be 32-bit word aligned. The memory
|
||||
location specified by this address must be located in DDR memory if the
|
||||
transfer_dir parameter is set to HPDM_TO_DDR.
|
||||
|
||||
@param transfer_size
|
||||
The parameter transfer_size specifies the size in bytes of the requested
|
||||
transfer. The value of transfer_size must be a multiple of four.
|
||||
|
||||
@param transfer_dir
|
||||
The parameter transfer_dir is used for specifying the data transfer
|
||||
direction. Allowed values for transfer_dir are as follows:
|
||||
- HPDMA_TO_DDR
|
||||
- HPDMA_FROM_DDR
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
*/
|
||||
void
|
||||
MSS_HPDMA_start
|
||||
(
|
||||
uint32_t src_addr,
|
||||
uint32_t dest_addr,
|
||||
uint32_t transfer_size,
|
||||
uint8_t transfer_dir
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_HPDMA_pause() function pauses the current HPDMA transfer. The HPDMA
|
||||
transfer can be resumed later by calling MSS_HPDMA_resume().
|
||||
|
||||
@param
|
||||
This function has no parameters.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
*/
|
||||
void
|
||||
MSS_HPDMA_pause
|
||||
(
|
||||
void
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_HPDMA_pause() function resumes the current HPDMA transfer after it was
|
||||
previously paused through a call to MSS_HPDMA_pause().
|
||||
|
||||
@param
|
||||
This function has no parameters.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
*/
|
||||
void
|
||||
MSS_HPDMA_resume
|
||||
(
|
||||
void
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_HPDMA_abort() function aborts the current HPDMA transfer.
|
||||
|
||||
@param
|
||||
This function has no parameters.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
*/
|
||||
void
|
||||
MSS_HPDMA_abort
|
||||
(
|
||||
void
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_HPDMA_get_transfer_status() function returns the status of the HPDMA
|
||||
transfer initiated by a call to MSS_HPDMA_start().
|
||||
|
||||
@param
|
||||
This function has no parameters.
|
||||
|
||||
@return
|
||||
The MSS_HPDMA_get_transfer_status() function returns the status of the HPDMA
|
||||
transfer as a value of type hpdma_status_t. The possible return values are:
|
||||
- HPDMA_IN_PROGRESS
|
||||
- HPDMA_COMPLETED
|
||||
- HPDMA_SOURCE_ERROR
|
||||
- HPDMA_DESTINATION_ERROR
|
||||
- HPDMA_WORD_ALIGN_ERROR
|
||||
|
||||
The example code below demonstrates the use of the
|
||||
MSS_HPDMA_get_transfer_status() function to detect the completion of the
|
||||
transfer of the content of eNVM into MDDR memory.
|
||||
@code
|
||||
void copy_envm_to_mddr(void)
|
||||
{
|
||||
MSS_HPDMA_start(ENVM_BASE_ADDR,
|
||||
MDDR_BASE_ADDR,
|
||||
ENVM_SIZE_BYTE,
|
||||
HPDMA_TO_DDR);
|
||||
|
||||
do {
|
||||
xfer_state = MSS_HPDMA_get_transfer_status();
|
||||
} while(HPDMA_IN_PROGRESS == xfer_state);
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
hpdma_status_t
|
||||
MSS_HPDMA_get_transfer_status
|
||||
(
|
||||
void
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_HPDMA_set_handler() function is used to register a handler function
|
||||
that will be called by the driver when the HPDMA transfer completes. You must
|
||||
create and register a transfer completion handler function to suit your
|
||||
application. The MSS HPDMA driver passes the outcome of the transfer to the
|
||||
completion handler in the form of a hpdma_status_t parameter indicating if the
|
||||
transfer was successful or the type of error that occurred during the transfer
|
||||
if the transfer failed.
|
||||
|
||||
@param handler
|
||||
The handler parameter is a pointer to a handler function provided by your
|
||||
application. This handler is of type mss_hpdma_handler_t. The handler
|
||||
function must take one parameter of type hpdma_status_t and must not return
|
||||
a value.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
|
||||
This example code demonstrates the use of the MSS_HPDMA_set_handler()
|
||||
function:
|
||||
@code
|
||||
void transfer_complete_handler(hpdma_status_t status);
|
||||
|
||||
volatile uint32_t g_xfer_in_progress = 0;
|
||||
|
||||
void demo_transfer(void)
|
||||
{
|
||||
MSS_HPDMA_init();
|
||||
|
||||
MSS_HPDMA_set_handler(transfer_complete_handler);
|
||||
|
||||
g_xfer_in_progress = 1;
|
||||
MSS_HPDMA_start((uint32_t)0x20000000,
|
||||
(uint32_t)0x00000000,
|
||||
20,
|
||||
HPDMA_FROM_DDR);
|
||||
|
||||
while(g_xfer_in_progress)
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
void transfer_complete_handler(hpdma_status_t status)
|
||||
{
|
||||
g_xfer_in_progress = 0;
|
||||
|
||||
switch(status)
|
||||
{
|
||||
case HPDMA_COMPLETED:
|
||||
display("Transfer complete");
|
||||
break;
|
||||
|
||||
case HPDMA_SOURCE_ERROR:
|
||||
display("Transfer failed: source error");
|
||||
break;
|
||||
|
||||
case HPDMA_DESTINATION_ERROR:
|
||||
display("Transfer failed: destination error");
|
||||
break;
|
||||
|
||||
case HPDMA_WORD_ALIGN_ERROR:
|
||||
display("Transfer failed: word alignment error");
|
||||
break;
|
||||
|
||||
default:
|
||||
display("Unexpected status");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
void
|
||||
MSS_HPDMA_set_handler
|
||||
(
|
||||
mss_hpdma_handler_t handler
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MSS_HPDMA_H_ */
|
|
@ -0,0 +1,694 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2011-2013 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* This source file contains SmartFusion2 eNVM driver code.
|
||||
*
|
||||
* SVN $Revision: 5316 $
|
||||
* SVN $Date: 2013-03-24 12:33:15 +0000 (Sun, 24 Mar 2013) $
|
||||
*/
|
||||
|
||||
#include "../../CMSIS/m2sxxx.h"
|
||||
#include "../../CMSIS/mss_assert.h"
|
||||
#include "../../CMSIS/system_m2sxxx.h"
|
||||
#include "mss_nvm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**************************************************************************/
|
||||
/* Preprocessor definitions */
|
||||
/**************************************************************************/
|
||||
/* eNVM command codes */
|
||||
#define PROG_ADS 0x08000000u /* One shot program with data in WD */
|
||||
#define VERIFY_ADS 0x10000000u /* One shot verification with data in WD */
|
||||
#define USER_UNLOCK 0x13000000u /* User unlock */
|
||||
|
||||
#define BITS_PER_PAGE 1024u /* Number of bits per page */
|
||||
#define BYTES_PER_PAGE (BITS_PER_PAGE / 8u) /* Number of bytes per page */
|
||||
|
||||
#define NVM_OFFSET_SIGNIFICANT_BITS 0x0007FFFFu
|
||||
#define NVM1_BOTTOM_OFFSET 0x00040000u
|
||||
#define NVM1_TOP_OFFSET 0x0007FFFFu
|
||||
|
||||
#define NVM_BASE_ADDRESS 0x60000000u
|
||||
|
||||
#define PAGE_ADDR_MASK 0xFFFFFF80u
|
||||
|
||||
#define BLOCK1_FIRST_WORD_OFFSET 0x00010000u
|
||||
|
||||
#define WD_WORD_SIZE 32u
|
||||
|
||||
#define NB_OF_BYTES_IN_A_WORD 4u
|
||||
|
||||
#define WRITE_ERROR_MASK (MSS_NVM_VERIFY_FAIL | \
|
||||
MSS_NVM_EVERIFY_FAIL | \
|
||||
MSS_NVM_WVERIFY_FAIL | \
|
||||
MSS_NVM_PEFAIL_LOCK | \
|
||||
MSS_NVM_WRCNT_OVER | \
|
||||
MSS_NVM_WR_DENIED)
|
||||
|
||||
/*******************************************************************************
|
||||
* Combined status definitions
|
||||
* Below definitions should be used to decoded the bit encoded status returned
|
||||
* by the function MSS_NVM_get_status().
|
||||
*/
|
||||
#define MSS_NVM_BUSY_B (1u) /* NVM is performing an internal operation */
|
||||
#define MSS_NVM_VERIFY_FAIL ((uint32_t)1 << 1u) /* NVM verify operation failed */
|
||||
#define MSS_NVM_EVERIFY_FAIL ((uint32_t)1 << 2u) /* NVM erase verify operation failed */
|
||||
#define MSS_NVM_WVERIFY_FAIL ((uint32_t)1 << 3u) /* NVM write verify operation failed */
|
||||
#define MSS_NVM_PEFAIL_LOCK ((uint32_t)1 << 4u) /* NVM program / erase operation failed due to page lock */
|
||||
#define MSS_NVM_WRCNT_OVER ((uint32_t)1 << 5u) /* NVM write count overflowed */
|
||||
#define MSS_NVM_WR_DENIED ((uint32_t)1 << 18u) /* NVM write is denied due to protection */
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
*/
|
||||
#define NVM_BLOCK_0 0u
|
||||
#define NVM_BLOCK_1 1u
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
*/
|
||||
#define MAX_512K_OFFSET 0x00080000u
|
||||
|
||||
/**************************************************************************/
|
||||
/* Global data definitions */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************//**
|
||||
* Look-up table for NVM blocks.
|
||||
*/
|
||||
static NVM_TypeDef * const g_nvm[] =
|
||||
{
|
||||
ENVM_1 ,
|
||||
ENVM_2
|
||||
};
|
||||
|
||||
static NVM32_TypeDef * const g_nvm32[] =
|
||||
{
|
||||
(NVM32_TypeDef *)ENVM1_BASE ,
|
||||
(NVM32_TypeDef *)ENVM2_BASE
|
||||
};
|
||||
|
||||
/**************************************************************************/
|
||||
/* Private function declarations */
|
||||
/**************************************************************************/
|
||||
static nvm_status_t request_nvm_access
|
||||
(
|
||||
uint32_t nvm_block_id
|
||||
);
|
||||
|
||||
static nvm_status_t get_ctrl_access
|
||||
(
|
||||
uint32_t nvm_offset,
|
||||
uint32_t length
|
||||
);
|
||||
|
||||
static void release_ctrl_access(void);
|
||||
|
||||
static uint32_t get_remaining_page_length
|
||||
(
|
||||
uint32_t offset,
|
||||
uint32_t length
|
||||
);
|
||||
|
||||
static void fill_wd_buffer
|
||||
(
|
||||
const uint8_t * p_data,
|
||||
uint32_t length,
|
||||
uint32_t block,
|
||||
uint32_t offset
|
||||
);
|
||||
|
||||
static uint32_t
|
||||
write_nvm
|
||||
(
|
||||
uint32_t addr,
|
||||
const uint8_t * pidata,
|
||||
uint32_t length,
|
||||
uint32_t lock_page,
|
||||
uint32_t * p_status
|
||||
);
|
||||
|
||||
static uint32_t
|
||||
wait_nvm_ready
|
||||
(
|
||||
uint32_t block
|
||||
);
|
||||
|
||||
static nvm_status_t get_error_code(uint32_t nvm_hw_status);
|
||||
|
||||
/**************************************************************************/
|
||||
/* Public function definitions */
|
||||
/**************************************************************************/
|
||||
|
||||
/**************************************************************************//**
|
||||
* See mss_nvm.h for details of how to use this function.
|
||||
*/
|
||||
nvm_status_t
|
||||
NVM_write
|
||||
(
|
||||
uint32_t start_addr,
|
||||
const uint8_t * pidata,
|
||||
uint32_t length,
|
||||
uint32_t lock_page
|
||||
)
|
||||
{
|
||||
nvm_status_t status;
|
||||
uint32_t nvm_offset;
|
||||
uint32_t device_version;
|
||||
|
||||
/*
|
||||
* Prevent pages being locked for silicon versions which do not allow
|
||||
* locked pages to be unlocked.
|
||||
*/
|
||||
device_version = SYSREG->DEVICE_VERSION;
|
||||
if((0x0000F802u == device_version) || (0x0001F802u == device_version))
|
||||
{
|
||||
lock_page = NVM_DO_NOT_LOCK_PAGE;
|
||||
}
|
||||
|
||||
/* Ignore upper address bits to ignore remapping setting. */
|
||||
nvm_offset = start_addr & NVM_OFFSET_SIGNIFICANT_BITS; /* Ignore remapping. */
|
||||
|
||||
/* Check against attempt to write data larger than eNVM. */
|
||||
ASSERT((nvm_offset + length) < MAX_512K_OFFSET);
|
||||
if((nvm_offset + length) < MAX_512K_OFFSET)
|
||||
{
|
||||
/* Gain exclusive access to eNVM controller */
|
||||
status = get_ctrl_access(nvm_offset, length);
|
||||
|
||||
/* Write eNVM one page at a time. */
|
||||
if(NVM_SUCCESS == status)
|
||||
{
|
||||
uint32_t remaining_length = length;
|
||||
|
||||
while((remaining_length > 0u) && (NVM_SUCCESS == status))
|
||||
{
|
||||
uint32_t length_written;
|
||||
uint32_t nvm_hw_status = 0u;
|
||||
|
||||
length_written = write_nvm(start_addr + (length - remaining_length),
|
||||
&pidata[length - remaining_length],
|
||||
remaining_length,
|
||||
lock_page,
|
||||
&nvm_hw_status);
|
||||
|
||||
if(0u == length_written)
|
||||
{
|
||||
status = get_error_code(nvm_hw_status);
|
||||
}
|
||||
else if(remaining_length > length_written)
|
||||
{
|
||||
remaining_length -= length_written;
|
||||
}
|
||||
else
|
||||
{
|
||||
remaining_length = 0u;
|
||||
}
|
||||
}
|
||||
|
||||
/* Release eNVM controllers so that other masters can gain access to it. */
|
||||
release_ctrl_access();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = NVM_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
Generate error code based on NVM status value.
|
||||
|
||||
The hardware nvm status passed as parameter is expected to be masked using the
|
||||
following mask:
|
||||
(MSS_NVM_VERIFY_FAIL | \
|
||||
MSS_NVM_EVERIFY_FAIL | \
|
||||
MSS_NVM_WVERIFY_FAIL | \
|
||||
MSS_NVM_PEFAIL_LOCK | \
|
||||
MSS_NVM_WRCNT_OVER | \
|
||||
MSS_NVM_WR_DENIED)
|
||||
|
||||
*/
|
||||
static nvm_status_t get_error_code(uint32_t nvm_hw_status)
|
||||
{
|
||||
nvm_status_t status;
|
||||
if(nvm_hw_status & MSS_NVM_WR_DENIED)
|
||||
{
|
||||
status = NVM_PROTECTION_ERROR;
|
||||
}
|
||||
else if(nvm_hw_status & MSS_NVM_WRCNT_OVER)
|
||||
{
|
||||
status = NVM_WRITE_THRESHOLD_ERROR;
|
||||
}
|
||||
else if(nvm_hw_status & MSS_NVM_PEFAIL_LOCK)
|
||||
{
|
||||
status = NVM_PAGE_LOCK_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = NVM_VERIFY_FAILURE;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* See mss_nvm.h for details of how to use this function.
|
||||
*/
|
||||
nvm_status_t
|
||||
NVM_unlock
|
||||
(
|
||||
uint32_t start_addr,
|
||||
uint32_t length
|
||||
)
|
||||
{
|
||||
nvm_status_t status;
|
||||
uint32_t nvm_offset;
|
||||
uint32_t first_page;
|
||||
uint32_t last_page;
|
||||
uint32_t current_page;
|
||||
uint32_t current_offset;
|
||||
|
||||
/* Ignore upper address bits to ignore remapping setting. */
|
||||
nvm_offset = start_addr & NVM_OFFSET_SIGNIFICANT_BITS; /* Ignore remapping. */
|
||||
|
||||
/* Check against attempt to write data larger than eNVM. */
|
||||
ASSERT((nvm_offset + length) < MAX_512K_OFFSET);
|
||||
if((nvm_offset + length) < MAX_512K_OFFSET)
|
||||
{
|
||||
current_offset = nvm_offset;
|
||||
|
||||
first_page = nvm_offset / BYTES_PER_PAGE;
|
||||
last_page = (nvm_offset + length) / BYTES_PER_PAGE;
|
||||
|
||||
/* Gain exclusive access to eNVM controller */
|
||||
status = get_ctrl_access(nvm_offset, length);
|
||||
|
||||
/* Unlock eNVM one page at a time. */
|
||||
if(NVM_SUCCESS == status)
|
||||
{
|
||||
uint32_t block;
|
||||
uint32_t inc;
|
||||
uint32_t first_word;
|
||||
uint32_t word_offset;
|
||||
uint32_t * p_nvm32;
|
||||
uint32_t errors;
|
||||
|
||||
p_nvm32 = (uint32_t *)NVM_BASE_ADDRESS;
|
||||
|
||||
first_word = nvm_offset / 4u;
|
||||
word_offset = first_word;
|
||||
|
||||
for(current_page = first_page;
|
||||
(current_page <= last_page) && (NVM_SUCCESS == status);
|
||||
++current_page)
|
||||
{
|
||||
uint32_t ctrl_status;
|
||||
|
||||
if(word_offset >= BLOCK1_FIRST_WORD_OFFSET)
|
||||
{
|
||||
block = NVM_BLOCK_1;
|
||||
}
|
||||
else
|
||||
{
|
||||
block = NVM_BLOCK_0;
|
||||
}
|
||||
|
||||
for(inc = 0u; inc < WD_WORD_SIZE; ++inc)
|
||||
{
|
||||
g_nvm32[block]->WD[inc] = p_nvm32[word_offset];
|
||||
++word_offset;
|
||||
}
|
||||
|
||||
g_nvm[block]->PAGE_LOCK = NVM_DO_NOT_LOCK_PAGE;
|
||||
g_nvm[block]->CMD = USER_UNLOCK;
|
||||
|
||||
/* Issue program command */
|
||||
g_nvm[block]->CMD = PROG_ADS | (current_offset & PAGE_ADDR_MASK);
|
||||
current_offset += BYTES_PER_PAGE;
|
||||
|
||||
/* Wait for NVM to become ready. */
|
||||
ctrl_status = wait_nvm_ready(block);
|
||||
|
||||
/* Check for errors. */
|
||||
errors = ctrl_status & WRITE_ERROR_MASK;
|
||||
if(errors)
|
||||
{
|
||||
uint32_t nvm_hw_status;
|
||||
nvm_hw_status = g_nvm[block]->STATUS;
|
||||
status = get_error_code(nvm_hw_status);
|
||||
}
|
||||
}
|
||||
|
||||
/* Release eNVM controllers so that other masters can gain access to it. */
|
||||
release_ctrl_access();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = NVM_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/* Private function definitions */
|
||||
/**************************************************************************/
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
#define ACCESS_REQUEST_TIMEOUT 0x00800000u
|
||||
#define REQUEST_NVM_ACCESS 0x01u
|
||||
#define CORTEX_M3_ACCESS_GRANTED 0x05u
|
||||
|
||||
static uint8_t g_envm_ctrl_locks = 0x00u;
|
||||
|
||||
static nvm_status_t
|
||||
request_nvm_access
|
||||
(
|
||||
uint32_t nvm_block_id
|
||||
)
|
||||
{
|
||||
nvm_status_t status = NVM_SUCCESS;
|
||||
volatile uint32_t timeout_counter;
|
||||
uint32_t access;
|
||||
|
||||
/*
|
||||
* Use the SystemCoreClock frequency to compute a delay counter value giving
|
||||
* us a delay in the 500ms range. This is a very approximate delay.
|
||||
*/
|
||||
timeout_counter = SystemCoreClock / 16u;
|
||||
|
||||
/*
|
||||
* Gain access to eNVM controller.
|
||||
*/
|
||||
do {
|
||||
g_nvm[nvm_block_id]->REQ_ACCESS = REQUEST_NVM_ACCESS;
|
||||
access = g_nvm[nvm_block_id]->REQ_ACCESS;
|
||||
if(access != CORTEX_M3_ACCESS_GRANTED)
|
||||
{
|
||||
/*
|
||||
* Time out if another AHB master locked access to eNVM to prevent
|
||||
* the Cortex-M3 from locking up on eNVM write if some other part
|
||||
* of the system fails from releasing the eNVM.
|
||||
*/
|
||||
--timeout_counter;
|
||||
if(0u == timeout_counter)
|
||||
{
|
||||
status = NVM_IN_USE_BY_OTHER_MASTER;
|
||||
}
|
||||
}
|
||||
} while((access != CORTEX_M3_ACCESS_GRANTED) && (NVM_SUCCESS == status));
|
||||
|
||||
/*
|
||||
* Mark controller as locked if successful so that it will be unlocked by a
|
||||
* call to release_ctrl_access.
|
||||
*/
|
||||
if(NVM_SUCCESS == status)
|
||||
{
|
||||
g_envm_ctrl_locks |= (uint8_t)((uint32_t)0x01 << nvm_block_id);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
static nvm_status_t
|
||||
get_ctrl_access
|
||||
(
|
||||
uint32_t nvm_offset,
|
||||
uint32_t length
|
||||
)
|
||||
{
|
||||
nvm_status_t access_req_status;
|
||||
|
||||
/*
|
||||
* Gain access to eNVM controller(s).
|
||||
*/
|
||||
if(nvm_offset < NVM1_BOTTOM_OFFSET)
|
||||
{
|
||||
access_req_status = request_nvm_access(NVM_BLOCK_0);
|
||||
if(NVM_SUCCESS == access_req_status)
|
||||
{
|
||||
uint32_t last_offset;
|
||||
last_offset = nvm_offset + length;
|
||||
if(last_offset >= NVM1_BOTTOM_OFFSET)
|
||||
{
|
||||
access_req_status = request_nvm_access(NVM_BLOCK_1);
|
||||
if(NVM_IN_USE_BY_OTHER_MASTER == access_req_status)
|
||||
{
|
||||
release_ctrl_access();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
access_req_status = request_nvm_access(NVM_BLOCK_1);
|
||||
}
|
||||
|
||||
return access_req_status;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* Release access to eNVM controllers.
|
||||
*/
|
||||
#define NVM_BLOCK_0_LOCK_MASK 0x01u
|
||||
#define NVM_BLOCK_1_LOCK_MASK 0x02u
|
||||
|
||||
static void release_ctrl_access(void)
|
||||
{
|
||||
uint8_t block_locked;
|
||||
|
||||
block_locked = g_envm_ctrl_locks & NVM_BLOCK_0_LOCK_MASK;
|
||||
if(block_locked)
|
||||
{
|
||||
g_nvm[NVM_BLOCK_0]->REQ_ACCESS = 0x00u;
|
||||
g_envm_ctrl_locks &= ~NVM_BLOCK_0_LOCK_MASK;
|
||||
}
|
||||
|
||||
block_locked = g_envm_ctrl_locks & NVM_BLOCK_1_LOCK_MASK;
|
||||
if(block_locked)
|
||||
{
|
||||
g_nvm[NVM_BLOCK_1]->REQ_ACCESS = 0x00u;
|
||||
g_envm_ctrl_locks &= ~NVM_BLOCK_1_LOCK_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
static uint32_t wait_nvm_ready(uint32_t block)
|
||||
{
|
||||
volatile uint32_t ctrl_status;
|
||||
uint32_t ctrl_ready;
|
||||
uint32_t inc;
|
||||
|
||||
/*
|
||||
* Wait for NVM to become ready.
|
||||
* We must ensure that we can read the ready bit set to 1 twice before we
|
||||
* can assume that the other status bits are valid. See SmartFusion2 errata.
|
||||
*/
|
||||
for(inc = 0u; inc < 2u; ++inc)
|
||||
{
|
||||
do {
|
||||
ctrl_status = g_nvm[block]->STATUS;
|
||||
ctrl_ready = ctrl_status & MSS_NVM_BUSY_B;
|
||||
} while(0u == ctrl_ready);
|
||||
}
|
||||
|
||||
return ctrl_status;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
Write as much data as will fit into the eNVM page corresponding to the
|
||||
address "addr" passed as parameter. Return the number of bytes written into
|
||||
the page.
|
||||
In case of error, return the content of the eNVM controller status register
|
||||
into the 32-bit word pointed to by p_status.
|
||||
*/
|
||||
static uint32_t
|
||||
write_nvm
|
||||
(
|
||||
uint32_t addr,
|
||||
const uint8_t * pidata,
|
||||
uint32_t length,
|
||||
uint32_t lock_page,
|
||||
uint32_t * p_status
|
||||
)
|
||||
{
|
||||
uint32_t length_written;
|
||||
uint32_t offset;
|
||||
|
||||
*p_status = 0u;
|
||||
|
||||
offset = addr & NVM_OFFSET_SIGNIFICANT_BITS; /* Ignore remapping. */
|
||||
|
||||
ASSERT(offset <= NVM1_TOP_OFFSET);
|
||||
|
||||
/* Adjust length to fit within one page. */
|
||||
length_written = get_remaining_page_length(offset, length);
|
||||
|
||||
if(offset <= NVM1_TOP_OFFSET)
|
||||
{
|
||||
uint32_t block;
|
||||
volatile uint32_t ctrl_status;
|
||||
uint32_t errors;
|
||||
|
||||
if(offset < NVM1_BOTTOM_OFFSET)
|
||||
{
|
||||
block = NVM_BLOCK_0;
|
||||
}
|
||||
else
|
||||
{
|
||||
block = NVM_BLOCK_1;
|
||||
offset = offset - NVM1_BOTTOM_OFFSET;
|
||||
}
|
||||
|
||||
fill_wd_buffer(pidata, length_written, block, offset);
|
||||
|
||||
/* Set requested locking option. */
|
||||
g_nvm[block]->PAGE_LOCK = lock_page;
|
||||
|
||||
/* Issue program command */
|
||||
g_nvm[block]->CMD = PROG_ADS | (offset & PAGE_ADDR_MASK);
|
||||
|
||||
/* Wait for NVM to become ready. */
|
||||
ctrl_status = wait_nvm_ready(block);
|
||||
|
||||
/* Check for errors. */
|
||||
errors = ctrl_status & WRITE_ERROR_MASK;
|
||||
if(errors)
|
||||
{
|
||||
/* Signal that an error occured by returning 0 a a number of bytes written. */
|
||||
length_written = 0u;
|
||||
*p_status = g_nvm[block]->STATUS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Perform a verify. */
|
||||
g_nvm[block]->CMD = VERIFY_ADS | (offset & PAGE_ADDR_MASK);
|
||||
/* Wait for NVM to become ready. */
|
||||
ctrl_status = wait_nvm_ready(block);
|
||||
|
||||
/* Check for errors. */
|
||||
errors = ctrl_status & WRITE_ERROR_MASK;
|
||||
if(errors)
|
||||
{
|
||||
/* Signal that an error occured by returning 0 a a number of bytes written. */
|
||||
length_written = 0u;
|
||||
*p_status = g_nvm[block]->STATUS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return length_written;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
Return the number of bytes between the offset location and the end of the page
|
||||
containing the first offset location. This tells us how many actual bytes can
|
||||
be programmed with a single ProgramADS command.
|
||||
This also tells us if we are programming a full page. If the return value is
|
||||
equal to BYTES_PER_PAGE then we will be pragramming an entire NVM page.
|
||||
Alternatively, this function returning a value other than BYTES_PER_PAGE
|
||||
indicates that the WD[] buffer will have to be seeded with the existing
|
||||
content of the eNVM before copying the data to program to eNVM into the WD[]
|
||||
buffer.
|
||||
*/
|
||||
static uint32_t get_remaining_page_length
|
||||
(
|
||||
uint32_t offset,
|
||||
uint32_t length
|
||||
)
|
||||
{
|
||||
uint32_t start_page_plus_one;
|
||||
uint32_t last_page;
|
||||
|
||||
start_page_plus_one = (offset / BYTES_PER_PAGE) + 1u;
|
||||
last_page = (offset + length) / BYTES_PER_PAGE;
|
||||
if(last_page >= start_page_plus_one)
|
||||
{
|
||||
length = BYTES_PER_PAGE - (offset % BYTES_PER_PAGE);
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
*
|
||||
*/
|
||||
static void fill_wd_buffer
|
||||
(
|
||||
const uint8_t * p_data,
|
||||
uint32_t length,
|
||||
uint32_t block,
|
||||
uint32_t offset
|
||||
)
|
||||
{
|
||||
uint32_t inc;
|
||||
uint32_t wd_offset;
|
||||
|
||||
if(length != BYTES_PER_PAGE)
|
||||
{
|
||||
uint32_t * p_nvm32;
|
||||
uint32_t nb_non_written_words;
|
||||
uint32_t first_non_written_word;
|
||||
/*
|
||||
* Fill beginning of WD[] with current content of NVM page that must not
|
||||
* be overwritten.
|
||||
*/
|
||||
p_nvm32 = (uint32_t *)((NVM_BASE_ADDRESS + offset) & PAGE_ADDR_MASK);
|
||||
nb_non_written_words = (offset % BYTES_PER_PAGE) / NB_OF_BYTES_IN_A_WORD;
|
||||
if((offset % NB_OF_BYTES_IN_A_WORD) > 0u)
|
||||
{
|
||||
++nb_non_written_words;
|
||||
}
|
||||
for(inc = 0u; (inc < WD_WORD_SIZE) && (inc < nb_non_written_words); ++inc)
|
||||
{
|
||||
g_nvm32[block]->WD[inc] = p_nvm32[inc];
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill end of WD[] with current content of NVM page that must not be
|
||||
* overwritten.
|
||||
*/
|
||||
first_non_written_word = ((offset + length) % BYTES_PER_PAGE) / NB_OF_BYTES_IN_A_WORD;
|
||||
nb_non_written_words = (BYTES_PER_PAGE / NB_OF_BYTES_IN_A_WORD) - first_non_written_word;
|
||||
|
||||
for(inc = 0u; inc < nb_non_written_words; ++inc)
|
||||
{
|
||||
g_nvm32[block]->WD[first_non_written_word + inc] = p_nvm32[first_non_written_word + inc];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill WD[] with data requested to be written into NVM.
|
||||
*/
|
||||
wd_offset = offset % BYTES_PER_PAGE;
|
||||
for(inc = 0u; inc < length; ++inc)
|
||||
{
|
||||
g_nvm[block]->WD[wd_offset + inc] = p_data[inc];
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/******************************** END OF FILE ******************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,249 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2011-2013 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* This file contains public APIs for SmartFusion2 eNVM software driver.
|
||||
*
|
||||
* SVN $Revision: 5362 $
|
||||
* SVN $Date: 2013-03-26 21:37:53 +0000 (Tue, 26 Mar 2013) $
|
||||
*/
|
||||
/*=========================================================================*//**
|
||||
@mainpage SmartFusion2 MSS eNVM Bare Metal Driver.
|
||||
|
||||
@section intro_sec Introduction
|
||||
The SmartFusion2 microcontroller subsystem (MSS) includes up to two embedded
|
||||
non-volatile memory (eNVM) blocks. Each of these eNVM blocks can be a maximum
|
||||
size of 256kB. This software driver provides a set of functions for accessing
|
||||
and controlling the MSS eNVM as part of a bare metal system where no operating
|
||||
system is available. The driver can be adapted for use as part of an operating
|
||||
system, but the implementation of the adaptation layer between the driver and
|
||||
the operating system's driver model is outside the scope of the driver.
|
||||
|
||||
The MSS eNVM driver provides support for the following features:
|
||||
- eNVM write (program) operations.
|
||||
- eNVM page unlocking
|
||||
The MSS eNVM driver is provided as C source code.
|
||||
|
||||
|
||||
@section configuration Driver Configuration
|
||||
The size of the MSS eNVM varies with different SmartFusion2 device types. You
|
||||
must only use this driver to access memory locations within the valid MSS eNVM
|
||||
address space for the targeted device. The size of the valid MSS eNVM address
|
||||
space corresponds to the size of the MSS eNVM in the device. Some pages of the
|
||||
MSS eNVM may be write protected by the SmartFusion2 MSS configurator as part
|
||||
of the hardware design flow. The driver cannot unlock or write to these
|
||||
protected pages.
|
||||
The base address, register addresses and interrupt number assignment for the
|
||||
MSS eNVM blocks are defined as constants in the SmartFusion2 CMSIS HAL. You
|
||||
must ensure that the latest SmartFusion2 CMSIS HAL is included in the project
|
||||
settings of the software tool chain used to build your project and that it is
|
||||
generated into your project.
|
||||
|
||||
@section theory_op Theory of Operation
|
||||
The total amount of eNVM available in a SmartFusion device ranges from 128kB
|
||||
to 512kB, provided in one or two physical eNVM blocks. The eNVM blocks are
|
||||
divided into pages, with each page holding 128 bytes of data. The MSS eNVM
|
||||
driver treats the entire eNVM as a contiguous memory space. It provides write
|
||||
access to all pages that are in the valid eNVM address range for the
|
||||
SmartFusion device and that are not write-protected. The driver imposes no
|
||||
restrictions on writing data across eNVM block or page boundaries. The driver
|
||||
supports random access writes to the eNVM memory.
|
||||
|
||||
*//*=========================================================================*/
|
||||
#ifndef __MSS_NVM_H
|
||||
#define __MSS_NVM_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
/* Public definitions */
|
||||
/******************************************************************************/
|
||||
/*******************************************************************************
|
||||
* Page Locking constants:
|
||||
*/
|
||||
/*
|
||||
* Indicates that the NVM_write() function should not lock the addressed pages
|
||||
* after programming the data.
|
||||
*/
|
||||
#define NVM_DO_NOT_LOCK_PAGE 0u
|
||||
|
||||
/*
|
||||
* Indicates that the NVM_write() function should lock the addressed pages after
|
||||
* programming the data.
|
||||
*/
|
||||
#define NVM_LOCK_PAGE 1u
|
||||
|
||||
/*******************************************************************************
|
||||
The nvm_status_t enumeration specifies the possible return values from the
|
||||
NVM_write() and NVM_unlock() functions.
|
||||
|
||||
NVM_SUCCESS:
|
||||
Indicates that the programming was successful.
|
||||
|
||||
NVM_PROTECTION_ERROR:
|
||||
Indicates that the operation could not be completed because of a
|
||||
protection error. This happens when attempting to program a page that was
|
||||
set as protected in the hardware flow.
|
||||
|
||||
NVM_VERIFY_FAILURE:
|
||||
Indicates that one of the verify operations failed.
|
||||
|
||||
NVM_PAGE_LOCK_ERROR:
|
||||
Indicates that the operation could not complete because one of the pages
|
||||
is locked. This may happen if the page was locked during a previous call
|
||||
to NVM_write() or if the page was locked in the hardware design flow.
|
||||
|
||||
NVM_WRITE_THRESHOLD_ERROR:
|
||||
Indicates that the NVM maximum number of programming cycles has been
|
||||
reached.
|
||||
|
||||
NVM_IN_USE_BY_OTHER_MASTER:
|
||||
Indicates that some other MSS AHB Bus Matrix master is accessing the NVM.
|
||||
This could be due to the FPGA logic or the system controller programming
|
||||
the NVM.
|
||||
|
||||
NVM_INVALID_PARAMETER:
|
||||
Indicates that one of more of the function parameters has an invalid
|
||||
value. This is typically returned when attempting to write or unlock more
|
||||
eNVM than is available on the device.
|
||||
*/
|
||||
typedef enum nvm_status
|
||||
{
|
||||
NVM_SUCCESS = 0,
|
||||
NVM_PROTECTION_ERROR,
|
||||
NVM_VERIFY_FAILURE,
|
||||
NVM_PAGE_LOCK_ERROR,
|
||||
NVM_WRITE_THRESHOLD_ERROR,
|
||||
NVM_IN_USE_BY_OTHER_MASTER,
|
||||
NVM_INVALID_PARAMETER
|
||||
} nvm_status_t;
|
||||
|
||||
/******************************************************************************/
|
||||
/* Public variables */
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Public function declarations */
|
||||
/******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
The NVM_write() function is used to program (or write) data into the eNVM.
|
||||
This function treats the two eNVM blocks contiguously, so a total of 512kB of
|
||||
memory can be accessed linearly. The start address and end address of the
|
||||
memory range to be programmed do not need to be page aligned. This function
|
||||
supports programming of data that spans multiple pages. This function is a
|
||||
blocking function.
|
||||
Note: The NVM_write() function performs a verify operation on each page
|
||||
programmed to ensure the eNVM is programmed with the expected data.
|
||||
|
||||
@param start_addr
|
||||
The start_addr parameter is the byte aligned start address in the eNVM
|
||||
address space, to which the data is to be programmed.
|
||||
|
||||
@param pidata
|
||||
The pidata parameter is the byte aligned start address of the input data.
|
||||
|
||||
@param length
|
||||
The length parameter is the number of bytes of data to be programmed.
|
||||
|
||||
@param lock_page
|
||||
The lock_page parameter specifies whether the pages that are programmed
|
||||
must be locked or not once programmed. Locking the programmed pages prevents
|
||||
them from being overwritten by mistake. Subsequent programming of these
|
||||
pages will require the pages to be unlocked prior to calling NVM_write().
|
||||
Allowed values for lock_page are:
|
||||
- NVM_DO_NOT_LOCK_PAGE
|
||||
- NVM_LOCK_PAGE
|
||||
|
||||
@return
|
||||
This function returns NVM_SUCCESS on successful execution.
|
||||
It returns one of the following error codes if the programming of the eNVM
|
||||
fails:
|
||||
- NVM_PROTECTION_ERROR
|
||||
- NVM_VERIFY_FAILURE
|
||||
- NVM_PAGE_LOCK_ERROR
|
||||
- NVM_WRITE_THRESHOLD_ERROR
|
||||
- NVM_IN_USE_BY_OTHER_MASTER
|
||||
- NVM_INVALID_PARAMETER
|
||||
|
||||
Example:
|
||||
@code
|
||||
uint8_t idata[815] = {"Z"};
|
||||
status = NVM_write(0x0, idata, sizeof(idata), NVM_DO_NOT_LOCK_PAGE);
|
||||
@endcode
|
||||
*/
|
||||
nvm_status_t
|
||||
NVM_write
|
||||
(
|
||||
uint32_t start_addr,
|
||||
const uint8_t * pidata,
|
||||
uint32_t length,
|
||||
uint32_t lock_page
|
||||
);
|
||||
|
||||
/***************************************************************************//**
|
||||
The NVM_unlock() function is used to unlock the eNVM pages for a specified
|
||||
range of eNVM addresses in preparation for writing data into the unlocked
|
||||
locations. This function treats the two eNVM blocks contiguously, so a total
|
||||
of 512kB of memory can be accessed linearly. The start address and end address
|
||||
of the memory range to be unlocked do not need to be page aligned. This
|
||||
function supports unlocking of an eNVM address range that spans multiple
|
||||
pages. This function is a blocking function.
|
||||
|
||||
@param start_addr
|
||||
The start_addr parameter is the byte aligned start address, in the eNVM
|
||||
address space, of the memory range to be unlocked.
|
||||
|
||||
@param length
|
||||
The length parameter is the size in bytes of the memory range to be
|
||||
unlocked.
|
||||
|
||||
@return
|
||||
This function returns NVM_SUCCESS on successful execution.
|
||||
It returns one of the following error codes if the unlocking of the eNVM fails:
|
||||
- NVM_PROTECTION_ERROR
|
||||
- NVM_VERIFY_FAILURE
|
||||
- NVM_PAGE_LOCK_ERROR
|
||||
- NVM_WRITE_THRESHOLD_ERROR
|
||||
- NVM_IN_USE_BY_OTHER_MASTER
|
||||
- NVM_INVALID_PARAMETER
|
||||
|
||||
The example code below demonstrates the intended use of the NVM_unlock()
|
||||
function:
|
||||
@code
|
||||
int program_locked_nvm(uint32_t target_addr, uint32_t length)
|
||||
{
|
||||
nvm_status_t status;
|
||||
int success = 0;
|
||||
|
||||
status = NVM_unlock(target_addr, length);
|
||||
if(NVM_SUCCESS == status)
|
||||
{
|
||||
status = NVM_write(target_addr, buffer, length, NVM_LOCK_PAGE);
|
||||
if(NVM_SUCCESS == status)
|
||||
{
|
||||
success = 1;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
nvm_status_t
|
||||
NVM_unlock
|
||||
(
|
||||
uint32_t start_addr,
|
||||
uint32_t length
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __MSS_NVM_H */
|
||||
|
||||
|
|
@ -0,0 +1,666 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2008-2013 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* SmartFusion2 MSS RTC bare metal driver implementation.
|
||||
*
|
||||
* SVN $Revision: 5090 $
|
||||
* SVN $Date: 2013-02-18 12:13:31 +0000 (Mon, 18 Feb 2013) $
|
||||
*/
|
||||
#include "mss_rtc.h"
|
||||
#include "../../CMSIS/mss_assert.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* CONTROL_REG register masks.
|
||||
*/
|
||||
#define CONTROL_RUNNING_MASK 0x00000001u
|
||||
|
||||
#define CONTROL_RTC_START_MASK 0x00000001u
|
||||
#define CONTROL_RTC_STOP_MASK 0x00000002u
|
||||
#define CONTROL_ALARM_ON_MASK 0x00000004u
|
||||
#define CONTROL_ALARM_OFF_MASK 0x00000008u
|
||||
#define CONTROL_RESET_MASK 0x00000010u
|
||||
#define CONTROL_UPLOAD_MASK 0x00000020u
|
||||
#define CONTROL_WAKEUP_CLR_MASK 0x00000100u
|
||||
#define CONTROL_UPDATED_MASK 0x00000400u
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* MODE_REG register masks.
|
||||
*/
|
||||
#define MODE_CLK_MODE_MASK 0x00000001u
|
||||
#define MODE_WAKEUP_EN_MASK 0x00000002u
|
||||
#define MODE_WAKEUP_RESET_MASK 0x00000004u
|
||||
#define MODE_WAKEUP_CONTINUE_MASK 0x00000008u
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* Other masks.
|
||||
*/
|
||||
#define MAX_BINARY_HIGHER_COUNT 0x7FFu
|
||||
#define MASK_32_BIT 0xFFFFFFFFu
|
||||
#define MAX_PRESCALAR_COUNT 0x03FFFFFFu
|
||||
#define CALENDAR_SHIFT 8u
|
||||
|
||||
#define COMPARE_ALL_BITS 0xFFFFFFFFu
|
||||
|
||||
#define SYSREG_RTC_WAKEUP_M3_EN_MASK 0x00000001u
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* Index into look-up table.
|
||||
*/
|
||||
#define SECONDS 0
|
||||
#define MINUTES 1
|
||||
#define HOURS 2
|
||||
#define DAYS 3
|
||||
#define MONTHS 4
|
||||
#define YEARS 5
|
||||
#define WEEKDAYS 6
|
||||
#define WEEKS 7
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
Local functions.
|
||||
*/
|
||||
static uint8_t
|
||||
get_clock_mode
|
||||
(
|
||||
void
|
||||
);
|
||||
|
||||
static void set_rtc_mode(uint8_t requested_mode);
|
||||
|
||||
static void add_alarm_cfg_values
|
||||
(
|
||||
uint8_t calendar_item,
|
||||
uint32_t * p_calendar_value,
|
||||
uint32_t * p_compare_mask
|
||||
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* See "mss_rtc.h" for details of how to use this function.
|
||||
*/
|
||||
void
|
||||
MSS_RTC_init
|
||||
(
|
||||
uint8_t mode,
|
||||
uint32_t prescaler
|
||||
)
|
||||
{
|
||||
ASSERT(prescaler <= MAX_PRESCALAR_COUNT);
|
||||
|
||||
if(prescaler <= MAX_PRESCALAR_COUNT)
|
||||
{
|
||||
/* Stop the RTC. */
|
||||
MSS_RTC_stop();
|
||||
|
||||
/* Disable alarm. */
|
||||
RTC->CONTROL_REG = CONTROL_ALARM_OFF_MASK;
|
||||
|
||||
/* Disable Interrupt */
|
||||
MSS_RTC_disable_irq();
|
||||
NVIC_ClearPendingIRQ(RTC_Wakeup_IRQn);
|
||||
|
||||
/* Clear RTC wake up interrupt signal */
|
||||
MSS_RTC_clear_irq();
|
||||
|
||||
/* Enable the RTC to interrupt the Cortex-M3. */
|
||||
SYSREG->RTC_WAKEUP_CR |= SYSREG_RTC_WAKEUP_M3_EN_MASK;
|
||||
|
||||
/* Select mode of operation, including the wake configuration. */
|
||||
if(MSS_RTC_CALENDAR_MODE == mode)
|
||||
{
|
||||
RTC->MODE_REG = MODE_CLK_MODE_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
RTC->MODE_REG = 0u;
|
||||
}
|
||||
|
||||
/* Reset the alarm and compare registers to a known value. */
|
||||
RTC->ALARM_LOWER_REG = 0u;
|
||||
RTC->ALARM_UPPER_REG = 0u;
|
||||
RTC->COMPARE_LOWER_REG = 0u;
|
||||
RTC->COMPARE_UPPER_REG = 0u;
|
||||
|
||||
/* Reset the calendar counters */
|
||||
MSS_RTC_reset_counter();
|
||||
|
||||
/* Set new Prescaler value */
|
||||
RTC->PRESCALER_REG = prescaler;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
See "mss_rtc.h" for details of how to use this function.
|
||||
*/
|
||||
void
|
||||
MSS_RTC_set_calendar_count
|
||||
(
|
||||
const mss_rtc_calendar_t *new_rtc_value
|
||||
)
|
||||
{
|
||||
uint8_t error = 0u;
|
||||
uint8_t clock_mode;
|
||||
|
||||
const uint8_t g_rtc_max_count_lut[] =
|
||||
{
|
||||
/* Calendar mode */
|
||||
59u, /* Seconds */
|
||||
59u, /* Minutes */
|
||||
23u, /* Hours */
|
||||
31u, /* Days */
|
||||
12u, /* Months */
|
||||
254u, /* Years */
|
||||
7u, /* Weekdays*/
|
||||
52u /* Week */
|
||||
};
|
||||
|
||||
const uint8_t g_rtc_min_count_lut[] =
|
||||
{
|
||||
/* Calendar mode */
|
||||
0u, /* Seconds */
|
||||
0u, /* Minutes */
|
||||
0u, /* Hours */
|
||||
1u, /* Days */
|
||||
1u, /* Months */
|
||||
0u, /* Years */
|
||||
1u, /* Weekdays*/
|
||||
1u /* Week */
|
||||
};
|
||||
|
||||
/* Assert if the values cross the limit */
|
||||
ASSERT(new_rtc_value->second >= g_rtc_min_count_lut[SECONDS]);
|
||||
ASSERT(new_rtc_value->second <= g_rtc_max_count_lut[SECONDS]);
|
||||
ASSERT(new_rtc_value->minute >= g_rtc_min_count_lut[MINUTES]);
|
||||
ASSERT(new_rtc_value->minute <= g_rtc_max_count_lut[MINUTES]);
|
||||
ASSERT(new_rtc_value->hour >= g_rtc_min_count_lut[HOURS]);
|
||||
ASSERT(new_rtc_value->hour <= g_rtc_max_count_lut[HOURS]);
|
||||
ASSERT(new_rtc_value->day >= g_rtc_min_count_lut[DAYS]);
|
||||
ASSERT(new_rtc_value->day <= g_rtc_max_count_lut[DAYS]);
|
||||
ASSERT(new_rtc_value->month >= g_rtc_min_count_lut[MONTHS]);
|
||||
ASSERT(new_rtc_value->month <= g_rtc_max_count_lut[MONTHS]);
|
||||
ASSERT(new_rtc_value->year >= g_rtc_min_count_lut[YEARS]);
|
||||
ASSERT(new_rtc_value->year <= g_rtc_max_count_lut[YEARS]);
|
||||
ASSERT(new_rtc_value->weekday >= g_rtc_min_count_lut[WEEKDAYS]);
|
||||
ASSERT(new_rtc_value->weekday <= g_rtc_max_count_lut[WEEKDAYS]);
|
||||
ASSERT(new_rtc_value->week >= g_rtc_min_count_lut[WEEKS]);
|
||||
ASSERT(new_rtc_value->week <= g_rtc_max_count_lut[WEEKS]);
|
||||
|
||||
if(new_rtc_value->second < g_rtc_min_count_lut[SECONDS]) {error = 1u;}
|
||||
if(new_rtc_value->second > g_rtc_max_count_lut[SECONDS]) {error = 1u;}
|
||||
if(new_rtc_value->minute < g_rtc_min_count_lut[MINUTES]) {error = 1u;}
|
||||
if(new_rtc_value->minute > g_rtc_max_count_lut[MINUTES]) {error = 1u;}
|
||||
if(new_rtc_value->hour < g_rtc_min_count_lut[HOURS]) {error = 1u;}
|
||||
if(new_rtc_value->hour > g_rtc_max_count_lut[HOURS]) {error = 1u;}
|
||||
if(new_rtc_value->day < g_rtc_min_count_lut[DAYS]) {error = 1u;}
|
||||
if(new_rtc_value->day > g_rtc_max_count_lut[DAYS]) {error = 1u;}
|
||||
if(new_rtc_value->month < g_rtc_min_count_lut[MONTHS]) {error = 1u;}
|
||||
if(new_rtc_value->month > g_rtc_max_count_lut[MONTHS]) {error = 1u;}
|
||||
if(new_rtc_value->year < g_rtc_min_count_lut[YEARS]) {error = 1u;}
|
||||
if(new_rtc_value->year > g_rtc_max_count_lut[YEARS]) {error = 1u;}
|
||||
if(new_rtc_value->weekday < g_rtc_min_count_lut[WEEKDAYS]) {error = 1u;}
|
||||
if(new_rtc_value->weekday > g_rtc_max_count_lut[WEEKDAYS]) {error = 1u;}
|
||||
if(new_rtc_value->week < g_rtc_min_count_lut[WEEKS]) {error = 1u;}
|
||||
if(new_rtc_value->week > g_rtc_max_count_lut[WEEKS]) {error = 1u;}
|
||||
|
||||
/*
|
||||
* This function can only be used when the RTC is configured to operate in
|
||||
* calendar counter mode.
|
||||
*/
|
||||
clock_mode = get_clock_mode();
|
||||
ASSERT(MSS_RTC_CALENDAR_MODE == clock_mode);
|
||||
|
||||
if((0u == error) && (MSS_RTC_CALENDAR_MODE == clock_mode))
|
||||
{
|
||||
uint32_t upload_in_progress;
|
||||
|
||||
/*
|
||||
* Write the RTC new value.
|
||||
*/
|
||||
RTC->SECONDS_REG = new_rtc_value->second;
|
||||
RTC->MINUTES_REG = new_rtc_value->minute;
|
||||
RTC->HOURS_REG = new_rtc_value->hour;
|
||||
RTC->DAY_REG = new_rtc_value->day;
|
||||
RTC->MONTH_REG = new_rtc_value->month;
|
||||
RTC->YEAR_REG = new_rtc_value->year;
|
||||
RTC->WEEKDAY_REG = new_rtc_value->weekday;
|
||||
RTC->WEEK_REG = new_rtc_value->week;
|
||||
|
||||
/* Data is copied, now issue upload command */
|
||||
RTC->CONTROL_REG = CONTROL_UPLOAD_MASK ;
|
||||
|
||||
/* Wait for the upload to complete. */
|
||||
do {
|
||||
upload_in_progress = RTC->CONTROL_REG & CONTROL_UPLOAD_MASK;
|
||||
} while(upload_in_progress);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* See "mss_rtc.h" for details of how to use this function.
|
||||
*/
|
||||
void
|
||||
MSS_RTC_set_binary_count
|
||||
(
|
||||
uint64_t new_rtc_value
|
||||
)
|
||||
{
|
||||
uint8_t clock_mode;
|
||||
|
||||
/*
|
||||
* This function can only be used when the RTC is configured to operate in
|
||||
* binary counter mode.
|
||||
*/
|
||||
clock_mode = get_clock_mode();
|
||||
ASSERT(MSS_RTC_BINARY_MODE == clock_mode);
|
||||
|
||||
if(MSS_RTC_BINARY_MODE == clock_mode)
|
||||
{
|
||||
uint32_t rtc_upper_32_bit_value;
|
||||
|
||||
rtc_upper_32_bit_value = (uint32_t)(new_rtc_value >> 32u) & MASK_32_BIT;
|
||||
|
||||
/* Assert if the values cross the limit */
|
||||
ASSERT(rtc_upper_32_bit_value <= MAX_BINARY_HIGHER_COUNT);
|
||||
|
||||
if(rtc_upper_32_bit_value <= MAX_BINARY_HIGHER_COUNT)
|
||||
{
|
||||
uint32_t upload_in_progress;
|
||||
|
||||
/*
|
||||
* Write the RTC new value.
|
||||
*/
|
||||
RTC->DATE_TIME_LOWER_REG = (uint32_t)new_rtc_value;
|
||||
RTC->DATE_TIME_UPPER_REG =
|
||||
(uint32_t)(( new_rtc_value >> 32u) & MAX_BINARY_HIGHER_COUNT);
|
||||
|
||||
/* Data is copied, now issue upload command */
|
||||
RTC->CONTROL_REG = CONTROL_UPLOAD_MASK;
|
||||
|
||||
/* Wait for the upload to complete. */
|
||||
do {
|
||||
upload_in_progress = RTC->CONTROL_REG & CONTROL_UPLOAD_MASK;
|
||||
} while(upload_in_progress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* See "mss_rtc.h" for details of how to use this function.
|
||||
*/
|
||||
void
|
||||
MSS_RTC_get_calendar_count
|
||||
(
|
||||
mss_rtc_calendar_t *p_rtc_calendar
|
||||
)
|
||||
{
|
||||
uint8_t clock_mode;
|
||||
/*
|
||||
* This function can only be used when the RTC is configured to operate in
|
||||
* calendar counter mode.
|
||||
*/
|
||||
clock_mode = get_clock_mode();
|
||||
ASSERT(MSS_RTC_CALENDAR_MODE == clock_mode);
|
||||
|
||||
if(MSS_RTC_CALENDAR_MODE == clock_mode)
|
||||
{
|
||||
p_rtc_calendar->second = (uint8_t)RTC->SECONDS_REG;
|
||||
p_rtc_calendar->minute = (uint8_t)RTC->MINUTES_REG;
|
||||
p_rtc_calendar->hour = (uint8_t)RTC->HOURS_REG;
|
||||
p_rtc_calendar->day = (uint8_t)RTC->DAY_REG;
|
||||
p_rtc_calendar->month = (uint8_t)RTC->MONTH_REG;
|
||||
p_rtc_calendar->year = (uint8_t)RTC->YEAR_REG;
|
||||
p_rtc_calendar->weekday = (uint8_t)RTC->WEEKDAY_REG;
|
||||
p_rtc_calendar->week = (uint8_t)RTC->WEEK_REG;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Set returned calendar count to zero if the RTC is not configured for
|
||||
* calendar counter mode. This should make incorrect release application
|
||||
* code behave consistently and help application debugging.
|
||||
*/
|
||||
memset(p_rtc_calendar, 0, sizeof(mss_rtc_calendar_t));
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* See "mss_rtc.h" for details of how to use this function.
|
||||
*/
|
||||
uint64_t
|
||||
MSS_RTC_get_binary_count
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
uint64_t rtc_count;
|
||||
uint8_t clock_mode;
|
||||
|
||||
/*
|
||||
* This function can only be used when the RTC is configured to operate in
|
||||
* binary counter mode.
|
||||
*/
|
||||
clock_mode = get_clock_mode();
|
||||
ASSERT(MSS_RTC_BINARY_MODE == clock_mode);
|
||||
|
||||
if(MSS_RTC_BINARY_MODE == clock_mode)
|
||||
{
|
||||
rtc_count = RTC->DATE_TIME_LOWER_REG;
|
||||
rtc_count = rtc_count | ((uint64_t)RTC->DATE_TIME_UPPER_REG << 32u) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Set returned binary count to zero if the RTC is not configured for
|
||||
* binary counter mode. This should make incorrect release application
|
||||
* code behave consistently and help application debugging.
|
||||
*/
|
||||
rtc_count = 0u;
|
||||
}
|
||||
|
||||
return rtc_count;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
*
|
||||
*/
|
||||
static void add_alarm_cfg_values
|
||||
(
|
||||
uint8_t calendar_item,
|
||||
uint32_t * p_calendar_value,
|
||||
uint32_t * p_compare_mask
|
||||
|
||||
)
|
||||
{
|
||||
if(MSS_RTC_CALENDAR_DONT_CARE == calendar_item)
|
||||
{
|
||||
*p_calendar_value = (uint32_t)(*p_calendar_value << CALENDAR_SHIFT);
|
||||
*p_compare_mask = (uint32_t)(*p_compare_mask << CALENDAR_SHIFT);
|
||||
}
|
||||
else
|
||||
{
|
||||
*p_calendar_value = (uint32_t)((*p_calendar_value << CALENDAR_SHIFT) | (uint32_t)calendar_item);
|
||||
*p_compare_mask = (uint32_t)((*p_compare_mask << CALENDAR_SHIFT) | (uint32_t)0xFFu);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* See "mss_rtc.h" for details of how to use this function.
|
||||
*/
|
||||
void MSS_RTC_set_calendar_count_alarm
|
||||
(
|
||||
const mss_rtc_calendar_t * alarm_value
|
||||
)
|
||||
{
|
||||
uint32_t calendar_value;
|
||||
uint32_t compare_mask;
|
||||
uint8_t mode;
|
||||
|
||||
mode = (uint8_t)(RTC->MODE_REG & MODE_CLK_MODE_MASK);
|
||||
/*
|
||||
* This function can only be used with the RTC set to operate in calendar
|
||||
* mode.
|
||||
*/
|
||||
ASSERT(MSS_RTC_CALENDAR_MODE == mode);
|
||||
if(MSS_RTC_CALENDAR_MODE == mode)
|
||||
{
|
||||
uint8_t required_mode_reg;
|
||||
|
||||
/* Disable the alarm before updating*/
|
||||
RTC->CONTROL_REG = CONTROL_ALARM_OFF_MASK;
|
||||
|
||||
/* Set alarm and compare lower registers. */
|
||||
calendar_value = 0u;
|
||||
compare_mask = 0u;
|
||||
|
||||
add_alarm_cfg_values(alarm_value->day, &calendar_value, &compare_mask);
|
||||
add_alarm_cfg_values(alarm_value->hour, &calendar_value, &compare_mask);
|
||||
add_alarm_cfg_values(alarm_value->minute, &calendar_value, &compare_mask);
|
||||
add_alarm_cfg_values(alarm_value->second, &calendar_value, &compare_mask);
|
||||
|
||||
RTC->ALARM_LOWER_REG = calendar_value;
|
||||
RTC->COMPARE_LOWER_REG = compare_mask;
|
||||
|
||||
/* Set alarm and compare upper registers. */
|
||||
calendar_value = 0u;
|
||||
compare_mask = 0u;
|
||||
|
||||
add_alarm_cfg_values(alarm_value->week, &calendar_value, &compare_mask);
|
||||
add_alarm_cfg_values(alarm_value->weekday, &calendar_value, &compare_mask);
|
||||
add_alarm_cfg_values(alarm_value->year, &calendar_value, &compare_mask);
|
||||
add_alarm_cfg_values(alarm_value->month, &calendar_value, &compare_mask);
|
||||
|
||||
RTC->ALARM_UPPER_REG = calendar_value;
|
||||
RTC->COMPARE_UPPER_REG = compare_mask;
|
||||
|
||||
/* Configure the RTC to enable the alarm. */
|
||||
required_mode_reg = mode | MODE_WAKEUP_EN_MASK | MODE_WAKEUP_CONTINUE_MASK;
|
||||
set_rtc_mode(required_mode_reg);
|
||||
|
||||
/* Enable the alarm */
|
||||
RTC->CONTROL_REG = CONTROL_ALARM_ON_MASK ;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
We only write the RTC mode register if really required because the RTC needs
|
||||
to be stopped for the mode register to be written. Stopping the RTC everytime
|
||||
the wakeup alarm configuration is set might induce drift on the RTC time.
|
||||
This function is intended to be used when setting alarms.
|
||||
*/
|
||||
static void set_rtc_mode(uint8_t requested_mode)
|
||||
{
|
||||
if(RTC->MODE_REG != requested_mode)
|
||||
{
|
||||
uint32_t rtc_running;
|
||||
rtc_running = RTC->CONTROL_REG & CONTROL_RUNNING_MASK;
|
||||
if(rtc_running)
|
||||
{
|
||||
/* Stop the RTC in order to change the mode register content.*/
|
||||
MSS_RTC_stop();
|
||||
RTC->MODE_REG = requested_mode;
|
||||
MSS_RTC_start();
|
||||
}
|
||||
else
|
||||
{
|
||||
RTC->MODE_REG = requested_mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* See "mss_rtc.h" for details of how to use this function.
|
||||
*/
|
||||
void MSS_RTC_set_binary_count_alarm
|
||||
(
|
||||
uint64_t alarm_value,
|
||||
mss_rtc_alarm_type_t alarm_type
|
||||
)
|
||||
{
|
||||
uint8_t mode;
|
||||
|
||||
mode = (uint8_t)(RTC->MODE_REG & MODE_CLK_MODE_MASK);
|
||||
/*
|
||||
* This function can only be used with the RTC set to operate in binary
|
||||
* counter mode.
|
||||
*/
|
||||
ASSERT(MSS_RTC_BINARY_MODE == mode);
|
||||
if(MSS_RTC_BINARY_MODE == mode)
|
||||
{
|
||||
uint8_t required_mode_reg;
|
||||
|
||||
/* Disable the alarm before updating*/
|
||||
RTC->CONTROL_REG = CONTROL_ALARM_OFF_MASK;
|
||||
|
||||
/* Set the alarm value. */
|
||||
RTC->COMPARE_LOWER_REG = COMPARE_ALL_BITS;
|
||||
RTC->COMPARE_UPPER_REG = COMPARE_ALL_BITS;
|
||||
RTC->ALARM_LOWER_REG = (uint32_t)alarm_value;
|
||||
RTC->ALARM_UPPER_REG = (uint32_t)(alarm_value >> 32u);
|
||||
|
||||
/*
|
||||
* Configure the RTC to enable the alarm.
|
||||
*/
|
||||
required_mode_reg = mode | MODE_WAKEUP_EN_MASK | MODE_WAKEUP_CONTINUE_MASK;
|
||||
if(MSS_RTC_PERIODIC_ALARM == alarm_type)
|
||||
{
|
||||
/*
|
||||
* The RTC binary counter will be fully reset when the alarm occurs.
|
||||
* The counter will continue counting while the wake-up interrupt is
|
||||
* active.
|
||||
*/
|
||||
required_mode_reg |= MODE_WAKEUP_RESET_MASK;
|
||||
}
|
||||
set_rtc_mode(required_mode_reg);
|
||||
|
||||
/* Enable the alarm */
|
||||
RTC->CONTROL_REG = CONTROL_ALARM_ON_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* See "mss_rtc.h" for details of how to use this function.
|
||||
*/
|
||||
void
|
||||
MSS_RTC_start
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
RTC->CONTROL_REG = CONTROL_RTC_START_MASK;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* See "mss_rtc.h" for details of how to use this function.
|
||||
*/
|
||||
void
|
||||
MSS_RTC_stop
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
uint32_t rtc_running;
|
||||
|
||||
/*
|
||||
* Send command to stop RTC.
|
||||
*/
|
||||
RTC->CONTROL_REG = CONTROL_RTC_STOP_MASK;
|
||||
|
||||
/*
|
||||
* Wait for RTC internal synchronization to take place and RTC to actually
|
||||
* stop.
|
||||
*/
|
||||
do {
|
||||
rtc_running = RTC->CONTROL_REG & CONTROL_RUNNING_MASK;
|
||||
} while(rtc_running);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
See "mss_rtc.h" for details of how to use this function.
|
||||
*/
|
||||
void
|
||||
MSS_RTC_reset_counter
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
uint32_t upload_in_progress;
|
||||
|
||||
RTC->CONTROL_REG = CONTROL_RESET_MASK;
|
||||
|
||||
/* Wait for the upload to complete. */
|
||||
do {
|
||||
upload_in_progress = RTC->CONTROL_REG & CONTROL_UPLOAD_MASK;
|
||||
} while(upload_in_progress);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
See "mss_rtc.h" for details of how to use this function.
|
||||
*/
|
||||
uint32_t MSS_RTC_get_update_flag(void)
|
||||
{
|
||||
uint32_t updated;
|
||||
updated = RTC->CONTROL_REG & CONTROL_UPDATED_MASK;
|
||||
return updated;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
See "mss_rtc.h" for details of how to use this function.
|
||||
*/
|
||||
void MSS_RTC_clear_update_flag(void)
|
||||
{
|
||||
/* Clear the "updated" control bit. */
|
||||
RTC->CONTROL_REG = CONTROL_UPDATED_MASK;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
See "mss_rtc.h" for details of how to use this function.
|
||||
*/
|
||||
void MSS_RTC_enable_irq(void)
|
||||
{
|
||||
/*
|
||||
* Only the NVIC level interrupt enable is performed within this function.
|
||||
* The RTC level interrupt enable is performed within the alarm setting
|
||||
* functions.
|
||||
* This avoid the MODE register being modified whenever Cortex-M3 RTC
|
||||
* interrupts are enabled/disabled.
|
||||
*/
|
||||
NVIC_EnableIRQ(RTC_Wakeup_IRQn);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
See "mss_rtc.h" for details of how to use this function.
|
||||
*/
|
||||
void
|
||||
MSS_RTC_disable_irq
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
/*
|
||||
* Only the NVIC level interrupt disable is performed within this function.
|
||||
* This avoid the MODE register being modified whenever Cortex-M3 RTC
|
||||
* interrupts are enabled/disabled.
|
||||
*/
|
||||
NVIC_DisableIRQ(RTC_Wakeup_IRQn);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* See "mss_rtc.h" for details of how to use this function.
|
||||
*/
|
||||
void
|
||||
MSS_RTC_clear_irq
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
/* Clear wake up interrupt signal */
|
||||
RTC->CONTROL_REG = CONTROL_WAKEUP_CLR_MASK;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The get_clock_mode() function gets the clock mode of RTC hardware.
|
||||
Possible clock modes are:
|
||||
MSS_RTC_CALENDAR_MODE
|
||||
MSS_RTC_BINARY_MODE
|
||||
*/
|
||||
static uint8_t
|
||||
get_clock_mode
|
||||
(
|
||||
void
|
||||
)
|
||||
{
|
||||
uint8_t clock_mode;
|
||||
|
||||
clock_mode = (uint8_t)(RTC->MODE_REG & MODE_CLK_MODE_MASK);
|
||||
|
||||
return(clock_mode);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,710 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2008-2013 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* SmartFusion2 MSS RTC bare metal software driver public API.
|
||||
*
|
||||
* SVN $Revision: 5396 $
|
||||
* SVN $Date: 2013-03-27 21:57:50 +0000 (Wed, 27 Mar 2013) $
|
||||
*/
|
||||
|
||||
/*=========================================================================*//**
|
||||
@mainpage SmartFusion2 MSS RTC Bare Metal Driver.
|
||||
|
||||
@section intro_sec Introduction
|
||||
The SmartFusion2 microcontroller subsystem (MSS) includes a real time counter
|
||||
(RTC) that can generate alarms and wakeup interrupts in real time. This
|
||||
software driver provides a set of functions for controlling the MSS RTC as
|
||||
part of a bare metal system where no operating system is available. The driver
|
||||
can be adapted for use as part of an operating system, but the implementation
|
||||
of the adaptation layer between the driver and the operating system's driver
|
||||
model is outside the scope of the driver.
|
||||
|
||||
The MSS RTC driver provides support for the following features:
|
||||
- Initialization of the RTC
|
||||
- Configuration of the RTC timebase
|
||||
- Configuration as a calendar or binary mode counter
|
||||
- Set the current calendar or binary mode count
|
||||
- Get the current calendar or binary mode count
|
||||
- Start and stop the RTC counting
|
||||
- Set alarm conditions
|
||||
- Enable, disable and clear the wakeup interrupt
|
||||
|
||||
@section hw_dependencies Hardware Flow Dependencies
|
||||
The configuration of all features of the MSS RTC is covered by this driver
|
||||
with the exception of the clock source driving the MSS RTC clock (RTCCLK)
|
||||
input. The SmartFusion2 MSS clock controller can supply one of three clock
|
||||
sources to the MSS RTC clock input:
|
||||
- Crystal Oscillator 32.768 kHz
|
||||
- 1MHz Oscillator
|
||||
- 50MHz Oscillator. (25 MHz in a 1.0v part).
|
||||
The SmartFusion2 MSS configurator tool in the hardware flow configures one
|
||||
of these clocks as the RTCCLK input source.
|
||||
The base address and register addresses and interrupt number assignment for
|
||||
the MSS RTC block are defined as constants in the SmartFusion2 CMSIS HAL. You
|
||||
must ensure that the SmartFusion2 CMSIS HAL is either included in the software
|
||||
tool chain used to build your project or is included in your project.
|
||||
|
||||
@section theory_op Theory of Operation
|
||||
The MSS RTC driver functions are grouped into the following categories:
|
||||
- Initialization of the RTC driver and hardware
|
||||
- Setting and reading the RTC counter current value
|
||||
- Setting RTC alarm values
|
||||
- Starting and stopping the RTC
|
||||
- Interrupt Control
|
||||
|
||||
Initialization
|
||||
The MSS RTC driver is initialized through a call to the MSS_RTC_init()
|
||||
function. The MSS_RTC_init() function must be called before any other MSS RTC
|
||||
driver functions are called.
|
||||
The MSS_RTC_init() function:
|
||||
- Stops the RTC counters and disables the RTC alarm
|
||||
- Disables the RTC wakeup interrupt in the RTC and in the Cortex-M3
|
||||
interrupt controller (NVIC).
|
||||
- Clears any pending RTC wakeup interrupt in the RTC and in the Cortex-M3
|
||||
interrupt controller (NVIC).
|
||||
- Enables the RTC_WAKEUP_CR[0] mask bit in the MSS System Register to
|
||||
connect the RTC wakeup interrupt to the Cortex-M3 interrupt controller.
|
||||
- Resets the RTC counters and the alarm and compare registers
|
||||
- Sets the RTC's operating mode to binary counter mode or calendar counter
|
||||
mode, as specified by the mode parameter
|
||||
- Sets the RTC's prescaler register to the value specified by the prescaler
|
||||
parameter. The frequency of the clock source driving the MSS RTC clock
|
||||
(RTCCLK) input is required to calculate the prescaler value.
|
||||
|
||||
Setting and Reading the RTC Counter Value
|
||||
The MSS RTC supports two mode of operation – binary mode and calendar mode.
|
||||
The following functions are used to set and read the current value of the
|
||||
counter when the MSS RTC is configured to operate in binary mode:
|
||||
- MSS_RTC_set_binary_count() – This function is used to set the current
|
||||
value of the RTC binary counter.
|
||||
- MSS_RTC_get_binary_count() – This function is used to read the current
|
||||
value of the RTC binary counter.
|
||||
The following functions are used to set and read the current value of the
|
||||
counter the MSS RTC is configured to operate in calendar mode:
|
||||
- MSS_RTC_set_calendar_count() – This function is used to set the current
|
||||
value of the RTC calendar counter.
|
||||
- MSS_RTC_get_calendar_count() – This function is used to read the current
|
||||
value of the RTC calendar counter.
|
||||
|
||||
The following functions resets the RTC counter in either binary and calendar
|
||||
operating mode:
|
||||
- MSS_RTC_reset_counter() – This function resets the RTC counter.
|
||||
|
||||
Setting RTC Alarms
|
||||
The MSS RTC can generate alarms when the counter matches a specified count
|
||||
value in binary mode or a date and time in calendar mode.
|
||||
The following functions are used to set up alarms:
|
||||
- MSS_RTC_set_binary_count_alarm() – This function sets up one-shot or
|
||||
periodic alarms when the MSS RTC is configured to operate in binary mode.
|
||||
- MSS_RTC_set_calendar_count_alarm() – This function sets up one-shot or
|
||||
periodic alarms when the MSS RTC is configured to operate in calendar
|
||||
mode.
|
||||
Note: The alarm asserts a wakeup interrupt to the Cortex-M3. This function
|
||||
enables the RTC’s wakeup interrupt output, however the RTC wakeup
|
||||
interrupt input to the Cortex-M3 NVIC must be enabled separately by
|
||||
calling the MSS_RTC_enable_irq() function. The alarm can be disabled at
|
||||
any time by calling the MSS_RTC_disable_irq() function. activate
|
||||
|
||||
Starting and Stopping the RTC Counter
|
||||
The following functions start and stop the RTC counter:
|
||||
- MSS_RTC_start() – This function starts the RTC counter.
|
||||
- MSS_RTC_stop() – This function stops the RTC counter.
|
||||
|
||||
Interrupt Control
|
||||
The MSS_RTC_init() function enables the RTC_WAKEUP_CR[0] mask bit in the MSS
|
||||
System Register to connect the RTC wakeup interrupt to the Cortex-M3 interrupt
|
||||
controller.
|
||||
An RTC_Wakeup_IRQHandler() default implementation is defined, with weak
|
||||
linkage, in the SmartFusion2 CMSIS HAL. You must provide your own
|
||||
implementation of the RTC_Wakeup_IRQHandler() function, which will override
|
||||
the default implementation, to suit your application.
|
||||
The function prototype for the RTC wakeup interrupt handler is as follows:
|
||||
void RTC_Wakeup_IRQHandler ( void )
|
||||
The RTC wakeup interrupt is controlled using the following functions:
|
||||
- MSS_RTC_enable_irq() – The MSS_RTC_enable_irq() function enables the RTC
|
||||
to interrupt the Cortex-M3 when a wakeup alarm occurs.
|
||||
- MSS_RTC_disable_irq() – The MSS_RTC_disable_irq() function disables the
|
||||
RTC from interrupting the Cortex-M3 when a wakeup alarm occurs.
|
||||
- MSS_RTC_clear_irq() – The MSS_RTC_clear_irq() function clears a pending
|
||||
RTC wakeup interrupt at the RTC wakeup output. You must call the
|
||||
MSS_RTC_clear_irq() function as part of your implementation of the
|
||||
RTC_Wakeup_IRQHandler() interrupt service routine (ISR) in order to
|
||||
prevent the same interrupt event retriggering a call to the ISR.
|
||||
|
||||
*//*=========================================================================*/
|
||||
#ifndef MSS_RTC_H_
|
||||
#define MSS_RTC_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../../CMSIS/m2sxxx.h"
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_BINARY_MODE constant is used to specify the mode parameter to the
|
||||
MSS_RTC_init() function. The RTC will run in binary mode if this constant is
|
||||
used. In binary mode, the calendar counter counts consecutively from 0 all the
|
||||
way to 2^43.
|
||||
*/
|
||||
#define MSS_RTC_BINARY_MODE 0u
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_CALENDAR_MODE constant is used to specify the mode parameter to
|
||||
the MSS_RTC_init() function. The RTC will run in calendar mode if this
|
||||
constant is used. In calendar mode, the calendar counter counts seconds,
|
||||
minutes, hours, days, months, years, weekdays and weeks.
|
||||
*/
|
||||
#define MSS_RTC_CALENDAR_MODE 1u
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The alarm_value parameter of the MSS_RTC_set_calendar_count_alarm() function
|
||||
is a pointer to an mss_rtc_calendar_t data structure specifying the date and
|
||||
time at which the alarm is to occur. You must assign the required date and
|
||||
time values to the mss_rtc_calendar_t structure before calling the function.
|
||||
Any of the fields of the mss_rtc_calendar_t structure can be set to
|
||||
MSS_RTC_CALENDAR_DONT_CARE, to indicate that they are not to be considered in
|
||||
deciding when the alarm will occur; this is necessary when setting periodic
|
||||
alarms.
|
||||
*/
|
||||
#define MSS_RTC_CALENDAR_DONT_CARE 0xFFu
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
Days of the week.
|
||||
*/
|
||||
#define MSS_RTC_SUNDAY 1u
|
||||
#define MSS_RTC_MONDAY 2u
|
||||
#define MSS_RTC_TUESDAY 3u
|
||||
#define MSS_RTC_WEDNESDAY 4u
|
||||
#define MSS_RTC_THRUSDAY 5u
|
||||
#define MSS_RTC_FRIDAY 6u
|
||||
#define MSS_RTC_SATURDAY 7u
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The mss_rtc_alarm_type_t enumeration is used as the alarm_type parameter for
|
||||
the MSS_RTC_set_calendar_count_alarm() and MSS_RTC_set_binary_count_alarm()
|
||||
functions to specify whether the requested alarm should occur only one time or
|
||||
periodically.
|
||||
*/
|
||||
typedef enum {
|
||||
MSS_RTC_SINGLE_SHOT_ALARM,
|
||||
MSS_RTC_PERIODIC_ALARM
|
||||
} mss_rtc_alarm_type_t;
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
A pointer to an instance of the mss_rtc_calender_t data structure is used to
|
||||
write new date and time values to the RTC using the
|
||||
MSS_RTC_set_rtc_calendar_count() and MSS_RTC_set_calendar_count_alarm()
|
||||
functions. The MSS_RTC_get_calendar_count() function also uses a pointer to an
|
||||
instance of the mss_rtc_calender_t data structure to read the current date and
|
||||
time value from the RTC.
|
||||
*/
|
||||
typedef struct mss_rtc_calendar
|
||||
{
|
||||
uint8_t second;
|
||||
uint8_t minute;
|
||||
uint8_t hour;
|
||||
uint8_t day;
|
||||
uint8_t month;
|
||||
uint8_t year;
|
||||
uint8_t weekday;
|
||||
uint8_t week;
|
||||
} mss_rtc_calendar_t ;
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_init() function initializes the RTC driver and hardware to a known
|
||||
state.
|
||||
To initialize the RTC hardware, this function:
|
||||
- Stops the RTC counters and disables the RTC alarm
|
||||
- Disables the RTC wakeup interrupt in the RTC and in the Cortex-M3
|
||||
interrupt controller (NVIC).
|
||||
- Clears any pending RTC wakeup interrupt in the RTC and in the Cortex-M3
|
||||
interrupt controller (NVIC).
|
||||
- Resets the RTC counters and the alarm and compare registers
|
||||
- Sets the RTC's operating mode to binary counter mode or calendar counter
|
||||
mode, as specified by the mode parameter
|
||||
- Sets the RTC's prescaler register to the value specified by the prescaler
|
||||
parameter
|
||||
The MSS clock controller can supply one of three clock sources to the RTC
|
||||
clock input (RTCCLK):
|
||||
- Crystal Oscillator 32.768 kHz
|
||||
- 1MHz Oscillator
|
||||
- 50MHz Oscillator. (25 MHz in a 1.0v part).
|
||||
For calendar mode, program the prescaler register to generate a 1Hz signal
|
||||
from the active RTCCLK according to the following equation:
|
||||
prescaler = RTCCLK – 1 (where RTCCLK unit is Hz)
|
||||
For a 32.768 kHz clock, set the prescaler to 32768 - 1 = 32767. The prescaler
|
||||
register is 26 bits wide, allowing clock sources of up to 67 MHz to generate
|
||||
the 1Hz time base.
|
||||
For binary mode, the prescaler register can be programmed to generate a 1Hz
|
||||
time base or a different time base, as required.
|
||||
|
||||
@param mode
|
||||
The mode parameter is used to specify the operating mode of the RTC. The
|
||||
allowed values for mode are:
|
||||
- MSS_RTC_BINARY_MODE
|
||||
- MSS_RTC_CALENDAR_MODE
|
||||
|
||||
@param prescaler
|
||||
The prescaler parameter specifies the value to divide the incoming RTC clock
|
||||
by, to generate the RTC time base signal. For calendar mode, set the
|
||||
prescaler value to generate a 1Hz time base from the incoming RTC clock
|
||||
according to the following equation:
|
||||
prescaler = RTCCLK – 1 (where the RTCCLK unit is Hz)
|
||||
For binary mode, set the prescaler value to generate a 1Hz time base or a
|
||||
different time base, as required.
|
||||
The prescaler parameter can be any integer value in the range 2 to 2^26.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
|
||||
The example code below shows how the RTC can be initialized only after a power-on
|
||||
reset.
|
||||
@code
|
||||
#define PO_RESET_DETECT_MASK 0x00000001u
|
||||
|
||||
void init_application(void)
|
||||
{
|
||||
uint32_t power_on_reset;
|
||||
power_on_reset = SYSREG->RESET_SOURCE_CR & PO_RESET_DETECT_MASK;
|
||||
if(power_on_reset)
|
||||
{
|
||||
MSS_RTC_init(MSS_RTC_CALENDAR_MODE, 32767);
|
||||
SYSREG->RESET_SOURCE_CR = PO_RESET_DETECT_MASK;
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
void
|
||||
MSS_RTC_init
|
||||
(
|
||||
uint8_t mode,
|
||||
uint32_t prescaler
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_set_rtc_calendar_count() function sets the current value of the
|
||||
RTC calendar counter.
|
||||
Note: This function must only be used when the RTC is configured to operate in
|
||||
calendar counter mode.
|
||||
|
||||
@param new_rtc_value
|
||||
The new_rtc_value parameter is a pointer to an mss_rtc_calendar_t data
|
||||
structure specifying the new date and time value from which the RTC will
|
||||
increment. You must populate the mss_rtc_calendar_t structure with the
|
||||
required date and time values before calling this function.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
*/
|
||||
|
||||
void
|
||||
MSS_RTC_set_calendar_count
|
||||
(
|
||||
const mss_rtc_calendar_t *new_rtc_value
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_set_binary_count() function sets the current value of the RTC
|
||||
binary counter.
|
||||
Note: This function must only be used when the RTC is configured to operate in
|
||||
binary counter mode.
|
||||
|
||||
@param new_rtc_value
|
||||
The new_rtc_value parameter specifies the new count value from which the RTC
|
||||
will increment. The binary counter is 43 bits wide, so the maximum allowed
|
||||
binary value is 2^43.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
*/
|
||||
|
||||
void
|
||||
MSS_RTC_set_binary_count
|
||||
(
|
||||
uint64_t new_rtc_value
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_get_calendar_count() function returns the current value of the RTC
|
||||
calendar counter via the data structure pointed to by the p_rtc_calendar
|
||||
parameter.
|
||||
Note: This function must only be used when the RTC is configured to operate in
|
||||
calendar counter mode.
|
||||
|
||||
@param p_rtc_calendar
|
||||
The p_rtc_calendar parameter is a pointer to an mss_rtc_calendar_t data
|
||||
structure where the current value of the calendar counter will be written by
|
||||
the MSS_RTC_get_calendar_count() function
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
*/
|
||||
void
|
||||
MSS_RTC_get_calendar_count
|
||||
(
|
||||
mss_rtc_calendar_t *p_rtc_calendar
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_get_binary_count() function returns the current value of the RTC
|
||||
binary counter.
|
||||
Note: This function must only be used when the RTC is configured to operate in
|
||||
binary counter mode.
|
||||
|
||||
@param
|
||||
This function takes no parameters.
|
||||
|
||||
@return
|
||||
This function returns the current value of the RTC binary counter as an
|
||||
unsigned 64-bit integer.
|
||||
*/
|
||||
uint64_t
|
||||
MSS_RTC_get_binary_count(void);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_start() function starts the RTC incrementing.
|
||||
|
||||
@param
|
||||
This function takes no parameters.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
*/
|
||||
void MSS_RTC_start(void);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_stop() function stops the RTC from incrementing.
|
||||
|
||||
@param
|
||||
This function takes no parameters.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
*/
|
||||
void MSS_RTC_stop(void);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_reset_counter() function resets the RTC counters. If the counter
|
||||
was running before calling this function, then it continues incrementing from
|
||||
the counter’s reset value.
|
||||
|
||||
@param
|
||||
This function takes no parameters.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
*/
|
||||
void MSS_RTC_reset_counter(void);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_enable_irq() function enables the RTC wakeup output to interrupt
|
||||
the Cortex-M3 when an alarm occurs. It enables the RTC wakeup interrupt
|
||||
(RTC_Wakeup_IRQn) in the Cortex-M3 interrupt controller (NVIC). The
|
||||
RTC_Wakeup_IRQHandler() function will be called when an RTC wakeup interrupt
|
||||
occurs.
|
||||
Note: An RTC_Wakeup_IRQHandler() default implementation is defined, with weak
|
||||
linkage, in the SmartFusion2 CMSIS HAL. You must provide your own
|
||||
implementation of the RTC_Wakeup_IRQHandler() function, which will
|
||||
override the default implementation, to suit your application.
|
||||
Note: This function only enables the RTC wakeup interrupt at the Cortex-M3
|
||||
NVIC level. The alarm setting functions enable the wakeup interrupt
|
||||
output from the RTC.
|
||||
*/
|
||||
void MSS_RTC_enable_irq(void);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_disable_irq() function disables the RTC wakeup interrupt
|
||||
(RTC_Wakeup_IRQn) in the Cortex-M3 interrupt controller (NVIC).
|
||||
Note: This function only disables the RTC wakeup interrupt at the Cortex-M3
|
||||
NVIC level. It does not disable the wakeup interrupt output from the
|
||||
RTC.
|
||||
|
||||
@param
|
||||
This function takes no parameters.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
*/
|
||||
void MSS_RTC_disable_irq(void);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_clear_irq() function clears a pending wakeup interrupt from the
|
||||
RTC. This function does not clear the interrupt in the Cortex-M3 interrupt
|
||||
controller (NVIC); it only clears the wakeup output from the RTC.
|
||||
Note: You must call the MSS_RTC_clear_irq() function as part of your
|
||||
implementation of the RTC_Wakeup_IRQHandler() RTC wakeup interrupt
|
||||
service routine (ISR) in order to prevent the same interrupt event
|
||||
retriggering a call to the ISR.
|
||||
|
||||
@param
|
||||
This function takes no parameters.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
|
||||
Example:
|
||||
The example code below demoinstrates how the MSS_RTC_clear_irq() function is
|
||||
intended to be used as part of the RTC wakeup interrupt servicer routine used
|
||||
by an application to handle RTC alarms.
|
||||
@code
|
||||
#if defined(__GNUC__)
|
||||
__attribute__((__interrupt__)) void RTC_Wakeup_IRQHandler( void )
|
||||
#else
|
||||
void RTC_Wakeup_IRQHandler( void )
|
||||
#endif
|
||||
{
|
||||
process_alarm();
|
||||
MSS_RTC_clear_irq();
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
void MSS_RTC_clear_irq(void);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_set_calendar_count_alarm() function sets up the RTC to generate an
|
||||
alarm when the RTC count reaches the time/date specified by the alarm_value
|
||||
parameter. The alarm asserts a wakeup interrupt to the Cortex-M3. This
|
||||
function enables the RTC’s wakeup interrupt output, however the RTC wakeup
|
||||
interrupt input to the Cortex-M3 NVIC must be enabled separately by calling
|
||||
the MSS_RTC_enable_irq() function. The alarm can be disabled at any time by
|
||||
calling the MSS_RTC_disable_irq() function.
|
||||
|
||||
Single-shot alarm
|
||||
The alarm can be a single-shot alarm, which will generate a single wakeup
|
||||
interrupt the first time the RTC count reaches the time/date specified by
|
||||
alarm_value. A single shot alarm is achieved by specifying a value for every
|
||||
field of the mss_rtc_calendar_t data structure pointed to by the alarm_value
|
||||
parameter. The RTC counter will keep incrementing after a single shot alarm
|
||||
occurs.
|
||||
|
||||
Periodic alarm
|
||||
The alarm can also be a periodic alarm, which will generate a wakeup interrupt
|
||||
every time the RTC count reaches the time/date specified by alarm_value, with
|
||||
the counter running in a continuous loop. The periodic alarm can be set to
|
||||
occur every minute, hour, day, month, year, week, day of the week, or any
|
||||
valid combination of these. This is achieved by setting some of the fields of
|
||||
the mss_rtc_calendar_t data structure pointed to by the alarm_value parameter,
|
||||
to MSS_RTC_CALENDAR_DONT_CARE. For example, setting the weekday field to
|
||||
MSS_RTC_MONDAY and all other fields to MSS_RTC_CALENDAR_DONT_CARE will result
|
||||
in an alarm occurring every Monday. You can refine the time at which the alarm
|
||||
will occur by specifying values for the hour, minute and second fields.
|
||||
Note: This function must only be used when the RTC is configured to operate in
|
||||
calendar counter mode.
|
||||
|
||||
@param alarm_value
|
||||
The alarm_value parameter is a pointer to an mss_rtc_calendar_t data
|
||||
structure specifying the date and time at which the alarm is to occur. You
|
||||
must assign the required date and time values to the mss_rtc_calendar_t
|
||||
structure before calling this function. Some of the fields within the
|
||||
mss_rtc_calendar_t structure can be set to MSS_RTC_CALENDAR_DONT_CARE, to
|
||||
indicate that they are not to be considered in deciding when the alarm will
|
||||
occur; this is necessary when setting periodic alarms.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
|
||||
Examples:
|
||||
|
||||
The following example code demonstrates how to configure the RTC to generate a
|
||||
single calendar alarm at a specific date and time. The alarm will only occur
|
||||
once and the RTC will keep incrementing regardless of the alarm taking place.
|
||||
|
||||
@code
|
||||
const mss_rtc_calendar_t initial_calendar_count =
|
||||
{
|
||||
15u, second
|
||||
30u, minute
|
||||
6u, hour
|
||||
6u, day
|
||||
9u, month
|
||||
12u, year
|
||||
5u, weekday
|
||||
37u week
|
||||
};
|
||||
|
||||
mss_rtc_calendar_t alarm_calendar_count =
|
||||
{
|
||||
17u, second
|
||||
30u, minute
|
||||
6u, hour
|
||||
6u, day
|
||||
9u, month
|
||||
12u, year
|
||||
5u, weekday
|
||||
37u week
|
||||
};
|
||||
|
||||
MSS_RTC_init(MSS_RTC_CALENDAR_MODE, RTC_PRESCALER);
|
||||
MSS_RTC_clear_irq();
|
||||
MSS_RTC_set_calendar_count(&initial_calendar_count);
|
||||
MSS_RTC_enable_irq();
|
||||
MSS_RTC_start();
|
||||
|
||||
MSS_RTC_set_calendar_count_alarm(&alarm_calendar_count);
|
||||
@endcode
|
||||
|
||||
The following example code demonstrates how to configure the RTC to generate a
|
||||
periodic calendar alarm. The RTC is configured to generate an alarm every
|
||||
Tuesday at 16:45:00. The alarm will reoccur every week until the RTC wakeup
|
||||
interrupt is disabled using a call to MSS_RTC_disable_irq().
|
||||
|
||||
@code
|
||||
mss_rtc_calendar_t initial_calendar_count =
|
||||
{
|
||||
58u, <--second
|
||||
59u, <--minute
|
||||
23u, <--hour
|
||||
10u, <--day
|
||||
9u, <--month
|
||||
12u, <--year
|
||||
MSS_RTC_MONDAY, <--weekday
|
||||
37u <--week
|
||||
};
|
||||
|
||||
mss_rtc_calendar_t alarm_calendar_count =
|
||||
{
|
||||
MSS_RTC_CALENDAR_DONT_CARE, <--second
|
||||
45u, <--minute
|
||||
16u, <--hour
|
||||
MSS_RTC_CALENDAR_DONT_CARE, <--day
|
||||
MSS_RTC_CALENDAR_DONT_CARE, <--month
|
||||
MSS_RTC_CALENDAR_DONT_CARE, <--year
|
||||
MSS_RTC_TUESDAY, <--weekday
|
||||
MSS_RTC_CALENDAR_DONT_CARE <--week
|
||||
};
|
||||
|
||||
MSS_RTC_init(MSS_RTC_CALENDAR_MODE, RTC_PRESCALER);
|
||||
MSS_RTC_set_calendar_count(&initial_calendar_count);
|
||||
MSS_RTC_enable_irq();
|
||||
MSS_RTC_start();
|
||||
|
||||
MSS_RTC_set_calendar_count_alarm(&alarm_calendar_count);
|
||||
@endcode
|
||||
|
||||
The following example code demonstrates the code that you need to include in
|
||||
your application to handle alarms. It is the interrupt service routine for the
|
||||
RTC wakeup interrupt input to the Cortex-M3 NVIC. You need to add your
|
||||
application code in this function in place of the process_alarm() function but
|
||||
you must retain the call to MSS_RTC_clear_irq() to ensure that the same alarm
|
||||
does not retrigger the interrupt.
|
||||
|
||||
@code
|
||||
#if defined(__GNUC__)
|
||||
__attribute__((__interrupt__)) void RTC_Wakeup_IRQHandler( void )
|
||||
#else
|
||||
void RTC_Wakeup_IRQHandler( void )
|
||||
#endif
|
||||
{
|
||||
process_alarm();
|
||||
MSS_RTC_clear_irq();
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
void MSS_RTC_set_calendar_count_alarm
|
||||
(
|
||||
const mss_rtc_calendar_t * alarm_value
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_set_binary_count_alarm() function sets up the RTC to generate an
|
||||
alarm when the RTC count reaches the value specified by the alarm_value
|
||||
parameter. The alarm asserts a wakeup interrupt to the Cortex-M3. This
|
||||
function enables the RTC’s wakeup interrupt output, however the RTC wakeup
|
||||
interrupt input to the Cortex-M3 NVIC must be enabled separately by calling
|
||||
the MSS_RTC_enable_irq() function. The alarm can be disabled at any time by
|
||||
calling the MSS_RTC_disable_irq() function.
|
||||
|
||||
Single-shot alarm
|
||||
The alarm can be a single-shot alarm, which will generate a single wakeup
|
||||
interrupt the first time the RTC count reaches the value specified by the
|
||||
alarm_value parameter. Setting the alarm_value parameter to
|
||||
MSS_RTC_PERIODIC_ALARM produces a single-shot alarm. The RTC counter continues
|
||||
incrementing when a single shot alarm occurs.
|
||||
|
||||
Periodic alarm
|
||||
The alarm can also be a periodic alarm, which will generate a wakeup interrupt
|
||||
every time the RTC count reaches the value specified by the alarm_value
|
||||
parameter. Setting the alarm_value parameter to MSS_RTC_SINGLE_SHOT_ALARM
|
||||
produces a periodic alarm. The RTC counter automatically wraps around to zero
|
||||
and continues incrementing when a periodic alarm occurs.
|
||||
Note: This function must only be used when the RTC is configured to operate in
|
||||
binary counter mode
|
||||
|
||||
@param alarm_value
|
||||
The alarm_value parameter is a 64-bit unsigned value specifying the RTC
|
||||
counter value that must be reached for the requested alarm to occur.
|
||||
|
||||
@param alarm_type
|
||||
The alarm_type parameter specifies whether the requested alarm is a single
|
||||
shot or periodic alarm. It can only take one of these two values:
|
||||
- MSS_RTC_SINGLE_SHOT_ALARM,
|
||||
- MSS_RTC_PERIODIC_ALARM
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
*/
|
||||
void MSS_RTC_set_binary_count_alarm
|
||||
(
|
||||
uint64_t alarm_value,
|
||||
mss_rtc_alarm_type_t alarm_type
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_get_update_flag() function indicates if the RTC counter has
|
||||
incremented since the last call to MSS_RTC_clear_update_flag(). It returns
|
||||
zero if no RTC counter increment has occurred. It returns a non-zero value if
|
||||
the RTC counter has incremented. This function can be used whether the RTC is
|
||||
configured to operate in calendar or binary counter mode.
|
||||
|
||||
@return
|
||||
This function returns,
|
||||
zero: if the RTC has not incremented since the last call to
|
||||
MSS_RTC_clear_update_flag(),
|
||||
non-zero: if the RTC has incremented since the last call to
|
||||
MSS_RTC_clear_update_flag().
|
||||
|
||||
|
||||
Example
|
||||
This example waits for the RTC timer to increment by one second.
|
||||
@code
|
||||
void wait_start_of_second(void)
|
||||
{
|
||||
uint32_t rtc_count_updated;
|
||||
MSS_RTC_clear_update_flag();
|
||||
do {
|
||||
rtc_count_updated = MSS_RTC_get_update_flag();
|
||||
} while(!rtc_count_updated)
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
uint32_t MSS_RTC_get_update_flag(void);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_RTC_clear_update_flag() function clears the CONTROL register flag that
|
||||
is set when the RTC counter increments. It is used alongside function
|
||||
MSS_RTC_get_update_flag() to detect RTC counter increments.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
|
||||
Example
|
||||
The example below will wait for the RTC timer to increment by one second.
|
||||
@code
|
||||
void wait_start_of_second(void)
|
||||
{
|
||||
uint32_t rtc_count_updated;
|
||||
MSS_RTC_clear_update_flag();
|
||||
do {
|
||||
rtc_count_updated = MSS_RTC_get_update_flag();
|
||||
} while(!rtc_count_updated)
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
void MSS_RTC_clear_update_flag(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MSS_RTC_H_ */
|
|
@ -0,0 +1,703 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2012 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* SmartFusion2 COMBLK access functions.
|
||||
*
|
||||
* SVN $Revision: 5615 $
|
||||
* SVN $Date: 2013-04-05 14:48:10 +0100 (Fri, 05 Apr 2013) $
|
||||
*/
|
||||
|
||||
#include "mss_comblk.h"
|
||||
#include "../../CMSIS/mss_assert.h"
|
||||
|
||||
/*==============================================================================
|
||||
*
|
||||
*/
|
||||
/*------------------------------------------------------------------------------
|
||||
* Control register bit masks.
|
||||
*/
|
||||
#define CR_FLUSHOUT_MASK 0x01u
|
||||
#define CR_SIZETX_MASK 0x04u
|
||||
#define CR_ENABLE_MASK 0x10u
|
||||
#define CR_LOOPBACK_MASK 0x20u
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Status and interrupt enable registers bit masks.
|
||||
*/
|
||||
#define TXTOKAY_MASK 0x01u
|
||||
#define RCVOKAY_MASK 0x02u
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* DATA8 register bit masks.
|
||||
*/
|
||||
#define DATA8_COMMAND_MASK 0x8000u
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* COMBLK driver states.
|
||||
*/
|
||||
#define COMBLK_IDLE 0u
|
||||
#define COMBLK_TX_CMD 1u
|
||||
#define COMBLK_TX_DATA 2u
|
||||
#define COMBLK_WAIT_RESPONSE 3u
|
||||
#define COMBLK_RX_RESPONSE 4u
|
||||
#define COMBLK_TX_PAGED_DATA 5u
|
||||
|
||||
/*==============================================================================
|
||||
* COMBLK interrupt servcie routine.
|
||||
*/
|
||||
void ComBlk_IRQHandler(void);
|
||||
|
||||
/*==============================================================================
|
||||
* Local functions.
|
||||
*/
|
||||
static void abort_current_cmd(void);
|
||||
static void send_cmd_opcode(uint8_t opcode);
|
||||
static uint32_t fill_tx_fifo(const uint8_t * p_cmd, uint32_t cmd_size);
|
||||
static void handle_tx_okay_irq(void);
|
||||
static void handle_rx_okay_irq(void);
|
||||
static void complete_request(uint16_t response_length);
|
||||
static void process_sys_ctrl_command(uint8_t cmd_opcode);
|
||||
|
||||
/*==============================================================================
|
||||
* Global variables:
|
||||
*/
|
||||
static volatile uint8_t g_comblk_cmd_opcode = 0u;
|
||||
static const uint8_t * g_comblk_p_cmd = 0u;
|
||||
static volatile uint16_t g_comblk_cmd_size = 0u;
|
||||
static const uint8_t * g_comblk_p_data = 0u;
|
||||
static volatile uint32_t g_comblk_data_size = 0u;
|
||||
static uint8_t * g_comblk_p_response = 0u;
|
||||
static uint16_t g_comblk_response_size = 0u;
|
||||
static volatile uint16_t g_comblk_response_idx = 0u;
|
||||
static comblk_completion_handler_t g_comblk_completion_handler = 0;
|
||||
|
||||
/*typedef uint32_t (*comblk_page_handler_t)(uint8_t const ** pp_next_page);
|
||||
*/
|
||||
static uint32_t (*g_comblk_page_handler)(uint8_t const ** pp_next_page) = 0;
|
||||
|
||||
static uint8_t g_request_in_progress = 0u;
|
||||
|
||||
static uint8_t g_comblk_state = COMBLK_IDLE;
|
||||
|
||||
static comblk_async_event_handler_t g_async_event_handler = 0;
|
||||
|
||||
/*==============================================================================
|
||||
*
|
||||
*/
|
||||
void MSS_COMBLK_init(comblk_async_event_handler_t async_event_handler)
|
||||
{
|
||||
/*
|
||||
* Disable and clear previous interrupts.
|
||||
*/
|
||||
NVIC_DisableIRQ(ComBlk_IRQn);
|
||||
COMBLK->INT_ENABLE = 0u;
|
||||
NVIC_ClearPendingIRQ(ComBlk_IRQn);
|
||||
|
||||
g_async_event_handler = async_event_handler;
|
||||
|
||||
/*
|
||||
* Initialialize COMBLK driver state variables:
|
||||
*/
|
||||
g_request_in_progress = 0u;
|
||||
g_comblk_cmd_opcode = 0u;
|
||||
g_comblk_p_cmd = 0u;
|
||||
g_comblk_cmd_size = 0u;
|
||||
g_comblk_p_data = 0u;
|
||||
g_comblk_data_size = 0u;
|
||||
g_comblk_p_response = 0u;
|
||||
g_comblk_response_size = 0u;
|
||||
g_comblk_response_idx = 0u;
|
||||
g_comblk_completion_handler = 0;
|
||||
|
||||
g_comblk_state = COMBLK_IDLE;
|
||||
|
||||
COMBLK->CONTROL |= CR_ENABLE_MASK;
|
||||
COMBLK->CONTROL &= ~CR_LOOPBACK_MASK;
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* Enable receive interrupt to receive asynchronous events from the system
|
||||
* controller.
|
||||
*/
|
||||
COMBLK->INT_ENABLE &= ~TXTOKAY_MASK;
|
||||
COMBLK->INT_ENABLE |= RCVOKAY_MASK;
|
||||
NVIC_EnableIRQ(ComBlk_IRQn);
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
*
|
||||
*/
|
||||
void MSS_COMBLK_send_cmd_with_ptr
|
||||
(
|
||||
uint8_t cmd_opcode,
|
||||
uint32_t cmd_params_ptr,
|
||||
uint8_t * p_response,
|
||||
uint16_t response_size,
|
||||
comblk_completion_handler_t completion_handler
|
||||
)
|
||||
{
|
||||
uint32_t tx_okay;
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* Disable and clear previous interrupts.
|
||||
*/
|
||||
NVIC_DisableIRQ(ComBlk_IRQn);
|
||||
COMBLK->INT_ENABLE = 0u;
|
||||
NVIC_ClearPendingIRQ(ComBlk_IRQn);
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* Abort current command if any.
|
||||
*/
|
||||
abort_current_cmd();
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* Initialialize COMBLK driver state variables:
|
||||
*/
|
||||
g_request_in_progress = 1u;
|
||||
g_comblk_cmd_opcode = cmd_opcode;
|
||||
g_comblk_p_cmd = 0u;
|
||||
g_comblk_cmd_size = 0u;
|
||||
g_comblk_p_data = 0u;
|
||||
g_comblk_data_size = 0u;
|
||||
g_comblk_p_response = p_response;
|
||||
g_comblk_response_size = response_size;
|
||||
g_comblk_response_idx = 0u;
|
||||
g_comblk_page_handler = 0u;
|
||||
g_comblk_completion_handler = completion_handler;
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* Send command opcode as a single byte write to the Tx FIFO.
|
||||
*/
|
||||
send_cmd_opcode(g_comblk_cmd_opcode);
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* Send the command parameters pointer to the Tx FIFO as a single 4 bytes
|
||||
* write to the Tx FIFO.
|
||||
*/
|
||||
COMBLK->CONTROL |= CR_SIZETX_MASK;
|
||||
|
||||
/* Wait for space to become available in Tx FIFO. */
|
||||
do {
|
||||
tx_okay = COMBLK->STATUS & TXTOKAY_MASK;
|
||||
} while(0u == tx_okay);
|
||||
|
||||
/* Send command opcode. */
|
||||
COMBLK->DATA32 = cmd_params_ptr;
|
||||
|
||||
COMBLK->CONTROL &= ~CR_SIZETX_MASK;
|
||||
|
||||
g_comblk_state = COMBLK_WAIT_RESPONSE;
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* Enable interrupt.
|
||||
*/
|
||||
COMBLK->INT_ENABLE |= RCVOKAY_MASK;
|
||||
NVIC_EnableIRQ(ComBlk_IRQn);
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
*
|
||||
*/
|
||||
void MSS_COMBLK_send_cmd
|
||||
(
|
||||
const uint8_t * p_cmd,
|
||||
uint16_t cmd_size,
|
||||
const uint8_t * p_data,
|
||||
uint32_t data_size,
|
||||
uint8_t * p_response,
|
||||
uint16_t response_size,
|
||||
comblk_completion_handler_t completion_handler
|
||||
)
|
||||
{
|
||||
uint32_t size_sent;
|
||||
|
||||
ASSERT(cmd_size > 0);
|
||||
|
||||
/*
|
||||
* Disable and clear previous interrupts.
|
||||
*/
|
||||
NVIC_DisableIRQ(ComBlk_IRQn);
|
||||
COMBLK->INT_ENABLE = 0u;
|
||||
NVIC_ClearPendingIRQ(ComBlk_IRQn);
|
||||
|
||||
/*
|
||||
* Abort current command if any.
|
||||
*/
|
||||
abort_current_cmd();
|
||||
|
||||
/*
|
||||
* Initialialize COMBLK driver state variables:
|
||||
*/
|
||||
g_request_in_progress = 1u;
|
||||
g_comblk_cmd_opcode = p_cmd[0];
|
||||
g_comblk_p_cmd = p_cmd;
|
||||
g_comblk_cmd_size = cmd_size;
|
||||
g_comblk_p_data = p_data;
|
||||
g_comblk_data_size = data_size;
|
||||
g_comblk_p_response = p_response;
|
||||
g_comblk_response_size = response_size;
|
||||
g_comblk_response_idx = 0u;
|
||||
g_comblk_page_handler = 0u;
|
||||
g_comblk_completion_handler = completion_handler;
|
||||
|
||||
COMBLK->INT_ENABLE |= RCVOKAY_MASK;
|
||||
|
||||
/*
|
||||
* Fill FIFO with command.
|
||||
*/
|
||||
send_cmd_opcode(g_comblk_cmd_opcode);
|
||||
size_sent = fill_tx_fifo(&p_cmd[1], cmd_size - 1u);
|
||||
++size_sent; /* Adjust for opcode byte sent. */
|
||||
if(size_sent < cmd_size)
|
||||
{
|
||||
g_comblk_cmd_size = g_comblk_cmd_size - (uint16_t)size_sent;
|
||||
g_comblk_p_cmd = &g_comblk_p_cmd[size_sent];
|
||||
|
||||
g_comblk_state = COMBLK_TX_CMD;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_comblk_cmd_size = 0u;
|
||||
if(g_comblk_data_size > 0u)
|
||||
{
|
||||
g_comblk_state = COMBLK_TX_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_comblk_state = COMBLK_WAIT_RESPONSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable interrupt.
|
||||
*/
|
||||
NVIC_EnableIRQ(ComBlk_IRQn);
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
*
|
||||
*/
|
||||
void MSS_COMBLK_send_paged_cmd
|
||||
(
|
||||
const uint8_t * p_cmd,
|
||||
uint16_t cmd_size,
|
||||
uint8_t * p_response,
|
||||
uint16_t response_size,
|
||||
uint32_t (*page_read_handler)(uint8_t const **),
|
||||
void (*completion_handler)(uint8_t *, uint16_t)
|
||||
)
|
||||
{
|
||||
uint32_t size_sent;
|
||||
uint8_t irq_enable = 0u;
|
||||
|
||||
ASSERT(cmd_size > 0u);
|
||||
|
||||
/*
|
||||
* Disable and clear previous interrupts.
|
||||
*/
|
||||
NVIC_DisableIRQ(ComBlk_IRQn);
|
||||
COMBLK->INT_ENABLE = 0u;
|
||||
NVIC_ClearPendingIRQ(ComBlk_IRQn);
|
||||
|
||||
/*
|
||||
* Abort current command if any.
|
||||
*/
|
||||
abort_current_cmd();
|
||||
|
||||
/*
|
||||
* Initialialize COMBLK driver state variables:
|
||||
*/
|
||||
g_request_in_progress = 1u;
|
||||
g_comblk_cmd_opcode = p_cmd[0];
|
||||
g_comblk_p_cmd = p_cmd;
|
||||
g_comblk_cmd_size = cmd_size;
|
||||
g_comblk_p_data = 0;
|
||||
g_comblk_data_size = 0u;
|
||||
g_comblk_p_response = p_response;
|
||||
g_comblk_response_size = response_size;
|
||||
g_comblk_response_idx = 0u;
|
||||
g_comblk_page_handler = page_read_handler;
|
||||
g_comblk_completion_handler = completion_handler;
|
||||
|
||||
/*
|
||||
* Fill FIFO with command.
|
||||
*/
|
||||
send_cmd_opcode(g_comblk_cmd_opcode);
|
||||
size_sent = fill_tx_fifo(&p_cmd[1], cmd_size - 1u);
|
||||
++size_sent; /* Adjust for opcode byte sent. */
|
||||
if(size_sent < cmd_size)
|
||||
{
|
||||
g_comblk_cmd_size = g_comblk_cmd_size - (uint16_t)size_sent;
|
||||
g_comblk_p_cmd = &g_comblk_p_cmd[size_sent];
|
||||
|
||||
g_comblk_state = COMBLK_TX_CMD;
|
||||
irq_enable = TXTOKAY_MASK | RCVOKAY_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_comblk_cmd_size = 0u;
|
||||
g_comblk_state = COMBLK_TX_PAGED_DATA;
|
||||
irq_enable = TXTOKAY_MASK | RCVOKAY_MASK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable interrupt.
|
||||
*/
|
||||
COMBLK->INT_ENABLE |= irq_enable;
|
||||
NVIC_EnableIRQ(ComBlk_IRQn);
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* COMBLK interrupt handler.
|
||||
*/
|
||||
void ComBlk_IRQHandler(void)
|
||||
{
|
||||
uint8_t status;
|
||||
uint8_t tx_okay;
|
||||
uint8_t rcv_okay;
|
||||
|
||||
status = (uint8_t)COMBLK->STATUS;
|
||||
|
||||
/* Mask off interrupt that are not enabled.*/
|
||||
status &= COMBLK->INT_ENABLE;
|
||||
|
||||
rcv_okay = status & RCVOKAY_MASK;
|
||||
if(rcv_okay)
|
||||
{
|
||||
handle_rx_okay_irq();
|
||||
}
|
||||
|
||||
tx_okay = status & TXTOKAY_MASK;
|
||||
if(tx_okay)
|
||||
{
|
||||
handle_tx_okay_irq();
|
||||
}
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
*
|
||||
*/
|
||||
static void handle_tx_okay_irq(void)
|
||||
{
|
||||
switch(g_comblk_state)
|
||||
{
|
||||
/*----------------------------------------------------------------------
|
||||
* The TX_OKAY interrupt should only be enabled for states COMBLK_TX_CMD
|
||||
* and COMBLK_TX_DATA.
|
||||
*/
|
||||
case COMBLK_TX_CMD:
|
||||
if(g_comblk_cmd_size > 0u)
|
||||
{
|
||||
uint32_t size_sent;
|
||||
size_sent = fill_tx_fifo(g_comblk_p_cmd, g_comblk_cmd_size);
|
||||
if(size_sent < g_comblk_cmd_size)
|
||||
{
|
||||
g_comblk_cmd_size = g_comblk_cmd_size - (uint16_t)size_sent;
|
||||
g_comblk_p_cmd = &g_comblk_p_cmd[size_sent];
|
||||
}
|
||||
else
|
||||
{
|
||||
g_comblk_cmd_size = 0u;
|
||||
if(g_comblk_data_size > 0u)
|
||||
{
|
||||
g_comblk_state = COMBLK_TX_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_comblk_state = COMBLK_WAIT_RESPONSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* This is an invalid situation indicating a bug in the driver
|
||||
* or corrupted memory.
|
||||
*/
|
||||
ASSERT(0);
|
||||
abort_current_cmd();
|
||||
}
|
||||
break;
|
||||
|
||||
case COMBLK_TX_DATA:
|
||||
if(g_comblk_data_size > 0u)
|
||||
{
|
||||
uint32_t size_sent;
|
||||
size_sent = fill_tx_fifo(g_comblk_p_data, g_comblk_data_size);
|
||||
if(size_sent < g_comblk_data_size)
|
||||
{
|
||||
g_comblk_data_size = g_comblk_data_size - size_sent;
|
||||
g_comblk_p_data = &g_comblk_p_data[size_sent];
|
||||
}
|
||||
else
|
||||
{
|
||||
COMBLK->INT_ENABLE &= ~TXTOKAY_MASK;
|
||||
g_comblk_state = COMBLK_WAIT_RESPONSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* This is an invalid situation indicating a bug in the driver
|
||||
* or corrupted memory.
|
||||
*/
|
||||
ASSERT(0);
|
||||
abort_current_cmd();
|
||||
}
|
||||
break;
|
||||
|
||||
case COMBLK_TX_PAGED_DATA:
|
||||
/*
|
||||
* Read a page of data if required.
|
||||
*/
|
||||
if(0u == g_comblk_data_size)
|
||||
{
|
||||
if(g_comblk_page_handler != 0)
|
||||
{
|
||||
g_comblk_data_size = g_comblk_page_handler(&g_comblk_p_data);
|
||||
if(0u == g_comblk_data_size)
|
||||
{
|
||||
COMBLK->INT_ENABLE &= ~TXTOKAY_MASK;
|
||||
g_comblk_state = COMBLK_WAIT_RESPONSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(0);
|
||||
abort_current_cmd();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Transmit the page data or move to COMBLK_WAIT_RESPONSE state if
|
||||
* no further page data could be obtained by the call to the page
|
||||
* handler above.
|
||||
*/
|
||||
if(0u == g_comblk_data_size)
|
||||
{
|
||||
COMBLK->INT_ENABLE &= ~TXTOKAY_MASK;
|
||||
g_comblk_state = COMBLK_WAIT_RESPONSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t size_sent;
|
||||
size_sent = fill_tx_fifo(g_comblk_p_data, g_comblk_data_size);
|
||||
g_comblk_data_size = g_comblk_data_size - size_sent;
|
||||
g_comblk_p_data = &g_comblk_p_data[size_sent];
|
||||
}
|
||||
break;
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
* The TX_OKAY interrupt should NOT be enabled for states COMBLK_IDLE,
|
||||
* COMBLK_WAIT_RESPONSE and COMBLK_RX_RESPONSE.
|
||||
*/
|
||||
case COMBLK_IDLE:
|
||||
/* Fall through */
|
||||
case COMBLK_WAIT_RESPONSE:
|
||||
/* Fall through */
|
||||
case COMBLK_RX_RESPONSE:
|
||||
/* Fall through */
|
||||
default:
|
||||
COMBLK->INT_ENABLE &= ~TXTOKAY_MASK;
|
||||
complete_request(0u);
|
||||
g_comblk_state = COMBLK_IDLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
*
|
||||
*/
|
||||
static void handle_rx_okay_irq(void)
|
||||
{
|
||||
uint16_t data16;
|
||||
uint16_t is_command;
|
||||
|
||||
data16 = (uint16_t)COMBLK->DATA8;
|
||||
is_command = data16 & DATA8_COMMAND_MASK;
|
||||
|
||||
switch(g_comblk_state)
|
||||
{
|
||||
/*----------------------------------------------------------------------
|
||||
* The RCV_OKAY interrupt should only be enabled for states
|
||||
* COMBLK_WAIT_RESPONSE and COMBLK_RX_RESPONSE.
|
||||
*/
|
||||
case COMBLK_WAIT_RESPONSE:
|
||||
if(is_command)
|
||||
{
|
||||
uint8_t rxed_opcode;
|
||||
rxed_opcode = (uint8_t)data16;
|
||||
if(rxed_opcode == g_comblk_cmd_opcode)
|
||||
{
|
||||
g_comblk_response_idx = 0u;
|
||||
g_comblk_p_response[g_comblk_response_idx] = rxed_opcode;
|
||||
++g_comblk_response_idx;
|
||||
g_comblk_state = COMBLK_RX_RESPONSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
process_sys_ctrl_command(rxed_opcode);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case COMBLK_RX_RESPONSE:
|
||||
if(is_command)
|
||||
{
|
||||
uint8_t rxed_opcode;
|
||||
rxed_opcode = (uint8_t)data16;
|
||||
process_sys_ctrl_command(rxed_opcode);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(g_comblk_response_idx < g_comblk_response_size)
|
||||
{
|
||||
uint8_t rxed_data;
|
||||
|
||||
rxed_data = (uint8_t)data16;
|
||||
g_comblk_p_response[g_comblk_response_idx] = rxed_data;
|
||||
++g_comblk_response_idx;
|
||||
}
|
||||
|
||||
if(g_comblk_response_idx == g_comblk_response_size)
|
||||
{
|
||||
complete_request(g_comblk_response_idx);
|
||||
g_comblk_state = COMBLK_IDLE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
* The RCV_OKAY interrupt should NOT be enabled for states
|
||||
* COMBLK_IDLE, COMBLK_TX_CMD and COMBLK_TX_DATA.
|
||||
*/
|
||||
case COMBLK_TX_PAGED_DATA:
|
||||
/* This is needed because when there is an error, we need to terminate loading the data */
|
||||
if(!is_command)
|
||||
{
|
||||
g_comblk_p_response[1] = (uint8_t)data16;
|
||||
complete_request(2u);
|
||||
g_comblk_state = COMBLK_IDLE;
|
||||
}
|
||||
break;
|
||||
case COMBLK_IDLE:
|
||||
/* Fall through */
|
||||
case COMBLK_TX_CMD:
|
||||
/* Fall through */
|
||||
case COMBLK_TX_DATA:
|
||||
/* Fall through */
|
||||
if(is_command)
|
||||
{
|
||||
uint8_t rxed_opcode;
|
||||
rxed_opcode = (uint8_t)data16;
|
||||
process_sys_ctrl_command(rxed_opcode);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
complete_request(0u);
|
||||
g_comblk_state = COMBLK_IDLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
*
|
||||
*/
|
||||
static void complete_request
|
||||
(
|
||||
uint16_t response_length
|
||||
)
|
||||
{
|
||||
if(g_comblk_completion_handler != 0)
|
||||
{
|
||||
g_comblk_completion_handler(g_comblk_p_response, response_length);
|
||||
g_comblk_completion_handler = 0;
|
||||
g_request_in_progress = 0u;
|
||||
}
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
*
|
||||
*/
|
||||
static void abort_current_cmd(void)
|
||||
{
|
||||
if(g_request_in_progress)
|
||||
{
|
||||
uint32_t flush_in_progress;
|
||||
|
||||
/*
|
||||
* Call completion handler just in case we are in a multi threaded system
|
||||
* to avoid a task lockup.
|
||||
*/
|
||||
complete_request(g_comblk_response_idx);
|
||||
|
||||
/*
|
||||
* Flush the FIFOs
|
||||
*/
|
||||
COMBLK->CONTROL |= CR_FLUSHOUT_MASK;
|
||||
do {
|
||||
flush_in_progress = COMBLK->CONTROL & CR_FLUSHOUT_MASK;
|
||||
} while(flush_in_progress);
|
||||
}
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
*
|
||||
*/
|
||||
static void send_cmd_opcode
|
||||
(
|
||||
uint8_t opcode
|
||||
)
|
||||
{
|
||||
uint32_t tx_okay;
|
||||
|
||||
/* Set transmit FIFO to transfer bytes. */
|
||||
COMBLK->CONTROL &= ~CR_SIZETX_MASK;
|
||||
|
||||
/* Wait for space to become available in Tx FIFO. */
|
||||
do {
|
||||
tx_okay = COMBLK->STATUS & TXTOKAY_MASK;
|
||||
} while(0u == tx_okay);
|
||||
|
||||
/* Send command opcode. */
|
||||
COMBLK->FRAME_START8 = opcode;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
*
|
||||
*/
|
||||
static uint32_t fill_tx_fifo
|
||||
(
|
||||
const uint8_t * p_cmd,
|
||||
uint32_t cmd_size
|
||||
)
|
||||
{
|
||||
volatile uint32_t tx_okay;
|
||||
uint32_t size_sent;
|
||||
|
||||
/* Set transmit FIFO to transfer bytes. */
|
||||
COMBLK->CONTROL &= ~CR_SIZETX_MASK;
|
||||
|
||||
size_sent = 0u;
|
||||
tx_okay = COMBLK->STATUS & TXTOKAY_MASK;
|
||||
while((tx_okay != 0u) && (size_sent < cmd_size))
|
||||
{
|
||||
COMBLK->DATA8 = p_cmd[size_sent];
|
||||
++size_sent;
|
||||
tx_okay = COMBLK->STATUS & TXTOKAY_MASK;
|
||||
}
|
||||
|
||||
return size_sent;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
*
|
||||
*/
|
||||
static void process_sys_ctrl_command(uint8_t cmd_opcode)
|
||||
{
|
||||
if(g_async_event_handler != 0)
|
||||
{
|
||||
g_async_event_handler(cmd_opcode);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2012 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* SmartFusion2 COMBLK access functions.
|
||||
*
|
||||
* SVN $Revision: 5160 $
|
||||
* SVN $Date: 2013-03-14 14:50:49 +0000 (Thu, 14 Mar 2013) $
|
||||
*/
|
||||
#ifndef __MSS_COMBLK_H_
|
||||
#define __MSS_COMBLK_H_ 1
|
||||
|
||||
#include "../../CMSIS/m2sxxx.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
typedef void(*comblk_completion_handler_t)(uint8_t * p_response, uint16_t response_size);
|
||||
|
||||
typedef uint32_t (*comblk_page_handler_t)(uint8_t const ** pp_next_page);
|
||||
|
||||
typedef void (*comblk_async_event_handler_t)(uint8_t event_opcode);
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void MSS_COMBLK_init(comblk_async_event_handler_t async_event_handler);
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void MSS_COMBLK_send_cmd_with_ptr
|
||||
(
|
||||
uint8_t cmd_opcode,
|
||||
uint32_t cmd_params_ptr,
|
||||
uint8_t * p_response,
|
||||
uint16_t response_size,
|
||||
comblk_completion_handler_t completion_handler
|
||||
);
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void MSS_COMBLK_send_cmd
|
||||
(
|
||||
const uint8_t * p_cmd,
|
||||
uint16_t cmd_size,
|
||||
const uint8_t * p_data,
|
||||
uint32_t data_size,
|
||||
uint8_t * p_response,
|
||||
uint16_t response_size,
|
||||
comblk_completion_handler_t completion_handler
|
||||
);
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void MSS_COMBLK_read
|
||||
(
|
||||
const uint8_t * p_data,
|
||||
uint16_t cmd_size,
|
||||
uint8_t * p_response,
|
||||
uint16_t response_size,
|
||||
comblk_completion_handler_t completion_handler
|
||||
);
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void MSS_COMBLK_send_paged_cmd
|
||||
(
|
||||
const uint8_t * p_cmd,
|
||||
uint16_t cmd_size,
|
||||
uint8_t * p_response,
|
||||
uint16_t response_size,
|
||||
uint32_t (*)(uint8_t const **),
|
||||
void (*completion_handler)(uint8_t *, uint16_t)
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __MSS_COMBLK_H_ */
|
|
@ -0,0 +1,813 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2012 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* SmartFusion2 system services.
|
||||
*
|
||||
* SVN $Revision: 5615 $
|
||||
* SVN $Date: 2013-04-05 14:48:10 +0100 (Fri, 05 Apr 2013) $
|
||||
*/
|
||||
#include "mss_sys_services.h"
|
||||
#include "mss_comblk.h"
|
||||
#include "../../CMSIS/mss_assert.h"
|
||||
#include <string.h>
|
||||
|
||||
/*==============================================================================
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Service request command opcodes:
|
||||
*/
|
||||
#define DEVICE_CERTIFICATE_REQUEST_CMD 0u
|
||||
#define SERIAL_NUMBER_REQUEST_CMD 1u
|
||||
#define FLASH_FREEZE_REQUEST_CMD 2u
|
||||
#define AES128_REQUEST_CMD 3u
|
||||
#define USERCODE_REQUEST_CMD 4u
|
||||
#define DESIGNVER_REQUEST_CMD 5u
|
||||
#define AES256_REQUEST_CMD 6u
|
||||
#define KEYTREE_REQUEST_CMD 9u
|
||||
#define SHA256_REQUEST_CMD 10u
|
||||
#define HMAC_REQUEST_CMD 12u
|
||||
#define PPUF_CHALLENGE_RESP_REQUEST_CMD 14u
|
||||
#define ISP_PROGRAMMING_REQUEST_CMD 21u
|
||||
#define DIGEST_CHECK_REQUEST_CMD 23u
|
||||
#define NRBG_SELF_TEST_REQUEST_CMD 40u
|
||||
#define NRBG_INSTANTIATE_REQUEST_CMD 41u
|
||||
#define NRBG_GENERATE_REQUEST_CMD 42u
|
||||
#define NRBG_RESEED_REQUEST_CMD 43u
|
||||
#define NRBG_UNINSTANTIATE_REQUEST_CMD 44u
|
||||
#define NRBG_RESET_REQUEST_CMD 45u
|
||||
#define FLASHFREEZE_SHUTDOWN_CMD 224u
|
||||
#define ZEROIZATION_REQUEST_CMD 240u
|
||||
|
||||
#define POWER_ON_RESET_DIGEST_ERROR_CMD 241u
|
||||
|
||||
/*
|
||||
* System Services requests length:
|
||||
*/
|
||||
#define FLASH_FREEZE_REQUEST_LENGTH 2u
|
||||
|
||||
/*
|
||||
* Service response lengths:
|
||||
*/
|
||||
#define STANDARD_SERV_RESP_LENGTH 6u
|
||||
|
||||
#define SERIAL_NUMBER_SERV_RESP_LENGTH 6u
|
||||
#define USERCODE_SERV_RESP_LENGTH 6u
|
||||
#define DESIGNVER_SERV_RESP_LENGTH 6u
|
||||
#define DEVICE_CERT_SERV_RESP_LENGTH 6u
|
||||
#define ISP_PROG_SERV_RESP_LENGTH 2u
|
||||
#define NRBG_RESET_SERV_RESP_LENGTH 2u
|
||||
#define NRBG_SELF_TEST_SERV_RESP_LENGTH 2u
|
||||
#define NRBG_UNINST_SERV_RESP_LENGTH 3u
|
||||
|
||||
#define DIGEST_CHECK_SERV_RESP_LENGTH 2u
|
||||
#define FLASH_FREEZE_SERV_RESP_LENGTH 2u
|
||||
|
||||
/*
|
||||
* Non Deterministic Random Bit Generator defines:
|
||||
*/
|
||||
#define INVALID_NRBG_HANDLE 0xFFu
|
||||
|
||||
/*
|
||||
* RTC_WAKEUP_CR system register bit masks:
|
||||
*/
|
||||
#define RTC_WAKEUP_G4C_EN_MASK 0x00000004u
|
||||
#define RTC_WAKEUP_FAB_EN_MASK 0x00000002u
|
||||
|
||||
/*==============================================================================
|
||||
* Local functions.
|
||||
*/
|
||||
static void request_completion_handler(uint8_t * p_response, uint16_t response_size);
|
||||
static void signal_request_start(void);
|
||||
static uint16_t wait_for_request_completion(void);
|
||||
static uint8_t execute_service
|
||||
(
|
||||
uint8_t cmd_opcode,
|
||||
uint8_t * cmd_params_ptr,
|
||||
uint8_t * response,
|
||||
uint16_t response_length
|
||||
);
|
||||
|
||||
static void asynchronous_event_handler(uint8_t event_opcode);
|
||||
|
||||
static void write_ptr_value_into_array
|
||||
(
|
||||
const uint8_t * pointer,
|
||||
uint8_t target_array[],
|
||||
uint32_t array_index
|
||||
);
|
||||
|
||||
/*==============================================================================
|
||||
* Global variables
|
||||
*/
|
||||
static volatile uint8_t g_request_in_progress = 0u;
|
||||
static volatile uint16_t g_last_response_length = 0u;
|
||||
static sys_serv_async_event_handler_t g_event_handler = 0;
|
||||
|
||||
/*==============================================================================
|
||||
*
|
||||
*/
|
||||
void MSS_SYS_init(sys_serv_async_event_handler_t event_handler)
|
||||
{
|
||||
MSS_COMBLK_init(asynchronous_event_handler);
|
||||
|
||||
g_event_handler = event_handler;
|
||||
|
||||
g_request_in_progress = 0u;
|
||||
g_last_response_length = 0u;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
*
|
||||
*/
|
||||
static void asynchronous_event_handler(uint8_t event_opcode)
|
||||
{
|
||||
if(g_event_handler != 0)
|
||||
{
|
||||
switch(event_opcode)
|
||||
{
|
||||
case FLASH_FREEZE_SHUTDOWN_OPCODE:
|
||||
case FLASH_FREEZE_EXIT_OPCODE:
|
||||
g_event_handler(event_opcode);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Ignore all other events. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* See mss_sys_services.h for details.
|
||||
*/
|
||||
uint8_t MSS_SYS_get_serial_number
|
||||
(
|
||||
uint8_t * p_serial_number
|
||||
)
|
||||
{
|
||||
uint8_t response[SERIAL_NUMBER_SERV_RESP_LENGTH];
|
||||
uint8_t status;
|
||||
|
||||
status = execute_service(SERIAL_NUMBER_REQUEST_CMD,
|
||||
p_serial_number,
|
||||
response,
|
||||
SERIAL_NUMBER_SERV_RESP_LENGTH);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* See mss_sys_services.h for details.
|
||||
*/
|
||||
uint8_t MSS_SYS_get_user_code
|
||||
(
|
||||
uint8_t * p_user_code
|
||||
)
|
||||
{
|
||||
uint8_t response[USERCODE_SERV_RESP_LENGTH];
|
||||
uint8_t status;
|
||||
|
||||
status = execute_service(USERCODE_REQUEST_CMD,
|
||||
p_user_code,
|
||||
response,
|
||||
USERCODE_SERV_RESP_LENGTH);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* See mss_sys_services.h for details.
|
||||
*/
|
||||
uint8_t MSS_SYS_get_design_version
|
||||
(
|
||||
uint8_t * p_design_version
|
||||
)
|
||||
{
|
||||
uint8_t response[DESIGNVER_SERV_RESP_LENGTH];
|
||||
uint8_t status;
|
||||
|
||||
status = execute_service(DESIGNVER_REQUEST_CMD,
|
||||
p_design_version,
|
||||
response,
|
||||
DESIGNVER_SERV_RESP_LENGTH);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* See mss_sys_services.h for details.
|
||||
*/
|
||||
uint8_t MSS_SYS_get_device_certificate
|
||||
(
|
||||
uint8_t * p_device_certificate
|
||||
)
|
||||
{
|
||||
uint8_t response[DEVICE_CERT_SERV_RESP_LENGTH];
|
||||
uint8_t status;
|
||||
|
||||
status = execute_service(DEVICE_CERTIFICATE_REQUEST_CMD,
|
||||
p_device_certificate,
|
||||
response,
|
||||
DEVICE_CERT_SERV_RESP_LENGTH);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* See mss_sys_services.h for details.
|
||||
*/
|
||||
uint8_t MSS_SYS_flash_freeze(uint8_t options)
|
||||
{
|
||||
uint8_t status;
|
||||
uint16_t actual_response_length;
|
||||
uint8_t flash_freeze_req[FLASH_FREEZE_REQUEST_LENGTH];
|
||||
uint8_t response[FLASH_FREEZE_SERV_RESP_LENGTH];
|
||||
|
||||
/*
|
||||
* The Flash Freeze system service is not available on M2S050 rev A and rev B.
|
||||
*/
|
||||
ASSERT(0x0000F802u != SYSREG->DEVICE_VERSION);
|
||||
ASSERT(0x0001F802u != SYSREG->DEVICE_VERSION);
|
||||
|
||||
/*
|
||||
* Enable RTC wake-up interrupt to System Controller and FPGA fabric.
|
||||
*/
|
||||
SYSREG->RTC_WAKEUP_CR |= (RTC_WAKEUP_G4C_EN_MASK | RTC_WAKEUP_FAB_EN_MASK);
|
||||
|
||||
signal_request_start();
|
||||
|
||||
flash_freeze_req[0] = FLASH_FREEZE_REQUEST_CMD;
|
||||
flash_freeze_req[1] = options;
|
||||
|
||||
MSS_COMBLK_send_cmd(flash_freeze_req, /* p_cmd */
|
||||
FLASH_FREEZE_REQUEST_LENGTH, /* cmd_size */
|
||||
0, /* p_data */
|
||||
0u, /* data_size */
|
||||
response, /* p_response */
|
||||
FLASH_FREEZE_SERV_RESP_LENGTH, /* response_size */
|
||||
request_completion_handler); /* completion_handler */
|
||||
|
||||
actual_response_length = wait_for_request_completion();
|
||||
|
||||
if((FLASH_FREEZE_SERV_RESP_LENGTH == actual_response_length) &&
|
||||
(FLASH_FREEZE_REQUEST_CMD == response[0]))
|
||||
{
|
||||
status = response[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
status = MSS_SYS_UNEXPECTED_ERROR;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* See mss_sys_services.h for details.
|
||||
*/
|
||||
#define AES128_KEY_LENGTH 16u
|
||||
#define IV_LENGTH 16u
|
||||
|
||||
#define AES256_KEY_LENGTH 32u
|
||||
|
||||
#define HMAC_KEY_LENGTH 32u
|
||||
|
||||
uint8_t MSS_SYS_128bit_aes
|
||||
(
|
||||
const uint8_t * key,
|
||||
const uint8_t * iv,
|
||||
uint16_t nb_blocks,
|
||||
uint8_t mode,
|
||||
uint8_t * dest_addr,
|
||||
const uint8_t * src_addr)
|
||||
{
|
||||
uint8_t response[STANDARD_SERV_RESP_LENGTH];
|
||||
uint8_t params[44];
|
||||
uint8_t status;
|
||||
|
||||
memcpy(¶ms[0], key, AES128_KEY_LENGTH);
|
||||
memcpy(¶ms[16], iv, IV_LENGTH);
|
||||
|
||||
params[32] = (uint8_t)nb_blocks;
|
||||
params[33] = (uint8_t)(nb_blocks >> 8u);
|
||||
params[34] = mode;
|
||||
params[35] = 0u;
|
||||
#if 1
|
||||
write_ptr_value_into_array(dest_addr, params, 36u);
|
||||
write_ptr_value_into_array(src_addr, params, 40u);
|
||||
#else
|
||||
params[36] = (uint8_t)((uint32_t)dest_addr);
|
||||
params[37] = (uint8_t)((uint32_t)dest_addr >> 8u);
|
||||
params[38] = (uint8_t)((uint32_t)dest_addr >> 16u);
|
||||
params[39] = (uint8_t)((uint32_t)dest_addr >> 24u);
|
||||
|
||||
params[40] = (uint8_t)((uint32_t)src_addr);
|
||||
params[41] = (uint8_t)((uint32_t)src_addr >> 8u);
|
||||
params[42] = (uint8_t)((uint32_t)src_addr >> 16u);
|
||||
params[43] = (uint8_t)((uint32_t)src_addr >> 24u);
|
||||
#endif
|
||||
status = execute_service(AES128_REQUEST_CMD,
|
||||
params,
|
||||
response,
|
||||
STANDARD_SERV_RESP_LENGTH);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* See mss_sys_services.h for details.
|
||||
*/
|
||||
uint8_t MSS_SYS_256bit_aes
|
||||
(
|
||||
const uint8_t * key,
|
||||
const uint8_t * iv,
|
||||
uint16_t nb_blocks,
|
||||
uint8_t mode,
|
||||
uint8_t * dest_addr,
|
||||
const uint8_t * src_addr
|
||||
)
|
||||
{
|
||||
uint8_t response[STANDARD_SERV_RESP_LENGTH];
|
||||
uint8_t params[60];
|
||||
uint8_t status;
|
||||
|
||||
memcpy(¶ms[0], key, AES256_KEY_LENGTH);
|
||||
memcpy(¶ms[32], iv, IV_LENGTH);
|
||||
|
||||
params[48] = (uint8_t)nb_blocks;
|
||||
params[49] = (uint8_t)(nb_blocks >> 8u);
|
||||
params[50] = mode;
|
||||
params[51] = 0u;
|
||||
#if 1
|
||||
write_ptr_value_into_array(dest_addr, params, 52u);
|
||||
write_ptr_value_into_array(src_addr, params, 56u);
|
||||
#else
|
||||
params[52] = (uint8_t)((uint32_t)dest_addr);
|
||||
params[53] = (uint8_t)((uint32_t)dest_addr >> 8u);
|
||||
params[54] = (uint8_t)((uint32_t)dest_addr >> 16u);
|
||||
params[55] = (uint8_t)((uint32_t)dest_addr >> 24u);
|
||||
|
||||
params[56] = (uint8_t)((uint32_t)src_addr);
|
||||
params[57] = (uint8_t)((uint32_t)src_addr >> 8u);
|
||||
params[58] = (uint8_t)((uint32_t)src_addr >> 16u);
|
||||
params[59] = (uint8_t)((uint32_t)src_addr >> 24u);
|
||||
#endif
|
||||
status = execute_service(AES256_REQUEST_CMD,
|
||||
params,
|
||||
response,
|
||||
STANDARD_SERV_RESP_LENGTH);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* See mss_sys_services.h for details.
|
||||
*/
|
||||
uint8_t MSS_SYS_sha256
|
||||
(
|
||||
const uint8_t * p_data_in,
|
||||
uint32_t length,
|
||||
uint8_t * result
|
||||
)
|
||||
{
|
||||
uint8_t response[STANDARD_SERV_RESP_LENGTH];
|
||||
uint8_t params[12];
|
||||
uint8_t status;
|
||||
|
||||
params[0] = (uint8_t)((uint32_t)length);
|
||||
params[1] = (uint8_t)((uint32_t)length >> 8u);
|
||||
params[2] = (uint8_t)((uint32_t)length >> 16u);
|
||||
params[3] = (uint8_t)((uint32_t)length >> 24u);
|
||||
|
||||
#if 1
|
||||
write_ptr_value_into_array(result, params, 4u);
|
||||
write_ptr_value_into_array(p_data_in, params, 8u);
|
||||
#else
|
||||
params[4] = (uint8_t)((uint32_t)result);
|
||||
params[5] = (uint8_t)((uint32_t)result >> 8u);
|
||||
params[6] = (uint8_t)((uint32_t)result >> 16u);
|
||||
params[7] = (uint8_t)((uint32_t)result >> 24u);
|
||||
|
||||
params[8] = (uint8_t)((uint32_t)p_data_in);
|
||||
params[9] = (uint8_t)((uint32_t)p_data_in >> 8u);
|
||||
params[10] = (uint8_t)((uint32_t)p_data_in >> 16u);
|
||||
params[11] = (uint8_t)((uint32_t)p_data_in >> 24u);
|
||||
#endif
|
||||
status = execute_service(SHA256_REQUEST_CMD,
|
||||
params,
|
||||
response,
|
||||
STANDARD_SERV_RESP_LENGTH);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* See mss_sys_services.h for details.
|
||||
*/
|
||||
uint8_t MSS_SYS_hmac
|
||||
(
|
||||
const uint8_t * key,
|
||||
const uint8_t * p_data_in,
|
||||
uint32_t length,
|
||||
uint8_t * p_result
|
||||
)
|
||||
{
|
||||
uint8_t response[STANDARD_SERV_RESP_LENGTH];
|
||||
uint8_t params[58];
|
||||
uint8_t status;
|
||||
|
||||
memcpy(¶ms[0], key, HMAC_KEY_LENGTH);
|
||||
|
||||
params[32] = (uint8_t)((uint32_t)length);
|
||||
params[33] = (uint8_t)((uint32_t)length >> 8u);
|
||||
params[34] = (uint8_t)((uint32_t)length >> 16u);
|
||||
params[35] = (uint8_t)((uint32_t)length >> 24u);
|
||||
#if 1
|
||||
write_ptr_value_into_array(p_data_in, params, 36u);
|
||||
write_ptr_value_into_array(p_result, params, 40u);
|
||||
#else
|
||||
params[36] = (uint8_t)((uint32_t)p_data_in);
|
||||
params[37] = (uint8_t)((uint32_t)p_data_in >> 8u);
|
||||
params[38] = (uint8_t)((uint32_t)p_data_in >> 16u);
|
||||
params[39] = (uint8_t)((uint32_t)p_data_in >> 24u);
|
||||
|
||||
params[40] = (uint8_t)((uint32_t)p_result);
|
||||
params[41] = (uint8_t)((uint32_t)p_result >> 8u);
|
||||
params[42] = (uint8_t)((uint32_t)p_result >> 16u);
|
||||
params[43] = (uint8_t)((uint32_t)p_result >> 24u);
|
||||
#endif
|
||||
status = execute_service(HMAC_REQUEST_CMD,
|
||||
params,
|
||||
response,
|
||||
STANDARD_SERV_RESP_LENGTH);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* See mss_sys_services.h for details.
|
||||
*/
|
||||
uint8_t MSS_SYS_nrbg_self_test(void)
|
||||
{
|
||||
uint8_t status;
|
||||
uint16_t actual_response_length;
|
||||
uint8_t self_test;
|
||||
uint8_t response[NRBG_SELF_TEST_SERV_RESP_LENGTH];
|
||||
|
||||
signal_request_start();
|
||||
|
||||
self_test = NRBG_SELF_TEST_REQUEST_CMD;
|
||||
|
||||
MSS_COMBLK_send_cmd(&self_test, /* p_cmd */
|
||||
sizeof(self_test), /* cmd_size */
|
||||
0, /* p_data */
|
||||
0, /* data_size */
|
||||
response, /* p_response */
|
||||
NRBG_SELF_TEST_SERV_RESP_LENGTH, /* response_size */
|
||||
request_completion_handler); /* completion_handler */
|
||||
|
||||
actual_response_length = wait_for_request_completion();
|
||||
|
||||
if((NRBG_SELF_TEST_SERV_RESP_LENGTH == actual_response_length) &&
|
||||
(NRBG_SELF_TEST_REQUEST_CMD == response[0]))
|
||||
{
|
||||
status = response[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
status = MSS_SYS_UNEXPECTED_ERROR;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* See mss_sys_services.h for details.
|
||||
*/
|
||||
uint8_t MSS_SYS_nrbg_instantiate
|
||||
(
|
||||
const uint8_t * personalization_str,
|
||||
uint16_t personalization_str_length,
|
||||
uint8_t * p_nrbg_handle
|
||||
)
|
||||
{
|
||||
uint8_t response[STANDARD_SERV_RESP_LENGTH];
|
||||
uint8_t intantiate_params[7];
|
||||
uint8_t status;
|
||||
#if 1
|
||||
write_ptr_value_into_array(personalization_str, intantiate_params, 0u);
|
||||
#else
|
||||
intantiate_params[0] = (uint8_t)((uint32_t)personalization_str);
|
||||
intantiate_params[1] = (uint8_t)((uint32_t)personalization_str >> 8u);
|
||||
intantiate_params[2] = (uint8_t)((uint32_t)personalization_str >> 16u);
|
||||
intantiate_params[3] = (uint8_t)((uint32_t)personalization_str >> 24u);
|
||||
#endif
|
||||
intantiate_params[4] = (uint8_t)personalization_str_length;
|
||||
intantiate_params[5] = (uint8_t)(personalization_str_length >> 8u);
|
||||
intantiate_params[6] = INVALID_NRBG_HANDLE;
|
||||
|
||||
status = execute_service(NRBG_INSTANTIATE_REQUEST_CMD,
|
||||
intantiate_params,
|
||||
response,
|
||||
STANDARD_SERV_RESP_LENGTH);
|
||||
|
||||
if(MSS_SYS_SUCCESS == status)
|
||||
{
|
||||
*p_nrbg_handle = intantiate_params[6];
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* See mss_sys_services.h for details.
|
||||
*/
|
||||
uint8_t MSS_SYS_nrbg_generate
|
||||
(
|
||||
const uint8_t * p_requested_data,
|
||||
const uint8_t * p_additional_input,
|
||||
uint8_t requested_length,
|
||||
uint8_t additional_input_length,
|
||||
uint8_t pr_req,
|
||||
uint8_t nrbg_handle
|
||||
)
|
||||
{
|
||||
uint8_t response[STANDARD_SERV_RESP_LENGTH];
|
||||
uint8_t generate_params[12];
|
||||
uint8_t status;
|
||||
#if 1
|
||||
write_ptr_value_into_array(p_requested_data, generate_params, 0u);
|
||||
write_ptr_value_into_array(p_additional_input, generate_params, 4u);
|
||||
#else
|
||||
generate_params[0] = (uint8_t)((uint32_t)p_requested_data);
|
||||
generate_params[1] = (uint8_t)((uint32_t)p_requested_data >> 8u);
|
||||
generate_params[2] = (uint8_t)((uint32_t)p_requested_data >> 16u);
|
||||
generate_params[3] = (uint8_t)((uint32_t)p_requested_data >> 24u);
|
||||
generate_params[4] = (uint8_t)((uint32_t)p_additional_input);
|
||||
generate_params[5] = (uint8_t)((uint32_t)p_additional_input >> 8u);
|
||||
generate_params[6] = (uint8_t)((uint32_t)p_additional_input >> 16u);
|
||||
generate_params[7] = (uint8_t)((uint32_t)p_additional_input >> 24u);
|
||||
#endif
|
||||
generate_params[8] = requested_length;
|
||||
generate_params[9] = additional_input_length;
|
||||
generate_params[10] = pr_req;
|
||||
generate_params[11] = nrbg_handle;
|
||||
|
||||
status = execute_service(NRBG_GENERATE_REQUEST_CMD,
|
||||
generate_params,
|
||||
response,
|
||||
STANDARD_SERV_RESP_LENGTH);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* See mss_sys_services.h for details.
|
||||
*/
|
||||
uint8_t MSS_SYS_nrbg_reseed
|
||||
(
|
||||
const uint8_t * p_additional_input,
|
||||
uint8_t additional_input_length,
|
||||
uint8_t nrbg_handle
|
||||
)
|
||||
{
|
||||
uint8_t response[STANDARD_SERV_RESP_LENGTH];
|
||||
uint8_t params[6];
|
||||
uint8_t status;
|
||||
#if 1
|
||||
write_ptr_value_into_array(p_additional_input, params, 0u);
|
||||
#else
|
||||
params[0] = (uint8_t)((uint32_t)p_additional_input);
|
||||
params[1] = (uint8_t)((uint32_t)p_additional_input >> 8u);
|
||||
params[2] = (uint8_t)((uint32_t)p_additional_input >> 16u);
|
||||
params[3] = (uint8_t)((uint32_t)p_additional_input >> 24u);
|
||||
#endif
|
||||
params[4] = (uint8_t)additional_input_length;
|
||||
params[5] = nrbg_handle;
|
||||
|
||||
status = execute_service(NRBG_RESEED_REQUEST_CMD,
|
||||
params,
|
||||
response,
|
||||
STANDARD_SERV_RESP_LENGTH);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* See mss_sys_services.h for details.
|
||||
*/
|
||||
uint8_t MSS_SYS_nrbg_uninstantiate
|
||||
(
|
||||
uint8_t nrbg_handle
|
||||
)
|
||||
{
|
||||
uint8_t status;
|
||||
uint16_t actual_response_length;
|
||||
uint8_t uninstantiate_req[2];
|
||||
uint8_t response[NRBG_UNINST_SERV_RESP_LENGTH];
|
||||
|
||||
signal_request_start();
|
||||
|
||||
uninstantiate_req[0] = NRBG_UNINSTANTIATE_REQUEST_CMD;
|
||||
uninstantiate_req[1] = nrbg_handle;
|
||||
|
||||
MSS_COMBLK_send_cmd(uninstantiate_req, /* p_cmd */
|
||||
sizeof(uninstantiate_req), /* cmd_size */
|
||||
0, /* p_data */
|
||||
0, /* data_size */
|
||||
response, /* p_response */
|
||||
NRBG_UNINST_SERV_RESP_LENGTH, /* response_size */
|
||||
request_completion_handler); /* completion_handler */
|
||||
|
||||
actual_response_length = wait_for_request_completion();
|
||||
|
||||
if((NRBG_UNINST_SERV_RESP_LENGTH == actual_response_length) &&
|
||||
(NRBG_UNINSTANTIATE_REQUEST_CMD == response[0]))
|
||||
{
|
||||
status = response[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
status = MSS_SYS_UNEXPECTED_ERROR;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* See mss_sys_services.h for details.
|
||||
*/
|
||||
static uint8_t g_isp_response[ISP_PROG_SERV_RESP_LENGTH];
|
||||
void (*g_isp_completion_handler)(uint32_t) = 0;
|
||||
|
||||
static void isp_sys_completion_handler
|
||||
(
|
||||
uint8_t * p_response,
|
||||
uint16_t length
|
||||
)
|
||||
{
|
||||
if(g_isp_completion_handler != 0)
|
||||
{
|
||||
g_isp_completion_handler(p_response[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void MSS_SYS_start_isp
|
||||
(
|
||||
uint8_t mode,
|
||||
uint32_t (*page_read_handler)(uint8_t const **),
|
||||
void (*isp_completion_handler)(uint32_t)
|
||||
)
|
||||
{
|
||||
uint8_t isp_prog_request[2];
|
||||
|
||||
signal_request_start();
|
||||
|
||||
isp_prog_request[0] = ISP_PROGRAMMING_REQUEST_CMD;
|
||||
isp_prog_request[1] = mode;
|
||||
|
||||
g_isp_completion_handler = isp_completion_handler;
|
||||
|
||||
MSS_COMBLK_send_paged_cmd(isp_prog_request, /* p_cmd */
|
||||
sizeof(isp_prog_request), /* cmd_size */
|
||||
g_isp_response, /* p_response */
|
||||
ISP_PROG_SERV_RESP_LENGTH, /* response_size */
|
||||
page_read_handler, /* page_handler */
|
||||
isp_sys_completion_handler); /* completion_handler */
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
* See mss_sys_services.h for details.
|
||||
*/
|
||||
uint8_t MSS_SYS_check_digest
|
||||
(
|
||||
uint8_t options
|
||||
)
|
||||
{
|
||||
uint8_t status;
|
||||
uint16_t actual_response_length;
|
||||
uint8_t digest_check_req[2];
|
||||
uint8_t response[DIGEST_CHECK_SERV_RESP_LENGTH];
|
||||
|
||||
signal_request_start();
|
||||
|
||||
digest_check_req[0] = DIGEST_CHECK_REQUEST_CMD;
|
||||
digest_check_req[1] = options;
|
||||
|
||||
MSS_COMBLK_send_cmd(digest_check_req, /* p_cmd */
|
||||
sizeof(digest_check_req), /* cmd_size */
|
||||
0, /* p_data */
|
||||
0u, /* data_size */
|
||||
response, /* p_response */
|
||||
DIGEST_CHECK_SERV_RESP_LENGTH, /* response_size */
|
||||
request_completion_handler); /* completion_handler */
|
||||
|
||||
actual_response_length = wait_for_request_completion();
|
||||
|
||||
if((DIGEST_CHECK_SERV_RESP_LENGTH == actual_response_length) &&
|
||||
(DIGEST_CHECK_REQUEST_CMD == response[0]))
|
||||
{
|
||||
status = response[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
status = MSS_SYS_UNEXPECTED_ERROR;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
*
|
||||
*/
|
||||
static uint8_t execute_service
|
||||
(
|
||||
uint8_t cmd_opcode,
|
||||
uint8_t * cmd_params_ptr,
|
||||
uint8_t * response,
|
||||
uint16_t response_length
|
||||
)
|
||||
{
|
||||
uint8_t status;
|
||||
uint16_t actual_response_length;
|
||||
|
||||
signal_request_start();
|
||||
|
||||
MSS_COMBLK_send_cmd_with_ptr(cmd_opcode, /* cmd_opcode */
|
||||
(uint32_t)cmd_params_ptr, /* cmd_params_ptr */
|
||||
response, /* p_response */
|
||||
response_length, /* response_size */
|
||||
request_completion_handler); /* completion_handler */
|
||||
|
||||
actual_response_length = wait_for_request_completion();
|
||||
|
||||
if((response_length == actual_response_length) && (cmd_opcode == response[0]))
|
||||
{
|
||||
status = response[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
status = MSS_SYS_UNEXPECTED_ERROR;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
*
|
||||
*/
|
||||
static void request_completion_handler
|
||||
(
|
||||
uint8_t * p_response,
|
||||
uint16_t response_size
|
||||
)
|
||||
{
|
||||
g_request_in_progress = 0u;
|
||||
g_last_response_length = response_size;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
*
|
||||
*/
|
||||
static void signal_request_start(void)
|
||||
{
|
||||
/* Wait for current request to complete. */
|
||||
while(g_request_in_progress)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
g_request_in_progress = 1u;
|
||||
g_last_response_length = 0u;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
*
|
||||
*/
|
||||
static uint16_t wait_for_request_completion(void)
|
||||
{
|
||||
while(g_request_in_progress)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
return g_last_response_length;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
*
|
||||
*/
|
||||
static void write_ptr_value_into_array
|
||||
(
|
||||
const uint8_t * pointer,
|
||||
uint8_t target_array[],
|
||||
uint32_t array_index
|
||||
)
|
||||
{
|
||||
target_array[array_index] = (uint8_t)((uint32_t)pointer);
|
||||
target_array[array_index + 1] = (uint8_t)((uint32_t)pointer >> 8u);
|
||||
target_array[array_index + 2] = (uint8_t)((uint32_t)pointer >> 16u);
|
||||
target_array[array_index + 3] = (uint8_t)((uint32_t)pointer >> 24u);
|
||||
}
|
||||
|
|
@ -0,0 +1,883 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2012 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* SmartFusion2 MSS System Services bare metal software driver public API.
|
||||
*
|
||||
* SVN $Revision: 5591 $
|
||||
* SVN $Date: 2013-04-04 15:55:11 +0100 (Thu, 04 Apr 2013) $
|
||||
*/
|
||||
|
||||
/*=========================================================================*//**
|
||||
@mainpage SmartFusion2 MSS System Services Bare Metal Driver.
|
||||
|
||||
@section intro_sec Introduction
|
||||
The SmartFusion2 microcontroller subsystem (MSS) includes a communication
|
||||
block (COMM_BLK) allowing it to communicate with the SmartFusion2 System
|
||||
Controller. The SmartFusion2 System Controller performs a variety of system
|
||||
wide services. This software driver provides a set of functions to access
|
||||
these System Services. The driver can be adapted for use as part of an
|
||||
operating system, but the implementation of the adaptation layer between the
|
||||
driver and the operating system's driver model is outside the scope of the
|
||||
driver.
|
||||
|
||||
@section hw_dependencies Hardware Flow Dependencies
|
||||
The MSS System Services driver does not require any configuration. It relies
|
||||
on the SmartFusion2 communication block (MSS_COMM_BLK) to communicate with the
|
||||
System Controller. The MSS_COMM_BLK is always enabled.
|
||||
The base address, register addresses and interrupt number assignment for the
|
||||
MSS_COMM_BLK are defined as constants in the SmartFusion2 CMSIS HAL. You must
|
||||
ensure that the latest SmartFusion2 CMSIS HAL is included in the project
|
||||
settings of the software tool chain used to build your project and that it is
|
||||
generated into your project.
|
||||
|
||||
@section theory_op Theory of Operation
|
||||
The System Services driver provides access to the SmartFusion2 System
|
||||
Controller services. These system services are loosely grouped into the
|
||||
following features:
|
||||
- Reading system information
|
||||
- Cryptography
|
||||
- Non-deterministic random bit generator
|
||||
- Flash*Freeze
|
||||
Note: Refer to the function descriptions for further details about the
|
||||
features of each individual service.
|
||||
|
||||
Reading System Information
|
||||
The System Services driver can be used to read information about the
|
||||
SmartFusion2 device and the design programmed into it using the following
|
||||
functions:
|
||||
- MSS_SYS_get_serial_number()
|
||||
- MSS_SYS_get_user_code()
|
||||
- MSS_SYS_get_design_version()
|
||||
- MSS_SYS_get_device_certificate()
|
||||
|
||||
Cryptography Services
|
||||
The System Services driver provides cryptographic services using the following
|
||||
functions:
|
||||
- MSS_SYS_128bit_aes()
|
||||
- MSS_SYS_256bit_aes()
|
||||
- MSS_SYS_sha256()
|
||||
- MSS_SYS_hmac()
|
||||
|
||||
Non-Deterministic Random Bit Generator
|
||||
The System Services driver provides random number generation services using
|
||||
the following functions:
|
||||
- MSS_SYS_nrbg_instantiate()
|
||||
- MSS_SYS_nrbg_self_test()
|
||||
- MSS_SYS_nrbg_generate()
|
||||
- MSS_SYS_nrbg_reseed()
|
||||
- MSS_SYS_nrbg_uninstantiate()
|
||||
|
||||
Flash*Freeze
|
||||
The System Services driver can be used to request the system to enter
|
||||
Flash*Freeze mode using the following function:
|
||||
- MSS_SYS_flash_freeze()
|
||||
|
||||
*//*=========================================================================*/
|
||||
|
||||
#ifndef __MSS_SYS_SERVICES_H_
|
||||
#define __MSS_SYS_SERVICES_H_ 1
|
||||
|
||||
#include "../../CMSIS/m2sxxx.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*==============================================================================
|
||||
* Status codes:
|
||||
*/
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
These constants are used by multiple services to communicate the outcome of a
|
||||
system services request. These status codes are used across all types of
|
||||
services.
|
||||
|
||||
- MSS_SYS_SUCCESS:
|
||||
Indicates that the system services completed successfully.
|
||||
|
||||
- MSS_SYS_UNEXPECTED_ERROR:
|
||||
Indicates that the system failed in an unexpected way.
|
||||
|
||||
- MSS_SYS_MEM_ACCESS_ERROR:
|
||||
Indicates that the System Controller could not access the memory used to
|
||||
pass parameters to the System Controller or to return a service result to
|
||||
the Cortex-M3.
|
||||
|
||||
- MSS_SYS_SERVICE_DISABLED_BY_FACTORY:
|
||||
Indicates that the requested system service is not available on the
|
||||
SmartFusion2 device.
|
||||
|
||||
- MSS_SYS_SERVICE_DISABLED_BY_USER:
|
||||
Indicates that the requested system service has been disabled as part of
|
||||
the hardware design.
|
||||
*/
|
||||
#define MSS_SYS_SUCCESS 0u
|
||||
#define MSS_SYS_UNEXPECTED_ERROR 200u
|
||||
|
||||
#define MSS_SYS_MEM_ACCESS_ERROR 127u
|
||||
#define MSS_SYS_SERVICE_DISABLED_BY_FACTORY 254u
|
||||
#define MSS_SYS_SERVICE_DISABLED_BY_USER 255u
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* Programming services specific status codes:
|
||||
*/
|
||||
#define MSS_SYS_CHAINING_MISMATCH 1u
|
||||
#define MSS_SYS_UNEXPECTED_DATA_RECEIVED 2u
|
||||
#define MSS_SYS_INVALID_ENCRYPTION_KEY 3u
|
||||
#define MSS_SYS_INVALID_COMPONENT_HEADER 4u
|
||||
#define MSS_SYS_BACK_LEVEL_NOT_SATISFIED 5u
|
||||
#define MSS_SYS_DSN_BINDING_MISMATCH 7u
|
||||
#define MSS_SYS_ILLEGAL_COMPONENT_SEQUENCE 8u
|
||||
#define MSS_SYS_INSUFFICIENT_DEV_CAPABILITIES 9u
|
||||
#define MSS_SYS_INCORRECT_DEVICE_ID 10u
|
||||
#define MSS_SYS_UNSUPPORTED_BITSTREAM_PROT_VER 11u
|
||||
#define MSS_SYS_VERIFY_NOT_PERMITTED_ON_BITSTR 12u
|
||||
#define MSS_SYS_ABORT 127u
|
||||
#define MSS_SYS_NVM_VERIFY_FAILED 129u
|
||||
#define MSS_SYS_DEVICE_SECURITY_PROTECTED 130u
|
||||
#define MSS_SYS_PROGRAMMING_MODE_NOT_ENABLED 131u
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
These constants are used to specify the event_opcode parameter for the
|
||||
event_handler() function registered with the MSS_SYS_init() function. They are
|
||||
used to specify which asynchronous event is notified to the Cortex-M3 software
|
||||
by the System Controller. Asynchronous events are sent by the System
|
||||
Controller to the Cortex-M3 when some system events of interest occur.
|
||||
|
||||
- FLASH_FREEZE_SHUTDOWN_OPCODE:
|
||||
Indicates that the system is being shutdown as a result of entering the
|
||||
Flash*Freeze mode.
|
||||
|
||||
- FLASH_FREEZE_EXIT_OPCODE:
|
||||
Indicates that the system is exiting Flash*Freeze mode.
|
||||
*/
|
||||
#define FLASH_FREEZE_SHUTDOWN_OPCODE 0xE0u
|
||||
#define FLASH_FREEZE_EXIT_OPCODE 0xE1u
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
These constants are used to specify the options parameter for the
|
||||
MSS_SYS_flash_freeze() function.
|
||||
|
||||
- MSS_SYS_FPGA_POWER_DOWN:
|
||||
Indicates that the MSS_SYS_flash_freeze() function should request the FPGA
|
||||
fabric to enter Flash*Freeze mode.
|
||||
|
||||
- MSS_SYS_ENVM0_POWER_DOWN:
|
||||
Indicates that the MSS_SYS_flash_freeze() function should request eNVM0 to
|
||||
enter Flash*Freeze mode.
|
||||
|
||||
- MSS_SYS_ENVM1_POWER_DOWN:
|
||||
Indicates that the MSS_SYS_flash_freeze() function should request eNVM1 to
|
||||
enter Flash*Freeze mode.
|
||||
|
||||
- MSS_SYS_MPLL_POWER_DOWN:
|
||||
Indicates that the MSS_SYS_flash_freeze() function should request the MSS
|
||||
PLL to enter Flash*Freeze mode.
|
||||
*/
|
||||
#define MSS_SYS_FPGA_POWER_DOWN 0x00u
|
||||
#define MSS_SYS_ENVM0_POWER_DOWN 0x01u
|
||||
#define MSS_SYS_ENVM1_POWER_DOWN 0x02u
|
||||
#define MSS_SYS_MPLL_POWER_DOWN 0x04u
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
These constants are used to specify the mode parameter for the
|
||||
MSS_SYS_128aes() and MSS_SYS_256bit_aes() functions.
|
||||
|
||||
- MSS_SYS_ECB_ENCRYPT:
|
||||
Indicates that the cryptography function should perform encryption using
|
||||
the Electronic Codebook (ECB) mode.
|
||||
|
||||
- MSS_SYS_ECB_DECRYPT:
|
||||
Indicates that the cryptography function should perform decryption using
|
||||
the Electronic Codebook (ECB) mode.
|
||||
|
||||
- MSS_SYS_CBC_ENCRYPT:
|
||||
Indicates that the cryptography function should perform encryption using
|
||||
the Cipher-Block Chaining (CBC) mode.
|
||||
|
||||
- MSS_SYS_CBC_DECRYPT:
|
||||
Indicates that the cryptography function should perform decryption using
|
||||
the Cipher-Block Chaining (CBC) mode.
|
||||
|
||||
- MSS_SYS_OFB_ENCRYPT:
|
||||
Indicates that the cryptography function should perform encryption using
|
||||
the Output Feedback (OFB) mode.
|
||||
|
||||
- MSS_SYS_OFB_DECRYPT:
|
||||
Indicates that the cryptography function should perform decryption using
|
||||
the Output Feedback (OFB) mode.
|
||||
|
||||
- MSS_SYS_CTR_ENCRYPT:
|
||||
Indicates that the cryptography function should perform encryption using
|
||||
the Counter (CTR) mode.
|
||||
|
||||
- MSS_SYS_CTR_DECRYPT:
|
||||
Indicates that the cryptography function should perform decryption using
|
||||
the Counter (CTR) mode.
|
||||
*/
|
||||
#define MSS_SYS_ECB_ENCRYPT 0x00u
|
||||
#define MSS_SYS_ECB_DECRYPT 0x80u
|
||||
#define MSS_SYS_CBC_ENCRYPT 0x01u
|
||||
#define MSS_SYS_CBC_DECRYPT 0x81u
|
||||
#define MSS_SYS_OFB_ENCRYPT 0x02u
|
||||
#define MSS_SYS_OFB_DECRYPT 0x82u
|
||||
#define MSS_SYS_CTR_ENCRYPT 0x03u
|
||||
#define MSS_SYS_CTR_DECRYPT 0x83u
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
These constants are used by non deterministic random bit generator (NDRBG)
|
||||
services to communicate the outcome of a system services request. These status
|
||||
codes are only used by NDRBG services.
|
||||
|
||||
- MSS_SYS_NRBG_CATASTROPHIC_ERROR:
|
||||
Indicates that a catastrophic error occurred.
|
||||
|
||||
- MSS_SYS_NRBG_MAX_INST_EXCEEDED:
|
||||
Indicates that the maximum number of NDRBG instances has been exceeded.
|
||||
You need to release already instantiated NDRBG instances using the
|
||||
MSS_SYS_ndrbg_uninstantiate() function.
|
||||
|
||||
- MSS_SYS_NRBG_INVALID_HANDLE:
|
||||
Indicates that the handle parameter has an invalid value.
|
||||
|
||||
- MSS_SYS_NRBG_GEN_REQ_TOO_BIG:
|
||||
Indicates that the requested random number is too long. The requested
|
||||
length is larger than the maximum number of digits that can be generated.
|
||||
|
||||
- MSS_SYS_NRBG_MAX_LENGTH_EXCEEDED:
|
||||
Indicates that the supplied additional data length is exceeded.
|
||||
*/
|
||||
#define MSS_SYS_NRBG_CATASTROPHIC_ERROR 1u
|
||||
#define MSS_SYS_NRBG_MAX_INST_EXCEEDED 2u
|
||||
#define MSS_SYS_NRBG_INVALID_HANDLE 3u
|
||||
#define MSS_SYS_NRBG_GEN_REQ_TOO_BIG 4u
|
||||
#define MSS_SYS_NRBG_MAX_LENGTH_EXCEEDED 5u
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The sys_serv_async_event_handler_t typedef specifies the function prototype of
|
||||
an asynchronous event handler that can be registered with the System Services
|
||||
driver to handle asynchronous events. This is the prototype of a function can
|
||||
be optionally implemented by the application to handle asynchronous events
|
||||
such as Flash*Freeze shutdown and Flash*Freeze exit.
|
||||
*/
|
||||
typedef void (*sys_serv_async_event_handler_t)(uint8_t event_opcode);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
This constant is used as parameter to the MSS_SYS_init() function to indicate
|
||||
that the application code does not supply an asynchronous event handler
|
||||
function.
|
||||
*/
|
||||
#define MSS_SYS_NO_EVENT_HANDLER ((sys_serv_async_event_handler_t)0)
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_SYS_init function initializes the system services communication with
|
||||
the System Controller.
|
||||
|
||||
@param
|
||||
The event_handler parameter specifies an optional asynchronous event
|
||||
handler function. This event handler function is provided by the
|
||||
application. It will be called by the System Services driver whenever an
|
||||
asynchronous event is received from the SmartFusion2 System controller.
|
||||
This event handler is typically used to handle entry and exit of
|
||||
Flash*Freeze mode.
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
*/
|
||||
void MSS_SYS_init(sys_serv_async_event_handler_t event_handler);
|
||||
|
||||
/*==============================================================================
|
||||
* Device and Design Information Services.
|
||||
*/
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_SYS_get_serial_number function fetches the 128-bit Device Serial
|
||||
Number (DSN).
|
||||
|
||||
@param p_serial_number
|
||||
The p_serial_number parameter is a pointer to the 16-bytes buffer where the
|
||||
serial number will be written by this system service.
|
||||
|
||||
@return
|
||||
The MSS_SYS_get_serial_number function returns one of following status codes:
|
||||
- MSS_SYS_SUCCESS
|
||||
- MSS_SYS_MEM_ACCESS_ERROR
|
||||
- MSS_SYS_UNEXPECTED_ERROR
|
||||
*/
|
||||
uint8_t MSS_SYS_get_serial_number
|
||||
(
|
||||
uint8_t * p_serial_number
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_SYS_get_user_code functions fetches the 32-bit USERCODE.
|
||||
|
||||
@param p_user_code
|
||||
The p_user_code parameter is a pointer to the 4-bytes buffer where the
|
||||
USERCODE will be written by this system service.
|
||||
|
||||
@return
|
||||
The MSS_SYS_get_user_code function returns one of following status codes:
|
||||
- MSS_SYS_SUCCESS
|
||||
- MSS_SYS_MEM_ACCESS_ERROR
|
||||
- MSS_SYS_UNEXPECTED_ERROR
|
||||
*/
|
||||
uint8_t MSS_SYS_get_user_code
|
||||
(
|
||||
uint8_t * p_user_code
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_SYS_get_design_version function fetches the design version.
|
||||
|
||||
@param p_design_version
|
||||
The p_design_version parameter is a pointer to the 2-bytes buffer where the
|
||||
design version will be written by this system service.
|
||||
|
||||
@return
|
||||
The MSS_SYS_get_design_version function returns one of following status codes:
|
||||
- MSS_SYS_SUCCESS
|
||||
- MSS_SYS_MEM_ACCESS_ERROR
|
||||
- MSS_SYS_UNEXPECTED_ERROR
|
||||
*/
|
||||
uint8_t MSS_SYS_get_design_version
|
||||
(
|
||||
uint8_t * p_design_version
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_SYS_get_device_certificate function fetches the device certificate.
|
||||
|
||||
@param p_device_certificate
|
||||
The p_device_certificate parameter is a pointer to the 512-bytes buffer
|
||||
where the device certificate will be written by this system service.
|
||||
|
||||
@return
|
||||
The MSS_SYS_get_device_certificate function returns one of following status
|
||||
codes:
|
||||
- MSS_SYS_SUCCESS
|
||||
- MSS_SYS_MEM_ACCESS_ERROR
|
||||
- MSS_SYS_UNEXPECTED_ERROR
|
||||
*/
|
||||
uint8_t MSS_SYS_get_device_certificate
|
||||
(
|
||||
uint8_t * p_device_certificate
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_SYS_flash_freeze function requests the FPGA to enter the Flash*Freeze
|
||||
mode.
|
||||
|
||||
@param options
|
||||
The options parameter can be used to power down additional parts of
|
||||
SmartFusion2 when the FPGA fabric enters Flash*Freeze mode. This parameter
|
||||
is a bit mask of the following options:
|
||||
- MSS_SYS_FPGA_POWER_DOWN
|
||||
- MSS_SYS_ENVM0_POWER_DOWN
|
||||
- MSS_SYS_ENVM1_POWER_DOWN
|
||||
- MSS_SYS_MPLL_POWER_DOWN
|
||||
MSS_SYS_FPGA_POWER_DOWN on its own will only power down the FPGA fabric.
|
||||
MSS_SYS_ENVM0_POWER_DOWN and MSS_SYS_ENVM1_POWER_DOWN specify that eNVM
|
||||
blocks 0 and 1 respectively should enter the deep power down state during
|
||||
Flash*Freeze.
|
||||
MSS_SYS_MPLL_POWER_DOWN specifies that the MSS PLL is powered down during
|
||||
the Flash*Freeze period.
|
||||
|
||||
@return
|
||||
The MSS_SYS_flash_freeze function returns one of following status codes:
|
||||
- MSS_SYS_SUCCESS
|
||||
- MSS_SYS_MEM_ACCESS_ERROR
|
||||
- MSS_SYS_UNEXPECTED_ERROR
|
||||
|
||||
The following example demonstrates how to request the FPGA fabric and both
|
||||
eNVM0 and eNVM1 to enter the Flash*Freeze mode:
|
||||
@code
|
||||
MSS_SYS_flash_freeze(MSS_SYS_FPGA_POWER_DOWN | MSS_SYS_ENVM0_POWER_DOWN | MSS_SYS_MPLL_POWER_DOWN);
|
||||
@endcode
|
||||
*/
|
||||
uint8_t MSS_SYS_flash_freeze(uint8_t options);
|
||||
|
||||
/*==============================================================================
|
||||
* Cryptographic Services.
|
||||
*/
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_SYS_128bit_aes function provides access to the SmartFusion2 AES-128
|
||||
cryptography service.
|
||||
|
||||
@param key
|
||||
The key parameter is a pointer to a 16-bytes array containing the key to use
|
||||
for the requested encryption/decryption operation.
|
||||
|
||||
@param iv
|
||||
The iv parameter is a pointer to a 16-bytes array containing the
|
||||
intialization vector that will be used as part of the requested
|
||||
encryption/decryption operation. Its use is different depending on the mode.
|
||||
-----------------------------------------
|
||||
| Mode | Usage |
|
||||
-----------------------------------------
|
||||
| ECB | Ignored. |
|
||||
-----------------------------------------
|
||||
| CBC | Randomization. |
|
||||
-----------------------------------------
|
||||
| OFB | Randomization. |
|
||||
-----------------------------------------
|
||||
| CTR | Used as initial counter value. |
|
||||
-----------------------------------------
|
||||
|
||||
@param nb_blocks
|
||||
The nb_blocks parameter specifies the number of 128-bit blocks of
|
||||
plaintext/ciphertext to be processed by the AES-128 system service.
|
||||
|
||||
@param mode
|
||||
The mode parameter specifies the cipher mode of operation and whether the
|
||||
source text must be encrypted or decrypted. The modes of operation are:
|
||||
- Electronic Codebook (ECB)
|
||||
- Cipher-Block Chaining (CBC)
|
||||
- Output Feedback (OFB)
|
||||
- Counter (CTR)
|
||||
The CTR mode uses the content of the initialization vector as its intial
|
||||
counter value. The counter increment is 2^64.
|
||||
Allowed values for the mode parameter are:
|
||||
- MSS_SYS_ECB_ENCRYPT
|
||||
- MSS_SYS_ECB_DECRYPT
|
||||
- MSS_SYS_CBC_ENCRYPT
|
||||
- MSS_SYS_CBC_DECRYPT
|
||||
- MSS_SYS_OFB_ENCRYPT
|
||||
- MSS_SYS_OFB_DECRYPT
|
||||
- MSS_SYS_CTR_ENCRYPT
|
||||
- MSS_SYS_CTR_DECRYPT
|
||||
|
||||
@param dest_addr
|
||||
The dest_addr parameter is a pointer to the memory buffer where the result
|
||||
of the encryption/decryption operation will be stored.
|
||||
|
||||
@param src_addr
|
||||
The src_addr parameter is a pointer to the memory buffer containg the source
|
||||
plaintext/ciphertext to be encrypted/decrypted.
|
||||
|
||||
@return
|
||||
The MSS_SYS_128bit_aes function returns one of following status codes:
|
||||
- MSS_SYS_SUCCESS
|
||||
- MSS_SYS_MEM_ACCESS_ERROR
|
||||
- MSS_SYS_SERVICE_DISABLED_BY_USER
|
||||
*/
|
||||
uint8_t MSS_SYS_128bit_aes
|
||||
(
|
||||
const uint8_t * key,
|
||||
const uint8_t * iv,
|
||||
uint16_t nb_blocks,
|
||||
uint8_t mode,
|
||||
uint8_t * dest_addr,
|
||||
const uint8_t * src_addr
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_SYS_256bit_aes function provides access to the SmartFusion2 AES-256
|
||||
cryptography service.
|
||||
|
||||
@param key
|
||||
The key parameter is a pointer to a 32-bytes array containing the key to use
|
||||
for the requested encryption/decryption operation.
|
||||
|
||||
@param iv
|
||||
The iv parameter is a pointer to a 16-bytes array containing the
|
||||
intialization vector that will be used as part of the requested
|
||||
encryption/decryption operation. Its use is different depending on the mode.
|
||||
-----------------------------------------
|
||||
| Mode | Usage |
|
||||
-----------------------------------------
|
||||
| ECB | Ignored. |
|
||||
-----------------------------------------
|
||||
| CBC | Randomization. |
|
||||
-----------------------------------------
|
||||
| OFB | Randomization. |
|
||||
-----------------------------------------
|
||||
| CTR | Used as initial counter value. |
|
||||
-----------------------------------------
|
||||
|
||||
@param nb_blocks
|
||||
The nb_blocks parameter specifies the number of 128-bit blocks of
|
||||
plaintext/ciphertext requested to be processed by the AES-128 system service.
|
||||
|
||||
@param mode
|
||||
The mode parameter specifies the cipher mode of operation and whether the
|
||||
source text must be encrypted or decrypted. The modes of operation are:
|
||||
- Electronic Codebook (ECB)
|
||||
- Cypher-Block Chaining (CBC)
|
||||
- Output Feedback (OFB)
|
||||
- Counter (CTR)
|
||||
The CTR mode uses the content of the initialization vector as its intial
|
||||
counter value. The counter increment is 2^64.
|
||||
Allowed values for the mode parameter are:
|
||||
- MSS_SYS_ECB_ENCRYPT
|
||||
- MSS_SYS_ECB_DECRYPT
|
||||
- MSS_SYS_CBC_ENCRYPT
|
||||
- MSS_SYS_CBC_DECRYPT
|
||||
- MSS_SYS_OFB_ENCRYPT
|
||||
- MSS_SYS_OFB_DECRYPT
|
||||
- MSS_SYS_CTR_ENCRYPT
|
||||
- MSS_SYS_CTR_DECRYPT
|
||||
|
||||
@param dest_addr
|
||||
The dest_addr parameter is a pointer to the memory buffer where the result
|
||||
of the encryption/decryption operation will be stored.
|
||||
|
||||
@param src_addr
|
||||
The src_addr parameter is a pointer to the memory buffer containg the source
|
||||
plaintext/ciphertext to be encrypted/decrypted.
|
||||
|
||||
@return
|
||||
The MSS_SYS_256bit_aes function returns one of following status codes:
|
||||
- MSS_SYS_SUCCESS
|
||||
- MSS_SYS_MEM_ACCESS_ERROR
|
||||
- MSS_SYS_SERVICE_DISABLED_BY_USER
|
||||
*/
|
||||
uint8_t MSS_SYS_256bit_aes
|
||||
(
|
||||
const uint8_t * key,
|
||||
const uint8_t * iv,
|
||||
uint16_t nb_blocks,
|
||||
uint8_t mode,
|
||||
uint8_t * dest_addr,
|
||||
const uint8_t * src_addr
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_SYS_sha256 function provides access to the SmartFusion2 SHA-256
|
||||
cryptography service.
|
||||
|
||||
@param p_data_in
|
||||
The p_data_in parameter is a pointer to the memory location containing the
|
||||
data that will be hashed using the SHA-256 system service.
|
||||
|
||||
@param length
|
||||
The length parameter specifies the length in bits of the data to hash.
|
||||
|
||||
@param result
|
||||
The result parameter is a pointer to a 32 bytes buffer where the hash result
|
||||
will be stored.
|
||||
|
||||
@return
|
||||
The MSS_SYS_sha256 function returns one of following status codes:
|
||||
- MSS_SYS_SUCCESS
|
||||
- MSS_SYS_MEM_ACCESS_ERROR
|
||||
- MSS_SYS_SERVICE_DISABLED_BY_USER
|
||||
*/
|
||||
uint8_t MSS_SYS_sha256
|
||||
(
|
||||
const uint8_t * p_data_in,
|
||||
uint32_t length,
|
||||
uint8_t * result
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_SYS_hmac function provides access to the SmartFusion2 HMAC
|
||||
cryptography service. The HMAC system service generates message authentication
|
||||
codes using the SHA-256 hash function.
|
||||
|
||||
@param key
|
||||
The key parameter is a pointer to a 32 bytes array containing the key used
|
||||
to generate the message authentication code.
|
||||
|
||||
@param p_data_in
|
||||
The p_data_in parameter is a pointer to the data to be authenticated.
|
||||
|
||||
@param length
|
||||
The length parameter specifies the number of data bytes for which to generate
|
||||
the authentication code. It is the size of the data pointed to by the
|
||||
p_data_in parameter.
|
||||
|
||||
@param p_result
|
||||
The p_result parameter is a pointer to a 32 bytes buffer where the
|
||||
authentication code generated by the HMAC system service will be stored.
|
||||
|
||||
@return
|
||||
The MSS_SYS_hmac function returns one of following status codes:
|
||||
- MSS_SYS_SUCCESS
|
||||
- MSS_SYS_MEM_ACCESS_ERROR
|
||||
- MSS_SYS_SERVICE_DISABLED_BY_USER
|
||||
*/
|
||||
uint8_t MSS_SYS_hmac
|
||||
(
|
||||
const uint8_t * key,
|
||||
const uint8_t * p_data_in,
|
||||
uint32_t length,
|
||||
uint8_t * p_result
|
||||
);
|
||||
|
||||
/*==============================================================================
|
||||
* CRI Licensed Services.
|
||||
*/
|
||||
#define SYS_SERVICE_NOT_LICENCED 243u
|
||||
|
||||
/*==============================================================================
|
||||
* Non Deterministic Random Bit Generator Services.
|
||||
*/
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_SYS_nrbg_self_test() function performs a self test of the
|
||||
non-deterministic random bit generator (NRBG).
|
||||
|
||||
@return
|
||||
The MSS_SYS_nrbg_self_test function returns one of following status codes:
|
||||
- MSS_SYS_SUCCESS
|
||||
- MSS_SYS_NRBG_CATASTROPHIC_ERROR
|
||||
- MSS_SYS_NRBG_MAX_INST_EXCEEDED
|
||||
- MSS_SYS_NRBG_INVALID_HANDLE
|
||||
- MSS_SYS_NRBG_GEN_REQ_TOO_BIG
|
||||
- MSS_SYS_NRBG_MAX_LENGTH_EXCEEDED
|
||||
- MSS_SYS_SERVICE_DISABLED_BY_FACTORY
|
||||
- MSS_SYS_SERVICE_DISABLED_BY_USER
|
||||
*/
|
||||
uint8_t MSS_SYS_nrbg_self_test(void);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_SYS_nrbg_instantiate() function instantiates a non-deterministic
|
||||
random bit generator (NRBG) instance. A maximum of two concurrent instances
|
||||
are available.
|
||||
|
||||
@param personalization_str
|
||||
The personalization_str parameter is a pointer to a buffer containing a
|
||||
random bit generator personalization string. The personalization string
|
||||
can be up to 128 bytes long.
|
||||
|
||||
@param personalization_str_length
|
||||
The personalization_str_length parameter specifies the byte length of the
|
||||
personalization string pointed to by personalization_str.
|
||||
|
||||
@param p_nrbg_handle
|
||||
The p_nrbg_handle parameter is a pointer to a byte that will contain the
|
||||
handle of the instantiated NRBG if this function call suceeds.
|
||||
|
||||
@return
|
||||
The MSS_SYS_nrbg_instantiate function returns one of following status codes:
|
||||
- MSS_SYS_SUCCESS
|
||||
- MSS_SYS_NRBG_CATASTROPHIC_ERROR
|
||||
- MSS_SYS_NRBG_MAX_INST_EXCEEDED
|
||||
- MSS_SYS_NRBG_INVALID_HANDLE
|
||||
- MSS_SYS_NRBG_GEN_REQ_TOO_BIG
|
||||
- MSS_SYS_NRBG_MAX_LENGTH_EXCEEDED
|
||||
- MSS_SYS_SERVICE_DISABLED_BY_FACTORY
|
||||
- MSS_SYS_SERVICE_DISABLED_BY_USER
|
||||
*/
|
||||
uint8_t MSS_SYS_nrbg_instantiate
|
||||
(
|
||||
const uint8_t * personalization_str,
|
||||
uint16_t personalization_str_length,
|
||||
uint8_t * p_nrbg_handle
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_SYS_nrbg_generate function generates a random bit sequence up to
|
||||
128 bytes long.
|
||||
|
||||
@param p_requested_data
|
||||
The p_requested_data parameter is a pointer to the buffer where the requested
|
||||
random data will be stored on completion of this system servide.
|
||||
|
||||
@param p_additional_input
|
||||
The p_additional_input parameter is a pointer to the buffer containing
|
||||
additional input data for the random bit generation.
|
||||
|
||||
@param requested_length
|
||||
The requested_length parameter specifies the number of random data bytes
|
||||
requested to be generated. The maximum generated data length is 128 bytes.
|
||||
|
||||
@param additional_input_length
|
||||
The additional_input_length parameter specifies the number of addditonal
|
||||
input bytes to use in the random data generation.
|
||||
|
||||
@param pr_req
|
||||
The pr_req parameter specifies if prediction resistance is requested.
|
||||
|
||||
@param nrbg_handle
|
||||
The nrbg_handle parameter specifies which non-deterministic random bit
|
||||
generator (NRBG) instance will be used to generate the random data. The
|
||||
value of nrbg_handle is obtained as a result of a previous call to the
|
||||
MSS_SYS_nrbg_instantiate() function.
|
||||
|
||||
@return
|
||||
The MSS_SYS_nrbg_generate function returns one of following status codes:
|
||||
- MSS_SYS_SUCCESS
|
||||
- MSS_SYS_NRBG_CATASTROPHIC_ERROR
|
||||
- MSS_SYS_NRBG_MAX_INST_EXCEEDED
|
||||
- MSS_SYS_NRBG_INVALID_HANDLE
|
||||
- MSS_SYS_NRBG_GEN_REQ_TOO_BIG
|
||||
- MSS_SYS_NRBG_MAX_LENGTH_EXCEEDED
|
||||
- MSS_SYS_SERVICE_DISABLED_BY_FACTORY
|
||||
- MSS_SYS_SERVICE_DISABLED_BY_USER
|
||||
|
||||
*/
|
||||
uint8_t MSS_SYS_nrbg_generate
|
||||
(
|
||||
const uint8_t * p_requested_data,
|
||||
const uint8_t * p_additional_input,
|
||||
uint8_t requested_length,
|
||||
uint8_t additional_input_length,
|
||||
uint8_t pr_req,
|
||||
uint8_t nrbg_handle
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_SYS_nrbg_reseed() function is used to reseed the non-deterministic
|
||||
random bit generator (NRBG) identified by the nrbg_handle parameter.
|
||||
|
||||
@param p_additional_input
|
||||
The additional_input_length parameter specifies the number of additional
|
||||
input bytes used to reseed the NRBG identified by the nrbg_handle parameter.
|
||||
|
||||
@param additional_input_length
|
||||
The additional_input_length parameter specifies the number of additional
|
||||
input bytes used to reseed the NRBG.
|
||||
|
||||
@param nrbg_handle
|
||||
The nrbg_handle parameter specifies which NRBG instance to reseed. The value
|
||||
of nrbg_handle is obtained as a result of a previous call to the
|
||||
MSS_SYS_nrbg_instantiate() function.
|
||||
|
||||
@return
|
||||
The MSS_SYS_nrbg_reseed function returns one of following status codes:
|
||||
- MSS_SYS_SUCCESS
|
||||
- MSS_SYS_NRBG_CATASTROPHIC_ERROR
|
||||
- MSS_SYS_NRBG_MAX_INST_EXCEEDED
|
||||
- MSS_SYS_NRBG_INVALID_HANDLE
|
||||
- MSS_SYS_NRBG_GEN_REQ_TOO_BIG
|
||||
- MSS_SYS_NRBG_MAX_LENGTH_EXCEEDED
|
||||
- MSS_SYS_SERVICE_DISABLED_BY_FACTORY
|
||||
- MSS_SYS_SERVICE_DISABLED_BY_USER
|
||||
|
||||
*/
|
||||
uint8_t MSS_SYS_nrbg_reseed
|
||||
(
|
||||
const uint8_t * p_additional_input,
|
||||
uint8_t additional_input_length,
|
||||
uint8_t nrbg_handle
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_SYS_nrbg_uninstantiate() function releases the non-deterministic
|
||||
random bit generator (NRBG) identified by the nrbg_handle parameter.
|
||||
|
||||
@param nrbg_handle
|
||||
The nrbg_handle parameter specifies which NRBG instance will be released.
|
||||
The value of nrbg_handle is obtained as a result of a previous call to the
|
||||
MSS_SYS_nrbg_instantiate() function.
|
||||
|
||||
@return
|
||||
The MSS_SYS_nrbg_uninstantiate function returns one of following status codes:
|
||||
- MSS_SYS_SUCCESS
|
||||
- MSS_SYS_NRBG_CATASTROPHIC_ERROR
|
||||
- MSS_SYS_NRBG_MAX_INST_EXCEEDED
|
||||
- MSS_SYS_NRBG_INVALID_HANDLE
|
||||
- MSS_SYS_NRBG_GEN_REQ_TOO_BIG
|
||||
- MSS_SYS_NRBG_MAX_LENGTH_EXCEEDED
|
||||
- MSS_SYS_SERVICE_DISABLED_BY_FACTORY
|
||||
- MSS_SYS_SERVICE_DISABLED_BY_USER
|
||||
|
||||
*/
|
||||
uint8_t MSS_SYS_nrbg_uninstantiate
|
||||
(
|
||||
uint8_t nrbg_handle
|
||||
);
|
||||
|
||||
/*==============================================================================
|
||||
* Programming Services.
|
||||
*/
|
||||
|
||||
#define MSS_SYS_PROG_AUTHENTICATE 0u
|
||||
#define MSS_SYS_PROG_PROGRAM 1u
|
||||
#define MSS_SYS_PROG_VERIFY 2u
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The ISP Service allows the MSS Cortex-M3 processor to directly provide a
|
||||
bitstream for programming. The ISP Service is initiated by a call to
|
||||
MSS_SYS_start_isp(). The ISP Service can:
|
||||
- authenticate a programming bitstream
|
||||
- program a bitstream
|
||||
- verify that a programming bitstream has been correctly programmed
|
||||
|
||||
The application must provide two functions as parameter to the
|
||||
MSS_SYS_start_isp() function. The first function will be used by the ISP
|
||||
Service to read the programming bitstream. The second function will be used by
|
||||
the ISP Service to notify the application that the ISP Service completed.
|
||||
|
||||
@param mode
|
||||
The mode parameter specifies ISP service to perform. It can be one of:
|
||||
- MSS_SYS_PROG_AUTHENTICATE
|
||||
- MSS_SYS_PROG_PROGRAM
|
||||
- MSS_SYS_PROG_VERIFY
|
||||
|
||||
@param page_read_handler
|
||||
The page_read_handler parameter is a pointer to a function with the
|
||||
following prototype:
|
||||
uint32_t page_read_handler(uint8 const ** pp_next_page);
|
||||
|
||||
@param isp_completion_handler
|
||||
The isp_completion_handler parameter is a pointer to a function with the
|
||||
following prototype. This function will be called when the ISP service
|
||||
completes.
|
||||
|
||||
The isp_completion_handler function will receive one of the following status
|
||||
codes:
|
||||
- MSS_SYS_SUCCESS
|
||||
- MSS_SYS_CHAINING_MISMATCH
|
||||
- MSS_SYS_UNEXPECTED_DATA_RECEIVED
|
||||
- MSS_SYS_INVALID_ENCRYPTION_KEY
|
||||
- MSS_SYS_INVALID_COMPONENT_HEADER
|
||||
- MSS_SYS_BACK_LEVEL_NOT_SATISFIED
|
||||
- MSS_SYS_DSN_BINDING_MISMATCH
|
||||
- MSS_SYS_ILLEGAL_COMPONENT_SEQUENCE
|
||||
- MSS_SYS_INSUFFICIENT_DEV_CAPABILITIES
|
||||
- MSS_SYS_INCORRECT_DEVICE_ID
|
||||
- MSS_SYS_UNSUPPORTED_BITSTREAM_PROT_VER
|
||||
- MSS_SYS_VERIFY_NOT_PERMITTED_ON_BITSTR
|
||||
- MSS_SYS_ABORT
|
||||
- MSS_SYS_NVM_VERIFY_FAILED
|
||||
- MSS_SYS_DEVICE_SECURITY_PROTECTED
|
||||
- MSS_SYS_PROGRAMMING_MODE_NOT_ENABLED
|
||||
- MSS_SYS_SERVICE_DISABLED_BY_USER
|
||||
|
||||
@return
|
||||
This function does not return a value.
|
||||
*/
|
||||
void MSS_SYS_start_isp
|
||||
(
|
||||
uint8_t mode,
|
||||
uint32_t (*page_read_handler)(uint8_t const **),
|
||||
void (*isp_completion_handler)(uint32_t)
|
||||
);
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
Recalculates and compares digests of selected components.
|
||||
|
||||
@param options
|
||||
The options parameter specifies which components' digest will be recalculated
|
||||
and checked. Each bit is used to identify a componetn as follows:
|
||||
- bit 0: FPGA fabric
|
||||
- bit 1: eNVM0
|
||||
- bit 2: eNVM1
|
||||
Note: The FPGA fabric will enter the FlashFreeze state if powered up when
|
||||
its digest is checked.
|
||||
|
||||
@return
|
||||
The MSS_SYS_check_digest function returns the result of the digest check. The
|
||||
meaning of the digest check return value is as follows:
|
||||
bit 0: Fabric digest error
|
||||
bit 1: ENVM0 digest error
|
||||
bit 2: ENVM1 digest error
|
||||
A '1' in one of the above bits indicates a digest mismatch.
|
||||
*/
|
||||
#define MSS_SYS_DIGEST_CHECK_FABRIC 0x01u
|
||||
#define MSS_SYS_DIGEST_CHECK_ENVM0 0x02u
|
||||
#define MSS_SYS_DIGEST_CHECK_ENVM1 0x04u
|
||||
|
||||
uint8_t MSS_SYS_check_digest
|
||||
(
|
||||
uint8_t options
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __MSS_SYS_SERVICES_H_ */
|
|
@ -0,0 +1,595 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2010-2013 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* SmartFusion2 microcontroller subsystem (MSS) timer driver API.
|
||||
*
|
||||
* SVN $Revision: 5111 $
|
||||
* SVN $Date: 2013-02-18 17:03:09 +0000 (Mon, 18 Feb 2013) $
|
||||
*/
|
||||
/*=========================================================================*//**
|
||||
@mainpage SmartFusion2 MSS Timer Bare Metal Driver.
|
||||
|
||||
@section intro_sec Introduction
|
||||
The SmartFusion2 Microcontroller Subsystem (MSS) includes a timer hardware
|
||||
block which can be used as two independent 32-bits timers or as a single
|
||||
64-bits timer in periodic or one-shot mode.
|
||||
|
||||
This driver provides a set of functions for controlling the MSS timer as part
|
||||
of a bare metal system where no operating system is available. These drivers
|
||||
can be adapted for use as part of an operating system but the implementation
|
||||
of the adaptation layer between this driver and the operating system's driver
|
||||
model is outside the scope of this driver.
|
||||
|
||||
@section theory_op Theory of Operation
|
||||
The MSS Timer driver uses the SmartFusion2 "Cortex Microcontroler Software
|
||||
Interface Standard - Peripheral Access Layer" (CMSIS-PAL) to access hadware
|
||||
registers. You must ensure that the SmartFusion2 CMSIS-PAL is either included
|
||||
in the software toolchain used to build your project or is included in your
|
||||
project. The most up-to-date SmartFusion2 CMSIS-PAL files can be obtained using
|
||||
the Actel Firmware Catalog.
|
||||
The SmartFusion2 MSS Timer can be used in one of two mutually exclusive modes;
|
||||
either as a single 64-bits timer or as two independent 32-bits timers. The MSS
|
||||
Timer can be used in either periodic mode or one-shot mode. A timer configured
|
||||
for periodic mode operations will generate an interrupt and reload its
|
||||
down-counter when it reaches 0. The timer will then continue decrementing from
|
||||
its reload value without waiting for the interrupt to be cleared. A timer
|
||||
configured for one-shot mode will only generate an interrupt once when its
|
||||
down-counter reaches 0. It must be explitcitly reloaded to start decrementing
|
||||
again.
|
||||
|
||||
The MSS Timer driver functions are grouped into the following categories:
|
||||
- Initialization and Configuration
|
||||
- Timer control
|
||||
- Interrupt control
|
||||
|
||||
The MSS Timer driver provides three initialization functions:
|
||||
- MSS_TIM1_init()
|
||||
- MSS_TIM2_init()
|
||||
- MSS_TIM64_init()
|
||||
The MSS Timer driver is initialized through calls to these functions and at
|
||||
least one of them must be called before any other MSS Timer driver functions
|
||||
can be called.
|
||||
You should only use the MSS_TIM1_init() and MSS_TIM2_init() functions if you
|
||||
intend to use the timer in 32-bits mode. Use the MSS_TIM64_init() function is
|
||||
you intend to use the MSS Timer as a single 64-bits timer. The initialization
|
||||
functions take a single parameter specifying the operating mode of the timer
|
||||
being initialized.
|
||||
|
||||
Once initialized a timer can be controlled using the following functions:
|
||||
- MSS_TIM1_load_immediate()
|
||||
- MSS_TIM1_load_background()
|
||||
- MSS_TIM1_get_current_value()
|
||||
- MSS_TIM1_start()
|
||||
- MSS_TIM1_stop()
|
||||
- MSS_TIM2_load_immediate()
|
||||
- MSS_TIM2_load_background()
|
||||
- MSS_TIM2_get_current_value()
|
||||
- MSS_TIM2_start()
|
||||
- MSS_TIM2_stop()
|
||||
- MSS_TIM64_load_immediate()
|
||||
- MSS_TIM64_load_background()
|
||||
- MSS_TIM64_get_current_value()
|
||||
- MSS_TIM64_start()
|
||||
- MSS_TIM64_stop()
|
||||
|
||||
Timer interrupts are controlled using the following functions:
|
||||
- MSS_TIM1_enable_irq()
|
||||
- MSS_TIM1_disable_irq()
|
||||
- MSS_TIM1_clear_irq()
|
||||
- MSS_TIM2_enable_irq()
|
||||
- MSS_TIM2_disable_irq()
|
||||
- MSS_TIM2_clear_irq()
|
||||
- MSS_TIM64_enable_irq()
|
||||
- MSS_TIM64_disable_irq()
|
||||
- MSS_TIM64_clear_irq()
|
||||
|
||||
The function prototypes for the timer interrupt handlers are:
|
||||
- void Timer1_IRQHandler( void )
|
||||
- void Timer2_IRQHandler( void )
|
||||
Entries for these interrupt handlers are provided in the SmartFusion2 CMSIS-PAL
|
||||
vector table. To add a Timer 1 interrupt handler, you must implement a
|
||||
Timer1_IRQHandler( ) function as part of your application code. To add a
|
||||
Timer 2 interrupt handler, you must implement a Timer2_IRQHandler( ) function
|
||||
as part of your application code. When using the MSS Timer as a 64-bit timer,
|
||||
you must implement a Timer1_IRQHandler( ) function as part of your
|
||||
application code. The Timer 2 interrupt is not used when the MSS Timer is
|
||||
configured as a 64-bit timer.
|
||||
|
||||
*//*=========================================================================*/
|
||||
#ifndef MSS_TIMER_H_
|
||||
#define MSS_TIMER_H_
|
||||
|
||||
|
||||
#include "../../CMSIS/m2sxxx.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
* Timer mode selection. This enumeration is used to select between the two
|
||||
* possible timer modes of operation: periodic and one-shot mode. It is used as
|
||||
* an argument to the MSS_TIM1_init(), MSS_TIM2_init() and MSS_TIM64_init()
|
||||
* functions.
|
||||
* MSS_TIMER_PERIODIC_MODE:
|
||||
* In periodic mode the timer generates interrupts at constant intervals. On
|
||||
* reaching zero, the timer's counter is reloaded with a value held in a
|
||||
* register and begins counting down again.
|
||||
* MSS_TIMER_ONE_SHOT_MODE:
|
||||
* The timer generates a single interrupt in this mode. On reaching zero, the
|
||||
* timer's counter halts until reprogrammed by the user.
|
||||
*/
|
||||
typedef enum __mss_timer_mode_t
|
||||
{
|
||||
MSS_TIMER_PERIODIC_MODE = 0,
|
||||
MSS_TIMER_ONE_SHOT_MODE = 1
|
||||
} mss_timer_mode_t;
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM1_init() function initializes the SmartFusion2 MSS Timer block for
|
||||
use as a 32-bit timer and selects the operating mode for Timer 1. This function
|
||||
takes the MSS Timer block out of reset in case this hasn’t been done already,
|
||||
stops Timer 1, disables its interrupt and sets the Timer 1 operating mode.
|
||||
Please note that the SmartFusion2 MSS Timer block cannot be used both as a
|
||||
64-bit and 32-bit timer. Calling MSS_TIM1_init() will overwrite any previous
|
||||
configuration of the MSS Timer as a 64-bit timer.
|
||||
|
||||
|
||||
@param mode
|
||||
The mode parameter specifies whether the timer will operate in periodic or
|
||||
one-shot mode. Allowed values for this parameter are:
|
||||
- MSS_TIMER_PERIODIC_MODE
|
||||
- MSS_TIMER_ONE_SHOT_MODE
|
||||
*/
|
||||
static __INLINE void MSS_TIM1_init(mss_timer_mode_t mode)
|
||||
{
|
||||
NVIC_DisableIRQ(Timer1_IRQn); /* Disable timer 1 irq in the Cortex-M3 NVIC */
|
||||
|
||||
SYSREG->SOFT_RST_CR &= ~SYSREG_TIMER_SOFTRESET_MASK; /* Take timer block out of reset */
|
||||
|
||||
TIMER->TIM64_MODE = 0u; /* switch to 32 bits mode */
|
||||
|
||||
TIMER_BITBAND->TIM1ENABLE = 0u; /* disable timer */
|
||||
TIMER_BITBAND->TIM1INTEN = 0u; /* disable interrupt */
|
||||
TIMER_BITBAND->TIM1MODE = (uint32_t)mode; /* set mode (continuous/one-shot) */
|
||||
|
||||
TIMER->TIM1_RIS = 1u; /* clear timer 1 interrupt */
|
||||
NVIC_ClearPendingIRQ(Timer1_IRQn); /* clear timer 1 interrupt within NVIC */
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM1_start() function enables Timer 1 and starts its down-counter
|
||||
decrementing from the load_value specified in previous calls to the
|
||||
MSS_TIM1_load_immediate() or MSS_TIM1_load_background() functions.
|
||||
*/
|
||||
static __INLINE void MSS_TIM1_start(void)
|
||||
{
|
||||
TIMER_BITBAND->TIM1ENABLE = 1u; /* enable timer */
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM1_stop() function disables Timer 1 and stops its down-counter
|
||||
decrementing.
|
||||
*/
|
||||
static __INLINE void MSS_TIM1_stop(void)
|
||||
{
|
||||
TIMER_BITBAND->TIM1ENABLE = 0u; /* disable timer */
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM1_get_current_value() returns the current value of the Timer 1
|
||||
down-counter.
|
||||
|
||||
@return
|
||||
This function returns the 32-bits current value of the Timer 1 down-counter.
|
||||
*/
|
||||
static __INLINE uint32_t MSS_TIM1_get_current_value(void)
|
||||
{
|
||||
return TIMER->TIM1_VAL;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM1_load_immediate() function loads the value passed by the
|
||||
load_value parameter into the Timer 1 down-counter. The counter will decrement
|
||||
immediately from this value once Timer 1 is enabled. The MSS Timer will
|
||||
generate an interrupt when the counter reaches zero if Timer 1 interrupts are
|
||||
enabled. This function is intended to be used when Timer 1 is configured for
|
||||
one-shot mode to time a single delay.
|
||||
|
||||
@param load_value
|
||||
The load_value parameter specifies the value from which the Timer 1 down-counter
|
||||
will start decrementing from.
|
||||
*/
|
||||
static __INLINE void MSS_TIM1_load_immediate(uint32_t load_value)
|
||||
{
|
||||
TIMER->TIM1_LOADVAL = load_value;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM1_load_background() function is used to specify the value that will
|
||||
be reloaded into the Timer 1 down-counter the next time the counter reaches
|
||||
zero. This function is typically used when Timer 1 is configured for periodic
|
||||
mode operation to select or change the delay period between the interrupts
|
||||
generated by Timer 1.
|
||||
|
||||
@param load_value
|
||||
The load_value parameter specifies the value that will be loaded into the
|
||||
Timer 1 down-counter the next time the down-counter reaches zero. The Timer
|
||||
1 down-counter will start decrementing from this value after the current
|
||||
count expires.
|
||||
*/
|
||||
static __INLINE void MSS_TIM1_load_background(uint32_t load_value)
|
||||
{
|
||||
TIMER->TIM1_BGLOADVAL = load_value;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM1_enable_irq() function is used to enable interrupt generation for
|
||||
Timer 1. This function also enables the interrupt in the Cortex-M3 interrupt
|
||||
controller. The Timer1_IRQHandler() function will be called when a Timer 1
|
||||
interrupt occurs.
|
||||
Note: Note: A Timer1_IRQHandler() default implementation is defined, with
|
||||
weak linkage, in the SmartFusion2 CMSIS-PAL. You must provide your own
|
||||
implementation of the Timer1_IRQHandler() function, that will override the
|
||||
default implementation, to suit your application.
|
||||
|
||||
*/
|
||||
static __INLINE void MSS_TIM1_enable_irq(void)
|
||||
{
|
||||
TIMER_BITBAND->TIM1INTEN = 1u;
|
||||
NVIC_EnableIRQ(Timer1_IRQn);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM1_disable_irq() function is used to disable interrupt generation
|
||||
for Timer 1. This function also disables the interrupt in the Cortex-M3
|
||||
interrupt controller.
|
||||
*/
|
||||
static __INLINE void MSS_TIM1_disable_irq(void)
|
||||
{
|
||||
TIMER_BITBAND->TIM1INTEN = 0u;
|
||||
NVIC_DisableIRQ(Timer1_IRQn);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM1_clear_irq() function is used to clear a pending interrupt from
|
||||
Timer 1. This function also clears the interrupt in the Cortex-M3 interrupt
|
||||
controller.
|
||||
Note: You must call the MSS_TIM1_clear_irq() function as part of your
|
||||
implementation of the Timer1_IRQHandler() Timer 1 interrupt service routine
|
||||
(ISR) in order to prevent the same interrupt event retriggering a call to the
|
||||
ISR.
|
||||
|
||||
*/
|
||||
static __INLINE void MSS_TIM1_clear_irq(void)
|
||||
{
|
||||
TIMER->TIM1_RIS = 1u;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM2_init() function initializes the SmartFusion2 MSS Timer block for
|
||||
use as a 32-bit timer and selects the operating mode for Timer 2. This function
|
||||
takes the MSS Timer block out of reset in case this hasn’t been done already,
|
||||
stops Timer 2, disables its interrupt and sets the Timer 2 operating mode.
|
||||
Note: Please note that the SmartFusion2 MSS Timer block cannot be used both as
|
||||
a 64-bit and 32-bit timer. Calling MSS_TIM2_init() will overwrite any previous
|
||||
configuration of the MSS Timer as a 64-bit timer.
|
||||
|
||||
@param mode
|
||||
The mode parameter specifies whether the timer will operate in periodic or
|
||||
one-shot mode. Allowed values for this parameter are:
|
||||
- MSS_TIMER_PERIODIC_MODE
|
||||
- MSS_TIMER_ONE_SHOT_MODE
|
||||
*/
|
||||
static __INLINE void MSS_TIM2_init(mss_timer_mode_t mode)
|
||||
{
|
||||
NVIC_DisableIRQ(Timer2_IRQn); /* Disable timer 2 irq in the Cortex-M3 NVIC */
|
||||
|
||||
SYSREG->SOFT_RST_CR &= ~SYSREG_TIMER_SOFTRESET_MASK; /* Take timer block out of reset */
|
||||
|
||||
TIMER->TIM64_MODE = 0u; /* switch to 32 bits mode */
|
||||
|
||||
TIMER_BITBAND->TIM2ENABLE = 0u; /* disable timer */
|
||||
TIMER_BITBAND->TIM2INTEN = 0u; /* disable interrupt */
|
||||
TIMER_BITBAND->TIM2MODE = (uint32_t)mode; /* set mode (continuous/one-shot) */
|
||||
|
||||
TIMER->TIM2_RIS = 1u; /* clear timer 2 interrupt */
|
||||
NVIC_ClearPendingIRQ(Timer2_IRQn); /* clear timer 2 interrupt within NVIC */
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM2_start() function enables Timer 2 and starts its down-counter
|
||||
decrementing from the load_value specified in previous calls to the
|
||||
MSS_TIM2_load_immediate() or MSS_TIM2_load_background() functions.
|
||||
*/
|
||||
static __INLINE void MSS_TIM2_start(void)
|
||||
{
|
||||
TIMER_BITBAND->TIM2ENABLE = 1u; /* enable timer */
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM2_stop() function disables Timer 2 and stops its down-counter
|
||||
decrementing.
|
||||
*/
|
||||
static __INLINE void MSS_TIM2_stop(void)
|
||||
{
|
||||
TIMER_BITBAND->TIM2ENABLE = 0u; /* disable timer */
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM2_get_current_value() returns the current value of the Timer 2
|
||||
down-counter.
|
||||
*/
|
||||
static __INLINE uint32_t MSS_TIM2_get_current_value(void)
|
||||
{
|
||||
return TIMER->TIM2_VAL;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM2_load_immediate() function loads the value passed by the
|
||||
load_value parameter into the Timer 2 down-counter. The counter will decrement
|
||||
immediately from this value once Timer 2 is enabled. The MSS Timer will
|
||||
generate an interrupt when the counter reaches zero if Timer 2 interrupts are
|
||||
enabled. This function is intended to be used when Timer 2 is configured for
|
||||
one-shot mode to time a single delay.
|
||||
|
||||
@param load_value
|
||||
The load_value parameter specifies the value from which the Timer 2
|
||||
down-counter will start decrementing.
|
||||
*/
|
||||
static __INLINE void MSS_TIM2_load_immediate(uint32_t load_value)
|
||||
{
|
||||
TIMER->TIM2_LOADVAL = load_value;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM2_load_background() function is used to specify the value that will
|
||||
be reloaded into the Timer 2 down-counter the next time the counter reaches
|
||||
zero. This function is typically used when Timer 2 is configured for periodic
|
||||
mode operation to select or change the delay period between the interrupts
|
||||
generated by Timer 2.
|
||||
|
||||
@param load_value
|
||||
The load_value parameter specifies the value that will be loaded into the
|
||||
Timer 2 down-counter the next time the down-counter reaches zero. The Timer
|
||||
2 down-counter will start decrementing from this value after the current
|
||||
count expires.
|
||||
*/
|
||||
static __INLINE void MSS_TIM2_load_background(uint32_t load_value)
|
||||
{
|
||||
TIMER->TIM2_BGLOADVAL = load_value;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM2_enable_irq() function is used to enable interrupt generation for
|
||||
Timer 2. This function also enables the interrupt in the Cortex-M3 interrupt
|
||||
controller. The Timer2_IRQHandler() function will be called when a Timer 2
|
||||
interrupt occurs.
|
||||
Note: A Timer2_IRQHandler() default implementation is defined, with weak
|
||||
linkage, in the SmartFusion2 CMSIS-PAL. You must provide your own implementation
|
||||
of the Timer2_IRQHandler() function, that will override the default
|
||||
implementation, to suit your application.
|
||||
*/
|
||||
static __INLINE void MSS_TIM2_enable_irq(void)
|
||||
{
|
||||
TIMER_BITBAND->TIM2INTEN = 1u;
|
||||
NVIC_EnableIRQ( Timer2_IRQn );
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM2_disable_irq() function is used to disable interrupt generation
|
||||
for Timer 2. This function also disables the interrupt in the Cortex-M3
|
||||
interrupt controller.
|
||||
*/
|
||||
static __INLINE void MSS_TIM2_disable_irq(void)
|
||||
{
|
||||
TIMER_BITBAND->TIM2INTEN = 0u;
|
||||
NVIC_DisableIRQ(Timer2_IRQn);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM2_clear_irq() function is used to clear a pending interrupt from
|
||||
Timer 2. This function also clears the interrupt in the Cortex-M3 interrupt
|
||||
controller.
|
||||
Note: You must call the MSS_TIM2_clear_irq() function as part of your
|
||||
implementation of the Timer2_IRQHandler() Timer 2 interrupt service routine
|
||||
(ISR) in order to prevent the same interrupt event retriggering a call to the
|
||||
ISR.
|
||||
*/
|
||||
static __INLINE void MSS_TIM2_clear_irq(void)
|
||||
{
|
||||
TIMER->TIM2_RIS = 1u;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM64_init() function initializes the SmartFusion2 MSS Timer block for
|
||||
use as a single 64-bit timer and selects the operating mode of the timer. This
|
||||
function takes the MSS Timer block out of reset in case this hasn’t been done
|
||||
already, stops the timer, disables its interrupts and sets the timer's
|
||||
operating mode.
|
||||
Note: Please note that the SmartFusion2 MSS Timer block cannot be used both as
|
||||
a 64-bit and 32-bit timer. Calling MSS_TIM64_init() will overwrite any previous
|
||||
configuration of the MSS Timer as a 32-bit timer.
|
||||
|
||||
@param mode
|
||||
The mode parameter specifies whether the timer will operate in periodic or
|
||||
one-shot mode. Allowed values for this parameter are:
|
||||
- MSS_TIMER_PERIODIC_MODE
|
||||
- MSS_TIMER_ONE_SHOT_MODE
|
||||
*/
|
||||
static __INLINE void MSS_TIM64_init(mss_timer_mode_t mode)
|
||||
{
|
||||
NVIC_DisableIRQ(Timer1_IRQn); /* disable timer 1 interrupt within NVIC */
|
||||
NVIC_DisableIRQ(Timer2_IRQn); /* disable timer 2 interrupt within NVIC */
|
||||
|
||||
SYSREG->SOFT_RST_CR &= ~SYSREG_TIMER_SOFTRESET_MASK; /* Take timer block out of reset */
|
||||
|
||||
TIMER->TIM64_MODE = 1u; /* switch to 64 bits mode */
|
||||
|
||||
TIMER_BITBAND->TIM64ENABLE = 0u; /* disable timer */
|
||||
TIMER_BITBAND->TIM64INTEN = 0u; /* disable interrupt */
|
||||
TIMER_BITBAND->TIM64MODE = (uint32_t)mode; /* set mode (continuous/one-shot) */
|
||||
|
||||
TIMER->TIM1_RIS = 1u; /* clear timer 1 interrupt */
|
||||
TIMER->TIM2_RIS = 1u; /* clear timer 2 interrupt */
|
||||
NVIC_ClearPendingIRQ(Timer1_IRQn); /* clear timer 1 interrupt within NVIC */
|
||||
NVIC_ClearPendingIRQ(Timer2_IRQn); /* clear timer 2 interrupt within NVIC */
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM64_start() function enables the 64-bit timer and starts its
|
||||
down-counter decrementing from the load_value specified in previous calls to
|
||||
the MSS_TIM64_load_immediate() or MSS_TIM64_load_background() functions.
|
||||
*/
|
||||
static __INLINE void MSS_TIM64_start(void)
|
||||
{
|
||||
TIMER_BITBAND->TIM64ENABLE = 1u; /* enable timer */
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM64_stop() function disables the 64-bit timer and stops its
|
||||
down-counter decrementing.
|
||||
*/
|
||||
static __INLINE void MSS_TIM64_stop(void)
|
||||
{
|
||||
TIMER_BITBAND->TIM64ENABLE = 0u; /* disable timer */
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM64_get_current_value() is used to read the current value of the
|
||||
64-bit timer down-counter.
|
||||
|
||||
@param load_value_u
|
||||
The load_value_u parameter is a pointer to a 32-bit variable where the upper
|
||||
32 bits of the current value of the 64-bit timer down-counter will be copied.
|
||||
|
||||
@param load_value_l
|
||||
The load_value_l parameter is a pointer to a 32-bit variable where the lower
|
||||
32 bits of the current value of the 64-bit timer down-counter will be copied.
|
||||
|
||||
Example:
|
||||
@code
|
||||
uint32_t current_value_u = 0;
|
||||
uint32_t current_value_l = 0;
|
||||
MSS_TIM64_get_current_value( ¤t_value_u, ¤t_value_l );
|
||||
@endcode
|
||||
*/
|
||||
static __INLINE void MSS_TIM64_get_current_value
|
||||
(
|
||||
uint32_t * load_value_u,
|
||||
uint32_t * load_value_l
|
||||
)
|
||||
{
|
||||
*load_value_l = TIMER->TIM64_VAL_L;
|
||||
*load_value_u = TIMER->TIM64_VAL_U;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM64_load_immediate() function loads the values passed by the
|
||||
load_value_u and load_value_l parameters into the 64-bit timer down-counter.
|
||||
The counter will decrement immediately from the concatenated 64-bit value once
|
||||
the 64-bit timer is enabled. The MSS Timer will generate an interrupt when the
|
||||
counter reaches zero if 64-bit timer interrupts are enabled. This function is
|
||||
intended to be used when the 64-bit timer is configured for one-shot mode to
|
||||
time a single delay.
|
||||
|
||||
@param load_value_u
|
||||
The load_value_u parameter specifies the upper 32 bits of the 64-bit timer
|
||||
load value from which the 64-bit timer down-counter will start decrementing.
|
||||
|
||||
@param load_value_l
|
||||
The load_value_l parameter specifies the lower 32 bits of the 64-bit timer
|
||||
load value from which the 64-bit timer down-counter will start decrementing.
|
||||
*/
|
||||
static __INLINE void MSS_TIM64_load_immediate
|
||||
(
|
||||
uint32_t load_value_u,
|
||||
uint32_t load_value_l
|
||||
)
|
||||
{
|
||||
TIMER->TIM64_LOADVAL_U = load_value_u;
|
||||
TIMER->TIM64_LOADVAL_L = load_value_l;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM64_load_background() function is used to specify the 64-bit value
|
||||
that will be reloaded into the 64-bit timer down-counter the next time the
|
||||
counter reaches zero. This function is typically used when the 64-bit timer is
|
||||
configured for periodic mode operation to select or change the delay period
|
||||
between the interrupts generated by the 64-bit timer.
|
||||
|
||||
@param load_value_u
|
||||
The load_value_u parameter specifies the upper 32 bits of the 64-bit timer
|
||||
load value. The concatenated 64-bit value formed from load_value_u and
|
||||
load_value_l will be loaded into the 64-bit timer down-counter the next
|
||||
time the down-counter reaches zero. The 64-bit timer down-counter will start
|
||||
decrementing from the concatenated 64-bit value after the current count
|
||||
expires.
|
||||
|
||||
@param load_value_l
|
||||
The load_value_l parameter specifies the lower 32 bits of the 64-bit timer
|
||||
load value. The concatenated 64-bit value formed from load_value_u and
|
||||
load_value_l will be loaded into the 64-bit timer down-counter the next time
|
||||
the down-counter reaches zero. The 64-bit timer down-counter will start
|
||||
decrementing from the concatenated 64-bit value after the current count
|
||||
expires.
|
||||
|
||||
*/
|
||||
static __INLINE void MSS_TIM64_load_background
|
||||
(
|
||||
uint32_t load_value_u,
|
||||
uint32_t load_value_l
|
||||
)
|
||||
{
|
||||
TIMER->TIM64_BGLOADVAL_U = load_value_u;
|
||||
TIMER->TIM64_BGLOADVAL_L = load_value_l;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM64_enable_irq() function is used to enable interrupt generation for
|
||||
the 64-bit timer. This function also enables the interrupt in the Cortex-M3
|
||||
interrupt controller. The Timer1_IRQHandler() function will be called when a
|
||||
64-bit timer interrupt occurs.
|
||||
Note: A Timer1_IRQHandler() default implementation is defined, with weak
|
||||
linkage, in the SmartFusion2 CMSIS-PAL. You must provide your own
|
||||
implementation of the Timer1_IRQHandler() function, that will override the
|
||||
default implementation, to suit your application.
|
||||
Note: The MSS_TIM64_enable_irq() function enables and uses Timer 1 interrupts
|
||||
for the 64-bit timer. Timer 2 interrupts remain disabled.
|
||||
*/
|
||||
static __INLINE void MSS_TIM64_enable_irq(void)
|
||||
{
|
||||
TIMER_BITBAND->TIM64INTEN = 1u;
|
||||
NVIC_EnableIRQ(Timer1_IRQn);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM64_disable_irq() function is used to disable interrupt generation
|
||||
for the 64-bit timer. This function also disables the interrupt in the
|
||||
Cortex-M3 interrupt controller.
|
||||
*/
|
||||
static __INLINE void MSS_TIM64_disable_irq(void)
|
||||
{
|
||||
TIMER_BITBAND->TIM64INTEN = 0u;
|
||||
NVIC_DisableIRQ(Timer1_IRQn);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*//**
|
||||
The MSS_TIM64_clear_irq() function is used to clear a pending interrupt from
|
||||
the 64-bit timer. This function also clears the interrupt in the Cortex-M3
|
||||
interrupt controller.
|
||||
Note: You must call the MSS_TIM64_clear_irq() function as part of your
|
||||
implementation of the Timer1_IRQHandler() 64-bit timer interrupt service
|
||||
routine (ISR) in order to prevent the same interrupt event retriggering a
|
||||
call to the ISR.
|
||||
*/
|
||||
static __INLINE void MSS_TIM64_clear_irq(void)
|
||||
{
|
||||
TIMER->TIM64_RIS = 1u;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*MSS_TIMER_H_*/
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,83 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2011-2013 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* Register bit offsets and masks defintions for SmartFusion2 MSS MMUART.
|
||||
*
|
||||
* SVN $Revision: 5610 $
|
||||
* SVN $Date: 2013-04-05 14:19:30 +0100 (Fri, 05 Apr 2013) $
|
||||
*/
|
||||
#ifndef MSS_UART_REGS_H_
|
||||
#define MSS_UART_REGS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
Register Bit definitions
|
||||
*/
|
||||
|
||||
/* Line Control register bit definitions */
|
||||
#define SB 6u /* Set break */
|
||||
#define DLAB 7u /* Divisor latch access bit */
|
||||
|
||||
/* FIFO Control register bit definitions */
|
||||
#define RXRDY_TXRDYN_EN 0u /* Enable TXRDY and RXRDY signals */
|
||||
#define CLEAR_RX_FIFO 1u /* Clear receiver FIFO */
|
||||
#define CLEAR_TX_FIFO 2u /* Clear transimtter FIFO */
|
||||
#define RDYMODE 3u /* Mode 0 or Mode 1 for TXRDY and RXRDY */
|
||||
|
||||
/* Modem Control register bit definitions */
|
||||
#define LOOP 4u /* Local loopback */
|
||||
#define RLOOP 5u /* Remote loopback */
|
||||
#define ECHO 6u /* Automatic echo */
|
||||
#define RLOOP_MASK 0x6u /* Remote loopback & Automatic echo*/
|
||||
|
||||
/* Line Status register bit definitions */
|
||||
#define DR 0u /* Data ready */
|
||||
#define THRE 5u /* Transmitter holding register empty */
|
||||
#define TEMT 6u /* Transitter empty */
|
||||
|
||||
/* Interrupt Enable register bit definitions */
|
||||
#define ERBFI 0u /* Enable receiver buffer full interrupt */
|
||||
#define ETBEI 1u /* Enable transmitter buffer empty interrupt */
|
||||
#define ELSI 2u /* Enable line status interrupt */
|
||||
#define EDSSI 3u /* Enable modem status interrupt */
|
||||
|
||||
/* Multimode register 0 bit definitions */
|
||||
#define ELIN 3u /* Enable LIN header detection */
|
||||
#define ETTG 5u /* Enable transmitter time guard */
|
||||
#define ERTO 6u /* Enable receiver time-out */
|
||||
#define EFBR 7u /* Enable fractional baud rate mode */
|
||||
|
||||
/* Multimode register 1 bit definitions */
|
||||
#define E_MSB_RX 0u /* MSB / LSB first for receiver */
|
||||
#define E_MSB_TX 1u /* MSB / LSB first for transmitter */
|
||||
#define EIRD 2u /* Enable IrDA modem */
|
||||
#define EIRX 3u /* Input polarity for IrDA modem */
|
||||
#define EITX 4u /* Output polarity for IrDA modem */
|
||||
#define EITP 5u /* Output pulse width for IrDA modem */
|
||||
|
||||
/* Multimode register 2 bit definitions */
|
||||
#define EERR 0u /* Enable ERR / NACK during stop time */
|
||||
#define EAFM 1u /* Enable 9-bit address flag mode */
|
||||
#define EAFC 2u /* Enable address flag clear */
|
||||
#define ESWM 3u /* Enable single wire half-duplex mode */
|
||||
|
||||
/* Multimode Interrupt Enable register and
|
||||
Multimode Interrupt Identification register definitions */
|
||||
#define ERTOI 0u /* Enable receiver timeout interrupt */
|
||||
#define ENACKI 1u /* Enable NACK / ERR interrupt */
|
||||
#define EPID_PEI 2u /* Enable PID parity error interrupt */
|
||||
#define ELINBI 3u /* Enable LIN break interrupt */
|
||||
#define ELINSI 4u /* Enable LIN sync detection interrupt */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MSS_UART_REGS_H_ */
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,385 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2012 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* Smartfusion2 system configuration. This file is automatically generated
|
||||
* by the Libero tools. It contains the Smartfusion2 system configuration that
|
||||
* was selected during the hardware configuration flow.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../../CMSIS/m2sxxx.h"
|
||||
#include "../../CMSIS/sys_init_cfg_types.h"
|
||||
#include "sys_config.h"
|
||||
|
||||
/*==============================================================================
|
||||
* !!! WARNING !!!
|
||||
*==============================================================================
|
||||
* The project including this file must be linked so that the content of this
|
||||
* file is located in internal eNVM at run time. The content of this file is
|
||||
* used to configure the system prior to RAM content initialization. This means
|
||||
* that the content of the data structures below will be used before the copy
|
||||
* from LMA to VMA takes place. The LMA and VMA locations of the content of this
|
||||
* file must be identical for the system to be seamlessly configured as part of
|
||||
* the CMSIS boot process.
|
||||
*/
|
||||
|
||||
/*==============================================================================
|
||||
* Clock configuration
|
||||
*/
|
||||
/* No configuration data structure required. */
|
||||
|
||||
/*==============================================================================
|
||||
* Memory remapping configuration
|
||||
*/
|
||||
/* TBD. */
|
||||
|
||||
/*==============================================================================
|
||||
* MDDR configuration
|
||||
*/
|
||||
#if MSS_SYS_MDDR_CONFIG_BY_CORTEX
|
||||
|
||||
#include "sys_config_mddr_define.h"
|
||||
|
||||
MDDR_TypeDef * const g_m2s_mddr_addr = (MDDR_TypeDef *)0x40020800;
|
||||
|
||||
const ddr_subsys_cfg_t g_m2s_mddr_subsys_config =
|
||||
{
|
||||
/*---------------------------------------------------------------------
|
||||
* DDR Controller registers.
|
||||
* All registers are 16-bit wide unless mentioned beside the definition.
|
||||
*/
|
||||
{
|
||||
MDDR_DDRC_DYN_SOFT_RESET_CR,
|
||||
MDDR_DDRC_RESERVED0,
|
||||
MDDR_DDRC_DYN_REFRESH_1_CR,
|
||||
MDDR_DDRC_DYN_REFRESH_2_CR,
|
||||
MDDR_DDRC_DYN_POWERDOWN_CR,
|
||||
MDDR_DDRC_DYN_DEBUG_CR,
|
||||
MDDR_DDRC_MODE_CR,
|
||||
MDDR_DDRC_ADDR_MAP_BANK_CR,
|
||||
MDDR_DDRC_ECC_DATA_MASK_CR,
|
||||
MDDR_DDRC_ADDR_MAP_COL_1_CR,
|
||||
MDDR_DDRC_ADDR_MAP_COL_2_CR,
|
||||
MDDR_DDRC_ADDR_MAP_ROW_1_CR,
|
||||
MDDR_DDRC_ADDR_MAP_ROW_2_CR,
|
||||
MDDR_DDRC_INIT_1_CR,
|
||||
MDDR_DDRC_CKE_RSTN_CYCLES_1_CR,
|
||||
MDDR_DDRC_CKE_RSTN_CYCLES_2_CR,
|
||||
MDDR_DDRC_INIT_MR_CR,
|
||||
MDDR_DDRC_INIT_EMR_CR,
|
||||
MDDR_DDRC_INIT_EMR2_CR,
|
||||
MDDR_DDRC_INIT_EMR3_CR,
|
||||
MDDR_DDRC_DRAM_BANK_TIMING_PARAM_CR,
|
||||
MDDR_DDRC_DRAM_RD_WR_LATENCY_CR,
|
||||
MDDR_DDRC_DRAM_RD_WR_PRE_CR,
|
||||
MDDR_DDRC_DRAM_MR_TIMING_PARAM_CR,
|
||||
MDDR_DDRC_DRAM_RAS_TIMING_CR,
|
||||
MDDR_DDRC_DRAM_RD_WR_TRNARND_TIME_CR,
|
||||
MDDR_DDRC_DRAM_T_PD_CR,
|
||||
MDDR_DDRC_DRAM_BANK_ACT_TIMING_CR,
|
||||
MDDR_DDRC_ODT_PARAM_1_CR,
|
||||
MDDR_DDRC_ODT_PARAM_2_CR,
|
||||
MDDR_DDRC_ADDR_MAP_COL_3_CR,
|
||||
MDDR_DDRC_MODE_REG_RD_WR_CR,
|
||||
MDDR_DDRC_MODE_REG_DATA_CR,
|
||||
MDDR_DDRC_PWR_SAVE_1_CR,
|
||||
MDDR_DDRC_PWR_SAVE_2_CR,
|
||||
MDDR_DDRC_ZQ_LONG_TIME_CR,
|
||||
MDDR_DDRC_ZQ_SHORT_TIME_CR,
|
||||
MDDR_DDRC_ZQ_SHORT_INT_REFRESH_MARGIN_1_CR,
|
||||
MDDR_DDRC_ZQ_SHORT_INT_REFRESH_MARGIN_2_CR,
|
||||
MDDR_DDRC_PERF_PARAM_1_CR,
|
||||
MDDR_DDRC_HPR_QUEUE_PARAM_1_CR,
|
||||
MDDR_DDRC_HPR_QUEUE_PARAM_2_CR,
|
||||
MDDR_DDRC_LPR_QUEUE_PARAM_1_CR,
|
||||
MDDR_DDRC_LPR_QUEUE_PARAM_2_CR,
|
||||
MDDR_DDRC_WR_QUEUE_PARAM_CR,
|
||||
MDDR_DDRC_PERF_PARAM_2_CR,
|
||||
MDDR_DDRC_PERF_PARAM_3_CR,
|
||||
MDDR_DDRC_DFI_RDDATA_EN_CR,
|
||||
MDDR_DDRC_DFI_MIN_CTRLUPD_TIMING_CR,
|
||||
MDDR_DDRC_DFI_MAX_CTRLUPD_TIMING_CR,
|
||||
MDDR_DDRC_DFI_WR_LVL_CONTROL_1_CR,
|
||||
MDDR_DDRC_DFI_WR_LVL_CONTROL_2_CR,
|
||||
MDDR_DDRC_DFI_RD_LVL_CONTROL_1_CR,
|
||||
MDDR_DDRC_DFI_RD_LVL_CONTROL_2_CR,
|
||||
MDDR_DDRC_DFI_CTRLUPD_TIME_INTERVAL_CR,
|
||||
MDDR_DDRC_DYN_SOFT_RESET_ALIAS_CR,
|
||||
MDDR_DDRC_AXI_FABRIC_PRI_ID_CR,
|
||||
},
|
||||
|
||||
/*---------------------------------------------------------------------
|
||||
* DDR PHY configuration registers
|
||||
*/
|
||||
{
|
||||
MDDR_PHY_LOOPBACK_TEST_CR,
|
||||
MDDR_PHY_BOARD_LOOPBACK_CR,
|
||||
MDDR_PHY_CTRL_SLAVE_RATIO_CR,
|
||||
MDDR_PHY_CTRL_SLAVE_FORCE_CR,
|
||||
MDDR_PHY_CTRL_SLAVE_DELAY_CR,
|
||||
MDDR_PHY_DATA_SLICE_IN_USE_CR,
|
||||
MDDR_PHY_LVL_NUM_OF_DQ0_CR,
|
||||
MDDR_PHY_DQ_OFFSET_1_CR,
|
||||
MDDR_PHY_DQ_OFFSET_2_CR,
|
||||
MDDR_PHY_DQ_OFFSET_3_CR,
|
||||
MDDR_PHY_DIS_CALIB_RST_CR,
|
||||
MDDR_PHY_DLL_LOCK_DIFF_CR,
|
||||
MDDR_PHY_FIFO_WE_IN_DELAY_1_CR,
|
||||
MDDR_PHY_FIFO_WE_IN_DELAY_2_CR,
|
||||
MDDR_PHY_FIFO_WE_IN_DELAY_3_CR,
|
||||
MDDR_PHY_FIFO_WE_IN_FORCE_CR,
|
||||
MDDR_PHY_FIFO_WE_SLAVE_RATIO_1_CR,
|
||||
MDDR_PHY_FIFO_WE_SLAVE_RATIO_2_CR,
|
||||
MDDR_PHY_FIFO_WE_SLAVE_RATIO_3_CR,
|
||||
MDDR_PHY_FIFO_WE_SLAVE_RATIO_4_CR,
|
||||
MDDR_PHY_GATELVL_INIT_MODE_CR,
|
||||
MDDR_PHY_GATELVL_INIT_RATIO_1_CR,
|
||||
MDDR_PHY_GATELVL_INIT_RATIO_2_CR,
|
||||
MDDR_PHY_GATELVL_INIT_RATIO_3_CR,
|
||||
MDDR_PHY_GATELVL_INIT_RATIO_4_CR,
|
||||
MDDR_PHY_LOCAL_ODT_CR,
|
||||
MDDR_PHY_INVERT_CLKOUT_CR,
|
||||
MDDR_PHY_RD_DQS_SLAVE_DELAY_1_CR,
|
||||
MDDR_PHY_RD_DQS_SLAVE_DELAY_2_CR,
|
||||
MDDR_PHY_RD_DQS_SLAVE_DELAY_3_CR,
|
||||
MDDR_PHY_RD_DQS_SLAVE_FORCE_CR,
|
||||
MDDR_PHY_RD_DQS_SLAVE_RATIO_1_CR,
|
||||
MDDR_PHY_RD_DQS_SLAVE_RATIO_2_CR,
|
||||
MDDR_PHY_RD_DQS_SLAVE_RATIO_3_CR,
|
||||
MDDR_PHY_RD_DQS_SLAVE_RATIO_4_CR,
|
||||
MDDR_PHY_WR_DQS_SLAVE_DELAY_1_CR,
|
||||
MDDR_PHY_WR_DQS_SLAVE_DELAY_2_CR,
|
||||
MDDR_PHY_WR_DQS_SLAVE_DELAY_3_CR,
|
||||
MDDR_PHY_WR_DQS_SLAVE_FORCE_CR,
|
||||
MDDR_PHY_WR_DQS_SLAVE_RATIO_1_CR,
|
||||
MDDR_PHY_WR_DQS_SLAVE_RATIO_2_CR,
|
||||
MDDR_PHY_WR_DQS_SLAVE_RATIO_3_CR,
|
||||
MDDR_PHY_WR_DQS_SLAVE_RATIO_4_CR,
|
||||
MDDR_PHY_WR_DATA_SLAVE_DELAY_1_CR,
|
||||
MDDR_PHY_WR_DATA_SLAVE_DELAY_2_CR,
|
||||
MDDR_PHY_WR_DATA_SLAVE_DELAY_3_CR,
|
||||
MDDR_PHY_WR_DATA_SLAVE_FORCE_CR,
|
||||
MDDR_PHY_WR_DATA_SLAVE_RATIO_1_CR,
|
||||
MDDR_PHY_WR_DATA_SLAVE_RATIO_2_CR,
|
||||
MDDR_PHY_WR_DATA_SLAVE_RATIO_3_CR,
|
||||
MDDR_PHY_WR_DATA_SLAVE_RATIO_4_CR,
|
||||
MDDR_PHY_WRLVL_INIT_MODE_CR,
|
||||
MDDR_PHY_WRLVL_INIT_RATIO_1_CR,
|
||||
MDDR_PHY_WRLVL_INIT_RATIO_2_CR,
|
||||
MDDR_PHY_WRLVL_INIT_RATIO_3_CR,
|
||||
MDDR_PHY_WRLVL_INIT_RATIO_4_CR,
|
||||
MDDR_PHY_WR_RD_RL_CR,
|
||||
MDDR_PHY_RDC_FIFO_RST_ERR_CNT_CLR_CR,
|
||||
MDDR_PHY_RDC_WE_TO_RE_DELAY_CR,
|
||||
MDDR_PHY_USE_FIXED_RE_CR,
|
||||
MDDR_PHY_USE_RANK0_DELAYS_CR,
|
||||
MDDR_PHY_USE_LVL_TRNG_LEVEL_CR,
|
||||
MDDR_PHY_DYN_CONFIG_CR,
|
||||
MDDR_PHY_RD_WR_GATE_LVL_CR,
|
||||
MDDR_PHY_DYN_RESET_CR
|
||||
},
|
||||
|
||||
/*---------------------------------------------------------------------
|
||||
* FIC-64 registers
|
||||
* These registers are 16-bit wide and 32-bit aligned.
|
||||
*/
|
||||
{
|
||||
MDDR_DDR_FIC_NB_ADDR_CR,
|
||||
MDDR_DDR_FIC_NBRWB_SIZE_CR,
|
||||
MDDR_DDR_FIC_WB_TIMEOUT_CR,
|
||||
MDDR_DDR_FIC_HPD_SW_RW_EN_CR,
|
||||
MDDR_DDR_FIC_HPD_SW_RW_INVAL_CR,
|
||||
MDDR_DDR_FIC_SW_WR_ERCLR_CR,
|
||||
MDDR_DDR_FIC_ERR_INT_ENABLE_CR,
|
||||
MDDR_DDR_FIC_NUM_AHB_MASTERS_CR,
|
||||
MDDR_DDR_FIC_LOCK_TIMEOUTVAL_1_CR,
|
||||
MDDR_DDR_FIC_LOCK_TIMEOUTVAL_2_CR,
|
||||
MDDR_DDR_FIC_LOCK_TIMEOUT_EN_CR
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*==============================================================================
|
||||
* FDDR configuration
|
||||
*/
|
||||
#if MSS_SYS_FDDR_CONFIG_BY_CORTEX
|
||||
|
||||
#include "sys_config_fddr_define.h"
|
||||
|
||||
FDDR_TypeDef * const g_m2s_fddr_addr = (FDDR_TypeDef *)0x40021000;
|
||||
|
||||
const fddr_sysreg_t g_m2s_fddr_sysreg_subsys_config =
|
||||
{
|
||||
0x0001u, /* PLL_CONFIG_LOW_1 */
|
||||
0x0002u, /* PLL_CONFIG_LOW_2 */
|
||||
0x0003u, /* PLL_CONFIG_HIGH */
|
||||
0x0004u, /* FACC_CLK_EN */
|
||||
0x0005u, /* FACC_MUX_CONFIG */
|
||||
0x0006u, /* FACC_DIVISOR_RATIO */
|
||||
0x0007u, /* PLL_DELAY_LINE_SEL */
|
||||
0x0008u, /* SOFT_RESET */
|
||||
0x0009u, /* IO_CALIB */
|
||||
0x000Au, /* INTERRUPT_ENABLE */
|
||||
0x000Bu, /* AXI_AHB_MODE_SEL */
|
||||
0x000Cu /* PHY_SELF_REF_EN */
|
||||
};
|
||||
|
||||
const ddr_subsys_cfg_t g_m2s_fddr_subsys_config =
|
||||
{
|
||||
/*---------------------------------------------------------------------
|
||||
* DDR Controller registers.
|
||||
* All registers are 16-bit wide unless mentioned beside the definition.
|
||||
*/
|
||||
{
|
||||
FDDR_DDRC_DYN_SOFT_RESET_CR,
|
||||
FDDR_DDRC_RESERVED0,
|
||||
FDDR_DDRC_DYN_REFRESH_1_CR,
|
||||
FDDR_DDRC_DYN_REFRESH_2_CR,
|
||||
FDDR_DDRC_DYN_POWERDOWN_CR,
|
||||
FDDR_DDRC_DYN_DEBUG_CR,
|
||||
FDDR_DDRC_MODE_CR,
|
||||
FDDR_DDRC_ADDR_MAP_BANK_CR,
|
||||
FDDR_DDRC_ECC_DATA_MASK_CR,
|
||||
FDDR_DDRC_ADDR_MAP_COL_1_CR,
|
||||
FDDR_DDRC_ADDR_MAP_COL_2_CR,
|
||||
FDDR_DDRC_ADDR_MAP_ROW_1_CR,
|
||||
FDDR_DDRC_ADDR_MAP_ROW_2_CR,
|
||||
FDDR_DDRC_INIT_1_CR,
|
||||
FDDR_DDRC_CKE_RSTN_CYCLES_1_CR,
|
||||
FDDR_DDRC_CKE_RSTN_CYCLES_2_CR,
|
||||
FDDR_DDRC_INIT_MR_CR,
|
||||
FDDR_DDRC_INIT_EMR_CR,
|
||||
FDDR_DDRC_INIT_EMR2_CR,
|
||||
FDDR_DDRC_INIT_EMR3_CR,
|
||||
FDDR_DDRC_DRAM_BANK_TIMING_PARAM_CR,
|
||||
FDDR_DDRC_DRAM_RD_WR_LATENCY_CR,
|
||||
FDDR_DDRC_DRAM_RD_WR_PRE_CR,
|
||||
FDDR_DDRC_DRAM_MR_TIMING_PARAM_CR,
|
||||
FDDR_DDRC_DRAM_RAS_TIMING_CR,
|
||||
FDDR_DDRC_DRAM_RD_WR_TRNARND_TIME_CR,
|
||||
FDDR_DDRC_DRAM_T_PD_CR,
|
||||
FDDR_DDRC_DRAM_BANK_ACT_TIMING_CR,
|
||||
FDDR_DDRC_ODT_PARAM_1_CR,
|
||||
FDDR_DDRC_ODT_PARAM_2_CR,
|
||||
FDDR_DDRC_ADDR_MAP_COL_3_CR,
|
||||
FDDR_DDRC_MODE_REG_RD_WR_CR,
|
||||
FDDR_DDRC_MODE_REG_DATA_CR,
|
||||
FDDR_DDRC_PWR_SAVE_1_CR,
|
||||
FDDR_DDRC_PWR_SAVE_2_CR,
|
||||
FDDR_DDRC_ZQ_LONG_TIME_CR,
|
||||
FDDR_DDRC_ZQ_SHORT_TIME_CR,
|
||||
FDDR_DDRC_ZQ_SHORT_INT_REFRESH_MARGIN_1_CR,
|
||||
FDDR_DDRC_ZQ_SHORT_INT_REFRESH_MARGIN_2_CR,
|
||||
FDDR_DDRC_PERF_PARAM_1_CR,
|
||||
FDDR_DDRC_HPR_QUEUE_PARAM_1_CR,
|
||||
FDDR_DDRC_HPR_QUEUE_PARAM_2_CR,
|
||||
FDDR_DDRC_LPR_QUEUE_PARAM_1_CR,
|
||||
FDDR_DDRC_LPR_QUEUE_PARAM_2_CR,
|
||||
FDDR_DDRC_WR_QUEUE_PARAM_CR,
|
||||
FDDR_DDRC_PERF_PARAM_2_CR,
|
||||
FDDR_DDRC_PERF_PARAM_3_CR,
|
||||
FDDR_DDRC_DFI_RDDATA_EN_CR,
|
||||
FDDR_DDRC_DFI_MIN_CTRLUPD_TIMING_CR,
|
||||
FDDR_DDRC_DFI_MAX_CTRLUPD_TIMING_CR,
|
||||
FDDR_DDRC_DFI_WR_LVL_CONTROL_1_CR,
|
||||
FDDR_DDRC_DFI_WR_LVL_CONTROL_2_CR,
|
||||
FDDR_DDRC_DFI_RD_LVL_CONTROL_1_CR,
|
||||
FDDR_DDRC_DFI_RD_LVL_CONTROL_2_CR,
|
||||
FDDR_DDRC_DFI_CTRLUPD_TIME_INTERVAL_CR,
|
||||
FDDR_DDRC_DYN_SOFT_RESET_ALIAS_CR,
|
||||
FDDR_DDRC_AXI_FABRIC_PRI_ID_CR
|
||||
},
|
||||
|
||||
/*---------------------------------------------------------------------
|
||||
* DDR PHY configuration registers
|
||||
*/
|
||||
{
|
||||
FDDR_PHY_LOOPBACK_TEST_CR,
|
||||
FDDR_PHY_BOARD_LOOPBACK_CR,
|
||||
FDDR_PHY_CTRL_SLAVE_RATIO_CR,
|
||||
FDDR_PHY_CTRL_SLAVE_FORCE_CR,
|
||||
FDDR_PHY_CTRL_SLAVE_DELAY_CR,
|
||||
FDDR_PHY_DATA_SLICE_IN_USE_CR,
|
||||
FDDR_PHY_LVL_NUM_OF_DQ0_CR,
|
||||
FDDR_PHY_DQ_OFFSET_1_CR,
|
||||
FDDR_PHY_DQ_OFFSET_2_CR,
|
||||
FDDR_PHY_DQ_OFFSET_3_CR,
|
||||
FDDR_PHY_DIS_CALIB_RST_CR,
|
||||
FDDR_PHY_DLL_LOCK_DIFF_CR,
|
||||
FDDR_PHY_FIFO_WE_IN_DELAY_1_CR,
|
||||
FDDR_PHY_FIFO_WE_IN_DELAY_2_CR,
|
||||
FDDR_PHY_FIFO_WE_IN_DELAY_3_CR,
|
||||
FDDR_PHY_FIFO_WE_IN_FORCE_CR,
|
||||
FDDR_PHY_FIFO_WE_SLAVE_RATIO_1_CR,
|
||||
FDDR_PHY_FIFO_WE_SLAVE_RATIO_2_CR,
|
||||
FDDR_PHY_FIFO_WE_SLAVE_RATIO_3_CR,
|
||||
FDDR_PHY_FIFO_WE_SLAVE_RATIO_4_CR,
|
||||
FDDR_PHY_GATELVL_INIT_MODE_CR,
|
||||
FDDR_PHY_GATELVL_INIT_RATIO_1_CR,
|
||||
FDDR_PHY_GATELVL_INIT_RATIO_2_CR,
|
||||
FDDR_PHY_GATELVL_INIT_RATIO_3_CR,
|
||||
FDDR_PHY_GATELVL_INIT_RATIO_4_CR,
|
||||
FDDR_PHY_LOCAL_ODT_CR,
|
||||
FDDR_PHY_INVERT_CLKOUT_CR,
|
||||
FDDR_PHY_RD_DQS_SLAVE_DELAY_1_CR,
|
||||
FDDR_PHY_RD_DQS_SLAVE_DELAY_2_CR,
|
||||
FDDR_PHY_RD_DQS_SLAVE_DELAY_3_CR,
|
||||
FDDR_PHY_RD_DQS_SLAVE_FORCE_CR,
|
||||
FDDR_PHY_RD_DQS_SLAVE_RATIO_1_CR,
|
||||
FDDR_PHY_RD_DQS_SLAVE_RATIO_2_CR,
|
||||
FDDR_PHY_RD_DQS_SLAVE_RATIO_3_CR,
|
||||
FDDR_PHY_RD_DQS_SLAVE_RATIO_4_CR,
|
||||
FDDR_PHY_WR_DQS_SLAVE_DELAY_1_CR,
|
||||
FDDR_PHY_WR_DQS_SLAVE_DELAY_2_CR,
|
||||
FDDR_PHY_WR_DQS_SLAVE_DELAY_3_CR,
|
||||
FDDR_PHY_WR_DQS_SLAVE_FORCE_CR,
|
||||
FDDR_PHY_WR_DQS_SLAVE_RATIO_1_CR,
|
||||
FDDR_PHY_WR_DQS_SLAVE_RATIO_2_CR,
|
||||
FDDR_PHY_WR_DQS_SLAVE_RATIO_3_CR,
|
||||
FDDR_PHY_WR_DQS_SLAVE_RATIO_4_CR,
|
||||
FDDR_PHY_WR_DATA_SLAVE_DELAY_1_CR,
|
||||
FDDR_PHY_WR_DATA_SLAVE_DELAY_2_CR,
|
||||
FDDR_PHY_WR_DATA_SLAVE_DELAY_3_CR,
|
||||
FDDR_PHY_WR_DATA_SLAVE_FORCE_CR,
|
||||
FDDR_PHY_WR_DATA_SLAVE_RATIO_1_CR,
|
||||
FDDR_PHY_WR_DATA_SLAVE_RATIO_2_CR,
|
||||
FDDR_PHY_WR_DATA_SLAVE_RATIO_3_CR,
|
||||
FDDR_PHY_WR_DATA_SLAVE_RATIO_4_CR,
|
||||
FDDR_PHY_WRLVL_INIT_MODE_CR,
|
||||
FDDR_PHY_WRLVL_INIT_RATIO_1_CR,
|
||||
FDDR_PHY_WRLVL_INIT_RATIO_2_CR,
|
||||
FDDR_PHY_WRLVL_INIT_RATIO_3_CR,
|
||||
FDDR_PHY_WRLVL_INIT_RATIO_4_CR,
|
||||
FDDR_PHY_WR_RD_RL_CR,
|
||||
FDDR_PHY_RDC_FIFO_RST_ERR_CNT_CLR_CR,
|
||||
FDDR_PHY_RDC_WE_TO_RE_DELAY_CR,
|
||||
FDDR_PHY_USE_FIXED_RE_CR,
|
||||
FDDR_PHY_USE_RANK0_DELAYS_CR,
|
||||
FDDR_PHY_USE_LVL_TRNG_LEVEL_CR,
|
||||
FDDR_PHY_DYN_CONFIG_CR,
|
||||
FDDR_PHY_RD_WR_GATE_LVL_CR,
|
||||
FDDR_PHY_DYN_RESET_CR,
|
||||
},
|
||||
|
||||
/*---------------------------------------------------------------------
|
||||
* FIC-64 registers
|
||||
* These registers are 16-bit wide and 32-bit aligned.
|
||||
*/
|
||||
{
|
||||
FDDR_DDR_FIC_NB_ADDR_CR,
|
||||
FDDR_DDR_FIC_NBRWB_SIZE_CR,
|
||||
FDDR_DDR_FIC_WB_TIMEOUT_CR,
|
||||
FDDR_DDR_FIC_HPD_SW_RW_EN_CR,
|
||||
FDDR_DDR_FIC_HPD_SW_RW_INVAL_CR,
|
||||
FDDR_DDR_FIC_SW_WR_ERCLR_CR,
|
||||
FDDR_DDR_FIC_ERR_INT_ENABLE_CR,
|
||||
FDDR_DDR_FIC_NUM_AHB_MASTERS_CR,
|
||||
FDDR_DDR_FIC_LOCK_TIMEOUTVAL_1_CR,
|
||||
FDDR_DDR_FIC_LOCK_TIMEOUTVAL_2_CR,
|
||||
FDDR_DDR_FIC_LOCK_TIMEOUT_EN_CR
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2012 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* Smartfusion2 system configuration. This file is automatically generated
|
||||
* by the Libero tools.
|
||||
*
|
||||
*/
|
||||
#ifndef MSS_SYSTEM_CONFIGURATION
|
||||
#define MSS_SYSTEM_CONFIGURATION
|
||||
|
||||
/*==============================================================================
|
||||
* Clock configuration
|
||||
*/
|
||||
#include "sys_config_mss_clocks.h"
|
||||
|
||||
/*==============================================================================
|
||||
* Memory remapping configuration
|
||||
*/
|
||||
/* TBD */
|
||||
|
||||
/*==============================================================================
|
||||
* FACC_INIT (Cortex-M3 runs the FACC INIT procedure)
|
||||
* Only set to 1 for design targeting the M2S050T_ES device
|
||||
*/
|
||||
#define MSS_SYS_FACC_INIT_BY_CORTEX 1
|
||||
|
||||
/*==============================================================================
|
||||
* MDDR configuration
|
||||
*/
|
||||
#define MSS_SYS_MDDR_CONFIG_BY_CORTEX 0
|
||||
|
||||
/*==============================================================================
|
||||
* FDDR configuration
|
||||
*/
|
||||
#define MSS_SYS_FDDR_CONFIG_BY_CORTEX 0
|
||||
|
||||
/*==============================================================================
|
||||
* SERDES Interface configuration
|
||||
*/
|
||||
#define MSS_SYS_SERDES_0_CONFIG_BY_CORTEX 0
|
||||
#if MSS_SYS_SERDES_0_CONFIG_BY_CORTEX
|
||||
#include "sys_config_SERDESIF_0.h"
|
||||
#endif
|
||||
|
||||
#define MSS_SYS_SERDES_1_CONFIG_BY_CORTEX 0
|
||||
#if MSS_SYS_SERDES_1_CONFIG_BY_CORTEX
|
||||
#include "sys_config_SERDESIF_1.h"
|
||||
#endif
|
||||
|
||||
#define MSS_SYS_SERDES_2_CONFIG_BY_CORTEX 0
|
||||
#if MSS_SYS_SERDES_2_CONFIG_BY_CORTEX
|
||||
#include "sys_config_SERDESIF_2.h"
|
||||
#endif
|
||||
|
||||
#define MSS_SYS_SERDES_3_CONFIG_BY_CORTEX 0
|
||||
#if MSS_SYS_SERDES_3_CONFIG_BY_CORTEX
|
||||
#include "sys_config_SERDESIF_3.h"
|
||||
#endif
|
||||
|
||||
/*==============================================================================
|
||||
* Cache configuration
|
||||
*/
|
||||
#define MSS_SYS_CACHE_CONFIG_BY_CORTEX 0
|
||||
|
||||
#endif /* MSS_SYSTEM_CONFIGURATION */
|
||||
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
/**************************************************************************
|
||||
* (c) Copyright 2012 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* Smartfusion2 system configuration.
|
||||
* - Automatically created by Microsemi Libero SoC Sun May 05 13:12:03 2013
|
||||
*
|
||||
* Warning: Do not modify this file, it may lead to unexpected
|
||||
* functional failures in your Microcontroller Subsystem.
|
||||
*/
|
||||
#ifndef SYS_CONFIG_MSS_CLOCKS
|
||||
#define SYS_CONFIG_MSS_CLOCKS
|
||||
|
||||
#define MSS_SYS_M3_CLK_FREQ 50000000u
|
||||
#define MSS_SYS_MDDR_CLK_FREQ 200000000u
|
||||
#define MSS_SYS_APB_0_CLK_FREQ 50000000u
|
||||
#define MSS_SYS_APB_1_CLK_FREQ 50000000u
|
||||
#define MSS_SYS_APB_2_CLK_FREQ 12500000u
|
||||
#define MSS_SYS_FIC_0_CLK_FREQ 50000000u
|
||||
#define MSS_SYS_FIC_1_CLK_FREQ 50000000u
|
||||
#define MSS_SYS_FIC64_CLK_FREQ 50000000u
|
||||
|
||||
#endif /* SYS_CONFIG_MSS_CLOCKS */
|
|
@ -0,0 +1,30 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2007-2013 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* SVN $Revision: 5258 $
|
||||
* SVN $Date: 2013-03-21 12:41:02 +0000 (Thu, 21 Mar 2013) $
|
||||
*/
|
||||
#ifndef __CPU_TYPES_H
|
||||
#define __CPU_TYPES_H 1
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
*/
|
||||
typedef unsigned int size_t;
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* addr_t: address type.
|
||||
* Used to specify the address of peripherals present in the processor's memory
|
||||
* map.
|
||||
*/
|
||||
typedef unsigned int addr_t;
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* psr_t: processor state register.
|
||||
* Used by HAL_disable_interrupts() and HAL_restore_interrupts() to store the
|
||||
* processor's state between disabling and restoring interrupts.
|
||||
*/
|
||||
typedef unsigned int psr_t;
|
||||
|
||||
#endif /* __CPU_TYPES_H */
|
|
@ -0,0 +1,31 @@
|
|||
#-------------------------------------------------------------------------------
|
||||
# (c) Copyright 2007-2013 Microsemi SoC Products Group. All rights reserved.
|
||||
#
|
||||
# Interrupt disabling/restoration for critical section protection.
|
||||
#
|
||||
# SVN $Revision: 5258 $
|
||||
# SVN $Date: 2013-03-21 12:41:02 +0000 (Thu, 21 Mar 2013) $
|
||||
#
|
||||
.text
|
||||
.global HAL_disable_interrupts
|
||||
.global HAL_restore_interrupts
|
||||
.code 16
|
||||
.syntax unified
|
||||
.type HAL_disable_interrupts, function
|
||||
.type HAL_restore_interrupts, function
|
||||
#-------------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
HAL_disable_interrupts:
|
||||
mrs r0, PRIMASK
|
||||
cpsid I
|
||||
bx lr
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
HAL_restore_interrupts:
|
||||
msr PRIMASK, r0
|
||||
bx lr
|
||||
|
||||
.end
|
|
@ -0,0 +1,96 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2007-2013 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* Hardware registers access macros.
|
||||
*
|
||||
* THE MACROS DEFINED IN THIS FILE ARE DEPRECATED. DO NOT USED FOR NEW
|
||||
* DEVELOPMENT.
|
||||
*
|
||||
* These macros are used to access peripheral's registers. They allow access to
|
||||
* 8, 16 and 32 bit wide registers. All accesses to peripheral registers should
|
||||
* be done through these macros in order to ease porting accross different
|
||||
* processors/bus architectures.
|
||||
*
|
||||
* Some of these macros also allow to access a specific register field.
|
||||
*
|
||||
* SVN $Revision: 5258 $
|
||||
* SVN $Date: 2013-03-21 12:41:02 +0000 (Thu, 21 Mar 2013) $
|
||||
*/
|
||||
#ifndef __HW_REGISTER_MACROS_H
|
||||
#define __HW_REGISTER_MACROS_H 1
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* 32 bits registers access:
|
||||
*/
|
||||
#define HW_get_uint32_reg(BASE_ADDR, REG_OFFSET) (*((uint32_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)))
|
||||
|
||||
#define HW_set_uint32_reg(BASE_ADDR, REG_OFFSET, VALUE) (*((uint32_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)) = (VALUE))
|
||||
|
||||
#define HW_set_uint32_reg_field(BASE_ADDR, FIELD, VALUE) \
|
||||
(*((uint32_t volatile *)(BASE_ADDR + FIELD##_OFFSET)) = \
|
||||
( \
|
||||
(uint32_t) \
|
||||
( \
|
||||
(*((uint32_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & ~FIELD##_MASK) | \
|
||||
(uint32_t)(((VALUE) << FIELD##_SHIFT) & FIELD##_MASK) \
|
||||
) \
|
||||
)
|
||||
|
||||
#define HW_get_uint32_reg_field( BASE_ADDR, FIELD ) \
|
||||
(( (*((uint32_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & FIELD##_MASK) >> FIELD##_SHIFT)
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* 32 bits memory access:
|
||||
*/
|
||||
#define HW_get_uint32(BASE_ADDR) (*((uint32_t volatile *)(BASE_ADDR)))
|
||||
|
||||
#define HW_set_uint32(BASE_ADDR, VALUE) (*((uint32_t volatile *)(BASE_ADDR)) = (VALUE))
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* 16 bits registers access:
|
||||
*/
|
||||
#define HW_get_uint16_reg(BASE_ADDR, REG_OFFSET) (*((uint16_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)))
|
||||
|
||||
#define HW_set_uint16_reg(BASE_ADDR, REG_OFFSET, VALUE) (*((uint16_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)) = (VALUE))
|
||||
|
||||
#define HW_set_uint16_reg_field(BASE_ADDR, FIELD, VALUE) \
|
||||
(*((uint16_t volatile *)(BASE_ADDR + FIELD##_OFFSET)) = \
|
||||
( \
|
||||
(uint16_t) \
|
||||
( \
|
||||
(*((uint16_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & ~FIELD##_MASK) | \
|
||||
(uint16_t)(((VALUE) << FIELD##_SHIFT) & FIELD##_MASK) \
|
||||
) \
|
||||
)
|
||||
|
||||
#define HW_get_uint16_reg_field( BASE_ADDR, FIELD ) \
|
||||
(( (*((uint16_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & FIELD##_MASK) >> FIELD##_SHIFT)
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* 8 bits registers access:
|
||||
*/
|
||||
#define HW_get_uint8_reg(BASE_ADDR, REG_OFFSET) (*((uint8_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)))
|
||||
|
||||
#define HW_set_uint8_reg(BASE_ADDR, REG_OFFSET, VALUE) (*((uint8_t volatile *)(BASE_ADDR + REG_OFFSET##_REG_OFFSET)) = (VALUE))
|
||||
|
||||
#define HW_set_uint8_reg_field(BASE_ADDR, FIELD, VALUE) \
|
||||
(*((uint8_t volatile *)(BASE_ADDR + FIELD##_OFFSET)) = \
|
||||
( \
|
||||
(uint8_t) \
|
||||
( \
|
||||
(*((uint8_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & ~FIELD##_MASK) | \
|
||||
(uint8_t)(((VALUE) << FIELD##_SHIFT) & FIELD##_MASK) \
|
||||
) \
|
||||
)
|
||||
|
||||
#define HW_get_uint8_reg_field( BASE_ADDR, FIELD ) \
|
||||
(( (*((uint8_t volatile *)(BASE_ADDR + FIELD##_OFFSET))) & FIELD##_MASK) >> FIELD##_SHIFT)
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* 8 bits memory access:
|
||||
*/
|
||||
#define HW_get_uint8(BASE_ADDR) (*((uint8_t volatile *)(BASE_ADDR)))
|
||||
|
||||
#define HW_set_uint8(BASE_ADDR, VALUE) (*((uint8_t volatile *)(BASE_ADDR)) = (VALUE))
|
||||
|
||||
#endif /* __HW_REGISTER_MACROS_H */
|
|
@ -0,0 +1,165 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2008-2013 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* SVN $Revision: 5258 $
|
||||
* SVN $Date: 2013-03-21 12:41:02 +0000 (Thu, 21 Mar 2013) $
|
||||
*/
|
||||
|
||||
.text
|
||||
.global HW_set_32bit_reg
|
||||
.global HW_get_32bit_reg
|
||||
.global HW_set_32bit_reg_field
|
||||
.global HW_get_32bit_reg_field
|
||||
.global HW_set_16bit_reg
|
||||
.global HW_get_16bit_reg
|
||||
.global HW_set_16bit_reg_field
|
||||
.global HW_get_16bit_reg_field
|
||||
.global HW_set_8bit_reg
|
||||
.global HW_get_8bit_reg
|
||||
.global HW_set_8bit_reg_field
|
||||
.global HW_get_8bit_reg_field
|
||||
.code 16
|
||||
.syntax unified
|
||||
.type HW_set_32bit_reg, function
|
||||
.type HW_get_32bit_reg, function
|
||||
.type HW_set_32bit_reg_field, function
|
||||
.type HW_get_32bit_reg_field, function
|
||||
.type HW_set_16bit_reg, function
|
||||
.type HW_get_16bit_reg, function
|
||||
.type HW_set_16bit_reg_field, function
|
||||
.type HW_get_16bit_reg_field, function
|
||||
.type HW_set_8bit_reg, function
|
||||
.type HW_get_8bit_reg, function
|
||||
.type HW_set_8bit_reg_field, function
|
||||
.type HW_get_8bit_reg_field, function
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* R0: addr_t reg_addr
|
||||
* R1: uint32_t value
|
||||
*/
|
||||
HW_set_32bit_reg:
|
||||
STR R1, [R0]
|
||||
BX LR
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* R0: addr_t reg_addr
|
||||
*/
|
||||
HW_get_32bit_reg:
|
||||
LDR R0, [R0]
|
||||
BX LR
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* R0: addr_t reg_addr
|
||||
* R1: int_fast8_t shift
|
||||
* R2: uint32_t mask
|
||||
* R3: uint32_t value
|
||||
*/
|
||||
HW_set_32bit_reg_field:
|
||||
PUSH {R1,R2,R3,LR}
|
||||
LSL.W R3, R3, R1
|
||||
AND.W R3, R3, R2
|
||||
LDR R1, [R0]
|
||||
MVN.W R2, R2
|
||||
AND.W R1, R1, R2
|
||||
ORR.W R1, R1, R3
|
||||
STR R1, [R0]
|
||||
POP {R1,R2,R3,PC}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* R0: addr_t reg_addr
|
||||
* R1: int_fast8_t shift
|
||||
* R2: uint32_t mask
|
||||
*/
|
||||
HW_get_32bit_reg_field:
|
||||
LDR R0, [R0]
|
||||
AND.W R0, R0, R2
|
||||
LSR.W R0, R0, R1
|
||||
BX LR
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* R0: addr_t reg_addr
|
||||
* R1: uint_fast16_t value
|
||||
*/
|
||||
HW_set_16bit_reg:
|
||||
STRH R1, [R0]
|
||||
BX LR
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* R0: addr_t reg_addr
|
||||
*/
|
||||
HW_get_16bit_reg:
|
||||
LDRH R0, [R0]
|
||||
BX LR
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* R0: addr_t reg_addr
|
||||
* R1: int_fast8_t shift
|
||||
* R2: uint_fast16_t mask
|
||||
* R3: uint_fast16_t value
|
||||
*/
|
||||
HW_set_16bit_reg_field:
|
||||
PUSH {R1,R2,R3,LR}
|
||||
LSL.W R3, R3, R1
|
||||
AND.W R3, R3, R2
|
||||
LDRH R1, [R0]
|
||||
MVN.W R2, R2
|
||||
AND.W R1, R1, R2
|
||||
ORR.W R1, R1, R3
|
||||
STRH R1, [R0]
|
||||
POP {R1,R2,R3,PC}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* R0: addr_t reg_addr
|
||||
* R1: int_fast8_t shift
|
||||
* R2: uint_fast16_t mask
|
||||
*/
|
||||
HW_get_16bit_reg_field:
|
||||
LDRH R0, [R0]
|
||||
AND.W R0, R0, R2
|
||||
LSR.W R0, R0, R1
|
||||
BX LR
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* R0: addr_t reg_addr
|
||||
* R1: uint_fast8_t value
|
||||
*/
|
||||
HW_set_8bit_reg:
|
||||
STRB R1, [R0]
|
||||
BX LR
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* R0: addr_t reg_addr
|
||||
*/
|
||||
HW_get_8bit_reg:
|
||||
LDRB R0, [R0]
|
||||
BX LR
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* R0: addr_t reg_addr,
|
||||
* R1: int_fast8_t shift
|
||||
* R2: uint_fast8_t mask
|
||||
* R3: uint_fast8_t value
|
||||
*/
|
||||
HW_set_8bit_reg_field:
|
||||
PUSH {R1,R2,R3,LR}
|
||||
LSL.W R3, R3, R1
|
||||
AND.W R3, R3, R2
|
||||
LDRB R1, [R0]
|
||||
MVN.W R2, R2
|
||||
AND.W R1, R1, R2
|
||||
ORR.W R1, R1, R3
|
||||
STRB R1, [R0]
|
||||
POP {R1,R2,R3,PC}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* R0: addr_t reg_addr
|
||||
* R1: int_fast8_t shift
|
||||
* R2: uint_fast8_t mask
|
||||
*/
|
||||
HW_get_8bit_reg_field:
|
||||
LDRB R0, [R0]
|
||||
AND.W R0, R0, R2
|
||||
LSR.W R0, R0, R1
|
||||
BX LR
|
||||
|
||||
.end
|
|
@ -0,0 +1,205 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2007-2013 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* Legacy Actel HAL Cortex NVIC control functions.
|
||||
* The use of these functions should be replaced by calls to the equivalent
|
||||
* CMSIS function in your application code.
|
||||
*
|
||||
* SVN $Revision: 5259 $
|
||||
* SVN $Date: 2013-03-21 12:58:05 +0000 (Thu, 21 Mar 2013) $
|
||||
*/
|
||||
#include "cortex_nvic.h"
|
||||
#include "../../CMSIS/mss_assert.h"
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
*
|
||||
*/
|
||||
void NVIC_init( void )
|
||||
{
|
||||
/*
|
||||
* Please use the NVIC control functions provided by the SmartFusion2 CMSIS
|
||||
* Hardware Abstraction Layer. The use of the Actel HAL NVIC control
|
||||
* functions is obsolete on SmartFusion2 devices.
|
||||
*
|
||||
* Simply remove the call to NVIC_init() from your application code.
|
||||
*/
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
*
|
||||
*/
|
||||
void NVIC_set_handler
|
||||
(
|
||||
uint32_t interrupt_number,
|
||||
hal_nvic_irq_handler_t handler
|
||||
)
|
||||
{
|
||||
/*
|
||||
* Please use the NVIC control functions provided by the SmartFusion2 CMSIS
|
||||
* Hardware Abstraction Layer. The use of the Actel HAL NVIC control
|
||||
* functions is obsolete on SmartFusion2 devices.
|
||||
*
|
||||
* Please remove the call to NVIC_set_handler() from your application code
|
||||
* and provide a function using one of the following function prototypes to
|
||||
* handle interrupts from peripherals implemeted in the SmartFusion2 FPGA
|
||||
* fabric:
|
||||
* - void FabricIrq0_IRQHandler(void)
|
||||
* - void FabricIrq1_IRQHandler(void)
|
||||
* - void FabricIrq2_IRQHandler(void)
|
||||
* - void FabricIrq3_IRQHandler(void)
|
||||
* - void FabricIrq4_IRQHandler(void)
|
||||
* - void FabricIrq5_IRQHandler(void)
|
||||
* - void FabricIrq6_IRQHandler(void)
|
||||
* - void FabricIrq7_IRQHandler(void)
|
||||
* - void FabricIrq8_IRQHandler(void)
|
||||
* - void FabricIrq9_IRQHandler(void)
|
||||
* - void FabricIrq10_IRQHandler(void)
|
||||
* - void FabricIrq11_IRQHandler(void)
|
||||
* - void FabricIrq12_IRQHandler(void)
|
||||
* - void FabricIrq13_IRQHandler(void)
|
||||
* - void FabricIrq14_IRQHandler(void)
|
||||
* - void FabricIrq15_IRQHandler(void)
|
||||
* The function to implement depends on which MSS_INT_F2M[n] signal is used
|
||||
* in your Libero design to connect the interrupt signal of the peripheral
|
||||
* generating the interrupt.
|
||||
*/
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
*
|
||||
*/
|
||||
void NVIC_set_priority
|
||||
(
|
||||
uint32_t interrupt_number,
|
||||
uint8_t priority_level
|
||||
)
|
||||
{
|
||||
/*
|
||||
* Please use the NVIC control functions provided by the SmartFusion2 CMSIS
|
||||
* Hardware Abstraction Layer. The use of the Actel HAL NVIC control
|
||||
* functions is obsolete on SmartFusion2 devices.
|
||||
*
|
||||
* Please replace calls to NVIC_set_priority() with a call to the CMSIS
|
||||
* void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) function where
|
||||
* IRQn is one of the following values:
|
||||
* - FabricIrq0_IRQn
|
||||
* - FabricIrq1_IRQn
|
||||
* - FabricIrq2_IRQn
|
||||
* - FabricIrq3_IRQn
|
||||
* - FabricIrq4_IRQn
|
||||
* - FabricIrq5_IRQn
|
||||
* - FabricIrq6_IRQn
|
||||
* - FabricIrq7_IRQn
|
||||
* - FabricIrq8_IRQn
|
||||
* - FabricIrq9_IRQn
|
||||
* - FabricIrq10_IRQn
|
||||
* - FabricIrq11_IRQn
|
||||
* - FabricIrq12_IRQn
|
||||
* - FabricIrq13_IRQn
|
||||
* - FabricIrq14_IRQn
|
||||
* - FabricIrq15_IRQn
|
||||
*/
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
*
|
||||
*/
|
||||
void NVIC_enable_interrupt( uint32_t interrupt_number )
|
||||
{
|
||||
/*
|
||||
* Please use the NVIC control functions provided by the SmartFusion2 CMSIS
|
||||
* Hardware Abstraction Layer. The use of the Actel HAL NVIC control
|
||||
* functions is obsolete on SmartFusion2 devices.
|
||||
*
|
||||
* Please replace calls to NVIC_enable_interrupt() with a call to the CMSIS
|
||||
* void NVIC_EnableIRQ(IRQn_Type IRQn) function where IRQn is one of the
|
||||
* following values:
|
||||
* - FabricIrq0_IRQn
|
||||
* - FabricIrq1_IRQn
|
||||
* - FabricIrq2_IRQn
|
||||
* - FabricIrq3_IRQn
|
||||
* - FabricIrq4_IRQn
|
||||
* - FabricIrq5_IRQn
|
||||
* - FabricIrq6_IRQn
|
||||
* - FabricIrq7_IRQn
|
||||
* - FabricIrq8_IRQn
|
||||
* - FabricIrq9_IRQn
|
||||
* - FabricIrq10_IRQn
|
||||
* - FabricIrq11_IRQn
|
||||
* - FabricIrq12_IRQn
|
||||
* - FabricIrq13_IRQn
|
||||
* - FabricIrq14_IRQn
|
||||
* - FabricIrq15_IRQn
|
||||
*/
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
*
|
||||
*/
|
||||
void NVIC_disable_interrupt( uint32_t interrupt_number )
|
||||
{
|
||||
/*
|
||||
* Please use the NVIC control functions provided by the SmartFusion2 CMSIS
|
||||
* Hardware Abstraction Layer. The use of the Actel HAL NVIC control
|
||||
* functions is obsolete on SmartFusion2 devices.
|
||||
*
|
||||
* Please replace calls to NVIC_disable_interrupt() with a call to the CMSIS
|
||||
* void NVIC_DisableIRQ(IRQn_Type IRQn) function where IRQn is one of the
|
||||
* following values:
|
||||
* - FabricIrq0_IRQn
|
||||
* - FabricIrq1_IRQn
|
||||
* - FabricIrq2_IRQn
|
||||
* - FabricIrq3_IRQn
|
||||
* - FabricIrq4_IRQn
|
||||
* - FabricIrq5_IRQn
|
||||
* - FabricIrq6_IRQn
|
||||
* - FabricIrq7_IRQn
|
||||
* - FabricIrq8_IRQn
|
||||
* - FabricIrq9_IRQn
|
||||
* - FabricIrq10_IRQn
|
||||
* - FabricIrq11_IRQn
|
||||
* - FabricIrq12_IRQn
|
||||
* - FabricIrq13_IRQn
|
||||
* - FabricIrq14_IRQn
|
||||
* - FabricIrq15_IRQn
|
||||
*/
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
*
|
||||
*/
|
||||
void NVIC_clear_interrupt( uint32_t interrupt_number )
|
||||
{
|
||||
/*
|
||||
* Please use the NVIC control functions provided by the SmartFusion2 CMSIS
|
||||
* Hardware Abstraction Layer. The use of the Actel HAL NVIC control
|
||||
* functions is obsolete on SmartFusion2 devices.
|
||||
*
|
||||
* Please replace calls to NVIC_clear_interrupt() with a call to the CMSIS
|
||||
* void NVIC_ClearPendingIRQ(IRQn_Type IRQn) function where IRQn is one of the
|
||||
* following values:
|
||||
* - FabricIrq0_IRQn
|
||||
* - FabricIrq1_IRQn
|
||||
* - FabricIrq2_IRQn
|
||||
* - FabricIrq3_IRQn
|
||||
* - FabricIrq4_IRQn
|
||||
* - FabricIrq5_IRQn
|
||||
* - FabricIrq6_IRQn
|
||||
* - FabricIrq7_IRQn
|
||||
* - FabricIrq8_IRQn
|
||||
* - FabricIrq9_IRQn
|
||||
* - FabricIrq10_IRQn
|
||||
* - FabricIrq11_IRQn
|
||||
* - FabricIrq12_IRQn
|
||||
* - FabricIrq13_IRQn
|
||||
* - FabricIrq14_IRQn
|
||||
* - FabricIrq15_IRQn
|
||||
*/
|
||||
ASSERT(0);
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2007-2013 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* Legacy Actel HAL Cortex NVIC control functions.
|
||||
* The use of these functions should be replaced by calls to the equivalent
|
||||
* CMSIS function in your application code.
|
||||
*
|
||||
* SVN $Revision: 5257 $
|
||||
* SVN $Date: 2013-03-21 12:24:10 +0000 (Thu, 21 Mar 2013) $
|
||||
*/
|
||||
#ifndef CORTEX_NVIC_H_
|
||||
#define CORTEX_NVIC_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef void (*hal_nvic_irq_handler_t)(void);
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void NVIC_init( void );
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void NVIC_set_handler
|
||||
(
|
||||
uint32_t interrupt_number,
|
||||
hal_nvic_irq_handler_t handler
|
||||
);
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void NVIC_set_priority
|
||||
(
|
||||
uint32_t interrupt_number,
|
||||
uint8_t priority_level
|
||||
);
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void NVIC_enable_interrupt( uint32_t interrupt_number );
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void NVIC_disable_interrupt( uint32_t interrupt_number );
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
void NVIC_clear_interrupt( uint32_t interrupt_number );
|
||||
|
||||
#endif /*CORTEX_NVIC_H_*/
|
|
@ -0,0 +1,206 @@
|
|||
/***************************************************************************//**
|
||||
* (c) Copyright 2007-2013 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* Hardware abstraction layer functions.
|
||||
*
|
||||
* SVN $Revision: 5258 $
|
||||
* SVN $Date: 2013-03-21 12:41:02 +0000 (Thu, 21 Mar 2013) $
|
||||
*/
|
||||
#ifndef HAL_H_
|
||||
#define HAL_H_
|
||||
|
||||
#include "cpu_types.h"
|
||||
#include "hw_reg_access.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* Enable all interrupts at the processor level.
|
||||
*/
|
||||
void HAL_enable_interrupts( void );
|
||||
|
||||
/***************************************************************************//**
|
||||
* Disable all interrupts at the processor core level.
|
||||
* Return the interrupts enable state before disabling occured so that it can
|
||||
* later be restored.
|
||||
*/
|
||||
psr_t HAL_disable_interrupts( void );
|
||||
|
||||
/***************************************************************************//**
|
||||
* Restore the interrupts enable state at the processor core level.
|
||||
* This function is normally passed the value returned from a previous call to
|
||||
* HAL_disable_interrupts().
|
||||
*/
|
||||
void HAL_restore_interrupts( psr_t saved_psr );
|
||||
|
||||
/***************************************************************************//**
|
||||
*/
|
||||
#define FIELD_OFFSET(FIELD_NAME) (FIELD_NAME##_OFFSET)
|
||||
#define FIELD_SHIFT(FIELD_NAME) (FIELD_NAME##_SHIFT)
|
||||
#define FIELD_MASK(FIELD_NAME) (FIELD_NAME##_MASK)
|
||||
|
||||
/***************************************************************************//**
|
||||
* The macro HAL_set_32bit_reg() allows writing a 32 bits wide register.
|
||||
*
|
||||
* BASE_ADDR: A variable of type addr_t specifying the base address of the
|
||||
* peripheral containing the register.
|
||||
* REG_NAME: A string identifying the register to write. These strings are
|
||||
* specified in a header file associated with the peripheral.
|
||||
* VALUE: A variable of type uint32_t containing the value to write.
|
||||
*/
|
||||
#define HAL_set_32bit_reg(BASE_ADDR, REG_NAME, VALUE) \
|
||||
(HW_set_32bit_reg( ((BASE_ADDR) + (REG_NAME##_REG_OFFSET)), (VALUE) ))
|
||||
|
||||
/***************************************************************************//**
|
||||
* The macro HAL_get_32bit_reg() is used to read the value of a 32 bits wide
|
||||
* register.
|
||||
*
|
||||
* BASE_ADDR: A variable of type addr_t specifying the base address of the
|
||||
* peripheral containing the register.
|
||||
* REG_NAME: A string identifying the register to read. These strings are
|
||||
* specified in a header file associated with the peripheral.
|
||||
* RETURN: This function-like macro returns a uint32_t value.
|
||||
*/
|
||||
#define HAL_get_32bit_reg(BASE_ADDR, REG_NAME) \
|
||||
(HW_get_32bit_reg( ((BASE_ADDR) + (REG_NAME##_REG_OFFSET)) ))
|
||||
|
||||
/***************************************************************************//**
|
||||
* The macro HAL_set_32bit_reg_field() is used to write a field within a
|
||||
* 32 bits wide register. The field written can be one or more bits.
|
||||
*
|
||||
* BASE_ADDR: A variable of type addr_t specifying the base address of the
|
||||
* peripheral containing the register.
|
||||
* FIELD_NAME: A string identifying the register field to write. These strings
|
||||
* are specified in a header file associated with the peripheral.
|
||||
* VALUE: A variable of type uint32_t containing the field value to write.
|
||||
*/
|
||||
#define HAL_set_32bit_reg_field(BASE_ADDR, FIELD_NAME, VALUE) \
|
||||
(HW_set_32bit_reg_field(\
|
||||
(BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\
|
||||
FIELD_SHIFT(FIELD_NAME),\
|
||||
FIELD_MASK(FIELD_NAME),\
|
||||
(VALUE)))
|
||||
|
||||
/***************************************************************************//**
|
||||
* The macro HAL_get_32bit_reg_field() is used to read a register field from
|
||||
* within a 32 bit wide peripheral register. The field can be one or more bits.
|
||||
*
|
||||
* BASE_ADDR: A variable of type addr_t specifying the base address of the
|
||||
* peripheral containing the register.
|
||||
* FIELD_NAME: A string identifying the register field to write. These strings
|
||||
* are specified in a header file associated with the peripheral.
|
||||
* RETURN: This function-like macro returns a uint32_t value.
|
||||
*/
|
||||
#define HAL_get_32bit_reg_field(BASE_ADDR, FIELD_NAME) \
|
||||
(HW_get_32bit_reg_field(\
|
||||
(BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\
|
||||
FIELD_SHIFT(FIELD_NAME),\
|
||||
FIELD_MASK(FIELD_NAME)))
|
||||
|
||||
/***************************************************************************//**
|
||||
* The macro HAL_set_16bit_reg() allows writing a 16 bits wide register.
|
||||
*
|
||||
* BASE_ADDR: A variable of type addr_t specifying the base address of the
|
||||
* peripheral containing the register.
|
||||
* REG_NAME: A string identifying the register to write. These strings are
|
||||
* specified in a header file associated with the peripheral.
|
||||
* VALUE: A variable of type uint_fast16_t containing the value to write.
|
||||
*/
|
||||
#define HAL_set_16bit_reg(BASE_ADDR, REG_NAME, VALUE) \
|
||||
(HW_set_16bit_reg( ((BASE_ADDR) + (REG_NAME##_REG_OFFSET)), (VALUE) ))
|
||||
|
||||
/***************************************************************************//**
|
||||
* The macro HAL_get_16bit_reg() is used to read the value of a 16 bits wide
|
||||
* register.
|
||||
*
|
||||
* BASE_ADDR: A variable of type addr_t specifying the base address of the
|
||||
* peripheral containing the register.
|
||||
* REG_NAME: A string identifying the register to read. These strings are
|
||||
* specified in a header file associated with the peripheral.
|
||||
* RETURN: This function-like macro returns a uint16_t value.
|
||||
*/
|
||||
#define HAL_get_16bit_reg(BASE_ADDR, REG_NAME) \
|
||||
(HW_get_16bit_reg( (BASE_ADDR) + (REG_NAME##_REG_OFFSET) ))
|
||||
|
||||
/***************************************************************************//**
|
||||
* The macro HAL_set_16bit_reg_field() is used to write a field within a
|
||||
* 16 bits wide register. The field written can be one or more bits.
|
||||
*
|
||||
* BASE_ADDR: A variable of type addr_t specifying the base address of the
|
||||
* peripheral containing the register.
|
||||
* FIELD_NAME: A string identifying the register field to write. These strings
|
||||
* are specified in a header file associated with the peripheral.
|
||||
* VALUE: A variable of type uint16_t containing the field value to write.
|
||||
*/
|
||||
#define HAL_set_16bit_reg_field(BASE_ADDR, FIELD_NAME, VALUE) \
|
||||
(HW_set_16bit_reg_field(\
|
||||
(BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\
|
||||
FIELD_SHIFT(FIELD_NAME),\
|
||||
FIELD_MASK(FIELD_NAME),\
|
||||
(VALUE)))
|
||||
|
||||
/***************************************************************************//**
|
||||
* The macro HAL_get_16bit_reg_field() is used to read a register field from
|
||||
* within a 8 bit wide peripheral register. The field can be one or more bits.
|
||||
*
|
||||
* BASE_ADDR: A variable of type addr_t specifying the base address of the
|
||||
* peripheral containing the register.
|
||||
* FIELD_NAME: A string identifying the register field to write. These strings
|
||||
* are specified in a header file associated with the peripheral.
|
||||
* RETURN: This function-like macro returns a uint16_t value.
|
||||
*/
|
||||
#define HAL_get_16bit_reg_field(BASE_ADDR, FIELD_NAME) \
|
||||
(HW_get_16bit_reg_field(\
|
||||
(BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\
|
||||
FIELD_SHIFT(FIELD_NAME),\
|
||||
FIELD_MASK(FIELD_NAME)))
|
||||
|
||||
/***************************************************************************//**
|
||||
* The macro HAL_set_8bit_reg() allows writing a 8 bits wide register.
|
||||
*
|
||||
* BASE_ADDR: A variable of type addr_t specifying the base address of the
|
||||
* peripheral containing the register.
|
||||
* REG_NAME: A string identifying the register to write. These strings are
|
||||
* specified in a header file associated with the peripheral.
|
||||
* VALUE: A variable of type uint_fast8_t containing the value to write.
|
||||
*/
|
||||
#define HAL_set_8bit_reg(BASE_ADDR, REG_NAME, VALUE) \
|
||||
(HW_set_8bit_reg( ((BASE_ADDR) + (REG_NAME##_REG_OFFSET)), (VALUE) ))
|
||||
|
||||
/***************************************************************************//**
|
||||
* The macro HAL_get_8bit_reg() is used to read the value of a 8 bits wide
|
||||
* register.
|
||||
*
|
||||
* BASE_ADDR: A variable of type addr_t specifying the base address of the
|
||||
* peripheral containing the register.
|
||||
* REG_NAME: A string identifying the register to read. These strings are
|
||||
* specified in a header file associated with the peripheral.
|
||||
* RETURN: This function-like macro returns a uint8_t value.
|
||||
*/
|
||||
#define HAL_get_8bit_reg(BASE_ADDR, REG_NAME) \
|
||||
(HW_get_8bit_reg( (BASE_ADDR) + (REG_NAME##_REG_OFFSET) ))
|
||||
|
||||
/***************************************************************************//**
|
||||
*/
|
||||
#define HAL_set_8bit_reg_field(BASE_ADDR, FIELD_NAME, VALUE) \
|
||||
(HW_set_8bit_reg_field(\
|
||||
(BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\
|
||||
FIELD_SHIFT(FIELD_NAME),\
|
||||
FIELD_MASK(FIELD_NAME),\
|
||||
(VALUE)))
|
||||
|
||||
/***************************************************************************//**
|
||||
* The macro HAL_get_8bit_reg_field() is used to read a register field from
|
||||
* within a 8 bit wide peripheral register. The field can be one or more bits.
|
||||
*
|
||||
* BASE_ADDR: A variable of type addr_t specifying the base address of the
|
||||
* peripheral containing the register.
|
||||
* FIELD_NAME: A string identifying the register field to write. These strings
|
||||
* are specified in a header file associated with the peripheral.
|
||||
* RETURN: This function-like macro returns a uint8_t value.
|
||||
*/
|
||||
#define HAL_get_8bit_reg_field(BASE_ADDR, FIELD_NAME) \
|
||||
(HW_get_8bit_reg_field(\
|
||||
(BASE_ADDR) + FIELD_OFFSET(FIELD_NAME),\
|
||||
FIELD_SHIFT(FIELD_NAME),\
|
||||
FIELD_MASK(FIELD_NAME)))
|
||||
|
||||
#endif /*HAL_H_*/
|
|
@ -0,0 +1,30 @@
|
|||
/*******************************************************************************
|
||||
* (c) Copyright 2008-2013 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* SVN $Revision: 5274 $
|
||||
* SVN $Date: 2013-03-22 13:18:44 +0000 (Fri, 22 Mar 2013) $
|
||||
*/
|
||||
#ifndef HAL_ASSERT_HEADER
|
||||
#define HAL_ASSERT_HEADER
|
||||
|
||||
#include "../CMSIS/mss_assert.h"
|
||||
|
||||
#if defined(NDEBUG)
|
||||
/***************************************************************************//**
|
||||
* HAL_ASSERT() is defined out when the NDEBUG symbol is used.
|
||||
******************************************************************************/
|
||||
#define HAL_ASSERT(CHECK)
|
||||
|
||||
#else
|
||||
/***************************************************************************//**
|
||||
* Default behaviour for HAL_ASSERT() macro:
|
||||
*------------------------------------------------------------------------------
|
||||
* Using the HAL_ASSERT() macro is the same as directly using the SmartFusion2
|
||||
* CMSIS ASSERT() macro. The behaviour is toolchain specific and project
|
||||
* setting specific.
|
||||
******************************************************************************/
|
||||
#define HAL_ASSERT(CHECK) ASSERT(CHECK);
|
||||
|
||||
#endif /* NDEBUG */
|
||||
|
||||
#endif /* HAL_ASSERT_HEADER */
|
|
@ -0,0 +1,227 @@
|
|||
/***************************************************************************//**
|
||||
* (c) Copyright 2007-2013 Microsemi SoC Products Group. All rights reserved.
|
||||
*
|
||||
* Hardware registers access functions.
|
||||
* The implementation of these function is platform and toolchain specific.
|
||||
* The functions declared here are implemented using assembler as part of the
|
||||
* processor/toolchain specific HAL.
|
||||
*
|
||||
* SVN $Revision: 5258 $
|
||||
* SVN $Date: 2013-03-21 12:41:02 +0000 (Thu, 21 Mar 2013) $
|
||||
*/
|
||||
#ifndef HW_REG_ACCESS
|
||||
#define HW_REG_ACCESS
|
||||
|
||||
/***************************************************************************//**
|
||||
* HW_set_32bit_reg is used to write the content of a 32 bits wide peripheral
|
||||
* register.
|
||||
*
|
||||
* @param reg_addr Address in the processor's memory map of the register to
|
||||
* write.
|
||||
* @param value Value to be written into the peripheral register.
|
||||
*/
|
||||
void
|
||||
HW_set_32bit_reg
|
||||
(
|
||||
addr_t reg_addr,
|
||||
uint32_t value
|
||||
);
|
||||
|
||||
/***************************************************************************//**
|
||||
* HW_get_32bit_reg is used to read the content of a 32 bits wide peripheral
|
||||
* register.
|
||||
*
|
||||
* @param reg_addr Address in the processor's memory map of the register to
|
||||
* read.
|
||||
* @return 32 bits value read from the peripheral register.
|
||||
*/
|
||||
uint32_t
|
||||
HW_get_32bit_reg
|
||||
(
|
||||
addr_t reg_addr
|
||||
);
|
||||
|
||||
/***************************************************************************//**
|
||||
* HW_set_32bit_reg_field is used to set the content of a field in a 32 bits
|
||||
* wide peripheral register.
|
||||
*
|
||||
* @param reg_addr Address in the processor's memory map of the register to
|
||||
* be written.
|
||||
* @param shift Bit offset of the register field to be read within the
|
||||
* register.
|
||||
* @param mask Bit mask to be applied to the raw register value to filter
|
||||
* out the other register fields values.
|
||||
* @param value Value to be written in the specified field.
|
||||
*/
|
||||
void
|
||||
HW_set_32bit_reg_field
|
||||
(
|
||||
addr_t reg_addr,
|
||||
int_fast8_t shift,
|
||||
uint32_t mask,
|
||||
uint32_t value
|
||||
);
|
||||
|
||||
/***************************************************************************//**
|
||||
* HW_get_32bit_reg_field is used to read the content of a field out of a
|
||||
* 32 bits wide peripheral register.
|
||||
*
|
||||
* @param reg_addr Address in the processor's memory map of the register to
|
||||
* read.
|
||||
* @param shift Bit offset of the register field to be written within the
|
||||
* register.
|
||||
* @param mask Bit mask to be applied to the raw register value to filter
|
||||
* out the other register fields values.
|
||||
*
|
||||
* @return 32 bits value containing the register field value specified
|
||||
* as parameter.
|
||||
*/
|
||||
uint32_t
|
||||
HW_get_32bit_reg_field
|
||||
(
|
||||
addr_t reg_addr,
|
||||
int_fast8_t shift,
|
||||
uint32_t mask
|
||||
);
|
||||
|
||||
/***************************************************************************//**
|
||||
* HW_set_16bit_reg is used to write the content of a 16 bits wide peripheral
|
||||
* register.
|
||||
*
|
||||
* @param reg_addr Address in the processor's memory map of the register to
|
||||
* write.
|
||||
* @param value Value to be written into the peripheral register.
|
||||
*/
|
||||
void
|
||||
HW_set_16bit_reg
|
||||
(
|
||||
addr_t reg_addr,
|
||||
uint_fast16_t value
|
||||
);
|
||||
|
||||
/***************************************************************************//**
|
||||
* HW_get_16bit_reg is used to read the content of a 16 bits wide peripheral
|
||||
* register.
|
||||
*
|
||||
* @param reg_addr Address in the processor's memory map of the register to
|
||||
* read.
|
||||
* @return 16 bits value read from the peripheral register.
|
||||
*/
|
||||
uint16_t
|
||||
HW_get_16bit_reg
|
||||
(
|
||||
addr_t reg_addr
|
||||
);
|
||||
|
||||
/***************************************************************************//**
|
||||
* HW_set_16bit_reg_field is used to set the content of a field in a 16 bits
|
||||
* wide peripheral register.
|
||||
*
|
||||
* @param reg_addr Address in the processor's memory map of the register to
|
||||
* be written.
|
||||
* @param shift Bit offset of the register field to be read within the
|
||||
* register.
|
||||
* @param mask Bit mask to be applied to the raw register value to filter
|
||||
* out the other register fields values.
|
||||
* @param value Value to be written in the specified field.
|
||||
*/
|
||||
void HW_set_16bit_reg_field
|
||||
(
|
||||
addr_t reg_addr,
|
||||
int_fast8_t shift,
|
||||
uint_fast16_t mask,
|
||||
uint_fast16_t value
|
||||
);
|
||||
|
||||
/***************************************************************************//**
|
||||
* HW_get_16bit_reg_field is used to read the content of a field from a
|
||||
* 16 bits wide peripheral register.
|
||||
*
|
||||
* @param reg_addr Address in the processor's memory map of the register to
|
||||
* read.
|
||||
* @param shift Bit offset of the register field to be written within the
|
||||
* register.
|
||||
* @param mask Bit mask to be applied to the raw register value to filter
|
||||
* out the other register fields values.
|
||||
*
|
||||
* @return 16 bits value containing the register field value specified
|
||||
* as parameter.
|
||||
*/
|
||||
uint16_t HW_get_16bit_reg_field
|
||||
(
|
||||
addr_t reg_addr,
|
||||
int_fast8_t shift,
|
||||
uint_fast16_t mask
|
||||
);
|
||||
|
||||
/***************************************************************************//**
|
||||
* HW_set_8bit_reg is used to write the content of a 8 bits wide peripheral
|
||||
* register.
|
||||
*
|
||||
* @param reg_addr Address in the processor's memory map of the register to
|
||||
* write.
|
||||
* @param value Value to be written into the peripheral register.
|
||||
*/
|
||||
void
|
||||
HW_set_8bit_reg
|
||||
(
|
||||
addr_t reg_addr,
|
||||
uint_fast8_t value
|
||||
);
|
||||
|
||||
/***************************************************************************//**
|
||||
* HW_get_8bit_reg is used to read the content of a 8 bits wide peripheral
|
||||
* register.
|
||||
*
|
||||
* @param reg_addr Address in the processor's memory map of the register to
|
||||
* read.
|
||||
* @return 8 bits value read from the peripheral register.
|
||||
*/
|
||||
uint8_t
|
||||
HW_get_8bit_reg
|
||||
(
|
||||
addr_t reg_addr
|
||||
);
|
||||
|
||||
/***************************************************************************//**
|
||||
* HW_set_8bit_reg_field is used to set the content of a field in a 8 bits
|
||||
* wide peripheral register.
|
||||
*
|
||||
* @param reg_addr Address in the processor's memory map of the register to
|
||||
* be written.
|
||||
* @param shift Bit offset of the register field to be read within the
|
||||
* register.
|
||||
* @param mask Bit mask to be applied to the raw register value to filter
|
||||
* out the other register fields values.
|
||||
* @param value Value to be written in the specified field.
|
||||
*/
|
||||
void HW_set_8bit_reg_field
|
||||
(
|
||||
addr_t reg_addr,
|
||||
int_fast8_t shift,
|
||||
uint_fast8_t mask,
|
||||
uint_fast8_t value
|
||||
);
|
||||
|
||||
/***************************************************************************//**
|
||||
* HW_get_8bit_reg_field is used to read the content of a field from a
|
||||
* 8 bits wide peripheral register.
|
||||
*
|
||||
* @param reg_addr Address in the processor's memory map of the register to
|
||||
* read.
|
||||
* @param shift Bit offset of the register field to be written within the
|
||||
* register.
|
||||
* @param mask Bit mask to be applied to the raw register value to filter
|
||||
* out the other register fields values.
|
||||
*
|
||||
* @return 16 bits value containing the register field value specified
|
||||
* as parameter.
|
||||
*/
|
||||
uint8_t HW_get_8bit_reg_field
|
||||
(
|
||||
addr_t reg_addr,
|
||||
int_fast8_t shift,
|
||||
uint_fast8_t mask
|
||||
);
|
||||
|
||||
#endif /* HW_REG_ACCESS */
|
Loading…
Reference in a new issue