]> git.sur5r.net Git - freertos/commitdiff
Update EFM32 demos to include an option to use the RTC as the clock source when using...
authorrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Mon, 1 Feb 2016 18:04:50 +0000 (18:04 +0000)
committerrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Mon, 1 Feb 2016 18:04:50 +0000 (18:04 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2412 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/.cproject
FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/FreeRTOSConfig.h
FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Full_Demo/main_full.c
FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Low_Power_Demo/low_power_tick_management.c [deleted file]
FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Low_Power_Demo/low_power_tick_management_BURTC.c [new file with mode: 0644]
FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Low_Power_Demo/low_power_tick_management_RTC.c [new file with mode: 0644]
FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Low_Power_Demo/main_low_power.c
FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/main.c

index f474883a1f4813c388f8a48580d29d4ea92229e0..7529f49236caa4b7d492c9402649246779595020 100644 (file)
@@ -53,7 +53,7 @@
                                                                        <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Source/SilLabs_Code/kits/EFM32GG_STK3700/config}&quot;"/>\r
                                                                        <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Source/SilLabs_Code/Device/SiliconLabs/EFM32GG/Include}&quot;"/>\r
                                                                </option>\r
-                                                               <option id="gnu.c.compiler.option.preprocessor.undef.symbol.1550566013" name="Undefined symbols (-U)" superClass="gnu.c.compiler.option.preprocessor.undef.symbol" valueType="undefDefinedSymbols"/>\r
+                                                               <option id="gnu.c.compiler.option.preprocessor.undef.symbol.1550566013" name="Undefined symbols (-U)" superClass="gnu.c.compiler.option.preprocessor.undef.symbol"/>\r
                                                                <inputType id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input.733848972" 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.1840601111" name="GNU ARM C++ Compiler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.base">\r
                                                        <tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.archiver.base.1920617400" name="GNU ARM Archiver" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.archiver.base"/>\r
                                                </toolChain>\r
                                        </folderInfo>\r
+                                       <fileInfo id="com.silabs.ide.si32.gcc.debug#com.silabs.ide.si32.gcc:4.8.3.20131129.566130702" name="low_power_tick_management_BURTC.c" rcbsApplicability="disable" resourcePath="Source/Low_Power_Demo/low_power_tick_management_BURTC.c" toolsToInvoke="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base.1299820402.669016646">\r
+                                               <tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base.1299820402.669016646" name="GNU ARM C Compiler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base.1299820402"/>\r
+                                       </fileInfo>\r
                                        <sourceEntries>\r
                                                <entry excluding="Source/FreeRTOS_Source/portable/GCC/ARM_CM4F|Source/SilLabs_Code/kits/EFM32WG_STK3800|Source/SilLabs_Code/Device/SiliconLabs/EFM32GG/Source|Source/SilLabs_Code/Device/SiliconLabs/EFM32WG|Source/SilLabs_Code/CMSIS/efm32wg|CMSIS/efm32wg|Source/SilLabs_Code/kits/bsp/bsp_dk_3201.c|Source/SilLabs_Code/kits/bsp/bsp_dk_3200.c|Source/SilLabs_Code/kits/bsp/bsp_dk_leds.c|Source/RTT|Source/SilLabs_Code/kits/bsp/bsp_dk_mcuboard.c|Source/SilLabs_Code/kits/bsp/bsp_bcc.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>\r
                                        </sourceEntries>\r
index 8c9f5192b0bc55384178dd024eef6dc1ceb7039d..e0f66cd52dd03180cc59905efa2a69ff776088ce 100644 (file)
@@ -87,16 +87,50 @@ extern "C" {
  *----------------------------------------------------------*/\r
 \r
 \r
-/* Set configCREATE_LOW_POWER_DEMO to one to run the simple blinky demo low power\r
-example, or 1 to run the more comprehensive test and demo application.  See\r
-the comments at the top of main.c for more information. */\r
-#define configCREATE_LOW_POWER_DEMO    1\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 BURTC.  EM3 will be entered, but use of the ULFRCO\r
+ *    clock means timing will be inaccurate.\r
+ * 2: Build the simple blinky tickless low power demo, generating the tick from\r
+ *    the RTC.  EM2 will be entered.  The LXFO clock is used, which is more\r
+ *    accurate than the ULFRCO clock.\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    2\r
 \r
 /* Some configuration is dependent on the demo being built. */\r
-#if( configCREATE_LOW_POWER_DEMO == 1 )\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
+#elif( configCREATE_LOW_POWER_DEMO == 1 )\r
+\r
+       /* Tickless idle mode, generating RTOS tick interrupts from the BURTC, fed\r
+       by the [inaccurate] ULFRCO clock. */\r
 \r
        /* The slow clock used to generate the tick interrupt in the low power demo\r
-       runs at 32768Hz.  Ensure the clock is a multiple of the tick rate. */\r
+       runs at 2KHz.  Ensure the tick rate is a multiple of the clock. */\r
        #define configTICK_RATE_HZ                              ( 100 )\r
 \r
        /* The low power demo uses the tickless idle feature. */\r
@@ -108,23 +142,27 @@ the comments at the top of main.c for more information. */
        #define configUSE_MALLOC_FAILED_HOOK    ( 0 )\r
        #define configUSE_IDLE_HOOK                             ( 0 )\r
 \r
-#else\r
+       #define configENERGY_MODE                               ( sleepEM4 )\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
+#elif( configCREATE_LOW_POWER_DEMO == 2 )\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
+       /* 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                             ( 1 )\r
-       #define configCHECK_FOR_STACK_OVERFLOW  ( 1 )\r
-       #define configUSE_MALLOC_FAILED_HOOK    ( 1 )\r
-       #define configUSE_IDLE_HOOK  ( 1 )\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
+       #define configENERGY_MODE                               ( sleepEM3 )\r
 \r
 #endif\r
 \r
index 4d1dc0a5ac91bdcd64cd4b792d7d5cc2f4624028..83e33d95325fdfd3e5f951df4e5a924228e401e2 100644 (file)
@@ -71,8 +71,9 @@
  * 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.  See the notes\r
- * on using conifgCREATE_LOW_POWER_DEMO in main.c.  This file implements the\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
diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Low_Power_Demo/low_power_tick_management.c b/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Low_Power_Demo/low_power_tick_management.c
deleted file mode 100644 (file)
index e7ab762..0000000
+++ /dev/null
@@ -1,328 +0,0 @@
-/*\r
-    FreeRTOS V8.2.3 - Copyright (C) 2015 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
-#warning Not functioning correctly above -O1 optimisation level.\r
-\r
-/* Standard includes. */\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_burtc.h"\r
-#include "em_rmu.h"\r
-#include "em_int.h"\r
-#include "sleep.h"\r
-\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
-#define mainTIMER_FREQUENCY_HZ ( 2000UL )\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
-/* 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 BURTC clock, as the tick is generated from the low power BURTC\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
-/* Calculate the maximum number of ticks that can be suppressed when using the\r
-high resolution clock and low resolution clock respectively. */\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 an timer interrupt or a different interrupt. */\r
-static volatile uint32_t ulTickFlag = pdFALSE;\r
-\r
-/* As the clock is only 2KHz, it is likely a value of 1 will be too much, so\r
-use zero - but leave the value here to assist porting to different clock\r
-speeds. */\r
-static const uint32_t ulStoppedTimerCompensation = 0UL;\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void vPortSetupTimerInterrupt( void )\r
-{\r
-BURTC_Init_TypeDef xBURTCInitStruct = BURTC_INIT_DEFAULT;\r
-\r
-       xMaximumPossibleSuppressedTicks = ULONG_MAX / ulReloadValueForOneTick;\r
-\r
-       /* Ensure LE modules are accessible. */\r
-       CMU_ClockEnable( cmuClock_CORELE, true );\r
-\r
-       /* Enable access to BURTC registers. */\r
-       RMU_ResetControl( rmuResetBU, false );\r
-\r
-       /* Generate the tick interrupt from BURTC. */\r
-       xBURTCInitStruct.mode   = burtcModeEM3;         /* Operational in EM3. */\r
-       xBURTCInitStruct.clkSel = burtcClkSelULFRCO;/* ULFRCO clock. */\r
-       xBURTCInitStruct.clkDiv = burtcClkDiv_1;        /* 2kHz ULFRCO clock. */\r
-       xBURTCInitStruct.compare0Top = true;            /* Wrap on COMP0. */\r
-       BURTC_IntDisable( BURTC_IF_COMP0 );\r
-       BURTC_Init( &xBURTCInitStruct );\r
-\r
-       /* The tick interrupt must be set to the lowest possible. */\r
-       NVIC_SetPriority( BURTC_IRQn, configKERNEL_INTERRUPT_PRIORITY );\r
-       NVIC_ClearPendingIRQ( BURTC_IRQn );\r
-       NVIC_EnableIRQ( BURTC_IRQn );\r
-       BURTC_CompareSet( 0, ulReloadValueForOneTick );\r
-       BURTC_IntClear( BURTC_IF_COMP0 );\r
-       BURTC_IntEnable( BURTC_IF_COMP0 );\r
-       BURTC_CounterReset();\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )\r
-{\r
-uint32_t ulReloadValue, ulCompleteTickPeriods, ulCurrentCount;\r
-eSleepModeStatus eSleepAction;\r
-TickType_t xModifiableIdleTime;\r
-\r
-       /* THIS FUNCTION IS CALLED WITH THE SCHEDULER SUSPENDED. */\r
-\r
-       /* Make sure the BURTC 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 BURTC is going to be stopped\r
-               momentarily. */\r
-               ulReloadValue -= ulStoppedTimerCompensation;\r
-       }\r
-\r
-       /* Stop the BURTC momentarily.  The time the BURTC is stopped for is\r
-       accounted 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 respect\r
-       to calendar time.  The count is latched before stopping the timer as\r
-       stopping the timer appears to clear the count. */\r
-       ulCurrentCount = BURTC_CounterGet();\r
-       BURTC_Enable( false );\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
-\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
-               BURTC_CompareSet( 0, ulReloadValueForOneTick - ulCurrentCount );\r
-               BURTC_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 -= ulCurrentCount;\r
-               BURTC_CompareSet( 0, ulReloadValue );\r
-\r
-               /* Restart the BURTC. */\r
-               BURTC_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 BURTC.  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
-               ulCurrentCount = BURTC_CounterGet();\r
-               BURTC_Enable( false );\r
-\r
-               /* Re-enable interrupts - see comments above the cpsid instruction()\r
-               above. */\r
-               INT_Enable();\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 - ulCurrentCount;\r
-                       BURTC_CompareSet( 0, 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? */\r
-                       ulCompleteTickPeriods = ulCurrentCount / ulReloadValueForOneTick;\r
-\r
-                       /* The reload value is set to whatever fraction of a single tick\r
-                       period remains. */\r
-                       ulReloadValue = ulCurrentCount - ( ulCompleteTickPeriods * ulReloadValueForOneTick );\r
-                       if( ulReloadValue == 0 )\r
-                       {\r
-                               /* There is no fraction remaining. */\r
-                               ulReloadValue = ulReloadValueForOneTick;\r
-                               ulCompleteTickPeriods++;\r
-                       }\r
-\r
-                       BURTC_CompareSet( 0, ulReloadValue );\r
-               }\r
-\r
-               /* Restart the BURTC 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 BURTC interrupt executes. */\r
-               BURTC_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 BURTC_IRQHandler(void)\r
-{\r
-       if( ulTickFlag == pdFALSE )\r
-       {\r
-               /* Set BURTC interrupt to one system tick period*/\r
-               BURTC_Enable( false );\r
-               BURTC_CompareSet( 0, ulReloadValueForOneTick );\r
-               ulTickFlag = pdTRUE;\r
-               BURTC_Enable( true );\r
-       }\r
-\r
-       BURTC_IntClear( _RTC_IFC_MASK );\r
-\r
-       /* Critical section which protect incrementing the tick*/\r
-       ( void ) portSET_INTERRUPT_MASK_FROM_ISR();\r
-       {\r
-               if( xTaskIncrementTick() != pdFALSE )\r
-               {\r
-                       /* Pend a context switch. */\r
-                       portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;\r
-               }\r
-       }\r
-       portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );\r
-}\r
-\r
-#endif /* ( configCREATE_LOW_POWER_DEMO == 1 ) */\r
-\r
diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Low_Power_Demo/low_power_tick_management_BURTC.c b/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Low_Power_Demo/low_power_tick_management_BURTC.c
new file mode 100644 (file)
index 0000000..6f3e380
--- /dev/null
@@ -0,0 +1,332 @@
+/*\r
+    FreeRTOS V8.2.3 - Copyright (C) 2015 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
+#warning Not functioning correctly above -O1 optimisation level.\r
+\r
+/* Standard includes. */\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_burtc.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
+#define mainTIMER_FREQUENCY_HZ ( 2000UL )\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 BURTC clock, as the tick is generated from the low power BURTC\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 2KHz, it is likely a value of 1 will be too much, so\r
+use zero - but leave the value here to assist porting to different clock\r
+speeds. */\r
+static const uint32_t ulStoppedTimerCompensation = 0UL;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void vPortSetupTimerInterrupt( void )\r
+{\r
+BURTC_Init_TypeDef xBURTCInitStruct = BURTC_INIT_DEFAULT;\r
+\r
+       /* Configure the BURTC to generate the RTOS tick interrupt. */\r
+\r
+       xMaximumPossibleSuppressedTicks = ULONG_MAX / ulReloadValueForOneTick;\r
+\r
+       /* Ensure LE modules are accessible. */\r
+       CMU_ClockEnable( cmuClock_CORELE, true );\r
+\r
+       /* Enable access to BURTC registers. */\r
+       RMU_ResetControl( rmuResetBU, false );\r
+\r
+       /* Generate the tick interrupt from BURTC. */\r
+       xBURTCInitStruct.mode   = burtcModeEM3;         /* Operational in EM3. */\r
+       xBURTCInitStruct.clkSel = burtcClkSelULFRCO;/* ULFRCO clock. */\r
+       xBURTCInitStruct.clkDiv = burtcClkDiv_1;        /* 2kHz ULFRCO clock. */\r
+       xBURTCInitStruct.compare0Top = true;            /* Wrap on COMP0. */\r
+       BURTC_IntDisable( BURTC_IF_COMP0 );\r
+       BURTC_Init( &xBURTCInitStruct );\r
+\r
+       /* The tick interrupt must be set to the lowest priority possible. */\r
+       NVIC_SetPriority( BURTC_IRQn, configKERNEL_INTERRUPT_PRIORITY );\r
+       NVIC_ClearPendingIRQ( BURTC_IRQn );\r
+       NVIC_EnableIRQ( BURTC_IRQn );\r
+       BURTC_CompareSet( 0, ulReloadValueForOneTick );\r
+       BURTC_IntClear( BURTC_IF_COMP0 );\r
+       BURTC_IntEnable( BURTC_IF_COMP0 );\r
+       BURTC_CounterReset();\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )\r
+{\r
+uint32_t ulReloadValue, ulCompleteTickPeriods, ulCurrentCount;\r
+eSleepModeStatus eSleepAction;\r
+TickType_t xModifiableIdleTime;\r
+\r
+       /* THIS FUNCTION IS CALLED WITH THE SCHEDULER SUSPENDED. */\r
+\r
+       /* Make sure the BURTC 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 BURTC is going to be stopped\r
+               momentarily. */\r
+               ulReloadValue -= ulStoppedTimerCompensation;\r
+       }\r
+\r
+       /* Stop the BURTC momentarily.  The time the BURTC is stopped for is\r
+       accounted 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 respect\r
+       to calendar time.  The count is latched before stopping the timer as\r
+       stopping the timer appears to clear the count. */\r
+       ulCurrentCount = BURTC_CounterGet();\r
+       BURTC_Enable( false );\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
+\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
+               BURTC_CompareSet( 0, ulReloadValueForOneTick - ulCurrentCount );\r
+               BURTC_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 -= ulCurrentCount;\r
+               BURTC_CompareSet( 0, ulReloadValue );\r
+\r
+               /* Restart the BURTC. */\r
+               BURTC_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 BURTC.  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
+               ulCurrentCount = BURTC_CounterGet();\r
+               BURTC_Enable( false );\r
+\r
+               /* Re-enable interrupts - see comments above the cpsid instruction()\r
+               above. */\r
+               INT_Enable();\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 - ulCurrentCount;\r
+                       BURTC_CompareSet( 0, 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? */\r
+                       ulCompleteTickPeriods = ulCurrentCount / ulReloadValueForOneTick;\r
+\r
+                       /* The reload value is set to whatever fraction of a single tick\r
+                       period remains. */\r
+                       ulReloadValue = ulCurrentCount - ( ulCompleteTickPeriods * ulReloadValueForOneTick );\r
+                       if( ulReloadValue == 0 )\r
+                       {\r
+                               /* There is no fraction remaining. */\r
+                               ulReloadValue = ulReloadValueForOneTick;\r
+                               ulCompleteTickPeriods++;\r
+                       }\r
+\r
+                       BURTC_CompareSet( 0, ulReloadValue );\r
+               }\r
+\r
+               /* Restart the BURTC 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 BURTC interrupt executes. */\r
+               BURTC_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 BURTC_IRQHandler( void )\r
+{\r
+       if( ulTickFlag == pdFALSE )\r
+       {\r
+               /* Set BURTC interrupt to one RTOS tick period. */\r
+               BURTC_Enable( false );\r
+               BURTC_CompareSet( 0, ulReloadValueForOneTick );\r
+               ulTickFlag = pdTRUE;\r
+               BURTC_Enable( true );\r
+       }\r
+\r
+       BURTC_IntClear( _RTC_IFC_MASK );\r
+\r
+       /* Critical section which protect incrementing the tick*/\r
+       ( void ) portSET_INTERRUPT_MASK_FROM_ISR();\r
+       {\r
+               if( xTaskIncrementTick() != pdFALSE )\r
+               {\r
+                       /* Pend a context switch. */\r
+                       portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;\r
+               }\r
+       }\r
+       portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );\r
+}\r
+\r
+#endif /* ( configCREATE_LOW_POWER_DEMO == 1 ) */\r
+\r
diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Low_Power_Demo/low_power_tick_management_RTC.c b/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Low_Power_Demo/low_power_tick_management_RTC.c
new file mode 100644 (file)
index 0000000..d736f26
--- /dev/null
@@ -0,0 +1,341 @@
+/*\r
+    FreeRTOS V8.2.3 - Copyright (C) 2015 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
+/* FreeRTOS includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+\r
+/* SiLabs library includes. */\r
+#include "em_cmu.h"\r
+#include "em_rtc.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 == 2 )\r
+\r
+#define mainTIMER_FREQUENCY_HZ ( 4096UL ) /* 32768 clock divided by 8. */\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
+/*-----------------------------------------------------------*/\r
+\r
+void vPortSetupTimerInterrupt( void )\r
+{\r
+RTC_Init_TypeDef xRTCInitStruct;\r
+const uint32_t ulMAX24BitValue = 0xffffffUL;\r
+\r
+       xMaximumPossibleSuppressedTicks = ulMAX24BitValue / ulReloadValueForOneTick;\r
+\r
+       /* Configure the RTC to generate the RTOS tick interrupt. */\r
+\r
+       /* LXFO setup.  For rev D use 70% boost */\r
+       CMU->CTRL = ( CMU->CTRL & ~_CMU_CTRL_LFXOBOOST_MASK ) | CMU_CTRL_LFXOBOOST_70PCENT;\r
+       #if defined( EMU_AUXCTRL_REDLFXOBOOST )\r
+               EMU->AUXCTRL = (EMU->AUXCTRL & ~_EMU_AUXCTRL_REDLFXOBOOST_MASK) | EMU_AUXCTRL_REDLFXOBOOST;\r
+       #endif\r
+\r
+       /* Ensure LE modules are accessible. */\r
+       CMU_ClockEnable( cmuClock_CORELE, true );\r
+\r
+       /* Use LFXO. */\r
+       CMU_ClockSelectSet( cmuClock_LFA, cmuSelect_LFXO );\r
+\r
+       /* Use 8x divider to reduce energy. */\r
+       CMU_ClockDivSet( cmuClock_RTC, cmuClkDiv_8 );\r
+\r
+       /* Enable clock to the RTC module. */\r
+       CMU_ClockEnable( cmuClock_RTC, true );\r
+       xRTCInitStruct.enable = false;\r
+       xRTCInitStruct.debugRun = false;\r
+       xRTCInitStruct.comp0Top = true;\r
+       RTC_Init( &xRTCInitStruct );\r
+\r
+       /* Disable RTC0 interrupt. */\r
+       RTC_IntDisable( RTC_IFC_COMP0 );\r
+\r
+       /* The tick interrupt must be set to the lowest priority possible. */\r
+       NVIC_SetPriority( RTC_IRQn, configKERNEL_INTERRUPT_PRIORITY );\r
+       NVIC_ClearPendingIRQ( RTC_IRQn );\r
+       NVIC_EnableIRQ( RTC_IRQn );\r
+       RTC_CompareSet( 0, ulReloadValueForOneTick );\r
+       RTC_IntClear( RTC_IFC_COMP0 );\r
+       RTC_IntEnable( RTC_IF_COMP0 );\r
+       RTC_Enable( true );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )\r
+{\r
+uint32_t ulReloadValue, ulCompleteTickPeriods, ulCurrentCount;\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
+       ulCurrentCount = RTC_CounterGet();\r
+       RTC_Enable( false );\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
+               RTC_CompareSet( 0, ulReloadValueForOneTick - ulCurrentCount );\r
+               RTC_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 -= ulCurrentCount;\r
+               RTC_CompareSet( 0, ulReloadValue );\r
+\r
+               /* Restart the RTC. */\r
+               RTC_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
+               ulCurrentCount = RTC_CounterGet();\r
+               RTC_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 - ulCurrentCount;\r
+                       RTC_CompareSet( 0, 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? */\r
+                       ulCompleteTickPeriods = ulCurrentCount / ulReloadValueForOneTick;\r
+\r
+                       /* The reload value is set to whatever fraction of a single tick\r
+                       period remains. */\r
+                       ulReloadValue = ulCurrentCount - ( ulCompleteTickPeriods * ulReloadValueForOneTick );\r
+                       if( ulReloadValue == 0 )\r
+                       {\r
+                               /* There is no fraction remaining. */\r
+                               ulReloadValue = ulReloadValueForOneTick;\r
+                               ulCompleteTickPeriods++;\r
+                       }\r
+\r
+                       RTC_CompareSet( 0, 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
+               RTC_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 RTC_IRQHandler( void )\r
+{\r
+       if( ulTickFlag == pdFALSE )\r
+       {\r
+               /* Set RTC interrupt to one RTOS tick period. */\r
+               RTC_Enable( false );\r
+               RTC_CompareSet( 0, ulReloadValueForOneTick );\r
+               ulTickFlag = pdTRUE;\r
+               RTC_Enable( true );\r
+       }\r
+\r
+       RTC_IntClear( _RTC_IFC_MASK );\r
+\r
+       /* Critical section which protect incrementing the tick*/\r
+       ( void ) portSET_INTERRUPT_MASK_FROM_ISR();\r
+       {\r
+               if( xTaskIncrementTick() != pdFALSE )\r
+               {\r
+                       /* Pend a context switch. */\r
+                       portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;\r
+               }\r
+       }\r
+       portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );\r
+}\r
+\r
+#endif /* ( configCREATE_LOW_POWER_DEMO == 1 ) */\r
+\r
index fe4824d8c6c90bb7dfbddbbe61bc084d4c6f62c4..ce30aa2400c1c37e998f17588ede041ffad68604 100644 (file)
  * 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.  See the notes on using\r
- * configCREATE_LOW_POWER_DEMO in main.c.  This file implements the low power\r
- * version.\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
@@ -211,7 +212,7 @@ const TickType_t xShortDelay = pdMS_TO_TICKS( 10 );
                if( ulReceivedValue == ulExpectedValue )\r
                {\r
                        /* Turn the LED on for a brief time only so it doens't distort the\r
-                       enerty reading. */\r
+                       energy reading. */\r
                        BSP_LedSet( mainTASK_LED );\r
                        vTaskDelay( xShortDelay );\r
                        BSP_LedClear( mainTASK_LED );\r
index 174073296e827227d7b5da8c24da66c437c8b095..fe76f5464c9413a2272ba6068669d3b300461856 100644 (file)
  * 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.  The simply\r
- * blinky low power demo is implemented and described in main_low_power.c.  The\r
- * more comprehensive test and demo application is implemented and described in\r
- * main_full.c.\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
@@ -85,6 +87,8 @@
  *\r
  */\r
 \r
+#warning Check the tick suppression routine in the case where the system unblocks before an entire tick period has expired.\r
+\r
 /* FreeRTOS includes. */\r
 #include "FreeRTOS.h"\r
 #include "task.h"\r
@@ -132,7 +136,7 @@ int main( void )
 \r
        /* The mainCREATE_LOW_POWER_DEMO setting is described at the top\r
        of this file. */\r
-       #if( configCREATE_LOW_POWER_DEMO == 1 )\r
+       #if( configCREATE_LOW_POWER_DEMO != 0 )\r
        {\r
                main_low_power();\r
        }\r
@@ -154,6 +158,8 @@ static void prvSetupHardware( void )
        BSP_TraceProfilerSetup();\r
        SLEEP_Init( NULL, NULL );\r
        BSP_LedsInit();\r
+\r
+       SLEEP_SleepBlockBegin( configENERGY_MODE );\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r