Add SmartFusion2 demo for the SmartFustion2 development kit.

This commit is contained in:
Richard Barry 2013-05-12 20:07:49 +00:00
parent 063c05ccad
commit 4d966adc8b
68 changed files with 77087 additions and 0 deletions

View File

@ -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

View File

@ -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="&quot;${workspace_loc:/RTOSDemo/Full-Demo}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/RTOSDemo/Full-Demo/FreeRTOS-Plus-CLI-Source}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/RTOSDemo/Full-Demo/FreeRTOS-Plus-FAT-SL-Source/api}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/RTOSDemo/Full-Demo/Common-Demo-Source/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/RTOSDemo/FreeRTOS-Source/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/RTOSDemo/FreeRTOS-Source/portable/GCC/ARM_CM3}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/RTOSDemo}&quot;"/>
<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="&quot;${workspace_loc:/RTOSDemo_Hardware_Platform/Debug}&quot;"/>
</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="&quot;${workspace_loc:/RTOSDemo_Hardware_Platform/Debug/CMSIS/startup_gcc/startup_m2sxxx.o}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/RTOSDemo_Hardware_Platform/Debug/CMSIS/startup_gcc/newlib_stubs.o}&quot;"/>
</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 &quot;${plugin_state_location}/${specs_file}&quot;'" 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 &quot;${plugin_state_location}/specs.cpp&quot;'" 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 &quot;${plugin_state_location}/specs.c&quot;'" 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 &quot;${plugin_state_location}/${specs_file}&quot;'" 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 &quot;${plugin_state_location}/specs.cpp&quot;'" 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 &quot;${plugin_state_location}/specs.c&quot;'" 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 &quot;${plugin_state_location}/${specs_file}&quot;'" 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 &quot;${plugin_state_location}/specs.cpp&quot;'" 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 &quot;${plugin_state_location}/specs.c&quot;'" 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>

View File

@ -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>

View File

@ -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;
}
}
}
/*-----------------------------------------------------------*/

View File

@ -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 */

View File

@ -0,0 +1 @@
Run the CreateProjectDirectoryStructure.bat batch file to populate this directory before building the demo.

View File

@ -0,0 +1 @@
Run the CreateProjectDirectoryStructure.bat batch file to populate this directory before building the demo.

View File

@ -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 );
}

View File

@ -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 );
}

View File

@ -0,0 +1 @@
Run the CreateProjectDirectoryStructure.bat batch file to populate this directory before building the demo.

View File

@ -0,0 +1 @@
Run the CreateProjectDirectoryStructure.bat batch file to populate this directory before building the demo.

View File

@ -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 */

View File

@ -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 );
}
}

View File

@ -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 */

View File

@ -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 */

View File

@ -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_ */

View File

@ -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();
}

View File

@ -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();
}
}

View File

@ -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;
}
/*-----------------------------------------------------------*/

View File

@ -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()). */
}
/*-----------------------------------------------------------*/

View File

@ -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;
}

View File

@ -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 &quot;${plugin_state_location}/${specs_file}&quot;'" 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 &quot;${plugin_state_location}/specs.cpp&quot;'" 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 &quot;${plugin_state_location}/specs.c&quot;'" 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 &quot;${plugin_state_location}/${specs_file}&quot;'" 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 &quot;${plugin_state_location}/specs.cpp&quot;'" 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 &quot;${plugin_state_location}/specs.c&quot;'" 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>

View File

@ -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>

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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) }
}

View File

@ -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) }
}

View File

@ -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) }
}

View File

@ -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 stdoutso 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;
}

View File

@ -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) }
}

View File

@ -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) }
}

View File

@ -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

View File

@ -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_ */

View File

@ -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

View File

@ -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

View File

@ -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_*/

View File

@ -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

View File

@ -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)
Users 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_ */

View File

@ -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

View File

@ -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_ */

View File

@ -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 ******************************/

View 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 */

View File

@ -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

View File

@ -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 RTCs 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 counters 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 RTCs 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 RTCs 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_ */

View File

@ -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);
}
}

View File

@ -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_ */

View File

@ -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(&params[0], key, AES128_KEY_LENGTH);
memcpy(&params[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(&params[0], key, AES256_KEY_LENGTH);
memcpy(&params[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(&params[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);
}

View File

@ -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_ */

View File

@ -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 hasnt 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 hasnt 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 hasnt 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( &current_value_u, &current_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_*/

View File

@ -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_ */

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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);
}

View File

@ -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_*/

View File

@ -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_*/

View File

@ -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 */

View File

@ -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 */