]> git.sur5r.net Git - freertos/commitdiff
Tidy up STM32L low power demo and add 'comprehensive demo' option.
authorrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Tue, 10 Dec 2013 16:20:43 +0000 (16:20 +0000)
committerrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Tue, 10 Dec 2013 16:20:43 +0000 (16:20 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2123 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

FreeRTOS/Demo/CORTEX_STM32L152_Discovery_IAR/RTOSDemo.ewd
FreeRTOS/Demo/CORTEX_STM32L152_Discovery_IAR/RTOSDemo.ewp
FreeRTOS/Demo/CORTEX_STM32L152_Discovery_IAR/STM32L_low_power_tick_management.c
FreeRTOS/Demo/CORTEX_STM32L152_Discovery_IAR/include/FreeRTOSConfig.h
FreeRTOS/Demo/CORTEX_STM32L152_Discovery_IAR/main.c
FreeRTOS/Demo/CORTEX_STM32L152_Discovery_IAR/main_full.c [new file with mode: 0644]
FreeRTOS/Demo/CORTEX_STM32L152_Discovery_IAR/main_low_power.c [new file with mode: 0644]
FreeRTOS/Demo/CORTEX_STM32L152_Discovery_IAR/stm32l1xx_flash.icf

index e9ce99b951d6d458195e31bceeb6477212be772b..41cec0bafe094439c55ee1ee093221f890fa20bc 100644 (file)
@@ -49,7 +49,7 @@
         </option>\r
         <option>\r
           <name>RunToEnable</name>\r
-          <state>0</state>\r
+          <state>1</state>\r
         </option>\r
         <option>\r
           <name>RunToName</name>\r
index 66e90c0e071ef24d7efae68e01b5f40895bfe459..8598fc929241686a54d14b9e128180b7a05ccf2d 100644 (file)
         <option>\r
           <name>Input variant</name>\r
           <version>3</version>\r
-          <state>1</state>\r
+          <state>7</state>\r
         </option>\r
         <option>\r
           <name>Input description</name>\r
-          <state>Full formatting.</state>\r
+          <state>No specifier n, no float nor long long, no scan set, no assignment suppressing, without multibyte support.</state>\r
         </option>\r
         <option>\r
           <name>Output variant</name>\r
           <version>2</version>\r
-          <state>1</state>\r
+          <state>7</state>\r
         </option>\r
         <option>\r
           <name>Output description</name>\r
-          <state>Full formatting.</state>\r
+          <state>No specifier a, A, no specifier n, no float nor long long, no flags.</state>\r
         </option>\r
         <option>\r
           <name>GOutputBinary</name>\r
         <option>\r
           <name>GRuntimeLibSelect</name>\r
           <version>0</version>\r
-          <state>2</state>\r
+          <state>1</state>\r
         </option>\r
         <option>\r
           <name>GRuntimeLibSelectSlave</name>\r
           <version>0</version>\r
-          <state>2</state>\r
+          <state>1</state>\r
         </option>\r
         <option>\r
           <name>RTDescription</name>\r
-          <state>Use the full configuration of the C/C++ runtime library. Full locale interface, C locale, file descriptor support, multibytes in printf and scanf, and hex floats in strtod.</state>\r
+          <state>Use the normal configuration of the C/C++ runtime library. No locale interface, C locale, no file descriptor support, no multibytes in printf and scanf, and no hex floats in strtod.</state>\r
         </option>\r
         <option>\r
           <name>OGProductVersion</name>\r
         </option>\r
         <option>\r
           <name>GenLowLevelInterface</name>\r
-          <state>1</state>\r
+          <state>0</state>\r
         </option>\r
         <option>\r
           <name>GEndianModeBE</name>\r
         </option>\r
         <option>\r
           <name>RTConfigPath2</name>\r
-          <state>$TOOLKIT_DIR$\INC\c\DLib_Config_Full.h</state>\r
+          <state>$TOOLKIT_DIR$\INC\c\DLib_Config_Normal.h</state>\r
         </option>\r
         <option>\r
           <name>GFPUCoreSlave</name>\r
           <state>$PROJ_DIR$\ST_Code\libraries\CMSIS\Device\ST\STM32L1xx\Include</state>\r
           <state>$PROJ_DIR$\..\..\Source\include</state>\r
           <state>$PROJ_DIR$\..\..\Source\portable\IAR\ARM_CM3</state>\r
+          <state>$PROJ_DIR$\..\Common\include</state>\r
         </option>\r
         <option>\r
           <name>CCStdIncCheck</name>\r
         </option>\r
         <option>\r
           <name>IlinkOutputFile</name>\r
-          <state>STM32L-Discovery.out</state>\r
+          <state>RTOSDemo.out</state>\r
         </option>\r
         <option>\r
           <name>IlinkDebugInfoEnable</name>\r
       </file>\r
     </group>\r
   </group>\r
+  <group>\r
+    <name>Standard Demo Tasks</name>\r
+    <file>\r
+      <name>$PROJ_DIR$\..\Common\Minimal\BlockQ.c</name>\r
+    </file>\r
+    <file>\r
+      <name>$PROJ_DIR$\..\Common\Minimal\blocktim.c</name>\r
+    </file>\r
+    <file>\r
+      <name>$PROJ_DIR$\..\Common\Minimal\countsem.c</name>\r
+    </file>\r
+    <file>\r
+      <name>$PROJ_DIR$\..\Common\Minimal\dynamic.c</name>\r
+    </file>\r
+    <file>\r
+      <name>$PROJ_DIR$\..\Common\Minimal\GenQTest.c</name>\r
+    </file>\r
+    <file>\r
+      <name>$PROJ_DIR$\..\Common\Minimal\PollQ.c</name>\r
+    </file>\r
+    <file>\r
+      <name>$PROJ_DIR$\..\Common\Minimal\recmutex.c</name>\r
+    </file>\r
+    <file>\r
+      <name>$PROJ_DIR$\..\Common\Minimal\semtest.c</name>\r
+    </file>\r
+  </group>\r
   <group>\r
     <name>System</name>\r
     <file>\r
   <file>\r
     <name>$PROJ_DIR$\main.c</name>\r
   </file>\r
+  <file>\r
+    <name>$PROJ_DIR$\main_full.c</name>\r
+  </file>\r
+  <file>\r
+    <name>$PROJ_DIR$\main_low_power.c</name>\r
+  </file>\r
   <file>\r
     <name>$PROJ_DIR$\stm32l1xx_it.c</name>\r
   </file>\r
index faff612d11aa8a696511e6031dde110045951d20..d7cd3b2e7e6c7ca0f8c2f768ad1fa96ee7ce065d 100644 (file)
@@ -75,8 +75,8 @@
 \r
 /*\r
  * When configCREATE_LOW_POWER_DEMO is set to 1 then the tick interrupt\r
- * is generated by the wakeup interrupt of the real time clock (RTC).  The RTC\r
- * configuration and handling functions are defined in this file.\r
+ * is generated by the TIM2 peripheral.  The TIM2 configuration and handling\r
+ * functions are defined in this file.\r
  *\r
  * When configCREATE_LOW_POWER_DEMO is set to 0 the tick interrupt is\r
  * generated by the standard FreeRTOS Cortex-M port layer, which uses the\r
  */\r
 #if configCREATE_LOW_POWER_DEMO == 1\r
 \r
-/* The frequency at which TIM2 should run. */\r
+/* The frequency at which TIM2 will run. */\r
 #define lpCLOCK_INPUT_FREQUENCY        ( 1000UL )\r
 \r
-/* Constants required to pend a PendSV interrupt from the tick ISR if the\r
-preemptive scheduler is being used.  These are just standard bits and registers\r
-within the Cortex-M core itself. */\r
-#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )\r
-\r
+/* STM32 register used to ensure the TIM2 clock stops when the MCU is in debug\r
+mode. */\r
 #define DBGMCU_APB1_FZ         ( * ( ( volatile unsigned long * ) 0xE0042008 ) )\r
+\r
 /*-----------------------------------------------------------*/\r
 \r
 /*\r
- * The tick interrupt is generated by the TIM2 timer.  The default interrupt\r
- * handler cannot be used (even with the TIM2 being handled from the tick hook\r
- * function) because the default tick interrupt accesses the SysTick registers\r
- * when configUSE_TICKLESS_IDLE set to 1.  TIM2_IRQHandler() is the default name\r
- * for the TIM2 interrupt handler.\r
+ * The tick interrupt is generated by the TIM2 timer.\r
  */\r
 void TIM2_IRQHandler( void );\r
 \r
@@ -115,15 +109,9 @@ initialisation. */
 static portTickType 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 RTC interrupt or a different interrupt. */\r
+sleep mode was exited because of an tick interrupt or a different interrupt. */\r
 static volatile uint32_t ulTickFlag = pdFALSE;\r
 \r
-/* The RTC counter is stopped temporarily each time it is re-programmed.  The\r
-following variable offsets the RTC counter alarm value by the number of RTC\r
-counts that would typically be missed while the counter was stopped to\r
-compensate for the lost time.  _RB_ Value needs calculating correctly. */\r
-static uint32_t ulStoppedTimerCompensation = 1;//_RB_ / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ );\r
-\r
 /*-----------------------------------------------------------*/\r
 \r
 /* The tick interrupt handler.  This is always the same other than the part that\r
@@ -131,10 +119,13 @@ clears the interrupt, which is specific to the clock being used to generate the
 tick. */\r
 void TIM2_IRQHandler( void )\r
 {\r
+       /* Clear the interrupt. */\r
        TIM_ClearITPendingBit( TIM2, TIM_IT_Update );\r
-       TIM_SetAutoreload( TIM2, ( uint16_t ) ulReloadValueForOneTick );\r
 \r
-       /* Protect incrementing the tick with an interrupt safe critical section. */\r
+       /* The next block of code is from the standard FreeRTOS tick interrupt\r
+       handler.  The standard handler is not called directly in case future\r
+       versions contain changes that make it no longer suitable for calling\r
+       here. */\r
        ( void ) portSET_INTERRUPT_MASK_FROM_ISR();\r
        {\r
                if( xTaskIncrementTick() != pdFALSE )\r
@@ -148,39 +139,42 @@ void TIM2_IRQHandler( void )
        }\r
        portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );\r
 \r
+       /* In case this is the first tick since the MCU left a low power mode the\r
+       reload value is reset to its default. */\r
+       TIM2->ARR = ( uint16_t ) ulReloadValueForOneTick;\r
+\r
        /* The CPU woke because of a tick. */\r
        ulTickFlag = pdTRUE;\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
 /* Override the default definition of vPortSetupTimerInterrupt() that is weakly\r
-defined in the FreeRTOS Cortex-M3 port layer with a version that configures the\r
-wakeup timer of the RTC to generate the tick interrupt. */\r
+defined in the FreeRTOS Cortex-M3 port layer with a version that configures TIM2\r
+to generate the tick interrupt. */\r
 void vPortSetupTimerInterrupt( void )\r
 {\r
 NVIC_InitTypeDef NVIC_InitStructure;\r
 TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;\r
 \r
-       /* Enable the TIM2 clock, which is used to generate long tickless periods\r
-       when the tickless period is finite. */\r
+       /* Enable the TIM2 clock. */\r
        RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM2, ENABLE );\r
 \r
        /* Ensure clock stops in debug mode. */\r
        DBGMCU_APB1_FZ |= DBGMCU_APB1_FZ_DBG_TIM2_STOP;\r
 \r
-       /* Scale the clock so very long tickless periods can be acheived.  The\r
-       SysTick is not used as even when its frequency is divided by 8 the maximum\r
-       tickless period with a system clock of 16MHz is only 8.3 seconds.  Using\r
-       a prescaled clock on the 16-bit TIM2 allows a tickless period of nearly\r
-       66 seconds, albeit at low resolution. */\r
+       /* Scale the clock so longer tickless periods can be achieved.  The     SysTick\r
+       is not used as even when its frequency is divided by 8 the maximum tickless\r
+       period with a system clock of 16MHz is only 8.3 seconds.  Using a prescaled\r
+       clock on the 16-bit TIM2 allows a tickless period of nearly     66 seconds,\r
+       albeit at low resolution. */\r
        TIM_TimeBaseStructure.TIM_Prescaler = ( uint16_t ) ( SystemCoreClock / lpCLOCK_INPUT_FREQUENCY );\r
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;\r
        TIM_TimeBaseStructure.TIM_Period = ( uint16_t ) ( lpCLOCK_INPUT_FREQUENCY / configTICK_RATE_HZ );\r
        TIM_TimeBaseStructure.TIM_ClockDivision = 0;\r
        TIM_TimeBaseInit( TIM2, &TIM_TimeBaseStructure );\r
 \r
-       /* Enable the TIM2 interrupt - used for the tick interrupt when the tickless\r
-       period is finite. */\r
+       /* Enable the TIM2 interrupt.  This must execute at the lowest interrupt\r
+       priority. */\r
        NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;\r
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_LOWEST_INTERRUPT_PRIORITY; /* Must be set to lowest priority. */\r
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;\r
@@ -216,17 +210,11 @@ const portTickType xRegulatorOffIdleTime = 30;
        /* Calculate the reload value required to wait xExpectedIdleTime tick\r
        periods. */\r
        ulCounterValue = ulReloadValueForOneTick * xExpectedIdleTime;\r
-       if( ulCounterValue > ulStoppedTimerCompensation )\r
-       {\r
-               /* Compensate for the fact that TIM2 is going to be stopped\r
-               momentarily. */\r
-               ulCounterValue -= ulStoppedTimerCompensation;\r
-       }\r
 \r
-       /* Stop TIM2 momentarily.  The time TIM2 is stopped for is accounted for as\r
-       best it can be, but using the tickless mode will inevitably result in some\r
-       tiny drift of the time maintained by the kernel with respect to calendar\r
-       time. */\r
+       /* Stop TIM2 momentarily.  The time TIM2 is stopped for is not accounted for\r
+       in this implementation (as it is in the generic implementation) because the\r
+       clock is so slow it is unlikely to be stopped for a complete count period\r
+       anyway. */\r
        TIM_Cmd( TIM2, DISABLE );\r
 \r
        /* Enter a critical section but don't use the taskENTER_CRITICAL() method as\r
@@ -255,13 +243,25 @@ const portTickType xRegulatorOffIdleTime = 30;
        }\r
        else if( eSleepAction == eNoTasksWaitingTimeout )\r
        {\r
+               /* A user definable macro that allows application code to be inserted\r
+               here.  Such application code can be used to minimise power consumption\r
+               further by turning off IO, peripheral clocks, the Flash, etc. */\r
+               configPRE_STOP_PROCESSING();\r
+\r
                /* There are no running state tasks and no tasks that are blocked with a\r
                time out.  Assuming the application does not care if the tick time slips\r
                with respect to calendar time then enter a deep sleep that can only be\r
                woken by (in this demo case) the user button being pushed on the\r
-               STM32L discovery board. */\r
-               configPRE_STOP_PROCESSING();\r
+               STM32L discovery board.  If the application does require the tick time\r
+               to keep better track of the calender time then the RTC peripheral can be\r
+               used to make rough adjustments. */\r
                PWR_EnterSTOPMode( PWR_Regulator_LowPower, PWR_SLEEPEntry_WFI );\r
+\r
+               /* A user definable macro that allows application code to be inserted\r
+               here.  Such application code can be used to reverse any actions taken\r
+               by the configPRE_STOP_PROCESSING().  In this demo\r
+               configPOST_STOP_PROCESSING() is used to re-initialise the clocks that\r
+               were turned off when STOP mode was entered. */\r
                configPOST_STOP_PROCESSING();\r
 \r
                /* Restart tick. */\r
@@ -274,36 +274,48 @@ const portTickType xRegulatorOffIdleTime = 30;
        }\r
        else\r
        {\r
+               /* Trap underflow before the next calculation. */\r
+               configASSERT( ulCounterValue >= TIM_GetCounter( TIM2 ) );\r
+\r
                /* Adjust the TIM2 value to take into account that the current time\r
                slice is already partially complete. */\r
-               configASSERT( ulCounterValue >= TIM_GetCounter( TIM2 ) );\r
                ulCounterValue -= ( uint32_t ) TIM_GetCounter( TIM2 );\r
+\r
+               /* Trap overflow/underflow before the calculated value is written to\r
+               TIM2. */\r
                configASSERT( ulCounterValue < ( uint32_t ) USHRT_MAX );\r
                configASSERT( ulCounterValue != 0 );\r
+\r
+               /* Update to use the calculated overflow value. */\r
                TIM_SetAutoreload( TIM2, ( uint16_t ) ulCounterValue );\r
                TIM_SetCounter( TIM2, 0 );\r
 \r
                /* Restart the TIM2. */\r
                TIM_Cmd( TIM2, ENABLE );\r
 \r
-               /* Allow the application to define some pre-sleep processing. */\r
+               /* Allow the application to define some pre-sleep processing.  This is\r
+               the standard configPRE_SLEEP_PROCESSING() macro as described on the\r
+               FreeRTOS.org website. */\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
+               means the application defined code has already executed the wait/sleep\r
                instruction. */\r
                if( xModifiableIdleTime > 0 )\r
                {\r
                        /* The sleep mode used is dependent on the expected idle time\r
-                       as the deeper the sleep the longer the wake up time. */\r
+                       as the deeper the sleep the longer the wake up time.  See the\r
+                       comments at the top of main_low_power.c.  Note xRegulatorOffIdleTime\r
+                       is set purely for convenience of demonstration and is not intended\r
+                       to be an optimised value. */\r
                        if( xModifiableIdleTime > xRegulatorOffIdleTime )\r
                        {\r
                                /* A slightly lower power sleep mode with a longer wake up\r
                                time. */\r
                                PWR_EnterSleepMode( PWR_Regulator_LowPower, PWR_SLEEPEntry_WFI );\r
                        }\r
-                       else if( pdTRUE )\r
+                       else\r
                        {\r
                                /* A slightly higher power sleep mode with a faster wake up\r
                                time. */\r
@@ -311,13 +323,14 @@ const portTickType xRegulatorOffIdleTime = 30;
                        }\r
                }\r
 \r
-               /* Allow the application to define some post sleep processing. */\r
+               /* Allow the application to define some post sleep processing.  This is\r
+               the standard configPOST_SLEEP_PROCESSING() macro, as described on the\r
+               FreeRTOS.org website. */\r
                configPOST_SLEEP_PROCESSING( xModifiableIdleTime );\r
 \r
-               /* Stop TIM2.  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. */\r
+               /* Stop TIM2.  Again, the time the clock is stopped for in not accounted\r
+               for here (as it would normally be) because the clock is so slow it is\r
+               unlikely it will be stopped for a complete count period anyway. */\r
                TIM_Cmd( TIM2, DISABLE );\r
 \r
                /* Re-enable interrupts - see comments above the cpsid instruction()\r
@@ -328,14 +341,20 @@ const portTickType xRegulatorOffIdleTime = 30;
 \r
                if( ulTickFlag != pdFALSE )\r
                {\r
+                       /* Trap overflows before the next calculation. */\r
+                       configASSERT( ulReloadValueForOneTick >= ( uint32_t ) TIM_GetCounter( TIM2 ) );\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
-                       configASSERT( ulReloadValueForOneTick >= ( uint32_t ) TIM_GetCounter( TIM2 ) );\r
                        ulCounterValue = ulReloadValueForOneTick - ( uint32_t ) TIM_GetCounter( TIM2 );\r
+\r
+                       /* Trap under/overflows before the calculated value is used. */\r
                        configASSERT( ulCounterValue <= ( uint32_t ) USHRT_MAX );\r
                        configASSERT( ulCounterValue != 0 );\r
+\r
+                       /* Use the calculated reload value. */\r
                        TIM_SetAutoreload( TIM2, ( uint16_t ) ulCounterValue );\r
                        TIM_SetCounter( TIM2, 0 );\r
 \r
@@ -353,9 +372,11 @@ const portTickType xRegulatorOffIdleTime = 30;
                        sleeping? */\r
                        ulCompleteTickPeriods = ( ( uint32_t ) TIM_GetCounter( TIM2 ) ) / ulReloadValueForOneTick;\r
 \r
+                       /* Check for over/under flows before the following calculation. */\r
+                       configASSERT( ( ( uint32_t ) TIM_GetCounter( TIM2 ) ) >= ( ulCompleteTickPeriods * ulReloadValueForOneTick ) );\r
+\r
                        /* The reload value is set to whatever fraction of a single tick\r
                        period remains. */\r
-                       configASSERT( ( ( uint32_t ) TIM_GetCounter( TIM2 ) ) >= ( ulCompleteTickPeriods * ulReloadValueForOneTick ) );\r
                        ulCounterValue = ( ( uint32_t ) TIM_GetCounter( TIM2 ) ) - ( ulCompleteTickPeriods * ulReloadValueForOneTick );\r
                        configASSERT( ulCounterValue <= ( uint32_t ) USHRT_MAX );\r
                        if( ulCounterValue == 0 )\r
@@ -379,7 +400,5 @@ const portTickType xRegulatorOffIdleTime = 30;
        }\r
 }\r
 \r
-\r
-\r
 #endif /* configCREATE_LOW_POWER_DEMO == 1 */\r
 \r
index 25a4a76efea027c3f9c17e145acca009d0f34337..46d059c915937c7f1f049f9a0439356a10fc6380 100644 (file)
@@ -78,7 +78,8 @@
  * See http://www.freertos.org/a00110.html.\r
  *----------------------------------------------------------*/\r
 \r
-/* Ensure stdint is only used by the compiler, and not the assembler. */\r
+/* Ensure stdint and C code is only used by the compiler, and not the\r
+assembler. */\r
 #ifdef __ICCARM__\r
        #include <stdint.h>\r
        extern uint32_t SystemCoreClock;\r
 \r
 /* Set configCREATE_LOW_POWER_DEMO to one to run the simple blinky low power\r
 demo, or 0 to run the more comprehensive test and demo application. */\r
-#define configCREATE_LOW_POWER_DEMO                    1\r
+#define configCREATE_LOW_POWER_DEMO                    0\r
 \r
+/* A few settings are dependent on the configCREATE_LOW_POWER_DEMO setting. */\r
 #if configCREATE_LOW_POWER_DEMO == 1\r
-       #define configCPU_CLOCK_HZ                                              SystemCoreClock\r
-       #define configUSE_TICKLESS_IDLE                                 1\r
        #define configTICK_RATE_HZ                                              ( 100 )\r
        #define configEXPECTED_IDLE_TIME_BEFORE_SLEEP   ( 20 + 1 ) /* ( ( 200 / portTICK_RATE_MS ) + 1 ) written out pre-processed to enable #error statements to check its value. */\r
+       #define configUSE_TIMERS                                                0\r
 #else\r
-       #define configCPU_CLOCK_HZ                                              SystemCoreClock\r
-       #define configSYSTICK_CLOCK_HZ                                  ( SystemCoreClock >> 3UL )\r
-       #define configUSE_TICKLESS_IDLE                                 0\r
+       #define configSYSTICK_CLOCK_HZ                                  ( SystemCoreClock >> 3UL ) /* Systick clock is one eighth the system clock. */\r
        #define configTICK_RATE_HZ                                              ( ( portTickType ) 1000 )\r
+       #define configUSE_TIMERS                                                1\r
 #endif /* configCREATE_LOW_POWER_DEMO */\r
 \r
+/* Demo specific macros that allow the application writer to insert code to be\r
+executed immediately before the MCU's STOP low power mode is entered and exited\r
+respectively.  These macros are in addition to the standard\r
+configPRE_SLEEP_PROCESSING() and configPOST_SLEEP_PROCESSING() macros, which are\r
+called pre and post the low power SLEEP mode being entered and exited.  These\r
+macros can be used to turn turn off and on IO, clocks, the Flash etc. to obtain\r
+the lowest power possible while the tick is off.  See the comments at the top of\r
+main_low_power.c and in STM32L_low_power_tick_management.c. */\r
 #define configPRE_STOP_PROCESSING()\r
 #define configPOST_STOP_PROCESSING()                           vMainPostStopProcessing()\r
 \r
+/* The configUSE_TICKLESS_IDLE setting is dependent on the users setting of\r
+configCREATE_LOW_POWER_DEMO at the top of this file. */\r
+#define configUSE_TICKLESS_IDLE                                        configCREATE_LOW_POWER_DEMO\r
+\r
+#define configCPU_CLOCK_HZ                                             SystemCoreClock\r
 #define configUSE_PREEMPTION                                   1\r
 #define configUSE_PORT_OPTIMISED_TASK_SELECTION        1\r
 #define configUSE_IDLE_HOOK                                            1\r
 #define configUSE_TICK_HOOK                                            1\r
 #define configMAX_PRIORITIES                                   ( 5 )\r
 #define configMINIMAL_STACK_SIZE                               ( ( unsigned short ) 70 )\r
-#define configTOTAL_HEAP_SIZE                                  ( ( size_t ) ( 10 * 1024 ) )\r
+#define configTOTAL_HEAP_SIZE                                  ( ( size_t ) ( 14 * 1024 ) )\r
 #define configMAX_TASK_NAME_LEN                                        ( 16 )\r
 #define configUSE_TRACE_FACILITY                               1\r
 #define configUSE_16_BIT_TICKS                                 0\r
@@ -119,9 +132,15 @@ demo, or 0 to run the more comprehensive test and demo application. */
 #define configUSE_MUTEXES                                              1\r
 #define configQUEUE_REGISTRY_SIZE                              5\r
 #define configCHECK_FOR_STACK_OVERFLOW                 2\r
-#define configUSE_RECURSIVE_MUTEXES                            0\r
+#define configUSE_RECURSIVE_MUTEXES                            1\r
 #define configUSE_MALLOC_FAILED_HOOK                   1\r
 #define configUSE_APPLICATION_TASK_TAG                 0\r
+#define configUSE_COUNTING_SEMAPHORES                  1\r
+\r
+/* Software timer related definitions. */\r
+#define configTIMER_TASK_PRIORITY                              ( configMAX_PRIORITIES - 1 )\r
+#define configTIMER_QUEUE_LENGTH                               10\r
+#define configTIMER_TASK_STACK_DEPTH                   configMINIMAL_STACK_SIZE\r
 \r
 /* Co-routine definitions. */\r
 #define configUSE_CO_ROUTINES                  0\r
index 6193f1833e0cc66a07cb39d9efc2d8fe449479bb..2e8bdf26dfc486a26e7b8afc4908452336377c96 100644 (file)
     1 tab == 4 spaces!\r
 */\r
 \r
-/*\r
-    FreeRTOS V7.6.0 - Copyright (C) 2013 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
-    ***************************************************************************\r
-     *                                                                       *\r
-     *    FreeRTOS provides completely free yet professionally developed,    *\r
-     *    robust, strictly quality controlled, supported, and cross          *\r
-     *    platform software that has become a de facto standard.             *\r
-     *                                                                       *\r
-     *    Help yourself get started quickly and support the FreeRTOS         *\r
-     *    project by purchasing a FreeRTOS tutorial book, reference          *\r
-     *    manual, or both from: http://www.FreeRTOS.org/Documentation        *\r
-     *                                                                       *\r
-     *    Thank you!                                                         *\r
-     *                                                                       *\r
-    ***************************************************************************\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
-    >>! NOTE: The modification to the GPL is included to allow you to distribute\r
-    >>! a combined work that includes FreeRTOS without being obliged to provide\r
-    >>! the source code for proprietary components outside of the FreeRTOS\r
-    >>! kernel.\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 from the following\r
-    link: http://www.freertos.org/a00114.html\r
-\r
-    1 tab == 4 spaces!\r
-\r
-    ***************************************************************************\r
-     *                                                                       *\r
-     *    Having a problem?  Start by reading the FAQ "My application does   *\r
-     *    not run, what could be wrong?"                                     *\r
-     *                                                                       *\r
-     *    http://www.FreeRTOS.org/FAQHelp.html                               *\r
-     *                                                                       *\r
-    ***************************************************************************\r
-\r
-    http://www.FreeRTOS.org - Documentation, books, training, latest versions,\r
-    license and Real Time Engineers Ltd. contact details.\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.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High\r
-    Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
-    licenses offer ticketed support, indemnification and 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
+ * This project provides two demo applications.  A low power project that\r
+ * demonstrates the FreeRTOS tickless mode, and a more comprehensive test and\r
+ * demo application.  The configCREATE_LOW_POWER_DEMO setting (defined at the\r
+ * top of FreeRTOSConfig.h) is used to select between the two.  The low power\r
+ * demo is implemented and described in main_low_power.c.  The more\r
+ * comprehensive test and demo application is implemented and described in\r
+ * main_full.c.\r
+ *\r
+ * This file implements the code that is not demo specific, including the\r
+ * hardware setup and FreeRTOS hook functions.\r
+ */\r
 \r
 /* Kernel includes. */\r
 #include "FreeRTOS.h"\r
 #include "task.h"\r
-#include "queue.h"\r
-#include "semphr.h"\r
 \r
 /* ST library functions. */\r
 #include "stm32l1xx.h"\r
 #include "discover_board.h"\r
 #include "discover_functions.h"\r
-#include "stm32l_discovery_lcd.h"\r
-\r
-/* Priorities at which the Rx and Tx tasks are created. */\r
-#define configQUEUE_RECEIVE_TASK_PRIORITY      ( tskIDLE_PRIORITY + 1 )\r
-#define        configQUEUE_SEND_TASK_PRIORITY          ( tskIDLE_PRIORITY + 2 )\r
-\r
-/* The number of items the queue can hold.  This is 1 as the Rx task will\r
-remove items as they are added so the Tx task should always find the queue\r
-empty. */\r
-#define mainQUEUE_LENGTH                                       ( 1 )\r
-\r
-/* The LED used to indicate that a value has been received on the queue. */\r
-#define mainQUEUE_LED                                          ( 0 )\r
-\r
-/* A block time of zero simply means "don't block". */\r
-#define mainDONT_BLOCK                                         ( 0 )\r
-\r
-/* The value that is sent from the Tx task to the Rx task on the queue. */\r
-#define mainQUEUED_VALUE                                       ( 100UL )\r
-\r
-/* The length of time the LED will remain on for.  It is on just long enough\r
-to be able to see with the human eye so as not to distort the power readings too\r
-much. */\r
-#define mainLED_TOGGLE_DELAY                           ( 10 / portTICK_RATE_MS )\r
 \r
 /*-----------------------------------------------------------*/\r
 \r
 /*\r
- * The Rx and Tx tasks as described at the top of this file.\r
+ * Set up the hardware ready to run this demo.\r
  */\r
-static void prvQueueReceiveTask( void *pvParameters );\r
-static void prvQueueSendTask( void *pvParameters );\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/* The queue to pass data from the Tx task to the Rx task. */\r
-static xQueueHandle xQueue = NULL;\r
+static void prvSetupHardware( void );\r
 \r
 /*\r
- * Set up the hardware ready to run this demo.\r
+ * main_low_power() is used when configCREATE_LOW_POWER_DEMO is set to 1.\r
+ * main_full() is used when configCREATE_LOW_POWER_DEMO is set to 0.\r
+ * configCREATE_LOW_POWER_DEMO is defined at the top of main.c.\r
  */\r
-static void prvSetupHardware( void );\r
+extern void main_low_power( void );\r
+extern void main_full( void );\r
 \r
-/*-----------------------------------------------------------*/\r
+/* Prototypes for the standard FreeRTOS callback/hook functions implemented\r
+within this file. */\r
+void vApplicationMallocFailedHook( void );\r
+void vApplicationIdleHook( void );\r
+void vApplicationStackOverflowHook( xTaskHandle pxTask, signed char *pcTaskName );\r
+void vApplicationTickHook( void );\r
 \r
-static const portTickType xMaxBlockTime = ( 500L / portTICK_RATE_MS ), xMinBlockTime = ( 100L / portTICK_RATE_MS );\r
-portTickType xSendBlockTime = ( 100UL / portTICK_RATE_MS );\r
-static xSemaphoreHandle xTxSemaphore = NULL;\r
+/*-----------------------------------------------------------*/\r
 \r
 int main( void )\r
 {\r
+       /* Prepare the hardware to run this demo. */\r
        prvSetupHardware();\r
 \r
-       xTxSemaphore = xSemaphoreCreateBinary();\r
-\r
-       /* Create the queue. */\r
-       xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) );\r
-       configASSERT( xQueue );\r
-\r
-       /* Start the two tasks as described at the top of this file. */\r
-       xTaskCreate( prvQueueReceiveTask, ( const signed char * const ) "Rx", configMINIMAL_STACK_SIZE, NULL, configQUEUE_RECEIVE_TASK_PRIORITY, NULL );\r
-       xTaskCreate( prvQueueSendTask, ( const signed char * const ) "TX", configMINIMAL_STACK_SIZE, NULL, configQUEUE_SEND_TASK_PRIORITY, NULL );\r
-\r
-       /* Start the scheduler running running. */\r
-       vTaskStartScheduler();\r
-\r
-       /* If all is well the next line of code will not be reached as the\r
-       scheduler will be running.  If the next line is reached then it is likely\r
-       there was insufficient FreeRTOS heap available for the idle task and/or\r
-       timer task to be created.  See http://www.freertos.org/a00111.html. */\r
-       for( ;; );\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvQueueSendTask( void *pvParameters )\r
-{\r
-const unsigned long ulValueToSend = mainQUEUED_VALUE;\r
-\r
-       /* Remove compiler warning about unused parameter. */\r
-       ( void ) pvParameters;\r
-\r
-       for( ;; )\r
-       {\r
-               /* Place this task into the blocked state until it is time to run\r
-               again. */\r
-               xSemaphoreTake( xTxSemaphore, xSendBlockTime );\r
-\r
-               /* Send to the queue - causing the queue receive task to flash its LED.\r
-               It should not be necessary to block on the queue send because the Rx\r
-               task will already have removed the last queued item. */\r
-               xQueueSend( xQueue, &ulValueToSend, mainDONT_BLOCK );\r
-       }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvQueueReceiveTask( void *pvParameters )\r
-{\r
-unsigned long ulReceivedValue;\r
-\r
-       /* Remove compiler warning about unused parameter. */\r
-       ( void ) pvParameters;\r
-\r
-       for( ;; )\r
-       {\r
-               /* Wait until something arrives in the queue. */\r
-               xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );\r
-\r
-               /*  To get here something must have arrived, but is it the expected\r
-               value?  If it is, turn the LED on for a short while. */\r
-               if( ulReceivedValue == mainQUEUED_VALUE )\r
-               {\r
-                       GPIO_HIGH( LD_GPIO_PORT, LD_GREEN_GPIO_PIN );\r
-                       vTaskDelay( mainLED_TOGGLE_DELAY );\r
-                       GPIO_LOW( LD_GPIO_PORT, LD_GREEN_GPIO_PIN );\r
-               }\r
-       }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void EXTI0_IRQHandler(void)\r
-{\r
-static const portTickType xIncrement = 200UL / portTICK_RATE_MS;\r
-\r
-       if( xSendBlockTime == portMAX_DELAY )\r
+       /* The configCREATE_LOW_POWER_DEMO setting is described at the top of\r
+       this file. */\r
+       #if configCREATE_LOW_POWER_DEMO == 1\r
        {\r
-               portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;\r
-\r
-               /* Unblock the Tx task again. */\r
-               xSemaphoreGiveFromISR( xTxSemaphore, &xHigherPriorityTaskWoken );\r
-\r
-               /* Start over with the short block time that will not result in the\r
-               tick being turned off or a low power mode being entered. */\r
-               xSendBlockTime = xMinBlockTime;\r
-\r
-               portYIELD_FROM_ISR( xHigherPriorityTaskWoken );\r
+               main_low_power();\r
        }\r
-       else\r
+       #else\r
        {\r
-               xSendBlockTime += xIncrement;\r
-\r
-               if( xSendBlockTime > xMaxBlockTime )\r
-               {\r
-                       /* Set the send block time to be infinite to force entry into the STOP\r
-                       sleep mode. */\r
-                       xSendBlockTime = portMAX_DELAY;\r
-               }\r
+               main_full();\r
        }\r
+       #endif\r
 \r
-       EXTI_ClearITPendingBit( EXTI_Line0 );\r
+       /* This line will never be reached. */\r
+       return 0;\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -298,6 +139,7 @@ EXTI_InitTypeDef EXTI_InitStructure;
 NVIC_InitTypeDef NVIC_InitStructure;\r
 void SystemCoreClockUpdate( void );\r
 \r
+       /* System function that updates the SystemCoreClock variable. */\r
        SystemCoreClockUpdate();\r
 \r
        /* Essential on STM32 Cortex-M devices. */\r
@@ -306,15 +148,6 @@ void SystemCoreClockUpdate( void );
        /* Systick is fed from HCLK/8. */\r
        SysTick_CLKSourceConfig( SysTick_CLKSource_HCLK_Div8 );\r
 \r
-       /* Enable HSI Clock. */\r
-//     RCC_HSICmd( ENABLE );\r
-\r
-       /*!< Wait till HSI is ready. */\r
-//     while( RCC_GetFlagStatus( RCC_FLAG_HSIRDY ) == RESET );\r
-\r
-       /* Set HSI as sys clock*/\r
-//     RCC_SYSCLKConfig( RCC_SYSCLKSource_HSI );\r
-\r
        /* Set MSI clock range to ~4.194MHz. */\r
        RCC_MSIRangeConfig( RCC_MSIRange_6 );\r
 \r
@@ -327,29 +160,6 @@ void SystemCoreClockUpdate( void );
        /* Enable SYSCFG clocks. */\r
        RCC_APB2PeriphClockCmd( RCC_APB2Periph_SYSCFG , ENABLE );\r
 \r
-       /* Allow access to the RTC */\r
-//     PWR_RTCAccessCmd( ENABLE );\r
-\r
-       /* Reset RTC Backup Domain */\r
-//     RCC_RTCResetCmd( ENABLE );\r
-//     RCC_RTCResetCmd( DISABLE );\r
-\r
-       /* LSE Enable */\r
-//     RCC_LSEConfig( RCC_LSE_ON );\r
-       //RCC_LSICmd( ENABLE ); //_RB_\r
-\r
-       /* Wait until LSE is ready */\r
-//     while( RCC_GetFlagStatus( RCC_FLAG_LSERDY ) == RESET );\r
-\r
-       /* Disable HSE */\r
-//     RCC_HSEConfig( RCC_HSE_OFF );\r
-\r
-//     if( RCC_GetFlagStatus( RCC_FLAG_HSERDY ) != RESET )\r
-//     {\r
-               /* Stay in infinite loop if HSE is not disabled. */\r
-//             while( 1 );\r
-//     }\r
-\r
        /* Set internal voltage regulator to 1.5V. */\r
        PWR_VoltageScalingConfig( PWR_VoltageScaling_Range2 );\r
 \r
@@ -448,20 +258,6 @@ void vApplicationTickHook( void )
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-void vMainPostStopProcessing( void )\r
-{\r
-extern void SetSysClock( void );\r
-\r
-       SetSysClock();\r
-       /* Unblock the Tx task again. */\r
-//     xSemaphoreGiveFromISR( xTxSemaphore, NULL );\r
-\r
-       /* Start over with the short block time that will not result in the\r
-       tick being turned off or a low power mode being entered. */\r
-//     xSendBlockTime = xMinBlockTime;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
 void vAssertCalled( unsigned long ulLine, const char * const pcFileName )\r
 {\r
 volatile unsigned long ulSetToNonZeroInDebuggerToContinue = 0;\r
@@ -484,835 +280,3 @@ volatile unsigned long ulSetToNonZeroInDebuggerToContinue = 0;
        taskEXIT_CRITICAL();\r
 }\r
 \r
-\r
-\r
-\r
-#ifdef  USE_FULL_ASSERT\r
-\r
-/**\r
-  * @brief  Reports the name of the source file and the source line number\r
-  *         where the assert_param error has occurred.\r
-  * @param  file: pointer to the source file name\r
-  * @param  line: assert_param error line source number\r
-  * @retval None\r
-  */\r
-void assert_failed(uint8_t* file, uint32_t line)\r
-{\r
-  /* User can add his own implementation to report the file name and line number,\r
-     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */\r
-  /* Infinite loop */\r
-  while (1);\r
-}\r
-\r
-#endif\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-#if 0\r
-/**\r
-  ******************************************************************************\r
-  * @file    main.c\r
-  * @author  Microcontroller Division\r
-  * @version V1.0.3\r
-  * @date    May-2013\r
-  * @brief   Main program body\r
-  ******************************************************************************\r
-  * @copy\r
-  *\r
-  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS\r
-  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE\r
-  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY\r
-  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING\r
-  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE\r
-  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.\r
-  *\r
-  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>\r
-  */\r
-\r
-/* Includes ------------------------------------------------------------------*/\r
-\r
-#include "main.h"\r
-\r
-#define BOR_MODIFY\r
-#define BOR_LEVEL OB_BOR_OFF  /*!< BOR is disabled at power down, the reset is asserted when the VDD power supply reachs the PDR(Power Down Reset) threshold (1.5V) */\r
-\r
-\r
-/* Private variables ---------------------------------------------------------*/\r
-\r
-static TSL_tTick_ms_T last_tick_tsl;  /* Hold the last tsl time value */\r
-extern unsigned char Bias_Current;    /* Bias Current stored in E²Prom used for ICC mesurement precision */\r
-extern uint8_t t_bar[2];              /* LCD bar graph: used for displaying active function */\r
-extern bool self_test;                /* Auto_test activation flag: set by interrupt handler if user button is pressed for a few seconds */\r
-extern bool Idd_WakeUP;               /* */\r
-extern volatile bool KeyPressed;      /* */\r
-extern bool UserButton;               /* Set by interrupt handler to indicate that user button is pressed */\r
-uint8_t state_machine;                /* Machine status used by main() wich indicats the active function, set by user button in interrupt handler */\r
-uint16_t Int_CurrentSTBY;             /* */\r
-\r
-#ifdef STM32L1XX_MDP\r
-  uint8_t message[29] = "     ** 32L152CDISCOVERY  **";\r
-       #else\r
-       uint8_t message[29] = "     ** STM32L1-DISCOVERY **";\r
-#endif\r
-/*******************************************************************************/\r
-/**\r
-  * @brief main entry point.\r
-  * @par Parameters None\r
-  * @retval void None\r
-  * @par Required preconditions: None\r
-  */\r
-int main(void)\r
-{\r
-  bool StanbyWakeUp ;\r
-  float Current_STBY;\r
-  __IO uint32_t BOROptionBytes = 0;\r
-\r
- /*!< At this stage the microcontroller clock setting is already configured,\r
-       this is done through SystemInit() function which is called from startup\r
-       file (startup_stm32l1xx_md.s) before to branch to application main.\r
-       To reconfigure the default setting of SystemInit() function, refer to\r
-       system_stm32l1xx.c file\r
-     */\r
-\r
-  /* store Standby Current*/\r
-  Int_CurrentSTBY = Current_Measurement();\r
-\r
-  /* Check if the StandBy flag is set */\r
-  if (PWR_GetFlagStatus(PWR_FLAG_SB) != RESET)\r
-  {\r
-    /* System resumed from STANDBY mode */\r
-    /* Clear StandBy flag */\r
-    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);\r
-    PWR_ClearFlag(PWR_FLAG_SB);\r
-    /* set StandbyWakeup indicator*/\r
-    StanbyWakeUp = TRUE;\r
-  } else\r
-  {\r
-    /* Reset StandbyWakeup indicator*/\r
-    StanbyWakeUp = FALSE;\r
-  }\r
-\r
-       #ifdef BOR_MODIFY\r
-  /* Get BOR Option Bytes */\r
-  BOROptionBytes = FLASH_OB_GetBOR();\r
-\r
-  if((BOROptionBytes & 0x0F) != BOR_LEVEL)\r
-  {\r
-    /* Unlocks the option bytes block access */\r
-    FLASH_OB_Unlock();\r
-\r
-    /* Clears the FLASH pending flags */\r
-    FLASH_ClearFlag(FLASH_FLAG_EOP|FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR\r
-                  | FLASH_FLAG_SIZERR | FLASH_FLAG_OPTVERR);\r
-\r
-    /* Select the desired V(BOR) Level ---------------------------------------*/\r
-    FLASH_OB_BORConfig(BOR_LEVEL);\r
-\r
-    /* Launch the option byte loading */\r
-    FLASH_OB_Launch();\r
-  }\r
-#endif\r
-\r
-  /* Configure Clocks for Application need */\r
-  RCC_Configuration();\r
-\r
-  /* Set internal voltage regulator to 1.8V */\r
-  PWR_VoltageScalingConfig(PWR_VoltageScaling_Range1);\r
-\r
-  /* Wait Until the Voltage Regulator is ready */\r
-  while (PWR_GetFlagStatus(PWR_FLAG_VOS) != RESET) ;\r
-\r
-  /* Init I/O ports */\r
-  Init_GPIOs();\r
-\r
-  /* Initializes ADC */\r
-  ADC_Icc_Init();\r
-\r
-  /* Enable General interrupts */\r
-  enableGlobalInterrupts();\r
-\r
-  /* Init Touch Sensing configuration */\r
-  TSL_user_Init();\r
-\r
-  /* Initializes the LCD glass */\r
-  LCD_GLASS_Init();\r
-\r
-  /* Reset Keypressed flag used in interrupt and Scrollsentence */\r
-  KeyPressed = FALSE;\r
-\r
-  /* user button actif */\r
-  UserButton = TRUE;\r
-\r
-  /* Check if User button press at Power ON  */\r
-  if ((USERBUTTON_GPIO_PORT->IDR & USERBUTTON_GPIO_PIN) != 0x0)\r
-  {\r
-    /* Measure operational amplifier bias current and store value in E²Prom for application need*/\r
-    Bias_measurement();\r
-  }\r
-\r
-  /* Standard application startup */\r
-  if ( !StanbyWakeUp )\r
-  {\r
-    /* Reset autotest flag stored in memory */\r
-    AUTOTEST(FALSE) ;\r
-\r
-               /* Display Welcome message */\r
-    LCD_GLASS_ScrollSentence(message,1,SCROLL_SPEED);\r
-    if (!KeyPressed)\r
-    {\r
-       /* if welcome message not skipped Display blinking message JP1 ON*/\r
-      LCD_BlinkConfig(LCD_BlinkMode_AllSEG_AllCOM,LCD_BlinkFrequency_Div512);\r
-      LCD_GLASS_DisplayString("JP1 ON");\r
-      TEMPO;\r
-      TEMPO;\r
-      TEMPO;\r
-      TEMPO;\r
-      LCD_BlinkConfig(LCD_BlinkMode_Off,LCD_BlinkFrequency_Div32);\r
-    }\r
-  /* Wake up from Standby or autotest */\r
-  }  else  {\r
-    /*Check Autotest value stored in flash to get wakeup context*/\r
-    if (self_test)\r
-    {\r
-      /* Wake UP: Return of RESET by Auto test */\r
-      auto_test_part2();\r
-    } else {\r
-      /* Wake UP: Return of RESET by Current STAND BY measurement */\r
-      LCD_GLASS_ScrollSentence("     STANDBY WAKEUP",1,SCROLL_SPEED);\r
-      /* Substract bias current from operational amplifier*/\r
-      if ( Int_CurrentSTBY > Bias_Current )\r
-        Int_CurrentSTBY -= Bias_Current;\r
-      Current_STBY = Int_CurrentSTBY * Vdd_appli()/ADC_CONV;\r
-      Current_STBY *= 20L;\r
-      display_MuAmp((uint32_t)Current_STBY);\r
-      /* Wait for user button press to continue */\r
-      while(!KeyPressed);\r
-    }\r
-  }\r
-  /* Reset KeyPress Flag */\r
-  KeyPressed = FALSE;\r
-  /* Clear LCD bars */\r
-  BAR0_OFF;\r
-  BAR1_OFF;\r
-  BAR2_OFF;\r
-  BAR3_OFF;\r
-  /* Switch off the leds*/\r
-  GPIO_HIGH(LD_GPIO_PORT,LD_GREEN_GPIO_PIN);\r
-  GPIO_LOW(LD_GPIO_PORT,LD_BLUE_GPIO_PIN);\r
-  /* Set application state machine to VREF state  */\r
-  state_machine = STATE_VREF ;\r
-  /*Until application reset*/\r
-  while (1)\r
-  {\r
-  /* run autotest if requested by the user */\r
-    if (self_test)\r
-      auto_test();\r
-    /* Perform Actions depending on current application State  */\r
-    switch (state_machine)\r
-    {\r
-        /* VREF State : Display VRef value */\r
-        case STATE_VREF:\r
-          GPIO_TOGGLE(LD_GPIO_PORT,LD_BLUE_GPIO_PIN);\r
-          GPIO_TOGGLE(LD_GPIO_PORT,LD_GREEN_GPIO_PIN);\r
-          Vref_measure();\r
-          TEMPO ;\r
-        break;\r
-\r
-        /* Slider Value State : Display the TS slider value */\r
-        case STATE_SLIDER_VALUE:\r
-\r
-        // Execute STMTouch Driver state machine\r
-        if (TSL_user_Action() == TSL_STATUS_OK)\r
-          {\r
-            ProcessSensors(); // Execute sensors related tasks\r
-          }\r
-        break;\r
-\r
-        /* Slider button State : Display the curent TS button pressed  */\r
-        case STATE_SLIDER_BUTTON:\r
-        // Execute STMTouch Driver state machine\r
-        if (TSL_user_Action() == TSL_STATUS_OK)\r
-          {\r
-            ProcessSensorsButtons(); // Execute sensors related tasks\r
-          }\r
-          break;\r
-\r
-        /* ICC RUN State : ICC mesurements in Run and Sleep modes   */\r
-        case STATE_ICC_RUN:\r
-          LCD_GLASS_DisplayString(" RUN  ");\r
-          TEMPO;\r
-          Icc_RUN();\r
-          TEMPO;\r
-          TEMPO;\r
-          TEMPO;\r
-          TEMPO;\r
-          LCD_GLASS_DisplayString(" SLEEP ");\r
-          TEMPO;\r
-          Icc_SLEEP();\r
-          TEMPO;\r
-          TEMPO;\r
-          TEMPO;\r
-          TEMPO;\r
-        break;\r
-\r
-        /* ICC LOW POWER RUN State : ICC mesurements in LowPower run and LowPower Sleep modes */\r
-        case STATE_ICC_LP_RUN:\r
-          LCD_GLASS_DisplayString("LP RUN");\r
-          TEMPO;\r
-          Icc_LPRUN();\r
-          TEMPO;\r
-          TEMPO;\r
-          TEMPO;\r
-          TEMPO;\r
-          LCD_GLASS_DisplayString("LP SLP");\r
-          TEMPO;\r
-          Icc_LPSLEEP();\r
-          TEMPO;\r
-          TEMPO;\r
-          TEMPO;\r
-          TEMPO;\r
-        break;\r
-\r
-        /* ICC STOP  State : ICC mesurements in Stop and STOP NoRTC modes */\r
-        case STATE_ICC_STOP:\r
-          LCD_GLASS_DisplayString(" STOP ");\r
-          TEMPO;\r
-          Icc_STOP();\r
-          TEMPO;\r
-          TEMPO;\r
-          TEMPO;\r
-          TEMPO;\r
-          LCD_GLASS_DisplayString("SP-NRTC");\r
-          TEMPO;\r
-          Icc_Stop_NoRTC();\r
-          TEMPO;\r
-          TEMPO;\r
-          TEMPO;\r
-          TEMPO;\r
-          break;\r
-\r
-        /* ICC Standby  State : ICC mesurements in Standby mode */\r
-        case STATE_ICC_STBY:\r
-          LCD_GLASS_DisplayString("STBY  ");\r
-          TEMPO;\r
-          TEMPO;\r
-        ADC_Icc_Test(MCU_STBY);\r
-        /* Following break never performed dues to software reset in previous function */\r
-        break;\r
-\r
-        /* for safe: normaly never reaches */\r
-        default:\r
-          LCD_GLASS_Clear();\r
-          LCD_GLASS_DisplayString("ERROR");\r
-        break;\r
-      }\r
-      /* Reset KeyPress flag*/\r
-      KeyPressed = FALSE;\r
-    }\r
-}\r
-\r
-/**\r
-  * @brief  Configures the different system clocks.\r
-  * @param  None\r
-  * @retval None\r
-  */\r
-void RCC_Configuration(void)\r
-{\r
-  /* Enable HSI Clock */\r
-  RCC_HSICmd(ENABLE);\r
-\r
-  /*!< Wait till HSI is ready */\r
-  while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET);\r
-\r
-  /* Set HSI as sys clock*/\r
-  RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);\r
-\r
-  /* Set MSI clock range to ~4.194MHz*/\r
-  RCC_MSIRangeConfig(RCC_MSIRange_6);\r
-\r
-  /* Enable the GPIOs clocks */\r
-  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC| RCC_AHBPeriph_GPIOD| RCC_AHBPeriph_GPIOE| RCC_AHBPeriph_GPIOH, ENABLE);\r
-\r
-  /* Enable comparator, LCD and PWR mngt clocks */\r
-  RCC_APB1PeriphClockCmd(RCC_APB1Periph_COMP | RCC_APB1Periph_LCD | RCC_APB1Periph_PWR,ENABLE);\r
-\r
-  /* Enable ADC & SYSCFG clocks */\r
-  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_SYSCFG , ENABLE);\r
-\r
-  /* Allow access to the RTC */\r
-  PWR_RTCAccessCmd(ENABLE);\r
-\r
-  /* Reset RTC Backup Domain */\r
-  RCC_RTCResetCmd(ENABLE);\r
-  RCC_RTCResetCmd(DISABLE);\r
-\r
-  /* LSE Enable */\r
-  RCC_LSEConfig(RCC_LSE_ON);\r
-\r
-  /* Wait until LSE is ready */\r
-  while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);\r
-\r
-   /* RTC Clock Source Selection */\r
-  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);\r
-\r
-  /* Enable the RTC */\r
-  RCC_RTCCLKCmd(ENABLE);\r
-\r
-  /*Disable HSE*/\r
-  RCC_HSEConfig(RCC_HSE_OFF);\r
-  if(RCC_GetFlagStatus(RCC_FLAG_HSERDY) != RESET )\r
-  {\r
-    /* Stay in infinite loop if HSE is not disabled*/\r
-    while(1);\r
-  }\r
-}\r
-\r
-/**\r
-  * @brief  To initialize the I/O ports\r
-  * @caller main\r
-  * @param None\r
-  * @retval None\r
-  */\r
-void  Init_GPIOs (void)\r
-{\r
-  /* GPIO, EXTI and NVIC Init structure declaration */\r
-  GPIO_InitTypeDef GPIO_InitStructure;\r
-  EXTI_InitTypeDef EXTI_InitStructure;\r
-  NVIC_InitTypeDef NVIC_InitStructure;\r
-\r
-  /* Configure User Button pin as input */\r
-  GPIO_InitStructure.GPIO_Pin = USERBUTTON_GPIO_PIN;\r
-  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;\r
-  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;\r
-  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;\r
-  GPIO_Init(USERBUTTON_GPIO_PORT, &GPIO_InitStructure);\r
-\r
-  /* Select User Button pin as input source for EXTI Line */\r
-  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource0);\r
-\r
-  /* Configure EXT1 Line 0 in interrupt mode trigged on Rising edge */\r
-  EXTI_InitStructure.EXTI_Line = EXTI_Line0 ;  // PA0 for User button AND IDD_WakeUP\r
-  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;\r
-  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;\r
-  EXTI_InitStructure.EXTI_LineCmd = ENABLE;\r
-  EXTI_Init(&EXTI_InitStructure);\r
-\r
-  /* Enable and set EXTI0 Interrupt to the lowest priority */\r
-  NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn ;\r
-  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;\r
-  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;\r
-  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;\r
-  NVIC_Init(&NVIC_InitStructure);\r
-\r
-  /* Configure the LED_pin as output push-pull for LD3 & LD4 usage*/\r
-  GPIO_InitStructure.GPIO_Pin = LD_GREEN_GPIO_PIN | LD_BLUE_GPIO_PIN;\r
-  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;\r
-  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;\r
-  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;\r
-  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;\r
-  GPIO_Init(LD_GPIO_PORT, &GPIO_InitStructure);\r
-\r
-  /* Force a low level on LEDs*/\r
-  GPIO_LOW(LD_GPIO_PORT,LD_GREEN_GPIO_PIN);\r
-  GPIO_LOW(LD_GPIO_PORT,LD_BLUE_GPIO_PIN);\r
-\r
-/* Counter enable: GPIO set in output for enable the counter */\r
-  GPIO_InitStructure.GPIO_Pin = CTN_CNTEN_GPIO_PIN;\r
-  GPIO_Init( CTN_GPIO_PORT, &GPIO_InitStructure);\r
-\r
-/* To prepare to start counter */\r
-  GPIO_HIGH(CTN_GPIO_PORT,CTN_CNTEN_GPIO_PIN);\r
-\r
-/* Configure Port A LCD Output pins as alternate function */\r
-  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_8 | GPIO_Pin_9 |GPIO_Pin_10 |GPIO_Pin_15;\r
-  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;\r
-  GPIO_Init( GPIOA, &GPIO_InitStructure);\r
-\r
-/* Select LCD alternate function for Port A LCD Output pins */\r
-  GPIO_PinAFConfig(GPIOA, GPIO_PinSource1,GPIO_AF_LCD) ;\r
-  GPIO_PinAFConfig(GPIOA, GPIO_PinSource2,GPIO_AF_LCD) ;\r
-  GPIO_PinAFConfig(GPIOA, GPIO_PinSource3,GPIO_AF_LCD) ;\r
-  GPIO_PinAFConfig(GPIOA, GPIO_PinSource8,GPIO_AF_LCD) ;\r
-  GPIO_PinAFConfig(GPIOA, GPIO_PinSource9,GPIO_AF_LCD) ;\r
-  GPIO_PinAFConfig(GPIOA, GPIO_PinSource10,GPIO_AF_LCD) ;\r
-  GPIO_PinAFConfig(GPIOA, GPIO_PinSource15,GPIO_AF_LCD) ;\r
-\r
-  /* Configure Port B LCD Output pins as alternate function */\r
-  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_8 | GPIO_Pin_9 \\r
-                                 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;\r
-  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;\r
-  GPIO_Init( GPIOB, &GPIO_InitStructure);\r
-\r
-  /* Select LCD alternate function for Port B LCD Output pins */\r
-  GPIO_PinAFConfig(GPIOB, GPIO_PinSource3,GPIO_AF_LCD) ;\r
-  GPIO_PinAFConfig(GPIOB, GPIO_PinSource4,GPIO_AF_LCD) ;\r
-  GPIO_PinAFConfig(GPIOB, GPIO_PinSource5,GPIO_AF_LCD) ;\r
-  GPIO_PinAFConfig(GPIOB, GPIO_PinSource8,GPIO_AF_LCD) ;\r
-  GPIO_PinAFConfig(GPIOB, GPIO_PinSource9,GPIO_AF_LCD) ;\r
-  GPIO_PinAFConfig(GPIOB, GPIO_PinSource10,GPIO_AF_LCD) ;\r
-  GPIO_PinAFConfig(GPIOB, GPIO_PinSource11,GPIO_AF_LCD) ;\r
-  GPIO_PinAFConfig(GPIOB, GPIO_PinSource12,GPIO_AF_LCD) ;\r
-  GPIO_PinAFConfig(GPIOB, GPIO_PinSource13,GPIO_AF_LCD) ;\r
-  GPIO_PinAFConfig(GPIOB, GPIO_PinSource14,GPIO_AF_LCD) ;\r
-  GPIO_PinAFConfig(GPIOB, GPIO_PinSource15,GPIO_AF_LCD) ;\r
-\r
-  /* Configure Port C LCD Output pins as alternate function */\r
-  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_6 \\r
-                                 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |GPIO_Pin_11 ;\r
-  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;\r
-  GPIO_Init( GPIOC, &GPIO_InitStructure);\r
-\r
-  /* Select LCD alternate function for Port B LCD Output pins */\r
-  GPIO_PinAFConfig(GPIOC, GPIO_PinSource0,GPIO_AF_LCD) ;\r
-  GPIO_PinAFConfig(GPIOC, GPIO_PinSource1,GPIO_AF_LCD) ;\r
-  GPIO_PinAFConfig(GPIOC, GPIO_PinSource2,GPIO_AF_LCD) ;\r
-  GPIO_PinAFConfig(GPIOC, GPIO_PinSource3,GPIO_AF_LCD) ;\r
-  GPIO_PinAFConfig(GPIOC, GPIO_PinSource6,GPIO_AF_LCD) ;\r
-  GPIO_PinAFConfig(GPIOC, GPIO_PinSource7,GPIO_AF_LCD) ;\r
-  GPIO_PinAFConfig(GPIOC, GPIO_PinSource8,GPIO_AF_LCD) ;\r
-  GPIO_PinAFConfig(GPIOC, GPIO_PinSource9,GPIO_AF_LCD) ;\r
-  GPIO_PinAFConfig(GPIOC, GPIO_PinSource10,GPIO_AF_LCD) ;\r
-  GPIO_PinAFConfig(GPIOC, GPIO_PinSource11,GPIO_AF_LCD) ;\r
-\r
-  /* Configure ADC (IDD_MEASURE) pin as Analogue */\r
-  GPIO_InitStructure.GPIO_Pin = IDD_MEASURE  ;\r
-  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;\r
-  GPIO_Init( IDD_MEASURE_PORT, &GPIO_InitStructure);\r
-}\r
-\r
-\r
-/**\r
-  * @brief  Executed when a sensor is in Error state\r
-  * @param  None\r
-  * @retval None\r
-  */\r
-void MyLinRots_ErrorStateProcess(void)\r
-{\r
-  // Add here your own processing when a sensor is in Error state\r
-  TSL_linrot_SetStateOff();\r
-}\r
-\r
-\r
-/**\r
-  * @brief  Executed when a sensor is in Off state\r
-  * @param  None\r
-  * @retval None\r
-  */\r
-void MyLinRots_OffStateProcess(void)\r
-{\r
-  // Add here your own processing when a sensor is in Off state\r
-}\r
-\r
-\r
-\r
-/**\r
-  * @brief  Inserts a delay time.\r
-  * @param  nTime: specifies the delay time length, in 1 ms.\r
-  * @retval None\r
-  */\r
-void Delay(uint32_t nTime)\r
-{\r
-  while (TSL_tim_CheckDelay_ms((TSL_tTick_ms_T) nTime, &last_tick_tsl) != TSL_STATUS_OK);\r
-}\r
-\r
-\r
-#ifdef  USE_FULL_ASSERT\r
-\r
-/**\r
-  * @brief  Reports the name of the source file and the source line number\r
-  *         where the assert_param error has occurred.\r
-  * @param  file: pointer to the source file name\r
-  * @param  line: assert_param error line source number\r
-  * @retval None\r
-  */\r
-void assert_failed(uint8_t* file, uint32_t line)\r
-{\r
-  /* User can add his own implementation to report the file name and line number,\r
-     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */\r
-  /* Infinite loop */\r
-  while (1);\r
-}\r
-\r
-#endif\r
-\r
-void vApplicationStackOverflowHook( void )\r
-{\r
-}\r
-\r
-/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/\r
-       /* Ensure the interrupt is clear before exiting.  The RTC uses EXTI line 20\r
-       to bring the CPU out of sleep. */\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-void _vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime )\r
-{\r
-uint32_t ulWakeupValue, ulCompleteTickPeriods;\r
-eSleepModeStatus eSleepAction;\r
-portTickType xModifiableIdleTime;\r
-\r
-       /* THIS FUNCTION IS CALLED WITH THE SCHEDULER SUSPENDED. */\r
-\r
-       /* Make sure the wakeup timer 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
-       ulWakeupValue = ( ( ulWakeupValueForOneTick + 1UL ) * xExpectedIdleTime ) - 1UL;\r
-       if( ulWakeupValue > ulStoppedTimerCompensation )\r
-       {\r
-               /* Compensate for the fact that the RTC is going to be stopped\r
-               momentarily. */\r
-               ulWakeupValue -= 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 in\r
-       some tiny drift of the time maintained by the kernel with respect to\r
-       calendar time. */\r
-       prvDisableWakeupTimer();\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
-       __asm volatile ( "cpsid i" );\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\r
-       the context switch might have been pended by an external interrupt that\r
-       requires processing. */\r
-       eSleepAction = eTaskConfirmSleepModeStatus();\r
-       if( eSleepAction == eAbortSleep )\r
-       {\r
-               /* Restart tick. */\r
-               prvEnableWakeupTimer();\r
-\r
-               /* Re-enable interrupts - see comments above the cpsid instruction()\r
-               above. */\r
-               __asm volatile ( "cpsie i" );\r
-       }\r
-       else\r
-       {\r
-               /* Adjust the alarm value to take into account that the current time\r
-               slice is already partially complete. */\r
-//             ulWakeupValue -= ( RTC->WUTR & RTC_WUTR_WUT ); /* Current value. */\r
-\r
-               /* Disable the write protection for RTC registers */\r
-               RTC->WPR = 0xCA;\r
-               RTC->WPR = 0x53;\r
-\r
-               /* Set the Wakeup Timer value */\r
-               RTC->WUTR = ulWakeupValue;\r
-\r
-               /* Enable the Wakeup Timer */\r
-               RTC->CR |= (uint32_t)RTC_CR_WUTE;\r
-\r
-               /* Enable the write protection for RTC registers. */\r
-               RTC->WPR = 0xFF;\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
-                       /* Sleep until something happens. */\r
-                       __asm volatile ( "wfi" );\r
-                       __asm volatile ( "dsb" );\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 clock 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. */\r
-               prvDisableWakeupTimer();\r
-\r
-               /* Re-enable interrupts - see comments above the cpsid instruction()\r
-               above. */\r
-               __asm volatile ( "cpsie i" );\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 alarm value with whatever remains of this tick period. */\r
-                       ulWakeupValue = ulWakeupValueForOneTick;//_RB_ - ( RTC->WUTR & RTC_WUTR_WUT ); /* Current value. */\r
-\r
-                       /* Disable the write protection for RTC registers */\r
-                       RTC->WPR = 0xCA;\r
-                       RTC->WPR = 0x53;\r
-\r
-                       /* Set the Wakeup Timer value */\r
-                       RTC->WUTR = ulWakeupValue;\r
-\r
-                       /* Enable the write protection for RTC registers. */\r
-                       RTC->WPR = 0xFF;\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 = ( RTC->WUTR & RTC_WUTR_WUT ) / ulWakeupValueForOneTick;\r
-\r
-                       /* The alarm value is set to whatever fraction of a single tick\r
-                       period remains. */\r
-                       ulWakeupValue = ( RTC->WUTR & RTC_WUTR_WUT ) - ( ulCompleteTickPeriods * ulWakeupValueForOneTick );\r
-\r
-                       /* Disable the write protection for RTC registers */\r
-                       RTC->WPR = 0xCA;\r
-                       RTC->WPR = 0x53;\r
-\r
-                       /* Set the Wakeup Timer value */\r
-                       RTC->WUTR = ulWakeupValue;\r
-\r
-                       /* Enable the write protection for RTC registers. */\r
-                       RTC->WPR = 0xFF;\r
-               }\r
-\r
-               /* Restart the RTC so it runs down from the wakeup value.  The wakeup\r
-               value will get set to the value required to generate exactly one tick\r
-               period the next time the wakeup interrupt executes. */\r
-               prvEnableWakeupTimer();\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
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-//     RTC_ClearITPendingBit( RTC_IT_WUT );\r
-//     EXTI_ClearITPendingBit( EXTI_Line20 );\r
-\r
-\r
-\r
-#ifdef USE_RTC\r
-NVIC_InitTypeDef NVIC_InitStructure;\r
-EXTI_InitTypeDef EXTI_InitStructure;\r
-\r
-       /* Enable access to the RTC registers. */\r
-       PWR_RTCAccessCmd( ENABLE );\r
-       RCC_RTCResetCmd( ENABLE );\r
-       RCC_RTCResetCmd( DISABLE );\r
-\r
-       /* LSE Enable */\r
-       RCC_LSEConfig( RCC_LSE_ON );\r
-\r
-       /* Wait until LSE is ready. */\r
-       while( RCC_GetFlagStatus( RCC_FLAG_LSERDY ) == RESET );\r
-\r
-       /* Enable the PWR clock. */\r
-       RCC_APB1PeriphClockCmd( RCC_APB1Periph_PWR, ENABLE );\r
-\r
-       /* LSE used as RTC clock source. */\r
-       RCC_RTCCLKConfig( RCC_RTCCLKSource_LSE ); /* 32.768KHz external */\r
-\r
-       /* Enable the RTC clock and wait for sync. */\r
-       RCC_RTCCLKCmd( ENABLE );\r
-       RTC_WaitForSynchro();\r
-\r
-       /* Watchdog timer user EXTI line 20 to wake from sleep. */\r
-       EXTI_ClearITPendingBit( EXTI_Line20 );\r
-       EXTI_InitStructure.EXTI_Line = EXTI_Line20;\r
-       EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;\r
-       EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;\r
-       EXTI_InitStructure.EXTI_LineCmd = ENABLE;\r
-       EXTI_Init( &EXTI_InitStructure );\r
-\r
-       /* Enable the RTC Wakeup Interrupt. */\r
-       NVIC_InitStructure.NVIC_IRQChannel = RTC_WKUP_IRQn;\r
-       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_LOWEST_INTERRUPT_PRIORITY;\r
-       NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;\r
-       NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;\r
-       NVIC_Init( &NVIC_InitStructure );\r
-\r
-       /* Drive the wakeup clock from LSE/2 (32768/2) */\r
-       RTC_WakeUpClockConfig( RTC_WakeUpClock_RTCCLK_Div2 );\r
-\r
-       /* Set count and reload values. */\r
-       RTC_SetWakeUpCounter( ulReloadValueForOneTick );\r
-\r
-       /* Enable the RTC Wakeup Interrupt. */\r
-       RTC_ITConfig( RTC_IT_WUT, ENABLE );\r
-\r
-       /* Enable Wakeup Counter. */\r
-       RTC_WakeUpCmd( ENABLE );\r
-#endif\r
-\r
-\r
-static void prvDisableWakeupTimer( void )\r
-{\r
-       RTC->WPR = 0xCA;\r
-       RTC->WPR = 0x53;\r
-\r
-       /* Disable the Wakeup Timer */\r
-       RTC->CR &= (uint32_t)~RTC_CR_WUTE;\r
-\r
-       /* Wait till RTC WUTWF flag is set. */\r
-       /* _RB_ Timeout needed. */\r
-       do\r
-       {\r
-       } while( ( RTC->ISR & RTC_ISR_WUTWF ) == 0x00 );\r
-\r
-       /* Enable the write protection for RTC registers */\r
-       RTC->WPR = 0xFF;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvEnableWakeupTimer( void )\r
-{\r
-       RTC->WPR = 0xCA;\r
-       RTC->WPR = 0x53;\r
-\r
-       /* Enable the Wakeup Timer */\r
-       RTC->CR |= (uint32_t)RTC_CR_WUTE;\r
-\r
-       /* Enable the write protection for RTC registers */\r
-       RTC->WPR = 0xFF;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-\r
-#endif\r
-\r
diff --git a/FreeRTOS/Demo/CORTEX_STM32L152_Discovery_IAR/main_full.c b/FreeRTOS/Demo/CORTEX_STM32L152_Discovery_IAR/main_full.c
new file mode 100644 (file)
index 0000000..cae1454
--- /dev/null
@@ -0,0 +1,263 @@
+/*\r
+    FreeRTOS V7.6.0 - Copyright (C) 2013 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
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS provides completely free yet professionally developed,    *\r
+     *    robust, strictly quality controlled, supported, and cross          *\r
+     *    platform software that has become a de facto standard.             *\r
+     *                                                                       *\r
+     *    Help yourself get started quickly and support the FreeRTOS         *\r
+     *    project by purchasing a FreeRTOS tutorial book, reference          *\r
+     *    manual, or both from: http://www.FreeRTOS.org/Documentation        *\r
+     *                                                                       *\r
+     *    Thank you!                                                         *\r
+     *                                                                       *\r
+    ***************************************************************************\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
+    >>! NOTE: The modification to the GPL is included to allow you to distribute\r
+    >>! a combined work that includes FreeRTOS without being obliged to provide\r
+    >>! the source code for proprietary components outside of the FreeRTOS\r
+    >>! kernel.\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 from the following\r
+    link: http://www.freertos.org/a00114.html\r
+\r
+    1 tab == 4 spaces!\r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    Having a problem?  Start by reading the FAQ "My application does   *\r
+     *    not run, what could be wrong?"                                     *\r
+     *                                                                       *\r
+     *    http://www.FreeRTOS.org/FAQHelp.html                               *\r
+     *                                                                       *\r
+    ***************************************************************************\r
+\r
+    http://www.FreeRTOS.org - Documentation, books, training, latest versions,\r
+    license and Real Time Engineers Ltd. contact details.\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.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High\r
+    Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
+    licenses offer ticketed support, indemnification and middleware.\r
+\r
+    http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+    engineered and independently SIL3 certified version for use in safety and\r
+    mission critical applications that require provable dependability.\r
+\r
+    1 tab == 4 spaces!\r
+*/\r
+\r
+/******************************************************************************\r
+ * NOTE 1:  This project provides two demo applications.  A low power tickless\r
+ * project, and a more comprehensive test and demo application.  The\r
+ * configCREATE_LOW_POWER_DEMO setting in FreeRTOSConfig.h is used to\r
+ * select between the two.  See the notes on using\r
+ * configCREATE_LOW_POWER_DEMO in FreeRTOSConfig.h.  This file implements\r
+ * the comprehensive test and demo version.\r
+ *\r
+ * NOTE 2:  This file only contains the source code that is specific to the\r
+ * full demo.  Generic functions, such FreeRTOS hook functions, and functions\r
+ * required to configure the hardware, are defined in main.c.\r
+ ******************************************************************************\r
+ *\r
+ * main_full() creates all the demo application tasks and a software timer, then\r
+ * starts the scheduler.  The web documentation provides more details of the\r
+ * standard demo application tasks, which provide no particular functionality,\r
+ * but do provide a good example of how to use the FreeRTOS API.\r
+ *\r
+ * In addition to the standard demo tasks, the following tasks and tests are\r
+ * defined and/or created within this file:\r
+ *\r
+ * "Check" timer - The check software timer period is initially set to three\r
+ * seconds.  The callback function associated with the check software timer\r
+ * checks that all the standard demo tasks are not only still executing, but\r
+ * are executing without reporting any errors.  If the check software timer\r
+ * discovers that a task has either stalled, or reported an error, then it\r
+ * changes its own execution period from the initial three seconds, to just\r
+ * 200ms.  The check software timer callback function also toggles an LED each\r
+ * time it is called.  This provides a visual indication of the system status:\r
+ * If the LED toggles every three seconds, then no issues have been discovered.\r
+ * If the LED toggles every 200ms, then an issue has been discovered with at\r
+ * least one task.\r
+ *\r
+ * See the documentation page for this demo on the FreeRTOS.org web site for\r
+ * full information, including hardware setup requirements.\r
+ */\r
+\r
+/* Standard includes. */\r
+#include <stdio.h>\r
+\r
+/* Kernel includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "timers.h"\r
+#include "semphr.h"\r
+\r
+/* Standard demo application includes. */\r
+#include "PollQ.h"\r
+#include "semtest.h"\r
+#include "dynamic.h"\r
+#include "BlockQ.h"\r
+#include "blocktim.h"\r
+#include "countsem.h"\r
+#include "GenQTest.h"\r
+#include "recmutex.h"\r
+\r
+/* ST library functions. */\r
+#include "stm32l1xx.h"\r
+#include "discover_board.h"\r
+#include "discover_functions.h"\r
+#include "stm32l_discovery_lcd.h"\r
+\r
+/* Priorities for the demo application tasks. */\r
+#define mainQUEUE_POLL_PRIORITY                                ( tskIDLE_PRIORITY + 2UL )\r
+#define mainSEM_TEST_PRIORITY                          ( tskIDLE_PRIORITY + 1UL )\r
+#define mainBLOCK_Q_PRIORITY                           ( tskIDLE_PRIORITY + 2UL )\r
+\r
+/* A block time of zero simply means "don't block". */\r
+#define mainDONT_BLOCK                                         ( 0UL )\r
+\r
+/* The period after which the check timer will expire providing no errors\r
+have been reported by any of the standard demo tasks.  ms are converted to the\r
+equivalent in ticks using the portTICK_RATE_MS constant. */\r
+#define mainCHECK_TIMER_PERIOD_MS                      ( 3000UL / portTICK_RATE_MS )\r
+\r
+/* The period at which the check timer will expire, in ms, if an error has been\r
+reported in one of the standard demo tasks.  ms are converted to the equivalent\r
+in ticks using the portTICK_RATE_MS constant. */\r
+#define mainERROR_CHECK_TIMER_PERIOD_MS        ( 200UL / portTICK_RATE_MS )\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * The check timer callback function, as described at the top of this file.\r
+ */\r
+static void prvCheckTimerCallback( xTimerHandle xTimer );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+void main_full( void )\r
+{\r
+xTimerHandle xCheckTimer = NULL;\r
+\r
+       /* Start all the other standard demo/test tasks.  They have not particular\r
+       functionality, but do demonstrate how to use the FreeRTOS API and test the\r
+       kernel port. */\r
+       vStartDynamicPriorityTasks();\r
+       vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );\r
+       vCreateBlockTimeTasks();\r
+       vStartCountingSemaphoreTasks();\r
+       vStartGenericQueueTasks( tskIDLE_PRIORITY );\r
+       vStartRecursiveMutexTasks();\r
+       vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );\r
+       vStartSemaphoreTasks( mainSEM_TEST_PRIORITY );\r
+\r
+       /* Create the software timer that performs the 'check' functionality,\r
+       as described at the top of this file. */\r
+       xCheckTimer = xTimerCreate( ( const signed char * ) "CheckTimer",/* A text name, purely to help debugging. */\r
+                                                               ( mainCHECK_TIMER_PERIOD_MS ),          /* The timer period, in this case 3000ms (3s). */\r
+                                                               pdTRUE,                                                         /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */\r
+                                                               ( void * ) 0,                                           /* The ID is not used, so can be set to anything. */\r
+                                                               prvCheckTimerCallback                           /* The callback function that inspects the status of all the other tasks. */\r
+                                                         );\r
+\r
+       if( xCheckTimer != NULL )\r
+       {\r
+               xTimerStart( xCheckTimer, mainDONT_BLOCK );\r
+       }\r
+\r
+       /* Start the scheduler. */\r
+       vTaskStartScheduler();\r
+\r
+       /* If all is well, the scheduler will now be running, and the following line\r
+       will never be reached.  If the following line does execute, then there was\r
+       insufficient FreeRTOS heap memory available for the idle and/or timer tasks\r
+       to be created.  See the memory management section on the FreeRTOS web site\r
+       for more details. */\r
+       for( ;; );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvCheckTimerCallback( xTimerHandle xTimer )\r
+{\r
+static long lChangedTimerPeriodAlready = pdFALSE;\r
+unsigned long ulErrorFound = pdFALSE;\r
+\r
+       /* Check all the demo tasks to ensure they are all still running, and that\r
+       none have detected an error. */\r
+\r
+       if( xAreDynamicPriorityTasksStillRunning() != pdTRUE )\r
+       {\r
+               ulErrorFound = pdTRUE;\r
+       }\r
+\r
+       if( xAreBlockingQueuesStillRunning() != pdTRUE )\r
+       {\r
+               ulErrorFound = pdTRUE;\r
+       }\r
+\r
+       if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE )\r
+       {\r
+               ulErrorFound = pdTRUE;\r
+       }\r
+\r
+       if ( xAreGenericQueueTasksStillRunning() != pdTRUE )\r
+       {\r
+               ulErrorFound = pdTRUE;\r
+       }\r
+\r
+       if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE )\r
+       {\r
+               ulErrorFound = pdTRUE;\r
+       }\r
+\r
+       if( xArePollingQueuesStillRunning() != pdTRUE )\r
+       {\r
+               ulErrorFound = pdTRUE;\r
+       }\r
+\r
+       if( xAreSemaphoreTasksStillRunning() != pdTRUE )\r
+       {\r
+               ulErrorFound = pdTRUE;\r
+       }\r
+\r
+       /* Toggle the check LED to give an indication of the system status.  If\r
+       the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then\r
+       everything is ok.  A faster toggle indicates an error. */\r
+       GPIO_TOGGLE( LD_GPIO_PORT, LD_GREEN_GPIO_PIN );\r
+\r
+       /* Have any errors been latch in ulErrorFound?  If so, shorten the\r
+       period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds.\r
+       This will result in an increase in the rate at which mainCHECK_LED\r
+       toggles. */\r
+       if( ulErrorFound != pdFALSE )\r
+       {\r
+               if( lChangedTimerPeriodAlready == pdFALSE )\r
+               {\r
+                       lChangedTimerPeriodAlready = pdTRUE;\r
+\r
+                       /* This call to xTimerChangePeriod() uses a zero block time.\r
+                       Functions called from inside of a timer callback function must\r
+                       *never* attempt to block. */\r
+                       xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );\r
+               }\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
diff --git a/FreeRTOS/Demo/CORTEX_STM32L152_Discovery_IAR/main_low_power.c b/FreeRTOS/Demo/CORTEX_STM32L152_Discovery_IAR/main_low_power.c
new file mode 100644 (file)
index 0000000..5e3744a
--- /dev/null
@@ -0,0 +1,337 @@
+/*\r
+    FreeRTOS V7.6.0 - Copyright (C) 2013 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
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    FreeRTOS provides completely free yet professionally developed,    *\r
+     *    robust, strictly quality controlled, supported, and cross          *\r
+     *    platform software that has become a de facto standard.             *\r
+     *                                                                       *\r
+     *    Help yourself get started quickly and support the FreeRTOS         *\r
+     *    project by purchasing a FreeRTOS tutorial book, reference          *\r
+     *    manual, or both from: http://www.FreeRTOS.org/Documentation        *\r
+     *                                                                       *\r
+     *    Thank you!                                                         *\r
+     *                                                                       *\r
+    ***************************************************************************\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
+    >>! NOTE: The modification to the GPL is included to allow you to distribute\r
+    >>! a combined work that includes FreeRTOS without being obliged to provide\r
+    >>! the source code for proprietary components outside of the FreeRTOS\r
+    >>! kernel.\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 from the following\r
+    link: http://www.freertos.org/a00114.html\r
+\r
+    1 tab == 4 spaces!\r
+\r
+    ***************************************************************************\r
+     *                                                                       *\r
+     *    Having a problem?  Start by reading the FAQ "My application does   *\r
+     *    not run, what could be wrong?"                                     *\r
+     *                                                                       *\r
+     *    http://www.FreeRTOS.org/FAQHelp.html                               *\r
+     *                                                                       *\r
+    ***************************************************************************\r
+\r
+    http://www.FreeRTOS.org - Documentation, books, training, latest versions,\r
+    license and Real Time Engineers Ltd. contact details.\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.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High\r
+    Integrity Systems to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
+    licenses offer ticketed support, indemnification and middleware.\r
+\r
+    http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
+    engineered and independently SIL3 certified version for use in safety and\r
+    mission critical applications that require provable dependability.\r
+\r
+    1 tab == 4 spaces!\r
+*/\r
+\r
+/* ****************************************************************************\r
+ * When configCREATE_LOW_POWER_DEMO is set to 1 in FreeRTOSConfig.h main() will\r
+ * call main_low_power(), which is defined in this file.  main_low_power()\r
+ * demonstrates FreeRTOS tick suppression being used to allow the MCU to be\r
+ * placed into the Sleep, Low Power Sleep and Stop low power modes.  When\r
+ * configCREATE_LOW_POWER_DEMO is set to 0 main will instead call main_full(),\r
+ * which is a more comprehensive RTOS demonstration.\r
+ * ****************************************************************************\r
+ *\r
+ * This application demonstrates the FreeRTOS tickless idle mode (tick\r
+ * suppression) being used to allow the STM32L to enter various low power modes\r
+ * during extended idle periods.  See\r
+ * http://www.freertos.org/low-power-tickless-rtos.html for information on\r
+ * tickless operation.\r
+ *\r
+ * Deeper low power modes have longer wake up periods that lighter low power\r
+ * modes, and power is also used simply entering and especially exiting the low\r
+ * power modes.  How the low power modes are used therefore requires careful\r
+ * consideration to ensure power consumption is truly minimised and that the\r
+ * embedded device meets its real time requirements.  This demo is configured to\r
+ * select between four different modes depending on the anticipated idle period.\r
+ * Note the time thresholds used to decide which low power mode to enter are\r
+ * purely for convenience of demonstration and are not intended to represent\r
+ * optimal values for any particular application.\r
+ *\r
+ * The STM32L specific part of the tickless operation is implemented in\r
+ * STM32L_low_power_tick_management.c.\r
+ *\r
+ * The demo is configured to execute on the STM32L Discovery board.\r
+ *\r
+ * Functionality:\r
+ *\r
+ *  + Two tasks are created, an Rx task and a Tx task.  A queue is created to\r
+ *       pass a message from the Tx task to the Rx task.\r
+ *\r
+ *  + The Rx task blocks on a queue to wait for data, blipping an LED each time\r
+ *    data is received (turning it on and then off again) before returning to\r
+ *    block on the queue once more.\r
+ *\r
+ *  + The Tx task repeatedly blocks on an attempt to obtain a semaphore, and\r
+ *       unblocks if either the semaphore is received or its block time expires.\r
+ *       After leaving the blocked state the Tx task uses the queue to send a\r
+ *       value to the Rx task, which in turn causes the Rx task to exit the\r
+ *       Blocked state and blip the LED.  The rate at which the LED is seen to blip\r
+ *       is therefore dependent on the block time.\r
+ *\r
+ *  + The Tx task's block time is changed by the interrupt service routine that\r
+ *       executes when the USER button is pressed.  The low power mode entered\r
+ *       depends on the block time (as described in the Observed Behaviour section\r
+ *       below).  Four block times are used: short, medium, long and infinite.\r
+ *\r
+ * Observed behaviour:\r
+ *\r
+ * 1) The block time used by the Tx task is initialised to its 'short' value,\r
+ * so when the Tx task blocks on the semaphore it times-out quickly, resulting\r
+ * in the LED toggling rapidly.  The timeout period is less than the value of\r
+ * configEXPECTED_IDLE_TIME_BEFORE_SLEEP (set in FreeRTOSConfig.h), so the\r
+ * initial state does not suppress the tick interrupt or enter a low power mode.\r
+ *\r
+ * 2) When the button is pressed the block time used by the Tx task is increased\r
+ * to its 'medium' value.  The longer block time results in a slowing of the\r
+ * rate at which the LED toggles.  The time the Tx task spends in the blocked\r
+ * state is now greater than configEXPECTED_IDLE_TIME_BEFORE_SLEEP, so the tick\r
+ * is suppressed.  The MCU is placed into the 'Sleep' low power state while the\r
+ * tick is suppressed.\r
+ *\r
+ * 3) When the button is pressed again the block time used by the Tx task is\r
+ * increased to its 'long' value, so the rate at which the LED is observed to\r
+ * blip gets even slow.  When the 'long' block time is used the MCU is placed\r
+ * into its 'Low Power Sleep' low power state.\r
+ *\r
+ * 4) The next time the button is pressed the block time used by the Tx task is\r
+ * set to infinite, so the Tx task does not time out when it attempts to obtain\r
+ * the semaphore, and therefore the LED stops blipping completely.  Both tasks\r
+ * are not blocked indefinitely and the MCU is placed into its 'Stop' low power\r
+ * state.\r
+ *\r
+ * 5) Pressing the button one final time results in the semaphore being 'given'\r
+ * to unblock the Tx task, the CPU clocks being returned to their pre-stop\r
+ * state, and the block time being reset to its 'short' time.  The system is\r
+ * then back to its initial condition with the LED blipping rapidly.\r
+ *\r
+ */\r
+\r
+/* Kernel includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "queue.h"\r
+#include "semphr.h"\r
+\r
+/* ST library functions. */\r
+#include "stm32l1xx.h"\r
+#include "discover_board.h"\r
+#include "discover_functions.h"\r
+#include "stm32l_discovery_lcd.h"\r
+\r
+/* Priorities at which the Rx and Tx tasks are created. */\r
+#define configQUEUE_RECEIVE_TASK_PRIORITY      ( tskIDLE_PRIORITY + 1 )\r
+#define        configQUEUE_SEND_TASK_PRIORITY          ( tskIDLE_PRIORITY + 2 )\r
+\r
+/* The number of items the queue can hold.  This is 1 as the Rx task will\r
+remove items as they are added so the Tx task should always find the queue\r
+empty. */\r
+#define mainQUEUE_LENGTH                                       ( 1 )\r
+\r
+/* A block time of zero simply means "don't block". */\r
+#define mainDONT_BLOCK                                         ( 0 )\r
+\r
+/* The value that is sent from the Tx task to the Rx task on the queue. */\r
+#define mainQUEUED_VALUE                                       ( 100UL )\r
+\r
+/* The length of time the LED will remain on for. */\r
+#define mainLED_TOGGLE_DELAY                           ( 10 / portTICK_RATE_MS )\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * The Rx and Tx tasks as described at the top of this file.\r
+ */\r
+static void prvQueueReceiveTask( void *pvParameters );\r
+static void prvQueueSendTask( void *pvParameters );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* The queue used to pass data from the Tx task to the Rx task. */\r
+static xQueueHandle xQueue = NULL;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Holds the block time used by the Tx task. */\r
+portTickType xSendBlockTime = ( 100UL / portTICK_RATE_MS );\r
+\r
+/* The lower an upper limits of the block time.  An infinite block time is used\r
+if xSendBlockTime is incremented past xMaxBlockTime. */\r
+static const portTickType xMaxBlockTime = ( 500L / portTICK_RATE_MS ), xMinBlockTime = ( 100L / portTICK_RATE_MS );\r
+\r
+/* The semaphore on which the Tx task blocks. */\r
+static xSemaphoreHandle xTxSemaphore = NULL;\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* See the comments at the top of the file. */\r
+void main_low_power( void )\r
+{\r
+       /* Create the semaphore as described at the top of this file. */\r
+       xTxSemaphore = xSemaphoreCreateBinary();\r
+       configASSERT( xTxSemaphore );\r
+\r
+       /* Create the queue as described at the top of this file. */\r
+       xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) );\r
+       configASSERT( xQueue );\r
+\r
+       /* Start the two tasks as described at the top of this file. */\r
+       xTaskCreate( prvQueueReceiveTask, ( const signed char * const ) "Rx", configMINIMAL_STACK_SIZE, NULL, configQUEUE_RECEIVE_TASK_PRIORITY, NULL );\r
+       xTaskCreate( prvQueueSendTask, ( const signed char * const ) "TX", configMINIMAL_STACK_SIZE, NULL, configQUEUE_SEND_TASK_PRIORITY, NULL );\r
+\r
+       /* Start the scheduler running running. */\r
+       vTaskStartScheduler();\r
+\r
+       /* If all is well the next line of code will not be reached as the\r
+       scheduler will be running.  If the next line is reached then it is likely\r
+       there was insufficient FreeRTOS heap available for the idle task and/or\r
+       timer task to be created.  See http://www.freertos.org/a00111.html. */\r
+       for( ;; );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvQueueSendTask( void *pvParameters )\r
+{\r
+const unsigned long ulValueToSend = mainQUEUED_VALUE;\r
+\r
+       /* Remove compiler warning about unused parameter. */\r
+       ( void ) pvParameters;\r
+\r
+       for( ;; )\r
+       {\r
+               /* Enter the Blocked state to wait for the semaphore.  The task will\r
+               leave the Blocked state if either the semaphore is received or\r
+               xSendBlockTime ticks pass without the semaphore being received. */\r
+               xSemaphoreTake( xTxSemaphore, xSendBlockTime );\r
+\r
+               /* Send to the queue - causing the Tx task to flash its LED. */\r
+               xQueueSend( xQueue, &ulValueToSend, mainDONT_BLOCK );\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvQueueReceiveTask( void *pvParameters )\r
+{\r
+unsigned long ulReceivedValue;\r
+\r
+       /* Remove compiler warning about unused parameter. */\r
+       ( void ) pvParameters;\r
+\r
+       for( ;; )\r
+       {\r
+               /* Wait until something arrives in the queue. */\r
+               xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );\r
+\r
+               /*  To get here something must have arrived, but is it the expected\r
+               value?  If it is, turn the LED on for a short while. */\r
+               if( ulReceivedValue == mainQUEUED_VALUE )\r
+               {\r
+                       /* LED on... */\r
+                       GPIO_HIGH( LD_GPIO_PORT, LD_GREEN_GPIO_PIN );\r
+\r
+                       /* ... short delay ... */\r
+                       vTaskDelay( mainLED_TOGGLE_DELAY );\r
+\r
+                       /* ... LED off again. */\r
+                       GPIO_LOW( LD_GPIO_PORT, LD_GREEN_GPIO_PIN );\r
+               }\r
+       }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Handles interrupts generated by pressing the USER button. */\r
+void EXTI0_IRQHandler(void)\r
+{\r
+static const portTickType xIncrement = 200UL / portTICK_RATE_MS;\r
+\r
+       /* If xSendBlockTime is already portMAX_DELAY then the Tx task was blocked\r
+       indefinitely, and this interrupt is bringing the MCU out of STOP low power\r
+       mode. */\r
+       if( xSendBlockTime == portMAX_DELAY )\r
+       {\r
+               portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;\r
+\r
+               /* Unblock the Tx task. */\r
+               xSemaphoreGiveFromISR( xTxSemaphore, &xHigherPriorityTaskWoken );\r
+\r
+               /* Start over with the 'short' block time as described at the top of\r
+               this file. */\r
+               xSendBlockTime = xMinBlockTime;\r
+\r
+               /* Request a yield if calling xSemaphoreGiveFromISR() caused a task to\r
+               leave the Blocked state (which it will have done) and the task that left\r
+               the Blocked state has a priority higher than the currently running task\r
+               (which it will have). */\r
+               portYIELD_FROM_ISR( xHigherPriorityTaskWoken );\r
+       }\r
+       else\r
+       {\r
+               /* Increase the block time used by the Tx task, as described at the top\r
+               of this file. */\r
+               xSendBlockTime += xIncrement;\r
+\r
+               /* If the block time has gone over the configured maximum then set it to\r
+               an infinite block time to allow the MCU to go into its STOP low power\r
+               mode. */\r
+               if( xSendBlockTime > xMaxBlockTime )\r
+               {\r
+                       xSendBlockTime = portMAX_DELAY;\r
+               }\r
+       }\r
+\r
+       EXTI_ClearITPendingBit( EXTI_Line0 );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/* The configPOST_STOP_PROCESSING() macro is called when the MCU leaves its\r
+STOP low power mode.  The macro is set in FreeRTOSConfig.h to call\r
+vMainPostStopProcessing(). */\r
+void vMainPostStopProcessing( void )\r
+{\r
+extern void SetSysClock( void );\r
+\r
+       /* The STOP low power mode has been exited.  Reconfigure the system clocks\r
+       ready for normally running again. */\r
+       SetSysClock();\r
+}\r
+/*-----------------------------------------------------------*/\r
index b3d3f25dd19ed7673857877b72e46df702d69cf1..208f6343887e4f6d54de9f3be163c5e8ad7851fc 100644 (file)
@@ -10,7 +10,7 @@ define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
 define symbol __ICFEDIT_region_RAM_end__   = 0x20003FFF;\r
 /*-Sizes-*/\r
 define symbol __ICFEDIT_size_cstack__ = 0x400;\r
-define symbol __ICFEDIT_size_heap__   = 0x200;\r
+define symbol __ICFEDIT_size_heap__   = 0x0;\r
 /**** End of ICF editor section. ###ICF###*/\r
 \r
 \r