forked from epagris/FreeRTOS-Kernel
		
	Update EFM32 demos to include an option to use the RTC as the clock source when using low power tickless mode.
This commit is contained in:
		
							parent
							
								
									c4dd17eeb5
								
							
						
					
					
						commit
						556de14a1d
					
				@ -53,7 +53,7 @@
 | 
			
		||||
									<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Source/SilLabs_Code/kits/EFM32GG_STK3700/config}""/>
 | 
			
		||||
									<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Source/SilLabs_Code/Device/SiliconLabs/EFM32GG/Include}""/>
 | 
			
		||||
								</option>
 | 
			
		||||
								<option id="gnu.c.compiler.option.preprocessor.undef.symbol.1550566013" name="Undefined symbols (-U)" superClass="gnu.c.compiler.option.preprocessor.undef.symbol" valueType="undefDefinedSymbols"/>
 | 
			
		||||
								<option id="gnu.c.compiler.option.preprocessor.undef.symbol.1550566013" name="Undefined symbols (-U)" superClass="gnu.c.compiler.option.preprocessor.undef.symbol"/>
 | 
			
		||||
								<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"/>
 | 
			
		||||
							</tool>
 | 
			
		||||
							<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">
 | 
			
		||||
@ -103,6 +103,9 @@
 | 
			
		||||
							<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"/>
 | 
			
		||||
						</toolChain>
 | 
			
		||||
					</folderInfo>
 | 
			
		||||
					<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">
 | 
			
		||||
						<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"/>
 | 
			
		||||
					</fileInfo>
 | 
			
		||||
					<sourceEntries>
 | 
			
		||||
						<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=""/>
 | 
			
		||||
					</sourceEntries>
 | 
			
		||||
 | 
			
		||||
@ -87,28 +87,24 @@ 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 )
 | 
			
		||||
 | 
			
		||||
	/* 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. */
 | 
			
		||||
	#define configTICK_RATE_HZ				( 100 )
 | 
			
		||||
 | 
			
		||||
	/* The low power demo uses the tickless idle feature. */
 | 
			
		||||
	#define configUSE_TICKLESS_IDLE			1
 | 
			
		||||
 | 
			
		||||
	/* Hook function related definitions. */
 | 
			
		||||
	#define configUSE_TICK_HOOK				( 0 )
 | 
			
		||||
	#define configCHECK_FOR_STACK_OVERFLOW	( 0 )
 | 
			
		||||
	#define configUSE_MALLOC_FAILED_HOOK	( 0 )
 | 
			
		||||
	#define configUSE_IDLE_HOOK				( 0 )
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
	/* 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
 | 
			
		||||
@ -124,7 +120,49 @@ the comments at the top of main.c for more information. */
 | 
			
		||||
	#define configUSE_TICK_HOOK				( 1 )
 | 
			
		||||
	#define configCHECK_FOR_STACK_OVERFLOW	( 1 )
 | 
			
		||||
	#define configUSE_MALLOC_FAILED_HOOK	( 1 )
 | 
			
		||||
	#define configUSE_IDLE_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 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. */
 | 
			
		||||
	#define configUSE_TICKLESS_IDLE			1
 | 
			
		||||
 | 
			
		||||
	/* Hook function related definitions. */
 | 
			
		||||
	#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				( sleepEM4 )
 | 
			
		||||
 | 
			
		||||
#elif( configCREATE_LOW_POWER_DEMO == 2 )
 | 
			
		||||
 | 
			
		||||
	/* 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				( 0 )
 | 
			
		||||
	#define configCHECK_FOR_STACK_OVERFLOW	( 0 )
 | 
			
		||||
	#define configUSE_MALLOC_FAILED_HOOK	( 0 )
 | 
			
		||||
	#define configUSE_IDLE_HOOK				( 0 )
 | 
			
		||||
 | 
			
		||||
	#define configENERGY_MODE				( sleepEM3 )
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
@ -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 ) */
 | 
			
		||||
 | 
			
		||||
@ -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 );
 | 
			
		||||
 | 
			
		||||
@ -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 );
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user