]> git.sur5r.net Git - freertos/commitdiff
Add Pearl Gecko demo.
authorrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Wed, 2 Mar 2016 16:03:25 +0000 (16:03 +0000)
committerrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Wed, 2 Mar 2016 16:03:25 +0000 (16:03 +0000)
Fix build error when configSUPPORT_STATIC_ALLOCATION and configNUM_THREAD_LOCAL_STORAGE_POINTERS were greater than zero at the same time.
Allow the pdMS_TO_TICKS macro to be overridden by a definition in FreeRTOSConfig.h.

git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2422 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

26 files changed:
FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Low_Power_Demo/low_power_tick_management_BURTC.c
FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Low_Power_Demo/low_power_tick_management_RTC.c
FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/.cproject [new file with mode: 0644]
FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/.project [new file with mode: 0644]
FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/FreeRTOSConfig.h [new file with mode: 0644]
FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/Full_Demo/RegTest.c [new file with mode: 0644]
FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/Full_Demo/main_full.c [new file with mode: 0644]
FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/Low_Power_Demo/low_power_tick_management_RTCC.c [new file with mode: 0644]
FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/Low_Power_Demo/main_low_power.c [new file with mode: 0644]
FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/BSP/bsp_stk_leds.c [new file with mode: 0644]
FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/CMSIS/efm32pg1b/startup_gcc_efm32pg1b.s [new file with mode: 0644]
FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/CMSIS/efm32pg1b/system_efm32pg1b.c [new file with mode: 0644]
FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/emdrv/sleep/inc/sleep.h [new file with mode: 0644]
FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/emdrv/sleep/src/sleep.c [new file with mode: 0644]
FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/emlib/em_assert.c [new file with mode: 0644]
FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/emlib/em_cmu.c [new file with mode: 0644]
FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/emlib/em_emu.c [new file with mode: 0644]
FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/emlib/em_gpio.c [new file with mode: 0644]
FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/emlib/em_int.c [new file with mode: 0644]
FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/emlib/em_rtcc.c [new file with mode: 0644]
FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/emlib/em_system.c [new file with mode: 0644]
FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/main.c [new file with mode: 0644]
FreeRTOS/Source/include/FreeRTOS.h
FreeRTOS/Source/include/projdefs.h
FreeRTOS/Source/portable/RVDS/ARM_CM4F/port.c
Upgrading-to-FreeRTOS-9.url [new file with mode: 0644]

index c097bebc8f8b0ac255ba44f9840b3a6899cbeb57..218dd7a4cd94ec262763caaefd5cb14dfe178a65 100644 (file)
@@ -81,7 +81,6 @@
 #include "em_burtc.h"\r
 #include "em_rmu.h"\r
 #include "em_int.h"\r
-#include "em_rtc.h"\r
 #include "sleep.h"\r
 \r
 /* SEE THE COMMENTS ABOVE THE DEFINITION OF configCREATE_LOW_POWER_DEMO IN\r
@@ -323,18 +322,18 @@ void BURTC_IRQHandler( void )
 {\r
        ulTickFlag = pdTRUE;\r
 \r
-       if( RTC_CompareGet( 0 ) != ulReloadValueForOneTick )\r
+       if( BURTC_CompareGet( 0 ) != ulReloadValueForOneTick )\r
        {\r
-               /* Set RTC interrupt to one RTOS tick period. */\r
+               /* Set BURTC interrupt to one RTOS tick period. */\r
                BURTC_Enable( false );\r
                BURTC_CompareSet( 0, ulReloadValueForOneTick );\r
                BURTC_Enable( true );\r
        }\r
 \r
-       BURTC_IntClear( _RTC_IFC_MASK );\r
+       BURTC_IntClear( _BURTC_IFC_MASK );\r
 \r
-       /* Critical section which protect incrementing the tick*/\r
-       ( void ) portSET_INTERRUPT_MASK_FROM_ISR();\r
+       /* Critical section which protect incrementing the tick*/\r
+       portDISABLE_INTERRUPTS();\r
        {\r
                if( xTaskIncrementTick() != pdFALSE )\r
                {\r
@@ -342,7 +341,7 @@ void BURTC_IRQHandler( void )
                        portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;\r
                }\r
        }\r
-       portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );\r
+       portENABLE_INTERRUPTS();\r
 }\r
 \r
 #endif /* ( configCREATE_LOW_POWER_DEMO == 1 ) */\r
index 4644e061dd7994545ea26bdff225564700e1de58..47fb7a9d1f584b70ccb469fee865cc45abab15b0 100644 (file)
@@ -356,8 +356,8 @@ void RTC_IRQHandler( void )
 \r
        RTC_IntClear( _RTC_IFC_MASK );\r
 \r
-       /* Critical section which protect incrementing the tick*/\r
-       ( void ) portSET_INTERRUPT_MASK_FROM_ISR();\r
+       /* Critical section which protect incrementing the tick*/\r
+       portDISABLE_INTERRUPTS();\r
        {\r
                if( xTaskIncrementTick() != pdFALSE )\r
                {\r
@@ -365,7 +365,7 @@ void RTC_IRQHandler( void )
                        portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;\r
                }\r
        }\r
-       portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );\r
+       portENABLE_INTERRUPTS();\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/.cproject b/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/.cproject
new file mode 100644 (file)
index 0000000..072724a
--- /dev/null
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>\r
+<?fileVersion 4.0.0?>\r
+\r
+<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">\r
+       <storageModule moduleId="org.eclipse.cdt.core.settings">\r
+               <cconfiguration id="com.silabs.ide.si32.gcc.debug#com.silabs.ide.si32.gcc:4.8.3.20131129">\r
+                       <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.silabs.ide.si32.gcc.debug#com.silabs.ide.si32.gcc:4.8.3.20131129" moduleId="org.eclipse.cdt.core.settings" name="GNU ARM v4.8.3 - Debug">\r
+                               <macros>\r
+                                       <stringMacro name="StudioToolchainPath" type="VALUE_PATH_DIR" value="${StudioToolchainPathFromID:com.silabs.ide.si32.gcc:4.8.3.20131129}"/>\r
+                                       <stringMacro name="StudioSdkPath" type="VALUE_PATH_DIR" value="${StudioSdkPathFromID:com.silabs.sdk.si32.efm32.sls:2.0.10}"/>\r
+                               </macros>\r
+                               <externalSettings/>\r
+                               <extensions>\r
+                                       <extension id="com.silabs.ide.debug.core.S37" point="org.eclipse.cdt.core.BinaryParser"/>\r
+                                       <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>\r
+                                       <extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>\r
+                                       <extension id="com.silabs.ide.debug.core.BIN" point="org.eclipse.cdt.core.BinaryParser"/>\r
+                                       <extension id="com.silabs.ide.debug.core.HEX" point="org.eclipse.cdt.core.BinaryParser"/>\r
+                                       <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>\r
+                                       <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>\r
+                                       <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>\r
+                                       <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>\r
+                                       <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>\r
+                               </extensions>\r
+                       </storageModule>\r
+                       <storageModule buildConfig.stockConfigId="com.silabs.ide.si32.gcc.debug#com.silabs.ide.si32.gcc:4.8.3.20131129" cppBuildConfig.builtinIncludes="studio:/sdk/kits/SLSTK3401A_EFM32PG/config/ studio:/sdk/CMSIS/Include/ studio:/sdk/emlib/inc/ studio:/sdk/kits/common/bsp/ studio:/sdk/kits/common/drivers/ studio:/sdk/Device/SiliconLabs/EFM32PG1B/Include/ studio:/sdk/kits/SLSTK3401A_EFM32PG/config/ studio:/sdk/CMSIS/Include/ studio:/sdk/emlib/inc/ studio:/sdk/kits/common/bsp/ studio:/sdk/kits/common/drivers/ studio:/sdk/Device/SiliconLabs/EFM32PG1B/Include/" cppBuildConfig.builtinLibraryFiles="" cppBuildConfig.builtinLibraryNames="" cppBuildConfig.builtinLibraryObjects="" cppBuildConfig.builtinLibraryPaths="" cppBuildConfig.builtinMacros="EFM32PG1B200F256GM48 EFM32PG1B200F256GM48 DEBUG" 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; builtin=\&quot;true\&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_system.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;/project:MModule&gt;&quot;,&quot;builtinExcludes&quot;:[],&quot;builtin&quot;:true,&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_system.c&quot;]},{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.ide.si32.sdk.efm32.v2.part\&quot;&gt;\r\n  &lt;inclusions pattern=\&quot;CMSIS/.*/startup_.*_.*.s\&quot;/&gt;\r\n  &lt;inclusions pattern=\&quot;CMSIS/.*/system_.*.c\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;,&quot;builtinExcludes&quot;:[],&quot;builtin&quot;:true,&quot;builtinSources&quot;:[&quot;CMSIS/efm32pg1b/startup_gcc_efm32pg1b.s&quot;,&quot;CMSIS/efm32pg1b/system_efm32pg1b.c&quot;]},{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; builtin=\&quot;true\&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;builtinExcludes&quot;:[],&quot;builtin&quot;:true,&quot;builtinSources&quot;:[]},{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; builtin=\&quot;true\&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;builtinExcludes&quot;:[],&quot;builtin&quot;:true,&quot;builtinSources&quot;:[]},{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.ide.si32.sdk.efm32.v2.common.drivers\&quot;&gt;\r\n  &lt;exclusions pattern=\&quot;.*\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;,&quot;builtinExcludes&quot;:[],&quot;builtin&quot;:true,&quot;builtinSources&quot;:[]},{&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/sls/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.ide.si32.sdk.efm32.v2.common.bsp\&quot;&gt;\r\n  &lt;inclusions pattern=\&quot;BSP/bsp_stk_leds.c\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;,&quot;builtinExcludes&quot;:[],&quot;builtin&quot;:true,&quot;builtinSources&quot;:[&quot;BSP/bsp_stk_leds.c&quot;]}]" projectCommon.toolchainId="com.silabs.ide.si32.gcc:4.8.3.20131129"/>\r
+                       <storageModule moduleId="cdtBuildSystem" version="4.0.0">\r
+                               <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.8.3.20131129" name="GNU ARM v4.8.3 - Debug" parent="com.silabs.ide.si32.gcc.cdt.managedbuild.config.gnu.exe">\r
+                                       <folderInfo id="com.silabs.ide.si32.gcc.debug#com.silabs.ide.si32.gcc:4.8.3.20131129." name="/" resourcePath="">\r
+                                               <toolChain id="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.exe.1210947266" name="Si32 GNU ARM" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.exe">\r
+                                                       <option id="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.debug.level.1491015159" 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"/>\r
+                                                       <targetPlatform binaryParser="org.eclipse.cdt.core.ELF;org.eclipse.cdt.core.GNU_ELF;com.silabs.ide.debug.core.BIN;com.silabs.ide.debug.core.HEX;com.silabs.ide.debug.core.S37" id="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.platform.base.1072192348" isAbstract="false" name="Debug Platform" osList="win32,linux,macosx" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.platform.base"/>\r
+                                                       <builder buildPath="${workspace_loc:/RTOSDemo}/GNU ARM v4.8.3 - Debug" id="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.builder.base.1216179401" 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"/>\r
+                                                       <tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base.1347880376" name="GNU ARM C Compiler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base">\r
+                                                               <option id="gnu.c.compiler.option.optimization.level.1992790616" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" value="gnu.c.optimization.level.none" valueType="enumerated"/>\r
+                                                               <option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.def.symbols.515358055" name="Defined symbols (-D)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.def.symbols" valueType="definedSymbols">\r
+                                                                       <listOptionValue builtIn="false" value="DEBUG_EFM=1"/>\r
+                                                                       <listOptionValue builtIn="false" value="SLEEP_LOWEST_ENERGY_MODE_DEFAULT=sleepEM2"/>\r
+                                                                       <listOptionValue builtIn="false" value="EFM32PG1B200F256GM48=1"/>\r
+                                                                       <listOptionValue builtIn="false" value="DEBUG=1"/>\r
+                                                               </option>\r
+                                                               <option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.builtin.1313176957" 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"/>\r
+                                                               <option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.prolog.1172189815" 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"/>\r
+                                                               <option id="gnu.c.compiler.option.include.paths.1242792235" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">\r
+                                                                       <listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/SLSTK3401A_EFM32PG/config&quot;"/>\r
+                                                                       <listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/CMSIS/Include&quot;"/>\r
+                                                                       <listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/emlib/inc&quot;"/>\r
+                                                                       <listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/common/bsp&quot;"/>\r
+                                                                       <listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/common/drivers&quot;"/>\r
+                                                                       <listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/SiliconLabs/EFM32PG1B/Include&quot;"/>\r
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}&quot;"/>\r
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/FreeRTOS_Source/include}&quot;"/>\r
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/FreeRTOS_Source/portable/GCC/ARM_CM3}&quot;"/>\r
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Full_Demo/Standard_Demo_Tasks/include}&quot;"/>\r
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/SilLabs_Source/emdrv/sleep/inc}&quot;"/>\r
+                                                               </option>\r
+                                                               <option id="gnu.c.compiler.option.warnings.extrawarn.257881085" name="Extra warnings (-Wextra)" superClass="gnu.c.compiler.option.warnings.extrawarn" value="true" valueType="boolean"/>\r
+                                                               <inputType id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input.1657907187" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input"/>\r
+                                                       </tool>\r
+                                                       <tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.base.404002511" name="GNU ARM C++ Compiler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.base">\r
+                                                               <option id="gnu.cpp.compiler.option.optimization.level.1331292595" name="Optimization Level" superClass="gnu.cpp.compiler.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>\r
+                                                               <option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.builtin.1708445238" 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"/>\r
+                                                               <option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.prolog.437089423" 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"/>\r
+                                                       </tool>\r
+                                                       <tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.assembler.base.146600794" name="GNU ARM Assembler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.assembler.base">\r
+                                                               <option id="gnu.both.asm.option.include.paths.1966239528" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath">\r
+                                                                       <listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/SLSTK3401A_EFM32PG/examples/blink&quot;"/>\r
+                                                                       <listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/SLSTK3401A_EFM32PG/config&quot;"/>\r
+                                                                       <listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/CMSIS/Include&quot;"/>\r
+                                                                       <listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/emlib/inc&quot;"/>\r
+                                                                       <listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/common/bsp&quot;"/>\r
+                                                                       <listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/kits/common/drivers&quot;"/>\r
+                                                                       <listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/SiliconLabs/EFM32PG1B/Include&quot;"/>\r
+                                                               </option>\r
+                                                               <option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.as.def.symbols.2072246944" name="Defined symbols (-D)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.as.def.symbols" valueType="definedSymbols">\r
+                                                                       <listOptionValue builtIn="false" value="EFM32PG1B200F256GM48=1"/>\r
+                                                               </option>\r
+                                                               <inputType id="cdt.managedbuild.tool.gnu.assembler.input.80652597" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>\r
+                                                       </tool>\r
+                                                       <tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.base.467472350" name="GNU ARM C Linker" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.base">\r
+                                                               <option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.nostdlibs.1491099628" name="No startup or default libs (-nostdlib)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.nostdlibs" value="false" valueType="boolean"/>\r
+                                                               <option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.category.ordering.selection.1386626351" name="Linker input ordering" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.category.ordering.selection" value="./emlib/em_assert.o;./emlib/em_cmu.o;./emlib/em_emu.o;./emlib/em_gpio.o;./emlib/em_rtc.o;./emlib/em_system.o;./emdrv/sleep/src/sleep.o;./Low_Power_Demo/low_power_tick_management_RTC.o;./Low_Power_Demo/main_low_power.o;./Full_Demo/Standard_Demo_Tasks/EventGroupsDemo.o;./Full_Demo/Standard_Demo_Tasks/GenQTest.o;./Full_Demo/Standard_Demo_Tasks/StaticAllocation.o;./Full_Demo/Standard_Demo_Tasks/TaskNotify.o;./Full_Demo/Standard_Demo_Tasks/TimerDemo.o;./Full_Demo/Standard_Demo_Tasks/blocktim.o;./Full_Demo/Standard_Demo_Tasks/dynamic.o;./Full_Demo/Standard_Demo_Tasks/flop.o;./Full_Demo/Standard_Demo_Tasks/recmutex.o;./Full_Demo/Standard_Demo_Tasks/semtest.o;./Full_Demo/RegTest.o;./Full_Demo/main_full.o;./FreeRTOS_Source/portable/MemMang/heap_4.o;./FreeRTOS_Source/portable/GCC/ARM_CM3/port.o;./FreeRTOS_Source/event_groups.o;./FreeRTOS_Source/list.o;./FreeRTOS_Source/queue.o;./FreeRTOS_Source/tasks.o;./FreeRTOS_Source/timers.o;./CMSIS/efm32pg1b/startup_gcc_efm32pg1b.o;./CMSIS/efm32pg1b/system_efm32pg1b.o;./BSP/bsp_stk_leds.o;./main.o" valueType="string"/>\r
+                                                               <inputType id="cdt.managedbuild.tool.gnu.c.linker.input.673598100" superClass="cdt.managedbuild.tool.gnu.c.linker.input">\r
+                                                                       <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>\r
+                                                                       <additionalInput kind="additionalinput" paths="$(LIBS)"/>\r
+                                                               </inputType>\r
+                                                       </tool>\r
+                                                       <tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.linker.base.737185930" name="GNU ARM C++ Linker" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.linker.base"/>\r
+                                                       <tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.archiver.base.1305574197" name="GNU ARM Archiver" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.archiver.base"/>\r
+                                               </toolChain>\r
+                                       </folderInfo>\r
+                               </configuration>\r
+                       </storageModule>\r
+                       <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>\r
+               </cconfiguration>\r
+       </storageModule>\r
+       <storageModule moduleId="com.silabs.ide.project.core" projectCommon.buildArtifactType="EXE" projectCommon.kitId="com.silabs.kit.si32.efm32.efm32pg.slstk3401a" projectCommon.partId="com.silabs.mcu.si32.efm32.efm32pg1b.efm32pg1b200f256gm48" projectCommon.sdkId="com.silabs.sdk.si32.efm32.sls:2.0.10"/>\r
+       <storageModule moduleId="cdtBuildSystem" version="4.0.0">\r
+               <project id="RTOSDemo.com.silabs.ide.project.core.cdt.cdtMbsProjectType.476959829" name="SLS CDT Project" projectType="com.silabs.ide.project.core.cdt.cdtMbsProjectType"/>\r
+       </storageModule>\r
+       <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>\r
+       <storageModule moduleId="scannerConfiguration">\r
+               <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>\r
+               <scannerConfigBuildInfo instanceId="com.silabs.ide.si32.gcc.debug#com.silabs.ide.si32.gcc:4.8.3.20131129;com.silabs.ide.si32.gcc.debug#com.silabs.ide.si32.gcc:4.8.3.20131129.;com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base.1347880376;com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input.1657907187">\r
+                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>\r
+               </scannerConfigBuildInfo>\r
+       </storageModule>\r
+       <storageModule moduleId="refreshScope"/>\r
+</cproject>\r
diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/.project b/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/.project
new file mode 100644 (file)
index 0000000..c257d44
--- /dev/null
@@ -0,0 +1,241 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>RTOSDemo</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>\r
+                       <triggers>clean,full,incremental,</triggers>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>\r
+                       <triggers>full,incremental,</triggers>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.cdt.core.cnature</nature>\r
+               <nature>com.silabs.ide.project.core.SLSProjectNature</nature>\r
+               <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>\r
+               <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>\r
+       </natures>\r
+       <linkedResources>\r
+               <link>\r
+                       <name>FreeRTOS_Source</name>\r
+                       <type>2</type>\r
+                       <locationURI>FREERTOS_ROOT/FreeRTOS/Source</locationURI>\r
+               </link>\r
+               <link>\r
+                       <name>Full_Demo/Standard_Demo_Tasks</name>\r
+                       <type>2</type>\r
+                       <locationURI>FREERTOS_ROOT/FreeRTOS/Demo/Common/Minimal</locationURI>\r
+               </link>\r
+               <link>\r
+                       <name>Full_Demo/Standard_Demo_Tasks/include</name>\r
+                       <type>2</type>\r
+                       <locationURI>FREERTOS_ROOT/FreeRTOS/Demo/Common/include</locationURI>\r
+               </link>\r
+       </linkedResources>\r
+       <filteredResources>\r
+               <filter>\r
+                       <id>1455990187566</id>\r
+                       <name>FreeRTOS_Source</name>\r
+                       <type>5</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-event_groups.c</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>1455990187573</id>\r
+                       <name>FreeRTOS_Source</name>\r
+                       <type>5</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-queue.c</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>1455990187577</id>\r
+                       <name>FreeRTOS_Source</name>\r
+                       <type>5</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-tasks.c</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>1455990187582</id>\r
+                       <name>FreeRTOS_Source</name>\r
+                       <type>5</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-timers.c</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>1455990187588</id>\r
+                       <name>FreeRTOS_Source</name>\r
+                       <type>9</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-include</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>1455990187592</id>\r
+                       <name>FreeRTOS_Source</name>\r
+                       <type>9</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-portable</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>1455990187597</id>\r
+                       <name>FreeRTOS_Source</name>\r
+                       <type>5</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-list.c</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>0</id>\r
+                       <name>FreeRTOS_Source/portable</name>\r
+                       <type>9</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-MemMang</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>0</id>\r
+                       <name>FreeRTOS_Source/portable</name>\r
+                       <type>9</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-GCC</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>0</id>\r
+                       <name>Full_Demo/Standard_Demo_Tasks</name>\r
+                       <type>5</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-flop.c</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>0</id>\r
+                       <name>Full_Demo/Standard_Demo_Tasks</name>\r
+                       <type>5</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-dynamic.c</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>0</id>\r
+                       <name>Full_Demo/Standard_Demo_Tasks</name>\r
+                       <type>5</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-blocktim.c</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>0</id>\r
+                       <name>Full_Demo/Standard_Demo_Tasks</name>\r
+                       <type>5</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-GenQTest.c</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>0</id>\r
+                       <name>Full_Demo/Standard_Demo_Tasks</name>\r
+                       <type>5</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-TimerDemo.c</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>0</id>\r
+                       <name>Full_Demo/Standard_Demo_Tasks</name>\r
+                       <type>5</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-EventGroupsDemo.c</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>0</id>\r
+                       <name>Full_Demo/Standard_Demo_Tasks</name>\r
+                       <type>5</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-TaskNotify.c</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>0</id>\r
+                       <name>Full_Demo/Standard_Demo_Tasks</name>\r
+                       <type>5</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-recmutex.c</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>0</id>\r
+                       <name>Full_Demo/Standard_Demo_Tasks</name>\r
+                       <type>5</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-semtest.c</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>0</id>\r
+                       <name>Full_Demo/Standard_Demo_Tasks</name>\r
+                       <type>5</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-StaticAllocation.c</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>1455989277852</id>\r
+                       <name>FreeRTOS_Source/portable/GCC</name>\r
+                       <type>9</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-ARM_CM3</arguments>\r
+                       </matcher>\r
+               </filter>\r
+               <filter>\r
+                       <id>1455989313240</id>\r
+                       <name>FreeRTOS_Source/portable/MemMang</name>\r
+                       <type>5</type>\r
+                       <matcher>\r
+                               <id>org.eclipse.ui.ide.multiFilter</id>\r
+                               <arguments>1.0-name-matches-false-false-heap_4.c</arguments>\r
+                       </matcher>\r
+               </filter>\r
+       </filteredResources>\r
+       <variableList>\r
+               <variable>\r
+                       <name>FREERTOS_ROOT</name>\r
+                       <value>$%7BPARENT-3-PROJECT_LOC%7D</value>\r
+               </variable>\r
+       </variableList>\r
+</projectDescription>\r
diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/FreeRTOSConfig.h b/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/FreeRTOSConfig.h
new file mode 100644 (file)
index 0000000..def429a
--- /dev/null
@@ -0,0 +1,237 @@
+/*\r
+    FreeRTOS V9.0.0rc1 - Copyright (C) 2016 Real Time Engineers Ltd.\r
+    All rights reserved\r
+\r
+    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+    This file is part of the FreeRTOS distribution.\r
+\r
+    FreeRTOS is free software; you can redistribute it and/or modify it under\r
+    the terms of the GNU General Public License (version 2) as published by the\r
+    Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.\r
+\r
+    ***************************************************************************\r
+    >>!   NOTE: The modification to the GPL is included to allow you to     !<<\r
+    >>!   distribute a combined work that includes FreeRTOS without being   !<<\r
+    >>!   obliged to provide the source code for proprietary components     !<<\r
+    >>!   outside of the FreeRTOS kernel.                                   !<<\r
+    ***************************************************************************\r
+\r
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+    FOR A PARTICULAR PURPOSE.  Full license text is available on the following\r
+    link: http://www.freertos.org/a00114.html\r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS provides completely free yet professionally developed,    *\r
+     *    robust, strictly quality controlled, supported, and cross          *\r
+     *    platform software that is more than just the market leader, it     *\r
+     *    is the industry's de facto standard.                               *\r
+     *                                                                       *\r
+     *    Help yourself get started quickly while simultaneously helping     *\r
+     *    to support the FreeRTOS project by purchasing a FreeRTOS           *\r
+     *    tutorial book, reference manual, or both:                          *\r
+     *    http://www.FreeRTOS.org/Documentation                              *\r
+     *                                                                       *\r
+    ***************************************************************************\r
+\r
+    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading\r
+    the FAQ page "My application does not run, what could be wrong?".  Have you\r
+    defined configASSERT()?\r
+\r
+    http://www.FreeRTOS.org/support - In return for receiving this top quality\r
+    embedded software for free we request you assist our global community by\r
+    participating in the support forum.\r
+\r
+    http://www.FreeRTOS.org/training - Investing in training allows your team to\r
+    be as productive as possible as early as possible.  Now you can receive\r
+    FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
+    Ltd, and the world's leading authority on the world's leading RTOS.\r
+\r
+    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+    including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
+    compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
+\r
+    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
+    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
+\r
+    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
+    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
+    licenses offer ticketed support, indemnification and commercial middleware.\r
+\r
+    http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+    engineered and independently SIL3 certified version for use in safety and\r
+    mission critical applications that require provable dependability.\r
+\r
+    1 tab == 4 spaces!\r
+*/\r
+\r
+#ifndef FREERTOS_CONFIG_H\r
+#define FREERTOS_CONFIG_H\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#include "em_chip.h"\r
+#include "em_cmu.h"\r
+\r
+/*-----------------------------------------------------------\r
+ * Application specific definitions.\r
+ *\r
+ * These definitions should be adjusted for your particular hardware and\r
+ * application requirements.\r
+ *\r
+ * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE\r
+ * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.\r
+ *\r
+ * See http://www.freertos.org/a00110.html.\r
+ *----------------------------------------------------------*/\r
+\r
+\r
+/* Set configCREATE_LOW_POWER_DEMO as follows:\r
+ *\r
+ * 0: Build the full test and demo application.\r
+ * 1: Build the simple blinky tickless low power demo, generating the tick\r
+ *    interrupt from the RTCC.  EM2 will be entered.  The LXFO clock is used.\r
+ *  See the comments at the top of main.c, main_full.c and main_low_power.c for\r
+ *  more information.\r
+ */\r
+#define configCREATE_LOW_POWER_DEMO    1\r
+\r
+/* Some configuration is dependent on the demo being built. */\r
+#if( configCREATE_LOW_POWER_DEMO == 0 )\r
+\r
+       /* Tickless mode is not used. */\r
+\r
+       /* Some of the standard demo test tasks assume a tick rate of 1KHz, even\r
+       though that is faster than would normally be warranted by a real\r
+       application. */\r
+       #define configTICK_RATE_HZ                              ( 1000 )\r
+\r
+       /* The full demo always has tasks to run so the tick will never be turned\r
+       off.  The blinky demo will use the default tickless idle implementation to\r
+       turn the tick off. */\r
+       #define configUSE_TICKLESS_IDLE                 0\r
+\r
+       /* Hook function related definitions. */\r
+       #define configUSE_TICK_HOOK                             ( 1 )\r
+       #define configCHECK_FOR_STACK_OVERFLOW  ( 1 )\r
+       #define configUSE_MALLOC_FAILED_HOOK    ( 1 )\r
+       #define configUSE_IDLE_HOOK                     ( 1 )\r
+\r
+       #define configENERGY_MODE                               ( sleepEM3 )\r
+\r
+#else\r
+\r
+       /* Tickless idle mode, generating RTOS tick interrupts from the RTC, fed\r
+       by the LXFO clock. */\r
+\r
+       /* The slow clock used to generate the tick interrupt in the low power demo\r
+       runs at 32768/8=4096Hz.  Ensure the tick rate is a multiple of the clock. */\r
+       #define configTICK_RATE_HZ                              ( 128 )\r
+\r
+       /* The low power demo uses the tickless idle feature. */\r
+       #define configUSE_TICKLESS_IDLE                 1\r
+\r
+       /* Hook function related definitions. */\r
+       #define configUSE_TICK_HOOK                             ( 0 )\r
+       #define configCHECK_FOR_STACK_OVERFLOW  ( 0 )\r
+       #define configUSE_MALLOC_FAILED_HOOK    ( 0 )\r
+       #define configUSE_IDLE_HOOK                             ( 0 )\r
+\r
+#endif\r
+\r
+/* Main functions*/\r
+#define configUSE_PREEMPTION                                   ( 1 )\r
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION        ( 1 )\r
+#define configSUPPORT_STATIC_ALLOCATION                        ( 1 )\r
+#define configCPU_CLOCK_HZ                                             ( CMU_ClockFreqGet( cmuClock_CORE ) )\r
+#define configMAX_PRIORITIES                                   ( 6 )\r
+#define configMINIMAL_STACK_SIZE                               (( unsigned short ) 130)\r
+#define configTOTAL_HEAP_SIZE                                  (( size_t )(25000))\r
+#define configMAX_TASK_NAME_LEN                                        ( 10 )\r
+#define configUSE_TRACE_FACILITY                               ( 0 )\r
+#define configUSE_16_BIT_TICKS                                 ( 0 )\r
+#define configIDLE_SHOULD_YIELD                                        ( 0 )\r
+#define configUSE_MUTEXES                                              ( 1 )\r
+#define configUSE_RECURSIVE_MUTEXES                            ( 1 )\r
+#define configUSE_COUNTING_SEMAPHORES                  ( 1 )\r
+#define configUSE_ALTERNATIVE_API                              ( 0 )/* Deprecated! */\r
+#define configQUEUE_REGISTRY_SIZE                              ( 10 )\r
+#define configUSE_QUEUE_SETS                                   ( 0 )\r
+\r
+/* Run time stats gathering related definitions. */\r
+#define configGENERATE_RUN_TIME_STATS                  ( 0 )\r
+\r
+/* Co-routine related definitions. */\r
+#define configUSE_CO_ROUTINES                                  ( 0 )\r
+#define configMAX_CO_ROUTINE_PRIORITIES                        ( 1 )\r
+\r
+/* Software timer related definitions. */\r
+#define configUSE_TIMERS                                               ( 1 )\r
+#define configTIMER_TASK_PRIORITY                              ( configMAX_PRIORITIES - 1 ) /* Highest priority */\r
+#define configTIMER_QUEUE_LENGTH                               ( 10 )\r
+#define configTIMER_TASK_STACK_DEPTH                   ( configMINIMAL_STACK_SIZE )\r
+\r
+/* Cortex-M specific definitions. */\r
+#ifdef __NVIC_PRIO_BITS\r
+       /* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */\r
+       #define configPRIO_BITS                __NVIC_PRIO_BITS\r
+#else\r
+       #define configPRIO_BITS                3        /* 7 priority levels */\r
+#endif\r
+\r
+/* The lowest interrupt priority that can be used in a call to a "set priority"\r
+function. */\r
+#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY                        0x07\r
+\r
+/* The highest interrupt priority that can be used by any interrupt service\r
+routine that makes calls to interrupt safe FreeRTOS API functions.  DO NOT CALL\r
+INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER\r
+PRIORITY THAN THIS! (higher priorities are lower numeric values. */\r
+#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY   0x05\r
+\r
+/* Interrupt priorities used by the kernel port layer itself.  These are generic\r
+to all Cortex-M ports, and do not rely on any particular library functions. */\r
+#define configKERNEL_INTERRUPT_PRIORITY                 ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )\r
+/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!\r
+See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */\r
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY    ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )\r
+\r
+\r
+/* Optional functions - most linkers will remove unused functions anyway. */\r
+#define INCLUDE_vTaskPrioritySet                               ( 1 )\r
+#define INCLUDE_uxTaskPriorityGet                              ( 1 )\r
+#define INCLUDE_vTaskDelete                                            ( 1 )\r
+#define INCLUDE_vTaskSuspend                                   ( 1 )\r
+#define INCLUDE_xResumeFromISR                                 ( 1 )\r
+#define INCLUDE_vTaskDelayUntil                                        ( 1 )\r
+#define INCLUDE_vTaskDelay                                             ( 1 )\r
+#define INCLUDE_xTaskGetSchedulerState                 ( 1 )\r
+#define INCLUDE_xTaskGetCurrentTaskHandle              ( 1 )\r
+#define INCLUDE_uxTaskGetStackHighWaterMark            ( 0 )\r
+#define INCLUDE_xTaskGetIdleTaskHandle                 ( 0 )\r
+#define INCLUDE_xTimerGetTimerDaemonTaskHandle ( 0 )\r
+#define INCLUDE_pcTaskGetTaskName                              ( 0 )\r
+#define INCLUDE_eTaskGetState                                  ( 1 )\r
+#define INCLUDE_xTimerPendFunctionCall                 ( 1 )\r
+\r
+/* Stop if an assertion fails. */\r
+#define configASSERT( x )      if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }\r
+\r
+/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS\r
+standard names. */\r
+#define vPortSVCHandler                SVC_Handler\r
+#define xPortPendSVHandler      PendSV_Handler\r
+#define xPortSysTickHandler    SysTick_Handler\r
+\r
+/* For the linker. */\r
+#define fabs __builtin_fabs\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+#endif /* FREERTOS_CONFIG_H */\r
+\r
diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/Full_Demo/RegTest.c b/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/Full_Demo/RegTest.c
new file mode 100644 (file)
index 0000000..08e2319
--- /dev/null
@@ -0,0 +1,228 @@
+/*\r
+    FreeRTOS V9.0.0rc1 - Copyright (C) 2016 Real Time Engineers Ltd.\r
+    All rights reserved\r
+\r
+    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+    This file is part of the FreeRTOS distribution.\r
+\r
+    FreeRTOS is free software; you can redistribute it and/or modify it under\r
+    the terms of the GNU General Public License (version 2) as published by the\r
+    Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.\r
+\r
+    ***************************************************************************\r
+    >>!   NOTE: The modification to the GPL is included to allow you to     !<<\r
+    >>!   distribute a combined work that includes FreeRTOS without being   !<<\r
+    >>!   obliged to provide the source code for proprietary components     !<<\r
+    >>!   outside of the FreeRTOS kernel.                                   !<<\r
+    ***************************************************************************\r
+\r
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+    FOR A PARTICULAR PURPOSE.  Full license text is available on the following\r
+    link: http://www.freertos.org/a00114.html\r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS provides completely free yet professionally developed,    *\r
+     *    robust, strictly quality controlled, supported, and cross          *\r
+     *    platform software that is more than just the market leader, it     *\r
+     *    is the industry's de facto standard.                               *\r
+     *                                                                       *\r
+     *    Help yourself get started quickly while simultaneously helping     *\r
+     *    to support the FreeRTOS project by purchasing a FreeRTOS           *\r
+     *    tutorial book, reference manual, or both:                          *\r
+     *    http://www.FreeRTOS.org/Documentation                              *\r
+     *                                                                       *\r
+    ***************************************************************************\r
+\r
+    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading\r
+    the FAQ page "My application does not run, what could be wrong?".  Have you\r
+    defined configASSERT()?\r
+\r
+    http://www.FreeRTOS.org/support - In return for receiving this top quality\r
+    embedded software for free we request you assist our global community by\r
+    participating in the support forum.\r
+\r
+    http://www.FreeRTOS.org/training - Investing in training allows your team to\r
+    be as productive as possible as early as possible.  Now you can receive\r
+    FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
+    Ltd, and the world's leading authority on the world's leading RTOS.\r
+\r
+    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+    including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
+    compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
+\r
+    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
+    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
+\r
+    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
+    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
+    licenses offer ticketed support, indemnification and commercial middleware.\r
+\r
+    http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+    engineered and independently SIL3 certified version for use in safety and\r
+    mission critical applications that require provable dependability.\r
+\r
+    1 tab == 4 spaces!\r
+*/\r
+\r
+/*\r
+ * "Reg test" tasks - These fill the registers with known values, then check\r
+ * that each register maintains its expected value for the lifetime of the\r
+ * task.  Each task uses a different set of values.  The reg test tasks execute\r
+ * with a very low priority, so get preempted very frequently.  A register\r
+ * containing an unexpected value is indicative of an error in the context\r
+ * switching mechanism.\r
+ */\r
+\r
+void vRegTest1Implementation( void ) __attribute__ ((naked));\r
+void vRegTest2Implementation( void ) __attribute__ ((naked));\r
+\r
+void vRegTest1Implementation( void )\r
+{\r
+       __asm volatile\r
+       (\r
+               ".extern ulRegTest1LoopCounter \n"\r
+               "/* Fill the core registers with known values. */               \n"\r
+               "mov    r0, #100                        \n"\r
+               "mov    r1, #101                        \n"\r
+               "mov    r2, #102                        \n"\r
+               "mov    r3, #103                        \n"\r
+               "mov    r4, #104                        \n"\r
+               "mov    r5, #105                        \n"\r
+               "mov    r6, #106                        \n"\r
+               "mov    r7, #107                        \n"\r
+               "mov    r8, #108                        \n"\r
+               "mov    r9, #109                        \n"\r
+               "mov    r10, #110                       \n"\r
+               "mov    r11, #111                       \n"\r
+               "mov    r12, #112                       \n"\r
+\r
+       "reg1_loop:                                             \n"\r
+\r
+               "/* Check each register has maintained its expected value. */   \n"\r
+               "cmp    r0, #100                        \n"\r
+               "bne    reg1_error_loop         \n"\r
+               "cmp    r1, #101                        \n"\r
+               "bne    reg1_error_loop         \n"\r
+               "cmp    r2, #102                        \n"\r
+               "bne    reg1_error_loop         \n"\r
+               "cmp    r3, #103                        \n"\r
+               "bne    reg1_error_loop         \n"\r
+               "cmp    r4, #104                        \n"\r
+               "bne    reg1_error_loop         \n"\r
+               "cmp    r5, #105                        \n"\r
+               "bne    reg1_error_loop         \n"\r
+               "cmp    r6, #106                        \n"\r
+               "bne    reg1_error_loop         \n"\r
+               "cmp    r7, #107                        \n"\r
+               "bne    reg1_error_loop         \n"\r
+               "cmp    r8, #108                        \n"\r
+               "bne    reg1_error_loop         \n"\r
+               "cmp    r9, #109                        \n"\r
+               "bne    reg1_error_loop         \n"\r
+               "cmp    r10, #110                       \n"\r
+               "bne    reg1_error_loop         \n"\r
+               "cmp    r11, #111                       \n"\r
+               "bne    reg1_error_loop         \n"\r
+               "cmp    r12, #112                       \n"\r
+               "bne    reg1_error_loop         \n"\r
+\r
+               "/* Everything passed, increment the loop counter. */   \n"\r
+               "push   { r0-r1 }                       \n"\r
+               "ldr    r0, =ulRegTest1LoopCounter      \n"\r
+               "ldr    r1, [r0]                        \n"\r
+               "adds   r1, r1, #1                      \n"\r
+               "str    r1, [r0]                        \n"\r
+               "pop    { r0-r1 }                       \n"\r
+\r
+               "/* Start again. */                     \n"\r
+               "b              reg1_loop                       \n"\r
+\r
+       "reg1_error_loop:                               \n"\r
+               "/* If this line is hit then there was an error in a core register value. \n"\r
+               "The loop ensures the loop counter stops incrementing. */       \n"\r
+               "b      reg1_error_loop                 \n"\r
+               "nop                                            "\r
+       ); /* __asm volatile. */\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vRegTest2Implementation( void )\r
+{\r
+       __asm volatile\r
+       (\r
+               ".extern ulRegTest2LoopCounter \n"\r
+               "/* Set all the core registers to known values. */      \n"\r
+               "mov    r0, #-1                         \n"\r
+               "mov    r1, #1                          \n"\r
+               "mov    r2, #2                          \n"\r
+               "mov    r3, #3                          \n"\r
+               "mov    r4, #4                          \n"\r
+               "mov    r5, #5                          \n"\r
+               "mov    r6, #6                          \n"\r
+               "mov    r7, #7                          \n"\r
+               "mov    r8, #8                          \n"\r
+               "mov    r9, #9                          \n"\r
+               "mov    r10, #10                        \n"\r
+               "mov    r11, #11                        \n"\r
+               "mov    r12, #12                        \n"\r
+\r
+       "reg2_loop:                                             \n"\r
+\r
+               "cmp    r0, #-1                         \n"\r
+               "bne    reg2_error_loop         \n"\r
+               "cmp    r1, #1                          \n"\r
+               "bne    reg2_error_loop         \n"\r
+               "cmp    r2, #2                          \n"\r
+               "bne    reg2_error_loop         \n"\r
+               "cmp    r3, #3                          \n"\r
+               "bne    reg2_error_loop         \n"\r
+               "cmp    r4, #4                          \n"\r
+               "bne    reg2_error_loop         \n"\r
+               "cmp    r5, #5                          \n"\r
+               "bne    reg2_error_loop         \n"\r
+               "cmp    r6, #6                          \n"\r
+               "bne    reg2_error_loop         \n"\r
+               "cmp    r7, #7                          \n"\r
+               "bne    reg2_error_loop         \n"\r
+               "cmp    r8, #8                          \n"\r
+               "bne    reg2_error_loop         \n"\r
+               "cmp    r9, #9                          \n"\r
+               "bne    reg2_error_loop         \n"\r
+               "cmp    r10, #10                        \n"\r
+               "bne    reg2_error_loop         \n"\r
+               "cmp    r11, #11                        \n"\r
+               "bne    reg2_error_loop         \n"\r
+               "cmp    r12, #12                        \n"\r
+               "bne    reg2_error_loop         \n"\r
+\r
+               "/* Increment the loop counter to indicate this test is still functioning       \n"\r
+               "correctly. */                          \n"\r
+               "push   { r0-r1 }                       \n"\r
+               "ldr    r0, =ulRegTest2LoopCounter      \n"\r
+               "ldr    r1, [r0]                        \n"\r
+               "adds   r1, r1, #1                      \n"\r
+               "str    r1, [r0]                        \n"\r
+\r
+               "/* Yield to increase test coverage. */                 \n"\r
+               "movs   r0, #0x01                       \n"\r
+               "ldr    r1, =0xe000ed04 /*NVIC_INT_CTRL */              \n"\r
+               "lsl    r0, r0, #28 /* Shift to PendSV bit */   \n"\r
+               "str    r0, [r1]                        \n"\r
+               "dsb                                            \n"\r
+\r
+               "pop { r0-r1 }                          \n"\r
+\r
+               "/* Start again. */                     \n"\r
+               "b reg2_loop                            \n"\r
+\r
+       "reg2_error_loop:                               \n"\r
+               "/* If this line is hit then there was an error in a core register value.       \n"\r
+               "This loop ensures the loop counter variable stops incrementing. */                     \n"\r
+               "b reg2_error_loop                      \n"\r
+       ); /* __asm volatile */\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/Full_Demo/main_full.c b/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/Full_Demo/main_full.c
new file mode 100644 (file)
index 0000000..67ccd0a
--- /dev/null
@@ -0,0 +1,414 @@
+/*\r
+    FreeRTOS V9.0.0rc1 - Copyright (C) 2016 Real Time Engineers Ltd.\r
+    All rights reserved\r
+\r
+    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+    This file is part of the FreeRTOS distribution.\r
+\r
+    FreeRTOS is free software; you can redistribute it and/or modify it under\r
+    the terms of the GNU General Public License (version 2) as published by the\r
+    Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.\r
+\r
+    ***************************************************************************\r
+    >>!   NOTE: The modification to the GPL is included to allow you to     !<<\r
+    >>!   distribute a combined work that includes FreeRTOS without being   !<<\r
+    >>!   obliged to provide the source code for proprietary components     !<<\r
+    >>!   outside of the FreeRTOS kernel.                                   !<<\r
+    ***************************************************************************\r
+\r
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+    FOR A PARTICULAR PURPOSE.  Full license text is available on the following\r
+    link: http://www.freertos.org/a00114.html\r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS provides completely free yet professionally developed,    *\r
+     *    robust, strictly quality controlled, supported, and cross          *\r
+     *    platform software that is more than just the market leader, it     *\r
+     *    is the industry's de facto standard.                               *\r
+     *                                                                       *\r
+     *    Help yourself get started quickly while simultaneously helping     *\r
+     *    to support the FreeRTOS project by purchasing a FreeRTOS           *\r
+     *    tutorial book, reference manual, or both:                          *\r
+     *    http://www.FreeRTOS.org/Documentation                              *\r
+     *                                                                       *\r
+    ***************************************************************************\r
+\r
+    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading\r
+    the FAQ page "My application does not run, what could be wrong?".  Have you\r
+    defined configASSERT()?\r
+\r
+    http://www.FreeRTOS.org/support - In return for receiving this top quality\r
+    embedded software for free we request you assist our global community by\r
+    participating in the support forum.\r
+\r
+    http://www.FreeRTOS.org/training - Investing in training allows your team to\r
+    be as productive as possible as early as possible.  Now you can receive\r
+    FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
+    Ltd, and the world's leading authority on the world's leading RTOS.\r
+\r
+    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+    including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
+    compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
+\r
+    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
+    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
+\r
+    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
+    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
+    licenses offer ticketed support, indemnification and commercial middleware.\r
+\r
+    http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+    engineered and independently SIL3 certified version for use in safety and\r
+    mission critical applications that require provable dependability.\r
+\r
+    1 tab == 4 spaces!\r
+*/\r
+\r
+/******************************************************************************\r
+ * NOTE 1:  This project provides two demo applications.  A simple blinky style\r
+ * project that demonstrates the tickless low power features of FreeRTOS, and a\r
+ * more comprehensive test and demo application.  The configCREATE_LOW_POWER_DEMO\r
+ * setting in FreeRTOSConifg.h is used to select between the two, and to select\r
+ * the clock used when tickless mode is used.  See the notes on using\r
+ * conifgCREATE_LOW_POWER_DEMO in main.c.  This file implements the\r
+ * comprehensive test and demo version.\r
+ *\r
+ * NOTE 2:  This file only contains the source code that is specific to the\r
+ * full demo.  Generic functions, such FreeRTOS hook functions, and functions\r
+ * required to configure the hardware, are defined in main.c.\r
+ *\r
+ ******************************************************************************\r
+ *\r
+ * main_full() creates all the demo application tasks and software timers, then\r
+ * starts the scheduler.  The web documentation provides more details of the\r
+ * standard demo application tasks, which provide no particular functionality,\r
+ * but do provide a good example of how to use the FreeRTOS API.\r
+ *\r
+ * In addition to the standard demo tasks, the following tasks and tests are\r
+ * defined and/or created within this file:\r
+ *\r
+ * "Reg test" tasks - These fill both the core and floating point registers with\r
+ * known values, then check that each register maintains its expected value for\r
+ * the lifetime of the task.  Each task uses a different set of values.  The reg\r
+ * test tasks execute with a very low priority, so get preempted very\r
+ * frequently.  A register containing an unexpected value is indicative of an\r
+ * error in the context switching mechanism.\r
+ *\r
+ * "Check" task - The check task period is initially set to three seconds.  The\r
+ * task checks that all the standard demo tasks, and the register check tasks,\r
+ * are not only still executing, but are executing without reporting any errors.\r
+ * If the check task discovers that a task has either stalled, or reported an\r
+ * error, then it changes its own execution period from the initial three\r
+ * seconds, to just 200ms.  The check task also toggles an LED each time it is\r
+ * called.  This provides a visual indication of the system status:  If the LED\r
+ * toggles every three seconds, then no issues have been discovered.  If the LED\r
+ * toggles every 200ms, then an issue has been discovered with at least one\r
+ * task.\r
+ */\r
+\r
+/* Standard includes. */\r
+#include <stdio.h>\r
+\r
+/* Kernel includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "timers.h"\r
+#include "semphr.h"\r
+\r
+/* SiLabs includes. */\r
+#include "bsp.h"\r
+\r
+/* Standard demo application includes. */\r
+#include "flop.h"\r
+#include "semtest.h"\r
+#include "dynamic.h"\r
+#include "blocktim.h"\r
+#include "GenQTest.h"\r
+#include "recmutex.h"\r
+#include "TimerDemo.h"\r
+#include "EventGroupsDemo.h"\r
+#include "TaskNotify.h"\r
+#include "StaticAllocation.h"\r
+\r
+/* Priorities for the demo application tasks. */\r
+#define mainSEM_TEST_PRIORITY                          ( tskIDLE_PRIORITY + 1UL )\r
+#define mainCREATOR_TASK_PRIORITY                      ( tskIDLE_PRIORITY + 3UL )\r
+#define mainFLOP_TASK_PRIORITY                         ( tskIDLE_PRIORITY )\r
+#define mainCHECK_TASK_PRIORITY                                ( configMAX_PRIORITIES - 1 )\r
+\r
+/* A block time of zero simply means "don't block". */\r
+#define mainDONT_BLOCK                                         ( 0UL )\r
+\r
+/* The period after which the check timer will expire, in ms, provided no errors\r
+have been reported by any of the standard demo tasks.  ms are converted to the\r
+equivalent in ticks using the portTICK_PERIOD_MS constant. */\r
+#define mainNO_ERROR_CHECK_TASK_PERIOD         ( 3000UL / portTICK_PERIOD_MS )\r
+\r
+/* The period at which the check timer will expire, in ms, if an error has been\r
+reported in one of the standard demo tasks.  ms are converted to the equivalent\r
+in ticks using the portTICK_PERIOD_MS constant. */\r
+#define mainERROR_CHECK_TASK_PERIOD            pdMS_TO_TICKS( 200UL )\r
+\r
+/* Parameters that are passed into the register check tasks solely for the\r
+purpose of ensuring parameters are passed into tasks correctly. */\r
+#define mainREG_TEST_TASK_1_PARAMETER          ( ( void * ) 0x12345678 )\r
+#define mainREG_TEST_TASK_2_PARAMETER          ( ( void * ) 0x87654321 )\r
+\r
+/* The base period used by the timer test tasks. */\r
+#define mainTIMER_TEST_PERIOD                          ( 50 )\r
+\r
+/* The LED toggled by the check task. */\r
+#define mainTASK_LED                                           ( 0 )\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Called by main() to run the full demo (as opposed to the blinky demo) when\r
+ * mainCREATE_LOW_POWER_DEMO is set to 0.\r
+ */\r
+void main_full( void );\r
+\r
+/*\r
+ * The check task, as described at the top of this file.\r
+ */\r
+static void prvCheckTask( void *pvParameters );\r
+\r
+/*\r
+ * Some of the tests and demo tasks executed by the full demo include\r
+ * interaction from an interrupt - for which the tick interrupt is used via the\r
+ * tick hook function.\r
+ */\r
+void vFullDemoTickHook( void );\r
+\r
+/*\r
+ * Register check tasks, and the tasks used to write over and check the contents\r
+ * of the FPU registers, as described at the top of this file.  The nature of\r
+ * these files necessitates that they are written in an assembly file, but the\r
+ * entry points are kept in the C file for the convenience of checking the task\r
+ * parameter.\r
+ */\r
+static void prvRegTestTaskEntry1( void *pvParameters );\r
+extern void vRegTest1Implementation( void );\r
+static void prvRegTestTaskEntry2( void *pvParameters );\r
+extern void vRegTest2Implementation( void );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* The following two variables are used to communicate the status of the\r
+register check tasks to the check task.  If the variables keep incrementing,\r
+then the register check tasks have not discovered any errors.  If a variable\r
+stops incrementing, then an error has been found. */\r
+volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;\r
+\r
+/* The variable incremented in lieu of having a proper LED outout. */\r
+extern volatile uint32_t ulLED;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void main_full( void )\r
+{\r
+       /* Start all the other standard demo/test tasks.  They have no particular\r
+       functionality, but do demonstrate how to use the FreeRTOS API and test the\r
+       kernel port. */\r
+       vStartDynamicPriorityTasks();\r
+       vCreateBlockTimeTasks();\r
+       vStartGenericQueueTasks( tskIDLE_PRIORITY );\r
+       vStartRecursiveMutexTasks();\r
+       vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );\r
+       vStartMathTasks( mainFLOP_TASK_PRIORITY );\r
+       vStartTimerDemoTask( mainTIMER_TEST_PERIOD );\r
+       vStartEventGroupTasks();\r
+       vStartTaskNotifyTask();\r
+       vStartStaticallyAllocatedTasks();\r
+\r
+       /* Create the register check tasks, as described at the top of this     file */\r
+       xTaskCreate( prvRegTestTaskEntry1, "Reg1", configMINIMAL_STACK_SIZE, mainREG_TEST_TASK_1_PARAMETER, tskIDLE_PRIORITY, NULL );\r
+       xTaskCreate( prvRegTestTaskEntry2, "Reg2", configMINIMAL_STACK_SIZE, mainREG_TEST_TASK_2_PARAMETER, tskIDLE_PRIORITY, NULL );\r
+\r
+       /* Create the task that performs the 'check' functionality,     as described at\r
+       the top of this file. */\r
+       xTaskCreate( prvCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );\r
+\r
+       /* Start the scheduler. */\r
+       vTaskStartScheduler();\r
+\r
+       /* If all is well, the scheduler will now be running, and the following\r
+       line will never be reached.  If the following line does execute, then\r
+       there was insufficient FreeRTOS heap memory available for the Idle and/or\r
+       timer tasks to be created.  See the memory management section on the\r
+       FreeRTOS web site for more details on the FreeRTOS heap\r
+       http://www.freertos.org/a00111.html. */\r
+       for( ;; );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvCheckTask( void *pvParameters )\r
+{\r
+TickType_t xDelayPeriod = mainNO_ERROR_CHECK_TASK_PERIOD;\r
+TickType_t xLastExecutionTime;\r
+static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;\r
+unsigned long ulErrorFound = pdFALSE;\r
+\r
+       /* Just to stop compiler warnings. */\r
+       ( void ) pvParameters;\r
+\r
+       /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()\r
+       works correctly. */\r
+       xLastExecutionTime = xTaskGetTickCount();\r
+\r
+       /* Cycle for ever, delaying then checking all the other tasks are still\r
+       operating without error.  The onboard LED is toggled on each iteration.\r
+       If an error is detected then the delay period is decreased from\r
+       mainNO_ERROR_CHECK_TASK_PERIOD to mainERROR_CHECK_TASK_PERIOD.  This has the\r
+       effect of increasing the rate at which the onboard LED toggles, and in so\r
+       doing gives visual feedback of the system status. */\r
+       for( ;; )\r
+       {\r
+               /* Delay until it is time to execute again. */\r
+               vTaskDelayUntil( &xLastExecutionTime, xDelayPeriod );\r
+\r
+               /* Check all the demo tasks (other than the flash tasks) to ensure\r
+               that they are all still running, and that none have detected an error. */\r
+               if( xAreMathsTaskStillRunning() != pdTRUE )\r
+               {\r
+                       ulErrorFound = 1UL << 1UL;\r
+               }\r
+\r
+               if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )\r
+               {\r
+                       ulErrorFound = 1UL << 2UL;\r
+               }\r
+\r
+               if( xAreStaticAllocationTasksStillRunning() != pdPASS )\r
+               {\r
+                       ulErrorFound = 1UL << 3UL;\r
+               }\r
+\r
+               if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE )\r
+               {\r
+                       ulErrorFound = 1UL << 4UL;\r
+               }\r
+\r
+               if ( xAreGenericQueueTasksStillRunning() != pdTRUE )\r
+               {\r
+                       ulErrorFound = 1UL << 5UL;\r
+               }\r
+\r
+               if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE )\r
+               {\r
+                       ulErrorFound = 1UL << 6UL;\r
+               }\r
+\r
+               if( xAreSemaphoreTasksStillRunning() != pdTRUE )\r
+               {\r
+                       ulErrorFound = 1UL << 8UL;\r
+               }\r
+\r
+               if( xAreTimerDemoTasksStillRunning( ( TickType_t ) xDelayPeriod ) != pdPASS )\r
+               {\r
+                       ulErrorFound = 1UL << 9UL;\r
+               }\r
+\r
+               if( xAreEventGroupTasksStillRunning() != pdPASS )\r
+               {\r
+                       ulErrorFound = 1UL << 12UL;\r
+               }\r
+\r
+               if( xAreTaskNotificationTasksStillRunning() != pdPASS )\r
+               {\r
+                       ulErrorFound = 1UL << 14UL;\r
+               }\r
+\r
+               /* Check that the register test 1 task is still running. */\r
+               if( ulLastRegTest1Value == ulRegTest1LoopCounter )\r
+               {\r
+                       ulErrorFound = 1UL << 15UL;\r
+               }\r
+               ulLastRegTest1Value = ulRegTest1LoopCounter;\r
+\r
+               /* Check that the register test 2 task is still running. */\r
+               if( ulLastRegTest2Value == ulRegTest2LoopCounter )\r
+               {\r
+                       ulErrorFound = 1UL << 16UL;\r
+               }\r
+               ulLastRegTest2Value = ulRegTest2LoopCounter;\r
+\r
+               /* Toggle the check LED to give an indication of the system status.  If\r
+               the LED toggles every mainNO_ERROR_CHECK_TASK_PERIOD milliseconds then\r
+               everything is ok.  A faster toggle indicates an error. */\r
+               BSP_LedToggle( mainTASK_LED );\r
+\r
+               if( ulErrorFound != pdFALSE )\r
+               {\r
+                       /* An error has been detected in one of the tasks - flash the LED\r
+                       at a higher frequency to give visible feedback that something has\r
+                       gone wrong. */\r
+                       xDelayPeriod = mainERROR_CHECK_TASK_PERIOD;\r
+               }\r
+\r
+               configASSERT( ulErrorFound == pdFALSE );\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvRegTestTaskEntry1( void *pvParameters )\r
+{\r
+       /* Although the regtest task is written in assembler, its entry point is\r
+       written in C for convenience of checking the task parameter is being passed\r
+       in correctly. */\r
+       if( pvParameters == mainREG_TEST_TASK_1_PARAMETER )\r
+       {\r
+               /* Start the part of the test that is written in assembler. */\r
+               vRegTest1Implementation();\r
+       }\r
+\r
+       /* The following line will only execute if the task parameter is found to\r
+       be incorrect.  The check timer will detect that the regtest loop counter is\r
+       not being incremented and flag an error. */\r
+       vTaskDelete( NULL );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvRegTestTaskEntry2( void *pvParameters )\r
+{\r
+       /* Although the regtest task is written in assembler, its entry point is\r
+       written in C for convenience of checking the task parameter is being passed\r
+       in correctly. */\r
+       if( pvParameters == mainREG_TEST_TASK_2_PARAMETER )\r
+       {\r
+               /* Start the part of the test that is written in assembler. */\r
+               vRegTest2Implementation();\r
+       }\r
+\r
+       /* The following line will only execute if the task parameter is found to\r
+       be incorrect.  The check timer will detect that the regtest loop counter is\r
+       not being incremented and flag an error. */\r
+       vTaskDelete( NULL );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vFullDemoTickHook( void )\r
+{\r
+       /* Some of the tests and demo tasks executed by the full demo include\r
+       interaction from an interrupt - for which the tick interrupt is used via\r
+       the tick hook function. */\r
+\r
+       /* The full demo includes a software timer demo/test that requires\r
+       prodding periodically from the tick interrupt. */\r
+       vTimerPeriodicISRTests();\r
+\r
+       /* Call the periodic event group from ISR demo. */\r
+       vPeriodicEventGroupsProcessing();\r
+\r
+       /* Call the code that 'gives' a task notification from an ISR. */\r
+       xNotifyTaskFromISR();\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/Low_Power_Demo/low_power_tick_management_RTCC.c b/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/Low_Power_Demo/low_power_tick_management_RTCC.c
new file mode 100644 (file)
index 0000000..6e75bae
--- /dev/null
@@ -0,0 +1,382 @@
+/*\r
+    FreeRTOS V9.0.0rc1 - Copyright (C) 2016 Real Time Engineers Ltd.\r
+    All rights reserved\r
+\r
+    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+    This file is part of the FreeRTOS distribution.\r
+\r
+    FreeRTOS is free software; you can redistribute it and/or modify it under\r
+    the terms of the GNU General Public License (version 2) as published by the\r
+    Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.\r
+\r
+    ***************************************************************************\r
+    >>!   NOTE: The modification to the GPL is included to allow you to     !<<\r
+    >>!   distribute a combined work that includes FreeRTOS without being   !<<\r
+    >>!   obliged to provide the source code for proprietary components     !<<\r
+    >>!   outside of the FreeRTOS kernel.                                   !<<\r
+    ***************************************************************************\r
+\r
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+    FOR A PARTICULAR PURPOSE.  Full license text is available on the following\r
+    link: http://www.freertos.org/a00114.html\r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS provides completely free yet professionally developed,    *\r
+     *    robust, strictly quality controlled, supported, and cross          *\r
+     *    platform software that is more than just the market leader, it     *\r
+     *    is the industry's de facto standard.                               *\r
+     *                                                                       *\r
+     *    Help yourself get started quickly while simultaneously helping     *\r
+     *    to support the FreeRTOS project by purchasing a FreeRTOS           *\r
+     *    tutorial book, reference manual, or both:                          *\r
+     *    http://www.FreeRTOS.org/Documentation                              *\r
+     *                                                                       *\r
+    ***************************************************************************\r
+\r
+    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading\r
+    the FAQ page "My application does not run, what could be wrong?".  Have you\r
+    defined configASSERT()?\r
+\r
+    http://www.FreeRTOS.org/support - In return for receiving this top quality\r
+    embedded software for free we request you assist our global community by\r
+    participating in the support forum.\r
+\r
+    http://www.FreeRTOS.org/training - Investing in training allows your team to\r
+    be as productive as possible as early as possible.  Now you can receive\r
+    FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
+    Ltd, and the world's leading authority on the world's leading RTOS.\r
+\r
+    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+    including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
+    compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
+\r
+    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
+    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
+\r
+    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
+    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
+    licenses offer ticketed support, indemnification and commercial middleware.\r
+\r
+    http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+    engineered and independently SIL3 certified version for use in safety and\r
+    mission critical applications that require provable dependability.\r
+\r
+    1 tab == 4 spaces!\r
+*/\r
+\r
+/* Standard inlcludes. */\r
+#include <limits.h>\r
+\r
+/* FreeRTOS includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+\r
+/* SiLabs library includes. */\r
+#include "em_cmu.h"\r
+#include "em_rtcc.h"\r
+#include "em_rmu.h"\r
+#include "em_int.h"\r
+#include "sleep.h"\r
+\r
+/* SEE THE COMMENTS ABOVE THE DEFINITION OF configCREATE_LOW_POWER_DEMO IN\r
+FreeRTOSConfig.h\r
+This file contains functions that will override the default implementations\r
+in the RTOS port layer.  Therefore only build this file if the low power demo\r
+is being built. */\r
+#if( configCREATE_LOW_POWER_DEMO == 1 )\r
+\r
+/* The RTCC channel used to generate the tick interrupt. */\r
+#define lpRTCC_CHANNEL         ( 1 )\r
+\r
+/* 32768 clock divided by 1.  Don't use a prescale if errata RTCC_E201\r
+applies. */\r
+#define mainTIMER_FREQUENCY_HZ ( 32768UL )\r
+\r
+/*\r
+ * The low power demo does not use the SysTick, so override the\r
+ * vPortSetupTickInterrupt() function with an implementation that configures\r
+ * a low power clock source.  NOTE:  This function name must not be changed as\r
+ * it is called from the RTOS portable layer.\r
+ */\r
+void vPortSetupTimerInterrupt( void );\r
+\r
+/*\r
+ * Override the default definition of vPortSuppressTicksAndSleep() that is\r
+ * weakly defined in the FreeRTOS Cortex-M port layer with a version that\r
+ * manages the RTC clock, as the tick is generated from the low power RTC\r
+ * and not the SysTick as would normally be the case on a Cortex-M.\r
+ */\r
+void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Calculate how many clock increments make up a single tick period. */\r
+static const uint32_t ulReloadValueForOneTick = ( mainTIMER_FREQUENCY_HZ / configTICK_RATE_HZ );\r
+\r
+/* Will hold the maximum number of ticks that can be suppressed. */\r
+static uint32_t xMaximumPossibleSuppressedTicks = 0;\r
+\r
+/* Flag set from the tick interrupt to allow the sleep processing to know if\r
+sleep mode was exited because of a timer interrupt or a different interrupt. */\r
+static volatile uint32_t ulTickFlag = pdFALSE;\r
+\r
+/* As the clock is only 32KHz, it is likely a value of 1 will be enough. */\r
+static const uint32_t ulStoppedTimerCompensation = 0UL;\r
+\r
+/* RTCC configuration structures. */\r
+static const RTCC_Init_TypeDef xRTCInitStruct =\r
+{\r
+       false,                /* Don't start counting when init complete. */\r
+       false,                /* Disable counter during debug halt. */\r
+       false,                /* Don't care. */\r
+       true,                 /* Enable counter wrap on ch. 1 CCV value. */\r
+       rtccCntPresc_1,       /* NOTE:  Do not use a pre-scale if errata RTCC_E201 applies. */\r
+       rtccCntTickPresc,     /* Count using the clock input directly. */\r
+#if defined(_RTCC_CTRL_BUMODETSEN_MASK)\r
+       false,                /* Disable storing RTCC counter value in RTCC_CCV2 upon backup mode entry. */\r
+#endif\r
+       false,                /* Oscillator fail detection disabled. */\r
+       rtccCntModeNormal,    /* Use RTCC in normal mode (increment by 1 on each tick) and not in calendar mode. */\r
+       false                 /* Don't care. */\r
+};\r
+\r
+static const RTCC_CCChConf_TypeDef xRTCCChannel1InitStruct =\r
+{\r
+       rtccCapComChModeCompare,    /* Use Compare mode. */\r
+       rtccCompMatchOutActionPulse,/* Don't care. */\r
+       rtccPRSCh0,                 /* PRS not used. */\r
+       rtccInEdgeNone,             /* Capture Input not used. */\r
+       rtccCompBaseCnt,            /* Compare with Base CNT register. */\r
+       0,                          /* Compare mask. */\r
+       rtccDayCompareModeMonth     /* Don't care. */\r
+};\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void vPortSetupTimerInterrupt( void )\r
+{\r
+       /* Configure the RTCC to generate the RTOS tick interrupt. */\r
+\r
+       /* The maximum number of ticks that can be suppressed depends on the clock\r
+       frequency. */\r
+       xMaximumPossibleSuppressedTicks = ULONG_MAX / ulReloadValueForOneTick;\r
+\r
+       /* Ensure LE modules are accessible. */\r
+       CMU_ClockEnable( cmuClock_CORELE, true );\r
+\r
+       /* Use LFXO. */\r
+       CMU_ClockSelectSet( cmuClock_LFE, cmuSelect_LFXO );\r
+\r
+       /* Enable clock to the RTC module. */\r
+       CMU_ClockEnable( cmuClock_RTCC, true );\r
+\r
+       /* Use channel 1 to generate the RTOS tick interrupt. */\r
+       RTCC_ChannelCCVSet( lpRTCC_CHANNEL, ulReloadValueForOneTick );\r
+\r
+       RTCC_Init( &xRTCInitStruct );\r
+       RTCC_ChannelInit( lpRTCC_CHANNEL, &xRTCCChannel1InitStruct );\r
+       RTCC_EM4WakeupEnable( true );\r
+\r
+       /* Disable RTCC interrupt. */\r
+       RTCC_IntDisable( _RTCC_IF_MASK );\r
+       RTCC_IntClear( _RTCC_IF_MASK );\r
+       RTCC->CNT = _RTCC_CNT_RESETVALUE;\r
+\r
+       /* The tick interrupt must be set to the lowest priority possible. */\r
+       NVIC_SetPriority( RTCC_IRQn, configLIBRARY_LOWEST_INTERRUPT_PRIORITY );\r
+       NVIC_ClearPendingIRQ( RTCC_IRQn );\r
+       NVIC_EnableIRQ( RTCC_IRQn );\r
+       RTCC_IntEnable( RTCC_IEN_CC1 );\r
+       RTCC_Enable( true );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )\r
+{\r
+uint32_t ulReloadValue, ulCompleteTickPeriods, ulCountBeforeSleep, ulCountAfterSleep;\r
+eSleepModeStatus eSleepAction;\r
+TickType_t xModifiableIdleTime;\r
+\r
+       /* THIS FUNCTION IS CALLED WITH THE SCHEDULER SUSPENDED. */\r
+\r
+       /* Make sure the RTC reload value does not overflow the counter. */\r
+       if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks )\r
+       {\r
+               xExpectedIdleTime = xMaximumPossibleSuppressedTicks;\r
+       }\r
+\r
+       /* Calculate the reload value required to wait xExpectedIdleTime tick\r
+       periods. */\r
+       ulReloadValue = ulReloadValueForOneTick * xExpectedIdleTime;\r
+       if( ulReloadValue > ulStoppedTimerCompensation )\r
+       {\r
+               /* Compensate for the fact that the RTC is going to be stopped\r
+               momentarily. */\r
+               ulReloadValue -= ulStoppedTimerCompensation;\r
+       }\r
+\r
+       /* Stop the RTC momentarily.  The time the RTC is stopped for is accounted\r
+       for as best it can be, but using the tickless mode will inevitably result\r
+       in some tiny drift of the time maintained by the kernel with respect to\r
+       calendar time.  The count is latched before stopping the timer as stopping\r
+       the timer appears to clear the count. */\r
+       ulCountBeforeSleep = RTCC_CounterGet();\r
+       RTCC_Enable( false );\r
+\r
+       /* If this function is re-entered before one complete tick period then the\r
+       reload value might be set to take into account a partial time slice, but\r
+       just reading the count assumes it is counting up to a full ticks worth - so\r
+       add in the difference if any. */\r
+       ulCountBeforeSleep += ( ulReloadValueForOneTick - RTCC_ChannelCCVGet( lpRTCC_CHANNEL ) );\r
+\r
+       /* Enter a critical section but don't use the taskENTER_CRITICAL() method as\r
+       that will mask interrupts that should exit sleep mode. */\r
+       INT_Disable();\r
+       __asm volatile( "dsb" );\r
+       __asm volatile( "isb" );\r
+\r
+       /* The tick flag is set to false before sleeping.  If it is true when sleep\r
+       mode is exited then sleep mode was probably exited because the tick was\r
+       suppressed for the entire xExpectedIdleTime period. */\r
+       ulTickFlag = pdFALSE;\r
+\r
+       /* If a context switch is pending then abandon the low power entry as the\r
+       context switch might have been pended by an external interrupt that     requires\r
+       processing. */\r
+       eSleepAction = eTaskConfirmSleepModeStatus();\r
+       if( eSleepAction == eAbortSleep )\r
+       {\r
+               /* Restart tick and count up to whatever was left of the current time\r
+               slice. */\r
+               RTCC_ChannelCCVSet( lpRTCC_CHANNEL, ( ulReloadValueForOneTick - ulCountBeforeSleep ) + ulStoppedTimerCompensation );\r
+               RTCC_Enable( true );\r
+\r
+               /* Re-enable interrupts - see comments above the cpsid instruction()\r
+               above. */\r
+               INT_Enable();\r
+       }\r
+       else\r
+       {\r
+               /* Adjust the reload value to take into account that the current time\r
+               slice is already partially complete. */\r
+               ulReloadValue -= ulCountBeforeSleep;\r
+               RTCC_ChannelCCVSet( lpRTCC_CHANNEL, ulReloadValue );\r
+\r
+               /* Restart the RTC. */\r
+               RTCC_Enable( true );\r
+\r
+               /* Allow the application to define some pre-sleep processing. */\r
+               xModifiableIdleTime = xExpectedIdleTime;\r
+               configPRE_SLEEP_PROCESSING( xModifiableIdleTime );\r
+\r
+               /* xExpectedIdleTime being set to 0 by configPRE_SLEEP_PROCESSING()\r
+               means the application defined code has already executed the WAIT\r
+               instruction. */\r
+               if( xModifiableIdleTime > 0 )\r
+               {\r
+                       __asm volatile( "dsb" );\r
+                       SLEEP_Sleep();\r
+                       __asm volatile( "isb" );\r
+               }\r
+\r
+               /* Allow the application to define some post sleep processing. */\r
+               configPOST_SLEEP_PROCESSING( xModifiableIdleTime );\r
+\r
+               /* Stop RTC.  Again, the time the SysTick is stopped for is accounted\r
+               for as best it can be, but using the tickless mode will inevitably\r
+               result in some tiny drift of the time maintained by the kernel with\r
+               respect to calendar time.  The count value is latched before stopping\r
+               the timer as stopping the timer appears to clear the count. */\r
+               ulCountAfterSleep = RTCC_CounterGet();\r
+               RTCC_Enable( false );\r
+\r
+               /* Re-enable interrupts - see comments above the cpsid instruction()\r
+               above. */\r
+               INT_Enable();\r
+               __asm volatile( "dsb" );\r
+               __asm volatile( "isb" );\r
+\r
+               if( ulTickFlag != pdFALSE )\r
+               {\r
+                       /* The tick interrupt has already executed, although because this\r
+                       function is called with the scheduler suspended the actual tick\r
+                       processing will not occur until after this function has exited.\r
+                       Reset the reload value with whatever remains of this tick period. */\r
+                       ulReloadValue = ulReloadValueForOneTick - ulCountAfterSleep;\r
+                       RTCC_ChannelCCVSet( lpRTCC_CHANNEL, ulReloadValue );\r
+\r
+                       /* The tick interrupt handler will already have pended the tick\r
+                       processing in the kernel.  As the pending tick will be processed as\r
+                       soon as this function exits, the tick value     maintained by the tick\r
+                       is stepped forward by one less than the time spent sleeping.  The\r
+                       actual stepping of the tick appears later in this function. */\r
+                       ulCompleteTickPeriods = xExpectedIdleTime - 1UL;\r
+               }\r
+               else\r
+               {\r
+                       /* Something other than the tick interrupt ended the sleep.  How\r
+                       many complete tick periods passed while the processor was\r
+                       sleeping?  Add back in the adjustment that was made to the reload\r
+                       value to account for the fact that a time slice was part way through\r
+                       when this function was called. */\r
+                       ulCountAfterSleep += ulCountBeforeSleep;\r
+                       ulCompleteTickPeriods = ulCountAfterSleep / ulReloadValueForOneTick;\r
+\r
+                       /* The reload value is set to whatever fraction of a single tick\r
+                       period remains. */\r
+                       ulCountAfterSleep -= ( ulCompleteTickPeriods * ulReloadValueForOneTick );\r
+                       ulReloadValue = ulReloadValueForOneTick - ulCountAfterSleep;\r
+\r
+                       if( ulReloadValue == 0 )\r
+                       {\r
+                               /* There is no fraction remaining. */\r
+                               ulReloadValue = ulReloadValueForOneTick;\r
+                               ulCompleteTickPeriods++;\r
+                       }\r
+\r
+                       RTCC_ChannelCCVSet( lpRTCC_CHANNEL, ulReloadValue );\r
+               }\r
+\r
+               /* Restart the RTC so it runs up to the alarm value.  The alarm value\r
+               will get set to the value required to generate exactly one tick period\r
+               the next time the RTC interrupt executes. */\r
+               RTCC_Enable( true );\r
+\r
+               /* Wind the tick forward by the number of tick periods that the CPU\r
+               remained in a low power state. */\r
+               vTaskStepTick( ulCompleteTickPeriods );\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void RTCC_IRQHandler( void )\r
+{\r
+       ulTickFlag = pdTRUE;\r
+\r
+       if( RTCC_ChannelCCVGet( lpRTCC_CHANNEL ) != ulReloadValueForOneTick )\r
+       {\r
+               /* Set RTC interrupt to one RTOS tick period. */\r
+               RTCC_Enable( false );\r
+               RTCC_ChannelCCVSet( lpRTCC_CHANNEL, ulReloadValueForOneTick );\r
+               RTCC_Enable( true );\r
+       }\r
+\r
+       RTCC_IntClear( _RTCC_IF_MASK );\r
+\r
+       /* Critical section which protect incrementing the tick*/\r
+       portDISABLE_INTERRUPTS();\r
+       {\r
+               if( xTaskIncrementTick() != pdFALSE )\r
+               {\r
+                       /* Pend a context switch. */\r
+                       portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;\r
+               }\r
+       }\r
+       portENABLE_INTERRUPTS();\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+#endif /* ( configCREATE_LOW_POWER_DEMO == 1 ) */\r
diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/Low_Power_Demo/main_low_power.c b/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/Low_Power_Demo/main_low_power.c
new file mode 100644 (file)
index 0000000..3fffc65
--- /dev/null
@@ -0,0 +1,236 @@
+/*\r
+    FreeRTOS V9.0.0rc1 - Copyright (C) 2016 Real Time Engineers Ltd.\r
+    All rights reserved\r
+\r
+    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+    This file is part of the FreeRTOS distribution.\r
+\r
+    FreeRTOS is free software; you can redistribute it and/or modify it under\r
+    the terms of the GNU General Public License (version 2) as published by the\r
+    Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.\r
+\r
+    ***************************************************************************\r
+    >>!   NOTE: The modification to the GPL is included to allow you to     !<<\r
+    >>!   distribute a combined work that includes FreeRTOS without being   !<<\r
+    >>!   obliged to provide the source code for proprietary components     !<<\r
+    >>!   outside of the FreeRTOS kernel.                                   !<<\r
+    ***************************************************************************\r
+\r
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+    FOR A PARTICULAR PURPOSE.  Full license text is available on the following\r
+    link: http://www.freertos.org/a00114.html\r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS provides completely free yet professionally developed,    *\r
+     *    robust, strictly quality controlled, supported, and cross          *\r
+     *    platform software that is more than just the market leader, it     *\r
+     *    is the industry's de facto standard.                               *\r
+     *                                                                       *\r
+     *    Help yourself get started quickly while simultaneously helping     *\r
+     *    to support the FreeRTOS project by purchasing a FreeRTOS           *\r
+     *    tutorial book, reference manual, or both:                          *\r
+     *    http://www.FreeRTOS.org/Documentation                              *\r
+     *                                                                       *\r
+    ***************************************************************************\r
+\r
+    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading\r
+    the FAQ page "My application does not run, what could be wrong?".  Have you\r
+    defined configASSERT()?\r
+\r
+    http://www.FreeRTOS.org/support - In return for receiving this top quality\r
+    embedded software for free we request you assist our global community by\r
+    participating in the support forum.\r
+\r
+    http://www.FreeRTOS.org/training - Investing in training allows your team to\r
+    be as productive as possible as early as possible.  Now you can receive\r
+    FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
+    Ltd, and the world's leading authority on the world's leading RTOS.\r
+\r
+    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+    including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
+    compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
+\r
+    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
+    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
+\r
+    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
+    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
+    licenses offer ticketed support, indemnification and commercial middleware.\r
+\r
+    http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+    engineered and independently SIL3 certified version for use in safety and\r
+    mission critical applications that require provable dependability.\r
+\r
+    1 tab == 4 spaces!\r
+*/\r
+\r
+/******************************************************************************\r
+ * NOTE 1:  This project provides two demo applications.  A simple blinky demo\r
+ * that demonstrates tickless low power operation, and a more comprehensive\r
+ * test and demo application.  The configCREATE_LOW_POWER_DEMO setting in\r
+ * FreeRTOSConfig.h is used to select between the two, and to select the clock\r
+ * used when tickless low power operation is demonstrated.  See the notes on\r
+ * using configCREATE_LOW_POWER_DEMO in main.c.  This file implements the low\r
+ * power version.\r
+ *\r
+ * NOTE 2:  This file only contains the source code that is specific to the\r
+ * low power demo.  Generic functions, such FreeRTOS hook functions, and\r
+ * functions required to configure the hardware are defined in main.c.\r
+ ******************************************************************************\r
+ *\r
+ * main_low_power() creates one queue, and two tasks.  It then starts the\r
+ * scheduler.\r
+ *\r
+ * The Queue Send Task:\r
+ * The queue send task is implemented by the prvQueueSendTask() function in\r
+ * this file.  It sends the value 100 to the queue every second.\r
+ *\r
+ * The Queue Receive Task:\r
+ * The queue receive task is implemented by the prvQueueReceiveTask() function\r
+ * in this file.  prvQueueReceiveTask() blocks on the queue, blipping (quickly\r
+ * turn on then off again) the LED each time it received the value 100 from the\r
+ * queue send task.  The queue send task writes to the queue every second, so\r
+ * the LED will blip once a second.\r
+ *\r
+ * The RTOS tick is turned off when the queue send task and queue receive task\r
+ * are both in the Blocked state.\r
+ *\r
+ */\r
+\r
+\r
+/* Kernel includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "semphr.h"\r
+\r
+/* SiLabs includes. */\r
+#include "bsp.h"\r
+\r
+/* Priorities at which the tasks are created. */\r
+#define mainQUEUE_RECEIVE_TASK_PRIORITY                ( tskIDLE_PRIORITY + 2 )\r
+#define        mainQUEUE_SEND_TASK_PRIORITY            ( tskIDLE_PRIORITY + 1 )\r
+\r
+/* The rate at which data is sent to the queue.  The 200ms value is converted\r
+to ticks using the portTICK_PERIOD_MS constant. */\r
+#define mainQUEUE_SEND_FREQUENCY_MS                    pdMS_TO_TICKS( 1000 )\r
+\r
+/* The number of items the queue can hold.  This is 1 as the receive task\r
+will remove items as they are added, meaning the send task should always find\r
+the queue empty. */\r
+#define mainQUEUE_LENGTH                                       ( 1 )\r
+\r
+/* The LED toggled by the Rx task. */\r
+#define mainTASK_LED                                           ( 0 )\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Called by main when mainCREATE_LOW_POWER_DEMO is set to 1 in\r
+ * main.c.\r
+ */\r
+void main_low_power( void );\r
+\r
+/*\r
+ * The tasks as described in the comments at the top of this file.\r
+ */\r
+static void prvQueueReceiveTask( void *pvParameters );\r
+static void prvQueueSendTask( void *pvParameters );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* The queue used by both tasks. */\r
+static QueueHandle_t xQueue = NULL;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void main_low_power( void )\r
+{\r
+       /* Create the queue. */\r
+       xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( uint32_t ) );\r
+\r
+       if( xQueue != NULL )\r
+       {\r
+               /* Start the two tasks as described in the comments at the top of this\r
+               file. */\r
+               xTaskCreate( prvQueueReceiveTask,                               /* The function that implements the task. */\r
+                                       "Rx",                                                           /* The text name assigned to the task - for debug only as it is not used by the kernel. */\r
+                                       configMINIMAL_STACK_SIZE,                       /* The size of the stack to allocate to the task. */\r
+                                       NULL,                                                           /* The parameter passed to the task - not used in this case. */\r
+                                       mainQUEUE_RECEIVE_TASK_PRIORITY,        /* The priority assigned to the task. */\r
+                                       NULL );                                                         /* The task handle is not required, so NULL is passed. */\r
+\r
+               xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );\r
+\r
+               /* Start the tasks and timer running. */\r
+               vTaskStartScheduler();\r
+       }\r
+\r
+       /* If all is well, the scheduler will now be running, and the following\r
+       line will never be reached.  If the following line does execute, then\r
+       there was insufficient FreeRTOS heap memory available for the Idle and/or\r
+       timer tasks to be created.  See the memory management section on the\r
+       FreeRTOS web site for more details on the FreeRTOS heap\r
+       http://www.freertos.org/a00111.html. */\r
+       for( ;; );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvQueueSendTask( void *pvParameters )\r
+{\r
+TickType_t xNextWakeTime;\r
+const uint32_t ulValueToSend = 100UL;\r
+\r
+       /* Remove compiler warning about unused parameter. */\r
+       ( void ) pvParameters;\r
+\r
+       /* Initialise xNextWakeTime - this only needs to be done once. */\r
+       xNextWakeTime = xTaskGetTickCount();\r
+\r
+       for( ;; )\r
+       {\r
+               /* Place this task in the blocked state until it is time to run again. */\r
+               vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );\r
+\r
+               /* Send to the queue - causing the queue receive task to unblock and\r
+               toggle the LED.  0 is used as the block time so the sending operation\r
+               will not block - it shouldn't need to block as the queue should always\r
+               be empty at this point in the code. */\r
+               xQueueSend( xQueue, &ulValueToSend, 0U );\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvQueueReceiveTask( void *pvParameters )\r
+{\r
+uint32_t ulReceivedValue;\r
+const uint32_t ulExpectedValue = 100UL;\r
+const TickType_t xShortDelay = pdMS_TO_TICKS( 10 );\r
+\r
+       /* Remove compiler warning about unused parameter. */\r
+       ( void ) pvParameters;\r
+\r
+       for( ;; )\r
+       {\r
+               /* Wait until something arrives in the queue - this task will block\r
+               indefinitely provided INCLUDE_vTaskSuspend is set to 1 in\r
+               FreeRTOSConfig.h. */\r
+               xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );\r
+\r
+               /*  To get here something must have been received from the queue, but\r
+               is it the expected value?  If it is, toggle the LED. */\r
+               if( ulReceivedValue == ulExpectedValue )\r
+               {\r
+                       /* Turn the LED on for a brief time only so it doens't distort the\r
+                       energy reading. */\r
+                       BSP_LedSet( mainTASK_LED );\r
+                       vTaskDelay( xShortDelay );\r
+                       BSP_LedClear( mainTASK_LED );\r
+                       ulReceivedValue = 0U;\r
+               }\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/BSP/bsp_stk_leds.c b/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/BSP/bsp_stk_leds.c
new file mode 100644 (file)
index 0000000..d972e3b
--- /dev/null
@@ -0,0 +1,117 @@
+/***************************************************************************//**\r
+ * @file\r
+ * @brief Board support package API for GPIO leds on STK's.\r
+ * @version 4.2.1\r
+ *******************************************************************************\r
+ * @section License\r
+ * <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>\r
+ *******************************************************************************\r
+ *\r
+ * This file is licensed under the Silabs License Agreement. See the file\r
+ * "Silabs_License_Agreement.txt" for details. Before using this software for\r
+ * any purpose, you must agree to the terms of that agreement.\r
+ *\r
+ ******************************************************************************/\r
+\r
+\r
+\r
+#include "em_device.h"\r
+#include "em_cmu.h"\r
+#include "em_gpio.h"\r
+#include "bsp.h"\r
+\r
+#if defined( BSP_GPIO_LEDS )\r
+/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */\r
+\r
+typedef struct\r
+{\r
+  GPIO_Port_TypeDef   port;\r
+  unsigned int        pin;\r
+} tLedArray;\r
+\r
+static const tLedArray ledArray[ BSP_NO_OF_LEDS ] = BSP_GPIO_LEDARRAY_INIT;\r
+\r
+int BSP_LedsInit(void)\r
+{\r
+  int i;\r
+\r
+  CMU_ClockEnable(cmuClock_HFPER, true);\r
+  CMU_ClockEnable(cmuClock_GPIO, true);\r
+  for ( i=0; i<BSP_NO_OF_LEDS; i++ )\r
+  {\r
+    GPIO_PinModeSet(ledArray[i].port, ledArray[i].pin, gpioModePushPull, 0);\r
+  }\r
+  return BSP_STATUS_OK;\r
+}\r
+\r
+uint32_t BSP_LedsGet(void)\r
+{\r
+  int i;\r
+  uint32_t retVal, mask;\r
+\r
+  for ( i=0, retVal=0, mask=0x1; i<BSP_NO_OF_LEDS; i++, mask <<= 1 )\r
+  {\r
+    if (GPIO_PinOutGet(ledArray[i].port, ledArray[i].pin))\r
+      retVal |= mask;\r
+  }\r
+  return retVal;\r
+}\r
+\r
+int BSP_LedsSet(uint32_t leds)\r
+{\r
+  int i;\r
+  uint32_t mask;\r
+\r
+  for ( i=0, mask=0x1; i<BSP_NO_OF_LEDS; i++, mask <<= 1 )\r
+  {\r
+    if ( leds & mask )\r
+      GPIO_PinOutSet(ledArray[i].port, ledArray[i].pin);\r
+    else\r
+      GPIO_PinOutClear(ledArray[i].port, ledArray[i].pin);\r
+  }\r
+  return BSP_STATUS_OK;\r
+}\r
+\r
+int BSP_LedClear(int ledNo)\r
+{\r
+  if ((ledNo >= 0) && (ledNo < BSP_NO_OF_LEDS))\r
+  {\r
+    GPIO_PinOutClear(ledArray[ledNo].port, ledArray[ledNo].pin);\r
+    return BSP_STATUS_OK;\r
+  }\r
+  return BSP_STATUS_ILLEGAL_PARAM;\r
+}\r
+\r
+int BSP_LedGet(int ledNo)\r
+{\r
+  int retVal = BSP_STATUS_ILLEGAL_PARAM;\r
+\r
+  if ((ledNo >= 0) && (ledNo < BSP_NO_OF_LEDS))\r
+  {\r
+    retVal = (int)GPIO_PinOutGet(ledArray[ledNo].port, ledArray[ledNo].pin);\r
+  }\r
+  return retVal;\r
+}\r
+\r
+int BSP_LedSet(int ledNo)\r
+{\r
+  if ((ledNo >= 0) && (ledNo < BSP_NO_OF_LEDS))\r
+  {\r
+    GPIO_PinOutSet(ledArray[ledNo].port, ledArray[ledNo].pin);\r
+    return BSP_STATUS_OK;\r
+  }\r
+  return BSP_STATUS_ILLEGAL_PARAM;\r
+}\r
+\r
+int BSP_LedToggle(int ledNo)\r
+{\r
+  if ((ledNo >= 0) && (ledNo < BSP_NO_OF_LEDS))\r
+  {\r
+    GPIO_PinOutToggle(ledArray[ledNo].port, ledArray[ledNo].pin);\r
+    return BSP_STATUS_OK;\r
+  }\r
+  return BSP_STATUS_ILLEGAL_PARAM;\r
+}\r
+\r
+/** @endcond */\r
+#endif  /* BSP_GPIO_LEDS */\r
diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/CMSIS/efm32pg1b/startup_gcc_efm32pg1b.s b/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/CMSIS/efm32pg1b/startup_gcc_efm32pg1b.s
new file mode 100644 (file)
index 0000000..d9e8a9d
--- /dev/null
@@ -0,0 +1,317 @@
+/* @file startup_efm32pg1b.S\r
+ * @brief startup file for Silicon Labs EFM32PG1B devices.\r
+ *        For use with GCC for ARM Embedded Processors\r
+ * @version 4.2.1\r
+ * Date:    12 June 2014\r
+ *\r
+ */\r
+/* Copyright (c) 2011 - 2014 ARM LIMITED\r
+\r
+   All rights reserved.\r
+   Redistribution and use in source and binary forms, with or without\r
+   modification, are permitted provided that the following conditions are met:\r
+   - Redistributions of source code must retain the above copyright\r
+     notice, this list of conditions and the following disclaimer.\r
+   - Redistributions in binary form must reproduce the above copyright\r
+     notice, this list of conditions and the following disclaimer in the\r
+     documentation and/or other materials provided with the distribution.\r
+   - Neither the name of ARM nor the names of its contributors may be used\r
+     to endorse or promote products derived from this software without\r
+     specific prior written permission.\r
+   *\r
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
+   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE\r
+   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+   POSSIBILITY OF SUCH DAMAGE.\r
+   ---------------------------------------------------------------------------*/\r
+\r
+    .syntax     unified\r
+    .arch       armv7-m\r
+    .section    .stack\r
+    .align      3\r
+#ifdef __STACK_SIZE\r
+    .equ        Stack_Size, __STACK_SIZE\r
+#else\r
+    .equ        Stack_Size, 0x00000400\r
+#endif\r
+    .globl      __StackTop\r
+    .globl      __StackLimit\r
+__StackLimit:\r
+    .space      Stack_Size\r
+    .size       __StackLimit, . - __StackLimit\r
+__StackTop:\r
+    .size       __StackTop, . - __StackTop\r
+\r
+    .section    .heap\r
+    .align      3\r
+#ifdef __HEAP_SIZE\r
+    .equ        Heap_Size, __HEAP_SIZE\r
+#else\r
+    .equ        Heap_Size, 0x00000C00\r
+#endif\r
+    .globl      __HeapBase\r
+    .globl      __HeapLimit\r
+__HeapBase:\r
+    .if Heap_Size\r
+    .space      Heap_Size\r
+    .endif\r
+    .size       __HeapBase, . - __HeapBase\r
+__HeapLimit:\r
+    .size       __HeapLimit, . - __HeapLimit\r
+\r
+    .section    .vectors\r
+    .align      2\r
+    .globl      __Vectors\r
+__Vectors:\r
+    .long       __StackTop            /* Top of Stack */\r
+    .long       Reset_Handler         /* Reset Handler */\r
+    .long       NMI_Handler           /* NMI Handler */\r
+    .long       HardFault_Handler     /* Hard Fault Handler */\r
+    .long       MemManage_Handler     /* MPU Fault Handler */\r
+    .long       BusFault_Handler      /* Bus Fault Handler */\r
+    .long       UsageFault_Handler    /* Usage Fault Handler */\r
+    .long       Default_Handler       /* Reserved */\r
+    .long       Default_Handler       /* Reserved */\r
+    .long       Default_Handler       /* Reserved */\r
+    .long       Default_Handler       /* Reserved */\r
+    .long       SVC_Handler           /* SVCall Handler */\r
+    .long       DebugMon_Handler      /* Debug Monitor Handler */\r
+    .long       Default_Handler       /* Reserved */\r
+    .long       PendSV_Handler        /* PendSV Handler */\r
+    .long       SysTick_Handler       /* SysTick Handler */\r
+\r
+    /* External interrupts */\r
+    .long       EMU_IRQHandler    /* 0 - EMU */\r
+    .long       Default_Handler    /* 1 - Reserved */\r
+    .long       WDOG0_IRQHandler    /* 2 - WDOG0 */\r
+    .long       Default_Handler    /* 3 - Reserved */\r
+    .long       Default_Handler    /* 4 - Reserved */\r
+    .long       Default_Handler    /* 5 - Reserved */\r
+    .long       Default_Handler    /* 6 - Reserved */\r
+    .long       Default_Handler    /* 7 - Reserved */\r
+    .long       LDMA_IRQHandler    /* 8 - LDMA */\r
+    .long       GPIO_EVEN_IRQHandler    /* 9 - GPIO_EVEN */\r
+    .long       TIMER0_IRQHandler    /* 10 - TIMER0 */\r
+    .long       USART0_RX_IRQHandler    /* 11 - USART0_RX */\r
+    .long       USART0_TX_IRQHandler    /* 12 - USART0_TX */\r
+    .long       ACMP0_IRQHandler    /* 13 - ACMP0 */\r
+    .long       ADC0_IRQHandler    /* 14 - ADC0 */\r
+    .long       IDAC0_IRQHandler    /* 15 - IDAC0 */\r
+    .long       I2C0_IRQHandler    /* 16 - I2C0 */\r
+    .long       GPIO_ODD_IRQHandler    /* 17 - GPIO_ODD */\r
+    .long       TIMER1_IRQHandler    /* 18 - TIMER1 */\r
+    .long       USART1_RX_IRQHandler    /* 19 - USART1_RX */\r
+    .long       USART1_TX_IRQHandler    /* 20 - USART1_TX */\r
+    .long       LEUART0_IRQHandler    /* 21 - LEUART0 */\r
+    .long       PCNT0_IRQHandler    /* 22 - PCNT0 */\r
+    .long       CMU_IRQHandler    /* 23 - CMU */\r
+    .long       MSC_IRQHandler    /* 24 - MSC */\r
+    .long       CRYPTO_IRQHandler    /* 25 - CRYPTO */\r
+    .long       LETIMER0_IRQHandler    /* 26 - LETIMER0 */\r
+    .long       Default_Handler    /* 27 - Reserved */\r
+    .long       Default_Handler    /* 28 - Reserved */\r
+    .long       RTCC_IRQHandler    /* 29 - RTCC */\r
+    .long       Default_Handler    /* 30 - Reserved */\r
+    .long       CRYOTIMER_IRQHandler    /* 31 - CRYOTIMER */\r
+    .long       Default_Handler    /* 32 - Reserved */\r
+    .long       FPUEH_IRQHandler    /* 33 - FPUEH */\r
+\r
+\r
+    .size       __Vectors, . - __Vectors\r
+\r
+    .text\r
+    .thumb\r
+    .thumb_func\r
+    .align      2\r
+    .globl      Reset_Handler\r
+    .type       Reset_Handler, %function\r
+Reset_Handler:\r
+#ifndef __NO_SYSTEM_INIT\r
+    ldr     r0, =SystemInit\r
+    blx     r0\r
+#endif\r
+\r
+/*  Firstly it copies data from read only memory to RAM. There are two schemes\r
+ *  to copy. One can copy more than one sections. Another can only copy\r
+ *  one section.  The former scheme needs more instructions and read-only\r
+ *  data to implement than the latter.\r
+ *  Macro __STARTUP_COPY_MULTIPLE is used to choose between two schemes.  */\r
+\r
+#ifdef __STARTUP_COPY_MULTIPLE\r
+/*  Multiple sections scheme.\r
+ *\r
+ *  Between symbol address __copy_table_start__ and __copy_table_end__,\r
+ *  there are array of triplets, each of which specify:\r
+ *    offset 0: LMA of start of a section to copy from\r
+ *    offset 4: VMA of start of a section to copy to\r
+ *    offset 8: size of the section to copy. Must be multiply of 4\r
+ *\r
+ *  All addresses must be aligned to 4 bytes boundary.\r
+ */\r
+    ldr     r4, =__copy_table_start__\r
+    ldr     r5, =__copy_table_end__\r
+\r
+.L_loop0:\r
+    cmp     r4, r5\r
+    bge     .L_loop0_done\r
+    ldr     r1, [r4]\r
+    ldr     r2, [r4, #4]\r
+    ldr     r3, [r4, #8]\r
+\r
+.L_loop0_0:\r
+    subs    r3, #4\r
+    ittt    ge\r
+    ldrge   r0, [r1, r3]\r
+    strge   r0, [r2, r3]\r
+    bge     .L_loop0_0\r
+\r
+    adds    r4, #12\r
+    b       .L_loop0\r
+\r
+.L_loop0_done:\r
+#else\r
+/*  Single section scheme.\r
+ *\r
+ *  The ranges of copy from/to are specified by following symbols\r
+ *    __etext: LMA of start of the section to copy from. Usually end of text\r
+ *    __data_start__: VMA of start of the section to copy to\r
+ *    __data_end__: VMA of end of the section to copy to\r
+ *\r
+ *  All addresses must be aligned to 4 bytes boundary.\r
+ */\r
+    ldr     r1, =__etext\r
+    ldr     r2, =__data_start__\r
+    ldr     r3, =__data_end__\r
+\r
+.L_loop1:\r
+    cmp     r2, r3\r
+    ittt    lt\r
+    ldrlt   r0, [r1], #4\r
+    strlt   r0, [r2], #4\r
+    blt     .L_loop1\r
+#endif /*__STARTUP_COPY_MULTIPLE */\r
+\r
+/*  This part of work usually is done in C library startup code. Otherwise,\r
+ *  define this macro to enable it in this startup.\r
+ *\r
+ *  There are two schemes too. One can clear multiple BSS sections. Another\r
+ *  can only clear one section. The former is more size expensive than the\r
+ *  latter.\r
+ *\r
+ *  Define macro __STARTUP_CLEAR_BSS_MULTIPLE to choose the former.\r
+ *  Otherwise efine macro __STARTUP_CLEAR_BSS to choose the later.\r
+ */\r
+#ifdef __STARTUP_CLEAR_BSS_MULTIPLE\r
+/*  Multiple sections scheme.\r
+ *\r
+ *  Between symbol address __copy_table_start__ and __copy_table_end__,\r
+ *  there are array of tuples specifying:\r
+ *    offset 0: Start of a BSS section\r
+ *    offset 4: Size of this BSS section. Must be multiply of 4\r
+ */\r
+    ldr     r3, =__zero_table_start__\r
+    ldr     r4, =__zero_table_end__\r
+\r
+.L_loop2:\r
+    cmp     r3, r4\r
+    bge     .L_loop2_done\r
+    ldr     r1, [r3]\r
+    ldr     r2, [r3, #4]\r
+    movs    r0, 0\r
+\r
+.L_loop2_0:\r
+    subs    r2, #4\r
+    itt     ge\r
+    strge   r0, [r1, r2]\r
+    bge     .L_loop2_0\r
+    adds    r3, #8\r
+    b       .L_loop2\r
+.L_loop2_done:\r
+#elif defined (__STARTUP_CLEAR_BSS)\r
+/*  Single BSS section scheme.\r
+ *\r
+ *  The BSS section is specified by following symbols\r
+ *    __bss_start__: start of the BSS section.\r
+ *    __bss_end__: end of the BSS section.\r
+ *\r
+ *  Both addresses must be aligned to 4 bytes boundary.\r
+ */\r
+    ldr     r1, =__bss_start__\r
+    ldr     r2, =__bss_end__\r
+\r
+    movs    r0, 0\r
+.L_loop3:\r
+    cmp     r1, r2\r
+    itt     lt\r
+    strlt   r0, [r1], #4\r
+    blt     .L_loop3\r
+#endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */\r
+\r
+#ifndef __START\r
+#define __START _start\r
+#endif\r
+    bl      __START\r
+\r
+    .pool\r
+    .size   Reset_Handler, . - Reset_Handler\r
+\r
+    .align  1\r
+    .thumb_func\r
+    .weak   Default_Handler\r
+    .type   Default_Handler, %function\r
+Default_Handler:\r
+    b       .\r
+    .size   Default_Handler, . - Default_Handler\r
+\r
+/*    Macro to define default handlers. Default handler\r
+ *    will be weak symbol and just dead loops. They can be\r
+ *    overwritten by other handlers */\r
+    .macro  def_irq_handler    handler_name\r
+    .weak   \handler_name\r
+    .set    \handler_name, Default_Handler\r
+    .endm\r
+\r
+    def_irq_handler     NMI_Handler\r
+    def_irq_handler     HardFault_Handler\r
+    def_irq_handler     MemManage_Handler\r
+    def_irq_handler     BusFault_Handler\r
+    def_irq_handler     UsageFault_Handler\r
+    def_irq_handler     SVC_Handler\r
+    def_irq_handler     DebugMon_Handler\r
+    def_irq_handler     PendSV_Handler\r
+    def_irq_handler     SysTick_Handler\r
+\r
+\r
+    def_irq_handler     EMU_IRQHandler\r
+    def_irq_handler     WDOG0_IRQHandler\r
+    def_irq_handler     LDMA_IRQHandler\r
+    def_irq_handler     GPIO_EVEN_IRQHandler\r
+    def_irq_handler     TIMER0_IRQHandler\r
+    def_irq_handler     USART0_RX_IRQHandler\r
+    def_irq_handler     USART0_TX_IRQHandler\r
+    def_irq_handler     ACMP0_IRQHandler\r
+    def_irq_handler     ADC0_IRQHandler\r
+    def_irq_handler     IDAC0_IRQHandler\r
+    def_irq_handler     I2C0_IRQHandler\r
+    def_irq_handler     GPIO_ODD_IRQHandler\r
+    def_irq_handler     TIMER1_IRQHandler\r
+    def_irq_handler     USART1_RX_IRQHandler\r
+    def_irq_handler     USART1_TX_IRQHandler\r
+    def_irq_handler     LEUART0_IRQHandler\r
+    def_irq_handler     PCNT0_IRQHandler\r
+    def_irq_handler     CMU_IRQHandler\r
+    def_irq_handler     MSC_IRQHandler\r
+    def_irq_handler     CRYPTO_IRQHandler\r
+    def_irq_handler     LETIMER0_IRQHandler\r
+    def_irq_handler     RTCC_IRQHandler\r
+    def_irq_handler     CRYOTIMER_IRQHandler\r
+    def_irq_handler     FPUEH_IRQHandler\r
+\r
+    .end\r
diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/CMSIS/efm32pg1b/system_efm32pg1b.c b/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/CMSIS/efm32pg1b/system_efm32pg1b.c
new file mode 100644 (file)
index 0000000..c2b6113
--- /dev/null
@@ -0,0 +1,383 @@
+/***************************************************************************//**\r
+ * @file system_efm32pg1b.c\r
+ * @brief CMSIS Cortex-M3/M4 System Layer for EFM32 devices.\r
+ * @version 4.2.1\r
+ ******************************************************************************\r
+ * @section License\r
+ * <b>Copyright 2015 Silicon Laboratories, Inc. http://www.silabs.com</b>\r
+ ******************************************************************************\r
+ *\r
+ * Permission is granted to anyone to use this software for any purpose,\r
+ * including commercial applications, and to alter it and redistribute it\r
+ * freely, subject to the following restrictions:\r
+ *\r
+ * 1. The origin of this software must not be misrepresented; you must not\r
+ *    claim that you wrote the original software.@n\r
+ * 2. Altered source versions must be plainly marked as such, and must not be\r
+ *    misrepresented as being the original software.@n\r
+ * 3. This notice may not be removed or altered from any source distribution.\r
+ *\r
+ * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc.\r
+ * has no obligation to support this Software. Silicon Laboratories, Inc. is\r
+ * providing the Software "AS IS", with no express or implied warranties of any\r
+ * kind, including, but not limited to, any implied warranties of\r
+ * merchantability or fitness for any particular purpose or warranties against\r
+ * infringement of any proprietary rights of a third party.\r
+ *\r
+ * Silicon Laboratories, Inc. will not be liable for any consequential,\r
+ * incidental, or special damages, or any other relief, or for any claim by\r
+ * any third party, arising from your use of this Software.\r
+ *\r
+ *****************************************************************************/\r
+\r
+#include <stdint.h>\r
+#include "em_device.h"\r
+\r
+/*******************************************************************************\r
+ ******************************   DEFINES   ************************************\r
+ ******************************************************************************/\r
+\r
+/** LFRCO frequency, tuned to below frequency during manufacturing. */\r
+#define EFM32_LFRCO_FREQ  (32768UL)\r
+#define EFM32_ULFRCO_FREQ (1000UL)\r
+\r
+/*******************************************************************************\r
+ **************************   LOCAL VARIABLES   ********************************\r
+ ******************************************************************************/\r
+\r
+/* System oscillator frequencies. These frequencies are normally constant */\r
+/* for a target, but they are made configurable in order to allow run-time */\r
+/* handling of different boards. The crystal oscillator clocks can be set */\r
+/* compile time to a non-default value by defining respective EFM_nFXO_FREQ */\r
+/* values according to board design. By defining the EFM_nFXO_FREQ to 0, */\r
+/* one indicates that the oscillator is not present, in order to save some */\r
+/* SW footprint. */\r
+\r
+#ifndef EFM32_HFRCO_MAX_FREQ\r
+#define EFM32_HFRCO_MAX_FREQ            (38000000UL)\r
+#endif\r
+\r
+#ifndef EFM32_HFXO_FREQ\r
+#define EFM32_HFXO_FREQ                 (40000000UL)\r
+#endif\r
+\r
+#ifndef EFM32_HFRCO_STARTUP_FREQ\r
+#define EFM32_HFRCO_STARTUP_FREQ        (19000000UL)\r
+#endif\r
+\r
+\r
+/* Do not define variable if HF crystal oscillator not present */\r
+#if (EFM32_HFXO_FREQ > 0UL)\r
+/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */\r
+/** System HFXO clock. */\r
+static uint32_t SystemHFXOClock = EFM32_HFXO_FREQ;\r
+/** @endcond (DO_NOT_INCLUDE_WITH_DOXYGEN) */\r
+#endif\r
+\r
+#ifndef EFM32_LFXO_FREQ\r
+#define EFM32_LFXO_FREQ (EFM32_LFRCO_FREQ)\r
+#endif\r
+/* Do not define variable if LF crystal oscillator not present */\r
+#if (EFM32_LFXO_FREQ > 0UL)\r
+/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */\r
+/** System LFXO clock. */\r
+static uint32_t SystemLFXOClock = 32768UL;\r
+/** @endcond (DO_NOT_INCLUDE_WITH_DOXYGEN) */\r
+#endif\r
+\r
+\r
+/*******************************************************************************\r
+ **************************   GLOBAL VARIABLES   *******************************\r
+ ******************************************************************************/\r
+\r
+/**\r
+ * @brief\r
+ *   System System Clock Frequency (Core Clock).\r
+ *\r
+ * @details\r
+ *   Required CMSIS global variable that must be kept up-to-date.\r
+ */\r
+uint32_t SystemCoreClock;\r
+\r
+\r
+/**\r
+ * @brief\r
+ *   System HFRCO frequency\r
+ *\r
+ * @note\r
+ *   This is an EFM32 proprietary variable, not part of the CMSIS definition.\r
+ *\r
+ * @details\r
+ *   Frequency of the system HFRCO oscillator\r
+ */\r
+uint32_t SystemHfrcoFreq = EFM32_HFRCO_STARTUP_FREQ;\r
+\r
+\r
+/*******************************************************************************\r
+ **************************   GLOBAL FUNCTIONS   *******************************\r
+ ******************************************************************************/\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Get the current core clock frequency.\r
+ *\r
+ * @details\r
+ *   Calculate and get the current core clock frequency based on the current\r
+ *   configuration. Assuming that the SystemCoreClock global variable is\r
+ *   maintained, the core clock frequency is stored in that variable as well.\r
+ *   This function will however calculate the core clock based on actual HW\r
+ *   configuration. It will also update the SystemCoreClock global variable.\r
+ *\r
+ * @note\r
+ *   This is an EFM32 proprietary function, not part of the CMSIS definition.\r
+ *\r
+ * @return\r
+ *   The current core clock frequency in Hz.\r
+ ******************************************************************************/\r
+uint32_t SystemCoreClockGet(void)\r
+{\r
+  uint32_t ret;\r
+  uint32_t presc;\r
+\r
+  ret   = SystemHFClockGet();\r
+  presc = (CMU->HFCOREPRESC & _CMU_HFCOREPRESC_PRESC_MASK) >>\r
+          _CMU_HFCOREPRESC_PRESC_SHIFT;\r
+  ret  /= (presc + 1);\r
+\r
+  /* Keep CMSIS system clock variable up-to-date */\r
+  SystemCoreClock = ret;\r
+\r
+  return ret;\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Get the maximum core clock frequency.\r
+ *\r
+ * @note\r
+ *   This is an EFM32 proprietary function, not part of the CMSIS definition.\r
+ *\r
+ * @return\r
+ *   The maximum core clock frequency in Hz.\r
+ ******************************************************************************/\r
+uint32_t SystemMaxCoreClockGet(void)\r
+{\r
+  return (EFM32_HFRCO_MAX_FREQ > EFM32_HFXO_FREQ ? \\r
+          EFM32_HFRCO_MAX_FREQ : EFM32_HFXO_FREQ);\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Get the current HFCLK frequency.\r
+ *\r
+ * @note\r
+ *   This is an EFM32 proprietary function, not part of the CMSIS definition.\r
+ *\r
+ * @return\r
+ *   The current HFCLK frequency in Hz.\r
+ ******************************************************************************/\r
+uint32_t SystemHFClockGet(void)\r
+{\r
+  uint32_t ret;\r
+\r
+  switch (CMU->HFCLKSTATUS & _CMU_HFCLKSTATUS_SELECTED_MASK)\r
+  {\r
+    case CMU_HFCLKSTATUS_SELECTED_LFXO:\r
+#if (EFM32_LFXO_FREQ > 0)\r
+      ret = SystemLFXOClock;\r
+#else\r
+      /* We should not get here, since core should not be clocked. May */\r
+      /* be caused by a misconfiguration though. */\r
+      ret = 0;\r
+#endif\r
+      break;\r
+\r
+    case CMU_HFCLKSTATUS_SELECTED_LFRCO:\r
+      ret = EFM32_LFRCO_FREQ;\r
+      break;\r
+\r
+    case CMU_HFCLKSTATUS_SELECTED_HFXO:\r
+#if (EFM32_HFXO_FREQ > 0)\r
+      ret = SystemHFXOClock;\r
+#else\r
+      /* We should not get here, since core should not be clocked. May */\r
+      /* be caused by a misconfiguration though. */\r
+      ret = 0;\r
+#endif\r
+      break;\r
+\r
+    default: /* CMU_HFCLKSTATUS_SELECTED_HFRCO */\r
+      ret = SystemHfrcoFreq;\r
+      break;\r
+  }\r
+\r
+  return ret;\r
+}\r
+\r
+\r
+/**************************************************************************//**\r
+ * @brief\r
+ *   Get high frequency crystal oscillator clock frequency for target system.\r
+ *\r
+ * @note\r
+ *   This is an EFM32 proprietary function, not part of the CMSIS definition.\r
+ *\r
+ * @return\r
+ *   HFXO frequency in Hz.\r
+ *****************************************************************************/\r
+uint32_t SystemHFXOClockGet(void)\r
+{\r
+  /* External crystal oscillator present? */\r
+#if (EFM32_HFXO_FREQ > 0)\r
+  return SystemHFXOClock;\r
+#else\r
+  return 0;\r
+#endif\r
+}\r
+\r
+\r
+/**************************************************************************//**\r
+ * @brief\r
+ *   Set high frequency crystal oscillator clock frequency for target system.\r
+ *\r
+ * @note\r
+ *   This function is mainly provided for being able to handle target systems\r
+ *   with different HF crystal oscillator frequencies run-time. If used, it\r
+ *   should probably only be used once during system startup.\r
+ *\r
+ * @note\r
+ *   This is an EFM32 proprietary function, not part of the CMSIS definition.\r
+ *\r
+ * @param[in] freq\r
+ *   HFXO frequency in Hz used for target.\r
+ *****************************************************************************/\r
+void SystemHFXOClockSet(uint32_t freq)\r
+{\r
+  /* External crystal oscillator present? */\r
+#if (EFM32_HFXO_FREQ > 0)\r
+  SystemHFXOClock = freq;\r
+\r
+  /* Update core clock frequency if HFXO is used to clock core */\r
+  if ((CMU->HFCLKSTATUS & _CMU_HFCLKSTATUS_SELECTED_MASK) == CMU_HFCLKSTATUS_SELECTED_HFXO)\r
+  {\r
+    /* The function will update the global variable */\r
+    SystemCoreClockGet();\r
+  }\r
+#else\r
+  (void)freq; /* Unused parameter */\r
+#endif\r
+}\r
+\r
+\r
+/**************************************************************************//**\r
+ * @brief\r
+ *   Initialize the system.\r
+ *\r
+ * @details\r
+ *   Do required generic HW system init.\r
+ *\r
+ * @note\r
+ *   This function is invoked during system init, before the main() routine\r
+ *   and any data has been initialized. For this reason, it cannot do any\r
+ *   initialization of variables etc.\r
+ *****************************************************************************/\r
+void SystemInit(void)\r
+{\r
+#if (__FPU_PRESENT == 1)\r
+  /* Set floating point coprosessor access mode. */\r
+  SCB->CPACR |= ((3UL << 10 * 2) |      /* set CP10 Full Access */\r
+                 (3UL << 11 * 2));      /* set CP11 Full Access */\r
+#endif\r
+}\r
+\r
+\r
+/**************************************************************************//**\r
+ * @brief\r
+ *   Get low frequency RC oscillator clock frequency for target system.\r
+ *\r
+ * @note\r
+ *   This is an EFM32 proprietary function, not part of the CMSIS definition.\r
+ *\r
+ * @return\r
+ *   LFRCO frequency in Hz.\r
+ *****************************************************************************/\r
+uint32_t SystemLFRCOClockGet(void)\r
+{\r
+  /* Currently we assume that this frequency is properly tuned during */\r
+  /* manufacturing and is not changed after reset. If future requirements */\r
+  /* for re-tuning by user, we can add support for that. */\r
+  return EFM32_LFRCO_FREQ;\r
+}\r
+\r
+\r
+/**************************************************************************//**\r
+ * @brief\r
+ *   Get ultra low frequency RC oscillator clock frequency for target system.\r
+ *\r
+ * @note\r
+ *   This is an EFM32 proprietary function, not part of the CMSIS definition.\r
+ *\r
+ * @return\r
+ *   ULFRCO frequency in Hz.\r
+ *****************************************************************************/\r
+uint32_t SystemULFRCOClockGet(void)\r
+{\r
+  /* The ULFRCO frequency is not tuned, and can be very inaccurate */\r
+  return EFM32_ULFRCO_FREQ;\r
+}\r
+\r
+\r
+/**************************************************************************//**\r
+ * @brief\r
+ *   Get low frequency crystal oscillator clock frequency for target system.\r
+ *\r
+ * @note\r
+ *   This is an EFM32 proprietary function, not part of the CMSIS definition.\r
+ *\r
+ * @return\r
+ *   LFXO frequency in Hz.\r
+ *****************************************************************************/\r
+uint32_t SystemLFXOClockGet(void)\r
+{\r
+  /* External crystal oscillator present? */\r
+#if (EFM32_LFXO_FREQ > 0)\r
+  return SystemLFXOClock;\r
+#else\r
+  return 0;\r
+#endif\r
+}\r
+\r
+\r
+/**************************************************************************//**\r
+ * @brief\r
+ *   Set low frequency crystal oscillator clock frequency for target system.\r
+ *\r
+ * @note\r
+ *   This function is mainly provided for being able to handle target systems\r
+ *   with different HF crystal oscillator frequencies run-time. If used, it\r
+ *   should probably only be used once during system startup.\r
+ *\r
+ * @note\r
+ *   This is an EFM32 proprietary function, not part of the CMSIS definition.\r
+ *\r
+ * @param[in] freq\r
+ *   LFXO frequency in Hz used for target.\r
+ *****************************************************************************/\r
+void SystemLFXOClockSet(uint32_t freq)\r
+{\r
+  /* External crystal oscillator present? */\r
+#if (EFM32_LFXO_FREQ > 0)\r
+  SystemLFXOClock = freq;\r
+\r
+  /* Update core clock frequency if LFXO is used to clock core */\r
+  if ((CMU->HFCLKSTATUS & _CMU_HFCLKSTATUS_SELECTED_MASK) == CMU_HFCLKSTATUS_SELECTED_LFXO)\r
+  {\r
+    /* The function will update the global variable */\r
+    SystemCoreClockGet();\r
+  }\r
+#else\r
+  (void)freq; /* Unused parameter */\r
+#endif\r
+}\r
diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/emdrv/sleep/inc/sleep.h b/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/emdrv/sleep/inc/sleep.h
new file mode 100644 (file)
index 0000000..c0b182f
--- /dev/null
@@ -0,0 +1,265 @@
+/***************************************************************************//**\r
+ * @file sleep.h\r
+ * @brief Energy Modes management driver\r
+ * @version 4.2.1\r
+ * @details\r
+ * This is a energy modes management module consisting of sleep.c and sleep.h\r
+ * source files. The main purpose of the module is to ease energy\r
+ * optimization with a simple API. The module allows the system to always sleep\r
+ * in the lowest possible energy mode. Users could set up callbacks that are\r
+ * being called before and after each and every sleep. A counting semaphore is\r
+ * available for each low energy mode (EM1/EM2/EM3) to protect certain system\r
+ * states from being corrupted. This semaphore has limit set to maximum 255 locks.\r
+ *\r
+ * The module provides the following public API to the users:\r
+ * SLEEP_Init()\r
+ * SLEEP_Sleep()\r
+ * SLEEP_SleepBlockBegin()\r
+ * SLEEP_SleepBlockEnd()\r
+ * SLEEP_ForceSleepInEM4()\r
+ *\r
+ *******************************************************************************\r
+ * @section License\r
+ * <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>\r
+ *******************************************************************************\r
+ *\r
+ * This file is licensed under the Silabs License Agreement. See the file\r
+ * "Silabs_License_Agreement.txt" for details. Before using this software for\r
+ * any purpose, you must agree to the terms of that agreement.\r
+ *\r
+ ******************************************************************************/\r
+\r
+#ifndef __SLEEP_H\r
+#define __SLEEP_H\r
+\r
+#include <stdint.h>\r
+#include <stdbool.h>\r
+\r
+/* Device specific header file(s). */\r
+#include "em_device.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/***************************************************************************//**\r
+ * @addtogroup EM_Drivers\r
+ * @{\r
+ ******************************************************************************/\r
+\r
+/***************************************************************************//**\r
+ * @addtogroup SLEEP\r
+ * @brief Energy Modes management driver.\r
+ * @details\r
+ * This is a energy modes management module consisting of sleep.c and sleep.h\r
+ * source files. The main purpose of the module is to ease energy\r
+ * optimization with a simple API. The module allows the system to always sleep\r
+ * in the lowest possible energy mode. Users could set up callbacks that are\r
+ * being called before and after each and every sleep. A counting semaphore is\r
+ * available for each low energy mode (EM1/EM2/EM3) to protect certain system\r
+ * states from being corrupted. This semaphore has limit set to maximum 255 locks.\r
+ * @{\r
+ ******************************************************************************/\r
+\r
+/*******************************************************************************\r
+ *******************************   MACROS   ************************************\r
+ ******************************************************************************/\r
+\r
+\r
+/*******************************************************************************\r
+ ****************************   CONFIGURATION   ********************************\r
+ ******************************************************************************/\r
+\r
+/** Enable/disable the HW block for protecting accidental setting of low energy\r
+ *  modes (recommended to be set to true). */\r
+#ifndef SLEEP_HW_LOW_ENERGY_BLOCK_ENABLED\r
+#define SLEEP_HW_LOW_ENERGY_BLOCK_ENABLED    true\r
+#endif\r
+\r
+/** Enable/disable calling wakeup callback after EM4 reset. */\r
+#ifndef SLEEP_EM4_WAKEUP_CALLBACK_ENABLED\r
+#define SLEEP_EM4_WAKEUP_CALLBACK_ENABLED    true\r
+#endif\r
+\r
+/** Configure default lowest energy mode that the system can be set to.\r
+ *  Possible values:\r
+ *  @li sleepEM1 - EM1, the CPU core is turned off.\r
+ *  @li sleepEM2 - EM2, like EM1 + all HF clocks are turned off, LF clocks are on.\r
+ *  @li sleepEM3 - EM3, like EM2 + LF clocks are off, RAM retention, GPIO and ACMP\r
+ *                   interrupt is on. */\r
+#ifndef SLEEP_LOWEST_ENERGY_MODE_DEFAULT\r
+#define SLEEP_LOWEST_ENERGY_MODE_DEFAULT    sleepEM3\r
+#endif\r
+\r
+/*******************************************************************************\r
+ ******************************   TYPEDEFS   ***********************************\r
+ ******************************************************************************/\r
+\r
+/** Status value used for showing the Energy Mode the device is currently in. */\r
+typedef enum\r
+{\r
+  /** Status value for EM0. */\r
+  sleepEM0 = 0,\r
+\r
+  /** Status value for EM1. */\r
+  sleepEM1 = 1,\r
+\r
+  /** Status value for EM2. */\r
+  sleepEM2 = 2,\r
+\r
+  /** Status value for EM3. */\r
+  sleepEM3 = 3,\r
+\r
+  /** Status value for EM4. */\r
+  sleepEM4 = 4\r
+} SLEEP_EnergyMode_t;\r
+\r
+/** Callback function pointer type. */\r
+typedef void (*SLEEP_CbFuncPtr_t)(SLEEP_EnergyMode_t);\r
+\r
+\r
+/*******************************************************************************\r
+ ******************************   PROTOTYPES   *********************************\r
+ ******************************************************************************/\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Initialize the Sleep module.\r
+ *\r
+ * @details\r
+ *   Use this function to initialize the Sleep module, should be called\r
+ *   only once! Pointers to sleep and wake-up callback functions shall be\r
+ *   provided when calling this function.\r
+ *   If SLEEP_EM4_WAKEUP_CALLBACK_ENABLED is set to true, this function checks\r
+ *   for the cause of the reset that implicitly called it and calls the wakeup\r
+ *   callback if the reset was a wakeup from EM4 (does not work on Gecko MCU).\r
+ *\r
+ * @param[in] pSleepCb\r
+ *   Pointer to the callback function that is being called before the device is\r
+ *   going to sleep.\r
+ *\r
+ * @param[in] pWakeUpCb\r
+ *   Pointer to the callback function that is being called after wake up.\r
+ ******************************************************************************/\r
+void SLEEP_Init(SLEEP_CbFuncPtr_t pSleepCb, SLEEP_CbFuncPtr_t pWakeUpCb);\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Gets the lowest energy mode that the system is allowed to be set to.\r
+ *\r
+ * @details\r
+ *   This function uses the low energy mode block counters to determine the\r
+ *   lowest possible that the system is allowed to be set to.\r
+ *\r
+ * @return\r
+ *   Lowest energy mode that the system can be set to. Possible values:\r
+ *   @li sleepEM0\r
+ *   @li sleepEM1\r
+ *   @li sleepEM2\r
+ *   @li sleepEM3\r
+ ******************************************************************************/\r
+SLEEP_EnergyMode_t SLEEP_LowestEnergyModeGet(void);\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Sets the system to sleep into the lowest possible energy mode.\r
+ *\r
+ * @details\r
+ *   This function takes care of the system states protected by the sleep block\r
+ *   provided by SLEEP_SleepBlockBegin() / SLEEP_SleepBlockEnd(). It allows\r
+ *   the system to go into the lowest possible energy mode that the device can\r
+ *   be set into at the time of the call of this function.\r
+ *   This function will not go lower than EM3 because leaving EM4 requires\r
+ *   resetting MCU. To enter into EM4 call SLEEP_ForceSleepInEM4().\r
+ *\r
+ * @return\r
+ *   Energy Mode that was entered. Possible values:\r
+ *   @li sleepEM0\r
+ *   @li sleepEM1\r
+ *   @li sleepEM2\r
+ *   @li sleepEM3\r
+ ******************************************************************************/\r
+SLEEP_EnergyMode_t SLEEP_Sleep(void);\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Force the device to go to EM4 without doing any checks.\r
+ *\r
+ * @details\r
+ *   This function unblocks the low energy sleep block then goes to EM4.\r
+ *\r
+ * @note\r
+ *   Regular RAM is not retained in EM4 and the wake up causes a reset.\r
+ *   If the configuration option SLEEP_EM4_WAKEUP_CALLBACK_ENABLED is set to\r
+ *   true, the SLEEP_Init() function checks for the reset cause and calls the\r
+ *   EM4 wakeup callback.\r
+ ******************************************************************************/\r
+void SLEEP_ForceSleepInEM4(void);\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Begin sleep block in the requested energy mode.\r
+ *\r
+ * @details\r
+ *   Blocking a critical system state from a certain energy mode makes sure that\r
+ *   the system is not set to that energy mode while the block is not being\r
+ *   released.\r
+ *   Every SLEEP_SleepBlockBegin() increases the corresponding counter and\r
+ *   every SLEEP_SleepBlockEnd() decreases it.\r
+ *\r
+ *   Example:\code\r
+ *      SLEEP_SleepBlockBegin(sleepEM2);  // do not allow EM2 or higher\r
+ *      // do some stuff that requires EM1 at least, like ADC sampling\r
+ *      SLEEP_SleepBlockEnd(sleepEM2);    // remove restriction for EM2\endcode\r
+ *\r
+ * @note\r
+ *   Be aware that there is limit of maximum blocks nesting to 255.\r
+ *\r
+ * @param[in] eMode\r
+ *   Energy mode to begin to block. Possible values:\r
+ *   @li sleepEM1 - Begin to block the system from being set to EM1 (and EM2..4).\r
+ *   @li sleepEM2 - Begin to block the system from being set to EM2 (and EM3/EM4).\r
+ *   @li sleepEM3 - Begin to block the system from being set to EM3 (and EM4).\r
+ ******************************************************************************/\r
+void SLEEP_SleepBlockBegin(SLEEP_EnergyMode_t eMode);\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   End sleep block in the requested energy mode.\r
+ *\r
+ * @details\r
+ *   Release restriction for entering certain energy mode. Every call of this\r
+ *   function reduce blocking counter by 1. Once the counter for specific energy\r
+ *   mode is 0 and all counters for lower energy modes are 0 as well, using\r
+ *   particular energy mode is allowed.\r
+ *   Every SLEEP_SleepBlockBegin() increases the corresponding counter and\r
+ *   every SLEEP_SleepBlockEnd() decreases it.\r
+ *\r
+ *   Example:\code\r
+ *      // at start all energy modes are allowed\r
+ *      SLEEP_SleepBlockBegin(sleepEM2); // EM2, EM3, EM4 are blocked\r
+ *      SLEEP_SleepBlockBegin(sleepEM1); // EM1, EM2, EM3, EM4 are blocked\r
+ *      SLEEP_SleepBlockBegin(sleepEM1); // EM1, EM2, EM3, EM4 are blocked\r
+ *      SLEEP_SleepBlockEnd(sleepEM2);   // still EM1, EM2, EM3, EM4 are blocked\r
+ *      SLEEP_SleepBlockEnd(sleepEM1);   // still EM1, EM2, EM3, EM4 are blocked\r
+ *      SLEEP_SleepBlockEnd(sleepEM1);   // all energy modes are allowed now\endcode\r
+ *\r
+ * @param[in] eMode\r
+ *   Energy mode to end to block. Possible values:\r
+ *   @li sleepEM1 - End to block the system from being set to EM1 (and EM2..4).\r
+ *   @li sleepEM2 - End to block the system from being set to EM2 (and EM3/EM4).\r
+ *   @li sleepEM3 - End to block the system from being set to EM3 (and EM4).\r
+ ******************************************************************************/\r
+void SLEEP_SleepBlockEnd(SLEEP_EnergyMode_t eMode);\r
+\r
+\r
+/** @} (end addtogroup SLEEP) */\r
+/** @} (end addtogroup EM_Drivers) */\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+#endif /* __SLEEP_H */\r
diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/emdrv/sleep/src/sleep.c b/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/emdrv/sleep/src/sleep.c
new file mode 100644 (file)
index 0000000..556ec6b
--- /dev/null
@@ -0,0 +1,427 @@
+/***************************************************************************//**\r
+ * @file sleep.c\r
+ * @brief Energy Modes management driver.\r
+ * @version 4.2.1\r
+ * @details\r
+ * This is a energy modes management module consisting of sleep.c and sleep.h\r
+ * source files. The main purpose of the module is to ease energy\r
+ * optimization with a simple API. The module allows the system to always sleep\r
+ * in the lowest possible energy mode. Users could set up callbacks that are\r
+ * being called before and after each and every sleep. A counting semaphore is\r
+ * available for each low energy mode (EM1/EM2/EM3) to protect certain system\r
+ * states from being corrupted. This semaphore has limit set to maximum 255 locks.\r
+ *\r
+ * The module provides the following public API to the users:\r
+ * SLEEP_Init()\r
+ * SLEEP_Sleep()\r
+ * SLEEP_SleepBlockBegin()\r
+ * SLEEP_SleepBlockEnd()\r
+ * SLEEP_ForceSleepInEM4()\r
+ *\r
+ *******************************************************************************\r
+ * @section License\r
+ * <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>\r
+ *******************************************************************************\r
+ *\r
+ * This file is licensed under the Silabs License Agreement. See the file\r
+ * "Silabs_License_Agreement.txt" for details. Before using this software for\r
+ * any purpose, you must agree to the terms of that agreement.\r
+ *\r
+ ******************************************************************************/\r
+\r
+\r
+/* Chip specific header file(s). */\r
+#include "em_device.h"\r
+#include "em_assert.h"\r
+#include "em_int.h"\r
+#include "em_rmu.h"\r
+#include "em_emu.h"\r
+\r
+/* Module header file(s). */\r
+#include "sleep.h"\r
+\r
+/* stdlib is needed for NULL definition */\r
+#include <stdlib.h>\r
+\r
+/***************************************************************************//**\r
+ * @addtogroup EM_Drivers\r
+ * @{\r
+ ******************************************************************************/\r
+\r
+/***************************************************************************//**\r
+ * @addtogroup SLEEP\r
+ * @brief Energy Modes management driver.\r
+ * @details\r
+ * This is a energy modes management module consisting of sleep.c and sleep.h\r
+ * source files. The main purpose of the module is to ease energy\r
+ * optimization with a simple API. The module allows the system to always sleep\r
+ * in the lowest possible energy mode. Users could set up callbacks that are\r
+ * being called before and after each and every sleep. A counting semaphore is\r
+ * available for each low energy mode (EM1/EM2/EM3) to protect certain system\r
+ * states from being corrupted. This semaphore has limit set to maximum 255 locks.\r
+ * @{\r
+ ******************************************************************************/\r
+\r
+/*******************************************************************************\r
+ *******************************   MACROS   ************************************\r
+ ******************************************************************************/\r
+\r
+/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */\r
+\r
+/* Number of low energy modes (EM1, EM2, EM3). Note: EM4 sleep/wakeup is handled\r
+ * differently therefore it is not part of the list! */\r
+#define SLEEP_NUMOF_LOW_ENERGY_MODES    3U\r
+\r
+\r
+\r
+/*******************************************************************************\r
+ ******************************   TYPEDEFS   ***********************************\r
+ ******************************************************************************/\r
+\r
+\r
+/*******************************************************************************\r
+ ******************************   CONSTANTS   **********************************\r
+ ******************************************************************************/\r
+\r
+\r
+/*******************************************************************************\r
+ *******************************   STATICS   ***********************************\r
+ ******************************************************************************/\r
+\r
+/* Callback functions to call before and after sleep. */\r
+static SLEEP_CbFuncPtr_t sleepCallback  = NULL;\r
+static SLEEP_CbFuncPtr_t wakeUpCallback = NULL;\r
+\r
+/* Sleep block counter array representing the nested sleep blocks for the low\r
+ * energy modes (EM1/EM2/EM3). Array index 0 corresponds to EM1, 1 to EM2 and 2\r
+ * to EM3 accordingly.\r
+ *\r
+ * Note:\r
+ * - EM4 sleep/wakeup is handled differently therefore it is not part of the\r
+ *   list!\r
+ * - Max. number of sleep block nesting is 255. */\r
+static uint8_t sleepBlockCnt[SLEEP_NUMOF_LOW_ENERGY_MODES];\r
+\r
+/*******************************************************************************\r
+ ******************************   PROTOTYPES   *********************************\r
+ ******************************************************************************/\r
+\r
+static void SLEEP_EnterEMx(SLEEP_EnergyMode_t eMode);\r
+//static SLEEP_EnergyMode_t SLEEP_LowestEnergyModeGet(void);\r
+\r
+/** @endcond */\r
+\r
+/*******************************************************************************\r
+ ***************************   GLOBAL FUNCTIONS   ******************************\r
+ ******************************************************************************/\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Initialize the Sleep module.\r
+ *\r
+ * @details\r
+ *   Use this function to initialize the Sleep module, should be called\r
+ *   only once! Pointers to sleep and wake-up callback functions shall be\r
+ *   provided when calling this function.\r
+ *   If SLEEP_EM4_WAKEUP_CALLBACK_ENABLED is set to true, this function checks\r
+ *   for the cause of the reset that implicitly called it and calls the wakeup\r
+ *   callback if the reset was a wakeup from EM4 (does not work on Gecko MCU).\r
+ *\r
+ * @param[in] pSleepCb\r
+ *   Pointer to the callback function that is being called before the device is\r
+ *   going to sleep.\r
+ *\r
+ * @param[in] pWakeUpCb\r
+ *   Pointer to the callback function that is being called after wake up.\r
+ ******************************************************************************/\r
+void SLEEP_Init(SLEEP_CbFuncPtr_t pSleepCb, SLEEP_CbFuncPtr_t pWakeUpCb)\r
+{\r
+  /* Initialize callback functions. */\r
+  sleepCallback  = pSleepCb;\r
+  wakeUpCallback = pWakeUpCb;\r
+\r
+  /* Reset sleep block counters. Note: not using for() saves code! */\r
+  sleepBlockCnt[0U] = 0U;\r
+  sleepBlockCnt[1U] = 0U;\r
+  sleepBlockCnt[2U] = 0U;\r
+\r
+#if (SLEEP_EM4_WAKEUP_CALLBACK_ENABLED == true) && defined(RMU_RSTCAUSE_EM4WURST)\r
+  /* Check if the Init() happened after an EM4 reset. */\r
+  if (RMU_ResetCauseGet() & RMU_RSTCAUSE_EM4WURST)\r
+  {\r
+    /* Clear the cause of the reset. */\r
+    RMU_ResetCauseClear();\r
+    /* Call wakeup callback with EM4 parameter. */\r
+    if (NULL != wakeUpCallback)\r
+    {\r
+      wakeUpCallback(sleepEM4);\r
+    }\r
+  }\r
+#endif\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Sets the system to sleep into the lowest possible energy mode.\r
+ *\r
+ * @details\r
+ *   This function takes care of the system states protected by the sleep block\r
+ *   provided by SLEEP_SleepBlockBegin() / SLEEP_SleepBlockEnd(). It allows\r
+ *   the system to go into the lowest possible energy mode that the device can\r
+ *   be set into at the time of the call of this function.\r
+ *   This function will not go lower than EM3 because leaving EM4 requires\r
+ *   resetting MCU. To enter into EM4 call SLEEP_ForceSleepInEM4().\r
+ *\r
+ * @return\r
+ *   Energy Mode that was entered. Possible values:\r
+ *   @li sleepEM0\r
+ *   @li sleepEM1\r
+ *   @li sleepEM2\r
+ *   @li sleepEM3\r
+ ******************************************************************************/\r
+SLEEP_EnergyMode_t SLEEP_Sleep(void)\r
+{\r
+  SLEEP_EnergyMode_t allowedEM;\r
+\r
+  INT_Disable();\r
+\r
+  allowedEM = SLEEP_LowestEnergyModeGet();\r
+\r
+  if ((allowedEM >= sleepEM1) && (allowedEM <= sleepEM3))\r
+  {\r
+    SLEEP_EnterEMx(allowedEM);\r
+  }\r
+  else\r
+  {\r
+    allowedEM = sleepEM0;\r
+  }\r
+\r
+  INT_Enable();\r
+\r
+  return(allowedEM);\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Force the device to go to EM4 without doing any checks.\r
+ *\r
+ * @details\r
+ *   This function unblocks the low energy sleep block then goes to EM4.\r
+ *\r
+ * @note\r
+ *   Regular RAM is not retained in EM4 and the wake up causes a reset.\r
+ *   If the configuration option SLEEP_EM4_WAKEUP_CALLBACK_ENABLED is set to\r
+ *   true, the SLEEP_Init() function checks for the reset cause and calls the\r
+ *   EM4 wakeup callback.\r
+ ******************************************************************************/\r
+void SLEEP_ForceSleepInEM4(void)\r
+{\r
+#if (SLEEP_HW_LOW_ENERGY_BLOCK_ENABLED == true)\r
+  /* Unblock the EM2/EM3/EM4 block in the EMU. */\r
+  EMU_EM2UnBlock();\r
+#endif\r
+\r
+  /* Request entering to EM4. */\r
+  SLEEP_EnterEMx(sleepEM4);\r
+}\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Begin sleep block in the requested energy mode.\r
+ *\r
+ * @details\r
+ *   Blocking a critical system state from a certain energy mode makes sure that\r
+ *   the system is not set to that energy mode while the block is not being\r
+ *   released.\r
+ *   Every SLEEP_SleepBlockBegin() increases the corresponding counter and\r
+ *   every SLEEP_SleepBlockEnd() decreases it.\r
+ *\r
+ *   Example:\code\r
+ *      SLEEP_SleepBlockBegin(sleepEM2);  // do not allow EM2 or higher\r
+ *      // do some stuff that requires EM1 at least, like ADC sampling\r
+ *      SLEEP_SleepBlockEnd(sleepEM2);    // remove restriction for EM2\endcode\r
+ *\r
+ * @note\r
+ *   Be aware that there is limit of maximum blocks nesting to 255.\r
+ *\r
+ * @param[in] eMode\r
+ *   Energy mode to begin to block. Possible values:\r
+ *   @li sleepEM1 - Begin to block the system from being set to EM1 (and EM2..4).\r
+ *   @li sleepEM2 - Begin to block the system from being set to EM2 (and EM3/EM4).\r
+ *   @li sleepEM3 - Begin to block the system from being set to EM3 (and EM4).\r
+ ******************************************************************************/\r
+void SLEEP_SleepBlockBegin(SLEEP_EnergyMode_t eMode)\r
+{\r
+  EFM_ASSERT((eMode >= sleepEM1) && (eMode < sleepEM4));\r
+  EFM_ASSERT((sleepBlockCnt[(uint8_t) eMode - 1U]) < 255U);\r
+\r
+  /* Increase the sleep block counter of the selected energy mode. */\r
+  sleepBlockCnt[(uint8_t) eMode - 1U]++;\r
+\r
+#if (SLEEP_HW_LOW_ENERGY_BLOCK_ENABLED == true)\r
+  /* Block EM2/EM3 sleep if the EM2 block begins. */\r
+  if (eMode == sleepEM2)\r
+  {\r
+    EMU_EM2Block();\r
+  }\r
+#endif\r
+}\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   End sleep block in the requested energy mode.\r
+ *\r
+ * @details\r
+ *   Release restriction for entering certain energy mode. Every call of this\r
+ *   function reduce blocking counter by 1. Once the counter for specific energy\r
+ *   mode is 0 and all counters for lower energy modes are 0 as well, using\r
+ *   particular energy mode is allowed.\r
+ *   Every SLEEP_SleepBlockBegin() increases the corresponding counter and\r
+ *   every SLEEP_SleepBlockEnd() decreases it.\r
+ *\r
+ *   Example:\code\r
+ *      // at start all energy modes are allowed\r
+ *      SLEEP_SleepBlockBegin(sleepEM2); // EM2, EM3, EM4 are blocked\r
+ *      SLEEP_SleepBlockBegin(sleepEM1); // EM1, EM2, EM3, EM4 are blocked\r
+ *      SLEEP_SleepBlockBegin(sleepEM1); // EM1, EM2, EM3, EM4 are blocked\r
+ *      SLEEP_SleepBlockEnd(sleepEM2);   // still EM1, EM2, EM3, EM4 are blocked\r
+ *      SLEEP_SleepBlockEnd(sleepEM1);   // still EM1, EM2, EM3, EM4 are blocked\r
+ *      SLEEP_SleepBlockEnd(sleepEM1);   // all energy modes are allowed now\endcode\r
+ *\r
+ * @param[in] eMode\r
+ *   Energy mode to end to block. Possible values:\r
+ *   @li sleepEM1 - End to block the system from being set to EM1 (and EM2..4).\r
+ *   @li sleepEM2 - End to block the system from being set to EM2 (and EM3/EM4).\r
+ *   @li sleepEM3 - End to block the system from being set to EM3 (and EM4).\r
+ ******************************************************************************/\r
+void SLEEP_SleepBlockEnd(SLEEP_EnergyMode_t eMode)\r
+{\r
+  EFM_ASSERT((eMode >= sleepEM1) && (eMode < sleepEM4));\r
+\r
+  /* Decrease the sleep block counter of the selected energy mode. */\r
+  if (sleepBlockCnt[(uint8_t) eMode - 1U] > 0U)\r
+  {\r
+    sleepBlockCnt[(uint8_t) eMode - 1U]--;\r
+  }\r
+\r
+#if (SLEEP_HW_LOW_ENERGY_BLOCK_ENABLED == true)\r
+  /* Check if the EM2/EM3 block should be unblocked in the EMU. */\r
+  if (0U == sleepBlockCnt[(uint8_t) sleepEM2 - 1U])\r
+  {\r
+    EMU_EM2UnBlock();\r
+  }\r
+#endif\r
+}\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Gets the lowest energy mode that the system is allowed to be set to.\r
+ *\r
+ * @details\r
+ *   This function uses the low energy mode block counters to determine the\r
+ *   lowest possible that the system is allowed to be set to.\r
+ *\r
+ * @return\r
+ *   Lowest energy mode that the system can be set to. Possible values:\r
+ *   @li sleepEM0\r
+ *   @li sleepEM1\r
+ *   @li sleepEM2\r
+ *   @li sleepEM3\r
+ ******************************************************************************/\r
+SLEEP_EnergyMode_t SLEEP_LowestEnergyModeGet(void)\r
+{\r
+  SLEEP_EnergyMode_t tmpLowestEM = sleepEM0;\r
+\r
+  /* Check which is the lowest energy mode that the system can be set to. */\r
+  if (0U == sleepBlockCnt[(uint8_t) sleepEM1 - 1U])\r
+  {\r
+    tmpLowestEM = sleepEM1;\r
+    if (0U == sleepBlockCnt[(uint8_t) sleepEM2 - 1U])\r
+    {\r
+      tmpLowestEM = sleepEM2;\r
+      if (0U == sleepBlockCnt[(uint8_t) sleepEM3 - 1U])\r
+      {\r
+        tmpLowestEM = sleepEM3;\r
+      }\r
+    }\r
+  }\r
+\r
+  /* Compare with the default lowest energy mode setting. */\r
+  if (SLEEP_LOWEST_ENERGY_MODE_DEFAULT < tmpLowestEM)\r
+  {\r
+    tmpLowestEM = SLEEP_LOWEST_ENERGY_MODE_DEFAULT;\r
+  }\r
+\r
+  return tmpLowestEM;\r
+}\r
+\r
+/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Call the callbacks and enter the requested energy mode.\r
+ *\r
+ * @details\r
+ *   This function is not part of the API, therefore it shall not be called by\r
+ *   the user directly as it doesn not have any checks if the system is ready\r
+ *   for sleep!\r
+ *\r
+ * @note\r
+ *   The EM4 wakeup callback is not being called from this function because\r
+ *   waking up from EM4 causes a reset.\r
+ *   If SLEEP_EM4_WAKEUP_CALLBACK_ENABLED is set to true, SLEEP_Init() function\r
+ *   checks for the cause of the reset and calls the wakeup callback if the\r
+ *   reset was a wakeup from EM4.\r
+ ******************************************************************************/\r
+static void SLEEP_EnterEMx(SLEEP_EnergyMode_t eMode)\r
+{\r
+  EFM_ASSERT((eMode > sleepEM0) && (eMode <= sleepEM4));\r
+\r
+  /* Call sleepCallback() before going to sleep. */\r
+  if (NULL != sleepCallback)\r
+  {\r
+    /* Call the callback before going to sleep. */\r
+    sleepCallback(eMode);\r
+  }\r
+\r
+  /* Enter the requested energy mode. */\r
+  switch (eMode)\r
+  {\r
+  case sleepEM1:\r
+  {\r
+    EMU_EnterEM1();\r
+  } break;\r
+\r
+  case sleepEM2:\r
+  {\r
+    EMU_EnterEM2(true);\r
+  } break;\r
+\r
+  case sleepEM3:\r
+  {\r
+    EMU_EnterEM3(true);\r
+  } break;\r
+\r
+  case sleepEM4:\r
+  {\r
+    EMU_EnterEM4();\r
+  } break;\r
+\r
+  default:\r
+  {\r
+    /* Don't do anything, stay in EM0. */\r
+  } break;\r
+  }\r
+\r
+  /* Call the callback after waking up from sleep. */\r
+  if (NULL != wakeUpCallback)\r
+  {\r
+    wakeUpCallback(eMode);\r
+  }\r
+}\r
+/** @endcond */\r
+\r
+/** @} (end addtogroup SLEEP */\r
+/** @} (end addtogroup EM_Drivers) */\r
diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/emlib/em_assert.c b/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/emlib/em_assert.c
new file mode 100644 (file)
index 0000000..9e9d99f
--- /dev/null
@@ -0,0 +1,69 @@
+/***************************************************************************//**\r
+ * @file em_assert.c\r
+ * @brief Assert API\r
+ * @version 4.2.1\r
+ *******************************************************************************\r
+ * @section License\r
+ * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>\r
+ *******************************************************************************\r
+ *\r
+ * Permission is granted to anyone to use this software for any purpose,\r
+ * including commercial applications, and to alter it and redistribute it\r
+ * freely, subject to the following restrictions:\r
+ *\r
+ * 1. The origin of this software must not be misrepresented; you must not\r
+ *    claim that you wrote the original software.\r
+ * 2. Altered source versions must be plainly marked as such, and must not be\r
+ *    misrepresented as being the original software.\r
+ * 3. This notice may not be removed or altered from any source distribution.\r
+ *\r
+ * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no\r
+ * obligation to support this Software. Silicon Labs is providing the\r
+ * Software "AS IS", with no express or implied warranties of any kind,\r
+ * including, but not limited to, any implied warranties of merchantability\r
+ * or fitness for any particular purpose or warranties against infringement\r
+ * of any proprietary rights of a third party.\r
+ *\r
+ * Silicon Labs will not be liable for any consequential, incidental, or\r
+ * special damages, or any other relief, or for any claim by any third party,\r
+ * arising from your use of this Software.\r
+ *\r
+ ******************************************************************************/\r
+\r
+\r
+#include "em_assert.h"\r
+\r
+#if defined(DEBUG_EFM)\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   EFM internal assert handling.\r
+ *\r
+ *   This function is invoked through EFM_ASSERT() macro usage only, it should\r
+ *   not be used explicitly.\r
+ *\r
+ *   Currently this implementation only enters an indefinite loop, allowing\r
+ *   the use of a debugger to determine cause of failure. By defining\r
+ *   DEBUG_EFM_USER to the preprocessor for all files, a user defined version\r
+ *   of this function must be defined and will be invoked instead, possibly\r
+ *   providing output of assertion location.\r
+ *\r
+ *   Please notice that this function is not used unless DEBUG_EFM is defined\r
+ *   during preprocessing of EFM_ASSERT() usage.\r
+ *\r
+ * @par file\r
+ *   Name of source file where assertion failed.\r
+ *\r
+ * @par line\r
+ *   Line number in source file where assertion failed.\r
+ ******************************************************************************/\r
+void assertEFM(const char *file, int line)\r
+{\r
+  (void)file;  /* Unused parameter */\r
+  (void)line;  /* Unused parameter */\r
+\r
+  while (1)\r
+    ;\r
+}\r
+\r
+#endif /* DEBUG_EFM */\r
diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/emlib/em_cmu.c b/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/emlib/em_cmu.c
new file mode 100644 (file)
index 0000000..93473ba
--- /dev/null
@@ -0,0 +1,3786 @@
+/***************************************************************************//**\r
+ * @file em_cmu.c\r
+ * @brief Clock management unit (CMU) Peripheral API\r
+ * @version 4.2.1\r
+ *******************************************************************************\r
+ * @section License\r
+ * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>\r
+ *******************************************************************************\r
+ *\r
+ * Permission is granted to anyone to use this software for any purpose,\r
+ * including commercial applications, and to alter it and redistribute it\r
+ * freely, subject to the following restrictions:\r
+ *\r
+ * 1. The origin of this software must not be misrepresented; you must not\r
+ *    claim that you wrote the original software.\r
+ * 2. Altered source versions must be plainly marked as such, and must not be\r
+ *    misrepresented as being the original software.\r
+ * 3. This notice may not be removed or altered from any source distribution.\r
+ *\r
+ * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no\r
+ * obligation to support this Software. Silicon Labs is providing the\r
+ * Software "AS IS", with no express or implied warranties of any kind,\r
+ * including, but not limited to, any implied warranties of merchantability\r
+ * or fitness for any particular purpose or warranties against infringement\r
+ * of any proprietary rights of a third party.\r
+ *\r
+ * Silicon Labs will not be liable for any consequential, incidental, or\r
+ * special damages, or any other relief, or for any claim by any third party,\r
+ * arising from your use of this Software.\r
+ *\r
+ ******************************************************************************/\r
+#include "em_cmu.h"\r
+#if defined( CMU_PRESENT )\r
+\r
+#include <stddef.h>\r
+#include <limits.h>\r
+#include "em_assert.h"\r
+#include "em_bus.h"\r
+#include "em_emu.h"\r
+#include "em_system.h"\r
+\r
+/***************************************************************************//**\r
+ * @addtogroup EM_Library\r
+ * @{\r
+ ******************************************************************************/\r
+\r
+/***************************************************************************//**\r
+ * @addtogroup CMU\r
+ * @brief Clock management unit (CMU) Peripheral API\r
+ * @{\r
+ ******************************************************************************/\r
+\r
+/*******************************************************************************\r
+ ******************************   DEFINES   ************************************\r
+ ******************************************************************************/\r
+\r
+/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */\r
+\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+/** Maximum allowed core frequency when using 0 wait-states on flash access. */\r
+#define CMU_MAX_FREQ_0WS    26000000\r
+/** Maximum allowed core frequency when using 1 wait-states on flash access */\r
+#define CMU_MAX_FREQ_1WS    40000000\r
+#elif defined( _SILICON_LABS_32B_PLATFORM_1 )\r
+/** Maximum allowed core frequency when using 0 wait-states on flash access. */\r
+#define CMU_MAX_FREQ_0WS    16000000\r
+/** Maximum allowed core frequency when using 1 wait-states on flash access */\r
+#define CMU_MAX_FREQ_1WS    32000000\r
+#else\r
+#error "Unkown MCU platform."\r
+#endif\r
+\r
+#if defined( CMU_CTRL_HFLE )\r
+/** Maximum frequency for HFLE needs to be enabled on Giant, Leopard and\r
+    Wonder. */\r
+#if defined( _EFM32_WONDER_FAMILY )     \\r
+    || defined( _EZR32_LEOPARD_FAMILY ) \\r
+    || defined( _EZR32_WONDER_FAMILY )\r
+#define CMU_MAX_FREQ_HFLE() 24000000\r
+#elif defined ( _EFM32_GIANT_FAMILY )\r
+#define CMU_MAX_FREQ_HFLE() (maxFreqHfle())\r
+#else\r
+#error Invalid part/device.\r
+#endif\r
+#endif\r
+\r
+/*******************************************************************************\r
+ **************************   LOCAL VARIABLES   ********************************\r
+ ******************************************************************************/\r
+\r
+#if defined( _CMU_AUXHFRCOCTRL_FREQRANGE_MASK )\r
+static CMU_AUXHFRCOFreq_TypeDef auxHfrcoFreq = cmuAUXHFRCOFreq_19M0Hz;\r
+#endif\r
+\r
+/** @endcond */\r
+\r
+/*******************************************************************************\r
+ **************************   LOCAL FUNCTIONS   ********************************\r
+ ******************************************************************************/\r
+\r
+/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Get the AUX clock frequency. Used by MSC flash programming and LESENSE,\r
+ *   by default also as debug clock.\r
+ *\r
+ * @return\r
+ *   AUX Frequency in Hz\r
+ ******************************************************************************/\r
+static uint32_t auxClkGet(void)\r
+{\r
+  uint32_t ret;\r
+\r
+#if defined( _CMU_AUXHFRCOCTRL_FREQRANGE_MASK )\r
+  ret = auxHfrcoFreq;\r
+\r
+#elif defined( _CMU_AUXHFRCOCTRL_BAND_MASK )\r
+  /* All Geckos from TG and newer */\r
+  switch(CMU->AUXHFRCOCTRL & _CMU_AUXHFRCOCTRL_BAND_MASK)\r
+  {\r
+    case CMU_AUXHFRCOCTRL_BAND_1MHZ:\r
+      ret = 1000000;\r
+      break;\r
+\r
+    case CMU_AUXHFRCOCTRL_BAND_7MHZ:\r
+      ret = 7000000;\r
+      break;\r
+\r
+    case CMU_AUXHFRCOCTRL_BAND_11MHZ:\r
+      ret = 11000000;\r
+      break;\r
+\r
+    case CMU_AUXHFRCOCTRL_BAND_14MHZ:\r
+      ret = 14000000;\r
+      break;\r
+\r
+    case CMU_AUXHFRCOCTRL_BAND_21MHZ:\r
+      ret = 21000000;\r
+      break;\r
+\r
+#if defined( _CMU_AUXHFRCOCTRL_BAND_28MHZ )\r
+    case CMU_AUXHFRCOCTRL_BAND_28MHZ:\r
+      ret = 28000000;\r
+      break;\r
+#endif\r
+\r
+    default:\r
+      EFM_ASSERT(0);\r
+      ret = 0;\r
+      break;\r
+  }\r
+\r
+#else\r
+  /* Gecko has a fixed 14Mhz AUXHFRCO clock */\r
+  ret = 14000000;\r
+\r
+#endif\r
+\r
+  return ret;\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Get the Debug Trace clock frequency\r
+ *\r
+ * @return\r
+ *   Debug Trace frequency in Hz\r
+ ******************************************************************************/\r
+static uint32_t dbgClkGet(void)\r
+{\r
+  uint32_t ret;\r
+  CMU_Select_TypeDef clk;\r
+\r
+  /* Get selected clock source */\r
+  clk = CMU_ClockSelectGet(cmuClock_DBG);\r
+\r
+  switch(clk)\r
+  {\r
+    case cmuSelect_HFCLK:\r
+      ret = SystemHFClockGet();\r
+#if defined( _CMU_CTRL_HFCLKDIV_MASK )\r
+      /* Family with an additional divider. */\r
+      ret = ret / (1 + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK)\r
+                        >> _CMU_CTRL_HFCLKDIV_SHIFT));\r
+#endif\r
+      break;\r
+\r
+    case cmuSelect_AUXHFRCO:\r
+      ret = auxClkGet();\r
+      break;\r
+\r
+    default:\r
+      EFM_ASSERT(0);\r
+      ret = 0;\r
+      break;\r
+  }\r
+  return ret;\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Configure flash access wait states in order to support given core clock\r
+ *   frequency.\r
+ *\r
+ * @param[in] coreFreq\r
+ *   Core clock frequency to configure flash wait-states for\r
+ ******************************************************************************/\r
+static void flashWaitStateControl(uint32_t coreFreq)\r
+{\r
+  uint32_t mode;\r
+  bool mscLocked;\r
+#if defined( MSC_READCTRL_MODE_WS0SCBTP )\r
+  bool scbtpEn;   /* Suppressed Conditional Branch Target Prefetch setting. */\r
+#endif\r
+\r
+  /* Make sure the MSC is unlocked */\r
+  mscLocked = MSC->LOCK;\r
+  MSC->LOCK = MSC_UNLOCK_CODE;\r
+\r
+  /* Get mode and SCBTP enable */\r
+  mode = MSC->READCTRL & _MSC_READCTRL_MODE_MASK;\r
+#if defined( MSC_READCTRL_MODE_WS0SCBTP )\r
+  switch(mode)\r
+  {\r
+    case MSC_READCTRL_MODE_WS0:\r
+    case MSC_READCTRL_MODE_WS1:\r
+#if defined( MSC_READCTRL_MODE_WS2 )\r
+    case MSC_READCTRL_MODE_WS2:\r
+#endif\r
+      scbtpEn = false;\r
+      break;\r
+\r
+    default: /* WSxSCBTP */\r
+      scbtpEn = true;\r
+    break;\r
+  }\r
+#endif\r
+\r
+\r
+  /* Set mode based on the core clock frequency and SCBTP enable */\r
+#if defined( MSC_READCTRL_MODE_WS0SCBTP )\r
+  if (false)\r
+  {\r
+  }\r
+#if defined( MSC_READCTRL_MODE_WS2 )\r
+  else if (coreFreq > CMU_MAX_FREQ_1WS)\r
+  {\r
+    mode = (scbtpEn ? MSC_READCTRL_MODE_WS2SCBTP : MSC_READCTRL_MODE_WS2);\r
+  }\r
+#endif\r
+  else if ((coreFreq <= CMU_MAX_FREQ_1WS) && (coreFreq > CMU_MAX_FREQ_0WS))\r
+  {\r
+    mode = (scbtpEn ? MSC_READCTRL_MODE_WS1SCBTP : MSC_READCTRL_MODE_WS1);\r
+  }\r
+  else\r
+  {\r
+    mode = (scbtpEn ? MSC_READCTRL_MODE_WS0SCBTP : MSC_READCTRL_MODE_WS0);\r
+  }\r
+\r
+#else /* If MODE and SCBTP is in separate register fields */\r
+\r
+  if (false)\r
+  {\r
+  }\r
+#if defined( MSC_READCTRL_MODE_WS2 )\r
+  else if (coreFreq > CMU_MAX_FREQ_1WS)\r
+  {\r
+    mode = MSC_READCTRL_MODE_WS2;\r
+  }\r
+#endif\r
+  else if ((coreFreq <= CMU_MAX_FREQ_1WS) && (coreFreq > CMU_MAX_FREQ_0WS))\r
+  {\r
+    mode = MSC_READCTRL_MODE_WS1;\r
+  }\r
+  else\r
+  {\r
+    mode = MSC_READCTRL_MODE_WS0;\r
+  }\r
+#endif\r
+\r
+  /* BUS_RegMaskedWrite cannot be used here as it would temporarely set the\r
+     mode field to WS0 */\r
+  MSC->READCTRL = (MSC->READCTRL &~_MSC_READCTRL_MODE_MASK) | mode;\r
+\r
+  if (mscLocked)\r
+  {\r
+    MSC->LOCK = 0;\r
+  }\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Configure flash access wait states to most conservative setting for\r
+ *   this target. Retain SCBTP (Suppressed Conditional Branch Target Prefetch)\r
+ *   setting.\r
+ ******************************************************************************/\r
+static void flashWaitStateMax(void)\r
+{\r
+  flashWaitStateControl(SystemMaxCoreClockGet());\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Get the LFnCLK frequency based on current configuration.\r
+ *\r
+ * @param[in] lfClkBranch\r
+ *   Selected LF branch\r
+ *\r
+ * @return\r
+ *   The LFnCLK frequency in Hz. If no LFnCLK is selected (disabled), 0 is\r
+ *   returned.\r
+ ******************************************************************************/\r
+static uint32_t lfClkGet(CMU_Clock_TypeDef lfClkBranch)\r
+{\r
+  uint32_t sel;\r
+  uint32_t ret = 0;\r
+\r
+  switch (lfClkBranch)\r
+  {\r
+    case cmuClock_LFA:\r
+    case cmuClock_LFB:\r
+#if defined( _CMU_LFCCLKEN0_MASK )\r
+    case cmuClock_LFC:\r
+#endif\r
+#if defined( _CMU_LFECLKSEL_MASK )\r
+    case cmuClock_LFE:\r
+#endif\r
+      break;\r
+\r
+    default:\r
+      EFM_ASSERT(0);\r
+      break;\r
+  }\r
+\r
+  sel = CMU_ClockSelectGet(lfClkBranch);\r
+\r
+  /* Get clock select field */\r
+  switch (lfClkBranch)\r
+  {\r
+    case cmuClock_LFA:\r
+#if defined( _CMU_LFCLKSEL_MASK )\r
+      sel = (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFA_MASK) >> _CMU_LFCLKSEL_LFA_SHIFT;\r
+#elif defined( _CMU_LFACLKSEL_MASK )\r
+      sel = (CMU->LFACLKSEL & _CMU_LFACLKSEL_LFA_MASK) >> _CMU_LFACLKSEL_LFA_SHIFT;\r
+#else\r
+      EFM_ASSERT(0);\r
+#endif\r
+      break;\r
+\r
+    case cmuClock_LFB:\r
+#if defined( _CMU_LFCLKSEL_MASK )\r
+      sel = (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFB_MASK) >> _CMU_LFCLKSEL_LFB_SHIFT;\r
+#elif defined( _CMU_LFBCLKSEL_MASK )\r
+      sel = (CMU->LFBCLKSEL & _CMU_LFBCLKSEL_LFB_MASK) >> _CMU_LFBCLKSEL_LFB_SHIFT;\r
+#else\r
+      EFM_ASSERT(0);\r
+#endif\r
+      break;\r
+\r
+#if defined( _CMU_LFCCLKEN0_MASK )\r
+    case cmuClock_LFC:\r
+      sel = (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFC_MASK) >> _CMU_LFCLKSEL_LFC_SHIFT;\r
+      break;\r
+#endif\r
+\r
+#if defined( _CMU_LFECLKSEL_MASK )\r
+    case cmuClock_LFE:\r
+      sel = (CMU->LFECLKSEL & _CMU_LFECLKSEL_LFE_MASK) >> _CMU_LFECLKSEL_LFE_SHIFT;\r
+      break;\r
+#endif\r
+\r
+    default:\r
+      EFM_ASSERT(0);\r
+      break;\r
+  }\r
+\r
+  /* Get clock frequency */\r
+#if defined( _CMU_LFCLKSEL_MASK )\r
+  switch (sel)\r
+  {\r
+    case _CMU_LFCLKSEL_LFA_LFRCO:\r
+      ret = SystemLFRCOClockGet();\r
+      break;\r
+\r
+    case _CMU_LFCLKSEL_LFA_LFXO:\r
+      ret = SystemLFXOClockGet();\r
+      break;\r
+\r
+#if defined( _CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2 )\r
+    case _CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2:\r
+#if defined( CMU_CTRL_HFLE )\r
+      /* Family which can use an extra div 4 divider  */\r
+      /* (and must if >32MHz) or HFLE is set.         */\r
+      if(((CMU->HFCORECLKDIV & _CMU_HFCORECLKDIV_HFCORECLKLEDIV_MASK)\r
+           == CMU_HFCORECLKDIV_HFCORECLKLEDIV_DIV4)\r
+         || (CMU->CTRL & CMU_CTRL_HFLE))\r
+      {\r
+        ret = SystemCoreClockGet() / 4U;\r
+      }\r
+      else\r
+      {\r
+        ret = SystemCoreClockGet() / 2U;\r
+      }\r
+#else\r
+      ret = SystemCoreClockGet() / 2U;\r
+#endif\r
+      break;\r
+#endif\r
+\r
+    case _CMU_LFCLKSEL_LFA_DISABLED:\r
+      ret = 0;\r
+#if defined( CMU_LFCLKSEL_LFAE )\r
+      /* Check LF Extended bit setting for LFA or LFB ULFRCO clock */\r
+      if ((lfClkBranch == cmuClock_LFA) || (lfClkBranch == cmuClock_LFB))\r
+      {\r
+        if (CMU->LFCLKSEL >> (lfClkBranch == cmuClock_LFA\r
+                              ? _CMU_LFCLKSEL_LFAE_SHIFT\r
+                              : _CMU_LFCLKSEL_LFBE_SHIFT))\r
+        {\r
+          ret = SystemULFRCOClockGet();\r
+        }\r
+      }\r
+#endif\r
+      break;\r
+\r
+    default:\r
+      EFM_ASSERT(0);\r
+      ret = 0U;\r
+      break;\r
+  }\r
+#endif /* _CMU_LFCLKSEL_MASK */\r
+\r
+#if defined( _CMU_LFACLKSEL_MASK )\r
+  switch (sel)\r
+  {\r
+    case _CMU_LFACLKSEL_LFA_LFRCO:\r
+      ret = SystemLFRCOClockGet();\r
+      break;\r
+\r
+    case _CMU_LFACLKSEL_LFA_LFXO:\r
+      ret = SystemLFXOClockGet();\r
+      break;\r
+\r
+    case _CMU_LFACLKSEL_LFA_ULFRCO:\r
+      ret = SystemULFRCOClockGet();\r
+      break;\r
+\r
+#if defined( _CMU_LFACLKSEL_LFA_HFCLKLE )\r
+    case _CMU_LFACLKSEL_LFA_HFCLKLE:\r
+      ret = ((CMU->HFPRESC & _CMU_HFPRESC_HFCLKLEPRESC_MASK)\r
+             == CMU_HFPRESC_HFCLKLEPRESC_DIV4)\r
+            ? SystemCoreClockGet() / 4U\r
+            : SystemCoreClockGet() / 2U;\r
+      break;\r
+#elif defined( _CMU_LFBCLKSEL_LFB_HFCLKLE )\r
+    case _CMU_LFBCLKSEL_LFB_HFCLKLE:\r
+      ret = ((CMU->HFPRESC & _CMU_HFPRESC_HFCLKLEPRESC_MASK)\r
+             == CMU_HFPRESC_HFCLKLEPRESC_DIV4)\r
+            ? SystemCoreClockGet() / 4U\r
+            : SystemCoreClockGet() / 2U;\r
+      break;\r
+#endif\r
+\r
+    case _CMU_LFACLKSEL_LFA_DISABLED:\r
+      ret = 0;\r
+      break;\r
+  }\r
+#endif\r
+\r
+  return ret;\r
+}\r
+\r
+\r
+#if defined( CMU_CTRL_HFLE )              \\r
+    && !defined( _EFM32_WONDER_FAMILY )   \\r
+    && !defined( _EZR32_LEOPARD_FAMILY )  \\r
+    && !defined( _EZR32_WONDER_FAMILY )\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Return max allowed frequency for low energy peripherals.\r
+ ******************************************************************************/\r
+static uint32_t maxFreqHfle(void)\r
+{\r
+  uint16_t majorMinorRev;\r
+\r
+  switch (SYSTEM_GetFamily())\r
+  {\r
+    case systemPartFamilyEfm32Leopard:\r
+      /* CHIP MAJOR bit [5:0] */\r
+      majorMinorRev = (((ROMTABLE->PID0 & _ROMTABLE_PID0_REVMAJOR_MASK)\r
+                        >> _ROMTABLE_PID0_REVMAJOR_SHIFT) << 8);\r
+      /* CHIP MINOR bit [7:4] */\r
+      majorMinorRev |= (((ROMTABLE->PID2 & _ROMTABLE_PID2_REVMINORMSB_MASK)\r
+                         >> _ROMTABLE_PID2_REVMINORMSB_SHIFT) << 4);\r
+      /* CHIP MINOR bit [3:0] */\r
+      majorMinorRev |=  ((ROMTABLE->PID3 & _ROMTABLE_PID3_REVMINORLSB_MASK)\r
+                         >> _ROMTABLE_PID3_REVMINORLSB_SHIFT);\r
+\r
+      if (majorMinorRev >= 0x0204)\r
+        return 24000000;\r
+      else\r
+        return 32000000;\r
+\r
+    case systemPartFamilyEfm32Giant:\r
+      return 32000000;\r
+\r
+    default:\r
+      /* Invalid device family. */\r
+      EFM_ASSERT(false);\r
+      return 0;\r
+  }\r
+}\r
+#endif\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Wait for ongoing sync of register(s) to low frequency domain to complete.\r
+ *\r
+ * @param[in] mask\r
+ *   Bitmask corresponding to SYNCBUSY register defined bits, indicating\r
+ *   registers that must complete any ongoing synchronization.\r
+ ******************************************************************************/\r
+__STATIC_INLINE void syncReg(uint32_t mask)\r
+{\r
+  /* Avoid deadlock if modifying the same register twice when freeze mode is */\r
+  /* activated. */\r
+  if (CMU->FREEZE & CMU_FREEZE_REGFREEZE)\r
+    return;\r
+\r
+  /* Wait for any pending previous write operation to have been completed */\r
+  /* in low frequency domain */\r
+  while (CMU->SYNCBUSY & mask)\r
+  {\r
+  }\r
+}\r
+\r
+\r
+#if defined(USB_PRESENT)\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Get the USBC frequency\r
+ *\r
+ * @return\r
+ *   USBC frequency in Hz\r
+ ******************************************************************************/\r
+static uint32_t usbCClkGet(void)\r
+{\r
+  uint32_t ret;\r
+  CMU_Select_TypeDef clk;\r
+\r
+  /* Get selected clock source */\r
+  clk = CMU_ClockSelectGet(cmuClock_USBC);\r
+\r
+  switch(clk)\r
+  {\r
+    case cmuSelect_LFXO:\r
+      ret = SystemLFXOClockGet();\r
+      break;\r
+    case cmuSelect_LFRCO:\r
+      ret = SystemLFRCOClockGet();\r
+      break;\r
+    case cmuSelect_HFCLK:\r
+      ret = SystemHFClockGet();\r
+      break;\r
+    default:\r
+      /* Clock is not enabled */\r
+      ret = 0;\r
+      break;\r
+  }\r
+  return ret;\r
+}\r
+#endif\r
+\r
+\r
+/** @endcond */\r
+\r
+/*******************************************************************************\r
+ **************************   GLOBAL FUNCTIONS   *******************************\r
+ ******************************************************************************/\r
+\r
+#if defined( _CMU_AUXHFRCOCTRL_BAND_MASK )\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Get AUXHFRCO band in use.\r
+ *\r
+ * @return\r
+ *   AUXHFRCO band in use.\r
+ ******************************************************************************/\r
+CMU_AUXHFRCOBand_TypeDef CMU_AUXHFRCOBandGet(void)\r
+{\r
+  return (CMU_AUXHFRCOBand_TypeDef)((CMU->AUXHFRCOCTRL\r
+                                     & _CMU_AUXHFRCOCTRL_BAND_MASK)\r
+                                    >> _CMU_AUXHFRCOCTRL_BAND_SHIFT);\r
+}\r
+#endif /* _CMU_AUXHFRCOCTRL_BAND_MASK */\r
+\r
+\r
+#if defined( _CMU_AUXHFRCOCTRL_BAND_MASK )\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Set AUXHFRCO band and the tuning value based on the value in the\r
+ *   calibration table made during production.\r
+ *\r
+ * @param[in] band\r
+ *   AUXHFRCO band to activate.\r
+ ******************************************************************************/\r
+void CMU_AUXHFRCOBandSet(CMU_AUXHFRCOBand_TypeDef band)\r
+{\r
+  uint32_t tuning;\r
+\r
+  /* Read tuning value from calibration table */\r
+  switch (band)\r
+  {\r
+    case cmuAUXHFRCOBand_1MHz:\r
+      tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND1_MASK)\r
+               >> _DEVINFO_AUXHFRCOCAL0_BAND1_SHIFT;\r
+      break;\r
+\r
+    case cmuAUXHFRCOBand_7MHz:\r
+      tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND7_MASK)\r
+               >> _DEVINFO_AUXHFRCOCAL0_BAND7_SHIFT;\r
+      break;\r
+\r
+    case cmuAUXHFRCOBand_11MHz:\r
+      tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND11_MASK)\r
+               >> _DEVINFO_AUXHFRCOCAL0_BAND11_SHIFT;\r
+      break;\r
+\r
+    case cmuAUXHFRCOBand_14MHz:\r
+      tuning = (DEVINFO->AUXHFRCOCAL0 & _DEVINFO_AUXHFRCOCAL0_BAND14_MASK)\r
+               >> _DEVINFO_AUXHFRCOCAL0_BAND14_SHIFT;\r
+      break;\r
+\r
+    case cmuAUXHFRCOBand_21MHz:\r
+      tuning = (DEVINFO->AUXHFRCOCAL1 & _DEVINFO_AUXHFRCOCAL1_BAND21_MASK)\r
+               >> _DEVINFO_AUXHFRCOCAL1_BAND21_SHIFT;\r
+      break;\r
+\r
+#if defined( _CMU_AUXHFRCOCTRL_BAND_28MHZ )\r
+    case cmuAUXHFRCOBand_28MHz:\r
+      tuning = (DEVINFO->AUXHFRCOCAL1 & _DEVINFO_AUXHFRCOCAL1_BAND28_MASK)\r
+               >> _DEVINFO_AUXHFRCOCAL1_BAND28_SHIFT;\r
+      break;\r
+#endif\r
+\r
+    default:\r
+      EFM_ASSERT(0);\r
+      return;\r
+  }\r
+\r
+  /* Set band/tuning */\r
+  CMU->AUXHFRCOCTRL = (CMU->AUXHFRCOCTRL &\r
+                       ~(_CMU_AUXHFRCOCTRL_BAND_MASK\r
+                         | _CMU_AUXHFRCOCTRL_TUNING_MASK))\r
+                      | (band << _CMU_AUXHFRCOCTRL_BAND_SHIFT)\r
+                      | (tuning << _CMU_AUXHFRCOCTRL_TUNING_SHIFT);\r
+\r
+}\r
+#endif /* _CMU_AUXHFRCOCTRL_BAND_MASK */\r
+\r
+\r
+#if defined( _CMU_AUXHFRCOCTRL_FREQRANGE_MASK )\r
+/**************************************************************************//**\r
+ * @brief\r
+ *   Get a pointer to the AUXHFRCO frequency calibration word in DEVINFO\r
+ *\r
+ * @param[in] freq\r
+ *   Frequency in Hz\r
+ *\r
+ * @return\r
+ *   AUXHFRCO calibration word for a given frequency\r
+ *****************************************************************************/\r
+static uint32_t CMU_AUXHFRCODevinfoGet(CMU_AUXHFRCOFreq_TypeDef freq)\r
+{\r
+  switch (freq)\r
+  {\r
+  /* 1, 2 and 4MHz share the same calibration word */\r
+    case cmuAUXHFRCOFreq_1M0Hz:\r
+    case cmuAUXHFRCOFreq_2M0Hz:\r
+    case cmuAUXHFRCOFreq_4M0Hz:\r
+      return DEVINFO->AUXHFRCOCAL0;\r
+\r
+    case cmuAUXHFRCOFreq_7M0Hz:\r
+      return DEVINFO->AUXHFRCOCAL3;\r
+\r
+    case cmuAUXHFRCOFreq_13M0Hz:\r
+      return DEVINFO->AUXHFRCOCAL6;\r
+\r
+    case cmuAUXHFRCOFreq_16M0Hz:\r
+      return DEVINFO->AUXHFRCOCAL7;\r
+\r
+    case cmuAUXHFRCOFreq_19M0Hz:\r
+      return DEVINFO->AUXHFRCOCAL8;\r
+\r
+    case cmuAUXHFRCOFreq_26M0Hz:\r
+      return DEVINFO->AUXHFRCOCAL10;\r
+\r
+    case cmuAUXHFRCOFreq_32M0Hz:\r
+      return DEVINFO->AUXHFRCOCAL11;\r
+\r
+    case cmuAUXHFRCOFreq_38M0Hz:\r
+      return DEVINFO->AUXHFRCOCAL12;\r
+\r
+    default: /* cmuAUXHFRCOFreq_UserDefined */\r
+      return 0;\r
+  }\r
+}\r
+#endif /* _CMU_AUXHFRCOCTRL_FREQRANGE_MASK */\r
+\r
+\r
+#if defined( _CMU_AUXHFRCOCTRL_FREQRANGE_MASK )\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Get AUXHFRCO frequency enumeration in use\r
+ *\r
+ * @return\r
+ *   AUXHFRCO frequency enumeration in use\r
+ ******************************************************************************/\r
+CMU_AUXHFRCOFreq_TypeDef CMU_AUXHFRCOFreqGet(void)\r
+{\r
+  return auxHfrcoFreq;\r
+}\r
+#endif /* _CMU_AUXHFRCOCTRL_FREQRANGE_MASK */\r
+\r
+\r
+#if defined( _CMU_AUXHFRCOCTRL_FREQRANGE_MASK )\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Set AUXHFRCO calibration for the selected target frequency\r
+ *\r
+ * @param[in] frequency\r
+ *   AUXHFRCO frequency to set\r
+ ******************************************************************************/\r
+void CMU_AUXHFRCOFreqSet(CMU_AUXHFRCOFreq_TypeDef freq)\r
+{\r
+  uint32_t freqCal;\r
+\r
+  /* Get DEVINFO index, set global auxHfrcoFreq */\r
+  freqCal = CMU_AUXHFRCODevinfoGet(freq);\r
+  EFM_ASSERT((freqCal != 0) && (freqCal != UINT_MAX));\r
+  auxHfrcoFreq = freq;\r
+\r
+  /* Wait for any previous sync to complete, and then set calibration data\r
+     for the selected frequency.  */\r
+  while(BUS_RegBitRead(&CMU->SYNCBUSY, _CMU_SYNCBUSY_AUXHFRCOBSY_SHIFT));\r
+\r
+  /* Set divider in AUXHFRCOCTRL for 1, 2 and 4MHz */\r
+  switch(freq)\r
+  {\r
+    case cmuAUXHFRCOFreq_1M0Hz:\r
+      freqCal = (freqCal & ~_CMU_AUXHFRCOCTRL_CLKDIV_MASK)\r
+                | CMU_AUXHFRCOCTRL_CLKDIV_DIV4;\r
+      break;\r
+\r
+    case cmuAUXHFRCOFreq_2M0Hz:\r
+      freqCal = (freqCal & ~_CMU_AUXHFRCOCTRL_CLKDIV_MASK)\r
+                | CMU_AUXHFRCOCTRL_CLKDIV_DIV2;\r
+      break;\r
+\r
+    case cmuAUXHFRCOFreq_4M0Hz:\r
+      freqCal = (freqCal & ~_CMU_AUXHFRCOCTRL_CLKDIV_MASK)\r
+                | CMU_AUXHFRCOCTRL_CLKDIV_DIV1;\r
+      break;\r
+\r
+    default:\r
+      break;\r
+  }\r
+  CMU->AUXHFRCOCTRL = freqCal;\r
+}\r
+#endif /* _CMU_AUXHFRCOCTRL_FREQRANGE_MASK */\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Calibrate clock.\r
+ *\r
+ * @details\r
+ *   Run a calibration for HFCLK against a selectable reference clock. Please\r
+ *   refer to the reference manual, CMU chapter, for further details.\r
+ *\r
+ * @note\r
+ *   This function will not return until calibration measurement is completed.\r
+ *\r
+ * @param[in] HFCycles\r
+ *   The number of HFCLK cycles to run calibration. Increasing this number\r
+ *   increases precision, but the calibration will take more time.\r
+ *\r
+ * @param[in] ref\r
+ *   The reference clock used to compare HFCLK with.\r
+ *\r
+ * @return\r
+ *   The number of ticks the reference clock after HFCycles ticks on the HF\r
+ *   clock.\r
+ ******************************************************************************/\r
+uint32_t CMU_Calibrate(uint32_t HFCycles, CMU_Osc_TypeDef ref)\r
+{\r
+  EFM_ASSERT(HFCycles <= (_CMU_CALCNT_CALCNT_MASK >> _CMU_CALCNT_CALCNT_SHIFT));\r
+\r
+  /* Set reference clock source */\r
+  switch (ref)\r
+  {\r
+    case cmuOsc_LFXO:\r
+      CMU->CALCTRL = CMU_CALCTRL_UPSEL_LFXO;\r
+      break;\r
+\r
+    case cmuOsc_LFRCO:\r
+      CMU->CALCTRL = CMU_CALCTRL_UPSEL_LFRCO;\r
+      break;\r
+\r
+    case cmuOsc_HFXO:\r
+      CMU->CALCTRL = CMU_CALCTRL_UPSEL_HFXO;\r
+      break;\r
+\r
+    case cmuOsc_HFRCO:\r
+      CMU->CALCTRL = CMU_CALCTRL_UPSEL_HFRCO;\r
+      break;\r
+\r
+    case cmuOsc_AUXHFRCO:\r
+      CMU->CALCTRL = CMU_CALCTRL_UPSEL_AUXHFRCO;\r
+      break;\r
+\r
+    default:\r
+      EFM_ASSERT(0);\r
+      return 0;\r
+  }\r
+\r
+  /* Set top value */\r
+  CMU->CALCNT = HFCycles;\r
+\r
+  /* Start calibration */\r
+  CMU->CMD = CMU_CMD_CALSTART;\r
+\r
+#if defined( CMU_STATUS_CALRDY )\r
+  /* Wait until calibration completes */\r
+  while (!BUS_RegBitRead(&CMU->STATUS, _CMU_STATUS_CALRDY_SHIFT))\r
+  {\r
+  }\r
+#else\r
+  /* Wait until calibration completes */\r
+  while (BUS_RegBitRead(&CMU->STATUS, _CMU_STATUS_CALBSY_SHIFT))\r
+  {\r
+  }\r
+#endif\r
+\r
+  return CMU->CALCNT;\r
+}\r
+\r
+\r
+#if defined( _CMU_CALCTRL_UPSEL_MASK ) && defined( _CMU_CALCTRL_DOWNSEL_MASK )\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Configure clock calibration\r
+ *\r
+ * @details\r
+ *   Configure a calibration for a selectable clock source against another\r
+ *   selectable reference clock.\r
+ *   Refer to the reference manual, CMU chapter, for further details.\r
+ *\r
+ * @note\r
+ *   After configuration, a call to CMU_CalibrateStart() is required, and\r
+ *   the resulting calibration value can be read out with the\r
+ *   CMU_CalibrateCountGet() function call.\r
+ *\r
+ * @param[in] downCycles\r
+ *   The number of downSel clock cycles to run calibration. Increasing this\r
+ *   number increases precision, but the calibration will take more time.\r
+ *\r
+ * @param[in] downSel\r
+ *   The clock which will be counted down downCycles\r
+ *\r
+ * @param[in] upSel\r
+ *   The reference clock, the number of cycles generated by this clock will\r
+ *   be counted and added up, the result can be given with the\r
+ *   CMU_CalibrateCountGet() function call.\r
+ ******************************************************************************/\r
+void CMU_CalibrateConfig(uint32_t downCycles, CMU_Osc_TypeDef downSel,\r
+                         CMU_Osc_TypeDef upSel)\r
+{\r
+  /* Keep untouched configuration settings */\r
+  uint32_t calCtrl = CMU->CALCTRL\r
+                     & ~(_CMU_CALCTRL_UPSEL_MASK | _CMU_CALCTRL_DOWNSEL_MASK);\r
+\r
+  /* 20 bits of precision to calibration count register */\r
+  EFM_ASSERT(downCycles <= (_CMU_CALCNT_CALCNT_MASK >> _CMU_CALCNT_CALCNT_SHIFT));\r
+\r
+  /* Set down counting clock source - down counter */\r
+  switch (downSel)\r
+  {\r
+    case cmuOsc_LFXO:\r
+      calCtrl |= CMU_CALCTRL_DOWNSEL_LFXO;\r
+      break;\r
+\r
+    case cmuOsc_LFRCO:\r
+      calCtrl |= CMU_CALCTRL_DOWNSEL_LFRCO;\r
+      break;\r
+\r
+    case cmuOsc_HFXO:\r
+      calCtrl |= CMU_CALCTRL_DOWNSEL_HFXO;\r
+      break;\r
+\r
+    case cmuOsc_HFRCO:\r
+      calCtrl |= CMU_CALCTRL_DOWNSEL_HFRCO;\r
+      break;\r
+\r
+    case cmuOsc_AUXHFRCO:\r
+      calCtrl |= CMU_CALCTRL_DOWNSEL_AUXHFRCO;\r
+      break;\r
+\r
+    default:\r
+      EFM_ASSERT(0);\r
+      break;\r
+  }\r
+\r
+  /* Set top value to be counted down by the downSel clock */\r
+  CMU->CALCNT = downCycles;\r
+\r
+  /* Set reference clock source - up counter */\r
+  switch (upSel)\r
+  {\r
+    case cmuOsc_LFXO:\r
+      calCtrl |= CMU_CALCTRL_UPSEL_LFXO;\r
+      break;\r
+\r
+    case cmuOsc_LFRCO:\r
+      calCtrl |= CMU_CALCTRL_UPSEL_LFRCO;\r
+      break;\r
+\r
+    case cmuOsc_HFXO:\r
+      calCtrl |= CMU_CALCTRL_UPSEL_HFXO;\r
+      break;\r
+\r
+    case cmuOsc_HFRCO:\r
+      calCtrl |= CMU_CALCTRL_UPSEL_HFRCO;\r
+      break;\r
+\r
+    case cmuOsc_AUXHFRCO:\r
+      calCtrl |= CMU_CALCTRL_UPSEL_AUXHFRCO;\r
+      break;\r
+\r
+    default:\r
+      EFM_ASSERT(0);\r
+      break;\r
+  }\r
+\r
+  CMU->CALCTRL = calCtrl;\r
+}\r
+#endif\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *    Get calibration count register\r
+ * @note\r
+ *    If continuous calibrartion mode is active, calibration busy will almost\r
+ *    always be off, and we just need to read the value, where the normal case\r
+ *    would be that this function call has been triggered by the CALRDY\r
+ *    interrupt flag.\r
+ * @return\r
+ *    Calibration count, the number of UPSEL clocks (see CMU_CalibrateConfig)\r
+ *    in the period of DOWNSEL oscillator clock cycles configured by a previous\r
+ *    write operation to CMU->CALCNT\r
+ ******************************************************************************/\r
+uint32_t CMU_CalibrateCountGet(void)\r
+{\r
+  /* Wait until calibration completes, UNLESS continuous calibration mode is  */\r
+  /* active */\r
+#if defined( CMU_CALCTRL_CONT )\r
+  if (!BUS_RegBitRead(&CMU->CALCTRL, _CMU_CALCTRL_CONT_SHIFT))\r
+  {\r
+#if defined( CMU_STATUS_CALRDY )\r
+    /* Wait until calibration completes */\r
+    while (!BUS_RegBitRead(&CMU->STATUS, _CMU_STATUS_CALRDY_SHIFT))\r
+    {\r
+    }\r
+#else\r
+    /* Wait until calibration completes */\r
+    while (BUS_RegBitRead(&CMU->STATUS, _CMU_STATUS_CALBSY_SHIFT))\r
+    {\r
+    }\r
+#endif\r
+  }\r
+#else\r
+  while (BUS_RegBitRead(&CMU->STATUS, _CMU_STATUS_CALBSY_SHIFT))\r
+  {\r
+  }\r
+#endif\r
+  return CMU->CALCNT;\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Get clock divisor/prescaler.\r
+ *\r
+ * @param[in] clock\r
+ *   Clock point to get divisor/prescaler for. Notice that not all clock points\r
+ *   have a divisor/prescaler. Please refer to CMU overview in reference manual.\r
+ *\r
+ * @return\r
+ *   The current clock point divisor/prescaler. 1 is returned\r
+ *   if @p clock specifies a clock point without a divisor/prescaler.\r
+ ******************************************************************************/\r
+CMU_ClkDiv_TypeDef CMU_ClockDivGet(CMU_Clock_TypeDef clock)\r
+{\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+  return 1 + (uint32_t)CMU_ClockPrescGet(clock);\r
+\r
+#elif defined( _SILICON_LABS_32B_PLATFORM_1 )\r
+  uint32_t           divReg;\r
+  CMU_ClkDiv_TypeDef ret;\r
+\r
+  /* Get divisor reg id */\r
+  divReg = (clock >> CMU_DIV_REG_POS) & CMU_DIV_REG_MASK;\r
+\r
+  switch (divReg)\r
+  {\r
+#if defined( _CMU_CTRL_HFCLKDIV_MASK )\r
+    case CMU_HFCLKDIV_REG:\r
+      ret = 1 + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK)\r
+                 >> _CMU_CTRL_HFCLKDIV_SHIFT);\r
+      break;\r
+#endif\r
+\r
+    case CMU_HFPERCLKDIV_REG:\r
+      ret = (CMU_ClkDiv_TypeDef)((CMU->HFPERCLKDIV\r
+                                  & _CMU_HFPERCLKDIV_HFPERCLKDIV_MASK)\r
+                                 >> _CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT);\r
+      ret = CMU_Log2ToDiv(ret);\r
+      break;\r
+\r
+    case CMU_HFCORECLKDIV_REG:\r
+      ret = (CMU_ClkDiv_TypeDef)((CMU->HFCORECLKDIV\r
+                                  & _CMU_HFCORECLKDIV_HFCORECLKDIV_MASK)\r
+                                 >> _CMU_HFCORECLKDIV_HFCORECLKDIV_SHIFT);\r
+      ret = CMU_Log2ToDiv(ret);\r
+      break;\r
+\r
+    case CMU_LFAPRESC0_REG:\r
+      switch (clock)\r
+      {\r
+        case cmuClock_RTC:\r
+          ret = (CMU_ClkDiv_TypeDef)((CMU->LFAPRESC0 & _CMU_LFAPRESC0_RTC_MASK)\r
+                                     >> _CMU_LFAPRESC0_RTC_SHIFT);\r
+          ret = CMU_Log2ToDiv(ret);\r
+          break;\r
+\r
+#if defined(_CMU_LFAPRESC0_LETIMER0_MASK)\r
+        case cmuClock_LETIMER0:\r
+          ret = (CMU_ClkDiv_TypeDef)((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LETIMER0_MASK)\r
+                                     >> _CMU_LFAPRESC0_LETIMER0_SHIFT);\r
+          ret = CMU_Log2ToDiv(ret);\r
+          break;\r
+#endif\r
+\r
+#if defined(_CMU_LFAPRESC0_LCD_MASK)\r
+        case cmuClock_LCDpre:\r
+          ret = (CMU_ClkDiv_TypeDef)(((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LCD_MASK)\r
+                                      >> _CMU_LFAPRESC0_LCD_SHIFT)\r
+                                     + CMU_DivToLog2(cmuClkDiv_16));\r
+          ret = CMU_Log2ToDiv(ret);\r
+          break;\r
+#endif\r
+\r
+#if defined(_CMU_LFAPRESC0_LESENSE_MASK)\r
+        case cmuClock_LESENSE:\r
+          ret = (CMU_ClkDiv_TypeDef)((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LESENSE_MASK)\r
+                                     >> _CMU_LFAPRESC0_LESENSE_SHIFT);\r
+          ret = CMU_Log2ToDiv(ret);\r
+          break;\r
+#endif\r
+\r
+        default:\r
+          EFM_ASSERT(0);\r
+          ret = cmuClkDiv_1;\r
+          break;\r
+      }\r
+      break;\r
+\r
+    case CMU_LFBPRESC0_REG:\r
+      switch (clock)\r
+      {\r
+#if defined(_CMU_LFBPRESC0_LEUART0_MASK)\r
+        case cmuClock_LEUART0:\r
+          ret = (CMU_ClkDiv_TypeDef)((CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART0_MASK)\r
+                                     >> _CMU_LFBPRESC0_LEUART0_SHIFT);\r
+          ret = CMU_Log2ToDiv(ret);\r
+          break;\r
+#endif\r
+\r
+#if defined(_CMU_LFBPRESC0_LEUART1_MASK)\r
+        case cmuClock_LEUART1:\r
+          ret = (CMU_ClkDiv_TypeDef)((CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART1_MASK)\r
+                                     >> _CMU_LFBPRESC0_LEUART1_SHIFT);\r
+          ret = CMU_Log2ToDiv(ret);\r
+          break;\r
+#endif\r
+\r
+        default:\r
+          EFM_ASSERT(0);\r
+          ret = cmuClkDiv_1;\r
+          break;\r
+      }\r
+      break;\r
+\r
+    default:\r
+      EFM_ASSERT(0);\r
+      ret = cmuClkDiv_1;\r
+      break;\r
+  }\r
+\r
+  return ret;\r
+#endif\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Set clock divisor/prescaler.\r
+ *\r
+ * @note\r
+ *   If setting a LF clock prescaler, synchronization into the low frequency\r
+ *   domain is required. If the same register is modified before a previous\r
+ *   update has completed, this function will stall until the previous\r
+ *   synchronization has completed. Please refer to CMU_FreezeEnable() for\r
+ *   a suggestion on how to reduce stalling time in some use cases.\r
+ *\r
+ * @param[in] clock\r
+ *   Clock point to set divisor/prescaler for. Notice that not all clock points\r
+ *   have a divisor/prescaler, please refer to CMU overview in the reference\r
+ *   manual.\r
+ *\r
+ * @param[in] div\r
+ *   The clock divisor to use (<= cmuClkDiv_512).\r
+ ******************************************************************************/\r
+void CMU_ClockDivSet(CMU_Clock_TypeDef clock, CMU_ClkDiv_TypeDef div)\r
+{\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+  CMU_ClockPrescSet(clock, (CMU_ClkPresc_TypeDef)(div - 1));\r
+\r
+#elif defined( _SILICON_LABS_32B_PLATFORM_1 )\r
+  uint32_t freq;\r
+  uint32_t divReg;\r
+\r
+  /* Get divisor reg id */\r
+  divReg = (clock >> CMU_DIV_REG_POS) & CMU_DIV_REG_MASK;\r
+\r
+  switch (divReg)\r
+  {\r
+#if defined( _CMU_CTRL_HFCLKDIV_MASK )\r
+    case CMU_HFCLKDIV_REG:\r
+      EFM_ASSERT((div>=cmuClkDiv_1) && (div<=cmuClkDiv_8));\r
+\r
+      /* Configure worst case wait states for flash access before setting divisor */\r
+      flashWaitStateMax();\r
+\r
+      /* Set divider */\r
+      CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_HFCLKDIV_MASK)\r
+                  | ((div-1) << _CMU_CTRL_HFCLKDIV_SHIFT);\r
+\r
+      /* Update CMSIS core clock variable */\r
+      /* (The function will update the global variable) */\r
+      freq = SystemCoreClockGet();\r
+\r
+      /* Optimize flash access wait state setting for current core clk */\r
+      flashWaitStateControl(freq);\r
+      break;\r
+#endif\r
+\r
+    case CMU_HFPERCLKDIV_REG:\r
+      EFM_ASSERT((div >= cmuClkDiv_1) && (div <= cmuClkDiv_512));\r
+      /* Convert to correct scale */\r
+      div = CMU_DivToLog2(div);\r
+      CMU->HFPERCLKDIV = (CMU->HFPERCLKDIV & ~_CMU_HFPERCLKDIV_HFPERCLKDIV_MASK)\r
+                         | (div << _CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT);\r
+      break;\r
+\r
+    case CMU_HFCORECLKDIV_REG:\r
+      EFM_ASSERT(div <= cmuClkDiv_512);\r
+\r
+      /* Configure worst case wait states for flash access before setting divisor */\r
+      flashWaitStateMax();\r
+\r
+#if defined( CMU_CTRL_HFLE )\r
+      /* Clear HFLE and set DIV2 factor for peripheral clock\r
+         when running at frequencies lower than or equal to CMU_MAX_FREQ_HFLE. */\r
+      if ((CMU_ClockFreqGet(cmuClock_HF) / div) <= CMU_MAX_FREQ_HFLE())\r
+      {\r
+        /* Clear CMU HFLE */\r
+        BUS_RegBitWrite(&CMU->CTRL, _CMU_CTRL_HFLE_SHIFT, 0);\r
+\r
+        /* Set DIV2 factor for peripheral clock */\r
+        BUS_RegBitWrite(&CMU->HFCORECLKDIV,\r
+                        _CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 0);\r
+      }\r
+      else\r
+      {\r
+        /* Set CMU HFLE */\r
+        BUS_RegBitWrite(&CMU->CTRL, _CMU_CTRL_HFLE_SHIFT, 1);\r
+\r
+        /* Set DIV4 factor for peripheral clock */\r
+        BUS_RegBitWrite(&CMU->HFCORECLKDIV,\r
+                        _CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);\r
+      }\r
+#endif\r
+\r
+      /* Convert to correct scale */\r
+      div = CMU_DivToLog2(div);\r
+\r
+      CMU->HFCORECLKDIV = (CMU->HFCORECLKDIV\r
+                           & ~_CMU_HFCORECLKDIV_HFCORECLKDIV_MASK)\r
+                          | (div << _CMU_HFCORECLKDIV_HFCORECLKDIV_SHIFT);\r
+\r
+      /* Update CMSIS core clock variable */\r
+      /* (The function will update the global variable) */\r
+      freq = SystemCoreClockGet();\r
+\r
+      /* Optimize flash access wait state setting for current core clk */\r
+      flashWaitStateControl(freq);\r
+      break;\r
+\r
+    case CMU_LFAPRESC0_REG:\r
+      switch (clock)\r
+      {\r
+        case cmuClock_RTC:\r
+          EFM_ASSERT(div <= cmuClkDiv_32768);\r
+\r
+          /* LF register about to be modified require sync. busy check */\r
+          syncReg(CMU_SYNCBUSY_LFAPRESC0);\r
+\r
+          /* Convert to correct scale */\r
+          div = CMU_DivToLog2(div);\r
+\r
+          CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_RTC_MASK)\r
+                           | (div << _CMU_LFAPRESC0_RTC_SHIFT);\r
+          break;\r
+\r
+#if defined(_CMU_LFAPRESC0_LETIMER0_MASK)\r
+        case cmuClock_LETIMER0:\r
+          EFM_ASSERT(div <= cmuClkDiv_32768);\r
+\r
+          /* LF register about to be modified require sync. busy check */\r
+          syncReg(CMU_SYNCBUSY_LFAPRESC0);\r
+\r
+          /* Convert to correct scale */\r
+          div = CMU_DivToLog2(div);\r
+\r
+          CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_LETIMER0_MASK)\r
+                           | (div << _CMU_LFAPRESC0_LETIMER0_SHIFT);\r
+          break;\r
+#endif\r
+\r
+#if defined(LCD_PRESENT)\r
+        case cmuClock_LCDpre:\r
+          EFM_ASSERT((div >= cmuClkDiv_16) && (div <= cmuClkDiv_128));\r
+\r
+          /* LF register about to be modified require sync. busy check */\r
+          syncReg(CMU_SYNCBUSY_LFAPRESC0);\r
+\r
+          /* Convert to correct scale */\r
+          div = CMU_DivToLog2(div);\r
+\r
+          CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_LCD_MASK)\r
+                           | ((div - CMU_DivToLog2(cmuClkDiv_16))\r
+                              << _CMU_LFAPRESC0_LCD_SHIFT);\r
+          break;\r
+#endif /* defined(LCD_PRESENT) */\r
+\r
+#if defined(LESENSE_PRESENT)\r
+        case cmuClock_LESENSE:\r
+          EFM_ASSERT(div <= cmuClkDiv_8);\r
+\r
+          /* LF register about to be modified require sync. busy check */\r
+          syncReg(CMU_SYNCBUSY_LFAPRESC0);\r
+\r
+          /* Convert to correct scale */\r
+          div = CMU_DivToLog2(div);\r
+\r
+          CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_LESENSE_MASK)\r
+                           | (div << _CMU_LFAPRESC0_LESENSE_SHIFT);\r
+          break;\r
+#endif /* defined(LESENSE_PRESENT) */\r
+\r
+        default:\r
+          EFM_ASSERT(0);\r
+          break;\r
+      }\r
+      break;\r
+\r
+    case CMU_LFBPRESC0_REG:\r
+      switch (clock)\r
+      {\r
+#if defined(_CMU_LFBPRESC0_LEUART0_MASK)\r
+        case cmuClock_LEUART0:\r
+          EFM_ASSERT(div <= cmuClkDiv_8);\r
+\r
+          /* LF register about to be modified require sync. busy check */\r
+          syncReg(CMU_SYNCBUSY_LFBPRESC0);\r
+\r
+          /* Convert to correct scale */\r
+          div = CMU_DivToLog2(div);\r
+\r
+          CMU->LFBPRESC0 = (CMU->LFBPRESC0 & ~_CMU_LFBPRESC0_LEUART0_MASK)\r
+                           | (((uint32_t)div) << _CMU_LFBPRESC0_LEUART0_SHIFT);\r
+          break;\r
+#endif\r
+\r
+#if defined(_CMU_LFBPRESC0_LEUART1_MASK)\r
+        case cmuClock_LEUART1:\r
+          EFM_ASSERT(div <= cmuClkDiv_8);\r
+\r
+          /* LF register about to be modified require sync. busy check */\r
+          syncReg(CMU_SYNCBUSY_LFBPRESC0);\r
+\r
+          /* Convert to correct scale */\r
+          div = CMU_DivToLog2(div);\r
+\r
+          CMU->LFBPRESC0 = (CMU->LFBPRESC0 & ~_CMU_LFBPRESC0_LEUART1_MASK)\r
+                           | (((uint32_t)div) << _CMU_LFBPRESC0_LEUART1_SHIFT);\r
+          break;\r
+#endif\r
+\r
+        default:\r
+          EFM_ASSERT(0);\r
+          break;\r
+      }\r
+      break;\r
+\r
+    default:\r
+      EFM_ASSERT(0);\r
+      break;\r
+  }\r
+#endif\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Enable/disable a clock.\r
+ *\r
+ * @details\r
+ *   In general, module clocking is disabled after a reset. If a module\r
+ *   clock is disabled, the registers of that module are not accessible and\r
+ *   reading from such registers may return undefined values. Writing to\r
+ *   registers of clock disabled modules have no effect. One should normally\r
+ *   avoid accessing module registers of a module with a disabled clock.\r
+ *\r
+ * @note\r
+ *   If enabling/disabling a LF clock, synchronization into the low frequency\r
+ *   domain is required. If the same register is modified before a previous\r
+ *   update has completed, this function will stall until the previous\r
+ *   synchronization has completed. Please refer to CMU_FreezeEnable() for\r
+ *   a suggestion on how to reduce stalling time in some use cases.\r
+ *\r
+ * @param[in] clock\r
+ *   The clock to enable/disable. Notice that not all defined clock\r
+ *   points have separate enable/disable control, please refer to CMU overview\r
+ *   in reference manual.\r
+ *\r
+ * @param[in] enable\r
+ *   @li true - enable specified clock.\r
+ *   @li false - disable specified clock.\r
+ ******************************************************************************/\r
+void CMU_ClockEnable(CMU_Clock_TypeDef clock, bool enable)\r
+{\r
+  volatile uint32_t *reg;\r
+  uint32_t          bit;\r
+  uint32_t          sync = 0;\r
+\r
+  /* Identify enable register */\r
+  switch ((clock >> CMU_EN_REG_POS) & CMU_EN_REG_MASK)\r
+  {\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+    case CMU_CTRL_EN_REG:\r
+      reg = &CMU->CTRL;\r
+      break;\r
+#endif\r
+\r
+#if defined( _SILICON_LABS_32B_PLATFORM_1 )\r
+    case CMU_HFCORECLKEN0_EN_REG:\r
+      reg = &CMU->HFCORECLKEN0;\r
+#if defined( CMU_CTRL_HFLE )\r
+      /* Set HFLE and DIV4 factor for peripheral clock when\r
+         running at frequencies higher than or equal to CMU_MAX_FREQ_HFLE. */\r
+      if ( CMU_ClockFreqGet(cmuClock_CORE) > CMU_MAX_FREQ_HFLE())\r
+      {\r
+        /* Enable CMU HFLE */\r
+        BUS_RegBitWrite(&CMU->CTRL, _CMU_CTRL_HFLE_SHIFT, 1);\r
+\r
+        /* Set DIV4 factor for peripheral clock */\r
+        BUS_RegBitWrite(&CMU->HFCORECLKDIV,\r
+                        _CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);\r
+      }\r
+#endif\r
+      break;\r
+#endif\r
+\r
+#if defined( _CMU_HFBUSCLKEN0_MASK )\r
+    case CMU_HFBUSCLKEN0_EN_REG:\r
+      reg = &CMU->HFBUSCLKEN0;\r
+      break;\r
+#endif\r
+\r
+#if defined( _CMU_HFRADIOCLKEN0_MASK )\r
+    case CMU_HFRADIOCLKEN0_EN_REG:\r
+      reg = &CMU->HFRADIOCLKEN0;\r
+      break;\r
+#endif\r
+\r
+#if defined( _CMU_HFPERCLKDIV_MASK )\r
+    case CMU_HFPERCLKDIV_EN_REG:\r
+      reg = &CMU->HFPERCLKDIV;\r
+      break;\r
+#endif\r
+\r
+    case CMU_HFPERCLKEN0_EN_REG:\r
+      reg = &CMU->HFPERCLKEN0;\r
+      break;\r
+\r
+    case CMU_LFACLKEN0_EN_REG:\r
+      reg  = &CMU->LFACLKEN0;\r
+      sync = CMU_SYNCBUSY_LFACLKEN0;\r
+      break;\r
+\r
+    case CMU_LFBCLKEN0_EN_REG:\r
+      reg  = &CMU->LFBCLKEN0;\r
+      sync = CMU_SYNCBUSY_LFBCLKEN0;\r
+      break;\r
+\r
+#if defined( _CMU_LFCCLKEN0_MASK )\r
+    case CMU_LFCCLKEN0_EN_REG:\r
+      reg = &CMU->LFCCLKEN0;\r
+      sync = CMU_SYNCBUSY_LFCCLKEN0;\r
+      break;\r
+#endif\r
+\r
+#if defined( _CMU_LFECLKEN0_MASK )\r
+    case CMU_LFECLKEN0_EN_REG:\r
+      reg  = &CMU->LFECLKEN0;\r
+      sync = CMU_SYNCBUSY_LFECLKEN0;\r
+      break;\r
+#endif\r
+\r
+    case CMU_PCNT_EN_REG:\r
+      reg = &CMU->PCNTCTRL;\r
+      break;\r
+\r
+    default: /* Cannot enable/disable clock point */\r
+      EFM_ASSERT(0);\r
+      return;\r
+  }\r
+\r
+  /* Get bit position used to enable/disable */\r
+  bit = (clock >> CMU_EN_BIT_POS) & CMU_EN_BIT_MASK;\r
+\r
+  /* LF synchronization required? */\r
+  if (sync)\r
+  {\r
+    syncReg(sync);\r
+  }\r
+\r
+  /* Set/clear bit as requested */\r
+  BUS_RegBitWrite(reg, bit, enable);\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Get clock frequency for a clock point.\r
+ *\r
+ * @param[in] clock\r
+ *   Clock point to fetch frequency for.\r
+ *\r
+ * @return\r
+ *   The current frequency in Hz.\r
+ ******************************************************************************/\r
+uint32_t CMU_ClockFreqGet(CMU_Clock_TypeDef clock)\r
+{\r
+  uint32_t ret;\r
+\r
+  switch(clock & (CMU_CLK_BRANCH_MASK << CMU_CLK_BRANCH_POS))\r
+  {\r
+    case (CMU_HF_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
+      ret = SystemHFClockGet();\r
+#if defined( _CMU_CTRL_HFCLKDIV_MASK )\r
+      /* Family with an additional divider. */\r
+      ret = ret / (1U + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK)\r
+                         >> _CMU_CTRL_HFCLKDIV_SHIFT));\r
+#endif\r
+#if defined( _CMU_HFPRESC_MASK )\r
+      ret = ret / (1U + ((CMU->HFPRESC & _CMU_HFPRESC_PRESC_MASK)\r
+                         >> _CMU_HFPRESC_PRESC_SHIFT));\r
+#endif\r
+      break;\r
+\r
+    case (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
+      ret = SystemHFClockGet();\r
+#if defined( _SILICON_LABS_32B_PLATFORM_1 )\r
+#if defined( _CMU_CTRL_HFCLKDIV_MASK )\r
+      /* Family with an additional divider. */\r
+      ret = ret / (1U + ((CMU->CTRL & _CMU_CTRL_HFCLKDIV_MASK)\r
+                         >> _CMU_CTRL_HFCLKDIV_SHIFT));\r
+#endif\r
+      ret >>= (CMU->HFPERCLKDIV & _CMU_HFPERCLKDIV_HFPERCLKDIV_MASK)\r
+              >> _CMU_HFPERCLKDIV_HFPERCLKDIV_SHIFT;\r
+#elif defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+      ret /= 1U + ((CMU->HFPERPRESC & _CMU_HFPERPRESC_PRESC_MASK)\r
+                   >> _CMU_HFPERPRESC_PRESC_SHIFT);\r
+#endif\r
+      break;\r
+\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+#if defined( _CMU_HFRADIOPRESC_PRESC_MASK )\r
+    case (CMU_HFRADIO_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
+      ret = SystemHFClockGet();\r
+      ret /= 1U + ((CMU->HFRADIOPRESC & _CMU_HFRADIOPRESC_PRESC_MASK)\r
+                   >> _CMU_HFRADIOPRESC_PRESC_SHIFT);\r
+      break;\r
+#endif\r
+\r
+#if defined( CRYPTO_PRESENT )   \\r
+    || defined( LDMA_PRESENT )  \\r
+    || defined( GPCRC_PRESENT ) \\r
+    || defined( PRS_PRESENT )   \\r
+    || defined( GPIO_PRESENT )\r
+    case (CMU_HFBUS_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
+      ret = SystemHFClockGet();\r
+      break;\r
+#endif\r
+\r
+    case (CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
+      ret = SystemHFClockGet();\r
+      ret /= 1U + ((CMU->HFCOREPRESC & _CMU_HFCOREPRESC_PRESC_MASK)\r
+                   >> _CMU_HFCOREPRESC_PRESC_SHIFT);\r
+      break;\r
+\r
+    case (CMU_HFEXP_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
+      ret = SystemHFClockGet();\r
+      ret /= 1U + ((CMU->HFEXPPRESC & _CMU_HFEXPPRESC_PRESC_MASK)\r
+                   >> _CMU_HFEXPPRESC_PRESC_SHIFT);\r
+      break;\r
+#endif\r
+\r
+#if defined( _SILICON_LABS_32B_PLATFORM_1 )\r
+#if defined(AES_PRESENT)    \\r
+    || defined(DMA_PRESENT) \\r
+    || defined(EBI_PRESENT) \\r
+    || defined(USB_PRESENT)\r
+    case (CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
+    {\r
+      ret = SystemCoreClockGet();\r
+    } break;\r
+#endif\r
+#endif\r
+\r
+    case (CMU_LFA_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
+      ret = lfClkGet(cmuClock_LFA);\r
+      break;\r
+\r
+#if defined( _CMU_LFACLKEN0_RTC_MASK )\r
+    case (CMU_RTC_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
+      ret = lfClkGet(cmuClock_LFA);\r
+      ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_RTC_MASK)\r
+              >> _CMU_LFAPRESC0_RTC_SHIFT;\r
+      break;\r
+#endif\r
+\r
+#if defined( _CMU_LFECLKEN0_RTCC_MASK )\r
+    case (CMU_RTCC_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
+      ret = lfClkGet(cmuClock_LFE);\r
+      break;\r
+#endif\r
+\r
+#if defined( _CMU_LFACLKEN0_LETIMER0_MASK )\r
+    case (CMU_LETIMER0_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
+      ret = lfClkGet(cmuClock_LFA);\r
+#if defined( _SILICON_LABS_32B_PLATFORM_1 )\r
+      ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_LETIMER0_MASK)\r
+              >> _CMU_LFAPRESC0_LETIMER0_SHIFT;\r
+#elif defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+      ret /= CMU_Log2ToDiv((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LETIMER0_MASK)\r
+                           >> _CMU_LFAPRESC0_LETIMER0_SHIFT);\r
+#endif\r
+      break;\r
+#endif\r
+\r
+#if defined(_CMU_LFACLKEN0_LCD_MASK)\r
+    case (CMU_LCDPRE_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
+      ret = lfClkGet(cmuClock_LFA);\r
+      ret >>= ((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LCD_MASK)\r
+               >> _CMU_LFAPRESC0_LCD_SHIFT)\r
+              + CMU_DivToLog2(cmuClkDiv_16);\r
+      break;\r
+\r
+    case (CMU_LCD_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
+      ret = lfClkGet(cmuClock_LFA);\r
+      ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_LCD_MASK)\r
+              >> _CMU_LFAPRESC0_LCD_SHIFT;\r
+      ret /= 1U + ((CMU->LCDCTRL & _CMU_LCDCTRL_FDIV_MASK)\r
+                   >> _CMU_LCDCTRL_FDIV_SHIFT);\r
+      break;\r
+#endif\r
+\r
+#if defined(_CMU_LFACLKEN0_LESENSE_MASK)\r
+    case (CMU_LESENSE_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
+      ret = lfClkGet(cmuClock_LFA);\r
+      ret >>= (CMU->LFAPRESC0 & _CMU_LFAPRESC0_LESENSE_MASK)\r
+              >> _CMU_LFAPRESC0_LESENSE_SHIFT;\r
+      break;\r
+#endif\r
+\r
+    case (CMU_LFB_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
+      ret = lfClkGet(cmuClock_LFB);\r
+      break;\r
+\r
+#if defined( _CMU_LFBCLKEN0_LEUART0_MASK )\r
+    case (CMU_LEUART0_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
+      ret = lfClkGet(cmuClock_LFB);\r
+#if defined( _SILICON_LABS_32B_PLATFORM_1 )\r
+      ret >>= (CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART0_MASK)\r
+              >> _CMU_LFBPRESC0_LEUART0_SHIFT;\r
+#elif defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+      ret /= CMU_Log2ToDiv((CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART0_MASK)\r
+                           >> _CMU_LFBPRESC0_LEUART0_SHIFT);\r
+#endif\r
+      break;\r
+#endif\r
+\r
+#if defined( _CMU_LFBCLKEN0_LEUART1_MASK )\r
+    case (CMU_LEUART1_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
+      ret = lfClkGet(cmuClock_LFB);\r
+#if defined( _SILICON_LABS_32B_PLATFORM_1 )\r
+      ret >>= (CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART1_MASK)\r
+              >> _CMU_LFBPRESC0_LEUART1_SHIFT;\r
+#elif defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+      ret /= CMU_Log2ToDiv((CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART1_MASK)\r
+                           >> _CMU_LFBPRESC0_LEUART1_SHIFT);\r
+#endif\r
+      break;\r
+#endif\r
+\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+    case (CMU_LFE_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
+      ret = lfClkGet(cmuClock_LFE);\r
+      break;\r
+#endif\r
+\r
+    case (CMU_DBG_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
+      ret = dbgClkGet();\r
+      break;\r
+\r
+    case (CMU_AUX_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
+      ret = auxClkGet();\r
+      break;\r
+\r
+#if defined(USB_PRESENT)\r
+    case (CMU_USBC_CLK_BRANCH << CMU_CLK_BRANCH_POS):\r
+      ret = usbCClkGet();\r
+      break;\r
+#endif\r
+\r
+    default:\r
+      EFM_ASSERT(0);\r
+      ret = 0;\r
+      break;\r
+  }\r
+\r
+  return ret;\r
+}\r
+\r
+\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Get clock prescaler.\r
+ *\r
+ * @param[in] clock\r
+ *   Clock point to get the prescaler for. Notice that not all clock points\r
+ *   have a prescaler. Please refer to CMU overview in reference manual.\r
+ *\r
+ * @return\r
+ *   The prescaler value of the current clock point. 0 is returned\r
+ *   if @p clock specifies a clock point without a prescaler.\r
+ ******************************************************************************/\r
+uint32_t CMU_ClockPrescGet(CMU_Clock_TypeDef clock)\r
+{\r
+  uint32_t  prescReg;\r
+  uint32_t  ret;\r
+\r
+  /* Get prescaler register id. */\r
+  prescReg = (clock >> CMU_PRESC_REG_POS) & CMU_PRESC_REG_MASK;\r
+\r
+  switch (prescReg)\r
+  {\r
+    case CMU_HFPRESC_REG:\r
+      ret = ((CMU->HFPRESC & _CMU_HFPRESC_PRESC_MASK)\r
+             >> _CMU_HFPRESC_PRESC_SHIFT);\r
+      break;\r
+\r
+    case CMU_HFEXPPRESC_REG:\r
+      ret = ((CMU->HFEXPPRESC & _CMU_HFEXPPRESC_PRESC_MASK)\r
+             >> _CMU_HFEXPPRESC_PRESC_SHIFT);\r
+      break;\r
+\r
+    case CMU_HFCLKLEPRESC_REG:\r
+      ret = ((CMU->HFPRESC & _CMU_HFPRESC_HFCLKLEPRESC_MASK)\r
+             >> _CMU_HFPRESC_HFCLKLEPRESC_SHIFT);\r
+      break;\r
+\r
+    case CMU_HFPERPRESC_REG:\r
+      ret = ((CMU->HFPERPRESC & _CMU_HFPERPRESC_PRESC_MASK)\r
+             >> _CMU_HFPERPRESC_PRESC_SHIFT);\r
+      break;\r
+\r
+#if defined( _CMU_HFRADIOPRESC_PRESC_MASK )\r
+    case CMU_HFRADIOPRESC_REG:\r
+      ret = ((CMU->HFRADIOPRESC & _CMU_HFRADIOPRESC_PRESC_MASK)\r
+             >> _CMU_HFRADIOPRESC_PRESC_SHIFT);\r
+      break;\r
+#endif\r
+\r
+    case CMU_HFCOREPRESC_REG:\r
+      ret = ((CMU->HFCOREPRESC & _CMU_HFCOREPRESC_PRESC_MASK)\r
+             >> _CMU_HFCOREPRESC_PRESC_SHIFT);\r
+      break;\r
+\r
+    case CMU_LFAPRESC0_REG:\r
+      switch (clock)\r
+      {\r
+#if defined( _CMU_LFAPRESC0_LETIMER0_MASK )\r
+        case cmuClock_LETIMER0:\r
+          ret = (((CMU->LFAPRESC0 & _CMU_LFAPRESC0_LETIMER0_MASK)\r
+                 >> _CMU_LFAPRESC0_LETIMER0_SHIFT));\r
+          /* Convert the exponent to prescaler value. */\r
+          ret = CMU_Log2ToDiv(ret) - 1U;\r
+          break;\r
+#endif\r
+\r
+        default:\r
+          EFM_ASSERT(0);\r
+          ret = 0U;\r
+          break;\r
+      }\r
+      break;\r
+\r
+    case CMU_LFBPRESC0_REG:\r
+      switch (clock)\r
+      {\r
+#if defined( _CMU_LFBPRESC0_LEUART0_MASK )\r
+        case cmuClock_LEUART0:\r
+          ret = (((CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART0_MASK)\r
+                 >> _CMU_LFBPRESC0_LEUART0_SHIFT));\r
+          /* Convert the exponent to prescaler value. */\r
+          ret = CMU_Log2ToDiv(ret) - 1U;\r
+          break;\r
+#endif\r
+\r
+#if defined( _CMU_LFBPRESC0_LEUART1_MASK )\r
+        case cmuClock_LEUART1:\r
+          ret = (((CMU->LFBPRESC0 & _CMU_LFBPRESC0_LEUART1_MASK)\r
+                 >> _CMU_LFBPRESC0_LEUART1_SHIFT));\r
+          /* Convert the exponent to prescaler value. */\r
+          ret = CMU_Log2ToDiv(ret) - 1U;\r
+          break;\r
+#endif\r
+\r
+        default:\r
+          EFM_ASSERT(0);\r
+          ret = 0U;\r
+          break;\r
+      }\r
+      break;\r
+\r
+    case CMU_LFEPRESC0_REG:\r
+      switch (clock)\r
+      {\r
+#if defined( RTCC_PRESENT )\r
+        case cmuClock_RTCC:\r
+          /* No need to compute with LFEPRESC0_RTCC - DIV1 is the only  */\r
+          /* allowed value. Convert the exponent to prescaler value.    */\r
+          ret = _CMU_LFEPRESC0_RTCC_DIV1;\r
+          break;\r
+\r
+        default:\r
+          EFM_ASSERT(0);\r
+          ret = 0U;\r
+          break;\r
+#endif\r
+      }\r
+      break;\r
+\r
+    default:\r
+      EFM_ASSERT(0);\r
+      ret = 0U;\r
+      break;\r
+  }\r
+\r
+  return ret;\r
+}\r
+#endif\r
+\r
+\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Set clock prescaler.\r
+ *\r
+ * @note\r
+ *   If setting a LF clock prescaler, synchronization into the low frequency\r
+ *   domain is required. If the same register is modified before a previous\r
+ *   update has completed, this function will stall until the previous\r
+ *   synchronization has completed. Please refer to CMU_FreezeEnable() for\r
+ *   a suggestion on how to reduce stalling time in some use cases.\r
+ *\r
+ * @param[in] clock\r
+ *   Clock point to set prescaler for. Notice that not all clock points\r
+ *   have a prescaler, please refer to CMU overview in the reference manual.\r
+ *\r
+ * @param[in] presc\r
+ *   The clock prescaler to use.\r
+ ******************************************************************************/\r
+void CMU_ClockPrescSet(CMU_Clock_TypeDef clock, CMU_ClkPresc_TypeDef presc)\r
+{\r
+  uint32_t freq;\r
+  uint32_t prescReg;\r
+\r
+  /* Get divisor reg id */\r
+  prescReg = (clock >> CMU_PRESC_REG_POS) & CMU_PRESC_REG_MASK;\r
+\r
+  switch (prescReg)\r
+  {\r
+    case CMU_HFPRESC_REG:\r
+      EFM_ASSERT(presc < 32U);\r
+\r
+      CMU->HFPRESC = (CMU->HFPRESC & ~_CMU_HFPRESC_PRESC_MASK)\r
+                     | (presc << _CMU_HFPRESC_PRESC_SHIFT);\r
+      break;\r
+\r
+    case CMU_HFEXPPRESC_REG:\r
+      EFM_ASSERT(presc < 32U);\r
+\r
+      CMU->HFEXPPRESC = (CMU->HFEXPPRESC & ~_CMU_HFEXPPRESC_PRESC_MASK)\r
+                        | (presc << _CMU_HFEXPPRESC_PRESC_SHIFT);\r
+      break;\r
+\r
+    case CMU_HFCLKLEPRESC_REG:\r
+      EFM_ASSERT(presc < 2U);\r
+\r
+      /* Specifies the clock divider for HFCLKLE. When running at frequencies\r
+       * higher than 32 MHz, this must be set to DIV4. */\r
+      CMU->HFPRESC = (CMU->HFPRESC & ~_CMU_HFPRESC_HFCLKLEPRESC_MASK)\r
+                     | (presc << _CMU_HFPRESC_HFCLKLEPRESC_SHIFT);\r
+      break;\r
+\r
+    case CMU_HFPERPRESC_REG:\r
+      EFM_ASSERT(presc < 512U);\r
+\r
+      CMU->HFPERPRESC = (CMU->HFPERPRESC & ~_CMU_HFPERPRESC_PRESC_MASK)\r
+                        | (presc << _CMU_HFPERPRESC_PRESC_SHIFT);\r
+      break;\r
+\r
+#if defined( _CMU_HFRADIOPRESC_PRESC_MASK )\r
+    case CMU_HFRADIOPRESC_REG:\r
+      EFM_ASSERT(presc < 512U);\r
+\r
+      CMU->HFRADIOPRESC = (CMU->HFRADIOPRESC & ~_CMU_HFRADIOPRESC_PRESC_MASK)\r
+                          | (presc << _CMU_HFRADIOPRESC_PRESC_SHIFT);\r
+      break;\r
+#endif\r
+\r
+    case CMU_HFCOREPRESC_REG:\r
+      EFM_ASSERT(presc < 512U);\r
+\r
+      /* Configure worst case wait states for flash access before setting\r
+       * the prescaler. */\r
+      flashWaitStateControl(CMU_MAX_FREQ_0WS + 1);\r
+\r
+      CMU->HFCOREPRESC = (CMU->HFCOREPRESC & ~_CMU_HFCOREPRESC_PRESC_MASK)\r
+                         | (presc << _CMU_HFCOREPRESC_PRESC_SHIFT);\r
+\r
+      /* Update CMSIS core clock variable */\r
+      /* (The function will update the global variable) */\r
+      freq = SystemCoreClockGet();\r
+\r
+      /* Optimize flash access wait state setting for current core clk */\r
+      flashWaitStateControl(freq);\r
+      break;\r
+\r
+    case CMU_LFAPRESC0_REG:\r
+      switch (clock)\r
+      {\r
+#if defined( RTC_PRESENT )\r
+        case cmuClock_RTC:\r
+          EFM_ASSERT(presc <= 32768U);\r
+\r
+          /* Convert prescaler value to DIV exponent scale. */\r
+          presc = CMU_PrescToLog2(presc);\r
+\r
+          /* LF register about to be modified require sync. Busy check. */\r
+          syncReg(CMU_SYNCBUSY_LFAPRESC0);\r
+\r
+          CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_RTC_MASK)\r
+                           | (presc << _CMU_LFAPRESC0_RTC_SHIFT);\r
+          break;\r
+#endif\r
+\r
+#if defined( RTCC_PRESENT )\r
+        case cmuClock_RTCC:\r
+#if defined( _CMU_LFEPRESC0_RTCC_MASK )\r
+          /* DIV1 is the only accepted value. */\r
+          EFM_ASSERT(presc <= 0U);\r
+\r
+          /* LF register about to be modified require sync. Busy check.. */\r
+          syncReg(CMU_SYNCBUSY_LFEPRESC0);\r
+\r
+          CMU->LFEPRESC0 = (CMU->LFEPRESC0 & ~_CMU_LFEPRESC0_RTCC_MASK)\r
+                           | (presc << _CMU_LFEPRESC0_RTCC_SHIFT);\r
+#else\r
+          EFM_ASSERT(presc <= 32768U);\r
+\r
+          /* Convert prescaler value to DIV exponent scale. */\r
+          presc = CMU_PrescToLog2(presc);\r
+\r
+          /* LF register about to be modified require sync. Busy check. */\r
+          syncReg(CMU_SYNCBUSY_LFAPRESC0);\r
+\r
+          CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_RTCC_MASK)\r
+                           | (presc << _CMU_LFAPRESC0_RTCC_SHIFT);\r
+#endif\r
+          break;\r
+#endif\r
+\r
+#if defined( _CMU_LFAPRESC0_LETIMER0_MASK )\r
+        case cmuClock_LETIMER0:\r
+          EFM_ASSERT(presc <= 32768U);\r
+\r
+          /* Convert prescaler value to DIV exponent scale. */\r
+          presc = CMU_PrescToLog2(presc);\r
+\r
+          /* LF register about to be modified require sync. Busy check. */\r
+          syncReg(CMU_SYNCBUSY_LFAPRESC0);\r
+\r
+          CMU->LFAPRESC0 = (CMU->LFAPRESC0 & ~_CMU_LFAPRESC0_LETIMER0_MASK)\r
+                           | (presc << _CMU_LFAPRESC0_LETIMER0_SHIFT);\r
+          break;\r
+#endif\r
+\r
+        default:\r
+          EFM_ASSERT(0);\r
+          break;\r
+      }\r
+      break;\r
+\r
+    case CMU_LFBPRESC0_REG:\r
+      switch (clock)\r
+      {\r
+#if defined( _CMU_LFBPRESC0_LEUART0_MASK )\r
+        case cmuClock_LEUART0:\r
+          EFM_ASSERT(presc <= 8U);\r
+\r
+          /* Convert prescaler value to DIV exponent scale. */\r
+          presc = CMU_PrescToLog2(presc);\r
+\r
+          /* LF register about to be modified require sync. Busy check. */\r
+          syncReg(CMU_SYNCBUSY_LFBPRESC0);\r
+\r
+          CMU->LFBPRESC0 = (CMU->LFBPRESC0 & ~_CMU_LFBPRESC0_LEUART0_MASK)\r
+                           | (presc << _CMU_LFBPRESC0_LEUART0_SHIFT);\r
+          break;\r
+#endif\r
+\r
+#if defined( _CMU_LFBPRESC0_LEUART1_MASK )\r
+        case cmuClock_LEUART1:\r
+          EFM_ASSERT(presc <= 8U);\r
+\r
+          /* Convert prescaler value to DIV exponent scale. */\r
+          presc = CMU_PrescToLog2(presc);\r
+\r
+          /* LF register about to be modified require sync. Busy check. */\r
+          syncReg(CMU_SYNCBUSY_LFBPRESC0);\r
+\r
+          CMU->LFBPRESC0 = (CMU->LFBPRESC0 & ~_CMU_LFBPRESC0_LEUART1_MASK)\r
+                           | (presc << _CMU_LFBPRESC0_LEUART1_SHIFT);\r
+          break;\r
+#endif\r
+\r
+        default:\r
+          EFM_ASSERT(0);\r
+          break;\r
+      }\r
+      break;\r
+\r
+    case CMU_LFEPRESC0_REG:\r
+      switch (clock)\r
+      {\r
+#if defined( _CMU_LFEPRESC0_RTCC_MASK )\r
+        case cmuClock_RTCC:\r
+          EFM_ASSERT(presc <= 0U);\r
+\r
+          /* LF register about to be modified require sync. Busy check. */\r
+          syncReg(CMU_SYNCBUSY_LFEPRESC0);\r
+\r
+          CMU->LFEPRESC0 = (CMU->LFEPRESC0 & ~_CMU_LFEPRESC0_RTCC_MASK)\r
+                           | (presc << _CMU_LFEPRESC0_RTCC_SHIFT);\r
+          break;\r
+#endif\r
+\r
+        default:\r
+          EFM_ASSERT(0);\r
+          break;\r
+      }\r
+      break;\r
+\r
+    default:\r
+      EFM_ASSERT(0);\r
+      break;\r
+  }\r
+}\r
+#endif\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Get currently selected reference clock used for a clock branch.\r
+ *\r
+ * @param[in] clock\r
+ *   Clock branch to fetch selected ref. clock for. One of:\r
+ *   @li #cmuClock_HF\r
+ *   @li #cmuClock_LFA\r
+ *   @li #cmuClock_LFB @if _CMU_LFCLKSEL_LFAE_ULFRCO\r
+ *   @li #cmuClock_LFC\r
+ *   @endif            @if _SILICON_LABS_32B_PLATFORM_2\r
+ *   @li #cmuClock_LFE\r
+ *   @endif\r
+ *   @li #cmuClock_DBG @if DOXYDOC_USB_PRESENT\r
+ *   @li #cmuClock_USBC\r
+ *   @endif\r
+ *\r
+ * @return\r
+ *   Reference clock used for clocking selected branch, #cmuSelect_Error if\r
+ *   invalid @p clock provided.\r
+ ******************************************************************************/\r
+CMU_Select_TypeDef CMU_ClockSelectGet(CMU_Clock_TypeDef clock)\r
+{\r
+  CMU_Select_TypeDef ret = cmuSelect_Disabled;\r
+  uint32_t selReg;\r
+\r
+  selReg = (clock >> CMU_SEL_REG_POS) & CMU_SEL_REG_MASK;\r
+\r
+  switch (selReg)\r
+  {\r
+    case CMU_HFCLKSEL_REG:\r
+#if defined( _CMU_HFCLKSEL_HF_MASK )\r
+      switch (CMU->HFCLKSEL & _CMU_HFCLKSEL_HF_MASK)\r
+      {\r
+        case CMU_HFCLKSEL_HF_LFXO:\r
+          ret = cmuSelect_LFXO;\r
+          break;\r
+\r
+        case CMU_HFCLKSEL_HF_LFRCO:\r
+          ret = cmuSelect_LFRCO;\r
+          break;\r
+\r
+        case CMU_HFCLKSEL_HF_HFXO:\r
+          ret = cmuSelect_HFXO;\r
+          break;\r
+\r
+        default:\r
+          ret = cmuSelect_HFRCO;\r
+          break;\r
+      }\r
+#else\r
+      switch (CMU->STATUS\r
+              & (CMU_STATUS_HFRCOSEL\r
+                 | CMU_STATUS_HFXOSEL\r
+                 | CMU_STATUS_LFRCOSEL\r
+#if defined( CMU_STATUS_USHFRCODIV2SEL )\r
+                 | CMU_STATUS_USHFRCODIV2SEL\r
+#endif\r
+                 | CMU_STATUS_LFXOSEL))\r
+      {\r
+        case CMU_STATUS_LFXOSEL:\r
+          ret = cmuSelect_LFXO;\r
+          break;\r
+\r
+        case CMU_STATUS_LFRCOSEL:\r
+          ret = cmuSelect_LFRCO;\r
+          break;\r
+\r
+        case CMU_STATUS_HFXOSEL:\r
+          ret = cmuSelect_HFXO;\r
+          break;\r
+\r
+#if defined( CMU_STATUS_USHFRCODIV2SEL )\r
+        case CMU_STATUS_USHFRCODIV2SEL:\r
+          ret = cmuSelect_USHFRCODIV2;\r
+          break;\r
+#endif\r
+\r
+        default:\r
+          ret = cmuSelect_HFRCO;\r
+          break;\r
+      }\r
+#endif\r
+      break;\r
+\r
+    case CMU_LFACLKSEL_REG:\r
+#if defined( _CMU_LFCLKSEL_MASK )\r
+      switch (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFA_MASK)\r
+      {\r
+        case CMU_LFCLKSEL_LFA_LFRCO:\r
+          ret = cmuSelect_LFRCO;\r
+          break;\r
+\r
+        case CMU_LFCLKSEL_LFA_LFXO:\r
+          ret = cmuSelect_LFXO;\r
+          break;\r
+\r
+#if defined( CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2 )\r
+        case CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2:\r
+          ret = cmuSelect_CORELEDIV2;\r
+          break;\r
+#endif\r
+\r
+        default:\r
+#if defined( CMU_LFCLKSEL_LFAE )\r
+          if (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFAE_MASK)\r
+          {\r
+            ret = cmuSelect_ULFRCO;\r
+            break;\r
+          }\r
+#else\r
+          ret = cmuSelect_Disabled;\r
+#endif\r
+          break;\r
+      }\r
+#endif /* _CMU_LFCLKSEL_MASK */\r
+\r
+#if defined( _CMU_LFACLKSEL_MASK )\r
+      switch (CMU->LFACLKSEL & _CMU_LFACLKSEL_LFA_MASK)\r
+      {\r
+        case CMU_LFACLKSEL_LFA_LFRCO:\r
+          ret = cmuSelect_LFRCO;\r
+          break;\r
+\r
+        case CMU_LFACLKSEL_LFA_LFXO:\r
+          ret = cmuSelect_LFXO;\r
+          break;\r
+\r
+        case CMU_LFACLKSEL_LFA_ULFRCO:\r
+          ret = cmuSelect_ULFRCO;\r
+          break;\r
+\r
+#if defined( _CMU_LFACLKSEL_LFA_HFCLKLE )\r
+        case CMU_LFACLKSEL_LFA_HFCLKLE:\r
+          ret = cmuSelect_HFCLKLE;\r
+          break;\r
+#endif\r
+\r
+        default:\r
+          ret = cmuSelect_Disabled;\r
+          break;\r
+      }\r
+#endif\r
+      break;\r
+\r
+    case CMU_LFBCLKSEL_REG:\r
+#if defined( _CMU_LFCLKSEL_MASK )\r
+      switch (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFB_MASK)\r
+      {\r
+        case CMU_LFCLKSEL_LFB_LFRCO:\r
+          ret = cmuSelect_LFRCO;\r
+          break;\r
+\r
+        case CMU_LFCLKSEL_LFB_LFXO:\r
+          ret = cmuSelect_LFXO;\r
+          break;\r
+\r
+#if defined( CMU_LFCLKSEL_LFB_HFCORECLKLEDIV2 )\r
+        case CMU_LFCLKSEL_LFB_HFCORECLKLEDIV2:\r
+          ret = cmuSelect_CORELEDIV2;\r
+          break;\r
+#endif\r
+\r
+#if defined( CMU_LFCLKSEL_LFB_HFCLKLE )\r
+        case CMU_LFCLKSEL_LFB_HFCLKLE:\r
+          ret = cmuSelect_HFCLKLE;\r
+          break;\r
+#endif\r
+\r
+        default:\r
+#if defined( CMU_LFCLKSEL_LFBE )\r
+          if (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFBE_MASK)\r
+          {\r
+            ret = cmuSelect_ULFRCO;\r
+            break;\r
+          }\r
+#else\r
+          ret = cmuSelect_Disabled;\r
+#endif\r
+          break;\r
+      }\r
+#endif /* _CMU_LFCLKSEL_MASK */\r
+\r
+#if defined( _CMU_LFBCLKSEL_MASK )\r
+      switch (CMU->LFBCLKSEL & _CMU_LFBCLKSEL_LFB_MASK)\r
+      {\r
+        case CMU_LFBCLKSEL_LFB_LFRCO:\r
+          ret = cmuSelect_LFRCO;\r
+          break;\r
+\r
+        case CMU_LFBCLKSEL_LFB_LFXO:\r
+          ret = cmuSelect_LFXO;\r
+          break;\r
+\r
+        case CMU_LFBCLKSEL_LFB_ULFRCO:\r
+          ret = cmuSelect_ULFRCO;\r
+          break;\r
+\r
+        case CMU_LFBCLKSEL_LFB_HFCLKLE:\r
+          ret = cmuSelect_HFCLKLE;\r
+          break;\r
+\r
+        default:\r
+          ret = cmuSelect_Disabled;\r
+          break;\r
+      }\r
+#endif\r
+      break;\r
+\r
+#if defined( _CMU_LFCLKSEL_LFC_MASK )\r
+    case CMU_LFCCLKSEL_REG:\r
+      switch (CMU->LFCLKSEL & _CMU_LFCLKSEL_LFC_MASK)\r
+      {\r
+        case CMU_LFCLKSEL_LFC_LFRCO:\r
+          ret = cmuSelect_LFRCO;\r
+          break;\r
+\r
+        case CMU_LFCLKSEL_LFC_LFXO:\r
+          ret = cmuSelect_LFXO;\r
+          break;\r
+\r
+        default:\r
+          ret = cmuSelect_Disabled;\r
+          break;\r
+      }\r
+      break;\r
+#endif\r
+\r
+#if defined( _CMU_LFECLKSEL_LFE_MASK )\r
+    case CMU_LFECLKSEL_REG:\r
+      switch (CMU->LFECLKSEL & _CMU_LFECLKSEL_LFE_MASK)\r
+      {\r
+        case CMU_LFECLKSEL_LFE_LFRCO:\r
+          ret = cmuSelect_LFRCO;\r
+          break;\r
+\r
+        case CMU_LFECLKSEL_LFE_LFXO:\r
+          ret = cmuSelect_LFXO;\r
+          break;\r
+\r
+        case CMU_LFECLKSEL_LFE_ULFRCO:\r
+          ret = cmuSelect_ULFRCO;\r
+          break;\r
+\r
+#if defined ( _CMU_LFECLKSEL_LFE_HFCLKLE )\r
+        case CMU_LFECLKSEL_LFE_HFCLKLE:\r
+          ret = cmuSelect_HFCLKLE;\r
+          break;\r
+#endif\r
+\r
+        default:\r
+          ret = cmuSelect_Disabled;\r
+          break;\r
+      }\r
+      break;\r
+#endif /* CMU_LFECLKSEL_REG */\r
+\r
+    case CMU_DBGCLKSEL_REG:\r
+#if defined( _CMU_DBGCLKSEL_DBG_MASK )\r
+      switch (CMU->DBGCLKSEL & _CMU_DBGCLKSEL_DBG_MASK)\r
+      {\r
+        case CMU_DBGCLKSEL_DBG_HFCLK:\r
+          ret = cmuSelect_HFCLK;\r
+          break;\r
+\r
+        case CMU_DBGCLKSEL_DBG_AUXHFRCO:\r
+          ret = cmuSelect_AUXHFRCO;\r
+          break;\r
+      }\r
+#else\r
+      ret = cmuSelect_AUXHFRCO;\r
+#endif /* CMU_DBGCLKSEL_DBG */\r
+\r
+#if defined( _CMU_CTRL_DBGCLK_MASK )\r
+      switch(CMU->CTRL & _CMU_CTRL_DBGCLK_MASK)\r
+      {\r
+        case CMU_CTRL_DBGCLK_AUXHFRCO:\r
+          ret = cmuSelect_AUXHFRCO;\r
+          break;\r
+\r
+        case CMU_CTRL_DBGCLK_HFCLK:\r
+          ret = cmuSelect_HFCLK;\r
+          break;\r
+      }\r
+#else\r
+      ret = cmuSelect_AUXHFRCO;\r
+#endif\r
+      break;\r
+\r
+\r
+#if defined( USB_PRESENT )\r
+    case CMU_USBCCLKSEL_REG:\r
+      switch (CMU->STATUS\r
+              & (CMU_STATUS_USBCLFXOSEL\r
+#if defined(_CMU_STATUS_USBCHFCLKSEL_MASK)\r
+                 | CMU_STATUS_USBCHFCLKSEL\r
+#endif\r
+#if defined(_CMU_STATUS_USBCUSHFRCOSEL_MASK)\r
+                 | CMU_STATUS_USBCUSHFRCOSEL\r
+#endif\r
+                 | CMU_STATUS_USBCLFRCOSEL))\r
+      {\r
+#if defined(_CMU_STATUS_USBCHFCLKSEL_MASK)\r
+        case CMU_STATUS_USBCHFCLKSEL:\r
+          ret = cmuSelect_HFCLK;\r
+          break;\r
+#endif\r
+\r
+#if defined(_CMU_STATUS_USBCUSHFRCOSEL_MASK)\r
+        case CMU_STATUS_USBCUSHFRCOSEL:\r
+          ret = cmuSelect_USHFRCO;\r
+          break;\r
+#endif\r
+\r
+        case CMU_STATUS_USBCLFXOSEL:\r
+          ret = cmuSelect_LFXO;\r
+          break;\r
+\r
+        case CMU_STATUS_USBCLFRCOSEL:\r
+          ret = cmuSelect_LFRCO;\r
+          break;\r
+\r
+        default:\r
+          ret = cmuSelect_Disabled;\r
+          break;\r
+      }\r
+      break;\r
+#endif\r
+\r
+    default:\r
+      EFM_ASSERT(0);\r
+      ret = cmuSelect_Error;\r
+      break;\r
+  }\r
+\r
+  return ret;\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Select reference clock/oscillator used for a clock branch.\r
+ *\r
+ * @details\r
+ *   Notice that if a selected reference is not enabled prior to selecting its\r
+ *   use, it will be enabled, and this function will wait for the selected\r
+ *   oscillator to be stable. It will however NOT be disabled if another\r
+ *   reference clock is selected later.\r
+ *\r
+ *   This feature is particularly important if selecting a new reference\r
+ *   clock for the clock branch clocking the core, otherwise the system\r
+ *   may halt.\r
+ *\r
+ * @param[in] clock\r
+ *   Clock branch to select reference clock for. One of:\r
+ *   @li #cmuClock_HF\r
+ *   @li #cmuClock_LFA\r
+ *   @li #cmuClock_LFB @if _CMU_LFCLKSEL_LFAE_ULFRCO\r
+ *   @li #cmuClock_LFC\r
+ *   @endif            @if _SILICON_LABS_32B_PLATFORM_2\r
+ *   @li #cmuClock_LFE\r
+ *   @endif\r
+ *   @li #cmuClock_DBG @if DOXYDOC_USB_PRESENT\r
+ *   @li #cmuClock_USBC\r
+ *   @endif\r
+ *\r
+ * @param[in] ref\r
+ *   Reference selected for clocking, please refer to reference manual for\r
+ *   for details on which reference is available for a specific clock branch.\r
+ *   @li #cmuSelect_HFRCO\r
+ *   @li #cmuSelect_LFRCO\r
+ *   @li #cmuSelect_HFXO\r
+ *   @li #cmuSelect_LFXO\r
+ *   @li #cmuSelect_CORELEDIV2\r
+ *   @li #cmuSelect_AUXHFRCO\r
+ *   @li #cmuSelect_HFCLK @ifnot DOXYDOC_EFM32_GECKO_FAMILY\r
+ *   @li #cmuSelect_ULFRCO\r
+ *   @endif\r
+ ******************************************************************************/\r
+void CMU_ClockSelectSet(CMU_Clock_TypeDef clock, CMU_Select_TypeDef ref)\r
+{\r
+  uint32_t        select = cmuOsc_HFRCO;\r
+  CMU_Osc_TypeDef osc    = cmuOsc_HFRCO;\r
+  uint32_t        freq;\r
+  uint32_t        tmp;\r
+  uint32_t        selRegId;\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+  volatile uint32_t *selReg = NULL;\r
+#endif\r
+#if defined( CMU_LFCLKSEL_LFAE_ULFRCO )\r
+  uint32_t        lfExtended = 0;\r
+#endif\r
+\r
+  selRegId = (clock >> CMU_SEL_REG_POS) & CMU_SEL_REG_MASK;\r
+\r
+  switch (selRegId)\r
+  {\r
+    case CMU_HFCLKSEL_REG:\r
+      switch (ref)\r
+      {\r
+        case cmuSelect_LFXO:\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+          select = CMU_HFCLKSEL_HF_LFXO;\r
+#elif defined( _SILICON_LABS_32B_PLATFORM_1 )\r
+          select = CMU_CMD_HFCLKSEL_LFXO;\r
+#endif\r
+          osc = cmuOsc_LFXO;\r
+          break;\r
+\r
+        case cmuSelect_LFRCO:\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+          select = CMU_HFCLKSEL_HF_LFRCO;\r
+#elif defined( _SILICON_LABS_32B_PLATFORM_1 )\r
+          select = CMU_CMD_HFCLKSEL_LFRCO;\r
+#endif\r
+          osc = cmuOsc_LFRCO;\r
+          break;\r
+\r
+        case cmuSelect_HFXO:\r
+          osc = cmuOsc_HFXO;\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+          select = CMU_HFCLKSEL_HF_HFXO;\r
+          /* Adjust HFXO buffer current for high frequencies, */\r
+          /* enable WSHFLE for frequencies above 32MHz.       */\r
+          if (SystemHFXOClockGet() > 32000000)\r
+          {\r
+            CMU->CTRL |= CMU_CTRL_WSHFLE;\r
+          }\r
+#elif defined( _SILICON_LABS_32B_PLATFORM_1 )\r
+          select = CMU_CMD_HFCLKSEL_HFXO;\r
+#if defined( CMU_CTRL_HFLE )\r
+          /* Adjust HFXO buffer current for high frequencies,     */\r
+          /* enable HFLE for frequencies above CMU_MAX_FREQ_HFLE. */\r
+          if(SystemHFXOClockGet() > CMU_MAX_FREQ_HFLE())\r
+          {\r
+            CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_HFXOBUFCUR_MASK)\r
+                        | CMU_CTRL_HFXOBUFCUR_BOOSTABOVE32MHZ\r
+            /* Must have HFLE enabled to access some LE peripherals >=32MHz */\r
+                        | CMU_CTRL_HFLE;\r
+\r
+            /* Set HFLE and DIV4 factor for peripheral clock if HFCORE  */\r
+            /* clock for LE is enabled.                                 */\r
+            if (CMU->HFCORECLKEN0 & CMU_HFCORECLKEN0_LE)\r
+            {\r
+              BUS_RegBitWrite(&CMU->HFCORECLKDIV,\r
+                              _CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);\r
+            }\r
+          }\r
+          else\r
+          {\r
+            /* This can happen if the user configures the EFM32_HFXO_FREQ to */\r
+            /* use another oscillator frequency */\r
+            CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_HFXOBUFCUR_MASK)\r
+                        | CMU_CTRL_HFXOBUFCUR_BOOSTUPTO32MHZ;\r
+          }\r
+#endif\r
+#endif\r
+          break;\r
+\r
+        case cmuSelect_HFRCO:\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+          select = CMU_HFCLKSEL_HF_HFRCO;\r
+#elif defined( _SILICON_LABS_32B_PLATFORM_1 )\r
+          select = CMU_CMD_HFCLKSEL_HFRCO;\r
+#endif\r
+          osc = cmuOsc_HFRCO;\r
+          break;\r
+\r
+#if defined( CMU_CMD_HFCLKSEL_USHFRCODIV2 )\r
+        case cmuSelect_USHFRCODIV2:\r
+          select = CMU_CMD_HFCLKSEL_USHFRCODIV2;\r
+          osc = cmuOsc_USHFRCO;\r
+          break;\r
+#endif\r
+\r
+#if defined( CMU_LFCLKSEL_LFAE_ULFRCO ) || defined( CMU_LFACLKSEL_LFA_ULFRCO )\r
+        case cmuSelect_ULFRCO:\r
+          /* ULFRCO cannot be used as HFCLK  */\r
+          EFM_ASSERT(0);\r
+          return;\r
+#endif\r
+\r
+        default:\r
+          EFM_ASSERT(0);\r
+          return;\r
+      }\r
+\r
+      /* Ensure selected oscillator is enabled, waiting for it to stabilize */\r
+      CMU_OscillatorEnable(osc, true, true);\r
+\r
+      /* Configure worst case wait states for flash access before selecting */\r
+      flashWaitStateMax();\r
+\r
+      /* Switch to selected oscillator */\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+      CMU->HFCLKSEL = select;\r
+#elif defined( _SILICON_LABS_32B_PLATFORM_1 )\r
+      CMU->CMD = select;\r
+#endif\r
+\r
+      /* Keep EMU module informed */\r
+      EMU_UpdateOscConfig();\r
+\r
+      /* Update CMSIS core clock variable */\r
+      /* (The function will update the global variable) */\r
+      freq = SystemCoreClockGet();\r
+\r
+      /* Optimize flash access wait state setting for currently selected core clk */\r
+      flashWaitStateControl(freq);\r
+      break;\r
+\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+    case CMU_LFACLKSEL_REG:\r
+      selReg = (selReg == NULL) ? &CMU->LFACLKSEL : selReg;\r
+#if !defined( _CMU_LFACLKSEL_LFA_HFCLKLE )\r
+      /* HFCLKCLE can not be used as LFACLK */\r
+      EFM_ASSERT(ref != cmuSelect_HFCLKLE);\r
+#endif\r
+    case CMU_LFECLKSEL_REG:\r
+      selReg = (selReg == NULL) ? &CMU->LFECLKSEL : selReg;\r
+#if !defined( _CMU_LFECLKSEL_LFE_HFCLKLE )\r
+      /* HFCLKCLE can not be used as LFECLK */\r
+      EFM_ASSERT(ref != cmuSelect_HFCLKLE);\r
+#endif\r
+    case CMU_LFBCLKSEL_REG:\r
+      selReg = (selReg == NULL) ? &CMU->LFBCLKSEL : selReg;\r
+      switch (ref)\r
+      {\r
+        case cmuSelect_Disabled:\r
+          tmp = _CMU_LFACLKSEL_LFA_DISABLED;\r
+          break;\r
+\r
+        case cmuSelect_LFXO:\r
+          /* Ensure selected oscillator is enabled, waiting for it to stabilize */\r
+          CMU_OscillatorEnable(cmuOsc_LFXO, true, true);\r
+          tmp = _CMU_LFACLKSEL_LFA_LFXO;\r
+          break;\r
+\r
+        case cmuSelect_LFRCO:\r
+          /* Ensure selected oscillator is enabled, waiting for it to stabilize */\r
+          CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);\r
+          tmp = _CMU_LFACLKSEL_LFA_LFRCO;\r
+          break;\r
+\r
+        case cmuSelect_HFCLKLE:\r
+          /* Ensure HFCORE to LE clocking is enabled */\r
+          BUS_RegBitWrite(&CMU->HFBUSCLKEN0, _CMU_HFBUSCLKEN0_LE_SHIFT, 1);\r
+          tmp = _CMU_LFBCLKSEL_LFB_HFCLKLE;\r
+\r
+          /* If core frequency is > 32MHz enable WSHFLE */\r
+          freq = SystemCoreClockGet();\r
+          if (freq > 32000000U)\r
+          {\r
+            /* Enable CMU HFLE */\r
+            BUS_RegBitWrite(&CMU->CTRL, _CMU_CTRL_WSHFLE_SHIFT, 1);\r
+\r
+            /* Enable DIV4 factor for peripheral clock */\r
+            BUS_RegBitWrite(&CMU->HFPRESC, _CMU_HFPRESC_HFCLKLEPRESC_SHIFT, 1);\r
+          }\r
+          break;\r
+\r
+        case cmuSelect_ULFRCO:\r
+          /* ULFRCO is always on, there is no need to enable it. */\r
+          tmp = _CMU_LFACLKSEL_LFA_ULFRCO;\r
+          break;\r
+\r
+        default:\r
+          EFM_ASSERT(0);\r
+          return;\r
+      }\r
+      *selReg = tmp;\r
+      break;\r
+\r
+#elif defined( _SILICON_LABS_32B_PLATFORM_1 )\r
+    case CMU_LFACLKSEL_REG:\r
+    case CMU_LFBCLKSEL_REG:\r
+      switch (ref)\r
+      {\r
+        case cmuSelect_Disabled:\r
+          tmp = _CMU_LFCLKSEL_LFA_DISABLED;\r
+          break;\r
+\r
+        case cmuSelect_LFXO:\r
+          /* Ensure selected oscillator is enabled, waiting for it to stabilize */\r
+          CMU_OscillatorEnable(cmuOsc_LFXO, true, true);\r
+          tmp = _CMU_LFCLKSEL_LFA_LFXO;\r
+          break;\r
+\r
+        case cmuSelect_LFRCO:\r
+          /* Ensure selected oscillator is enabled, waiting for it to stabilize */\r
+          CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);\r
+          tmp = _CMU_LFCLKSEL_LFA_LFRCO;\r
+          break;\r
+\r
+        case cmuSelect_CORELEDIV2:\r
+          /* Ensure HFCORE to LE clocking is enabled */\r
+          BUS_RegBitWrite(&(CMU->HFCORECLKEN0), _CMU_HFCORECLKEN0_LE_SHIFT, 1);\r
+          tmp = _CMU_LFCLKSEL_LFA_HFCORECLKLEDIV2;\r
+#if defined( CMU_CTRL_HFLE )\r
+          /* If core frequency is higher than CMU_MAX_FREQ_HFLE on\r
+             Giant/Leopard/Wonder, enable HFLE and DIV4. */\r
+          freq = SystemCoreClockGet();\r
+          if(freq > CMU_MAX_FREQ_HFLE())\r
+          {\r
+            /* Enable CMU HFLE */\r
+            BUS_RegBitWrite(&CMU->CTRL, _CMU_CTRL_HFLE_SHIFT, 1);\r
+\r
+            /* Enable DIV4 factor for peripheral clock */\r
+            BUS_RegBitWrite(&CMU->HFCORECLKDIV,\r
+                            _CMU_HFCORECLKDIV_HFCORECLKLEDIV_SHIFT, 1);\r
+          }\r
+#endif\r
+          break;\r
+\r
+#if defined( CMU_LFCLKSEL_LFAE_ULFRCO )\r
+        case cmuSelect_ULFRCO:\r
+          /* ULFRCO is always enabled */\r
+          tmp = _CMU_LFCLKSEL_LFA_DISABLED;\r
+          lfExtended = 1;\r
+          break;\r
+#endif\r
+\r
+        default:\r
+          /* Illegal clock source for LFA/LFB selected */\r
+          EFM_ASSERT(0);\r
+          return;\r
+      }\r
+\r
+      /* Apply select */\r
+      if (selRegId == CMU_LFACLKSEL_REG)\r
+      {\r
+#if defined( _CMU_LFCLKSEL_LFAE_MASK )\r
+        CMU->LFCLKSEL = (CMU->LFCLKSEL\r
+                         & ~(_CMU_LFCLKSEL_LFA_MASK | _CMU_LFCLKSEL_LFAE_MASK))\r
+                        | (tmp << _CMU_LFCLKSEL_LFA_SHIFT)\r
+                        | (lfExtended << _CMU_LFCLKSEL_LFAE_SHIFT);\r
+#else\r
+        CMU->LFCLKSEL = (CMU->LFCLKSEL & ~_CMU_LFCLKSEL_LFA_MASK)\r
+                        | (tmp << _CMU_LFCLKSEL_LFA_SHIFT);\r
+#endif\r
+      }\r
+      else\r
+      {\r
+#if defined( _CMU_LFCLKSEL_LFBE_MASK )\r
+        CMU->LFCLKSEL = (CMU->LFCLKSEL\r
+                         & ~(_CMU_LFCLKSEL_LFB_MASK | _CMU_LFCLKSEL_LFBE_MASK))\r
+                        | (tmp << _CMU_LFCLKSEL_LFB_SHIFT)\r
+                        | (lfExtended << _CMU_LFCLKSEL_LFBE_SHIFT);\r
+#else\r
+        CMU->LFCLKSEL = (CMU->LFCLKSEL & ~_CMU_LFCLKSEL_LFB_MASK)\r
+                        | (tmp << _CMU_LFCLKSEL_LFB_SHIFT);\r
+#endif\r
+      }\r
+      break;\r
+\r
+#if defined( _CMU_LFCLKSEL_LFC_MASK )\r
+    case CMU_LFCCLKSEL_REG:\r
+      switch(ref)\r
+      {\r
+        case cmuSelect_Disabled:\r
+          tmp = _CMU_LFCLKSEL_LFA_DISABLED;\r
+          break;\r
+\r
+        case cmuSelect_LFXO:\r
+          /* Ensure selected oscillator is enabled, waiting for it to stabilize */\r
+          CMU_OscillatorEnable(cmuOsc_LFXO, true, true);\r
+          tmp = _CMU_LFCLKSEL_LFC_LFXO;\r
+          break;\r
+\r
+        case cmuSelect_LFRCO:\r
+          /* Ensure selected oscillator is enabled, waiting for it to stabilize */\r
+          CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);\r
+          tmp = _CMU_LFCLKSEL_LFC_LFRCO;\r
+          break;\r
+\r
+        default:\r
+          /* Illegal clock source for LFC selected */\r
+          EFM_ASSERT(0);\r
+          return;\r
+      }\r
+\r
+      /* Apply select */\r
+      CMU->LFCLKSEL = (CMU->LFCLKSEL & ~_CMU_LFCLKSEL_LFC_MASK)\r
+                      | (tmp << _CMU_LFCLKSEL_LFC_SHIFT);\r
+      break;\r
+#endif\r
+#endif\r
+\r
+#if defined( CMU_DBGCLKSEL_DBG ) || defined( CMU_CTRL_DBGCLK )\r
+    case CMU_DBGCLKSEL_REG:\r
+      switch(ref)\r
+      {\r
+#if defined( CMU_DBGCLKSEL_DBG )\r
+        case cmuSelect_AUXHFRCO:\r
+          /* Select AUXHFRCO as debug clock */\r
+          CMU->DBGCLKSEL = CMU_DBGCLKSEL_DBG_AUXHFRCO;\r
+          break;\r
+\r
+        case cmuSelect_HFCLK:\r
+          /* Select divided HFCLK as debug clock */\r
+          CMU->DBGCLKSEL = CMU_DBGCLKSEL_DBG_HFCLK;\r
+          break;\r
+#endif\r
+\r
+#if defined( CMU_CTRL_DBGCLK )\r
+        case cmuSelect_AUXHFRCO:\r
+          /* Select AUXHFRCO as debug clock */\r
+          CMU->CTRL = (CMU->CTRL & ~(_CMU_CTRL_DBGCLK_MASK))\r
+                      | CMU_CTRL_DBGCLK_AUXHFRCO;\r
+          break;\r
+\r
+        case cmuSelect_HFCLK:\r
+          /* Select divided HFCLK as debug clock */\r
+          CMU->CTRL = (CMU->CTRL & ~(_CMU_CTRL_DBGCLK_MASK))\r
+                      | CMU_CTRL_DBGCLK_HFCLK;\r
+          break;\r
+#endif\r
+\r
+        default:\r
+          /* Illegal clock source for debug selected */\r
+          EFM_ASSERT(0);\r
+          return;\r
+      }\r
+      break;\r
+#endif\r
+\r
+#if defined(USB_PRESENT)\r
+    case CMU_USBCCLKSEL_REG:\r
+      switch(ref)\r
+      {\r
+        case cmuSelect_LFXO:\r
+          /* Select LFXO as clock source for USB, can only be used in sleep mode */\r
+          /* Ensure selected oscillator is enabled, waiting for it to stabilize */\r
+          CMU_OscillatorEnable(cmuOsc_LFXO, true, true);\r
+\r
+          /* Switch oscillator */\r
+          CMU->CMD = CMU_CMD_USBCCLKSEL_LFXO;\r
+\r
+          /* Wait until clock is activated */\r
+          while((CMU->STATUS & CMU_STATUS_USBCLFXOSEL)==0)\r
+          {\r
+          }\r
+          break;\r
+\r
+        case cmuSelect_LFRCO:\r
+          /* Select LFRCO as clock source for USB, can only be used in sleep mode */\r
+          /* Ensure selected oscillator is enabled, waiting for it to stabilize */\r
+          CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);\r
+\r
+          /* Switch oscillator */\r
+          CMU->CMD = CMU_CMD_USBCCLKSEL_LFRCO;\r
+\r
+          /* Wait until clock is activated */\r
+          while((CMU->STATUS & CMU_STATUS_USBCLFRCOSEL)==0)\r
+          {\r
+          }\r
+          break;\r
+\r
+#if defined( CMU_STATUS_USBCHFCLKSEL )\r
+        case cmuSelect_HFCLK:\r
+          /* Select undivided HFCLK as clock source for USB */\r
+          /* Oscillator must already be enabled to avoid a core lockup */\r
+          CMU->CMD = CMU_CMD_USBCCLKSEL_HFCLKNODIV;\r
+          /* Wait until clock is activated */\r
+          while((CMU->STATUS & CMU_STATUS_USBCHFCLKSEL)==0)\r
+          {\r
+          }\r
+          break;\r
+#endif\r
+\r
+#if defined( CMU_CMD_USBCCLKSEL_USHFRCO )\r
+        case cmuSelect_USHFRCO:\r
+          /* Select USHFRCO as clock source for USB */\r
+          /* Ensure selected oscillator is enabled, waiting for it to stabilize */\r
+          CMU_OscillatorEnable(cmuOsc_USHFRCO, true, true);\r
+\r
+          /* Switch oscillator */\r
+          CMU->CMD = CMU_CMD_USBCCLKSEL_USHFRCO;\r
+\r
+          /* Wait until clock is activated */\r
+          while((CMU->STATUS & CMU_STATUS_USBCUSHFRCOSEL)==0)\r
+          {\r
+          }\r
+          break;\r
+#endif\r
+\r
+        default:\r
+          /* Illegal clock source for USB */\r
+          EFM_ASSERT(0);\r
+          return;\r
+      }\r
+      break;\r
+#endif\r
+\r
+    default:\r
+      EFM_ASSERT(0);\r
+      break;\r
+  }\r
+}\r
+\r
+\r
+/**************************************************************************//**\r
+ * @brief\r
+ *   CMU low frequency register synchronization freeze control.\r
+ *\r
+ * @details\r
+ *   Some CMU registers requires synchronization into the low frequency (LF)\r
+ *   domain. The freeze feature allows for several such registers to be\r
+ *   modified before passing them to the LF domain simultaneously (which\r
+ *   takes place when the freeze mode is disabled).\r
+ *\r
+ *   Another usage scenario of this feature, is when using an API (such\r
+ *   as the CMU API) for modifying several bit fields consecutively in the\r
+ *   same register. If freeze mode is enabled during this sequence, stalling\r
+ *   can be avoided.\r
+ *\r
+ * @note\r
+ *   When enabling freeze mode, this function will wait for all current\r
+ *   ongoing CMU synchronization to LF domain to complete (Normally\r
+ *   synchronization will not be in progress.) However for this reason, when\r
+ *   using freeze mode, modifications of registers requiring LF synchronization\r
+ *   should be done within one freeze enable/disable block to avoid unecessary\r
+ *   stalling.\r
+ *\r
+ * @param[in] enable\r
+ *   @li true - enable freeze, modified registers are not propagated to the\r
+ *       LF domain\r
+ *   @li false - disable freeze, modified registers are propagated to LF\r
+ *       domain\r
+ *****************************************************************************/\r
+void CMU_FreezeEnable(bool enable)\r
+{\r
+  if (enable)\r
+  {\r
+    /* Wait for any ongoing LF synchronization to complete. This is just to */\r
+    /* protect against the rare case when a user                            */\r
+    /* - modifies a register requiring LF sync                              */\r
+    /* - then enables freeze before LF sync completed                       */\r
+    /* - then modifies the same register again                              */\r
+    /* since modifying a register while it is in sync progress should be    */\r
+    /* avoided.                                                             */\r
+    while (CMU->SYNCBUSY)\r
+    {\r
+    }\r
+\r
+    CMU->FREEZE = CMU_FREEZE_REGFREEZE;\r
+  }\r
+  else\r
+  {\r
+    CMU->FREEZE = 0;\r
+  }\r
+}\r
+\r
+\r
+#if defined( _CMU_HFRCOCTRL_BAND_MASK )\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Get HFRCO band in use.\r
+ *\r
+ * @return\r
+ *   HFRCO band in use.\r
+ ******************************************************************************/\r
+CMU_HFRCOBand_TypeDef CMU_HFRCOBandGet(void)\r
+{\r
+  return (CMU_HFRCOBand_TypeDef)((CMU->HFRCOCTRL & _CMU_HFRCOCTRL_BAND_MASK)\r
+                                 >> _CMU_HFRCOCTRL_BAND_SHIFT);\r
+}\r
+#endif /* _CMU_HFRCOCTRL_BAND_MASK */\r
+\r
+\r
+#if defined( _CMU_HFRCOCTRL_BAND_MASK )\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Set HFRCO band and the tuning value based on the value in the calibration\r
+ *   table made during production.\r
+ *\r
+ * @param[in] band\r
+ *   HFRCO band to activate.\r
+ ******************************************************************************/\r
+void CMU_HFRCOBandSet(CMU_HFRCOBand_TypeDef band)\r
+{\r
+  uint32_t           tuning;\r
+  uint32_t           freq;\r
+  CMU_Select_TypeDef osc;\r
+\r
+  /* Read tuning value from calibration table */\r
+  switch (band)\r
+  {\r
+    case cmuHFRCOBand_1MHz:\r
+      tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND1_MASK)\r
+               >> _DEVINFO_HFRCOCAL0_BAND1_SHIFT;\r
+      break;\r
+\r
+    case cmuHFRCOBand_7MHz:\r
+      tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND7_MASK)\r
+               >> _DEVINFO_HFRCOCAL0_BAND7_SHIFT;\r
+      break;\r
+\r
+    case cmuHFRCOBand_11MHz:\r
+      tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND11_MASK)\r
+               >> _DEVINFO_HFRCOCAL0_BAND11_SHIFT;\r
+      break;\r
+\r
+    case cmuHFRCOBand_14MHz:\r
+      tuning = (DEVINFO->HFRCOCAL0 & _DEVINFO_HFRCOCAL0_BAND14_MASK)\r
+               >> _DEVINFO_HFRCOCAL0_BAND14_SHIFT;\r
+      break;\r
+\r
+    case cmuHFRCOBand_21MHz:\r
+      tuning = (DEVINFO->HFRCOCAL1 & _DEVINFO_HFRCOCAL1_BAND21_MASK)\r
+               >> _DEVINFO_HFRCOCAL1_BAND21_SHIFT;\r
+      break;\r
+\r
+#if defined( _CMU_HFRCOCTRL_BAND_28MHZ )\r
+    case cmuHFRCOBand_28MHz:\r
+      tuning = (DEVINFO->HFRCOCAL1 & _DEVINFO_HFRCOCAL1_BAND28_MASK)\r
+               >> _DEVINFO_HFRCOCAL1_BAND28_SHIFT;\r
+      break;\r
+#endif\r
+\r
+    default:\r
+      EFM_ASSERT(0);\r
+      return;\r
+  }\r
+\r
+  /* If HFRCO is used for core clock, we have to consider flash access WS. */\r
+  osc = CMU_ClockSelectGet(cmuClock_HF);\r
+  if (osc == cmuSelect_HFRCO)\r
+  {\r
+    /* Configure worst case wait states for flash access before setting divider */\r
+    flashWaitStateMax();\r
+  }\r
+\r
+  /* Set band/tuning */\r
+  CMU->HFRCOCTRL = (CMU->HFRCOCTRL &\r
+                    ~(_CMU_HFRCOCTRL_BAND_MASK | _CMU_HFRCOCTRL_TUNING_MASK))\r
+                   | (band << _CMU_HFRCOCTRL_BAND_SHIFT)\r
+                   | (tuning << _CMU_HFRCOCTRL_TUNING_SHIFT);\r
+\r
+  /* If HFRCO is used for core clock, optimize flash WS */\r
+  if (osc == cmuSelect_HFRCO)\r
+  {\r
+    /* Update CMSIS core clock variable and get current core clock */\r
+    /* (The function will update the global variable) */\r
+    /* NOTE! We need at least 21 cycles before setting zero wait state to flash */\r
+    /* (i.e. WS0) when going from the 28MHz to 1MHz in the HFRCO band */\r
+    freq = SystemCoreClockGet();\r
+\r
+    /* Optimize flash access wait state setting for current core clk */\r
+    flashWaitStateControl(freq);\r
+  }\r
+}\r
+#endif /* _CMU_HFRCOCTRL_BAND_MASK */\r
+\r
+\r
+#if defined( _CMU_HFRCOCTRL_FREQRANGE_MASK )\r
+/**************************************************************************//**\r
+ * @brief\r
+ *   Get a pointer to the HFRCO frequency calibration word in DEVINFO\r
+ *\r
+ * @param[in] freq\r
+ *   Frequency in Hz\r
+ *\r
+ * @return\r
+ *   HFRCO calibration word for a given frequency\r
+ *****************************************************************************/\r
+static uint32_t CMU_HFRCODevinfoGet(CMU_HFRCOFreq_TypeDef freq)\r
+{\r
+  switch (freq)\r
+  {\r
+    /* 1, 2 and 4MHz share the same calibration word */\r
+    case cmuHFRCOFreq_1M0Hz:\r
+    case cmuHFRCOFreq_2M0Hz:\r
+    case cmuHFRCOFreq_4M0Hz:\r
+      return DEVINFO->HFRCOCAL0;\r
+\r
+    case cmuHFRCOFreq_7M0Hz:\r
+      return DEVINFO->HFRCOCAL3;\r
+\r
+    case cmuHFRCOFreq_13M0Hz:\r
+      return DEVINFO->HFRCOCAL6;\r
+\r
+    case cmuHFRCOFreq_16M0Hz:\r
+      return DEVINFO->HFRCOCAL7;\r
+\r
+    case cmuHFRCOFreq_19M0Hz:\r
+      return DEVINFO->HFRCOCAL8;\r
+\r
+    case cmuHFRCOFreq_26M0Hz:\r
+      return DEVINFO->HFRCOCAL10;\r
+\r
+    case cmuHFRCOFreq_32M0Hz:\r
+      return DEVINFO->HFRCOCAL11;\r
+\r
+    case cmuHFRCOFreq_38M0Hz:\r
+      return DEVINFO->HFRCOCAL12;\r
+\r
+    default: /* cmuHFRCOFreq_UserDefined */\r
+      return 0;\r
+  }\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Get HFRCO frequency enumeration in use\r
+ *\r
+ * @return\r
+ *   HFRCO frequency enumeration in use\r
+ ******************************************************************************/\r
+CMU_HFRCOFreq_TypeDef CMU_HFRCOFreqGet(void)\r
+{\r
+  return (CMU_HFRCOFreq_TypeDef)SystemHfrcoFreq;\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Set HFRCO calibration for the selected target frequency\r
+ *\r
+ * @param[in] freq\r
+ *   HFRCO frequency band to set\r
+ ******************************************************************************/\r
+void CMU_HFRCOFreqSet(CMU_HFRCOFreq_TypeDef freq)\r
+{\r
+  uint32_t freqCal;\r
+\r
+  /* Get DEVINFO index, set CMSIS frequency SystemHfrcoFreq */\r
+  freqCal = CMU_HFRCODevinfoGet(freq);\r
+  EFM_ASSERT((freqCal != 0) && (freqCal != UINT_MAX));\r
+  SystemHfrcoFreq = (uint32_t)freq;\r
+\r
+  /* Set max wait-states while changing core clock */\r
+  if (CMU_ClockSelectGet(cmuClock_HF) == cmuSelect_HFRCO)\r
+  {\r
+    flashWaitStateMax();\r
+  }\r
+\r
+  /* Wait for any previous sync to complete, and then set calibration data\r
+     for the selected frequency.  */\r
+  while(BUS_RegBitRead(&CMU->SYNCBUSY, _CMU_SYNCBUSY_HFRCOBSY_SHIFT));\r
+\r
+  /* Check for valid calibration data */\r
+  EFM_ASSERT(freqCal != UINT_MAX);\r
+\r
+  /* Set divider in HFRCOCTRL for 1, 2 and 4MHz */\r
+  switch(freq)\r
+  {\r
+    case cmuHFRCOFreq_1M0Hz:\r
+      freqCal = (freqCal & ~_CMU_HFRCOCTRL_CLKDIV_MASK)\r
+                | CMU_HFRCOCTRL_CLKDIV_DIV4;\r
+      break;\r
+\r
+    case cmuHFRCOFreq_2M0Hz:\r
+      freqCal = (freqCal & ~_CMU_HFRCOCTRL_CLKDIV_MASK)\r
+                | CMU_HFRCOCTRL_CLKDIV_DIV2;\r
+      break;\r
+\r
+    case cmuHFRCOFreq_4M0Hz:\r
+      freqCal = (freqCal & ~_CMU_HFRCOCTRL_CLKDIV_MASK)\r
+                | CMU_HFRCOCTRL_CLKDIV_DIV1;\r
+      break;\r
+\r
+    default:\r
+      break;\r
+  }\r
+  CMU->HFRCOCTRL = freqCal;\r
+\r
+  /* Optimize flash access wait-state configuration for this frequency, */\r
+  /* if HFRCO is reference for core clock.                              */\r
+  if (CMU_ClockSelectGet(cmuClock_HF) == cmuSelect_HFRCO)\r
+  {\r
+    flashWaitStateControl((uint32_t)freq);\r
+  }\r
+}\r
+#endif /* _CMU_HFRCOCTRL_FREQRANGE_MASK */\r
+\r
+#if defined( _CMU_HFRCOCTRL_SUDELAY_MASK )\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Get the HFRCO startup delay.\r
+ *\r
+ * @details\r
+ *   Please refer to the reference manual for further details.\r
+ *\r
+ * @return\r
+ *   The startup delay in use.\r
+ ******************************************************************************/\r
+uint32_t CMU_HFRCOStartupDelayGet(void)\r
+{\r
+  return (CMU->HFRCOCTRL & _CMU_HFRCOCTRL_SUDELAY_MASK)\r
+         >> _CMU_HFRCOCTRL_SUDELAY_SHIFT;\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Set the HFRCO startup delay.\r
+ *\r
+ * @details\r
+ *   Please refer to the reference manual for further details.\r
+ *\r
+ * @param[in] delay\r
+ *   The startup delay to set (<= 31).\r
+ ******************************************************************************/\r
+void CMU_HFRCOStartupDelaySet(uint32_t delay)\r
+{\r
+  EFM_ASSERT(delay <= 31);\r
+\r
+  delay &= _CMU_HFRCOCTRL_SUDELAY_MASK >> _CMU_HFRCOCTRL_SUDELAY_SHIFT;\r
+  CMU->HFRCOCTRL = (CMU->HFRCOCTRL & ~(_CMU_HFRCOCTRL_SUDELAY_MASK))\r
+                   | (delay << _CMU_HFRCOCTRL_SUDELAY_SHIFT);\r
+}\r
+#endif\r
+\r
+\r
+#if defined( _CMU_HFXOCTRL_AUTOSTARTRDYSELRAC_MASK )\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Enable or disable HFXO autostart\r
+ *\r
+ * @param[in] enRACStartSel\r
+ *   If true, HFXO is automatically started and selected upon RAC wakeup.\r
+ *   If false, HFXO is not started or selected automatically upon RAC wakeup.\r
+ *\r
+ * @param[in] enEM0EM1Start\r
+ *   If true, HFXO is automatically started upon entering EM0/EM1 entry from\r
+ *   EM2/EM3. HFXO selection has to be handled by the user.\r
+ *   If false, HFXO is not started automatically when entering EM0/EM1.\r
+ *\r
+ * @param[in] enEM0EM1StartSel\r
+ *   If true, HFXO is automatically started and immediately selected upon\r
+ *   entering EM0/EM1 entry from EM2/EM3. Note that this option stalls the use of\r
+ *   HFSRCCLK until HFXO becomes ready.\r
+ *   If false, HFXO is not started or selected automatically when entering\r
+ *   EM0/EM1.\r
+ ******************************************************************************/\r
+void CMU_HFXOAutostartEnable(bool enRACStartSel,\r
+                             bool enEM0EM1Start,\r
+                             bool enEM0EM1StartSel)\r
+{\r
+  uint32_t hfxoCtrl;\r
+  hfxoCtrl = CMU->HFXOCTRL & ~(_CMU_HFXOCTRL_AUTOSTARTRDYSELRAC_MASK\r
+                              | _CMU_HFXOCTRL_AUTOSTARTEM0EM1_MASK\r
+                              | _CMU_HFXOCTRL_AUTOSTARTSELEM0EM1_MASK);\r
+\r
+  hfxoCtrl |= (enRACStartSel ? CMU_HFXOCTRL_AUTOSTARTRDYSELRAC : 0)\r
+              | (enEM0EM1Start ? CMU_HFXOCTRL_AUTOSTARTEM0EM1 : 0)\r
+              | (enEM0EM1StartSel ? CMU_HFXOCTRL_AUTOSTARTSELEM0EM1 : 0);\r
+\r
+  CMU->HFXOCTRL = hfxoCtrl;\r
+}\r
+#endif /* _CMU_HFXOCTRL_AUTOSTARTRDYSELRAC_MASK */\r
+\r
+\r
+#if defined( _CMU_HFXOCTRL_MASK )\r
+/**************************************************************************//**\r
+ * @brief\r
+ *   Set HFXO control registers\r
+ *\r
+ * @note\r
+ *   HFXO configuration should be obtained from a configuration tool,\r
+ *   app note or xtal datasheet. This function disables the HFXO to ensure\r
+ *   a valid state before update.\r
+ *\r
+ * @param[in] hfxoInit\r
+ *    HFXO setup parameters\r
+ *****************************************************************************/\r
+void CMU_HFXOInit(CMU_HFXOInit_TypeDef *hfxoInit)\r
+{\r
+  uint32_t ishReg;\r
+  uint32_t ishMax;\r
+\r
+  /* Do not disable HFXO if it is currently selected as HF/Core clock */\r
+  EFM_ASSERT(CMU_ClockSelectGet(cmuClock_HF) != cmuSelect_HFXO);\r
+\r
+  /* HFXO must be disabled before reconfiguration */\r
+  CMU_OscillatorEnable(cmuOsc_HFXO, false, false);\r
+\r
+  /* Apply control settings */\r
+  BUS_RegMaskedWrite(&CMU->HFXOCTRL,\r
+                     _CMU_HFXOCTRL_LOWPOWER_MASK\r
+#if defined( _CMU_HFXOCTRL_AUTOSTARTRDYSELRAC_MASK )\r
+                     | _CMU_HFXOCTRL_AUTOSTARTRDYSELRAC_MASK\r
+#endif\r
+                     | _CMU_HFXOCTRL_AUTOSTARTEM0EM1_MASK\r
+                     | _CMU_HFXOCTRL_AUTOSTARTSELEM0EM1_MASK,\r
+                     (hfxoInit->lowPowerMode\r
+                      ? CMU_HFXOCTRL_LOWPOWER : 0)\r
+#if defined( _CMU_HFXOCTRL_AUTOSTARTRDYSELRAC_MASK )\r
+                     | (hfxoInit->autoStartSelOnRacWakeup\r
+                        ? CMU_HFXOCTRL_AUTOSTARTRDYSELRAC : 0)\r
+#endif\r
+                     | (hfxoInit->autoStartEm01\r
+                        ? CMU_HFXOCTRL_AUTOSTARTEM0EM1 : 0)\r
+                     | (hfxoInit->autoSelEm01\r
+                        ? CMU_HFXOCTRL_AUTOSTARTSELEM0EM1 : 0));\r
+\r
+  /* Set XTAL tuning parameters */\r
+\r
+  /* Set peak detection threshold in CMU_HFXOCTRL1_PEAKDETTHR[2:0] (hidden). */\r
+  BUS_RegMaskedWrite((volatile uint32_t *)0x400E4028, 0x7, hfxoInit->thresholdPeakDetect);\r
+\r
+  /* Set tuning for startup and steady state */\r
+  BUS_RegMaskedWrite(&CMU->HFXOSTARTUPCTRL,\r
+                     _CMU_HFXOSTARTUPCTRL_CTUNE_MASK\r
+                     | _CMU_HFXOSTARTUPCTRL_REGISHWARM_MASK\r
+                     | _CMU_HFXOSTARTUPCTRL_IBTRIMXOCORE_MASK\r
+                     | _CMU_HFXOSTARTUPCTRL_IBTRIMXOCOREWARM_MASK,\r
+                     (hfxoInit->ctuneStartup\r
+                      << _CMU_HFXOSTARTUPCTRL_CTUNE_SHIFT)\r
+                     | (hfxoInit->regIshStartup\r
+                        << _CMU_HFXOSTARTUPCTRL_REGISHWARM_SHIFT)\r
+                     | (hfxoInit->xoCoreBiasTrimStartup\r
+                        << _CMU_HFXOSTARTUPCTRL_IBTRIMXOCORE_SHIFT)\r
+                     | 0x4 /* Recommended tuning */\r
+                        << _CMU_HFXOSTARTUPCTRL_IBTRIMXOCOREWARM_SHIFT);\r
+\r
+  /* Adjust CMU_HFXOSTEADYSTATECTRL_REGISHUPPER according to regIshSteadyState.\r
+     Saturate at max value. Please see the reference manual page 433 and Section\r
+     12.5.10 CMU_HFXOSTEADYSTATECTRL for more details. */\r
+  ishReg = hfxoInit->regIshSteadyState + 3;\r
+  ishMax = _CMU_HFXOSTEADYSTATECTRL_REGISHUPPER_MASK\r
+            >> _CMU_HFXOSTEADYSTATECTRL_REGISHUPPER_SHIFT;\r
+  ishReg = ishReg > ishMax ? ishMax : ishReg;\r
+  ishReg <<= _CMU_HFXOSTEADYSTATECTRL_REGISHUPPER_SHIFT;\r
+\r
+  BUS_RegMaskedWrite(&CMU->HFXOSTEADYSTATECTRL,\r
+                     _CMU_HFXOSTEADYSTATECTRL_CTUNE_MASK\r
+                     | _CMU_HFXOSTEADYSTATECTRL_REGISH_MASK\r
+                     | _CMU_HFXOSTEADYSTATECTRL_IBTRIMXOCORE_MASK\r
+                     | _CMU_HFXOSTEADYSTATECTRL_REGISHUPPER_MASK,\r
+                     (hfxoInit->ctuneSteadyState\r
+                      << _CMU_HFXOSTEADYSTATECTRL_CTUNE_SHIFT)\r
+                     | (hfxoInit->regIshSteadyState\r
+                        << _CMU_HFXOSTEADYSTATECTRL_REGISH_SHIFT)\r
+                     | (hfxoInit->xoCoreBiasTrimSteadyState\r
+                        << _CMU_HFXOSTEADYSTATECTRL_IBTRIMXOCORE_SHIFT)\r
+                     | ishReg);\r
+\r
+  /* Set timeouts */\r
+  BUS_RegMaskedWrite(&CMU->HFXOTIMEOUTCTRL,\r
+                     _CMU_HFXOTIMEOUTCTRL_SHUNTOPTTIMEOUT_MASK\r
+                     | _CMU_HFXOTIMEOUTCTRL_PEAKDETTIMEOUT_MASK\r
+                     | _CMU_HFXOTIMEOUTCTRL_WARMSTEADYTIMEOUT_MASK\r
+                     | _CMU_HFXOTIMEOUTCTRL_STEADYTIMEOUT_MASK\r
+                     | _CMU_HFXOTIMEOUTCTRL_STARTUPTIMEOUT_MASK,\r
+                     (hfxoInit->timeoutShuntOptimization\r
+                      << _CMU_HFXOTIMEOUTCTRL_SHUNTOPTTIMEOUT_SHIFT)\r
+                     | (hfxoInit->timeoutPeakDetect\r
+                        << _CMU_HFXOTIMEOUTCTRL_PEAKDETTIMEOUT_SHIFT)\r
+                     | (hfxoInit->timeoutWarmSteady\r
+                        << _CMU_HFXOTIMEOUTCTRL_WARMSTEADYTIMEOUT_SHIFT)\r
+                     | (hfxoInit->timeoutSteady\r
+                        << _CMU_HFXOTIMEOUTCTRL_STEADYTIMEOUT_SHIFT)\r
+                     | (hfxoInit->timeoutStartup\r
+                        << _CMU_HFXOTIMEOUTCTRL_STARTUPTIMEOUT_SHIFT));\r
+}\r
+#endif\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Get the LCD framerate divisor (FDIV) setting.\r
+ *\r
+ * @return\r
+ *   The LCD framerate divisor.\r
+ ******************************************************************************/\r
+uint32_t CMU_LCDClkFDIVGet(void)\r
+{\r
+#if defined( LCD_PRESENT )\r
+  return (CMU->LCDCTRL & _CMU_LCDCTRL_FDIV_MASK) >> _CMU_LCDCTRL_FDIV_SHIFT;\r
+#else\r
+  return 0;\r
+#endif /* defined(LCD_PRESENT) */\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Set the LCD framerate divisor (FDIV) setting.\r
+ *\r
+ * @note\r
+ *   The FDIV field (CMU LCDCTRL register) should only be modified while the\r
+ *   LCD module is clock disabled (CMU LFACLKEN0.LCD bit is 0). This function\r
+ *   will NOT modify FDIV if the LCD module clock is enabled. Please refer to\r
+ *   CMU_ClockEnable() for disabling/enabling LCD clock.\r
+ *\r
+ * @param[in] div\r
+ *   The FDIV setting to use.\r
+ ******************************************************************************/\r
+void CMU_LCDClkFDIVSet(uint32_t div)\r
+{\r
+#if defined( LCD_PRESENT )\r
+  EFM_ASSERT(div <= cmuClkDiv_128);\r
+\r
+  /* Do not allow modification if LCD clock enabled */\r
+  if (CMU->LFACLKEN0 & CMU_LFACLKEN0_LCD)\r
+  {\r
+    return;\r
+  }\r
+\r
+  div        <<= _CMU_LCDCTRL_FDIV_SHIFT;\r
+  div         &= _CMU_LCDCTRL_FDIV_MASK;\r
+  CMU->LCDCTRL = (CMU->LCDCTRL & ~_CMU_LCDCTRL_FDIV_MASK) | div;\r
+#else\r
+  (void)div;  /* Unused parameter */\r
+#endif /* defined(LCD_PRESENT) */\r
+}\r
+\r
+\r
+#if defined( _CMU_LFXOCTRL_MASK )\r
+/**************************************************************************//**\r
+ * @brief\r
+ *   Set LFXO control registers\r
+ *\r
+ * @note\r
+ *   LFXO configuration should be obtained from a configuration tool,\r
+ *   app note or xtal datasheet. This function disables the LFXO to ensure\r
+ *   a valid state before update.\r
+ *\r
+ * @param[in] lfxoInit\r
+ *    LFXO setup parameters\r
+ *****************************************************************************/\r
+void CMU_LFXOInit(CMU_LFXOInit_TypeDef *lfxoInit)\r
+{\r
+  /* Do not disable LFXO if it is currently selected as HF/Core clock */\r
+  EFM_ASSERT(CMU_ClockSelectGet(cmuClock_HF) != cmuSelect_LFXO);\r
+\r
+  /* LFXO must be disabled before reconfiguration */\r
+  CMU_OscillatorEnable(cmuOsc_LFXO, false, false);\r
+\r
+  BUS_RegMaskedWrite(&CMU->LFXOCTRL,\r
+                     _CMU_LFXOCTRL_TUNING_MASK\r
+                     | _CMU_LFXOCTRL_GAIN_MASK\r
+                     | _CMU_LFXOCTRL_TIMEOUT_MASK,\r
+                     (lfxoInit->ctune << _CMU_LFXOCTRL_TUNING_SHIFT)\r
+                     | (lfxoInit->gain << _CMU_LFXOCTRL_GAIN_SHIFT)\r
+                     | (lfxoInit->timeout << _CMU_LFXOCTRL_TIMEOUT_SHIFT));\r
+}\r
+#endif\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Enable/disable oscillator.\r
+ *\r
+ * @note\r
+ *   WARNING: When this function is called to disable either cmuOsc_LFXO or\r
+ *   cmuOsc_HFXO the LFXOMODE or HFXOMODE fields of the CMU_CTRL register\r
+ *   are reset to the reset value. I.e. if external clock sources are selected\r
+ *   in either LFXOMODE or HFXOMODE fields, the configuration will be cleared\r
+ *   and needs to be reconfigured if needed later.\r
+ *\r
+ * @param[in] osc\r
+ *   The oscillator to enable/disable.\r
+ *\r
+ * @param[in] enable\r
+ *   @li true - enable specified oscillator.\r
+ *   @li false - disable specified oscillator.\r
+ *\r
+ * @param[in] wait\r
+ *   Only used if @p enable is true.\r
+ *   @li true - wait for oscillator start-up time to timeout before returning.\r
+ *   @li false - do not wait for oscillator start-up time to timeout before\r
+ *     returning.\r
+ ******************************************************************************/\r
+void CMU_OscillatorEnable(CMU_Osc_TypeDef osc, bool enable, bool wait)\r
+{\r
+  uint32_t rdyBitPos;\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+  uint32_t ensBitPos;\r
+#endif\r
+  uint32_t enBit;\r
+  uint32_t disBit;\r
+\r
+  switch (osc)\r
+  {\r
+    case cmuOsc_HFRCO:\r
+      enBit  = CMU_OSCENCMD_HFRCOEN;\r
+      disBit = CMU_OSCENCMD_HFRCODIS;\r
+      rdyBitPos = _CMU_STATUS_HFRCORDY_SHIFT;\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+      ensBitPos = _CMU_STATUS_HFRCOENS_SHIFT;\r
+#endif\r
+      break;\r
+\r
+    case cmuOsc_HFXO:\r
+      enBit  = CMU_OSCENCMD_HFXOEN;\r
+      disBit = CMU_OSCENCMD_HFXODIS;\r
+      rdyBitPos = _CMU_STATUS_HFXORDY_SHIFT;\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+      ensBitPos = _CMU_STATUS_HFXOENS_SHIFT;\r
+#endif\r
+      break;\r
+\r
+    case cmuOsc_AUXHFRCO:\r
+      enBit  = CMU_OSCENCMD_AUXHFRCOEN;\r
+      disBit = CMU_OSCENCMD_AUXHFRCODIS;\r
+      rdyBitPos = _CMU_STATUS_AUXHFRCORDY_SHIFT;\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+      ensBitPos = _CMU_STATUS_AUXHFRCOENS_SHIFT;\r
+#endif\r
+      break;\r
+\r
+    case cmuOsc_LFRCO:\r
+      enBit  = CMU_OSCENCMD_LFRCOEN;\r
+      disBit = CMU_OSCENCMD_LFRCODIS;\r
+      rdyBitPos = _CMU_STATUS_LFRCORDY_SHIFT;\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+      ensBitPos = _CMU_STATUS_LFRCOENS_SHIFT;\r
+#endif\r
+      break;\r
+\r
+    case cmuOsc_LFXO:\r
+      enBit  = CMU_OSCENCMD_LFXOEN;\r
+      disBit = CMU_OSCENCMD_LFXODIS;\r
+      rdyBitPos = _CMU_STATUS_LFXORDY_SHIFT;\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+      ensBitPos = _CMU_STATUS_LFXOENS_SHIFT;\r
+#endif\r
+      break;\r
+\r
+#if defined( _CMU_STATUS_USHFRCOENS_MASK )\r
+    case cmuOsc_USHFRCO:\r
+      enBit  = CMU_OSCENCMD_USHFRCOEN;\r
+      disBit = CMU_OSCENCMD_USHFRCODIS;\r
+      rdyBitPos = _CMU_STATUS_USHFRCORDY_SHIFT;\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+      ensBitPos = _CMU_STATUS_USHFRCOENS_SHIFT;\r
+#endif\r
+      break;\r
+#endif\r
+\r
+#if defined( CMU_LFCLKSEL_LFAE_ULFRCO )\r
+    case cmuOsc_ULFRCO:\r
+      /* ULFRCO is always enabled, and cannot be turned off */\r
+      return;\r
+#endif\r
+\r
+    default:\r
+      /* Undefined clock source */\r
+      EFM_ASSERT(0);\r
+      return;\r
+  }\r
+\r
+  if (enable)\r
+  {\r
+    CMU->OSCENCMD = enBit;\r
+\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+    /* Always wait for ENS to go high */\r
+    while (!BUS_RegBitRead(&CMU->STATUS, ensBitPos))\r
+    {\r
+    }\r
+#endif\r
+\r
+    /* Wait for clock to become ready after enable */\r
+    if (wait)\r
+    {\r
+      while (!BUS_RegBitRead(&CMU->STATUS, rdyBitPos));\r
+#if defined( _CMU_STATUS_HFXOSHUNTOPTRDY_MASK )\r
+      /* Wait for shunt current optimization to complete */\r
+      if ((osc == cmuOsc_HFXO)\r
+          && (BUS_RegMaskedRead(&CMU->HFXOCTRL,\r
+                                _CMU_HFXOCTRL_PEAKDETSHUNTOPTMODE_MASK)\r
+              == CMU_HFXOCTRL_PEAKDETSHUNTOPTMODE_AUTOCMD))\r
+      {\r
+        while (!BUS_RegBitRead(&CMU->STATUS, _CMU_STATUS_HFXOSHUNTOPTRDY_SHIFT))\r
+        {\r
+        }\r
+        /* Assert on failed peak detection. Incorrect HFXO initialization parameters\r
+           caused startup to fail. Please review parameters. */\r
+        EFM_ASSERT(BUS_RegBitRead(&CMU->STATUS, _CMU_STATUS_HFXOPEAKDETRDY_SHIFT));\r
+      }\r
+#endif\r
+    }\r
+  }\r
+  else\r
+  {\r
+    CMU->OSCENCMD = disBit;\r
+\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+    /* Always wait for ENS to go low */\r
+    while (BUS_RegBitRead(&CMU->STATUS, ensBitPos))\r
+    {\r
+    }\r
+#endif\r
+  }\r
+\r
+  /* Keep EMU module informed */\r
+  EMU_UpdateOscConfig();\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Get oscillator frequency tuning setting.\r
+ *\r
+ * @param[in] osc\r
+ *   Oscillator to get tuning value for, one of:\r
+ *   @li #cmuOsc_LFRCO\r
+ *   @li #cmuOsc_HFRCO\r
+ *   @li #cmuOsc_AUXHFRCO\r
+ *\r
+ * @return\r
+ *   The oscillator frequency tuning setting in use.\r
+ ******************************************************************************/\r
+uint32_t CMU_OscillatorTuningGet(CMU_Osc_TypeDef osc)\r
+{\r
+  uint32_t ret;\r
+\r
+  switch (osc)\r
+  {\r
+    case cmuOsc_LFRCO:\r
+      ret = (CMU->LFRCOCTRL & _CMU_LFRCOCTRL_TUNING_MASK)\r
+            >> _CMU_LFRCOCTRL_TUNING_SHIFT;\r
+      break;\r
+\r
+    case cmuOsc_HFRCO:\r
+      ret = (CMU->HFRCOCTRL & _CMU_HFRCOCTRL_TUNING_MASK)\r
+            >> _CMU_HFRCOCTRL_TUNING_SHIFT;\r
+      break;\r
+\r
+    case cmuOsc_AUXHFRCO:\r
+      ret = (CMU->AUXHFRCOCTRL & _CMU_AUXHFRCOCTRL_TUNING_MASK)\r
+            >> _CMU_AUXHFRCOCTRL_TUNING_SHIFT;\r
+      break;\r
+\r
+    default:\r
+      EFM_ASSERT(0);\r
+      ret = 0;\r
+      break;\r
+  }\r
+\r
+  return ret;\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Set the oscillator frequency tuning control.\r
+ *\r
+ * @note\r
+ *   Oscillator tuning is done during production, and the tuning value is\r
+ *   automatically loaded after a reset. Changing the tuning value from the\r
+ *   calibrated value is for more advanced use.\r
+ *\r
+ * @param[in] osc\r
+ *   Oscillator to set tuning value for, one of:\r
+ *   @li #cmuOsc_LFRCO\r
+ *   @li #cmuOsc_HFRCO\r
+ *   @li #cmuOsc_AUXHFRCO\r
+ *\r
+ * @param[in] val\r
+ *   The oscillator frequency tuning setting to use.\r
+ ******************************************************************************/\r
+void CMU_OscillatorTuningSet(CMU_Osc_TypeDef osc, uint32_t val)\r
+{\r
+  switch (osc)\r
+  {\r
+    case cmuOsc_LFRCO:\r
+      EFM_ASSERT(val <= (_CMU_LFRCOCTRL_TUNING_MASK\r
+                         >> _CMU_LFRCOCTRL_TUNING_SHIFT));\r
+      val &= (_CMU_LFRCOCTRL_TUNING_MASK >> _CMU_LFRCOCTRL_TUNING_SHIFT);\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+      while(BUS_RegBitRead(&CMU->SYNCBUSY, _CMU_SYNCBUSY_LFRCOBSY_SHIFT));\r
+#endif\r
+      CMU->LFRCOCTRL = (CMU->LFRCOCTRL & ~(_CMU_LFRCOCTRL_TUNING_MASK))\r
+                       | (val << _CMU_LFRCOCTRL_TUNING_SHIFT);\r
+      break;\r
+\r
+    case cmuOsc_HFRCO:\r
+      EFM_ASSERT(val <= (_CMU_HFRCOCTRL_TUNING_MASK\r
+                         >> _CMU_HFRCOCTRL_TUNING_SHIFT));\r
+      val &= (_CMU_HFRCOCTRL_TUNING_MASK >> _CMU_HFRCOCTRL_TUNING_SHIFT);\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+      while(BUS_RegBitRead(&CMU->SYNCBUSY, _CMU_SYNCBUSY_HFRCOBSY_SHIFT))\r
+      {\r
+      }\r
+#endif\r
+      CMU->HFRCOCTRL = (CMU->HFRCOCTRL & ~(_CMU_HFRCOCTRL_TUNING_MASK))\r
+                       | (val << _CMU_HFRCOCTRL_TUNING_SHIFT);\r
+      break;\r
+\r
+    case cmuOsc_AUXHFRCO:\r
+      EFM_ASSERT(val <= (_CMU_AUXHFRCOCTRL_TUNING_MASK\r
+                         >> _CMU_AUXHFRCOCTRL_TUNING_SHIFT));\r
+      val &= (_CMU_AUXHFRCOCTRL_TUNING_MASK >> _CMU_AUXHFRCOCTRL_TUNING_SHIFT);\r
+#if defined( _SILICON_LABS_32B_PLATFORM_2 )\r
+      while(BUS_RegBitRead(&CMU->SYNCBUSY, _CMU_SYNCBUSY_AUXHFRCOBSY_SHIFT))\r
+      {\r
+      }\r
+#endif\r
+      CMU->AUXHFRCOCTRL = (CMU->AUXHFRCOCTRL & ~(_CMU_AUXHFRCOCTRL_TUNING_MASK))\r
+                          | (val << _CMU_AUXHFRCOCTRL_TUNING_SHIFT);\r
+      break;\r
+\r
+    default:\r
+      EFM_ASSERT(0);\r
+      break;\r
+  }\r
+}\r
+\r
+\r
+/**************************************************************************//**\r
+ * @brief\r
+ *   Determine if currently selected PCNTn clock used is external or LFBCLK.\r
+ *\r
+ * @param[in] instance\r
+ *   PCNT instance number to get currently selected clock source for.\r
+ *\r
+ * @return\r
+ *   @li true - selected clock is external clock.\r
+ *   @li false - selected clock is LFBCLK.\r
+ *****************************************************************************/\r
+bool CMU_PCNTClockExternalGet(unsigned int instance)\r
+{\r
+  uint32_t setting;\r
+\r
+  switch (instance)\r
+  {\r
+#if defined( _CMU_PCNTCTRL_PCNT0CLKEN_MASK )\r
+    case 0:\r
+      setting = CMU->PCNTCTRL & CMU_PCNTCTRL_PCNT0CLKSEL_PCNT0S0;\r
+      break;\r
+\r
+#if defined( _CMU_PCNTCTRL_PCNT1CLKEN_MASK )\r
+    case 1:\r
+      setting = CMU->PCNTCTRL & CMU_PCNTCTRL_PCNT1CLKSEL_PCNT1S0;\r
+      break;\r
+\r
+#if defined( _CMU_PCNTCTRL_PCNT2CLKEN_MASK )\r
+    case 2:\r
+      setting = CMU->PCNTCTRL & CMU_PCNTCTRL_PCNT2CLKSEL_PCNT2S0;\r
+      break;\r
+#endif\r
+#endif\r
+#endif\r
+\r
+    default:\r
+      setting = 0;\r
+      break;\r
+  }\r
+  return (setting ? true : false);\r
+}\r
+\r
+\r
+/**************************************************************************//**\r
+ * @brief\r
+ *   Select PCNTn clock.\r
+ *\r
+ * @param[in] instance\r
+ *   PCNT instance number to set selected clock source for.\r
+ *\r
+ * @param[in] external\r
+ *   Set to true to select external clock, false to select LFBCLK.\r
+ *****************************************************************************/\r
+void CMU_PCNTClockExternalSet(unsigned int instance, bool external)\r
+{\r
+#if defined( PCNT_PRESENT )\r
+  uint32_t setting = 0;\r
+\r
+  EFM_ASSERT(instance < PCNT_COUNT);\r
+\r
+  if (external)\r
+  {\r
+    setting = 1;\r
+  }\r
+\r
+  BUS_RegBitWrite(&(CMU->PCNTCTRL), (instance * 2) + 1, setting);\r
+\r
+#else\r
+  (void)instance;  /* Unused parameter */\r
+  (void)external;  /* Unused parameter */\r
+#endif\r
+}\r
+\r
+\r
+#if defined( _CMU_USHFRCOCONF_BAND_MASK )\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Get USHFRCO band in use.\r
+ *\r
+ * @return\r
+ *   USHFRCO band in use.\r
+ ******************************************************************************/\r
+CMU_USHFRCOBand_TypeDef CMU_USHFRCOBandGet(void)\r
+{\r
+  return (CMU_USHFRCOBand_TypeDef)((CMU->USHFRCOCONF\r
+                                    & _CMU_USHFRCOCONF_BAND_MASK)\r
+                                   >> _CMU_USHFRCOCONF_BAND_SHIFT);\r
+}\r
+#endif\r
+\r
+#if defined( _CMU_USHFRCOCONF_BAND_MASK )\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Set USHFRCO band to use.\r
+ *\r
+ * @param[in] band\r
+ *   USHFRCO band to activate.\r
+ ******************************************************************************/\r
+void CMU_USHFRCOBandSet(CMU_USHFRCOBand_TypeDef band)\r
+{\r
+  uint32_t           tuning;\r
+  uint32_t           fineTuning;\r
+  CMU_Select_TypeDef osc;\r
+\r
+  /* Cannot switch band if USHFRCO is already selected as HF clock. */\r
+  osc = CMU_ClockSelectGet(cmuClock_HF);\r
+  EFM_ASSERT((CMU_USHFRCOBandGet() != band) && (osc != cmuSelect_USHFRCO));\r
+\r
+  /* Read tuning value from calibration table */\r
+  switch (band)\r
+  {\r
+    case cmuUSHFRCOBand_24MHz:\r
+      tuning = (DEVINFO->USHFRCOCAL0 & _DEVINFO_USHFRCOCAL0_BAND24_TUNING_MASK)\r
+               >> _DEVINFO_USHFRCOCAL0_BAND24_TUNING_SHIFT;\r
+      fineTuning = (DEVINFO->USHFRCOCAL0\r
+                    & _DEVINFO_USHFRCOCAL0_BAND24_FINETUNING_MASK)\r
+                   >> _DEVINFO_USHFRCOCAL0_BAND24_FINETUNING_SHIFT;\r
+      break;\r
+\r
+    case cmuUSHFRCOBand_48MHz:\r
+      tuning = (DEVINFO->USHFRCOCAL0 & _DEVINFO_USHFRCOCAL0_BAND48_TUNING_MASK)\r
+               >> _DEVINFO_USHFRCOCAL0_BAND48_TUNING_SHIFT;\r
+      fineTuning = (DEVINFO->USHFRCOCAL0\r
+                    & _DEVINFO_USHFRCOCAL0_BAND48_FINETUNING_MASK)\r
+                   >> _DEVINFO_USHFRCOCAL0_BAND48_FINETUNING_SHIFT;\r
+      /* Enable the clock divider before switching the band from 24 to 48MHz */\r
+      BUS_RegBitWrite(&CMU->USHFRCOCONF, _CMU_USHFRCOCONF_USHFRCODIV2DIS_SHIFT, 0);\r
+      break;\r
+\r
+    default:\r
+      EFM_ASSERT(0);\r
+      return;\r
+  }\r
+\r
+  /* Set band and tuning */\r
+  CMU->USHFRCOCONF = (CMU->USHFRCOCONF & ~_CMU_USHFRCOCONF_BAND_MASK)\r
+                     | (band << _CMU_USHFRCOCONF_BAND_SHIFT);\r
+  CMU->USHFRCOCTRL = (CMU->USHFRCOCTRL & ~_CMU_USHFRCOCTRL_TUNING_MASK)\r
+                     | (tuning << _CMU_USHFRCOCTRL_TUNING_SHIFT);\r
+  CMU->USHFRCOTUNE = (CMU->USHFRCOTUNE & ~_CMU_USHFRCOTUNE_FINETUNING_MASK)\r
+                     | (fineTuning << _CMU_USHFRCOTUNE_FINETUNING_SHIFT);\r
+\r
+  /* Disable the clock divider after switching the band from 48 to 24MHz */\r
+  if (band == cmuUSHFRCOBand_24MHz)\r
+  {\r
+    BUS_RegBitWrite(&CMU->USHFRCOCONF, _CMU_USHFRCOCONF_USHFRCODIV2DIS_SHIFT, 1);\r
+  }\r
+}\r
+#endif\r
+\r
+\r
+\r
+/** @} (end addtogroup CMU) */\r
+/** @} (end addtogroup EM_Library) */\r
+#endif /* __EM_CMU_H */\r
diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/emlib/em_emu.c b/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/emlib/em_emu.c
new file mode 100644 (file)
index 0000000..2548900
--- /dev/null
@@ -0,0 +1,1805 @@
+/***************************************************************************//**\r
+ * @file em_emu.c\r
+ * @brief Energy Management Unit (EMU) Peripheral API\r
+ * @version 4.2.1\r
+ *******************************************************************************\r
+ * @section License\r
+ * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>\r
+ *******************************************************************************\r
+ *\r
+ * Permission is granted to anyone to use this software for any purpose,\r
+ * including commercial applications, and to alter it and redistribute it\r
+ * freely, subject to the following restrictions:\r
+ *\r
+ * 1. The origin of this software must not be misrepresented; you must not\r
+ *    claim that you wrote the original software.\r
+ * 2. Altered source versions must be plainly marked as such, and must not be\r
+ *    misrepresented as being the original software.\r
+ * 3. This notice may not be removed or altered from any source distribution.\r
+ *\r
+ * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no\r
+ * obligation to support this Software. Silicon Labs is providing the\r
+ * Software "AS IS", with no express or implied warranties of any kind,\r
+ * including, but not limited to, any implied warranties of merchantability\r
+ * or fitness for any particular purpose or warranties against infringement\r
+ * of any proprietary rights of a third party.\r
+ *\r
+ * Silicon Labs will not be liable for any consequential, incidental, or\r
+ * special damages, or any other relief, or for any claim by any third party,\r
+ * arising from your use of this Software.\r
+ *\r
+ ******************************************************************************/\r
+\r
+#include <limits.h>\r
+\r
+#include "em_emu.h"\r
+#if defined( EMU_PRESENT ) && ( EMU_COUNT > 0 )\r
+\r
+#include "em_cmu.h"\r
+#include "em_system.h"\r
+#include "em_assert.h"\r
+\r
+/***************************************************************************//**\r
+ * @addtogroup EM_Library\r
+ * @{\r
+ ******************************************************************************/\r
+\r
+/***************************************************************************//**\r
+ * @addtogroup EMU\r
+ * @brief Energy Management Unit (EMU) Peripheral API\r
+ * @{\r
+ ******************************************************************************/\r
+\r
+/* Consistency check, since restoring assumes similar bitpositions in */\r
+/* CMU OSCENCMD and STATUS regs */\r
+#if (CMU_STATUS_AUXHFRCOENS != CMU_OSCENCMD_AUXHFRCOEN)\r
+#error Conflict in AUXHFRCOENS and AUXHFRCOEN bitpositions\r
+#endif\r
+#if (CMU_STATUS_HFXOENS != CMU_OSCENCMD_HFXOEN)\r
+#error Conflict in HFXOENS and HFXOEN bitpositions\r
+#endif\r
+#if (CMU_STATUS_LFRCOENS != CMU_OSCENCMD_LFRCOEN)\r
+#error Conflict in LFRCOENS and LFRCOEN bitpositions\r
+#endif\r
+#if (CMU_STATUS_LFXOENS != CMU_OSCENCMD_LFXOEN)\r
+#error Conflict in LFXOENS and LFXOEN bitpositions\r
+#endif\r
+\r
+\r
+/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */\r
+/* Fix for errata EMU_E107 - non-WIC interrupt masks. */\r
+#if defined( _EFM32_GECKO_FAMILY )\r
+#define ERRATA_FIX_EMU_E107_EN\r
+#define NON_WIC_INT_MASK_0    (~(0x0dfc0323U))\r
+#define NON_WIC_INT_MASK_1    (~(0x0U))\r
+\r
+#elif defined( _EFM32_TINY_FAMILY )\r
+#define ERRATA_FIX_EMU_E107_EN\r
+#define NON_WIC_INT_MASK_0    (~(0x001be323U))\r
+#define NON_WIC_INT_MASK_1    (~(0x0U))\r
+\r
+#elif defined( _EFM32_GIANT_FAMILY )\r
+#define ERRATA_FIX_EMU_E107_EN\r
+#define NON_WIC_INT_MASK_0    (~(0xff020e63U))\r
+#define NON_WIC_INT_MASK_1    (~(0x00000046U))\r
+\r
+#elif defined( _EFM32_WONDER_FAMILY )\r
+#define ERRATA_FIX_EMU_E107_EN\r
+#define NON_WIC_INT_MASK_0    (~(0xff020e63U))\r
+#define NON_WIC_INT_MASK_1    (~(0x00000046U))\r
+\r
+#else\r
+/* Zero Gecko and future families are not affected by errata EMU_E107 */\r
+#endif\r
+\r
+/* Fix for errata EMU_E108 - High Current Consumption on EM4 Entry. */\r
+#if defined( _EFM32_HAPPY_FAMILY )\r
+#define ERRATA_FIX_EMU_E108_EN\r
+#endif\r
+/** @endcond */\r
+\r
+\r
+#if defined( _EMU_DCDCCTRL_MASK )\r
+/* DCDCTODVDD output range min/max */\r
+#define PWRCFG_DCDCTODVDD_VMIN          1200\r
+#define PWRCFG_DCDCTODVDD_VMAX          3000\r
+typedef enum\r
+{\r
+  errataFixDcdcHsInit,\r
+  errataFixDcdcHsTrimSet,\r
+  errataFixDcdcHsLnWaitDone\r
+} errataFixDcdcHs_TypeDef;\r
+errataFixDcdcHs_TypeDef errataFixDcdcHsState = errataFixDcdcHsInit;\r
+#endif\r
+\r
+/*******************************************************************************\r
+ **************************   LOCAL VARIABLES   ********************************\r
+ ******************************************************************************/\r
+\r
+/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */\r
+/**\r
+ * CMU configured oscillator selection and oscillator enable status. When a\r
+ * user configures oscillators, this varaiable shall shadow the configuration.\r
+ * It is used by the EMU module in order to be able to restore the oscillator\r
+ * config after having been in certain energy modes (since HW may automatically\r
+ * alter config when going into an energy mode). It is the responsibility of\r
+ * the CMU module to keep it up-to-date (or a user if not using the CMU API\r
+ * for oscillator control).\r
+ */\r
+static uint32_t cmuStatus;\r
+#if defined( _CMU_HFCLKSTATUS_RESETVALUE )\r
+static uint16_t cmuHfclkStatus;\r
+#endif\r
+#if defined( _EMU_DCDCCTRL_MASK )\r
+static uint16_t dcdcMaxCurrent_mA;\r
+static uint16_t dcdcOutput_mVout;\r
+#endif\r
+\r
+/** @endcond */\r
+\r
+\r
+/*******************************************************************************\r
+ **************************   LOCAL FUNCTIONS   ********************************\r
+ ******************************************************************************/\r
+\r
+/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Restore oscillators and core clock after having been in EM2 or EM3.\r
+ ******************************************************************************/\r
+static void emuRestore(void)\r
+{\r
+  uint32_t oscEnCmd;\r
+  uint32_t cmuLocked;\r
+\r
+  /* Although we could use the CMU API for most of the below handling, we */\r
+  /* would like this function to be as efficient as possible. */\r
+\r
+  /* CMU registers may be locked */\r
+  cmuLocked = CMU->LOCK & CMU_LOCK_LOCKKEY_LOCKED;\r
+  CMU_Unlock();\r
+\r
+  /* AUXHFRCO are automatically disabled (except if using debugger). */\r
+  /* HFRCO, USHFRCO and HFXO are automatically disabled. */\r
+  /* LFRCO/LFXO may be disabled by SW in EM3. */\r
+  /* Restore according to status prior to entering energy mode. */\r
+  oscEnCmd = 0;\r
+  oscEnCmd |= ((cmuStatus & CMU_STATUS_HFRCOENS)    ? CMU_OSCENCMD_HFRCOEN : 0);\r
+  oscEnCmd |= ((cmuStatus & CMU_STATUS_AUXHFRCOENS) ? CMU_OSCENCMD_AUXHFRCOEN : 0);\r
+  oscEnCmd |= ((cmuStatus & CMU_STATUS_LFRCOENS)    ? CMU_OSCENCMD_LFRCOEN : 0);\r
+  oscEnCmd |= ((cmuStatus & CMU_STATUS_HFXOENS)     ? CMU_OSCENCMD_HFXOEN : 0);\r
+  oscEnCmd |= ((cmuStatus & CMU_STATUS_LFXOENS)     ? CMU_OSCENCMD_LFXOEN : 0);\r
+#if defined( _CMU_STATUS_USHFRCOENS_MASK )\r
+  oscEnCmd |= ((cmuStatus & CMU_STATUS_USHFRCOENS)  ? CMU_OSCENCMD_USHFRCOEN : 0);\r
+#endif\r
+  CMU->OSCENCMD = oscEnCmd;\r
+\r
+\r
+#if defined( _CMU_HFCLKSTATUS_RESETVALUE )\r
+  /* Restore oscillator used for clocking core */\r
+  switch (cmuHfclkStatus & _CMU_HFCLKSTATUS_SELECTED_MASK)\r
+  {\r
+    case CMU_HFCLKSTATUS_SELECTED_LFRCO:\r
+      /* HFRCO could only be selected if the autostart HFXO feature is not\r
+       * enabled, otherwise the HFXO would be started and selected automatically.\r
+       * Note: this error hook helps catching erroneous oscillator configurations,\r
+       * when the AUTOSTARTSELEM0EM1 is set in CMU_HFXOCTRL. */\r
+      if (!(CMU->HFXOCTRL & CMU_HFXOCTRL_AUTOSTARTSELEM0EM1))\r
+      {\r
+        /* Wait for LFRCO to stabilize */\r
+        while (!(CMU->STATUS & CMU_STATUS_LFRCORDY))\r
+          ;\r
+        CMU->HFCLKSEL = CMU_HFCLKSEL_HF_LFRCO;\r
+      }\r
+      else\r
+      {\r
+        EFM_ASSERT(0);\r
+      }\r
+      break;\r
+\r
+    case CMU_HFCLKSTATUS_SELECTED_LFXO:\r
+      /* Wait for LFXO to stabilize */\r
+      while (!(CMU->STATUS & CMU_STATUS_LFXORDY))\r
+        ;\r
+      CMU->HFCLKSEL = CMU_HFCLKSEL_HF_LFXO;\r
+      break;\r
+\r
+    case CMU_HFCLKSTATUS_SELECTED_HFXO:\r
+      /* Wait for HFXO to stabilize */\r
+      while (!(CMU->STATUS & CMU_STATUS_HFXORDY))\r
+        ;\r
+      CMU->HFCLKSEL = CMU_HFCLKSEL_HF_HFXO;\r
+      break;\r
+\r
+    default: /* CMU_HFCLKSTATUS_SELECTED_HFRCO */\r
+      /* If core clock was HFRCO core clock, it is automatically restored to */\r
+      /* state prior to entering energy mode. No need for further action. */\r
+      break;\r
+  }\r
+#else\r
+  switch (cmuStatus & (CMU_STATUS_HFRCOSEL\r
+                      | CMU_STATUS_HFXOSEL\r
+                      | CMU_STATUS_LFRCOSEL\r
+#if defined( CMU_STATUS_USHFRCODIV2SEL )\r
+                      | CMU_STATUS_USHFRCODIV2SEL\r
+#endif\r
+                      | CMU_STATUS_LFXOSEL))\r
+  {\r
+    case CMU_STATUS_LFRCOSEL:\r
+      /* Wait for LFRCO to stabilize */\r
+      while (!(CMU->STATUS & CMU_STATUS_LFRCORDY))\r
+        ;\r
+      CMU->CMD = CMU_CMD_HFCLKSEL_LFRCO;\r
+      break;\r
+\r
+    case CMU_STATUS_LFXOSEL:\r
+      /* Wait for LFXO to stabilize */\r
+      while (!(CMU->STATUS & CMU_STATUS_LFXORDY))\r
+        ;\r
+      CMU->CMD = CMU_CMD_HFCLKSEL_LFXO;\r
+      break;\r
+\r
+    case CMU_STATUS_HFXOSEL:\r
+      /* Wait for HFXO to stabilize */\r
+      while (!(CMU->STATUS & CMU_STATUS_HFXORDY))\r
+        ;\r
+      CMU->CMD = CMU_CMD_HFCLKSEL_HFXO;\r
+      break;\r
+\r
+#if defined( CMU_STATUS_USHFRCODIV2SEL )\r
+    case CMU_STATUS_USHFRCODIV2SEL:\r
+      /* Wait for USHFRCO to stabilize */\r
+      while (!(CMU->STATUS & CMU_STATUS_USHFRCORDY))\r
+        ;\r
+      CMU->CMD = _CMU_CMD_HFCLKSEL_USHFRCODIV2;\r
+      break;\r
+#endif\r
+\r
+    default: /* CMU_STATUS_HFRCOSEL */\r
+      /* If core clock was HFRCO core clock, it is automatically restored to */\r
+      /* state prior to entering energy mode. No need for further action. */\r
+      break;\r
+  }\r
+\r
+  /* If HFRCO was disabled before entering Energy Mode, turn it off again */\r
+  /* as it is automatically enabled by wake up */\r
+  if ( ! (cmuStatus & CMU_STATUS_HFRCOENS) )\r
+  {\r
+    CMU->OSCENCMD = CMU_OSCENCMD_HFRCODIS;\r
+  }\r
+#endif\r
+  /* Restore CMU register locking */\r
+  if (cmuLocked)\r
+  {\r
+    CMU_Lock();\r
+  }\r
+}\r
+\r
+\r
+#if defined( ERRATA_FIX_EMU_E107_EN )\r
+/* Get enable conditions for errata EMU_E107 fix. */\r
+static __INLINE bool getErrataFixEmuE107En(void)\r
+{\r
+  /* SYSTEM_ChipRevisionGet could have been used here, but we would like a\r
+   * faster implementation in this case.\r
+   */\r
+  uint16_t majorMinorRev;\r
+\r
+  /* CHIP MAJOR bit [3:0] */\r
+  majorMinorRev = ((ROMTABLE->PID0 & _ROMTABLE_PID0_REVMAJOR_MASK)\r
+                   >> _ROMTABLE_PID0_REVMAJOR_SHIFT)\r
+                  << 8;\r
+  /* CHIP MINOR bit [7:4] */\r
+  majorMinorRev |= ((ROMTABLE->PID2 & _ROMTABLE_PID2_REVMINORMSB_MASK)\r
+                    >> _ROMTABLE_PID2_REVMINORMSB_SHIFT)\r
+                   << 4;\r
+  /* CHIP MINOR bit [3:0] */\r
+  majorMinorRev |= (ROMTABLE->PID3 & _ROMTABLE_PID3_REVMINORLSB_MASK)\r
+                   >> _ROMTABLE_PID3_REVMINORLSB_SHIFT;\r
+\r
+#if defined( _EFM32_GECKO_FAMILY )\r
+  return (majorMinorRev <= 0x0103);\r
+#elif defined( _EFM32_TINY_FAMILY )\r
+  return (majorMinorRev <= 0x0102);\r
+#elif defined( _EFM32_GIANT_FAMILY )\r
+  return (majorMinorRev <= 0x0103) || (majorMinorRev == 0x0204);\r
+#elif defined( _EFM32_WONDER_FAMILY )\r
+  return (majorMinorRev == 0x0100);\r
+#else\r
+  /* Zero Gecko and future families are not affected by errata EMU_E107 */\r
+  return false;\r
+#endif\r
+}\r
+#endif\r
+\r
+\r
+#if defined( _EMU_DCDCCTRL_MASK )\r
+/* LP prepare / LN restore P/NFET count */\r
+static void maxCurrentUpdate(void);\r
+#define DCDC_LP_PFET_CNT        7\r
+#define DCDC_LP_NFET_CNT        15\r
+void dcdcFetCntSet(bool lpModeSet)\r
+{\r
+  uint32_t tmp;\r
+  static uint32_t emuDcdcMiscCtrlReg;\r
+\r
+  if (lpModeSet)\r
+  {\r
+    emuDcdcMiscCtrlReg = EMU->DCDCMISCCTRL;\r
+    tmp  = EMU->DCDCMISCCTRL\r
+           & ~(_EMU_DCDCMISCCTRL_PFETCNT_MASK | _EMU_DCDCMISCCTRL_NFETCNT_MASK);\r
+    tmp |= (DCDC_LP_PFET_CNT << _EMU_DCDCMISCCTRL_PFETCNT_SHIFT)\r
+            | (DCDC_LP_NFET_CNT << _EMU_DCDCMISCCTRL_NFETCNT_SHIFT);\r
+    EMU->DCDCMISCCTRL = tmp;\r
+    maxCurrentUpdate();\r
+  }\r
+  else\r
+  {\r
+    EMU->DCDCMISCCTRL = emuDcdcMiscCtrlReg;\r
+    maxCurrentUpdate();\r
+  }\r
+}\r
+\r
+void dcdcHsFixLnBlock(void)\r
+{\r
+#define EMU_DCDCSTATUS  (* (volatile uint32_t *)(EMU_BASE + 0x7C))\r
+  if (errataFixDcdcHsState == errataFixDcdcHsTrimSet)\r
+  {\r
+    /* Wait for LNRUNNING */\r
+    if ((EMU->DCDCCTRL & ~_EMU_DCDCCTRL_DCDCMODE_MASK) == EMU_DCDCCTRL_DCDCMODE_LOWNOISE)\r
+    {\r
+      while (!(EMU_DCDCSTATUS & (0x1 << 16)));\r
+    }\r
+    errataFixDcdcHsState = errataFixDcdcHsLnWaitDone;\r
+  }\r
+}\r
+#endif\r
+\r
+\r
+/** @endcond */\r
+\r
+\r
+/*******************************************************************************\r
+ **************************   GLOBAL FUNCTIONS   *******************************\r
+ ******************************************************************************/\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Enter energy mode 2 (EM2).\r
+ *\r
+ * @details\r
+ *   When entering EM2, the high frequency clocks are disabled, ie HFXO, HFRCO\r
+ *   and AUXHFRCO (for AUXHFRCO, see exception note below). When re-entering\r
+ *   EM0, HFRCO is re-enabled and the core will be clocked by the configured\r
+ *   HFRCO band. This ensures a quick wakeup from EM2.\r
+ *\r
+ *   However, prior to entering EM2, the core may have been using another\r
+ *   oscillator than HFRCO. The @p restore parameter gives the user the option\r
+ *   to restore all HF oscillators according to state prior to entering EM2,\r
+ *   as well as the clock used to clock the core. This restore procedure is\r
+ *   handled by SW. However, since handled by SW, it will not be restored\r
+ *   before completing the interrupt function(s) waking up the core!\r
+ *\r
+ * @note\r
+ *   If restoring core clock to use the HFXO oscillator, which has been\r
+ *   disabled during EM2 mode, this function will stall until the oscillator\r
+ *   has stabilized. Stalling time can be reduced by adding interrupt\r
+ *   support detecting stable oscillator, and an asynchronous switch to the\r
+ *   original oscillator. See CMU documentation. Such a feature is however\r
+ *   outside the scope of the implementation in this function.\r
+ * @par\r
+ *   If HFXO is re-enabled by this function, and NOT used to clock the core,\r
+ *   this function will not wait for HFXO to stabilize. This must be considered\r
+ *   by the application if trying to use features relying on that oscillator\r
+ *   upon return.\r
+ * @par\r
+ *   If a debugger is attached, the AUXHFRCO will not be disabled if enabled\r
+ *   upon entering EM2. It will thus remain enabled when returning to EM0\r
+ *   regardless of the @p restore parameter.\r
+ * @par\r
+ *   If HFXO autostart and select is enabled by using CMU_HFXOAutostartEnable(),\r
+ *   the starting and selecting of the core clocks will be identical to the user\r
+ *   independently of the value of the @p restore parameter when waking up on\r
+ *   the wakeup sources corresponding to the autostart and select setting.\r
+ *\r
+ * @param[in] restore\r
+ *   @li true - restore oscillators and clocks, see function details.\r
+ *   @li false - do not restore oscillators and clocks, see function details.\r
+ * @par\r
+ *   The @p restore option should only be used if all clock control is done\r
+ *   via the CMU API.\r
+ ******************************************************************************/\r
+void EMU_EnterEM2(bool restore)\r
+{\r
+#if defined( ERRATA_FIX_EMU_E107_EN )\r
+  bool errataFixEmuE107En;\r
+  uint32_t nonWicIntEn[2];\r
+#endif\r
+\r
+  /* Auto-update CMU status just in case before entering energy mode. */\r
+  /* This variable is normally kept up-to-date by the CMU API. */\r
+  cmuStatus = CMU->STATUS;\r
+#if defined( _CMU_HFCLKSTATUS_RESETVALUE )\r
+  cmuHfclkStatus = (uint16_t)(CMU->HFCLKSTATUS);\r
+#endif\r
+\r
+  /* Enter Cortex deep sleep mode */\r
+  SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;\r
+\r
+  /* Fix for errata EMU_E107 - store non-WIC interrupt enable flags.\r
+     Disable the enabled non-WIC interrupts. */\r
+#if defined( ERRATA_FIX_EMU_E107_EN )\r
+  errataFixEmuE107En = getErrataFixEmuE107En();\r
+  if (errataFixEmuE107En)\r
+  {\r
+    nonWicIntEn[0] = NVIC->ISER[0] & NON_WIC_INT_MASK_0;\r
+    NVIC->ICER[0] = nonWicIntEn[0];\r
+#if (NON_WIC_INT_MASK_1 != (~(0x0U)))\r
+    nonWicIntEn[1] = NVIC->ISER[1] & NON_WIC_INT_MASK_1;\r
+    NVIC->ICER[1] = nonWicIntEn[1];\r
+#endif\r
+  }\r
+#endif\r
+\r
+#if defined( _EMU_DCDCCTRL_MASK )\r
+  dcdcFetCntSet(true);\r
+  dcdcHsFixLnBlock();\r
+#endif\r
+\r
+  __WFI();\r
+\r
+#if defined( _EMU_DCDCCTRL_MASK )\r
+  dcdcFetCntSet(false);\r
+#endif\r
+\r
+  /* Fix for errata EMU_E107 - restore state of non-WIC interrupt enable flags. */\r
+#if defined( ERRATA_FIX_EMU_E107_EN )\r
+  if (errataFixEmuE107En)\r
+  {\r
+    NVIC->ISER[0] = nonWicIntEn[0];\r
+#if (NON_WIC_INT_MASK_1 != (~(0x0U)))\r
+    NVIC->ISER[1] = nonWicIntEn[1];\r
+#endif\r
+  }\r
+#endif\r
+\r
+  /* Restore oscillators/clocks if specified */\r
+  if (restore)\r
+  {\r
+    emuRestore();\r
+  }\r
+  /* If not restoring, and original clock was not HFRCO, we have to */\r
+  /* update CMSIS core clock variable since core clock has changed */\r
+  /* to using HFRCO. */\r
+#if defined( _CMU_HFCLKSTATUS_RESETVALUE )\r
+  else if ((cmuHfclkStatus & _CMU_HFCLKSTATUS_SELECTED_MASK)\r
+           != CMU_HFCLKSTATUS_SELECTED_HFRCO)\r
+#else\r
+  else if (!(cmuStatus & CMU_STATUS_HFRCOSEL))\r
+#endif\r
+  {\r
+    SystemCoreClockUpdate();\r
+  }\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Enter energy mode 3 (EM3).\r
+ *\r
+ * @details\r
+ *   When entering EM3, the high frequency clocks are disabled by HW, ie HFXO,\r
+ *   HFRCO and AUXHFRCO (for AUXHFRCO, see exception note below). In addition,\r
+ *   the low frequency clocks, ie LFXO and LFRCO are disabled by SW. When\r
+ *   re-entering EM0, HFRCO is re-enabled and the core will be clocked by the\r
+ *   configured HFRCO band. This ensures a quick wakeup from EM3.\r
+ *\r
+ *   However, prior to entering EM3, the core may have been using another\r
+ *   oscillator than HFRCO. The @p restore parameter gives the user the option\r
+ *   to restore all HF/LF oscillators according to state prior to entering EM3,\r
+ *   as well as the clock used to clock the core. This restore procedure is\r
+ *   handled by SW. However, since handled by SW, it will not be restored\r
+ *   before completing the interrupt function(s) waking up the core!\r
+ *\r
+ * @note\r
+ *   If restoring core clock to use an oscillator other than HFRCO, this\r
+ *   function will stall until the oscillator has stabilized. Stalling time\r
+ *   can be reduced by adding interrupt support detecting stable oscillator,\r
+ *   and an asynchronous switch to the original oscillator. See CMU\r
+ *   documentation. Such a feature is however outside the scope of the\r
+ *   implementation in this function.\r
+ * @par\r
+ *   If HFXO/LFXO/LFRCO are re-enabled by this function, and NOT used to clock\r
+ *   the core, this function will not wait for those oscillators to stabilize.\r
+ *   This must be considered by the application if trying to use features\r
+ *   relying on those oscillators upon return.\r
+ * @par\r
+ *   If a debugger is attached, the AUXHFRCO will not be disabled if enabled\r
+ *   upon entering EM3. It will thus remain enabled when returning to EM0\r
+ *   regardless of the @p restore parameter.\r
+ *\r
+ * @param[in] restore\r
+ *   @li true - restore oscillators and clocks, see function details.\r
+ *   @li false - do not restore oscillators and clocks, see function details.\r
+ * @par\r
+ *   The @p restore option should only be used if all clock control is done\r
+ *   via the CMU API.\r
+ ******************************************************************************/\r
+void EMU_EnterEM3(bool restore)\r
+{\r
+  uint32_t cmuLocked;\r
+\r
+#if defined( ERRATA_FIX_EMU_E107_EN )\r
+  bool errataFixEmuE107En;\r
+  uint32_t nonWicIntEn[2];\r
+#endif\r
+\r
+  /* Auto-update CMU status just in case before entering energy mode. */\r
+  /* This variable is normally kept up-to-date by the CMU API. */\r
+  cmuStatus = CMU->STATUS;\r
+#if defined( _CMU_HFCLKSTATUS_RESETVALUE )\r
+  cmuHfclkStatus = (uint16_t)(CMU->HFCLKSTATUS);\r
+#endif\r
+\r
+  /* CMU registers may be locked */\r
+  cmuLocked = CMU->LOCK & CMU_LOCK_LOCKKEY_LOCKED;\r
+  CMU_Unlock();\r
+\r
+  /* Disable LF oscillators */\r
+  CMU->OSCENCMD = CMU_OSCENCMD_LFXODIS | CMU_OSCENCMD_LFRCODIS;\r
+\r
+  /* Restore CMU register locking */\r
+  if (cmuLocked)\r
+  {\r
+    CMU_Lock();\r
+  }\r
+\r
+  /* Enter Cortex deep sleep mode */\r
+  SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;\r
+\r
+  /* Fix for errata EMU_E107 - store non-WIC interrupt enable flags.\r
+     Disable the enabled non-WIC interrupts. */\r
+#if defined( ERRATA_FIX_EMU_E107_EN )\r
+  errataFixEmuE107En = getErrataFixEmuE107En();\r
+  if (errataFixEmuE107En)\r
+  {\r
+    nonWicIntEn[0] = NVIC->ISER[0] & NON_WIC_INT_MASK_0;\r
+    NVIC->ICER[0] = nonWicIntEn[0];\r
+#if (NON_WIC_INT_MASK_1 != (~(0x0U)))\r
+    nonWicIntEn[1] = NVIC->ISER[1] & NON_WIC_INT_MASK_1;\r
+    NVIC->ICER[1] = nonWicIntEn[1];\r
+#endif\r
+\r
+  }\r
+#endif\r
+\r
+#if defined( _EMU_DCDCCTRL_MASK )\r
+  dcdcFetCntSet(true);\r
+  dcdcHsFixLnBlock();\r
+#endif\r
+\r
+  __WFI();\r
+\r
+#if defined( _EMU_DCDCCTRL_MASK )\r
+  dcdcFetCntSet(false);\r
+#endif\r
+\r
+  /* Fix for errata EMU_E107 - restore state of non-WIC interrupt enable flags. */\r
+#if defined( ERRATA_FIX_EMU_E107_EN )\r
+  if (errataFixEmuE107En)\r
+  {\r
+    NVIC->ISER[0] = nonWicIntEn[0];\r
+#if (NON_WIC_INT_MASK_1 != (~(0x0U)))\r
+    NVIC->ISER[1] = nonWicIntEn[1];\r
+#endif\r
+  }\r
+#endif\r
+\r
+  /* Restore oscillators/clocks if specified */\r
+  if (restore)\r
+  {\r
+    emuRestore();\r
+  }\r
+  /* If not restoring, and original clock was not HFRCO, we have to */\r
+  /* update CMSIS core clock variable since core clock has changed */\r
+  /* to using HFRCO. */\r
+#if defined( _CMU_HFCLKSTATUS_RESETVALUE )\r
+  else if ((cmuHfclkStatus & _CMU_HFCLKSTATUS_SELECTED_MASK)\r
+           != CMU_HFCLKSTATUS_SELECTED_HFRCO)\r
+#else\r
+  else if (!(cmuStatus & CMU_STATUS_HFRCOSEL))\r
+#endif\r
+  {\r
+    SystemCoreClockUpdate();\r
+  }\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Enter energy mode 4 (EM4).\r
+ *\r
+ * @note\r
+ *   Only a power on reset or external reset pin can wake the device from EM4.\r
+ ******************************************************************************/\r
+void EMU_EnterEM4(void)\r
+{\r
+  int i;\r
+\r
+#if defined( _EMU_EM4CTRL_EM4ENTRY_SHIFT )\r
+  uint32_t em4seq2 = (EMU->EM4CTRL & ~_EMU_EM4CTRL_EM4ENTRY_MASK)\r
+                     | (2 << _EMU_EM4CTRL_EM4ENTRY_SHIFT);\r
+  uint32_t em4seq3 = (EMU->EM4CTRL & ~_EMU_EM4CTRL_EM4ENTRY_MASK)\r
+                     | (3 << _EMU_EM4CTRL_EM4ENTRY_SHIFT);\r
+#else\r
+  uint32_t em4seq2 = (EMU->CTRL & ~_EMU_CTRL_EM4CTRL_MASK)\r
+                     | (2 << _EMU_CTRL_EM4CTRL_SHIFT);\r
+  uint32_t em4seq3 = (EMU->CTRL & ~_EMU_CTRL_EM4CTRL_MASK)\r
+                     | (3 << _EMU_CTRL_EM4CTRL_SHIFT);\r
+#endif\r
+\r
+  /* Make sure register write lock is disabled */\r
+  EMU_Unlock();\r
+\r
+#if defined( ERRATA_FIX_EMU_E108_EN )\r
+  /* Fix for errata EMU_E108 - High Current Consumption on EM4 Entry. */\r
+  __disable_irq();\r
+  *(volatile uint32_t *)0x400C80E4 = 0;\r
+#endif\r
+\r
+#if defined( _EMU_DCDCCTRL_MASK )\r
+  dcdcFetCntSet(true);\r
+  dcdcHsFixLnBlock();\r
+#endif\r
+\r
+  for (i = 0; i < 4; i++)\r
+  {\r
+#if defined( _EMU_EM4CTRL_EM4ENTRY_SHIFT )\r
+    EMU->EM4CTRL = em4seq2;\r
+    EMU->EM4CTRL = em4seq3;\r
+  }\r
+  EMU->EM4CTRL = em4seq2;\r
+#else\r
+    EMU->CTRL = em4seq2;\r
+    EMU->CTRL = em4seq3;\r
+  }\r
+  EMU->CTRL = em4seq2;\r
+#endif\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Power down memory block.\r
+ *\r
+ * @param[in] blocks\r
+ *   Specifies a logical OR of bits indicating memory blocks to power down.\r
+ *   Bit 0 selects block 1, bit 1 selects block 2, etc. Memory block 0 cannot\r
+ *   be disabled. Please refer to the reference manual for available\r
+ *   memory blocks for a device.\r
+ *\r
+ * @note\r
+ *   Only a reset can make the specified memory block(s) available for use\r
+ *   after having been powered down. Function will be void for devices not\r
+ *   supporting this feature.\r
+ ******************************************************************************/\r
+void EMU_MemPwrDown(uint32_t blocks)\r
+{\r
+#if defined( _EMU_MEMCTRL_POWERDOWN_MASK )\r
+  EFM_ASSERT(blocks <= (_EMU_MEMCTRL_POWERDOWN_MASK\r
+                        >> _EMU_MEMCTRL_POWERDOWN_SHIFT));\r
+  EMU->MEMCTRL = blocks;\r
+\r
+#elif defined( _EMU_MEMCTRL_RAMPOWERDOWN_MASK )       \\r
+      && defined( _EMU_MEMCTRL_RAMHPOWERDOWN_MASK )   \\r
+      && defined( _EMU_MEMCTRL_SEQRAMPOWERDOWN_MASK )\r
+  EFM_ASSERT((blocks & (_EMU_MEMCTRL_RAMPOWERDOWN_MASK\r
+                        | _EMU_MEMCTRL_RAMHPOWERDOWN_MASK\r
+                        | _EMU_MEMCTRL_SEQRAMPOWERDOWN_MASK))\r
+             == blocks);\r
+  EMU->MEMCTRL = blocks;\r
+\r
+#elif defined( _EMU_MEMCTRL_RAMPOWERDOWN_MASK )\r
+  EFM_ASSERT((blocks & _EMU_MEMCTRL_RAMPOWERDOWN_MASK) == blocks);\r
+  EMU->MEMCTRL = blocks;\r
+\r
+#elif defined( _EMU_RAM0CTRL_RAMPOWERDOWN_MASK )\r
+  EFM_ASSERT((blocks & _EMU_RAM0CTRL_RAMPOWERDOWN_MASK) == blocks);\r
+  EMU->RAM0CTRL = blocks;\r
+\r
+#else\r
+  (void)blocks;\r
+#endif\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Update EMU module with CMU oscillator selection/enable status.\r
+ *\r
+ * @details\r
+ *   When entering EM2 and EM3, the HW may change the core clock oscillator\r
+ *   used, as well as disabling some oscillators. The user may optionally select\r
+ *   to restore the oscillators after waking up from EM2 and EM3 through the\r
+ *   SW API.\r
+ *\r
+ *   However, in order to support this in a safe way, the EMU module must\r
+ *   be kept up-to-date on the actual selected configuration. The CMU\r
+ *   module must keep the EMU module up-to-date.\r
+ *\r
+ *   This function is mainly intended for internal use by the CMU module,\r
+ *   but if the applications changes oscillator configurations without\r
+ *   using the CMU API, this function can be used to keep the EMU module\r
+ *   up-to-date.\r
+ ******************************************************************************/\r
+void EMU_UpdateOscConfig(void)\r
+{\r
+  /* Fetch current configuration */\r
+  cmuStatus = CMU->STATUS;\r
+#if defined( _CMU_HFCLKSTATUS_RESETVALUE )\r
+  cmuHfclkStatus = (uint16_t)(CMU->HFCLKSTATUS);\r
+#endif\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Update EMU module with Energy Mode 2 and 3 configuration\r
+ *\r
+ * @param[in] em23Init\r
+ *    Energy Mode 2 and 3 configuration structure\r
+ ******************************************************************************/\r
+void EMU_EM23Init(EMU_EM23Init_TypeDef *em23Init)\r
+{\r
+#if defined( _EMU_CTRL_EMVREG_MASK )\r
+  EMU->CTRL = em23Init->em23VregFullEn ? (EMU->CTRL | EMU_CTRL_EMVREG)\r
+                                         : (EMU->CTRL & ~EMU_CTRL_EMVREG);\r
+#elif defined( _EMU_CTRL_EM23VREG_MASK )\r
+  EMU->CTRL = em23Init->em23VregFullEn ? (EMU->CTRL | EMU_CTRL_EM23VREG)\r
+                                         : (EMU->CTRL & ~EMU_CTRL_EM23VREG);\r
+#else\r
+  (void)em23Init;\r
+#endif\r
+}\r
+\r
+\r
+#if defined( _EMU_EM4CONF_MASK ) || defined( _EMU_EM4CTRL_MASK )\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Update EMU module with Energy Mode 4 configuration\r
+ *\r
+ * @param[in] em4Init\r
+ *    Energy Mode 4 configuration structure\r
+ ******************************************************************************/\r
+void EMU_EM4Init(EMU_EM4Init_TypeDef *em4Init)\r
+{\r
+#if defined( _EMU_EM4CONF_MASK )\r
+  /* Init for platforms with EMU->EM4CONF register */\r
+  uint32_t em4conf = EMU->EM4CONF;\r
+\r
+  /* Clear fields that will be reconfigured */\r
+  em4conf &= ~(_EMU_EM4CONF_LOCKCONF_MASK\r
+               | _EMU_EM4CONF_OSC_MASK\r
+               | _EMU_EM4CONF_BURTCWU_MASK\r
+               | _EMU_EM4CONF_VREGEN_MASK);\r
+\r
+  /* Configure new settings */\r
+  em4conf |= (em4Init->lockConfig << _EMU_EM4CONF_LOCKCONF_SHIFT)\r
+             | (em4Init->osc)\r
+             | (em4Init->buRtcWakeup << _EMU_EM4CONF_BURTCWU_SHIFT)\r
+             | (em4Init->vreg << _EMU_EM4CONF_VREGEN_SHIFT);\r
+\r
+  /* Apply configuration. Note that lock can be set after this stage. */\r
+  EMU->EM4CONF = em4conf;\r
+\r
+#elif defined( _EMU_EM4CTRL_MASK )\r
+  /* Init for platforms with EMU->EM4CTRL register */\r
+\r
+  uint32_t em4ctrl = EMU->EM4CTRL;\r
+\r
+  em4ctrl &= ~(_EMU_EM4CTRL_RETAINLFXO_MASK\r
+               | _EMU_EM4CTRL_RETAINLFRCO_MASK\r
+               | _EMU_EM4CTRL_RETAINULFRCO_MASK\r
+               | _EMU_EM4CTRL_EM4STATE_MASK\r
+               | _EMU_EM4CTRL_EM4IORETMODE_MASK);\r
+\r
+     em4ctrl |= (em4Init->retainLfxo     ? EMU_EM4CTRL_RETAINLFXO : 0)\r
+                | (em4Init->retainLfrco  ? EMU_EM4CTRL_RETAINLFRCO : 0)\r
+                | (em4Init->retainUlfrco ? EMU_EM4CTRL_RETAINULFRCO : 0)\r
+                | (em4Init->em4State     ? EMU_EM4CTRL_EM4STATE_EM4H : 0)\r
+                | (em4Init->pinRetentionMode);\r
+\r
+  EMU->EM4CTRL = em4ctrl;\r
+#endif\r
+}\r
+#endif\r
+\r
+\r
+#if defined( BU_PRESENT )\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Configure Backup Power Domain settings\r
+ *\r
+ * @param[in] bupdInit\r
+ *   Backup power domain initialization structure\r
+ ******************************************************************************/\r
+void EMU_BUPDInit(EMU_BUPDInit_TypeDef *bupdInit)\r
+{\r
+  uint32_t reg;\r
+\r
+  /* Set power connection configuration */\r
+  reg = EMU->PWRCONF & ~(_EMU_PWRCONF_PWRRES_MASK\r
+                         | _EMU_PWRCONF_VOUTSTRONG_MASK\r
+                         | _EMU_PWRCONF_VOUTMED_MASK\r
+                         | _EMU_PWRCONF_VOUTWEAK_MASK);\r
+\r
+  reg |= bupdInit->resistor\r
+         | (bupdInit->voutStrong << _EMU_PWRCONF_VOUTSTRONG_SHIFT)\r
+         | (bupdInit->voutMed    << _EMU_PWRCONF_VOUTMED_SHIFT)\r
+         | (bupdInit->voutWeak   << _EMU_PWRCONF_VOUTWEAK_SHIFT);\r
+\r
+  EMU->PWRCONF = reg;\r
+\r
+  /* Set backup domain inactive mode configuration */\r
+  reg = EMU->BUINACT & ~(_EMU_BUINACT_PWRCON_MASK);\r
+  reg |= (bupdInit->inactivePower);\r
+  EMU->BUINACT = reg;\r
+\r
+  /* Set backup domain active mode configuration */\r
+  reg = EMU->BUACT & ~(_EMU_BUACT_PWRCON_MASK);\r
+  reg |= (bupdInit->activePower);\r
+  EMU->BUACT = reg;\r
+\r
+  /* Set power control configuration */\r
+  reg = EMU->BUCTRL & ~(_EMU_BUCTRL_PROBE_MASK\r
+                        | _EMU_BUCTRL_BODCAL_MASK\r
+                        | _EMU_BUCTRL_STATEN_MASK\r
+                        | _EMU_BUCTRL_EN_MASK);\r
+\r
+  /* Note use of ->enable to both enable BUPD, use BU_VIN pin input and\r
+     release reset */\r
+  reg |= bupdInit->probe\r
+         | (bupdInit->bodCal          << _EMU_BUCTRL_BODCAL_SHIFT)\r
+         | (bupdInit->statusPinEnable << _EMU_BUCTRL_STATEN_SHIFT)\r
+         | (bupdInit->enable          << _EMU_BUCTRL_EN_SHIFT);\r
+\r
+  /* Enable configuration */\r
+  EMU->BUCTRL = reg;\r
+\r
+  /* If enable is true, enable BU_VIN input power pin, if not disable it  */\r
+  EMU_BUPinEnable(bupdInit->enable);\r
+\r
+  /* If enable is true, release BU reset, if not keep reset asserted */\r
+  BUS_RegBitWrite(&(RMU->CTRL), _RMU_CTRL_BURSTEN_SHIFT, !bupdInit->enable);\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Configure Backup Power Domain BOD Threshold value\r
+ * @note\r
+ *   These values are precalibrated\r
+ * @param[in] mode Active or Inactive mode\r
+ * @param[in] value\r
+ ******************************************************************************/\r
+void EMU_BUThresholdSet(EMU_BODMode_TypeDef mode, uint32_t value)\r
+{\r
+  EFM_ASSERT(value<8);\r
+  EFM_ASSERT(value<=(_EMU_BUACT_BUEXTHRES_MASK>>_EMU_BUACT_BUEXTHRES_SHIFT));\r
+\r
+  switch(mode)\r
+  {\r
+    case emuBODMode_Active:\r
+      EMU->BUACT = (EMU->BUACT & ~_EMU_BUACT_BUEXTHRES_MASK)\r
+                   | (value<<_EMU_BUACT_BUEXTHRES_SHIFT);\r
+      break;\r
+    case emuBODMode_Inactive:\r
+      EMU->BUINACT = (EMU->BUINACT & ~_EMU_BUINACT_BUENTHRES_MASK)\r
+                     | (value<<_EMU_BUINACT_BUENTHRES_SHIFT);\r
+      break;\r
+  }\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *  Configure Backup Power Domain BOD Threshold Range\r
+ * @note\r
+ *  These values are precalibrated\r
+ * @param[in] mode Active or Inactive mode\r
+ * @param[in] value\r
+ ******************************************************************************/\r
+void EMU_BUThresRangeSet(EMU_BODMode_TypeDef mode, uint32_t value)\r
+{\r
+  EFM_ASSERT(value < 4);\r
+  EFM_ASSERT(value<=(_EMU_BUACT_BUEXRANGE_MASK>>_EMU_BUACT_BUEXRANGE_SHIFT));\r
+\r
+  switch(mode)\r
+  {\r
+    case emuBODMode_Active:\r
+      EMU->BUACT = (EMU->BUACT & ~_EMU_BUACT_BUEXRANGE_MASK)\r
+                   | (value<<_EMU_BUACT_BUEXRANGE_SHIFT);\r
+      break;\r
+    case emuBODMode_Inactive:\r
+      EMU->BUINACT = (EMU->BUINACT & ~_EMU_BUINACT_BUENRANGE_MASK)\r
+                     | (value<<_EMU_BUINACT_BUENRANGE_SHIFT);\r
+      break;\r
+  }\r
+}\r
+#endif\r
+\r
+\r
+#if defined( _EMU_DCDCCTRL_MASK )\r
+\r
+/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Load DCDC calibration constants from DI page. Const means calibration\r
+ *   data that does not change depending on other configuration parameters.\r
+ *\r
+ * @return\r
+ *   False if calibration registers are locked\r
+ ******************************************************************************/\r
+static bool ConstCalibrationLoad(void)\r
+{\r
+  uint32_t val;\r
+  volatile uint32_t *reg;\r
+\r
+  /* DI calib data in flash */\r
+  volatile uint32_t* const diCal_EMU_DCDCLNFREQCTRL =  (volatile uint32_t *)(0x0FE08038);\r
+  volatile uint32_t* const diCal_EMU_DCDCLNVCTRL =     (volatile uint32_t *)(0x0FE08040);\r
+  volatile uint32_t* const diCal_EMU_DCDCLPCTRL =      (volatile uint32_t *)(0x0FE08048);\r
+  volatile uint32_t* const diCal_EMU_DCDCLPVCTRL =     (volatile uint32_t *)(0x0FE08050);\r
+  volatile uint32_t* const diCal_EMU_DCDCTRIM0 =       (volatile uint32_t *)(0x0FE08058);\r
+  volatile uint32_t* const diCal_EMU_DCDCTRIM1 =       (volatile uint32_t *)(0x0FE08060);\r
+\r
+  if (DEVINFO->DCDCLPVCTRL0 != UINT_MAX)\r
+  {\r
+    val = *(diCal_EMU_DCDCLNFREQCTRL + 1);\r
+    reg = (volatile uint32_t *)*diCal_EMU_DCDCLNFREQCTRL;\r
+    *reg = val;\r
+\r
+    val = *(diCal_EMU_DCDCLNVCTRL + 1);\r
+    reg = (volatile uint32_t *)*diCal_EMU_DCDCLNVCTRL;\r
+    *reg = val;\r
+\r
+    val = *(diCal_EMU_DCDCLPCTRL + 1);\r
+    reg = (volatile uint32_t *)*diCal_EMU_DCDCLPCTRL;\r
+    *reg = val;\r
+\r
+    val = *(diCal_EMU_DCDCLPVCTRL + 1);\r
+    reg = (volatile uint32_t *)*diCal_EMU_DCDCLPVCTRL;\r
+    *reg = val;\r
+\r
+    val = *(diCal_EMU_DCDCTRIM0 + 1);\r
+    reg = (volatile uint32_t *)*diCal_EMU_DCDCTRIM0;\r
+    *reg = val;\r
+\r
+    val = *(diCal_EMU_DCDCTRIM1 + 1);\r
+    reg = (volatile uint32_t *)*diCal_EMU_DCDCTRIM1;\r
+    *reg = val;\r
+\r
+    return true;\r
+  }\r
+  EFM_ASSERT(false);\r
+  /* Return when assertions are disabled */\r
+  return false;\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Set recommended and validated current optimization settings\r
+ *\r
+ ******************************************************************************/\r
+void ValidatedConfigSet(void)\r
+{\r
+#define EMU_DCDCSMCTRL  (* (volatile uint32_t *)(EMU_BASE + 0x44))\r
+\r
+  uint32_t dcdcTiming;\r
+  SYSTEM_PartFamily_TypeDef family;\r
+  SYSTEM_ChipRevision_TypeDef rev;\r
+\r
+  /* Enable duty cycling of the bias */\r
+  EMU->DCDCLPCTRL |= EMU_DCDCLPCTRL_LPVREFDUTYEN;\r
+\r
+  /* Set low-noise RCO for EFM32 and EFR32 */\r
+#if defined( _EFR_DEVICE )\r
+  /* 7MHz is recommended for all EFR32 parts with DCDC */\r
+  EMU->DCDCLNFREQCTRL = (EMU->DCDCLNFREQCTRL & ~_EMU_DCDCLNFREQCTRL_RCOBAND_MASK)\r
+                          | (EMU_DcdcLnRcoBand_7MHz << _EMU_DCDCLNFREQCTRL_RCOBAND_SHIFT);\r
+#else\r
+  /* 3MHz is recommended for all EFM32 parts with DCDC */\r
+  EMU->DCDCLNFREQCTRL = (EMU->DCDCLNFREQCTRL & ~_EMU_DCDCLNFREQCTRL_RCOBAND_MASK)\r
+                          | (EMU_DcdcLnRcoBand_3MHz << _EMU_DCDCLNFREQCTRL_RCOBAND_SHIFT);\r
+#endif\r
+\r
+  EMU->DCDCTIMING &= ~_EMU_DCDCTIMING_DUTYSCALE_MASK;\r
+\r
+  family = SYSTEM_GetFamily();\r
+  SYSTEM_ChipRevisionGet(&rev);\r
+  if ((((family >= systemPartFamilyMighty1P)\r
+         && (family <= systemPartFamilyFlex1V))\r
+       || (family == systemPartFamilyEfm32Pearl1B)\r
+       || (family == systemPartFamilyEfm32Jade1B))\r
+      && ((rev.major == 1) && (rev.minor < 3))\r
+      && (errataFixDcdcHsState == errataFixDcdcHsInit))\r
+  {\r
+    /* LPCMPWAITDIS = 1 */\r
+    EMU_DCDCSMCTRL |= 1;\r
+\r
+    dcdcTiming = EMU->DCDCTIMING;\r
+    dcdcTiming &= ~(_EMU_DCDCTIMING_LPINITWAIT_MASK\r
+                    |_EMU_DCDCTIMING_LNWAIT_MASK\r
+                    |_EMU_DCDCTIMING_BYPWAIT_MASK);\r
+\r
+    dcdcTiming |= ((180 << _EMU_DCDCTIMING_LPINITWAIT_SHIFT)\r
+                   | (12 << _EMU_DCDCTIMING_LNWAIT_SHIFT)\r
+                   | (180 << _EMU_DCDCTIMING_BYPWAIT_SHIFT));\r
+    EMU->DCDCTIMING = dcdcTiming;\r
+\r
+    errataFixDcdcHsState = errataFixDcdcHsTrimSet;\r
+  }\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Calculate and update EMU->DCDCMISCCTRL for maximum DCDC current based\r
+ *   on the slice configuration and user set maximum.\r
+ ******************************************************************************/\r
+static void maxCurrentUpdate(void)\r
+{\r
+  uint32_t lncLimImSel;\r
+  uint32_t lpcLimImSel;\r
+  uint32_t pFetCnt;\r
+\r
+  pFetCnt = (EMU->DCDCMISCCTRL & _EMU_DCDCMISCCTRL_PFETCNT_MASK)\r
+             >> _EMU_DCDCMISCCTRL_PFETCNT_SHIFT;\r
+\r
+  /* Equation from Reference Manual section 11.5.20, in the register\r
+     field description for LNCLIMILIMSEL and LPCLIMILIMSEL. */\r
+  lncLimImSel = (dcdcMaxCurrent_mA / (5 * (pFetCnt + 1))) - 1;\r
+  /* 80mA as recommended in Application Note AN0948 */\r
+  lpcLimImSel = (80 / (5 * (pFetCnt + 1))) - 1;\r
+\r
+  lncLimImSel <<= _EMU_DCDCMISCCTRL_LNCLIMILIMSEL_SHIFT;\r
+  lpcLimImSel <<= _EMU_DCDCMISCCTRL_LPCLIMILIMSEL_SHIFT;\r
+  EMU->DCDCMISCCTRL = (EMU->DCDCMISCCTRL & ~(_EMU_DCDCMISCCTRL_LNCLIMILIMSEL_MASK\r
+                                             | _EMU_DCDCMISCCTRL_LPCLIMILIMSEL_MASK))\r
+                       | (lncLimImSel | lpcLimImSel);\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Set static variable that holds the user set maximum current. Update\r
+ *   DCDC configuration.\r
+ *\r
+ * @param[in] mAmaxCurrent\r
+ *   Maximum allowed current drawn by the DCDC from VREGVDD in mA.\r
+ ******************************************************************************/\r
+static void maxCurrentSet(uint32_t mAmaxCurrent)\r
+{\r
+  dcdcMaxCurrent_mA = mAmaxCurrent;\r
+  maxCurrentUpdate();\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Load EMU_DCDCLPCTRL_LPCMPHYSSEL depending on LP bias, LP feedback\r
+ *   attenuation and DEVINFOREV.\r
+ *\r
+ * @param[in] attSet\r
+ *   LP feedback attenuation.\r
+ * @param[in] lpCmpBias\r
+ *   lpCmpBias selection\r
+ ******************************************************************************/\r
+static bool LpCmpHystCalibrationLoad(bool lpAttenuation, uint32_t lpCmpBias)\r
+{\r
+  uint8_t devinfoRev;\r
+  uint32_t lpcmpHystSel;\r
+\r
+  /* Get calib data revision */\r
+  devinfoRev = SYSTEM_GetDevinfoRev();\r
+\r
+  /* Load LPATT indexed calibration data */\r
+  if (devinfoRev < 4)\r
+  {\r
+    lpcmpHystSel = DEVINFO->DCDCLPCMPHYSSEL0;\r
+\r
+    if (lpAttenuation)\r
+    {\r
+      lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL0_LPCMPHYSSELLPATT1_MASK)\r
+                      >> _DEVINFO_DCDCLPCMPHYSSEL0_LPCMPHYSSELLPATT1_SHIFT;\r
+    }\r
+    else\r
+    {\r
+      lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL0_LPCMPHYSSELLPATT0_MASK)\r
+                      >> _DEVINFO_DCDCLPCMPHYSSEL0_LPCMPHYSSELLPATT0_SHIFT;\r
+    }\r
+  }\r
+  /* devinfoRev >= 4\r
+     Load LPCMPBIAS indexed calibration data */\r
+  else\r
+  {\r
+    lpcmpHystSel = DEVINFO->DCDCLPCMPHYSSEL1;\r
+    switch (lpCmpBias)\r
+    {\r
+      case _EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS0:\r
+        lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS0_MASK)\r
+                        >> _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS0_SHIFT;\r
+        break;\r
+\r
+      case _EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS1:\r
+        lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS1_MASK)\r
+                        >> _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS1_SHIFT;\r
+        break;\r
+\r
+      case _EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS2:\r
+        lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS2_MASK)\r
+                        >> _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS2_SHIFT;\r
+        break;\r
+\r
+      case _EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS3:\r
+        lpcmpHystSel = (lpcmpHystSel & _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS3_MASK)\r
+                        >> _DEVINFO_DCDCLPCMPHYSSEL1_LPCMPHYSSELLPCMPBIAS3_SHIFT;\r
+        break;\r
+\r
+      default:\r
+        EFM_ASSERT(false);\r
+        /* Return when assertions are disabled */\r
+        return false;\r
+    }\r
+  }\r
+\r
+  /* Make sure the sel value is within the field range. */\r
+  lpcmpHystSel <<= _EMU_DCDCLPCTRL_LPCMPHYSSEL_SHIFT;\r
+  if (lpcmpHystSel & ~_EMU_DCDCLPCTRL_LPCMPHYSSEL_MASK)\r
+  {\r
+    EFM_ASSERT(false);\r
+    /* Return when assertions are disabled */\r
+    return false;\r
+  }\r
+  EMU->DCDCLPCTRL = (EMU->DCDCLPCTRL & ~_EMU_DCDCLPCTRL_LPCMPHYSSEL_MASK) | lpcmpHystSel;\r
+\r
+  return true;\r
+}\r
+\r
+\r
+/** @endcond */\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Set DCDC regulator operating mode\r
+ *\r
+ * @param[in] dcdcMode\r
+ *   DCDC mode\r
+ ******************************************************************************/\r
+void EMU_DCDCModeSet(EMU_DcdcMode_TypeDef dcdcMode)\r
+{\r
+  while(EMU->DCDCSYNC & EMU_DCDCSYNC_DCDCCTRLBUSY);\r
+  BUS_RegBitWrite(&EMU->DCDCCLIMCTRL, _EMU_DCDCCLIMCTRL_BYPLIMEN_SHIFT, dcdcMode == emuDcdcMode_Bypass ? 0 : 1);\r
+  EMU->DCDCCTRL = (EMU->DCDCCTRL & ~_EMU_DCDCCTRL_DCDCMODE_MASK) | dcdcMode;\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Configure DCDC regulator\r
+ *\r
+ * @note\r
+ *   Use the function EMU_DCDCPowerDown() to if the power circuit is configured\r
+ *   for NODCDC as decribed in Section 11.3.4.3 in the Reference Manual.\r
+ *\r
+ * @param[in] dcdcInit\r
+ *   DCDC initialization structure\r
+ *\r
+ * @return\r
+ *   True if initialization parameters are valid\r
+ ******************************************************************************/\r
+bool EMU_DCDCInit(EMU_DCDCInit_TypeDef *dcdcInit)\r
+{\r
+  uint32_t lpCmpBiasSel;\r
+\r
+  /* Set external power configuration. This enables writing to the other\r
+     DCDC registers. */\r
+  EMU->PWRCFG = dcdcInit->powerConfig;\r
+\r
+  /* EMU->PWRCFG is write-once and POR reset only. Check that\r
+     we could set the desired power configuration. */\r
+  if ((EMU->PWRCFG & _EMU_PWRCFG_PWRCFG_MASK) != dcdcInit->powerConfig)\r
+  {\r
+    /* If this assert triggers unexpectedly, please power cycle the\r
+       kit to reset the power configuration. */\r
+    EFM_ASSERT(false);\r
+    /* Return when assertions are disabled */\r
+    return false;\r
+  }\r
+\r
+  /* Load DCDC calibration data from the DI page */\r
+  ConstCalibrationLoad();\r
+\r
+  /* Check current parameters */\r
+  EFM_ASSERT(dcdcInit->maxCurrent_mA <= 200);\r
+  EFM_ASSERT(dcdcInit->em01LoadCurrent_mA <= dcdcInit->maxCurrent_mA);\r
+\r
+  /* DCDC low-noise supports max 200mA */\r
+  if (dcdcInit->dcdcMode == emuDcdcMode_LowNoise)\r
+  {\r
+    EFM_ASSERT(dcdcInit->em01LoadCurrent_mA <= 200);\r
+  }\r
+\r
+  /* EM2, 3 and 4 current above 100uA is not supported */\r
+  EFM_ASSERT(dcdcInit->em234LoadCurrent_uA <= 100);\r
+\r
+  /* Decode LP comparator bias for EM0/1 and EM2/3 */\r
+  lpCmpBiasSel  = EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS1;\r
+  if (dcdcInit->em234LoadCurrent_uA <= 10)\r
+  {\r
+    lpCmpBiasSel  = EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS0;\r
+  }\r
+\r
+  /* Set DCDC low-power mode comparator bias selection */\r
+  EMU->DCDCMISCCTRL = (EMU->DCDCMISCCTRL & ~(_EMU_DCDCMISCCTRL_LPCMPBIAS_MASK\r
+                                             | _EMU_DCDCMISCCTRL_LNFORCECCM_MASK))\r
+                       | ((uint32_t)lpCmpBiasSel\r
+                          | (uint32_t)dcdcInit->lnTransientMode);\r
+\r
+  /* Set recommended and validated current optimization settings */\r
+  ValidatedConfigSet();\r
+\r
+  /* Set the maximum current that the DCDC can draw from the power source */\r
+  maxCurrentSet(dcdcInit->maxCurrent_mA);\r
+\r
+  /* Optimize LN slice based on given load current estimate */\r
+  EMU_DCDCOptimizeSlice(dcdcInit->em01LoadCurrent_mA);\r
+\r
+  /* Set DCDC output voltage */\r
+  dcdcOutput_mVout = dcdcInit->mVout;\r
+  if (!EMU_DCDCOutputVoltageSet(dcdcOutput_mVout, true, true))\r
+  {\r
+    EFM_ASSERT(false);\r
+    /* Return when assertions are disabled */\r
+    return false;\r
+  }\r
+\r
+  /* Set EM0 DCDC operating mode. Output voltage set in EMU_DCDCOutputVoltageSet()\r
+     above takes effect if mode is changed from bypass here. */\r
+  EMU_DCDCModeSet(dcdcInit->dcdcMode);\r
+\r
+  /* Select analog peripheral power supply */\r
+  BUS_RegBitWrite(&EMU->PWRCTRL, _EMU_PWRCTRL_ANASW_SHIFT, dcdcInit->anaPeripheralPower ? 1 : 0);\r
+\r
+  return true;\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Set DCDC output voltage\r
+ *\r
+ * @param[in] mV\r
+ *   Target DCDC output voltage in mV\r
+ *\r
+ * @return\r
+ *   True if the mV parameter is valid\r
+ ******************************************************************************/\r
+bool EMU_DCDCOutputVoltageSet(uint32_t mV,\r
+                              bool setLpVoltage,\r
+                              bool setLnVoltage)\r
+{\r
+#if defined( _DEVINFO_DCDCLNVCTRL0_3V0LNATT1_MASK )\r
+\r
+  bool validOutVoltage;\r
+  uint8_t lnMode;\r
+  bool attSet;\r
+  uint32_t attMask;\r
+  uint32_t vrefLow = 0;\r
+  uint32_t vrefHigh = 0;\r
+  uint32_t vrefVal = 0;\r
+  uint32_t mVlow = 0;\r
+  uint32_t mVhigh = 0;\r
+  uint32_t vrefShift;\r
+  uint32_t lpcmpBias;\r
+  volatile uint32_t* ctrlReg;\r
+\r
+  /* Check that the set voltage is within valid range.\r
+     Voltages are obtained from the datasheet. */\r
+  validOutVoltage = false;\r
+  if ((EMU->PWRCFG & _EMU_PWRCFG_PWRCFG_MASK) == EMU_PWRCFG_PWRCFG_DCDCTODVDD)\r
+  {\r
+    validOutVoltage = ((mV >= PWRCFG_DCDCTODVDD_VMIN)\r
+                       && (mV <= PWRCFG_DCDCTODVDD_VMAX));\r
+  }\r
+\r
+  if (!validOutVoltage)\r
+  {\r
+    EFM_ASSERT(false);\r
+    /* Return when assertions are disabled */\r
+    return false;\r
+  }\r
+\r
+  /* Populate both LP and LN registers, set control reg pointer and VREF shift. */\r
+  for (lnMode = 0; lnMode <= 1; lnMode++)\r
+  {\r
+    if (((lnMode == 0) && !setLpVoltage)\r
+        || ((lnMode == 1) && !setLnVoltage))\r
+    {\r
+      continue;\r
+    }\r
+\r
+    ctrlReg   = (lnMode ? &EMU->DCDCLNVCTRL : &EMU->DCDCLPVCTRL);\r
+    vrefShift = (lnMode ? _EMU_DCDCLNVCTRL_LNVREF_SHIFT\r
+                        : _EMU_DCDCLPVCTRL_LPVREF_SHIFT);\r
+\r
+    /* Set attenuation to use */\r
+    attSet = (mV > 1800);\r
+    if (attSet)\r
+    {\r
+      mVlow = 1800;\r
+      mVhigh = 3000;\r
+      attMask = (lnMode ? EMU_DCDCLNVCTRL_LNATT : EMU_DCDCLPVCTRL_LPATT);\r
+    }\r
+    else\r
+    {\r
+      mVlow = 1200;\r
+      mVhigh = 1800;\r
+      attMask = 0;\r
+    }\r
+\r
+    /* Get 2-point calib data from DEVINFO, calculate trimming and set voltege */\r
+    if (lnMode)\r
+    {\r
+      /* Set low-noise DCDC output voltage tuning */\r
+      if (attSet)\r
+      {\r
+        vrefLow  = DEVINFO->DCDCLNVCTRL0;\r
+        vrefHigh = (vrefLow & _DEVINFO_DCDCLNVCTRL0_3V0LNATT1_MASK)\r
+                   >> _DEVINFO_DCDCLNVCTRL0_3V0LNATT1_SHIFT;\r
+        vrefLow  = (vrefLow & _DEVINFO_DCDCLNVCTRL0_1V8LNATT1_MASK)\r
+                   >> _DEVINFO_DCDCLNVCTRL0_1V8LNATT1_SHIFT;\r
+      }\r
+      else\r
+      {\r
+        vrefLow  = DEVINFO->DCDCLNVCTRL0;\r
+        vrefHigh = (vrefLow & _DEVINFO_DCDCLNVCTRL0_1V8LNATT0_MASK)\r
+                   >> _DEVINFO_DCDCLNVCTRL0_1V8LNATT0_SHIFT;\r
+        vrefLow  = (vrefLow & _DEVINFO_DCDCLNVCTRL0_1V2LNATT0_MASK)\r
+                   >> _DEVINFO_DCDCLNVCTRL0_1V2LNATT0_SHIFT;\r
+      }\r
+    }\r
+    else\r
+    {\r
+      /* Set low-power DCDC output voltage tuning */\r
+\r
+      /* Get LPCMPBIAS and make sure masks are not overlayed */\r
+      lpcmpBias = EMU->DCDCMISCCTRL & _EMU_DCDCMISCCTRL_LPCMPBIAS_MASK;\r
+      EFM_ASSERT(!(_EMU_DCDCMISCCTRL_LPCMPBIAS_MASK & attMask));\r
+      switch (attMask | lpcmpBias)\r
+      {\r
+        case EMU_DCDCLPVCTRL_LPATT | EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS0:\r
+          vrefLow  = DEVINFO->DCDCLPVCTRL2;\r
+          vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS0_MASK)\r
+                     >> _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS0_SHIFT;\r
+          vrefLow  = (vrefLow & _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS0_MASK)\r
+                     >> _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS0_SHIFT;\r
+          break;\r
+\r
+        case EMU_DCDCLPVCTRL_LPATT | EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS1:\r
+          vrefLow  = DEVINFO->DCDCLPVCTRL2;\r
+          vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS1_MASK)\r
+                     >> _DEVINFO_DCDCLPVCTRL2_3V0LPATT1LPCMPBIAS1_SHIFT;\r
+          vrefLow  = (vrefLow & _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS1_MASK)\r
+                     >> _DEVINFO_DCDCLPVCTRL2_1V8LPATT1LPCMPBIAS1_SHIFT;\r
+          break;\r
+\r
+        case EMU_DCDCLPVCTRL_LPATT | EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS2:\r
+          vrefLow  = DEVINFO->DCDCLPVCTRL3;\r
+          vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS2_MASK)\r
+                     >> _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS2_SHIFT;\r
+          vrefLow  = (vrefLow & _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS2_MASK)\r
+                     >> _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS2_SHIFT;\r
+          break;\r
+\r
+        case EMU_DCDCLPVCTRL_LPATT | EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS3:\r
+          vrefLow  = DEVINFO->DCDCLPVCTRL3;\r
+          vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS3_MASK)\r
+                     >> _DEVINFO_DCDCLPVCTRL3_3V0LPATT1LPCMPBIAS3_SHIFT;\r
+          vrefLow  = (vrefLow & _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS3_MASK)\r
+                     >> _DEVINFO_DCDCLPVCTRL3_1V8LPATT1LPCMPBIAS3_SHIFT;\r
+          break;\r
+\r
+        case EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS0:\r
+          vrefLow  = DEVINFO->DCDCLPVCTRL0;\r
+          vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL0_1V8LPATT0LPCMPBIAS0_MASK)\r
+                     >> _DEVINFO_DCDCLPVCTRL0_1V8LPATT0LPCMPBIAS0_SHIFT;\r
+          vrefLow  = (vrefLow & _DEVINFO_DCDCLPVCTRL0_1V2LPATT0LPCMPBIAS0_MASK)\r
+                     >> _DEVINFO_DCDCLPVCTRL0_1V2LPATT0LPCMPBIAS0_SHIFT;\r
+          break;\r
+\r
+        case EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS1:\r
+          vrefLow  = DEVINFO->DCDCLPVCTRL0;\r
+          vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL0_1V8LPATT0LPCMPBIAS1_MASK)\r
+                     >> _DEVINFO_DCDCLPVCTRL0_1V8LPATT0LPCMPBIAS1_SHIFT;\r
+          vrefLow  = (vrefLow & _DEVINFO_DCDCLPVCTRL0_1V2LPATT0LPCMPBIAS1_MASK)\r
+                     >> _DEVINFO_DCDCLPVCTRL0_1V2LPATT0LPCMPBIAS1_SHIFT;\r
+          break;\r
+\r
+        case EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS2:\r
+          vrefLow  = DEVINFO->DCDCLPVCTRL1;\r
+          vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL1_1V8LPATT0LPCMPBIAS2_MASK)\r
+                     >> _DEVINFO_DCDCLPVCTRL1_1V8LPATT0LPCMPBIAS2_SHIFT;\r
+          vrefLow  = (vrefLow & _DEVINFO_DCDCLPVCTRL1_1V2LPATT0LPCMPBIAS2_MASK)\r
+                     >> _DEVINFO_DCDCLPVCTRL1_1V2LPATT0LPCMPBIAS2_SHIFT;\r
+          break;\r
+\r
+        case EMU_DCDCMISCCTRL_LPCMPBIAS_BIAS3:\r
+          vrefLow  = DEVINFO->DCDCLPVCTRL1;\r
+          vrefHigh = (vrefLow & _DEVINFO_DCDCLPVCTRL1_1V8LPATT0LPCMPBIAS3_MASK)\r
+                     >> _DEVINFO_DCDCLPVCTRL1_1V8LPATT0LPCMPBIAS3_SHIFT;\r
+          vrefLow  = (vrefLow & _DEVINFO_DCDCLPVCTRL1_1V2LPATT0LPCMPBIAS3_MASK)\r
+                     >> _DEVINFO_DCDCLPVCTRL1_1V2LPATT0LPCMPBIAS3_SHIFT;\r
+          break;\r
+\r
+        default:\r
+          EFM_ASSERT(false);\r
+          break;\r
+      }\r
+\r
+      /* Load LP comparator hysteresis calibration */\r
+      if(!(LpCmpHystCalibrationLoad(attSet, lpcmpBias >> _EMU_DCDCMISCCTRL_LPCMPBIAS_SHIFT)))\r
+      {\r
+        EFM_ASSERT(false);\r
+        /* Return when assertions are disabled */\r
+        return false;\r
+      }\r
+    } /* Low-nise / low-power mode */\r
+\r
+\r
+    /* Check for valid 2-point trim values */\r
+    if ((vrefLow == 0xFF) && (vrefHigh == 0xFF))\r
+    {\r
+      EFM_ASSERT(false);\r
+      /* Return when assertions are disabled */\r
+      return false;\r
+    }\r
+\r
+    /* Calculate and set voltage trim */\r
+    vrefVal = ((mV - mVlow) * (vrefHigh - vrefLow))  / (mVhigh - mVlow);\r
+    vrefVal += vrefLow;\r
+\r
+    /* Range check */\r
+    if ((vrefVal > vrefHigh) || (vrefVal < vrefLow))\r
+    {\r
+      EFM_ASSERT(false);\r
+      /* Return when assertions are disabled */\r
+      return false;\r
+    }\r
+\r
+    /* Update DCDCLNVCTRL/DCDCLPVCTRL */\r
+    *ctrlReg = (vrefVal << vrefShift) | attMask;\r
+  }\r
+#endif\r
+  return true;\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Optimize DCDC slice count based on the estimated average load current\r
+ *   in EM0\r
+ *\r
+ * @param[in] mAEm0LoadCurrent\r
+ *   Estimated average EM0 load current in mA.\r
+ ******************************************************************************/\r
+void EMU_DCDCOptimizeSlice(uint32_t mAEm0LoadCurrent)\r
+{\r
+  uint32_t sliceCount = 0;\r
+  uint32_t rcoBand = (EMU->DCDCLNFREQCTRL & _EMU_DCDCLNFREQCTRL_RCOBAND_MASK)\r
+                      >> _EMU_DCDCLNFREQCTRL_RCOBAND_SHIFT;\r
+\r
+  /* Set recommended slice count */\r
+  if ((EMU->DCDCMISCCTRL & _EMU_DCDCMISCCTRL_LNFORCECCM_MASK) && (rcoBand >= EMU_DcdcLnRcoBand_5MHz))\r
+  {\r
+    if (mAEm0LoadCurrent < 20)\r
+    {\r
+      sliceCount = 4;\r
+    }\r
+    else if ((mAEm0LoadCurrent >= 20) && (mAEm0LoadCurrent < 40))\r
+    {\r
+      sliceCount = 8;\r
+    }\r
+    else\r
+    {\r
+      sliceCount = 16;\r
+    }\r
+  }\r
+  else if ((!(EMU->DCDCMISCCTRL & _EMU_DCDCMISCCTRL_LNFORCECCM_MASK)) && (rcoBand <= EMU_DcdcLnRcoBand_4MHz))\r
+  {\r
+    if (mAEm0LoadCurrent < 10)\r
+    {\r
+      sliceCount = 4;\r
+    }\r
+    else if ((mAEm0LoadCurrent >= 10) && (mAEm0LoadCurrent < 20))\r
+    {\r
+      sliceCount = 8;\r
+    }\r
+    else\r
+    {\r
+      sliceCount = 16;\r
+    }\r
+  }\r
+  else if ((EMU->DCDCMISCCTRL & _EMU_DCDCMISCCTRL_LNFORCECCM_MASK) && (rcoBand <= EMU_DcdcLnRcoBand_4MHz))\r
+  {\r
+    if (mAEm0LoadCurrent < 40)\r
+    {\r
+      sliceCount = 8;\r
+    }\r
+    else\r
+    {\r
+      sliceCount = 16;\r
+    }\r
+  }\r
+  else\r
+  {\r
+    /* This configuration is not recommended. EMU_DCDCInit() applies a recommended\r
+       configuration. */\r
+    EFM_ASSERT(false);\r
+  }\r
+\r
+  /* The selected silices are PSLICESEL + 1 */\r
+  sliceCount--;\r
+\r
+  /* Apply slice count to both N and P slice */\r
+  sliceCount = (sliceCount << _EMU_DCDCMISCCTRL_PFETCNT_SHIFT\r
+                | sliceCount << _EMU_DCDCMISCCTRL_NFETCNT_SHIFT);\r
+  EMU->DCDCMISCCTRL = (EMU->DCDCMISCCTRL & ~(_EMU_DCDCMISCCTRL_PFETCNT_MASK\r
+                                             | _EMU_DCDCMISCCTRL_NFETCNT_MASK))\r
+                      | sliceCount;\r
+\r
+  /* Update current limit configuration as it depends on the slice configuration. */\r
+  maxCurrentUpdate();\r
+}\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Set DCDC Low-noise RCO band.\r
+ *\r
+ * @param[in] band\r
+ *   RCO band to set.\r
+ ******************************************************************************/\r
+void EMU_DCDCLnRcoBandSet(EMU_DcdcLnRcoBand_TypeDef band)\r
+{\r
+  EMU->DCDCLNFREQCTRL = (EMU->DCDCLNFREQCTRL & ~_EMU_DCDCLNFREQCTRL_RCOBAND_MASK)\r
+                         | (band << _EMU_DCDCLNFREQCTRL_RCOBAND_SHIFT);\r
+}\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Power off the DCDC regulator.\r
+ *\r
+ * @details\r
+ *   This function powers off the DCDC controller. This function should only be\r
+ *   used if the external power circuit is wired for no DCDC. If the external power\r
+ *   circuit is wired for DCDC usage, then use EMU_DCDCInit() and set the\r
+ *   DCDC in bypass mode to disable DCDC.\r
+ *\r
+ * @return\r
+ *   Return false if the DCDC could not be disabled.\r
+ ******************************************************************************/\r
+bool EMU_DCDCPowerOff(void)\r
+{\r
+  /* Set power configuration to hard bypass */\r
+  EMU->PWRCFG = 0xF;\r
+  if ((EMU->PWRCFG & _EMU_PWRCFG_PWRCFG_MASK) != 0xF)\r
+  {\r
+    EFM_ASSERT(false);\r
+    /* Return when assertions are disabled */\r
+    return false;\r
+  }\r
+\r
+  /* Set DCDC to OFF and disable LP in EM2/3/4 */\r
+  EMU->DCDCCTRL = EMU_DCDCCTRL_DCDCMODE_OFF;\r
+  return true;\r
+}\r
+#endif\r
+\r
+\r
+#if defined( EMU_STATUS_VMONRDY )\r
+/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */\r
+__STATIC_INLINE uint32_t vmonMilliVoltToCoarseThreshold(int mV)\r
+{\r
+  return (mV - 1200) / 200;\r
+}\r
+\r
+__STATIC_INLINE uint32_t vmonMilliVoltToFineThreshold(int mV, uint32_t coarseThreshold)\r
+{\r
+  return (mV - 1200 - (coarseThreshold * 200)) / 20;\r
+}\r
+/** @endcond */\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Initialize VMON channel.\r
+ *\r
+ * @details\r
+ *   Initialize a VMON channel without hysteresis. If the channel supports\r
+ *   separate rise and fall triggers, both thresholds will be set to the same\r
+ *   value.\r
+ *\r
+ * @param[in] vmonInit\r
+ *   VMON initialization struct\r
+ ******************************************************************************/\r
+void EMU_VmonInit(EMU_VmonInit_TypeDef *vmonInit)\r
+{\r
+  uint32_t thresholdCoarse, thresholdFine;\r
+  EFM_ASSERT((vmonInit->threshold >= 1200) && (vmonInit->threshold <= 3980));\r
+\r
+  thresholdCoarse = vmonMilliVoltToCoarseThreshold(vmonInit->threshold);\r
+  thresholdFine = vmonMilliVoltToFineThreshold(vmonInit->threshold, thresholdCoarse);\r
+\r
+  switch(vmonInit->channel)\r
+  {\r
+  case emuVmonChannel_AVDD:\r
+    EMU->VMONAVDDCTRL = (thresholdCoarse << _EMU_VMONAVDDCTRL_RISETHRESCOARSE_SHIFT)\r
+                      | (thresholdFine << _EMU_VMONAVDDCTRL_RISETHRESFINE_SHIFT)\r
+                      | (thresholdCoarse << _EMU_VMONAVDDCTRL_FALLTHRESCOARSE_SHIFT)\r
+                      | (thresholdFine << _EMU_VMONAVDDCTRL_FALLTHRESFINE_SHIFT)\r
+                      | (vmonInit->riseWakeup ? EMU_VMONAVDDCTRL_RISEWU : 0)\r
+                      | (vmonInit->fallWakeup ? EMU_VMONAVDDCTRL_FALLWU : 0)\r
+                      | (vmonInit->enable     ? EMU_VMONAVDDCTRL_EN     : 0);\r
+    break;\r
+  case emuVmonChannel_ALTAVDD:\r
+    EMU->VMONALTAVDDCTRL = (thresholdCoarse << _EMU_VMONALTAVDDCTRL_THRESCOARSE_SHIFT)\r
+                         | (thresholdFine << _EMU_VMONALTAVDDCTRL_THRESFINE_SHIFT)\r
+                         | (vmonInit->riseWakeup ? EMU_VMONALTAVDDCTRL_RISEWU : 0)\r
+                         | (vmonInit->fallWakeup ? EMU_VMONALTAVDDCTRL_FALLWU : 0)\r
+                         | (vmonInit->enable     ? EMU_VMONALTAVDDCTRL_EN     : 0);\r
+    break;\r
+  case emuVmonChannel_DVDD:\r
+    EMU->VMONDVDDCTRL = (thresholdCoarse << _EMU_VMONDVDDCTRL_THRESCOARSE_SHIFT)\r
+                      | (thresholdFine << _EMU_VMONDVDDCTRL_THRESFINE_SHIFT)\r
+                      | (vmonInit->riseWakeup ? EMU_VMONDVDDCTRL_RISEWU : 0)\r
+                      | (vmonInit->fallWakeup ? EMU_VMONDVDDCTRL_FALLWU : 0)\r
+                      | (vmonInit->enable     ? EMU_VMONDVDDCTRL_EN     : 0);\r
+    break;\r
+  case emuVmonChannel_IOVDD0:\r
+    EMU->VMONIO0CTRL = (thresholdCoarse << _EMU_VMONIO0CTRL_THRESCOARSE_SHIFT)\r
+                     | (thresholdFine << _EMU_VMONIO0CTRL_THRESFINE_SHIFT)\r
+                     | (vmonInit->retDisable ? EMU_VMONIO0CTRL_RETDIS : 0)\r
+                     | (vmonInit->riseWakeup ? EMU_VMONIO0CTRL_RISEWU : 0)\r
+                     | (vmonInit->fallWakeup ? EMU_VMONIO0CTRL_FALLWU : 0)\r
+                     | (vmonInit->enable     ? EMU_VMONIO0CTRL_EN     : 0);\r
+    break;\r
+  default:\r
+    EFM_ASSERT(false);\r
+    return;\r
+  }\r
+}\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Initialize VMON channel with hysteresis (separate rise and fall triggers).\r
+ *\r
+ * @details\r
+ *   Initialize a VMON channel which supports hysteresis. The AVDD channel is\r
+ *   the only channel to support separate rise and fall triggers.\r
+ *\r
+ * @param[in] vmonInit\r
+ *   VMON Hysteresis initialization struct\r
+ ******************************************************************************/\r
+void EMU_VmonHystInit(EMU_VmonHystInit_TypeDef *vmonInit)\r
+{\r
+  uint32_t riseThresholdCoarse, riseThresholdFine, fallThresholdCoarse, fallThresholdFine;\r
+  /* VMON supports voltages between 1200 mV and 3980 mV (inclusive) in 20 mV increments */\r
+  EFM_ASSERT((vmonInit->riseThreshold >= 1200) && (vmonInit->riseThreshold < 4000));\r
+  EFM_ASSERT((vmonInit->fallThreshold >= 1200) && (vmonInit->fallThreshold < 4000));\r
+  /* Fall threshold has to be lower than rise threshold */\r
+  EFM_ASSERT(vmonInit->fallThreshold <= vmonInit->riseThreshold);\r
+\r
+  riseThresholdCoarse = vmonMilliVoltToCoarseThreshold(vmonInit->riseThreshold);\r
+  riseThresholdFine = vmonMilliVoltToFineThreshold(vmonInit->riseThreshold, riseThresholdCoarse);\r
+  fallThresholdCoarse = vmonMilliVoltToCoarseThreshold(vmonInit->fallThreshold);\r
+  fallThresholdFine = vmonMilliVoltToFineThreshold(vmonInit->fallThreshold, fallThresholdCoarse);\r
+\r
+  switch(vmonInit->channel)\r
+  {\r
+  case emuVmonChannel_AVDD:\r
+    EMU->VMONAVDDCTRL = (riseThresholdCoarse << _EMU_VMONAVDDCTRL_RISETHRESCOARSE_SHIFT)\r
+                      | (riseThresholdFine << _EMU_VMONAVDDCTRL_RISETHRESFINE_SHIFT)\r
+                      | (fallThresholdCoarse << _EMU_VMONAVDDCTRL_FALLTHRESCOARSE_SHIFT)\r
+                      | (fallThresholdFine << _EMU_VMONAVDDCTRL_FALLTHRESFINE_SHIFT)\r
+                      | (vmonInit->riseWakeup ? EMU_VMONAVDDCTRL_RISEWU : 0)\r
+                      | (vmonInit->fallWakeup ? EMU_VMONAVDDCTRL_FALLWU : 0)\r
+                      | (vmonInit->enable     ? EMU_VMONAVDDCTRL_EN     : 0);\r
+    break;\r
+  default:\r
+    EFM_ASSERT(false);\r
+    return;\r
+  }\r
+}\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Enable or disable a VMON channel\r
+ *\r
+ * @param[in] channel\r
+ *   VMON channel to enable/disable\r
+ *\r
+ * @param[in] enable\r
+ *   Whether to enable or disable\r
+ ******************************************************************************/\r
+void EMU_VmonEnable(EMU_VmonChannel_TypeDef channel, bool enable)\r
+{\r
+  uint32_t volatile * reg;\r
+  uint32_t bit;\r
+\r
+  switch(channel)\r
+  {\r
+  case emuVmonChannel_AVDD:\r
+    reg = &(EMU->VMONAVDDCTRL);\r
+    bit = _EMU_VMONAVDDCTRL_EN_SHIFT;\r
+    break;\r
+  case emuVmonChannel_ALTAVDD:\r
+    reg = &(EMU->VMONALTAVDDCTRL);\r
+    bit = _EMU_VMONALTAVDDCTRL_EN_SHIFT;\r
+    break;\r
+  case emuVmonChannel_DVDD:\r
+    reg = &(EMU->VMONDVDDCTRL);\r
+    bit = _EMU_VMONDVDDCTRL_EN_SHIFT;\r
+    break;\r
+  case emuVmonChannel_IOVDD0:\r
+    reg = &(EMU->VMONIO0CTRL);\r
+    bit = _EMU_VMONIO0CTRL_EN_SHIFT;\r
+    break;\r
+  default:\r
+    EFM_ASSERT(false);\r
+    return;\r
+  }\r
+\r
+  BUS_RegBitWrite(reg, bit, enable);\r
+}\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Get the status of a voltage monitor channel.\r
+ *\r
+ * @param[in] channel\r
+ *   VMON channel to get status for\r
+ *\r
+ * @return\r
+ *   Status of the selected VMON channel. True if channel is triggered.\r
+ ******************************************************************************/\r
+bool EMU_VmonChannelStatusGet(EMU_VmonChannel_TypeDef channel)\r
+{\r
+  uint32_t bit;\r
+  switch(channel)\r
+  {\r
+  case emuVmonChannel_AVDD:\r
+    bit = _EMU_STATUS_VMONAVDD_SHIFT;\r
+    break;\r
+  case emuVmonChannel_ALTAVDD:\r
+    bit = _EMU_STATUS_VMONALTAVDD_SHIFT;\r
+    break;\r
+  case emuVmonChannel_DVDD:\r
+    bit = _EMU_STATUS_VMONDVDD_SHIFT;\r
+    break;\r
+  case emuVmonChannel_IOVDD0:\r
+    bit = _EMU_STATUS_VMONIO0_SHIFT;\r
+    break;\r
+  default:\r
+    EFM_ASSERT(false);\r
+    bit = 0;\r
+  }\r
+\r
+  return BUS_RegBitRead(&EMU->STATUS, bit);\r
+}\r
+#endif /* EMU_STATUS_VMONRDY */\r
+\r
+/** @} (end addtogroup EMU) */\r
+/** @} (end addtogroup EM_Library) */\r
+#endif /* __EM_EMU_H */\r
diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/emlib/em_gpio.c b/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/emlib/em_gpio.c
new file mode 100644 (file)
index 0000000..46db335
--- /dev/null
@@ -0,0 +1,320 @@
+/***************************************************************************//**\r
+ * @file em_gpio.c\r
+ * @brief General Purpose IO (GPIO) peripheral API\r
+ *   devices.\r
+ * @version 4.2.1\r
+ *******************************************************************************\r
+ * @section License\r
+ * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>\r
+ *******************************************************************************\r
+ *\r
+ * Permission is granted to anyone to use this software for any purpose,\r
+ * including commercial applications, and to alter it and redistribute it\r
+ * freely, subject to the following restrictions:\r
+ *\r
+ * 1. The origin of this software must not be misrepresented; you must not\r
+ *    claim that you wrote the original software.\r
+ * 2. Altered source versions must be plainly marked as such, and must not be\r
+ *    misrepresented as being the original software.\r
+ * 3. This notice may not be removed or altered from any source distribution.\r
+ *\r
+ * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no\r
+ * obligation to support this Software. Silicon Labs is providing the\r
+ * Software "AS IS", with no express or implied warranties of any kind,\r
+ * including, but not limited to, any implied warranties of merchantability\r
+ * or fitness for any particular purpose or warranties against infringement\r
+ * of any proprietary rights of a third party.\r
+ *\r
+ * Silicon Labs will not be liable for any consequential, incidental, or\r
+ * special damages, or any other relief, or for any claim by any third party,\r
+ * arising from your use of this Software.\r
+ *\r
+ ******************************************************************************/\r
+\r
+\r
+#include "em_gpio.h"\r
+\r
+#if defined(GPIO_COUNT) && (GPIO_COUNT > 0)\r
+\r
+/***************************************************************************//**\r
+ * @addtogroup EM_Library\r
+ * @{\r
+ ******************************************************************************/\r
+\r
+/***************************************************************************//**\r
+ * @addtogroup GPIO\r
+ * @brief General Purpose Input/Output (GPIO) API\r
+ * @{\r
+ ******************************************************************************/\r
+\r
+/*******************************************************************************\r
+ *******************************   DEFINES   ***********************************\r
+ ******************************************************************************/\r
+\r
+/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */\r
+\r
+/** Validation of pin typically usable in assert statements. */\r
+#define GPIO_DRIVEMODE_VALID(mode)    ((mode) <= 3)\r
+#define GPIO_STRENGHT_VALID(strenght) (!((strenght) & \\r
+                                         ~(_GPIO_P_CTRL_DRIVESTRENGTH_MASK \\r
+                                           | _GPIO_P_CTRL_DRIVESTRENGTHALT_MASK)))\r
+/** @endcond */\r
+\r
+\r
+/*******************************************************************************\r
+ **************************   GLOBAL FUNCTIONS   *******************************\r
+ ******************************************************************************/\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Sets the pin location of the debug pins (Serial Wire interface).\r
+ *\r
+ * @note\r
+ *   Changing the pins used for debugging uncontrolled, may result in a lockout.\r
+ *\r
+ * @param[in] location\r
+ *   The debug pin location to use (0-3).\r
+ ******************************************************************************/\r
+void GPIO_DbgLocationSet(unsigned int location)\r
+{\r
+#if defined ( _GPIO_ROUTE_SWLOCATION_MASK )\r
+  EFM_ASSERT(location < AFCHANLOC_MAX);\r
+\r
+  GPIO->ROUTE = (GPIO->ROUTE & ~_GPIO_ROUTE_SWLOCATION_MASK) |\r
+                (location << _GPIO_ROUTE_SWLOCATION_SHIFT);\r
+#else\r
+  (void)location;\r
+#endif\r
+}\r
+\r
+#if defined (_GPIO_P_CTRL_DRIVEMODE_MASK)\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Sets the drive mode for a GPIO port.\r
+ *\r
+ * @param[in] port\r
+ *   The GPIO port to access.\r
+ *\r
+ * @param[in] mode\r
+ *   Drive mode to use for port.\r
+ ******************************************************************************/\r
+void GPIO_DriveModeSet(GPIO_Port_TypeDef port, GPIO_DriveMode_TypeDef mode)\r
+{\r
+  EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_DRIVEMODE_VALID(mode));\r
+\r
+  GPIO->P[port].CTRL = (GPIO->P[port].CTRL & ~(_GPIO_P_CTRL_DRIVEMODE_MASK))\r
+                       | (mode << _GPIO_P_CTRL_DRIVEMODE_SHIFT);\r
+}\r
+#endif\r
+\r
+\r
+#if defined (_GPIO_P_CTRL_DRIVESTRENGTH_MASK)\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Sets the drive strength for a GPIO port.\r
+ *\r
+ * @param[in] port\r
+ *   The GPIO port to access.\r
+ *\r
+ * @param[in] strength\r
+ *   Drive strength to use for port.\r
+ ******************************************************************************/\r
+void GPIO_DriveStrengthSet(GPIO_Port_TypeDef port,\r
+                           GPIO_DriveStrength_TypeDef strength)\r
+{\r
+  EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_STRENGHT_VALID(strength));\r
+  BUS_RegMaskedWrite(&GPIO->P[port].CTRL,\r
+                     _GPIO_P_CTRL_DRIVESTRENGTH_MASK | _GPIO_P_CTRL_DRIVESTRENGTHALT_MASK,\r
+                     strength);\r
+}\r
+#endif\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Configure GPIO interrupt.\r
+ *\r
+ * @details\r
+ *   If reconfiguring a GPIO interrupt that is already enabled, it is generally\r
+ *   recommended to disable it first, see GPIO_Disable().\r
+ *\r
+ *   The actual GPIO interrupt handler must be in place before enabling the\r
+ *   interrupt.\r
+ *\r
+ *   Notice that any pending interrupt for the selected pin is cleared by this\r
+ *   function.\r
+ *\r
+ * @note\r
+ *   A certain pin number can only be associated with one port. Ie, if GPIO\r
+ *   interrupt 1 is assigned to port A/pin 1, then it is not possibly to use\r
+ *   pin 1 from any other ports for interrupts. Please refer to the reference\r
+ *   manual.\r
+ *\r
+ * @param[in] port\r
+ *   The port to associate with @p pin.\r
+ *\r
+ * @param[in] pin\r
+ *   The GPIO interrupt number (= port pin).\r
+ *\r
+ * @param[in] risingEdge\r
+ *   Set to true if interrupts shall be enabled on rising edge, otherwise false.\r
+ *\r
+ * @param[in] fallingEdge\r
+ *   Set to true if interrupts shall be enabled on falling edge, otherwise false.\r
+ *\r
+ * @param[in] enable\r
+ *   Set to true if interrupt shall be enabled after configuration completed,\r
+ *   false to leave disabled. See GPIO_IntDisable() and GPIO_IntEnable().\r
+ ******************************************************************************/\r
+void GPIO_IntConfig(GPIO_Port_TypeDef port,\r
+                    unsigned int pin,\r
+                    bool risingEdge,\r
+                    bool fallingEdge,\r
+                    bool enable)\r
+{\r
+  uint32_t tmp;\r
+\r
+  EFM_ASSERT(GPIO_PORT_PIN_VALID(port, pin));\r
+\r
+  /* There are two registers controlling the interrupt configuration:\r
+   * The EXTIPSELL register controls pins 0-7 and EXTIPSELH controls\r
+   * pins 8-15. */\r
+  if (pin < 8)\r
+  {\r
+    BUS_RegMaskedWrite(&GPIO->EXTIPSELL,\r
+                       0xF << (4 * pin),\r
+                       port << (4 * pin));\r
+  }\r
+  else\r
+  {\r
+    tmp             = pin - 8;\r
+    BUS_RegMaskedWrite(&GPIO->EXTIPSELH,\r
+                       0xF << (4 * tmp),\r
+                       port << (4 * tmp));\r
+  }\r
+\r
+  /* Enable/disable rising edge */\r
+  BUS_RegBitWrite(&(GPIO->EXTIRISE), pin, risingEdge);\r
+\r
+  /* Enable/disable falling edge */\r
+  BUS_RegBitWrite(&(GPIO->EXTIFALL), pin, fallingEdge);\r
+\r
+  /* Clear any pending interrupt */\r
+  GPIO->IFC = 1 << pin;\r
+\r
+  /* Finally enable/disable interrupt */\r
+  BUS_RegBitWrite(&(GPIO->IEN), pin, enable);\r
+}\r
+\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Set the mode for a GPIO pin.\r
+ *\r
+ * @param[in] port\r
+ *   The GPIO port to access.\r
+ *\r
+ * @param[in] pin\r
+ *   The pin number in the port.\r
+ *\r
+ * @param[in] mode\r
+ *   The desired pin mode.\r
+ *\r
+ * @param[in] out\r
+ *   Value to set for pin in DOUT register. The DOUT setting is important for\r
+ *   even some input mode configurations, determining pull-up/down direction.\r
+ ******************************************************************************/\r
+void GPIO_PinModeSet(GPIO_Port_TypeDef port,\r
+                     unsigned int pin,\r
+                     GPIO_Mode_TypeDef mode,\r
+                     unsigned int out)\r
+{\r
+  EFM_ASSERT(GPIO_PORT_PIN_VALID(port, pin));\r
+\r
+  /* If disabling pin, do not modify DOUT in order to reduce chance for */\r
+  /* glitch/spike (may not be sufficient precaution in all use cases) */\r
+  if (mode != gpioModeDisabled)\r
+  {\r
+    if (out)\r
+    {\r
+      GPIO_PinOutSet(port, pin);\r
+    }\r
+    else\r
+    {\r
+      GPIO_PinOutClear(port, pin);\r
+    }\r
+  }\r
+\r
+  /* There are two registers controlling the pins for each port. The MODEL\r
+   * register controls pins 0-7 and MODEH controls pins 8-15. */\r
+  if (pin < 8)\r
+  {\r
+    BUS_RegMaskedWrite(&GPIO->P[port].MODEL,\r
+                       0xF << (pin * 4),\r
+                       mode << (pin * 4));\r
+  }\r
+  else\r
+  {\r
+    BUS_RegMaskedWrite(&GPIO->P[port].MODEH,\r
+                       0xF << ((pin - 8) * 4),\r
+                       mode << ((pin - 8) * 4));\r
+  }\r
+\r
+  if (mode == gpioModeDisabled)\r
+  {\r
+    if (out)\r
+    {\r
+      GPIO_PinOutSet(port, pin);\r
+    }\r
+    else\r
+    {\r
+      GPIO_PinOutClear(port, pin);\r
+    }\r
+  }\r
+}\r
+\r
+#if defined( _GPIO_EM4WUEN_MASK )\r
+/**************************************************************************//**\r
+ * @brief\r
+ *   Enable GPIO pin wake-up from EM4. When the function exits,\r
+ *   EM4 mode can be safely entered.\r
+ *\r
+ * @note\r
+ *   It is assumed that the GPIO pin modes are set correctly.\r
+ *   Valid modes are @ref gpioModeInput and @ref gpioModeInputPull.\r
+ *\r
+ * @param[in] pinmask\r
+ *   Bitmask containing the bitwise logic OR of which GPIO pin(s) to enable.\r
+ *   Refer to Reference Manuals for pinmask to GPIO port/pin mapping.\r
+ * @param[in] polaritymask\r
+ *   Bitmask containing the bitwise logic OR of GPIO pin(s) wake-up polarity.\r
+ *   Refer to Reference Manuals for pinmask to GPIO port/pin mapping.\r
+ *****************************************************************************/\r
+void GPIO_EM4EnablePinWakeup(uint32_t pinmask, uint32_t polaritymask)\r
+{\r
+  EFM_ASSERT((pinmask & ~_GPIO_EM4WUEN_MASK) == 0);\r
+\r
+#if defined( _GPIO_EM4WUPOL_MASK )\r
+  EFM_ASSERT((polaritymask & ~_GPIO_EM4WUPOL_MASK) == 0);\r
+  GPIO->EM4WUPOL &= ~pinmask;               /* Set wakeup polarity */\r
+  GPIO->EM4WUPOL |= pinmask & polaritymask;\r
+#elif defined( _GPIO_EXTILEVEL_MASK )\r
+  EFM_ASSERT((polaritymask & ~_GPIO_EXTILEVEL_MASK) == 0);\r
+  GPIO->EXTILEVEL &= ~pinmask;\r
+  GPIO->EXTILEVEL |= pinmask & polaritymask;\r
+#endif\r
+  GPIO->EM4WUEN  |= pinmask;                /* Enable wakeup */\r
+\r
+  GPIO_EM4SetPinRetention(true);            /* Enable pin retention */\r
+\r
+#if defined( _GPIO_CMD_EM4WUCLR_MASK )\r
+  GPIO->CMD = GPIO_CMD_EM4WUCLR;            /* Clear wake-up logic */\r
+#elif defined( _GPIO_IFC_EM4WU_MASK )\r
+  GPIO_IntClear(pinmask);\r
+#endif\r
+}\r
+#endif\r
+\r
+/** @} (end addtogroup GPIO) */\r
+/** @} (end addtogroup EM_Library) */\r
+\r
+#endif /* defined(GPIO_COUNT) && (GPIO_COUNT > 0) */\r
diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/emlib/em_int.c b/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/emlib/em_int.c
new file mode 100644 (file)
index 0000000..cab8c34
--- /dev/null
@@ -0,0 +1,73 @@
+/**************************************************************************//**\r
+ * @file em_int.c\r
+ * @brief Interrupt enable/disable unit API\r
+ * @version 4.2.1\r
+ ******************************************************************************\r
+ * @section License\r
+ * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>\r
+ *******************************************************************************\r
+ *\r
+ * Permission is granted to anyone to use this software for any purpose,\r
+ * including commercial applications, and to alter it and redistribute it\r
+ * freely, subject to the following restrictions:\r
+ *\r
+ * 1. The origin of this software must not be misrepresented; you must not\r
+ *    claim that you wrote the original software.\r
+ * 2. Altered source versions must be plainly marked as such, and must not be\r
+ *    misrepresented as being the original software.\r
+ * 3. This notice may not be removed or altered from any source distribution.\r
+ *\r
+ * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no\r
+ * obligation to support this Software. Silicon Labs is providing the\r
+ * Software "AS IS", with no express or implied warranties of any kind,\r
+ * including, but not limited to, any implied warranties of merchantability\r
+ * or fitness for any particular purpose or warranties against infringement\r
+ * of any proprietary rights of a third party.\r
+ *\r
+ * Silicon Labs will not be liable for any consequential, incidental, or\r
+ * special damages, or any other relief, or for any claim by any third party,\r
+ * arising from your use of this Software.\r
+ *\r
+ ******************************************************************************/\r
+\r
+#include <stdint.h>\r
+#include "em_int.h"\r
+\r
+/***************************************************************************//**\r
+ * @addtogroup EM_Library\r
+ * @{\r
+ ******************************************************************************/\r
+\r
+/***************************************************************************//**\r
+ * @addtogroup INT\r
+ * @brief Safe nesting of interrupt disable/enable API\r
+ * @{\r
+ * @details\r
+ *  This module contains functions to safely disable and enable interrupts\r
+ *  at CPU level. INT_Disable() disables interrupts globally and increments a lock\r
+ *  level counter (counting semaphore). INT_Enable() decrements the lock level \r
+ *  counter and enable interrupts if the counter reaches zero.\r
+ *\r
+ *  These functions would normally be used to secure critical regions, and \r
+ *  to make sure that a critical section that calls into another critical \r
+ *  section does not unintentionally terminate the callee critical section.\r
+ *\r
+ *  These functions should also be used inside interrupt handlers:\r
+ *  @verbatim\r
+ *  void SysTick_Handler(void)\r
+ *  {\r
+ *    INT_Disable();\r
+ *      .\r
+ *      .\r
+ *      .\r
+ *    INT_Enable();\r
+ *  }\r
+ * @endverbatim\r
+ ******************************************************************************/\r
+\r
+/** Interrupt lock level counter. Set to zero initially as we normally enter\r
+ * main with interrupts enabled  */\r
+uint32_t INT_LockCnt = 0;\r
+\r
+/** @} (end addtogroup INT) */\r
+/** @} (end addtogroup EM_Library) */\r
diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/emlib/em_rtcc.c b/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/emlib/em_rtcc.c
new file mode 100644 (file)
index 0000000..c2b0fb5
--- /dev/null
@@ -0,0 +1,180 @@
+/***************************************************************************//**\r
+ * @file\r
+ * @brief Real Time Counter with Calendar (RTCC) Peripheral API\r
+ * @version 4.2.1\r
+ *******************************************************************************\r
+ * @section License\r
+ * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>\r
+ *******************************************************************************\r
+ *\r
+ * Permission is granted to anyone to use this software for any purpose,\r
+ * including commercial applications, and to alter it and redistribute it\r
+ * freely, subject to the following restrictions:\r
+ *\r
+ * 1. The origin of this software must not be misrepresented; you must not\r
+ *    claim that you wrote the original software.\r
+ * 2. Altered source versions must be plainly marked as such, and must not be\r
+ *    misrepresented as being the original software.\r
+ * 3. This notice may not be removed or altered from any source distribution.\r
+ *\r
+ * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no\r
+ * obligation to support this Software. Silicon Labs is providing the\r
+ * Software "AS IS", with no express or implied warranties of any kind,\r
+ * including, but not limited to, any implied warranties of merchantability\r
+ * or fitness for any particular purpose or warranties against infringement\r
+ * of any proprietary rights of a third party.\r
+ *\r
+ * Silicon Labs will not be liable for any consequential, incidental, or\r
+ * special damages, or any other relief, or for any claim by any third party,\r
+ * arising from your use of this Software.\r
+ *\r
+ ******************************************************************************/\r
+\r
+#include "em_rtcc.h"\r
+#if defined( RTCC_COUNT ) && ( RTCC_COUNT == 1 )\r
+#include "em_bus.h"\r
+\r
+/***************************************************************************//**\r
+ * @addtogroup EM_Library\r
+ * @{\r
+ ******************************************************************************/\r
+\r
+/***************************************************************************//**\r
+ * @addtogroup RTCC\r
+ * @brief Real Time Counter (RTCC) Peripheral API\r
+ * @{\r
+ ******************************************************************************/\r
+\r
+/*******************************************************************************\r
+ *******************************   DEFINES   ***********************************\r
+ ******************************************************************************/\r
+\r
+/*******************************************************************************\r
+ **************************   LOCAL FUNCTIONS   ********************************\r
+ ******************************************************************************/\r
+\r
+/*******************************************************************************\r
+ **************************   GLOBAL FUNCTIONS   *******************************\r
+ ******************************************************************************/\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Configure the selected capture/compare channel of the RTCC.\r
+ *\r
+ * @details\r
+ *   Use this function to configure a RTCC channel.\r
+ *   Select capture/compare mode, match output action, overflow output action\r
+ *   and PRS input configuration.\r
+ *   Refer to the configuration structure @ref RTCC_CCChConf_TypeDef for more\r
+ *   details.\r
+ *\r
+ * @param[in] ch\r
+ *   Channel selector.\r
+ *\r
+ * @param[in] confPtr\r
+ *   Pointer to configuration structure.\r
+ ******************************************************************************/\r
+void RTCC_ChannelInit( int ch, RTCC_CCChConf_TypeDef const *confPtr )\r
+{\r
+  EFM_ASSERT( RTCC_CH_VALID( ch ) );\r
+  EFM_ASSERT( (uint32_t)confPtr->compMask\r
+              < ( _RTCC_CC_CTRL_COMPMASK_MASK >> _RTCC_CC_CTRL_COMPMASK_SHIFT )\r
+              + 1 );\r
+\r
+  /** Configure the selected capture/compare channel. */\r
+  RTCC->CC[ch].CTRL = ( (uint32_t)confPtr->chMode << _RTCC_CC_CTRL_MODE_SHIFT )\r
+                      | ( (uint32_t)confPtr->compMatchOutAction << _RTCC_CC_CTRL_CMOA_SHIFT )\r
+                      | ( (uint32_t)confPtr->prsSel << _RTCC_CC_CTRL_PRSSEL_SHIFT )\r
+                      | ( (uint32_t)confPtr->inputEdgeSel << _RTCC_CC_CTRL_ICEDGE_SHIFT )\r
+                      | ( (uint32_t)confPtr->compBase << _RTCC_CC_CTRL_COMPBASE_SHIFT )\r
+                      | ( (uint32_t)confPtr->compMask << _RTCC_CC_CTRL_COMPMASK_SHIFT )\r
+                      | ( (uint32_t)confPtr->dayCompMode << _RTCC_CC_CTRL_DAYCC_SHIFT );\r
+}\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Enable/disable RTCC.\r
+ *\r
+ * @param[in] enable\r
+ *   True to enable RTCC, false to disable.\r
+ ******************************************************************************/\r
+void RTCC_Enable( bool enable )\r
+{\r
+  /* Bitbanding the enable bit in the CTRL register (atomic). */\r
+  BUS_RegBitWrite((&RTCC->CTRL), _RTCC_CTRL_ENABLE_SHIFT, enable);\r
+}\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Initialize RTCC.\r
+ *\r
+ * @details\r
+ *   Note that the compare values must be set separately with RTCC_CompareSet().\r
+ *   That should probably be done prior to the use of this function if\r
+ *   configuring the RTCC to start when initialization is completed.\r
+ *\r
+ * @param[in] init\r
+ *   Pointer to RTCC initialization structure.\r
+ ******************************************************************************/\r
+void RTCC_Init( const RTCC_Init_TypeDef *init )\r
+{\r
+  RTCC->CTRL = ( (uint32_t)init->enable << _RTCC_CTRL_ENABLE_SHIFT )\r
+               | ( (uint32_t)init->debugRun << _RTCC_CTRL_DEBUGRUN_SHIFT )\r
+               | ( (uint32_t)init->precntWrapOnCCV0 << _RTCC_CTRL_PRECCV0TOP_SHIFT )\r
+               | ( (uint32_t)init->cntWrapOnCCV1 << _RTCC_CTRL_CCV1TOP_SHIFT )\r
+               | ( (uint32_t)init->presc << _RTCC_CTRL_CNTPRESC_SHIFT )\r
+               | ( (uint32_t)init->prescMode << _RTCC_CTRL_CNTTICK_SHIFT )\r
+#if defined(_RTCC_CTRL_BUMODETSEN_MASK)\r
+               | ( (uint32_t)init->enaBackupModeSet << _RTCC_CTRL_BUMODETSEN_SHIFT )\r
+#endif\r
+               | ( (uint32_t)init->enaOSCFailDetect << _RTCC_CTRL_OSCFDETEN_SHIFT )\r
+               | ( (uint32_t)init->cntMode << _RTCC_CTRL_CNTMODE_SHIFT )\r
+               | ( (uint32_t)init->disLeapYearCorr << _RTCC_CTRL_LYEARCORRDIS_SHIFT );\r
+}\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Restore RTCC to its reset state.\r
+ ******************************************************************************/\r
+void RTCC_Reset( void )\r
+{\r
+  int i;\r
+\r
+  /* Restore all RTCC registers to their default values. */\r
+  RTCC_Unlock();\r
+  RTCC->CTRL    = _RTCC_CTRL_RESETVALUE;\r
+  RTCC->PRECNT  = _RTCC_PRECNT_RESETVALUE;\r
+  RTCC->CNT     = _RTCC_CNT_RESETVALUE;\r
+  RTCC->TIME    = _RTCC_TIME_RESETVALUE;\r
+  RTCC->DATE    = _RTCC_DATE_RESETVALUE;\r
+  RTCC->IEN     = _RTCC_IEN_RESETVALUE;\r
+  RTCC->IFC     = _RTCC_IFC_MASK;\r
+  RTCC_StatusClear();\r
+  RTCC->EM4WUEN = _RTCC_EM4WUEN_RESETVALUE;\r
+\r
+  for (i = 0; i < 3; i++)\r
+  {\r
+    RTCC->CC[i].CTRL = _RTCC_CC_CTRL_RESETVALUE;\r
+    RTCC->CC[i].CCV  = _RTCC_CC_CCV_RESETVALUE;\r
+    RTCC->CC[i].TIME = _RTCC_CC_TIME_RESETVALUE;\r
+    RTCC->CC[i].DATE = _RTCC_CC_DATE_RESETVALUE;\r
+  }\r
+}\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Clear STATUS register.\r
+ ******************************************************************************/\r
+void RTCC_StatusClear( void )\r
+{\r
+  while ( RTCC->SYNCBUSY & RTCC_SYNCBUSY_CMD )\r
+  {\r
+    // Wait for syncronization.\r
+  }\r
+  RTCC->CMD = RTCC_CMD_CLRSTATUS;\r
+}\r
+\r
+/** @} (end addtogroup RTCC) */\r
+/** @} (end addtogroup EM_Library) */\r
+\r
+#endif /* defined( RTCC_COUNT ) && ( RTCC_COUNT == 1 ) */\r
diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/emlib/em_system.c b/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/SilLabs_Source/emlib/em_system.c
new file mode 100644 (file)
index 0000000..98e8a0a
--- /dev/null
@@ -0,0 +1,121 @@
+/***************************************************************************//**\r
+ * @file em_system.c\r
+ * @brief System Peripheral API\r
+ * @version 4.2.1\r
+ *******************************************************************************\r
+ * @section License\r
+ * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>\r
+ *******************************************************************************\r
+ *\r
+ * Permission is granted to anyone to use this software for any purpose,\r
+ * including commercial applications, and to alter it and redistribute it\r
+ * freely, subject to the following restrictions:\r
+ *\r
+ * 1. The origin of this software must not be misrepresented; you must not\r
+ *    claim that you wrote the original software.\r
+ * 2. Altered source versions must be plainly marked as such, and must not be\r
+ *    misrepresented as being the original software.\r
+ * 3. This notice may not be removed or altered from any source distribution.\r
+ *\r
+ * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no\r
+ * obligation to support this Software. Silicon Labs is providing the\r
+ * Software "AS IS", with no express or implied warranties of any kind,\r
+ * including, but not limited to, any implied warranties of merchantability\r
+ * or fitness for any particular purpose or warranties against infringement\r
+ * of any proprietary rights of a third party.\r
+ *\r
+ * Silicon Labs will not be liable for any consequential, incidental, or\r
+ * special damages, or any other relief, or for any claim by any third party,\r
+ * arising from your use of this Software.\r
+ *\r
+ ******************************************************************************/\r
+\r
+#include "em_system.h"\r
+#include "em_assert.h"\r
+\r
+/***************************************************************************//**\r
+ * @addtogroup EM_Library\r
+ * @{\r
+ ******************************************************************************/\r
+\r
+/***************************************************************************//**\r
+ * @addtogroup SYSTEM\r
+ * @brief System Peripheral API\r
+ * @{\r
+ ******************************************************************************/\r
+\r
+/*******************************************************************************\r
+ **************************   GLOBAL FUNCTIONS   *******************************\r
+ ******************************************************************************/\r
+\r
+/***************************************************************************//**\r
+ * @brief\r
+ *   Get chip major/minor revision.\r
+ *\r
+ * @param[out] rev\r
+ *   Location to place chip revision info.\r
+ ******************************************************************************/\r
+void SYSTEM_ChipRevisionGet(SYSTEM_ChipRevision_TypeDef *rev)\r
+{\r
+  uint8_t tmp;\r
+\r
+  EFM_ASSERT(rev);\r
+\r
+  /* CHIP FAMILY bit [5:2] */\r
+  tmp  = (((ROMTABLE->PID1 & _ROMTABLE_PID1_FAMILYMSB_MASK) >> _ROMTABLE_PID1_FAMILYMSB_SHIFT) << 2);\r
+  /* CHIP FAMILY bit [1:0] */\r
+  tmp |=  ((ROMTABLE->PID0 & _ROMTABLE_PID0_FAMILYLSB_MASK) >> _ROMTABLE_PID0_FAMILYLSB_SHIFT);\r
+  rev->family = tmp;\r
+\r
+  /* CHIP MAJOR bit [3:0] */\r
+  rev->major = (ROMTABLE->PID0 & _ROMTABLE_PID0_REVMAJOR_MASK) >> _ROMTABLE_PID0_REVMAJOR_SHIFT;\r
+\r
+  /* CHIP MINOR bit [7:4] */\r
+  tmp  = (((ROMTABLE->PID2 & _ROMTABLE_PID2_REVMINORMSB_MASK) >> _ROMTABLE_PID2_REVMINORMSB_SHIFT) << 4);\r
+  /* CHIP MINOR bit [3:0] */\r
+  tmp |=  ((ROMTABLE->PID3 & _ROMTABLE_PID3_REVMINORLSB_MASK) >> _ROMTABLE_PID3_REVMINORLSB_SHIFT);\r
+  rev->minor = tmp;\r
+}\r
+\r
+\r
+#if defined(CALIBRATE)\r
+/***************************************************************************//**\r
+ * @brief\r
+ *    Get factory calibration value for a given peripheral register.\r
+ *\r
+ * @param[in] regAddress\r
+ *    Address of register to get a calibration value for.\r
+ *\r
+ * @return\r
+ *    Calibration value for the requested register.\r
+ ******************************************************************************/\r
+uint32_t SYSTEM_GetCalibrationValue(volatile uint32_t *regAddress)\r
+{\r
+  int               regCount;\r
+  CALIBRATE_TypeDef *p;\r
+\r
+  regCount = 1;\r
+  p        = CALIBRATE;\r
+\r
+  for (;; )\r
+  {\r
+    if ((regCount > CALIBRATE_MAX_REGISTERS) ||\r
+        (p->VALUE == 0xFFFFFFFF))\r
+    {\r
+      EFM_ASSERT(false);\r
+      return 0;                 /* End of device calibration table reached. */\r
+    }\r
+\r
+    if (p->ADDRESS == (uint32_t)regAddress)\r
+    {\r
+      return p->VALUE;          /* Calibration value found ! */\r
+    }\r
+\r
+    p++;\r
+    regCount++;\r
+  }\r
+}\r
+#endif /* defined (CALIBRATE) */\r
+\r
+/** @} (end addtogroup SYSTEM) */\r
+/** @} (end addtogroup EM_Library) */\r
diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/main.c b/FreeRTOS/Demo/CORTEX_EFM32_Pearl_Gecko_Simplicity_Studio/main.c
new file mode 100644 (file)
index 0000000..de94bcb
--- /dev/null
@@ -0,0 +1,255 @@
+/*\r
+    FreeRTOS V9.0.0rc1 - Copyright (C) 2016 Real Time Engineers Ltd.\r
+    All rights reserved\r
+\r
+    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
+\r
+    This file is part of the FreeRTOS distribution.\r
+\r
+    FreeRTOS is free software; you can redistribute it and/or modify it under\r
+    the terms of the GNU General Public License (version 2) as published by the\r
+    Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.\r
+\r
+    ***************************************************************************\r
+    >>!   NOTE: The modification to the GPL is included to allow you to     !<<\r
+    >>!   distribute a combined work that includes FreeRTOS without being   !<<\r
+    >>!   obliged to provide the source code for proprietary components     !<<\r
+    >>!   outside of the FreeRTOS kernel.                                   !<<\r
+    ***************************************************************************\r
+\r
+    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
+    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
+    FOR A PARTICULAR PURPOSE.  Full license text is available on the following\r
+    link: http://www.freertos.org/a00114.html\r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS provides completely free yet professionally developed,    *\r
+     *    robust, strictly quality controlled, supported, and cross          *\r
+     *    platform software that is more than just the market leader, it     *\r
+     *    is the industry's de facto standard.                               *\r
+     *                                                                       *\r
+     *    Help yourself get started quickly while simultaneously helping     *\r
+     *    to support the FreeRTOS project by purchasing a FreeRTOS           *\r
+     *    tutorial book, reference manual, or both:                          *\r
+     *    http://www.FreeRTOS.org/Documentation                              *\r
+     *                                                                       *\r
+    ***************************************************************************\r
+\r
+    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading\r
+    the FAQ page "My application does not run, what could be wrong?".  Have you\r
+    defined configASSERT()?\r
+\r
+    http://www.FreeRTOS.org/support - In return for receiving this top quality\r
+    embedded software for free we request you assist our global community by\r
+    participating in the support forum.\r
+\r
+    http://www.FreeRTOS.org/training - Investing in training allows your team to\r
+    be as productive as possible as early as possible.  Now you can receive\r
+    FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
+    Ltd, and the world's leading authority on the world's leading RTOS.\r
+\r
+    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
+    including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
+    compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
+\r
+    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
+    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
+\r
+    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
+    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
+    licenses offer ticketed support, indemnification and commercial middleware.\r
+\r
+    http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+    engineered and independently SIL3 certified version for use in safety and\r
+    mission critical applications that require provable dependability.\r
+\r
+    1 tab == 4 spaces!\r
+*/\r
+\r
+/******************************************************************************\r
+ * This project provides two demo applications.  A simple blinky style project\r
+ * that demonstrates low power tickless functionality, and a more comprehensive\r
+ * test and demo application.  The configCREATE_LOW_POWER_DEMO setting, which is\r
+ * defined in FreeRTOSConfig.h, is used to select between the two, and to select\r
+ * the clock used when demonstrating tickless functionality.\r
+ *\r
+ * The simply blinky low power demo is implemented and described in\r
+ * main_low_power.c.  The more comprehensive test and demo application is\r
+ * implemented and described in main_full.c.\r
+ *\r
+ * This file implements the code that is not demo specific, including the\r
+ * hardware setup and standard FreeRTOS hook functions.\r
+ *\r
+ * ENSURE TO READ THE DOCUMENTATION PAGE FOR THIS PORT AND DEMO APPLICATION ON\r
+ * THE http://www.FreeRTOS.org WEB SITE FOR FULL INFORMATION ON USING THIS DEMO\r
+ * APPLICATION, AND ITS ASSOCIATE FreeRTOS ARCHITECTURE PORT!\r
+ *\r
+ */\r
+\r
+/* FreeRTOS includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+\r
+/* SiLabs includes. */\r
+#include "em_emu.h"\r
+#include "bsp.h"\r
+#include "bsp_trace.h"\r
+#include "sleep.h"\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Configure the hardware as necessary to run this demo.\r
+ */\r
+static void prvSetupHardware( void );\r
+\r
+/*\r
+ * main_low_power() is used when configCREATE_LOW_POWER_DEMO is set to 1.\r
+ * main_full() is used when configCREATE_LOW_POWER_DEMO is set to 0.\r
+ */\r
+#if( configCREATE_LOW_POWER_DEMO != 0 )\r
+       extern void main_low_power( void );\r
+#else\r
+       extern void main_full( void );\r
+#endif /* #if configCREATE_LOW_POWER_DEMO == 1 */\r
+\r
+/* Prototypes for the standard FreeRTOS callback/hook functions implemented\r
+within this file. */\r
+void vApplicationMallocFailedHook( void );\r
+void vApplicationIdleHook( void );\r
+void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );\r
+void vApplicationTickHook( void );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+int main( void )\r
+{\r
+       /* Configure the hardware ready to run the demo. */\r
+       prvSetupHardware();\r
+\r
+       /* The mainCREATE_LOW_POWER_DEMO setting is described at the top\r
+       of this file. */\r
+       #if( configCREATE_LOW_POWER_DEMO != 0 )\r
+       {\r
+               main_low_power();\r
+       }\r
+       #else\r
+       {\r
+               main_full();\r
+       }\r
+       #endif\r
+\r
+       /* Should not get here. */\r
+       return 0;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvSetupHardware( void )\r
+{\r
+EMU_DCDCInit_TypeDef xDCDInit = EMU_DCDCINIT_STK_DEFAULT;\r
+CMU_HFXOInit_TypeDef xHFXOInit = CMU_HFXOINIT_STK_DEFAULT;\r
+\r
+       /* Chip errata */\r
+       CHIP_Init();\r
+\r
+       /* Init DCDC regulator and HFXO with kit specific parameters */\r
+       EMU_DCDCInit( &xDCDInit );\r
+       CMU_HFXOInit( &xHFXOInit );\r
+\r
+       /* Switch HFCLK to HFXO and disable HFRCO */\r
+       CMU_ClockSelectSet( cmuClock_HF, cmuSelect_HFXO );\r
+       CMU_OscillatorEnable( cmuOsc_HFRCO, false, false );\r
+\r
+       /* Initialize LED driver. */\r
+       BSP_LedsInit();\r
+       BSP_LedSet( 0 );\r
+       BSP_LedClear( 1 );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vApplicationMallocFailedHook( void )\r
+{\r
+       /* Called if a call to pvPortMalloc() fails because there is insufficient\r
+       free memory available in the FreeRTOS heap.  pvPortMalloc() is called\r
+       internally by FreeRTOS API functions that create tasks, queues, software\r
+       timers, and semaphores.  The size of the FreeRTOS heap is set by the\r
+       configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */\r
+\r
+       /* Force an assert. */\r
+       configASSERT( ( volatile void * ) NULL );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )\r
+{\r
+       ( void ) pcTaskName;\r
+       ( void ) pxTask;\r
+\r
+       /* Run time stack overflow checking is performed if\r
+       configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2.  This hook\r
+       function is called if a stack overflow is detected. */\r
+\r
+       /* Force an assert. */\r
+       configASSERT( ( volatile void * ) NULL );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vApplicationIdleHook( void )\r
+{\r
+volatile size_t xFreeHeapSpace;\r
+\r
+       /* This is just a trivial example of an idle hook.  It is called on each\r
+       cycle of the idle task.  It must *NOT* attempt to block.  In this case the\r
+       idle task just queries the amount of FreeRTOS heap that remains.  See the\r
+       memory management section on the http://www.FreeRTOS.org web site for memory\r
+       management options.  If there is a lot of heap memory free then the\r
+       configTOTAL_HEAP_SIZE value in FreeRTOSConfig.h can be reduced to free up\r
+       RAM. */\r
+       xFreeHeapSpace = xPortGetFreeHeapSize();\r
+\r
+       /* Remove compiler warning about xFreeHeapSpace being set but never used. */\r
+       ( void ) xFreeHeapSpace;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vApplicationTickHook( void )\r
+{\r
+       /* The full demo includes tests that run from the tick hook. */\r
+       #if( configCREATE_LOW_POWER_DEMO == 0 )\r
+       {\r
+       extern void vFullDemoTickHook( void );\r
+\r
+               /* Some of the tests and demo tasks executed by the full demo include\r
+               interaction from an interrupt - for which the tick interrupt is used\r
+               via the tick hook function. */\r
+               vFullDemoTickHook();\r
+       }\r
+       #endif\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint16_t *pusIdleTaskStackSize )\r
+{\r
+       /* configUSE_STATIC_ALLOCATION is set to 1, so the application has the\r
+       opportunity to supply the buffers that will be used by the Idle task as its\r
+       stack and to hold its TCB.  If these are set to NULL then the buffers will\r
+       be allocated dynamically, just as if xTaskCreate() had been called. */\r
+       *ppxIdleTaskTCBBuffer = NULL;\r
+       *ppxIdleTaskStackBuffer = NULL;\r
+       *pusIdleTaskStackSize = configMINIMAL_STACK_SIZE; /* In words.  NOT in bytes! */\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint16_t *pusTimerTaskStackSize )\r
+{\r
+       /* configUSE_STATIC_ALLOCATION is set to 1, so the application has the\r
+       opportunity to supply the buffers that will be used by the Timer/RTOS daemon\r
+       task as its     stack and to hold its TCB.  If these are set to NULL then the\r
+       buffers will be allocated dynamically, just as if xTaskCreate() had been\r
+       called. */\r
+       *ppxTimerTaskTCBBuffer = NULL;\r
+       *ppxTimerTaskStackBuffer = NULL;\r
+       *pusTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; /* In words.  NOT in bytes! */\r
+}\r
+/*-----------------------------------------------------------*/\r
index dfb7e024a26f0da57af2d9c15976672f0da9d370..3ea860df13ca7c9f2e991d96614d9dfeb14ac0eb 100644 (file)
@@ -923,7 +923,7 @@ typedef struct xSTATIC_TCB
                void                    *pxDummy14;\r
        #endif\r
        #if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 )\r
-               void                    pvDummy15[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];\r
+               void                    *pvDummy15[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];\r
        #endif\r
        #if ( configGENERATE_RUN_TIME_STATS == 1 )\r
                uint32_t                ulDummy16;\r
index bfb0fd88c22a5750698650d0734816c1ee23a20f..2cdfea54da7e0ceaa50ba14fee2e230319503820 100644 (file)
  */\r
 typedef void (*TaskFunction_t)( void * );\r
 \r
-/* Converts a time in milliseconds to a time in ticks. */\r
-#define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000 ) )\r
+/* Converts a time in milliseconds to a time in ticks.  This macro can be\r
+overridden by a macro of the same name defined in FreeRTOSConfig.h in case the\r
+definition here is not suitable for your application. */\r
+#ifndef pdMS_TO_TICKS\r
+       #define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000 ) )\r
+#endif\r
 \r
 #define pdFALSE                        ( ( BaseType_t ) 0 )\r
 #define pdTRUE                 ( ( BaseType_t ) 1 )\r
index 3f6d9fd4f0c65cf78b2a4ccd9425294849d818cb..9fe686e7d987ef8b547c8270bfc88b26622cf29e 100644 (file)
@@ -509,7 +509,6 @@ __asm void xPortPendSVHandler( void )
        #endif\r
 \r
        bx r14\r
-       nop\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
diff --git a/Upgrading-to-FreeRTOS-9.url b/Upgrading-to-FreeRTOS-9.url
new file mode 100644 (file)
index 0000000..716c8e1
--- /dev/null
@@ -0,0 +1,5 @@
+[{000214A0-0000-0000-C000-000000000046}]\r
+Prop3=19,2\r
+[InternetShortcut]\r
+URL=http://www.freertos.org/FreeRTOS-V9.html\r
+IDList=\r