diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/.cproject b/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/.cproject
index f474883a1..7529f4923 100644
--- a/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/.cproject
+++ b/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/.cproject
@@ -53,7 +53,7 @@
-
+
@@ -103,6 +103,9 @@
+
+
+
diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/FreeRTOSConfig.h b/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/FreeRTOSConfig.h
index 8c9f5192b..e0f66cd52 100644
--- a/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/FreeRTOSConfig.h
+++ b/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/FreeRTOSConfig.h
@@ -87,16 +87,50 @@ extern "C" {
*----------------------------------------------------------*/
-/* Set configCREATE_LOW_POWER_DEMO to one to run the simple blinky demo low power
-example, or 1 to run the more comprehensive test and demo application. See
-the comments at the top of main.c for more information. */
-#define configCREATE_LOW_POWER_DEMO 1
+/* Set configCREATE_LOW_POWER_DEMO as follows:
+ *
+ * 0: Build the full test and demo application.
+ * 1: Build the simple blinky tickless low power demo, generating the tick
+ * interrupt from the BURTC. EM3 will be entered, but use of the ULFRCO
+ * clock means timing will be inaccurate.
+ * 2: Build the simple blinky tickless low power demo, generating the tick from
+ * the RTC. EM2 will be entered. The LXFO clock is used, which is more
+ * accurate than the ULFRCO clock.
+ * See the comments at the top of main.c, main_full.c and main_low_power.c for
+ * more information.
+ */
+#define configCREATE_LOW_POWER_DEMO 2
/* Some configuration is dependent on the demo being built. */
-#if( configCREATE_LOW_POWER_DEMO == 1 )
+#if( configCREATE_LOW_POWER_DEMO == 0 )
+
+ /* Tickless mode is not used. */
+
+ /* Some of the standard demo test tasks assume a tick rate of 1KHz, even
+ though that is faster than would normally be warranted by a real
+ application. */
+ #define configTICK_RATE_HZ ( 1000 )
+
+ /* The full demo always has tasks to run so the tick will never be turned
+ off. The blinky demo will use the default tickless idle implementation to
+ turn the tick off. */
+ #define configUSE_TICKLESS_IDLE 0
+
+ /* Hook function related definitions. */
+ #define configUSE_TICK_HOOK ( 1 )
+ #define configCHECK_FOR_STACK_OVERFLOW ( 1 )
+ #define configUSE_MALLOC_FAILED_HOOK ( 1 )
+ #define configUSE_IDLE_HOOK ( 1 )
+
+ #define configENERGY_MODE ( sleepEM3 )
+
+#elif( configCREATE_LOW_POWER_DEMO == 1 )
+
+ /* Tickless idle mode, generating RTOS tick interrupts from the BURTC, fed
+ by the [inaccurate] ULFRCO clock. */
/* The slow clock used to generate the tick interrupt in the low power demo
- runs at 32768Hz. Ensure the clock is a multiple of the tick rate. */
+ runs at 2KHz. Ensure the tick rate is a multiple of the clock. */
#define configTICK_RATE_HZ ( 100 )
/* The low power demo uses the tickless idle feature. */
@@ -108,23 +142,27 @@ the comments at the top of main.c for more information. */
#define configUSE_MALLOC_FAILED_HOOK ( 0 )
#define configUSE_IDLE_HOOK ( 0 )
-#else
+ #define configENERGY_MODE ( sleepEM4 )
- /* Some of the standard demo test tasks assume a tick rate of 1KHz, even
- though that is faster than would normally be warranted by a real
- application. */
- #define configTICK_RATE_HZ ( 1000 )
+#elif( configCREATE_LOW_POWER_DEMO == 2 )
- /* The full demo always has tasks to run so the tick will never be turned
- off. The blinky demo will use the default tickless idle implementation to
- turn the tick off. */
- #define configUSE_TICKLESS_IDLE 0
+ /* Tickless idle mode, generating RTOS tick interrupts from the RTC, fed
+ by the LXFO clock. */
+
+ /* The slow clock used to generate the tick interrupt in the low power demo
+ runs at 32768/8=4096Hz. Ensure the tick rate is a multiple of the clock. */
+ #define configTICK_RATE_HZ ( 128 )
+
+ /* The low power demo uses the tickless idle feature. */
+ #define configUSE_TICKLESS_IDLE 1
/* Hook function related definitions. */
- #define configUSE_TICK_HOOK ( 1 )
- #define configCHECK_FOR_STACK_OVERFLOW ( 1 )
- #define configUSE_MALLOC_FAILED_HOOK ( 1 )
- #define configUSE_IDLE_HOOK ( 1 )
+ #define configUSE_TICK_HOOK ( 0 )
+ #define configCHECK_FOR_STACK_OVERFLOW ( 0 )
+ #define configUSE_MALLOC_FAILED_HOOK ( 0 )
+ #define configUSE_IDLE_HOOK ( 0 )
+
+ #define configENERGY_MODE ( sleepEM3 )
#endif
diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Full_Demo/main_full.c b/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Full_Demo/main_full.c
index 4d1dc0a5a..83e33d953 100644
--- a/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Full_Demo/main_full.c
+++ b/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Full_Demo/main_full.c
@@ -71,8 +71,9 @@
* NOTE 1: This project provides two demo applications. A simple blinky style
* project that demonstrates the tickless low power features of FreeRTOS, and a
* more comprehensive test and demo application. The configCREATE_LOW_POWER_DEMO
- * setting in FreeRTOSConifg.h is used to select between the two. See the notes
- * on using conifgCREATE_LOW_POWER_DEMO in main.c. This file implements the
+ * setting in FreeRTOSConifg.h is used to select between the two, and to select
+ * the clock used when tickless mode is used. See the notes on using
+ * conifgCREATE_LOW_POWER_DEMO in main.c. This file implements the
* comprehensive test and demo version.
*
* NOTE 2: This file only contains the source code that is specific to the
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_BURTC.c
similarity index 93%
rename from FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Low_Power_Demo/low_power_tick_management.c
rename to FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Low_Power_Demo/low_power_tick_management_BURTC.c
index e7ab76250..6f3e38085 100644
--- 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_BURTC.c
@@ -83,7 +83,9 @@
#include "em_int.h"
#include "sleep.h"
-/* This file contains functions that will override the default implementations
+/* SEE THE COMMENTS ABOVE THE DEFINITION OF configCREATE_LOW_POWER_DEMO IN
+FreeRTOSConfig.h
+This file contains functions that will override the default implementations
in the RTOS port layer. Therefore only build this file if the low power demo
is being built. */
#if( configCREATE_LOW_POWER_DEMO == 1 )
@@ -98,7 +100,8 @@ is being built. */
*/
void vPortSetupTimerInterrupt( void );
-/* Override the default definition of vPortSuppressTicksAndSleep() that is
+/*
+ * Override the default definition of vPortSuppressTicksAndSleep() that is
* weakly defined in the FreeRTOS Cortex-M port layer with a version that
* manages the BURTC clock, as the tick is generated from the low power BURTC
* and not the SysTick as would normally be the case on a Cortex-M.
@@ -110,12 +113,11 @@ void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
/* Calculate how many clock increments make up a single tick period. */
static const uint32_t ulReloadValueForOneTick = ( mainTIMER_FREQUENCY_HZ / configTICK_RATE_HZ );
-/* Calculate the maximum number of ticks that can be suppressed when using the
-high resolution clock and low resolution clock respectively. */
+/* Will hold the maximum number of ticks that can be suppressed. */
static uint32_t xMaximumPossibleSuppressedTicks = 0;
/* Flag set from the tick interrupt to allow the sleep processing to know if
-sleep mode was exited because of an timer interrupt or a different interrupt. */
+sleep mode was exited because of a timer interrupt or a different interrupt. */
static volatile uint32_t ulTickFlag = pdFALSE;
/* As the clock is only 2KHz, it is likely a value of 1 will be too much, so
@@ -129,6 +131,8 @@ void vPortSetupTimerInterrupt( void )
{
BURTC_Init_TypeDef xBURTCInitStruct = BURTC_INIT_DEFAULT;
+ /* Configure the BURTC to generate the RTOS tick interrupt. */
+
xMaximumPossibleSuppressedTicks = ULONG_MAX / ulReloadValueForOneTick;
/* Ensure LE modules are accessible. */
@@ -145,7 +149,7 @@ BURTC_Init_TypeDef xBURTCInitStruct = BURTC_INIT_DEFAULT;
BURTC_IntDisable( BURTC_IF_COMP0 );
BURTC_Init( &xBURTCInitStruct );
- /* The tick interrupt must be set to the lowest possible. */
+ /* The tick interrupt must be set to the lowest priority possible. */
NVIC_SetPriority( BURTC_IRQn, configKERNEL_INTERRUPT_PRIORITY );
NVIC_ClearPendingIRQ( BURTC_IRQn );
NVIC_EnableIRQ( BURTC_IRQn );
@@ -299,11 +303,11 @@ TickType_t xModifiableIdleTime;
}
/*-----------------------------------------------------------*/
-void BURTC_IRQHandler(void)
+void BURTC_IRQHandler( void )
{
if( ulTickFlag == pdFALSE )
{
- /* Set BURTC interrupt to one system tick period*/
+ /* Set BURTC interrupt to one RTOS tick period. */
BURTC_Enable( false );
BURTC_CompareSet( 0, ulReloadValueForOneTick );
ulTickFlag = pdTRUE;
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
index 000000000..d736f2670
--- /dev/null
+++ b/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Low_Power_Demo/low_power_tick_management_RTC.c
@@ -0,0 +1,341 @@
+/*
+ FreeRTOS V8.2.3 - Copyright (C) 2015 Real Time Engineers Ltd.
+ All rights reserved
+
+ VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
+
+ This file is part of the FreeRTOS distribution.
+
+ FreeRTOS is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License (version 2) as published by the
+ Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
+
+ ***************************************************************************
+ >>! NOTE: The modification to the GPL is included to allow you to !<<
+ >>! distribute a combined work that includes FreeRTOS without being !<<
+ >>! obliged to provide the source code for proprietary components !<<
+ >>! outside of the FreeRTOS kernel. !<<
+ ***************************************************************************
+
+ FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. Full license text is available on the following
+ link: http://www.freertos.org/a00114.html
+
+ ***************************************************************************
+ * *
+ * FreeRTOS provides completely free yet professionally developed, *
+ * robust, strictly quality controlled, supported, and cross *
+ * platform software that is more than just the market leader, it *
+ * is the industry's de facto standard. *
+ * *
+ * Help yourself get started quickly while simultaneously helping *
+ * to support the FreeRTOS project by purchasing a FreeRTOS *
+ * tutorial book, reference manual, or both: *
+ * http://www.FreeRTOS.org/Documentation *
+ * *
+ ***************************************************************************
+
+ http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
+ the FAQ page "My application does not run, what could be wrong?". Have you
+ defined configASSERT()?
+
+ http://www.FreeRTOS.org/support - In return for receiving this top quality
+ embedded software for free we request you assist our global community by
+ participating in the support forum.
+
+ http://www.FreeRTOS.org/training - Investing in training allows your team to
+ be as productive as possible as early as possible. Now you can receive
+ FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
+ Ltd, and the world's leading authority on the world's leading RTOS.
+
+ http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
+ including FreeRTOS+Trace - an indispensable productivity tool, a DOS
+ compatible FAT file system, and our tiny thread aware UDP/IP stack.
+
+ http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
+ Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
+
+ http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
+ Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
+ licenses offer ticketed support, indemnification and commercial middleware.
+
+ http://www.SafeRTOS.com - High Integrity Systems also provide a safety
+ engineered and independently SIL3 certified version for use in safety and
+ mission critical applications that require provable dependability.
+
+ 1 tab == 4 spaces!
+*/
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+
+/* SiLabs library includes. */
+#include "em_cmu.h"
+#include "em_rtc.h"
+#include "em_rmu.h"
+#include "em_int.h"
+#include "sleep.h"
+
+/* SEE THE COMMENTS ABOVE THE DEFINITION OF configCREATE_LOW_POWER_DEMO IN
+FreeRTOSConfig.h
+This file contains functions that will override the default implementations
+in the RTOS port layer. Therefore only build this file if the low power demo
+is being built. */
+#if( configCREATE_LOW_POWER_DEMO == 2 )
+
+#define mainTIMER_FREQUENCY_HZ ( 4096UL ) /* 32768 clock divided by 8. */
+
+/*
+ * The low power demo does not use the SysTick, so override the
+ * vPortSetupTickInterrupt() function with an implementation that configures
+ * a low power clock source. NOTE: This function name must not be changed as
+ * it is called from the RTOS portable layer.
+ */
+void vPortSetupTimerInterrupt( void );
+
+/*
+ * Override the default definition of vPortSuppressTicksAndSleep() that is
+ * weakly defined in the FreeRTOS Cortex-M port layer with a version that
+ * manages the RTC clock, as the tick is generated from the low power RTC
+ * and not the SysTick as would normally be the case on a Cortex-M.
+ */
+void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
+
+/*-----------------------------------------------------------*/
+
+/* Calculate how many clock increments make up a single tick period. */
+static const uint32_t ulReloadValueForOneTick = ( mainTIMER_FREQUENCY_HZ / configTICK_RATE_HZ );
+
+/* Will hold the maximum number of ticks that can be suppressed. */
+static uint32_t xMaximumPossibleSuppressedTicks = 0;
+
+/* Flag set from the tick interrupt to allow the sleep processing to know if
+sleep mode was exited because of a timer interrupt or a different interrupt. */
+static volatile uint32_t ulTickFlag = pdFALSE;
+
+/* As the clock is only 32KHz, it is likely a value of 1 will be enough. */
+static const uint32_t ulStoppedTimerCompensation = 0UL;
+
+/*-----------------------------------------------------------*/
+
+void vPortSetupTimerInterrupt( void )
+{
+RTC_Init_TypeDef xRTCInitStruct;
+const uint32_t ulMAX24BitValue = 0xffffffUL;
+
+ xMaximumPossibleSuppressedTicks = ulMAX24BitValue / ulReloadValueForOneTick;
+
+ /* Configure the RTC to generate the RTOS tick interrupt. */
+
+ /* LXFO setup. For rev D use 70% boost */
+ CMU->CTRL = ( CMU->CTRL & ~_CMU_CTRL_LFXOBOOST_MASK ) | CMU_CTRL_LFXOBOOST_70PCENT;
+ #if defined( EMU_AUXCTRL_REDLFXOBOOST )
+ EMU->AUXCTRL = (EMU->AUXCTRL & ~_EMU_AUXCTRL_REDLFXOBOOST_MASK) | EMU_AUXCTRL_REDLFXOBOOST;
+ #endif
+
+ /* Ensure LE modules are accessible. */
+ CMU_ClockEnable( cmuClock_CORELE, true );
+
+ /* Use LFXO. */
+ CMU_ClockSelectSet( cmuClock_LFA, cmuSelect_LFXO );
+
+ /* Use 8x divider to reduce energy. */
+ CMU_ClockDivSet( cmuClock_RTC, cmuClkDiv_8 );
+
+ /* Enable clock to the RTC module. */
+ CMU_ClockEnable( cmuClock_RTC, true );
+ xRTCInitStruct.enable = false;
+ xRTCInitStruct.debugRun = false;
+ xRTCInitStruct.comp0Top = true;
+ RTC_Init( &xRTCInitStruct );
+
+ /* Disable RTC0 interrupt. */
+ RTC_IntDisable( RTC_IFC_COMP0 );
+
+ /* The tick interrupt must be set to the lowest priority possible. */
+ NVIC_SetPriority( RTC_IRQn, configKERNEL_INTERRUPT_PRIORITY );
+ NVIC_ClearPendingIRQ( RTC_IRQn );
+ NVIC_EnableIRQ( RTC_IRQn );
+ RTC_CompareSet( 0, ulReloadValueForOneTick );
+ RTC_IntClear( RTC_IFC_COMP0 );
+ RTC_IntEnable( RTC_IF_COMP0 );
+ RTC_Enable( true );
+}
+/*-----------------------------------------------------------*/
+
+void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
+{
+uint32_t ulReloadValue, ulCompleteTickPeriods, ulCurrentCount;
+eSleepModeStatus eSleepAction;
+TickType_t xModifiableIdleTime;
+
+ /* THIS FUNCTION IS CALLED WITH THE SCHEDULER SUSPENDED. */
+
+ /* Make sure the RTC reload value does not overflow the counter. */
+ if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks )
+ {
+ xExpectedIdleTime = xMaximumPossibleSuppressedTicks;
+ }
+
+ /* Calculate the reload value required to wait xExpectedIdleTime tick
+ periods. */
+ ulReloadValue = ulReloadValueForOneTick * xExpectedIdleTime;
+ if( ulReloadValue > ulStoppedTimerCompensation )
+ {
+ /* Compensate for the fact that the RTC is going to be stopped
+ momentarily. */
+ ulReloadValue -= ulStoppedTimerCompensation;
+ }
+
+ /* Stop the RTC momentarily. The time the RTC is stopped for is accounted
+ for as best it can be, but using the tickless mode will inevitably result
+ in some tiny drift of the time maintained by the kernel with respect to
+ calendar time. The count is latched before stopping the timer as stopping
+ the timer appears to clear the count. */
+ ulCurrentCount = RTC_CounterGet();
+ RTC_Enable( false );
+
+ /* Enter a critical section but don't use the taskENTER_CRITICAL() method as
+ that will mask interrupts that should exit sleep mode. */
+ INT_Disable();
+ __asm volatile( "dsb" );
+ __asm volatile( "isb" );
+
+ /* The tick flag is set to false before sleeping. If it is true when sleep
+ mode is exited then sleep mode was probably exited because the tick was
+ suppressed for the entire xExpectedIdleTime period. */
+ ulTickFlag = pdFALSE;
+
+ /* If a context switch is pending then abandon the low power entry as the
+ context switch might have been pended by an external interrupt that requires
+ processing. */
+ eSleepAction = eTaskConfirmSleepModeStatus();
+ if( eSleepAction == eAbortSleep )
+ {
+ /* Restart tick and count up to whatever was left of the current time
+ slice. */
+ RTC_CompareSet( 0, ulReloadValueForOneTick - ulCurrentCount );
+ RTC_Enable( true );
+
+ /* Re-enable interrupts - see comments above the cpsid instruction()
+ above. */
+ INT_Enable();
+ }
+ else
+ {
+ /* Adjust the reload value to take into account that the current time
+ slice is already partially complete. */
+ ulReloadValue -= ulCurrentCount;
+ RTC_CompareSet( 0, ulReloadValue );
+
+ /* Restart the RTC. */
+ RTC_Enable( true );
+
+ /* Allow the application to define some pre-sleep processing. */
+ xModifiableIdleTime = xExpectedIdleTime;
+ configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
+
+ /* xExpectedIdleTime being set to 0 by configPRE_SLEEP_PROCESSING()
+ means the application defined code has already executed the WAIT
+ instruction. */
+ if( xModifiableIdleTime > 0 )
+ {
+ __asm volatile( "dsb" );
+ SLEEP_Sleep();
+ __asm volatile( "isb" );
+ }
+
+ /* Allow the application to define some post sleep processing. */
+ configPOST_SLEEP_PROCESSING( xModifiableIdleTime );
+
+ /* Stop RTC. Again, the time the SysTick is stopped for is accounted
+ for as best it can be, but using the tickless mode will inevitably
+ result in some tiny drift of the time maintained by the kernel with
+ respect to calendar time. The count value is latched before stopping
+ the timer as stopping the timer appears to clear the count. */
+ ulCurrentCount = RTC_CounterGet();
+ RTC_Enable( false );
+
+ /* Re-enable interrupts - see comments above the cpsid instruction()
+ above. */
+ INT_Enable();
+ __asm volatile( "dsb" );
+ __asm volatile( "isb" );
+
+ if( ulTickFlag != pdFALSE )
+ {
+ /* The tick interrupt has already executed, although because this
+ function is called with the scheduler suspended the actual tick
+ processing will not occur until after this function has exited.
+ Reset the reload value with whatever remains of this tick period. */
+ ulReloadValue = ulReloadValueForOneTick - ulCurrentCount;
+ RTC_CompareSet( 0, ulReloadValue );
+
+ /* The tick interrupt handler will already have pended the tick
+ processing in the kernel. As the pending tick will be processed as
+ soon as this function exits, the tick value maintained by the tick
+ is stepped forward by one less than the time spent sleeping. The
+ actual stepping of the tick appears later in this function. */
+ ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
+ }
+ else
+ {
+ /* Something other than the tick interrupt ended the sleep. How
+ many complete tick periods passed while the processor was
+ sleeping? */
+ ulCompleteTickPeriods = ulCurrentCount / ulReloadValueForOneTick;
+
+ /* The reload value is set to whatever fraction of a single tick
+ period remains. */
+ ulReloadValue = ulCurrentCount - ( ulCompleteTickPeriods * ulReloadValueForOneTick );
+ if( ulReloadValue == 0 )
+ {
+ /* There is no fraction remaining. */
+ ulReloadValue = ulReloadValueForOneTick;
+ ulCompleteTickPeriods++;
+ }
+
+ RTC_CompareSet( 0, ulReloadValue );
+ }
+
+ /* Restart the RTC so it runs up to the alarm value. The alarm value
+ will get set to the value required to generate exactly one tick period
+ the next time the RTC interrupt executes. */
+ RTC_Enable( true );
+
+ /* Wind the tick forward by the number of tick periods that the CPU
+ remained in a low power state. */
+ vTaskStepTick( ulCompleteTickPeriods );
+ }
+}
+/*-----------------------------------------------------------*/
+
+void RTC_IRQHandler( void )
+{
+ if( ulTickFlag == pdFALSE )
+ {
+ /* Set RTC interrupt to one RTOS tick period. */
+ RTC_Enable( false );
+ RTC_CompareSet( 0, ulReloadValueForOneTick );
+ ulTickFlag = pdTRUE;
+ RTC_Enable( true );
+ }
+
+ RTC_IntClear( _RTC_IFC_MASK );
+
+ /* Critical section which protect incrementing the tick*/
+ ( void ) portSET_INTERRUPT_MASK_FROM_ISR();
+ {
+ if( xTaskIncrementTick() != pdFALSE )
+ {
+ /* Pend a context switch. */
+ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
+ }
+ }
+ portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );
+}
+
+#endif /* ( configCREATE_LOW_POWER_DEMO == 1 ) */
+
diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Low_Power_Demo/main_low_power.c b/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Low_Power_Demo/main_low_power.c
index fe4824d8c..ce30aa240 100644
--- a/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Low_Power_Demo/main_low_power.c
+++ b/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/Low_Power_Demo/main_low_power.c
@@ -71,9 +71,10 @@
* NOTE 1: This project provides two demo applications. A simple blinky demo
* that demonstrates tickless low power operation, and a more comprehensive
* test and demo application. The configCREATE_LOW_POWER_DEMO setting in
- * FreeRTOSConfig.h is used to select between the two. See the notes on using
- * configCREATE_LOW_POWER_DEMO in main.c. This file implements the low power
- * version.
+ * FreeRTOSConfig.h is used to select between the two, and to select the clock
+ * used when tickless low power operation is demonstrated. See the notes on
+ * using configCREATE_LOW_POWER_DEMO in main.c. This file implements the low
+ * power version.
*
* NOTE 2: This file only contains the source code that is specific to the
* low power demo. Generic functions, such FreeRTOS hook functions, and
@@ -211,7 +212,7 @@ const TickType_t xShortDelay = pdMS_TO_TICKS( 10 );
if( ulReceivedValue == ulExpectedValue )
{
/* Turn the LED on for a brief time only so it doens't distort the
- enerty reading. */
+ energy reading. */
BSP_LedSet( mainTASK_LED );
vTaskDelay( xShortDelay );
BSP_LedClear( mainTASK_LED );
diff --git a/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/main.c b/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/main.c
index 174073296..fe76f5464 100644
--- a/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/main.c
+++ b/FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/main.c
@@ -71,10 +71,12 @@
* This project provides two demo applications. A simple blinky style project
* that demonstrates low power tickless functionality, and a more comprehensive
* test and demo application. The configCREATE_LOW_POWER_DEMO setting, which is
- * defined in FreeRTOSConfig.h, is used to select between the two. The simply
- * blinky low power demo is implemented and described in main_low_power.c. The
- * more comprehensive test and demo application is implemented and described in
- * main_full.c.
+ * defined in FreeRTOSConfig.h, is used to select between the two, and to select
+ * the clock used when demonstrating tickless functionality.
+ *
+ * The simply blinky low power demo is implemented and described in
+ * main_low_power.c. The more comprehensive test and demo application is
+ * implemented and described in main_full.c.
*
* This file implements the code that is not demo specific, including the
* hardware setup and standard FreeRTOS hook functions.
@@ -85,6 +87,8 @@
*
*/
+#warning Check the tick suppression routine in the case where the system unblocks before an entire tick period has expired.
+
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
@@ -132,7 +136,7 @@ int main( void )
/* The mainCREATE_LOW_POWER_DEMO setting is described at the top
of this file. */
- #if( configCREATE_LOW_POWER_DEMO == 1 )
+ #if( configCREATE_LOW_POWER_DEMO != 0 )
{
main_low_power();
}
@@ -154,6 +158,8 @@ static void prvSetupHardware( void )
BSP_TraceProfilerSetup();
SLEEP_Init( NULL, NULL );
BSP_LedsInit();
+
+ SLEEP_SleepBlockBegin( configENERGY_MODE );
}
/*-----------------------------------------------------------*/