<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Source/SilLabs_Code/kits/EFM32GG_STK3700/config}""/>\r
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Source/SilLabs_Code/Device/SiliconLabs/EFM32GG/Include}""/>\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
*----------------------------------------------------------*/\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
#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
* 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
+++ /dev/null
-/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
* 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
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
* 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
*\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
\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
BSP_TraceProfilerSetup();\r
SLEEP_Init( NULL, NULL );\r
BSP_LedsInit();\r
+\r
+ SLEEP_SleepBlockBegin( configENERGY_MODE );\r
}\r
/*-----------------------------------------------------------*/\r
\r