Commit 4dc6649b authored by Theodor-Adrian Stana's avatar Theodor-Adrian Stana

sw: Removed OS comparison Win projects`

parent fe2195af
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?>
<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="com.silabs.ide.si32.gcc.debug#com.silabs.ide.si32.gcc:4.7.3.20130312">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.silabs.ide.si32.gcc.debug#com.silabs.ide.si32.gcc:4.7.3.20130312" moduleId="org.eclipse.cdt.core.settings" name="GNU ARM 4.7.3 - Debug">
<macros>
<stringMacro name="StudioToolchainPath" type="VALUE_PATH_DIR" value="C:\SiliconLabs\SimplicityStudio\v2\developer\toolchains\gnu_arm\4.7_2013q1"/>
<stringMacro name="StudioSdkPath" type="VALUE_PATH_DIR" value="C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2"/>
</macros>
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule buildConfig.stockConfigId="com.silabs.ide.si32.gcc.debug#com.silabs.ide.si32.gcc:4.7.3.20130312" cppBuildConfig.builtinIncludes="unresolved:$%7BStudioSdkPath%7D/kits/EFM32GG_STK3700/config/ unresolved:$%7BStudioSdkPath%7D/Device/EnergyMicro/EFM32GG/Include/ unresolved:$%7BStudioSdkPath%7D/emlib/inc/ unresolved:$%7BStudioSdkPath%7D/reptile/FreeRTOS/Source/include/ unresolved:$%7BStudioSdkPath%7D/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3/ unresolved:$%7BStudioSdkPath%7D/kits/common/bsp/ unresolved:$%7BStudioSdkPath%7D/CMSIS/Include/ unresolved:$%7BStudioSdkPath%7D/emdrv/gpiointerrupt/inc/ unresolved:$%7BStudioSdkPath%7D/emdrv/nvm/inc/ unresolved:$%7BStudioSdkPath%7D/emdrv/sleep/inc/ unresolved:$%7BStudioSdkPath%7D/kits/EFM32GG_STK3700/config/ unresolved:$%7BStudioSdkPath%7D/Device/EnergyMicro/EFM32GG/Include/ unresolved:$%7BStudioSdkPath%7D/emlib/inc/ unresolved:$%7BStudioSdkPath%7D/reptile/FreeRTOS/Source/include/ unresolved:$%7BStudioSdkPath%7D/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3/ unresolved:$%7BStudioSdkPath%7D/kits/common/bsp/ unresolved:$%7BStudioSdkPath%7D/CMSIS/Include/ unresolved:$%7BStudioSdkPath%7D/emdrv/gpiointerrupt/inc/ unresolved:$%7BStudioSdkPath%7D/emdrv/nvm/inc/ unresolved:$%7BStudioSdkPath%7D/emdrv/sleep/inc/" cppBuildConfig.builtinLibraryFiles="" cppBuildConfig.builtinLibraryNames="" cppBuildConfig.builtinLibraryObjects="" cppBuildConfig.builtinLibraryPaths="" cppBuildConfig.builtinMacros="EFM32GG990F1024 EFM32GG990F1024" moduleId="com.silabs.ide.project.core" projectCommon.kitId="com.silabs.kit.si32.efm32.efm32gg.stk3700" projectCommon.partId="com.silabs.mcu.si32.efm32.efm32gg.efm32gg990f1024" projectCommon.referencedModules="[{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; id=\&quot;com.silabs.ide.si32.sdk.efm32.v2.part\&quot;&gt;\r\n &lt;inclusions pattern=\&quot;CMSIS/.*/startup_gcc_.*.s\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;CMSIS/.*/startup_iar_.*.s\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;CMSIS/.*/system_.*.c\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;,&quot;builtinSources&quot;:[&quot;CMSIS/efm32gg/startup_gcc_efm32gg.s&quot;,&quot;CMSIS/efm32gg/system_efm32gg.c&quot;]},{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; id=\&quot;com.silabs.ide.si32.sdk.efm32.v2.common.emlib\&quot;&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_assert.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_burtc.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_cmu.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_emu.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_gpio.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_int.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_rmu.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_rtc.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_system.c\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;,&quot;builtinSources&quot;:[&quot;emlib/em_assert.c&quot;,&quot;emlib/em_burtc.c&quot;,&quot;emlib/em_cmu.c&quot;,&quot;emlib/em_emu.c&quot;,&quot;emlib/em_gpio.c&quot;,&quot;emlib/em_int.c&quot;,&quot;emlib/em_rmu.c&quot;,&quot;emlib/em_rtc.c&quot;,&quot;emlib/em_system.c&quot;]},{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; id=\&quot;com.silabs.ide.si32.sdk.efm32.v2.kit\&quot;&gt;\r\n &lt;exclusions pattern=\&quot;.*\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;,&quot;builtinSources&quot;:[]},{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; id=\&quot;com.silabs.ide.si32.sdk.efm32.v2.external.FreeRTOS\&quot;&gt;\r\n &lt;inclusions pattern=\&quot;FreeRTOS/.*/timers.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;FreeRTOS/.*/tasks.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;FreeRTOS/.*/queue.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;FreeRTOS/.*/list.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;FreeRTOS/.*/croutine.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;FreeRTOS/.*/heap_1.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;FreeRTOS/.*/port_gcc.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;FreeRTOS/.*/port_iar.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;FreeRTOS/.*/portasm.s\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;,&quot;builtinSources&quot;:[&quot;FreeRTOS/$(partGroupName)/timers.c&quot;,&quot;FreeRTOS/$(partGroupName)/tasks.c&quot;,&quot;FreeRTOS/$(partGroupName)/queue.c&quot;,&quot;FreeRTOS/$(partGroupName)/list.c&quot;,&quot;FreeRTOS/$(partGroupName)/croutine.c&quot;,&quot;FreeRTOS/$(partGroupName)/heap_1.c&quot;,&quot;FreeRTOS/$(partGroupName)/port_gcc.c&quot;]},{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; id=\&quot;com.silabs.ide.si32.sdk.efm32.v2.common.emdrv\&quot;&gt;\r\n &lt;inclusions pattern=\&quot;Drivers/sleep.c\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;,&quot;builtinSources&quot;:[&quot;Drivers/sleep.c&quot;]},{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; id=\&quot;com.silabs.ide.si32.sdk.efm32.v2.common.CMSIS\&quot;&gt;\r\n &lt;exclusions pattern=\&quot;.*\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;,&quot;builtinSources&quot;:[]},{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; id=\&quot;com.silabs.ide.si32.sdk.efm32.v2.common.bsp\&quot;&gt;\r\n &lt;inclusions pattern=\&quot;BSP/bsp_trace.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;BSP/bsp_stk_leds.c\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;,&quot;builtinSources&quot;:[&quot;BSP/bsp_stk_leds.c&quot;,&quot;BSP/bsp_trace.c&quot;]}]" projectCommon.sdkId="com.silabs.sdk.si32.efm32.sls:2.0.0" projectCommon.toolchainId="com.silabs.ide.si32.gcc:4.7.3.20130312"/>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" description="" id="com.silabs.ide.si32.gcc.debug#com.silabs.ide.si32.gcc:4.7.3.20130312" name="GNU ARM 4.7.3 - Debug" parent="com.silabs.ide.si32.gcc.cdt.managedbuild.config.gnu.exe">
<folderInfo id="com.silabs.ide.si32.gcc.debug#com.silabs.ide.si32.gcc:4.7.3.20130312." name="/" resourcePath="">
<toolChain id="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.exe.627615561" name="Si32 GNU ARM" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.exe">
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.debug.level.1801045348" name="Debug Level" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.debug.level" value="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.debug.level.default" valueType="enumerated"/>
<targetPlatform binaryParser="org.eclipse.cdt.core.ELF;org.eclipse.cdt.core.GNU_ELF" id="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.platform.base.645058492" isAbstract="false" name="Debug Platform" osList="win32,linux,macosx" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.platform.base"/>
<builder buildPath="${workspace_loc:/EFM32GG_freertos_blink}/GNU ARM 4.7.3 - Debug" id="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.builder.base.898765689" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Si32 GNU ARM Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.builder.base"/>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base.1488235087" name="GNU ARM C Compiler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base">
<option id="gnu.c.compiler.option.optimization.level.1126261547" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" value="gnu.c.optimization.level.none" valueType="enumerated"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.builtin.235464924" name="Always branch to builtin functions (-fno-builtin)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.builtin" value="true" valueType="boolean"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.prolog.1576845455" name="Generate debugger-friendly prologs (-mno-sched-prolog)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.prolog" value="true" valueType="boolean"/>
<option id="gnu.c.compiler.option.include.paths.2105331445" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/EFM32GG_STK3700/examples/freertos_blink&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/EFM32GG_STK3700/config&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/EnergyMicro/EFM32GG/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/emlib/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/reptile/FreeRTOS/Source/include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/common/bsp&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/common/drivers&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/CMSIS/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/emdrv/gpiointerrupt/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/emdrv/nvm/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/emdrv/sleep/inc&quot;"/>
</option>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.def.symbols.408585762" name="Defined symbols (-D)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.def.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="GCC_ARMCM3=1"/>
<listOptionValue builtIn="false" value="DEBUG_EFM=1"/>
<listOptionValue builtIn="false" value="EFM32GG990F1024=1"/>
</option>
<inputType id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input.140264909" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.base.1670654518" name="GNU ARM C++ Compiler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.base">
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.builtin.2069726132" name="Always branch to builtin functions (-fno-builtin)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.builtin" value="true" valueType="boolean"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.prolog.636500873" name="Generate debugger-friendly prologs (-mno-sched-prolog)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.prolog" value="true" valueType="boolean"/>
</tool>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.assembler.base.372968914" name="GNU ARM Assembler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.assembler.base">
<option id="gnu.both.asm.option.include.paths.1275487146" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/EFM32GG_STK3700/examples/freertos_blink&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/EFM32GG_STK3700/config&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/EnergyMicro/EFM32GG/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/emlib/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/reptile/FreeRTOS/Source/include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/common/bsp&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/CMSIS/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/emdrv/gpiointerrupt/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/emdrv/nvm/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/emdrv/sleep/inc&quot;"/>
</option>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.as.def.symbols.943909059" name="Defined symbols (-D)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.as.def.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="GCC_ARMCM3=1"/>
<listOptionValue builtIn="false" value="DEBUG_EFM=1"/>
<listOptionValue builtIn="false" value="EFM32GG990F1024=1"/>
</option>
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1554223734" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.base.1137453093" name="GNU ARM C Linker" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.base">
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.nostdlibs.516735880" name="No startup or default libs (-nostdlib)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.nostdlibs" value="false" valueType="boolean"/>
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.1858762434" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.linker.base.1582889064" name="GNU ARM C++ Linker" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.linker.base"/>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.archiver.base.73287458" name="GNU ARM Archiver" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.archiver.base"/>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
<cconfiguration id="com.silabs.ide.si32.gcc.release#com.silabs.ide.si32.gcc:4.7.3.20130312">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.silabs.ide.si32.gcc.release#com.silabs.ide.si32.gcc:4.7.3.20130312" moduleId="org.eclipse.cdt.core.settings" name="GNU ARM 4.7.3 - Release">
<macros>
<stringMacro name="StudioToolchainPath" type="VALUE_PATH_DIR" value="C:\SiliconLabs\SimplicityStudio\v2\developer\toolchains\gnu_arm\4.7_2013q1"/>
<stringMacro name="StudioSdkPath" type="VALUE_PATH_DIR" value="C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2"/>
</macros>
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule buildConfig.stockConfigId="com.silabs.ide.si32.gcc.release#com.silabs.ide.si32.gcc:4.7.3.20130312" cppBuildConfig.builtinIncludes="unresolved:$%7BStudioSdkPath%7D/CMSIS/Include/ unresolved:$%7BStudioSdkPath%7D/emlib/inc/ unresolved:$%7BStudioSdkPath%7D/emdrv/gpiointerrupt/inc/ unresolved:$%7BStudioSdkPath%7D/emdrv/nvm/inc/ unresolved:$%7BStudioSdkPath%7D/emdrv/sleep/inc/ unresolved:$%7BStudioSdkPath%7D/kits/common/bsp/ unresolved:$%7BStudioSdkPath%7D/Device/EnergyMicro/EFM32GG/Include/ unresolved:$%7BStudioSdkPath%7D/reptile/FreeRTOS/Source/include/ unresolved:$%7BStudioSdkPath%7D/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3/ unresolved:$%7BStudioSdkPath%7D/kits/EFM32GG_STK3700/config/ unresolved:$%7BStudioSdkPath%7D/CMSIS/Include/ unresolved:$%7BStudioSdkPath%7D/emlib/inc/ unresolved:$%7BStudioSdkPath%7D/emdrv/gpiointerrupt/inc/ unresolved:$%7BStudioSdkPath%7D/emdrv/nvm/inc/ unresolved:$%7BStudioSdkPath%7D/emdrv/sleep/inc/ unresolved:$%7BStudioSdkPath%7D/kits/common/bsp/ unresolved:$%7BStudioSdkPath%7D/Device/EnergyMicro/EFM32GG/Include/ unresolved:$%7BStudioSdkPath%7D/reptile/FreeRTOS/Source/include/ unresolved:$%7BStudioSdkPath%7D/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3/ unresolved:$%7BStudioSdkPath%7D/kits/EFM32GG_STK3700/config/" cppBuildConfig.builtinLibraryFiles="" cppBuildConfig.builtinLibraryNames="" cppBuildConfig.builtinLibraryObjects="" cppBuildConfig.builtinLibraryPaths="" cppBuildConfig.builtinMacros="EFM32GG990F1024 EFM32GG990F1024 NDEBUG" moduleId="com.silabs.ide.project.core" projectCommon.referencedModules="[{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; id=\&quot;com.silabs.ide.si32.sdk.efm32.v2.common.CMSIS\&quot;&gt;\r\n &lt;exclusions pattern=\&quot;.*\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;,&quot;builtinSources&quot;:[]},{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; id=\&quot;com.silabs.ide.si32.sdk.efm32.v2.kit\&quot;&gt;\r\n &lt;exclusions pattern=\&quot;.*\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;,&quot;builtinSources&quot;:[]},{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; id=\&quot;com.silabs.ide.si32.sdk.efm32.v2.part\&quot;&gt;\r\n &lt;inclusions pattern=\&quot;CMSIS/.*/startup_gcc_.*.s\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;CMSIS/.*/startup_iar_.*.s\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;CMSIS/.*/system_.*.c\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;,&quot;builtinSources&quot;:[&quot;CMSIS/efm32gg/startup_gcc_efm32gg.s&quot;,&quot;CMSIS/efm32gg/system_efm32gg.c&quot;]},{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; id=\&quot;com.silabs.ide.si32.sdk.efm32.v2.common.emlib\&quot;&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_assert.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_burtc.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_cmu.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_emu.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_gpio.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_int.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_rmu.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_rtc.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_system.c\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;,&quot;builtinSources&quot;:[&quot;emlib/em_assert.c&quot;,&quot;emlib/em_burtc.c&quot;,&quot;emlib/em_cmu.c&quot;,&quot;emlib/em_emu.c&quot;,&quot;emlib/em_gpio.c&quot;,&quot;emlib/em_int.c&quot;,&quot;emlib/em_rmu.c&quot;,&quot;emlib/em_rtc.c&quot;,&quot;emlib/em_system.c&quot;]},{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; id=\&quot;com.silabs.ide.si32.sdk.efm32.v2.external.FreeRTOS\&quot;&gt;\r\n &lt;inclusions pattern=\&quot;FreeRTOS/.*/timers.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;FreeRTOS/.*/tasks.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;FreeRTOS/.*/queue.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;FreeRTOS/.*/list.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;FreeRTOS/.*/croutine.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;FreeRTOS/.*/heap_1.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;FreeRTOS/.*/port_gcc.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;FreeRTOS/.*/port_iar.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;FreeRTOS/.*/portasm.s\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;,&quot;builtinSources&quot;:[&quot;FreeRTOS/$(partGroupName)/timers.c&quot;,&quot;FreeRTOS/$(partGroupName)/tasks.c&quot;,&quot;FreeRTOS/$(partGroupName)/queue.c&quot;,&quot;FreeRTOS/$(partGroupName)/list.c&quot;,&quot;FreeRTOS/$(partGroupName)/croutine.c&quot;,&quot;FreeRTOS/$(partGroupName)/heap_1.c&quot;,&quot;FreeRTOS/$(partGroupName)/port_gcc.c&quot;]},{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; id=\&quot;com.silabs.ide.si32.sdk.efm32.v2.common.emdrv\&quot;&gt;\r\n &lt;inclusions pattern=\&quot;Drivers/sleep.c\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;,&quot;builtinSources&quot;:[&quot;Drivers/sleep.c&quot;]},{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; id=\&quot;com.silabs.ide.si32.sdk.efm32.v2.common.bsp\&quot;&gt;\r\n &lt;inclusions pattern=\&quot;BSP/bsp_trace.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;BSP/bsp_stk_leds.c\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;,&quot;builtinSources&quot;:[&quot;BSP/bsp_stk_leds.c&quot;,&quot;BSP/bsp_trace.c&quot;]}]" projectCommon.toolchainId="com.silabs.ide.si32.gcc:4.7.3.20130312"/>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" description="" id="com.silabs.ide.si32.gcc.release#com.silabs.ide.si32.gcc:4.7.3.20130312" name="GNU ARM 4.7.3 - Release" parent="com.silabs.ide.si32.gcc.cdt.managedbuild.config.gnu.exe">
<folderInfo id="com.silabs.ide.si32.gcc.release#com.silabs.ide.si32.gcc:4.7.3.20130312." name="/" resourcePath="">
<toolChain id="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.exe.975919620" name="Si32 GNU ARM" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.exe">
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.debug.level.231774989" name="Debug Level" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.debug.level" value="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.debug.level.default" valueType="enumerated"/>
<targetPlatform binaryParser="org.eclipse.cdt.core.ELF;org.eclipse.cdt.core.GNU_ELF" id="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.platform.base.556268531" isAbstract="false" name="Debug Platform" osList="win32,linux,macosx" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.platform.base"/>
<builder buildPath="${workspace_loc:/EFM32GG_freertos_blink}/GNU ARM 4.7.3 - Release" id="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.builder.base.271909463" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Si32 GNU ARM Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.builder.base"/>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base.397583724" name="GNU ARM C Compiler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base">
<option id="gnu.c.compiler.option.optimization.level.2144728588" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" value="gnu.c.optimization.level.most" valueType="enumerated"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.builtin.1042202462" name="Always branch to builtin functions (-fno-builtin)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.builtin" value="true" valueType="boolean"/>
<option id="gnu.c.compiler.option.include.paths.1013592341" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/EFM32GG_STK3700/examples/freertos_blink&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/CMSIS/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/emlib/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/emdrv/gpiointerrupt/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/emdrv/nvm/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/emdrv/sleep/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/common/bsp&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/EnergyMicro/EFM32GG/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/reptile/FreeRTOS/Source/include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/EFM32GG_STK3700/config&quot;"/>
</option>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.def.symbols.211896403" name="Defined symbols (-D)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.def.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="GCC_ARMCM3=1"/>
<listOptionValue builtIn="false" value="DEBUG_EFM=1"/>
<listOptionValue builtIn="false" value="EFM32GG990F1024=1"/>
<listOptionValue builtIn="false" value="NDEBUG=1"/>
</option>
<inputType id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input.924952390" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.base.2130907103" name="GNU ARM C++ Compiler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.base"/>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.assembler.base.1244234018" name="GNU ARM Assembler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.assembler.base">
<option id="gnu.both.asm.option.include.paths.736233783" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/EFM32GG_STK3700/examples/freertos_blink&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/CMSIS/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/emlib/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/emdrv/gpiointerrupt/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/emdrv/nvm/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/emdrv/sleep/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/common/bsp&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/EnergyMicro/EFM32GG/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/reptile/FreeRTOS/Source/include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/EFM32GG_STK3700/config&quot;"/>
</option>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.as.def.symbols.1475395922" name="Defined symbols (-D)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.as.def.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="GCC_ARMCM3=1"/>
<listOptionValue builtIn="false" value="DEBUG_EFM=1"/>
<listOptionValue builtIn="false" value="EFM32GG990F1024=1"/>
</option>
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.779428569" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.base.554261973" name="GNU ARM C Linker" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.base">
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.nostdlibs.899201671" name="No startup or default libs (-nostdlib)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.nostdlibs" value="false" valueType="boolean"/>
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.120473691" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.linker.base.664659283" name="GNU ARM C++ Linker" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.linker.base"/>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.archiver.base.2036887599" name="GNU ARM Archiver" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.archiver.base"/>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="com.silabs.ide.project.core" projectCommon.kitId="com.silabs.kit.si32.efm32.efm32gg.stk3700" projectCommon.partId="com.silabs.mcu.si32.efm32.efm32gg.efm32gg990f1024" projectCommon.sdkId="com.silabs.sdk.si32.efm32.sls:2.0.0"/>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="EFM32GG_freertos_blink.com.silabs.ide.project.core.cdt.cdtMbsProjectType.838374362" name="SLS CDT Project" projectType="com.silabs.ide.project.core.cdt.cdtMbsProjectType"/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="com.silabs.ide.si32.gcc.debug#com.silabs.ide.si32.gcc:4.7.3.20130312;com.silabs.ide.si32.gcc.debug#com.silabs.ide.si32.gcc:4.7.3.20130312.;com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base.1488235087;com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input.140264909">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="com.silabs.ide.si32.gcc.release#com.silabs.ide.si32.gcc:4.7.3.20130312;com.silabs.ide.si32.gcc.release#com.silabs.ide.si32.gcc:4.7.3.20130312.;com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base.397583724;com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input.924952390">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="refreshScope"/>
</cproject>
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>EFM32GG_freertos_blink</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>com.silabs.ide.project.core.SLSProjectNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>
/***************************************************************************//**
* @file
* @brief Board support package API for GPIO leds on STK's.
* @author Energy Micro AS
* @version 3.20.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* This file is licensed under the Silicon Labs Software License Agreement. See
* "http://developer.silabs.com/legal/version/v11/Silicon_Labs_Software_License_Agreement.txt"
* for details. Before using this software for any purpose, you must agree to the
* terms of that agreement.
*
******************************************************************************/
#include "em_device.h"
#include "em_cmu.h"
#include "em_gpio.h"
#include "bsp.h"
#if defined( BSP_GPIO_LEDS )
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
typedef struct
{
GPIO_Port_TypeDef port;
unsigned int pin;
} tLedArray;
static const tLedArray ledArray[ BSP_NO_OF_LEDS ] = BSP_GPIO_LEDARRAY_INIT;
int BSP_LedsInit(void)
{
int i;
CMU_ClockEnable(cmuClock_HFPER, true);
CMU_ClockEnable(cmuClock_GPIO, true);
for ( i=0; i<BSP_NO_OF_LEDS; i++ )
{
GPIO_PinModeSet(ledArray[i].port, ledArray[i].pin, gpioModePushPull, 0);
}
return BSP_STATUS_OK;
}
uint32_t BSP_LedsGet(void)
{
int i;
uint32_t retVal, mask;
for ( i=0, retVal=0, mask=0x1; i<BSP_NO_OF_LEDS; i++, mask <<= 1 )
{
if (GPIO_PinOutGet(ledArray[i].port, ledArray[i].pin))
retVal |= mask;
}
return retVal;
}
int BSP_LedsSet(uint32_t leds)
{
int i;
uint32_t mask;
for ( i=0, mask=0x1; i<BSP_NO_OF_LEDS; i++, mask <<= 1 )
{
if ( leds & mask )
GPIO_PinOutSet(ledArray[i].port, ledArray[i].pin);
else
GPIO_PinOutClear(ledArray[i].port, ledArray[i].pin);
}
return BSP_STATUS_OK;
}
int BSP_LedClear(int ledNo)
{
if ((ledNo >= 0) && (ledNo < BSP_NO_OF_LEDS))
{
GPIO_PinOutClear(ledArray[ledNo].port, ledArray[ledNo].pin);
return BSP_STATUS_OK;
}
return BSP_STATUS_ILLEGAL_PARAM;
}
int BSP_LedGet(int ledNo)
{
int retVal = BSP_STATUS_ILLEGAL_PARAM;
if ((ledNo >= 0) && (ledNo < BSP_NO_OF_LEDS))
{
retVal = (int)GPIO_PinOutGet(ledArray[ledNo].port, ledArray[ledNo].pin);
}
return retVal;
}
int BSP_LedSet(int ledNo)
{
if ((ledNo >= 0) && (ledNo < BSP_NO_OF_LEDS))
{
GPIO_PinOutSet(ledArray[ledNo].port, ledArray[ledNo].pin);
return BSP_STATUS_OK;
}
return BSP_STATUS_ILLEGAL_PARAM;
}
int BSP_LedToggle(int ledNo)
{
if ((ledNo >= 0) && (ledNo < BSP_NO_OF_LEDS))
{
GPIO_PinOutToggle(ledArray[ledNo].port, ledArray[ledNo].pin);
return BSP_STATUS_OK;
}
return BSP_STATUS_ILLEGAL_PARAM;
}
/** @endcond */
#endif /* BSP_GPIO_LEDS */
/**************************************************************************//**
* @file
* @brief API for enabling SWO and ETM trace.
* @author Energy Micro AS
* @version 3.20.2
******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* This file is licensed under the Silicon Labs Software License Agreement. See
* "http://developer.silabs.com/legal/version/v11/Silicon_Labs_Software_License_Agreement.txt"
* for details. Before using this software for any purpose, you must agree to the
* terms of that agreement.
*
******************************************************************************/
#include <stdbool.h>
#include "em_device.h"
#include "em_gpio.h"
#include "em_cmu.h"
#include "bsp_trace.h"
#include "bsp.h"
#if defined(BSP_ETM_TRACE) && defined( ETM_PRESENT )
/**************************************************************************//**
* @brief Configure EFM32 for ETM trace output.
* @note You need to configure ETM trace on kit config menu as well!
*****************************************************************************/
void BSP_TraceEtmSetup(void)
{
/* Enable peripheral clocks */
CMU->HFCORECLKEN0 |= CMU_HFCORECLKEN0_LE;
CMU->HFPERCLKEN0 |= CMU_HFPERCLKEN0_GPIO;
CMU->OSCENCMD = CMU_OSCENCMD_AUXHFRCOEN;
/* Wait until AUXHFRCO clock is ready */
while (!(CMU->STATUS & CMU_STATUS_AUXHFRCORDY)) ;
/* Enable Port D, pins 3,4,5,6 for ETM Trace Data output */
GPIO->P[3].MODEL = (GPIO->P[3].MODEL & ~_GPIO_P_MODEL_MODE3_MASK) | GPIO_P_MODEL_MODE3_PUSHPULL;
GPIO->P[3].MODEL = (GPIO->P[3].MODEL & ~_GPIO_P_MODEL_MODE4_MASK) | GPIO_P_MODEL_MODE4_PUSHPULL;
GPIO->P[3].MODEL = (GPIO->P[3].MODEL & ~_GPIO_P_MODEL_MODE5_MASK) | GPIO_P_MODEL_MODE5_PUSHPULL;
GPIO->P[3].MODEL = (GPIO->P[3].MODEL & ~_GPIO_P_MODEL_MODE6_MASK) | GPIO_P_MODEL_MODE6_PUSHPULL;
/* Enable Port D, pin 7 for DBG_TCLK */
GPIO->P[3].MODEL = (GPIO->P[3].MODEL & ~_GPIO_P_MODEL_MODE7_MASK) | GPIO_P_MODEL_MODE7_PUSHPULL;
/* Configure trace output for alternate location */
GPIO->ROUTE = GPIO->ROUTE | GPIO_ROUTE_TCLKPEN | GPIO_ROUTE_TD0PEN | GPIO_ROUTE_TD1PEN
| GPIO_ROUTE_TD2PEN | GPIO_ROUTE_TD3PEN
| GPIO_ROUTE_ETMLOCATION_LOC0;
}
#endif
#if defined( GPIO_ROUTE_SWOPEN )
/**************************************************************************//**
* @brief Configure trace output for energyAware Profiler
* @note Enabling trace will add 80uA current for the EFM32_Gxxx_STK.
* DK's needs to be initialized with SPI-mode:
* @verbatim BSP_Init(BSP_INIT_DK_SPI); @endverbatim
*****************************************************************************/
void BSP_TraceSwoSetup(void)
{
/* Enable GPIO clock */
CMU->HFPERCLKEN0 |= CMU_HFPERCLKEN0_GPIO;
/* Enable Serial wire output pin */
GPIO->ROUTE |= GPIO_ROUTE_SWOPEN;
/* Set correct location */
GPIO->ROUTE = (GPIO->ROUTE & ~(_GPIO_ROUTE_SWLOCATION_MASK)) | BSP_TRACE_SWO_LOCATION;
/* Enable output on correct pin. */
TRACE_ENABLE_PINS();
/* Enable debug clock AUXHFRCO */
CMU->OSCENCMD = CMU_OSCENCMD_AUXHFRCOEN;
/* Wait until clock is ready */
while (!(CMU->STATUS & CMU_STATUS_AUXHFRCORDY)) ;
/* Enable trace in core debug */
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
/* Enable PC and IRQ sampling output */
DWT->CTRL = 0x400113FF;
/* Set TPIU prescaler to 16. */
TPI->ACPR = 0xf;
/* Set protocol to NRZ */
TPI->SPPR = 2;
/* Disable continuous formatting */
TPI->FFCR = 0x100;
/* Unlock ITM and output data */
ITM->LAR = 0xC5ACCE55;
ITM->TCR = 0x10009;
}
#endif
#if defined( GPIO_ROUTE_SWOPEN )
/**************************************************************************//**
* @brief Profiler configuration.
* @return true if energyAware Profiler/SWO is enabled, false if not
* @note If first word of the user page is zero, this will not
* enable SWO profiler output.
*****************************************************************************/
bool BSP_TraceProfilerSetup(void)
{
volatile uint32_t *userData = (uint32_t *) USER_PAGE;
/* Check magic "trace" word in user page */
if (*userData == 0x00000000UL)
{
return false;
}
else
{
BSP_TraceSwoSetup();
return true;
}
}
#endif
/* @file
* @brief startup file for Energy Micro EFM32GG devices.
* For use with GCC for ARM Embedded Processors
* @version 3.20.2
* Date: 08 Feb 2012
*
* Copyright (c) 2012, ARM Limited
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the ARM Limited nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ARM LIMITED BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
.syntax unified
.arch armv7-m
.section .stack
.align 3
#ifdef __STACK_SIZE
.equ Stack_Size, __STACK_SIZE
#else
.equ Stack_Size, 0x400
#endif
.globl __StackTop
.globl __StackLimit
__StackLimit:
.space Stack_Size
.size __StackLimit, . - __StackLimit
__StackTop:
.size __StackTop, . - __StackTop
.section .heap
.align 3
#ifdef __HEAP_SIZE
.equ Heap_Size, __HEAP_SIZE
#else
.equ Heap_Size, 0xC00
#endif
.globl __HeapBase
.globl __HeapLimit
__HeapBase:
.if Heap_Size
.space Heap_Size
.endif
.size __HeapBase, . - __HeapBase
__HeapLimit:
.size __HeapLimit, . - __HeapLimit
.section .isr_vector
.align 8
.globl __isr_vector
__isr_vector:
.long __StackTop /* Top of Stack */
.long Reset_Handler /* Reset Handler */
.long NMI_Handler /* NMI Handler */
.long HardFault_Handler /* Hard Fault Handler */
.long MemManage_Handler /* MPU Fault Handler */
.long BusFault_Handler /* Bus Fault Handler */
.long UsageFault_Handler /* Usage Fault Handler */
.long Default_Handler /* Reserved */
.long Default_Handler /* Reserved */
.long Default_Handler /* Reserved */
.long Default_Handler /* Reserved */
.long SVC_Handler /* SVCall Handler */
.long DebugMon_Handler /* Debug Monitor Handler */
.long Default_Handler /* Reserved */
.long PendSV_Handler /* PendSV Handler */
.long SysTick_Handler /* SysTick Handler */
/* External interrupts */
.long DMA_IRQHandler /* 0 - DMA */
.long GPIO_EVEN_IRQHandler /* 1 - GPIO_EVEN */
.long TIMER0_IRQHandler /* 2 - TIMER0 */
.long USART0_RX_IRQHandler /* 3 - USART0_RX */
.long USART0_TX_IRQHandler /* 4 - USART0_TX */
.long USB_IRQHandler /* 5 - USB */
.long ACMP0_IRQHandler /* 6 - ACMP0 */
.long ADC0_IRQHandler /* 7 - ADC0 */
.long DAC0_IRQHandler /* 8 - DAC0 */
.long I2C0_IRQHandler /* 9 - I2C0 */
.long I2C1_IRQHandler /* 10 - I2C1 */
.long GPIO_ODD_IRQHandler /* 11 - GPIO_ODD */
.long TIMER1_IRQHandler /* 12 - TIMER1 */
.long TIMER2_IRQHandler /* 13 - TIMER2 */
.long TIMER3_IRQHandler /* 14 - TIMER3 */
.long USART1_RX_IRQHandler /* 15 - USART1_RX */
.long USART1_TX_IRQHandler /* 16 - USART1_TX */
.long LESENSE_IRQHandler /* 17 - LESENSE */
.long USART2_RX_IRQHandler /* 18 - USART2_RX */
.long USART2_TX_IRQHandler /* 19 - USART2_TX */
.long UART0_RX_IRQHandler /* 20 - UART0_RX */
.long UART0_TX_IRQHandler /* 21 - UART0_TX */
.long UART1_RX_IRQHandler /* 22 - UART1_RX */
.long UART1_TX_IRQHandler /* 23 - UART1_TX */
.long LEUART0_IRQHandler /* 24 - LEUART0 */
.long LEUART1_IRQHandler /* 25 - LEUART1 */
.long LETIMER0_IRQHandler /* 26 - LETIMER0 */
.long PCNT0_IRQHandler /* 27 - PCNT0 */
.long PCNT1_IRQHandler /* 28 - PCNT1 */
.long PCNT2_IRQHandler /* 29 - PCNT2 */
.long RTC_IRQHandler /* 30 - RTC */
.long BURTC_IRQHandler /* 31 - BURTC */
.long CMU_IRQHandler /* 32 - CMU */
.long VCMP_IRQHandler /* 33 - VCMP */
.long LCD_IRQHandler /* 34 - LCD */
.long MSC_IRQHandler /* 35 - MSC */
.long AES_IRQHandler /* 36 - AES */
.long EBI_IRQHandler /* 37 - EBI */
.long EMU_IRQHandler /* 38 - EMU */
.size __isr_vector, . - __isr_vector
.text
.thumb
.thumb_func
.align 2
.globl Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
/* Loop to copy data from read only memory to RAM. The ranges
* of copy from/to are specified by following symbols evaluated in
* linker script.
* __etext: End of code section, i.e., begin of data sections to copy from.
* __data_start__/__data_end__: RAM address range that data should be
* copied to. Both must be aligned to 4 bytes boundary. */
#ifndef __NO_SYSTEM_INIT
ldr r0, =SystemInit
blx r0
#endif
ldr r1, =__etext
ldr r2, =__data_start__
ldr r3, =__data_end__
subs r3, r2
ble .flash_to_ram_loop_end
.flash_to_ram_loop:
subs r3, #4
ldr r0, [r1, r3]
str r0, [r2, r3]
bgt .flash_to_ram_loop
.flash_to_ram_loop_end:
ldr r0, =_start
bx r0
.pool
.size Reset_Handler, . - Reset_Handler
/* Macro to define default handlers. Default handler
* will be weak symbol and just dead loops. They can be
* overwritten by other handlers */
.macro def_irq_handler handler_name
.align 1
.thumb_func
.weak \handler_name
.type \handler_name, %function
\handler_name:
b .
.size \handler_name, . - \handler_name
.endm
def_irq_handler Default_Handler
def_irq_handler NMI_Handler
def_irq_handler HardFault_Handler
def_irq_handler MemManage_Handler
def_irq_handler BusFault_Handler
def_irq_handler UsageFault_Handler
def_irq_handler SVC_Handler
def_irq_handler DebugMon_Handler
def_irq_handler PendSV_Handler
def_irq_handler SysTick_Handler
def_irq_handler DMA_IRQHandler
def_irq_handler GPIO_EVEN_IRQHandler
def_irq_handler TIMER0_IRQHandler
def_irq_handler USART0_RX_IRQHandler
def_irq_handler USART0_TX_IRQHandler
def_irq_handler USB_IRQHandler
def_irq_handler ACMP0_IRQHandler
def_irq_handler ADC0_IRQHandler
def_irq_handler DAC0_IRQHandler
def_irq_handler I2C0_IRQHandler
def_irq_handler I2C1_IRQHandler
def_irq_handler GPIO_ODD_IRQHandler
def_irq_handler TIMER1_IRQHandler
def_irq_handler TIMER2_IRQHandler
def_irq_handler TIMER3_IRQHandler
def_irq_handler USART1_RX_IRQHandler
def_irq_handler USART1_TX_IRQHandler
def_irq_handler LESENSE_IRQHandler
def_irq_handler USART2_RX_IRQHandler
def_irq_handler USART2_TX_IRQHandler
def_irq_handler UART0_RX_IRQHandler
def_irq_handler UART0_TX_IRQHandler
def_irq_handler UART1_RX_IRQHandler
def_irq_handler UART1_TX_IRQHandler
def_irq_handler LEUART0_IRQHandler
def_irq_handler LEUART1_IRQHandler
def_irq_handler LETIMER0_IRQHandler
def_irq_handler PCNT0_IRQHandler
def_irq_handler PCNT1_IRQHandler
def_irq_handler PCNT2_IRQHandler
def_irq_handler RTC_IRQHandler
def_irq_handler BURTC_IRQHandler
def_irq_handler CMU_IRQHandler
def_irq_handler VCMP_IRQHandler
def_irq_handler LCD_IRQHandler
def_irq_handler MSC_IRQHandler
def_irq_handler AES_IRQHandler
def_irq_handler EBI_IRQHandler
def_irq_handler EMU_IRQHandler
.end
/***************************************************************************//**
* @file
* @brief CMSIS Cortex-M3 System Layer for EFM32GG devices.
* @author Energy Micro AS
* @version 3.20.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include <stdint.h>
#include "em_device.h"
/*******************************************************************************
****************************** DEFINES ************************************
******************************************************************************/
/** LFRCO frequency, tuned to below frequency during manufacturing. */
#define EFM32_LFRCO_FREQ (32768UL)
#define EFM32_ULFRCO_FREQ (1000UL)
/*******************************************************************************
************************** LOCAL VARIABLES ********************************
******************************************************************************/
/* System oscillator frequencies. These frequencies are normally constant */
/* for a target, but they are made configurable in order to allow run-time */
/* handling of different boards. The crystal oscillator clocks can be set */
/* compile time to a non-default value by defining respective EFM32_nFXO_FREQ */
/* values according to board design. By defining the EFM32_nFXO_FREQ to 0, */
/* one indicates that the oscillator is not present, in order to save some */
/* SW footprint. */
#ifndef EFM32_HFXO_FREQ
#ifdef _EFM32_GIANT_FAMILY
#define EFM32_HFXO_FREQ (48000000UL)
#else
#define EFM32_HFXO_FREQ (32000000UL)
#endif
#endif
/* Do not define variable if HF crystal oscillator not present */
#if (EFM32_HFXO_FREQ > 0)
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** System HFXO clock. */
static uint32_t SystemHFXOClock = EFM32_HFXO_FREQ;
/** @endcond (DO_NOT_INCLUDE_WITH_DOXYGEN) */
#endif
#ifndef EFM32_LFXO_FREQ
#define EFM32_LFXO_FREQ (EFM32_LFRCO_FREQ)
#endif
/* Do not define variable if LF crystal oscillator not present */
#if (EFM32_LFXO_FREQ > 0)
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** System LFXO clock. */
static uint32_t SystemLFXOClock = EFM32_LFXO_FREQ;
/** @endcond (DO_NOT_INCLUDE_WITH_DOXYGEN) */
#endif
/* Inline function to get the chip's Production Revision. */
__STATIC_INLINE uint8_t GetProdRev(void)
{
return ((DEVINFO->PART & _DEVINFO_PART_PROD_REV_MASK)
>> _DEVINFO_PART_PROD_REV_SHIFT);
}
/*******************************************************************************
************************** GLOBAL VARIABLES *******************************
******************************************************************************/
/**
* @brief
* System System Clock Frequency (Core Clock).
*
* @details
* Required CMSIS global variable that must be kept up-to-date.
*/
uint32_t SystemCoreClock;
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Get the current core clock frequency.
*
* @details
* Calculate and get the current core clock frequency based on the current
* configuration. Assuming that the SystemCoreClock global variable is
* maintained, the core clock frequency is stored in that variable as well.
* This function will however calculate the core clock based on actual HW
* configuration. It will also update the SystemCoreClock global variable.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* The current core clock frequency in Hz.
******************************************************************************/
uint32_t SystemCoreClockGet(void)
{
uint32_t ret;
ret = SystemHFClockGet();
#if defined (_EFM32_GIANT_FAMILY)
/* Leopard/Giant Gecko has an additional divider */
ret = ret / (1 + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK)>>_CMU_CTRL_HFCLKDIV_SHIFT));
#endif
ret >>= (CMU->HFCORECLKDIV & _CMU_HFCORECLKDIV_HFCORECLKDIV_MASK) >>
_CMU_HFCORECLKDIV_HFCORECLKDIV_SHIFT;
/* Keep CMSIS variable up-to-date just in case */
SystemCoreClock = ret;
return ret;
}
/***************************************************************************//**
* @brief
* Get the current HFCLK frequency.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* The current HFCLK frequency in Hz.
******************************************************************************/
uint32_t SystemHFClockGet(void)
{
uint32_t ret;
switch (CMU->STATUS & (CMU_STATUS_HFRCOSEL | CMU_STATUS_HFXOSEL |
CMU_STATUS_LFRCOSEL | CMU_STATUS_LFXOSEL))
{
case CMU_STATUS_LFXOSEL:
#if (EFM32_LFXO_FREQ > 0)
ret = SystemLFXOClock;
#else
/* We should not get here, since core should not be clocked. May */
/* be caused by a misconfiguration though. */
ret = 0;
#endif
break;
case CMU_STATUS_LFRCOSEL:
ret = EFM32_LFRCO_FREQ;
break;
case CMU_STATUS_HFXOSEL:
#if (EFM32_HFXO_FREQ > 0)
ret = SystemHFXOClock;
#else
/* We should not get here, since core should not be clocked. May */
/* be caused by a misconfiguration though. */
ret = 0;
#endif
break;
default: /* CMU_STATUS_HFRCOSEL */
switch (CMU->HFRCOCTRL & _CMU_HFRCOCTRL_BAND_MASK)
{
case CMU_HFRCOCTRL_BAND_28MHZ:
ret = 28000000;
break;
case CMU_HFRCOCTRL_BAND_21MHZ:
ret = 21000000;
break;
case CMU_HFRCOCTRL_BAND_14MHZ:
ret = 14000000;
break;
case CMU_HFRCOCTRL_BAND_11MHZ:
ret = 11000000;
break;
case CMU_HFRCOCTRL_BAND_7MHZ:
if ( GetProdRev() >= 19 )
ret = 6600000;
else
ret = 7000000;
break;
case CMU_HFRCOCTRL_BAND_1MHZ:
if ( GetProdRev() >= 19 )
ret = 1200000;
else
ret = 1000000;
break;
default:
ret = 0;
break;
}
break;
}
return ret;
}
/**************************************************************************//**
* @brief
* Get high frequency crystal oscillator clock frequency for target system.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* HFXO frequency in Hz.
*****************************************************************************/
uint32_t SystemHFXOClockGet(void)
{
/* External crystal oscillator present? */
#if (EFM32_HFXO_FREQ > 0)
return SystemHFXOClock;
#else
return 0;
#endif
}
/**************************************************************************//**
* @brief
* Set high frequency crystal oscillator clock frequency for target system.
*
* @note
* This function is mainly provided for being able to handle target systems
* with different HF crystal oscillator frequencies run-time. If used, it
* should probably only be used once during system startup.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @param[in] freq
* HFXO frequency in Hz used for target.
*****************************************************************************/
void SystemHFXOClockSet(uint32_t freq)
{
/* External crystal oscillator present? */
#if (EFM32_HFXO_FREQ > 0)
SystemHFXOClock = freq;
/* Update core clock frequency if HFXO is used to clock core */
if (CMU->STATUS & CMU_STATUS_HFXOSEL)
{
/* The function will update the global variable */
SystemCoreClockGet();
}
#else
(void)freq; /* Unused parameter */
#endif
}
/**************************************************************************//**
* @brief
* Initialize the system.
*
* @details
* Do required generic HW system init.
*
* @note
* This function is invoked during system init, before the main() routine
* and any data has been initialized. For this reason, it cannot do any
* initialization of variables etc.
*****************************************************************************/
void SystemInit(void)
{
}
/**************************************************************************//**
* @brief
* Get low frequency RC oscillator clock frequency for target system.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* LFRCO frequency in Hz.
*****************************************************************************/
uint32_t SystemLFRCOClockGet(void)
{
/* Currently we assume that this frequency is properly tuned during */
/* manufacturing and is not changed after reset. If future requirements */
/* for re-tuning by user, we can add support for that. */
return EFM32_LFRCO_FREQ;
}
/**************************************************************************//**
* @brief
* Get ultra low frequency RC oscillator clock frequency for target system.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* ULFRCO frequency in Hz.
*****************************************************************************/
uint32_t SystemULFRCOClockGet(void)
{
/* The ULFRCO frequency is not tuned, and can be very inaccurate */
return EFM32_ULFRCO_FREQ;
}
/**************************************************************************//**
* @brief
* Get low frequency crystal oscillator clock frequency for target system.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* LFXO frequency in Hz.
*****************************************************************************/
uint32_t SystemLFXOClockGet(void)
{
/* External crystal oscillator present? */
#if (EFM32_LFXO_FREQ > 0)
return SystemLFXOClock;
#else
return 0;
#endif
}
/**************************************************************************//**
* @brief
* Set low frequency crystal oscillator clock frequency for target system.
*
* @note
* This function is mainly provided for being able to handle target systems
* with different HF crystal oscillator frequencies run-time. If used, it
* should probably only be used once during system startup.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @param[in] freq
* LFXO frequency in Hz used for target.
*****************************************************************************/
void SystemLFXOClockSet(uint32_t freq)
{
/* External crystal oscillator present? */
#if (EFM32_LFXO_FREQ > 0)
SystemLFXOClock = freq;
/* Update core clock frequency if LFXO is used to clock core */
if (CMU->STATUS & CMU_STATUS_LFXOSEL)
{
/* The function will update the global variable */
SystemCoreClockGet();
}
#else
(void)freq; /* Unused parameter */
#endif
}
/**************************************************************************//**
* @file
* @brief EFM32 Segment LCD Display driver
* @author Energy Micro AS
* @version 3.20.2
******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* This file is licensed under the Silicon Labs Software License Agreement. See
* "http://developer.silabs.com/legal/version/v11/Silicon_Labs_Software_License_Agreement.txt"
* for details. Before using this software for any purpose, you must agree to the
* terms of that agreement.
*
******************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include "em_device.h"
#include "em_cmu.h"
#include "em_gpio.h"
#include "segmentlcd.h"
/**************************************************************************//**
* @brief
* Defines each text symbol's segment in terms of COM and BIT numbers,
* in a way that we can enumerate each bit for each text segment in the
* following bit pattern:
* @verbatim
* -------0------
*
* | \7 |8 /9 |
* |5 \ | / |1
*
* --6--- ---10--
*
* | / | \11 |
* |4 /13 |12 \ |2
*
* -------3------
* @endverbatim
* E.g.: First text character bit pattern #3 (above) is
* Segment 1D for Display
* Location COM 3, BIT 0
*****************************************************************************/
typedef struct
{
uint8_t com[14]; /**< LCD COM line (for multiplexing) */
uint8_t bit[14]; /**< LCD bit number */
} CHAR_TypeDef;
/**************************************************************************//**
* @brief Defines segment COM and BIT fields numeric display
*****************************************************************************/
typedef struct
{
uint8_t com[7]; /**< LCD COM line (for multiplexing) */
uint8_t bit[7]; /**< LCD bit number */
} NUMBER_TypeDef;
/**************************************************************************//**
* @brief Defines segment COM and BIT fields for Energy Modes on display
*****************************************************************************/
typedef struct
{
uint8_t com[5]; /**< LCD COM line (for multiplexing) */
uint8_t bit[5]; /**< LCD bit number */
} EM_TypeDef;
/**************************************************************************//**
* @brief Defines segment COM and BIT fields for A-wheel (suited for Anim)
*****************************************************************************/
typedef struct
{
uint8_t com[8]; /**< LCD COM line (for multiplexing) */
uint8_t bit[8]; /**< LCD bit number */
} ARING_TypeDef;
/**************************************************************************//**
* @brief Defines segment COM and BIT fields for A-wheel (suited for Anim)
*****************************************************************************/
typedef struct
{
uint8_t com[4]; /**< LCD COM line (for multiplexing) */
uint8_t bit[4]; /**< LCD bit number */
} BATTERY_TypeDef;
/**************************************************************************//**
* @brief Defines prototype for all segments in display
*****************************************************************************/
typedef struct
{
CHAR_TypeDef Text[7]; /**< Text on display */
NUMBER_TypeDef Number[4]; /**< Numbers on display */
EM_TypeDef EMode; /**< Display energy mode */
ARING_TypeDef ARing; /**< Display ring */
BATTERY_TypeDef Battery; /**< Display battery */
} MCU_DISPLAY;
/**************************************************************************//**
* @brief Working instance of LCD display
*****************************************************************************/
static const MCU_DISPLAY EFM_Display = EFM_DISPLAY_DEF;
/**************************************************************************//**
* @brief
* Defines higlighted segments for the alphabet, starting from "blank" (SPACE)
* Uses bit pattern as defined for text segments above.
* E.g. a capital O, would have bits 0 1 2 3 4 5 => 0x003f defined
*****************************************************************************/
static const uint16_t EFM_Alphabet[] = {
0x0000, /* space */
0x1100, /* ! */
0x0280, /* " */
0x0000, /* # */
0x0000, /* $ */
0x0602, /* % */
0x0000, /* & */
0x0020, /* ' */
0x0039, /* ( */
0x000f, /* ) */
0x0000, /* * */
0x1540, /* + */
0x2000, /* , */
0x0440, /* - */
0x1000, /* . */
0x2200, /* / */
0x003f, /* 0 */
0x0006, /* 1 */
0x045b, /* 2 */
0x044f, /* 3 */
0x0466, /* 4 */
0x046d, /* 5 */
0x047d, /* 6 */
0x0007, /* 7 */
0x047f, /* 8 */
0x046f, /* 9 */
0x0000, /* : */
0x0000, /* ; */
0x0a00, /* < */
0x0000, /* = */
0x2080, /* > */
0x0000, /* ? */
0xffff, /* @ */
0x0477, /* A */
0x0a79, /* B */
0x0039, /* C */
0x20b0, /* D */
0x0079, /* E */
0x0071, /* F */
0x047d, /* G */
0x0476, /* H */
0x0006, /* I */
0x000e, /* J */
0x0a70, /* K */
0x0038, /* L */
0x02b6, /* M */
0x08b6, /* N */
0x003f, /* O */
0x0473, /* P */
0x083f, /* Q */
0x0c73, /* R */
0x046d, /* S */
0x1101, /* T */
0x003e, /* U */
0x2230, /* V */
0x2836, /* W */
0x2a80, /* X */
0x046e, /* Y */
0x2209, /* Z */
0x0039, /* [ */
0x0880, /* backslash */
0x000f, /* ] */
0x0001, /* ^ */
0x0008, /* _ */
0x0100, /* ` */
0x1058, /* a */
0x047c, /* b */
0x0058, /* c */
0x045e, /* d */
0x2058, /* e */
0x0471, /* f */
0x0c0c, /* g */
0x0474, /* h */
0x0004, /* i */
0x000e, /* j */
0x0c70, /* k */
0x0038, /* l */
0x1454, /* m */
0x0454, /* n */
0x045c, /* o */
0x0473, /* p */
0x0467, /* q */
0x0450, /* r */
0x0c08, /* s */
0x0078, /* t */
0x001c, /* u */
0x2010, /* v */
0x2814, /* w */
0x2a80, /* x */
0x080c, /* y */
0x2048, /* z */
0x0000,
};
/**************************************************************************//**
* @brief
* Defines higlighted segments for the numeric display
*****************************************************************************/
static const uint16_t EFM_Numbers[] = {
0x003f, /* 0 */
0x0006, /* 1 */
0x005b, /* 2 */
0x004f, /* 3 */
0x0066, /* 4 */
0x006d, /* 5 */
0x007d, /* 6 */
0x0007, /* 7 */
0x007f, /* 8 */
0x006f, /* 9 */
0x0077, /* A */
0x007c, /* b */
0x0039, /* C */
0x005e, /* d */
0x0079, /* E */
0x0071, /* F */
0x0040 /* - */
};
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/* sign is last element of the table */
static const uint16_t signIndex = sizeof(EFM_Numbers)/sizeof(uint16_t) - 1 ;
static const LCD_Init_TypeDef lcdInit = LCD_INIT_DEF;
/** @endcond */
/**************************************************************************//**
* @brief Disable all segments
*****************************************************************************/
void SegmentLCD_AllOff(void)
{
/* Turn on low segments */
LCD_ALL_SEGMENTS_OFF();
}
/**************************************************************************//**
* @brief Enable all segments
*****************************************************************************/
void SegmentLCD_AllOn(void)
{
LCD_ALL_SEGMENTS_ON();
}
/**************************************************************************//**
* @brief Turn all segments on alpha characters in display off
*****************************************************************************/
void SegmentLCD_AlphaNumberOff(void)
{
LCD_ALPHA_NUMBER_OFF();
return;
}
/**************************************************************************//**
* @brief Light up or shut off Ring of Indicators
* @param anum "Segment number" on "Ring", range 0 - 7
* @param on Zero is off, non-zero is on
*****************************************************************************/
void SegmentLCD_ARing(int anum, int on)
{
uint32_t com, bit;
com = EFM_Display.ARing.com[anum];
bit = EFM_Display.ARing.bit[anum];
if (on)
{
LCD_SegmentSet(com, bit, true);
}
else
{
LCD_SegmentSet(com, bit, false);
}
}
/**************************************************************************//**
* @brief Light up or shut off Battery Indicator
* @param batteryLevel Battery Level, 0 to 4 (0 turns all off)
*****************************************************************************/
void SegmentLCD_Battery(int batteryLevel)
{
uint32_t com, bit;
int i, on;
for (i = 0; i < 4; i++)
{
if (i < batteryLevel)
{
on = 1;
}
else
{
on = 0;
}
com = EFM_Display.Battery.com[i];
bit = EFM_Display.Battery.bit[i];
if (on)
{
LCD_SegmentSet(com, bit, true);
}
else
{
LCD_SegmentSet(com, bit, false);
}
}
}
/**************************************************************************//**
* @brief Disables LCD controller
*****************************************************************************/
void SegmentLCD_Disable(void)
{
/* Disable LCD */
LCD_Enable(false);
/* Make sure CTRL register has been updated */
LCD_SyncBusyDelay(LCD_SYNCBUSY_CTRL);
/* Turn off LCD clock */
CMU_ClockEnable(cmuClock_LCD, false);
/* Turn off voltage boost if enabled */
CMU->LCDCTRL = 0;
}
/**************************************************************************//**
* @brief Light up or shut off Energy Mode indicator
* @param em Energy Mode numer 0 to 4
* @param on Zero is off, non-zero is on
*****************************************************************************/
void SegmentLCD_EnergyMode(int em, int on)
{
uint32_t com, bit;
com = EFM_Display.EMode.com[em];
bit = EFM_Display.EMode.bit[em];
if (on)
{
LCD_SegmentSet(com, bit, true);
}
else
{
LCD_SegmentSet(com, bit, false);
}
}
/**************************************************************************//**
* @brief Segment LCD Initialization routine for EFM32 STK display
* @param useBoost Set to use voltage boost
*****************************************************************************/
void SegmentLCD_Init(bool useBoost)
{
/* Ensure LE modules are accessible */
CMU_ClockEnable(cmuClock_CORELE, true);
/* Enable LFRCO as LFACLK in CMU (will also enable oscillator if not enabled) */
CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFRCO);
/* LCD Controller Prescaler */
CMU_ClockDivSet(cmuClock_LCDpre, LCD_CMU_CLK_PRE);
/* Frame Rate */
CMU_LCDClkFDIVSet(LCD_CMU_CLK_DIV);
/* Enable clock to LCD module */
CMU_ClockEnable(cmuClock_LCD, true);
LCD_DISPLAY_ENABLE();
/* Disable interrupts */
LCD_IntDisable(0xFFFFFFFF);
/* Initialize and enable LCD controller */
LCD_Init(&lcdInit);
/* Enable all display segments */
LCD_SEGMENTS_ENABLE();
/* Enable boost if necessary */
if (useBoost)
{
LCD_VBoostSet(LCD_BOOST_LEVEL);
LCD_VLCDSelect(lcdVLCDSelVExtBoost);
CMU->LCDCTRL |= CMU_LCDCTRL_VBOOSTEN;
}
/* Turn all segments off */
SegmentLCD_AllOff();
LCD_SyncBusyDelay(0xFFFFFFFF);
}
/**************************************************************************//**
* @brief Write a hexadecimal number on lower alphanumeric part of
* Segment LCD display
* @param num Hexadecimal number value to put on display, in range 0
* to 0x0FFFFFFF
*****************************************************************************/
void SegmentLCD_LowerHex( uint32_t num )
{
int i;
char str[7];
uint32_t nibble;
SegmentLCD_Symbol(LCD_SYMBOL_MINUS, 0);
for ( i=6; i>=0; i-- )
{
nibble = num & 0xF;
if ( nibble < 10 )
str[i] = nibble + '0';
else if ( nibble == 11 )
str[i] = 'b';
else if ( nibble == 13 )
str[i] = 'd';
else
str[i] = (nibble - 10) + 'A';
num >>= 4;
}
SegmentLCD_Write(str);
}
/**************************************************************************//**
* @brief Write number on lower alphanumeric part of Segment LCD display
* @param num Numeric value to put on display, in range -9999999 to +9999999
*****************************************************************************/
void SegmentLCD_LowerNumber( int num )
{
int i;
char str[7];
SegmentLCD_Symbol(LCD_SYMBOL_MINUS, 0);
if ( ( num > 9999999 ) || ( num < -9999999 ) )
{
SegmentLCD_Write("Ovrflow");
return;
}
if ( num < 0 )
{
SegmentLCD_Symbol(LCD_SYMBOL_MINUS, 1);
num = -num;
}
for ( i=6; i>=0; i-- )
{
if ( ( i < 6 ) && ( num == 0 ) )
{
str[i] = ' ';
}
else
{
str[i] = (num % 10) + '0';
num /= 10;
}
}
SegmentLCD_Write(str);
}
/**************************************************************************//**
* @brief Write number on numeric part on Segment LCD display
* @param value Numeric value to put on display, in range -999 to +9999
*****************************************************************************/
void SegmentLCD_Number(int value)
{
int i, com, bit, digit, div, neg;
uint16_t bitpattern;
uint16_t num;
/* Parameter consistancy check */
if (value >= 9999)
{
value = 9999;
}
if (value <= -1000)
{
value = -999;
}
if (value < 0)
{
value = abs(value);
neg = 1;
}
else
{
neg = 0;
}
/* If an update is in progress we must block, or there might be tearing */
LCD_SyncBusyDelay(0xFFFFFFFF);
/* Freeze updates to avoid partial refresh of display */
LCD_FreezeEnable(true);
/* Turn off all number LCD segments */
SegmentLCD_NumberOff();
/* Extract useful digits */
div = 1;
for (digit = 0; digit < 4; digit++)
{
num = (value / div) % 10;
if ((neg == 1) && (digit == 3)) num = signIndex;
/* Get number layout of display */
bitpattern = EFM_Numbers[num];
for (i = 0; i < 7; i++)
{
bit = EFM_Display.Number[digit].bit[i];
com = EFM_Display.Number[digit].com[i];
if (bitpattern & (1 << i))
{
LCD_SegmentSet(com, bit, true);
}
}
div = div * 10;
}
/* Sync LCD registers to LE domain */
LCD_FreezeEnable(false);
}
/**************************************************************************//**
* @brief Turn all segments on numeric digits in display off
*****************************************************************************/
void SegmentLCD_NumberOff(void)
{
/* Turn off all number segments */
LCD_NUMBER_OFF();
return;
}
/**************************************************************************//**
* @brief Light up or shut off various symbols on Segment LCD
* @param s Which symbol to turn on or off
* @param on Zero is off, non-zero is on
*****************************************************************************/
void SegmentLCD_Symbol(lcdSymbol s, int on)
{
int com = 0;
int bit = 0;
switch (s)
{
case LCD_SYMBOL_GECKO:
com = LCD_SYMBOL_GECKO_COM;
bit = LCD_SYMBOL_GECKO_SEG;
break;
case LCD_SYMBOL_ANT:
com = LCD_SYMBOL_ANT_COM;
bit = LCD_SYMBOL_ANT_SEG;
break;
case LCD_SYMBOL_PAD0:
com = LCD_SYMBOL_PAD0_COM;
bit = LCD_SYMBOL_PAD0_SEG;
break;
case LCD_SYMBOL_PAD1:
com = LCD_SYMBOL_PAD1_COM;
bit = LCD_SYMBOL_PAD1_SEG;
break;
case LCD_SYMBOL_EFM32:
com = LCD_SYMBOL_EFM32_COM;
bit = LCD_SYMBOL_EFM32_SEG;
break;
case LCD_SYMBOL_MINUS:
com = LCD_SYMBOL_MINUS_COM;
bit = LCD_SYMBOL_MINUS_SEG;
break;
case LCD_SYMBOL_COL3:
com = LCD_SYMBOL_COL3_COM;
bit = LCD_SYMBOL_COL3_SEG;
break;
case LCD_SYMBOL_COL5:
com = LCD_SYMBOL_COL5_COM;
bit = LCD_SYMBOL_COL5_SEG;
break;
case LCD_SYMBOL_COL10:
com = LCD_SYMBOL_COL10_COM;
bit = LCD_SYMBOL_COL10_SEG;
break;
#ifdef LCD_SYMBOL_DEGC_SEG
case LCD_SYMBOL_DEGC:
com = LCD_SYMBOL_DEGC_COM;
bit = LCD_SYMBOL_DEGC_SEG;
break;
#endif
#ifdef LCD_SYMBOL_DEGF_SEG
case LCD_SYMBOL_DEGF:
com = LCD_SYMBOL_DEGF_COM;
bit = LCD_SYMBOL_DEGF_SEG;
break;
#endif
#ifdef LCD_SYMBOL_DP2_SEG
case LCD_SYMBOL_DP2:
com = LCD_SYMBOL_DP2_COM;
bit = LCD_SYMBOL_DP2_SEG;
break;
#endif
#ifdef LCD_SYMBOL_DP3_SEG
case LCD_SYMBOL_DP3:
com = LCD_SYMBOL_DP3_COM;
bit = LCD_SYMBOL_DP3_SEG;
break;
#endif
#ifdef LCD_SYMBOL_DP4_SEG
case LCD_SYMBOL_DP4:
com = LCD_SYMBOL_DP4_COM;
bit = LCD_SYMBOL_DP4_SEG;
break;
#endif
#ifdef LCD_SYMBOL_DP5_SEG
case LCD_SYMBOL_DP5:
com = LCD_SYMBOL_DP5_COM;
bit = LCD_SYMBOL_DP5_SEG;
break;
#endif
case LCD_SYMBOL_DP6:
com = LCD_SYMBOL_DP6_COM;
bit = LCD_SYMBOL_DP6_SEG;
break;
case LCD_SYMBOL_DP10:
com = LCD_SYMBOL_DP10_COM;
bit = LCD_SYMBOL_DP10_SEG;
break;
#ifdef LCD_SYMBOL_AM_SEG
case LCD_SYMBOL_AM:
com = LCD_SYMBOL_AM_COM;
bit = LCD_SYMBOL_AM_SEG;
break;
#endif
#ifdef LCD_SYMBOL_PM_SEG
case LCD_SYMBOL_PM:
com = LCD_SYMBOL_PM_COM;
bit = LCD_SYMBOL_PM_SEG;
break;
#endif
#ifdef LCD_SYMBOL_MICROAMP_SEG
case LCD_SYMBOL_MICROAMP:
com = LCD_SYMBOL_MICROAMP_COM;
bit = LCD_SYMBOL_MICROAMP_SEG;
break;
#endif
#ifdef LCD_SYMBOL_MILLIAMP_SEG
case LCD_SYMBOL_MILLIAMP:
com = LCD_SYMBOL_MILLIAMP_COM;
bit = LCD_SYMBOL_MILLIAMP_SEG;
break;
#endif
}
if (on)
{
LCD_SegmentSet(com, bit, true);
}
else
{
LCD_SegmentSet(com, bit, false);
}
}
/**************************************************************************//**
* @brief Write hexadecimal number on numeric part on Segment LCD display
* @param value Numeric value to put on display, in range 0x0000-0xFFFF
*****************************************************************************/
void SegmentLCD_UnsignedHex(uint16_t value)
{
int num, i, com, bit, digit;
uint16_t bitpattern;
/* Parameter consistancy check */
if (value >= 0xffff)
{
value = 0xffff;
}
/* If an update is in progress we must block, or there might be tearing */
LCD_SyncBusyDelay(0xFFFFFFFF);
/* Freeze updates to avoid partial refresh of display */
LCD_FreezeEnable(true);
/* Turn off all number LCD segments */
SegmentLCD_NumberOff();
for (digit = 0; digit < 4; digit++)
{
num = (value >> (4 * digit)) & 0x0f;
bitpattern = EFM_Numbers[num];
for (i = 0; i < 7; i++)
{
bit = EFM_Display.Number[digit].bit[i];
com = EFM_Display.Number[digit].com[i];
if (bitpattern & (1 << i))
{
LCD_SegmentSet(com, bit, true);
}
}
}
/* Sync LCD registers to LE domain */
LCD_FreezeEnable(false);
}
/**************************************************************************//**
* @brief Write text on LCD display
* @param string Text string to show on display
*****************************************************************************/
void SegmentLCD_Write(char *string)
{
int data, length, index;
uint16_t bitfield;
uint32_t com, bit;
int i;
length = strlen(string);
index = 0;
/* If an update is in progress we must block, or there might be tearing */
LCD_SyncBusyDelay(0xFFFFFFFF);
/* Freeze LCD to avoid partial updates */
LCD_FreezeEnable(true);
/* Turn all segments off */
SegmentLCD_AlphaNumberOff();
/* Fill out all characters on display */
for (index = 0; index < 7; index++)
{
if (index < length)
{
data = (int) *string;
}
else /* Padding with space */
{
data = 0x20; /* SPACE */
}
/* Defined letters currently starts at "SPACE" - ASCII 0x20; */
data = data - 0x20;
/* Get font for this letter */
bitfield = EFM_Alphabet[data];
for (i = 0; i < 14; i++)
{
bit = EFM_Display.Text[index].bit[i];
com = EFM_Display.Text[index].com[i];
if (bitfield & (1 << i))
{
/* Turn on segment */
LCD_SegmentSet(com, bit, true);
}
}
string++;
}
/* Enable update */
LCD_FreezeEnable(false);
}
/***************************************************************************//**
* @file
* @brief Energy Modes management driver.
* @author Energy Micro AS
* @version 3.20.2
* @details
* This is a energy modes management module consisting of sleep.c and sleep.h
* source files. The main purpose of the module is to ease energy
* optimization with a simple API. The module allows the system to always sleep
* in the lowest possible energy mode. Users could set up callbacks that are
* being called before and after each and every sleep. A counting semaphore is
* available for each low energy mode (EM1/EM2/EM3) to protect certain system
* states from being corrupted. This semaphore has limit set to maximum 255 locks.
*
* The module provides the following public API to the users:
* SLEEP_Init()
* SLEEP_Sleep()
* SLEEP_SleepBlockBegin()
* SLEEP_SleepBlockEnd()
* SLEEP_ForceSleepInEM4()
*
*******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* This file is licensed under the Silicon Labs Software License Agreement. See
* "http://developer.silabs.com/legal/version/v11/Silicon_Labs_Software_License_Agreement.txt"
* for details. Before using this software for any purpose, you must agree to the
* terms of that agreement.
*
******************************************************************************/
/* Chip specific header file(s). */
#include "em_device.h"
#include "em_assert.h"
#include "em_int.h"
#include "em_rmu.h"
#include "em_emu.h"
/* Module header file(s). */
#include "sleep.h"
/* stdlib is needed for NULL definition */
#include <stdlib.h>
/***************************************************************************//**
* @addtogroup EM_Drivers
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup SLEEP
* @brief Energy Modes management driver.
* @details
* This is a energy modes management module consisting of sleep.c and sleep.h
* source files. The main purpose of the module is to ease energy
* optimization with a simple API. The module allows the system to always sleep
* in the lowest possible energy mode. Users could set up callbacks that are
* being called before and after each and every sleep. A counting semaphore is
* available for each low energy mode (EM1/EM2/EM3) to protect certain system
* states from being corrupted. This semaphore has limit set to maximum 255 locks.
* @{
******************************************************************************/
/*******************************************************************************
******************************* MACROS ************************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/* Number of low energy modes (EM1, EM2, EM3). Note: EM4 sleep/wakeup is handled
* differently therefore it is not part of the list! */
#define SLEEP_NUMOF_LOW_ENERGY_MODES 3U
/*******************************************************************************
****************************** TYPEDEFS ***********************************
******************************************************************************/
/*******************************************************************************
****************************** CONSTANTS **********************************
******************************************************************************/
/*******************************************************************************
******************************* STATICS ***********************************
******************************************************************************/
/* Callback functions to call before and after sleep. */
static SLEEP_CbFuncPtr_t sleepCallback = NULL;
static SLEEP_CbFuncPtr_t wakeUpCallback = NULL;
/* Sleep block counter array representing the nested sleep blocks for the low
* energy modes (EM1/EM2/EM3). Array index 0 corresponds to EM1, 1 to EM2 and 2
* to EM3 accordingly.
*
* Note:
* - EM4 sleep/wakeup is handled differently therefore it is not part of the
* list!
* - Max. number of sleep block nesting is 255. */
static uint8_t sleepBlockCnt[SLEEP_NUMOF_LOW_ENERGY_MODES];
/*******************************************************************************
****************************** PROTOTYPES *********************************
******************************************************************************/
static void SLEEP_EnterEMx(SLEEP_EnergyMode_t eMode);
static SLEEP_EnergyMode_t SLEEP_LowestEnergyModeGet(void);
/** @endcond */
/*******************************************************************************
*************************** GLOBAL FUNCTIONS ******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Initialize the Sleep module.
*
* @details
* Use this function to initialize the Sleep module, should be called
* only once! Pointers to sleep and wake-up callback functions shall be
* provided when calling this function.
* If SLEEP_EM4_WAKEUP_CALLBACK_ENABLED is set to true, this function checks
* for the cause of the reset that implicitly called it and calls the wakeup
* callback if the reset was a wakeup from EM4 (does not work on Gecko MCU).
*
* @param[in] pSleepCb
* Pointer to the callback function that is being called before the device is
* going to sleep.
*
* @param[in] pWakeUpCb
* Pointer to the callback function that is being called after wake up.
******************************************************************************/
void SLEEP_Init(SLEEP_CbFuncPtr_t pSleepCb, SLEEP_CbFuncPtr_t pWakeUpCb)
{
/* Initialize callback functions. */
sleepCallback = pSleepCb;
wakeUpCallback = pWakeUpCb;
/* Reset sleep block counters. Note: not using for() saves code! */
sleepBlockCnt[0U] = 0U;
sleepBlockCnt[1U] = 0U;
sleepBlockCnt[2U] = 0U;
#if (SLEEP_EM4_WAKEUP_CALLBACK_ENABLED == true) && defined(RMU_RSTCAUSE_EM4WURST)
/* Check if the Init() happened after an EM4 reset. */
if (RMU_ResetCauseGet() & RMU_RSTCAUSE_EM4WURST)
{
/* Clear the cause of the reset. */
RMU_ResetCauseClear();
/* Call wakeup callback with EM4 parameter. */
if (NULL != wakeUpCallback)
{
wakeUpCallback(sleepEM4);
}
}
#endif
}
/***************************************************************************//**
* @brief
* Sets the system to sleep into the lowest possible energy mode.
*
* @details
* This function takes care of the system states protected by the sleep block
* provided by SLEEP_SleepBlockBegin() / SLEEP_SleepBlockEnd(). It allows
* the system to go into the lowest possible energy mode that the device can
* be set into at the time of the call of this function.
* This function will not go lower than EM3 because leaving EM4 requires
* resetting MCU. To enter into EM4 call SLEEP_ForceSleepInEM4().
*
* @return
* Energy Mode that was entered. Possible values:
* @li sleepEM0
* @li sleepEM1
* @li sleepEM2
* @li sleepEM3
******************************************************************************/
SLEEP_EnergyMode_t SLEEP_Sleep(void)
{
SLEEP_EnergyMode_t allowedEM;
INT_Disable();
allowedEM = SLEEP_LowestEnergyModeGet();
if ((allowedEM >= sleepEM1) && (allowedEM <= sleepEM3))
{
SLEEP_EnterEMx(allowedEM);
}
else
{
allowedEM = sleepEM0;
}
INT_Enable();
return(allowedEM);
}
/***************************************************************************//**
* @brief
* Force the device to go to EM4 without doing any checks.
*
* @details
* This function unblocks the low energy sleep block then goes to EM4.
*
* @note
* Regular RAM is not retained in EM4 and the wake up causes a reset.
* If the configuration option SLEEP_EM4_WAKEUP_CALLBACK_ENABLED is set to
* true, the SLEEP_Init() function checks for the reset cause and calls the
* EM4 wakeup callback.
******************************************************************************/
void SLEEP_ForceSleepInEM4(void)
{
#if (SLEEP_HW_LOW_ENERGY_BLOCK_ENABLED == true)
/* Unblock the EM2/EM3/EM4 block in the EMU. */
EMU_EM2UnBlock();
#endif
/* Request entering to EM4. */
SLEEP_EnterEMx(sleepEM4);
}
/***************************************************************************//**
* @brief
* Begin sleep block in the requested energy mode.
*
* @details
* Blocking a critical system state from a certain energy mode makes sure that
* the system is not set to that energy mode while the block is not being
* released.
* Every SLEEP_SleepBlockBegin() increases the corresponding counter and
* every SLEEP_SleepBlockEnd() decreases it.
*
* Example:\code
* SLEEP_SleepBlockBegin(sleepEM2); // do not allow EM2 or higher
* // do some stuff that requires EM1 at least, like ADC sampling
* SLEEP_SleepBlockEnd(sleepEM2); // remove restriction for EM2\endcode
*
* @note
* Be aware that there is limit of maximum blocks nesting to 255.
*
* @param[in] eMode
* Energy mode to begin to block. Possible values:
* @li sleepEM1 - Begin to block the system from being set to EM1 (and EM2..4).
* @li sleepEM2 - Begin to block the system from being set to EM2 (and EM3/EM4).
* @li sleepEM3 - Begin to block the system from being set to EM3 (and EM4).
******************************************************************************/
void SLEEP_SleepBlockBegin(SLEEP_EnergyMode_t eMode)
{
EFM_ASSERT((eMode >= sleepEM1) && (eMode < sleepEM4));
EFM_ASSERT((sleepBlockCnt[(uint8_t) eMode - 1U]) < 255U);
/* Increase the sleep block counter of the selected energy mode. */
sleepBlockCnt[(uint8_t) eMode - 1U]++;
#if (SLEEP_HW_LOW_ENERGY_BLOCK_ENABLED == true)
/* Block EM2/EM3 sleep if the EM2 block begins. */
if (eMode == sleepEM2)
{
EMU_EM2Block();
}
#endif
}
/***************************************************************************//**
* @brief
* End sleep block in the requested energy mode.
*
* @details
* Release restriction for entering certain energy mode. Every call of this
* function reduce blocking counter by 1. Once the counter for specific energy
* mode is 0 and all counters for lower energy modes are 0 as well, using
* particular energy mode is allowed.
* Every SLEEP_SleepBlockBegin() increases the corresponding counter and
* every SLEEP_SleepBlockEnd() decreases it.
*
* Example:\code
* // at start all energy modes are allowed
* SLEEP_SleepBlockBegin(sleepEM2); // EM2, EM3, EM4 are blocked
* SLEEP_SleepBlockBegin(sleepEM1); // EM1, EM2, EM3, EM4 are blocked
* SLEEP_SleepBlockBegin(sleepEM1); // EM1, EM2, EM3, EM4 are blocked
* SLEEP_SleepBlockEnd(sleepEM2); // still EM1, EM2, EM3, EM4 are blocked
* SLEEP_SleepBlockEnd(sleepEM1); // still EM1, EM2, EM3, EM4 are blocked
* SLEEP_SleepBlockEnd(sleepEM1); // all energy modes are allowed now\endcode
*
* @param[in] eMode
* Energy mode to end to block. Possible values:
* @li sleepEM1 - End to block the system from being set to EM1 (and EM2..4).
* @li sleepEM2 - End to block the system from being set to EM2 (and EM3/EM4).
* @li sleepEM3 - End to block the system from being set to EM3 (and EM4).
******************************************************************************/
void SLEEP_SleepBlockEnd(SLEEP_EnergyMode_t eMode)
{
EFM_ASSERT((eMode >= sleepEM1) && (eMode < sleepEM4));
/* Decrease the sleep block counter of the selected energy mode. */
if (sleepBlockCnt[(uint8_t) eMode - 1U] > 0U)
{
sleepBlockCnt[(uint8_t) eMode - 1U]--;
}
#if (SLEEP_HW_LOW_ENERGY_BLOCK_ENABLED == true)
/* Check if the EM2/EM3 block should be unblocked in the EMU. */
if (0U == sleepBlockCnt[(uint8_t) sleepEM2 - 1U])
{
EMU_EM2UnBlock();
}
#endif
}
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/***************************************************************************//**
* @brief
* Gets the lowest energy mode that the system is allowed to be set to.
*
* @details
* This function uses the low energy mode block counters to determine the
* lowest possible that the system is allowed to be set to.
*
* @return
* Lowest energy mode that the system can be set to. Possible values:
* @li sleepEM0
* @li sleepEM1
* @li sleepEM2
* @li sleepEM3
******************************************************************************/
static SLEEP_EnergyMode_t SLEEP_LowestEnergyModeGet(void)
{
SLEEP_EnergyMode_t tmpLowestEM = sleepEM0;
/* Check which is the lowest energy mode that the system can be set to. */
if (0U == sleepBlockCnt[(uint8_t) sleepEM1 - 1U])
{
tmpLowestEM = sleepEM1;
if (0U == sleepBlockCnt[(uint8_t) sleepEM2 - 1U])
{
tmpLowestEM = sleepEM2;
if (0U == sleepBlockCnt[(uint8_t) sleepEM3 - 1U])
{
tmpLowestEM = sleepEM3;
}
}
}
/* Compare with the default lowest energy mode setting. */
if (SLEEP_LOWEST_ENERGY_MODE_DEFAULT < tmpLowestEM)
{
tmpLowestEM = SLEEP_LOWEST_ENERGY_MODE_DEFAULT;
}
return tmpLowestEM;
}
/***************************************************************************//**
* @brief
* Call the callbacks and enter the requested energy mode.
*
* @details
* This function is not part of the API, therefore it shall not be called by
* the user directly as it doesn not have any checks if the system is ready
* for sleep!
*
* @note
* The EM4 wakeup callback is not being called from this function because
* waking up from EM4 causes a reset.
* If SLEEP_EM4_WAKEUP_CALLBACK_ENABLED is set to true, SLEEP_Init() function
* checks for the cause of the reset and calls the wakeup callback if the
* reset was a wakeup from EM4.
******************************************************************************/
static void SLEEP_EnterEMx(SLEEP_EnergyMode_t eMode)
{
EFM_ASSERT((eMode > sleepEM0) && (eMode <= sleepEM4));
/* Call sleepCallback() before going to sleep. */
if (NULL != sleepCallback)
{
/* Call the callback before going to sleep. */
sleepCallback(eMode);
}
/* Enter the requested energy mode. */
switch (eMode)
{
case sleepEM1:
{
EMU_EnterEM1();
} break;
case sleepEM2:
{
EMU_EnterEM2(true);
} break;
case sleepEM3:
{
EMU_EnterEM3(true);
} break;
case sleepEM4:
{
EMU_EnterEM4();
} break;
default:
{
/* Don't do anything, stay in EM0. */
} break;
}
/* Call the callback after waking up from sleep. */
if (NULL != wakeUpCallback)
{
wakeUpCallback(eMode);
}
}
/** @endcond */
/** @} (end addtogroup SLEEP */
/** @} (end addtogroup EM_Drivers) */
/*
FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
***************************************************************************
* *
* FreeRTOS provides completely free yet professionally developed, *
* robust, strictly quality controlled, supported, and cross *
* platform software that has become a de facto standard. *
* *
* Help yourself get started quickly and support the FreeRTOS *
* project by purchasing a FreeRTOS tutorial book, reference *
* manual, or both from: http://www.FreeRTOS.org/Documentation *
* *
* Thank you! *
* *
***************************************************************************
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. Full license text is available from the following
link: http://www.freertos.org/a00114.html
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, a DOS
compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
licenses offer ticketed support, indemnification and middleware.
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.
1 tab == 4 spaces!
*/
#include "FreeRTOS.h"
#include "task.h"
#include "croutine.h"
/*
* Some kernel aware debuggers require data to be viewed to be global, rather
* than file scope.
*/
#ifdef portREMOVE_STATIC_QUALIFIER
#define static
#endif
/* Lists for ready and blocked co-routines. --------------------*/
static xList pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */
static xList xDelayedCoRoutineList1; /*< Delayed co-routines. */
static xList xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */
static xList * pxDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used. */
static xList * pxOverflowDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */
static xList xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */
/* Other file private variables. --------------------------------*/
corCRCB * pxCurrentCoRoutine = NULL;
static unsigned portBASE_TYPE uxTopCoRoutineReadyPriority = 0;
static portTickType xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0;
/* The initial state of the co-routine when it is created. */
#define corINITIAL_STATE ( 0 )
/*
* Place the co-routine represented by pxCRCB into the appropriate ready queue
* for the priority. It is inserted at the end of the list.
*
* This macro accesses the co-routine ready lists and therefore must not be
* used from within an ISR.
*/
#define prvAddCoRoutineToReadyQueue( pxCRCB ) \
{ \
if( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority ) \
{ \
uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \
} \
vListInsertEnd( ( xList * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \
}
/*
* Utility to ready all the lists used by the scheduler. This is called
* automatically upon the creation of the first co-routine.
*/
static void prvInitialiseCoRoutineLists( void );
/*
* Co-routines that are readied by an interrupt cannot be placed directly into
* the ready lists (there is no mutual exclusion). Instead they are placed in
* in the pending ready list in order that they can later be moved to the ready
* list by the co-routine scheduler.
*/
static void prvCheckPendingReadyList( void );
/*
* Macro that looks at the list of co-routines that are currently delayed to
* see if any require waking.
*
* Co-routines are stored in the queue in the order of their wake time -
* meaning once one co-routine has been found whose timer has not expired
* we need not look any further down the list.
*/
static void prvCheckDelayedList( void );
/*-----------------------------------------------------------*/
signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex )
{
signed portBASE_TYPE xReturn;
corCRCB *pxCoRoutine;
/* Allocate the memory that will store the co-routine control block. */
pxCoRoutine = ( corCRCB * ) pvPortMalloc( sizeof( corCRCB ) );
if( pxCoRoutine )
{
/* If pxCurrentCoRoutine is NULL then this is the first co-routine to
be created and the co-routine data structures need initialising. */
if( pxCurrentCoRoutine == NULL )
{
pxCurrentCoRoutine = pxCoRoutine;
prvInitialiseCoRoutineLists();
}
/* Check the priority is within limits. */
if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES )
{
uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1;
}
/* Fill out the co-routine control block from the function parameters. */
pxCoRoutine->uxState = corINITIAL_STATE;
pxCoRoutine->uxPriority = uxPriority;
pxCoRoutine->uxIndex = uxIndex;
pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode;
/* Initialise all the other co-routine control block parameters. */
vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) );
vListInitialiseItem( &( pxCoRoutine->xEventListItem ) );
/* Set the co-routine control block as a link back from the xListItem.
This is so we can get back to the containing CRCB from a generic item
in a list. */
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine );
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine );
/* Event lists are always in priority order. */
listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) uxPriority );
/* Now the co-routine has been initialised it can be added to the ready
list at the correct priority. */
prvAddCoRoutineToReadyQueue( pxCoRoutine );
xReturn = pdPASS;
}
else
{
xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
}
return xReturn;
}
/*-----------------------------------------------------------*/
void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList )
{
portTickType xTimeToWake;
/* Calculate the time to wake - this may overflow but this is
not a problem. */
xTimeToWake = xCoRoutineTickCount + xTicksToDelay;
/* We must remove ourselves from the ready list before adding
ourselves to the blocked list as the same list item is used for
both lists. */
( void ) uxListRemove( ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) );
/* The list item will be inserted in wake time order. */
listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake );
if( xTimeToWake < xCoRoutineTickCount )
{
/* Wake time has overflowed. Place this item in the
overflow list. */
vListInsert( ( xList * ) pxOverflowDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) );
}
else
{
/* The wake time has not overflowed, so we can use the
current block list. */
vListInsert( ( xList * ) pxDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) );
}
if( pxEventList )
{
/* Also add the co-routine to an event list. If this is done then the
function must be called with interrupts disabled. */
vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) );
}
}
/*-----------------------------------------------------------*/
static void prvCheckPendingReadyList( void )
{
/* Are there any co-routines waiting to get moved to the ready list? These
are co-routines that have been readied by an ISR. The ISR cannot access
the ready lists itself. */
while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE )
{
corCRCB *pxUnblockedCRCB;
/* The pending ready list can be accessed by an ISR. */
portDISABLE_INTERRUPTS();
{
pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) );
( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
}
portENABLE_INTERRUPTS();
( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) );
prvAddCoRoutineToReadyQueue( pxUnblockedCRCB );
}
}
/*-----------------------------------------------------------*/
static void prvCheckDelayedList( void )
{
corCRCB *pxCRCB;
xPassedTicks = xTaskGetTickCount() - xLastTickCount;
while( xPassedTicks )
{
xCoRoutineTickCount++;
xPassedTicks--;
/* If the tick count has overflowed we need to swap the ready lists. */
if( xCoRoutineTickCount == 0 )
{
xList * pxTemp;
/* Tick count has overflowed so we need to swap the delay lists. If there are
any items in pxDelayedCoRoutineList here then there is an error! */
pxTemp = pxDelayedCoRoutineList;
pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList;
pxOverflowDelayedCoRoutineList = pxTemp;
}
/* See if this tick has made a timeout expire. */
while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE )
{
pxCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList );
if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) )
{
/* Timeout not yet expired. */
break;
}
portDISABLE_INTERRUPTS();
{
/* The event could have occurred just before this critical
section. If this is the case then the generic list item will
have been moved to the pending ready list and the following
line is still valid. Also the pvContainer parameter will have
been set to NULL so the following lines are also valid. */
uxListRemove( &( pxCRCB->xGenericListItem ) );
/* Is the co-routine waiting on an event also? */
if( pxCRCB->xEventListItem.pvContainer )
{
( void ) uxListRemove( &( pxCRCB->xEventListItem ) );
}
}
portENABLE_INTERRUPTS();
prvAddCoRoutineToReadyQueue( pxCRCB );
}
}
xLastTickCount = xCoRoutineTickCount;
}
/*-----------------------------------------------------------*/
void vCoRoutineSchedule( void )
{
/* See if any co-routines readied by events need moving to the ready lists. */
prvCheckPendingReadyList();
/* See if any delayed co-routines have timed out. */
prvCheckDelayedList();
/* Find the highest priority queue that contains ready co-routines. */
while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) )
{
if( uxTopCoRoutineReadyPriority == 0 )
{
/* No more co-routines to check. */
return;
}
--uxTopCoRoutineReadyPriority;
}
/* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines
of the same priority get an equal share of the processor time. */
listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) );
/* Call the co-routine. */
( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex );
return;
}
/*-----------------------------------------------------------*/
static void prvInitialiseCoRoutineLists( void )
{
unsigned portBASE_TYPE uxPriority;
for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ )
{
vListInitialise( ( xList * ) &( pxReadyCoRoutineLists[ uxPriority ] ) );
}
vListInitialise( ( xList * ) &xDelayedCoRoutineList1 );
vListInitialise( ( xList * ) &xDelayedCoRoutineList2 );
vListInitialise( ( xList * ) &xPendingReadyCoRoutineList );
/* Start with pxDelayedCoRoutineList using list1 and the
pxOverflowDelayedCoRoutineList using list2. */
pxDelayedCoRoutineList = &xDelayedCoRoutineList1;
pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2;
}
/*-----------------------------------------------------------*/
signed portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList )
{
corCRCB *pxUnblockedCRCB;
signed portBASE_TYPE xReturn;
/* This function is called from within an interrupt. It can only access
event lists and the pending ready list. This function assumes that a
check has already been made to ensure pxEventList is not empty. */
pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
vListInsertEnd( ( xList * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) );
if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority )
{
xReturn = pdTRUE;
}
else
{
xReturn = pdFALSE;
}
return xReturn;
}
/*
FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
***************************************************************************
* *
* FreeRTOS provides completely free yet professionally developed, *
* robust, strictly quality controlled, supported, and cross *
* platform software that has become a de facto standard. *
* *
* Help yourself get started quickly and support the FreeRTOS *
* project by purchasing a FreeRTOS tutorial book, reference *
* manual, or both from: http://www.FreeRTOS.org/Documentation *
* *
* Thank you! *
* *
***************************************************************************
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. Full license text is available from the following
link: http://www.freertos.org/a00114.html
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, a DOS
compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
licenses offer ticketed support, indemnification and middleware.
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.
1 tab == 4 spaces!
*/
/*
* The simplest possible implementation of pvPortMalloc(). Note that this
* implementation does NOT allow allocated memory to be freed again.
*
* See heap_2.c, heap_3.c and heap_4.c for alternative implementations, and the
* memory management pages of http://www.FreeRTOS.org for more information.
*/
#include <stdlib.h>
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
all the API functions to use the MPU wrappers. That should only be done when
task.h is included from an application file. */
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#include "FreeRTOS.h"
#include "task.h"
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
/* A few bytes might be lost to byte aligning the heap start address. */
#define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT )
/* Allocate the memory for the heap. */
static unsigned char ucHeap[ configTOTAL_HEAP_SIZE ];
static size_t xNextFreeByte = ( size_t ) 0;
/*-----------------------------------------------------------*/
void *pvPortMalloc( size_t xWantedSize )
{
void *pvReturn = NULL;
static unsigned char *pucAlignedHeap = NULL;
/* Ensure that blocks are always aligned to the required number of bytes. */
#if portBYTE_ALIGNMENT != 1
if( xWantedSize & portBYTE_ALIGNMENT_MASK )
{
/* Byte alignment required. */
xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
}
#endif
vTaskSuspendAll();
{
if( pucAlignedHeap == NULL )
{
/* Ensure the heap starts on a correctly aligned boundary. */
pucAlignedHeap = ( unsigned char * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ( portPOINTER_SIZE_TYPE ) ~portBYTE_ALIGNMENT_MASK ) );
}
/* Check there is enough room left for the allocation. */
if( ( ( xNextFreeByte + xWantedSize ) < configADJUSTED_HEAP_SIZE ) &&
( ( xNextFreeByte + xWantedSize ) > xNextFreeByte ) )/* Check for overflow. */
{
/* Return the next free byte then increment the index past this
block. */
pvReturn = pucAlignedHeap + xNextFreeByte;
xNextFreeByte += xWantedSize;
}
}
xTaskResumeAll();
#if( configUSE_MALLOC_FAILED_HOOK == 1 )
{
if( pvReturn == NULL )
{
extern void vApplicationMallocFailedHook( void );
vApplicationMallocFailedHook();
}
}
#endif
return pvReturn;
}
/*-----------------------------------------------------------*/
void vPortFree( void *pv )
{
/* Memory cannot be freed using this scheme. See heap_2.c, heap_3.c and
heap_4.c for alternative implementations, and the memory management pages of
http://www.FreeRTOS.org for more information. */
( void ) pv;
/* Force an assert as it is invalid to call this function. */
configASSERT( pv == NULL );
}
/*-----------------------------------------------------------*/
void vPortInitialiseBlocks( void )
{
/* Only required when static memory is not cleared. */
xNextFreeByte = ( size_t ) 0;
}
/*-----------------------------------------------------------*/
size_t xPortGetFreeHeapSize( void )
{
return ( configADJUSTED_HEAP_SIZE - xNextFreeByte );
}
/*
FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
***************************************************************************
* *
* FreeRTOS provides completely free yet professionally developed, *
* robust, strictly quality controlled, supported, and cross *
* platform software that has become a de facto standard. *
* *
* Help yourself get started quickly and support the FreeRTOS *
* project by purchasing a FreeRTOS tutorial book, reference *
* manual, or both from: http://www.FreeRTOS.org/Documentation *
* *
* Thank you! *
* *
***************************************************************************
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. Full license text is available from the following
link: http://www.freertos.org/a00114.html
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, a DOS
compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
licenses offer ticketed support, indemnification and middleware.
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.
1 tab == 4 spaces!
*/
#include <stdlib.h>
#include "FreeRTOS.h"
#include "list.h"
/*-----------------------------------------------------------
* PUBLIC LIST API documented in list.h
*----------------------------------------------------------*/
void vListInitialise( xList * const pxList )
{
/* The list structure contains a list item which is used to mark the
end of the list. To initialise the list the list end is inserted
as the only list entry. */
pxList->pxIndex = ( xListItem * ) &( pxList->xListEnd ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
/* The list end value is the highest possible value in the list to
ensure it remains at the end of the list. */
pxList->xListEnd.xItemValue = portMAX_DELAY;
/* The list end next and previous pointers point to itself so we know
when the list is empty. */
pxList->xListEnd.pxNext = ( xListItem * ) &( pxList->xListEnd ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
pxList->xListEnd.pxPrevious = ( xListItem * ) &( pxList->xListEnd );/*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
pxList->uxNumberOfItems = ( unsigned portBASE_TYPE ) 0U;
}
/*-----------------------------------------------------------*/
void vListInitialiseItem( xListItem * const pxItem )
{
/* Make sure the list item is not recorded as being on a list. */
pxItem->pvContainer = NULL;
}
/*-----------------------------------------------------------*/
void vListInsertEnd( xList * const pxList, xListItem * const pxNewListItem )
{
xListItem * pxIndex;
/* Insert a new list item into pxList, but rather than sort the list,
makes the new list item the last item to be removed by a call to
pvListGetOwnerOfNextEntry. */
pxIndex = pxList->pxIndex;
pxNewListItem->pxNext = pxIndex;
pxNewListItem->pxPrevious = pxIndex->pxPrevious;
pxIndex->pxPrevious->pxNext = pxNewListItem;
pxIndex->pxPrevious = pxNewListItem;
/* Remember which list the item is in. */
pxNewListItem->pvContainer = ( void * ) pxList;
( pxList->uxNumberOfItems )++;
}
/*-----------------------------------------------------------*/
void vListInsert( xList * const pxList, xListItem * const pxNewListItem )
{
xListItem *pxIterator;
portTickType xValueOfInsertion;
/* Insert the new list item into the list, sorted in ulListItem order. */
xValueOfInsertion = pxNewListItem->xItemValue;
/* If the list already contains a list item with the same item value then
the new list item should be placed after it. This ensures that TCB's which
are stored in ready lists (all of which have the same ulListItem value)
get an equal share of the CPU. However, if the xItemValue is the same as
the back marker the iteration loop below will not end. This means we need
to guard against this by checking the value first and modifying the
algorithm slightly if necessary. */
if( xValueOfInsertion == portMAX_DELAY )
{
pxIterator = pxList->xListEnd.pxPrevious;
}
else
{
/* *** NOTE ***********************************************************
If you find your application is crashing here then likely causes are:
1) Stack overflow -
see http://www.freertos.org/Stacks-and-stack-overflow-checking.html
2) Incorrect interrupt priority assignment, especially on Cortex-M3
parts where numerically high priority values denote low actual
interrupt priories, which can seem counter intuitive. See
configMAX_SYSCALL_INTERRUPT_PRIORITY on http://www.freertos.org/a00110.html
3) Calling an API function from within a critical section or when
the scheduler is suspended, or calling an API function that does
not end in "FromISR" from an interrupt.
4) Using a queue or semaphore before it has been initialised or
before the scheduler has been started (are interrupts firing
before vTaskStartScheduler() has been called?).
See http://www.freertos.org/FAQHelp.html for more tips.
**********************************************************************/
for( pxIterator = ( xListItem * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
{
/* There is nothing to do here, we are just iterating to the
wanted insertion position. */
}
}
pxNewListItem->pxNext = pxIterator->pxNext;
pxNewListItem->pxNext->pxPrevious = pxNewListItem;
pxNewListItem->pxPrevious = pxIterator;
pxIterator->pxNext = pxNewListItem;
/* Remember which list the item is in. This allows fast removal of the
item later. */
pxNewListItem->pvContainer = ( void * ) pxList;
( pxList->uxNumberOfItems )++;
}
/*-----------------------------------------------------------*/
unsigned portBASE_TYPE uxListRemove( xListItem * const pxItemToRemove )
{
xList * pxList;
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
/* The list item knows which list it is in. Obtain the list from the list
item. */
pxList = ( xList * ) pxItemToRemove->pvContainer;
/* Make sure the index is left pointing to a valid item. */
if( pxList->pxIndex == pxItemToRemove )
{
pxList->pxIndex = pxItemToRemove->pxPrevious;
}
pxItemToRemove->pvContainer = NULL;
( pxList->uxNumberOfItems )--;
return pxList->uxNumberOfItems;
}
/*-----------------------------------------------------------*/
/*
FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
***************************************************************************
* *
* FreeRTOS provides completely free yet professionally developed, *
* robust, strictly quality controlled, supported, and cross *
* platform software that has become a de facto standard. *
* *
* Help yourself get started quickly and support the FreeRTOS *
* project by purchasing a FreeRTOS tutorial book, reference *
* manual, or both from: http://www.FreeRTOS.org/Documentation *
* *
* Thank you! *
* *
***************************************************************************
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. Full license text is available from the following
link: http://www.freertos.org/a00114.html
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, a DOS
compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
licenses offer ticketed support, indemnification and middleware.
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.
1 tab == 4 spaces!
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the ARM CM3 port.
*----------------------------------------------------------*/
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
/* For backward compatibility, ensure configKERNEL_INTERRUPT_PRIORITY is
defined. The value should also ensure backward compatibility.
FreeRTOS.org versions prior to V4.4.0 did not include this definition. */
#ifndef configKERNEL_INTERRUPT_PRIORITY
#define configKERNEL_INTERRUPT_PRIORITY 255
#endif
#ifndef configSYSTICK_CLOCK_HZ
#define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ
#endif
/* Constants required to manipulate the core. Registers first... */
#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile unsigned long * ) 0xe000e010 ) )
#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile unsigned long * ) 0xe000e014 ) )
#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile unsigned long * ) 0xe000e018 ) )
#define portNVIC_SYSPRI2_REG ( * ( ( volatile unsigned long * ) 0xe000ed20 ) )
/* ...then bits in the registers. */
#define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL )
#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL )
#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL )
#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL )
#define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL )
#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL )
#define portNVIC_PENDSV_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL )
#define portNVIC_SYSTICK_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL )
/* Constants required to check the validity of an interrupt priority. */
#define portFIRST_USER_INTERRUPT_NUMBER ( 16 )
#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 )
#define portAIRCR_REG ( * ( ( volatile unsigned long * ) 0xE000ED0C ) )
#define portMAX_8_BIT_VALUE ( ( unsigned char ) 0xff )
#define portTOP_BIT_OF_BYTE ( ( unsigned char ) 0x80 )
#define portMAX_PRIGROUP_BITS ( ( unsigned char ) 7 )
#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL )
#define portPRIGROUP_SHIFT ( 8UL )
/* Constants required to set up the initial stack. */
#define portINITIAL_XPSR ( 0x01000000UL )
/* The systick is a 24-bit counter. */
#define portMAX_24_BIT_NUMBER ( 0xffffffUL )
/* A fiddle factor to estimate the number of SysTick counts that would have
occurred while the SysTick counter is stopped during tickless idle
calculations. */
#define portMISSED_COUNTS_FACTOR ( 45UL )
/* Each task maintains its own interrupt status in the critical nesting
variable. */
static unsigned portBASE_TYPE uxCriticalNesting = 0xaaaaaaaa;
/*
* Setup the timer to generate the tick interrupts. The implementation in this
* file is weak to allow application writers to change the timer used to
* generate the tick interrupt.
*/
void vPortSetupTimerInterrupt( void );
/*
* Exception handlers.
*/
void xPortPendSVHandler( void ) __attribute__ (( naked ));
void xPortSysTickHandler( void );
void vPortSVCHandler( void ) __attribute__ (( naked ));
/*
* Start first task is a separate function so it can be tested in isolation.
*/
static void prvPortStartFirstTask( void ) __attribute__ (( naked ));
/*-----------------------------------------------------------*/
/*
* The number of SysTick increments that make up one tick period.
*/
#if configUSE_TICKLESS_IDLE == 1
static unsigned long ulTimerCountsForOneTick = 0;
#endif /* configUSE_TICKLESS_IDLE */
/*
* The maximum number of tick periods that can be suppressed is limited by the
* 24 bit resolution of the SysTick timer.
*/
#if configUSE_TICKLESS_IDLE == 1
static unsigned long xMaximumPossibleSuppressedTicks = 0;
#endif /* configUSE_TICKLESS_IDLE */
/*
* Compensate for the CPU cycles that pass while the SysTick is stopped (low
* power functionality only.
*/
#if configUSE_TICKLESS_IDLE == 1
static unsigned long ulStoppedTimerCompensation = 0;
#endif /* configUSE_TICKLESS_IDLE */
/*
* Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure
* FreeRTOS API functions are not called from interrupts that have been assigned
* a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY.
*/
#if ( configASSERT_DEFINED == 1 )
static unsigned char ucMaxSysCallPriority = 0;
static unsigned long ulMaxPRIGROUPValue = 0;
static const volatile unsigned char * const pcInterruptPriorityRegisters = ( const volatile unsigned char * const ) portNVIC_IP_REGISTERS_OFFSET_16;
#endif /* configASSERT_DEFINED */
/*-----------------------------------------------------------*/
/*
* See header file for description.
*/
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
/* Simulate the stack frame as it would be created by a context switch
interrupt. */
pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* PC */
pxTopOfStack--;
*pxTopOfStack = 0; /* LR */
pxTopOfStack -= 5; /* R12, R3, R2 and R1. */
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
void vPortSVCHandler( void )
{
__asm volatile (
" ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */
" ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
" ldmia r0!, {r4-r11} \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */
" msr psp, r0 \n" /* Restore the task stack pointer. */
" mov r0, #0 \n"
" msr basepri, r0 \n"
" orr r14, #0xd \n"
" bx r14 \n"
" \n"
" .align 2 \n"
"pxCurrentTCBConst2: .word pxCurrentTCB \n"
);
}
/*-----------------------------------------------------------*/
static void prvPortStartFirstTask( void )
{
__asm volatile(
" ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */
" ldr r0, [r0] \n"
" ldr r0, [r0] \n"
" msr msp, r0 \n" /* Set the msp back to the start of the stack. */
" cpsie i \n" /* Globally enable interrupts. */
" svc 0 \n" /* System call to start first task. */
" nop \n"
);
}
/*-----------------------------------------------------------*/
/*
* See header file for description.
*/
portBASE_TYPE xPortStartScheduler( void )
{
/* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0.
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY );
#if( configASSERT_DEFINED == 1 )
{
volatile unsigned long ulOriginalPriority;
volatile char * const pcFirstUserPriorityRegister = ( volatile char * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
volatile unsigned char ucMaxPriorityValue;
/* Determine the maximum priority from which ISR safe FreeRTOS API
functions can be called. ISR safe functions are those that end in
"FromISR". FreeRTOS maintains separate thread and ISR API functions to
ensure interrupt entry is as fast and simple as possible.
Save the interrupt priority value that is about to be clobbered. */
ulOriginalPriority = *pcFirstUserPriorityRegister;
/* Determine the number of priority bits available. First write to all
possible bits. */
*pcFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
/* Read the value back to see how many bits stuck. */
ucMaxPriorityValue = *pcFirstUserPriorityRegister;
/* Use the same mask on the maximum system call priority. */
ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
/* Calculate the maximum acceptable priority group value for the number
of bits read back. */
ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
{
ulMaxPRIGROUPValue--;
ucMaxPriorityValue <<= ( unsigned char ) 0x01;
}
/* Shift the priority group value back to its position within the AIRCR
register. */
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
/* Restore the clobbered interrupt priority register to its original
value. */
*pcFirstUserPriorityRegister = ulOriginalPriority;
}
#endif /* conifgASSERT_DEFINED */
/* Make PendSV and SysTick the lowest priority interrupts. */
portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
/* Start the timer that generates the tick ISR. Interrupts are disabled
here already. */
vPortSetupTimerInterrupt();
/* Initialise the critical nesting count ready for the first task. */
uxCriticalNesting = 0;
/* Start the first task. */
prvPortStartFirstTask();
/* Should not get here! */
return 0;
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* It is unlikely that the CM3 port will require this function as there
is nothing to return to. */
}
/*-----------------------------------------------------------*/
void vPortYield( void )
{
/* Set a PendSV to request a context switch. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
/* Barriers are normally not required but do ensure the code is completely
within the specified behaviour for the architecture. */
__asm volatile( "dsb" );
__asm volatile( "isb" );
}
/*-----------------------------------------------------------*/
void vPortEnterCritical( void )
{
portDISABLE_INTERRUPTS();
uxCriticalNesting++;
__asm volatile( "dsb" );
__asm volatile( "isb" );
}
/*-----------------------------------------------------------*/
void vPortExitCritical( void )
{
uxCriticalNesting--;
if( uxCriticalNesting == 0 )
{
portENABLE_INTERRUPTS();
}
}
/*-----------------------------------------------------------*/
__attribute__(( naked )) unsigned long ulPortSetInterruptMask( void )
{
__asm volatile \
( \
" mrs r0, basepri \n" \
" mov r1, %0 \n" \
" msr basepri, r1 \n" \
" bx lr \n" \
:: "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "r0", "r1" \
);
/* This return will not be reached but is necessary to prevent compiler
warnings. */
return 0;
}
/*-----------------------------------------------------------*/
__attribute__(( naked )) void vPortClearInterruptMask( unsigned long ulNewMaskValue )
{
__asm volatile \
( \
" msr basepri, r0 \n" \
" bx lr \n" \
:::"r0" \
);
/* Just to avoid compiler warnings. */
( void ) ulNewMaskValue;
}
/*-----------------------------------------------------------*/
void xPortPendSVHandler( void )
{
/* This is a naked function. */
__asm volatile
(
" mrs r0, psp \n"
" \n"
" ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */
" ldr r2, [r3] \n"
" \n"
" stmdb r0!, {r4-r11} \n" /* Save the remaining registers. */
" str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */
" \n"
" stmdb sp!, {r3, r14} \n"
" mov r0, %0 \n"
" msr basepri, r0 \n"
" bl vTaskSwitchContext \n"
" mov r0, #0 \n"
" msr basepri, r0 \n"
" ldmia sp!, {r3, r14} \n"
" \n" /* Restore the context, including the critical nesting count. */
" ldr r1, [r3] \n"
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
" ldmia r0!, {r4-r11} \n" /* Pop the registers. */
" msr psp, r0 \n"
" bx r14 \n"
" \n"
" .align 2 \n"
"pxCurrentTCBConst: .word pxCurrentTCB \n"
::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY)
);
}
/*-----------------------------------------------------------*/
void xPortSysTickHandler( void )
{
/* The SysTick runs at the lowest interrupt priority, so when this interrupt
executes all interrupts must be unmasked. There is therefore no need to
save and then restore the interrupt mask value as its value is already
known. */
( void ) portSET_INTERRUPT_MASK_FROM_ISR();
{
/* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE )
{
/* A context switch is required. Context switching is performed in
the PendSV interrupt. Pend the PendSV interrupt. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
}
}
portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );
}
/*-----------------------------------------------------------*/
#if configUSE_TICKLESS_IDLE == 1
__attribute__((weak)) void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime )
{
unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;
portTickType xModifiableIdleTime;
/* Make sure the SysTick reload value does not overflow the counter. */
if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks )
{
xExpectedIdleTime = xMaximumPossibleSuppressedTicks;
}
/* Stop the SysTick momentarily. The time the SysTick is stopped for
is accounted for as best it can be, but using the tickless mode will
inevitably result in some tiny drift of the time maintained by the
kernel with respect to calendar time. */
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT;
/* Calculate the reload value required to wait xExpectedIdleTime
tick periods. -1 is used because this code will execute part way
through one of the tick periods. */
ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
if( ulReloadValue > ulStoppedTimerCompensation )
{
ulReloadValue -= ulStoppedTimerCompensation;
}
/* Enter a critical section but don't use the taskENTER_CRITICAL()
method as that will mask interrupts that should exit sleep mode. */
__asm volatile( "cpsid i" );
/* If a context switch is pending or a task is waiting for the scheduler
to be unsuspended then abandon the low power entry. */
if( eTaskConfirmSleepModeStatus() == eAbortSleep )
{
/* Restart SysTick. */
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
/* Re-enable interrupts - see comments above the cpsid instruction()
above. */
__asm volatile( "cpsie i" );
}
else
{
/* Set the new reload value. */
portNVIC_SYSTICK_LOAD_REG = ulReloadValue;
/* Clear the SysTick count flag and set the count value back to
zero. */
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
/* Restart SysTick. */
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
set its parameter to 0 to indicate that its implementation contains
its own wait for interrupt or wait for event instruction, and so wfi
should not be executed again. However, the original expected idle
time variable must remain unmodified, so a copy is taken. */
xModifiableIdleTime = xExpectedIdleTime;
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
if( xModifiableIdleTime > 0 )
{
__asm volatile( "dsb" );
__asm volatile( "wfi" );
__asm volatile( "isb" );
}
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
/* Stop SysTick. Again, the time the SysTick is stopped for is
accounted for as best it can be, but using the tickless mode will
inevitably result in some tiny drift of the time maintained by the
kernel with respect to calendar time. */
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT;
/* Re-enable interrupts - see comments above the cpsid instruction()
above. */
__asm volatile( "cpsie i" );
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
{
/* The tick interrupt has already executed, and the SysTick
count reloaded with ulReloadValue. Reset the
portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick
period. */
portNVIC_SYSTICK_LOAD_REG = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
/* The tick interrupt handler will already have pended the tick
processing in the kernel. As the pending tick will be
processed as soon as this function exits, the tick value
maintained by the tick is stepped forward by one less than the
time spent waiting. */
ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
}
else
{
/* Something other than the tick interrupt ended the sleep.
Work out how long the sleep lasted rounded to complete tick
periods (not the ulReload value which accounted for part
ticks). */
ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG;
/* How many complete tick periods passed while the processor
was waiting? */
ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;
/* The reload value is set to whatever fraction of a single tick
period remains. */
portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1 ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
}
/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG
again, then set portNVIC_SYSTICK_LOAD_REG back to its standard
value. The critical section is used to ensure the tick interrupt
can only execute once in the case that the reload register is near
zero. */
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
portENTER_CRITICAL();
{
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
vTaskStepTick( ulCompleteTickPeriods );
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
}
portEXIT_CRITICAL();
}
}
#endif /* #if configUSE_TICKLESS_IDLE */
/*-----------------------------------------------------------*/
/*
* Setup the systick timer to generate the tick interrupts at the required
* frequency.
*/
__attribute__(( weak )) void vPortSetupTimerInterrupt( void )
{
/* Calculate the constants required to configure the tick interrupt. */
#if configUSE_TICKLESS_IDLE == 1
{
ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ );
}
#endif /* configUSE_TICKLESS_IDLE */
/* Configure SysTick to interrupt at the requested rate. */
portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;;
portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT;
}
/*-----------------------------------------------------------*/
#if( configASSERT_DEFINED == 1 )
void vPortValidateInterruptPriority( void )
{
unsigned long ulCurrentInterrupt;
unsigned char ucCurrentPriority;
/* Obtain the number of the currently executing interrupt. */
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) );
/* Is the interrupt number a user defined interrupt? */
if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
{
/* Look up the interrupt's priority. */
ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];
/* The following assertion will fail if a service routine (ISR) for
an interrupt that has been assigned a priority above
configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
function. ISR safe FreeRTOS API functions must *only* be called
from interrupts that have been assigned a priority at or below
configMAX_SYSCALL_INTERRUPT_PRIORITY.
Numerically low interrupt priority numbers represent logically high
interrupt priorities, therefore the priority of the interrupt must
be set to a value equal to or numerically *higher* than
configMAX_SYSCALL_INTERRUPT_PRIORITY.
Interrupts that use the FreeRTOS API must not be left at their
default priority of zero as that is the highest possible priority,
which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
and therefore also guaranteed to be invalid.
FreeRTOS maintains separate thread and ISR API functions to ensure
interrupt entry is as fast and simple as possible.
The following links provide detailed information:
http://www.freertos.org/RTOS-Cortex-M3-M4.html
http://www.freertos.org/FAQHelp.html */
configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
}
/* Priority grouping: The interrupt controller (NVIC) allows the bits
that define each interrupt's priority to be split between bits that
define the interrupt's pre-emption priority bits and bits that define
the interrupt's sub-priority. For simplicity all bits must be defined
to be pre-emption priority bits. The following assertion will fail if
this is not the case (if some bits represent a sub-priority).
If the application only uses CMSIS libraries for interrupt
configuration then the correct setting can be achieved on all Cortex-M
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
scheduler. Note however that some vendor specific peripheral libraries
assume a non-zero priority group setting, in which cases using a value
of zero will result in unpredicable behaviour. */
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
}
#endif /* configASSERT_DEFINED */
/*
FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
***************************************************************************
* *
* FreeRTOS provides completely free yet professionally developed, *
* robust, strictly quality controlled, supported, and cross *
* platform software that has become a de facto standard. *
* *
* Help yourself get started quickly and support the FreeRTOS *
* project by purchasing a FreeRTOS tutorial book, reference *
* manual, or both from: http://www.FreeRTOS.org/Documentation *
* *
* Thank you! *
* *
***************************************************************************
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. Full license text is available from the following
link: http://www.freertos.org/a00114.html
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, a DOS
compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
licenses offer ticketed support, indemnification and middleware.
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.
1 tab == 4 spaces!
*/
#include <stdlib.h>
#include <string.h>
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
all the API functions to use the MPU wrappers. That should only be done when
task.h is included from an application file. */
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#if ( configUSE_CO_ROUTINES == 1 )
#include "croutine.h"
#endif
/* Lint e961 and e750 are suppressed as a MISRA exception justified because the
MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the
header files above, but not in this file, in order to generate the correct
privileged Vs unprivileged linkage and placement. */
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */
/* Constants used with the cRxLock and xTxLock structure members. */
#define queueUNLOCKED ( ( signed portBASE_TYPE ) -1 )
#define queueLOCKED_UNMODIFIED ( ( signed portBASE_TYPE ) 0 )
/* When the xQUEUE structure is used to represent a base queue its pcHead and
pcTail members are used as pointers into the queue storage area. When the
xQUEUE structure is used to represent a mutex pcHead and pcTail pointers are
not necessary, and the pcHead pointer is set to NULL to indicate that the
pcTail pointer actually points to the mutex holder (if any). Map alternative
names to the pcHead and pcTail structure members to ensure the readability of
the code is maintained despite this dual use of two structure members. An
alternative implementation would be to use a union, but use of a union is
against the coding standard (although an exception to the standard has been
permitted where the dual use also significantly changes the type of the
structure member). */
#define pxMutexHolder pcTail
#define uxQueueType pcHead
#define queueQUEUE_IS_MUTEX NULL
/* Semaphores do not actually store or copy data, so have an item size of
zero. */
#define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( ( unsigned portBASE_TYPE ) 0 )
#define queueMUTEX_GIVE_BLOCK_TIME ( ( portTickType ) 0U )
/*
* Definition of the queue used by the scheduler.
* Items are queued by copy, not reference.
*/
typedef struct QueueDefinition
{
signed char *pcHead; /*< Points to the beginning of the queue storage area. */
signed char *pcTail; /*< Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. */
signed char *pcWriteTo; /*< Points to the free next place in the storage area. */
union /* Use of a union is an exception to the coding standard to ensure two mutually exclusive structure members don't appear simultaneously (wasting RAM). */
{
signed char *pcReadFrom; /*< Points to the last place that a queued item was read from when the structure is used as a queue. */
unsigned portBASE_TYPE uxRecursiveCallCount;/*< Maintains a count of the numebr of times a recursive mutex has been recursively 'taken' when the structure is used as a mutex. */
} u;
xList xTasksWaitingToSend; /*< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */
xList xTasksWaitingToReceive; /*< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */
volatile unsigned portBASE_TYPE uxMessagesWaiting;/*< The number of items currently in the queue. */
unsigned portBASE_TYPE uxLength; /*< The length of the queue defined as the number of items it will hold, not the number of bytes. */
unsigned portBASE_TYPE uxItemSize; /*< The size of each items that the queue will hold. */
volatile signed portBASE_TYPE xRxLock; /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */
volatile signed portBASE_TYPE xTxLock; /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */
#if ( configUSE_TRACE_FACILITY == 1 )
unsigned char ucQueueNumber;
unsigned char ucQueueType;
#endif
#if ( configUSE_QUEUE_SETS == 1 )
struct QueueDefinition *pxQueueSetContainer;
#endif
} xQUEUE;
/*-----------------------------------------------------------*/
/*
* The queue registry is just a means for kernel aware debuggers to locate
* queue structures. It has no other purpose so is an optional component.
*/
#if ( configQUEUE_REGISTRY_SIZE > 0 )
/* The type stored within the queue registry array. This allows a name
to be assigned to each queue making kernel aware debugging a little
more user friendly. */
typedef struct QUEUE_REGISTRY_ITEM
{
signed char *pcQueueName;
xQueueHandle xHandle;
} xQueueRegistryItem;
/* The queue registry is simply an array of xQueueRegistryItem structures.
The pcQueueName member of a structure being NULL is indicative of the
array position being vacant. */
xQueueRegistryItem xQueueRegistry[ configQUEUE_REGISTRY_SIZE ];
#endif /* configQUEUE_REGISTRY_SIZE */
/*
* Unlocks a queue locked by a call to prvLockQueue. Locking a queue does not
* prevent an ISR from adding or removing items to the queue, but does prevent
* an ISR from removing tasks from the queue event lists. If an ISR finds a
* queue is locked it will instead increment the appropriate queue lock count
* to indicate that a task may require unblocking. When the queue in unlocked
* these lock counts are inspected, and the appropriate action taken.
*/
static void prvUnlockQueue( xQUEUE *pxQueue ) PRIVILEGED_FUNCTION;
/*
* Uses a critical section to determine if there is any data in a queue.
*
* @return pdTRUE if the queue contains no items, otherwise pdFALSE.
*/
static signed portBASE_TYPE prvIsQueueEmpty( const xQUEUE *pxQueue ) PRIVILEGED_FUNCTION;
/*
* Uses a critical section to determine if there is any space in a queue.
*
* @return pdTRUE if there is no space, otherwise pdFALSE;
*/
static signed portBASE_TYPE prvIsQueueFull( const xQUEUE *pxQueue ) PRIVILEGED_FUNCTION;
/*
* Copies an item into the queue, either at the front of the queue or the
* back of the queue.
*/
static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition ) PRIVILEGED_FUNCTION;
/*
* Copies an item out of a queue.
*/
static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void * const pvBuffer ) PRIVILEGED_FUNCTION;
#if ( configUSE_QUEUE_SETS == 1 )
/*
* Checks to see if a queue is a member of a queue set, and if so, notifies
* the queue set that the queue contains data.
*/
static portBASE_TYPE prvNotifyQueueSetContainer( const xQUEUE * const pxQueue, portBASE_TYPE xCopyPosition ) PRIVILEGED_FUNCTION;
#endif
/*-----------------------------------------------------------*/
/*
* Macro to mark a queue as locked. Locking a queue prevents an ISR from
* accessing the queue event lists.
*/
#define prvLockQueue( pxQueue ) \
taskENTER_CRITICAL(); \
{ \
if( ( pxQueue )->xRxLock == queueUNLOCKED ) \
{ \
( pxQueue )->xRxLock = queueLOCKED_UNMODIFIED; \
} \
if( ( pxQueue )->xTxLock == queueUNLOCKED ) \
{ \
( pxQueue )->xTxLock = queueLOCKED_UNMODIFIED; \
} \
} \
taskEXIT_CRITICAL()
/*-----------------------------------------------------------*/
portBASE_TYPE xQueueGenericReset( xQueueHandle xQueue, portBASE_TYPE xNewQueue )
{
xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
configASSERT( pxQueue );
taskENTER_CRITICAL();
{
pxQueue->pcTail = pxQueue->pcHead + ( pxQueue->uxLength * pxQueue->uxItemSize );
pxQueue->uxMessagesWaiting = ( unsigned portBASE_TYPE ) 0U;
pxQueue->pcWriteTo = pxQueue->pcHead;
pxQueue->u.pcReadFrom = pxQueue->pcHead + ( ( pxQueue->uxLength - ( unsigned portBASE_TYPE ) 1U ) * pxQueue->uxItemSize );
pxQueue->xRxLock = queueUNLOCKED;
pxQueue->xTxLock = queueUNLOCKED;
if( xNewQueue == pdFALSE )
{
/* If there are tasks blocked waiting to read from the queue, then
the tasks will remain blocked as after this function exits the queue
will still be empty. If there are tasks blocked waiting to write to
the queue, then one should be unblocked as after this function exits
it will be possible to write to it. */
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE )
{
portYIELD_WITHIN_API();
}
}
}
else
{
/* Ensure the event queues start in the correct state. */
vListInitialise( &( pxQueue->xTasksWaitingToSend ) );
vListInitialise( &( pxQueue->xTasksWaitingToReceive ) );
}
}
taskEXIT_CRITICAL();
/* A value is returned for calling semantic consistency with previous
versions. */
return pdPASS;
}
/*-----------------------------------------------------------*/
xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType )
{
xQUEUE *pxNewQueue;
size_t xQueueSizeInBytes;
xQueueHandle xReturn = NULL;
/* Remove compiler warnings about unused parameters should
configUSE_TRACE_FACILITY not be set to 1. */
( void ) ucQueueType;
/* Allocate the new queue structure. */
if( uxQueueLength > ( unsigned portBASE_TYPE ) 0 )
{
pxNewQueue = ( xQUEUE * ) pvPortMalloc( sizeof( xQUEUE ) );
if( pxNewQueue != NULL )
{
/* Create the list of pointers to queue items. The queue is one byte
longer than asked for to make wrap checking easier/faster. */
xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ) + ( size_t ) 1; /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
pxNewQueue->pcHead = ( signed char * ) pvPortMalloc( xQueueSizeInBytes );
if( pxNewQueue->pcHead != NULL )
{
/* Initialise the queue members as described above where the
queue type is defined. */
pxNewQueue->uxLength = uxQueueLength;
pxNewQueue->uxItemSize = uxItemSize;
( void ) xQueueGenericReset( pxNewQueue, pdTRUE );
#if ( configUSE_TRACE_FACILITY == 1 )
{
pxNewQueue->ucQueueType = ucQueueType;
}
#endif /* configUSE_TRACE_FACILITY */
#if( configUSE_QUEUE_SETS == 1 )
{
pxNewQueue->pxQueueSetContainer = NULL;
}
#endif /* configUSE_QUEUE_SETS */
traceQUEUE_CREATE( pxNewQueue );
xReturn = pxNewQueue;
}
else
{
traceQUEUE_CREATE_FAILED( ucQueueType );
vPortFree( pxNewQueue );
}
}
}
configASSERT( xReturn );
return xReturn;
}
/*-----------------------------------------------------------*/
#if ( configUSE_MUTEXES == 1 )
xQueueHandle xQueueCreateMutex( unsigned char ucQueueType )
{
xQUEUE *pxNewQueue;
/* Prevent compiler warnings about unused parameters if
configUSE_TRACE_FACILITY does not equal 1. */
( void ) ucQueueType;
/* Allocate the new queue structure. */
pxNewQueue = ( xQUEUE * ) pvPortMalloc( sizeof( xQUEUE ) );
if( pxNewQueue != NULL )
{
/* Information required for priority inheritance. */
pxNewQueue->pxMutexHolder = NULL;
pxNewQueue->uxQueueType = queueQUEUE_IS_MUTEX;
/* Queues used as a mutex no data is actually copied into or out
of the queue. */
pxNewQueue->pcWriteTo = NULL;
pxNewQueue->u.pcReadFrom = NULL;
/* Each mutex has a length of 1 (like a binary semaphore) and
an item size of 0 as nothing is actually copied into or out
of the mutex. */
pxNewQueue->uxMessagesWaiting = ( unsigned portBASE_TYPE ) 0U;
pxNewQueue->uxLength = ( unsigned portBASE_TYPE ) 1U;
pxNewQueue->uxItemSize = ( unsigned portBASE_TYPE ) 0U;
pxNewQueue->xRxLock = queueUNLOCKED;
pxNewQueue->xTxLock = queueUNLOCKED;
#if ( configUSE_TRACE_FACILITY == 1 )
{
pxNewQueue->ucQueueType = ucQueueType;
}
#endif
#if ( configUSE_QUEUE_SETS == 1 )
{
pxNewQueue->pxQueueSetContainer = NULL;
}
#endif
/* Ensure the event queues start with the correct state. */
vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) );
vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) );
traceCREATE_MUTEX( pxNewQueue );
/* Start with the semaphore in the expected state. */
( void ) xQueueGenericSend( pxNewQueue, NULL, ( portTickType ) 0U, queueSEND_TO_BACK );
}
else
{
traceCREATE_MUTEX_FAILED();
}
configASSERT( pxNewQueue );
return pxNewQueue;
}
#endif /* configUSE_MUTEXES */
/*-----------------------------------------------------------*/
#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) )
void* xQueueGetMutexHolder( xQueueHandle xSemaphore )
{
void *pxReturn;
/* This function is called by xSemaphoreGetMutexHolder(), and should not
be called directly. Note: This is is a good way of determining if the
calling task is the mutex holder, but not a good way of determining the
identity of the mutex holder, as the holder may change between the
following critical section exiting and the function returning. */
taskENTER_CRITICAL();
{
if( ( ( xQUEUE * ) xSemaphore )->uxQueueType == queueQUEUE_IS_MUTEX )
{
pxReturn = ( void * ) ( ( xQUEUE * ) xSemaphore )->pxMutexHolder;
}
else
{
pxReturn = NULL;
}
}
taskEXIT_CRITICAL();
return pxReturn;
}
#endif
/*-----------------------------------------------------------*/
#if ( configUSE_RECURSIVE_MUTEXES == 1 )
portBASE_TYPE xQueueGiveMutexRecursive( xQueueHandle xMutex )
{
portBASE_TYPE xReturn;
xQUEUE * const pxMutex = ( xQUEUE * ) xMutex;
configASSERT( pxMutex );
/* If this is the task that holds the mutex then pxMutexHolder will not
change outside of this task. If this task does not hold the mutex then
pxMutexHolder can never coincidentally equal the tasks handle, and as
this is the only condition we are interested in it does not matter if
pxMutexHolder is accessed simultaneously by another task. Therefore no
mutual exclusion is required to test the pxMutexHolder variable. */
if( pxMutex->pxMutexHolder == ( void * ) xTaskGetCurrentTaskHandle() ) /*lint !e961 Not a redundant cast as xTaskHandle is a typedef. */
{
traceGIVE_MUTEX_RECURSIVE( pxMutex );
/* uxRecursiveCallCount cannot be zero if pxMutexHolder is equal to
the task handle, therefore no underflow check is required. Also,
uxRecursiveCallCount is only modified by the mutex holder, and as
there can only be one, no mutual exclusion is required to modify the
uxRecursiveCallCount member. */
( pxMutex->u.uxRecursiveCallCount )--;
/* Have we unwound the call count? */
if( pxMutex->u.uxRecursiveCallCount == ( unsigned portBASE_TYPE ) 0 )
{
/* Return the mutex. This will automatically unblock any other
task that might be waiting to access the mutex. */
( void ) xQueueGenericSend( pxMutex, NULL, queueMUTEX_GIVE_BLOCK_TIME, queueSEND_TO_BACK );
}
xReturn = pdPASS;
}
else
{
/* We cannot give the mutex because we are not the holder. */
xReturn = pdFAIL;
traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex );
}
return xReturn;
}
#endif /* configUSE_RECURSIVE_MUTEXES */
/*-----------------------------------------------------------*/
#if ( configUSE_RECURSIVE_MUTEXES == 1 )
portBASE_TYPE xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime )
{
portBASE_TYPE xReturn;
xQUEUE * const pxMutex = ( xQUEUE * ) xMutex;
configASSERT( pxMutex );
/* Comments regarding mutual exclusion as per those within
xQueueGiveMutexRecursive(). */
traceTAKE_MUTEX_RECURSIVE( pxMutex );
if( pxMutex->pxMutexHolder == ( void * ) xTaskGetCurrentTaskHandle() ) /*lint !e961 Cast is not redundant as xTaskHandle is a typedef. */
{
( pxMutex->u.uxRecursiveCallCount )++;
xReturn = pdPASS;
}
else
{
xReturn = xQueueGenericReceive( pxMutex, NULL, xBlockTime, pdFALSE );
/* pdPASS will only be returned if we successfully obtained the mutex,
we may have blocked to reach here. */
if( xReturn == pdPASS )
{
( pxMutex->u.uxRecursiveCallCount )++;
}
else
{
traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex );
}
}
return xReturn;
}
#endif /* configUSE_RECURSIVE_MUTEXES */
/*-----------------------------------------------------------*/
#if ( configUSE_COUNTING_SEMAPHORES == 1 )
xQueueHandle xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount )
{
xQueueHandle xHandle;
xHandle = xQueueGenericCreate( uxCountValue, queueSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_COUNTING_SEMAPHORE );
if( xHandle != NULL )
{
( ( xQUEUE * ) xHandle )->uxMessagesWaiting = uxInitialCount;
traceCREATE_COUNTING_SEMAPHORE();
}
else
{
traceCREATE_COUNTING_SEMAPHORE_FAILED();
}
configASSERT( xHandle );
return xHandle;
}
#endif /* configUSE_COUNTING_SEMAPHORES */
/*-----------------------------------------------------------*/
signed portBASE_TYPE xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )
{
signed portBASE_TYPE xEntryTimeSet = pdFALSE;
xTimeOutType xTimeOut;
xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
configASSERT( pxQueue );
configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) );
/* This function relaxes the coding standard somewhat to allow return
statements within the function itself. This is done in the interest
of execution time efficiency. */
for( ;; )
{
taskENTER_CRITICAL();
{
/* Is there room on the queue now? The running task must be
the highest priority task wanting to access the queue. If
the head item in the queue is to be overwritten then it does
not matter if the queue is full. */
if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) )
{
traceQUEUE_SEND( pxQueue );
prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
#if ( configUSE_QUEUE_SETS == 1 )
{
if( pxQueue->pxQueueSetContainer != NULL )
{
if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) == pdTRUE )
{
/* The queue is a member of a queue set, and posting
to the queue set caused a higher priority task to
unblock. A context switch is required. */
portYIELD_WITHIN_API();
}
}
else
{
/* If there was a task waiting for data to arrive on the
queue then unblock it now. */
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE )
{
/* The unblocked task has a priority higher than
our own so yield immediately. Yes it is ok to
do this from within the critical section - the
kernel takes care of that. */
portYIELD_WITHIN_API();
}
}
}
}
#else /* configUSE_QUEUE_SETS */
{
/* If there was a task waiting for data to arrive on the
queue then unblock it now. */
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE )
{
/* The unblocked task has a priority higher than
our own so yield immediately. Yes it is ok to do
this from within the critical section - the kernel
takes care of that. */
portYIELD_WITHIN_API();
}
}
}
#endif /* configUSE_QUEUE_SETS */
taskEXIT_CRITICAL();
/* Return to the original privilege level before exiting the
function. */
return pdPASS;
}
else
{
if( xTicksToWait == ( portTickType ) 0 )
{
/* The queue was full and no block time is specified (or
the block time has expired) so leave now. */
taskEXIT_CRITICAL();
/* Return to the original privilege level before exiting
the function. */
traceQUEUE_SEND_FAILED( pxQueue );
return errQUEUE_FULL;
}
else if( xEntryTimeSet == pdFALSE )
{
/* The queue was full and a block time was specified so
configure the timeout structure. */
vTaskSetTimeOutState( &xTimeOut );
xEntryTimeSet = pdTRUE;
}
else
{
/* Entry time was already set. */
}
}
}
taskEXIT_CRITICAL();
/* Interrupts and other tasks can send to and receive from the queue
now the critical section has been exited. */
vTaskSuspendAll();
prvLockQueue( pxQueue );
/* Update the timeout state to see if it has expired yet. */
if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
{
if( prvIsQueueFull( pxQueue ) != pdFALSE )
{
traceBLOCKING_ON_QUEUE_SEND( pxQueue );
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );
/* Unlocking the queue means queue events can effect the
event list. It is possible that interrupts occurring now
remove this task from the event list again - but as the
scheduler is suspended the task will go onto the pending
ready last instead of the actual ready list. */
prvUnlockQueue( pxQueue );
/* Resuming the scheduler will move tasks from the pending
ready list into the ready list - so it is feasible that this
task is already in a ready list before it yields - in which
case the yield will not cause a context switch unless there
is also a higher priority task in the pending ready list. */
if( xTaskResumeAll() == pdFALSE )
{
portYIELD_WITHIN_API();
}
}
else
{
/* Try again. */
prvUnlockQueue( pxQueue );
( void ) xTaskResumeAll();
}
}
else
{
/* The timeout has expired. */
prvUnlockQueue( pxQueue );
( void ) xTaskResumeAll();
/* Return to the original privilege level before exiting the
function. */
traceQUEUE_SEND_FAILED( pxQueue );
return errQUEUE_FULL;
}
}
}
/*-----------------------------------------------------------*/
#if ( configUSE_ALTERNATIVE_API == 1 )
signed portBASE_TYPE xQueueAltGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )
{
signed portBASE_TYPE xEntryTimeSet = pdFALSE;
xTimeOutType xTimeOut;
xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
configASSERT( pxQueue );
configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
for( ;; )
{
taskENTER_CRITICAL();
{
/* Is there room on the queue now? To be running we must be
the highest priority task wanting to access the queue. */
if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
{
traceQUEUE_SEND( pxQueue );
prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
/* If there was a task waiting for data to arrive on the
queue then unblock it now. */
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE )
{
/* The unblocked task has a priority higher than
our own so yield immediately. */
portYIELD_WITHIN_API();
}
}
taskEXIT_CRITICAL();
return pdPASS;
}
else
{
if( xTicksToWait == ( portTickType ) 0 )
{
taskEXIT_CRITICAL();
return errQUEUE_FULL;
}
else if( xEntryTimeSet == pdFALSE )
{
vTaskSetTimeOutState( &xTimeOut );
xEntryTimeSet = pdTRUE;
}
}
}
taskEXIT_CRITICAL();
taskENTER_CRITICAL();
{
if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
{
if( prvIsQueueFull( pxQueue ) != pdFALSE )
{
traceBLOCKING_ON_QUEUE_SEND( pxQueue );
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );
portYIELD_WITHIN_API();
}
}
else
{
taskEXIT_CRITICAL();
traceQUEUE_SEND_FAILED( pxQueue );
return errQUEUE_FULL;
}
}
taskEXIT_CRITICAL();
}
}
#endif /* configUSE_ALTERNATIVE_API */
/*-----------------------------------------------------------*/
#if ( configUSE_ALTERNATIVE_API == 1 )
signed portBASE_TYPE xQueueAltGenericReceive( xQueueHandle xQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )
{
signed portBASE_TYPE xEntryTimeSet = pdFALSE;
xTimeOutType xTimeOut;
signed char *pcOriginalReadPosition;
xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
configASSERT( pxQueue );
configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
for( ;; )
{
taskENTER_CRITICAL();
{
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
{
/* Remember our read position in case we are just peeking. */
pcOriginalReadPosition = pxQueue->u.pcReadFrom;
prvCopyDataFromQueue( pxQueue, pvBuffer );
if( xJustPeeking == pdFALSE )
{
traceQUEUE_RECEIVE( pxQueue );
/* Data is actually being removed (not just peeked). */
--( pxQueue->uxMessagesWaiting );
#if ( configUSE_MUTEXES == 1 )
{
if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
{
/* Record the information required to implement
priority inheritance should it become necessary. */
pxQueue->pxMutexHolder = ( signed char * ) xTaskGetCurrentTaskHandle();
}
}
#endif
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE )
{
portYIELD_WITHIN_API();
}
}
}
else
{
traceQUEUE_PEEK( pxQueue );
/* We are not removing the data, so reset our read
pointer. */
pxQueue->u.pcReadFrom = pcOriginalReadPosition;
/* The data is being left in the queue, so see if there are
any other tasks waiting for the data. */
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
{
/* Tasks that are removed from the event list will get added to
the pending ready list as the scheduler is still suspended. */
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
{
/* The task waiting has a higher priority than this task. */
portYIELD_WITHIN_API();
}
}
}
taskEXIT_CRITICAL();
return pdPASS;
}
else
{
if( xTicksToWait == ( portTickType ) 0 )
{
taskEXIT_CRITICAL();
traceQUEUE_RECEIVE_FAILED( pxQueue );
return errQUEUE_EMPTY;
}
else if( xEntryTimeSet == pdFALSE )
{
vTaskSetTimeOutState( &xTimeOut );
xEntryTimeSet = pdTRUE;
}
}
}
taskEXIT_CRITICAL();
taskENTER_CRITICAL();
{
if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
{
if( prvIsQueueEmpty( pxQueue ) != pdFALSE )
{
traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );
#if ( configUSE_MUTEXES == 1 )
{
if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
{
portENTER_CRITICAL();
{
vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );
}
portEXIT_CRITICAL();
}
}
#endif
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );
portYIELD_WITHIN_API();
}
}
else
{
taskEXIT_CRITICAL();
traceQUEUE_RECEIVE_FAILED( pxQueue );
return errQUEUE_EMPTY;
}
}
taskEXIT_CRITICAL();
}
}
#endif /* configUSE_ALTERNATIVE_API */
/*-----------------------------------------------------------*/
signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle xQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition )
{
signed portBASE_TYPE xReturn;
unsigned portBASE_TYPE uxSavedInterruptStatus;
xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
configASSERT( pxQueue );
configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) );
/* RTOS ports that support interrupt nesting have the concept of a maximum
system call (or maximum API call) interrupt priority. Interrupts that are
above the maximum system call priority are keep permanently enabled, even
when the RTOS kernel is in a critical section, but cannot make any calls to
FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h
then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
failure if a FreeRTOS API function is called from an interrupt that has been
assigned a priority above the configured maximum system call priority.
Only FreeRTOS functions that end in FromISR can be called from interrupts
that have been assigned a priority at or (logically) below the maximum
system call interrupt priority. FreeRTOS maintains a separate interrupt
safe API to ensure interrupt entry is as fast and as simple as possible.
More information (albeit Cortex-M specific) is provided on the following
link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */
portASSERT_IF_INTERRUPT_PRIORITY_INVALID();
/* Similar to xQueueGenericSend, except we don't block if there is no room
in the queue. Also we don't directly wake a task that was blocked on a
queue read, instead we return a flag to say whether a context switch is
required or not (i.e. has a task with a higher priority than us been woken
by this post). */
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
{
if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) )
{
traceQUEUE_SEND_FROM_ISR( pxQueue );
prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
/* If the queue is locked we do not alter the event list. This will
be done when the queue is unlocked later. */
if( pxQueue->xTxLock == queueUNLOCKED )
{
#if ( configUSE_QUEUE_SETS == 1 )
{
if( pxQueue->pxQueueSetContainer != NULL )
{
if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) == pdTRUE )
{
/* The queue is a member of a queue set, and posting
to the queue set caused a higher priority task to
unblock. A context switch is required. */
if( pxHigherPriorityTaskWoken != NULL )
{
*pxHigherPriorityTaskWoken = pdTRUE;
}
}
}
else
{
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
{
/* The task waiting has a higher priority so record that a
context switch is required. */
if( pxHigherPriorityTaskWoken != NULL )
{
*pxHigherPriorityTaskWoken = pdTRUE;
}
}
}
}
}
#else /* configUSE_QUEUE_SETS */
{
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
{
/* The task waiting has a higher priority so record that a
context switch is required. */
if( pxHigherPriorityTaskWoken != NULL )
{
*pxHigherPriorityTaskWoken = pdTRUE;
}
}
}
}
#endif /* configUSE_QUEUE_SETS */
}
else
{
/* Increment the lock count so the task that unlocks the queue
knows that data was posted while it was locked. */
++( pxQueue->xTxLock );
}
xReturn = pdPASS;
}
else
{
traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue );
xReturn = errQUEUE_FULL;
}
}
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
return xReturn;
}
/*-----------------------------------------------------------*/
signed portBASE_TYPE xQueueGenericReceive( xQueueHandle xQueue, const void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )
{
signed portBASE_TYPE xEntryTimeSet = pdFALSE;
xTimeOutType xTimeOut;
signed char *pcOriginalReadPosition;
xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
configASSERT( pxQueue );
configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
/* This function relaxes the coding standard somewhat to allow return
statements within the function itself. This is done in the interest
of execution time efficiency. */
for( ;; )
{
taskENTER_CRITICAL();
{
/* Is there data in the queue now? To be running we must be
the highest priority task wanting to access the queue. */
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
{
/* Remember the read position in case the queue is only being
peeked. */
pcOriginalReadPosition = pxQueue->u.pcReadFrom;
prvCopyDataFromQueue( pxQueue, pvBuffer );
if( xJustPeeking == pdFALSE )
{
traceQUEUE_RECEIVE( pxQueue );
/* Actually removing data, not just peeking. */
--( pxQueue->uxMessagesWaiting );
#if ( configUSE_MUTEXES == 1 )
{
if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
{
/* Record the information required to implement
priority inheritance should it become necessary. */
pxQueue->pxMutexHolder = ( signed char * ) xTaskGetCurrentTaskHandle(); /*lint !e961 Cast is not redundant as xTaskHandle is a typedef. */
}
}
#endif
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE )
{
portYIELD_WITHIN_API();
}
}
}
else
{
traceQUEUE_PEEK( pxQueue );
/* The data is not being removed, so reset the read
pointer. */
pxQueue->u.pcReadFrom = pcOriginalReadPosition;
/* The data is being left in the queue, so see if there are
any other tasks waiting for the data. */
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
{
/* Tasks that are removed from the event list will get added to
the pending ready list as the scheduler is still suspended. */
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
{
/* The task waiting has a higher priority than this task. */
portYIELD_WITHIN_API();
}
}
}
taskEXIT_CRITICAL();
return pdPASS;
}
else
{
if( xTicksToWait == ( portTickType ) 0 )
{
/* The queue was empty and no block time is specified (or
the block time has expired) so leave now. */
taskEXIT_CRITICAL();
traceQUEUE_RECEIVE_FAILED( pxQueue );
return errQUEUE_EMPTY;
}
else if( xEntryTimeSet == pdFALSE )
{
/* The queue was empty and a block time was specified so
configure the timeout structure. */
vTaskSetTimeOutState( &xTimeOut );
xEntryTimeSet = pdTRUE;
}
else
{
/* Entry time was already set. */
}
}
}
taskEXIT_CRITICAL();
/* Interrupts and other tasks can send to and receive from the queue
now the critical section has been exited. */
vTaskSuspendAll();
prvLockQueue( pxQueue );
/* Update the timeout state to see if it has expired yet. */
if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
{
if( prvIsQueueEmpty( pxQueue ) != pdFALSE )
{
traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );
#if ( configUSE_MUTEXES == 1 )
{
if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
{
portENTER_CRITICAL();
{
vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder );
}
portEXIT_CRITICAL();
}
}
#endif
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );
prvUnlockQueue( pxQueue );
if( xTaskResumeAll() == pdFALSE )
{
portYIELD_WITHIN_API();
}
}
else
{
/* Try again. */
prvUnlockQueue( pxQueue );
( void ) xTaskResumeAll();
}
}
else
{
prvUnlockQueue( pxQueue );
( void ) xTaskResumeAll();
traceQUEUE_RECEIVE_FAILED( pxQueue );
return errQUEUE_EMPTY;
}
}
}
/*-----------------------------------------------------------*/
signed portBASE_TYPE xQueueReceiveFromISR( xQueueHandle xQueue, const void * const pvBuffer, signed portBASE_TYPE *pxHigherPriorityTaskWoken )
{
signed portBASE_TYPE xReturn;
unsigned portBASE_TYPE uxSavedInterruptStatus;
xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
configASSERT( pxQueue );
configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
/* RTOS ports that support interrupt nesting have the concept of a maximum
system call (or maximum API call) interrupt priority. Interrupts that are
above the maximum system call priority are keep permanently enabled, even
when the RTOS kernel is in a critical section, but cannot make any calls to
FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h
then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
failure if a FreeRTOS API function is called from an interrupt that has been
assigned a priority above the configured maximum system call priority.
Only FreeRTOS functions that end in FromISR can be called from interrupts
that have been assigned a priority at or (logically) below the maximum
system call interrupt priority. FreeRTOS maintains a separate interrupt
safe API to ensure interrupt entry is as fast and as simple as possible.
More information (albeit Cortex-M specific) is provided on the following
link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */
portASSERT_IF_INTERRUPT_PRIORITY_INVALID();
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
{
/* Cannot block in an ISR, so check there is data available. */
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
{
traceQUEUE_RECEIVE_FROM_ISR( pxQueue );
prvCopyDataFromQueue( pxQueue, pvBuffer );
--( pxQueue->uxMessagesWaiting );
/* If the queue is locked the event list will not be modified.
Instead update the lock count so the task that unlocks the queue
will know that an ISR has removed data while the queue was
locked. */
if( pxQueue->xRxLock == queueUNLOCKED )
{
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
{
/* The task waiting has a higher priority than us so
force a context switch. */
if( pxHigherPriorityTaskWoken != NULL )
{
*pxHigherPriorityTaskWoken = pdTRUE;
}
}
}
}
else
{
/* Increment the lock count so the task that unlocks the queue
knows that data was removed while it was locked. */
++( pxQueue->xRxLock );
}
xReturn = pdPASS;
}
else
{
xReturn = pdFAIL;
traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue );
}
}
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
return xReturn;
}
/*-----------------------------------------------------------*/
signed portBASE_TYPE xQueuePeekFromISR( xQueueHandle xQueue, const void * const pvBuffer )
{
signed portBASE_TYPE xReturn;
unsigned portBASE_TYPE uxSavedInterruptStatus;
signed char *pcOriginalReadPosition;
xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
configASSERT( pxQueue );
configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( unsigned portBASE_TYPE ) 0U ) ) );
/* RTOS ports that support interrupt nesting have the concept of a maximum
system call (or maximum API call) interrupt priority. Interrupts that are
above the maximum system call priority are keep permanently enabled, even
when the RTOS kernel is in a critical section, but cannot make any calls to
FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h
then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion
failure if a FreeRTOS API function is called from an interrupt that has been
assigned a priority above the configured maximum system call priority.
Only FreeRTOS functions that end in FromISR can be called from interrupts
that have been assigned a priority at or (logically) below the maximum
system call interrupt priority. FreeRTOS maintains a separate interrupt
safe API to ensure interrupt entry is as fast and as simple as possible.
More information (albeit Cortex-M specific) is provided on the following
link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */
portASSERT_IF_INTERRUPT_PRIORITY_INVALID();
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
{
/* Cannot block in an ISR, so check there is data available. */
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
{
traceQUEUE_PEEK_FROM_ISR( pxQueue );
/* Remember the read position so it can be reset as nothing is
actually being removed from the queue. */
pcOriginalReadPosition = pxQueue->u.pcReadFrom;
prvCopyDataFromQueue( pxQueue, pvBuffer );
pxQueue->u.pcReadFrom = pcOriginalReadPosition;
xReturn = pdPASS;
}
else
{
xReturn = pdFAIL;
traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue );
}
}
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
return xReturn;
}
/*-----------------------------------------------------------*/
unsigned portBASE_TYPE uxQueueMessagesWaiting( const xQueueHandle xQueue )
{
unsigned portBASE_TYPE uxReturn;
configASSERT( xQueue );
taskENTER_CRITICAL();
uxReturn = ( ( xQUEUE * ) xQueue )->uxMessagesWaiting;
taskEXIT_CRITICAL();
return uxReturn;
} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */
/*-----------------------------------------------------------*/
unsigned portBASE_TYPE uxQueueMessagesWaitingFromISR( const xQueueHandle xQueue )
{
unsigned portBASE_TYPE uxReturn;
configASSERT( xQueue );
uxReturn = ( ( xQUEUE * ) xQueue )->uxMessagesWaiting;
return uxReturn;
} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */
/*-----------------------------------------------------------*/
void vQueueDelete( xQueueHandle xQueue )
{
xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
configASSERT( pxQueue );
traceQUEUE_DELETE( pxQueue );
#if ( configQUEUE_REGISTRY_SIZE > 0 )
{
vQueueUnregisterQueue( pxQueue );
}
#endif
vPortFree( pxQueue->pcHead );
vPortFree( pxQueue );
}
/*-----------------------------------------------------------*/
#if ( configUSE_TRACE_FACILITY == 1 )
unsigned char ucQueueGetQueueNumber( xQueueHandle xQueue )
{
return ( ( xQUEUE * ) xQueue )->ucQueueNumber;
}
#endif /* configUSE_TRACE_FACILITY */
/*-----------------------------------------------------------*/
#if ( configUSE_TRACE_FACILITY == 1 )
void vQueueSetQueueNumber( xQueueHandle xQueue, unsigned char ucQueueNumber )
{
( ( xQUEUE * ) xQueue )->ucQueueNumber = ucQueueNumber;
}
#endif /* configUSE_TRACE_FACILITY */
/*-----------------------------------------------------------*/
#if ( configUSE_TRACE_FACILITY == 1 )
unsigned char ucQueueGetQueueType( xQueueHandle xQueue )
{
return ( ( xQUEUE * ) xQueue )->ucQueueType;
}
#endif /* configUSE_TRACE_FACILITY */
/*-----------------------------------------------------------*/
static void prvCopyDataToQueue( xQUEUE *pxQueue, const void *pvItemToQueue, portBASE_TYPE xPosition )
{
if( pxQueue->uxItemSize == ( unsigned portBASE_TYPE ) 0 )
{
#if ( configUSE_MUTEXES == 1 )
{
if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
{
/* The mutex is no longer being held. */
vTaskPriorityDisinherit( ( void * ) pxQueue->pxMutexHolder );
pxQueue->pxMutexHolder = NULL;
}
}
#endif /* configUSE_MUTEXES */
}
else if( xPosition == queueSEND_TO_BACK )
{
( void ) memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 MISRA exception as the casts are only redundant for some ports, plus previous logic ensures a null pointer can only be passed to memcpy() if the copy size is 0. */
pxQueue->pcWriteTo += pxQueue->uxItemSize;
if( pxQueue->pcWriteTo >= pxQueue->pcTail ) /*lint !e946 MISRA exception justified as comparison of pointers is the cleanest solution. */
{
pxQueue->pcWriteTo = pxQueue->pcHead;
}
}
else
{
( void ) memcpy( ( void * ) pxQueue->u.pcReadFrom, pvItemToQueue, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
pxQueue->u.pcReadFrom -= pxQueue->uxItemSize;
if( pxQueue->u.pcReadFrom < pxQueue->pcHead ) /*lint !e946 MISRA exception justified as comparison of pointers is the cleanest solution. */
{
pxQueue->u.pcReadFrom = ( pxQueue->pcTail - pxQueue->uxItemSize );
}
if( xPosition == queueOVERWRITE )
{
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
{
/* An item is not being added but overwritten, so subtract
one from the recorded number of items in the queue so when
one is added again below the number of recorded items remains
correct. */
--( pxQueue->uxMessagesWaiting );
}
}
}
++( pxQueue->uxMessagesWaiting );
}
/*-----------------------------------------------------------*/
static void prvCopyDataFromQueue( xQUEUE * const pxQueue, const void * const pvBuffer )
{
if( pxQueue->uxQueueType != queueQUEUE_IS_MUTEX )
{
pxQueue->u.pcReadFrom += pxQueue->uxItemSize;
if( pxQueue->u.pcReadFrom >= pxQueue->pcTail ) /*lint !e946 MISRA exception justified as use of the relational operator is the cleanest solutions. */
{
pxQueue->u.pcReadFrom = pxQueue->pcHead;
}
( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.pcReadFrom, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 MISRA exception as the casts are only redundant for some ports. Also previous logic ensures a null pointer can only be passed to memcpy() when the count is 0. */
}
}
/*-----------------------------------------------------------*/
static void prvUnlockQueue( xQUEUE *pxQueue )
{
/* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */
/* The lock counts contains the number of extra data items placed or
removed from the queue while the queue was locked. When a queue is
locked items can be added or removed, but the event lists cannot be
updated. */
taskENTER_CRITICAL();
{
/* See if data was added to the queue while it was locked. */
while( pxQueue->xTxLock > queueLOCKED_UNMODIFIED )
{
/* Data was posted while the queue was locked. Are any tasks
blocked waiting for data to become available? */
#if ( configUSE_QUEUE_SETS == 1 )
{
if( pxQueue->pxQueueSetContainer != NULL )
{
if( prvNotifyQueueSetContainer( pxQueue, queueSEND_TO_BACK ) == pdTRUE )
{
/* The queue is a member of a queue set, and posting to
the queue set caused a higher priority task to unblock.
A context switch is required. */
vTaskMissedYield();
}
}
else
{
/* Tasks that are removed from the event list will get added to
the pending ready list as the scheduler is still suspended. */
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
{
/* The task waiting has a higher priority so record that a
context switch is required. */
vTaskMissedYield();
}
}
else
{
break;
}
}
}
#else /* configUSE_QUEUE_SETS */
{
/* Tasks that are removed from the event list will get added to
the pending ready list as the scheduler is still suspended. */
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
{
/* The task waiting has a higher priority so record that a
context switch is required. */
vTaskMissedYield();
}
}
else
{
break;
}
}
#endif /* configUSE_QUEUE_SETS */
--( pxQueue->xTxLock );
}
pxQueue->xTxLock = queueUNLOCKED;
}
taskEXIT_CRITICAL();
/* Do the same for the Rx lock. */
taskENTER_CRITICAL();
{
while( pxQueue->xRxLock > queueLOCKED_UNMODIFIED )
{
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
{
vTaskMissedYield();
}
--( pxQueue->xRxLock );
}
else
{
break;
}
}
pxQueue->xRxLock = queueUNLOCKED;
}
taskEXIT_CRITICAL();
}
/*-----------------------------------------------------------*/
static signed portBASE_TYPE prvIsQueueEmpty( const xQUEUE *pxQueue )
{
signed portBASE_TYPE xReturn;
taskENTER_CRITICAL();
{
if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 )
{
xReturn = pdTRUE;
}
else
{
xReturn = pdFALSE;
}
}
taskEXIT_CRITICAL();
return xReturn;
}
/*-----------------------------------------------------------*/
signed portBASE_TYPE xQueueIsQueueEmptyFromISR( const xQueueHandle xQueue )
{
signed portBASE_TYPE xReturn;
configASSERT( xQueue );
if( ( ( xQUEUE * ) xQueue )->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 )
{
xReturn = pdTRUE;
}
else
{
xReturn = pdFALSE;
}
return xReturn;
} /*lint !e818 xQueue could not be pointer to const because it is a typedef. */
/*-----------------------------------------------------------*/
static signed portBASE_TYPE prvIsQueueFull( const xQUEUE *pxQueue )
{
signed portBASE_TYPE xReturn;
taskENTER_CRITICAL();
{
if( pxQueue->uxMessagesWaiting == pxQueue->uxLength )
{
xReturn = pdTRUE;
}
else
{
xReturn = pdFALSE;
}
}
taskEXIT_CRITICAL();
return xReturn;
}
/*-----------------------------------------------------------*/
signed portBASE_TYPE xQueueIsQueueFullFromISR( const xQueueHandle xQueue )
{
signed portBASE_TYPE xReturn;
configASSERT( xQueue );
if( ( ( xQUEUE * ) xQueue )->uxMessagesWaiting == ( ( xQUEUE * ) xQueue )->uxLength )
{
xReturn = pdTRUE;
}
else
{
xReturn = pdFALSE;
}
return xReturn;
} /*lint !e818 xQueue could not be pointer to const because it is a typedef. */
/*-----------------------------------------------------------*/
#if ( configUSE_CO_ROUTINES == 1 )
signed portBASE_TYPE xQueueCRSend( xQueueHandle xQueue, const void *pvItemToQueue, portTickType xTicksToWait )
{
signed portBASE_TYPE xReturn;
xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
/* If the queue is already full we may have to block. A critical section
is required to prevent an interrupt removing something from the queue
between the check to see if the queue is full and blocking on the queue. */
portDISABLE_INTERRUPTS();
{
if( prvIsQueueFull( pxQueue ) != pdFALSE )
{
/* The queue is full - do we want to block or just leave without
posting? */
if( xTicksToWait > ( portTickType ) 0 )
{
/* As this is called from a coroutine we cannot block directly, but
return indicating that we need to block. */
vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToSend ) );
portENABLE_INTERRUPTS();
return errQUEUE_BLOCKED;
}
else
{
portENABLE_INTERRUPTS();
return errQUEUE_FULL;
}
}
}
portENABLE_INTERRUPTS();
portDISABLE_INTERRUPTS();
{
if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
{
/* There is room in the queue, copy the data into the queue. */
prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );
xReturn = pdPASS;
/* Were any co-routines waiting for data to become available? */
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
{
/* In this instance the co-routine could be placed directly
into the ready list as we are within a critical section.
Instead the same pending ready list mechanism is used as if
the event were caused from within an interrupt. */
if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
{
/* The co-routine waiting has a higher priority so record
that a yield might be appropriate. */
xReturn = errQUEUE_YIELD;
}
}
}
else
{
xReturn = errQUEUE_FULL;
}
}
portENABLE_INTERRUPTS();
return xReturn;
}
#endif /* configUSE_CO_ROUTINES */
/*-----------------------------------------------------------*/
#if ( configUSE_CO_ROUTINES == 1 )
signed portBASE_TYPE xQueueCRReceive( xQueueHandle xQueue, void *pvBuffer, portTickType xTicksToWait )
{
signed portBASE_TYPE xReturn;
xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
/* If the queue is already empty we may have to block. A critical section
is required to prevent an interrupt adding something to the queue
between the check to see if the queue is empty and blocking on the queue. */
portDISABLE_INTERRUPTS();
{
if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 )
{
/* There are no messages in the queue, do we want to block or just
leave with nothing? */
if( xTicksToWait > ( portTickType ) 0 )
{
/* As this is a co-routine we cannot block directly, but return
indicating that we need to block. */
vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToReceive ) );
portENABLE_INTERRUPTS();
return errQUEUE_BLOCKED;
}
else
{
portENABLE_INTERRUPTS();
return errQUEUE_FULL;
}
}
}
portENABLE_INTERRUPTS();
portDISABLE_INTERRUPTS();
{
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
{
/* Data is available from the queue. */
pxQueue->u.pcReadFrom += pxQueue->uxItemSize;
if( pxQueue->u.pcReadFrom >= pxQueue->pcTail )
{
pxQueue->u.pcReadFrom = pxQueue->pcHead;
}
--( pxQueue->uxMessagesWaiting );
( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.pcReadFrom, ( unsigned ) pxQueue->uxItemSize );
xReturn = pdPASS;
/* Were any co-routines waiting for space to become available? */
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
{
/* In this instance the co-routine could be placed directly
into the ready list as we are within a critical section.
Instead the same pending ready list mechanism is used as if
the event were caused from within an interrupt. */
if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
{
xReturn = errQUEUE_YIELD;
}
}
}
else
{
xReturn = pdFAIL;
}
}
portENABLE_INTERRUPTS();
return xReturn;
}
#endif /* configUSE_CO_ROUTINES */
/*-----------------------------------------------------------*/
#if ( configUSE_CO_ROUTINES == 1 )
signed portBASE_TYPE xQueueCRSendFromISR( xQueueHandle xQueue, const void *pvItemToQueue, signed portBASE_TYPE xCoRoutinePreviouslyWoken )
{
xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
/* Cannot block within an ISR so if there is no space on the queue then
exit without doing anything. */
if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
{
prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK );
/* We only want to wake one co-routine per ISR, so check that a
co-routine has not already been woken. */
if( xCoRoutinePreviouslyWoken == pdFALSE )
{
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
{
if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
{
return pdTRUE;
}
}
}
}
return xCoRoutinePreviouslyWoken;
}
#endif /* configUSE_CO_ROUTINES */
/*-----------------------------------------------------------*/
#if ( configUSE_CO_ROUTINES == 1 )
signed portBASE_TYPE xQueueCRReceiveFromISR( xQueueHandle xQueue, void *pvBuffer, signed portBASE_TYPE *pxCoRoutineWoken )
{
signed portBASE_TYPE xReturn;
xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
/* We cannot block from an ISR, so check there is data available. If
not then just leave without doing anything. */
if( pxQueue->uxMessagesWaiting > ( unsigned portBASE_TYPE ) 0 )
{
/* Copy the data from the queue. */
pxQueue->u.pcReadFrom += pxQueue->uxItemSize;
if( pxQueue->u.pcReadFrom >= pxQueue->pcTail )
{
pxQueue->u.pcReadFrom = pxQueue->pcHead;
}
--( pxQueue->uxMessagesWaiting );
( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.pcReadFrom, ( unsigned ) pxQueue->uxItemSize );
if( ( *pxCoRoutineWoken ) == pdFALSE )
{
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
{
if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
{
*pxCoRoutineWoken = pdTRUE;
}
}
}
xReturn = pdPASS;
}
else
{
xReturn = pdFAIL;
}
return xReturn;
}
#endif /* configUSE_CO_ROUTINES */
/*-----------------------------------------------------------*/
#if ( configQUEUE_REGISTRY_SIZE > 0 )
void vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcQueueName )
{
unsigned portBASE_TYPE ux;
/* See if there is an empty space in the registry. A NULL name denotes
a free slot. */
for( ux = ( unsigned portBASE_TYPE ) 0U; ux < ( unsigned portBASE_TYPE ) configQUEUE_REGISTRY_SIZE; ux++ )
{
if( xQueueRegistry[ ux ].pcQueueName == NULL )
{
/* Store the information on this queue. */
xQueueRegistry[ ux ].pcQueueName = pcQueueName;
xQueueRegistry[ ux ].xHandle = xQueue;
break;
}
}
}
#endif /* configQUEUE_REGISTRY_SIZE */
/*-----------------------------------------------------------*/
#if ( configQUEUE_REGISTRY_SIZE > 0 )
void vQueueUnregisterQueue( xQueueHandle xQueue )
{
unsigned portBASE_TYPE ux;
/* See if the handle of the queue being unregistered in actually in the
registry. */
for( ux = ( unsigned portBASE_TYPE ) 0U; ux < ( unsigned portBASE_TYPE ) configQUEUE_REGISTRY_SIZE; ux++ )
{
if( xQueueRegistry[ ux ].xHandle == xQueue )
{
/* Set the name to NULL to show that this slot if free again. */
xQueueRegistry[ ux ].pcQueueName = NULL;
break;
}
}
} /*lint !e818 xQueue could not be pointer to const because it is a typedef. */
#endif /* configQUEUE_REGISTRY_SIZE */
/*-----------------------------------------------------------*/
#if ( configUSE_TIMERS == 1 )
void vQueueWaitForMessageRestricted( xQueueHandle xQueue, portTickType xTicksToWait )
{
xQUEUE * const pxQueue = ( xQUEUE * ) xQueue;
/* This function should not be called by application code hence the
'Restricted' in its name. It is not part of the public API. It is
designed for use by kernel code, and has special calling requirements.
It can result in vListInsert() being called on a list that can only
possibly ever have one item in it, so the list will be fast, but even
so it should be called with the scheduler locked and not from a critical
section. */
/* Only do anything if there are no messages in the queue. This function
will not actually cause the task to block, just place it on a blocked
list. It will not block until the scheduler is unlocked - at which
time a yield will be performed. If an item is added to the queue while
the queue is locked, and the calling task blocks on the queue, then the
calling task will be immediately unblocked when the queue is unlocked. */
prvLockQueue( pxQueue );
if( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0U )
{
/* There is nothing in the queue, block for the specified period. */
vTaskPlaceOnEventListRestricted( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );
}
prvUnlockQueue( pxQueue );
}
#endif /* configUSE_TIMERS */
/*-----------------------------------------------------------*/
#if ( configUSE_QUEUE_SETS == 1 )
xQueueSetHandle xQueueCreateSet( unsigned portBASE_TYPE uxEventQueueLength )
{
xQueueSetHandle pxQueue;
pxQueue = xQueueGenericCreate( uxEventQueueLength, sizeof( xQUEUE * ), queueQUEUE_TYPE_SET );
return pxQueue;
}
#endif /* configUSE_QUEUE_SETS */
/*-----------------------------------------------------------*/
#if ( configUSE_QUEUE_SETS == 1 )
portBASE_TYPE xQueueAddToSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet )
{
portBASE_TYPE xReturn;
if( ( ( xQUEUE * ) xQueueOrSemaphore )->pxQueueSetContainer != NULL )
{
/* Cannot add a queue/semaphore to more than one queue set. */
xReturn = pdFAIL;
}
else if( ( ( xQUEUE * ) xQueueOrSemaphore )->uxMessagesWaiting != ( unsigned portBASE_TYPE ) 0 )
{
/* Cannot add a queue/semaphore to a queue set if there are already
items in the queue/semaphore. */
xReturn = pdFAIL;
}
else
{
taskENTER_CRITICAL();
{
( ( xQUEUE * ) xQueueOrSemaphore )->pxQueueSetContainer = xQueueSet;
}
taskEXIT_CRITICAL();
xReturn = pdPASS;
}
return xReturn;
}
#endif /* configUSE_QUEUE_SETS */
/*-----------------------------------------------------------*/
#if ( configUSE_QUEUE_SETS == 1 )
portBASE_TYPE xQueueRemoveFromSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet )
{
portBASE_TYPE xReturn;
xQUEUE * const pxQueueOrSemaphore = ( xQUEUE * ) xQueueOrSemaphore;
if( pxQueueOrSemaphore->pxQueueSetContainer != xQueueSet )
{
/* The queue was not a member of the set. */
xReturn = pdFAIL;
}
else if( pxQueueOrSemaphore->uxMessagesWaiting != ( unsigned portBASE_TYPE ) 0 )
{
/* It is dangerous to remove a queue from a set when the queue is
not empty because the queue set will still hold pending events for
the queue. */
xReturn = pdFAIL;
}
else
{
taskENTER_CRITICAL();
{
/* The queue is no longer contained in the set. */
pxQueueOrSemaphore->pxQueueSetContainer = NULL;
}
taskEXIT_CRITICAL();
xReturn = pdPASS;
}
return xReturn;
} /*lint !e818 xQueueSet could not be declared as pointing to const as it is a typedef. */
#endif /* configUSE_QUEUE_SETS */
/*-----------------------------------------------------------*/
#if ( configUSE_QUEUE_SETS == 1 )
xQueueSetMemberHandle xQueueSelectFromSet( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks )
{
xQueueSetMemberHandle xReturn = NULL;
( void ) xQueueGenericReceive( ( xQueueHandle ) xQueueSet, &xReturn, xBlockTimeTicks, pdFALSE ); /*lint !e961 Casting from one typedef to another is not redundant. */
return xReturn;
}
#endif /* configUSE_QUEUE_SETS */
/*-----------------------------------------------------------*/
#if ( configUSE_QUEUE_SETS == 1 )
xQueueSetMemberHandle xQueueSelectFromSetFromISR( xQueueSetHandle xQueueSet )
{
xQueueSetMemberHandle xReturn = NULL;
( void ) xQueueReceiveFromISR( ( xQueueHandle ) xQueueSet, &xReturn, NULL ); /*lint !e961 Casting from one typedef to another is not redundant. */
return xReturn;
}
#endif /* configUSE_QUEUE_SETS */
/*-----------------------------------------------------------*/
#if ( configUSE_QUEUE_SETS == 1 )
static portBASE_TYPE prvNotifyQueueSetContainer( const xQUEUE * const pxQueue, portBASE_TYPE xCopyPosition )
{
xQUEUE *pxQueueSetContainer = pxQueue->pxQueueSetContainer;
portBASE_TYPE xReturn = pdFALSE;
configASSERT( pxQueueSetContainer );
configASSERT( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength );
if( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength )
{
traceQUEUE_SEND( pxQueueSetContainer );
/* The data copies is the handle of the queue that contains data. */
prvCopyDataToQueue( pxQueueSetContainer, &pxQueue, xCopyPosition );
if( listLIST_IS_EMPTY( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) != pdFALSE )
{
/* The task waiting has a higher priority */
xReturn = pdTRUE;
}
}
}
return xReturn;
}
#endif /* configUSE_QUEUE_SETS */
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
FreeRTOS V7.5.2 - Copyright (C) 2013 Real Time Engineers Ltd.
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
***************************************************************************
* *
* FreeRTOS provides completely free yet professionally developed, *
* robust, strictly quality controlled, supported, and cross *
* platform software that has become a de facto standard. *
* *
* Help yourself get started quickly and support the FreeRTOS *
* project by purchasing a FreeRTOS tutorial book, reference *
* manual, or both from: http://www.FreeRTOS.org/Documentation *
* *
* Thank you! *
* *
***************************************************************************
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. Full license text is available from the following
link: http://www.freertos.org/a00114.html
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, a DOS
compatible FAT file system, and our tiny thread aware UDP/IP stack.
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
licenses offer ticketed support, indemnification and middleware.
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.
1 tab == 4 spaces!
*/
/* Standard includes. */
#include <stdlib.h>
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
all the API functions to use the MPU wrappers. That should only be done when
task.h is included from an application file. */
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "timers.h"
/* Lint e961 and e750 are suppressed as a MISRA exception justified because the
MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the
header files above, but not in this file, in order to generate the correct
privileged Vs unprivileged linkage and placement. */
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */
/* This entire source file will be skipped if the application is not configured
to include software timer functionality. This #if is closed at the very bottom
of this file. If you want to include software timer functionality then ensure
configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */
#if ( configUSE_TIMERS == 1 )
/* Misc definitions. */
#define tmrNO_DELAY ( portTickType ) 0U
/* The definition of the timers themselves. */
typedef struct tmrTimerControl
{
const signed char *pcTimerName; /*<< Text name. This is not used by the kernel, it is included simply to make debugging easier. */
xListItem xTimerListItem; /*<< Standard linked list item as used by all kernel features for event management. */
portTickType xTimerPeriodInTicks;/*<< How quickly and often the timer expires. */
unsigned portBASE_TYPE uxAutoReload; /*<< Set to pdTRUE if the timer should be automatically restarted once expired. Set to pdFALSE if the timer is, in effect, a one shot timer. */
void *pvTimerID; /*<< An ID to identify the timer. This allows the timer to be identified when the same callback is used for multiple timers. */
tmrTIMER_CALLBACK pxCallbackFunction; /*<< The function that will be called when the timer expires. */
} xTIMER;
/* The definition of messages that can be sent and received on the timer
queue. */
typedef struct tmrTimerQueueMessage
{
portBASE_TYPE xMessageID; /*<< The command being sent to the timer service task. */
portTickType xMessageValue; /*<< An optional value used by a subset of commands, for example, when changing the period of a timer. */
xTIMER * pxTimer; /*<< The timer to which the command will be applied. */
} xTIMER_MESSAGE;
/*lint -e956 A manual analysis and inspection has been used to determine which
static variables must be declared volatile. */
/* The list in which active timers are stored. Timers are referenced in expire
time order, with the nearest expiry time at the front of the list. Only the
timer service task is allowed to access xActiveTimerList. */
PRIVILEGED_DATA static xList xActiveTimerList1;
PRIVILEGED_DATA static xList xActiveTimerList2;
PRIVILEGED_DATA static xList *pxCurrentTimerList;
PRIVILEGED_DATA static xList *pxOverflowTimerList;
/* A queue that is used to send commands to the timer service task. */
PRIVILEGED_DATA static xQueueHandle xTimerQueue = NULL;
#if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 )
PRIVILEGED_DATA static xTaskHandle xTimerTaskHandle = NULL;
#endif
/*lint +e956 */
/*-----------------------------------------------------------*/
/*
* Initialise the infrastructure used by the timer service task if it has not
* been initialised already.
*/
static void prvCheckForValidListAndQueue( void ) PRIVILEGED_FUNCTION;
/*
* The timer service task (daemon). Timer functionality is controlled by this
* task. Other tasks communicate with the timer service task using the
* xTimerQueue queue.
*/
static void prvTimerTask( void *pvParameters ) PRIVILEGED_FUNCTION;
/*
* Called by the timer service task to interpret and process a command it
* received on the timer queue.
*/
static void prvProcessReceivedCommands( void ) PRIVILEGED_FUNCTION;
/*
* Insert the timer into either xActiveTimerList1, or xActiveTimerList2,
* depending on if the expire time causes a timer counter overflow.
*/
static portBASE_TYPE prvInsertTimerInActiveList( xTIMER *pxTimer, portTickType xNextExpiryTime, portTickType xTimeNow, portTickType xCommandTime ) PRIVILEGED_FUNCTION;
/*
* An active timer has reached its expire time. Reload the timer if it is an
* auto reload timer, then call its callback.
*/
static void prvProcessExpiredTimer( portTickType xNextExpireTime, portTickType xTimeNow ) PRIVILEGED_FUNCTION;
/*
* The tick count has overflowed. Switch the timer lists after ensuring the
* current timer list does not still reference some timers.
*/
static void prvSwitchTimerLists( portTickType xLastTime ) PRIVILEGED_FUNCTION;
/*
* Obtain the current tick count, setting *pxTimerListsWereSwitched to pdTRUE
* if a tick count overflow occurred since prvSampleTimeNow() was last called.
*/
static portTickType prvSampleTimeNow( portBASE_TYPE *pxTimerListsWereSwitched ) PRIVILEGED_FUNCTION;
/*
* If the timer list contains any active timers then return the expire time of
* the timer that will expire first and set *pxListWasEmpty to false. If the
* timer list does not contain any timers then return 0 and set *pxListWasEmpty
* to pdTRUE.
*/
static portTickType prvGetNextExpireTime( portBASE_TYPE *pxListWasEmpty ) PRIVILEGED_FUNCTION;
/*
* If a timer has expired, process it. Otherwise, block the timer service task
* until either a timer does expire or a command is received.
*/
static void prvProcessTimerOrBlockTask( portTickType xNextExpireTime, portBASE_TYPE xListWasEmpty ) PRIVILEGED_FUNCTION;
/*-----------------------------------------------------------*/
portBASE_TYPE xTimerCreateTimerTask( void )
{
portBASE_TYPE xReturn = pdFAIL;
/* This function is called when the scheduler is started if
configUSE_TIMERS is set to 1. Check that the infrastructure used by the
timer service task has been created/initialised. If timers have already
been created then the initialisation will already have been performed. */
prvCheckForValidListAndQueue();
if( xTimerQueue != NULL )
{
#if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 )
{
/* Create the timer task, storing its handle in xTimerTaskHandle so
it can be returned by the xTimerGetTimerDaemonTaskHandle() function. */
xReturn = xTaskCreate( prvTimerTask, ( const signed char * ) "Tmr Svc", ( unsigned short ) configTIMER_TASK_STACK_DEPTH, NULL, ( ( unsigned portBASE_TYPE ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, &xTimerTaskHandle );
}
#else
{
/* Create the timer task without storing its handle. */
xReturn = xTaskCreate( prvTimerTask, ( const signed char * ) "Tmr Svc", ( unsigned short ) configTIMER_TASK_STACK_DEPTH, NULL, ( ( unsigned portBASE_TYPE ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, NULL);
}
#endif
}
configASSERT( xReturn );
return xReturn;
}
/*-----------------------------------------------------------*/
xTimerHandle xTimerCreate( const signed char * const pcTimerName, portTickType xTimerPeriodInTicks, unsigned portBASE_TYPE uxAutoReload, void *pvTimerID, tmrTIMER_CALLBACK pxCallbackFunction )
{
xTIMER *pxNewTimer;
/* Allocate the timer structure. */
if( xTimerPeriodInTicks == ( portTickType ) 0U )
{
pxNewTimer = NULL;
configASSERT( ( xTimerPeriodInTicks > 0 ) );
}
else
{
pxNewTimer = ( xTIMER * ) pvPortMalloc( sizeof( xTIMER ) );
if( pxNewTimer != NULL )
{
/* Ensure the infrastructure used by the timer service task has been
created/initialised. */
prvCheckForValidListAndQueue();
/* Initialise the timer structure members using the function parameters. */
pxNewTimer->pcTimerName = pcTimerName;
pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks;
pxNewTimer->uxAutoReload = uxAutoReload;
pxNewTimer->pvTimerID = pvTimerID;
pxNewTimer->pxCallbackFunction = pxCallbackFunction;
vListInitialiseItem( &( pxNewTimer->xTimerListItem ) );
traceTIMER_CREATE( pxNewTimer );
}
else
{
traceTIMER_CREATE_FAILED();
}
}
return ( xTimerHandle ) pxNewTimer;
}
/*-----------------------------------------------------------*/
portBASE_TYPE xTimerGenericCommand( xTimerHandle xTimer, portBASE_TYPE xCommandID, portTickType xOptionalValue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portTickType xBlockTime )
{
portBASE_TYPE xReturn = pdFAIL;
xTIMER_MESSAGE xMessage;
/* Send a message to the timer service task to perform a particular action
on a particular timer definition. */
if( xTimerQueue != NULL )
{
/* Send a command to the timer service task to start the xTimer timer. */
xMessage.xMessageID = xCommandID;
xMessage.xMessageValue = xOptionalValue;
xMessage.pxTimer = ( xTIMER * ) xTimer;
if( pxHigherPriorityTaskWoken == NULL )
{
if( xTaskGetSchedulerState() == taskSCHEDULER_RUNNING )
{
xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xBlockTime );
}
else
{
xReturn = xQueueSendToBack( xTimerQueue, &xMessage, tmrNO_DELAY );
}
}
else
{
xReturn = xQueueSendToBackFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken );
}
traceTIMER_COMMAND_SEND( xTimer, xCommandID, xOptionalValue, xReturn );
}
return xReturn;
}
/*-----------------------------------------------------------*/
#if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 )
xTaskHandle xTimerGetTimerDaemonTaskHandle( void )
{
/* If xTimerGetTimerDaemonTaskHandle() is called before the scheduler has been
started, then xTimerTaskHandle will be NULL. */
configASSERT( ( xTimerTaskHandle != NULL ) );
return xTimerTaskHandle;
}
#endif
/*-----------------------------------------------------------*/
static void prvProcessExpiredTimer( portTickType xNextExpireTime, portTickType xTimeNow )
{
xTIMER *pxTimer;
portBASE_TYPE xResult;
/* Remove the timer from the list of active timers. A check has already
been performed to ensure the list is not empty. */
pxTimer = ( xTIMER * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList );
( void ) uxListRemove( &( pxTimer->xTimerListItem ) );
traceTIMER_EXPIRED( pxTimer );
/* If the timer is an auto reload timer then calculate the next
expiry time and re-insert the timer in the list of active timers. */
if( pxTimer->uxAutoReload == ( unsigned portBASE_TYPE ) pdTRUE )
{
/* This is the only time a timer is inserted into a list using
a time relative to anything other than the current time. It
will therefore be inserted into the correct list relative to
the time this task thinks it is now, even if a command to
switch lists due to a tick count overflow is already waiting in
the timer queue. */
if( prvInsertTimerInActiveList( pxTimer, ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ), xTimeNow, xNextExpireTime ) == pdTRUE )
{
/* The timer expired before it was added to the active timer
list. Reload it now. */
xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START, xNextExpireTime, NULL, tmrNO_DELAY );
configASSERT( xResult );
( void ) xResult;
}
}
/* Call the timer callback. */
pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer );
}
/*-----------------------------------------------------------*/
static void prvTimerTask( void *pvParameters )
{
portTickType xNextExpireTime;
portBASE_TYPE xListWasEmpty;
/* Just to avoid compiler warnings. */
( void ) pvParameters;
for( ;; )
{
/* Query the timers list to see if it contains any timers, and if so,
obtain the time at which the next timer will expire. */
xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );
/* If a timer has expired, process it. Otherwise, block this task
until either a timer does expire, or a command is received. */
prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty );
/* Empty the command queue. */
prvProcessReceivedCommands();
}
}
/*-----------------------------------------------------------*/
static void prvProcessTimerOrBlockTask( portTickType xNextExpireTime, portBASE_TYPE xListWasEmpty )
{
portTickType xTimeNow;
portBASE_TYPE xTimerListsWereSwitched;
vTaskSuspendAll();
{
/* Obtain the time now to make an assessment as to whether the timer
has expired or not. If obtaining the time causes the lists to switch
then don't process this timer as any timers that remained in the list
when the lists were switched will have been processed within the
prvSampelTimeNow() function. */
xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched );
if( xTimerListsWereSwitched == pdFALSE )
{
/* The tick count has not overflowed, has the timer expired? */
if( ( xListWasEmpty == pdFALSE ) && ( xNextExpireTime <= xTimeNow ) )
{
( void ) xTaskResumeAll();
prvProcessExpiredTimer( xNextExpireTime, xTimeNow );
}
else
{
/* The tick count has not overflowed, and the next expire
time has not been reached yet. This task should therefore
block to wait for the next expire time or a command to be
received - whichever comes first. The following line cannot
be reached unless xNextExpireTime > xTimeNow, except in the
case when the current timer list is empty. */
vQueueWaitForMessageRestricted( xTimerQueue, ( xNextExpireTime - xTimeNow ) );
if( xTaskResumeAll() == pdFALSE )
{
/* Yield to wait for either a command to arrive, or the block time
to expire. If a command arrived between the critical section being
exited and this yield then the yield will not cause the task
to block. */
portYIELD_WITHIN_API();
}
}
}
else
{
( void ) xTaskResumeAll();
}
}
}
/*-----------------------------------------------------------*/
static portTickType prvGetNextExpireTime( portBASE_TYPE *pxListWasEmpty )
{
portTickType xNextExpireTime;
/* Timers are listed in expiry time order, with the head of the list
referencing the task that will expire first. Obtain the time at which
the timer with the nearest expiry time will expire. If there are no
active timers then just set the next expire time to 0. That will cause
this task to unblock when the tick count overflows, at which point the
timer lists will be switched and the next expiry time can be
re-assessed. */
*pxListWasEmpty = listLIST_IS_EMPTY( pxCurrentTimerList );
if( *pxListWasEmpty == pdFALSE )
{
xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList );
}
else
{
/* Ensure the task unblocks when the tick count rolls over. */
xNextExpireTime = ( portTickType ) 0U;
}
return xNextExpireTime;
}
/*-----------------------------------------------------------*/
static portTickType prvSampleTimeNow( portBASE_TYPE *pxTimerListsWereSwitched )
{
portTickType xTimeNow;
PRIVILEGED_DATA static portTickType xLastTime = ( portTickType ) 0U; /*lint !e956 Variable is only accessible to one task. */
xTimeNow = xTaskGetTickCount();
if( xTimeNow < xLastTime )
{
prvSwitchTimerLists( xLastTime );
*pxTimerListsWereSwitched = pdTRUE;
}
else
{
*pxTimerListsWereSwitched = pdFALSE;
}
xLastTime = xTimeNow;
return xTimeNow;
}
/*-----------------------------------------------------------*/
static portBASE_TYPE prvInsertTimerInActiveList( xTIMER *pxTimer, portTickType xNextExpiryTime, portTickType xTimeNow, portTickType xCommandTime )
{
portBASE_TYPE xProcessTimerNow = pdFALSE;
listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xNextExpiryTime );
listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer );
if( xNextExpiryTime <= xTimeNow )
{
/* Has the expiry time elapsed between the command to start/reset a
timer was issued, and the time the command was processed? */
if( ( xTimeNow - xCommandTime ) >= pxTimer->xTimerPeriodInTicks )
{
/* The time between a command being issued and the command being
processed actually exceeds the timers period. */
xProcessTimerNow = pdTRUE;
}
else
{
vListInsert( pxOverflowTimerList, &( pxTimer->xTimerListItem ) );
}
}
else
{
if( ( xTimeNow < xCommandTime ) && ( xNextExpiryTime >= xCommandTime ) )
{
/* If, since the command was issued, the tick count has overflowed
but the expiry time has not, then the timer must have already passed
its expiry time and should be processed immediately. */
xProcessTimerNow = pdTRUE;
}
else
{
vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) );
}
}
return xProcessTimerNow;
}
/*-----------------------------------------------------------*/
static void prvProcessReceivedCommands( void )
{
xTIMER_MESSAGE xMessage;
xTIMER *pxTimer;
portBASE_TYPE xTimerListsWereSwitched, xResult;
portTickType xTimeNow;
while( xQueueReceive( xTimerQueue, &xMessage, tmrNO_DELAY ) != pdFAIL ) /*lint !e603 xMessage does not have to be initialised as it is passed out, not in, and it is not used unless xQueueReceive() returns pdTRUE. */
{
pxTimer = xMessage.pxTimer;
if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE )
{
/* The timer is in a list, remove it. */
( void ) uxListRemove( &( pxTimer->xTimerListItem ) );
}
traceTIMER_COMMAND_RECEIVED( pxTimer, xMessage.xMessageID, xMessage.xMessageValue );
/* In this case the xTimerListsWereSwitched parameter is not used, but
it must be present in the function call. prvSampleTimeNow() must be
called after the message is received from xTimerQueue so there is no
possibility of a higher priority task adding a message to the message
queue with a time that is ahead of the timer daemon task (because it
pre-empted the timer daemon task after the xTimeNow value was set). */
xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched );
switch( xMessage.xMessageID )
{
case tmrCOMMAND_START :
/* Start or restart a timer. */
if( prvInsertTimerInActiveList( pxTimer, xMessage.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.xMessageValue ) == pdTRUE )
{
/* The timer expired before it was added to the active timer
list. Process it now. */
pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer );
if( pxTimer->uxAutoReload == ( unsigned portBASE_TYPE ) pdTRUE )
{
xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START, xMessage.xMessageValue + pxTimer->xTimerPeriodInTicks, NULL, tmrNO_DELAY );
configASSERT( xResult );
( void ) xResult;
}
}
break;
case tmrCOMMAND_STOP :
/* The timer has already been removed from the active list.
There is nothing to do here. */
break;
case tmrCOMMAND_CHANGE_PERIOD :
pxTimer->xTimerPeriodInTicks = xMessage.xMessageValue;
configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) );
( void ) prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow );
break;
case tmrCOMMAND_DELETE :
/* The timer has already been removed from the active list,
just free up the memory. */
vPortFree( pxTimer );
break;
default :
/* Don't expect to get here. */
break;
}
}
}
/*-----------------------------------------------------------*/
static void prvSwitchTimerLists( portTickType xLastTime )
{
portTickType xNextExpireTime, xReloadTime;
xList *pxTemp;
xTIMER *pxTimer;
portBASE_TYPE xResult;
/* Remove compiler warnings if configASSERT() is not defined. */
( void ) xLastTime;
/* The tick count has overflowed. The timer lists must be switched.
If there are any timers still referenced from the current timer list
then they must have expired and should be processed before the lists
are switched. */
while( listLIST_IS_EMPTY( pxCurrentTimerList ) == pdFALSE )
{
xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList );
/* Remove the timer from the list. */
pxTimer = ( xTIMER * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList );
( void ) uxListRemove( &( pxTimer->xTimerListItem ) );
/* Execute its callback, then send a command to restart the timer if
it is an auto-reload timer. It cannot be restarted here as the lists
have not yet been switched. */
pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer );
if( pxTimer->uxAutoReload == ( unsigned portBASE_TYPE ) pdTRUE )
{
/* Calculate the reload value, and if the reload value results in
the timer going into the same timer list then it has already expired
and the timer should be re-inserted into the current list so it is
processed again within this loop. Otherwise a command should be sent
to restart the timer to ensure it is only inserted into a list after
the lists have been swapped. */
xReloadTime = ( xNextExpireTime + pxTimer->xTimerPeriodInTicks );
if( xReloadTime > xNextExpireTime )
{
listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xReloadTime );
listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer );
vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) );
}
else
{
xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START, xNextExpireTime, NULL, tmrNO_DELAY );
configASSERT( xResult );
( void ) xResult;
}
}
}
pxTemp = pxCurrentTimerList;
pxCurrentTimerList = pxOverflowTimerList;
pxOverflowTimerList = pxTemp;
}
/*-----------------------------------------------------------*/
static void prvCheckForValidListAndQueue( void )
{
/* Check that the list from which active timers are referenced, and the
queue used to communicate with the timer service, have been
initialised. */
taskENTER_CRITICAL();
{
if( xTimerQueue == NULL )
{
vListInitialise( &xActiveTimerList1 );
vListInitialise( &xActiveTimerList2 );
pxCurrentTimerList = &xActiveTimerList1;
pxOverflowTimerList = &xActiveTimerList2;
xTimerQueue = xQueueCreate( ( unsigned portBASE_TYPE ) configTIMER_QUEUE_LENGTH, sizeof( xTIMER_MESSAGE ) );
}
}
taskEXIT_CRITICAL();
}
/*-----------------------------------------------------------*/
portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer )
{
portBASE_TYPE xTimerIsInActiveList;
xTIMER *pxTimer = ( xTIMER * ) xTimer;
/* Is the timer in the list of active timers? */
taskENTER_CRITICAL();
{
/* Checking to see if it is in the NULL list in effect checks to see if
it is referenced from either the current or the overflow timer lists in
one go, but the logic has to be reversed, hence the '!'. */
xTimerIsInActiveList = !( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) );
}
taskEXIT_CRITICAL();
return xTimerIsInActiveList;
}
/*-----------------------------------------------------------*/
void *pvTimerGetTimerID( xTimerHandle xTimer )
{
xTIMER *pxTimer = ( xTIMER * ) xTimer;
return pxTimer->pvTimerID;
}
/*-----------------------------------------------------------*/
/* This entire source file will be skipped if the application is not configured
to include software timer functionality. If you want to include software timer
functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */
#endif /* configUSE_TIMERS == 1 */
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
# Add inputs and outputs from these tool invocations to the build variables
C_SRCS += \
../BSP/bsp_stk_leds.c \
../BSP/bsp_trace.c
OBJS += \
./BSP/bsp_stk_leds.o \
./BSP/bsp_trace.o
C_DEPS += \
./BSP/bsp_stk_leds.d \
./BSP/bsp_trace.d
# Each subdirectory must supply rules for building sources it contributes
BSP/bsp_stk_leds.o: ../BSP/bsp_stk_leds.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DGCC_ARMCM3=1' '-DDEBUG_EFM=1' '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/freertos_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/gpiointerrupt/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/nvm/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/sleep/inc" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"BSP/bsp_stk_leds.d" -MT"BSP/bsp_stk_leds.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
BSP/bsp_trace.o: ../BSP/bsp_trace.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DGCC_ARMCM3=1' '-DDEBUG_EFM=1' '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/freertos_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/gpiointerrupt/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/nvm/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/sleep/inc" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"BSP/bsp_trace.d" -MT"BSP/bsp_trace.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
# Add inputs and outputs from these tool invocations to the build variables
C_SRCS += \
../CMSIS/efm32gg/system_efm32gg.c
S_SRCS += \
../CMSIS/efm32gg/startup_gcc_efm32gg.s
OBJS += \
./CMSIS/efm32gg/startup_gcc_efm32gg.o \
./CMSIS/efm32gg/system_efm32gg.o
C_DEPS += \
./CMSIS/efm32gg/system_efm32gg.d
# Each subdirectory must supply rules for building sources it contributes
CMSIS/efm32gg/%.o: ../CMSIS/efm32gg/%.s
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM Assembler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb -c -x assembler-with-cpp -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/freertos_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/gpiointerrupt/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/nvm/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/sleep/inc" '-DGCC_ARMCM3=1' '-DDEBUG_EFM=1' '-DEFM32GG990F1024=1' -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
CMSIS/efm32gg/system_efm32gg.o: ../CMSIS/efm32gg/system_efm32gg.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DGCC_ARMCM3=1' '-DDEBUG_EFM=1' '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/freertos_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/gpiointerrupt/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/nvm/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/sleep/inc" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"CMSIS/efm32gg/system_efm32gg.d" -MT"CMSIS/efm32gg/system_efm32gg.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
# Add inputs and outputs from these tool invocations to the build variables
C_SRCS += \
../Drivers/segmentlcd.c \
../Drivers/sleep.c
OBJS += \
./Drivers/segmentlcd.o \
./Drivers/sleep.o
C_DEPS += \
./Drivers/segmentlcd.d \
./Drivers/sleep.d
# Each subdirectory must supply rules for building sources it contributes
Drivers/segmentlcd.o: ../Drivers/segmentlcd.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DGCC_ARMCM3=1' '-DDEBUG_EFM=1' '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/freertos_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/gpiointerrupt/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/nvm/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/sleep/inc" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"Drivers/segmentlcd.d" -MT"Drivers/segmentlcd.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
Drivers/sleep.o: ../Drivers/sleep.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DGCC_ARMCM3=1' '-DDEBUG_EFM=1' '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/freertos_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/gpiointerrupt/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/nvm/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/sleep/inc" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"Drivers/sleep.d" -MT"Drivers/sleep.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
:1000000000000220013F0000373F0000393F0000A0
:100010003B3F00003D3F00003F3F0000353F0000F8
:10002000353F0000353F0000353F0000011E000055
:10003000433F0000353F0000251F0000611F000006
:10004000493F00004B3F00004D3F00004F3F000084
:10005000513F0000533F0000553F0000573F000054
:10006000593F00005B3F00005D3F00005F3F000024
:10007000613F0000633F0000653F0000673F0000F4
:10008000693F00006B3F00006D3F00006F3F0000C4
:10009000713F0000733F0000753F0000773F000094
:1000A000793F00007B3F00007D3F00007F3F000064
:1000B000813F0000833F0000853F0000C503000032
:1000C000893F00008B3F00008D3F00008F3F000004
:1000D000913F0000933F0000953F000000000000AA
:1000E0000000000000000000000000000000000010
:1000F0000000000000000000000000000000000000
:1001000010B5054C237833B9044810B10448AFF357
:1001100000800121217010BD7C0000200000000043
:100120005849000008B5064B1BB106480649AFF315
:1001300000800648016811B1054A02B1904708BD28
:100140000000000058490000800000207C000020D2
:1001500000000000154B002B08BF134B9D46A3F574
:10016000803A00218B460F461348144A121A04F0B5
:1001700006FA0F4B002B00D098470E4B002B00D0F7
:1001800098470020002104460D4600200C4900221B
:10019000002304F08FF904F0C3F92046294600F04B
:1001A00039FA04F091F900BF0000080000000220B5
:1001B00000000000000000007C000020002500205E
:1001C000F544000080B483B000AF0346FB714FF4E8
:1001D0006143CEF2000397F907204FEA5212F979F2
:1001E00001F01F014FF0010000FA01F143F8221065
:1001F00007F10C07BD4680BC704700BF80B483B0D8
:1002000000AF0346FB714FF46143CEF2000397F950
:1002100007204FEA5212F97901F01F014FF0010057
:1002200000FA01F102F1600243F8221007F10C0715
:10023000BD4680BC704700BF80B483B000AF0346AA
:100240003960FB7197F90730002B10DA4FF46D43DA
:10025000CEF20003FA7902F00F02A2F104013A682B
:10026000D2B24FEA4212D2B25B181A760DE04FF4C6
:100270006143CEF2000397F907103A68D2B24FEA11
:100280004212D2B25B1883F8002307F10C07BD4677
:1002900080BC704780B487B000AFF860B9607A6006
:1002A000FB6803F104734FEAC302BB68D3184FEA3B
:1002B00083037B617B697A681A6007F11C07BD467E
:1002C00080BC704780B483B000AF78604FF4805337
:1002D000C4F208037A681A6307F10C07BD4680BCB4
:1002E000704700BF80B483B000AF78604FF4805394
:1002F000C4F208034FF48052C4F20802516B7A68CA
:100300006FEA02020A405A6307F10C07BD4680BC3F
:10031000704700BF80B483B000AF78604FF4805363
:10032000C4F208034FF48052C4F20802516B7A6899
:100330000A435A6307F10C07BD4680BC704700BFF3
:1003400080B582B000AF0346FB71FB7983F00103F7
:10035000DBB2002B08D14FF48053C4F208031B68B2
:1003600003F00303002B0AD1FB79002B07D044F2E2
:10037000BC50C0F2000040F2211100F0A5F9FB7959
:10038000002B0AD04FF48050C4F208004FF0030154
:100390004FF00002FFF77EFF09E04FF48050C4F2F7
:1003A00008004FF003014FF00102FFF773FF07F160
:1003B0000807BD4680BD00BF80B500AF03F0F8FC64
:1003C00080BD00BF80B500AF4EF60453CEF20003EF
:1003D0004FF080521A604FF00000FFF7B1FF40F27B
:1003E0009803C2F200031B684FF00000194600F0AA
:1003F000CBFA00F0E7FA01F087FD02F05BFB4FF06B
:10040000000001F08BFD4FF00700FFF75BFF00F0ED
:10041000D9FA80BDB0B586B000AF40F29803C2F201
:1004200000034FF032021A604FF48640C0F204001D
:100430004FF0010100F044FC4FF001004FF00001CB
:1004400001F03EFB44F20C63C0F2000307F1040428
:100450001D460FCD0FC42B6823604FF002037B7144
:100460004FF440533B814FF00103FB6007F104035D
:10047000184600F0D9F94FF00200FFF733FF4FF0B4
:100480001F004FF0FF01FFF7D7FE4FF01F00FFF7EF
:10049000B5FE4FF01F00FFF795FE4FF000004FF044
:1004A000320100F071FA4FF00200FFF70BFF4FF03E
:1004B0000200FFF72FFF00F085FA07F11807BD468D
:1004C000B0BD00BF80B582B000AF48F2FC13C0F6EB
:1004D000E0731B687B603B46184601F007FB7B68B6
:1004E0004FEA1363102B10D17B78032B0DD148F208
:1004F000C003C4F20C0348F2C002C4F20C0212683A
:1005000022F0500242F010021A6007F10807BD46BF
:1005100080BD00BF80B584B000AF786042F2F04388
:10052000C2F20003FB6000E000BF42F2F843C2F2F7
:1005300000031B681846F9684FF0FF324FF00003C4
:1005400001F09CFE0346002BEED0F86803F052FB4E
:10055000EAE700BF80B584B000AF786040F29C034A
:10056000C2F200031B6803F1010303F00F0240F223
:100570009C03C2F200031A6040F29C03C2F2000323
:100580001B68184603F076FE42F2F043C2F2000305
:10059000FB6040F29C03C2F200031B68092B02DDE2
:1005A0004FF0310301E04FF03003FA68137040F26E
:1005B0009C03C2F20003196846F26763C6F26663E1
:1005C00083FB01234FEAA3024FEAE173D21A1346D9
:1005D0004FEA83039B184FEA4303CA1AD3B203F1CD
:1005E0003003DAB2FB685A70FB684FF000029A7071
:1005F00042F2F843C2F200031B681846F9684FF054
:10060000FF324FF0000301F059FD4FF0140002F0EB
:100610000BF9A3E780B584B004AFFFF753FF03F0F5
:1006200033FF03F0E9FD4FF0000003F06FFE4FF0E1
:10063000010003F06BFE4FF010004FF008014FF087
:10064000000201F0FDFC024642F2F843C2F2000350
:100650001A604FF0010300934FF0000301934FF035
:10066000000302934FF00003039340F25550C0F291
:10067000000044F22061C0F200014FF096024FF0FA
:10068000000302F00DF84FF0010300934FF0000358
:1006900001934FF0000302934FF00003039340F2E5
:1006A0001550C0F2000044F22C61C0F200014FF07E
:1006B00096024FF0000301F0F3FF02F0E3F84FF071
:1006C00000031846BD4680BD80B483B000AF78609B
:1006D0003960FEE780B487B000AFF860B9607A6037
:1006E000FB6803F104734FEAC302BB68D3184FEAF7
:1006F00083037B617B697A681A6007F11C07BD463A
:1007000080BC704780B582B000AF0346FB71FB79B7
:1007100083F00103DBB2002B08D14FF48053C4F205
:1007200008031B6803F00303002B0AD1FB79002B9D
:1007300007D044F23C60C0F2000040F22111FFF704
:10074000C3FFFB79002B0AD04FF48050C4F208009D
:100750004FF003014FF00002FFF7BCFF09E04FF438
:100760008050C4F208004FF003014FF00102FFF780
:10077000B1FF07F10807BD4680BD00BF80B582B05C
:1007800000AF0346FB71FB7941F23800C4F2080068
:100790004FF000011A46FFF79DFF07F10807BD461D
:1007A00080BD00BF90B587B000AF78607B68002B3C
:1007B00003D07B68B3F5004F07D944F28C60C0F2D8
:1007C00000004FF04701FFF77FFF7B683B613B690B
:1007D000B3FA83F4FC60FB68DBB2C3F11F037B61F7
:1007E0007B69184607F11C07BD4690BD80B483B0F5
:1007F00000AF78604FF48053C4F208039B6B03F0A2
:100800000103002B0AD100BF4FF48053C4F2080348
:10081000DA6B7B681340002BF6D100E000BF07F1D4
:100820000C07BD4680BC704780B584B000AF7860CF
:100830007B68002B07D144F28C60C0F200004FF0BF
:100840008201FFF741FF7B689B68002B03D07B6828
:100850009B68802B07D944F28C60C0F200004FF0F7
:100860008401FFF731FF7B68DB68062B07D944F270
:100870008C60C0F200004FF08701FFF725FF7B6816
:100880001B78002B12D07B681B7883F00103DBB24E
:10089000002B03D17B685B78002B07D144F28C607E
:1008A000C0F200004FF08A01FFF70EFF7B689B88C3
:1008B000B3F5405F10D17B689B88B3F5405F03D1EF
:1008C0007B689B7C002B07D044F28C60C0F2000058
:1008D0004FF08D01FFF7F8FE7B689B681846FFF725
:1008E00061FFF8607B681B78002B03D04FF001009C
:1008F000FFF744FF4FF00100FFF778FF4FF48053FC
:10090000C4F208037A68927C5A607B685B7843F093
:100910000803DBB21A467B689B784FEA83031A43CD
:100920007B685B7C4FEA03131A437B68DB684FEA02
:1009300043131A43FB684FEA03231A437B689B88DF
:100940001A437B681B7C4FEA83331343BB604FF42D
:100950008053C4F208034FF0FF321A634FF4805300
:10096000C4F20803BA681A607B681B78002B07D0B2
:100970004FF00100FFF7C6FE4FF00000FFF7FEFE4C
:1009800007F11007BD4680BD80B582B000AF78602A
:1009900039607B68002B07D044F28C60C0F2000005
:1009A0004FF0C901FFF790FE4FF00200FFF71EFF66
:1009B0004FF48053C4F208033A68DA6007F108077D
:1009C000BD4680BD80B500AF4FF48050C4F2080032
:1009D0004FF003014FF00102FFF77CFE4FF480500F
:1009E000C4F208004FF003014FF00002FFF772FE5F
:1009F00080BD00BF80B487B000AFF860B9607A6096
:100A0000FB6803F104734FEAC302BB68D3184FEAD3
:100A100083037B617B697A681A6007F11C07BD4616
:100A200080BC704790B587B000AF78607B68002BC2
:100A300003D07B68B3F5004F07D944F2A060C0F241
:100A400000004FF08801FFF73FFE7B683B613B6988
:100A5000B3FA83F4FC60FB68DBB2C3F11F037B6174
:100A60007B69184607F11C07BD4690BD80B483B072
:100A700000AF78607B684FF0010202FA03F318467A
:100A800007F10C07BD4680BC704700BF80B483B03F
:100A900000AF78604FF40043C4F20C035B6D03F0C9
:100AA0000103002B0AD100BF4FF40043C4F20C0332
:100AB0001A6D7B681340002BF6D100E000BF07F1F0
:100AC0000C07BD4680BC704790B585B000AF78601C
:100AD0007B684FEA131303F00F03BB60BB6803F19D
:100AE000FF33042B00F2DA8001A252F823F000BF9A
:100AF0001F0B0000390B0000530B00002F0C0000EF
:100B0000050B00004FF40043C4F20C031B6803F410
:100B1000E0334FEA933303F10103FB60CAE04FF483
:100B20000043C4F20C039B6803F00F03FB60F868FA
:100B3000FFF79CFFF860BDE04FF40043C4F20C03E4
:100B40005B6803F00F03FB60F868FFF78FFFF86046
:100B5000B0E07B6842F23042C0F20A02934228D0F1
:100B600042F23042C0F20A02934206D841F23042C9
:100B7000C0F2080293420DD04CE04FF03002C0F2B8
:100B80000C02934224D04FF48662C0F210029342CA
:100B900033D03FE04FF40043C4F20C039B6E03F0EC
:100BA000F0034FEA1313FB60F868FFF75FFFF8608C
:100BB0003CE04FF40043C4F20C039B6E03F47063FB
:100BC0004FEA1323FB60F868FFF750FFF8602DE051
:100BD0004FF40043C4F20C039B6E03F440534FEAFE
:100BE00013344FF01000FFF71DFF0346E318FB60BE
:100BF000F868FFF73BFFF86018E04FF40043C4F2D9
:100C00000C039B6E03F00303FB60F868FFF72EFFF5
:100C1000F8600BE044F2A060C0F2000040F2BF2197
:100C2000FFF752FD4FF00103FB6000BF42E07A681E
:100C30004FF4A863C0F214039A4206D04FF4AA53AB
:100C4000C0F216039A420DD01BE04FF40043C4F2E9
:100C50000C031B6F03F00303FB60F868FFF706FF4C
:100C6000F8601AE04FF40043C4F20C031B6F03F06A
:100C700030034FEA1313FB60F868FFF7F7FEF860E4
:100C80000BE044F2A060C0F2000040F2D921FFF76F
:100C90001BFD4FF00103FB6000BF0BE044F2A060BE
:100CA000C0F200004FF43871FFF70EFD4FF0010362
:100CB000FB6000BFFB68184607F11407BD4690BDF6
:100CC00090B587B000AF78600B46FB704FF0000323
:100CD0003B617B684FEA132303F00F0303F1FF33FB
:100CE000052B66D801A252F823F000BF050D0000C5
:100CF000110D00001D0D0000830D0000950D00007A
:100D0000A70D000048F20803C4F20C037B615AE00F
:100D100048F24403C4F20C037B6154E048F2400300
:100D2000C4F20C037B614FF0510000F063F80346FE
:100D3000042B47D103F0F2F904464FF02000C0F233
:100D40000400FFF7C1FE0346B4FBF3F24FF49043F7
:100D5000C0F2E8139A4235D94FF40040C4F20C00B7
:100D60004FF01E014FF00102FFF744FE48F204006D
:100D7000C4F20C004FF008014FF00102FFF73AFEF9
:100D800020E048F25803C4F20C037B614FF00103EA
:100D90003B6118E048F26003C4F20C037B614FF042
:100DA00010033B610FE048F27803C4F20C037B614F
:100DB00009E044F2A060C0F2000040F20E41FFF7EB
:100DC00083FC12E000BF7B684FEA133303F01F037C
:100DD000FB603B69002B02D03869FFF757FEFB78B8
:100DE0007869F9681A46FFF705FE07F11C07BD464A
:100DF00090BD00BF80B584B000AF78604FF00103B4
:100E0000FB737B6803F00F03BB60BB6803F1FF3328
:100E1000042B00F2B68001A252F823F0310E00003C
:100E2000750E0000C50E0000150F0000410F0000F8
:100E30004FF40043C4F20C03DB6A03F47053B3F5C0
:100E4000805F0AD0B3F5005F03D0B3F5006F08D020
:100E50000BE04FF00203FB730BE04FF00303FB7357
:100E600007E04FF00403FB7303E04FF00503FB734F
:100E700000BF92E04FF40043C4F20C039B6A03F0FE
:100E80000303022B07D0032B09D0012B0BD14FF00A
:100E90000303FB7315E04FF00203FB7311E04FF007
:100EA0000603FB730DE04FF40043C4F20C039B6A8E
:100EB00003F48033002B03D04FF00903FB7300E0F1
:100EC00000BF6AE04FF40043C4F20C039B6A03F0D6
:100ED0000C03082B07D00C2B09D0042B0BD14FF09F
:100EE0000303FB7315E04FF00203FB7311E04FF0B7
:100EF0000603FB730DE04FF40043C4F20C039B6A3E
:100F000003F48013002B03D04FF00903FB7300E0C0
:100F100000BF42E04FF40043C4F20C031B6803F02F
:100F20008053002B03D0B3F1805F04D007E04FF073
:100F30000703FB7303E04FF00803FB7300BF2CE0D3
:100F40004FF40043C4F20C03DB6A03F46033B3F5DF
:100F5000803F09D0B3F5003F0AD0B3F5004F0BD165
:100F60004FF00803FB730BE04FF00203FB7307E045
:100F70004FF00303FB7303E04FF00103FB7300BF6B
:100F80000BE044F2A060C0F2000040F25651FFF7BF
:100F90009BFB4FF00003FB7300BFFB7B184607F180
:100FA0001007BD4680BD00BF80B500AF03F002F85A
:100FB00080BD00BF80B400AF4FF40043C4F20C0307
:100FC0004FF00002C3F88420BD4680BC704700BFCC
:100FD00080B400AF4FF40043C4F20C0345F60E0298
:100FE000C3F88420BD4680BC704700BF80B582B086
:100FF00000AF4FF40043C4F20C03D3F8843003F085
:1010000001037B60FFF7E4FF4FF40043C4F20C03DD
:1010100040F2A002C2F20002128802F4AA721A621E
:1010200040F2A003C2F200031B8803F47053B3F52F
:10103000805F06D0B3F5005F15D0B3F5006F24D004
:1010400035E000BF4FF40043C4F20C03DB6A03F049
:101050008003002BF6D04FF40043C4F20C034FF092
:1010600003025A6224E000BF4FF40043C4F20C03B1
:10107000DB6A03F40073002BF6D04FF40043C4F294
:101080000C034FF004025A6212E000BF4FF4004319
:10109000C4F20C03DB6A03F00803002BF6D04FF414
:1010A0000043C4F20C034FF002025A6200E000BF9A
:1010B00040F2A003C2F200031B8803F00103002BDF
:1010C00006D14FF40043C4F20C034FF002021A623F
:1010D0007B68002B01D0FFF76DFF07F10807BD46C5
:1010E00080BD00BF80B582B000AF0346FB714FF4F6
:1010F0000043C4F20C03DB6A9AB240F2A003C2F2CE
:1011000000031A804FF46D43CEF200034FF46D429A
:10111000CEF20002126942F004021A6130BFFB797C
:10112000002B02D0FFF762FF0AE040F2A003C2F2F8
:1011300000031B8803F48063002B01D1FFF734FF09
:1011400007F10807BD4680BD80B584B000AF0346F7
:10115000FB714FF40043C4F20C03DB6A9AB240F215
:10116000A003C2F200031A804FF40043C4F20C0340
:10117000D3F8843003F00103FB60FFF729FF4FF43D
:101180000043C4F20C034FF420721A62FB68002B78
:1011900001D0FFF70FFF4FF46D43CEF200034FF481
:1011A0006D42CEF20002126942F004021A6130BFB1
:1011B000FB79002B02D0FFF719FF0AE040F2A003F1
:1011C000C2F200031B8803F48063002B01D1FFF7F8
:1011D000EBFE07F11007BD4680BD00BF80B483B0B1
:1011E00000AF4FF4C043C4F20C034AF6E8529A60D1
:1011F0004FF000037B6011E04FF4C043C4F20C03D6
:101200004FF008021A604FF4C043C4F20C034FF0D1
:101210000C021A607B6803F101037B607B68032B7F
:10122000EADD4FF4C043C4F20C034FF008021A6029
:1012300007F10C07BD4680BC704700BF90B585B074
:1012400000AFB9607B600346FB731346BB73FB7B47
:10125000052B02D8BB680F2B07D944F2B460C0F24B
:1012600000004FF0CC01FFF72FFABB7B002B2DD0F5
:101270007B68002B15D04FF4C042C4F20002F97B0A
:10128000BB684FF0010000FA03F318460B464FEA23
:10129000C3035B184FEA8303D31803F110031860EC
:1012A00014E04FF4C042C4F20002F97BBB684FF077
:1012B000010000FA03F318460B464FEAC3035B181C
:1012C0004FEA8303D31803F110035860BB68072B60
:1012D0002BD84FF4C042C4F20002F87B4FF4C04157
:1012E000C4F20001FC7B23464FEAC3031B194FEAFB
:1012F0008303CB185968BB684FEA83034FF00F0490
:1013000004FA03F36FEA03031940BC7BBB684FEA9E
:10131000830304FA03F3194303464FEAC3031B187C
:101320004FEA8303D318596036E04FF4C042C4F249
:101330000002F87B4FF4C041C4F20001FC7B23465D
:101340004FEAC3031B194FEA8303CB1803F10803C9
:101350001968BB6803F18043A3F108034FEA8303D4
:101360004FF00F0404FA03F36FEA03031940BC7B48
:10137000BB6803F18043A3F108034FEA830304FA37
:1013800003F3194303464FEAC3031B184FEA8303D1
:10139000D31803F108031960BB7B002B2DD17B68A8
:1013A000002B15D04FF4C042C4F20002F97BBB6899
:1013B0004FF0010000FA03F318460B464FEAC3034F
:1013C0005B184FEA8303D31803F11003186014E08D
:1013D0004FF4C042C4F20002F97BBB684FF0010039
:1013E00000FA03F318460B464FEAC3035B184FEAB3
:1013F0008303D31803F11003586007F11407BD46A7
:1014000090BD00BF80B487B000AFF860B9607A606B
:10141000FB6803F104734FEAC302BB68D3184FEAB9
:1014200083037B617B697A681A6007F11C07BD46FC
:1014300080BC704780B584B000AFF860B9601346D7
:10144000FB71FB68072B07DD44F2C860C0F20000A7
:1014500040F20911FFF738F9BB68272B07DD44F28A
:10146000C860C0F200004FF48871FFF72DF9FB68E7
:10147000072B00F2FB8001A252F823F09D1400001C
:10148000D7140000111500004B1500008515000051
:10149000BF150000F915000033160000BB681F2BB4
:1014A0000ADCBA68FB794AF24000C4F2080011462F
:1014B0001A46FFF7A7FFE2E0BB68A3F12003BB6079
:1014C000BA68FB794AF25000C4F2080011461A4685
:1014D000FFF798FFD3E0BB681F2B0ADCBA68FB79E3
:1014E0004AF24400C4F2080011461A46FFF78AFF88
:1014F000C5E0BB68A3F12003BB60BA68FB794AF280
:101500005400C4F2080011461A46FFF77BFFB6E00C
:10151000BB681F2B0ADCBA68FB794AF24800C4F2A8
:10152000080011461A46FFF76DFFA8E0BB68A3F15B
:101530002003BB60BA68FB794AF25800C4F2080085
:1015400011461A46FFF75EFF99E0BB681F2B0ADCC5
:10155000BA68FB794AF24C00C4F2080011461A46F8
:10156000FFF750FF8BE0BB68A3F12003BB60BA68B4
:10157000FB794AF25C00C4F2080011461A46FFF7F4
:1015800041FF7CE0BB681F2B0ADCBA68FB794AF29A
:10159000CC00C4F2080011461A46FFF733FF6EE094
:1015A000BB68A3F12003BB60BA68FB794AF2B400C0
:1015B000C4F2080011461A46FFF724FF5FE0BB683B
:1015C0001F2B0ADCBA68FB794AF2D000C4F208008B
:1015D00011461A46FFF716FF51E0BB68A3F120033E
:1015E000BB60BA68FB794AF2B800C4F20800114641
:1015F0001A46FFF707FF42E0BB681F2B0ADCBA68F8
:10160000FB794AF2D400C4F2080011461A46FFF7EB
:10161000F9FE34E0BB68A3F12003BB60BA68FB7934
:101620004AF2BC00C4F2080011461A46FFF7EAFE6F
:1016300025E0BB681F2B0ADCBA68FB794AF2D800A8
:10164000C4F2080011461A46FFF7DCFE17E0BB683B
:10165000A3F12003BB60BA68FB794AF2C000C4F270
:10166000080011461A46FFF7CDFE08E044F2C860B4
:10167000C0F2000040F28B11FFF726F800BF07F11F
:101680001007BD4680BD00BF80B586B000AFF860D2
:10169000B9607A60FB68072B07DD44F2C860C0F2CE
:1016A000000040F2A511FFF70FF8FB68072B00F2CE
:1016B000E38001A252F823F0D91600000B170000B6
:1016C0003D1700006F170000A1170000D71700009A
:1016D0000D180000431800004FF42043C4F2080323
:1016E0001B6C7B61BB686FEA03037A6913407B6103
:1016F000BA687B6813407A6913437B614FF42043D7
:10170000C4F208037A691A64BFE04FF42043C4F2BC
:1017100008035B6C7B61BB686FEA03037A69134063
:101720007B61BA687B6813407A6913437B614FF42D
:101730002043C4F208037A695A64A6E04FF42043B8
:10174000C4F208039B6C7B61BB686FEA03037A6990
:1017500013407B61BA687B6813407A6913437B61ED
:101760004FF42043C4F208037A699A648DE04FF481
:101770002043C4F20803DB6C7B61BB686FEA0303A0
:101780007A6913407B61BA687B6813407A691343B6
:101790007B614FF42043C4F208037A69DA6474E091
:1017A0004FF42043C4F20803D3F8CC307B61BB680C
:1017B0006FEA03037A6913407B61BA687B68134060
:1017C0007A6913437B614FF42043C4F208037A69BA
:1017D000C3F8CC2059E04FF42043C4F20803D3F8F7
:1017E000D0307B61BB686FEA03037A6913407B6189
:1017F000BA687B6813407A6913437B614FF42043D6
:10180000C4F208037A69C3F8D0203EE04FF42043C5
:10181000C4F20803D3F8D4307B61BB686FEA0303DA
:101820007A6913407B61BA687B6813407A69134315
:101830007B614FF42043C4F208037A69C3F8D420D3
:1018400023E04FF42043C4F20803D3F8D8307B617F
:10185000BB686FEA03037A6913407B61BA687B68EF
:1018600013407A6913437B614FF42043C4F20803A9
:101870007A69C3F8D82008E044F2C860C0F20000DA
:101880004FF4F371FEF720FF00BF07F11807BD46C4
:1018900080BD00BF80B586B000AFF860B9607A60E7
:1018A000FB68072B07DD44F2C860C0F2000040F27D
:1018B000FF11FEF709FFFB68072B00F2E38001A28E
:1018C00052F823F0E518000017190000491900002C
:1018D0007B190000AD190000E3190000191A00007F
:1018E0004F1A00004FF42043C4F208031B6D7B61C4
:1018F000BB686FEA03037A6913407B61BA687B684F
:1019000013407A6913437B614FF42043C4F2080308
:101910007A691A65B7E04FF42043C4F208035B6D9F
:101920007B61BB686FEA03037A6913407B61BA6825
:101930007B6813407A6913437B614FF42043C4F200
:1019400008037A695A659EE04FF42043C4F2080305
:101950009B6D7B61BB686FEA03037A6913407B610F
:10196000BA687B6813407A6913437B614FF4204364
:10197000C4F208037A699A6585E04FF42043C4F203
:101980000803DB6D7B61BB686FEA03037A69134070
:101990007B61BA687B6813407A6913437B614FF4BB
:1019A0002043C4F208037A69DA656CE04FF42043FF
:1019B000C4F20803D3F8B4307B61BB686FEA030359
:1019C0007A6913407B61BA687B6813407A69134374
:1019D0007B614FF42043C4F208037A69C3F8B42052
:1019E00051E04FF42043C4F20803D3F8B8307B61D0
:1019F000BB686FEA03037A6913407B61BA687B684E
:101A000013407A6913437B614FF42043C4F2080307
:101A10007A69C3F8B82036E04FF42043C4F20803D3
:101A2000D3F8BC307B61BB686FEA03037A6913406B
:101A30007B61BA687B6813407A6913437B614FF41A
:101A40002043C4F208037A69C3F8BC201BE04FF4BA
:101A50002043C4F20803D3F8C0307B61BB686FEA4F
:101A600003037A6913407B61BA687B6813407A6923
:101A700013437B614FF42043C4F208037A69C3F82F
:101A8000C02000E000BF07F11807BD4680BD00BFC1
:101A900080B487B000AFF860B9607A60FB6803F18A
:101AA00004734FEAC302BB68D3184FEA83037B6118
:101AB0007B697A681A6007F11C07BD4680BC7047D5
:101AC00080B582B000AF02460B46FA71BB71FA795D
:101AD000BB794FF42040C4F20C0011461A46FFF7C0
:101AE000D7FF07F10807BD4680BD00BF80B584B0B1
:101AF00000AF78607B68002B07D144F2DC60C0F255
:101B000000004FF03F01FEF7DFFD4FF6D073CEF23D
:101B10000F031B69DBB203F03F03DAB27B681A7074
:101B20004FF6D073CEF20F039B69DBB223F00F03A5
:101B3000FB734FF6D073CEF20F03DB6903F0F003B3
:101B40004FEA1313DAB2FB7B1343FB737B68FA7B18
:101B50005A7007F11007BD4680BD00BF80B584B044
:101B600000AF78604FF00003FB607B6803F0070371
:101B7000002B05D07B6823F0070303F108037B608B
:101B800000F0BEFE42F2D433C2F200031B68002B09
:101B900008D1214B23F007031A4642F2D433C2F294
:101BA00000031A6042F2D033C2F200031A687B6865
:101BB000D21842F21F339A4225D842F2D033C2F2F1
:101BC00000031A687B68D21842F2D033C2F20003D5
:101BD0001B689A4217D942F2D433C2F200031A6842
:101BE00042F2D033C2F200031B68D318FB6042F20A
:101BF000D033C2F200031A687B68D21842F2D033A5
:101C0000C2F200031A6000F08DFEFB68184607F16F
:101C10001007BD4680BD00BFB000002080B483B077
:101C200000AF786007F10C07BD4680BC704700BF6D
:101C300080B483B000AF78607B6803F108027B68F2
:101C40005A607B684FF0FF329A607B6803F10802AC
:101C50007B68DA607B6803F108027B681A617B6845
:101C60004FF000021A6007F10C07BD4680BC7047B8
:101C700080B483B000AF78607B684FF000021A61D7
:101C800007F10C07BD4680BC704700BF80B485B02B
:101C900000AF786039607B685B68FB603B68FA681E
:101CA0005A60FB689A683B689A60FB689B683A6870
:101CB0005A60FB683A689A603B687A681A617B6888
:101CC0001B6803F101027B681A6007F11407BD4627
:101CD00080BC704780B485B000AF786039603B68E5
:101CE0001B68BB60BB68B3F1FF3F03D17B681B6916
:101CF000FB600DE07B6803F10803FB6002E0FB681A
:101D00005B68FB60FB685B681A68BB689A42F6D93F
:101D1000FB685A683B685A603B685B683A689A603F
:101D20003B68FA689A60FB683A685A603B687A6870
:101D30001A617B681B6803F101027B681A6007F176
:101D40001407BD4680BC704780B485B000AF786092
:101D50007B685B687A6892689A607B689B687A683F
:101D600052685A607B681B69FB60FB685A687B6835
:101D70009A4203D17B689A68FB685A607B684FF08F
:101D800000021A61FB681B6803F1FF32FB681A60EE
:101D9000FB681B68184607F11407BD4680BC7047F6
:101DA00080B485B000AFF860B9607A60FB68A3F1D9
:101DB0000403FB60FB684FF080721A60FB68A3F1BC
:101DC0000403FB60BA68FB681A60FB68A3F10403B4
:101DD000FB60FB684FF000021A60FB68A3F114037C
:101DE000FB607A68FB681A60FB68A3F12003FB6064
:101DF000FB68184607F11407BD4680BC704700BF5A
:101E0000064B19680868B0E8F00F80F309884FF0B6
:101E1000000080F311884EF00D0E7047D82300208B
:101E200003480068006880F3088862B600DF00BFDE
:101E300008ED00E080B500AF4EF62053CEF200036F
:101E40004EF62052CEF20002126842F47F021A606F
:101E50004EF62053CEF200034EF62052CEF2000290
:101E6000126842F07F421A60FEF7D4FA40F2000393
:101E7000C2F200034FF000021A60FFF7D1FF4FF0EB
:101E80000003184680BD00BF80B400AF4EF6045377
:101E9000CEF200034FF080521A60BFF34F8FBFF3B2
:101EA0006F8FBD4680BC704780B500AF00F02CF846
:101EB00040F20003C2F200031B6803F1010240F28A
:101EC0000003C2F200031A60BFF34F8FBFF36F8F9E
:101ED00080BD00BF80B500AF40F20003C2F2000336
:101EE0001B6803F1FF3240F20003C2F200031A60E4
:101EF00040F20003C2F200031B68002B03D14FF035
:101F0000000000F00BF880BDEFF311804FF0BF012F
:101F100081F3118870474FF00003184680F3118851
:101F2000704700BFEFF309800C4B1A6820E9F00FEF
:101F300010602DE908404FF0BF0080F3118800F0D9
:101F4000C7FE4FF0000080F31188BDE80840196813
:101F50000868B0E8F00F80F309887047D8230020A4
:101F600080B500AFFFF7D0FF00F0A4FD0346002BC3
:101F700006D04EF60453CEF200034FF080521A60A2
:101F80004FF00000FFF7CAFF80BD00BF80B584B0EE
:101F900000AF786039607B68FB60FFF785FFFB6806
:101FA0001A68FB68DB6BF968096C01FB03F3D21854
:101FB000FB685A60FB684FF000029A63FB681A687E
:101FC000FB689A60FB681A68FB68DB6B03F1FF3300
:101FD000F968096C01FB03F3D218FB68DA60FB684F
:101FE0004FF0FF325A64FB684FF0FF329A643B684F
:101FF000002B0FD1FB681B69002B17D0FB6803F186
:102000001003184600F02AFF0346012B0ED1FFF7FC
:102010003BFF0BE0FB6803F110031846FFF708FED7
:10202000FB6803F124031846FFF702FEFFF752FF97
:102030004FF00103184607F11007BD4680BD00BFF1
:1020400080B588B000AFF860B9601346FB714FF0FF
:102050000003FB61FB68002B29D04FF04C00FFF719
:102060007DFDB861BB69002B21D0FB68BA6802FB1B
:1020700003F303F101037B617869FFF76FFD02460B
:10208000BB691A60BB691B68002B0DD0BB69FA687D
:10209000DA63BB69BA681A64B8694FF00101FFF7E7
:1020A00075FFBB69FB6102E0B869FFF7B7FDFB692B
:1020B000184607F12007BD4680BD00BF80B588B037
:1020C00000AFF860B9607A603B604FF00003FB61DD
:1020D000FB68BB6100E000BFFFF7E6FEBB699A6BDF
:1020E000BB69DB6B9A4202D33B68022B18D1B869FB
:1020F000B9683A6800F088F9BB695B6A002B0AD0BE
:10210000BB6903F12403184600F0A8FE0346012B27
:1021100001D1FFF7B9FEFFF7DDFE4FF001035DE0EF
:102120007B68002B04D1FFF7D5FE4FF0000355E08C
:10213000FB69002B07D107F11003184600F0F0FEF1
:102140004FF00103FB61FFF7C5FE00F0D9FBFFF77D
:10215000ABFEBB695B6CB3F1FF3F03D1BB694FF0D2
:1021600000025A64BB699B6CB3F1FF3F03D1BB69AA
:102170004FF000029A64FFF7ADFE07F1100207F17D
:1021800004031046194600F0E3FE0346002B1ED15F
:10219000B86900F039FA0346002B12D0BB6903F18D
:1021A00010027B681046194600F0F2FDB86900F095
:1021B000C1F900F0B7FB0346002B8CD1FFF764FE9A
:1021C00089E7B86900F0B6F900F0ACFB83E7B869BD
:1021D00000F0B0F900F0A6FB4FF00003184607F13D
:1021E0002007BD4680BD00BF80B588B000AFF86055
:1021F000B9607A603B60FB68BB61FFF785FE786180
:10220000BB699A6BBB69DB6B9A4202D33B68022BBA
:1022100028D1B869B9683A6800F0F6F8BB699B6CD8
:10222000B3F1FF3F14D1BB695B6A002B16D0BB69C9
:1022300003F12403184600F011FE0346002B0DD0D5
:102240007B68002B0AD07B684FF001021A6005E022
:10225000BB699B6C03F10102BB699A644FF00103F7
:10226000FB6102E04FF00003FB617869FFF756FE67
:10227000FB69184607F12007BD4680BD80B58AB0CE
:1022800000AFF860B9607A603B604FF000037B629A
:10229000FB683B6200E000BFFFF706FE3B6A9B6BFA
:1022A000002B3FD03B6ADB68FB61386AB96800F0FD
:1022B00019F93B68002B1ED13B6A9B6B03F1FF327F
:1022C0003B6A9A633B6A1B68002B04D101F020F83B
:1022D00002463B6A5A603B6A1B69002B1DD03B6A71
:1022E00003F11003184600F0B9FD0346012B14D189
:1022F000FFF7CAFD11E03B6AFA69DA603B6A5B6A84
:10230000002B0AD03B6A03F12403184600F0A6FD17
:102310000346002B01D0FFF7B7FDFFF7DBFD4FF0C1
:1023200001036BE07B68002B04D1FFF7D3FD4FF076
:10233000000363E07B6A002B07D107F11403184602
:1023400000F0EEFD4FF001037B62FFF7C3FD00F0EC
:10235000D7FAFFF7A9FD3B6A5B6CB3F1FF3F03D1EE
:102360003B6A4FF000025A643B6A9B6CB3F1FF3F3B
:1023700003D13B6A4FF000029A64FFF7ABFD07F10F
:10238000140207F104031046194600F0E1FD03466C
:10239000002B2CD1386A00F01DF90346002B20D009
:1023A0003B6A1B68002B08D1FFF77EFD3B6A5B6828
:1023B000184600F0E1FFFFF78DFD3B6A03F12402B0
:1023C0007B681046194600F0E3FC386A00F0B2F86A
:1023D00000F0A8FA0346002B7FF45DAFFFF754FD31
:1023E00059E7386A00F0A6F800F09CFA53E7386A1B
:1023F00000F0A0F800F096FA4FF00003184607F13D
:102400002807BD4680BD00BF80B584B000AFF8602E
:10241000B9607A60FB681B6C002B0DD1FB681B68F0
:10242000002B55D1FB685B68184601F019F8FB6872
:102430004FF000025A604BE07B68002B1AD1FB681A
:102440009A68FB681B6C1046B9681A4602F08EF851
:10245000FB689A68FB681B6CD218FB689A60FB6883
:102460009A68FB685B689A4232D3FB681A68FB681B
:102470009A602DE0FB68DA68FB681B6C1046B9684F
:102480001A4602F073F8FB68DA68FB681B6CC3F14C
:102490000003D218FB68DA60FB68DA68FB681B6827
:1024A0009A4208D2FB685A68FB681B6CC3F10003B0
:1024B000D218FB68DA607B68022B09D1FB689B6B42
:1024C000002B05D0FB689B6B03F1FF32FB689A631E
:1024D000FB689B6B03F10102FB689A6307F110072D
:1024E000BD4680BD80B582B000AF786039607B6842
:1024F0001B68002B19D07B68DA687B681B6CD218CC
:102500007B68DA607B68DA687B685B689A4203D331
:102510007B681A687B68DA607B68DA687B681B6CAA
:10252000386811461A4602F021F807F10807BD463F
:1025300080BD00BF80B582B000AF7860FFF7B4FC0B
:1025400014E07B685B6A002B15D07B6803F12403E1
:10255000184600F083FC0346002B01D000F044FD38
:102560007B689B6C03F1FF327B689A647B689B6C91
:10257000002BE6DC00E000BF7B684FF0FF329A647E
:10258000FFF7A8FCFFF790FC14E07B681B69002BA9
:1025900015D07B6803F11003184600F05FFC03467A
:1025A000002B01D000F020FD7B685B6C03F1FF3253
:1025B0007B685A647B685B6C002BE6DC00E000BF44
:1025C0007B684FF0FF325A64FFF784FC07F108077D
:1025D000BD4680BD80B584B000AF7860FFF764FC75
:1025E0007B689B6B002B03D14FF00103FB6002E083
:1025F0004FF00003FB60FFF76DFCFB68184607F126
:102600001007BD4680BD00BF80B584B000AF7860C4
:10261000FFF74AFC7B689A6B7B68DB6B9A4203D1BD
:102620004FF00103FB6002E04FF00003FB60FFF797
:1026300051FCFB68184607F11007BD4680BD00BF7E
:1026400080B584B000AF786039607B68FB60FFF7CD
:102650002BFCFB685B6CB3F1FF3F03D1FB684FF0D1
:1026600000025A64FB689B6CB3F1FF3F03D1FB6827
:102670004FF000029A64FFF72DFCFB689B6B002B68
:1026800006D1FB6803F124031846396800F0BCFB4F
:10269000F868FFF74FFF07F11007BD4680BD00BF88
:1026A00080B58AB002AFF860B9603B601346FB802A
:1026B000FB881846396B00F0E3FDB861BB69002B5D
:1026C00000F09480BB691A6BFB8803F1FF334FEA7B
:1026D0008303D3187B617B6923F007037B61FB884D
:1026E0000093B869B968BA6A7B6B00F093FC7869AB
:1026F000F9683A68FFF754FB0246BB691A60FB6A47
:10270000002B02D0FB6ABA691A60FFF7CDFB42F2D8
:102710008843C2F200031B6803F1010242F28843BE
:10272000C2F200031A6042F2D833C2F200031B68FF
:10273000002B0FD142F2D833C2F20003BA691A60FB
:1027400042F28843C2F200031B68012B18D100F04B
:10275000B1FC15E042F29443C2F200031B68002B67
:102760000ED142F2D833C2F200031B68DA6ABB6AA8
:102770009A4205D842F2D833C2F20003BA691A600D
:1027800042F2A843C2F200031B6803F1010242F2C5
:10279000A843C2F200031A60BB69DA6A42F29043AE
:1027A000C2F200031B689A4206D9BB69DA6A42F298
:1027B0009043C2F200031A60BB69DA6A13464FEA1B
:1027C00083039B184FEA830342F2DC32C2F2000219
:1027D0009A18BB6903F1040310461946FFF756FA2D
:1027E0004FF00103FB61FFF775FB02E04FF0FF3391
:1027F000FB61FB69012B11D142F29443C2F2000349
:102800001B68002B0AD042F2D833C2F200031B68C7
:10281000DA6ABB6A9A4201D2FFF736FBFB691846B7
:1028200007F12007BD4680BD80B584B000AF786059
:102830004FF00003FB607B68002B19D000F060F8BC
:1028400042F28C43C2F200031A687B68D318BB6063
:1028500042F2D833C2F200031B6803F104031846A6
:10286000FFF772FAB86800F0C5FC00F05BF8F8609A
:10287000FB68002B01D1FFF707FB07F11007BD46EE
:1028800080BD00BF80B586B004AF4FF00003009359
:102890004FF0000301934FF0000302934FF0000349
:1028A000039343F20100C0F2000044F2F461C0F26D
:1028B00000014FF08C024FF00003FFF7F1FE78604B
:1028C0007B68012B02D100F013FE78607B68012B3E
:1028D00011D1FFF719FB42F29443C2F200034FF00B
:1028E00001021A6042F28C43C2F200034FF0000270
:1028F0001A60FFF79FFA07F10807BD4680BD00BFC9
:1029000080B400AF42F29843C2F200031B6803F1A7
:10291000010242F29843C2F200031A60BD4680BC35
:10292000704700BF80B584B000AF4FF00003FB607C
:102930004FF00003BB60FFF7B7FA42F29843C2F2D0
:1029400000031B6803F1FF3242F29843C2F2000316
:102950001A6042F29843C2F200031B68002B40F059
:102960008D8042F28843C2F200031B68002B00F006
:10297000858043E042F24843C2F20003DB68DB6833
:102980007B607B6803F118031846FFF7DDF97B686D
:1029900003F104031846FFF7D7F97B68DA6A42F2BD
:1029A0009043C2F200031B689A4206D97B68DA6A38
:1029B00042F29043C2F200031A607B68DA6A13465F
:1029C0004FEA83039B184FEA830342F2DC32C2F2E0
:1029D00000029A187B6803F1040310461946FFF7BA
:1029E00055F97B68DA6A42F2D833C2F200031B68F9
:1029F000DB6A9A4202D34FF00103BB6042F24843C4
:102A0000C2F200031B68002BB4D142F29C43C2F215
:102A100000031B68002B1BD013E000F04BF80346AB
:102A2000002B02D04FF00103BB6042F29C43C2F284
:102A300000031B6803F1FF3242F29C43C2F2000321
:102A40001A6042F29C43C2F200031B68002BE4D1DF
:102A5000BB68012B06D042F2A043C2F200031B6800
:102A6000012B0BD14FF00103FB6042F2A043C2F2F5
:102A700000034FF000021A60FFF706FAFFF72AFA88
:102A8000FB68184607F11007BD4680BD80B582B0CF
:102A900000AFFFF709FA42F28C43C2F200031B6851
:102AA0007B60FFF717FA7B68184607F10807BD46F9
:102AB00080BD00BF80B586B000AF4FF000037B61E2
:102AC00042F29843C2F200031B68002B40F0EE80F4
:102AD00042F28C43C2F200031B6803F1010242F28E
:102AE0008C43C2F200031A6042F28C43C2F200032C
:102AF0001B683B613B69002B47D142F24043C2F265
:102B000000031B68FB6042F24443C2F200031A68F0
:102B100042F24043C2F200031A6042F24443C2F25E
:102B20000003FA681A6042F2A443C2F200031B6871
:102B300003F1010242F2A443C2F200031A6042F21E
:102B40004043C2F200031B681B68002B02D14FF008
:102B5000010301E04FF00003002B07D040F2040313
:102B6000C2F200034FF0FF321A600EE042F240431F
:102B7000C2F200031B68DB68DB68BB60BB685A6895
:102B800040F20403C2F200031A6040F20403C2F2EE
:102B900000031B683A699A4270D300E000BF42F21A
:102BA0004043C2F200031B681B68002B02D14FF0A8
:102BB000010301E04FF00003002B07D040F20403B3
:102BC000C2F200034FF0FF321A6057E042F2404376
:102BD000C2F200031B68DB68DB68BB60BB685B6834
:102BE0007B603A697B689A4206D240F20403C2F2E3
:102BF00000037A681A6041E0BB6803F104031846D9
:102C0000FFF7A2F8BB689B6A002B05D0BB6803F1F5
:102C100018031846FFF798F8BB68DA6A42F2904347
:102C2000C2F200031B689A4206D9BB68DA6A42F214
:102C30009043C2F200031A60BB68DA6A13464FEA97
:102C400083039B184FEA830342F2DC32C2F2000294
:102C50009A18BB6803F1040310461946FFF716F8EB
:102C6000BB68DA6A42F2D833C2F200031B68DB6A3F
:102C70009A4293D34FF001037B618FE742F2D8333E
:102C8000C2F200031B68D96A42F2DC32C2F20002CF
:102C90000B464FEA83035B184FEA8303D3181B6884
:102CA000012B0FD94FF001037B610BE042F29C43F3
:102CB000C2F200031B6803F1010242F29C43C2F21C
:102CC00000031A607B69184607F11807BD4680BDEE
:102CD00080B483B000AF42F29843C2F200031B6895
:102CE000002B13D042F2A043C2F200034FF00102C6
:102CF0001A6048E042F29043C2F200031B6803F1FD
:102D0000FF3242F29043C2F200031A6042F2904353
:102D1000C2F20003196842F2DC32C2F200020B4632
:102D20004FEA83035B184FEA8303D3181B68002B19
:102D3000E0D042F29043C2F200031A6813464FEA11
:102D400083039B184FEA830342F2DC32C2F2000293
:102D50009B187B607B685B685A687B685A607B68FD
:102D60005A687B6803F108039A4204D17B685B6868
:102D70005A687B685A607B685B68DA6842F2D833CD
:102D8000C2F200031A6007F10C07BD4680BC704711
:102D900080B584B000AF7860396042F2D833C2F2B7
:102DA00000031B6803F1180378681946FEF792FFC9
:102DB00042F2D833C2F200031B6803F10403184641
:102DC000FEF7C2FF3B68B3F1FF3F0ED142F2D833AA
:102DD000C2F200031B6803F1040342F27440C2F222
:102DE00000001946FEF752FF0AE042F28C43C2F29D
:102DF00000031A683B68D318FB60F86800F0FAF922
:102E000007F11007BD4680BD80B584B000AF786083
:102E1000396042F2D833C2F200031B6803F1180391
:102E200078681946FEF732FF42F2D833C2F2000347
:102E30001B6803F104031846FEF786FF42F28C4339
:102E4000C2F200031A683B68D318FB60F86800F010
:102E5000D1F907F11007BD4680BD00BF80B584B031
:102E600000AF78607B68DB68DB68BB60BB6803F140
:102E700018031846FEF768FF42F29843C2F20003B7
:102E80001B68002B2AD1BB6803F104031846FEF728
:102E90005BFFBB68DA6A42F29043C2F200031B6830
:102EA0009A4206D9BB68DA6A42F29043C2F2000342
:102EB0001A60BB68DA6A13464FEA83039B184FEA2D
:102EC000830342F2DC32C2F200029A18BB6803F1BB
:102ED000040310461946FEF7D9FE09E0BB6803F16A
:102EE000180342F24840C2F200001946FEF7CEFE37
:102EF000BB68DA6A42F2D833C2F200031B68DB6AAD
:102F00009A4203D34FF00103FB6002E04FF000034D
:102F1000FB60FB68184607F11007BD4680BD00BF87
:102F200080B483B000AF786042F2A443C2F20003E1
:102F30001A687B681A6042F28C43C2F200031A6876
:102F40007B685A6007F10C07BD4680BC704700BF24
:102F500080B584B000AF78603960FEF7A5FF42F21B
:102F60008C43C2F200031B68BB603B681B68B3F173
:102F7000FF3F03D14FF00003FB602CE07B681A6831
:102F800042F2A443C2F200031B689A4208D07B6855
:102F90005A68BB689A4203D84FF00103FB601AE0FD
:102FA0007B685B68BA68D21A3B681B689A420FD28A
:102FB0003B681A687B685968BB68CB1AD2183B68B3
:102FC0001A607868FFF7ACFF4FF00003FB6002E087
:102FD0004FF00103FB60FEF77DFFFB68184607F129
:102FE0001007BD4680BD00BF80B400AF42F2A043D1
:102FF000C2F200034FF001021A60BD4680BC704768
:1030000080B582B000AF786000F0A6F8FDF7D4F983
:10301000FAE700BF80B586B000AFF860B9607A60AB
:103020003B604FF000037B6113E0BA687B69D31803
:103030001A78F9687B69CB1803F130031A71BA6802
:103040007B69D3181B78002B07D07B6903F1010340
:103050007B617B69092BE8D900E000BFFB684FF07A
:10306000000283F83D207B68022B02D94FF0020357
:103070007B60FB687A68DA62FB687A681A64FB68CE
:1030800003F104031846FEF7F3FDFB6803F1180390
:103090001846FEF7EDFDFB68FA681A617B68C3F11C
:1030A0000302FB689A61FB68FA685A6207F1180725
:1030B000BD4680BD80B582B000AF4FF000037B609D
:1030C00012E07A6813464FEA83039B184FEA8303A2
:1030D00042F2DC32C2F200029B181846FEF7A8FD4D
:1030E0007B6803F101037B607B68022BE9D942F224
:1030F0001840C2F20000FEF79BFD42F22C40C2F2E3
:103100000000FEF795FD42F24840C2F20000FEF7D3
:103110008FFD42F25C40C2F20000FEF789FD42F2F0
:103120007440C2F20000FEF783FD42F24043C2F257
:10313000000342F21842C2F200021A6042F2444313
:10314000C2F2000342F22C42C2F200021A6007F1FE
:103150000807BD4680BD00BF80B582B000AF3DE02E
:10316000FFF7CEFB42F25C43C2F200031B68002B68
:1031700014BF00230123DBB27B60FFF7D3FB7B6826
:10318000002B2BD1FEF790FE42F25C43C2F200030B
:10319000DB68DB683B603B6803F104031846FEF71D
:1031A000D3FD42F28843C2F200031B6803F1FF32F1
:1031B00042F28843C2F200031A6042F27043C2F244
:1031C00000031B6803F1FF3242F27043C2F20003B6
:1031D0001A60FEF77FFE386800F08AF842F270430A
:1031E000C2F200031B68002BBAD107F10807BD46E5
:1031F00080BD00BF80B582B000AF786042F2D833A6
:10320000C2F200031B687A685A6042F28C43C2F231
:1032100000031B687A689A4210D242F24443C2F219
:1032200000031A6842F2D833C2F200031B6803F1AC
:10323000040310461946FEF74DFD1DE042F24043DF
:10324000C2F200031A6842F2D833C2F200031B68CC
:1032500003F1040310461946FEF73CFD40F2040357
:10326000C2F200031B687A689A4205D240F2040356
:10327000C2F200037A681A6007F10807BD4680BDF4
:1032800080B584B000AF03463960FB804FF0440046
:10329000FEF764FCF860FB68002B23D03B68002B32
:1032A00007D1FB884FEA83031846FEF757FC034615
:1032B00000E03B68FA681363FB681B6B002B06D1C8
:1032C000F868FEF7ABFC4FF00003FB600AE0FB6818
:1032D0001A6BFB884FEA830310464FF0A5011A468C
:1032E00001F04DF9FB68184607F11007BD4680BD97
:1032F00080B582B000AF78607B681B6B1846FEF724
:103300008DFC7868FEF78AFC07F10807BD4680BD92
:1033100080B483B000AF42F2D833C2F200031B681E
:103320007B607B68184607F10C07BD4680BC704780
:1033300080B483B000AF42F29443C2F200031B6832
:10334000002B03D14FF000037B600DE042F2984365
:10335000C2F200031B68002B03D14FF001037B6016
:1033600002E04FF002037B607B68184607F10C0710
:10337000BD4680BC704700BF80B584B000AF7860A8
:103380007B68FB607B68002B66D0FB68DA6A42F2E0
:10339000D833C2F200031B68DB6A9A425CD242F265
:1033A000D833C2F200031B68DB6AC3F10302FB6877
:1033B0009A61FB685969FB68DA6A13464FEA83032E
:1033C0009B184FEA830342F2DC32C2F200029B18E0
:1033D000994202D14FF0010301E04FF00003002BAE
:1033E00032D0FB6803F104031846FEF7ADFC42F24D
:1033F000D833C2F200031B68DA6AFB68DA62FB6842
:10340000DA6A42F29043C2F200031B689A4206D97C
:10341000FB68DA6A42F29043C2F200031A60FB686A
:10342000DA6A13464FEA83039B184FEA830342F29A
:10343000DC32C2F200029A18FB6803F10403104662
:103440001946FEF723FC07E042F2D833C2F200032C
:103450001B68DA6AFB68DA6207F11007BD4680BDB7
:1034600080B584B000AF78607B68FB607B68002B20
:1034700039D0FB68DA6AFB681B6C9A4233D0FB6870
:1034800003F104031846FEF75FFCFB681A6CFB6847
:10349000DA62FB68DB6AC3F10302FB689A61FB68CE
:1034A000DA6A42F29043C2F200031B689A4206D9DC
:1034B000FB68DA6A42F29043C2F200031A60FB68CA
:1034C000DA6A13464FEA83039B184FEA830342F2FA
:1034D000DC32C2F200029A18FB6803F104031046C2
:1034E0001946FEF7D3FB07F11007BD4680BD00BFAC
:1034F00080B586B004AF4FF000037B6000F086FA21
:1035000042F2DC43C2F200031B68002B1AD04FF0DA
:10351000030300934FF0000301934FF00003029365
:103520004FF00003039343F26D60C0F2000044F2D9
:10353000FC61C0F200014FF08C024FF00003FFF776
:10354000AFF878607B68184607F10807BD4680BD74
:1035500080B588B000AFF860B9607A603B604FF02A
:103560000003FB6142F2DC43C2F200031B68002B44
:103570003DD0BB683B617B687B61FB68BB613B689E
:10358000002B25D1FFF7D4FE0346012B0FD142F2C9
:10359000DC43C2F200031A6807F110031046194613
:1035A000BA6A4FF00003FEF789FDF8611FE042F2AE
:1035B000DC43C2F200031A6807F1100310461946F3
:1035C0004FF000024FF00003FEF778FDF8610EE0C7
:1035D00042F2DC43C2F200031A6807F110031046FE
:1035E00019463A684FF00003FEF7FEFDF861FB69EB
:1035F000184607F12007BD4680BD00BF80B586B0E4
:1036000002AF7860396042F2D443C2F200031B6813
:10361000DB68DB68FB60FB6803F104031846FEF718
:1036200093FBFB68DB69012B18D1FB689A697B6807
:10363000D318F86819463A687B6800F0B9F8034671
:10364000012B0BD14FF000030093F8684FF00001FD
:103650007A684FF00003FFF77BFFB860FB685B6A96
:10366000F868984707F11007BD4680BD80B584B063
:1036700000AF786007F10803184600F043F8F860DF
:10368000BB68F868194600F003F800F0DBF8F1E7D2
:1036900080B584B000AF78603960FFF731F907F189
:1036A0000803184600F058F8F860BB68002B21D1D9
:1036B0003B68002B0AD17A68FB689A4206D8FFF76C
:1036C00031F97868F968FFF799FF17E042F2DC43B7
:1036D000C2F200031A687968FB68CB1A10461946D3
:1036E000FEF7AEFFFFF71EF90346002B05D1FEF7EC
:1036F000CBFB02E0FFF716F900E000BF07F110076F
:10370000BD4680BD80B485B000AF786042F2D4433E
:10371000C2F200031B681B68002B14BF00230123A7
:10372000DBB21A467B681A607B681B68002B08D1E5
:1037300042F2D443C2F200031B68DB681B68FB60E3
:1037400002E04FF00003FB60FB68184607F1140726
:10375000BD4680BC704700BF80B584B000AF7860C4
:10376000FFF794F9F86042F2E043C2F200031B68ED
:10377000FA689A420CD242F2E043C2F200031B689C
:10378000184600F0D5F87B684FF001021A6003E09C
:103790007B684FF000021A6042F2E043C2F200037D
:1037A000FA681A60FB68184607F11007BD4680BD2D
:1037B00080B586B000AFF860B9607A603B604FF0CA
:1037C00000037B61FB68BA685A60FB68FA681A619B
:1037D000BA687B689A4217D87A683B68D21AFB6845
:1037E0009B699A4203D34FF001037B6124E042F2CC
:1037F000D843C2F200031A68FB6803F104031046C1
:103800001946FEF767FA17E07A683B689A4207D2D2
:10381000BA683B689A4203D34FF001037B610BE027
:1038200042F2D443C2F200031A68FB6803F10403B6
:1038300010461946FEF74EFA7B69184607F118073D
:10384000BD4680BD80B58AB002AF5AE03B69FB61DE
:10385000FB695B69002B05D0FB6903F10403184683
:10386000FEF772FA07F104031846FFF775FFB86117
:10387000BB68032B42D801A252F823F08D38000018
:10388000FD380000D9380000F5380000FA68FB69FF
:103890009B69D218FB68F8691146BA69FFF788FF7F
:1038A0000346012B2CD1FB695B6AF8699847FB69D9
:1038B000DB69012B24D1FA68FB699B69D3184FF0AF
:1038C00000020092F8694FF000011A464FF0000321
:1038D000FFF73EFE786113E0FA68FB699A61FB69C5
:1038E0009A69BB69D318F8691946BA69BB69FFF7C9
:1038F0005FFF06E0F869FEF791F902E000BF00E023
:1039000000BF42F2DC43C2F200031A6807F1080369
:10391000104619464FF000024FF00003FEF7AEFCD0
:103920000346002B92D107F12007BD4680BD00BFA2
:1039300080B58AB002AF786045E042F2D443C2F26B
:1039400000031B68DB681B68FB6142F2D443C2F2D0
:1039500000031B68DB68DB68BB61BB6903F1040320
:103960001846FEF7F1F9BB695B6AB8699847BB690D
:10397000DB69012B27D1BB699A69FB69D3187B618D
:103980007A69FB699A4212D9BB697A695A60BB6944
:10399000BA691A6142F2D443C2F200031A68BB69E1
:1039A00003F1040310461946FEF794F90BE04FF0BB
:1039B00000030093B8694FF00001FA694FF000036B
:1039C000FFF7C6FD386142F2D443C2F200031B6820
:1039D0001B68002BB1D142F2D443C2F200031B6832
:1039E000FB6042F2D843C2F200031A6842F2D443A9
:1039F000C2F200031A6042F2D843C2F20003FA682E
:103A00001A6007F12007BD4680BD00BF80B500AF3A
:103A1000FEF74AFA42F2DC43C2F200031B68002BB5
:103A20002BD142F2AC40C2F20000FEF701F942F2A3
:103A3000C040C2F20000FEF7FBF842F2D443C2F2EB
:103A4000000342F2AC42C2F200021A6042F2D843D2
:103A5000C2F2000342F2C042C2F200021A604FF00A
:103A60000A004FF00C014FF00002FEF7E9FA02469F
:103A700042F2DC43C2F200031A60FEF72BFA80BD6B
:103A800080B483B000AF0346FB71FB79002B07D0F5
:103A90004FF42043C4F208034FF001021A6606E017
:103AA0004FF42043C4F208034FF000021A6607F1F6
:103AB0000C07BD4680BC704780B483B000AF78600F
:103AC00000BF4FF42043C4F208035A6E7B681340D2
:103AD000002BF6D107F10C07BD4680BC704700BF34
:103AE00080B500AF4FF007004FF46041C5F20F0101
:103AF0004FF00002FDF7C8FD4FF006004FF46041A3
:103B0000CFF20F014FF00002FDF7BEFD4FF00500B0
:103B10004FF46041CFF20F014FF00002FDF7B4FD0A
:103B20004FF004004FF46041CFF20F014FF000025C
:103B3000FDF7AAFD4FF003004FF46041CFF20F01F3
:103B40004FF00002FDF7A0FD4FF002004FF460417E
:103B5000CFF20F014FF00002FDF796FD4FF001008C
:103B60004FF46041CFF20F014FF00002FDF78CFDE2
:103B70004FF000004FF020414FF00002FDF784FDB0
:103B80004FF007004FF007014FF00002FDF782FEF3
:103B90004FF006004FF007014FF00002FDF77AFEEC
:103BA0004FF005004FF007014FF00002FDF772FEE5
:103BB0004FF004004FF007014FF00002FDF76AFEDE
:103BC0004FF003004FF007014FF00002FDF762FED7
:103BD0004FF002004FF007014FF00002FDF75AFED0
:103BE0004FF001004FF007014FF00002FDF752FEC9
:103BF00000BF80BD80B58AB000AF7860786800F003
:103C0000C6FC0346BB614FF000033B624FF0FF3040
:103C1000FFF752FF4FF00100FFF732FFFFF760FFA1
:103C20004FF000033B625BE03A6ABB699A4203DAF9
:103C30007B681B787B6202E04FF020037B627B6A2B
:103C4000A3F120037B6244F62403C0F200037A6AE6
:103C500033F81230FB824FF00003FB6135E044F291
:103C60000472C0F20002396A0B464FEAC3035B1AC2
:103C70004FEA8303D218FB69D31803F108039B7939
:103C80003B6144F20472C0F20002396A0B464FEA0B
:103C9000C3035B1A4FEA8303F9695B18D3181B78D7
:103CA000FB60FA8AFB6942FA03F303F00103002B7D
:103CB00007D0FA683B69104619464FF00102FDF73C
:103CC000B9FBFB6903F10103FB61FB690D2BC6DD49
:103CD0007B6803F101037B603B6A03F101033B62F4
:103CE0003B6A062BA0DD4FF00000FFF7C9FE07F18D
:103CF0002807BD4680BD00BF80B400AF72B640F259
:103D0000A403C2F200031B68B3F1FF3F0BD040F2E3
:103D1000A403C2F200031B6803F1010240F2A403F2
:103D2000C2F200031A6040F2A403C2F200031B684F
:103D30001846BD4680BC704780B483B000AF40F2E7
:103D4000A403C2F200031B68002B17D040F2A403A7
:103D5000C2F200031B6803F1FF3240F2A403C2F277
:103D600000031A6040F2A403C2F200031B687B60E8
:103D70007B68002B00D162B67B6801E04FF0000346
:103D8000184607F10C07BD4680BC704780B400AFF1
:103D90004FF46D43CEF200034FF46D42CEF20002B9
:103DA000126922F004021A6130BFBD4680BC704720
:103DB00080B582B000AFFFF79FFF00F019F803460F
:103DC000FB71FB79002B07D0FB79032B04D8FB791F
:103DD000184600F03FF802E04FF00003FB71FFF7D8
:103DE000ABFFFB79184607F10807BD4680BD00BF51
:103DF00080B483B000AF4FF00003FB7142F2EC439C
:103E0000C2F200031B78002B16D14FF00103FB71A7
:103E100042F2EC43C2F200035B78002B0CD14FF06E
:103E20000203FB7142F2EC43C2F200039B78002BC9
:103E300002D14FF00303FB71FB79032B02D94FF042
:103E40000303FB71FB79184607F10C07BD4680BCE4
:103E5000704700BF80B582B000AF0346FB71FB79AD
:103E6000002B02D0FB79042B07D944F6DC00C0F20A
:103E700000004FF4C271FCF727FC42F2E443C2F2A7
:103E800000031B68002B07D042F2E443C2F2000398
:103E90001B68FA7910469847FB7903F1FF33032B2F
:103EA0001AD801A252F823F0B93E0000BF3E00002C
:103EB000C93E0000D33E0000FFF768FF0DE04FF061
:103EC0000100FDF70FF908E04FF00100FDF73CF9A4
:103ED00003E0FDF783F900E000BF42F2E843C2F2DD
:103EE00000031B68002B07D042F2E843C2F2000334
:103EF0001B68FA791046984707F10807BD4680BD50
:103F0000074880470749084A084B9B1A40F3058039
:103F1000043BC858D0503FF7FBAF054800470000AE
:103F20003541000064490000000000207C000020B2
:103F300055010000FEE7FEE7FEE7FEE7FEE7FEE7CD
:103F4000FEE7FEE7FEE7FEE7FEE7FEE7FEE7FEE749
:103F5000FEE7FEE7FEE7FEE7FEE7FEE7FEE7FEE739
:103F6000FEE7FEE7FEE7FEE7FEE7FEE7FEE7FEE729
:103F7000FEE7FEE7FEE7FEE7FEE7FEE7FEE7FEE719
:103F8000FEE7FEE7FEE7FEE7FEE7FEE7FEE7FEE709
:103F9000FEE7FEE7FEE700BF80B400AF48F2B013D3
:103FA000C0F6E073DB6C4FEA1363DBB21846BD4624
:103FB00080BC704780B582B000AF00F027F8786011
:103FC0004FF40043C4F20C031B6803F4E0334FEAE0
:103FD000933303F101037A68B2FBF3F37B604FF490
:103FE0000043C4F20C035B6803F00F037A6822FA03
:103FF00003F37B6042F2FC43C2F200037A681A606A
:104000007B68184607F10807BD4680BD80B582B0C1
:1040100000AF4FF40043C4F20C03DB6A03F47053A7
:10402000B3F5805F0DD0B3F5005F03D0B3F5006F3B
:104030000BD011E040F20C03C2F200031B687B605E
:1040400066E04FF400437B6062E040F20803C2F296
:1040500000031B687B605BE04FF40043C4F20C0379
:10406000DB6803F4E063B3F5007F24D0B3F5007F91
:1040700005D8002B36D0B3F5807F22D043E0B3F5CE
:10408000806F0CD0B3F5A06F03D0B3F5407F0CD098
:1040900039E04FF47C53C0F2AB137B6037E046F657
:1040A0004073C0F240137B6031E049F68073C0F288
:1040B000D5037B602BE04DF6C003C0F2A7037B6005
:1040C00025E0FFF769FF0346122B05D94BF2405359
:1040D000C0F264037B601AE04CF6C073C0F26A035E
:1040E0007B6014E0FFF758FF0346122B05D94FF40D
:1040F0009F43C0F212037B6009E044F24023C0F208
:104100000F037B6003E04FF000037B6000BF00BF44
:104110007B68184607F10807BD4680BD80B400AF34
:1041200040F20803C2F200031B681846BD4680BC7B
:10413000704700BF80B400AFBD4680BC704700BF71
:1041400080B582B000AF03463960FB71FB79052B67
:1041500002D83B680F2B07D944F6F000C0F20000EC
:1041600040F2DF11FCF7B0FA4FF4C042C4F2000293
:10417000F9793B684FF0010000FA03F318460B464B
:104180004FEAC3035B184FEA8303D31803F110030C
:10419000586007F10807BD4680BD00BF80B582B0FA
:1041A00000AF03463960FB71FB79052B02D83B68F1
:1041B0000F2B07D944F6F000C0F2000040F20B21AB
:1041C000FCF782FA4FF4C042C4F20002F9793B686E
:1041D0004FF0010000FA03F318460B464FEAC30301
:1041E0005B184FEA8303D31803F11003186007F13B
:1041F0000807BD4680BD00BF80B582B000AF48F261
:104200001010C0F202004FF00101FCF759FD4FF40D
:104210005240C0F202004FF00101FCF751FD4FF097
:1042200000037B601BE044F64013C0F200037A6891
:1042300013F8321044F64012C0F200027B684FEAD5
:10424000C303D3185B68084619464FF004024FF0C9
:104250000003FCF7F3FF7B6803F101037B607B68DD
:10426000012BE0DD4FF00003184607F10807BD46BB
:1042700080BD00BF80B584B000AF78604FF0000310
:10428000FB604FF00103BB6035E07A68BB68134008
:10429000002B14D044F64013C0F20003FA6813F860
:1042A000321044F64012C0F20002FB684FEAC3032A
:1042B000D3185B6808461946FFF770FF13E044F611
:1042C0004013C0F20003FA6813F8321044F64012AB
:1042D000C0F20002FB684FEAC303D3185B680846CC
:1042E0001946FFF72DFFFB6803F10103FB60BB6874
:1042F0004FEA4303BB60FB68012BC6DD4FF00003B0
:10430000184607F11007BD4680BD00BF80B582B0DA
:1043100000AF78607B68002B19DB7B68012B16DC13
:1043200044F64013C0F200037A6813F8321044F6E2
:104330004012C0F200027B684FEAC303D3185B68E7
:1043400008461946FFF72AFF4FF0000301E04FF03F
:10435000FF33184607F10807BD4680BD80B400AFA3
:104360004FF40043C4F20C034FF40042C4F20C02B9
:10437000526C42F400525A644FF4C043C4F200033A
:104380004FF4C042C4F20002D2F8202142F00402ED
:10439000C3F820214FF4C043C4F200034FF4C042DD
:1043A000C4F20002D2F8202122F44072C3F8202186
:1043B0004FF4C043C4F200034FF4C042C4F2000201
:1043C000D2F8B82022F47062C3F8B8204FF4C0438A
:1043D000C4F200034FF4C042C4F20002D2F8B82085
:1043E00042F48062C3F8B8204FF40043C4F20C03D7
:1043F0004FF010021A6200BF4FF40043C4F20C03E6
:10440000DB6A03F02003002BF6D04EF6F053CEF219
:1044100000034EF6F052CEF20002D26842F08072F3
:10442000DA604FF48053CEF2000341F2FF32C4F25F
:1044300001021A604FF00003CEF204034FF00F02A6
:104440001A614FF00003CEF204034FF00202C3F8EA
:10445000F0204FF00003CEF204034FF48072C3F853
:1044600004234FF060424CF65563CCF2AC53C2F8D3
:10447000B03F4FF060424FF00903C0F20103C2F8B1
:10448000803EBD4680BC704780B582B000AF4FF023
:104490007E637B607B681B68002B02D14FF00003BA
:1044A00003E0FFF75BFF4FF00103184607F1080731
:1044B000BD4680BD10B5034C14B1AFF3008010BDF4
:1044C000204610BD0000000008B5084B04461BB193
:1044D0000021AFF3008001E000F00CF80448006810
:1044E000816A01B18847204600F05AF800000000B8
:1044F0005449000070B5084B084C0025E01A8410A0
:1045000003EB8406043D1CB172599047013CF9E766
:10451000BDE8704000F04CB8780000207C0000201E
:1045200038B50E4D0E4B0024E81A8510AC4205D06C
:104530000B4951F8242090470134F7E700F032F896
:104540000849094A541AA5100024AC4205D0054B6D
:1045500053F8240080470134F7E738BD7400002089
:1045600074000020740000207800002010B50023A3
:10457000934203D0CC5CC4540133F9E710BD8218D8
:104580000346934202D003F8011BFAE77047034643
:1045900013F8012B002AFBD1181A013870470000CC
:1045A000FEE700BFF8B500BFF8BC08BC9E467047E8
:1045B000F8B500BFF8BC08BC9E467047433A5C5350
:1045C000696C69636F6E4C6162735C53696D706C8A
:1045D000696369747953747564696F5C76325C647D
:1045E0006576656C6F7065725C73646B735C656631
:1045F0006D33325C76322F656D6C69622F696E6344
:104600002F656D5F62757274632E68000101000092
:104610000030000001000000000000000100000068
:104620005075744F6E4C6364000000005072696EE8
:10463000744C63645468726561640000433A5C536F
:10464000696C69636F6E4C6162735C53696D706C09
:10465000696369747953747564696F5C76325C64FC
:104660006576656C6F7065725C73646B735C6566B0
:104670006D33325C76322F656D6C69622F696E63C3
:104680002F656D5F62757274632E68002E2E2F6524
:104690006D6C69622F656D5F62757274632E630065
:1046A0002E2E2F656D6C69622F656D5F636D752EA3
:1046B000630000002E2E2F656D6C69622F656D5FA3
:1046C0006770696F2E6300002E2E2F656D6C696216
:1046D0002F656D5F6C63642E630000002E2E2F65C6
:1046E0006D6C69622F656D5F73797374656D2E6390
:1046F0000000000049444C4500000000546D722049
:104700005376630001010507070304020302040650
:1047100005060D0E0E0E0D0D0D0D0E0E0E0E0D0DD1
:1047200001010507070304020302040605060F1032
:1047300010100F0F0F0F101010100F0F01010507B1
:1047400007030402030204060506111212121111D6
:1047500011111212121211110101050707030402AF
:10476000030204060506131C1C1C131313131C1C44
:104770001C1C1313000105070602030103020406B3
:1047800004051D1E1E1E1D1D1D1D1E1E1E1E1D1D83
:1047900000010507060203010302040604051F20A9
:1047A00020201F1F1F1F202020201F1F0101050781
:1047B0000703040203020406050621222222212106
:1047C000212122222222212107050201030604239E
:1047D000232323232323070502010306042424247F
:1047E0002424242407050201030604252525252564
:1047F0002525070502010306042626262626262649
:1048000000010702062727272727000000000000D5
:104810000000131211100F0E0D0C000000002125D6
:1048200024260000000000118002000000000206A3
:104830000000200039000F00000040150020400457
:10484000001000223F0006005B044F0466046D0464
:104850007D0407007F046F0400000000000A0000D0
:1048600080200000FFFF7704790A3900B02079002A
:1048700071007D04760406000E00700A3800B6024E
:10488000B6083F0073043F08730C6D0401113E002D
:1048900030223628802A6E040922390080080F0051
:1048A00001000800000158107C0458005E045820E4
:1048B00071040C0C740404000E00700C38005414C5
:1048C00054045C04730467045004080C78001C0052
:1048D00010201428802A0C08482000002E2E2F4477
:1048E0007269766572732F736C6565702E63000054
:1048F000433A5C53696C69636F6E4C6162735C53DD
:10490000696D706C696369747953747564696F5CFF
:1049100076325C646576656C6F7065725C73646B2F
:10492000735C65666D33325C76322F656D6C6962DF
:104930002F696E632F656D5F6770696F2E68000069
:10494000040000000200000004000000030000005A
:0C495000430000001000002000000000E8
:08495C00F8B7FF7F0100000025
:10496400AAAAAAAAFFFFFFFF006CDC0200800000D5
:104974000000000000000000000000000000000033
:104984000000000000000000000000000000000023
:10499400504900000000000000000000000000007A
:1049A4000000000000000000000000000000000003
:1049B40000000000000000000000000000000000F3
:1049C40000000000000000000000000000000000E3
:0C49D400000000002501000001010000AF
:0400000300003F01B9
:00000001FF
/* Linker script for Energy Micro EFM32GG devices */
/* */
/* This file is subject to the license terms as defined in ARM's */
/* CMSIS END USER LICENSE AGREEMENT.pdf, governing the use of */
/* Example Code. */
/* */
/* Energy Micro AS, 2012 */
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 1048576
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 131072
}
/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH and RAM.
* It references following symbols, which must be defined in code:
* Reset_Handler : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
* __exidx_start
* __exidx_end
* __etext
* __data_start__
* __preinit_array_start
* __preinit_array_end
* __init_array_start
* __init_array_end
* __fini_array_start
* __fini_array_end
* __data_end__
* __bss_start__
* __bss_end__
* __end__
* end
* __HeapLimit
* __StackLimit
* __StackTop
* __stack
*/
ENTRY(Reset_Handler)
SECTIONS
{
.text :
{
KEEP(*(.isr_vector))
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.rodata*)
KEEP(*(.eh_frame*))
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
__etext = .;
.data : AT (__etext)
{
__data_start__ = .;
*(vtable)
*(.data*)
. = ALIGN (4);
*(.ram)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
. = ALIGN(4);
/* All data end */
__data_end__ = .;
} > RAM
.bss :
{
__bss_start__ = .;
*(.bss*)
*(COMMON)
__bss_end__ = .;
} > RAM
.heap :
{
__end__ = .;
end = __end__;
_end = __end__;
*(.heap*)
__HeapLimit = .;
} > RAM
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy :
{
*(.stack)
} > RAM
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
}
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
# Add inputs and outputs from these tool invocations to the build variables
C_SRCS += \
../FreeRTOS/efm32gg/croutine.c \
../FreeRTOS/efm32gg/heap_1.c \
../FreeRTOS/efm32gg/list.c \
../FreeRTOS/efm32gg/port_gcc.c \
../FreeRTOS/efm32gg/queue.c \
../FreeRTOS/efm32gg/tasks.c \
../FreeRTOS/efm32gg/timers.c
OBJS += \
./FreeRTOS/efm32gg/croutine.o \
./FreeRTOS/efm32gg/heap_1.o \
./FreeRTOS/efm32gg/list.o \
./FreeRTOS/efm32gg/port_gcc.o \
./FreeRTOS/efm32gg/queue.o \
./FreeRTOS/efm32gg/tasks.o \
./FreeRTOS/efm32gg/timers.o
C_DEPS += \
./FreeRTOS/efm32gg/croutine.d \
./FreeRTOS/efm32gg/heap_1.d \
./FreeRTOS/efm32gg/list.d \
./FreeRTOS/efm32gg/port_gcc.d \
./FreeRTOS/efm32gg/queue.d \
./FreeRTOS/efm32gg/tasks.d \
./FreeRTOS/efm32gg/timers.d
# Each subdirectory must supply rules for building sources it contributes
FreeRTOS/efm32gg/croutine.o: ../FreeRTOS/efm32gg/croutine.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DGCC_ARMCM3=1' '-DDEBUG_EFM=1' '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/freertos_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/gpiointerrupt/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/nvm/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/sleep/inc" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"FreeRTOS/efm32gg/croutine.d" -MT"FreeRTOS/efm32gg/croutine.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
FreeRTOS/efm32gg/heap_1.o: ../FreeRTOS/efm32gg/heap_1.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DGCC_ARMCM3=1' '-DDEBUG_EFM=1' '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/freertos_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/gpiointerrupt/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/nvm/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/sleep/inc" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"FreeRTOS/efm32gg/heap_1.d" -MT"FreeRTOS/efm32gg/heap_1.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
FreeRTOS/efm32gg/list.o: ../FreeRTOS/efm32gg/list.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DGCC_ARMCM3=1' '-DDEBUG_EFM=1' '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/freertos_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/gpiointerrupt/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/nvm/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/sleep/inc" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"FreeRTOS/efm32gg/list.d" -MT"FreeRTOS/efm32gg/list.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
FreeRTOS/efm32gg/port_gcc.o: ../FreeRTOS/efm32gg/port_gcc.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DGCC_ARMCM3=1' '-DDEBUG_EFM=1' '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/freertos_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/gpiointerrupt/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/nvm/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/sleep/inc" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"FreeRTOS/efm32gg/port_gcc.d" -MT"FreeRTOS/efm32gg/port_gcc.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
FreeRTOS/efm32gg/queue.o: ../FreeRTOS/efm32gg/queue.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DGCC_ARMCM3=1' '-DDEBUG_EFM=1' '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/freertos_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/gpiointerrupt/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/nvm/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/sleep/inc" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"FreeRTOS/efm32gg/queue.d" -MT"FreeRTOS/efm32gg/queue.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
FreeRTOS/efm32gg/tasks.o: ../FreeRTOS/efm32gg/tasks.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DGCC_ARMCM3=1' '-DDEBUG_EFM=1' '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/freertos_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/gpiointerrupt/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/nvm/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/sleep/inc" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"FreeRTOS/efm32gg/tasks.d" -MT"FreeRTOS/efm32gg/tasks.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
FreeRTOS/efm32gg/timers.o: ../FreeRTOS/efm32gg/timers.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DGCC_ARMCM3=1' '-DDEBUG_EFM=1' '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/freertos_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/gpiointerrupt/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/nvm/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/sleep/inc" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"FreeRTOS/efm32gg/timers.d" -MT"FreeRTOS/efm32gg/timers.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
# Add inputs and outputs from these tool invocations to the build variables
C_SRCS += \
../emlib/em_assert.c \
../emlib/em_burtc.c \
../emlib/em_cmu.c \
../emlib/em_emu.c \
../emlib/em_gpio.c \
../emlib/em_int.c \
../emlib/em_lcd.c \
../emlib/em_rmu.c \
../emlib/em_rtc.c \
../emlib/em_system.c
OBJS += \
./emlib/em_assert.o \
./emlib/em_burtc.o \
./emlib/em_cmu.o \
./emlib/em_emu.o \
./emlib/em_gpio.o \
./emlib/em_int.o \
./emlib/em_lcd.o \
./emlib/em_rmu.o \
./emlib/em_rtc.o \
./emlib/em_system.o
C_DEPS += \
./emlib/em_assert.d \
./emlib/em_burtc.d \
./emlib/em_cmu.d \
./emlib/em_emu.d \
./emlib/em_gpio.d \
./emlib/em_int.d \
./emlib/em_lcd.d \
./emlib/em_rmu.d \
./emlib/em_rtc.d \
./emlib/em_system.d
# Each subdirectory must supply rules for building sources it contributes
emlib/em_assert.o: ../emlib/em_assert.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DGCC_ARMCM3=1' '-DDEBUG_EFM=1' '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/freertos_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/gpiointerrupt/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/nvm/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/sleep/inc" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"emlib/em_assert.d" -MT"emlib/em_assert.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
emlib/em_burtc.o: ../emlib/em_burtc.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DGCC_ARMCM3=1' '-DDEBUG_EFM=1' '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/freertos_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/gpiointerrupt/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/nvm/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/sleep/inc" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"emlib/em_burtc.d" -MT"emlib/em_burtc.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
emlib/em_cmu.o: ../emlib/em_cmu.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DGCC_ARMCM3=1' '-DDEBUG_EFM=1' '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/freertos_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/gpiointerrupt/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/nvm/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/sleep/inc" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"emlib/em_cmu.d" -MT"emlib/em_cmu.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
emlib/em_emu.o: ../emlib/em_emu.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DGCC_ARMCM3=1' '-DDEBUG_EFM=1' '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/freertos_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/gpiointerrupt/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/nvm/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/sleep/inc" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"emlib/em_emu.d" -MT"emlib/em_emu.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
emlib/em_gpio.o: ../emlib/em_gpio.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DGCC_ARMCM3=1' '-DDEBUG_EFM=1' '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/freertos_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/gpiointerrupt/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/nvm/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/sleep/inc" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"emlib/em_gpio.d" -MT"emlib/em_gpio.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
emlib/em_int.o: ../emlib/em_int.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DGCC_ARMCM3=1' '-DDEBUG_EFM=1' '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/freertos_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/gpiointerrupt/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/nvm/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/sleep/inc" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"emlib/em_int.d" -MT"emlib/em_int.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
emlib/em_lcd.o: ../emlib/em_lcd.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DGCC_ARMCM3=1' '-DDEBUG_EFM=1' '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/freertos_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/gpiointerrupt/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/nvm/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/sleep/inc" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"emlib/em_lcd.d" -MT"emlib/em_lcd.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
emlib/em_rmu.o: ../emlib/em_rmu.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DGCC_ARMCM3=1' '-DDEBUG_EFM=1' '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/freertos_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/gpiointerrupt/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/nvm/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/sleep/inc" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"emlib/em_rmu.d" -MT"emlib/em_rmu.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
emlib/em_rtc.o: ../emlib/em_rtc.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DGCC_ARMCM3=1' '-DDEBUG_EFM=1' '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/freertos_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/gpiointerrupt/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/nvm/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/sleep/inc" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"emlib/em_rtc.d" -MT"emlib/em_rtc.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
emlib/em_system.o: ../emlib/em_system.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DGCC_ARMCM3=1' '-DDEBUG_EFM=1' '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/freertos_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/gpiointerrupt/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/nvm/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/sleep/inc" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"emlib/em_system.d" -MT"emlib/em_system.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
-include ../makefile.init
RM := rm -rf
# All of the sources participating in the build are defined here
-include sources.mk
-include src/subdir.mk
-include emlib/subdir.mk
-include FreeRTOS/efm32gg/subdir.mk
-include Drivers/subdir.mk
-include CMSIS/efm32gg/subdir.mk
-include BSP/subdir.mk
-include subdir.mk
-include objects.mk
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(strip $(C_DEPS)),)
-include $(C_DEPS)
endif
endif
-include ../makefile.defs
# Add inputs and outputs from these tool invocations to the build variables
# All Target
all: EFM32GG_freertos_blink.axf
# Tool invocations
EFM32GG_freertos_blink.axf: $(OBJS) $(USER_OBJS)
@echo 'Building target: $@'
@echo 'Invoking: GNU ARM C Linker'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb --specs=nano.specs -Xlinker --gc-sections -Xlinker -Map="EFM32GG_freertos_blink.map" -T "EFM32GG_freertos_blink.ld" -o EFM32GG_freertos_blink.axf "./src/low_power_tick_management.o" "./src/main.o" "./emlib/em_assert.o" "./emlib/em_burtc.o" "./emlib/em_cmu.o" "./emlib/em_emu.o" "./emlib/em_gpio.o" "./emlib/em_int.o" "./emlib/em_lcd.o" "./emlib/em_rmu.o" "./emlib/em_rtc.o" "./emlib/em_system.o" "./FreeRTOS/efm32gg/croutine.o" "./FreeRTOS/efm32gg/heap_1.o" "./FreeRTOS/efm32gg/list.o" "./FreeRTOS/efm32gg/port_gcc.o" "./FreeRTOS/efm32gg/queue.o" "./FreeRTOS/efm32gg/tasks.o" "./FreeRTOS/efm32gg/timers.o" "./Drivers/segmentlcd.o" "./Drivers/sleep.o" "./CMSIS/efm32gg/startup_gcc_efm32gg.o" "./CMSIS/efm32gg/system_efm32gg.o" "./BSP/bsp_stk_leds.o" "./BSP/bsp_trace.o" -Wl,--start-group -lgcc -lc -lnosys -Wl,--end-group
@echo 'Finished building target: $@'
@echo ' '
@echo 'Building hex file: EFM32GG_freertos_blink.hex'
arm-none-eabi-objcopy -O ihex "EFM32GG_freertos_blink.axf" "EFM32GG_freertos_blink.hex"
@echo ' '
@echo 'Running size tool'
arm-none-eabi-size "EFM32GG_freertos_blink.axf"
@echo ' '
# Other Targets
clean:
-$(RM) $(OBJS)$(C_DEPS)$(EXECUTABLES) EFM32GG_freertos_blink.axf
-@echo ' '
.PHONY: all clean dependents
.SECONDARY:
-include ../makefile.targets
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
USER_OBJS :=
LIBS :=
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
O_SRCS :=
C_SRCS :=
S_SRCS :=
S_UPPER_SRCS :=
OBJ_SRCS :=
ASM_SRCS :=
OBJS :=
C_DEPS :=
EXECUTABLES :=
# Every subdirectory with source files must be described here
SUBDIRS := \
src \
emlib \
FreeRTOS/efm32gg \
Drivers \
CMSIS/efm32gg \
BSP \
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
# Add inputs and outputs from these tool invocations to the build variables
C_SRCS += \
../src/low_power_tick_management.c \
../src/main.c
OBJS += \
./src/low_power_tick_management.o \
./src/main.o
C_DEPS += \
./src/low_power_tick_management.d \
./src/main.d
# Each subdirectory must supply rules for building sources it contributes
src/low_power_tick_management.o: ../src/low_power_tick_management.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DGCC_ARMCM3=1' '-DDEBUG_EFM=1' '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/freertos_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/gpiointerrupt/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/nvm/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/sleep/inc" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"src/low_power_tick_management.d" -MT"src/low_power_tick_management.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
src/main.o: ../src/main.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DGCC_ARMCM3=1' '-DDEBUG_EFM=1' '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/freertos_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/FreeRTOS/Source/portable/GCC/ARM_CM3" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/gpiointerrupt/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/nvm/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emdrv/sleep/inc" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"src/main.d" -MT"src/main.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
/***************************************************************************//**
* @file
* @brief Assert API
* @author Energy Micro AS
* @version 3.20.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_assert.h"
#if defined(DEBUG_EFM)
/***************************************************************************//**
* @brief
* EFM internal assert handling.
*
* This function is invoked through EFM_ASSERT() macro usage only, it should
* not be used explicitly.
*
* Currently this implementation only enters an indefinite loop, allowing
* the use of a debugger to determine cause of failure. By defining
* DEBUG_EFM_USER to the preprocessor for all files, a user defined version
* of this function must be defined and will be invoked instead, possibly
* providing output of assertion location.
*
* Please notice that this function is not used unless DEBUG_EFM is defined
* during preprocessing of EFM_ASSERT() usage.
*
* @par file
* Name of source file where assertion failed.
*
* @par line
* Line number in source file where assertion failed.
******************************************************************************/
void assertEFM(const char *file, int line)
{
(void)file; /* Unused parameter */
(void)line; /* Unused parameter */
while (1)
;
}
#endif /* DEBUG_EFM */
/***************************************************************************//**
* @file
* @brief Backup Real Time Counter (BURTC) Peripheral API
* @author Energy Micro AS
* @version 3.20.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_device.h"
#if defined(BURTC_PRESENT)
#include "em_burtc.h"
#include "em_assert.h"
#include "em_bitband.h"
/***************************************************************************//**
* @addtogroup EM_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup BURTC
* @brief Backup Real Time Counter (BURTC) Peripheral API
* @{
******************************************************************************/
/*******************************************************************************
******************************* DEFINES ***********************************
******************************************************************************/
/*******************************************************************************
************************** LOCAL FUNCTIONS ********************************
******************************************************************************/
/***************************************************************************//**
* @brief Convert dividend to prescaler logarithmic value. Only works for even
* numbers equal to 2^n
* @param[in] div Unscaled dividend,
* @return Base 2 logarithm of input, as used by fixed prescalers
******************************************************************************/
__STATIC_INLINE uint32_t BURTC_DivToLog2(uint32_t div)
{
uint32_t log2;
/* Prescaler accepts an argument of 128 or less, valid values being 2^n */
EFM_ASSERT((div > 0) && (div <= 32768));
/* Count leading zeroes and "reverse" result, Cortex-M3 intrinsic */
log2 = (31 - __CLZ(div));
return log2;
}
/***************************************************************************//**
* @brief
* Wait for ongoing sync of register(s) to low frequency domain to complete.
*
* @param[in] mask
* Bitmask corresponding to SYNCBUSY register defined bits, indicating
* registers that must complete any ongoing synchronization.
******************************************************************************/
__STATIC_INLINE void BURTC_Sync(uint32_t mask)
{
/* Avoid deadlock if modifying the same register twice when freeze mode is */
/* activated. */
if (BURTC->FREEZE & BURTC_FREEZE_REGFREEZE)
return;
/* Wait for any pending previous write operation to have been completed */
/* in low frequency domain. This is only required for the Gecko Family */
while (BURTC->SYNCBUSY & mask)
;
}
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief Initialize BURTC
*
* @details
* Configures the BURTC peripheral.
*
* @note
* Before initialization, BURTC module must first be enabled by clearing the
* reset bit in the RMU, i.e.
* @verbatim
* RMU_ResetControl(rmuResetBU, false);
* @endverbatim
* Compare channel 0 must be configured outside this function, before
* initialization if enable is set to true. The counter will always be reset.
*
* @param[in] burtcInit
* Pointer to BURTC initialization structure
******************************************************************************/
void BURTC_Init(const BURTC_Init_TypeDef *burtcInit)
{
uint32_t ctrl;
uint32_t presc;
/* Check initializer structure integrity */
EFM_ASSERT(burtcInit != (BURTC_Init_TypeDef *) 0);
/* Clock divider must be between 1 and 128, really on the form 2^n */
EFM_ASSERT((burtcInit->clkDiv >= 1) && (burtcInit->clkDiv <= 128));
/* Ignored compare bits during low power operation must be less than 7 */
/* Note! Giant Gecko revision C errata, do NOT use LPCOMP=7 */
EFM_ASSERT(burtcInit->lowPowerComp <= 6);
/* You cannot enable the BURTC if mode is set to disabled */
EFM_ASSERT((burtcInit->enable == false) ||
((burtcInit->enable == true) && (burtcInit->mode != burtcModeDisable)));
/* Low power mode is only available with LFRCO or LFXO as clock source */
EFM_ASSERT((burtcInit->clkSel != burtcClkSelULFRCO) ||
((burtcInit->clkSel == burtcClkSelULFRCO) && (burtcInit->lowPowerMode == burtcLPDisable)));
/* Calculate prescaler value from clock divider input */
/* Note! If clock select (clkSel) is ULFRCO, a clock divisor (clkDiv) of
value 1 will select a 2kHz ULFRCO clock, while any other value will
select a 1kHz ULFRCO clock source. */
presc = BURTC_DivToLog2(burtcInit->clkDiv);
/* Make sure all registers are updated simultaneously */
if (burtcInit->enable)
{
BURTC_FreezeEnable(true);
}
/* Modification of LPMODE register requires sync with potential ongoing
* register updates in LF domain. */
BURTC_Sync(BURTC_SYNCBUSY_LPMODE);
/* Configure low power mode */
BURTC->LPMODE = (uint32_t) (burtcInit->lowPowerMode);
/* New configuration */
ctrl = ((BURTC_CTRL_RSTEN) |
(burtcInit->mode) |
(burtcInit->debugRun << _BURTC_CTRL_DEBUGRUN_SHIFT) |
(burtcInit->compare0Top << _BURTC_CTRL_COMP0TOP_SHIFT) |
(burtcInit->lowPowerComp << _BURTC_CTRL_LPCOMP_SHIFT) |
(presc << _BURTC_CTRL_PRESC_SHIFT) |
(burtcInit->clkSel) |
(burtcInit->timeStamp << _BURTC_CTRL_BUMODETSEN_SHIFT));
/* Clear interrupts */
BURTC->IFC = 0xFFFFFFFF;
/* Set new configuration */
BURTC->CTRL = ctrl;
/* Enable BURTC and counter */
if (burtcInit->enable)
{
/* To enable BURTC counter, we need to disable reset */
BURTC_Enable(true);
/* Clear freeze */
BURTC_FreezeEnable(false);
}
}
/***************************************************************************//**
* @brief Set BURTC compare channel
*
* @param[in] comp Compare channel index, must be 0 for Giant / Leopard Gecko
*
* @param[in] value New compare value
******************************************************************************/
void BURTC_CompareSet(unsigned int comp, uint32_t value)
{
(void) comp; /* Unused parameter when EFM_ASSERT is undefined. */
EFM_ASSERT(comp == 0);
/* Modification of COMP0 register requires sync with potential ongoing
* register updates in LF domain. */
BURTC_Sync(BURTC_SYNCBUSY_COMP0);
/* Configure compare channel 0 */
BURTC->COMP0 = value;
}
/***************************************************************************//**
* @brief Get BURTC compare value
*
* @param[in] comp Compare channel index value, must be 0 for Giant/Leopard.
*
* @return Currently configured value for this compare channel
******************************************************************************/
uint32_t BURTC_CompareGet(unsigned int comp)
{
(void) comp; /* Unused parameter when EFM_ASSERT is undefined. */
EFM_ASSERT(comp == 0);
return BURTC->COMP0;
}
/***************************************************************************//**
* @brief Reset counter
*
* @param[in] mode New mode of operation, after clearing
******************************************************************************/
void BURTC_CounterReset(void)
{
/* Set and clear reset bit */
BITBAND_Peripheral(&BURTC->CTRL, _BURTC_CTRL_RSTEN_SHIFT, 1);
BITBAND_Peripheral(&BURTC->CTRL, _BURTC_CTRL_RSTEN_SHIFT, 0);
}
/***************************************************************************//**
* @brief
* Restore BURTC to reset state
* @note
* Before accessing the BURTC, BURSTEN in RMU->CTRL must be cleared.
* LOCK will not be reset to default value, as this will disable access
* to core BURTC registers.
******************************************************************************/
void BURTC_Reset(void)
{
/* Verify RMU BURSTEN is disabled */
EFM_ASSERT((RMU->CTRL & RMU_CTRL_BURSTEN) == 0);
/* Restore all essential BURTC registers to default config */
BURTC->IEN = _BURTC_IEN_RESETVALUE;
/* Modification of LPMODE register requires sync with potential ongoing
* register updates in LF domain. */
BURTC_Sync(BURTC_SYNCBUSY_LPMODE);
BURTC->LPMODE = _BURTC_LPMODE_RESETVALUE;
BURTC->LFXOFDET = _BURTC_LFXOFDET_RESETVALUE;
/* Modification of COMP0 register requires sync with potential ongoing
* register updates in LF domain. */
BURTC_Sync(BURTC_SYNCBUSY_COMP0);
BURTC->COMP0 = _BURTC_COMP0_RESETVALUE;
BURTC->FREEZE = _BURTC_FREEZE_RESETVALUE;
/* We must wait for SYNCBUSY before resetting the CTRL register. */
BURTC_Sync(BURTC_SYNCBUSY_LPMODE | BURTC_SYNCBUSY_COMP0);
BURTC->CTRL = _BURTC_CTRL_RESETVALUE;
}
/***************************************************************************//**
* @brief
* Get clock frequency of the BURTC.
*
* @return
* The current frequency in Hz.
******************************************************************************/
uint32_t BURTC_ClockFreqGet(void)
{
uint32_t clkSel;
uint32_t clkDiv;
uint32_t frequency;
clkSel = BURTC->CTRL & _BURTC_CTRL_CLKSEL_MASK;
clkDiv = (BURTC->CTRL & _BURTC_CTRL_PRESC_MASK) >> _BURTC_CTRL_PRESC_SHIFT;
switch (clkSel)
{
/** Ultra low frequency (1 kHz) clock */
case BURTC_CTRL_CLKSEL_ULFRCO:
if (_BURTC_CTRL_PRESC_DIV1 == clkDiv)
{
frequency = 2000; /* 2KHz when clock divisor is 1. */
}
else
{
frequency = SystemULFRCOClockGet(); /* 1KHz when divisor is different
from 1. */
}
break;
/** Low frequency RC oscillator */
case BURTC_CTRL_CLKSEL_LFRCO:
frequency = SystemLFRCOClockGet() / (1 << clkDiv); /* freq=32768/2^clkDiv */
break;
/** Low frequency crystal osciallator */
case BURTC_CTRL_CLKSEL_LFXO:
frequency = SystemLFXOClockGet() / (1 << clkDiv); /* freq=32768/2^clkDiv */
break;
default:
/* No clock selected for BURTC. */
frequency = 0;
}
return frequency;
}
/** @} (end addtogroup BURTC) */
/** @} (end addtogroup EM_Library) */
#endif /* BURTC_PRESENT */
/***************************************************************************//**
* @file
* @brief Clock management unit (CMU) Peripheral API
* @author Energy Micro AS
* @version 3.20.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_cmu.h"
#if defined( CMU_PRESENT )
#include "em_assert.h"
#include "em_bitband.h"
#include "em_emu.h"
/***************************************************************************//**
* @addtogroup EM_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup CMU
* @brief Clock management unit (CMU) Peripheral API
* @{
******************************************************************************/
/*******************************************************************************
****************************** DEFINES ************************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** Maximum allowed core frequency when using 0 wait states on flash access. */
#define CMU_MAX_FREQ_0WS 16000000
/** Maximum allowed core frequency when using 1 wait states on flash access */
#define CMU_MAX_FREQ_1WS 32000000
/** Maximum frequency before HFLE needs to be enabled on Giant Gecko */
#define CMU_MAX_FREQ_HFLE 32000000
/** Low frequency A group identifier */
#define CMU_LFA 0
/** Low frequency B group identifier */
#define CMU_LFB 1
/** @endcond */
/*******************************************************************************
************************** LOCAL FUNCTIONS ********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/***************************************************************************//**
* @brief
* Configure flash access wait states to most conservative setting for
* this target. Retain SCBTP setting.
******************************************************************************/
static void CMU_FlashWaitStateMax(void)
{
uint32_t cfg;
cfg = MSC->READCTRL;
switch(cfg & _MSC_READCTRL_MODE_MASK)
{
case MSC_READCTRL_MODE_WS1:
case MSC_READCTRL_MODE_WS0:
#if defined( MSC_READCTRL_MODE_WS2 )
case MSC_READCTRL_MODE_WS2:
cfg = (cfg & ~_MSC_READCTRL_MODE_MASK) | MSC_READCTRL_MODE_WS2;
#else
cfg = (cfg & ~_MSC_READCTRL_MODE_MASK) | MSC_READCTRL_MODE_WS1;
#endif
break;
#if defined( MSC_READCTRL_MODE_WS1SCBTP )
case MSC_READCTRL_MODE_WS1SCBTP:
#endif
#if defined( MSC_READCTRL_MODE_WS0SCBTP )
case MSC_READCTRL_MODE_WS0SCBTP:
#endif
#if defined( MSC_READCTRL_MODE_WS2SCBTP )
case MSC_READCTRL_MODE_WS2SCBTP:
cfg = (cfg & ~_MSC_READCTRL_MODE_MASK) | MSC_READCTRL_MODE_WS2SCBTP;
#elif defined( MSC_READCTRL_MODE_WS1SCBTP )
cfg = (cfg & ~_MSC_READCTRL_MODE_MASK) | MSC_READCTRL_MODE_WS1SCBTP;
#endif
#if defined( MSC_READCTRL_MODE_WS2SCBTP ) || \
defined( MSC_READCTRL_MODE_WS1SCBTP ) || defined( MSC_READCTRL_MODE_WS0SCBTP )
break;
#endif
}
MSC->READCTRL = cfg;
}
/***************************************************************************//**
* @brief Convert dividend to prescaler logarithmic value. Only works for even
* numbers equal to 2^n
* @param[in] div Unscaled dividend,
* @return Base 2 logarithm of input, as used by fixed prescalers
******************************************************************************/
__STATIC_INLINE uint32_t CMU_DivToLog2(CMU_ClkDiv_TypeDef div)
{
uint32_t log2;
/* Prescalers take argument of 32768 or less */
EFM_ASSERT((div>0) && (div <= 32768));
/* Count leading zeroes and "reverse" result, Cortex-M3 intrinsic */
log2 = (31 - __CLZ(div));
return log2;
}
/***************************************************************************//**
* @brief Convert logarithm of 2 prescaler to division factor
* @param[in] log2
* @return Dividend
******************************************************************************/
__STATIC_INLINE uint32_t CMU_Log2ToDiv(uint32_t log2)
{
return 1<<log2;
}
/***************************************************************************//**
* @brief
* Configure flash access wait states in order to support given HFCORECLK
* frequency.
*
* @param[in] hfcoreclk
* HFCORECLK frequency that flash access wait states must be configured for.
******************************************************************************/
static void CMU_FlashWaitStateControl(uint32_t hfcoreclk)
{
uint32_t cfg;
cfg = MSC->READCTRL;
#if defined( MSC_READCTRL_MODE_WS2 )
if (hfcoreclk > CMU_MAX_FREQ_1WS)
{
switch(cfg & _MSC_READCTRL_MODE_MASK)
{
case MSC_READCTRL_MODE_WS0SCBTP:
case MSC_READCTRL_MODE_WS1SCBTP:
cfg = (cfg & ~_MSC_READCTRL_MODE_MASK) | MSC_READCTRL_MODE_WS2SCBTP;
break;
case MSC_READCTRL_MODE_WS0:
case MSC_READCTRL_MODE_WS1:
default:
cfg = (cfg & ~_MSC_READCTRL_MODE_MASK) | MSC_READCTRL_MODE_WS2;
break;
}
}
#endif
if ((hfcoreclk > CMU_MAX_FREQ_0WS) && (hfcoreclk <= CMU_MAX_FREQ_1WS))
{
switch (cfg & _MSC_READCTRL_MODE_MASK)
{
#if defined( MSC_READCTRL_MODE_WS2SCBTP )
case MSC_READCTRL_MODE_WS2SCBTP:
#endif
#if defined( MSC_READCTRL_MODE_WS1SCBTP ) && defined( MSC_READCTRL_MODE_WS0SCBTP )
case MSC_READCTRL_MODE_WS0SCBTP:
case MSC_READCTRL_MODE_WS1SCBTP:
cfg = (cfg & ~_MSC_READCTRL_MODE_MASK) | MSC_READCTRL_MODE_WS1SCBTP;
#endif
#if defined( MSC_READCTRL_MODE_WS2SCBTP ) || \
defined( MSC_READCTRL_MODE_WS1SCBTP ) || defined( MSC_READCTRL_MODE_WS0SCBTP )
break;
#endif
default:
cfg = (cfg & ~_MSC_READCTRL_MODE_MASK) | MSC_READCTRL_MODE_WS1;
break;
}
}
if (hfcoreclk <= CMU_MAX_FREQ_0WS)
{
switch (cfg & _MSC_READCTRL_MODE_MASK)
{
#if defined( MSC_READCTRL_MODE_WS2SCBTP )
case MSC_READCTRL_MODE_WS2SCBTP:
#endif
#if defined( MSC_READCTRL_MODE_WS0SCBTP )
case MSC_READCTRL_MODE_WS1SCBTP:
case MSC_READCTRL_MODE_WS0SCBTP:
cfg = (cfg & ~_MSC_READCTRL_MODE_MASK) | MSC_READCTRL_MODE_WS0SCBTP;
#endif
#if defined( MSC_READCTRL_MODE_WS2SCBTP ) || \
defined( MSC_READCTRL_MODE_WS1SCBTP ) || defined( MSC_READCTRL_MODE_WS0SCBTP )
break;
#endif
default:
cfg = (cfg & ~_MSC_READCTRL_MODE_MASK) | MSC_READCTRL_MODE_WS0;
break;
}
}
MSC->READCTRL = cfg;
}
#if defined(USB_PRESENT)
/***************************************************************************//**
* @brief
* Get the USBC frequency
*
* @return
* USBC frequency in Hz
******************************************************************************/
static uint32_t CMU_USBCClkGet(void)
{
uint32_t ret;
CMU_Select_TypeDef clk;
/* Get selected clock source */
clk = CMU_ClockSelectGet(cmuClock_USBC);
switch(clk)
{
case cmuSelect_LFXO:
ret = SystemLFXOClockGet();
break;
case cmuSelect_LFRCO:
ret = SystemLFRCOClockGet();
break;
case cmuSelect_HFCLK:
ret = SystemHFClockGet();
break;
default:
/* Clock is not enabled */
ret = 0;
break;
}
return ret;
}
#endif
/***************************************************************************//**
* @brief
* Get the AUX clock frequency. Used by MSC flash programming and LESENSE,
* by default also as debug clock.
*
* @return
* AUX Frequency in Hz
******************************************************************************/
static uint32_t CMU_AUXClkGet(void)
{
uint32_t ret;
#if defined(_EFM32_GECKO_FAMILY)
/* Gecko has a fixed 14Mhz AUXHFRCO clock */
ret = 14000000;
#else
switch(CMU->AUXHFRCOCTRL & _CMU_AUXHFRCOCTRL_BAND_MASK)
{
case CMU_AUXHFRCOCTRL_BAND_1MHZ:
ret = 1000000;
break;
case CMU_AUXHFRCOCTRL_BAND_7MHZ:
ret = 7000000;
break;
case CMU_AUXHFRCOCTRL_BAND_11MHZ:
ret = 11000000;
break;
case CMU_AUXHFRCOCTRL_BAND_14MHZ:
ret = 14000000;
break;
case CMU_AUXHFRCOCTRL_BAND_21MHZ:
ret = 21000000;
break;
#if defined( _CMU_AUXHFRCOCTRL_BAND_28MHZ )
case CMU_AUXHFRCOCTRL_BAND_28MHZ:
ret = 28000000;
break;
#endif
default:
ret = 0;
break;
}
#endif
return ret;
}
/***************************************************************************//**
* @brief
* Get the Debug Trace clock frequency
*
* @return
* Debug Trace frequency in Hz
******************************************************************************/
static uint32_t CMU_DBGClkGet(void)
{
uint32_t ret;
CMU_Select_TypeDef clk;
/* Get selected clock source */
clk = CMU_ClockSelectGet(cmuClock_DBG);
switch(clk)
{
case cmuSelect_HFCLK:
ret = SystemHFClockGet();
#if defined( _CMU_CTRL_HFCLKDIV_MASK )
/* Giant Gecko has an additional divider, not used by USBC */
ret = ret / (1 + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK) >>
_CMU_CTRL_HFCLKDIV_SHIFT));
#endif
break;
case cmuSelect_AUXHFRCO:
ret = CMU_AUXClkGet();
break;
default:
EFM_ASSERT(0);
ret = 0;
break;
}
return ret;
}
/***************************************************************************//**
* @brief
* Get the LFnCLK frequency based on current configuration.
*
* @param[in] lfClkBranch
* LF branch, 0 = LFA, 1 = LFB, ...
*
* @return
* The LFnCLK frequency in Hz. If no LFnCLK is selected (disabled), 0 is
* returned.
******************************************************************************/
static uint32_t CMU_LFClkGet(unsigned int lfClkBranch)
{
uint32_t ret;
EFM_ASSERT(lfClkBranch == CMU_LFA || lfClkBranch == CMU_LFB);
switch ((CMU->LFCLKSEL >> (lfClkBranch * 2)) & 0x3)
{
case _CMU_LFCLKSEL_LFA_LFRCO:
ret = SystemLFRCOClockGet();
break;
case _CMU_LFCLKSEL_LFA_LFXO:
ret = SystemLFXOClockGet();
break;
case _CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2:
#if defined( CMU_CTRL_HFLE )
/* Giant Gecko can use a /4 divider (and must if >32MHz) or HFLE is set */
if(((CMU->HFCORECLKDIV & _CMU_HFCORECLKDIV_HFCORECLKLEDIV_MASK) == CMU_HFCORECLKDIV_HFCORECLKLEDIV_DIV4)||
(CMU->CTRL & CMU_CTRL_HFLE))
{
ret = SystemCoreClockGet() / 4;
}
else
{
ret = SystemCoreClockGet() / 2;
}
#else
ret = SystemCoreClockGet() / 2;
#endif
break;
case _CMU_LFCLKSEL_LFA_DISABLED:
#if defined( CMU_LFCLKSEL_LFAE )
/* Check LF Extended bit setting for ULFRCO clock */
if(CMU->LFCLKSEL >> (_CMU_LFCLKSEL_LFAE_SHIFT + lfClkBranch * 4))
{
ret = SystemULFRCOClockGet();
}
else
{
ret = 0;
}
#else
ret = 0;
#endif
break;
default:
ret = 0;
break;
}
return ret;
}
/***************************************************************************//**
* @brief
* Wait for ongoing sync of register(s) to low frequency domain to complete.
*
* @param[in] mask
* Bitmask corresponding to SYNCBUSY register defined bits, indicating
* registers that must complete any ongoing synchronization.
******************************************************************************/
__STATIC_INLINE void CMU_Sync(uint32_t mask)
{
/* Avoid deadlock if modifying the same register twice when freeze mode is */
/* activated. */
if (CMU->FREEZE & CMU_FREEZE_REGFREEZE)
return;
/* Wait for any pending previous write operation to have been completed */
/* in low frequency domain */
while (CMU->SYNCBUSY & mask)
;
}
/** @endcond */
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Calibrate clock.
*
* @details
* Run a calibration for HFCLK against a selectable reference clock. Please
* refer to the EFM32 reference manual, CMU chapter, for further details.
*
* @note
* This function will not return until calibration measurement is completed.
*
* @param[in] HFCycles
* The number of HFCLK cycles to run calibration. Increasing this number
* increases precision, but the calibration will take more time.
*
* @param[in] ref
* The reference clock used to compare HFCLK with.
*
* @return
* The number of ticks the reference clock after HFCycles ticks on the HF
* clock.
******************************************************************************/
uint32_t CMU_Calibrate(uint32_t HFCycles, CMU_Osc_TypeDef ref)
{
EFM_ASSERT(HFCycles <= (_CMU_CALCNT_CALCNT_MASK >> _CMU_CALCNT_CALCNT_SHIFT));
/* Set reference clock source */
switch (ref)
{
case cmuOsc_LFXO:
CMU->CALCTRL = CMU_CALCTRL_UPSEL_LFXO;
break;
case cmuOsc_LFRCO:
CMU->CALCTRL = CMU_CALCTRL_UPSEL_LFRCO;
break;
case cmuOsc_HFXO:
CMU->CALCTRL = CMU_CALCTRL_UPSEL_HFXO;
break;
case cmuOsc_HFRCO:
CMU->CALCTRL = CMU_CALCTRL_UPSEL_HFRCO;
break;
case cmuOsc_AUXHFRCO:
CMU->CALCTRL = CMU_CALCTRL_UPSEL_AUXHFRCO;
break;
default:
EFM_ASSERT(0);
return 0;
}
/* Set top value */
CMU->CALCNT = HFCycles;
/* Start calibration */
CMU->CMD = CMU_CMD_CALSTART;
/* Wait until calibration completes */
while (CMU->STATUS & CMU_STATUS_CALBSY)
;
return CMU->CALCNT;
}
#if defined( _CMU_CALCTRL_UPSEL_MASK ) && defined( _CMU_CALCTRL_DOWNSEL_MASK )
/***************************************************************************//**
* @brief
* Configure clock calibration
*
* @details
* Configure a calibration for a selectable clock source against another
* selectable reference clock.
* Refer to the EFM32 reference manual, CMU chapter, for further details.
*
* @note
* After configuration, a call to CMU_CalibrateStart() is required, and
* the resulting calibration value can be read out with the
* CMU_CalibrateCountGet() function call.
*
* @param[in] downCycles
* The number of downSel clock cycles to run calibration. Increasing this
* number increases precision, but the calibration will take more time.
*
* @param[in] downSel
* The clock which will be counted down downCycles
*
* @param[in] upSel
* The reference clock, the number of cycles generated by this clock will
* be counted and added up, the result can be given with the
* CMU_CalibrateCountGet() function call.
******************************************************************************/
void CMU_CalibrateConfig(uint32_t downCycles, CMU_Osc_TypeDef downSel,
CMU_Osc_TypeDef upSel)
{
/* Keep untouched configuration settings */
uint32_t calCtrl = CMU->CALCTRL & ~(_CMU_CALCTRL_UPSEL_MASK | _CMU_CALCTRL_DOWNSEL_MASK);
/* 20 bits of precision to calibration count register */
EFM_ASSERT(downCycles <= (_CMU_CALCNT_CALCNT_MASK >> _CMU_CALCNT_CALCNT_SHIFT));
/* Set down counting clock source - down counter */
switch (downSel)
{
case cmuOsc_LFXO:
calCtrl |= CMU_CALCTRL_DOWNSEL_LFXO;
break;
case cmuOsc_LFRCO:
calCtrl |= CMU_CALCTRL_DOWNSEL_LFRCO;
break;
case cmuOsc_HFXO:
calCtrl |= CMU_CALCTRL_DOWNSEL_HFXO;
break;
case cmuOsc_HFRCO:
calCtrl |= CMU_CALCTRL_DOWNSEL_HFRCO;
break;
case cmuOsc_AUXHFRCO:
calCtrl |= CMU_CALCTRL_DOWNSEL_AUXHFRCO;
break;
default:
EFM_ASSERT(0);
break;
}
/* Set top value to be counted down by the downSel clock */
CMU->CALCNT = downCycles;
/* Set reference clock source - up counter */
switch (upSel)
{
case cmuOsc_LFXO:
calCtrl |= CMU_CALCTRL_UPSEL_LFXO;
break;
case cmuOsc_LFRCO:
calCtrl |= CMU_CALCTRL_UPSEL_LFRCO;
break;
case cmuOsc_HFXO:
calCtrl |= CMU_CALCTRL_UPSEL_HFXO;
break;
case cmuOsc_HFRCO:
calCtrl |= CMU_CALCTRL_UPSEL_HFRCO;
break;
case cmuOsc_AUXHFRCO:
calCtrl |= CMU_CALCTRL_UPSEL_AUXHFRCO;
break;
default:
EFM_ASSERT(0);
break;
}
CMU->CALCTRL = calCtrl;
}
#endif
/***************************************************************************//**
* @brief
* Get clock divisor/prescaler.
*
* @param[in] clock
* Clock point to get divisor/prescaler for. Notice that not all clock points
* have a divisor/prescaler. Please refer to CMU overview in reference manual.
*
* @return
* The current clock point divisor/prescaler. 1 is returned
* if @p clock specifies a clock point without a divisor/prescaler.
******************************************************************************/
CMU_ClkDiv_TypeDef CMU_ClockDivGet(CMU_Clock_TypeDef clock)
{
uint32_t divReg;
CMU_ClkDiv_TypeDef ret;
/* Get divisor reg id */
divReg = (clock >> CMU_DIV_REG_POS) & CMU_DIV_REG_MASK;
switch (divReg)
{
#if defined( _CMU_CTRL_HFCLKDIV_MASK )
case CMU_HFCLKDIV_REG:
ret = 1 + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK) >>
_CMU_CTRL_HFCLKDIV_SHIFT);
break;
#endif
case CMU_HFPERCLKDIV_REG:
ret = (CMU_ClkDiv_TypeDef)((CMU->HFPERCLKDIV &
_CMU_HFPERCLKDIV_HFPERCLKDIV_MASK) >>
_CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT);
ret = CMU_Log2ToDiv(ret);
break;
case CMU_HFCORECLKDIV_REG:
ret = (CMU_ClkDiv_TypeDef)((CMU->HFCORECLKDIV &
_CMU_HFCORECLKDIV_HFCORECLKDIV_MASK) >>
_CMU_HFCORECLKDIV_HFCORECLKDIV_SHIFT);
ret = CMU_Log2ToDiv(ret);
break;
case CMU_LFAPRESC0_REG:
switch (clock)
{
case cmuClock_RTC:
ret = (CMU_ClkDiv_TypeDef)(((CMU->LFAPRESC0 & _CMU_LFAPRESC0_RTC_MASK) >>
_CMU_LFAPRESC0_RTC_SHIFT));
ret = CMU_Log2ToDiv(ret);
break;
#if defined(_CMU_LFAPRESC0_LETIMER0_MASK)
case cmuClock_LETIMER0:
ret = (CMU_ClkDiv_TypeDef)(((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LETIMER0_MASK) >>
_CMU_LFAPRESC0_LETIMER0_SHIFT));
ret = CMU_Log2ToDiv(ret);
break;
#endif
#if defined(_CMU_LFAPRESC0_LCD_MASK)
case cmuClock_LCDpre:
ret = (CMU_ClkDiv_TypeDef)(((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LCD_MASK) >>
_CMU_LFAPRESC0_LCD_SHIFT) + CMU_DivToLog2(cmuClkDiv_16));
ret = CMU_Log2ToDiv(ret);
break;
#endif
#if defined(_CMU_LFAPRESC0_LESENSE_MASK)
case cmuClock_LESENSE:
ret = (CMU_ClkDiv_TypeDef)(((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LESENSE_MASK) >>
_CMU_LFAPRESC0_LESENSE_SHIFT));
ret = CMU_Log2ToDiv(ret);
break;
#endif
default:
EFM_ASSERT(0);
ret = cmuClkDiv_1;
break;
}
break;
case CMU_LFBPRESC0_REG:
switch (clock)
{
#if defined(_CMU_LFBPRESC0_LEUART0_MASK)
case cmuClock_LEUART0:
ret = (CMU_ClkDiv_TypeDef)(((CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART0_MASK) >>
_CMU_LFBPRESC0_LEUART0_SHIFT));
ret = CMU_Log2ToDiv(ret);
break;
#endif
#if defined(_CMU_LFBPRESC0_LEUART1_MASK)
case cmuClock_LEUART1:
ret = (CMU_ClkDiv_TypeDef)(((CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART1_MASK) >>
_CMU_LFBPRESC0_LEUART1_SHIFT));
ret = CMU_Log2ToDiv(ret);
break;
#endif
default:
EFM_ASSERT(0);
ret = cmuClkDiv_1;
break;
}
break;
default:
EFM_ASSERT(0);
ret = cmuClkDiv_1;
break;
}
return(ret);
}
/***************************************************************************//**
* @brief
* Set clock divisor/prescaler.
*
* @note
* If setting a LF clock prescaler, synchronization into the low frequency
* domain is required. If the same register is modified before a previous
* update has completed, this function will stall until the previous
* synchronization has completed. Please refer to CMU_FreezeEnable() for
* a suggestion on how to reduce stalling time in some use cases.
*
* @param[in] clock
* Clock point to set divisor/prescaler for. Notice that not all clock points
* have a divisor/prescaler, please refer to CMU overview in the reference
* manual.
*
* @param[in] div
* The clock divisor to use (<= cmuClkDiv_512).
******************************************************************************/
void CMU_ClockDivSet(CMU_Clock_TypeDef clock, CMU_ClkDiv_TypeDef div)
{
uint32_t freq;
uint32_t divReg;
/* Get divisor reg id */
divReg = (clock >> CMU_DIV_REG_POS) & CMU_DIV_REG_MASK;
switch (divReg)
{
#if defined( _CMU_CTRL_HFCLKDIV_MASK )
case CMU_HFCLKDIV_REG:
EFM_ASSERT((div>=cmuClkDiv_1) && (div<=cmuClkDiv_8));
/* Configure worst case wait states for flash access before setting divisor */
CMU_FlashWaitStateMax();
/* Set divider */
CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_HFCLKDIV_MASK) |
((div-1) << _CMU_CTRL_HFCLKDIV_SHIFT);
/* Update CMSIS core clock variable */
/* (The function will update the global variable) */
freq = SystemCoreClockGet();
/* Optimize flash access wait state setting for current core clk */
CMU_FlashWaitStateControl(freq);
break;
#endif
case CMU_HFPERCLKDIV_REG:
EFM_ASSERT((div >= cmuClkDiv_1) && (div <= cmuClkDiv_512));
/* Convert to correct scale */
div = CMU_DivToLog2(div);
CMU->HFPERCLKDIV = (CMU->HFPERCLKDIV & ~_CMU_HFPERCLKDIV_HFPERCLKDIV_MASK) |
(div << _CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT);
break;
case CMU_HFCORECLKDIV_REG:
EFM_ASSERT(div <= cmuClkDiv_512);
/* Configure worst case wait states for flash access before setting divisor */
CMU_FlashWaitStateMax();
#if defined( CMU_CTRL_HFLE )
/* Clear HFLE and set DIV2 factor for peripheral clock
when running at frequencies lower than 32 MHz. */
if ( (cmuSelect_HFXO != CMU_ClockSelectGet(cmuClock_HF)) ||
((SystemHFXOClockGet()/div) <= CMU_MAX_FREQ_HFLE) )
{
/* Clear CMU HFLE */
BITBAND_Peripheral(&(CMU->CTRL), _CMU_CTRL_HFLE_SHIFT, 0);
/* Set DIV2 factor for peripheral clock */
BITBAND_Peripheral(&(CMU->HFCORECLKDIV),
_CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 0);
}
else
{
/* Set CMU HFLE */
BITBAND_Peripheral(&(CMU->CTRL), _CMU_CTRL_HFLE_SHIFT, 1);
/* Set DIV4 factor for peripheral clock */
BITBAND_Peripheral(&(CMU->HFCORECLKDIV),
_CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);
}
#endif
/* Convert to correct scale */
div = CMU_DivToLog2(div);
CMU->HFCORECLKDIV = (CMU->HFCORECLKDIV & ~_CMU_HFCORECLKDIV_HFCORECLKDIV_MASK) |
(div << _CMU_HFCORECLKDIV_HFCORECLKDIV_SHIFT);
/* Update CMSIS core clock variable */
/* (The function will update the global variable) */
freq = SystemCoreClockGet();
/* Optimize flash access wait state setting for current core clk */
CMU_FlashWaitStateControl(freq);
break;
case CMU_LFAPRESC0_REG:
switch (clock)
{
case cmuClock_RTC:
EFM_ASSERT(div <= cmuClkDiv_32768);
/* LF register about to be modified require sync. busy check */
CMU_Sync(CMU_SYNCBUSY_LFAPRESC0);
/* Convert to correct scale */
div = CMU_DivToLog2(div);
CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_RTC_MASK) |
(div << _CMU_LFAPRESC0_RTC_SHIFT);
break;
#if defined(_CMU_LFAPRESC0_LETIMER0_MASK)
case cmuClock_LETIMER0:
EFM_ASSERT(div <= cmuClkDiv_32768);
/* LF register about to be modified require sync. busy check */
CMU_Sync(CMU_SYNCBUSY_LFAPRESC0);
/* Convert to correct scale */
div = CMU_DivToLog2(div);
CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_LETIMER0_MASK) |
(div << _CMU_LFAPRESC0_LETIMER0_SHIFT);
break;
#endif
#if defined(LCD_PRESENT)
case cmuClock_LCDpre:
EFM_ASSERT((div >= cmuClkDiv_16) && (div <= cmuClkDiv_128));
/* LF register about to be modified require sync. busy check */
CMU_Sync(CMU_SYNCBUSY_LFAPRESC0);
/* Convert to correct scale */
div = CMU_DivToLog2(div);
CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_LCD_MASK) |
((div - CMU_DivToLog2(cmuClkDiv_16)) << _CMU_LFAPRESC0_LCD_SHIFT);
break;
#endif /* defined(LCD_PRESENT) */
#if defined(LESENSE_PRESENT)
case cmuClock_LESENSE:
EFM_ASSERT(div <= cmuClkDiv_8);
/* LF register about to be modified require sync. busy check */
CMU_Sync(CMU_SYNCBUSY_LFAPRESC0);
/* Convert to correct scale */
div = CMU_DivToLog2(div);
CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_LESENSE_MASK) |
(div << _CMU_LFAPRESC0_LESENSE_SHIFT);
break;
#endif /* defined(LESENSE_PRESENT) */
default:
EFM_ASSERT(0);
break;
}
break;
case CMU_LFBPRESC0_REG:
switch (clock)
{
#if defined(_CMU_LFBPRESC0_LEUART0_MASK)
case cmuClock_LEUART0:
EFM_ASSERT(div <= cmuClkDiv_8);
/* LF register about to be modified require sync. busy check */
CMU_Sync(CMU_SYNCBUSY_LFBPRESC0);
/* Convert to correct scale */
div = CMU_DivToLog2(div);
CMU->LFBPRESC0 = (CMU->LFBPRESC0 & ~_CMU_LFBPRESC0_LEUART0_MASK) |
(((uint32_t)div) << _CMU_LFBPRESC0_LEUART0_SHIFT);
break;
#endif
#if defined(_CMU_LFBPRESC0_LEUART1_MASK)
case cmuClock_LEUART1:
EFM_ASSERT(div <= cmuClkDiv_8);
/* LF register about to be modified require sync. busy check */
CMU_Sync(CMU_SYNCBUSY_LFBPRESC0);
/* Convert to correct scale */
div = CMU_DivToLog2(div);
CMU->LFBPRESC0 = (CMU->LFBPRESC0 & ~_CMU_LFBPRESC0_LEUART1_MASK) |
(((uint32_t)div) << _CMU_LFBPRESC0_LEUART1_SHIFT);
break;
#endif
default:
EFM_ASSERT(0);
break;
}
break;
default:
EFM_ASSERT(0);
break;
}
}
/***************************************************************************//**
* @brief
* Enable/disable a clock.
*
* @details
* In general, module clocking is disabled after a reset. If a module
* clock is disabled, the registers of that module are not accessible and
* reading from such registers may return undefined values. Writing to
* registers of clock disabled modules have no effect. One should normally
* avoid accessing module registers of a module with a disabled clock.
*
* @note
* If enabling/disabling a LF clock, synchronization into the low frequency
* domain is required. If the same register is modified before a previous
* update has completed, this function will stall until the previous
* synchronization has completed. Please refer to CMU_FreezeEnable() for
* a suggestion on how to reduce stalling time in some use cases.
*
* @param[in] clock
* The clock to enable/disable. Notice that not all defined clock
* points have separate enable/disable control, please refer to CMU overview
* in reference manual.
*
* @param[in] enable
* @li true - enable specified clock.
* @li false - disable specified clock.
******************************************************************************/
void CMU_ClockEnable(CMU_Clock_TypeDef clock, bool enable)
{
volatile uint32_t *reg;
uint32_t bit;
uint32_t sync = 0;
/* Identify enable register */
switch ((clock >> CMU_EN_REG_POS) & CMU_EN_REG_MASK)
{
case CMU_HFPERCLKDIV_EN_REG:
reg = &(CMU->HFPERCLKDIV);
break;
case CMU_HFPERCLKEN0_EN_REG:
reg = &(CMU->HFPERCLKEN0);
break;
case CMU_HFCORECLKEN0_EN_REG:
reg = &(CMU->HFCORECLKEN0);
#if defined( CMU_CTRL_HFLE )
/* Set HFLE and DIV4 factor for peripheral clock
when running at frequencies higher than 32 MHz. */
if ( (cmuSelect_HFXO == CMU_ClockSelectGet(cmuClock_HF)) &&
((SystemHFXOClockGet()/CMU_ClockDivGet(cmuClock_CORE)) >
CMU_MAX_FREQ_HFLE) )
{
/* Enable CMU HFLE */
BITBAND_Peripheral(&(CMU->CTRL), _CMU_CTRL_HFLE_SHIFT, 1);
/* Set DIV4 factor for peripheral clock */
BITBAND_Peripheral(&(CMU->HFCORECLKDIV),
_CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);
}
#endif
break;
case CMU_LFACLKEN0_EN_REG:
reg = &(CMU->LFACLKEN0);
sync = CMU_SYNCBUSY_LFACLKEN0;
break;
case CMU_LFBCLKEN0_EN_REG:
reg = &(CMU->LFBCLKEN0);
sync = CMU_SYNCBUSY_LFBCLKEN0;
break;
case CMU_PCNT_EN_REG:
reg = &(CMU->PCNTCTRL);
break;
default: /* Cannot enable/disable clock point */
EFM_ASSERT(0);
return;
}
/* Get bit position used to enable/disable */
bit = (clock >> CMU_EN_BIT_POS) & CMU_EN_BIT_MASK;
/* LF synchronization required? */
if (sync)
{
CMU_Sync(sync);
}
/* Set/clear bit as requested */
BITBAND_Peripheral(reg, bit, (unsigned int)enable);
}
/***************************************************************************//**
* @brief
* Get clock frequency for a clock point.
*
* @param[in] clock
* Clock point to fetch frequency for.
*
* @return
* The current frequency in Hz.
******************************************************************************/
uint32_t CMU_ClockFreqGet(CMU_Clock_TypeDef clock)
{
uint32_t ret;
switch(clock & (CMU_CLK_BRANCH_MASK << CMU_CLK_BRANCH_POS))
{
case (CMU_HF_CLK_BRANCH << CMU_CLK_BRANCH_POS):
{
ret = SystemHFClockGet();
#if defined( _CMU_CTRL_HFCLKDIV_MASK )
/* Giant Gecko has an additional divider, not used by USBC */
ret = ret / (1 + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK) >>
_CMU_CTRL_HFCLKDIV_SHIFT));
#endif
} break;
#if defined(_CMU_HFPERCLKEN0_USART0_MASK) || \
defined(_CMU_HFPERCLKEN0_USART1_MASK) || \
defined(_CMU_HFPERCLKEN0_USART2_MASK) || \
defined(_CMU_HFPERCLKEN0_UART0_MASK) || \
defined(_CMU_HFPERCLKEN0_UART1_MASK) || \
defined(_CMU_HFPERCLKEN0_TIMER0_MASK) || \
defined(_CMU_HFPERCLKEN0_TIMER1_MASK) || \
defined(_CMU_HFPERCLKEN0_TIMER2_MASK) || \
defined(_CMU_HFPERCLKEN0_TIMER3_MASK) || \
defined(_CMU_HFPERCLKEN0_ACMP0_MASK) || \
defined(_CMU_HFPERCLKEN0_ACMP1_MASK) || \
defined(_CMU_HFPERCLKEN0_DAC0_MASK) || \
defined(_CMU_HFPERCLKEN0_IDAC0_MASK) || \
defined(_CMU_HFPERCLKEN0_ADC0_MASK) || \
defined(_CMU_HFPERCLKEN0_I2C0_MASK) || \
defined(_CMU_HFPERCLKEN0_I2C1_MASK) || \
defined(PRS_PRESENT) || \
defined(VCMP_PRESENT)|| \
defined(GPIO_PRESENT)
case (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS):
{
ret = SystemHFClockGet();
#if defined( _CMU_CTRL_HFCLKDIV_MASK )
/* Leopard/Giant Gecko has an additional divider */
ret = ret / (1 + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK) >>
_CMU_CTRL_HFCLKDIV_SHIFT));
#endif
ret >>= (CMU->HFPERCLKDIV & _CMU_HFPERCLKDIV_HFPERCLKDIV_MASK) >>
_CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT;
} break;
#endif
#if defined(AES_PRESENT) || \
defined(DMA_PRESENT) || \
defined(EBI_PRESENT) || \
defined(USB_PRESENT)
case (CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS):
{
ret = SystemCoreClockGet();
} break;
#endif
case (CMU_LFA_CLK_BRANCH << CMU_CLK_BRANCH_POS):
{
ret = CMU_LFClkGet(CMU_LFA);
} break;
#if defined(_CMU_LFACLKEN0_RTC_MASK)
case (CMU_RTC_CLK_BRANCH << CMU_CLK_BRANCH_POS):
{
ret = CMU_LFClkGet(CMU_LFA);
ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_RTC_MASK) >>
_CMU_LFAPRESC0_RTC_SHIFT;
} break;
#endif
#if defined(_CMU_LFACLKEN0_LETIMER0_MASK)
case (CMU_LETIMER_CLK_BRANCH << CMU_CLK_BRANCH_POS):
{
ret = CMU_LFClkGet(CMU_LFA);
ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_LETIMER0_MASK) >>
_CMU_LFAPRESC0_LETIMER0_SHIFT;
} break;
#endif
#if defined(_CMU_LFACLKEN0_LCD_MASK)
case (CMU_LCDPRE_CLK_BRANCH << CMU_CLK_BRANCH_POS):
{
ret = CMU_LFClkGet(CMU_LFA);
ret >>= ((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LCD_MASK) >>
_CMU_LFAPRESC0_LCD_SHIFT) + CMU_DivToLog2(cmuClkDiv_16);
} break;
case (CMU_LCD_CLK_BRANCH << CMU_CLK_BRANCH_POS):
{
ret = CMU_LFClkGet(CMU_LFA);
ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_LCD_MASK) >>
_CMU_LFAPRESC0_LCD_SHIFT;
ret /= (1 + ((CMU->LCDCTRL & _CMU_LCDCTRL_FDIV_MASK) >>
_CMU_LCDCTRL_FDIV_SHIFT));
} break;
#endif
#if defined(_CMU_LFACLKEN0_LESENSE_MASK)
case (CMU_LESENSE_CLK_BRANCH << CMU_CLK_BRANCH_POS):
{
ret = CMU_LFClkGet(CMU_LFA);
ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_LESENSE_MASK) >>
_CMU_LFAPRESC0_LESENSE_SHIFT;
} break;
#endif
case (CMU_LFB_CLK_BRANCH << CMU_CLK_BRANCH_POS):
{
ret = CMU_LFClkGet(CMU_LFB);
} break;
#if defined(_CMU_LFBCLKEN0_LEUART0_MASK)
case (CMU_LEUART0_CLK_BRANCH << CMU_CLK_BRANCH_POS):
{
ret = CMU_LFClkGet(CMU_LFB);
ret >>= (CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART0_MASK) >>
_CMU_LFBPRESC0_LEUART0_SHIFT;
} break;
#endif
#if defined(_CMU_LFBCLKEN0_LEUART1_MASK)
case (CMU_LEUART1_CLK_BRANCH << CMU_CLK_BRANCH_POS):
{
ret = CMU_LFClkGet(CMU_LFB);
ret >>= (CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART1_MASK) >>
_CMU_LFBPRESC0_LEUART1_SHIFT;
} break;
#endif
case (CMU_DBG_CLK_BRANCH << CMU_CLK_BRANCH_POS):
{
ret = CMU_DBGClkGet();
} break;
case (CMU_AUX_CLK_BRANCH << CMU_CLK_BRANCH_POS):
{
ret = CMU_AUXClkGet();
} break;
#if defined(USB_PRESENT)
case (CMU_USBC_CLK_BRANCH << CMU_CLK_BRANCH_POS):
{
ret = CMU_USBCClkGet();
} break;
#endif
default:
{
EFM_ASSERT(0);
ret = 0;
} break;
}
return ret;
}
/**************************************************************************//**
* @brief
* Get currently selected reference clock used for a clock branch.
*
* @param[in] clock
* Clock branch to fetch selected ref. clock for. One of:
* @li #cmuClock_HF
* @li #cmuClock_LFA
* @li #cmuClock_LFB
* @li #cmuClock_USBC
* @li #cmuClock_DBG
*
* @return
* Reference clock used for clocking selected branch, #cmuSelect_Error if
* invalid @p clock provided.
*****************************************************************************/
CMU_Select_TypeDef CMU_ClockSelectGet(CMU_Clock_TypeDef clock)
{
CMU_Select_TypeDef ret = cmuSelect_Disabled;
uint32_t selReg;
selReg = (clock >> CMU_SEL_REG_POS) & CMU_SEL_REG_MASK;
switch (selReg)
{
case CMU_HFCLKSEL_REG:
switch (CMU->STATUS & (CMU_STATUS_HFRCOSEL | CMU_STATUS_HFXOSEL |
CMU_STATUS_LFRCOSEL | CMU_STATUS_LFXOSEL))
{
case CMU_STATUS_LFXOSEL:
ret = cmuSelect_LFXO;
break;
case CMU_STATUS_LFRCOSEL:
ret = cmuSelect_LFRCO;
break;
case CMU_STATUS_HFXOSEL:
ret = cmuSelect_HFXO;
break;
default:
ret = cmuSelect_HFRCO;
break;
}
break;
case CMU_LFACLKSEL_REG:
switch (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFA_MASK)
{
case CMU_LFCLKSEL_LFA_LFRCO:
ret = cmuSelect_LFRCO;
break;
case CMU_LFCLKSEL_LFA_LFXO:
ret = cmuSelect_LFXO;
break;
case CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2:
ret = cmuSelect_CORELEDIV2;
break;
default:
#if defined( CMU_LFCLKSEL_LFAE )
if (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFAE_MASK)
{
ret = cmuSelect_ULFRCO;
break;
}
#else
ret = cmuSelect_Disabled;
#endif
break;
}
break;
case CMU_LFBCLKSEL_REG:
switch (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFB_MASK)
{
case CMU_LFCLKSEL_LFB_LFRCO:
ret = cmuSelect_LFRCO;
break;
case CMU_LFCLKSEL_LFB_LFXO:
ret = cmuSelect_LFXO;
break;
case CMU_LFCLKSEL_LFB_HFCORECLKLEDIV2:
ret = cmuSelect_CORELEDIV2;
break;
default:
#if defined( CMU_LFCLKSEL_LFBE )
if (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFBE_MASK)
{
ret = cmuSelect_ULFRCO;
break;
}
#else
ret = cmuSelect_Disabled;
#endif
break;
}
break;
case CMU_DBGCLKSEL_REG:
#if defined( CMU_CTRL_DBGCLK )
switch(CMU->CTRL & _CMU_CTRL_DBGCLK_MASK)
{
case CMU_CTRL_DBGCLK_AUXHFRCO:
ret = cmuSelect_AUXHFRCO;
break;
case CMU_CTRL_DBGCLK_HFCLK:
ret = cmuSelect_HFCLK;
break;
}
#endif
#if defined(_EFM32_GECKO_FAMILY)
ret = cmuSelect_AUXHFRCO;
#endif
break;
#if defined(USB_PRESENT)
case CMU_USBCCLKSEL_REG:
switch(CMU->STATUS & (CMU_STATUS_USBCHFCLKSEL |
CMU_STATUS_USBCLFXOSEL |
CMU_STATUS_USBCLFRCOSEL))
{
case CMU_STATUS_USBCHFCLKSEL:
ret = cmuSelect_HFCLK;
break;
case CMU_STATUS_USBCLFXOSEL:
ret = cmuSelect_LFXO;
break;
case CMU_STATUS_USBCLFRCOSEL:
ret = cmuSelect_LFRCO;
break;
default:
ret = cmuSelect_Disabled;
break;
}
break;
#endif
default:
EFM_ASSERT(0);
ret = cmuSelect_Error;
break;
}
return ret;
}
/**************************************************************************//**
* @brief
* Select reference clock/oscillator used for a clock branch.
*
* @details
* Notice that if a selected reference is not enabled prior to selecting its
* use, it will be enabled, and this function will wait for the selected
* oscillator to be stable. It will however NOT be disabled if another
* reference clock is selected later.
*
* This feature is particularly important if selecting a new reference
* clock for the clock branch clocking the core, otherwise the system
* may halt.
*
* @param[in] clock
* Clock branch to select reference clock for. One of:
* @li #cmuClock_HF
* @li #cmuClock_LFA
* @li #cmuClock_LFB
* @li #cmuClock_USBC
* @li #cmuClock_DBG
*
* @param[in] ref
* Reference selected for clocking, please refer to reference manual for
* for details on which reference is available for a specific clock branch.
* @li #cmuSelect_HFRCO
* @li #cmuSelect_LFRCO
* @li #cmuSelect_HFXO
* @li #cmuSelect_LFXO
* @li #cmuSelect_CORELEDIV2
* @li #cmuSelect_AUXHFRC
* @li #cmuSelect_HFCLK
* @li #cmuSelect_ULFRCO
*****************************************************************************/
void CMU_ClockSelectSet(CMU_Clock_TypeDef clock, CMU_Select_TypeDef ref)
{
uint32_t select = cmuOsc_HFRCO;
CMU_Osc_TypeDef osc = cmuOsc_HFRCO;
uint32_t freq;
uint32_t selReg;
#if !defined(_EFM32_GECKO_FAMILY)
uint32_t lfExtended = 0;
#endif
uint32_t tmp;
selReg = (clock >> CMU_SEL_REG_POS) & CMU_SEL_REG_MASK;
switch (selReg)
{
case CMU_HFCLKSEL_REG:
switch (ref)
{
case cmuSelect_LFXO:
select = CMU_CMD_HFCLKSEL_LFXO;
osc = cmuOsc_LFXO;
break;
case cmuSelect_LFRCO:
select = CMU_CMD_HFCLKSEL_LFRCO;
osc = cmuOsc_LFRCO;
break;
case cmuSelect_HFXO:
select = CMU_CMD_HFCLKSEL_HFXO;
osc = cmuOsc_HFXO;
#if defined( CMU_CTRL_HFLE )
/* Adjust HFXO buffer current for high frequencies, enable HFLE for */
/* frequencies above 32MHz */
if(SystemHFXOClockGet() > CMU_MAX_FREQ_HFLE)
{
CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_HFXOBUFCUR_MASK) |
CMU_CTRL_HFXOBUFCUR_BOOSTABOVE32MHZ |
/* Must have HFLE enabled to access some LE peripherals >=32MHz */
CMU_CTRL_HFLE;
/* Set HFLE and DIV4 factor for peripheral clock if HFCORE clock for
LE is enabled. */
if (CMU->HFCORECLKEN0 & CMU_HFCORECLKEN0_LE)
{
BITBAND_Peripheral(&(CMU->HFCORECLKDIV),
_CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);
}
} else {
/* This can happen if the user configures the EFM32_HFXO_FREQ to */
/* use another oscillator frequency */
CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_HFXOBUFCUR_MASK) |
CMU_CTRL_HFXOBUFCUR_BOOSTUPTO32MHZ;
}
#endif
break;
case cmuSelect_HFRCO:
select = CMU_CMD_HFCLKSEL_HFRCO;
osc = cmuOsc_HFRCO;
break;
#if !defined(_EFM32_GECKO_FAMILY)
case cmuSelect_ULFRCO:
/* ULFRCO cannot be used as HFCLK */
EFM_ASSERT(0);
break;
#endif
default:
EFM_ASSERT(0);
return;
}
/* Ensure selected oscillator is enabled, waiting for it to stabilize */
CMU_OscillatorEnable(osc, true, true);
/* Configure worst case wait states for flash access before selecting */
CMU_FlashWaitStateMax();
/* Switch to selected oscillator */
CMU->CMD = select;
/* Keep EMU module informed */
EMU_UpdateOscConfig();
/* Update CMSIS core clock variable */
/* (The function will update the global variable) */
freq = SystemCoreClockGet();
/* Optimize flash access wait state setting for currently selected core clk */
CMU_FlashWaitStateControl(freq);
break;
case CMU_LFACLKSEL_REG:
case CMU_LFBCLKSEL_REG:
switch (ref)
{
case cmuSelect_Disabled:
tmp = _CMU_LFCLKSEL_LFA_DISABLED;
break;
case cmuSelect_LFXO:
/* Ensure selected oscillator is enabled, waiting for it to stabilize */
CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
tmp = _CMU_LFCLKSEL_LFA_LFXO;
break;
case cmuSelect_LFRCO:
/* Ensure selected oscillator is enabled, waiting for it to stabilize */
CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);
tmp = _CMU_LFCLKSEL_LFA_LFRCO;
break;
case cmuSelect_CORELEDIV2:
/* Ensure HFCORE to LE clocking is enabled */
BITBAND_Peripheral(&(CMU->HFCORECLKEN0), _CMU_HFCORECLKEN0_LE_SHIFT, 1);
tmp = _CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2;
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
/* If core frequency is > 32MHz on Giant/Leopard, enable HFLE and DIV4 */
freq = SystemCoreClockGet();
if(freq > CMU_MAX_FREQ_HFLE)
{
/* Enable CMU HFLE */
BITBAND_Peripheral(&(CMU->CTRL), _CMU_CTRL_HFLE_SHIFT, 1);
/* Enable DIV4 factor for peripheral clock */
BITBAND_Peripheral(&(CMU->HFCORECLKDIV),
_CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);
}
#endif
break;
#if !defined(_EFM32_GECKO_FAMILY)
case cmuSelect_ULFRCO:
/* ULFRCO is always enabled */
tmp = _CMU_LFCLKSEL_LFA_DISABLED;
lfExtended = 1;
break;
#endif
default:
/* Illegal clock source for LFA/LFB selected */
EFM_ASSERT(0);
return;
}
if (selReg == CMU_LFACLKSEL_REG)
{
#if !defined(_EFM32_GECKO_FAMILY)
CMU->LFCLKSEL = (CMU->LFCLKSEL & ~(_CMU_LFCLKSEL_LFA_MASK | _CMU_LFCLKSEL_LFAE_MASK) ) |
(tmp << _CMU_LFCLKSEL_LFA_SHIFT) | (lfExtended << _CMU_LFCLKSEL_LFAE_SHIFT);
#else
CMU->LFCLKSEL = (CMU->LFCLKSEL & ~_CMU_LFCLKSEL_LFA_MASK) |
(tmp << _CMU_LFCLKSEL_LFA_SHIFT);
#endif
}
else
{
#if !defined(_EFM32_GECKO_FAMILY)
CMU->LFCLKSEL = (CMU->LFCLKSEL & ~(_CMU_LFCLKSEL_LFB_MASK | _CMU_LFCLKSEL_LFBE_MASK) ) |
(tmp << _CMU_LFCLKSEL_LFB_SHIFT) | (lfExtended << _CMU_LFCLKSEL_LFBE_SHIFT);
#else
CMU->LFCLKSEL = (CMU->LFCLKSEL & ~_CMU_LFCLKSEL_LFB_MASK) |
(tmp << _CMU_LFCLKSEL_LFB_SHIFT);
#endif
}
break;
#if defined( CMU_CTRL_DBGCLK )
case CMU_DBGCLKSEL_REG:
switch(ref)
{
case cmuSelect_AUXHFRCO:
/* Select AUXHFRCO as debug clock */
CMU->CTRL = (CMU->CTRL & ~(_CMU_CTRL_DBGCLK_MASK))| CMU_CTRL_DBGCLK_AUXHFRCO;
break;
case cmuSelect_HFCLK:
/* Select divided HFCLK as debug clock */
CMU->CTRL = (CMU->CTRL & ~(_CMU_CTRL_DBGCLK_MASK))| CMU_CTRL_DBGCLK_HFCLK;
break;
default:
/* Illegal clock source for debug selected */
EFM_ASSERT(0);
return;
}
break;
#endif
#if defined(USB_PRESENT)
case CMU_USBCCLKSEL_REG:
switch(ref)
{
case cmuSelect_HFCLK:
/* Select undivided HFCLK as clock source for USB */
/* Oscillator must already be enabled, if not the core had stopped */
CMU->CMD = CMU_CMD_USBCCLKSEL_HFCLKNODIV;
/* Wait until clock is activated */
while((CMU->STATUS & CMU_STATUS_USBCHFCLKSEL)==0);
break;
case cmuSelect_LFXO:
/* Select LFXO as clock source for USB, can only be used in sleep mode */
/* Ensure selected oscillator is enabled, waiting for it to stabilize */
CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
/* Switch oscillator */
CMU->CMD = CMU_CMD_USBCCLKSEL_LFXO;
/* Wait until clock is activated */
while((CMU->STATUS & CMU_STATUS_USBCLFXOSEL)==0);
break;
case cmuSelect_LFRCO:
/* Select LFRCO as clock source for USB, can only be used in sleep mode */
/* Ensure selected oscillator is enabled, waiting for it to stabilize */
CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);
/* Switch oscillator */
CMU->CMD = CMU_CMD_USBCCLKSEL_LFRCO;
/* Wait until clock is activated */
while((CMU->STATUS & CMU_STATUS_USBCLFRCOSEL)==0);
break;
default:
/* Illegal clock source for USB */
EFM_ASSERT(0);
return;
}
/* Wait until clock has been activated */
break;
#endif
default:
EFM_ASSERT(0);
break;
}
}
/**************************************************************************//**
* @brief
* CMU low frequency register synchronization freeze control.
*
* @details
* Some CMU registers requires synchronization into the low frequency (LF)
* domain. The freeze feature allows for several such registers to be
* modified before passing them to the LF domain simultaneously (which
* takes place when the freeze mode is disabled).
*
* Another usage scenario of this feature, is when using an API (such
* as the CMU API) for modifying several bit fields consecutively in the
* same register. If freeze mode is enabled during this sequence, stalling
* can be avoided.
*
* @note
* When enabling freeze mode, this function will wait for all current
* ongoing CMU synchronization to LF domain to complete (Normally
* synchronization will not be in progress.) However for this reason, when
* using freeze mode, modifications of registers requiring LF synchronization
* should be done within one freeze enable/disable block to avoid unecessary
* stalling.
*
* @param[in] enable
* @li true - enable freeze, modified registers are not propagated to the
* LF domain
* @li false - disable freeze, modified registers are propagated to LF
* domain
*****************************************************************************/
void CMU_FreezeEnable(bool enable)
{
if (enable)
{
/* Wait for any ongoing LF synchronization to complete. This is just to */
/* protect against the rare case when a user */
/* - modifies a register requiring LF sync */
/* - then enables freeze before LF sync completed */
/* - then modifies the same register again */
/* since modifying a register while it is in sync progress should be */
/* avoided. */
while (CMU->SYNCBUSY)
;
CMU->FREEZE = CMU_FREEZE_REGFREEZE;
}
else
{
CMU->FREEZE = 0;
}
}
#if defined( _CMU_AUXHFRCOCTRL_BAND_MASK )
/***************************************************************************//**
* @brief
* Get AUXHFRCO band in use.
*
* @return
* AUXHFRCO band in use.
******************************************************************************/
CMU_AUXHFRCOBand_TypeDef CMU_AUXHFRCOBandGet(void)
{
return (CMU_AUXHFRCOBand_TypeDef)((CMU->AUXHFRCOCTRL & _CMU_AUXHFRCOCTRL_BAND_MASK) >>
_CMU_AUXHFRCOCTRL_BAND_SHIFT);
}
/***************************************************************************//**
* @brief
* Set AUIXHFRCO band and the tuning value based on the value in the
* calibration table made during production.
*
* @param[in] band
* AUXHFRCO band to activate.
******************************************************************************/
void CMU_AUXHFRCOBandSet(CMU_AUXHFRCOBand_TypeDef band)
{
uint32_t tuning;
/* Read tuning value from calibration table */
switch (band)
{
case cmuAUXHFRCOBand_1MHz:
tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND1_MASK) >>
_DEVINFO_AUXHFRCOCAL0_BAND1_SHIFT;
break;
case cmuAUXHFRCOBand_7MHz:
tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND7_MASK) >>
_DEVINFO_AUXHFRCOCAL0_BAND7_SHIFT;
break;
case cmuAUXHFRCOBand_11MHz:
tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND11_MASK) >>
_DEVINFO_AUXHFRCOCAL0_BAND11_SHIFT;
break;
case cmuAUXHFRCOBand_14MHz:
tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND14_MASK) >>
_DEVINFO_AUXHFRCOCAL0_BAND14_SHIFT;
break;
case cmuAUXHFRCOBand_21MHz:
tuning = (DEVINFO->AUXHFRCOCAL1 & _DEVINFO_AUXHFRCOCAL1_BAND21_MASK) >>
_DEVINFO_AUXHFRCOCAL1_BAND21_SHIFT;
break;
#if defined( _CMU_AUXHFRCOCTRL_BAND_28MHZ )
case cmuAUXHFRCOBand_28MHz:
tuning = (DEVINFO->AUXHFRCOCAL1 & _DEVINFO_AUXHFRCOCAL1_BAND28_MASK) >>
_DEVINFO_AUXHFRCOCAL1_BAND28_SHIFT;
break;
#endif
default:
EFM_ASSERT(0);
return;
}
/* Set band/tuning */
CMU->AUXHFRCOCTRL = (CMU->AUXHFRCOCTRL &
~(_CMU_AUXHFRCOCTRL_BAND_MASK | _CMU_AUXHFRCOCTRL_TUNING_MASK)) |
(band << _CMU_AUXHFRCOCTRL_BAND_SHIFT) |
(tuning << _CMU_AUXHFRCOCTRL_TUNING_SHIFT);
}
#endif
/***************************************************************************//**
* @brief
* Get HFRCO band in use.
*
* @return
* HFRCO band in use.
******************************************************************************/
CMU_HFRCOBand_TypeDef CMU_HFRCOBandGet(void)
{
return (CMU_HFRCOBand_TypeDef)((CMU->HFRCOCTRL & _CMU_HFRCOCTRL_BAND_MASK) >>
_CMU_HFRCOCTRL_BAND_SHIFT);
}
/***************************************************************************//**
* @brief
* Set HFRCO band and the tuning value based on the value in the calibration
* table made during production.
*
* @param[in] band
* HFRCO band to activate.
******************************************************************************/
void CMU_HFRCOBandSet(CMU_HFRCOBand_TypeDef band)
{
uint32_t tuning;
uint32_t freq;
CMU_Select_TypeDef osc;
/* Read tuning value from calibration table */
switch (band)
{
case cmuHFRCOBand_1MHz:
tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND1_MASK) >>
_DEVINFO_HFRCOCAL0_BAND1_SHIFT;
break;
case cmuHFRCOBand_7MHz:
tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND7_MASK) >>
_DEVINFO_HFRCOCAL0_BAND7_SHIFT;
break;
case cmuHFRCOBand_11MHz:
tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND11_MASK) >>
_DEVINFO_HFRCOCAL0_BAND11_SHIFT;
break;
case cmuHFRCOBand_14MHz:
tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND14_MASK) >>
_DEVINFO_HFRCOCAL0_BAND14_SHIFT;
break;
case cmuHFRCOBand_21MHz:
tuning = (DEVINFO->HFRCOCAL1 & _DEVINFO_HFRCOCAL1_BAND21_MASK) >>
_DEVINFO_HFRCOCAL1_BAND21_SHIFT;
break;
#if defined( _CMU_HFRCOCTRL_BAND_28MHZ )
case cmuHFRCOBand_28MHz:
tuning = (DEVINFO->HFRCOCAL1 & _DEVINFO_HFRCOCAL1_BAND28_MASK) >>
_DEVINFO_HFRCOCAL1_BAND28_SHIFT;
break;
#endif
default:
EFM_ASSERT(0);
return;
}
/* If HFRCO is used for core clock, we have to consider flash access WS. */
osc = CMU_ClockSelectGet(cmuClock_HF);
if (osc == cmuSelect_HFRCO)
{
/* Configure worst case wait states for flash access before setting divider */
CMU_FlashWaitStateMax();
}
/* Set band/tuning */
CMU->HFRCOCTRL = (CMU->HFRCOCTRL &
~(_CMU_HFRCOCTRL_BAND_MASK | _CMU_HFRCOCTRL_TUNING_MASK)) |
(band << _CMU_HFRCOCTRL_BAND_SHIFT) |
(tuning << _CMU_HFRCOCTRL_TUNING_SHIFT);
/* If HFRCO is used for core clock, optimize flash WS */
if (osc == cmuSelect_HFRCO)
{
/* Update CMSIS core clock variable and get current core clock */
/* (The function will update the global variable) */
/* NOTE! We need at least 21 cycles before setting zero wait state to flash */
/* (i.e. WS0) when going from the 28MHz to 1MHz in the HFRCO band */
freq = SystemCoreClockGet();
/* Optimize flash access wait state setting for current core clk */
CMU_FlashWaitStateControl(freq);
}
}
/***************************************************************************//**
* @brief
* Get the HFRCO startup delay.
*
* @details
* Please refer to the reference manual for further details.
*
* @return
* The startup delay in use.
******************************************************************************/
uint32_t CMU_HFRCOStartupDelayGet(void)
{
return((CMU->HFRCOCTRL & _CMU_HFRCOCTRL_SUDELAY_MASK) >>
_CMU_HFRCOCTRL_SUDELAY_SHIFT);
}
/***************************************************************************//**
* @brief
* Set the HFRCO startup delay.
*
* @details
* Please refer to the reference manual for further details.
*
* @param[in] delay
* The startup delay to set (<= 31).
******************************************************************************/
void CMU_HFRCOStartupDelaySet(uint32_t delay)
{
EFM_ASSERT(delay <= 31);
delay &= (_CMU_HFRCOCTRL_SUDELAY_MASK >> _CMU_HFRCOCTRL_SUDELAY_SHIFT);
CMU->HFRCOCTRL = (CMU->HFRCOCTRL & ~(_CMU_HFRCOCTRL_SUDELAY_MASK)) |
(delay << _CMU_HFRCOCTRL_SUDELAY_SHIFT);
}
/***************************************************************************//**
* @brief
* Get the LCD framerate divisor (FDIV) setting.
*
* @return
* The LCD framerate divisor.
******************************************************************************/
uint32_t CMU_LCDClkFDIVGet(void)
{
#if defined(LCD_PRESENT)
return((CMU->LCDCTRL & _CMU_LCDCTRL_FDIV_MASK) >> _CMU_LCDCTRL_FDIV_SHIFT);
#else
return 0;
#endif /* defined(LCD_PRESENT) */
}
/***************************************************************************//**
* @brief
* Set the LCD framerate divisor (FDIV) setting.
*
* @note
* The FDIV field (CMU LCDCTRL register) should only be modified while the
* LCD module is clock disabled (CMU LFACLKEN0.LCD bit is 0). This function
* will NOT modify FDIV if the LCD module clock is enabled. Please refer to
* CMU_ClockEnable() for disabling/enabling LCD clock.
*
* @param[in] div
* The FDIV setting to use.
******************************************************************************/
void CMU_LCDClkFDIVSet(uint32_t div)
{
#if defined(LCD_PRESENT)
EFM_ASSERT(div <= cmuClkDiv_128);
/* Do not allow modification if LCD clock enabled */
if (CMU->LFACLKEN0 & CMU_LFACLKEN0_LCD)
{
return;
}
div <<= _CMU_LCDCTRL_FDIV_SHIFT;
div &= _CMU_LCDCTRL_FDIV_MASK;
CMU->LCDCTRL = (CMU->LCDCTRL & ~_CMU_LCDCTRL_FDIV_MASK) | div;
#else
(void)div; /* Unused parameter */
#endif /* defined(LCD_PRESENT) */
}
/***************************************************************************//**
* @brief
* Enable/disable oscillator.
*
* @note
* WARNING: When this function is called to disable either cmuOsc_LFXO or
* cmuOsc_HFXO the LFXOMODE or HFXOMODE fields of the CMU_CTRL register
* are reset to the reset value. I.e. if external clock sources are selected
* in either LFXOMODE or HFXOMODE fields, the configuration will be cleared
* and needs to be reconfigured if needed later.
*
* @param[in] osc
* The oscillator to enable/disable.
*
* @param[in] enable
* @li true - enable specified oscillator.
* @li false - disable specified oscillator.
*
* @param[in] wait
* Only used if @p enable is true.
* @li true - wait for oscillator start-up time to timeout before returning.
* @li false - do not wait for oscillator start-up time to timeout before
* returning.
******************************************************************************/
void CMU_OscillatorEnable(CMU_Osc_TypeDef osc, bool enable, bool wait)
{
uint32_t status;
uint32_t enBit;
uint32_t disBit;
switch (osc)
{
case cmuOsc_HFRCO:
enBit = CMU_OSCENCMD_HFRCOEN;
disBit = CMU_OSCENCMD_HFRCODIS;
status = CMU_STATUS_HFRCORDY;
break;
case cmuOsc_HFXO:
enBit = CMU_OSCENCMD_HFXOEN;
disBit = CMU_OSCENCMD_HFXODIS;
status = CMU_STATUS_HFXORDY;
break;
case cmuOsc_AUXHFRCO:
enBit = CMU_OSCENCMD_AUXHFRCOEN;
disBit = CMU_OSCENCMD_AUXHFRCODIS;
status = CMU_STATUS_AUXHFRCORDY;
break;
case cmuOsc_LFRCO:
enBit = CMU_OSCENCMD_LFRCOEN;
disBit = CMU_OSCENCMD_LFRCODIS;
status = CMU_STATUS_LFRCORDY;
break;
case cmuOsc_LFXO:
enBit = CMU_OSCENCMD_LFXOEN;
disBit = CMU_OSCENCMD_LFXODIS;
status = CMU_STATUS_LFXORDY;
break;
#if defined _CMU_LFCLKSEL_LFAE_ULFRCO
case cmuOsc_ULFRCO:
/* ULFRCO is always enabled, and cannot be turned off */
return;
#endif
default:
/* Undefined clock source */
EFM_ASSERT(0);
return;
}
if (enable)
{
CMU->OSCENCMD = enBit;
/* Wait for clock to stabilize if requested */
if (wait)
{
while (!(CMU->STATUS & status))
;
}
}
else
{
CMU->OSCENCMD = disBit;
}
/* Keep EMU module informed */
EMU_UpdateOscConfig();
}
/***************************************************************************//**
* @brief
* Get oscillator frequency tuning setting.
*
* @param[in] osc
* Oscillator to get tuning value for, one of:
* @li #cmuOsc_LFRCO
* @li #cmuOsc_HFRCO
* @li #cmuOsc_AUXHFRCO
*
* @return
* The oscillator frequency tuning setting in use.
******************************************************************************/
uint32_t CMU_OscillatorTuningGet(CMU_Osc_TypeDef osc)
{
uint32_t ret;
switch (osc)
{
case cmuOsc_LFRCO:
ret = (CMU->LFRCOCTRL & _CMU_LFRCOCTRL_TUNING_MASK) >>
_CMU_LFRCOCTRL_TUNING_SHIFT;
break;
case cmuOsc_HFRCO:
ret = (CMU->HFRCOCTRL & _CMU_HFRCOCTRL_TUNING_MASK) >>
_CMU_HFRCOCTRL_TUNING_SHIFT;
break;
case cmuOsc_AUXHFRCO:
ret = (CMU->AUXHFRCOCTRL & _CMU_AUXHFRCOCTRL_TUNING_MASK) >>
_CMU_AUXHFRCOCTRL_TUNING_SHIFT;
break;
default:
EFM_ASSERT(0);
ret = 0;
break;
}
return(ret);
}
/***************************************************************************//**
* @brief
* Set the oscillator frequency tuning control.
*
* @note
* Oscillator tuning is done during production, and the tuning value is
* automatically loaded after a reset. Changing the tuning value from the
* calibrated value is for more advanced use.
*
* @param[in] osc
* Oscillator to set tuning value for, one of:
* @li #cmuOsc_LFRCO
* @li #cmuOsc_HFRCO
* @li #cmuOsc_AUXHFRCO
*
* @param[in] val
* The oscillator frequency tuning setting to use.
******************************************************************************/
void CMU_OscillatorTuningSet(CMU_Osc_TypeDef osc, uint32_t val)
{
switch (osc)
{
case cmuOsc_LFRCO:
EFM_ASSERT(val <= (_CMU_LFRCOCTRL_TUNING_MASK >> _CMU_LFRCOCTRL_TUNING_SHIFT));
val &= (_CMU_LFRCOCTRL_TUNING_MASK >> _CMU_LFRCOCTRL_TUNING_SHIFT);
CMU->LFRCOCTRL = (CMU->LFRCOCTRL & ~(_CMU_LFRCOCTRL_TUNING_MASK)) |
(val << _CMU_LFRCOCTRL_TUNING_SHIFT);
break;
case cmuOsc_HFRCO:
EFM_ASSERT(val <= (_CMU_HFRCOCTRL_TUNING_MASK >> _CMU_HFRCOCTRL_TUNING_SHIFT));
val &= (_CMU_HFRCOCTRL_TUNING_MASK >> _CMU_HFRCOCTRL_TUNING_SHIFT);
CMU->HFRCOCTRL = (CMU->HFRCOCTRL & ~(_CMU_HFRCOCTRL_TUNING_MASK)) |
(val << _CMU_HFRCOCTRL_TUNING_SHIFT);
break;
case cmuOsc_AUXHFRCO:
EFM_ASSERT(val <= (_CMU_AUXHFRCOCTRL_TUNING_MASK >> _CMU_AUXHFRCOCTRL_TUNING_SHIFT));
val <<= _CMU_AUXHFRCOCTRL_TUNING_SHIFT;
val &= _CMU_AUXHFRCOCTRL_TUNING_MASK;
CMU->AUXHFRCOCTRL = (CMU->AUXHFRCOCTRL & ~(_CMU_AUXHFRCOCTRL_TUNING_MASK)) | val;
break;
default:
EFM_ASSERT(0);
break;
}
}
/**************************************************************************//**
* @brief
* Determine if currently selected PCNTn clock used is external or LFBCLK.
*
* @param[in] inst
* PCNT instance number to get currently selected clock source for.
*
* @return
* @li true - selected clock is external clock.
* @li false - selected clock is LFBCLK.
*****************************************************************************/
bool CMU_PCNTClockExternalGet(unsigned int inst)
{
bool ret;
uint32_t setting;
switch (inst)
{
#if defined(_CMU_PCNTCTRL_PCNT0CLKEN_MASK)
case 0:
setting = CMU->PCNTCTRL & CMU_PCNTCTRL_PCNT0CLKSEL_PCNT0S0;
break;
#if defined(_CMU_PCNTCTRL_PCNT1CLKEN_MASK)
case 1:
setting = CMU->PCNTCTRL & CMU_PCNTCTRL_PCNT1CLKSEL_PCNT1S0;
break;
#if defined(_CMU_PCNTCTRL_PCNT2CLKEN_MASK)
case 2:
setting = CMU->PCNTCTRL & CMU_PCNTCTRL_PCNT2CLKSEL_PCNT2S0;
break;
#endif
#endif
#endif
default:
setting = 0;
break;
}
if (setting)
{
ret = true;
}
else
{
ret = false;
}
return ret;
}
/**************************************************************************//**
* @brief
* Select PCNTn clock.
*
* @param[in] inst
* PCNT instance number to set selected clock source for.
*
* @param[in] external
* Set to true to select external clock, false to select LFBCLK.
*****************************************************************************/
void CMU_PCNTClockExternalSet(unsigned int inst, bool external)
{
#if defined(PCNT_PRESENT)
uint32_t setting = 0;
EFM_ASSERT(inst < PCNT_COUNT);
if (external)
{
setting = 1;
}
BITBAND_Peripheral(&(CMU->PCNTCTRL), (inst * 2) + 1, setting);
#else
(void)inst; /* Unused parameter */
(void)external; /* Unused parameter */
#endif
}
/** @} (end addtogroup CMU) */
/** @} (end addtogroup EM_Library) */
#endif /* __EM_CMU_H */
/***************************************************************************//**
* @file
* @brief Energy Management Unit (EMU) Peripheral API
* @author Energy Micro AS
* @version 3.20.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_emu.h"
#if defined( EMU_PRESENT )
#include "em_cmu.h"
#include "em_assert.h"
/***************************************************************************//**
* @addtogroup EM_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup EMU
* @brief Energy Management Unit (EMU) Peripheral API
* @{
******************************************************************************/
/* Consistency check, since restoring assumes similar bitpositions in */
/* CMU OSCENCMD and STATUS regs */
#if (CMU_STATUS_AUXHFRCOENS != CMU_OSCENCMD_AUXHFRCOEN)
#error Conflict in AUXHFRCOENS and AUXHFRCOEN bitpositions
#endif
#if (CMU_STATUS_HFXOENS != CMU_OSCENCMD_HFXOEN)
#error Conflict in HFXOENS and HFXOEN bitpositions
#endif
#if (CMU_STATUS_LFRCOENS != CMU_OSCENCMD_LFRCOEN)
#error Conflict in LFRCOENS and LFRCOEN bitpositions
#endif
#if (CMU_STATUS_LFXOENS != CMU_OSCENCMD_LFXOEN)
#error Conflict in LFXOENS and LFXOEN bitpositions
#endif
/*******************************************************************************
************************** LOCAL VARIABLES ********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/**
* CMU configured oscillator selection and oscillator enable status. When a
* user configures oscillators, this varaiable shall shadow the configuration.
* It is used by the EMU module in order to be able to restore the oscillator
* config after having been in certain energy modes (since HW may automatically
* alter config when going into an energy mode). It is the responsibility of
* the CMU module to keep it up-to-date (or a user if not using the CMU API
* for oscillator control).
*/
static uint16_t cmuStatus;
/** @endcond */
/*******************************************************************************
************************** LOCAL FUNCTIONS ********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/***************************************************************************//**
* @brief
* Restore oscillators and core clock after having been in EM2 or EM3.
******************************************************************************/
static void EMU_Restore(void)
{
uint32_t cmuLocked;
/* Although we could use the CMU API for most of the below handling, we */
/* would like this function to be as efficient as possible. */
/* CMU registers may be locked */
cmuLocked = CMU->LOCK & CMU_LOCK_LOCKKEY_LOCKED;
CMU_Unlock();
/* AUXHFRCO was automatically disabled (except if using debugger). */
/* HFXO was automatically disabled. */
/* LFRCO/LFXO were possibly disabled by SW in EM3. */
/* Restore according to status prior to entering EM. */
CMU->OSCENCMD = cmuStatus & (CMU_STATUS_AUXHFRCOENS |
CMU_STATUS_HFXOENS |
CMU_STATUS_LFRCOENS |
CMU_STATUS_LFXOENS);
/* Restore oscillator used for clocking core */
switch (cmuStatus & (CMU_STATUS_HFXOSEL | CMU_STATUS_HFRCOSEL |
CMU_STATUS_LFXOSEL | CMU_STATUS_LFRCOSEL))
{
case CMU_STATUS_LFRCOSEL:
/* Wait for LFRCO to stabilize */
while (!(CMU->STATUS & CMU_STATUS_LFRCORDY))
;
CMU->CMD = CMU_CMD_HFCLKSEL_LFRCO;
break;
case CMU_STATUS_LFXOSEL:
/* Wait for LFXO to stabilize */
while (!(CMU->STATUS & CMU_STATUS_LFXORDY))
;
CMU->CMD = CMU_CMD_HFCLKSEL_LFXO;
break;
case CMU_STATUS_HFXOSEL:
/* Wait for HFXO to stabilize */
while (!(CMU->STATUS & CMU_STATUS_HFXORDY))
;
CMU->CMD = CMU_CMD_HFCLKSEL_HFXO;
break;
default: /* CMU_STATUS_HFRCOSEL */
/* If core clock was HFRCO core clock, it is automatically restored to */
/* state prior to entering energy mode. No need for further action. */
break;
}
/* If HFRCO was disabled before entering Energy Mode, turn it off again */
/* as it is automatically enabled by wake up */
if ( ! (cmuStatus & CMU_STATUS_HFRCOENS) )
{
CMU->OSCENCMD = CMU_OSCENCMD_HFRCODIS;
}
/* Restore CMU register locking */
if (cmuLocked)
{
CMU_Lock();
}
}
/** @endcond */
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Enter energy mode 2 (EM2).
*
* @details
* When entering EM2, the high frequency clocks are disabled, ie HFXO, HFRCO
* and AUXHFRCO (for AUXHFRCO, see exception note below). When re-entering
* EM0, HFRCO is re-enabled and the core will be clocked by the configured
* HFRCO band. This ensures a quick wakeup from EM2.
*
* However, prior to entering EM2, the core may have been using another
* oscillator than HFRCO. The @p restore parameter gives the user the option
* to restore all HF oscillators according to state prior to entering EM2,
* as well as the clock used to clock the core. This restore procedure is
* handled by SW. However, since handled by SW, it will not be restored
* before completing the interrupt function(s) waking up the core!
*
* @note
* If restoring core clock to use the HFXO oscillator, which has been
* disabled during EM2 mode, this function will stall until the oscillator
* has stabilized. Stalling time can be reduced by adding interrupt
* support detecting stable oscillator, and an asynchronous switch to the
* original oscillator. See CMU documentation. Such a feature is however
* outside the scope of the implementation in this function.
* @par
* If HFXO is re-enabled by this function, and NOT used to clock the core,
* this function will not wait for HFXO to stabilize. This must be considered
* by the application if trying to use features relying on that oscillator
* upon return.
* @par
* If a debugger is attached, the AUXHFRCO will not be disabled if enabled
* upon entering EM2. It will thus remain enabled when returning to EM0
* regardless of the @p restore parameter.
*
* @param[in] restore
* @li true - restore oscillators and clocks, see function details.
* @li false - do not restore oscillators and clocks, see function details.
* @par
* The @p restore option should only be used if all clock control is done
* via the CMU API.
******************************************************************************/
void EMU_EnterEM2(bool restore)
{
/* Auto-update CMU status just in case before entering energy mode. */
/* This variable is normally kept up-to-date by the CMU API. */
cmuStatus = (uint16_t)(CMU->STATUS);
/* Enter Cortex-M3 deep sleep mode */
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
__WFI();
/* Restore oscillators/clocks if specified */
if (restore)
{
EMU_Restore();
}
/* If not restoring, and original clock was not HFRCO, we have to */
/* update CMSIS core clock variable since core clock has changed */
/* to using HFRCO. */
else if (!(cmuStatus & CMU_STATUS_HFRCOSEL))
{
SystemCoreClockUpdate();
}
}
/***************************************************************************//**
* @brief
* Enter energy mode 3 (EM3).
*
* @details
* When entering EM3, the high frequency clocks are disabled by HW, ie HFXO,
* HFRCO and AUXHFRCO (for AUXHFRCO, see exception note below). In addition,
* the low frequency clocks, ie LFXO and LFRCO are disabled by SW. When
* re-entering EM0, HFRCO is re-enabled and the core will be clocked by the
* configured HFRCO band. This ensures a quick wakeup from EM3.
*
* However, prior to entering EM3, the core may have been using another
* oscillator than HFRCO. The @p restore parameter gives the user the option
* to restore all HF/LF oscillators according to state prior to entering EM3,
* as well as the clock used to clock the core. This restore procedure is
* handled by SW. However, since handled by SW, it will not be restored
* before completing the interrupt function(s) waking up the core!
*
* @note
* If restoring core clock to use an oscillator other than HFRCO, this
* function will stall until the oscillator has stabilized. Stalling time
* can be reduced by adding interrupt support detecting stable oscillator,
* and an asynchronous switch to the original oscillator. See CMU
* documentation. Such a feature is however outside the scope of the
* implementation in this function.
* @par
* If HFXO/LFXO/LFRCO are re-enabled by this function, and NOT used to clock
* the core, this function will not wait for those oscillators to stabilize.
* This must be considered by the application if trying to use features
* relying on those oscillators upon return.
* @par
* If a debugger is attached, the AUXHFRCO will not be disabled if enabled
* upon entering EM3. It will thus remain enabled when returning to EM0
* regardless of the @p restore parameter.
*
* @param[in] restore
* @li true - restore oscillators and clocks, see function details.
* @li false - do not restore oscillators and clocks, see function details.
* @par
* The @p restore option should only be used if all clock control is done
* via the CMU API.
******************************************************************************/
void EMU_EnterEM3(bool restore)
{
uint32_t cmuLocked;
/* Auto-update CMU status just in case before entering energy mode. */
/* This variable is normally kept up-to-date by the CMU API. */
cmuStatus = (uint16_t)(CMU->STATUS);
/* CMU registers may be locked */
cmuLocked = CMU->LOCK & CMU_LOCK_LOCKKEY_LOCKED;
CMU_Unlock();
/* Disable LF oscillators */
CMU->OSCENCMD = CMU_OSCENCMD_LFXODIS | CMU_OSCENCMD_LFRCODIS;
/* Restore CMU register locking */
if (cmuLocked)
{
CMU_Lock();
}
/* Enter Cortex-M3 deep sleep mode */
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
__WFI();
/* Restore oscillators/clocks if specified */
if (restore)
{
EMU_Restore();
}
/* If not restoring, and original clock was not HFRCO, we have to */
/* update CMSIS core clock variable since core clock has changed */
/* to using HFRCO. */
else if (!(cmuStatus & CMU_STATUS_HFRCOSEL))
{
SystemCoreClockUpdate();
}
}
/***************************************************************************//**
* @brief
* Enter energy mode 4 (EM4).
*
* @note
* Only a power on reset or external reset pin can wake the device from EM4.
******************************************************************************/
void EMU_EnterEM4(void)
{
int i;
/* Make sure register write lock is disabled */
EMU->LOCK = EMU_LOCK_LOCKKEY_UNLOCK;
for (i = 0; i < 4; i++)
{
EMU->CTRL = (2 << _EMU_CTRL_EM4CTRL_SHIFT);
EMU->CTRL = (3 << _EMU_CTRL_EM4CTRL_SHIFT);
}
EMU->CTRL = (2 << _EMU_CTRL_EM4CTRL_SHIFT);
}
/***************************************************************************//**
* @brief
* Power down memory block.
*
* @param[in] blocks
* Specifies a logical OR of bits indicating memory blocks to power down.
* Bit 0 selects block 1, bit 1 selects block 2, etc. Memory block 0 cannot
* be disabled. Please refer to the EFM32 reference manual for available
* memory blocks for a device.
*
* @note
* Only a reset can make the specified memory block(s) available for use
* after having been powered down. Function will be void for devices not
* supporting this feature.
******************************************************************************/
void EMU_MemPwrDown(uint32_t blocks)
{
#if defined(_EMU_MEMCTRL_RESETVALUE)
EFM_ASSERT(blocks <= _EMU_MEMCTRL_MASK);
EMU->MEMCTRL = blocks;
#else
(void)blocks;
#endif
}
/***************************************************************************//**
* @brief
* Update EMU module with CMU oscillator selection/enable status.
*
* @details
* When entering EM2 and EM3, the HW may change the core clock oscillator
* used, as well as disabling some oscillators. The user may optionally select
* to restore the oscillators after waking up from EM2 and EM3 through the
* SW API.
*
* However, in order to support this in a safe way, the EMU module must
* be kept up-to-date on the actual selected configuration. The CMU
* module must keep the EMU module up-to-date.
*
* This function is mainly intended for internal use by the CMU module,
* but if the applications changes oscillator configurations without
* using the CMU API, this function can be used to keep the EMU module
* up-to-date.
******************************************************************************/
void EMU_UpdateOscConfig(void)
{
/* Fetch current configuration */
cmuStatus = (uint16_t)(CMU->STATUS);
}
#if defined( _EMU_EM4CONF_MASK )
/***************************************************************************//**
* @brief
* Update EMU module with Energy Mode 4 configuration
*
* @param[in] em4init
* Energy Mode 4 configuration structure
******************************************************************************/
void EMU_EM4Init(EMU_EM4Init_TypeDef *em4init)
{
uint32_t em4conf = EMU->EM4CONF;
/* Clear fields that will be reconfigured */
em4conf &= ~(
_EMU_EM4CONF_LOCKCONF_MASK|
_EMU_EM4CONF_OSC_MASK|
_EMU_EM4CONF_BURTCWU_MASK|
_EMU_EM4CONF_VREGEN_MASK);
/* Configure new settings */
em4conf |= (
(em4init->lockConfig << _EMU_EM4CONF_LOCKCONF_SHIFT)|
(em4init->osc)|
(em4init->buRtcWakeup << _EMU_EM4CONF_BURTCWU_SHIFT)|
(em4init->vreg << _EMU_EM4CONF_VREGEN_SHIFT));
/* Apply configuration. Note that lock can be set after this stage. */
EMU->EM4CONF = em4conf;
}
/***************************************************************************//**
* @brief
* Configure Backup Power Domain settings
*
* @param[in] bupdInit
* Backup power domain initialization structure
******************************************************************************/
void EMU_BUPDInit(EMU_BUPDInit_TypeDef *bupdInit)
{
uint32_t reg;
/* Set power connection configuration */
reg = EMU->PWRCONF & ~(
_EMU_PWRCONF_PWRRES_MASK|
_EMU_PWRCONF_VOUTSTRONG_MASK|
_EMU_PWRCONF_VOUTMED_MASK|
_EMU_PWRCONF_VOUTWEAK_MASK);
reg |= (bupdInit->resistor|
(bupdInit->voutStrong << _EMU_PWRCONF_VOUTSTRONG_SHIFT)|
(bupdInit->voutMed << _EMU_PWRCONF_VOUTMED_SHIFT)|
(bupdInit->voutWeak << _EMU_PWRCONF_VOUTWEAK_SHIFT));
EMU->PWRCONF = reg;
/* Set backup domain inactive mode configuration */
reg = EMU->BUINACT & ~(_EMU_BUINACT_PWRCON_MASK);
reg |= (bupdInit->inactivePower);
EMU->BUINACT = reg;
/* Set backup domain active mode configuration */
reg = EMU->BUACT & ~(_EMU_BUACT_PWRCON_MASK);
reg |= (bupdInit->activePower);
EMU->BUACT = reg;
/* Set power control configuration */
reg = EMU->BUCTRL & ~(
_EMU_BUCTRL_PROBE_MASK|
_EMU_BUCTRL_BODCAL_MASK|
_EMU_BUCTRL_STATEN_MASK|
_EMU_BUCTRL_EN_MASK);
/* Note use of ->enable to both enable BUPD, use BU_VIN pin input and
release reset */
reg |= (bupdInit->probe|
(bupdInit->bodCal << _EMU_BUCTRL_BODCAL_SHIFT)|
(bupdInit->statusPinEnable << _EMU_BUCTRL_STATEN_SHIFT)|
(bupdInit->enable << _EMU_BUCTRL_EN_SHIFT));
/* Enable configuration */
EMU->BUCTRL = reg;
/* If enable is true, enable BU_VIN input power pin, if not disable it */
EMU_BUPinEnable(bupdInit->enable);
/* If enable is true, release BU reset, if not keep reset asserted */
BITBAND_Peripheral(&(RMU->CTRL), _RMU_CTRL_BURSTEN_SHIFT, !bupdInit->enable);
}
/***************************************************************************//**
* @brief
* Configure Backup Power Domain BOD Threshold value
* @note
* These values are precalibrated
* @param[in] mode Active or Inactive mode
* @param[in] value
******************************************************************************/
void EMU_BUThresholdSet(EMU_BODMode_TypeDef mode, uint32_t value)
{
EFM_ASSERT(value<=(_EMU_BUACT_BUEXTHRES_MASK>>_EMU_BUACT_BUEXTHRES_SHIFT));
switch(mode)
{
case emuBODMode_Active:
EMU->BUACT = (EMU->BUACT & ~(_EMU_BUACT_BUEXTHRES_MASK))|(value<<_EMU_BUACT_BUEXTHRES_SHIFT);
break;
case emuBODMode_Inactive:
EMU->BUINACT = (EMU->BUINACT & ~(_EMU_BUINACT_BUENTHRES_MASK))|(value<<_EMU_BUINACT_BUENTHRES_SHIFT);
break;
}
}
/***************************************************************************//**
* @brief
* Configure Backup Power Domain BOD Threshold Range
* @note
* These values are precalibrated
* @param[in] mode Active or Inactive mode
* @param[in] value
******************************************************************************/
void EMU_BUThresRangeSet(EMU_BODMode_TypeDef mode, uint32_t value)
{
EFM_ASSERT(value<=(_EMU_BUACT_BUEXRANGE_MASK>>_EMU_BUACT_BUEXRANGE_SHIFT));
switch(mode)
{
case emuBODMode_Active:
EMU->BUACT = (EMU->BUACT & ~(_EMU_BUACT_BUEXRANGE_MASK))|(value<<_EMU_BUACT_BUEXRANGE_SHIFT);
break;
case emuBODMode_Inactive:
EMU->BUINACT = (EMU->BUINACT & ~(_EMU_BUINACT_BUENRANGE_MASK))|(value<<_EMU_BUINACT_BUENRANGE_SHIFT);
break;
}
}
#endif
/** @} (end addtogroup EMU) */
/** @} (end addtogroup EM_Library) */
#endif /* __EM_EMU_H */
/***************************************************************************//**
* @file
* @brief General Purpose IO (GPIO) peripheral API
* devices.
* @author Energy Micro AS
* @version 3.20.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_gpio.h"
#if defined(GPIO_COUNT) && (GPIO_COUNT > 0)
/***************************************************************************//**
* @addtogroup EM_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup GPIO
* @brief General Purpose Input/Output (GPIO) API
* @{
******************************************************************************/
/*******************************************************************************
******************************* DEFINES ***********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** Validation of pin typically usable in assert statements. */
#define GPIO_DRIVEMODE_VALID(mode) ((mode) <= 3)
/** @endcond */
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Sets the pin location of the debug pins (Serial Wire interface).
*
* @note
* Changing the pins used for debugging uncontrolled, may result in a lockout.
*
* @param[in] location
* The debug pin location to use (0-3).
******************************************************************************/
void GPIO_DbgLocationSet(unsigned int location)
{
#if defined ( _GPIO_ROUTE_SWLOCATION_MASK )
EFM_ASSERT(location < AFCHANLOC_MAX);
GPIO->ROUTE = (GPIO->ROUTE & ~_GPIO_ROUTE_SWLOCATION_MASK) |
(location << _GPIO_ROUTE_SWLOCATION_SHIFT);
#else
(void)location;
#endif
}
/***************************************************************************//**
* @brief
* Sets the drive mode for a GPIO port.
*
* @param[in] port
* The GPIO port to access.
*
* @param[in] mode
* Drive mode to use for port.
******************************************************************************/
void GPIO_DriveModeSet(GPIO_Port_TypeDef port, GPIO_DriveMode_TypeDef mode)
{
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_DRIVEMODE_VALID(mode));
GPIO->P[port].CTRL = (GPIO->P[port].CTRL & ~(_GPIO_P_CTRL_DRIVEMODE_MASK))
| (mode << _GPIO_P_CTRL_DRIVEMODE_SHIFT);
}
/***************************************************************************//**
* @brief
* Configure GPIO interrupt.
*
* @details
* If reconfiguring a GPIO interrupt that is already enabled, it is generally
* recommended to disable it first, see GPIO_Disable().
*
* The actual GPIO interrupt handler must be in place before enabling the
* interrupt.
*
* Notice that any pending interrupt for the selected pin is cleared by this
* function.
*
* @note
* A certain pin number can only be associated with one port. Ie, if GPIO
* interrupt 1 is assigned to port A/pin 1, then it is not possibly to use
* pin 1 from any other ports for interrupts. Please refer to the reference
* manual.
*
* @param[in] port
* The port to associate with @p pin.
*
* @param[in] pin
* The GPIO interrupt number (= port pin).
*
* @param[in] risingEdge
* Set to true if interrupts shall be enabled on rising edge, otherwise false.
*
* @param[in] fallingEdge
* Set to true if interrupts shall be enabled on falling edge, otherwise false.
*
* @param[in] enable
* Set to true if interrupt shall be enabled after configuration completed,
* false to leave disabled. See GPIO_IntDisable() and GPIO_IntEnable().
******************************************************************************/
void GPIO_IntConfig(GPIO_Port_TypeDef port,
unsigned int pin,
bool risingEdge,
bool fallingEdge,
bool enable)
{
uint32_t tmp;
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_PIN_VALID(pin));
/* There are two registers controlling the interrupt configuration:
* The EXTIPSELL register controls pins 0-7 and EXTIPSELH controls
* pins 8-15. */
if (pin < 8)
{
GPIO->EXTIPSELL = (GPIO->EXTIPSELL & ~(0xF << (4 * pin))) |
(port << (4 * pin));
}
else
{
tmp = pin - 8;
GPIO->EXTIPSELH = (GPIO->EXTIPSELH & ~(0xF << (4 * tmp))) |
(port << (4 * tmp));
}
/* Enable/disable rising edge */
BITBAND_Peripheral(&(GPIO->EXTIRISE), pin, (unsigned int)risingEdge);
/* Enable/disable falling edge */
BITBAND_Peripheral(&(GPIO->EXTIFALL), pin, (unsigned int)fallingEdge);
/* Clear any pending interrupt */
GPIO->IFC = 1 << pin;
/* Finally enable/disable interrupt */
BITBAND_Peripheral(&(GPIO->IEN), pin, (unsigned int)enable);
}
/***************************************************************************//**
* @brief
* Set the mode for a GPIO pin.
*
* @param[in] port
* The GPIO port to access.
*
* @param[in] pin
* The pin number in the port.
*
* @param[in] mode
* The desired pin mode.
*
* @param[in] out
* Value to set for pin in DOUT register. The DOUT setting is important for
* even some input mode configurations, determining pull-up/down direction.
******************************************************************************/
void GPIO_PinModeSet(GPIO_Port_TypeDef port,
unsigned int pin,
GPIO_Mode_TypeDef mode,
unsigned int out)
{
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_PIN_VALID(pin));
/* If disabling pin, do not modify DOUT in order to reduce chance for */
/* glitch/spike (may not be sufficient precaution in all use cases) */
if (mode != gpioModeDisabled)
{
if (out)
{
GPIO->P[port].DOUTSET = 1 << pin;
}
else
{
GPIO->P[port].DOUTCLR = 1 << pin;
}
}
/* There are two registers controlling the pins for each port. The MODEL
* register controls pins 0-7 and MODEH controls pins 8-15. */
if (pin < 8)
{
GPIO->P[port].MODEL = (GPIO->P[port].MODEL & ~(0xF << (pin * 4))) |
(mode << (pin * 4));
}
else
{
GPIO->P[port].MODEH = (GPIO->P[port].MODEH & ~(0xF << ((pin - 8) * 4))) |
(mode << ((pin - 8) * 4));
}
if (mode == gpioModeDisabled)
{
if (out)
{
GPIO->P[port].DOUTSET = 1 << pin;
}
else
{
GPIO->P[port].DOUTCLR = 1 << pin;
}
}
}
/** @} (end addtogroup GPIO) */
/** @} (end addtogroup EM_Library) */
#endif /* defined(GPIO_COUNT) && (GPIO_COUNT > 0) */
/**************************************************************************//**
* @file
* @brief Interrupt enable/disable unit API
* @author Energy Micro AS
* @version 3.20.2
******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include <stdint.h>
#include "em_int.h"
/***************************************************************************//**
* @addtogroup EM_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup INT
* @brief Safe nesting interrupt disable/enable API
* @{
* @details
* This module contains functions to safely disable and enable interrupts
* at cpu level. INT_Disable() disables interrupts and increments a lock
* level counter. INT_Enable() decrements the lock level counter and enable
* interrupts if the counter was decremented to zero.
*
* These functions would normally be used to secure critical regions.
*
* These functions should also be used inside interrupt handlers:
* @verbatim
* void SysTick_Handler(void)
* {
* INT_Disable();
* .
* .
* .
* INT_Enable();
* }
* @endverbatim
******************************************************************************/
/** Interrupt lock level counter. Set to zero initially as we normally enter
* main with interrupts enabled */
uint32_t INT_LockCnt = 0;
/** @} (end addtogroup INT) */
/** @} (end addtogroup EM_Library) */
/***************************************************************************//**
* @file
* @brief Liquid Crystal Display (LCD) Peripheral API
* @author Energy Micro AS
* @version 3.20.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_lcd.h"
#if defined(LCD_COUNT) && (LCD_COUNT > 0)
#include "em_assert.h"
#include "em_bitband.h"
/***************************************************************************//**
* @addtogroup EM_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup LCD
* @brief Liquid Crystal Display (LCD) Peripheral API
* @{
******************************************************************************/
/***************************************************************************//**
* @brief
* Initalize Liquid Crystal Display (LCD) controller
*
* @details
* This function call will only configure the LCD controller. You must enable
* it afterwards, potentially configuring Frame Control and interrupts first
* according to requirements.
*
* @param[in] lcdInit
* Pointer to initialization structure which configures LCD controller.
*
******************************************************************************/
void LCD_Init(const LCD_Init_TypeDef *lcdInit)
{
uint32_t dispCtrl = LCD->DISPCTRL;
EFM_ASSERT(lcdInit != (void *) 0);
/* Disable controller before reconfiguration */
LCD_Enable(false);
/* Make sure we don't touch other bit fields (i.e. voltage boost) */
dispCtrl &= ~(
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
_LCD_DISPCTRL_MUXE_MASK |
#endif
_LCD_DISPCTRL_MUX_MASK |
_LCD_DISPCTRL_BIAS_MASK |
_LCD_DISPCTRL_WAVE_MASK |
_LCD_DISPCTRL_VLCDSEL_MASK |
_LCD_DISPCTRL_CONCONF_MASK);
/* Configure controller according to initialization structure */
dispCtrl |= lcdInit->mux; /* also configures MUXE */
dispCtrl |= lcdInit->bias;
dispCtrl |= lcdInit->wave;
dispCtrl |= lcdInit->vlcd;
dispCtrl |= lcdInit->contrast;
/* Update display controller */
LCD->DISPCTRL = dispCtrl;
/* Enable controller if wanted */
if (lcdInit->enable)
{
LCD_Enable(true);
}
}
/***************************************************************************//**
* @brief
* Select source for VLCD
*
* @param[in] vlcd
* Select source for VLD voltage
******************************************************************************/
void LCD_VLCDSelect(LCD_VLCDSel_TypeDef vlcd)
{
uint32_t dispctrl = LCD->DISPCTRL;
/* Select VEXT or VDD */
dispctrl &= ~(_LCD_DISPCTRL_VLCDSEL_MASK);
switch (vlcd)
{
case lcdVLCDSelVExtBoost:
dispctrl |= LCD_DISPCTRL_VLCDSEL_VEXTBOOST;
break;
case lcdVLCDSelVDD:
dispctrl |= LCD_DISPCTRL_VLCDSEL_VDD;
break;
default:
break;
}
LCD->DISPCTRL = dispctrl;
}
/***************************************************************************//**
* @brief
* Configure Update Control
*
* @param[in] ud
* Configures LCD update method
******************************************************************************/
void LCD_UpdateCtrl(LCD_UpdateCtrl_TypeDef ud)
{
LCD->CTRL = (LCD->CTRL & ~_LCD_CTRL_UDCTRL_MASK) | ud;
}
/***************************************************************************//**
* @brief
* Initialize LCD Frame Counter
*
* @param[in] fcInit
* Pointer to Frame Counter initialization structure
******************************************************************************/
void LCD_FrameCountInit(const LCD_FrameCountInit_TypeDef *fcInit)
{
uint32_t bactrl = LCD->BACTRL;
EFM_ASSERT(fcInit != (void *) 0);
/* Verify FC Top Counter to be within limits */
EFM_ASSERT(fcInit->top < 64);
/* Reconfigure frame count configuration */
bactrl &= ~(_LCD_BACTRL_FCTOP_MASK |
_LCD_BACTRL_FCPRESC_MASK);
bactrl |= (fcInit->top << _LCD_BACTRL_FCTOP_SHIFT);
bactrl |= fcInit->prescale;
/* Set Blink and Animation Control Register */
LCD->BACTRL = bactrl;
LCD_FrameCountEnable(fcInit->enable);
}
/***************************************************************************//**
* @brief
* Configures LCD controller Animation feature
*
* @param[in] animInit
* Pointer to LCD Animation initialization structure
******************************************************************************/
void LCD_AnimInit(const LCD_AnimInit_TypeDef *animInit)
{
uint32_t bactrl = LCD->BACTRL;
EFM_ASSERT(animInit != (void *) 0);
/* Set Animation Register Values */
LCD->AREGA = animInit->AReg;
LCD->AREGB = animInit->BReg;
/* Configure Animation Shift and Logic */
bactrl &= ~(_LCD_BACTRL_AREGASC_MASK |
_LCD_BACTRL_AREGBSC_MASK |
_LCD_BACTRL_ALOGSEL_MASK);
bactrl |= (animInit->AShift << _LCD_BACTRL_AREGASC_SHIFT);
bactrl |= (animInit->BShift << _LCD_BACTRL_AREGBSC_SHIFT);
bactrl |= animInit->animLogic;
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
bactrl &= ~(_LCD_BACTRL_ALOC_MASK);
if(animInit->startSeg == 0)
{
bactrl |= LCD_BACTRL_ALOC_SEG0TO7;
}
else if(animInit->startSeg == 8)
{
bactrl |= LCD_BACTRL_ALOC_SEG8TO15;
}
#endif
/* Reconfigure */
LCD->BACTRL = bactrl;
/* Enable */
LCD_AnimEnable(animInit->enable);
}
/***************************************************************************//**
* @brief
* Enables update of this range of LCD segment lines
*
* @param[in] segmentRange
* Range of 4 LCD segments lines to enable or disable, for all enabled COM
* lines
*
* @param[in] enable
* Bool true to enable segment updates, false to disable updates
******************************************************************************/
void LCD_SegmentRangeEnable(LCD_SegmentRange_TypeDef segmentRange, bool enable)
{
if (enable)
{
LCD->SEGEN |= segmentRange;
}
else
{
LCD->SEGEN &= ~((uint32_t)segmentRange);
}
}
/***************************************************************************//**
* @brief
* Turn on or clear a segment
*
* @note
* On Gecko Family, max configuration is (COM-lines x Segment-Lines) 4x40
* On Tiny Family, max configuration is 8x20 or 4x24
* On Giant Family, max configuration is 8x36 or 4x40
*
* @param[in] com
* COM line to change
*
* @param[in] bit
* Bit index of which field to change
*
* @param[in] enable
* When true will set segment, when false will clear segment
******************************************************************************/
void LCD_SegmentSet(int com, int bit, bool enable)
{
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
/* Tiny and Giant Family supports up to 8 COM lines */
EFM_ASSERT(com < 8);
#else
/* Gecko Family supports up to 4 COM lines */
EFM_ASSERT(com < 4);
#endif
#if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
EFM_ASSERT(bit < 40);
#else
/* Tiny Gecko Family supports only "low" segment registers */
EFM_ASSERT(bit < 32);
#endif
/* Use bitband access for atomic bit set/clear of segment */
switch (com)
{
case 0:
if (bit < 32)
{
BITBAND_Peripheral(&(LCD->SEGD0L), bit, (unsigned int)enable);
}
#if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
else
{
bit -= 32;
BITBAND_Peripheral(&(LCD->SEGD0H), bit, (unsigned int)enable);
}
#endif
break;
case 1:
if (bit < 32)
{
BITBAND_Peripheral(&(LCD->SEGD1L), bit, (unsigned int)enable);
}
#if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
else
{
bit -= 32;
BITBAND_Peripheral(&(LCD->SEGD1H), bit, (unsigned int)enable);
}
#endif
break;
case 2:
if (bit < 32)
{
BITBAND_Peripheral(&(LCD->SEGD2L), bit, (unsigned int)enable);
}
#if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
else
{
bit -= 32;
BITBAND_Peripheral(&(LCD->SEGD2H), bit, (unsigned int)enable);
}
#endif
break;
case 3:
if (bit < 32)
{
BITBAND_Peripheral(&(LCD->SEGD3L), bit, (unsigned int)enable);
}
#if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
else
{
bit -= 32;
BITBAND_Peripheral(&(LCD->SEGD3H), bit, (unsigned int)enable);
}
#endif
break;
case 4:
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
if (bit < 32)
{
BITBAND_Peripheral(&(LCD->SEGD4L), bit, (unsigned int)enable);
}
#endif
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
else
{
bit -= 32;
BITBAND_Peripheral(&(LCD->SEGD4H), bit, (unsigned int)enable);
}
#endif
break;
case 5:
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
if (bit < 32)
{
BITBAND_Peripheral(&(LCD->SEGD5L), bit, (unsigned int)enable);
}
#endif
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
else
{
bit -= 32;
BITBAND_Peripheral(&(LCD->SEGD5H), bit, (unsigned int)enable);
}
#endif
break;
case 6:
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
if (bit < 32)
{
BITBAND_Peripheral(&(LCD->SEGD6L), bit, (unsigned int)enable);
}
#endif
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
else
{
bit -= 32;
BITBAND_Peripheral(&(LCD->SEGD6H), bit, (unsigned int)enable);
}
#endif
break;
case 7:
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
if (bit < 32)
{
BITBAND_Peripheral(&(LCD->SEGD7L), bit, (unsigned int)enable);
}
#endif
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
else
{
bit -= 32;
BITBAND_Peripheral(&(LCD->SEGD7H), bit, (unsigned int)enable);
}
#endif
break;
default:
EFM_ASSERT(0);
break;
}
}
/***************************************************************************//**
* @brief
* Updates the 0-31 lowest segments on a given COM-line in one operation,
* according to bit mask
*
* @param[in] com
* Which COM line to update
*
* @param[in] mask
* Bit mask for segments 0-31
*
* @param[in] bits
* Bit pattern for segments 0-31
******************************************************************************/
void LCD_SegmentSetLow(int com, uint32_t mask, uint32_t bits)
{
uint32_t segData;
/* Maximum number of com lines */
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
EFM_ASSERT(com < 8);
#else
/* Gecko Family supports up to 4 COM lines */
EFM_ASSERT(com < 4);
#endif
switch (com)
{
case 0:
segData = LCD->SEGD0L;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD0L = segData;
break;
case 1:
segData = LCD->SEGD1L;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD1L = segData;
break;
case 2:
segData = LCD->SEGD2L;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD2L = segData;
break;
case 3:
segData = LCD->SEGD3L;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD3L = segData;
break;
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
case 4:
segData = LCD->SEGD4L;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD4L = segData;
break;
#endif
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
case 5:
segData = LCD->SEGD5L;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD5L = segData;
break;
#endif
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
case 6:
segData = LCD->SEGD6L;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD6L = segData;
break;
#endif
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
case 7:
segData = LCD->SEGD7L;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD7L = segData;
break;
#endif
default:
EFM_ASSERT(0);
break;
}
}
#if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
/***************************************************************************//**
* @brief
* Updated the high (32-39) segments on a given COM-line in one operation
*
* @param[in] com
* Which COM line to update
*
* @param[in] mask
* Bit mask for segments 32-39
*
* @param[in] bits
* Bit pattern for segments 32-39
******************************************************************************/
void LCD_SegmentSetHigh(int com, uint32_t mask, uint32_t bits)
{
uint32_t segData;
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
EFM_ASSERT(com < 8);
#endif
#if defined(_EFM32_GECKO_FAMILY)
EFM_ASSERT(com < 4);
#endif
/* Maximum number of com lines */
switch (com)
{
case 0:
segData = LCD->SEGD0H;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD0H = segData;
break;
case 1:
segData = LCD->SEGD1H;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD1H = segData;
break;
case 2:
segData = LCD->SEGD2H;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD2H = segData;
break;
case 3:
segData = LCD->SEGD3H;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD3H = segData;
break;
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
case 4:
segData = LCD->SEGD4H;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD4H = segData;
break;
#endif
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
case 5:
segData = LCD->SEGD5H;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD5H = segData;
break;
#endif
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
case 6:
segData = LCD->SEGD6H;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD6H = segData;
break;
#endif
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
case 7:
segData = LCD->SEGD7H;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD7H = segData;
break;
#endif
default:
break;
}
}
#endif
/***************************************************************************//**
* @brief
* Configure contrast level on LCD panel
*
* @param[in] level
* Contrast level in the range 0-31
******************************************************************************/
void LCD_ContrastSet(int level)
{
EFM_ASSERT(level < 32);
LCD->DISPCTRL = (LCD->DISPCTRL & ~_LCD_DISPCTRL_CONLEV_MASK)
| (level << _LCD_DISPCTRL_CONLEV_SHIFT);
}
/***************************************************************************//**
* @brief
* Configure voltage booster
*
* The resulting voltage level is described in each part number's data sheet
*
* @param[in] vboost
* Voltage boost level
******************************************************************************/
void LCD_VBoostSet(LCD_VBoostLevel_TypeDef vboost)
{
/* Reconfigure Voltage Boost */
LCD->DISPCTRL = (LCD->DISPCTRL & ~_LCD_DISPCTRL_VBLEV_MASK) | vboost;
}
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
/***************************************************************************//**
* @brief
* Configure bias level for a specific segment line for Direct Segment Control
*
* @note
* When DSC is active, each configuration takes up 4 bits in the Segment
* Registers (SEGD0L/SEGD1H) which defines bias level.
* For optimal use of this feature, the entire SEGD-registers should be set
* at once in a optimized routine, so this function is mainly here to
* demonstrate how to correctly configure the bias levels, and should be used
* with care.
*
* @param[in] segmentLine
* Segment line number
*
* @param[in] biasLevel
* Bias configuration level, 0-4. This value must be within the constraint
* defined by the LCD_DISPCTRL bias setting, see Reference Manual/Datasheet
******************************************************************************/
void LCD_BiasSegmentSet(int segmentLine, int biasLevel)
{
int biasRegister;
int bitShift;
volatile uint32_t *segmentRegister;
#if defined(_EFM32_TINY_FAMILY)
EFM_ASSERT(segmentLine < 20);
#endif
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
EFM_ASSERT(segmentLine < 40);
#endif
#if defined(_EFM32_TINY_FAMILY)
/* Bias config for 8 segment lines per SEGDnL register */
biasRegister = segmentLine / 8;
bitShift = (segmentLine % 8) * 4;
switch (biasRegister)
{
case 0:
segmentRegister = &LCD->SEGD0L;
break;
case 1:
segmentRegister = &LCD->SEGD1L;
break;
case 2:
segmentRegister = &LCD->SEGD2L;
break;
case 3:
segmentRegister = &LCD->SEGD3L;
break;
default:
segmentRegister = (uint32_t *)0x00000000;
EFM_ASSERT(0);
break;
}
#endif
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
/* Bias config for 10 segment lines per SEGDn L+H registers */
biasRegister = segmentLine / 10;
bitShift = (segmentLine % 10) * 4;
switch (biasRegister)
{
case 0:
if (bitShift < 32)
{
segmentRegister = &LCD->SEGD0L;
}
else
{
segmentRegister = &LCD->SEGD0H;
bitShift -= 32;
}
break;
case 1:
if (bitShift < 32)
{
segmentRegister = &LCD->SEGD1L;
}
else
{
segmentRegister = &LCD->SEGD1H;
bitShift -= 32;
}
break;
case 2:
if (bitShift < 32)
{
segmentRegister = &LCD->SEGD2L;
}
else
{
segmentRegister = &LCD->SEGD1H;
bitShift -= 32;
}
break;
case 3:
if (bitShift < 32)
{
segmentRegister = &LCD->SEGD3L;
}
else
{
segmentRegister = &LCD->SEGD3H;
bitShift -= 32;
}
break;
default:
segmentRegister = (uint32_t *)0x00000000;
EFM_ASSERT(0);
break;
}
#endif
/* Configure new bias setting */
*segmentRegister = (*segmentRegister & ~(0xF << bitShift)) | (biasLevel << bitShift);
}
/***************************************************************************//**
* @brief
* Configure bias level for a specific segment line
*
* @note
* When DSC is active, each configuration takes up 4 bits in the Segment
* Registers (SEGD4L/SEGD4H) which defines bias level.
* For optimal use of this feature, the entire SEGD-registers should be set
* at once in a optimized routine, so this function is mainly here to
* demonstrate how to correctly configure the bias levels, and should be used
* with care.
*
* @param[in] comLine
* COM line number, 0-7
*
* @param[in] biasLevel
* Bias configuration level, 0-4. This value must be within the constraint
* defined by the LCD_DISPCTRL bias setting, see Reference Manual/Datasheet
******************************************************************************/
void LCD_BiasComSet(int comLine, int biasLevel)
{
int bitShift;
EFM_ASSERT(comLine < 8);
bitShift = comLine * 4;
LCD->SEGD4L = (LCD->SEGD4L & ~(0xF << bitShift)) | (biasLevel << bitShift);
}
#endif
/** @} (end addtogroup LCD) */
/** @} (end addtogroup EM_Library) */
#endif /* defined(LCD_COUNT) && (LCD_COUNT > 0) */
/***************************************************************************//**
* @file
* @brief Reset Management Unit (RMU) peripheral module peripheral API
*
* @author Energy Micro AS
* @version 3.20.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_rmu.h"
#if defined(RMU_COUNT) && (RMU_COUNT > 0)
#include "em_emu.h"
#include "em_bitband.h"
/***************************************************************************//**
* @addtogroup EM_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup RMU
* @brief Reset Management Unit (RMU) Peripheral API
* @{
******************************************************************************/
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Disable/enable reset for various peripherals and signal sources
*
* @param[in] reset Reset types to enable/disable
*
* @param[in] enable
* @li false - Disable reset signal or flag
* @li true - Enable reset signal or flag
******************************************************************************/
void RMU_ResetControl(RMU_Reset_TypeDef reset, bool enable)
{
BITBAND_Peripheral(&(RMU->CTRL), (uint32_t)reset, (uint32_t)enable);
}
/***************************************************************************//**
* @brief
* Clear the reset cause register.
******************************************************************************/
void RMU_ResetCauseClear(void)
{
uint32_t locked;
RMU->CMD = RMU_CMD_RCCLR;
/* Clear some reset causes not cleared with RMU CMD register */
/* (If EMU registers locked, they must be unlocked first) */
locked = EMU->LOCK & EMU_LOCK_LOCKKEY_LOCKED;
if (locked)
{
EMU_Unlock();
}
BITBAND_Peripheral(&(EMU->AUXCTRL), 0, 1);
BITBAND_Peripheral(&(EMU->AUXCTRL), 0, 0);
if (locked)
{
EMU_Lock();
}
}
/***************************************************************************//**
* @brief
* Get the cause of the last reset.
*
* @details
* In order to be useful, the reset cause must be cleared by SW before a new
* reset occurs, otherwise reset causes may accumulate. See
* RMU_ResetCauseClear(). This function call will return the main cause for
* reset, which can be a bit mask (several causes), and clear away "noise".
*
* @return
* The reset cause, a bit mask of (typically, but not always, only one) of:
* @li RMU_RSTCAUSE_PORST - Power on reset
* @li RMU_RSTCAUSE_BODUNREGRST - Brown out detector, unregulated power
* @li RMU_RSTCAUSE_BODREGRST - Brown out detector, regulated power
* @li RMU_RSTCAUSE_EXTRST - External reset
* @li RMU_RSTCAUSE_WDOGRST - Watchdog reset
* @li RMU_RSTCAUSE_LOCKUPRST - Cortex-M3 lockup reset
* @li RMU_RSTCAUSE_SYSREQRST - Cortex-M3 system request reset
* @li RMU_RSTCAUSE_EM4RST - Set if the system has been in EM4
* @li RMU_RSTCAUSE_EM4WURST - Set if the system woke up on a pin from EM4
* @li RMU_RSTCAUSE_BODAVDD0 - Analog power domain 0 brown out detector reset
* @li RMU_RSTCAUSE_BODAVDD1 - Analog power domain 1 brown out detector reset
* @li RMU_RSTCAUSE_BUBODVDDDREG - Backup BOD on VDDD_REG triggered
* @li RMU_RSTCAUSE_BUBODBUVIN - Backup BOD on BU_VIN triggered
* @li RMU_RSTCAUSE_BUBODUNREG - Backup BOD on unregulated power triggered
* @li RMU_RSTCAUSE_BUBODREG - Backup BOD on regulated powered has triggered
* @li RMU_RSTCAUSE_BUMODERST - System has been in Backup mode
******************************************************************************/
uint32_t RMU_ResetCauseGet(void)
{
uint32_t ret = RMU->RSTCAUSE;
/* Inspect and decode bits. The decoding must be done in correct order, */
/* since some reset causes may trigger other reset causes due to internal */
/* design. We are only interested in the main cause. */
#if defined( RMU_RSTCAUSE_EM4RST )
/* Clear "stray" bits if EM4 bit is set, they will always be active */
if (ret & RMU_RSTCAUSE_EM4RST)
{
ret &= ~(RMU_RSTCAUSE_BODREGRST|
RMU_RSTCAUSE_BODUNREGRST|
RMU_RSTCAUSE_LOCKUPRST|
RMU_RSTCAUSE_SYSREQRST);
}
#endif
if (ret & RMU_RSTCAUSE_PORST)
{
ret = RMU_RSTCAUSE_PORST;
}
else if ((ret & 0x83) == RMU_RSTCAUSE_BODUNREGRST)
{
ret = RMU_RSTCAUSE_BODUNREGRST;
}
else if ((ret & 0x1f) == RMU_RSTCAUSE_BODREGRST)
{
ret = RMU_RSTCAUSE_BODREGRST;
}
/* Both external and watchdog reset may occur at the same time */
else if ((ret & 0x1b) & (RMU_RSTCAUSE_EXTRST | RMU_RSTCAUSE_WDOGRST))
{
ret &= RMU_RSTCAUSE_EXTRST | RMU_RSTCAUSE_WDOGRST;
}
/* Both lockup and system reset may occur at the same time */
else if ((ret & 0x7ff) & (RMU_RSTCAUSE_LOCKUPRST | RMU_RSTCAUSE_SYSREQRST))
{
ret &= RMU_RSTCAUSE_LOCKUPRST | RMU_RSTCAUSE_SYSREQRST;
}
#if defined( RMU_RSTCAUSE_BODAVDD0 )
/* EM4 wake up and pin retention support */
else if (ret & RMU_RSTCAUSE_BODAVDD0)
{
ret = RMU_RSTCAUSE_BODAVDD0;
}
else if (ret & RMU_RSTCAUSE_BODAVDD1)
{
ret = RMU_RSTCAUSE_BODAVDD1;
}
else if (ret & (RMU_RSTCAUSE_EM4WURST|RMU_RSTCAUSE_EM4RST))
{
ret &= (RMU_RSTCAUSE_EM4WURST|
#if defined( RMU_RSTCAUSE_BUMODERST )
RMU_RSTCAUSE_BUMODERST|
#endif
RMU_RSTCAUSE_EM4RST);
}
else if (ret & (RMU_RSTCAUSE_EM4RST|RMU_RSTCAUSE_EXTRST))
{
ret &= (RMU_RSTCAUSE_EM4RST|RMU_RSTCAUSE_EXTRST);
}
#endif
#if defined( RMU_RSTCAUSE_BUBODVDDDREG )
/* Backup power domain support */
else if (ret & (RMU_RSTCAUSE_BUBODVDDDREG))
{
/* Keep backup mode flag, will only be present in this scenario */
ret &= (RMU_RSTCAUSE_BUBODVDDDREG|RMU_RSTCAUSE_BUMODERST);
}
else if (ret & (RMU_RSTCAUSE_BUBODBUVIN))
{
ret &= (RMU_RSTCAUSE_BUBODBUVIN);
}
else if (ret & (RMU_RSTCAUSE_BUBODUNREG))
{
ret &= (RMU_RSTCAUSE_BUBODUNREG);
}
else if (ret & (RMU_RSTCAUSE_BUBODREG))
{
ret &= (RMU_RSTCAUSE_BUBODREG);
}
#endif
else
{
ret = 0;
}
return ret;
}
/** @} (end addtogroup RMU) */
/** @} (end addtogroup EM_Library) */
#endif /* defined(RMU_COUNT) && (RMU_COUNT > 0) */
/***************************************************************************//**
* @file
* @brief Real Time Counter (RTC) Peripheral API
* @author Energy Micro AS
* @version 3.20.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_rtc.h"
#if defined(RTC_COUNT) && (RTC_COUNT > 0)
#include "em_assert.h"
#include "em_bitband.h"
/***************************************************************************//**
* @addtogroup EM_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup RTC
* @brief Real Time Counter (RTC) Peripheral API
* @{
******************************************************************************/
/*******************************************************************************
******************************* DEFINES ***********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** Validation of valid comparator register for assert statements. */
#define RTC_COMP_REG_VALID(reg) (((reg) <= 1))
/** @endcond */
/*******************************************************************************
************************** LOCAL FUNCTIONS ********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
#if defined(_EFM32_GECKO_FAMILY)
/***************************************************************************//**
* @brief
* Wait for ongoing sync of register(s) to low frequency domain to complete.
*
* @note
* This only applies to the Gecko Family, see the reference manual
* chapter about Access to Low Energy Peripherals (Asynchronos Registers)
* for details. For Tiny Gecko and Giant Gecko, the RTC supports immediate
* updates of registers, and will automatically hold the bus until the
* register has been updated.
*
* @param[in] mask
* Bitmask corresponding to SYNCBUSY register defined bits, indicating
* registers that must complete any ongoing synchronization.
******************************************************************************/
__STATIC_INLINE void RTC_Sync(uint32_t mask)
{
/* Avoid deadlock if modifying the same register twice when freeze mode is */
/* activated. */
if (RTC->FREEZE & RTC_FREEZE_REGFREEZE)
return;
/* Wait for any pending previous write operation to have been completed */
/* in low frequency domain. This is only required for the Gecko Family */
while (RTC->SYNCBUSY & mask)
;
}
#endif
/** @endcond */
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Get RTC compare register value.
*
* @param[in] comp
* Compare register to get, either 0 or 1
*
* @return
* Compare register value, 0 if invalid register selected.
******************************************************************************/
uint32_t RTC_CompareGet(unsigned int comp)
{
uint32_t ret;
EFM_ASSERT(RTC_COMP_REG_VALID(comp));
/* Initialize selected compare value */
switch (comp)
{
case 0:
ret = RTC->COMP0;
break;
case 1:
ret = RTC->COMP1;
break;
default:
/* Unknown compare register selected */
ret = 0;
break;
}
return ret;
}
/***************************************************************************//**
* @brief
* Set RTC compare register value.
*
* @note
* The setting of a compare register requires synchronization into the
* low frequency domain. If the same register is modified before a previous
* update has completed, this function will stall until the previous
* synchronization has completed. This only applies to the Gecko Family, see
* comment in the RTC_Sync() internal function call.
*
* @param[in] comp
* Compare register to set, either 0 or 1
*
* @param[in] value
* Initialization value (<= 0x00ffffff)
******************************************************************************/
void RTC_CompareSet(unsigned int comp, uint32_t value)
{
volatile uint32_t *compReg;
#if defined(_EFM32_GECKO_FAMILY)
uint32_t syncbusy;
#endif
EFM_ASSERT(RTC_COMP_REG_VALID(comp) &&
((value & ~(_RTC_COMP0_COMP0_MASK >> _RTC_COMP0_COMP0_SHIFT)) == 0));
/* Initialize selected compare value */
switch (comp)
{
case 0:
compReg = &(RTC->COMP0);
#if defined(_EFM32_GECKO_FAMILY)
syncbusy = RTC_SYNCBUSY_COMP0;
#endif
break;
case 1:
compReg = &(RTC->COMP1);
#if defined(_EFM32_GECKO_FAMILY)
syncbusy = RTC_SYNCBUSY_COMP1;
#endif
break;
default:
/* Unknown compare register selected, abort */
return;
}
#if defined(_EFM32_GECKO_FAMILY)
/* LF register about to be modified require sync. busy check */
RTC_Sync(syncbusy);
#endif
*compReg = value;
}
/***************************************************************************//**
* @brief
* Enable/disable RTC.
*
* @note
* The enabling/disabling of the RTC modifies the RTC CTRL register which
* requires synchronization into the low frequency domain. If this register is
* modified before a previous update to the same register has completed, this
* function will stall until the previous synchronization has completed. This
* only applies to the Gecko Family, see comment in the RTC_Sync() internal
* function call.
*
* @param[in] enable
* true to enable counting, false to disable.
******************************************************************************/
void RTC_Enable(bool enable)
{
#if defined(_EFM32_GECKO_FAMILY)
/* LF register about to be modified require sync. busy check */
RTC_Sync(RTC_SYNCBUSY_CTRL);
#endif
BITBAND_Peripheral(&(RTC->CTRL), _RTC_CTRL_EN_SHIFT, (unsigned int) enable);
}
/***************************************************************************//**
* @brief
* RTC register synchronization freeze control.
*
* @details
* Some RTC registers require synchronization into the low frequency (LF)
* domain. The freeze feature allows for several such registers to be
* modified before passing them to the LF domain simultaneously (which
* takes place when the freeze mode is disabled).
*
* @note
* When enabling freeze mode, this function will wait for all current
* ongoing RTC synchronization to LF domain to complete (Normally
* synchronization will not be in progress.) However for this reason, when
* using freeze mode, modifications of registers requiring LF synchronization
* should be done within one freeze enable/disable block to avoid unecessary
* stalling. This only applies to the Gecko Family, see the reference manual
* chapter about Access to Low Energy Peripherals (Asynchronos Registers)
* for details.
*
* @param[in] enable
* @li true - enable freeze, modified registers are not propagated to the
* LF domain
* @li false - disables freeze, modified registers are propagated to LF
* domain
******************************************************************************/
void RTC_FreezeEnable(bool enable)
{
if (enable)
{
#if defined(_EFM32_GECKO_FAMILY)
/* Wait for any ongoing LF synchronization to complete. This is just to */
/* protect against the rare case when a user */
/* - modifies a register requiring LF sync */
/* - then enables freeze before LF sync completed */
/* - then modifies the same register again */
/* since modifying a register while it is in sync progress should be */
/* avoided. */
while (RTC->SYNCBUSY)
;
#endif
RTC->FREEZE = RTC_FREEZE_REGFREEZE;
}
else
{
RTC->FREEZE = 0;
}
}
/***************************************************************************//**
* @brief
* Initialize RTC.
*
* @details
* Note that the compare values must be set separately with RTC_CompareSet().
* That should probably be done prior to the use of this function if
* configuring the RTC to start when initialization is completed.
*
* @note
* The initialization of the RTC modifies the RTC CTRL register which requires
* synchronization into the low frequency domain. If this register is
* modified before a previous update to the same register has completed, this
* function will stall until the previous synchronization has completed. This
* only applies to the Gecko Family, see comment in the RTC_Sync() internal
* function call.
*
* @param[in] init
* Pointer to RTC initialization structure.
******************************************************************************/
void RTC_Init(const RTC_Init_TypeDef *init)
{
uint32_t tmp;
if (init->enable)
{
tmp = RTC_CTRL_EN;
}
else
{
tmp = 0;
}
/* Configure DEBUGRUN flag, sets whether or not counter should be
* updated when debugger is active */
if (init->debugRun)
{
tmp |= RTC_CTRL_DEBUGRUN;
}
/* Configure COMP0TOP, this will use the COMP0 compare value as an
* overflow value, instead of default 24-bit 0x00ffffff */
if (init->comp0Top)
{
tmp |= RTC_CTRL_COMP0TOP;
}
#if defined(_EFM32_GECKO_FAMILY)
/* LF register about to be modified require sync. busy check */
RTC_Sync(RTC_SYNCBUSY_CTRL);
#endif
RTC->CTRL = tmp;
}
/***************************************************************************//**
* @brief
* Restore RTC to reset state
******************************************************************************/
void RTC_Reset(void)
{
/* Restore all essential RTC register to default config */
RTC->FREEZE = _RTC_FREEZE_RESETVALUE;
RTC->CTRL = _RTC_CTRL_RESETVALUE;
RTC->COMP0 = _RTC_COMP0_RESETVALUE;
RTC->COMP1 = _RTC_COMP1_RESETVALUE;
RTC->IEN = _RTC_IEN_RESETVALUE;
RTC->IFC = _RTC_IFC_RESETVALUE;
}
/***************************************************************************//**
* @brief
* Restart RTC counter from zero
******************************************************************************/
void RTC_CounterReset(void)
{
/* A disable/enable sequnce will start the counter at zero */
RTC_Enable(false);
RTC_Enable(true);
}
/** @} (end addtogroup RTC) */
/** @} (end addtogroup EM_Library) */
#endif /* defined(RTC_COUNT) && (RTC_COUNT > 0) */
/***************************************************************************//**
* @file
* @brief System Peripheral API
* @author Energy Micro AS
* @version 3.20.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_system.h"
#include "em_assert.h"
/***************************************************************************//**
* @addtogroup EM_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup SYSTEM
* @brief System Peripheral API
* @{
******************************************************************************/
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Get chip major/minor revision.
*
* @param[out] rev
* Location to place chip revision info.
******************************************************************************/
void SYSTEM_ChipRevisionGet(SYSTEM_ChipRevision_TypeDef *rev)
{
uint8_t tmp;
EFM_ASSERT(rev);
rev->major = (ROMTABLE->PID0 & _ROMTABLE_PID0_REVMAJOR_MASK) >> _ROMTABLE_PID0_REVMAJOR_SHIFT;
tmp = (ROMTABLE->PID2 & _ROMTABLE_PID2_REVMINORMSB_MASK);
tmp |= ((ROMTABLE->PID3 & _ROMTABLE_PID3_REVMINORLSB_MASK) >> _ROMTABLE_PID3_REVMINORLSB_SHIFT);
rev->minor = tmp;
}
/***************************************************************************//**
* @brief
* Get factory calibration value for a given peripheral register.
*
* @param[in] regAddress
* Address of register to get a calibration value for.
*
* @return
* Calibration value for the requested register.
******************************************************************************/
uint32_t SYSTEM_GetCalibrationValue(volatile uint32_t *regAddress)
{
int regCount;
CALIBRATE_TypeDef *p;
regCount = 1;
p = CALIBRATE;
for (;; )
{
if ((regCount > CALIBRATE_MAX_REGISTERS) ||
(p->VALUE == 0xFFFFFFFF))
{
EFM_ASSERT(false);
return 0; /* End of device calibration table reached. */
}
if (p->ADDRESS == (uint32_t)regAddress)
{
return p->VALUE; /* Calibration value found ! */
}
p++;
regCount++;
}
}
/** @} (end addtogroup SYSTEM) */
/** @} (end addtogroup EM_Library) */
FreeRTOS - Blink example
This example project uses the FreeRTOS, and gives a basic demonstration of using two tasks to blink the LEDs on the board.
It also shows how to use idle with different energy saving modes ( from EM1 to EM3 - configured in FreeRTOSConfig.h file).
This example is intended as a skeleton for new projects using FreeRTOS.
Board: Silicon Labs EFM32GG_STK3700 Starter Kit
Device: EFM32GG990F1024
\ No newline at end of file
/*
* 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.
*/
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
/* emlib includes. */
#include "em_cmu.h"
#include "em_emu.h"
#include "em_rtc.h"
#include "em_burtc.h"
#include "em_rmu.h"
#include "em_int.h"
/* emdrv includes */
#include "sleep.h"
#if (configUSE_SLEEP_MODE_IN_IDLE == 1)
/**************************************************************************//**
* @brief vApplicationIdleHook
* Override the default definition of vApplicationIdleHook()
*****************************************************************************/
void vApplicationIdleHook(void)
{
SLEEP_Sleep();
}
#endif
/* Including only if tickless_idle is set to 1 or ( configUSE_TICKLESS_IDLE is set to 0 and configUSE_SLEEP_MODE_IN_IDLE is set to 1 ) and EM2 or EM3 mode is choosed
* in other hand standard Cortex M3 FreeRTOS functions are used. */
#if (((configUSE_TICKLESS_IDLE == 1) || ((configUSE_TICKLESS_IDLE == 0) && (configUSE_SLEEP_MODE_IN_IDLE == 1))) && (configSLEEP_MODE == 2 || configSLEEP_MODE == 3))
/* Constants required to pend a PendSV interrupt from the tick ISR if the
* preemptive scheduler is being used. These are just standard bits and registers
* within the Cortex-M core itself. */
#define port_NVIC_INT_CTRL_REG (*(( volatile unsigned long * ) 0xe000ed04))
#define port_NVIC_PENDSVSET_BIT (1UL << 28UL)
#if (configUSE_TICKLESS_IDLE == 1)
/* Flag used only in EM2 and EM3 to get know whether
* sleep mode was exited because of an interrupt */
static volatile bool intTickFlag = false;
#endif /* (configUSE_TICKLESS_IDLE == 1) */
/* Preload value for RTC and BURTC counter */
#define SYSTICK_LOAD_VALUE ((configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ))
/*
* The number of SysTick increments that make up one tick period.
*/
static unsigned long ulTimerReloadValueForOneTick = 0;
/*
* The maximum number of tick periods that can be suppressed is limited by the
* 24 bit resolution RTC and 32 bit BURTC.
*/
#if (configUSE_TICKLESS_IDLE == 1)
static unsigned long xMaximumPossibleSuppressedTicks = 0;
/*
* Compensate for the CPU cycles that pass while the SysTick is stopped (low
* power functionality only.
*/
static unsigned long ulStoppedTimerCompensation = 0;
#endif /* (configUSE_TICKLESS_IDLE == 1) */
/* Functions which are used in EM2 mode*/
#if (configSLEEP_MODE == 2)
#define TIMER_CAPACITY (0xFFFFFF)
#if (configUSE_TICKLESS_IDLE == 1)
#define TIMER_COMPENSATION (45)
#endif /* (configUSE_TICKLESS_IDLE == 1) */
/**************************************************************************//**
* @brief RTC_IRQHandler
* Interrupt Service Routine for RTC which is used as system tick counter in EM2
*****************************************************************************/
void RTC_IRQHandler(void)
{
/* If using preemption, also force a context switch. */
#if (configUSE_PREEMPTION == 1)
port_NVIC_INT_CTRL_REG = port_NVIC_PENDSVSET_BIT;
#endif /* (configUSE_PREEMPTION == 1) */
/* Set RTC interrupt to one system tick period*/
RTC_Enable(false);
RTC_CompareSet(0, ulTimerReloadValueForOneTick);
/* Restart the counter */
#if (configUSE_TICKLESS_IDLE == 1)
/* Set flag that interrupt was made*/
intTickFlag = true;
#endif /* (configUSE_TICKLESS_IDLE == 1) */
/* Critical section which protect incrementing the tick*/
( void ) portSET_INTERRUPT_MASK_FROM_ISR();
{
xTaskIncrementTick();
}
portCLEAR_INTERRUPT_MASK_FROM_ISR(0);
/* Clear interrupt */
RTC_IntClear(_RTC_IFC_MASK);
RTC_CounterReset();
}
/**************************************************************************//**
* @brief vPortSetupTimerInterrupt
* Override the default definition of vPortSetupTimerInterrupt() that is weakly
* defined in the FreeRTOS Cortex-M3, which set source of system tick interrupt
*****************************************************************************/
void vPortSetupTimerInterrupt(void)
{
/* Set our data about timer used as system ticks*/
ulTimerReloadValueForOneTick = SYSTICK_LOAD_VALUE ;
#if (configUSE_TICKLESS_IDLE == 1)
xMaximumPossibleSuppressedTicks = TIMER_CAPACITY / (SYSTICK_LOAD_VALUE);
ulStoppedTimerCompensation = TIMER_COMPENSATION / (configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ);
#endif /* (configUSE_TICKLESS_IDLE == 1) */
/* Configure RTC as system tick source */
/* Structure of RTC init */
RTC_Init_TypeDef init;
#if (configCRYSTAL_IN_EM2 == 1)
/* LFXO setup */
/* For cut D, use 70% boost */
CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_LFXOBOOST_MASK) | CMU_CTRL_LFXOBOOST_70PCENT;
#if defined( EMU_AUXCTRL_REDLFXOBOOST )
EMU->AUXCTRL = (EMU->AUXCTRL & ~_EMU_AUXCTRL_REDLFXOBOOST_MASK) | EMU_AUXCTRL_REDLFXOBOOST;
#endif
#else
/* RC oscillator */
CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);
#endif
/* Ensure LE modules are accessible */
CMU_ClockEnable(cmuClock_CORELE, true);
#if (configCRYSTAL_IN_EM2 == 1)
/* Enable osc as LFACLK in CMU (will also enable oscillator if not enabled) */
CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFXO);
#else
/* Enable osc as LFACLK in CMU (will also enable oscillator if not enabled) */
CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFRCO);
#endif
/* Set 2 times divider to reduce energy*/
CMU_ClockDivSet(cmuClock_RTC, cmuClkDiv_2);
/* Enable clock to RTC module */
CMU_ClockEnable(cmuClock_RTC, true);
init.enable = false;
init.debugRun = false;
init.comp0Top = false; /* Count to max value before wrapping */
/* Initialization of RTC */
RTC_Init(&init);
/* Disable interrupt generation from RTC0 */
RTC_IntDisable(RTC_IFC_COMP0);
/* Tick interrupt MUST execute at the lowest interrupt priority. */
NVIC_SetPriority(RTC_IRQn, 255);
/* Enable interrupts */
NVIC_ClearPendingIRQ(RTC_IRQn);
NVIC_EnableIRQ(RTC_IRQn);
RTC_CompareSet(0, SYSTICK_LOAD_VALUE);
RTC_IntClear(RTC_IFC_COMP0);
RTC_IntEnable(RTC_IF_COMP0);
RTC_Enable(true);
//RTC_CounterReset();
}
#if (configUSE_TICKLESS_IDLE == 1)
/**************************************************************************//**
* @brief vPortSuppressTicksAndSleep
* Override the default definition of vPortSuppressTicksAndSleep() that is weakly
* defined in the FreeRTOS Cortex-M3 port layer layer
*****************************************************************************/
void vPortSuppressTicksAndSleep(portTickType xExpectedIdleTime)
{
unsigned long ulReloadValue, ulCompleteTickPeriods;
portTickType xModifiableIdleTime;
/* Make sure the SysTick reload value does not overflow the counter. */
if (xExpectedIdleTime > xMaximumPossibleSuppressedTicks)
{
xExpectedIdleTime = xMaximumPossibleSuppressedTicks;
}
/* Calculate the reload value required to wait xExpectedIdleTime
* tick periods.
*/
ulReloadValue = (ulTimerReloadValueForOneTick * (xExpectedIdleTime ));
if (ulReloadValue > ulStoppedTimerCompensation)
{
ulReloadValue -= ulStoppedTimerCompensation;
}
/* Stop the System Tick momentarily. The time the System Tick is stopped for
* is accounted for as best it can be, but using the tickless mode will
* inevitably result in some tiny drift of the time maintained by the
* kernel with respect to calendar time. */
/* Stop the RTC clock*/
RTC_Enable(false);
/* Enter a critical section but don't use the taskENTER_CRITICAL()
* method as that will mask interrupts that should exit sleep mode. */
INT_Disable();
/* The tick flag is set to false before sleeping. If it is true when sleep
* mode is exited then sleep mode was probably exited because the tick was
* suppressed for the entire xExpectedIdleTime period. */
intTickFlag = false;
/* If a context switch is pending or a task is waiting for the scheduler
* to be unsuspended then abandon the low power entry. */
if (eTaskConfirmSleepModeStatus() == eAbortSleep)
{
RTC_Enable(true);
/* Re-enable interrupts - see comments above __disable_interrupt()
* call above. */
INT_Enable();
}
else
{
/* Set the new reload value. */
ulReloadValue -= RTC_CounterGet();
RTC_CompareSet(0, ulReloadValue);
/* Restart the counter*/
RTC_CounterReset();
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
* set its parameter to 0 to indicate that its implementation contains
* its own wait for interrupt or wait for event instruction, and so wfi
* should not be executed again. However, the original expected idle
* time variable must remain unmodified, so a copy is taken. */
xModifiableIdleTime = xExpectedIdleTime;
configPRE_SLEEP_PROCESSING(xModifiableIdleTime);
if (xModifiableIdleTime > 0)
{
SLEEP_Sleep();
__DSB();
__ISB();
}
configPOST_SLEEP_PROCESSING(xExpectedIdleTime);
/* Stop SysTick. Again, the time the SysTick is stopped for is
* accounted for as best it can be, but using the tickless mode will
* inevitably result in some tiny drift of the time maintained by the
* kernel with respect to calendar time. */
/* Stop the RTC clock*/
RTC_Enable(false);
/* Re-enable interrupts */
INT_Enable();
if (intTickFlag != false)
{
/* The tick interrupt has already executed,
* Reset the alarm value with whatever remains of this tick period. */
RTC_CompareSet(0, TIMER_CAPACITY & (ulTimerReloadValueForOneTick - RTC_CounterGet()));
/* The tick interrupt handler will already have pended the tick
* processing in the kernel. As the pending tick will be
* processed as soon as this function exits, the tick value
* maintained by the tick is stepped forward by one less than the
* time spent waiting. */
ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
}
else
{
/* Some other interrupt than system tick ended the sleep.
* Calculate how many tick periods passed while the processor
* was waiting */
ulCompleteTickPeriods = RTC_CounterGet() / ulTimerReloadValueForOneTick;
/* The reload value is set to whatever fraction of a single tick
* period remains. */
if (ulCompleteTickPeriods == 0)
{
ulReloadValue = ulTimerReloadValueForOneTick - RTC_CounterGet();
}
else
{
ulReloadValue = RTC_CounterGet() - (ulCompleteTickPeriods * ulTimerReloadValueForOneTick);
}
RTC_CompareSet(0, ulReloadValue);
}
/* Restart the RTCounter */
RTC_CounterReset();
/* The tick forward by the number of tick periods that
* remained in a low power state. */
vTaskStepTick(ulCompleteTickPeriods);
}
}
#endif /* (configUSE_TICKLESS_IDLE == 1) */
#endif /* (configSLEEP_MODE == 2) */
/* Functions which are used in EM3 mode*/
#if (configSLEEP_MODE == 3)
#define TIMER_CAPACITY (0xFFFFFFFF)
#if (configUSE_TICKLESS_IDLE == 1)
#define TIMER_COMPENSATION (45)
#endif /* (configUSE_TICKLESS_IDLE == 1) */
/**************************************************************************//**
* @brief BURTC_IRQHandler
* Interrupt Service Routine for RTC which is used as system tick counter in EM3
*****************************************************************************/
void BURTC_IRQHandler(void)
{
/* If using preemption, also force a context switch. */
#if (configUSE_PREEMPTION == 1)
port_NVIC_INT_CTRL_REG = port_NVIC_PENDSVSET_BIT;
#endif /* (configUSE_PREEMPTION == 1) */
/* Set BURTC interrupt to one system tick period*/
BURTC_Enable(false);
BURTC_CompareSet(0, ulTimerReloadValueForOneTick);
/* Restart the counter */
BURTC_CounterReset();
#if (configUSE_TICKLESS_IDLE == 1)
/* Set flag that interrupt was made*/
intTickFlag = true;
#endif /* (configUSE_TICKLESS_IDLE == 1) */
/* Critical section which protect incrementing the tick*/
( void ) portSET_INTERRUPT_MASK_FROM_ISR();
{
xTaskIncrementTick();
}
portCLEAR_INTERRUPT_MASK_FROM_ISR(0);
/* Clear interrupt */
BURTC_IntClear(_RTC_IFC_MASK);
BURTC_CounterReset();
}
/**************************************************************************//**
* @brief vPortSetupTimerInterrupt
* Override the default definition of vPortSetupTimerInterrupt() that is weakly
* defined in the FreeRTOS Cortex-M3, which set source of system tick interrupt
*****************************************************************************/
void vPortSetupTimerInterrupt(void)
{
/* Set our timer's data used as system ticks*/
ulTimerReloadValueForOneTick = SYSTICK_LOAD_VALUE;
#if (configUSE_TICKLESS_IDLE == 1)
xMaximumPossibleSuppressedTicks = TIMER_CAPACITY / (SYSTICK_LOAD_VALUE);
ulStoppedTimerCompensation = TIMER_COMPENSATION / (configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ);
#endif /* (configUSE_TICKLESS_IDLE == 1) */
/* Ensure LE modules are accessible */
CMU_ClockEnable(cmuClock_CORELE, true);
/* Enable access to BURTC registers */
RMU_ResetControl(rmuResetBU, false);
/* Configure BURTC as system tick source */
BURTC_Init_TypeDef burtcInit = BURTC_INIT_DEFAULT;
burtcInit.mode = burtcModeEM3; /* BURTC is enabled to EM3 */
burtcInit.clkSel = burtcClkSelULFRCO; /* Select ULFRCO as clock source */
burtcInit.clkDiv = burtcClkDiv_1; /* Choose 2kHz ULFRCO clock frequency */
/* Initialization of BURTC */
BURTC_Init(&burtcInit);
/* Disable interrupt generation from BURTC */
BURTC_IntDisable(BURTC_IF_COMP0);
/* Tick interrupt MUST execute at the lowest interrupt priority. */
NVIC_SetPriority(BURTC_IRQn, 255);
/* Enable interrupts */
NVIC_ClearPendingIRQ(BURTC_IRQn);
NVIC_EnableIRQ(BURTC_IRQn);
BURTC_CompareSet(0, SYSTICK_LOAD_VALUE);
BURTC_IntClear(BURTC_IF_COMP0);
BURTC_IntEnable(BURTC_IF_COMP0);
BURTC_CounterReset();
}
#if (configUSE_TICKLESS_IDLE == 1)
/**************************************************************************//**
* @brief vPortSetupTimerInterrupt
* Override the default definition of vPortSuppressTicksAndSleep() that is weakly
* defined in the FreeRTOS Cortex-M3 port layer layer
*****************************************************************************/
void vPortSuppressTicksAndSleep(portTickType xExpectedIdleTime)
{
unsigned long ulReloadValue, ulCompleteTickPeriods;
portTickType xModifiableIdleTime;
/* Make sure the SysTick reload value does not overflow the counter. */
if (xExpectedIdleTime > xMaximumPossibleSuppressedTicks)
{
xExpectedIdleTime = xMaximumPossibleSuppressedTicks;
}
/* Calculate the reload value required to wait xExpectedIdleTime
* tick periods. -1 is used because this code will execute part way
* through one of the tick periods, and the fraction of a tick period is
* accounted for later. */
ulReloadValue = (ulTimerReloadValueForOneTick * (xExpectedIdleTime ));
if (ulReloadValue > ulStoppedTimerCompensation)
{
ulReloadValue -= ulStoppedTimerCompensation;
}
/* Stop the SysTick momentarily. The time the SysTick is stopped for
* is accounted for as best it can be, but using the tickless mode will
* inevitably result in some tiny drift of the time maintained by the
* kernel with respect to calendar time. */
/* Stop the RTC clock*/
BURTC_Enable(false);
/* Enter a critical section but don't use the taskENTER_CRITICAL()
* method as that will mask interrupts that should exit sleep mode. */
INT_Disable();
/* The tick flag is set to false before sleeping. If it is true when sleep
* mode is exited then sleep mode was probably exited because the tick was
* suppressed for the entire xExpectedIdleTime period. */
intTickFlag = false;
/* If a context switch is pending or a task is waiting for the scheduler
* to be unsuspended then abandon the low power entry. */
if (eTaskConfirmSleepModeStatus() == eAbortSleep)
{
BURTC_Enable(true);
/* Re-enable interrupts */
INT_Enable();
}
else
{
/* Set the new reload value. */
ulReloadValue -= BURTC_CounterGet();
BURTC_CompareSet(0, ulReloadValue);
/* Restart the counter*/
BURTC_CounterReset();
/* Sleep until something happens. configPRE_SLEEP_PROCESSING() can
* set its parameter to 0 to indicate that its implementation contains
* its own wait for interrupt or wait for event instruction, and so wfi
* should not be executed again. However, the original expected idle
* time variable must remain unmodified, so a copy is taken. */
xModifiableIdleTime = xExpectedIdleTime;
configPRE_SLEEP_PROCESSING(xModifiableIdleTime);
if (xModifiableIdleTime > 0)
{
SLEEP_Sleep();
__DSB();
__ISB();
}
configPOST_SLEEP_PROCESSING(xExpectedIdleTime);
/* Stop SysTick. Again, the time the SysTick is stopped for is
* accounted for as best it can be, but using the tickless mode will
* inevitably result in some tiny drift of the time maintained by the
* kernel with respect to calendar time. */
BURTC_Enable(false);
/* Re-enable interrupts - see comments above __disable_interrupt()
* call above. */
INT_Enable();
if (intTickFlag != false)
{
/* The tick interrupt has already executed,
* Reset the alarm value with whatever remains of this tick period. */
BURTC_CompareSet(0, TIMER_CAPACITY & (ulTimerReloadValueForOneTick - BURTC_CounterGet()));
/* The tick interrupt handler will already have pended the tick
* processing in the kernel. As the pending tick will be
* processed as soon as this function exits, the tick value
* maintained by the tick is stepped forward by one less than the
* time spent waiting. */
ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
}
else
{
/* Some other interrupt than system tick ended the sleep.
* Calculate how many tick periods passed while the processor
* was waiting */
ulCompleteTickPeriods = BURTC_CounterGet() / ulTimerReloadValueForOneTick;
/* The reload value is set to whatever fraction of a single tick
* period remains. */
if (ulCompleteTickPeriods == 0)
{
ulReloadValue = ulTimerReloadValueForOneTick - BURTC_CounterGet();
}
else
{
ulReloadValue = BURTC_CounterGet() - (ulCompleteTickPeriods * ulTimerReloadValueForOneTick);
}
BURTC_CompareSet(0, ulReloadValue);
}
/* Restart the RTCounter*/
BURTC_CounterReset();
/* The tick forward by the number of tick periods that
* remained in a low power state. */
vTaskStepTick(ulCompleteTickPeriods);
}
}
#endif /* (configUSE_TICKLESS_IDLE == 1) */
#endif /* (configSLEEP_MODE == 3) */
#endif /* (((configUSE_TICKLESS_IDLE == 1) || (( configUSE_TICKLESS_IDLE == 0 ) && ( configUSE_SLEEP_MODE_IN_IDLE == 1 ))) && (configSLEEP_MODE == 2 || configSLEEP_MODE == 3)) */
/**************************************************************************//**
* @file
* @brief FreeRTOS Blink Demo for Energy Micro EFM32GG_STK3700 Starter Kit
* @author Energy Micro AS
* @version 3.20.3
******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* This file is licensed under the Silicon Labs Software License Agreement. See
* "http://developer.silabs.com/legal/version/v11/Silicon_Labs_Software_License_Agreement.txt"
* for details. Before using this software for any purpose, you must agree to the
* terms of that agreement.
*
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "FreeRTOSConfig.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
#include "croutine.h"
#include "em_chip.h"
#include "bsp.h"
#include "bsp_trace.h"
#include "sleep.h"
#include "segmentlcd.h"
#define STACK_SIZE_FOR_TASK (configMINIMAL_STACK_SIZE + 10)
#define TASK_PRIORITY (tskIDLE_PRIORITY + 1)
/* Structure with parameters for LedBlink */
typedef struct
{
/* Delay between blink of led */
portTickType delay;
/* Number of led */
int ledNo;
} TaskParams_t;
typedef char lcdText_t[8];
lcdText_t lcdtext;
xQueueHandle msgBox;
/**************************************************************************//**
* @brief Simple task which is blinking led
* @param *pParameters pointer to parameters passed to the function
*****************************************************************************/
static void PrintLcdThread(void const *argument) {
lcdText_t *rptr = &lcdtext;
(void)argument; /* Unused parameter. */
while (1)
{
/* Wait for message */
if (xQueueReceive(msgBox, rptr, portMAX_DELAY))
{
SegmentLCD_Write(*rptr);
}
}
}
static void PutOnLcd(void const *arg)
{
static int count = 0;
/* Infinite loop */
while (1)
{
count = (count+1)&0xF;
BSP_LedsSet(count);
/* Send message to PrintLcdThread */
/* Allocate memory for the message */
lcdText_t *mptr = &lcdtext;
/* Set the message content */
(*mptr)[0] = count>=10 ? '1' : '0';
(*mptr)[1] = count%10 + '0';
(*mptr)[2] = '\0';
/* Send message */
xQueueSend(msgBox, (void *)mptr, portMAX_DELAY);
/* Wait now for half a second */
vTaskDelay(500 / portTICK_RATE_MS);
}
}
/**************************************************************************//**
* @brief Main function
*****************************************************************************/
int main(void)
{
/* Chip errata */
CHIP_Init();
/* If first word of user data page is non-zero, enable eA Profiler trace */
BSP_TraceProfilerSetup();
/* Initialize LED driver */
BSP_LedsInit();
/* Setting state of leds*/
BSP_LedSet(0);
BSP_LedSet(1);
#if (configSLEEP_MODE < 3)
/* do not let to sleep deeper than define */
SLEEP_SleepBlockBegin((SLEEP_EnergyMode_t)(configSLEEP_MODE+1));
#endif
msgBox = xQueueCreate(16, sizeof(lcdText_t));
/*Create two task for blinking leds*/
xTaskCreate( PutOnLcd, (const signed char *) "PutOnLcd", STACK_SIZE_FOR_TASK, NULL, TASK_PRIORITY, NULL);
xTaskCreate( PrintLcdThread, (const signed char *) "PrintLcdThread", STACK_SIZE_FOR_TASK, NULL, TASK_PRIORITY, NULL);
/*Start FreeRTOS Scheduler*/
vTaskStartScheduler();
return 0;
}
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?>
<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="com.silabs.ide.si32.gcc.release#com.silabs.ide.si32.gcc:4.7.3.20130312">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.silabs.ide.si32.gcc.release#com.silabs.ide.si32.gcc:4.7.3.20130312" moduleId="org.eclipse.cdt.core.settings" name="GNU ARM 4.7.3 - Release">
<macros>
<stringMacro name="StudioToolchainPath" type="VALUE_PATH_DIR" value="C:\SiliconLabs\SimplicityStudio\v2\developer\toolchains\gnu_arm\4.7_2013q1"/>
<stringMacro name="StudioSdkPath" type="VALUE_PATH_DIR" value="C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2"/>
</macros>
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule buildConfig.stockConfigId="com.silabs.ide.si32.gcc.release#com.silabs.ide.si32.gcc:4.7.3.20130312" cppBuildConfig.builtinIncludes="unresolved:$%7BStudioSdkPath%7D/CMSIS/Include/ unresolved:$%7BStudioSdkPath%7D/emlib/inc/ unresolved:$%7BStudioSdkPath%7D/kits/common/bsp/ unresolved:$%7BStudioSdkPath%7D/kits/common/drivers/ unresolved:$%7BStudioSdkPath%7D/Device/EnergyMicro/EFM32GG/Include/ unresolved:$%7BStudioSdkPath%7D/reptile/RTX/INC/ unresolved:$%7BStudioSdkPath%7D/kits/EFM32GG_STK3700/config/ unresolved:$%7BStudioSdkPath%7D/CMSIS/Include/ unresolved:$%7BStudioSdkPath%7D/emlib/inc/ unresolved:$%7BStudioSdkPath%7D/kits/common/bsp/ unresolved:$%7BStudioSdkPath%7D/kits/common/drivers/ unresolved:$%7BStudioSdkPath%7D/Device/EnergyMicro/EFM32GG/Include/ unresolved:$%7BStudioSdkPath%7D/reptile/RTX/INC/ unresolved:$%7BStudioSdkPath%7D/kits/EFM32GG_STK3700/config/" cppBuildConfig.builtinLibraryFiles="" cppBuildConfig.builtinLibraryNames="RTX_CM3" cppBuildConfig.builtinLibraryObjects="" cppBuildConfig.builtinLibraryPaths="unresolved:$%7BStudioSdkPath%7D/reptile/RTX/LIB/GCC/" cppBuildConfig.builtinMacros="EFM32GG990F1024 EFM32GG990F1024 NDEBUG" moduleId="com.silabs.ide.project.core" projectCommon.referencedModules="[{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; id=\&quot;com.silabs.ide.si32.sdk.efm32.v2.common.drivers\&quot;&gt;\r\n &lt;inclusions pattern=\&quot;Drivers/segmentlcd.c\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;,&quot;builtinSources&quot;:[&quot;Drivers/segmentlcd.c&quot;]},{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; id=\&quot;com.silabs.ide.si32.sdk.efm32.v2.common.CMSIS\&quot;&gt;\r\n &lt;exclusions pattern=\&quot;.*\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;,&quot;builtinSources&quot;:[]},{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; id=\&quot;com.silabs.ide.si32.sdk.efm32.v2.kit\&quot;&gt;\r\n &lt;exclusions pattern=\&quot;.*\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;,&quot;builtinSources&quot;:[]},{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; id=\&quot;com.silabs.ide.si32.sdk.efm32.v2.common.emlib\&quot;&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_assert.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_cmu.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_emu.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_gpio.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_lcd.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_system.c\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;,&quot;builtinSources&quot;:[&quot;emlib/em_assert.c&quot;,&quot;emlib/em_cmu.c&quot;,&quot;emlib/em_emu.c&quot;,&quot;emlib/em_gpio.c&quot;,&quot;emlib/em_lcd.c&quot;,&quot;emlib/em_system.c&quot;]},{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; id=\&quot;com.silabs.ide.si32.sdk.efm32.v2.part\&quot;&gt;\r\n &lt;inclusions pattern=\&quot;CMSIS/.*/startup_gcc_.*.s\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;CMSIS/.*/startup_iar_.*.s\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;CMSIS/.*/system_.*.c\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;,&quot;builtinSources&quot;:[&quot;CMSIS/efm32gg/startup_gcc_efm32gg.s&quot;,&quot;CMSIS/efm32gg/system_efm32gg.c&quot;]},{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; id=\&quot;com.silabs.ide.si32.sdk.efm32.v2.common.bsp\&quot;&gt;\r\n &lt;inclusions pattern=\&quot;BSP/bsp_trace.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;BSP/bsp_stk_leds.c\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;,&quot;builtinSources&quot;:[&quot;BSP/bsp_stk_leds.c&quot;,&quot;BSP/bsp_trace.c&quot;]},{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; id=\&quot;com.silabs.ide.si32.sdk.efm32.v2.external.RTX\&quot;&gt;\r\n &lt;exclusions pattern=\&quot;.*\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;,&quot;builtinSources&quot;:[]}]" projectCommon.toolchainId="com.silabs.ide.si32.gcc:4.7.3.20130312"/>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" description="" id="com.silabs.ide.si32.gcc.release#com.silabs.ide.si32.gcc:4.7.3.20130312" name="GNU ARM 4.7.3 - Release" parent="com.silabs.ide.si32.gcc.cdt.managedbuild.config.gnu.exe">
<folderInfo id="com.silabs.ide.si32.gcc.release#com.silabs.ide.si32.gcc:4.7.3.20130312." name="/" resourcePath="">
<toolChain id="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.exe.1936628392" name="Si32 GNU ARM" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.exe">
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.debug.level.542251548" name="Debug Level" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.debug.level" value="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.debug.level.default" valueType="enumerated"/>
<targetPlatform binaryParser="org.eclipse.cdt.core.ELF;org.eclipse.cdt.core.GNU_ELF" id="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.platform.base.2019015035" isAbstract="false" name="Debug Platform" osList="win32,linux,macosx" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.platform.base"/>
<builder buildPath="${workspace_loc:/EFM32GG_rtx_blink}/GNU ARM 4.7.3 - Release" id="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.builder.base.112051789" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Si32 GNU ARM Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.builder.base"/>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base.911627407" name="GNU ARM C Compiler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base">
<option id="gnu.c.compiler.option.optimization.level.1997095516" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" value="gnu.c.optimization.level.most" valueType="enumerated"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.builtin.241381609" name="Always branch to builtin functions (-fno-builtin)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.builtin" value="true" valueType="boolean"/>
<option id="gnu.c.compiler.option.include.paths.164282250" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/EFM32GG_STK3700/examples/rtx_blink&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/CMSIS/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/emlib/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/common/bsp&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/common/drivers&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/EnergyMicro/EFM32GG/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/reptile/RTX/INC&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/EFM32GG_STK3700/config&quot;"/>
</option>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.def.symbols.1831688523" name="Defined symbols (-D)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.def.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="EFM32GG990F1024=1"/>
<listOptionValue builtIn="false" value="NDEBUG=1"/>
</option>
<inputType id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input.897129740" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.base.175050868" name="GNU ARM C++ Compiler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.base"/>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.assembler.base.1344927230" name="GNU ARM Assembler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.assembler.base">
<option id="gnu.both.asm.option.include.paths.1619799327" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/EFM32GG_STK3700/examples/rtx_blink&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/CMSIS/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/emlib/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/common/bsp&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/common/drivers&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/EnergyMicro/EFM32GG/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/reptile/RTX/INC&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/EFM32GG_STK3700/config&quot;"/>
</option>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.as.def.symbols.480259861" name="Defined symbols (-D)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.as.def.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="EFM32GG990F1024=1"/>
</option>
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.2137832125" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.base.780842768" name="GNU ARM C Linker" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.base">
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.nostdlibs.1838456290" name="No startup or default libs (-nostdlib)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.nostdlibs" value="false" valueType="boolean"/>
<option id="gnu.c.link.option.paths.1019052790" name="Library search path (-L)" superClass="gnu.c.link.option.paths" valueType="libPaths">
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/reptile/RTX/LIB/GCC/&quot;"/>
</option>
<option id="gnu.c.link.option.libs.1378010210" name="Libraries (-l)" superClass="gnu.c.link.option.libs" valueType="libs">
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="RTX_CM3"/>
</option>
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.1342201056" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.linker.base.1047528956" name="GNU ARM C++ Linker" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.linker.base"/>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.archiver.base.182750352" name="GNU ARM Archiver" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.archiver.base"/>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
<cconfiguration id="com.silabs.ide.si32.gcc.debug#com.silabs.ide.si32.gcc:4.7.3.20130312">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.silabs.ide.si32.gcc.debug#com.silabs.ide.si32.gcc:4.7.3.20130312" moduleId="org.eclipse.cdt.core.settings" name="GNU ARM 4.7.3 - Debug">
<macros>
<stringMacro name="StudioToolchainPath" type="VALUE_PATH_DIR" value="C:\SiliconLabs\SimplicityStudio\v2\developer\toolchains\gnu_arm\4.7_2013q1"/>
<stringMacro name="StudioSdkPath" type="VALUE_PATH_DIR" value="C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2"/>
</macros>
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule buildConfig.stockConfigId="com.silabs.ide.si32.gcc.debug#com.silabs.ide.si32.gcc:4.7.3.20130312" cppBuildConfig.builtinIncludes="unresolved:$%7BStudioSdkPath%7D/Device/EnergyMicro/EFM32GG/Include/ unresolved:$%7BStudioSdkPath%7D/reptile/RTX/INC/ unresolved:$%7BStudioSdkPath%7D/kits/common/bsp/ unresolved:$%7BStudioSdkPath%7D/CMSIS/Include/ unresolved:$%7BStudioSdkPath%7D/emlib/inc/ unresolved:$%7BStudioSdkPath%7D/kits/common/drivers/ unresolved:$%7BStudioSdkPath%7D/Device/EnergyMicro/EFM32GG/Include/ unresolved:$%7BStudioSdkPath%7D/reptile/RTX/INC/ unresolved:$%7BStudioSdkPath%7D/kits/common/bsp/ unresolved:$%7BStudioSdkPath%7D/CMSIS/Include/ unresolved:$%7BStudioSdkPath%7D/emlib/inc/ unresolved:$%7BStudioSdkPath%7D/kits/common/drivers/" cppBuildConfig.builtinLibraryFiles="" cppBuildConfig.builtinLibraryNames="RTX_CM3" cppBuildConfig.builtinLibraryObjects="" cppBuildConfig.builtinLibraryPaths="unresolved:$%7BStudioSdkPath%7D/reptile/RTX/LIB/GCC/" cppBuildConfig.builtinMacros="EFM32GG990F1024 EFM32GG990F1024" moduleId="com.silabs.ide.project.core" projectCommon.kitId="com.silabs.kit.si32.efm32.efm32gg.stk3700" projectCommon.partId="com.silabs.mcu.si32.efm32.efm32gg.efm32gg990f1024" projectCommon.referencedModules="[{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; id=\&quot;com.silabs.ide.si32.sdk.efm32.v2.part\&quot;&gt;\r\n &lt;inclusions pattern=\&quot;CMSIS/.*/startup_gcc_.*.s\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;CMSIS/.*/startup_iar_.*.s\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;CMSIS/.*/system_.*.c\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;,&quot;builtinSources&quot;:[&quot;CMSIS/efm32gg/startup_gcc_efm32gg.s&quot;,&quot;CMSIS/efm32gg/system_efm32gg.c&quot;]},{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; id=\&quot;com.silabs.ide.si32.sdk.efm32.v2.common.emlib\&quot;&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_assert.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_cmu.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_emu.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_gpio.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_lcd.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_system.c\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;,&quot;builtinSources&quot;:[&quot;emlib/em_assert.c&quot;,&quot;emlib/em_cmu.c&quot;,&quot;emlib/em_emu.c&quot;,&quot;emlib/em_gpio.c&quot;,&quot;emlib/em_lcd.c&quot;,&quot;emlib/em_system.c&quot;]},{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; id=\&quot;com.silabs.ide.si32.sdk.efm32.v2.kit\&quot;&gt;\r\n &lt;exclusions pattern=\&quot;.*\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;,&quot;builtinSources&quot;:[]},{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; id=\&quot;com.silabs.ide.si32.sdk.efm32.v2.common.drivers\&quot;&gt;\r\n &lt;inclusions pattern=\&quot;Drivers/segmentlcd.c\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;,&quot;builtinSources&quot;:[&quot;Drivers/segmentlcd.c&quot;]},{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; id=\&quot;com.silabs.ide.si32.sdk.efm32.v2.external.RTX\&quot;&gt;\r\n &lt;exclusions pattern=\&quot;.*\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;,&quot;builtinSources&quot;:[]},{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; id=\&quot;com.silabs.ide.si32.sdk.efm32.v2.common.CMSIS\&quot;&gt;\r\n &lt;exclusions pattern=\&quot;.*\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;,&quot;builtinSources&quot;:[]},{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; id=\&quot;com.silabs.ide.si32.sdk.efm32.v2.common.bsp\&quot;&gt;\r\n &lt;inclusions pattern=\&quot;BSP/bsp_trace.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;BSP/bsp_stk_leds.c\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;,&quot;builtinSources&quot;:[&quot;BSP/bsp_stk_leds.c&quot;,&quot;BSP/bsp_trace.c&quot;]}]" projectCommon.sdkId="com.silabs.sdk.si32.efm32.sls:2.0.0" projectCommon.toolchainId="com.silabs.ide.si32.gcc:4.7.3.20130312"/>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" description="" id="com.silabs.ide.si32.gcc.debug#com.silabs.ide.si32.gcc:4.7.3.20130312" name="GNU ARM 4.7.3 - Debug" parent="com.silabs.ide.si32.gcc.cdt.managedbuild.config.gnu.exe">
<folderInfo id="com.silabs.ide.si32.gcc.debug#com.silabs.ide.si32.gcc:4.7.3.20130312." name="/" resourcePath="">
<toolChain id="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.exe.2093499202" name="Si32 GNU ARM" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.exe">
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.debug.level.222080562" name="Debug Level" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.debug.level" value="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.debug.level.default" valueType="enumerated"/>
<targetPlatform binaryParser="org.eclipse.cdt.core.ELF;org.eclipse.cdt.core.GNU_ELF" id="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.platform.base.2020621629" isAbstract="false" name="Debug Platform" osList="win32,linux,macosx" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.platform.base"/>
<builder buildPath="${workspace_loc:/EFM32GG_rtx_blink}/GNU ARM 4.7.3 - Debug" id="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.builder.base.1526986341" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Si32 GNU ARM Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.builder.base"/>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base.1883388945" name="GNU ARM C Compiler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base">
<option id="gnu.c.compiler.option.optimization.level.407029314" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" value="gnu.c.optimization.level.none" valueType="enumerated"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.builtin.197751932" name="Always branch to builtin functions (-fno-builtin)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.builtin" value="true" valueType="boolean"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.prolog.533105394" name="Generate debugger-friendly prologs (-mno-sched-prolog)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.prolog" value="true" valueType="boolean"/>
<option id="gnu.c.compiler.option.include.paths.788376617" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/EFM32GG_STK3700/examples/rtx_blink&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/EFM32GG_STK3700/config&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/EnergyMicro/EFM32GG/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/reptile/RTX/INC&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/common/bsp&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/CMSIS/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/emlib/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/common/drivers&quot;"/>
</option>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.def.symbols.1901010885" name="Defined symbols (-D)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.def.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="EFM32GG990F1024=1"/>
</option>
<inputType id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input.533382802" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.base.174752480" name="GNU ARM C++ Compiler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.base">
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.builtin.1233926733" name="Always branch to builtin functions (-fno-builtin)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.builtin" value="true" valueType="boolean"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.prolog.1346479261" name="Generate debugger-friendly prologs (-mno-sched-prolog)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.prolog" value="true" valueType="boolean"/>
</tool>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.assembler.base.319717641" name="GNU ARM Assembler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.assembler.base">
<option id="gnu.both.asm.option.include.paths.394569379" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/EFM32GG_STK3700/examples/rtx_blink&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/EFM32GG_STK3700/config&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/EnergyMicro/EFM32GG/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/reptile/RTX/INC&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/common/bsp&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/CMSIS/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/emlib/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/common/drivers&quot;"/>
</option>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.as.def.symbols.1306910205" name="Defined symbols (-D)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.as.def.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="EFM32GG990F1024=1"/>
</option>
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1058810564" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.base.533412976" name="GNU ARM C Linker" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.base">
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.nostdlibs.182902710" name="No startup or default libs (-nostdlib)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.nostdlibs" value="false" valueType="boolean"/>
<option id="gnu.c.link.option.paths.979647247" name="Library search path (-L)" superClass="gnu.c.link.option.paths" valueType="libPaths">
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/reptile/RTX/LIB/GCC/&quot;"/>
</option>
<option id="gnu.c.link.option.libs.212703731" name="Libraries (-l)" superClass="gnu.c.link.option.libs" valueType="libs">
<listOptionValue builtIn="false" srcPrefixMapping="" srcRootPath="" value="RTX_CM3"/>
</option>
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.1345474934" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.linker.base.1686061767" name="GNU ARM C++ Linker" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.linker.base"/>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.archiver.base.1807903476" name="GNU ARM Archiver" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.archiver.base"/>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="com.silabs.ide.project.core" projectCommon.kitId="com.silabs.kit.si32.efm32.efm32gg.stk3700" projectCommon.partId="com.silabs.mcu.si32.efm32.efm32gg.efm32gg990f1024" projectCommon.sdkId="com.silabs.sdk.si32.efm32.sls:2.0.0"/>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="EFM32GG_rtx_blink.com.silabs.ide.project.core.cdt.cdtMbsProjectType.2077007272" name="SLS CDT Project" projectType="com.silabs.ide.project.core.cdt.cdtMbsProjectType"/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="com.silabs.ide.si32.gcc.release#com.silabs.ide.si32.gcc:4.7.3.20130312;com.silabs.ide.si32.gcc.release#com.silabs.ide.si32.gcc:4.7.3.20130312.;com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base.911627407;com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input.897129740">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="com.silabs.ide.si32.gcc.debug#com.silabs.ide.si32.gcc:4.7.3.20130312;com.silabs.ide.si32.gcc.debug#com.silabs.ide.si32.gcc:4.7.3.20130312.;com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base.1883388945;com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input.533382802">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="refreshScope"/>
</cproject>
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>EFM32GG_rtx_blink</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>com.silabs.ide.project.core.SLSProjectNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>
eclipse.preferences.version=1
org.eclipse.cdt.codan.checkers.errnoreturn=Warning
org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false}
org.eclipse.cdt.codan.checkers.errreturnvalue=Error
org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.checkers.noreturn=Error
org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false}
org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=Error
org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=Error
org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning
org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning
org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false}
org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning
org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},unknown\=>false,exceptions\=>()}
org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=Error
org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=Warning
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},skip\=>true}
org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=Error
org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=Error
org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.InvalidArguments=Error
org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=Error
org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=Error
org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=Error
org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=Error
org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info
org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},pattern\=>"^[a-z]",macro\=>true,exceptions\=>()}
org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning
org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.OverloadProblem=Error
org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=Error
org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=Error
org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning
org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning
org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning
org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>()}
org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning
org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},paramNot\=>false}
org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning
org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},else\=>false,afterelse\=>false}
org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=Error
org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning
org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true}
org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning
org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true}
org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning
org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>("@(\#)","$Id")}
org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=Error
org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
/***************************************************************************//**
* @file
* @brief Board support package API for GPIO leds on STK's.
* @author Energy Micro AS
* @version 3.20.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* This file is licensed under the Silicon Labs Software License Agreement. See
* "http://developer.silabs.com/legal/version/v11/Silicon_Labs_Software_License_Agreement.txt"
* for details. Before using this software for any purpose, you must agree to the
* terms of that agreement.
*
******************************************************************************/
#include "em_device.h"
#include "em_cmu.h"
#include "em_gpio.h"
#include "bsp.h"
#if defined( BSP_GPIO_LEDS )
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
typedef struct
{
GPIO_Port_TypeDef port;
unsigned int pin;
} tLedArray;
static const tLedArray ledArray[ BSP_NO_OF_LEDS ] = BSP_GPIO_LEDARRAY_INIT;
int BSP_LedsInit(void)
{
int i;
CMU_ClockEnable(cmuClock_HFPER, true);
CMU_ClockEnable(cmuClock_GPIO, true);
for ( i=0; i<BSP_NO_OF_LEDS; i++ )
{
GPIO_PinModeSet(ledArray[i].port, ledArray[i].pin, gpioModePushPull, 0);
}
return BSP_STATUS_OK;
}
uint32_t BSP_LedsGet(void)
{
int i;
uint32_t retVal, mask;
for ( i=0, retVal=0, mask=0x1; i<BSP_NO_OF_LEDS; i++, mask <<= 1 )
{
if (GPIO_PinOutGet(ledArray[i].port, ledArray[i].pin))
retVal |= mask;
}
return retVal;
}
int BSP_LedsSet(uint32_t leds)
{
int i;
uint32_t mask;
for ( i=0, mask=0x1; i<BSP_NO_OF_LEDS; i++, mask <<= 1 )
{
if ( leds & mask )
GPIO_PinOutSet(ledArray[i].port, ledArray[i].pin);
else
GPIO_PinOutClear(ledArray[i].port, ledArray[i].pin);
}
return BSP_STATUS_OK;
}
int BSP_LedClear(int ledNo)
{
if ((ledNo >= 0) && (ledNo < BSP_NO_OF_LEDS))
{
GPIO_PinOutClear(ledArray[ledNo].port, ledArray[ledNo].pin);
return BSP_STATUS_OK;
}
return BSP_STATUS_ILLEGAL_PARAM;
}
int BSP_LedGet(int ledNo)
{
int retVal = BSP_STATUS_ILLEGAL_PARAM;
if ((ledNo >= 0) && (ledNo < BSP_NO_OF_LEDS))
{
retVal = (int)GPIO_PinOutGet(ledArray[ledNo].port, ledArray[ledNo].pin);
}
return retVal;
}
int BSP_LedSet(int ledNo)
{
if ((ledNo >= 0) && (ledNo < BSP_NO_OF_LEDS))
{
GPIO_PinOutSet(ledArray[ledNo].port, ledArray[ledNo].pin);
return BSP_STATUS_OK;
}
return BSP_STATUS_ILLEGAL_PARAM;
}
int BSP_LedToggle(int ledNo)
{
if ((ledNo >= 0) && (ledNo < BSP_NO_OF_LEDS))
{
GPIO_PinOutToggle(ledArray[ledNo].port, ledArray[ledNo].pin);
return BSP_STATUS_OK;
}
return BSP_STATUS_ILLEGAL_PARAM;
}
/** @endcond */
#endif /* BSP_GPIO_LEDS */
/**************************************************************************//**
* @file
* @brief API for enabling SWO and ETM trace.
* @author Energy Micro AS
* @version 3.20.2
******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* This file is licensed under the Silicon Labs Software License Agreement. See
* "http://developer.silabs.com/legal/version/v11/Silicon_Labs_Software_License_Agreement.txt"
* for details. Before using this software for any purpose, you must agree to the
* terms of that agreement.
*
******************************************************************************/
#include <stdbool.h>
#include "em_device.h"
#include "em_gpio.h"
#include "em_cmu.h"
#include "bsp_trace.h"
#include "bsp.h"
#if defined(BSP_ETM_TRACE) && defined( ETM_PRESENT )
/**************************************************************************//**
* @brief Configure EFM32 for ETM trace output.
* @note You need to configure ETM trace on kit config menu as well!
*****************************************************************************/
void BSP_TraceEtmSetup(void)
{
/* Enable peripheral clocks */
CMU->HFCORECLKEN0 |= CMU_HFCORECLKEN0_LE;
CMU->HFPERCLKEN0 |= CMU_HFPERCLKEN0_GPIO;
CMU->OSCENCMD = CMU_OSCENCMD_AUXHFRCOEN;
/* Wait until AUXHFRCO clock is ready */
while (!(CMU->STATUS & CMU_STATUS_AUXHFRCORDY)) ;
/* Enable Port D, pins 3,4,5,6 for ETM Trace Data output */
GPIO->P[3].MODEL = (GPIO->P[3].MODEL & ~_GPIO_P_MODEL_MODE3_MASK) | GPIO_P_MODEL_MODE3_PUSHPULL;
GPIO->P[3].MODEL = (GPIO->P[3].MODEL & ~_GPIO_P_MODEL_MODE4_MASK) | GPIO_P_MODEL_MODE4_PUSHPULL;
GPIO->P[3].MODEL = (GPIO->P[3].MODEL & ~_GPIO_P_MODEL_MODE5_MASK) | GPIO_P_MODEL_MODE5_PUSHPULL;
GPIO->P[3].MODEL = (GPIO->P[3].MODEL & ~_GPIO_P_MODEL_MODE6_MASK) | GPIO_P_MODEL_MODE6_PUSHPULL;
/* Enable Port D, pin 7 for DBG_TCLK */
GPIO->P[3].MODEL = (GPIO->P[3].MODEL & ~_GPIO_P_MODEL_MODE7_MASK) | GPIO_P_MODEL_MODE7_PUSHPULL;
/* Configure trace output for alternate location */
GPIO->ROUTE = GPIO->ROUTE | GPIO_ROUTE_TCLKPEN | GPIO_ROUTE_TD0PEN | GPIO_ROUTE_TD1PEN
| GPIO_ROUTE_TD2PEN | GPIO_ROUTE_TD3PEN
| GPIO_ROUTE_ETMLOCATION_LOC0;
}
#endif
#if defined( GPIO_ROUTE_SWOPEN )
/**************************************************************************//**
* @brief Configure trace output for energyAware Profiler
* @note Enabling trace will add 80uA current for the EFM32_Gxxx_STK.
* DK's needs to be initialized with SPI-mode:
* @verbatim BSP_Init(BSP_INIT_DK_SPI); @endverbatim
*****************************************************************************/
void BSP_TraceSwoSetup(void)
{
/* Enable GPIO clock */
CMU->HFPERCLKEN0 |= CMU_HFPERCLKEN0_GPIO;
/* Enable Serial wire output pin */
GPIO->ROUTE |= GPIO_ROUTE_SWOPEN;
/* Set correct location */
GPIO->ROUTE = (GPIO->ROUTE & ~(_GPIO_ROUTE_SWLOCATION_MASK)) | BSP_TRACE_SWO_LOCATION;
/* Enable output on correct pin. */
TRACE_ENABLE_PINS();
/* Enable debug clock AUXHFRCO */
CMU->OSCENCMD = CMU_OSCENCMD_AUXHFRCOEN;
/* Wait until clock is ready */
while (!(CMU->STATUS & CMU_STATUS_AUXHFRCORDY)) ;
/* Enable trace in core debug */
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
/* Enable PC and IRQ sampling output */
DWT->CTRL = 0x400113FF;
/* Set TPIU prescaler to 16. */
TPI->ACPR = 0xf;
/* Set protocol to NRZ */
TPI->SPPR = 2;
/* Disable continuous formatting */
TPI->FFCR = 0x100;
/* Unlock ITM and output data */
ITM->LAR = 0xC5ACCE55;
ITM->TCR = 0x10009;
}
#endif
#if defined( GPIO_ROUTE_SWOPEN )
/**************************************************************************//**
* @brief Profiler configuration.
* @return true if energyAware Profiler/SWO is enabled, false if not
* @note If first word of the user page is zero, this will not
* enable SWO profiler output.
*****************************************************************************/
bool BSP_TraceProfilerSetup(void)
{
volatile uint32_t *userData = (uint32_t *) USER_PAGE;
/* Check magic "trace" word in user page */
if (*userData == 0x00000000UL)
{
return false;
}
else
{
BSP_TraceSwoSetup();
return true;
}
}
#endif
/* @file
* @brief startup file for Energy Micro EFM32GG devices.
* For use with GCC for ARM Embedded Processors
* @version 3.20.2
* Date: 08 Feb 2012
*
* Copyright (c) 2012, ARM Limited
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the ARM Limited nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ARM LIMITED BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
.syntax unified
.arch armv7-m
.section .stack
.align 3
#ifdef __STACK_SIZE
.equ Stack_Size, __STACK_SIZE
#else
.equ Stack_Size, 0x400
#endif
.globl __StackTop
.globl __StackLimit
__StackLimit:
.space Stack_Size
.size __StackLimit, . - __StackLimit
__StackTop:
.size __StackTop, . - __StackTop
.section .heap
.align 3
#ifdef __HEAP_SIZE
.equ Heap_Size, __HEAP_SIZE
#else
.equ Heap_Size, 0xC00
#endif
.globl __HeapBase
.globl __HeapLimit
__HeapBase:
.if Heap_Size
.space Heap_Size
.endif
.size __HeapBase, . - __HeapBase
__HeapLimit:
.size __HeapLimit, . - __HeapLimit
.section .isr_vector
.align 8
.globl __isr_vector
__isr_vector:
.long __StackTop /* Top of Stack */
.long Reset_Handler /* Reset Handler */
.long NMI_Handler /* NMI Handler */
.long HardFault_Handler /* Hard Fault Handler */
.long MemManage_Handler /* MPU Fault Handler */
.long BusFault_Handler /* Bus Fault Handler */
.long UsageFault_Handler /* Usage Fault Handler */
.long Default_Handler /* Reserved */
.long Default_Handler /* Reserved */
.long Default_Handler /* Reserved */
.long Default_Handler /* Reserved */
.long SVC_Handler /* SVCall Handler */
.long DebugMon_Handler /* Debug Monitor Handler */
.long Default_Handler /* Reserved */
.long PendSV_Handler /* PendSV Handler */
.long SysTick_Handler /* SysTick Handler */
/* External interrupts */
.long DMA_IRQHandler /* 0 - DMA */
.long GPIO_EVEN_IRQHandler /* 1 - GPIO_EVEN */
.long TIMER0_IRQHandler /* 2 - TIMER0 */
.long USART0_RX_IRQHandler /* 3 - USART0_RX */
.long USART0_TX_IRQHandler /* 4 - USART0_TX */
.long USB_IRQHandler /* 5 - USB */
.long ACMP0_IRQHandler /* 6 - ACMP0 */
.long ADC0_IRQHandler /* 7 - ADC0 */
.long DAC0_IRQHandler /* 8 - DAC0 */
.long I2C0_IRQHandler /* 9 - I2C0 */
.long I2C1_IRQHandler /* 10 - I2C1 */
.long GPIO_ODD_IRQHandler /* 11 - GPIO_ODD */
.long TIMER1_IRQHandler /* 12 - TIMER1 */
.long TIMER2_IRQHandler /* 13 - TIMER2 */
.long TIMER3_IRQHandler /* 14 - TIMER3 */
.long USART1_RX_IRQHandler /* 15 - USART1_RX */
.long USART1_TX_IRQHandler /* 16 - USART1_TX */
.long LESENSE_IRQHandler /* 17 - LESENSE */
.long USART2_RX_IRQHandler /* 18 - USART2_RX */
.long USART2_TX_IRQHandler /* 19 - USART2_TX */
.long UART0_RX_IRQHandler /* 20 - UART0_RX */
.long UART0_TX_IRQHandler /* 21 - UART0_TX */
.long UART1_RX_IRQHandler /* 22 - UART1_RX */
.long UART1_TX_IRQHandler /* 23 - UART1_TX */
.long LEUART0_IRQHandler /* 24 - LEUART0 */
.long LEUART1_IRQHandler /* 25 - LEUART1 */
.long LETIMER0_IRQHandler /* 26 - LETIMER0 */
.long PCNT0_IRQHandler /* 27 - PCNT0 */
.long PCNT1_IRQHandler /* 28 - PCNT1 */
.long PCNT2_IRQHandler /* 29 - PCNT2 */
.long RTC_IRQHandler /* 30 - RTC */
.long BURTC_IRQHandler /* 31 - BURTC */
.long CMU_IRQHandler /* 32 - CMU */
.long VCMP_IRQHandler /* 33 - VCMP */
.long LCD_IRQHandler /* 34 - LCD */
.long MSC_IRQHandler /* 35 - MSC */
.long AES_IRQHandler /* 36 - AES */
.long EBI_IRQHandler /* 37 - EBI */
.long EMU_IRQHandler /* 38 - EMU */
.size __isr_vector, . - __isr_vector
.text
.thumb
.thumb_func
.align 2
.globl Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
/* Loop to copy data from read only memory to RAM. The ranges
* of copy from/to are specified by following symbols evaluated in
* linker script.
* __etext: End of code section, i.e., begin of data sections to copy from.
* __data_start__/__data_end__: RAM address range that data should be
* copied to. Both must be aligned to 4 bytes boundary. */
#ifndef __NO_SYSTEM_INIT
ldr r0, =SystemInit
blx r0
#endif
ldr r1, =__etext
ldr r2, =__data_start__
ldr r3, =__data_end__
subs r3, r2
ble .flash_to_ram_loop_end
.flash_to_ram_loop:
subs r3, #4
ldr r0, [r1, r3]
str r0, [r2, r3]
bgt .flash_to_ram_loop
.flash_to_ram_loop_end:
ldr r0, =_start
bx r0
.pool
.size Reset_Handler, . - Reset_Handler
/* Macro to define default handlers. Default handler
* will be weak symbol and just dead loops. They can be
* overwritten by other handlers */
.macro def_irq_handler handler_name
.align 1
.thumb_func
.weak \handler_name
.type \handler_name, %function
\handler_name:
b .
.size \handler_name, . - \handler_name
.endm
def_irq_handler Default_Handler
def_irq_handler NMI_Handler
def_irq_handler HardFault_Handler
def_irq_handler MemManage_Handler
def_irq_handler BusFault_Handler
def_irq_handler UsageFault_Handler
def_irq_handler SVC_Handler
def_irq_handler DebugMon_Handler
def_irq_handler PendSV_Handler
def_irq_handler SysTick_Handler
def_irq_handler DMA_IRQHandler
def_irq_handler GPIO_EVEN_IRQHandler
def_irq_handler TIMER0_IRQHandler
def_irq_handler USART0_RX_IRQHandler
def_irq_handler USART0_TX_IRQHandler
def_irq_handler USB_IRQHandler
def_irq_handler ACMP0_IRQHandler
def_irq_handler ADC0_IRQHandler
def_irq_handler DAC0_IRQHandler
def_irq_handler I2C0_IRQHandler
def_irq_handler I2C1_IRQHandler
def_irq_handler GPIO_ODD_IRQHandler
def_irq_handler TIMER1_IRQHandler
def_irq_handler TIMER2_IRQHandler
def_irq_handler TIMER3_IRQHandler
def_irq_handler USART1_RX_IRQHandler
def_irq_handler USART1_TX_IRQHandler
def_irq_handler LESENSE_IRQHandler
def_irq_handler USART2_RX_IRQHandler
def_irq_handler USART2_TX_IRQHandler
def_irq_handler UART0_RX_IRQHandler
def_irq_handler UART0_TX_IRQHandler
def_irq_handler UART1_RX_IRQHandler
def_irq_handler UART1_TX_IRQHandler
def_irq_handler LEUART0_IRQHandler
def_irq_handler LEUART1_IRQHandler
def_irq_handler LETIMER0_IRQHandler
def_irq_handler PCNT0_IRQHandler
def_irq_handler PCNT1_IRQHandler
def_irq_handler PCNT2_IRQHandler
def_irq_handler RTC_IRQHandler
def_irq_handler BURTC_IRQHandler
def_irq_handler CMU_IRQHandler
def_irq_handler VCMP_IRQHandler
def_irq_handler LCD_IRQHandler
def_irq_handler MSC_IRQHandler
def_irq_handler AES_IRQHandler
def_irq_handler EBI_IRQHandler
def_irq_handler EMU_IRQHandler
.end
/***************************************************************************//**
* @file
* @brief CMSIS Cortex-M3 System Layer for EFM32GG devices.
* @author Energy Micro AS
* @version 3.20.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include <stdint.h>
#include "em_device.h"
/*******************************************************************************
****************************** DEFINES ************************************
******************************************************************************/
/** LFRCO frequency, tuned to below frequency during manufacturing. */
#define EFM32_LFRCO_FREQ (32768UL)
#define EFM32_ULFRCO_FREQ (1000UL)
/*******************************************************************************
************************** LOCAL VARIABLES ********************************
******************************************************************************/
/* System oscillator frequencies. These frequencies are normally constant */
/* for a target, but they are made configurable in order to allow run-time */
/* handling of different boards. The crystal oscillator clocks can be set */
/* compile time to a non-default value by defining respective EFM32_nFXO_FREQ */
/* values according to board design. By defining the EFM32_nFXO_FREQ to 0, */
/* one indicates that the oscillator is not present, in order to save some */
/* SW footprint. */
#ifndef EFM32_HFXO_FREQ
#ifdef _EFM32_GIANT_FAMILY
#define EFM32_HFXO_FREQ (48000000UL)
#else
#define EFM32_HFXO_FREQ (32000000UL)
#endif
#endif
/* Do not define variable if HF crystal oscillator not present */
#if (EFM32_HFXO_FREQ > 0)
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** System HFXO clock. */
static uint32_t SystemHFXOClock = EFM32_HFXO_FREQ;
/** @endcond (DO_NOT_INCLUDE_WITH_DOXYGEN) */
#endif
#ifndef EFM32_LFXO_FREQ
#define EFM32_LFXO_FREQ (EFM32_LFRCO_FREQ)
#endif
/* Do not define variable if LF crystal oscillator not present */
#if (EFM32_LFXO_FREQ > 0)
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** System LFXO clock. */
static uint32_t SystemLFXOClock = EFM32_LFXO_FREQ;
/** @endcond (DO_NOT_INCLUDE_WITH_DOXYGEN) */
#endif
/* Inline function to get the chip's Production Revision. */
__STATIC_INLINE uint8_t GetProdRev(void)
{
return ((DEVINFO->PART & _DEVINFO_PART_PROD_REV_MASK)
>> _DEVINFO_PART_PROD_REV_SHIFT);
}
/*******************************************************************************
************************** GLOBAL VARIABLES *******************************
******************************************************************************/
/**
* @brief
* System System Clock Frequency (Core Clock).
*
* @details
* Required CMSIS global variable that must be kept up-to-date.
*/
uint32_t SystemCoreClock;
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Get the current core clock frequency.
*
* @details
* Calculate and get the current core clock frequency based on the current
* configuration. Assuming that the SystemCoreClock global variable is
* maintained, the core clock frequency is stored in that variable as well.
* This function will however calculate the core clock based on actual HW
* configuration. It will also update the SystemCoreClock global variable.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* The current core clock frequency in Hz.
******************************************************************************/
uint32_t SystemCoreClockGet(void)
{
uint32_t ret;
ret = SystemHFClockGet();
#if defined (_EFM32_GIANT_FAMILY)
/* Leopard/Giant Gecko has an additional divider */
ret = ret / (1 + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK)>>_CMU_CTRL_HFCLKDIV_SHIFT));
#endif
ret >>= (CMU->HFCORECLKDIV & _CMU_HFCORECLKDIV_HFCORECLKDIV_MASK) >>
_CMU_HFCORECLKDIV_HFCORECLKDIV_SHIFT;
/* Keep CMSIS variable up-to-date just in case */
SystemCoreClock = ret;
return ret;
}
/***************************************************************************//**
* @brief
* Get the current HFCLK frequency.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* The current HFCLK frequency in Hz.
******************************************************************************/
uint32_t SystemHFClockGet(void)
{
uint32_t ret;
switch (CMU->STATUS & (CMU_STATUS_HFRCOSEL | CMU_STATUS_HFXOSEL |
CMU_STATUS_LFRCOSEL | CMU_STATUS_LFXOSEL))
{
case CMU_STATUS_LFXOSEL:
#if (EFM32_LFXO_FREQ > 0)
ret = SystemLFXOClock;
#else
/* We should not get here, since core should not be clocked. May */
/* be caused by a misconfiguration though. */
ret = 0;
#endif
break;
case CMU_STATUS_LFRCOSEL:
ret = EFM32_LFRCO_FREQ;
break;
case CMU_STATUS_HFXOSEL:
#if (EFM32_HFXO_FREQ > 0)
ret = SystemHFXOClock;
#else
/* We should not get here, since core should not be clocked. May */
/* be caused by a misconfiguration though. */
ret = 0;
#endif
break;
default: /* CMU_STATUS_HFRCOSEL */
switch (CMU->HFRCOCTRL & _CMU_HFRCOCTRL_BAND_MASK)
{
case CMU_HFRCOCTRL_BAND_28MHZ:
ret = 28000000;
break;
case CMU_HFRCOCTRL_BAND_21MHZ:
ret = 21000000;
break;
case CMU_HFRCOCTRL_BAND_14MHZ:
ret = 14000000;
break;
case CMU_HFRCOCTRL_BAND_11MHZ:
ret = 11000000;
break;
case CMU_HFRCOCTRL_BAND_7MHZ:
if ( GetProdRev() >= 19 )
ret = 6600000;
else
ret = 7000000;
break;
case CMU_HFRCOCTRL_BAND_1MHZ:
if ( GetProdRev() >= 19 )
ret = 1200000;
else
ret = 1000000;
break;
default:
ret = 0;
break;
}
break;
}
return ret;
}
/**************************************************************************//**
* @brief
* Get high frequency crystal oscillator clock frequency for target system.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* HFXO frequency in Hz.
*****************************************************************************/
uint32_t SystemHFXOClockGet(void)
{
/* External crystal oscillator present? */
#if (EFM32_HFXO_FREQ > 0)
return SystemHFXOClock;
#else
return 0;
#endif
}
/**************************************************************************//**
* @brief
* Set high frequency crystal oscillator clock frequency for target system.
*
* @note
* This function is mainly provided for being able to handle target systems
* with different HF crystal oscillator frequencies run-time. If used, it
* should probably only be used once during system startup.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @param[in] freq
* HFXO frequency in Hz used for target.
*****************************************************************************/
void SystemHFXOClockSet(uint32_t freq)
{
/* External crystal oscillator present? */
#if (EFM32_HFXO_FREQ > 0)
SystemHFXOClock = freq;
/* Update core clock frequency if HFXO is used to clock core */
if (CMU->STATUS & CMU_STATUS_HFXOSEL)
{
/* The function will update the global variable */
SystemCoreClockGet();
}
#else
(void)freq; /* Unused parameter */
#endif
}
/**************************************************************************//**
* @brief
* Initialize the system.
*
* @details
* Do required generic HW system init.
*
* @note
* This function is invoked during system init, before the main() routine
* and any data has been initialized. For this reason, it cannot do any
* initialization of variables etc.
*****************************************************************************/
void SystemInit(void)
{
}
/**************************************************************************//**
* @brief
* Get low frequency RC oscillator clock frequency for target system.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* LFRCO frequency in Hz.
*****************************************************************************/
uint32_t SystemLFRCOClockGet(void)
{
/* Currently we assume that this frequency is properly tuned during */
/* manufacturing and is not changed after reset. If future requirements */
/* for re-tuning by user, we can add support for that. */
return EFM32_LFRCO_FREQ;
}
/**************************************************************************//**
* @brief
* Get ultra low frequency RC oscillator clock frequency for target system.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* ULFRCO frequency in Hz.
*****************************************************************************/
uint32_t SystemULFRCOClockGet(void)
{
/* The ULFRCO frequency is not tuned, and can be very inaccurate */
return EFM32_ULFRCO_FREQ;
}
/**************************************************************************//**
* @brief
* Get low frequency crystal oscillator clock frequency for target system.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* LFXO frequency in Hz.
*****************************************************************************/
uint32_t SystemLFXOClockGet(void)
{
/* External crystal oscillator present? */
#if (EFM32_LFXO_FREQ > 0)
return SystemLFXOClock;
#else
return 0;
#endif
}
/**************************************************************************//**
* @brief
* Set low frequency crystal oscillator clock frequency for target system.
*
* @note
* This function is mainly provided for being able to handle target systems
* with different HF crystal oscillator frequencies run-time. If used, it
* should probably only be used once during system startup.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @param[in] freq
* LFXO frequency in Hz used for target.
*****************************************************************************/
void SystemLFXOClockSet(uint32_t freq)
{
/* External crystal oscillator present? */
#if (EFM32_LFXO_FREQ > 0)
SystemLFXOClock = freq;
/* Update core clock frequency if LFXO is used to clock core */
if (CMU->STATUS & CMU_STATUS_LFXOSEL)
{
/* The function will update the global variable */
SystemCoreClockGet();
}
#else
(void)freq; /* Unused parameter */
#endif
}
/**************************************************************************//**
* @file
* @brief EFM32 Segment LCD Display driver
* @author Energy Micro AS
* @version 3.20.2
******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* This file is licensed under the Silicon Labs Software License Agreement. See
* "http://developer.silabs.com/legal/version/v11/Silicon_Labs_Software_License_Agreement.txt"
* for details. Before using this software for any purpose, you must agree to the
* terms of that agreement.
*
******************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include "em_device.h"
#include "em_cmu.h"
#include "em_gpio.h"
#include "segmentlcd.h"
/**************************************************************************//**
* @brief
* Defines each text symbol's segment in terms of COM and BIT numbers,
* in a way that we can enumerate each bit for each text segment in the
* following bit pattern:
* @verbatim
* -------0------
*
* | \7 |8 /9 |
* |5 \ | / |1
*
* --6--- ---10--
*
* | / | \11 |
* |4 /13 |12 \ |2
*
* -------3------
* @endverbatim
* E.g.: First text character bit pattern #3 (above) is
* Segment 1D for Display
* Location COM 3, BIT 0
*****************************************************************************/
typedef struct
{
uint8_t com[14]; /**< LCD COM line (for multiplexing) */
uint8_t bit[14]; /**< LCD bit number */
} CHAR_TypeDef;
/**************************************************************************//**
* @brief Defines segment COM and BIT fields numeric display
*****************************************************************************/
typedef struct
{
uint8_t com[7]; /**< LCD COM line (for multiplexing) */
uint8_t bit[7]; /**< LCD bit number */
} NUMBER_TypeDef;
/**************************************************************************//**
* @brief Defines segment COM and BIT fields for Energy Modes on display
*****************************************************************************/
typedef struct
{
uint8_t com[5]; /**< LCD COM line (for multiplexing) */
uint8_t bit[5]; /**< LCD bit number */
} EM_TypeDef;
/**************************************************************************//**
* @brief Defines segment COM and BIT fields for A-wheel (suited for Anim)
*****************************************************************************/
typedef struct
{
uint8_t com[8]; /**< LCD COM line (for multiplexing) */
uint8_t bit[8]; /**< LCD bit number */
} ARING_TypeDef;
/**************************************************************************//**
* @brief Defines segment COM and BIT fields for A-wheel (suited for Anim)
*****************************************************************************/
typedef struct
{
uint8_t com[4]; /**< LCD COM line (for multiplexing) */
uint8_t bit[4]; /**< LCD bit number */
} BATTERY_TypeDef;
/**************************************************************************//**
* @brief Defines prototype for all segments in display
*****************************************************************************/
typedef struct
{
CHAR_TypeDef Text[7]; /**< Text on display */
NUMBER_TypeDef Number[4]; /**< Numbers on display */
EM_TypeDef EMode; /**< Display energy mode */
ARING_TypeDef ARing; /**< Display ring */
BATTERY_TypeDef Battery; /**< Display battery */
} MCU_DISPLAY;
/**************************************************************************//**
* @brief Working instance of LCD display
*****************************************************************************/
static const MCU_DISPLAY EFM_Display = EFM_DISPLAY_DEF;
/**************************************************************************//**
* @brief
* Defines higlighted segments for the alphabet, starting from "blank" (SPACE)
* Uses bit pattern as defined for text segments above.
* E.g. a capital O, would have bits 0 1 2 3 4 5 => 0x003f defined
*****************************************************************************/
static const uint16_t EFM_Alphabet[] = {
0x0000, /* space */
0x1100, /* ! */
0x0280, /* " */
0x0000, /* # */
0x0000, /* $ */
0x0602, /* % */
0x0000, /* & */
0x0020, /* ' */
0x0039, /* ( */
0x000f, /* ) */
0x0000, /* * */
0x1540, /* + */
0x2000, /* , */
0x0440, /* - */
0x1000, /* . */
0x2200, /* / */
0x003f, /* 0 */
0x0006, /* 1 */
0x045b, /* 2 */
0x044f, /* 3 */
0x0466, /* 4 */
0x046d, /* 5 */
0x047d, /* 6 */
0x0007, /* 7 */
0x047f, /* 8 */
0x046f, /* 9 */
0x0000, /* : */
0x0000, /* ; */
0x0a00, /* < */
0x0000, /* = */
0x2080, /* > */
0x0000, /* ? */
0xffff, /* @ */
0x0477, /* A */
0x0a79, /* B */
0x0039, /* C */
0x20b0, /* D */
0x0079, /* E */
0x0071, /* F */
0x047d, /* G */
0x0476, /* H */
0x0006, /* I */
0x000e, /* J */
0x0a70, /* K */
0x0038, /* L */
0x02b6, /* M */
0x08b6, /* N */
0x003f, /* O */
0x0473, /* P */
0x083f, /* Q */
0x0c73, /* R */
0x046d, /* S */
0x1101, /* T */
0x003e, /* U */
0x2230, /* V */
0x2836, /* W */
0x2a80, /* X */
0x046e, /* Y */
0x2209, /* Z */
0x0039, /* [ */
0x0880, /* backslash */
0x000f, /* ] */
0x0001, /* ^ */
0x0008, /* _ */
0x0100, /* ` */
0x1058, /* a */
0x047c, /* b */
0x0058, /* c */
0x045e, /* d */
0x2058, /* e */
0x0471, /* f */
0x0c0c, /* g */
0x0474, /* h */
0x0004, /* i */
0x000e, /* j */
0x0c70, /* k */
0x0038, /* l */
0x1454, /* m */
0x0454, /* n */
0x045c, /* o */
0x0473, /* p */
0x0467, /* q */
0x0450, /* r */
0x0c08, /* s */
0x0078, /* t */
0x001c, /* u */
0x2010, /* v */
0x2814, /* w */
0x2a80, /* x */
0x080c, /* y */
0x2048, /* z */
0x0000,
};
/**************************************************************************//**
* @brief
* Defines higlighted segments for the numeric display
*****************************************************************************/
static const uint16_t EFM_Numbers[] = {
0x003f, /* 0 */
0x0006, /* 1 */
0x005b, /* 2 */
0x004f, /* 3 */
0x0066, /* 4 */
0x006d, /* 5 */
0x007d, /* 6 */
0x0007, /* 7 */
0x007f, /* 8 */
0x006f, /* 9 */
0x0077, /* A */
0x007c, /* b */
0x0039, /* C */
0x005e, /* d */
0x0079, /* E */
0x0071, /* F */
0x0040 /* - */
};
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/* sign is last element of the table */
static const uint16_t signIndex = sizeof(EFM_Numbers)/sizeof(uint16_t) - 1 ;
static const LCD_Init_TypeDef lcdInit = LCD_INIT_DEF;
/** @endcond */
/**************************************************************************//**
* @brief Disable all segments
*****************************************************************************/
void SegmentLCD_AllOff(void)
{
/* Turn on low segments */
LCD_ALL_SEGMENTS_OFF();
}
/**************************************************************************//**
* @brief Enable all segments
*****************************************************************************/
void SegmentLCD_AllOn(void)
{
LCD_ALL_SEGMENTS_ON();
}
/**************************************************************************//**
* @brief Turn all segments on alpha characters in display off
*****************************************************************************/
void SegmentLCD_AlphaNumberOff(void)
{
LCD_ALPHA_NUMBER_OFF();
return;
}
/**************************************************************************//**
* @brief Light up or shut off Ring of Indicators
* @param anum "Segment number" on "Ring", range 0 - 7
* @param on Zero is off, non-zero is on
*****************************************************************************/
void SegmentLCD_ARing(int anum, int on)
{
uint32_t com, bit;
com = EFM_Display.ARing.com[anum];
bit = EFM_Display.ARing.bit[anum];
if (on)
{
LCD_SegmentSet(com, bit, true);
}
else
{
LCD_SegmentSet(com, bit, false);
}
}
/**************************************************************************//**
* @brief Light up or shut off Battery Indicator
* @param batteryLevel Battery Level, 0 to 4 (0 turns all off)
*****************************************************************************/
void SegmentLCD_Battery(int batteryLevel)
{
uint32_t com, bit;
int i, on;
for (i = 0; i < 4; i++)
{
if (i < batteryLevel)
{
on = 1;
}
else
{
on = 0;
}
com = EFM_Display.Battery.com[i];
bit = EFM_Display.Battery.bit[i];
if (on)
{
LCD_SegmentSet(com, bit, true);
}
else
{
LCD_SegmentSet(com, bit, false);
}
}
}
/**************************************************************************//**
* @brief Disables LCD controller
*****************************************************************************/
void SegmentLCD_Disable(void)
{
/* Disable LCD */
LCD_Enable(false);
/* Make sure CTRL register has been updated */
LCD_SyncBusyDelay(LCD_SYNCBUSY_CTRL);
/* Turn off LCD clock */
CMU_ClockEnable(cmuClock_LCD, false);
/* Turn off voltage boost if enabled */
CMU->LCDCTRL = 0;
}
/**************************************************************************//**
* @brief Light up or shut off Energy Mode indicator
* @param em Energy Mode numer 0 to 4
* @param on Zero is off, non-zero is on
*****************************************************************************/
void SegmentLCD_EnergyMode(int em, int on)
{
uint32_t com, bit;
com = EFM_Display.EMode.com[em];
bit = EFM_Display.EMode.bit[em];
if (on)
{
LCD_SegmentSet(com, bit, true);
}
else
{
LCD_SegmentSet(com, bit, false);
}
}
/**************************************************************************//**
* @brief Segment LCD Initialization routine for EFM32 STK display
* @param useBoost Set to use voltage boost
*****************************************************************************/
void SegmentLCD_Init(bool useBoost)
{
/* Ensure LE modules are accessible */
CMU_ClockEnable(cmuClock_CORELE, true);
/* Enable LFRCO as LFACLK in CMU (will also enable oscillator if not enabled) */
CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFRCO);
/* LCD Controller Prescaler */
CMU_ClockDivSet(cmuClock_LCDpre, LCD_CMU_CLK_PRE);
/* Frame Rate */
CMU_LCDClkFDIVSet(LCD_CMU_CLK_DIV);
/* Enable clock to LCD module */
CMU_ClockEnable(cmuClock_LCD, true);
LCD_DISPLAY_ENABLE();
/* Disable interrupts */
LCD_IntDisable(0xFFFFFFFF);
/* Initialize and enable LCD controller */
LCD_Init(&lcdInit);
/* Enable all display segments */
LCD_SEGMENTS_ENABLE();
/* Enable boost if necessary */
if (useBoost)
{
LCD_VBoostSet(LCD_BOOST_LEVEL);
LCD_VLCDSelect(lcdVLCDSelVExtBoost);
CMU->LCDCTRL |= CMU_LCDCTRL_VBOOSTEN;
}
/* Turn all segments off */
SegmentLCD_AllOff();
LCD_SyncBusyDelay(0xFFFFFFFF);
}
/**************************************************************************//**
* @brief Write a hexadecimal number on lower alphanumeric part of
* Segment LCD display
* @param num Hexadecimal number value to put on display, in range 0
* to 0x0FFFFFFF
*****************************************************************************/
void SegmentLCD_LowerHex( uint32_t num )
{
int i;
char str[7];
uint32_t nibble;
SegmentLCD_Symbol(LCD_SYMBOL_MINUS, 0);
for ( i=6; i>=0; i-- )
{
nibble = num & 0xF;
if ( nibble < 10 )
str[i] = nibble + '0';
else if ( nibble == 11 )
str[i] = 'b';
else if ( nibble == 13 )
str[i] = 'd';
else
str[i] = (nibble - 10) + 'A';
num >>= 4;
}
SegmentLCD_Write(str);
}
/**************************************************************************//**
* @brief Write number on lower alphanumeric part of Segment LCD display
* @param num Numeric value to put on display, in range -9999999 to +9999999
*****************************************************************************/
void SegmentLCD_LowerNumber( int num )
{
int i;
char str[7];
SegmentLCD_Symbol(LCD_SYMBOL_MINUS, 0);
if ( ( num > 9999999 ) || ( num < -9999999 ) )
{
SegmentLCD_Write("Ovrflow");
return;
}
if ( num < 0 )
{
SegmentLCD_Symbol(LCD_SYMBOL_MINUS, 1);
num = -num;
}
for ( i=6; i>=0; i-- )
{
if ( ( i < 6 ) && ( num == 0 ) )
{
str[i] = ' ';
}
else
{
str[i] = (num % 10) + '0';
num /= 10;
}
}
SegmentLCD_Write(str);
}
/**************************************************************************//**
* @brief Write number on numeric part on Segment LCD display
* @param value Numeric value to put on display, in range -999 to +9999
*****************************************************************************/
void SegmentLCD_Number(int value)
{
int i, com, bit, digit, div, neg;
uint16_t bitpattern;
uint16_t num;
/* Parameter consistancy check */
if (value >= 9999)
{
value = 9999;
}
if (value <= -1000)
{
value = -999;
}
if (value < 0)
{
value = abs(value);
neg = 1;
}
else
{
neg = 0;
}
/* If an update is in progress we must block, or there might be tearing */
LCD_SyncBusyDelay(0xFFFFFFFF);
/* Freeze updates to avoid partial refresh of display */
LCD_FreezeEnable(true);
/* Turn off all number LCD segments */
SegmentLCD_NumberOff();
/* Extract useful digits */
div = 1;
for (digit = 0; digit < 4; digit++)
{
num = (value / div) % 10;
if ((neg == 1) && (digit == 3)) num = signIndex;
/* Get number layout of display */
bitpattern = EFM_Numbers[num];
for (i = 0; i < 7; i++)
{
bit = EFM_Display.Number[digit].bit[i];
com = EFM_Display.Number[digit].com[i];
if (bitpattern & (1 << i))
{
LCD_SegmentSet(com, bit, true);
}
}
div = div * 10;
}
/* Sync LCD registers to LE domain */
LCD_FreezeEnable(false);
}
/**************************************************************************//**
* @brief Turn all segments on numeric digits in display off
*****************************************************************************/
void SegmentLCD_NumberOff(void)
{
/* Turn off all number segments */
LCD_NUMBER_OFF();
return;
}
/**************************************************************************//**
* @brief Light up or shut off various symbols on Segment LCD
* @param s Which symbol to turn on or off
* @param on Zero is off, non-zero is on
*****************************************************************************/
void SegmentLCD_Symbol(lcdSymbol s, int on)
{
int com = 0;
int bit = 0;
switch (s)
{
case LCD_SYMBOL_GECKO:
com = LCD_SYMBOL_GECKO_COM;
bit = LCD_SYMBOL_GECKO_SEG;
break;
case LCD_SYMBOL_ANT:
com = LCD_SYMBOL_ANT_COM;
bit = LCD_SYMBOL_ANT_SEG;
break;
case LCD_SYMBOL_PAD0:
com = LCD_SYMBOL_PAD0_COM;
bit = LCD_SYMBOL_PAD0_SEG;
break;
case LCD_SYMBOL_PAD1:
com = LCD_SYMBOL_PAD1_COM;
bit = LCD_SYMBOL_PAD1_SEG;
break;
case LCD_SYMBOL_EFM32:
com = LCD_SYMBOL_EFM32_COM;
bit = LCD_SYMBOL_EFM32_SEG;
break;
case LCD_SYMBOL_MINUS:
com = LCD_SYMBOL_MINUS_COM;
bit = LCD_SYMBOL_MINUS_SEG;
break;
case LCD_SYMBOL_COL3:
com = LCD_SYMBOL_COL3_COM;
bit = LCD_SYMBOL_COL3_SEG;
break;
case LCD_SYMBOL_COL5:
com = LCD_SYMBOL_COL5_COM;
bit = LCD_SYMBOL_COL5_SEG;
break;
case LCD_SYMBOL_COL10:
com = LCD_SYMBOL_COL10_COM;
bit = LCD_SYMBOL_COL10_SEG;
break;
#ifdef LCD_SYMBOL_DEGC_SEG
case LCD_SYMBOL_DEGC:
com = LCD_SYMBOL_DEGC_COM;
bit = LCD_SYMBOL_DEGC_SEG;
break;
#endif
#ifdef LCD_SYMBOL_DEGF_SEG
case LCD_SYMBOL_DEGF:
com = LCD_SYMBOL_DEGF_COM;
bit = LCD_SYMBOL_DEGF_SEG;
break;
#endif
#ifdef LCD_SYMBOL_DP2_SEG
case LCD_SYMBOL_DP2:
com = LCD_SYMBOL_DP2_COM;
bit = LCD_SYMBOL_DP2_SEG;
break;
#endif
#ifdef LCD_SYMBOL_DP3_SEG
case LCD_SYMBOL_DP3:
com = LCD_SYMBOL_DP3_COM;
bit = LCD_SYMBOL_DP3_SEG;
break;
#endif
#ifdef LCD_SYMBOL_DP4_SEG
case LCD_SYMBOL_DP4:
com = LCD_SYMBOL_DP4_COM;
bit = LCD_SYMBOL_DP4_SEG;
break;
#endif
#ifdef LCD_SYMBOL_DP5_SEG
case LCD_SYMBOL_DP5:
com = LCD_SYMBOL_DP5_COM;
bit = LCD_SYMBOL_DP5_SEG;
break;
#endif
case LCD_SYMBOL_DP6:
com = LCD_SYMBOL_DP6_COM;
bit = LCD_SYMBOL_DP6_SEG;
break;
case LCD_SYMBOL_DP10:
com = LCD_SYMBOL_DP10_COM;
bit = LCD_SYMBOL_DP10_SEG;
break;
#ifdef LCD_SYMBOL_AM_SEG
case LCD_SYMBOL_AM:
com = LCD_SYMBOL_AM_COM;
bit = LCD_SYMBOL_AM_SEG;
break;
#endif
#ifdef LCD_SYMBOL_PM_SEG
case LCD_SYMBOL_PM:
com = LCD_SYMBOL_PM_COM;
bit = LCD_SYMBOL_PM_SEG;
break;
#endif
#ifdef LCD_SYMBOL_MICROAMP_SEG
case LCD_SYMBOL_MICROAMP:
com = LCD_SYMBOL_MICROAMP_COM;
bit = LCD_SYMBOL_MICROAMP_SEG;
break;
#endif
#ifdef LCD_SYMBOL_MILLIAMP_SEG
case LCD_SYMBOL_MILLIAMP:
com = LCD_SYMBOL_MILLIAMP_COM;
bit = LCD_SYMBOL_MILLIAMP_SEG;
break;
#endif
}
if (on)
{
LCD_SegmentSet(com, bit, true);
}
else
{
LCD_SegmentSet(com, bit, false);
}
}
/**************************************************************************//**
* @brief Write hexadecimal number on numeric part on Segment LCD display
* @param value Numeric value to put on display, in range 0x0000-0xFFFF
*****************************************************************************/
void SegmentLCD_UnsignedHex(uint16_t value)
{
int num, i, com, bit, digit;
uint16_t bitpattern;
/* Parameter consistancy check */
if (value >= 0xffff)
{
value = 0xffff;
}
/* If an update is in progress we must block, or there might be tearing */
LCD_SyncBusyDelay(0xFFFFFFFF);
/* Freeze updates to avoid partial refresh of display */
LCD_FreezeEnable(true);
/* Turn off all number LCD segments */
SegmentLCD_NumberOff();
for (digit = 0; digit < 4; digit++)
{
num = (value >> (4 * digit)) & 0x0f;
bitpattern = EFM_Numbers[num];
for (i = 0; i < 7; i++)
{
bit = EFM_Display.Number[digit].bit[i];
com = EFM_Display.Number[digit].com[i];
if (bitpattern & (1 << i))
{
LCD_SegmentSet(com, bit, true);
}
}
}
/* Sync LCD registers to LE domain */
LCD_FreezeEnable(false);
}
/**************************************************************************//**
* @brief Write text on LCD display
* @param string Text string to show on display
*****************************************************************************/
void SegmentLCD_Write(char *string)
{
int data, length, index;
uint16_t bitfield;
uint32_t com, bit;
int i;
length = strlen(string);
index = 0;
/* If an update is in progress we must block, or there might be tearing */
LCD_SyncBusyDelay(0xFFFFFFFF);
/* Freeze LCD to avoid partial updates */
LCD_FreezeEnable(true);
/* Turn all segments off */
SegmentLCD_AlphaNumberOff();
/* Fill out all characters on display */
for (index = 0; index < 7; index++)
{
if (index < length)
{
data = (int) *string;
}
else /* Padding with space */
{
data = 0x20; /* SPACE */
}
/* Defined letters currently starts at "SPACE" - ASCII 0x20; */
data = data - 0x20;
/* Get font for this letter */
bitfield = EFM_Alphabet[data];
for (i = 0; i < 14; i++)
{
bit = EFM_Display.Text[index].bit[i];
com = EFM_Display.Text[index].com[i];
if (bitfield & (1 << i))
{
/* Turn on segment */
LCD_SegmentSet(com, bit, true);
}
}
string++;
}
/* Enable update */
LCD_FreezeEnable(false);
}
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
# Add inputs and outputs from these tool invocations to the build variables
C_SRCS += \
../BSP/bsp_stk_leds.c \
../BSP/bsp_trace.c
OBJS += \
./BSP/bsp_stk_leds.o \
./BSP/bsp_trace.o
C_DEPS += \
./BSP/bsp_stk_leds.d \
./BSP/bsp_trace.d
# Each subdirectory must supply rules for building sources it contributes
BSP/bsp_stk_leds.o: ../BSP/bsp_stk_leds.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/rtx_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/RTX/INC" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"BSP/bsp_stk_leds.d" -MT"BSP/bsp_stk_leds.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
BSP/bsp_trace.o: ../BSP/bsp_trace.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/rtx_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/RTX/INC" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"BSP/bsp_trace.d" -MT"BSP/bsp_trace.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
# Add inputs and outputs from these tool invocations to the build variables
C_SRCS += \
../CMSIS/efm32gg/system_efm32gg.c
S_SRCS += \
../CMSIS/efm32gg/startup_gcc_efm32gg.s
OBJS += \
./CMSIS/efm32gg/startup_gcc_efm32gg.o \
./CMSIS/efm32gg/system_efm32gg.o
C_DEPS += \
./CMSIS/efm32gg/system_efm32gg.d
# Each subdirectory must supply rules for building sources it contributes
CMSIS/efm32gg/%.o: ../CMSIS/efm32gg/%.s
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM Assembler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb -c -x assembler-with-cpp -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/rtx_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/RTX/INC" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" '-DEFM32GG990F1024=1' -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
CMSIS/efm32gg/system_efm32gg.o: ../CMSIS/efm32gg/system_efm32gg.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/rtx_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/RTX/INC" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"CMSIS/efm32gg/system_efm32gg.d" -MT"CMSIS/efm32gg/system_efm32gg.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
# Add inputs and outputs from these tool invocations to the build variables
C_SRCS += \
../Drivers/segmentlcd.c
OBJS += \
./Drivers/segmentlcd.o
C_DEPS += \
./Drivers/segmentlcd.d
# Each subdirectory must supply rules for building sources it contributes
Drivers/segmentlcd.o: ../Drivers/segmentlcd.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/rtx_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/RTX/INC" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"Drivers/segmentlcd.d" -MT"Drivers/segmentlcd.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
:1000000000000220F120000027210000292100002B
:100010002B2100002D2100002F21000025210000B0
:10002000252100002521000025210000053E0000BB
:100030003321000025210000733E0000AB3E00008C
:10004000392100003B2100003D2100003F2100003C
:10005000412100004321000045210000472100000C
:10006000492100004B2100004D2100004F210000DC
:1000700051210000532100005521000057210000AC
:10008000592100005B2100005D2100005F2100007C
:10009000612100006321000065210000672100004C
:1000A000692100006B2100006D2100006F2100001C
:1000B00071210000732100007521000077210000EC
:1000C000792100007B2100007D2100007F210000BC
:1000D0008121000083210000852100000000000034
:1000E0000000000000000000000000000000000010
:1000F0000000000000000000000000000000000000
:1001000010B5054C237833B9044810B10448AFF357
:1001100000800121217010BD880000200000000037
:100120005C45000008B5064B1BB106480649AFF315
:1001300000800648016811B1054A02B1904708BD28
:10014000000000005C4500008C00002088000020BA
:1001500000000000154B002B08BF134B9D46A3F574
:10016000803A00218B460F461348144A121A03F0B6
:100170004BFF0F4B002B00D098470E4B002B00D0AD
:1001800098470020002104460D4600200C4900221B
:10019000002303F0D7FE03F011FF2046294600F0AC
:1001A000FBF803F0DFFE00BF0000080000000220A3
:1001B000000000000102000088000020900C0020D8
:1001C000913F000080B400AF4FF46D43CEF20003C6
:1001D0004FF46D42CEF20002126922F004021A615D
:1001E00030BFBD4680BC704780B500AFFFF7EAFF67
:1001F000FCE700BF80B483B000AF7860FEE700BFCB
:100200000020002104460D46084803F0A5FE03F037
:10021000D5FE2046294602F0A9FA0548002102F041
:1002200061FB02F0B9FA03F09DFE0000913F00006F
:100230000000002080B582B000AF48F2FC13C0F689
:10024000E0731B687B603B46184601F0C9FC7B6885
:100250004FEA1363102B10D17B78032B0DD148F29A
:10026000C003C4F20C0348F2C002C4F20C021268CC
:1002700022F0500242F010021A6007F10807BD4652
:1002800080BD00BF80B586B000AF786000E000BFE1
:1002900040F60043C2F200031B6807F10802104653
:1002A00019464FF0FF3202F089FDBB68102BEED1EA
:1002B000FB687B61786901F099FE40F67033C2F209
:1002C00000031B681846796902F07AFCDFE700BF7B
:1002D00080B584B000AF786040F2B803C2F200038A
:1002E0001B6803F1010303F00F0240F2B803C2F2EE
:1002F00000031A6040F2B803C2F200031B681846FC
:1003000002F094F840F67033C2F200031B681846FE
:1003100002F03EFCF86040F2B803C2F200031B6832
:10032000092B02DD4FF0310301E04FF03003FA6892
:10033000137040F2B803C2F20003196846F2676313
:10034000C6F2666383FB01234FEAA3024FEAE1731F
:10035000D21A13464FEA83039B184FEA4303CA1A83
:10036000D3B203F13003DAB2FB685A70FB684FF086
:1003700000029A7040F60043C2F200031A68FB685C
:10038000104619464FF0FF3202F0F8FC4FF4FA70B5
:1003900002F020FBA0E700BF80B500AFFFF74AFFE7
:1003A00002F0E4F902F024F902F002F84FF0000044
:1003B00001F0AAFD44F22430C0F2000002F0BAFBC2
:1003C000024640F67033C2F200031A6044F2303045
:1003D000C0F200004FF0000102F0A2FC024640F61D
:1003E0000043C2F200031A6044F24830C0F2000039
:1003F0004FF0000102F076FA44F23830C0F200000B
:100400004FF0000102F06EFA02F0C6F94FF000035F
:10041000184680BD80B487B000AFF860B9607A60DC
:10042000FB6803F104734FEAC302BB68D3184FEAB9
:1004300083037B617B697A681A6007F11C07BD46FC
:1004400080BC704780B483B000AF4FF00003C4F2AB
:100450000C035B687B607B6803F00703052B19D8EE
:100460004FF0010202FA03F303F02C02002A0AD132
:1004700003F01303002B0DD07B6823F0070343F038
:1004800004037B6006E07B6823F0070343F0050369
:100490007B6000BF4FF00003C4F20C037A685A601F
:1004A00007F10C07BD4680BC704700BF90B486B012
:1004B00000AF78607B683B613B69B3FA83F4FC6012
:1004C000FB68DBB2C3F11F037B617B69184607F150
:1004D0001807BD4690BC704780B483B000AF786009
:1004E0007B684FF0010202FA03F3184607F10C078C
:1004F000BD4680BC704700BF80B485B000AF786057
:100500004FF00003C4F20C035B68FB607A684FF4A1
:100510009043C0F2E8139A4214D9FB6803F0070332
:10052000A3F10203012B06D8FB6823F0070343F075
:100530000503FB6006E0FB6823F0070343F00403B8
:10054000FB6000BF7A684FF41053C0F2F4039A4284
:1005500021D97A684FF49043C0F2E8139A421AD82E
:10056000FB6803F00703052B0ED84FF0010202FAD7
:1005700003F303F02C03002B06D0FB6823F00703E2
:1005800043F00303FB6006E0FB6823F0070343F03E
:100590000103FB6000BF7A684FF41053C0F2F4030C
:1005A0009A4218D8FB6803F00703052B0ED84FF0CA
:1005B000010202FA03F303F02C03002B06D0FB68C0
:1005C00023F0070343F00203FB6004E0FB6823F021
:1005D0000703FB6000BF4FF00003C4F20C03FA688E
:1005E0005A6007F11407BD4680BC704780B483B0E1
:1005F00000AF78604FF40043C4F20C035B6D03F06E
:100600000103002B0AD100BF4FF40043C4F20C03D6
:100610001A6D7B681340002BF6D100E000BF07F194
:100620000C07BD4680BC704790B585B000AF7860C0
:100630007B684FEA131303F00F03BB60BB6803F141
:10064000FF33042B00F2CA8001A252F823F000BF4E
:100650007F06000099060000B30600007F07000037
:10066000650600004FF40043C4F20C031B6803F45A
:10067000E0334FEA933303F10103FB60B2E04FF440
:100680000043C4F20C039B6803F00F03FB60F8689F
:10069000FFF722FFF860A5E04FF40043C4F20C031B
:1006A0005B6803F00F03FB60F868FFF715FFF86065
:1006B00098E07B6842F23042C0F20A02934228D0AE
:1006C00042F23042C0F20A02934206D841F230426E
:1006D000C0F2080293420DD04CE04FF03002C0F25D
:1006E0000C02934224D04FF48662C0F2100293426F
:1006F00033D03FE04FF40043C4F20C039B6E03F091
:10070000F0034FEA1313FB60F868FFF7E5FEF860AB
:1007100034E04FF40043C4F20C039B6E03F47063A7
:100720004FEA1323FB60F868FFF7D6FEF86025E078
:100730004FF40043C4F20C039B6E03F440534FEAA2
:1007400013344FF01000FFF7B1FE0346E318FB60CF
:10075000F868FFF7C1FEF86010E04FF40043C4F200
:100760000C039B6E03F00303FB60F868FFF7B4FE15
:10077000F86003E04FF00103FB6000BF32E07A68ED
:100780004FF4A863C0F214039A4206D04FF4AA5360
:10079000C0F216039A420DD01BE04FF40043C4F29E
:1007A0000C031B6F03F00303FB60F868FFF794FE74
:1007B000F86012E04FF40043C4F20C031B6F03F027
:1007C00030034FEA1313FB60F868FFF785FEF8600B
:1007D00003E04FF00103FB6000BF03E04FF00103B3
:1007E000FB6000BFFB68184607F11407BD4690BDCB
:1007F000B0B584B000AF786039607B684FEA1313FE
:1008000003F00F03FB60FB6803F1FF33042B00F2DE
:100810005D8101A252F823F06308000089080000FE
:10082000370900004D0A00002D080000FFF70AFEFE
:100830004FF40043C4F20C034FF40042C4F20C0224
:10084000126822F4E0313A6802F1FF324FEA823254
:100850000A431A6001F0A6FCB860B868FFF74CFEC6
:1008600035E13868FFF722FE38604FF40043C4F2E8
:100870000C034FF40042C4F20C02926822F00F0104
:100880003A680A439A6022E1FFF7DCFD4FF051001D
:1008900000F0B4F90346042B0BD101F037FD0246FA
:1008A0003B68B2FBF3F24FF49043C0F2E8139A4274
:1008B00014D84FF40040C4F20C004FF01E014FF06A
:1008C0000002FFF7A7FD48F20400C4F20C004FF04D
:1008D00008014FF00002FFF79DFD13E04FF40040C8
:1008E000C4F20C004FF01E014FF00102FFF792FD21
:1008F00048F20400C4F20C004FF008014FF001026E
:10090000FFF788FD3868FFF7D1FD38604FF40043EA
:10091000C4F20C034FF40042C4F20C02526822F0FD
:100920000F013A680A435A6001F03CFCB860B868AD
:10093000FFF7E2FDCBE07B6842F23042C0F20A02F0
:10094000934232D042F23042C0F20A02934206D8B9
:1009500041F23042C0F2080293420DD074E04FF0F1
:100960003002C0F20C02934238D04FF48662C0F2DB
:100970001002934251D067E04FF00400FFF736FEBB
:100980003868FFF793FD38604FF40043C4F20C035E
:100990004FF40042C4F20C02926E22F0F0013A6869
:1009A0004FEA02120A439A664FE04FF00400FFF745
:1009B0001DFE3868FFF77AFD38604FF40043C4F23B
:1009C0000C034FF40042C4F20C02926E22F47061E8
:1009D0003A684FEA02220A439A6636E04FF0040072
:1009E000FFF704FE3868FFF761FD38604FF40044FC
:1009F000C4F20C044FF40043C4F20C039B6E23F4C6
:100A000040554FF01000FFF751FD03463A68D31AE6
:100A10004FEA03332B43A36617E04FF00400FFF7C0
:100A2000E5FD3868FFF742FD38604FF40043C4F23B
:100A30000C034FF40042C4F20C02926E22F0030148
:100A40003A680A439A6600E000BF40E07A684FF4D3
:100A5000A863C0F214039A4206D04FF4AA53C0F21E
:100A600016039A4217D02FE04FF04000FFF7BEFD6B
:100A70003868FFF71BFD38604FF40043C4F20C03E5
:100A80004FF40042C4F20C02126F22F003013A68E4
:100A90000A431A6719E04FF04000FFF7A7FD3868D6
:100AA000FFF704FD38604FF40043C4F20C034FF429
:100AB0000042C4F20C02126F22F030013A684FEA91
:100AC00002120A431A6700E000BF00E000BF07F10E
:100AD0001007BD46B0BD00BF90B587B000AF7860CD
:100AE0000B46FB704FF000033B617B684FEA13231A
:100AF00003F00F0303F1FF33052B7AD801A252F85C
:100B000023F000BF1D0B0000290B0000350B000077
:100B10009B0B0000AD0B0000BF0B000048F2080368
:100B2000C4F20C037B6151E048F24403C4F20C03AD
:100B30007B614BE048F24003C4F20C037B614FF051
:100B4000510000F05BF80346042B3ED101F0DEFBC0
:100B500004464FF02000C0F20400FFF765FD034695
:100B6000B4FBF3F24FF49043C0F2E8139A422CD94D
:100B70004FF40040C4F20C004FF01E014FF0010290
:100B8000FFF748FC48F20400C4F20C004FF00801E3
:100B90004FF00102FFF73EFC17E048F25803C4F2A1
:100BA0000C037B614FF001033B610FE048F26003EF
:100BB000C4F20C037B614FF010033B6106E048F286
:100BC0007803C4F20C037B6100E000BF7B684FEA4E
:100BD000133303F01F03FB603B69002B02D038691D
:100BE000FFF704FDFB787869F9681A46FFF712FCF5
:100BF00000E000BF07F11C07BD4690BD80B485B082
:100C000000AF78604FF00103FB737B6803F00F03C4
:100C1000BB60BB6803F1FF33042B00F2B68001A276
:100C200052F823F0390C00007D0C0000CD0C0000C0
:100C30001D0D0000490D00004FF40043C4F20C03E9
:100C4000DB6A03F47053B3F5805F0AD0B3F5005F3D
:100C500003D0B3F5006F08D00BE04FF00203FB7335
:100C60000BE04FF00303FB7307E04FF00403FB734B
:100C700003E04FF00503FB7300BF8AE04FF400432D
:100C8000C4F20C039B6A03F00303022B07D0032B6F
:100C900009D0012B0BD14FF00303FB7315E04FF08C
:100CA0000203FB7311E04FF00603FB730DE04FF4FA
:100CB0000043C4F20C039B6A03F48033002B03D07F
:100CC0004FF00903FB7300E000BF62E04FF4004304
:100CD000C4F20C039B6A03F00C03082B07D00C2B07
:100CE00009D0042B0BD14FF00303FB7315E04FF039
:100CF0000203FB7311E04FF00603FB730DE04FF4AA
:100D00000043C4F20C039B6A03F48013002B03D04E
:100D10004FF00903FB7300E000BF3AE04FF40043DB
:100D2000C4F20C031B6803F08053002B03D0B3F113
:100D3000805F04D007E04FF00703FB7303E04FF040
:100D40000803FB7300BF24E04FF40043C4F20C031C
:100D5000DB6A03F46033B3F5803F09D0B3F5003F9D
:100D60000AD0B3F5004F0BD14FF00803FB730BE033
:100D70004FF00203FB7307E04FF00303FB7303E044
:100D80004FF00103FB7300BF03E04FF00003FB7360
:100D900000BFFB7B184607F11407BD4680BC7047B7
:100DA00080B588B000AF78600B46FB704FF003034E
:100DB000FB614FF00303FB764FF000037B617B6820
:100DC00003F00F03FB60FB6803F1FF33042B00F219
:100DD000A48101A252F823F0ED0D0000030F0000E2
:100DE000030F0000371000007B100000FB78A3F118
:100DF0000203072B00F2938101A252F823F000BFF7
:100E0000210E00002F0E00003D0E0000BD0E000060
:100E10001F1100001F1100001F110000CB0E000069
:100E20004FF00403FB614FF00003FB7650E04FF0FE
:100E30000303FB614FF00103FB7649E04FF002032F
:100E4000FB614FF00203FB7601F060FA02464FF4BB
:100E50009043C0F2E8139A4221D94FF40043C4F200
:100E60000C034FF40042C4F20C02126842F08042BC
:100E700042F060021A604FF40043C4F20C031B6C92
:100E800003F01003002B22D048F20400C4F20C003F
:100E90004FF008014FF00102FFF7BCFA17E04FF4E2
:100EA0000043C4F20C034FF40042C4F20C02126877
:100EB00022F0600242F020021A6008E04FF00103C5
:100EC000FB614FF00303FB7602E000BF00E000BFD0
:100ED000FB7E18464FF001014FF0010200F04CF983
:100EE000FFF7B0FA4FF40043C4F20C03FA695A62F8
:100EF00000F0B6F901F056F9B860B868FFF7FCFAEF
:100F000010E1FB7803F1FF33082B00F20A8101A204
:100F100052F823F0390F0000410F0000590F000074
:100F20002311000023110000710F000023110000A5
:100F300023110000C90F00004FF000033B614BE09C
:100F40004FF000004FF001014FF0010200F014F9E2
:100F50004FF002033B613FE04FF001004FF0010111
:100F60004FF0010200F008F94FF001033B6133E05C
:100F700048F24000C4F20C004FF004014FF00102AF
:100F8000FFF748FA4FF003033B6101F00BF9B8603B
:100F9000BA684FF49043C0F2E8139A421BD94FF459
:100FA0000040C4F20C004FF01E014FF00102FFF7A9
:100FB00031FA48F20400C4F20C004FF008014FF07F
:100FC0000102FFF727FA06E04FF000033B614FF004
:100FD00001037B6100E000BFFB68022B14D14FF4DA
:100FE0000043C4F20C034FF40042C4F20C02926AB4
:100FF00022F4803222F00302396911437A694FEA00
:1010000002420A439A628DE04FF40043C4F20C039B
:101010004FF40042C4F20C02926A22F4801222F0D1
:101020000C0239694FEA810111437A694FEA025291
:101030000A439A6276E0FB78072B02D0082B0DD08A
:1010400019E04FF40043C4F20C034FF40042C4F221
:101050000C02126822F080521A600DE04FF4004337
:10106000C4F20C034FF40042C4F20C02126842F0C6
:1010700080521A6000E055E054E0FB78032B30D03A
:10108000082B02D0022B12D045E04FF40043C4F2EB
:101090000C034FF020025A6200BF4FF40043C4F229
:1010A0000C03DB6A03F40043002BF6D034E04FF06E
:1010B00000004FF001014FF0010200F05DF84FF425
:1010C0000043C4F20C034FF040025A6200BF4FF4D9
:1010D0000043C4F20C03DB6A03F48033002BF6D028
:1010E0001AE04FF001004FF001014FF0010200F053
:1010F00043F84FF40043C4F20C034FF060025A620D
:1011000000BF4FF40043C4F20C03DB6A03F4003366
:10111000002BF6D000E005E004E000BF02E000BFD5
:1011200000E000BF07F12007BD4680BD80B483B05A
:1011300000AF78604FF40043C4F20C039B6D03F0E2
:101140000803002B12D17B6803F007037B604FF488
:101150000043C4F20C034FF40042C4F20C02D26FFD
:1011600022F007017A680A43DA6700E000BF07F15E
:101170000C07BD4680BC704780B586B000AF1346F3
:101180000246FA710A46BA717B71FB79052B61D868
:1011900001A252F823F000BF01120000ED1100007F
:1011A000C5110000B1110000D91100005512000056
:1011B0004FF001033B614FF00203FB604FF002036D
:1011C0007B6127E04FF004033B614FF00803FB60B5
:1011D0004FF008037B611DE04FF010033B614FF0BF
:1011E0002003FB604FF020037B6113E04FF04003CE
:1011F0003B614FF08003FB604FF080037B6109E0AF
:101200004FF480733B614FF40073FB604FF4007345
:101210007B6100BFBB79002B13D04FF40043C4F2B5
:101220000C033A691A627B79002B10D000BF4FF48F
:101230000043C4F20C03DA6A7B691340002BF6D03A
:1012400005E04FF40043C4F20C03FA681A6200F0A0
:1012500007F800E000BF07F11807BD4680BD00BFDA
:1012600080B400AF4FF40043C4F20C03DB6A9AB2BF
:1012700040F2BC03C2F200031A80BD4680BC704736
:1012800090B484B000AFB9607B600346FB73134633
:10129000BB73BB7B002B2DD07B68002B15D04FF48C
:1012A000C042C4F20002F97BBB684FF0010000FAB3
:1012B00003F318460B464FEAC3035B184FEA830358
:1012C000D31803F11003186014E04FF4C042C4F2C5
:1012D0000002F97BBB684FF0010000FA03F31846E7
:1012E0000B464FEAC3035B184FEA8303D31803F19D
:1012F00010035860BB68072B2BD84FF4C042C4F2D0
:101300000002F87B4FF4C041C4F20001FC7B23468D
:101310004FEAC3031B194FEA8303CB185968BB6814
:101320004FEA83034FF00F0404FA03F36FEA030359
:101330001940BC7BBB684FEA830304FA03F31943EB
:1013400003464FEAC3031B184FEA8303D3185960BF
:1013500036E04FF4C042C4F20002F87B4FF4C041C3
:10136000C4F20001FC7B23464FEAC3031B194FEA7A
:101370008303CB1803F108031968BB6803F18043AA
:10138000A3F108034FEA83034FF00F0404FA03F3B9
:101390006FEA03031940BC7BBB6803F18043A3F1F0
:1013A00008034FEA830304FA03F3194303464FEAA1
:1013B000C3031B184FEA8303D31803F10803196012
:1013C000BB7B002B2DD17B68002B15D04FF4C04286
:1013D000C4F20002F97BBB684FF0010000FA03F38E
:1013E00018460B464FEAC3035B184FEA8303D31832
:1013F00003F11003186014E04FF4C042C4F200027D
:10140000F97BBB684FF0010000FA03F318460B4666
:101410004FEAC3035B184FEA8303D31803F11003A9
:10142000586007F11007BD4690BC704780B483B088
:1014300000AF0346FB71FB79002B0CD04FF4204327
:10144000C4F208034FF42042C4F20802126842F0CA
:1014500001021A600BE04FF42043C4F208034FF47A
:101460002042C4F20802126822F001021A6007F159
:101470000C07BD4680BC704780B487B000AFF860F1
:10148000B9607A60FB6803F104734FEAC302BB687A
:10149000D3184FEA83037B617B697A681A6007F18E
:1014A0001C07BD4680BC704780B584B000AF786033
:1014B0004FF42043C4F208035B68FB604FF0000068
:1014C000FFF7B4FFFB6823F4830323F01F03FB60E3
:1014D0007B685B68FA681343FB607B681B7AFA6879
:1014E0001343FB607B685B7AFA681343FB607B689D
:1014F000DB68FA681343FB607B681B8AFA68134356
:10150000FB604FF42043C4F20803FA685A607B681A
:101510001B78002B03D04FF00100FFF787FF07F186
:101520001007BD4680BD00BF80B485B000AF7860B5
:101530004FF42043C4F208035B68FB60FB6823F4AC
:101540008033FB607B68002B08D0B3F5803F04D16B
:10155000FB6843F48033FB6001E000E000BF4FF420
:101560002043C4F20803FA685A6007F11407BD4625
:1015700080BC704780B483B000AF02460B46FA804F
:101580007B717B79002B0CD04FF42043C4F208030D
:101590004FF42042C4F208029168FA880A439A6024
:1015A0000DE04FF42043C4F208034FF42042C4F28C
:1015B00008029168FA886FEA02020A409A6007F10D
:1015C0000C07BD4680BC704780B584B000AFF860A2
:1015D000B9601346FB71FB68072B00F2FB8001A288
:1015E00052F823F0051600003F160000791600009F
:1015F000B3160000ED160000271700006117000069
:101600009B170000BB681F2B0ADCBA68FB794AF203
:101610004000C4F2080011461A46FFF72DFFDAE039
:10162000BB68A3F12003BB60BA68FB794AF25000A3
:10163000C4F2080011461A46FFF71EFFCBE0BB6854
:101640001F2B0ADCBA68FB794AF24400C4F2080096
:1016500011461A46FFF710FFBDE0BB68A3F1200357
:10166000BB60BA68FB794AF25400C4F20800114624
:101670001A46FFF701FFAEE0BB681F2B0ADCBA6811
:10168000FB794AF24800C4F2080011461A46FFF7F7
:10169000F3FEA0E0BB68A3F12003BB60BA68FB794E
:1016A0004AF25800C4F2080011461A46FFF7E4FE59
:1016B00091E0BB681F2B0ADCBA68FB794AF24C0048
:1016C000C4F2080011461A46FFF7D6FE83E0BB6855
:1016D000A3F12003BB60BA68FB794AF25C00C4F254
:1016E000080011461A46FFF7C7FE74E0BB681F2BBF
:1016F0000ADCBA68FB794AF2CC00C4F20800114651
:101700001A46FFF7B9FE66E0BB68A3F12003BB6091
:10171000BA68FB794AF2B400C4F2080011461A46CE
:10172000FFF7AAFE57E0BB681F2B0ADCBA68FB79FB
:101730004AF2D000C4F2080011461A46FFF79CFE98
:1017400049E0BB68A3F12003BB60BA68FB794AF2A9
:10175000B800C4F2080011461A46FFF78DFE3AE0C1
:10176000BB681F2B0ADCBA68FB794AF2D400C4F2CA
:10177000080011461A46FFF77FFE2CE0BB68A3F174
:101780002003BB60BA68FB794AF2BC00C4F20800CF
:1017900011461A46FFF770FE1DE0BB681F2B0ADCDE
:1017A000BA68FB794AF2D800C4F2080011461A461A
:1017B000FFF762FE0FE0BB68A3F12003BB60BA68CD
:1017C000FB794AF2C000C4F2080011461A46FFF73E
:1017D00053FE00E000BF07F11007BD4680BD00BF0B
:1017E00080B487B000AFF860B9607A60FB68072BFF
:1017F00000F2E48001A252F823F000BF1D1800009F
:101800004F18000081180000B3180000E518000010
:101810001B19000051190000871900004FF42043E4
:10182000C4F208031B6C7B61BB686FEA03037A692F
:1018300013407B61BA687B6813407A6913437B610C
:101840004FF42043C4F208037A691A64B7E04FF4F6
:101850002043C4F208035B6C7B61BB686FEA03033F
:101860007A6913407B61BA687B6813407A691343D5
:101870007B614FF42043C4F208037A695A649EE006
:101880004FF42043C4F208039B6C7B61BB686FEA92
:1018900003037A6913407B61BA687B6813407A69F5
:1018A00013437B614FF42043C4F208037A699A64BE
:1018B00085E04FF42043C4F20803DB6C7B61BB6816
:1018C0006FEA03037A6913407B61BA687B6813404F
:1018D0007A6913437B614FF42043C4F208037A69A9
:1018E000DA646CE04FF42043C4F20803D3F8CC3040
:1018F0007B61BB686FEA03037A6913407B61BA6856
:101900007B6813407A6913437B614FF42043C4F230
:1019100008037A69C3F8CC2051E04FF42043C4F2A5
:101920000803D3F8D0307B61BB686FEA03037A69A0
:1019300013407B61BA687B6813407A6913437B610B
:101940004FF42043C4F208037A69C3F8D02036E08C
:101950004FF42043C4F20803D3F8D4307B61BB6852
:101960006FEA03037A6913407B61BA687B681340AE
:101970007A6913437B614FF42043C4F208037A6908
:10198000C3F8D4201BE04FF42043C4F20803D3F87B
:10199000D8307B61BB686FEA03037A6913407B61CF
:1019A000BA687B6813407A6913437B614FF4204324
:1019B000C4F208037A69C3F8D82000E000BF07F139
:1019C0001C07BD4680BC704780B487B000AFF8608C
:1019D000B9607A60FB68072B00F2E48001A252F83C
:1019E00023F000BF051A0000371A0000691A000032
:1019F0009B1A0000CD1A0000031B0000391B0000D9
:101A00006F1B00004FF42043C4F208031B6D7B6181
:101A1000BB686FEA03037A6913407B61BA687B682D
:101A200013407A6913437B614FF42043C4F20803E7
:101A30007A691A65B7E04FF42043C4F208035B6D7E
:101A40007B61BB686FEA03037A6913407B61BA6804
:101A50007B6813407A6913437B614FF42043C4F2DF
:101A600008037A695A659EE04FF42043C4F20803E4
:101A70009B6D7B61BB686FEA03037A6913407B61EE
:101A8000BA687B6813407A6913437B614FF4204343
:101A9000C4F208037A699A6585E04FF42043C4F2E2
:101AA0000803DB6D7B61BB686FEA03037A6913404F
:101AB0007B61BA687B6813407A6913437B614FF49A
:101AC0002043C4F208037A69DA656CE04FF42043DE
:101AD000C4F20803D3F8B4307B61BB686FEA030338
:101AE0007A6913407B61BA687B6813407A69134353
:101AF0007B614FF42043C4F208037A69C3F8B42031
:101B000051E04FF42043C4F20803D3F8B8307B61AE
:101B1000BB686FEA03037A6913407B61BA687B682C
:101B200013407A6913437B614FF42043C4F20803E6
:101B30007A69C3F8B82036E04FF42043C4F20803B2
:101B4000D3F8BC307B61BB686FEA03037A6913404A
:101B50007B61BA687B6813407A6913437B614FF4F9
:101B60002043C4F208037A69C3F8BC201BE04FF499
:101B70002043C4F20803D3F8C0307B61BB686FEA2E
:101B800003037A6913407B61BA687B6813407A6902
:101B900013437B614FF42043C4F208037A69C3F80E
:101BA000C02000E000BF07F11C07BD4680BC7047A5
:101BB00080B483B000AF78604FF42043C4F20803D0
:101BC0004FF42042C4F20802526822F4E0117A680D
:101BD0000A435A6007F10C07BD4680BC704700BF3E
:101BE00080B485B000AF78604FF6D073CEF20F03AB
:101BF0001B69DBB203F03F03DAB27B681A704FF661
:101C0000D073CEF20F039B69DBB223F00F03FB739B
:101C10004FF6D073CEF20F03DB6903F0F0034FEA07
:101C20001313DAB2FB7B1343FB737B68FA7B5A70A6
:101C300007F11407BD4680BC704700BF80B483B075
:101C400000AF0346FB71FB79002B07D04FF4204314
:101C5000C4F208034FF001021A6606E04FF4204375
:101C6000C4F208034FF000021A6607F10C07BD46E4
:101C700080BC704780B483B000AF786000BF4FF481
:101C80002043C4F208035A6E7B681340002BF6D140
:101C900007F10C07BD4680BC704700BF80B483B01D
:101CA00000AF78604FF42043C4F208034FF42042A1
:101CB000C4F20802916A7A686FEA02020A409A62E4
:101CC00007F10C07BD4680BC704700BF80B500AF70
:101CD0004FF000004FF47041CFF20F014FF00002BF
:101CE000FFF77EFD4FF001004FF47041CFF20F017E
:101CF0004FF00002FFF774FD4FF002004FF4704107
:101D0000CFF20F014FF00002FFF76AFD4FF0030022
:101D10004FF47041CFF20F014FF00002FFF760FD6A
:101D20004FF004004FF47041CFF20F014FF000026A
:101D3000FFF756FD4FF005004FF47041CFF20F0151
:101D40004FF00002FFF74CFD4FF006004FF47041DA
:101D5000CFF20F014FF00002FFF742FD4FF00700F6
:101D60004FF47041CFF20F014FF00002FFF738FD42
:101D70004FF000004FF0FF014FF00002FFF724FE8C
:101D80004FF001004FF0FF014FF00002FFF71CFE83
:101D90004FF002004FF0FF014FF00002FFF714FE7A
:101DA0004FF003004FF0FF014FF00002FFF70CFE71
:101DB0004FF004004FF0FF014FF00002FFF704FE68
:101DC0004FF005004FF0FF014FF00002FFF7FCFD60
:101DD0004FF006004FF0FF014FF00002FFF7F4FD57
:101DE0004FF007004FF0FF014FF00002FFF7ECFD4E
:101DF00080BD00BF80B500AF4FF007004FF46041D9
:101E0000C5F20F014FF00002FFF7EAFC4FF00600A9
:101E10004FF46041CFF20F014FF00002FFF7E0FCFA
:101E20004FF005004FF46041CFF20F014FF0000278
:101E3000FFF7D6FC4FF004004FF46041CFF20F01E2
:101E40004FF00002FFF7CCFC4FF003004FF460416D
:101E5000CFF20F014FF00002FFF7C2FC4FF002007B
:101E60004FF46041CFF20F014FF00002FFF7B8FCD2
:101E70004FF001004FF46041CFF20F014FF000022C
:101E8000FFF7AEFC4FF000004FF020414FF0000292
:101E9000FFF7A6FC4FF007004FF007014FF00002DC
:101EA000FFF792FD4FF006004FF007014FF00002E0
:101EB000FFF78AFD4FF005004FF007014FF00002D9
:101EC000FFF782FD4FF004004FF007014FF00002D2
:101ED000FFF77AFD4FF003004FF007014FF00002CB
:101EE000FFF772FD4FF002004FF007014FF00002C4
:101EF000FFF76AFD4FF001004FF007014FF00002BD
:101F0000FFF762FD00BF80BD80B582B000AF034621
:101F1000FB714FF48640C0F204004FF00101FEF760
:101F2000DBFD4FF00200C0F206004FF00301FEF7A8
:101F300037FF4FF03000C0F20C004FF04001FEF7C9
:101F400057FC4FF00100FFF7F1F84FF45050C0F28A
:101F50000E004FF00101FEF7BFFD4FF0FF30FFF71D
:101F60009DFE44F23050C0F20000FFF79DFA4FF0A2
:101F700008004FF00101FFF7FDFA4FF010004FF09D
:101F80000101FFF7F7FA4FF080004FF00101FFF772
:101F9000F1FA4FF480704FF00101FFF7EBFA4FF4C4
:101FA00000704FF00101FFF7E5FAFB79002B13D029
:101FB0004FF44020FFF7FCFD4FF48030FFF7B4FAF8
:101FC0004FF40043C4F20C034FF40042C4F20C027D
:101FD000D26F42F00802DA67FFF778FE4FF0FF3069
:101FE000FFF748FE07F10807BD4680BD80B58AB0FF
:101FF00000AF7860786802F00FF80346BB614FF0DD
:1020000000033B624FF0FF30FFF734FE4FF001005A
:10201000FFF714FEFFF7EEFE4FF000033B625BE0BC
:102020003A6ABB699A4203DA7B681B787B6202E0FA
:102030004FF020037B627B6AA3F120037B6244F2B2
:102040007843C0F200037A6A33F81230FB824FF013
:102050000003FB6135E044F25832C0F20002396AF5
:102060000B464FEAC3035B1A4FEA8303D218FB699E
:10207000D31803F108039B793B6144F25832C0F254
:102080000002396A0B464FEAC3035B1A4FEA830327
:10209000F9695B18D3181B78FB60FA8AFB6942FA6E
:1020A00003F303F00103002B07D0FA683B691046E5
:1020B00019464FF00102FFF787FAFB6903F10103AC
:1020C000FB61FB690D2BC6DD7B6803F101037B60BF
:1020D0003B6A03F101033B623B6A062BA0DD4FF034
:1020E0000000FFF7ABFD07F12807BD4680BD00BF2C
:1020F000074880470749084A084B9B1A40F3058068
:10210000043BC858D0503FF7FBAF054800470000DC
:102110002523000068450000000000208800002002
:1021200055010000FEE7FEE7FEE7FEE7FEE7FEE7FB
:10213000FEE7FEE7FEE7FEE7FEE7FEE7FEE7FEE777
:10214000FEE7FEE7FEE7FEE7FEE7FEE7FEE7FEE767
:10215000FEE7FEE7FEE7FEE7FEE7FEE7FEE7FEE757
:10216000FEE7FEE7FEE7FEE7FEE7FEE7FEE7FEE747
:10217000FEE7FEE7FEE7FEE7FEE7FEE7FEE7FEE737
:10218000FEE7FEE7FEE700BF80B400AF48F2B01301
:10219000C0F6E073DB6C4FEA1363DBB21846BD4652
:1021A00080BC704780B582B000AF00F027F878603F
:1021B0004FF40043C4F20C031B6803F4E0334FEA0E
:1021C000933303F101037A68B2FBF3F37B604FF4BE
:1021D0000043C4F20C035B6803F00F037A6822FA31
:1021E00003F37B6040F60443C2F200037A681A608E
:1021F0007B68184607F10807BD4680BD80B582B0F0
:1022000000AF4FF40043C4F20C03DB6A03F47053D5
:10221000B3F5805F0DD0B3F5005F03D0B3F5006F69
:102220000BD011E040F21403C2F200031B687B6084
:1022300066E04FF400437B6062E040F21003C2F2BC
:1022400000031B687B605BE04FF40043C4F20C03A7
:10225000DB6803F4E063B3F5007F24D0B3F5007FBF
:1022600005D8002B36D0B3F5807F22D043E0B3F5FC
:10227000806F0CD0B3F5A06F03D0B3F5407F0CD0C6
:1022800039E04FF47C53C0F2AB137B6037E046F685
:102290004073C0F240137B6031E049F68073C0F2B6
:1022A000D5037B602BE04DF6C003C0F2A7037B6033
:1022B00025E0FFF769FF0346122B05D94BF2405387
:1022C000C0F264037B601AE04CF6C073C0F26A038C
:1022D0007B6014E0FFF758FF0346122B05D94FF43B
:1022E0009F43C0F212037B6009E044F24023C0F236
:1022F0000F037B6003E04FF000037B6000BF00BF73
:102300007B68184607F10807BD4680BD80B400AF62
:1023100040F21003C2F200031B681846BD4680BCA1
:10232000704700BF80B400AFBD4680BC704700BF9F
:1023300080B483B000AF03463960FB714FF4C042F4
:10234000C4F20002F9793B684FF0010000FA03F390
:1023500018460B464FEAC3035B184FEA8303D318B2
:1023600003F11003586007F10C07BD4680BC7047AD
:1023700080B483B000AF03463960FB714FF4C042B4
:10238000C4F20002F9793B684FF0010000FA03F350
:1023900018460B464FEAC3035B184FEA8303D31872
:1023A00003F11003186007F10C07BD4680BC7047AD
:1023B00080B582B000AF48F21010C0F202004FF0BA
:1023C0000101FEF789FB4FF45240C0F202004FF0CA
:1023D0000101FEF781FB4FF000037B601BE044F23C
:1023E0004453C0F200037A6813F8321044F24452A6
:1023F000C0F200027B684FEAC303D3185B6808464B
:1024000019464FF004024FF00003FEF739FF7B68D6
:1024100003F101037B607B68012BE0DD4FF00003DB
:10242000184607F10807BD4680BD00BF80B584B0DF
:1024300000AF78604FF00003FB604FF00103BB601A
:1024400035E07A68BB681340002B14D044F2445343
:10245000C0F20003FA6813F8321044F24452C0F29A
:102460000002FB684FEAC303D3185B6808461946AD
:10247000FFF77EFF13E044F24453C0F20003FA6812
:1024800013F8321044F24452C0F20002FB684FEAE3
:10249000C303D3185B6808461946FFF749FFFB687A
:1024A00003F10103FB60BB684FEA4303BB60FB68B9
:1024B000012BC6DD4FF00003184607F11007BD469B
:1024C00080BD00BF80B400AF4FF40043C4F20C03E2
:1024D0004FF40042C4F20C02526C42F400525A64AF
:1024E0004FF4C043C4F200034FF4C042C4F20002F0
:1024F000D2F8202142F00402C3F820214FF4C04357
:10250000C4F200034FF4C042C4F20002D2F820210A
:1025100022F44072C3F820214FF4C043C4F20003F8
:102520004FF4C042C4F20002D2F8B82022F4706224
:10253000C3F8B8204FF4C043C4F200034FF4C042C4
:10254000C4F20002D2F8B82042F48062C3F8B82086
:102550004FF40043C4F20C034FF010021A6200BFA4
:102560004FF40043C4F20C03DB6A03F02003002B9A
:10257000F6D04EF6F053CEF200034EF6F052CEF205
:102580000002D26842F08072DA604FF48053CEF2DB
:10259000000341F2FF32C4F201021A604FF000035F
:1025A000CEF204034FF00F021A614FF00003CEF297
:1025B00004034FF00202C3F8F0204FF00003CEF204
:1025C00004034FF48072C3F804234FF060424CF6CA
:1025D0005563CCF2AC53C2F8B03F4FF060424FF0BD
:1025E0000903C0F20103C2F8803EBD4680BC7047BB
:1025F00080B582B000AF4FF07E637B607B681B6864
:10260000002B02D14FF0000303E0FFF75BFF4FF018
:102610000103184607F10807BD4680BD00B5DFF885
:102620000CC000DFDFF808C000DFFEE78D280000E7
:10263000A5280000F0B5364C83B0237843B1354867
:10264000FF2201688A7001202070002003B0F0BDD5
:10265000314B3248196800F06BFC08B18520F5E772
:1026600001F0D4FA2B4920780B68FF229A700028D9
:10267000E9D12B4D2968002948D06D6855B12B78D8
:10268000002B41D1081D82004FF6FC7128461140F5
:1026900000F00AFD234924480B6805600193019A64
:1026A0007AB1B1F90450EA1C0BDB032D09DCCF68C9
:1026B0004FB9291D3A4601983B4601F093F905466A
:1026C000D0B9002015E01548394600F03FFC064619
:1026D0000028F6D0043545EA072101983246002348
:1026E00001F080F9054638B90C48314600F052FC3B
:1026F00028460E4B1860A6E70D4B691E53F82100C3
:102700000C49426A5163F4E70546C3E70D46C1E749
:10271000080C00204C0C002010430000180800207A
:1027200018430000A4000020EC0900201C0B00202E
:10273000000800201D26000010B50A4C207878B94A
:10274000014601F0D7F8084B1868416A203181F33F
:102750000988054B00221A6001F008FB0120207057
:10276000002010BD090C00204C0C002010B5EFF328
:1027700005840CB1822010BDEFF3148414F0010F16
:1027800003D0DFF810C000DF10BDBDE81040FFF738
:1027900051BF00003526000010B588B0EFF3058466
:1027A00014B1822008B010BDEFF3148404F00304C8
:1027B000022C1CD0032C13D0012C16D008AC84F3AF
:1027C0000988104C2478E40717D4032484F3148870
:1027D000BFF34F8FBFF36F8FDFF82CC000DFE1E74F
:1027E000084C247814F0010FF6D0FF20DAE7054CEE
:1027F000247814F0010FEFD1E7E7022484F3148862
:10280000E6E700BF004300003927000070B504462A
:102810000E46002831D0006800282ED0B4F90410EC
:10282000CB1C2ADB032928DCE268C2B1144811461C
:1028300000F08CFB054600B3B4F90430E268191DC2
:10284000206841EA022133462A4601F0CBF80446CB
:1028500058B929460A4800F09DFB204670BD043156
:10286000334601F0BFF8044638B1064B601E53F8FA
:102870002000054A416A4A6370BD002070BD00BF58
:1028800018080020000800201D26000008B501F0EF
:1028900029F818B1024B013853F8200008BD00BFD9
:1028A0000008002010B588B182070FD103786BB9FA
:1028B000448C6CB9C07801F039F9FF280ED01CB1F6
:1028C0000748214600F066FB002010BD802010BDA7
:1028D000846AC07801F02AF9FF28F0D1812010BD68
:1028E0001808002070B504460D46EFF30580002857
:1028F0002FD1EFF31481C90702D41E48017829B102
:1029000020462946DFF87CC000DF70BD0CB320688C
:10291000F8B1B4F90410CB1C1BDB032919DCE26805
:10292000CAB11548114600F011FB064688B1B4F94A
:102930000430E268191D41EA0221206832462B4624
:1029400001F050F868B931460B4800F023FB002035
:1029500070BD002070BD04312B4601F043F8002803
:10296000F7D0064B013853F82000054A416A4A6304
:1029700070BD00BF090C00201808002000080020CE
:102980001D2600000D28000008B500B908BD431C35
:1029900008D04FF41063C0F23D03984208D94FF6B7
:1029A000FE7001E04FF6FF7000F05EFB402008BDB6
:1029B00007490B684FF47A715A1E01FB00204FF64D
:1029C000FE72B0FBF3F3934228BF134698B2EBE7D5
:1029D0000443000010B5EFF305840CB1822010BD54
:1029E000DFF804C000DF10BD892900002DE9F047A1
:1029F000284F3D68002D34D02B89DFF89C80581E6D
:102A000083B22B814FF001094FF0000A8BB92C687B
:102A1000D8F800603C6016B1317801292FD06A796E
:102A2000012A08D085F80490DCB123892546002BC3
:102A3000EDD0BDE8F08738686A8958B101898A42CB
:102A400004D210E0198991420FD818460368521A2F
:102A5000002BF7D1C5F800A02A8170B10560002CC9
:102A6000E3D1BDE8F0870346002092B22A8119899C
:102A70002B608A1A1A810028F0D13D60D4E73046D5
:102A800000F0C6FB0028CAD03046294600F0C4FB3F
:102A9000C5E700BF0C0C0020EC09002010B504466F
:102AA00098B1016879B143685BB1806850B1DA1CB4
:102AB00022F0030201FB02F10C3100F08BFAA06856
:102AC00010BD184610BD084610BD10BD38B50C46E7
:102AD0000546F0B100F0A6FAD4B1D0B1AB68BBB1F5
:102AE00001461A1F002441F8044B13460431C2F377
:102AF000800283B122B141F8044C0431043B0BD075
:102B00000A4641F8044C42F8044B111D083BF7D12A
:102B100038BD002038BD38BD38BD00BF08B530B164
:102B200000F08EFA002814BF8620002008BD802007
:102B300008BD00BF10B50446EFF30580E0B9EFF320
:102B40001480C00702D41048007820B12046DFF876
:102B50003CC000DF10BDACB123687BB162687AB1C4
:102B6000A06850B1D11C21F0030203FB02F10C312B
:102B700000F030FAA06810BD002010BD184610BD4E
:102B8000104610BD204610BD090C00209D2A0000F3
:102B900030B50446EFF3058141B9EFF3148515F024
:102BA000010F03D0DFF814C000DF30BD20461CB198
:102BB000BDE8304000F036BA30BD0000CD2A00003C
:102BC00070B505460E46EFF3058444B9EFF314845F
:102BD00014F0010F03D0DFF820C000DF70BD45B155
:102BE0002846314600F02CFA002814BF8620002029
:102BF00070BD802070BD00001D2B000010B5044684
:102C000090B1036873B1406858B1027842B9191D98
:102C10008B004FF6FC71194000F046FA606810BD59
:102C2000002010BD184610BD10BD00BF70B5034692
:102C30000E46154610B10478012C01D0802070BDDD
:102C400001320FD04FF41062C0F23D02954215D907
:102C50004FF6FE721846314600F034FA012809D0CA
:102C6000002070BD4FF6FF7200F02CFA0128F7D15A
:102C7000C12070BD002DFBD1812070BD07480268C6
:102C80004FF47A70511E00FB05114FF6FE70B1FB38
:102C9000F2F2824228BF024692B2DBE70443000010
:102CA00010B5034684B00C4610B10278012A05D055
:102CB000002180200022134604B010BD013113D042
:102CC0004FF41060C0F23D00844216D94FF6FE72F8
:102CD000184602A900F044FA012802D010200299F7
:102CE000E8E744B92046FAE702A94FF6FF7200F080
:102CF00037FA0128F2D14020F1E708494FF47A7001
:102D00000A68511E00FB04114FF6FE70B1FBF2F28F
:102D1000824228BF024692B2DAE700BF04430000B5
:102D200038B50446EFF30580D8B9EFF31480C00737
:102D300002D4104D2D7825B12046DFF83CC000DFCD
:102D400038BDA4B1236883B1606858B1027852B924
:102D5000191D8B004FF6FC71194000F0A5F9606851
:102D600038BD002038BD284638BD184638BD20463D
:102D700038BD00BF090C0020FD2B0000F8B505464A
:102D80000F461646EFF305841CB9DFF82CC000DFB0
:102D9000F8BD18B112B90378012B01D08020F8BD1D
:102DA00000F036FA08B98120F8BD2846394600F00F
:102DB00033FA3046F8BD00002D2C000070B50446F3
:102DC00084B01646EFF305854DB908461146DFF885
:102DD00050C000DF84E80700204604B070BD19B180
:102DE00012B90B78012B07D004A9802241F80C2DD1
:102DF00007C984E80700EFE7084602A900F014FAC3
:102E0000042801AD05D0019695E8070084E8070085
:102E1000E2E71020019095E8070084E80700DBE76F
:102E2000A12C0000438CF0B49D0802D11A4A1488EA
:102E3000A508846A4FF0807604EB85035A0748BFE3
:102E4000043B002243F8402C43F83C2C43F8382C38
:102E500043F8342C43F8302C43F82C2C43F8282C1E
:102E600043F8242C43F81C2C43F8182C43F8142C5A
:102E700043F8102C43F80C2C42F6A565C269A3F167
:102E80004007CEF25A2503E9420043F8202C47625E
:102E9000C1622560F0BC7047F4420000436A1962C9
:102EA000704700BF436A19625A6270474EF6FC537E
:102EB000CEF200031868C0010DD54FF46861CEF260
:102EC00000010A68D10706D54FF46063CEF2000313
:102ED0001868002800DB7047014A01211170704713
:102EE000100C002010B47C24CEF2000422687C2355
:102EF000CEF20003002AF9D0C26A1C461A6022688A
:102F00007C23CEF20003002AF9D0C07840EA0121E8
:102F10008AB21A8010BC70477C21CEF200010A6888
:102F20007C23CEF20003002AF9D0C0B2187070479B
:102F300050B1072908D9411800230A1F80E80C0066
:102F400041F8043C184670470120704730B488B1FE
:102F5000E9B101F10B05036825F00305024600E025
:102F600003465468991A081B854205D918681A4601
:102F70000028F5D130BC70471CB9556002F108003B
:102F8000F8E7A018A350456010600830F2E7084643
:102F9000F0E700BF30B478B171B1A1F10804A042EC
:102FA00013D0036843B1054600E013469C4206D0A7
:102FB0001A681D46002AF8D1012030BC70472DB197
:102FC00051F8081C00202960F7E7034600205860EC
:102FD000F3E700BF002A70B41DDBD51C25F0030504
:102FE0000C24ADB162198A4212D8041941184E1B43
:102FF00063199E4204604160856001D205E003468A
:103000005819864223601C46F9D20020206000E057
:10301000012070BC704722F00042D31D23F0070549
:103020001024DEE7EFF3108272B6036802F00102AB
:103030000BB11968016002B962B61846704700BF4B
:1030400081420DD3436899420AD2EFF3108372B6DE
:1030500002680A60016013F0010003D162B6704794
:103060000120704700207047032100F013BC00BF0F
:10307000426810B5034682B100F098F9044600F0AA
:10308000B1FA0123204619466370FFF707FF054890
:103090002146BDE8104000F061B94088411C5980CC
:1030A00010BD00BF180C0020103900238908012230
:1030B0000270437083704360038143818381C181C7
:1030C000704700BFF0B5466883B003460F4616B19F
:1030D000417801292BD09D89DC89A54214D018891B
:1030E000021D43F82270EFF3108272B601359D8104
:1030F00062B6411C88B2844203D01881002003B01C
:10310000F0BD00201881FAE77AB1FEB1134C1846E1
:103110002168019200F022F92168019ACF611046DE
:10312000082100F0B7FB0120E9E70120E7E700F004
:103130003DF9102104463A46FFF7B4FE204600F060
:1031400051FA204600F068FB0020D8E7034902202E
:10315000096859604E608B605870DFE74C0C0020A6
:1031600038B5838904461546BBB14289C589101D0F
:10317000013292B254F820009542086062811BD05F
:10318000606810B16278022A24D0EFF3108272B620
:10319000013BA38162B6002038BD5AB1416889B1B4
:1031A0001A49096800F0DAF82846082100F072FB95
:1031B000012038BD012038BD6068002161810028F0
:1031C000E0D1E2E7114A0123106860604160846049
:1031D0006370E9E7204600F0E9F800210546FFF7B3
:1031E0005DFE2289E089531CE9699BB20432984252
:1031F00044F82210238101D100212181284600F0CA
:10320000F1F9284600F008FB002038BD4C0C0020E6
:10321000C2898089101A704708B500F0F7F9BDE837
:10322000084000F03FBA00BF38B583890446ABB10F
:103230004289151D50F825500D604178022913D0A0
:10324000EFF3108172B6581EA08162B6511CE3895B
:103250008AB29342628103D0042038BD184638BD3B
:1032600000206081042038BD002100F0CFF900F07B
:1032700019FAA3896289E3E7436870B504460E46EC
:10328000002B4FD04578022D26D0032D02D0012DE2
:1032900011D070BD0846FFF7C5FE05460028F8D0DE
:1032A000204600F083F829460446FFF7F7FD012386
:1032B0002046637008E000F079F810210446324699
:1032C000FFF7F0FD2046657000F08CF9224821469A
:1032D000BDE8704000F042B800F068F800210546F3
:1032E000FFF7DCFD2089EA69011D44F82120EFF396
:1032F000108272B6A3895A1CA28162B60130E1899C
:1033000083B2994223810AD001212846697000F0D6
:1033100069F911482946BDE8704000F01FB8002245
:103320002281F1E78189C289914210D20089051D6D
:1033300044F82560EFF3108572B60131A18162B6C1
:10334000013081B28A422181A3D1238170BD032043
:10335000BDE87040FCF74EBF180C002070B4037835
:1033600042685C1E022C8CBF002601268C785AB164
:103370009578A54204D214E0987884420BD81A4676
:103380005368002BF8D1104600224A60416056B1C4
:10339000886070BC704710464B6041601EB19960F8
:1033A000F6E71346F8E70020F2E700BF436801782C
:1033B0005A6801390229426007D812B19060002290
:1033C0005A600021996018467047002058601846DE
:1033D000704700BF40F61843C2F200035A6800214C
:1033E0004260816058607047816870B4002927D0BE
:1033F0000B780A461BB992681478002CFBD04368FE
:103400004B60446804B1A160137851685C1E022CC3
:103410008CBF00260126847800292AD08D78A54209
:1034200004D21DE09A7894421CD819464B68002BB0
:10343000F8D1002242604860CEB90021816002E0EC
:103440004178012901D070BC70470C4B01E0134654
:103450008AB15A689042FAD14468084A5C60D3E75E
:103460000B46114643604860002EE6D098608160AC
:10347000E9E71146DDE7014AC6E700BF180C002066
:1034800030B4164CE368002B22D0A28A914203D8B4
:1034900021E0DC689CB123469C8A12199142F8D83D
:1034A000DD68C560D860C468036104B12061511A49
:1034B0008AB28282988A811A998230BC704792B20D
:1034C0000024891AC4609982D86003618482F4E779
:1034D0001A462346F4E71D462346E2E7300C002057
:1034E0002DE9F003314EF068002833D0B58A691E0B
:1034F0008DB2B582002D2DD12D4F2E4B97F8009017
:10350000B3F8008009F1FF39B9F1020F8CBF4FF019
:1035100000094FF001094FF0010C826832B1446894
:103520005460416809B18A60456085607A68847832
:103530009AB19378A34204D22DE099788C422CD88A
:103540001A465368002BF8D108E00161002A1FD108
:10355000B282F260BDE8F0037047154A45605060E2
:10356000B9F1000F20D043788260042B828A0AD000
:10357000C16880F801C00029E7D00E61C56005610F
:1035800032B90846C9E7C18A08EB01038382EFE735
:10359000B282F160DEE71346054A43605060B9F13C
:1035A000000F01D09860DEE70022DCE7300C00203D
:1035B000180C0020140C0020836833B142685A6054
:1035C000416809B18B6070477047054902E01146B8
:1035D000002AF9D04A688242F9D1406848607047B1
:1035E000180C0020036910B463B1C268DA60C268C5
:1035F00052B1998A848A1361611899820023C36049
:103600000022026110BC70479A82F9E730B40F4B78
:10361000DC78EFF3108272B69A78944208D9551C80
:103620001A789D70551CAC4214BFEDB200251D7078
:1036300062B6944205D903EBC2035860996030BC6E
:103640007047022030BCFCF7D5BD00BF68090020E0
:1036500010B5028B43781143062B04460183408B3F
:1036600019D0052B00D010BD11EA0002FBD06283F7
:1036700021EA000121832046FFF7B4FF0122204602
:1036800008216270628BFFF70DFC05482146BDE8FA
:103690001040FFF763BE01EA00038342E8D010BD8B
:1036A000180C0020064B1A7812B101209870704750
:1036B0004EF60451CEF200014FF080530B6070477C
:1036C000BE00002038B51A4B1A4C18680121417011
:1036D000FFF780FEA078657890B921E0012A1AD022
:1036E000FFF7C6FCE0780135854208BF0025EFF3FF
:1036F000108372B6A1784B1EDAB2A27062B67AB1AC
:1037000004EBC5014B681A781846002AE6D10989EE
:10371000FFF79EFFE6E718468968FFF7ADFDE1E792
:1037200005486570FFF742FEBDE8384000F062B81A
:103730004C0C002068090020180C002044F2FC23E7
:10374000C0F2000310B44EF214001C68CEF2000068
:103750004EF218010460CEF2000100204EF2100279
:103760000860CEF2000207214EF620531160CEF21F
:1037700000031A684FF0FF3042F07F41196010BC1F
:10378000704700BF704700BF08B540F64C43C2F217
:103790000003196801224A700846FFF71BFE00F07B
:1037A000A9FB40F61440C2F200000368591C0160F6
:1037B000FFF796FEFFF71AF940F61840C2F2000034
:1037C000FFF7F4FDBDE8084000F014B8084B186896
:1037D000826A416A8A4206D842F6A5631068CEF230
:1037E0005A23984202D00120FCF704BD704700BF65
:1037F0004C0C0020064A074B127802215860417099
:103800002AB11B68984202D0C078FFF785BB704789
:10381000100C00204C0C002038B50446002820D0A5
:10382000194D8278286883789A4207D80120607001
:1038300016482146BDE83840FFF790BDFFF7CAFDA6
:1038400013492B680A780120022158706C6061705E
:1038500032B19C4204D0E078BDE83840FFF75CBB51
:1038600038BD0A48FFF7A2FD094A074B127802212A
:1038700058604170002AF3D01B689842F0D0C0789D
:10388000BDE83840FFF748BB4C0C0020180C002066
:10389000100C002038B50D46E0B14FF6FF7398428A
:1038A0000D4C03D001462068FFF7EAFD21680B4864
:1038B0004D70FFF77BFD0A4A02211378606041706A
:1038C00043B1054A1368984204D0C078BDE8384037
:1038D000FFF722BB38BD00BF4C0C0020180C0020A5
:1038E000100C0020024B186800B1C078704700BF70
:1038F0004C0C002070B548B9354C2568A970354D81
:10390000686882788A422AD8002070BD324B1A88B3
:10391000904201D9FF2070BD304D013855F820503C
:10392000002DF7D02A4CA97023689D42E7D0284685
:10393000FFF75AFD6D78012DE6D12648FFF736FDD9
:103940000646002836D02068B178827891421FD888
:10395000757020483146FFF701FD002070BD2846F4
:103960002168FFF7FBFC216801234B702846FFF715
:103970001DFD1B4A02231178606043700029C3D0EB
:10398000134A11688842BFD0C078FFF7C5FABBE779
:10399000FFF720FD124B20681A78022145706660FF
:1039A0007170002AB0D08642AED0F078FFF7B4FA3A
:1039B000002070BD0748FFF7F9FC094B0222197877
:1039C0006060427000299FD023689842DCD19BE759
:1039D0004C0C0020180C0020F042000000080020D1
:1039E000100C00202DE9F04711F0FF0F80464848E9
:1039F0000E469246994608BF4E1CFFF713FB05463C
:103A0000002879D00024C6F30F270122C0F828A08F
:103A10004784C0F81C9004704270867044608460D3
:103A2000C46004618482C4820483448385F8204096
:103A3000002F49D028464146FFF7F4F93548018860
:103A400000295DD0344E3368002B5ED00124CA07B4
:103A500037461CD402248C421CD8374657F8042F12
:103A6000AAB92E4F631E46F823503E78E1B2E970A2
:103A7000DEB128460121FFF735FA16E057F8040FAA
:103A80000028EED057F8043F0134002BE9D0013470
:103A90008C42F3D900214FF0FF330C461F4F46F8FC
:103AA00023503E78E970002EE3D11D4EAA7830688D
:103AB00083789A420DD80120687029461948FFF78B
:103AC0004DFC2046BDE8F0871748FFF7ABFAA86227
:103AD000B0E7FFF77FFC33683A7801210220597084
:103AE00075606870002AECD09D42EAD0E878FFF754
:103AF00013FA2046BDE8F08704462046BDE8F0876B
:103B00004FF0FF330C46044EC8E701210C46C5E7D1
:103B1000F0090020F042000000080020100C0020F6
:103B20004C0C0020180C0020D0000020F8B5304CC0
:103B3000256840B1EB78834205D02E490A8890422F
:103B400033D9FF20F8BD00266E7000F030F96862AE
:103B5000FFF73CFE2368284AD978284D481E42F8D2
:103B60002060996A2648FFF76BFA21682B788E62ED
:103B70002BB1084631461E4EFFF7B4F93168214893
:103B8000FFF75EFA002620482660FFF70FFC297831
:103B900002226060427019B3154B196888421FD029
:103BA000C078FFF7B9F93046F8BD134D461E55F8F9
:103BB0002640002CC5D02046FFF7FEFC00272046FB
:103BC000FFF710FD45F826700D48A16AFFF738FA97
:103BD0000A48A76203782BB90A482146FFF730FA52
:103BE0000020F8BD20463946FFF77CF9F4E700BF16
:103BF0004C0C0020F042000000080020100C0020B7
:103C0000D0000020F0090020180C002070B5FFF74C
:103C10004DF9464B1C88A4B1454D01260020621E7B
:103C2000B442286002F001010BD921B10226B4424E
:103C300045F8040F05D902366860A8600835B4421B
:103C4000F9D83C4B3C4C198830223C48FFF7C2F96C
:103C500025883B4845F0004201683A48FFF7BAF929
:103C6000394E3A493A4C0822098830680025FFF756
:103C7000B1F9FF2201233348E27063706584257037
:103C8000A5706560A560E5602561A582E582258354
:103C9000658384F82050FFF7C5F92E49A0622046BD
:103CA000FFF7C0F82C4B2D48042119700170DD601E
:103CB0001D619D822A492B4B2B4A1C600B78456065
:103CC0000220607015705570D37000F005F94EF643
:103CD0002050CEF2000002682E4642F47F010160BF
:103CE0000368180200F07F42D143B1FA81F34EF627
:103CF0000C50CEF200000268D9B2C1F10803C2F341
:103D00000220834200DC431C6FF0807101FA03F152
:103D10004EF61C50CEF20000026801F07F4322F004
:103D20007F4143EA0102026070BD00BFF042000023
:103D30000008002008430000F4420000F0090020C1
:103D40000C430000D0000020B400002020430000FD
:103D5000540C0020E9010000300C0020180C002059
:103D6000144300004C0C00206809002008B5FFF740
:103D7000E5FC0C4B0028186012DB00F1604000F5F8
:103D80006441FF220A701B68012103F01F0001FA41
:103D900000F25B11980000F1604101F561431A6087
:103DA00008BD00BF480C002080F309887047EFF37E
:103DB00009807047684680F3098841480078C00749
:103DC00014BF0220032080F314887047DFF8F4C08A
:103DD000EFF305831B0618BF6047EFF31483DB077F
:103DE00008BF604700DF7047DFF8DCC0EFF30583F2
:103DF0001B0618BF6047EFF31483DB0708BF60475B
:103E000000DF7047EFF30980816911F8021CF9B9EE
:103E100090E80F10E047EFF3098C8CE807002B4B7C
:103E200093E80600914200F0108039B12CE9F00FC0
:103E3000C1F824C00CB4FFF7C9FC0CBC1A60D2F85E
:103E400024C0BCE8F00F8CF309886FF0020E7047B5
:103E500010B51F4A1268914200F20A801D4C54F8B6
:103E6000214090E80F10A047EFF3098C8CE80F0079
:103E700010BDFFF727FC154B93E80600914200F0B8
:103E80001180EFF3098C2CE9F00FC1F824C00CB4B9
:103E9000FFF79CFC0CBC1A60D2F824C0BCE8F00F01
:103EA0008CF309886FF0020E7047FFF76DFCFFF787
:103EB000E2BFFFF767FCFFF767FCFFF7DCBF00001E
:103EC0000043000025300000413000004C0C002071
:103ED00000000000FCFFFFFF44F2F822C0F20002E5
:103EE00040F684431068C2F2000300211960D880B4
:103EF000704700BF08B5104A104B506819688142DE
:103F000016D00F49DA880968013A521892B218603F
:103F10009A8088B2904200D008BD002106481960FE
:103F2000FFF744FA01460448BDE80840FFF716BA17
:103F300003489A880168ECE7180C0020840C0020E4
:103F4000140C002010B5034C14B100F06DF810BD36
:103F5000204610BD294000000146002002460346CD
:103F600000F062B808B5084B04461BB1002100F010
:103F700099F801E000F00CF804480068816A01B18A
:103F80008847204600F0A6F9A540000058450000EB
:103F900070B5084B084C0025E01A841003EB84062A
:103FA000043D1CB172599047013CF9E7BDE87040EF
:103FB00000F098B9840000208800002038B50E4D2C
:103FC0000E4B0024E81A8510AC4205D00B4951F87D
:103FD000242090470134F7E700F07EF90849094AA8
:103FE000541AA5100024AC4205D0054B53F8240008
:103FF00080470134F7E738BD8000002080000020B2
:10400000800000208400002082180346934202D0E2
:1040100003F8011BFAE77047034613F8012B002A47
:10402000FBD1181A013870472DE9F84399461C4B0B
:1040300006461D680F46AC6C904654B94FF4C670E6
:1040400000F080F80021A8644FF4C6720446FFF720
:10405000DBFF25681F2D1EDCAEB1012202FA05F23E
:10406000D4F8841104EB85001143022EC0F884803B
:10407000C4F88411C0F8049105D1D4F8883143EA1A
:104080000200C4F8880104EB850201355760256001
:104090000020BDE8F8834FF0FF30BDE8F88300BF93
:1040A000584500002DE9F843244B804618680F4618
:1040B000846C002C40D0214651F8846B751E1F364D
:1040C00001EB8606002D30DB2FB13068B84202D0FC
:1040D000013D043EF6E72168A6F18402481E8542B0
:1040E00052F87C3C01D1256002E0002142F87C1CA2
:1040F000002BEDD0012202FA05F2D4F88401D4F8A5
:104100000090024201D198470BE0D4F888110A428E
:1041100004D1404656F8801C984702E056F8800CBF
:10412000984723689945D3D0C5E7054A22B123684B
:1041300013B9204600F00EF8BDE8F883584500009A
:1041400055410000024B0146186800F00BB800BF53
:104150007C000020024B0146186800F05DB800BFEB
:104160007C00002070B5CD1C25F0030508350C2D12
:1041700038BF0C25002D06462DDB8D422BD31D4B61
:104180001B681C469CB12268501B0DD40B2802D919
:104190002060241817E0A34203D16068154A10601C
:1041A0001DE0616859601AE023466468EAE7294621
:1041B000304600F021F8431C01460CD0CC1C24F002
:1041C00003048C4201D1256009E03046611A00F0F9
:1041D00013F80130F7D10C203060002070BD04F1DD
:1041E0000B01231D21F00700C31A02D05A42E250EE
:1041F00070BD70BDC400002038B5064C00230546D4
:104200000846236000F04CF8431C02D1216801B13C
:10421000296038BD8C0C002030B500293CD051F805
:10422000042C0B1F1D49002AB8BF9B180A6812B93D
:104230005A600B6030BD93420ED2196858189042F4
:1042400003D15A5889184268196014485A600360AB
:1042500030BD994203D80A4651680029F9D1146843
:1042600015199D420AD118682318D0188842136086
:1042700012D108681B1813604B680CE002D90C239C
:10428000036030BD18681C188C4203D10C68496863
:10429000001918605960536030BD00BFC400002091
:1042A000094A13686BB118186946884202D8106031
:1042B00018467047054B0C221A604FF0FF33184622
:1042C0007047034B1360EEE7C80000208C0C002001
:1042D000900C0020FEE700BFF8B500BFF8BC08BC9A
:1042E0009E467047F8B500BFF8BC08BC9E467047B4
:1042F000060000002C01010105000100AF3600009E
:1043000001000000E80300002C010000300700005D
:1043100040010000100000000000000058090020CB
:10432000000000001000000008000000740B0020D6
:1043300010000000200B002085020000000000009B
:104340000100000096000000D10200000000000003
:1043500001000000960000000101050707030402A8
:104360000302040605060D0E0E0E0D0D0D0D0E0EAC
:104370000E0E0D0D010105070703040203020406DA
:1043800005060F1010100F0F0F0F101010100F0F49
:1043900001010507070304020302040605061112C2
:1043A000121211111111121212121111010105072D
:1043B00007030402030204060506131C1C1C131346
:1043C00013131C1C1C1C1313000105070602030118
:1043D0000302040604051D1E1E1E1D1D1D1D1E1E9E
:1043E0001E1E1D1D0001050706020301030204062F
:1043F00004051F2020201F1F1F1F202020201F1FFB
:104400000101050707030402030204060506212231
:1044100022222121212122222222212107050201FB
:104420000306042323232323232307050201030672
:10443000042424242424242407050201030604253B
:104440002525252525250705020103060426262600
:1044500026262626000107020627272727270000F1
:10446000000000000000131211100F0E0D0C0000D0
:104470000000212524260000000000118002000019
:10448000000002060000200039000F000000401567
:1044900000204004001000223F0006005B044F048F
:1044A00066046D047D0407007F046F0400000000B3
:1044B000000A000080200000FFFF7704790A39001D
:1044C000B020790071007D04760406000E00700AA9
:1044D0003800B602B6083F0073043F08730C6D0441
:1044E00001113E0030223628802A6E04092239004C
:1044F00080080F0001000800000158107C045800DB
:104500005E04582071040C0C740404000E00700C3E
:104510003800541454045C04730467045004080CF9
:1045200078001C0010201428802A0C084820000065
:1045300001000000030040000C000000000000002B
:104540000000000004000000020000000400000061
:1045500003000000430000001800002000000000DD
:08456000F4BBFF7F0100000025
:104568009903000000000000010000002C01000079
:10457800006CDC0200800000000000000000000069
:104588000000000000000000000000000000000023
:10459800000000000000000054450000000000007A
:1045A8000000000000000000000000000000000003
:1045B80000000000000000000000000000000000F3
:1045C80000000000000000000000000000000000E3
:1045D800000000000000000000000000180000209B
:0845E8002501000001010000A3
:04000003000020F1E8
:00000001FF
/* Linker script for Energy Micro EFM32GG devices */
/* */
/* This file is subject to the license terms as defined in ARM's */
/* CMSIS END USER LICENSE AGREEMENT.pdf, governing the use of */
/* Example Code. */
/* */
/* Energy Micro AS, 2012 */
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 1048576
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 131072
}
/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH and RAM.
* It references following symbols, which must be defined in code:
* Reset_Handler : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
* __exidx_start
* __exidx_end
* __etext
* __data_start__
* __preinit_array_start
* __preinit_array_end
* __init_array_start
* __init_array_end
* __fini_array_start
* __fini_array_end
* __data_end__
* __bss_start__
* __bss_end__
* __end__
* end
* __HeapLimit
* __StackLimit
* __StackTop
* __stack
*/
ENTRY(Reset_Handler)
SECTIONS
{
.text :
{
KEEP(*(.isr_vector))
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.rodata*)
KEEP(*(.eh_frame*))
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
__etext = .;
.data : AT (__etext)
{
__data_start__ = .;
*(vtable)
*(.data*)
. = ALIGN (4);
*(.ram)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
. = ALIGN(4);
/* All data end */
__data_end__ = .;
} > RAM
.bss :
{
__bss_start__ = .;
*(.bss*)
*(COMMON)
__bss_end__ = .;
} > RAM
.heap :
{
__end__ = .;
end = __end__;
_end = __end__;
*(.heap*)
__HeapLimit = .;
} > RAM
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy :
{
*(.stack)
} > RAM
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
}
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
# Add inputs and outputs from these tool invocations to the build variables
C_SRCS += \
../emlib/em_assert.c \
../emlib/em_cmu.c \
../emlib/em_emu.c \
../emlib/em_gpio.c \
../emlib/em_lcd.c \
../emlib/em_system.c
OBJS += \
./emlib/em_assert.o \
./emlib/em_cmu.o \
./emlib/em_emu.o \
./emlib/em_gpio.o \
./emlib/em_lcd.o \
./emlib/em_system.o
C_DEPS += \
./emlib/em_assert.d \
./emlib/em_cmu.d \
./emlib/em_emu.d \
./emlib/em_gpio.d \
./emlib/em_lcd.d \
./emlib/em_system.d
# Each subdirectory must supply rules for building sources it contributes
emlib/em_assert.o: ../emlib/em_assert.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/rtx_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/RTX/INC" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"emlib/em_assert.d" -MT"emlib/em_assert.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
emlib/em_cmu.o: ../emlib/em_cmu.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/rtx_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/RTX/INC" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"emlib/em_cmu.d" -MT"emlib/em_cmu.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
emlib/em_emu.o: ../emlib/em_emu.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/rtx_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/RTX/INC" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"emlib/em_emu.d" -MT"emlib/em_emu.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
emlib/em_gpio.o: ../emlib/em_gpio.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/rtx_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/RTX/INC" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"emlib/em_gpio.d" -MT"emlib/em_gpio.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
emlib/em_lcd.o: ../emlib/em_lcd.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/rtx_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/RTX/INC" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"emlib/em_lcd.d" -MT"emlib/em_lcd.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
emlib/em_system.o: ../emlib/em_system.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/rtx_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/RTX/INC" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"emlib/em_system.d" -MT"emlib/em_system.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
-include ../makefile.init
RM := rm -rf
# All of the sources participating in the build are defined here
-include sources.mk
-include src/subdir.mk
-include emlib/subdir.mk
-include Drivers/subdir.mk
-include CMSIS/efm32gg/subdir.mk
-include BSP/subdir.mk
-include subdir.mk
-include objects.mk
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(strip $(C_DEPS)),)
-include $(C_DEPS)
endif
endif
-include ../makefile.defs
# Add inputs and outputs from these tool invocations to the build variables
# All Target
all: EFM32GG_rtx_blink.axf
# Tool invocations
EFM32GG_rtx_blink.axf: $(OBJS) $(USER_OBJS)
@echo 'Building target: $@'
@echo 'Invoking: GNU ARM C Linker'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb --specs=nano.specs -L"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/RTX/LIB/GCC/" -Xlinker --gc-sections -Xlinker -Map="EFM32GG_rtx_blink.map" -T "EFM32GG_rtx_blink.ld" -o EFM32GG_rtx_blink.axf "./src/RTX_Conf_CM.o" "./src/rtx_blink.o" "./emlib/em_assert.o" "./emlib/em_cmu.o" "./emlib/em_emu.o" "./emlib/em_gpio.o" "./emlib/em_lcd.o" "./emlib/em_system.o" "./Drivers/segmentlcd.o" "./CMSIS/efm32gg/startup_gcc_efm32gg.o" "./CMSIS/efm32gg/system_efm32gg.o" "./BSP/bsp_stk_leds.o" "./BSP/bsp_trace.o" "-lRTX_CM3" -Wl,--start-group -lgcc -lc -lnosys -Wl,--end-group
@echo 'Finished building target: $@'
@echo ' '
@echo 'Building hex file: EFM32GG_rtx_blink.hex'
arm-none-eabi-objcopy -O ihex "EFM32GG_rtx_blink.axf" "EFM32GG_rtx_blink.hex"
@echo ' '
@echo 'Running size tool'
arm-none-eabi-size "EFM32GG_rtx_blink.axf"
@echo ' '
# Other Targets
clean:
-$(RM) $(OBJS)$(C_DEPS)$(EXECUTABLES) EFM32GG_rtx_blink.axf
-@echo ' '
.PHONY: all clean dependents
.SECONDARY:
-include ../makefile.targets
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
USER_OBJS :=
LIBS := -lRTX_CM3
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
O_SRCS :=
C_SRCS :=
S_SRCS :=
S_UPPER_SRCS :=
OBJ_SRCS :=
ASM_SRCS :=
OBJS :=
C_DEPS :=
EXECUTABLES :=
# Every subdirectory with source files must be described here
SUBDIRS := \
src \
emlib \
Drivers \
CMSIS/efm32gg \
BSP \
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
# Add inputs and outputs from these tool invocations to the build variables
C_SRCS += \
../src/RTX_Conf_CM.c \
../src/rtx_blink.c
OBJS += \
./src/RTX_Conf_CM.o \
./src/rtx_blink.o
C_DEPS += \
./src/RTX_Conf_CM.d \
./src/rtx_blink.d
# Each subdirectory must supply rules for building sources it contributes
src/RTX_Conf_CM.o: ../src/RTX_Conf_CM.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/rtx_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/RTX/INC" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"src/RTX_Conf_CM.d" -MT"src/RTX_Conf_CM.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
src/rtx_blink.o: ../src/rtx_blink.c
@echo 'Building file: $<'
@echo 'Invoking: GNU ARM C Compiler'
arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m3 -mthumb '-DEFM32GG990F1024=1' -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/examples/rtx_blink" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/EFM32GG_STK3700/config" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/Device/EnergyMicro/EFM32GG/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/reptile/RTX/INC" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/bsp" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/CMSIS/Include" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/emlib/inc" -I"C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2/kits/common/drivers" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -std=c99 -MMD -MP -MF"src/rtx_blink.d" -MT"src/rtx_blink.o" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
/***************************************************************************//**
* @file
* @brief Assert API
* @author Energy Micro AS
* @version 3.20.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_assert.h"
#if defined(DEBUG_EFM)
/***************************************************************************//**
* @brief
* EFM internal assert handling.
*
* This function is invoked through EFM_ASSERT() macro usage only, it should
* not be used explicitly.
*
* Currently this implementation only enters an indefinite loop, allowing
* the use of a debugger to determine cause of failure. By defining
* DEBUG_EFM_USER to the preprocessor for all files, a user defined version
* of this function must be defined and will be invoked instead, possibly
* providing output of assertion location.
*
* Please notice that this function is not used unless DEBUG_EFM is defined
* during preprocessing of EFM_ASSERT() usage.
*
* @par file
* Name of source file where assertion failed.
*
* @par line
* Line number in source file where assertion failed.
******************************************************************************/
void assertEFM(const char *file, int line)
{
(void)file; /* Unused parameter */
(void)line; /* Unused parameter */
while (1)
;
}
#endif /* DEBUG_EFM */
/***************************************************************************//**
* @file
* @brief Clock management unit (CMU) Peripheral API
* @author Energy Micro AS
* @version 3.20.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_cmu.h"
#if defined( CMU_PRESENT )
#include "em_assert.h"
#include "em_bitband.h"
#include "em_emu.h"
/***************************************************************************//**
* @addtogroup EM_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup CMU
* @brief Clock management unit (CMU) Peripheral API
* @{
******************************************************************************/
/*******************************************************************************
****************************** DEFINES ************************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** Maximum allowed core frequency when using 0 wait states on flash access. */
#define CMU_MAX_FREQ_0WS 16000000
/** Maximum allowed core frequency when using 1 wait states on flash access */
#define CMU_MAX_FREQ_1WS 32000000
/** Maximum frequency before HFLE needs to be enabled on Giant Gecko */
#define CMU_MAX_FREQ_HFLE 32000000
/** Low frequency A group identifier */
#define CMU_LFA 0
/** Low frequency B group identifier */
#define CMU_LFB 1
/** @endcond */
/*******************************************************************************
************************** LOCAL FUNCTIONS ********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/***************************************************************************//**
* @brief
* Configure flash access wait states to most conservative setting for
* this target. Retain SCBTP setting.
******************************************************************************/
static void CMU_FlashWaitStateMax(void)
{
uint32_t cfg;
cfg = MSC->READCTRL;
switch(cfg & _MSC_READCTRL_MODE_MASK)
{
case MSC_READCTRL_MODE_WS1:
case MSC_READCTRL_MODE_WS0:
#if defined( MSC_READCTRL_MODE_WS2 )
case MSC_READCTRL_MODE_WS2:
cfg = (cfg & ~_MSC_READCTRL_MODE_MASK) | MSC_READCTRL_MODE_WS2;
#else
cfg = (cfg & ~_MSC_READCTRL_MODE_MASK) | MSC_READCTRL_MODE_WS1;
#endif
break;
#if defined( MSC_READCTRL_MODE_WS1SCBTP )
case MSC_READCTRL_MODE_WS1SCBTP:
#endif
#if defined( MSC_READCTRL_MODE_WS0SCBTP )
case MSC_READCTRL_MODE_WS0SCBTP:
#endif
#if defined( MSC_READCTRL_MODE_WS2SCBTP )
case MSC_READCTRL_MODE_WS2SCBTP:
cfg = (cfg & ~_MSC_READCTRL_MODE_MASK) | MSC_READCTRL_MODE_WS2SCBTP;
#elif defined( MSC_READCTRL_MODE_WS1SCBTP )
cfg = (cfg & ~_MSC_READCTRL_MODE_MASK) | MSC_READCTRL_MODE_WS1SCBTP;
#endif
#if defined( MSC_READCTRL_MODE_WS2SCBTP ) || \
defined( MSC_READCTRL_MODE_WS1SCBTP ) || defined( MSC_READCTRL_MODE_WS0SCBTP )
break;
#endif
}
MSC->READCTRL = cfg;
}
/***************************************************************************//**
* @brief Convert dividend to prescaler logarithmic value. Only works for even
* numbers equal to 2^n
* @param[in] div Unscaled dividend,
* @return Base 2 logarithm of input, as used by fixed prescalers
******************************************************************************/
__STATIC_INLINE uint32_t CMU_DivToLog2(CMU_ClkDiv_TypeDef div)
{
uint32_t log2;
/* Prescalers take argument of 32768 or less */
EFM_ASSERT((div>0) && (div <= 32768));
/* Count leading zeroes and "reverse" result, Cortex-M3 intrinsic */
log2 = (31 - __CLZ(div));
return log2;
}
/***************************************************************************//**
* @brief Convert logarithm of 2 prescaler to division factor
* @param[in] log2
* @return Dividend
******************************************************************************/
__STATIC_INLINE uint32_t CMU_Log2ToDiv(uint32_t log2)
{
return 1<<log2;
}
/***************************************************************************//**
* @brief
* Configure flash access wait states in order to support given HFCORECLK
* frequency.
*
* @param[in] hfcoreclk
* HFCORECLK frequency that flash access wait states must be configured for.
******************************************************************************/
static void CMU_FlashWaitStateControl(uint32_t hfcoreclk)
{
uint32_t cfg;
cfg = MSC->READCTRL;
#if defined( MSC_READCTRL_MODE_WS2 )
if (hfcoreclk > CMU_MAX_FREQ_1WS)
{
switch(cfg & _MSC_READCTRL_MODE_MASK)
{
case MSC_READCTRL_MODE_WS0SCBTP:
case MSC_READCTRL_MODE_WS1SCBTP:
cfg = (cfg & ~_MSC_READCTRL_MODE_MASK) | MSC_READCTRL_MODE_WS2SCBTP;
break;
case MSC_READCTRL_MODE_WS0:
case MSC_READCTRL_MODE_WS1:
default:
cfg = (cfg & ~_MSC_READCTRL_MODE_MASK) | MSC_READCTRL_MODE_WS2;
break;
}
}
#endif
if ((hfcoreclk > CMU_MAX_FREQ_0WS) && (hfcoreclk <= CMU_MAX_FREQ_1WS))
{
switch (cfg & _MSC_READCTRL_MODE_MASK)
{
#if defined( MSC_READCTRL_MODE_WS2SCBTP )
case MSC_READCTRL_MODE_WS2SCBTP:
#endif
#if defined( MSC_READCTRL_MODE_WS1SCBTP ) && defined( MSC_READCTRL_MODE_WS0SCBTP )
case MSC_READCTRL_MODE_WS0SCBTP:
case MSC_READCTRL_MODE_WS1SCBTP:
cfg = (cfg & ~_MSC_READCTRL_MODE_MASK) | MSC_READCTRL_MODE_WS1SCBTP;
#endif
#if defined( MSC_READCTRL_MODE_WS2SCBTP ) || \
defined( MSC_READCTRL_MODE_WS1SCBTP ) || defined( MSC_READCTRL_MODE_WS0SCBTP )
break;
#endif
default:
cfg = (cfg & ~_MSC_READCTRL_MODE_MASK) | MSC_READCTRL_MODE_WS1;
break;
}
}
if (hfcoreclk <= CMU_MAX_FREQ_0WS)
{
switch (cfg & _MSC_READCTRL_MODE_MASK)
{
#if defined( MSC_READCTRL_MODE_WS2SCBTP )
case MSC_READCTRL_MODE_WS2SCBTP:
#endif
#if defined( MSC_READCTRL_MODE_WS0SCBTP )
case MSC_READCTRL_MODE_WS1SCBTP:
case MSC_READCTRL_MODE_WS0SCBTP:
cfg = (cfg & ~_MSC_READCTRL_MODE_MASK) | MSC_READCTRL_MODE_WS0SCBTP;
#endif
#if defined( MSC_READCTRL_MODE_WS2SCBTP ) || \
defined( MSC_READCTRL_MODE_WS1SCBTP ) || defined( MSC_READCTRL_MODE_WS0SCBTP )
break;
#endif
default:
cfg = (cfg & ~_MSC_READCTRL_MODE_MASK) | MSC_READCTRL_MODE_WS0;
break;
}
}
MSC->READCTRL = cfg;
}
#if defined(USB_PRESENT)
/***************************************************************************//**
* @brief
* Get the USBC frequency
*
* @return
* USBC frequency in Hz
******************************************************************************/
static uint32_t CMU_USBCClkGet(void)
{
uint32_t ret;
CMU_Select_TypeDef clk;
/* Get selected clock source */
clk = CMU_ClockSelectGet(cmuClock_USBC);
switch(clk)
{
case cmuSelect_LFXO:
ret = SystemLFXOClockGet();
break;
case cmuSelect_LFRCO:
ret = SystemLFRCOClockGet();
break;
case cmuSelect_HFCLK:
ret = SystemHFClockGet();
break;
default:
/* Clock is not enabled */
ret = 0;
break;
}
return ret;
}
#endif
/***************************************************************************//**
* @brief
* Get the AUX clock frequency. Used by MSC flash programming and LESENSE,
* by default also as debug clock.
*
* @return
* AUX Frequency in Hz
******************************************************************************/
static uint32_t CMU_AUXClkGet(void)
{
uint32_t ret;
#if defined(_EFM32_GECKO_FAMILY)
/* Gecko has a fixed 14Mhz AUXHFRCO clock */
ret = 14000000;
#else
switch(CMU->AUXHFRCOCTRL & _CMU_AUXHFRCOCTRL_BAND_MASK)
{
case CMU_AUXHFRCOCTRL_BAND_1MHZ:
ret = 1000000;
break;
case CMU_AUXHFRCOCTRL_BAND_7MHZ:
ret = 7000000;
break;
case CMU_AUXHFRCOCTRL_BAND_11MHZ:
ret = 11000000;
break;
case CMU_AUXHFRCOCTRL_BAND_14MHZ:
ret = 14000000;
break;
case CMU_AUXHFRCOCTRL_BAND_21MHZ:
ret = 21000000;
break;
#if defined( _CMU_AUXHFRCOCTRL_BAND_28MHZ )
case CMU_AUXHFRCOCTRL_BAND_28MHZ:
ret = 28000000;
break;
#endif
default:
ret = 0;
break;
}
#endif
return ret;
}
/***************************************************************************//**
* @brief
* Get the Debug Trace clock frequency
*
* @return
* Debug Trace frequency in Hz
******************************************************************************/
static uint32_t CMU_DBGClkGet(void)
{
uint32_t ret;
CMU_Select_TypeDef clk;
/* Get selected clock source */
clk = CMU_ClockSelectGet(cmuClock_DBG);
switch(clk)
{
case cmuSelect_HFCLK:
ret = SystemHFClockGet();
#if defined( _CMU_CTRL_HFCLKDIV_MASK )
/* Giant Gecko has an additional divider, not used by USBC */
ret = ret / (1 + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK) >>
_CMU_CTRL_HFCLKDIV_SHIFT));
#endif
break;
case cmuSelect_AUXHFRCO:
ret = CMU_AUXClkGet();
break;
default:
EFM_ASSERT(0);
ret = 0;
break;
}
return ret;
}
/***************************************************************************//**
* @brief
* Get the LFnCLK frequency based on current configuration.
*
* @param[in] lfClkBranch
* LF branch, 0 = LFA, 1 = LFB, ...
*
* @return
* The LFnCLK frequency in Hz. If no LFnCLK is selected (disabled), 0 is
* returned.
******************************************************************************/
static uint32_t CMU_LFClkGet(unsigned int lfClkBranch)
{
uint32_t ret;
EFM_ASSERT(lfClkBranch == CMU_LFA || lfClkBranch == CMU_LFB);
switch ((CMU->LFCLKSEL >> (lfClkBranch * 2)) & 0x3)
{
case _CMU_LFCLKSEL_LFA_LFRCO:
ret = SystemLFRCOClockGet();
break;
case _CMU_LFCLKSEL_LFA_LFXO:
ret = SystemLFXOClockGet();
break;
case _CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2:
#if defined( CMU_CTRL_HFLE )
/* Giant Gecko can use a /4 divider (and must if >32MHz) or HFLE is set */
if(((CMU->HFCORECLKDIV & _CMU_HFCORECLKDIV_HFCORECLKLEDIV_MASK) == CMU_HFCORECLKDIV_HFCORECLKLEDIV_DIV4)||
(CMU->CTRL & CMU_CTRL_HFLE))
{
ret = SystemCoreClockGet() / 4;
}
else
{
ret = SystemCoreClockGet() / 2;
}
#else
ret = SystemCoreClockGet() / 2;
#endif
break;
case _CMU_LFCLKSEL_LFA_DISABLED:
#if defined( CMU_LFCLKSEL_LFAE )
/* Check LF Extended bit setting for ULFRCO clock */
if(CMU->LFCLKSEL >> (_CMU_LFCLKSEL_LFAE_SHIFT + lfClkBranch * 4))
{
ret = SystemULFRCOClockGet();
}
else
{
ret = 0;
}
#else
ret = 0;
#endif
break;
default:
ret = 0;
break;
}
return ret;
}
/***************************************************************************//**
* @brief
* Wait for ongoing sync of register(s) to low frequency domain to complete.
*
* @param[in] mask
* Bitmask corresponding to SYNCBUSY register defined bits, indicating
* registers that must complete any ongoing synchronization.
******************************************************************************/
__STATIC_INLINE void CMU_Sync(uint32_t mask)
{
/* Avoid deadlock if modifying the same register twice when freeze mode is */
/* activated. */
if (CMU->FREEZE & CMU_FREEZE_REGFREEZE)
return;
/* Wait for any pending previous write operation to have been completed */
/* in low frequency domain */
while (CMU->SYNCBUSY & mask)
;
}
/** @endcond */
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Calibrate clock.
*
* @details
* Run a calibration for HFCLK against a selectable reference clock. Please
* refer to the EFM32 reference manual, CMU chapter, for further details.
*
* @note
* This function will not return until calibration measurement is completed.
*
* @param[in] HFCycles
* The number of HFCLK cycles to run calibration. Increasing this number
* increases precision, but the calibration will take more time.
*
* @param[in] ref
* The reference clock used to compare HFCLK with.
*
* @return
* The number of ticks the reference clock after HFCycles ticks on the HF
* clock.
******************************************************************************/
uint32_t CMU_Calibrate(uint32_t HFCycles, CMU_Osc_TypeDef ref)
{
EFM_ASSERT(HFCycles <= (_CMU_CALCNT_CALCNT_MASK >> _CMU_CALCNT_CALCNT_SHIFT));
/* Set reference clock source */
switch (ref)
{
case cmuOsc_LFXO:
CMU->CALCTRL = CMU_CALCTRL_UPSEL_LFXO;
break;
case cmuOsc_LFRCO:
CMU->CALCTRL = CMU_CALCTRL_UPSEL_LFRCO;
break;
case cmuOsc_HFXO:
CMU->CALCTRL = CMU_CALCTRL_UPSEL_HFXO;
break;
case cmuOsc_HFRCO:
CMU->CALCTRL = CMU_CALCTRL_UPSEL_HFRCO;
break;
case cmuOsc_AUXHFRCO:
CMU->CALCTRL = CMU_CALCTRL_UPSEL_AUXHFRCO;
break;
default:
EFM_ASSERT(0);
return 0;
}
/* Set top value */
CMU->CALCNT = HFCycles;
/* Start calibration */
CMU->CMD = CMU_CMD_CALSTART;
/* Wait until calibration completes */
while (CMU->STATUS & CMU_STATUS_CALBSY)
;
return CMU->CALCNT;
}
#if defined( _CMU_CALCTRL_UPSEL_MASK ) && defined( _CMU_CALCTRL_DOWNSEL_MASK )
/***************************************************************************//**
* @brief
* Configure clock calibration
*
* @details
* Configure a calibration for a selectable clock source against another
* selectable reference clock.
* Refer to the EFM32 reference manual, CMU chapter, for further details.
*
* @note
* After configuration, a call to CMU_CalibrateStart() is required, and
* the resulting calibration value can be read out with the
* CMU_CalibrateCountGet() function call.
*
* @param[in] downCycles
* The number of downSel clock cycles to run calibration. Increasing this
* number increases precision, but the calibration will take more time.
*
* @param[in] downSel
* The clock which will be counted down downCycles
*
* @param[in] upSel
* The reference clock, the number of cycles generated by this clock will
* be counted and added up, the result can be given with the
* CMU_CalibrateCountGet() function call.
******************************************************************************/
void CMU_CalibrateConfig(uint32_t downCycles, CMU_Osc_TypeDef downSel,
CMU_Osc_TypeDef upSel)
{
/* Keep untouched configuration settings */
uint32_t calCtrl = CMU->CALCTRL & ~(_CMU_CALCTRL_UPSEL_MASK | _CMU_CALCTRL_DOWNSEL_MASK);
/* 20 bits of precision to calibration count register */
EFM_ASSERT(downCycles <= (_CMU_CALCNT_CALCNT_MASK >> _CMU_CALCNT_CALCNT_SHIFT));
/* Set down counting clock source - down counter */
switch (downSel)
{
case cmuOsc_LFXO:
calCtrl |= CMU_CALCTRL_DOWNSEL_LFXO;
break;
case cmuOsc_LFRCO:
calCtrl |= CMU_CALCTRL_DOWNSEL_LFRCO;
break;
case cmuOsc_HFXO:
calCtrl |= CMU_CALCTRL_DOWNSEL_HFXO;
break;
case cmuOsc_HFRCO:
calCtrl |= CMU_CALCTRL_DOWNSEL_HFRCO;
break;
case cmuOsc_AUXHFRCO:
calCtrl |= CMU_CALCTRL_DOWNSEL_AUXHFRCO;
break;
default:
EFM_ASSERT(0);
break;
}
/* Set top value to be counted down by the downSel clock */
CMU->CALCNT = downCycles;
/* Set reference clock source - up counter */
switch (upSel)
{
case cmuOsc_LFXO:
calCtrl |= CMU_CALCTRL_UPSEL_LFXO;
break;
case cmuOsc_LFRCO:
calCtrl |= CMU_CALCTRL_UPSEL_LFRCO;
break;
case cmuOsc_HFXO:
calCtrl |= CMU_CALCTRL_UPSEL_HFXO;
break;
case cmuOsc_HFRCO:
calCtrl |= CMU_CALCTRL_UPSEL_HFRCO;
break;
case cmuOsc_AUXHFRCO:
calCtrl |= CMU_CALCTRL_UPSEL_AUXHFRCO;
break;
default:
EFM_ASSERT(0);
break;
}
CMU->CALCTRL = calCtrl;
}
#endif
/***************************************************************************//**
* @brief
* Get clock divisor/prescaler.
*
* @param[in] clock
* Clock point to get divisor/prescaler for. Notice that not all clock points
* have a divisor/prescaler. Please refer to CMU overview in reference manual.
*
* @return
* The current clock point divisor/prescaler. 1 is returned
* if @p clock specifies a clock point without a divisor/prescaler.
******************************************************************************/
CMU_ClkDiv_TypeDef CMU_ClockDivGet(CMU_Clock_TypeDef clock)
{
uint32_t divReg;
CMU_ClkDiv_TypeDef ret;
/* Get divisor reg id */
divReg = (clock >> CMU_DIV_REG_POS) & CMU_DIV_REG_MASK;
switch (divReg)
{
#if defined( _CMU_CTRL_HFCLKDIV_MASK )
case CMU_HFCLKDIV_REG:
ret = 1 + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK) >>
_CMU_CTRL_HFCLKDIV_SHIFT);
break;
#endif
case CMU_HFPERCLKDIV_REG:
ret = (CMU_ClkDiv_TypeDef)((CMU->HFPERCLKDIV &
_CMU_HFPERCLKDIV_HFPERCLKDIV_MASK) >>
_CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT);
ret = CMU_Log2ToDiv(ret);
break;
case CMU_HFCORECLKDIV_REG:
ret = (CMU_ClkDiv_TypeDef)((CMU->HFCORECLKDIV &
_CMU_HFCORECLKDIV_HFCORECLKDIV_MASK) >>
_CMU_HFCORECLKDIV_HFCORECLKDIV_SHIFT);
ret = CMU_Log2ToDiv(ret);
break;
case CMU_LFAPRESC0_REG:
switch (clock)
{
case cmuClock_RTC:
ret = (CMU_ClkDiv_TypeDef)(((CMU->LFAPRESC0 & _CMU_LFAPRESC0_RTC_MASK) >>
_CMU_LFAPRESC0_RTC_SHIFT));
ret = CMU_Log2ToDiv(ret);
break;
#if defined(_CMU_LFAPRESC0_LETIMER0_MASK)
case cmuClock_LETIMER0:
ret = (CMU_ClkDiv_TypeDef)(((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LETIMER0_MASK) >>
_CMU_LFAPRESC0_LETIMER0_SHIFT));
ret = CMU_Log2ToDiv(ret);
break;
#endif
#if defined(_CMU_LFAPRESC0_LCD_MASK)
case cmuClock_LCDpre:
ret = (CMU_ClkDiv_TypeDef)(((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LCD_MASK) >>
_CMU_LFAPRESC0_LCD_SHIFT) + CMU_DivToLog2(cmuClkDiv_16));
ret = CMU_Log2ToDiv(ret);
break;
#endif
#if defined(_CMU_LFAPRESC0_LESENSE_MASK)
case cmuClock_LESENSE:
ret = (CMU_ClkDiv_TypeDef)(((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LESENSE_MASK) >>
_CMU_LFAPRESC0_LESENSE_SHIFT));
ret = CMU_Log2ToDiv(ret);
break;
#endif
default:
EFM_ASSERT(0);
ret = cmuClkDiv_1;
break;
}
break;
case CMU_LFBPRESC0_REG:
switch (clock)
{
#if defined(_CMU_LFBPRESC0_LEUART0_MASK)
case cmuClock_LEUART0:
ret = (CMU_ClkDiv_TypeDef)(((CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART0_MASK) >>
_CMU_LFBPRESC0_LEUART0_SHIFT));
ret = CMU_Log2ToDiv(ret);
break;
#endif
#if defined(_CMU_LFBPRESC0_LEUART1_MASK)
case cmuClock_LEUART1:
ret = (CMU_ClkDiv_TypeDef)(((CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART1_MASK) >>
_CMU_LFBPRESC0_LEUART1_SHIFT));
ret = CMU_Log2ToDiv(ret);
break;
#endif
default:
EFM_ASSERT(0);
ret = cmuClkDiv_1;
break;
}
break;
default:
EFM_ASSERT(0);
ret = cmuClkDiv_1;
break;
}
return(ret);
}
/***************************************************************************//**
* @brief
* Set clock divisor/prescaler.
*
* @note
* If setting a LF clock prescaler, synchronization into the low frequency
* domain is required. If the same register is modified before a previous
* update has completed, this function will stall until the previous
* synchronization has completed. Please refer to CMU_FreezeEnable() for
* a suggestion on how to reduce stalling time in some use cases.
*
* @param[in] clock
* Clock point to set divisor/prescaler for. Notice that not all clock points
* have a divisor/prescaler, please refer to CMU overview in the reference
* manual.
*
* @param[in] div
* The clock divisor to use (<= cmuClkDiv_512).
******************************************************************************/
void CMU_ClockDivSet(CMU_Clock_TypeDef clock, CMU_ClkDiv_TypeDef div)
{
uint32_t freq;
uint32_t divReg;
/* Get divisor reg id */
divReg = (clock >> CMU_DIV_REG_POS) & CMU_DIV_REG_MASK;
switch (divReg)
{
#if defined( _CMU_CTRL_HFCLKDIV_MASK )
case CMU_HFCLKDIV_REG:
EFM_ASSERT((div>=cmuClkDiv_1) && (div<=cmuClkDiv_8));
/* Configure worst case wait states for flash access before setting divisor */
CMU_FlashWaitStateMax();
/* Set divider */
CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_HFCLKDIV_MASK) |
((div-1) << _CMU_CTRL_HFCLKDIV_SHIFT);
/* Update CMSIS core clock variable */
/* (The function will update the global variable) */
freq = SystemCoreClockGet();
/* Optimize flash access wait state setting for current core clk */
CMU_FlashWaitStateControl(freq);
break;
#endif
case CMU_HFPERCLKDIV_REG:
EFM_ASSERT((div >= cmuClkDiv_1) && (div <= cmuClkDiv_512));
/* Convert to correct scale */
div = CMU_DivToLog2(div);
CMU->HFPERCLKDIV = (CMU->HFPERCLKDIV & ~_CMU_HFPERCLKDIV_HFPERCLKDIV_MASK) |
(div << _CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT);
break;
case CMU_HFCORECLKDIV_REG:
EFM_ASSERT(div <= cmuClkDiv_512);
/* Configure worst case wait states for flash access before setting divisor */
CMU_FlashWaitStateMax();
#if defined( CMU_CTRL_HFLE )
/* Clear HFLE and set DIV2 factor for peripheral clock
when running at frequencies lower than 32 MHz. */
if ( (cmuSelect_HFXO != CMU_ClockSelectGet(cmuClock_HF)) ||
((SystemHFXOClockGet()/div) <= CMU_MAX_FREQ_HFLE) )
{
/* Clear CMU HFLE */
BITBAND_Peripheral(&(CMU->CTRL), _CMU_CTRL_HFLE_SHIFT, 0);
/* Set DIV2 factor for peripheral clock */
BITBAND_Peripheral(&(CMU->HFCORECLKDIV),
_CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 0);
}
else
{
/* Set CMU HFLE */
BITBAND_Peripheral(&(CMU->CTRL), _CMU_CTRL_HFLE_SHIFT, 1);
/* Set DIV4 factor for peripheral clock */
BITBAND_Peripheral(&(CMU->HFCORECLKDIV),
_CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);
}
#endif
/* Convert to correct scale */
div = CMU_DivToLog2(div);
CMU->HFCORECLKDIV = (CMU->HFCORECLKDIV & ~_CMU_HFCORECLKDIV_HFCORECLKDIV_MASK) |
(div << _CMU_HFCORECLKDIV_HFCORECLKDIV_SHIFT);
/* Update CMSIS core clock variable */
/* (The function will update the global variable) */
freq = SystemCoreClockGet();
/* Optimize flash access wait state setting for current core clk */
CMU_FlashWaitStateControl(freq);
break;
case CMU_LFAPRESC0_REG:
switch (clock)
{
case cmuClock_RTC:
EFM_ASSERT(div <= cmuClkDiv_32768);
/* LF register about to be modified require sync. busy check */
CMU_Sync(CMU_SYNCBUSY_LFAPRESC0);
/* Convert to correct scale */
div = CMU_DivToLog2(div);
CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_RTC_MASK) |
(div << _CMU_LFAPRESC0_RTC_SHIFT);
break;
#if defined(_CMU_LFAPRESC0_LETIMER0_MASK)
case cmuClock_LETIMER0:
EFM_ASSERT(div <= cmuClkDiv_32768);
/* LF register about to be modified require sync. busy check */
CMU_Sync(CMU_SYNCBUSY_LFAPRESC0);
/* Convert to correct scale */
div = CMU_DivToLog2(div);
CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_LETIMER0_MASK) |
(div << _CMU_LFAPRESC0_LETIMER0_SHIFT);
break;
#endif
#if defined(LCD_PRESENT)
case cmuClock_LCDpre:
EFM_ASSERT((div >= cmuClkDiv_16) && (div <= cmuClkDiv_128));
/* LF register about to be modified require sync. busy check */
CMU_Sync(CMU_SYNCBUSY_LFAPRESC0);
/* Convert to correct scale */
div = CMU_DivToLog2(div);
CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_LCD_MASK) |
((div - CMU_DivToLog2(cmuClkDiv_16)) << _CMU_LFAPRESC0_LCD_SHIFT);
break;
#endif /* defined(LCD_PRESENT) */
#if defined(LESENSE_PRESENT)
case cmuClock_LESENSE:
EFM_ASSERT(div <= cmuClkDiv_8);
/* LF register about to be modified require sync. busy check */
CMU_Sync(CMU_SYNCBUSY_LFAPRESC0);
/* Convert to correct scale */
div = CMU_DivToLog2(div);
CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_LESENSE_MASK) |
(div << _CMU_LFAPRESC0_LESENSE_SHIFT);
break;
#endif /* defined(LESENSE_PRESENT) */
default:
EFM_ASSERT(0);
break;
}
break;
case CMU_LFBPRESC0_REG:
switch (clock)
{
#if defined(_CMU_LFBPRESC0_LEUART0_MASK)
case cmuClock_LEUART0:
EFM_ASSERT(div <= cmuClkDiv_8);
/* LF register about to be modified require sync. busy check */
CMU_Sync(CMU_SYNCBUSY_LFBPRESC0);
/* Convert to correct scale */
div = CMU_DivToLog2(div);
CMU->LFBPRESC0 = (CMU->LFBPRESC0 & ~_CMU_LFBPRESC0_LEUART0_MASK) |
(((uint32_t)div) << _CMU_LFBPRESC0_LEUART0_SHIFT);
break;
#endif
#if defined(_CMU_LFBPRESC0_LEUART1_MASK)
case cmuClock_LEUART1:
EFM_ASSERT(div <= cmuClkDiv_8);
/* LF register about to be modified require sync. busy check */
CMU_Sync(CMU_SYNCBUSY_LFBPRESC0);
/* Convert to correct scale */
div = CMU_DivToLog2(div);
CMU->LFBPRESC0 = (CMU->LFBPRESC0 & ~_CMU_LFBPRESC0_LEUART1_MASK) |
(((uint32_t)div) << _CMU_LFBPRESC0_LEUART1_SHIFT);
break;
#endif
default:
EFM_ASSERT(0);
break;
}
break;
default:
EFM_ASSERT(0);
break;
}
}
/***************************************************************************//**
* @brief
* Enable/disable a clock.
*
* @details
* In general, module clocking is disabled after a reset. If a module
* clock is disabled, the registers of that module are not accessible and
* reading from such registers may return undefined values. Writing to
* registers of clock disabled modules have no effect. One should normally
* avoid accessing module registers of a module with a disabled clock.
*
* @note
* If enabling/disabling a LF clock, synchronization into the low frequency
* domain is required. If the same register is modified before a previous
* update has completed, this function will stall until the previous
* synchronization has completed. Please refer to CMU_FreezeEnable() for
* a suggestion on how to reduce stalling time in some use cases.
*
* @param[in] clock
* The clock to enable/disable. Notice that not all defined clock
* points have separate enable/disable control, please refer to CMU overview
* in reference manual.
*
* @param[in] enable
* @li true - enable specified clock.
* @li false - disable specified clock.
******************************************************************************/
void CMU_ClockEnable(CMU_Clock_TypeDef clock, bool enable)
{
volatile uint32_t *reg;
uint32_t bit;
uint32_t sync = 0;
/* Identify enable register */
switch ((clock >> CMU_EN_REG_POS) & CMU_EN_REG_MASK)
{
case CMU_HFPERCLKDIV_EN_REG:
reg = &(CMU->HFPERCLKDIV);
break;
case CMU_HFPERCLKEN0_EN_REG:
reg = &(CMU->HFPERCLKEN0);
break;
case CMU_HFCORECLKEN0_EN_REG:
reg = &(CMU->HFCORECLKEN0);
#if defined( CMU_CTRL_HFLE )
/* Set HFLE and DIV4 factor for peripheral clock
when running at frequencies higher than 32 MHz. */
if ( (cmuSelect_HFXO == CMU_ClockSelectGet(cmuClock_HF)) &&
((SystemHFXOClockGet()/CMU_ClockDivGet(cmuClock_CORE)) >
CMU_MAX_FREQ_HFLE) )
{
/* Enable CMU HFLE */
BITBAND_Peripheral(&(CMU->CTRL), _CMU_CTRL_HFLE_SHIFT, 1);
/* Set DIV4 factor for peripheral clock */
BITBAND_Peripheral(&(CMU->HFCORECLKDIV),
_CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);
}
#endif
break;
case CMU_LFACLKEN0_EN_REG:
reg = &(CMU->LFACLKEN0);
sync = CMU_SYNCBUSY_LFACLKEN0;
break;
case CMU_LFBCLKEN0_EN_REG:
reg = &(CMU->LFBCLKEN0);
sync = CMU_SYNCBUSY_LFBCLKEN0;
break;
case CMU_PCNT_EN_REG:
reg = &(CMU->PCNTCTRL);
break;
default: /* Cannot enable/disable clock point */
EFM_ASSERT(0);
return;
}
/* Get bit position used to enable/disable */
bit = (clock >> CMU_EN_BIT_POS) & CMU_EN_BIT_MASK;
/* LF synchronization required? */
if (sync)
{
CMU_Sync(sync);
}
/* Set/clear bit as requested */
BITBAND_Peripheral(reg, bit, (unsigned int)enable);
}
/***************************************************************************//**
* @brief
* Get clock frequency for a clock point.
*
* @param[in] clock
* Clock point to fetch frequency for.
*
* @return
* The current frequency in Hz.
******************************************************************************/
uint32_t CMU_ClockFreqGet(CMU_Clock_TypeDef clock)
{
uint32_t ret;
switch(clock & (CMU_CLK_BRANCH_MASK << CMU_CLK_BRANCH_POS))
{
case (CMU_HF_CLK_BRANCH << CMU_CLK_BRANCH_POS):
{
ret = SystemHFClockGet();
#if defined( _CMU_CTRL_HFCLKDIV_MASK )
/* Giant Gecko has an additional divider, not used by USBC */
ret = ret / (1 + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK) >>
_CMU_CTRL_HFCLKDIV_SHIFT));
#endif
} break;
#if defined(_CMU_HFPERCLKEN0_USART0_MASK) || \
defined(_CMU_HFPERCLKEN0_USART1_MASK) || \
defined(_CMU_HFPERCLKEN0_USART2_MASK) || \
defined(_CMU_HFPERCLKEN0_UART0_MASK) || \
defined(_CMU_HFPERCLKEN0_UART1_MASK) || \
defined(_CMU_HFPERCLKEN0_TIMER0_MASK) || \
defined(_CMU_HFPERCLKEN0_TIMER1_MASK) || \
defined(_CMU_HFPERCLKEN0_TIMER2_MASK) || \
defined(_CMU_HFPERCLKEN0_TIMER3_MASK) || \
defined(_CMU_HFPERCLKEN0_ACMP0_MASK) || \
defined(_CMU_HFPERCLKEN0_ACMP1_MASK) || \
defined(_CMU_HFPERCLKEN0_DAC0_MASK) || \
defined(_CMU_HFPERCLKEN0_IDAC0_MASK) || \
defined(_CMU_HFPERCLKEN0_ADC0_MASK) || \
defined(_CMU_HFPERCLKEN0_I2C0_MASK) || \
defined(_CMU_HFPERCLKEN0_I2C1_MASK) || \
defined(PRS_PRESENT) || \
defined(VCMP_PRESENT)|| \
defined(GPIO_PRESENT)
case (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS):
{
ret = SystemHFClockGet();
#if defined( _CMU_CTRL_HFCLKDIV_MASK )
/* Leopard/Giant Gecko has an additional divider */
ret = ret / (1 + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK) >>
_CMU_CTRL_HFCLKDIV_SHIFT));
#endif
ret >>= (CMU->HFPERCLKDIV & _CMU_HFPERCLKDIV_HFPERCLKDIV_MASK) >>
_CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT;
} break;
#endif
#if defined(AES_PRESENT) || \
defined(DMA_PRESENT) || \
defined(EBI_PRESENT) || \
defined(USB_PRESENT)
case (CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS):
{
ret = SystemCoreClockGet();
} break;
#endif
case (CMU_LFA_CLK_BRANCH << CMU_CLK_BRANCH_POS):
{
ret = CMU_LFClkGet(CMU_LFA);
} break;
#if defined(_CMU_LFACLKEN0_RTC_MASK)
case (CMU_RTC_CLK_BRANCH << CMU_CLK_BRANCH_POS):
{
ret = CMU_LFClkGet(CMU_LFA);
ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_RTC_MASK) >>
_CMU_LFAPRESC0_RTC_SHIFT;
} break;
#endif
#if defined(_CMU_LFACLKEN0_LETIMER0_MASK)
case (CMU_LETIMER_CLK_BRANCH << CMU_CLK_BRANCH_POS):
{
ret = CMU_LFClkGet(CMU_LFA);
ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_LETIMER0_MASK) >>
_CMU_LFAPRESC0_LETIMER0_SHIFT;
} break;
#endif
#if defined(_CMU_LFACLKEN0_LCD_MASK)
case (CMU_LCDPRE_CLK_BRANCH << CMU_CLK_BRANCH_POS):
{
ret = CMU_LFClkGet(CMU_LFA);
ret >>= ((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LCD_MASK) >>
_CMU_LFAPRESC0_LCD_SHIFT) + CMU_DivToLog2(cmuClkDiv_16);
} break;
case (CMU_LCD_CLK_BRANCH << CMU_CLK_BRANCH_POS):
{
ret = CMU_LFClkGet(CMU_LFA);
ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_LCD_MASK) >>
_CMU_LFAPRESC0_LCD_SHIFT;
ret /= (1 + ((CMU->LCDCTRL & _CMU_LCDCTRL_FDIV_MASK) >>
_CMU_LCDCTRL_FDIV_SHIFT));
} break;
#endif
#if defined(_CMU_LFACLKEN0_LESENSE_MASK)
case (CMU_LESENSE_CLK_BRANCH << CMU_CLK_BRANCH_POS):
{
ret = CMU_LFClkGet(CMU_LFA);
ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_LESENSE_MASK) >>
_CMU_LFAPRESC0_LESENSE_SHIFT;
} break;
#endif
case (CMU_LFB_CLK_BRANCH << CMU_CLK_BRANCH_POS):
{
ret = CMU_LFClkGet(CMU_LFB);
} break;
#if defined(_CMU_LFBCLKEN0_LEUART0_MASK)
case (CMU_LEUART0_CLK_BRANCH << CMU_CLK_BRANCH_POS):
{
ret = CMU_LFClkGet(CMU_LFB);
ret >>= (CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART0_MASK) >>
_CMU_LFBPRESC0_LEUART0_SHIFT;
} break;
#endif
#if defined(_CMU_LFBCLKEN0_LEUART1_MASK)
case (CMU_LEUART1_CLK_BRANCH << CMU_CLK_BRANCH_POS):
{
ret = CMU_LFClkGet(CMU_LFB);
ret >>= (CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART1_MASK) >>
_CMU_LFBPRESC0_LEUART1_SHIFT;
} break;
#endif
case (CMU_DBG_CLK_BRANCH << CMU_CLK_BRANCH_POS):
{
ret = CMU_DBGClkGet();
} break;
case (CMU_AUX_CLK_BRANCH << CMU_CLK_BRANCH_POS):
{
ret = CMU_AUXClkGet();
} break;
#if defined(USB_PRESENT)
case (CMU_USBC_CLK_BRANCH << CMU_CLK_BRANCH_POS):
{
ret = CMU_USBCClkGet();
} break;
#endif
default:
{
EFM_ASSERT(0);
ret = 0;
} break;
}
return ret;
}
/**************************************************************************//**
* @brief
* Get currently selected reference clock used for a clock branch.
*
* @param[in] clock
* Clock branch to fetch selected ref. clock for. One of:
* @li #cmuClock_HF
* @li #cmuClock_LFA
* @li #cmuClock_LFB
* @li #cmuClock_USBC
* @li #cmuClock_DBG
*
* @return
* Reference clock used for clocking selected branch, #cmuSelect_Error if
* invalid @p clock provided.
*****************************************************************************/
CMU_Select_TypeDef CMU_ClockSelectGet(CMU_Clock_TypeDef clock)
{
CMU_Select_TypeDef ret = cmuSelect_Disabled;
uint32_t selReg;
selReg = (clock >> CMU_SEL_REG_POS) & CMU_SEL_REG_MASK;
switch (selReg)
{
case CMU_HFCLKSEL_REG:
switch (CMU->STATUS & (CMU_STATUS_HFRCOSEL | CMU_STATUS_HFXOSEL |
CMU_STATUS_LFRCOSEL | CMU_STATUS_LFXOSEL))
{
case CMU_STATUS_LFXOSEL:
ret = cmuSelect_LFXO;
break;
case CMU_STATUS_LFRCOSEL:
ret = cmuSelect_LFRCO;
break;
case CMU_STATUS_HFXOSEL:
ret = cmuSelect_HFXO;
break;
default:
ret = cmuSelect_HFRCO;
break;
}
break;
case CMU_LFACLKSEL_REG:
switch (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFA_MASK)
{
case CMU_LFCLKSEL_LFA_LFRCO:
ret = cmuSelect_LFRCO;
break;
case CMU_LFCLKSEL_LFA_LFXO:
ret = cmuSelect_LFXO;
break;
case CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2:
ret = cmuSelect_CORELEDIV2;
break;
default:
#if defined( CMU_LFCLKSEL_LFAE )
if (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFAE_MASK)
{
ret = cmuSelect_ULFRCO;
break;
}
#else
ret = cmuSelect_Disabled;
#endif
break;
}
break;
case CMU_LFBCLKSEL_REG:
switch (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFB_MASK)
{
case CMU_LFCLKSEL_LFB_LFRCO:
ret = cmuSelect_LFRCO;
break;
case CMU_LFCLKSEL_LFB_LFXO:
ret = cmuSelect_LFXO;
break;
case CMU_LFCLKSEL_LFB_HFCORECLKLEDIV2:
ret = cmuSelect_CORELEDIV2;
break;
default:
#if defined( CMU_LFCLKSEL_LFBE )
if (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFBE_MASK)
{
ret = cmuSelect_ULFRCO;
break;
}
#else
ret = cmuSelect_Disabled;
#endif
break;
}
break;
case CMU_DBGCLKSEL_REG:
#if defined( CMU_CTRL_DBGCLK )
switch(CMU->CTRL & _CMU_CTRL_DBGCLK_MASK)
{
case CMU_CTRL_DBGCLK_AUXHFRCO:
ret = cmuSelect_AUXHFRCO;
break;
case CMU_CTRL_DBGCLK_HFCLK:
ret = cmuSelect_HFCLK;
break;
}
#endif
#if defined(_EFM32_GECKO_FAMILY)
ret = cmuSelect_AUXHFRCO;
#endif
break;
#if defined(USB_PRESENT)
case CMU_USBCCLKSEL_REG:
switch(CMU->STATUS & (CMU_STATUS_USBCHFCLKSEL |
CMU_STATUS_USBCLFXOSEL |
CMU_STATUS_USBCLFRCOSEL))
{
case CMU_STATUS_USBCHFCLKSEL:
ret = cmuSelect_HFCLK;
break;
case CMU_STATUS_USBCLFXOSEL:
ret = cmuSelect_LFXO;
break;
case CMU_STATUS_USBCLFRCOSEL:
ret = cmuSelect_LFRCO;
break;
default:
ret = cmuSelect_Disabled;
break;
}
break;
#endif
default:
EFM_ASSERT(0);
ret = cmuSelect_Error;
break;
}
return ret;
}
/**************************************************************************//**
* @brief
* Select reference clock/oscillator used for a clock branch.
*
* @details
* Notice that if a selected reference is not enabled prior to selecting its
* use, it will be enabled, and this function will wait for the selected
* oscillator to be stable. It will however NOT be disabled if another
* reference clock is selected later.
*
* This feature is particularly important if selecting a new reference
* clock for the clock branch clocking the core, otherwise the system
* may halt.
*
* @param[in] clock
* Clock branch to select reference clock for. One of:
* @li #cmuClock_HF
* @li #cmuClock_LFA
* @li #cmuClock_LFB
* @li #cmuClock_USBC
* @li #cmuClock_DBG
*
* @param[in] ref
* Reference selected for clocking, please refer to reference manual for
* for details on which reference is available for a specific clock branch.
* @li #cmuSelect_HFRCO
* @li #cmuSelect_LFRCO
* @li #cmuSelect_HFXO
* @li #cmuSelect_LFXO
* @li #cmuSelect_CORELEDIV2
* @li #cmuSelect_AUXHFRC
* @li #cmuSelect_HFCLK
* @li #cmuSelect_ULFRCO
*****************************************************************************/
void CMU_ClockSelectSet(CMU_Clock_TypeDef clock, CMU_Select_TypeDef ref)
{
uint32_t select = cmuOsc_HFRCO;
CMU_Osc_TypeDef osc = cmuOsc_HFRCO;
uint32_t freq;
uint32_t selReg;
#if !defined(_EFM32_GECKO_FAMILY)
uint32_t lfExtended = 0;
#endif
uint32_t tmp;
selReg = (clock >> CMU_SEL_REG_POS) & CMU_SEL_REG_MASK;
switch (selReg)
{
case CMU_HFCLKSEL_REG:
switch (ref)
{
case cmuSelect_LFXO:
select = CMU_CMD_HFCLKSEL_LFXO;
osc = cmuOsc_LFXO;
break;
case cmuSelect_LFRCO:
select = CMU_CMD_HFCLKSEL_LFRCO;
osc = cmuOsc_LFRCO;
break;
case cmuSelect_HFXO:
select = CMU_CMD_HFCLKSEL_HFXO;
osc = cmuOsc_HFXO;
#if defined( CMU_CTRL_HFLE )
/* Adjust HFXO buffer current for high frequencies, enable HFLE for */
/* frequencies above 32MHz */
if(SystemHFXOClockGet() > CMU_MAX_FREQ_HFLE)
{
CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_HFXOBUFCUR_MASK) |
CMU_CTRL_HFXOBUFCUR_BOOSTABOVE32MHZ |
/* Must have HFLE enabled to access some LE peripherals >=32MHz */
CMU_CTRL_HFLE;
/* Set HFLE and DIV4 factor for peripheral clock if HFCORE clock for
LE is enabled. */
if (CMU->HFCORECLKEN0 & CMU_HFCORECLKEN0_LE)
{
BITBAND_Peripheral(&(CMU->HFCORECLKDIV),
_CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);
}
} else {
/* This can happen if the user configures the EFM32_HFXO_FREQ to */
/* use another oscillator frequency */
CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_HFXOBUFCUR_MASK) |
CMU_CTRL_HFXOBUFCUR_BOOSTUPTO32MHZ;
}
#endif
break;
case cmuSelect_HFRCO:
select = CMU_CMD_HFCLKSEL_HFRCO;
osc = cmuOsc_HFRCO;
break;
#if !defined(_EFM32_GECKO_FAMILY)
case cmuSelect_ULFRCO:
/* ULFRCO cannot be used as HFCLK */
EFM_ASSERT(0);
break;
#endif
default:
EFM_ASSERT(0);
return;
}
/* Ensure selected oscillator is enabled, waiting for it to stabilize */
CMU_OscillatorEnable(osc, true, true);
/* Configure worst case wait states for flash access before selecting */
CMU_FlashWaitStateMax();
/* Switch to selected oscillator */
CMU->CMD = select;
/* Keep EMU module informed */
EMU_UpdateOscConfig();
/* Update CMSIS core clock variable */
/* (The function will update the global variable) */
freq = SystemCoreClockGet();
/* Optimize flash access wait state setting for currently selected core clk */
CMU_FlashWaitStateControl(freq);
break;
case CMU_LFACLKSEL_REG:
case CMU_LFBCLKSEL_REG:
switch (ref)
{
case cmuSelect_Disabled:
tmp = _CMU_LFCLKSEL_LFA_DISABLED;
break;
case cmuSelect_LFXO:
/* Ensure selected oscillator is enabled, waiting for it to stabilize */
CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
tmp = _CMU_LFCLKSEL_LFA_LFXO;
break;
case cmuSelect_LFRCO:
/* Ensure selected oscillator is enabled, waiting for it to stabilize */
CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);
tmp = _CMU_LFCLKSEL_LFA_LFRCO;
break;
case cmuSelect_CORELEDIV2:
/* Ensure HFCORE to LE clocking is enabled */
BITBAND_Peripheral(&(CMU->HFCORECLKEN0), _CMU_HFCORECLKEN0_LE_SHIFT, 1);
tmp = _CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2;
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
/* If core frequency is > 32MHz on Giant/Leopard, enable HFLE and DIV4 */
freq = SystemCoreClockGet();
if(freq > CMU_MAX_FREQ_HFLE)
{
/* Enable CMU HFLE */
BITBAND_Peripheral(&(CMU->CTRL), _CMU_CTRL_HFLE_SHIFT, 1);
/* Enable DIV4 factor for peripheral clock */
BITBAND_Peripheral(&(CMU->HFCORECLKDIV),
_CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);
}
#endif
break;
#if !defined(_EFM32_GECKO_FAMILY)
case cmuSelect_ULFRCO:
/* ULFRCO is always enabled */
tmp = _CMU_LFCLKSEL_LFA_DISABLED;
lfExtended = 1;
break;
#endif
default:
/* Illegal clock source for LFA/LFB selected */
EFM_ASSERT(0);
return;
}
if (selReg == CMU_LFACLKSEL_REG)
{
#if !defined(_EFM32_GECKO_FAMILY)
CMU->LFCLKSEL = (CMU->LFCLKSEL & ~(_CMU_LFCLKSEL_LFA_MASK | _CMU_LFCLKSEL_LFAE_MASK) ) |
(tmp << _CMU_LFCLKSEL_LFA_SHIFT) | (lfExtended << _CMU_LFCLKSEL_LFAE_SHIFT);
#else
CMU->LFCLKSEL = (CMU->LFCLKSEL & ~_CMU_LFCLKSEL_LFA_MASK) |
(tmp << _CMU_LFCLKSEL_LFA_SHIFT);
#endif
}
else
{
#if !defined(_EFM32_GECKO_FAMILY)
CMU->LFCLKSEL = (CMU->LFCLKSEL & ~(_CMU_LFCLKSEL_LFB_MASK | _CMU_LFCLKSEL_LFBE_MASK) ) |
(tmp << _CMU_LFCLKSEL_LFB_SHIFT) | (lfExtended << _CMU_LFCLKSEL_LFBE_SHIFT);
#else
CMU->LFCLKSEL = (CMU->LFCLKSEL & ~_CMU_LFCLKSEL_LFB_MASK) |
(tmp << _CMU_LFCLKSEL_LFB_SHIFT);
#endif
}
break;
#if defined( CMU_CTRL_DBGCLK )
case CMU_DBGCLKSEL_REG:
switch(ref)
{
case cmuSelect_AUXHFRCO:
/* Select AUXHFRCO as debug clock */
CMU->CTRL = (CMU->CTRL & ~(_CMU_CTRL_DBGCLK_MASK))| CMU_CTRL_DBGCLK_AUXHFRCO;
break;
case cmuSelect_HFCLK:
/* Select divided HFCLK as debug clock */
CMU->CTRL = (CMU->CTRL & ~(_CMU_CTRL_DBGCLK_MASK))| CMU_CTRL_DBGCLK_HFCLK;
break;
default:
/* Illegal clock source for debug selected */
EFM_ASSERT(0);
return;
}
break;
#endif
#if defined(USB_PRESENT)
case CMU_USBCCLKSEL_REG:
switch(ref)
{
case cmuSelect_HFCLK:
/* Select undivided HFCLK as clock source for USB */
/* Oscillator must already be enabled, if not the core had stopped */
CMU->CMD = CMU_CMD_USBCCLKSEL_HFCLKNODIV;
/* Wait until clock is activated */
while((CMU->STATUS & CMU_STATUS_USBCHFCLKSEL)==0);
break;
case cmuSelect_LFXO:
/* Select LFXO as clock source for USB, can only be used in sleep mode */
/* Ensure selected oscillator is enabled, waiting for it to stabilize */
CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
/* Switch oscillator */
CMU->CMD = CMU_CMD_USBCCLKSEL_LFXO;
/* Wait until clock is activated */
while((CMU->STATUS & CMU_STATUS_USBCLFXOSEL)==0);
break;
case cmuSelect_LFRCO:
/* Select LFRCO as clock source for USB, can only be used in sleep mode */
/* Ensure selected oscillator is enabled, waiting for it to stabilize */
CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);
/* Switch oscillator */
CMU->CMD = CMU_CMD_USBCCLKSEL_LFRCO;
/* Wait until clock is activated */
while((CMU->STATUS & CMU_STATUS_USBCLFRCOSEL)==0);
break;
default:
/* Illegal clock source for USB */
EFM_ASSERT(0);
return;
}
/* Wait until clock has been activated */
break;
#endif
default:
EFM_ASSERT(0);
break;
}
}
/**************************************************************************//**
* @brief
* CMU low frequency register synchronization freeze control.
*
* @details
* Some CMU registers requires synchronization into the low frequency (LF)
* domain. The freeze feature allows for several such registers to be
* modified before passing them to the LF domain simultaneously (which
* takes place when the freeze mode is disabled).
*
* Another usage scenario of this feature, is when using an API (such
* as the CMU API) for modifying several bit fields consecutively in the
* same register. If freeze mode is enabled during this sequence, stalling
* can be avoided.
*
* @note
* When enabling freeze mode, this function will wait for all current
* ongoing CMU synchronization to LF domain to complete (Normally
* synchronization will not be in progress.) However for this reason, when
* using freeze mode, modifications of registers requiring LF synchronization
* should be done within one freeze enable/disable block to avoid unecessary
* stalling.
*
* @param[in] enable
* @li true - enable freeze, modified registers are not propagated to the
* LF domain
* @li false - disable freeze, modified registers are propagated to LF
* domain
*****************************************************************************/
void CMU_FreezeEnable(bool enable)
{
if (enable)
{
/* Wait for any ongoing LF synchronization to complete. This is just to */
/* protect against the rare case when a user */
/* - modifies a register requiring LF sync */
/* - then enables freeze before LF sync completed */
/* - then modifies the same register again */
/* since modifying a register while it is in sync progress should be */
/* avoided. */
while (CMU->SYNCBUSY)
;
CMU->FREEZE = CMU_FREEZE_REGFREEZE;
}
else
{
CMU->FREEZE = 0;
}
}
#if defined( _CMU_AUXHFRCOCTRL_BAND_MASK )
/***************************************************************************//**
* @brief
* Get AUXHFRCO band in use.
*
* @return
* AUXHFRCO band in use.
******************************************************************************/
CMU_AUXHFRCOBand_TypeDef CMU_AUXHFRCOBandGet(void)
{
return (CMU_AUXHFRCOBand_TypeDef)((CMU->AUXHFRCOCTRL & _CMU_AUXHFRCOCTRL_BAND_MASK) >>
_CMU_AUXHFRCOCTRL_BAND_SHIFT);
}
/***************************************************************************//**
* @brief
* Set AUIXHFRCO band and the tuning value based on the value in the
* calibration table made during production.
*
* @param[in] band
* AUXHFRCO band to activate.
******************************************************************************/
void CMU_AUXHFRCOBandSet(CMU_AUXHFRCOBand_TypeDef band)
{
uint32_t tuning;
/* Read tuning value from calibration table */
switch (band)
{
case cmuAUXHFRCOBand_1MHz:
tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND1_MASK) >>
_DEVINFO_AUXHFRCOCAL0_BAND1_SHIFT;
break;
case cmuAUXHFRCOBand_7MHz:
tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND7_MASK) >>
_DEVINFO_AUXHFRCOCAL0_BAND7_SHIFT;
break;
case cmuAUXHFRCOBand_11MHz:
tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND11_MASK) >>
_DEVINFO_AUXHFRCOCAL0_BAND11_SHIFT;
break;
case cmuAUXHFRCOBand_14MHz:
tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND14_MASK) >>
_DEVINFO_AUXHFRCOCAL0_BAND14_SHIFT;
break;
case cmuAUXHFRCOBand_21MHz:
tuning = (DEVINFO->AUXHFRCOCAL1 & _DEVINFO_AUXHFRCOCAL1_BAND21_MASK) >>
_DEVINFO_AUXHFRCOCAL1_BAND21_SHIFT;
break;
#if defined( _CMU_AUXHFRCOCTRL_BAND_28MHZ )
case cmuAUXHFRCOBand_28MHz:
tuning = (DEVINFO->AUXHFRCOCAL1 & _DEVINFO_AUXHFRCOCAL1_BAND28_MASK) >>
_DEVINFO_AUXHFRCOCAL1_BAND28_SHIFT;
break;
#endif
default:
EFM_ASSERT(0);
return;
}
/* Set band/tuning */
CMU->AUXHFRCOCTRL = (CMU->AUXHFRCOCTRL &
~(_CMU_AUXHFRCOCTRL_BAND_MASK | _CMU_AUXHFRCOCTRL_TUNING_MASK)) |
(band << _CMU_AUXHFRCOCTRL_BAND_SHIFT) |
(tuning << _CMU_AUXHFRCOCTRL_TUNING_SHIFT);
}
#endif
/***************************************************************************//**
* @brief
* Get HFRCO band in use.
*
* @return
* HFRCO band in use.
******************************************************************************/
CMU_HFRCOBand_TypeDef CMU_HFRCOBandGet(void)
{
return (CMU_HFRCOBand_TypeDef)((CMU->HFRCOCTRL & _CMU_HFRCOCTRL_BAND_MASK) >>
_CMU_HFRCOCTRL_BAND_SHIFT);
}
/***************************************************************************//**
* @brief
* Set HFRCO band and the tuning value based on the value in the calibration
* table made during production.
*
* @param[in] band
* HFRCO band to activate.
******************************************************************************/
void CMU_HFRCOBandSet(CMU_HFRCOBand_TypeDef band)
{
uint32_t tuning;
uint32_t freq;
CMU_Select_TypeDef osc;
/* Read tuning value from calibration table */
switch (band)
{
case cmuHFRCOBand_1MHz:
tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND1_MASK) >>
_DEVINFO_HFRCOCAL0_BAND1_SHIFT;
break;
case cmuHFRCOBand_7MHz:
tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND7_MASK) >>
_DEVINFO_HFRCOCAL0_BAND7_SHIFT;
break;
case cmuHFRCOBand_11MHz:
tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND11_MASK) >>
_DEVINFO_HFRCOCAL0_BAND11_SHIFT;
break;
case cmuHFRCOBand_14MHz:
tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND14_MASK) >>
_DEVINFO_HFRCOCAL0_BAND14_SHIFT;
break;
case cmuHFRCOBand_21MHz:
tuning = (DEVINFO->HFRCOCAL1 & _DEVINFO_HFRCOCAL1_BAND21_MASK) >>
_DEVINFO_HFRCOCAL1_BAND21_SHIFT;
break;
#if defined( _CMU_HFRCOCTRL_BAND_28MHZ )
case cmuHFRCOBand_28MHz:
tuning = (DEVINFO->HFRCOCAL1 & _DEVINFO_HFRCOCAL1_BAND28_MASK) >>
_DEVINFO_HFRCOCAL1_BAND28_SHIFT;
break;
#endif
default:
EFM_ASSERT(0);
return;
}
/* If HFRCO is used for core clock, we have to consider flash access WS. */
osc = CMU_ClockSelectGet(cmuClock_HF);
if (osc == cmuSelect_HFRCO)
{
/* Configure worst case wait states for flash access before setting divider */
CMU_FlashWaitStateMax();
}
/* Set band/tuning */
CMU->HFRCOCTRL = (CMU->HFRCOCTRL &
~(_CMU_HFRCOCTRL_BAND_MASK | _CMU_HFRCOCTRL_TUNING_MASK)) |
(band << _CMU_HFRCOCTRL_BAND_SHIFT) |
(tuning << _CMU_HFRCOCTRL_TUNING_SHIFT);
/* If HFRCO is used for core clock, optimize flash WS */
if (osc == cmuSelect_HFRCO)
{
/* Update CMSIS core clock variable and get current core clock */
/* (The function will update the global variable) */
/* NOTE! We need at least 21 cycles before setting zero wait state to flash */
/* (i.e. WS0) when going from the 28MHz to 1MHz in the HFRCO band */
freq = SystemCoreClockGet();
/* Optimize flash access wait state setting for current core clk */
CMU_FlashWaitStateControl(freq);
}
}
/***************************************************************************//**
* @brief
* Get the HFRCO startup delay.
*
* @details
* Please refer to the reference manual for further details.
*
* @return
* The startup delay in use.
******************************************************************************/
uint32_t CMU_HFRCOStartupDelayGet(void)
{
return((CMU->HFRCOCTRL & _CMU_HFRCOCTRL_SUDELAY_MASK) >>
_CMU_HFRCOCTRL_SUDELAY_SHIFT);
}
/***************************************************************************//**
* @brief
* Set the HFRCO startup delay.
*
* @details
* Please refer to the reference manual for further details.
*
* @param[in] delay
* The startup delay to set (<= 31).
******************************************************************************/
void CMU_HFRCOStartupDelaySet(uint32_t delay)
{
EFM_ASSERT(delay <= 31);
delay &= (_CMU_HFRCOCTRL_SUDELAY_MASK >> _CMU_HFRCOCTRL_SUDELAY_SHIFT);
CMU->HFRCOCTRL = (CMU->HFRCOCTRL & ~(_CMU_HFRCOCTRL_SUDELAY_MASK)) |
(delay << _CMU_HFRCOCTRL_SUDELAY_SHIFT);
}
/***************************************************************************//**
* @brief
* Get the LCD framerate divisor (FDIV) setting.
*
* @return
* The LCD framerate divisor.
******************************************************************************/
uint32_t CMU_LCDClkFDIVGet(void)
{
#if defined(LCD_PRESENT)
return((CMU->LCDCTRL & _CMU_LCDCTRL_FDIV_MASK) >> _CMU_LCDCTRL_FDIV_SHIFT);
#else
return 0;
#endif /* defined(LCD_PRESENT) */
}
/***************************************************************************//**
* @brief
* Set the LCD framerate divisor (FDIV) setting.
*
* @note
* The FDIV field (CMU LCDCTRL register) should only be modified while the
* LCD module is clock disabled (CMU LFACLKEN0.LCD bit is 0). This function
* will NOT modify FDIV if the LCD module clock is enabled. Please refer to
* CMU_ClockEnable() for disabling/enabling LCD clock.
*
* @param[in] div
* The FDIV setting to use.
******************************************************************************/
void CMU_LCDClkFDIVSet(uint32_t div)
{
#if defined(LCD_PRESENT)
EFM_ASSERT(div <= cmuClkDiv_128);
/* Do not allow modification if LCD clock enabled */
if (CMU->LFACLKEN0 & CMU_LFACLKEN0_LCD)
{
return;
}
div <<= _CMU_LCDCTRL_FDIV_SHIFT;
div &= _CMU_LCDCTRL_FDIV_MASK;
CMU->LCDCTRL = (CMU->LCDCTRL & ~_CMU_LCDCTRL_FDIV_MASK) | div;
#else
(void)div; /* Unused parameter */
#endif /* defined(LCD_PRESENT) */
}
/***************************************************************************//**
* @brief
* Enable/disable oscillator.
*
* @note
* WARNING: When this function is called to disable either cmuOsc_LFXO or
* cmuOsc_HFXO the LFXOMODE or HFXOMODE fields of the CMU_CTRL register
* are reset to the reset value. I.e. if external clock sources are selected
* in either LFXOMODE or HFXOMODE fields, the configuration will be cleared
* and needs to be reconfigured if needed later.
*
* @param[in] osc
* The oscillator to enable/disable.
*
* @param[in] enable
* @li true - enable specified oscillator.
* @li false - disable specified oscillator.
*
* @param[in] wait
* Only used if @p enable is true.
* @li true - wait for oscillator start-up time to timeout before returning.
* @li false - do not wait for oscillator start-up time to timeout before
* returning.
******************************************************************************/
void CMU_OscillatorEnable(CMU_Osc_TypeDef osc, bool enable, bool wait)
{
uint32_t status;
uint32_t enBit;
uint32_t disBit;
switch (osc)
{
case cmuOsc_HFRCO:
enBit = CMU_OSCENCMD_HFRCOEN;
disBit = CMU_OSCENCMD_HFRCODIS;
status = CMU_STATUS_HFRCORDY;
break;
case cmuOsc_HFXO:
enBit = CMU_OSCENCMD_HFXOEN;
disBit = CMU_OSCENCMD_HFXODIS;
status = CMU_STATUS_HFXORDY;
break;
case cmuOsc_AUXHFRCO:
enBit = CMU_OSCENCMD_AUXHFRCOEN;
disBit = CMU_OSCENCMD_AUXHFRCODIS;
status = CMU_STATUS_AUXHFRCORDY;
break;
case cmuOsc_LFRCO:
enBit = CMU_OSCENCMD_LFRCOEN;
disBit = CMU_OSCENCMD_LFRCODIS;
status = CMU_STATUS_LFRCORDY;
break;
case cmuOsc_LFXO:
enBit = CMU_OSCENCMD_LFXOEN;
disBit = CMU_OSCENCMD_LFXODIS;
status = CMU_STATUS_LFXORDY;
break;
#if defined _CMU_LFCLKSEL_LFAE_ULFRCO
case cmuOsc_ULFRCO:
/* ULFRCO is always enabled, and cannot be turned off */
return;
#endif
default:
/* Undefined clock source */
EFM_ASSERT(0);
return;
}
if (enable)
{
CMU->OSCENCMD = enBit;
/* Wait for clock to stabilize if requested */
if (wait)
{
while (!(CMU->STATUS & status))
;
}
}
else
{
CMU->OSCENCMD = disBit;
}
/* Keep EMU module informed */
EMU_UpdateOscConfig();
}
/***************************************************************************//**
* @brief
* Get oscillator frequency tuning setting.
*
* @param[in] osc
* Oscillator to get tuning value for, one of:
* @li #cmuOsc_LFRCO
* @li #cmuOsc_HFRCO
* @li #cmuOsc_AUXHFRCO
*
* @return
* The oscillator frequency tuning setting in use.
******************************************************************************/
uint32_t CMU_OscillatorTuningGet(CMU_Osc_TypeDef osc)
{
uint32_t ret;
switch (osc)
{
case cmuOsc_LFRCO:
ret = (CMU->LFRCOCTRL & _CMU_LFRCOCTRL_TUNING_MASK) >>
_CMU_LFRCOCTRL_TUNING_SHIFT;
break;
case cmuOsc_HFRCO:
ret = (CMU->HFRCOCTRL & _CMU_HFRCOCTRL_TUNING_MASK) >>
_CMU_HFRCOCTRL_TUNING_SHIFT;
break;
case cmuOsc_AUXHFRCO:
ret = (CMU->AUXHFRCOCTRL & _CMU_AUXHFRCOCTRL_TUNING_MASK) >>
_CMU_AUXHFRCOCTRL_TUNING_SHIFT;
break;
default:
EFM_ASSERT(0);
ret = 0;
break;
}
return(ret);
}
/***************************************************************************//**
* @brief
* Set the oscillator frequency tuning control.
*
* @note
* Oscillator tuning is done during production, and the tuning value is
* automatically loaded after a reset. Changing the tuning value from the
* calibrated value is for more advanced use.
*
* @param[in] osc
* Oscillator to set tuning value for, one of:
* @li #cmuOsc_LFRCO
* @li #cmuOsc_HFRCO
* @li #cmuOsc_AUXHFRCO
*
* @param[in] val
* The oscillator frequency tuning setting to use.
******************************************************************************/
void CMU_OscillatorTuningSet(CMU_Osc_TypeDef osc, uint32_t val)
{
switch (osc)
{
case cmuOsc_LFRCO:
EFM_ASSERT(val <= (_CMU_LFRCOCTRL_TUNING_MASK >> _CMU_LFRCOCTRL_TUNING_SHIFT));
val &= (_CMU_LFRCOCTRL_TUNING_MASK >> _CMU_LFRCOCTRL_TUNING_SHIFT);
CMU->LFRCOCTRL = (CMU->LFRCOCTRL & ~(_CMU_LFRCOCTRL_TUNING_MASK)) |
(val << _CMU_LFRCOCTRL_TUNING_SHIFT);
break;
case cmuOsc_HFRCO:
EFM_ASSERT(val <= (_CMU_HFRCOCTRL_TUNING_MASK >> _CMU_HFRCOCTRL_TUNING_SHIFT));
val &= (_CMU_HFRCOCTRL_TUNING_MASK >> _CMU_HFRCOCTRL_TUNING_SHIFT);
CMU->HFRCOCTRL = (CMU->HFRCOCTRL & ~(_CMU_HFRCOCTRL_TUNING_MASK)) |
(val << _CMU_HFRCOCTRL_TUNING_SHIFT);
break;
case cmuOsc_AUXHFRCO:
EFM_ASSERT(val <= (_CMU_AUXHFRCOCTRL_TUNING_MASK >> _CMU_AUXHFRCOCTRL_TUNING_SHIFT));
val <<= _CMU_AUXHFRCOCTRL_TUNING_SHIFT;
val &= _CMU_AUXHFRCOCTRL_TUNING_MASK;
CMU->AUXHFRCOCTRL = (CMU->AUXHFRCOCTRL & ~(_CMU_AUXHFRCOCTRL_TUNING_MASK)) | val;
break;
default:
EFM_ASSERT(0);
break;
}
}
/**************************************************************************//**
* @brief
* Determine if currently selected PCNTn clock used is external or LFBCLK.
*
* @param[in] inst
* PCNT instance number to get currently selected clock source for.
*
* @return
* @li true - selected clock is external clock.
* @li false - selected clock is LFBCLK.
*****************************************************************************/
bool CMU_PCNTClockExternalGet(unsigned int inst)
{
bool ret;
uint32_t setting;
switch (inst)
{
#if defined(_CMU_PCNTCTRL_PCNT0CLKEN_MASK)
case 0:
setting = CMU->PCNTCTRL & CMU_PCNTCTRL_PCNT0CLKSEL_PCNT0S0;
break;
#if defined(_CMU_PCNTCTRL_PCNT1CLKEN_MASK)
case 1:
setting = CMU->PCNTCTRL & CMU_PCNTCTRL_PCNT1CLKSEL_PCNT1S0;
break;
#if defined(_CMU_PCNTCTRL_PCNT2CLKEN_MASK)
case 2:
setting = CMU->PCNTCTRL & CMU_PCNTCTRL_PCNT2CLKSEL_PCNT2S0;
break;
#endif
#endif
#endif
default:
setting = 0;
break;
}
if (setting)
{
ret = true;
}
else
{
ret = false;
}
return ret;
}
/**************************************************************************//**
* @brief
* Select PCNTn clock.
*
* @param[in] inst
* PCNT instance number to set selected clock source for.
*
* @param[in] external
* Set to true to select external clock, false to select LFBCLK.
*****************************************************************************/
void CMU_PCNTClockExternalSet(unsigned int inst, bool external)
{
#if defined(PCNT_PRESENT)
uint32_t setting = 0;
EFM_ASSERT(inst < PCNT_COUNT);
if (external)
{
setting = 1;
}
BITBAND_Peripheral(&(CMU->PCNTCTRL), (inst * 2) + 1, setting);
#else
(void)inst; /* Unused parameter */
(void)external; /* Unused parameter */
#endif
}
/** @} (end addtogroup CMU) */
/** @} (end addtogroup EM_Library) */
#endif /* __EM_CMU_H */
/***************************************************************************//**
* @file
* @brief Energy Management Unit (EMU) Peripheral API
* @author Energy Micro AS
* @version 3.20.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_emu.h"
#if defined( EMU_PRESENT )
#include "em_cmu.h"
#include "em_assert.h"
/***************************************************************************//**
* @addtogroup EM_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup EMU
* @brief Energy Management Unit (EMU) Peripheral API
* @{
******************************************************************************/
/* Consistency check, since restoring assumes similar bitpositions in */
/* CMU OSCENCMD and STATUS regs */
#if (CMU_STATUS_AUXHFRCOENS != CMU_OSCENCMD_AUXHFRCOEN)
#error Conflict in AUXHFRCOENS and AUXHFRCOEN bitpositions
#endif
#if (CMU_STATUS_HFXOENS != CMU_OSCENCMD_HFXOEN)
#error Conflict in HFXOENS and HFXOEN bitpositions
#endif
#if (CMU_STATUS_LFRCOENS != CMU_OSCENCMD_LFRCOEN)
#error Conflict in LFRCOENS and LFRCOEN bitpositions
#endif
#if (CMU_STATUS_LFXOENS != CMU_OSCENCMD_LFXOEN)
#error Conflict in LFXOENS and LFXOEN bitpositions
#endif
/*******************************************************************************
************************** LOCAL VARIABLES ********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/**
* CMU configured oscillator selection and oscillator enable status. When a
* user configures oscillators, this varaiable shall shadow the configuration.
* It is used by the EMU module in order to be able to restore the oscillator
* config after having been in certain energy modes (since HW may automatically
* alter config when going into an energy mode). It is the responsibility of
* the CMU module to keep it up-to-date (or a user if not using the CMU API
* for oscillator control).
*/
static uint16_t cmuStatus;
/** @endcond */
/*******************************************************************************
************************** LOCAL FUNCTIONS ********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/***************************************************************************//**
* @brief
* Restore oscillators and core clock after having been in EM2 or EM3.
******************************************************************************/
static void EMU_Restore(void)
{
uint32_t cmuLocked;
/* Although we could use the CMU API for most of the below handling, we */
/* would like this function to be as efficient as possible. */
/* CMU registers may be locked */
cmuLocked = CMU->LOCK & CMU_LOCK_LOCKKEY_LOCKED;
CMU_Unlock();
/* AUXHFRCO was automatically disabled (except if using debugger). */
/* HFXO was automatically disabled. */
/* LFRCO/LFXO were possibly disabled by SW in EM3. */
/* Restore according to status prior to entering EM. */
CMU->OSCENCMD = cmuStatus & (CMU_STATUS_AUXHFRCOENS |
CMU_STATUS_HFXOENS |
CMU_STATUS_LFRCOENS |
CMU_STATUS_LFXOENS);
/* Restore oscillator used for clocking core */
switch (cmuStatus & (CMU_STATUS_HFXOSEL | CMU_STATUS_HFRCOSEL |
CMU_STATUS_LFXOSEL | CMU_STATUS_LFRCOSEL))
{
case CMU_STATUS_LFRCOSEL:
/* Wait for LFRCO to stabilize */
while (!(CMU->STATUS & CMU_STATUS_LFRCORDY))
;
CMU->CMD = CMU_CMD_HFCLKSEL_LFRCO;
break;
case CMU_STATUS_LFXOSEL:
/* Wait for LFXO to stabilize */
while (!(CMU->STATUS & CMU_STATUS_LFXORDY))
;
CMU->CMD = CMU_CMD_HFCLKSEL_LFXO;
break;
case CMU_STATUS_HFXOSEL:
/* Wait for HFXO to stabilize */
while (!(CMU->STATUS & CMU_STATUS_HFXORDY))
;
CMU->CMD = CMU_CMD_HFCLKSEL_HFXO;
break;
default: /* CMU_STATUS_HFRCOSEL */
/* If core clock was HFRCO core clock, it is automatically restored to */
/* state prior to entering energy mode. No need for further action. */
break;
}
/* If HFRCO was disabled before entering Energy Mode, turn it off again */
/* as it is automatically enabled by wake up */
if ( ! (cmuStatus & CMU_STATUS_HFRCOENS) )
{
CMU->OSCENCMD = CMU_OSCENCMD_HFRCODIS;
}
/* Restore CMU register locking */
if (cmuLocked)
{
CMU_Lock();
}
}
/** @endcond */
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Enter energy mode 2 (EM2).
*
* @details
* When entering EM2, the high frequency clocks are disabled, ie HFXO, HFRCO
* and AUXHFRCO (for AUXHFRCO, see exception note below). When re-entering
* EM0, HFRCO is re-enabled and the core will be clocked by the configured
* HFRCO band. This ensures a quick wakeup from EM2.
*
* However, prior to entering EM2, the core may have been using another
* oscillator than HFRCO. The @p restore parameter gives the user the option
* to restore all HF oscillators according to state prior to entering EM2,
* as well as the clock used to clock the core. This restore procedure is
* handled by SW. However, since handled by SW, it will not be restored
* before completing the interrupt function(s) waking up the core!
*
* @note
* If restoring core clock to use the HFXO oscillator, which has been
* disabled during EM2 mode, this function will stall until the oscillator
* has stabilized. Stalling time can be reduced by adding interrupt
* support detecting stable oscillator, and an asynchronous switch to the
* original oscillator. See CMU documentation. Such a feature is however
* outside the scope of the implementation in this function.
* @par
* If HFXO is re-enabled by this function, and NOT used to clock the core,
* this function will not wait for HFXO to stabilize. This must be considered
* by the application if trying to use features relying on that oscillator
* upon return.
* @par
* If a debugger is attached, the AUXHFRCO will not be disabled if enabled
* upon entering EM2. It will thus remain enabled when returning to EM0
* regardless of the @p restore parameter.
*
* @param[in] restore
* @li true - restore oscillators and clocks, see function details.
* @li false - do not restore oscillators and clocks, see function details.
* @par
* The @p restore option should only be used if all clock control is done
* via the CMU API.
******************************************************************************/
void EMU_EnterEM2(bool restore)
{
/* Auto-update CMU status just in case before entering energy mode. */
/* This variable is normally kept up-to-date by the CMU API. */
cmuStatus = (uint16_t)(CMU->STATUS);
/* Enter Cortex-M3 deep sleep mode */
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
__WFI();
/* Restore oscillators/clocks if specified */
if (restore)
{
EMU_Restore();
}
/* If not restoring, and original clock was not HFRCO, we have to */
/* update CMSIS core clock variable since core clock has changed */
/* to using HFRCO. */
else if (!(cmuStatus & CMU_STATUS_HFRCOSEL))
{
SystemCoreClockUpdate();
}
}
/***************************************************************************//**
* @brief
* Enter energy mode 3 (EM3).
*
* @details
* When entering EM3, the high frequency clocks are disabled by HW, ie HFXO,
* HFRCO and AUXHFRCO (for AUXHFRCO, see exception note below). In addition,
* the low frequency clocks, ie LFXO and LFRCO are disabled by SW. When
* re-entering EM0, HFRCO is re-enabled and the core will be clocked by the
* configured HFRCO band. This ensures a quick wakeup from EM3.
*
* However, prior to entering EM3, the core may have been using another
* oscillator than HFRCO. The @p restore parameter gives the user the option
* to restore all HF/LF oscillators according to state prior to entering EM3,
* as well as the clock used to clock the core. This restore procedure is
* handled by SW. However, since handled by SW, it will not be restored
* before completing the interrupt function(s) waking up the core!
*
* @note
* If restoring core clock to use an oscillator other than HFRCO, this
* function will stall until the oscillator has stabilized. Stalling time
* can be reduced by adding interrupt support detecting stable oscillator,
* and an asynchronous switch to the original oscillator. See CMU
* documentation. Such a feature is however outside the scope of the
* implementation in this function.
* @par
* If HFXO/LFXO/LFRCO are re-enabled by this function, and NOT used to clock
* the core, this function will not wait for those oscillators to stabilize.
* This must be considered by the application if trying to use features
* relying on those oscillators upon return.
* @par
* If a debugger is attached, the AUXHFRCO will not be disabled if enabled
* upon entering EM3. It will thus remain enabled when returning to EM0
* regardless of the @p restore parameter.
*
* @param[in] restore
* @li true - restore oscillators and clocks, see function details.
* @li false - do not restore oscillators and clocks, see function details.
* @par
* The @p restore option should only be used if all clock control is done
* via the CMU API.
******************************************************************************/
void EMU_EnterEM3(bool restore)
{
uint32_t cmuLocked;
/* Auto-update CMU status just in case before entering energy mode. */
/* This variable is normally kept up-to-date by the CMU API. */
cmuStatus = (uint16_t)(CMU->STATUS);
/* CMU registers may be locked */
cmuLocked = CMU->LOCK & CMU_LOCK_LOCKKEY_LOCKED;
CMU_Unlock();
/* Disable LF oscillators */
CMU->OSCENCMD = CMU_OSCENCMD_LFXODIS | CMU_OSCENCMD_LFRCODIS;
/* Restore CMU register locking */
if (cmuLocked)
{
CMU_Lock();
}
/* Enter Cortex-M3 deep sleep mode */
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
__WFI();
/* Restore oscillators/clocks if specified */
if (restore)
{
EMU_Restore();
}
/* If not restoring, and original clock was not HFRCO, we have to */
/* update CMSIS core clock variable since core clock has changed */
/* to using HFRCO. */
else if (!(cmuStatus & CMU_STATUS_HFRCOSEL))
{
SystemCoreClockUpdate();
}
}
/***************************************************************************//**
* @brief
* Enter energy mode 4 (EM4).
*
* @note
* Only a power on reset or external reset pin can wake the device from EM4.
******************************************************************************/
void EMU_EnterEM4(void)
{
int i;
/* Make sure register write lock is disabled */
EMU->LOCK = EMU_LOCK_LOCKKEY_UNLOCK;
for (i = 0; i < 4; i++)
{
EMU->CTRL = (2 << _EMU_CTRL_EM4CTRL_SHIFT);
EMU->CTRL = (3 << _EMU_CTRL_EM4CTRL_SHIFT);
}
EMU->CTRL = (2 << _EMU_CTRL_EM4CTRL_SHIFT);
}
/***************************************************************************//**
* @brief
* Power down memory block.
*
* @param[in] blocks
* Specifies a logical OR of bits indicating memory blocks to power down.
* Bit 0 selects block 1, bit 1 selects block 2, etc. Memory block 0 cannot
* be disabled. Please refer to the EFM32 reference manual for available
* memory blocks for a device.
*
* @note
* Only a reset can make the specified memory block(s) available for use
* after having been powered down. Function will be void for devices not
* supporting this feature.
******************************************************************************/
void EMU_MemPwrDown(uint32_t blocks)
{
#if defined(_EMU_MEMCTRL_RESETVALUE)
EFM_ASSERT(blocks <= _EMU_MEMCTRL_MASK);
EMU->MEMCTRL = blocks;
#else
(void)blocks;
#endif
}
/***************************************************************************//**
* @brief
* Update EMU module with CMU oscillator selection/enable status.
*
* @details
* When entering EM2 and EM3, the HW may change the core clock oscillator
* used, as well as disabling some oscillators. The user may optionally select
* to restore the oscillators after waking up from EM2 and EM3 through the
* SW API.
*
* However, in order to support this in a safe way, the EMU module must
* be kept up-to-date on the actual selected configuration. The CMU
* module must keep the EMU module up-to-date.
*
* This function is mainly intended for internal use by the CMU module,
* but if the applications changes oscillator configurations without
* using the CMU API, this function can be used to keep the EMU module
* up-to-date.
******************************************************************************/
void EMU_UpdateOscConfig(void)
{
/* Fetch current configuration */
cmuStatus = (uint16_t)(CMU->STATUS);
}
#if defined( _EMU_EM4CONF_MASK )
/***************************************************************************//**
* @brief
* Update EMU module with Energy Mode 4 configuration
*
* @param[in] em4init
* Energy Mode 4 configuration structure
******************************************************************************/
void EMU_EM4Init(EMU_EM4Init_TypeDef *em4init)
{
uint32_t em4conf = EMU->EM4CONF;
/* Clear fields that will be reconfigured */
em4conf &= ~(
_EMU_EM4CONF_LOCKCONF_MASK|
_EMU_EM4CONF_OSC_MASK|
_EMU_EM4CONF_BURTCWU_MASK|
_EMU_EM4CONF_VREGEN_MASK);
/* Configure new settings */
em4conf |= (
(em4init->lockConfig << _EMU_EM4CONF_LOCKCONF_SHIFT)|
(em4init->osc)|
(em4init->buRtcWakeup << _EMU_EM4CONF_BURTCWU_SHIFT)|
(em4init->vreg << _EMU_EM4CONF_VREGEN_SHIFT));
/* Apply configuration. Note that lock can be set after this stage. */
EMU->EM4CONF = em4conf;
}
/***************************************************************************//**
* @brief
* Configure Backup Power Domain settings
*
* @param[in] bupdInit
* Backup power domain initialization structure
******************************************************************************/
void EMU_BUPDInit(EMU_BUPDInit_TypeDef *bupdInit)
{
uint32_t reg;
/* Set power connection configuration */
reg = EMU->PWRCONF & ~(
_EMU_PWRCONF_PWRRES_MASK|
_EMU_PWRCONF_VOUTSTRONG_MASK|
_EMU_PWRCONF_VOUTMED_MASK|
_EMU_PWRCONF_VOUTWEAK_MASK);
reg |= (bupdInit->resistor|
(bupdInit->voutStrong << _EMU_PWRCONF_VOUTSTRONG_SHIFT)|
(bupdInit->voutMed << _EMU_PWRCONF_VOUTMED_SHIFT)|
(bupdInit->voutWeak << _EMU_PWRCONF_VOUTWEAK_SHIFT));
EMU->PWRCONF = reg;
/* Set backup domain inactive mode configuration */
reg = EMU->BUINACT & ~(_EMU_BUINACT_PWRCON_MASK);
reg |= (bupdInit->inactivePower);
EMU->BUINACT = reg;
/* Set backup domain active mode configuration */
reg = EMU->BUACT & ~(_EMU_BUACT_PWRCON_MASK);
reg |= (bupdInit->activePower);
EMU->BUACT = reg;
/* Set power control configuration */
reg = EMU->BUCTRL & ~(
_EMU_BUCTRL_PROBE_MASK|
_EMU_BUCTRL_BODCAL_MASK|
_EMU_BUCTRL_STATEN_MASK|
_EMU_BUCTRL_EN_MASK);
/* Note use of ->enable to both enable BUPD, use BU_VIN pin input and
release reset */
reg |= (bupdInit->probe|
(bupdInit->bodCal << _EMU_BUCTRL_BODCAL_SHIFT)|
(bupdInit->statusPinEnable << _EMU_BUCTRL_STATEN_SHIFT)|
(bupdInit->enable << _EMU_BUCTRL_EN_SHIFT));
/* Enable configuration */
EMU->BUCTRL = reg;
/* If enable is true, enable BU_VIN input power pin, if not disable it */
EMU_BUPinEnable(bupdInit->enable);
/* If enable is true, release BU reset, if not keep reset asserted */
BITBAND_Peripheral(&(RMU->CTRL), _RMU_CTRL_BURSTEN_SHIFT, !bupdInit->enable);
}
/***************************************************************************//**
* @brief
* Configure Backup Power Domain BOD Threshold value
* @note
* These values are precalibrated
* @param[in] mode Active or Inactive mode
* @param[in] value
******************************************************************************/
void EMU_BUThresholdSet(EMU_BODMode_TypeDef mode, uint32_t value)
{
EFM_ASSERT(value<=(_EMU_BUACT_BUEXTHRES_MASK>>_EMU_BUACT_BUEXTHRES_SHIFT));
switch(mode)
{
case emuBODMode_Active:
EMU->BUACT = (EMU->BUACT & ~(_EMU_BUACT_BUEXTHRES_MASK))|(value<<_EMU_BUACT_BUEXTHRES_SHIFT);
break;
case emuBODMode_Inactive:
EMU->BUINACT = (EMU->BUINACT & ~(_EMU_BUINACT_BUENTHRES_MASK))|(value<<_EMU_BUINACT_BUENTHRES_SHIFT);
break;
}
}
/***************************************************************************//**
* @brief
* Configure Backup Power Domain BOD Threshold Range
* @note
* These values are precalibrated
* @param[in] mode Active or Inactive mode
* @param[in] value
******************************************************************************/
void EMU_BUThresRangeSet(EMU_BODMode_TypeDef mode, uint32_t value)
{
EFM_ASSERT(value<=(_EMU_BUACT_BUEXRANGE_MASK>>_EMU_BUACT_BUEXRANGE_SHIFT));
switch(mode)
{
case emuBODMode_Active:
EMU->BUACT = (EMU->BUACT & ~(_EMU_BUACT_BUEXRANGE_MASK))|(value<<_EMU_BUACT_BUEXRANGE_SHIFT);
break;
case emuBODMode_Inactive:
EMU->BUINACT = (EMU->BUINACT & ~(_EMU_BUINACT_BUENRANGE_MASK))|(value<<_EMU_BUINACT_BUENRANGE_SHIFT);
break;
}
}
#endif
/** @} (end addtogroup EMU) */
/** @} (end addtogroup EM_Library) */
#endif /* __EM_EMU_H */
/***************************************************************************//**
* @file
* @brief General Purpose IO (GPIO) peripheral API
* devices.
* @author Energy Micro AS
* @version 3.20.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_gpio.h"
#if defined(GPIO_COUNT) && (GPIO_COUNT > 0)
/***************************************************************************//**
* @addtogroup EM_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup GPIO
* @brief General Purpose Input/Output (GPIO) API
* @{
******************************************************************************/
/*******************************************************************************
******************************* DEFINES ***********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** Validation of pin typically usable in assert statements. */
#define GPIO_DRIVEMODE_VALID(mode) ((mode) <= 3)
/** @endcond */
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Sets the pin location of the debug pins (Serial Wire interface).
*
* @note
* Changing the pins used for debugging uncontrolled, may result in a lockout.
*
* @param[in] location
* The debug pin location to use (0-3).
******************************************************************************/
void GPIO_DbgLocationSet(unsigned int location)
{
#if defined ( _GPIO_ROUTE_SWLOCATION_MASK )
EFM_ASSERT(location < AFCHANLOC_MAX);
GPIO->ROUTE = (GPIO->ROUTE & ~_GPIO_ROUTE_SWLOCATION_MASK) |
(location << _GPIO_ROUTE_SWLOCATION_SHIFT);
#else
(void)location;
#endif
}
/***************************************************************************//**
* @brief
* Sets the drive mode for a GPIO port.
*
* @param[in] port
* The GPIO port to access.
*
* @param[in] mode
* Drive mode to use for port.
******************************************************************************/
void GPIO_DriveModeSet(GPIO_Port_TypeDef port, GPIO_DriveMode_TypeDef mode)
{
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_DRIVEMODE_VALID(mode));
GPIO->P[port].CTRL = (GPIO->P[port].CTRL & ~(_GPIO_P_CTRL_DRIVEMODE_MASK))
| (mode << _GPIO_P_CTRL_DRIVEMODE_SHIFT);
}
/***************************************************************************//**
* @brief
* Configure GPIO interrupt.
*
* @details
* If reconfiguring a GPIO interrupt that is already enabled, it is generally
* recommended to disable it first, see GPIO_Disable().
*
* The actual GPIO interrupt handler must be in place before enabling the
* interrupt.
*
* Notice that any pending interrupt for the selected pin is cleared by this
* function.
*
* @note
* A certain pin number can only be associated with one port. Ie, if GPIO
* interrupt 1 is assigned to port A/pin 1, then it is not possibly to use
* pin 1 from any other ports for interrupts. Please refer to the reference
* manual.
*
* @param[in] port
* The port to associate with @p pin.
*
* @param[in] pin
* The GPIO interrupt number (= port pin).
*
* @param[in] risingEdge
* Set to true if interrupts shall be enabled on rising edge, otherwise false.
*
* @param[in] fallingEdge
* Set to true if interrupts shall be enabled on falling edge, otherwise false.
*
* @param[in] enable
* Set to true if interrupt shall be enabled after configuration completed,
* false to leave disabled. See GPIO_IntDisable() and GPIO_IntEnable().
******************************************************************************/
void GPIO_IntConfig(GPIO_Port_TypeDef port,
unsigned int pin,
bool risingEdge,
bool fallingEdge,
bool enable)
{
uint32_t tmp;
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_PIN_VALID(pin));
/* There are two registers controlling the interrupt configuration:
* The EXTIPSELL register controls pins 0-7 and EXTIPSELH controls
* pins 8-15. */
if (pin < 8)
{
GPIO->EXTIPSELL = (GPIO->EXTIPSELL & ~(0xF << (4 * pin))) |
(port << (4 * pin));
}
else
{
tmp = pin - 8;
GPIO->EXTIPSELH = (GPIO->EXTIPSELH & ~(0xF << (4 * tmp))) |
(port << (4 * tmp));
}
/* Enable/disable rising edge */
BITBAND_Peripheral(&(GPIO->EXTIRISE), pin, (unsigned int)risingEdge);
/* Enable/disable falling edge */
BITBAND_Peripheral(&(GPIO->EXTIFALL), pin, (unsigned int)fallingEdge);
/* Clear any pending interrupt */
GPIO->IFC = 1 << pin;
/* Finally enable/disable interrupt */
BITBAND_Peripheral(&(GPIO->IEN), pin, (unsigned int)enable);
}
/***************************************************************************//**
* @brief
* Set the mode for a GPIO pin.
*
* @param[in] port
* The GPIO port to access.
*
* @param[in] pin
* The pin number in the port.
*
* @param[in] mode
* The desired pin mode.
*
* @param[in] out
* Value to set for pin in DOUT register. The DOUT setting is important for
* even some input mode configurations, determining pull-up/down direction.
******************************************************************************/
void GPIO_PinModeSet(GPIO_Port_TypeDef port,
unsigned int pin,
GPIO_Mode_TypeDef mode,
unsigned int out)
{
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_PIN_VALID(pin));
/* If disabling pin, do not modify DOUT in order to reduce chance for */
/* glitch/spike (may not be sufficient precaution in all use cases) */
if (mode != gpioModeDisabled)
{
if (out)
{
GPIO->P[port].DOUTSET = 1 << pin;
}
else
{
GPIO->P[port].DOUTCLR = 1 << pin;
}
}
/* There are two registers controlling the pins for each port. The MODEL
* register controls pins 0-7 and MODEH controls pins 8-15. */
if (pin < 8)
{
GPIO->P[port].MODEL = (GPIO->P[port].MODEL & ~(0xF << (pin * 4))) |
(mode << (pin * 4));
}
else
{
GPIO->P[port].MODEH = (GPIO->P[port].MODEH & ~(0xF << ((pin - 8) * 4))) |
(mode << ((pin - 8) * 4));
}
if (mode == gpioModeDisabled)
{
if (out)
{
GPIO->P[port].DOUTSET = 1 << pin;
}
else
{
GPIO->P[port].DOUTCLR = 1 << pin;
}
}
}
/** @} (end addtogroup GPIO) */
/** @} (end addtogroup EM_Library) */
#endif /* defined(GPIO_COUNT) && (GPIO_COUNT > 0) */
/***************************************************************************//**
* @file
* @brief Liquid Crystal Display (LCD) Peripheral API
* @author Energy Micro AS
* @version 3.20.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_lcd.h"
#if defined(LCD_COUNT) && (LCD_COUNT > 0)
#include "em_assert.h"
#include "em_bitband.h"
/***************************************************************************//**
* @addtogroup EM_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup LCD
* @brief Liquid Crystal Display (LCD) Peripheral API
* @{
******************************************************************************/
/***************************************************************************//**
* @brief
* Initalize Liquid Crystal Display (LCD) controller
*
* @details
* This function call will only configure the LCD controller. You must enable
* it afterwards, potentially configuring Frame Control and interrupts first
* according to requirements.
*
* @param[in] lcdInit
* Pointer to initialization structure which configures LCD controller.
*
******************************************************************************/
void LCD_Init(const LCD_Init_TypeDef *lcdInit)
{
uint32_t dispCtrl = LCD->DISPCTRL;
EFM_ASSERT(lcdInit != (void *) 0);
/* Disable controller before reconfiguration */
LCD_Enable(false);
/* Make sure we don't touch other bit fields (i.e. voltage boost) */
dispCtrl &= ~(
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
_LCD_DISPCTRL_MUXE_MASK |
#endif
_LCD_DISPCTRL_MUX_MASK |
_LCD_DISPCTRL_BIAS_MASK |
_LCD_DISPCTRL_WAVE_MASK |
_LCD_DISPCTRL_VLCDSEL_MASK |
_LCD_DISPCTRL_CONCONF_MASK);
/* Configure controller according to initialization structure */
dispCtrl |= lcdInit->mux; /* also configures MUXE */
dispCtrl |= lcdInit->bias;
dispCtrl |= lcdInit->wave;
dispCtrl |= lcdInit->vlcd;
dispCtrl |= lcdInit->contrast;
/* Update display controller */
LCD->DISPCTRL = dispCtrl;
/* Enable controller if wanted */
if (lcdInit->enable)
{
LCD_Enable(true);
}
}
/***************************************************************************//**
* @brief
* Select source for VLCD
*
* @param[in] vlcd
* Select source for VLD voltage
******************************************************************************/
void LCD_VLCDSelect(LCD_VLCDSel_TypeDef vlcd)
{
uint32_t dispctrl = LCD->DISPCTRL;
/* Select VEXT or VDD */
dispctrl &= ~(_LCD_DISPCTRL_VLCDSEL_MASK);
switch (vlcd)
{
case lcdVLCDSelVExtBoost:
dispctrl |= LCD_DISPCTRL_VLCDSEL_VEXTBOOST;
break;
case lcdVLCDSelVDD:
dispctrl |= LCD_DISPCTRL_VLCDSEL_VDD;
break;
default:
break;
}
LCD->DISPCTRL = dispctrl;
}
/***************************************************************************//**
* @brief
* Configure Update Control
*
* @param[in] ud
* Configures LCD update method
******************************************************************************/
void LCD_UpdateCtrl(LCD_UpdateCtrl_TypeDef ud)
{
LCD->CTRL = (LCD->CTRL & ~_LCD_CTRL_UDCTRL_MASK) | ud;
}
/***************************************************************************//**
* @brief
* Initialize LCD Frame Counter
*
* @param[in] fcInit
* Pointer to Frame Counter initialization structure
******************************************************************************/
void LCD_FrameCountInit(const LCD_FrameCountInit_TypeDef *fcInit)
{
uint32_t bactrl = LCD->BACTRL;
EFM_ASSERT(fcInit != (void *) 0);
/* Verify FC Top Counter to be within limits */
EFM_ASSERT(fcInit->top < 64);
/* Reconfigure frame count configuration */
bactrl &= ~(_LCD_BACTRL_FCTOP_MASK |
_LCD_BACTRL_FCPRESC_MASK);
bactrl |= (fcInit->top << _LCD_BACTRL_FCTOP_SHIFT);
bactrl |= fcInit->prescale;
/* Set Blink and Animation Control Register */
LCD->BACTRL = bactrl;
LCD_FrameCountEnable(fcInit->enable);
}
/***************************************************************************//**
* @brief
* Configures LCD controller Animation feature
*
* @param[in] animInit
* Pointer to LCD Animation initialization structure
******************************************************************************/
void LCD_AnimInit(const LCD_AnimInit_TypeDef *animInit)
{
uint32_t bactrl = LCD->BACTRL;
EFM_ASSERT(animInit != (void *) 0);
/* Set Animation Register Values */
LCD->AREGA = animInit->AReg;
LCD->AREGB = animInit->BReg;
/* Configure Animation Shift and Logic */
bactrl &= ~(_LCD_BACTRL_AREGASC_MASK |
_LCD_BACTRL_AREGBSC_MASK |
_LCD_BACTRL_ALOGSEL_MASK);
bactrl |= (animInit->AShift << _LCD_BACTRL_AREGASC_SHIFT);
bactrl |= (animInit->BShift << _LCD_BACTRL_AREGBSC_SHIFT);
bactrl |= animInit->animLogic;
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
bactrl &= ~(_LCD_BACTRL_ALOC_MASK);
if(animInit->startSeg == 0)
{
bactrl |= LCD_BACTRL_ALOC_SEG0TO7;
}
else if(animInit->startSeg == 8)
{
bactrl |= LCD_BACTRL_ALOC_SEG8TO15;
}
#endif
/* Reconfigure */
LCD->BACTRL = bactrl;
/* Enable */
LCD_AnimEnable(animInit->enable);
}
/***************************************************************************//**
* @brief
* Enables update of this range of LCD segment lines
*
* @param[in] segmentRange
* Range of 4 LCD segments lines to enable or disable, for all enabled COM
* lines
*
* @param[in] enable
* Bool true to enable segment updates, false to disable updates
******************************************************************************/
void LCD_SegmentRangeEnable(LCD_SegmentRange_TypeDef segmentRange, bool enable)
{
if (enable)
{
LCD->SEGEN |= segmentRange;
}
else
{
LCD->SEGEN &= ~((uint32_t)segmentRange);
}
}
/***************************************************************************//**
* @brief
* Turn on or clear a segment
*
* @note
* On Gecko Family, max configuration is (COM-lines x Segment-Lines) 4x40
* On Tiny Family, max configuration is 8x20 or 4x24
* On Giant Family, max configuration is 8x36 or 4x40
*
* @param[in] com
* COM line to change
*
* @param[in] bit
* Bit index of which field to change
*
* @param[in] enable
* When true will set segment, when false will clear segment
******************************************************************************/
void LCD_SegmentSet(int com, int bit, bool enable)
{
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
/* Tiny and Giant Family supports up to 8 COM lines */
EFM_ASSERT(com < 8);
#else
/* Gecko Family supports up to 4 COM lines */
EFM_ASSERT(com < 4);
#endif
#if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
EFM_ASSERT(bit < 40);
#else
/* Tiny Gecko Family supports only "low" segment registers */
EFM_ASSERT(bit < 32);
#endif
/* Use bitband access for atomic bit set/clear of segment */
switch (com)
{
case 0:
if (bit < 32)
{
BITBAND_Peripheral(&(LCD->SEGD0L), bit, (unsigned int)enable);
}
#if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
else
{
bit -= 32;
BITBAND_Peripheral(&(LCD->SEGD0H), bit, (unsigned int)enable);
}
#endif
break;
case 1:
if (bit < 32)
{
BITBAND_Peripheral(&(LCD->SEGD1L), bit, (unsigned int)enable);
}
#if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
else
{
bit -= 32;
BITBAND_Peripheral(&(LCD->SEGD1H), bit, (unsigned int)enable);
}
#endif
break;
case 2:
if (bit < 32)
{
BITBAND_Peripheral(&(LCD->SEGD2L), bit, (unsigned int)enable);
}
#if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
else
{
bit -= 32;
BITBAND_Peripheral(&(LCD->SEGD2H), bit, (unsigned int)enable);
}
#endif
break;
case 3:
if (bit < 32)
{
BITBAND_Peripheral(&(LCD->SEGD3L), bit, (unsigned int)enable);
}
#if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
else
{
bit -= 32;
BITBAND_Peripheral(&(LCD->SEGD3H), bit, (unsigned int)enable);
}
#endif
break;
case 4:
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
if (bit < 32)
{
BITBAND_Peripheral(&(LCD->SEGD4L), bit, (unsigned int)enable);
}
#endif
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
else
{
bit -= 32;
BITBAND_Peripheral(&(LCD->SEGD4H), bit, (unsigned int)enable);
}
#endif
break;
case 5:
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
if (bit < 32)
{
BITBAND_Peripheral(&(LCD->SEGD5L), bit, (unsigned int)enable);
}
#endif
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
else
{
bit -= 32;
BITBAND_Peripheral(&(LCD->SEGD5H), bit, (unsigned int)enable);
}
#endif
break;
case 6:
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
if (bit < 32)
{
BITBAND_Peripheral(&(LCD->SEGD6L), bit, (unsigned int)enable);
}
#endif
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
else
{
bit -= 32;
BITBAND_Peripheral(&(LCD->SEGD6H), bit, (unsigned int)enable);
}
#endif
break;
case 7:
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
if (bit < 32)
{
BITBAND_Peripheral(&(LCD->SEGD7L), bit, (unsigned int)enable);
}
#endif
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
else
{
bit -= 32;
BITBAND_Peripheral(&(LCD->SEGD7H), bit, (unsigned int)enable);
}
#endif
break;
default:
EFM_ASSERT(0);
break;
}
}
/***************************************************************************//**
* @brief
* Updates the 0-31 lowest segments on a given COM-line in one operation,
* according to bit mask
*
* @param[in] com
* Which COM line to update
*
* @param[in] mask
* Bit mask for segments 0-31
*
* @param[in] bits
* Bit pattern for segments 0-31
******************************************************************************/
void LCD_SegmentSetLow(int com, uint32_t mask, uint32_t bits)
{
uint32_t segData;
/* Maximum number of com lines */
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
EFM_ASSERT(com < 8);
#else
/* Gecko Family supports up to 4 COM lines */
EFM_ASSERT(com < 4);
#endif
switch (com)
{
case 0:
segData = LCD->SEGD0L;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD0L = segData;
break;
case 1:
segData = LCD->SEGD1L;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD1L = segData;
break;
case 2:
segData = LCD->SEGD2L;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD2L = segData;
break;
case 3:
segData = LCD->SEGD3L;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD3L = segData;
break;
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
case 4:
segData = LCD->SEGD4L;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD4L = segData;
break;
#endif
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
case 5:
segData = LCD->SEGD5L;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD5L = segData;
break;
#endif
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
case 6:
segData = LCD->SEGD6L;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD6L = segData;
break;
#endif
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
case 7:
segData = LCD->SEGD7L;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD7L = segData;
break;
#endif
default:
EFM_ASSERT(0);
break;
}
}
#if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
/***************************************************************************//**
* @brief
* Updated the high (32-39) segments on a given COM-line in one operation
*
* @param[in] com
* Which COM line to update
*
* @param[in] mask
* Bit mask for segments 32-39
*
* @param[in] bits
* Bit pattern for segments 32-39
******************************************************************************/
void LCD_SegmentSetHigh(int com, uint32_t mask, uint32_t bits)
{
uint32_t segData;
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
EFM_ASSERT(com < 8);
#endif
#if defined(_EFM32_GECKO_FAMILY)
EFM_ASSERT(com < 4);
#endif
/* Maximum number of com lines */
switch (com)
{
case 0:
segData = LCD->SEGD0H;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD0H = segData;
break;
case 1:
segData = LCD->SEGD1H;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD1H = segData;
break;
case 2:
segData = LCD->SEGD2H;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD2H = segData;
break;
case 3:
segData = LCD->SEGD3H;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD3H = segData;
break;
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
case 4:
segData = LCD->SEGD4H;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD4H = segData;
break;
#endif
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
case 5:
segData = LCD->SEGD5H;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD5H = segData;
break;
#endif
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
case 6:
segData = LCD->SEGD6H;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD6H = segData;
break;
#endif
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
case 7:
segData = LCD->SEGD7H;
segData &= ~(mask);
segData |= (mask & bits);
LCD->SEGD7H = segData;
break;
#endif
default:
break;
}
}
#endif
/***************************************************************************//**
* @brief
* Configure contrast level on LCD panel
*
* @param[in] level
* Contrast level in the range 0-31
******************************************************************************/
void LCD_ContrastSet(int level)
{
EFM_ASSERT(level < 32);
LCD->DISPCTRL = (LCD->DISPCTRL & ~_LCD_DISPCTRL_CONLEV_MASK)
| (level << _LCD_DISPCTRL_CONLEV_SHIFT);
}
/***************************************************************************//**
* @brief
* Configure voltage booster
*
* The resulting voltage level is described in each part number's data sheet
*
* @param[in] vboost
* Voltage boost level
******************************************************************************/
void LCD_VBoostSet(LCD_VBoostLevel_TypeDef vboost)
{
/* Reconfigure Voltage Boost */
LCD->DISPCTRL = (LCD->DISPCTRL & ~_LCD_DISPCTRL_VBLEV_MASK) | vboost;
}
#if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
/***************************************************************************//**
* @brief
* Configure bias level for a specific segment line for Direct Segment Control
*
* @note
* When DSC is active, each configuration takes up 4 bits in the Segment
* Registers (SEGD0L/SEGD1H) which defines bias level.
* For optimal use of this feature, the entire SEGD-registers should be set
* at once in a optimized routine, so this function is mainly here to
* demonstrate how to correctly configure the bias levels, and should be used
* with care.
*
* @param[in] segmentLine
* Segment line number
*
* @param[in] biasLevel
* Bias configuration level, 0-4. This value must be within the constraint
* defined by the LCD_DISPCTRL bias setting, see Reference Manual/Datasheet
******************************************************************************/
void LCD_BiasSegmentSet(int segmentLine, int biasLevel)
{
int biasRegister;
int bitShift;
volatile uint32_t *segmentRegister;
#if defined(_EFM32_TINY_FAMILY)
EFM_ASSERT(segmentLine < 20);
#endif
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
EFM_ASSERT(segmentLine < 40);
#endif
#if defined(_EFM32_TINY_FAMILY)
/* Bias config for 8 segment lines per SEGDnL register */
biasRegister = segmentLine / 8;
bitShift = (segmentLine % 8) * 4;
switch (biasRegister)
{
case 0:
segmentRegister = &LCD->SEGD0L;
break;
case 1:
segmentRegister = &LCD->SEGD1L;
break;
case 2:
segmentRegister = &LCD->SEGD2L;
break;
case 3:
segmentRegister = &LCD->SEGD3L;
break;
default:
segmentRegister = (uint32_t *)0x00000000;
EFM_ASSERT(0);
break;
}
#endif
#if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY)
/* Bias config for 10 segment lines per SEGDn L+H registers */
biasRegister = segmentLine / 10;
bitShift = (segmentLine % 10) * 4;
switch (biasRegister)
{
case 0:
if (bitShift < 32)
{
segmentRegister = &LCD->SEGD0L;
}
else
{
segmentRegister = &LCD->SEGD0H;
bitShift -= 32;
}
break;
case 1:
if (bitShift < 32)
{
segmentRegister = &LCD->SEGD1L;
}
else
{
segmentRegister = &LCD->SEGD1H;
bitShift -= 32;
}
break;
case 2:
if (bitShift < 32)
{
segmentRegister = &LCD->SEGD2L;
}
else
{
segmentRegister = &LCD->SEGD1H;
bitShift -= 32;
}
break;
case 3:
if (bitShift < 32)
{
segmentRegister = &LCD->SEGD3L;
}
else
{
segmentRegister = &LCD->SEGD3H;
bitShift -= 32;
}
break;
default:
segmentRegister = (uint32_t *)0x00000000;
EFM_ASSERT(0);
break;
}
#endif
/* Configure new bias setting */
*segmentRegister = (*segmentRegister & ~(0xF << bitShift)) | (biasLevel << bitShift);
}
/***************************************************************************//**
* @brief
* Configure bias level for a specific segment line
*
* @note
* When DSC is active, each configuration takes up 4 bits in the Segment
* Registers (SEGD4L/SEGD4H) which defines bias level.
* For optimal use of this feature, the entire SEGD-registers should be set
* at once in a optimized routine, so this function is mainly here to
* demonstrate how to correctly configure the bias levels, and should be used
* with care.
*
* @param[in] comLine
* COM line number, 0-7
*
* @param[in] biasLevel
* Bias configuration level, 0-4. This value must be within the constraint
* defined by the LCD_DISPCTRL bias setting, see Reference Manual/Datasheet
******************************************************************************/
void LCD_BiasComSet(int comLine, int biasLevel)
{
int bitShift;
EFM_ASSERT(comLine < 8);
bitShift = comLine * 4;
LCD->SEGD4L = (LCD->SEGD4L & ~(0xF << bitShift)) | (biasLevel << bitShift);
}
#endif
/** @} (end addtogroup LCD) */
/** @} (end addtogroup EM_Library) */
#endif /* defined(LCD_COUNT) && (LCD_COUNT > 0) */
/***************************************************************************//**
* @file
* @brief System Peripheral API
* @author Energy Micro AS
* @version 3.20.2
*******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_system.h"
#include "em_assert.h"
/***************************************************************************//**
* @addtogroup EM_Library
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup SYSTEM
* @brief System Peripheral API
* @{
******************************************************************************/
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Get chip major/minor revision.
*
* @param[out] rev
* Location to place chip revision info.
******************************************************************************/
void SYSTEM_ChipRevisionGet(SYSTEM_ChipRevision_TypeDef *rev)
{
uint8_t tmp;
EFM_ASSERT(rev);
rev->major = (ROMTABLE->PID0 & _ROMTABLE_PID0_REVMAJOR_MASK) >> _ROMTABLE_PID0_REVMAJOR_SHIFT;
tmp = (ROMTABLE->PID2 & _ROMTABLE_PID2_REVMINORMSB_MASK);
tmp |= ((ROMTABLE->PID3 & _ROMTABLE_PID3_REVMINORLSB_MASK) >> _ROMTABLE_PID3_REVMINORLSB_SHIFT);
rev->minor = tmp;
}
/***************************************************************************//**
* @brief
* Get factory calibration value for a given peripheral register.
*
* @param[in] regAddress
* Address of register to get a calibration value for.
*
* @return
* Calibration value for the requested register.
******************************************************************************/
uint32_t SYSTEM_GetCalibrationValue(volatile uint32_t *regAddress)
{
int regCount;
CALIBRATE_TypeDef *p;
regCount = 1;
p = CALIBRATE;
for (;; )
{
if ((regCount > CALIBRATE_MAX_REGISTERS) ||
(p->VALUE == 0xFFFFFFFF))
{
EFM_ASSERT(false);
return 0; /* End of device calibration table reached. */
}
if (p->ADDRESS == (uint32_t)regAddress)
{
return p->VALUE; /* Calibration value found ! */
}
p++;
regCount++;
}
}
/** @} (end addtogroup SYSTEM) */
/** @} (end addtogroup EM_Library) */
Keil RTX RTOS - Blink example
This example project uses the Keil RTX RTOS, and gives a basic demonstration of using two tasks to blink the LEDs on the board.
This example is intended as a skeleton for new projects using Keil RTX.
Board: Silicon Labs EFM32GG-STK3700
Device: EFM32GG990F1024
/*----------------------------------------------------------------------------
* RL-ARM - RTX
*----------------------------------------------------------------------------
* Name: RTX_Conf_CM.C
* Purpose: Configuration of CMSIS RTX Kernel for Cortex-M
* Rev.: V4.70
*----------------------------------------------------------------------------
*
* Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*---------------------------------------------------------------------------*/
#include "cmsis_os.h"
#include "em_emu.h"
/*----------------------------------------------------------------------------
* RTX User configuration part BEGIN
*---------------------------------------------------------------------------*/
//-------- <<< Use Configuration Wizard in Context Menu >>> -----------------
//
// <h>Thread Configuration
// =======================
//
// <o>Number of concurrent running threads <0-250>
// <i> Defines max. number of threads that will run at the same time.
// <i> Default: 6
#ifndef OS_TASKCNT
#define OS_TASKCNT 6
#endif
// <o>Default Thread stack size [bytes] <64-4096:8><#/4>
// <i> Defines default stack size for threads with osThreadDef stacksz = 0
// <i> Default: 200
#ifndef OS_STKSIZE
#define OS_STKSIZE 75
#endif
// <o>Main Thread stack size [bytes] <64-4096:8><#/4>
// <i> Defines stack size for main thread.
// <i> Default: 200
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 75
#endif
// <o>Number of threads with user-provided stack size <0-250>
// <i> Defines the number of threads with user-provided stack size.
// <i> Default: 0
#ifndef OS_PRIVCNT
#define OS_PRIVCNT 0
#endif
// <o>Total stack size [bytes] for threads with user-provided stack size <0-4096:8><#/4>
// <i> Defines the combined stack size for threads with user-provided stack size.
// <i> Default: 0
#ifndef OS_PRIVSTKSIZE
#define OS_PRIVSTKSIZE 0
#endif
// <q>Check for stack overflow
// <i> Includes the stack checking code for stack overflow.
// <i> Note that additional code reduces the Kernel performance.
#ifndef OS_STKCHECK
#define OS_STKCHECK 1
#endif
// <o>Processor mode for thread execution
// <0=> Unprivileged mode
// <1=> Privileged mode
// <i> Default: Privileged mode
#ifndef OS_RUNPRIV
#define OS_RUNPRIV 1
#endif
// </h>
// <h>RTX Kernel Timer Tick Configuration
// ======================================
// <q> Use Cortex-M SysTick timer as RTX Kernel Timer
// <i> Use the Cortex-M SysTick timer as a time-base for RTX.
#ifndef OS_SYSTICK
#define OS_SYSTICK 1
#endif
//
// <o>Timer clock value [Hz] <1-1000000000>
// <i> Defines the timer clock value.
// <i> Default: 12000000 (12MHz)
#ifndef OS_CLOCK
#define OS_CLOCK 14000000
#endif
// <o>Timer tick value [us] <1-1000000>
// <i> Defines the timer tick value.
// <i> Default: 1000 (1ms)
#ifndef OS_TICK
#define OS_TICK 1000
#endif
// </h>
// <h>System Configuration
// =======================
//
// <e>Round-Robin Thread switching
// ===============================
//
// <i> Enables Round-Robin Thread switching.
#ifndef OS_ROBIN
#define OS_ROBIN 1
#endif
// <o>Round-Robin Timeout [ticks] <1-1000>
// <i> Defines how long a thread will execute before a thread switch.
// <i> Default: 5
#ifndef OS_ROBINTOUT
#define OS_ROBINTOUT 5
#endif
// </e>
// <e>User Timers
// ==============
// <i> Enables user Timers
#ifndef OS_TIMERS
#define OS_TIMERS 0
#endif
// <o>Timer Thread Priority
// <1=> Low
// <2=> Below Normal <3=> Normal <4=> Above Normal
// <5=> High
// <6=> Realtime (highest)
// <i> Defines priority for Timer Thread
// <i> Default: High
#ifndef OS_TIMERPRIO
#define OS_TIMERPRIO 5
#endif
// <o>Timer Thread stack size [bytes] <64-4096:8><#/4>
// <i> Defines stack size for Timer thread.
// <i> Default: 200
#ifndef OS_TIMERSTKSZ
#define OS_TIMERSTKSZ 75
#endif
// <o>Timer Callback Queue size <1-32>
// <i> Number of concurrent active timer callback functions.
// <i> Default: 4
#ifndef OS_TIMERCBQS
#define OS_TIMERCBQS 4
#endif
// </e>
// <o>ISR FIFO Queue size<4=> 4 entries <8=> 8 entries
// <12=> 12 entries <16=> 16 entries
// <24=> 24 entries <32=> 32 entries
// <48=> 48 entries <64=> 64 entries
// <96=> 96 entries
// <i> ISR functions store requests to this buffer,
// <i> when they are called from the interrupt handler.
// <i> Default: 16 entries
#ifndef OS_FIFOSZ
#define OS_FIFOSZ 16
#endif
// </h>
//------------- <<< end of configuration section >>> -----------------------
// Standard library system mutexes
// ===============================
// Define max. number system mutexes that are used to protect
// the arm standard runtime library. For microlib they are not used.
#ifndef OS_MUTEXCNT
#define OS_MUTEXCNT 8
#endif
/*----------------------------------------------------------------------------
* RTX User configuration part END
*---------------------------------------------------------------------------*/
#define OS_TRV ((uint32_t)(((double)OS_CLOCK*(double)OS_TICK)/1E6)-1)
/*----------------------------------------------------------------------------
* Global Functions
*---------------------------------------------------------------------------*/
/*--------------------------- os_idle_demon ---------------------------------*/
void os_idle_demon (void) {
/* The idle demon is a system thread, running when no other thread is */
/* ready to run. */
for (;;) {
/* HERE: include optional user code to be executed when no thread runs.*/
/* Enter EM1. This is always safe to do, independently of which peripherals
are active. */
EMU_EnterEM1();
}
}
#if (OS_SYSTICK == 0) // Functions for alternative timer as RTX kernel timer
/*--------------------------- os_tick_init ----------------------------------*/
// Initialize alternative hardware timer as RTX kernel timer
// Return: IRQ number of the alternative hardware timer
int os_tick_init (void) {
return (-1); /* Return IRQ number of timer (0..239) */
}
/*--------------------------- os_tick_irqack --------------------------------*/
// Acknowledge alternative hardware timer interrupt
void os_tick_irqack (void) {
/* ... */
}
#endif // (OS_SYSTICK == 0)
/*--------------------------- os_error --------------------------------------*/
void os_error (uint32_t err_code) {
(void)err_code; /* Unused parameter. */
/* This function is called when a runtime error is detected. Parameter */
/* 'err_code' holds the runtime error code (defined in RTL.H). */
/* HERE: include optional code to be executed on runtime error. */
for (;;);
}
/*----------------------------------------------------------------------------
* RTX Configuration Functions
*---------------------------------------------------------------------------*/
#include "RTX_CM_lib.h"
/*----------------------------------------------------------------------------
* end of file
*---------------------------------------------------------------------------*/
/**************************************************************************//**
* @file
* @brief Simple LCD blink demo for EFM32GG_STK3700 using CMSIS RTOS
* @author Energy Micro AS
* @version 3.20.3
******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* This file is licensed under the Silicon Labs Software License Agreement. See
* "http://developer.silabs.com/legal/version/v11/Silicon_Labs_Software_License_Agreement.txt"
* for details. Before using this software for any purpose, you must agree to the
* terms of that agreement.
*
******************************************************************************/
#include <stdint.h>
#include "cmsis_os.h"
#include "bsp_trace.h"
#include "em_chip.h"
#include "bsp.h"
#include "segmentlcd.h"
typedef char lcdText_t[8];
/* Define memory pool */
osPoolDef(mpool, 16, lcdText_t);
osPoolId mpool;
/* Define message queue */
osMessageQDef(msgBox, 16, lcdText_t);
osMessageQId msgBox;
#define OS_STKSIZE 150
/**************************************************************************//**
* @brief
* Thread 1: Print LCD thread
*****************************************************************************/
void PrintLcdThread(void const *argument) {
lcdText_t *rptr;
osEvent evt;
(void)argument; /* Unused parameter. */
while (1)
{
/* Wait for message */
evt = osMessageGet(msgBox, osWaitForever);
if (evt.status == osEventMessage)
{
rptr = evt.value.p;
SegmentLCD_Write(*rptr);
/* Free memory allocated for message */
osPoolFree(mpool,rptr);
}
}
}
/* Thread definition */
osThreadDef(PrintLcdThread, osPriorityNormal, 1, 0);
/**************************************************************************//**
* @brief
* Thread 2: Put on LCD
*****************************************************************************/
void PutOnLcd(void const *arg)
{
static int count = 0;
/* Infinite loop */
while (1)
{
count = (count+1)&0xF;
BSP_LedsSet(count);
/* Send message to PrintLcdThread */
/* Allocate memory for the message */
lcdText_t *mptr = osPoolAlloc(mpool);
/* Set the message content */
(*mptr)[0] = count>=10 ? '1' : '0';
(*mptr)[1] = count%10 + '0';
(*mptr)[2] = '\0';
/* Send message */
osMessagePut(msgBox, (uint32_t)mptr, osWaitForever);
/* Wait now for half a second */
osDelay(500);
}
}
osThreadDef(PutOnLcd, osPriorityNormal, 1, 0);
/**************************************************************************//**
* @brief
* Main function is a CMSIS RTOS thread in itself
*
* @note
* This example uses threads, memory pool and message queue to demonstrate the
* usage of these CMSIS RTOS features. In this simple example, the same
* functionality could more easily be achieved by doing everything in the main
* loop.
*****************************************************************************/
int main(void)
{
/* Chip errata */
CHIP_Init();
osKernelInitialize();
/* If first word of user data page is non-zero, enable eA Profiler trace */
BSP_TraceProfilerSetup();
/* Initialize LED driver */
BSP_LedsInit();
/* Initialize the LCD driver */
SegmentLCD_Init(false);
/* Initialize CMSIS RTOS structures */
/* create memory pool */
mpool = osPoolCreate(osPool(mpool));
/* create msg queue */
msgBox = osMessageCreate(osMessageQ(msgBox), NULL);
/* create thread 1 */
osThreadCreate(osThread(PutOnLcd), NULL);
osThreadCreate(osThread(PrintLcdThread), NULL);
osKernelStart();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment