]> git.sur5r.net Git - freertos/commitdiff
STM32L discovery demo is now demonstrating three low power modes - still needs clean up.
authorrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Tue, 10 Dec 2013 10:07:53 +0000 (10:07 +0000)
committerrtel <rtel@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Tue, 10 Dec 2013 10:07:53 +0000 (10:07 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2121 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 [new file with mode: 0644]
FreeRTOS/Demo/CORTEX_STM32L152_Discovery_IAR/System/system_stm32l1xx.c
FreeRTOS/Demo/CORTEX_STM32L152_Discovery_IAR/include/FreeRTOSConfig.h
FreeRTOS/Demo/CORTEX_STM32L152_Discovery_IAR/main.c
FreeRTOS/Demo/CORTEX_STM32L152_Discovery_IAR/stm32l1xx_it.c

index f4d28006bf1c37434174d944b876576aa5727416..e9ce99b951d6d458195e31bceeb6477212be772b 100644 (file)
@@ -49,7 +49,7 @@
         </option>\r
         <option>\r
           <name>RunToEnable</name>\r
-          <state>1</state>\r
+          <state>0</state>\r
         </option>\r
         <option>\r
           <name>RunToName</name>\r
       </plugin>\r
       <plugin>\r
         <file>$TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin</file>\r
-        <loadFlag>0</loadFlag>\r
+        <loadFlag>1</loadFlag>\r
       </plugin>\r
       <plugin>\r
         <file>$TOOLKIT_DIR$\plugins\rtos\PowerPac\PowerPacRTOS.ewplugin</file>\r
index 2c910bbe003a935080e2921f8fb8a1104cdfb90c..66e90c0e071ef24d7efae68e01b5f40895bfe459 100644 (file)
         <option>\r
           <name>CCAllowList</name>\r
           <version>1</version>\r
-          <state>1111111</state>\r
+          <state>0000000</state>\r
         </option>\r
         <option>\r
           <name>CCDebugInfo</name>\r
         </option>\r
         <option>\r
           <name>CCOptLevel</name>\r
-          <state>3</state>\r
+          <state>0</state>\r
         </option>\r
         <option>\r
           <name>CCOptStrategy</name>\r
         </option>\r
         <option>\r
           <name>CCOptLevelSlave</name>\r
-          <state>3</state>\r
+          <state>0</state>\r
         </option>\r
         <option>\r
           <name>CompilerMisraRules98</name>\r
       <file>\r
         <name>$PROJ_DIR$\ST_Code\Libraries\STM32L1xx_StdPeriph_Driver\src\stm32l1xx_syscfg.c</name>\r
       </file>\r
+      <file>\r
+        <name>$PROJ_DIR$\ST_Code\Libraries\STM32L1xx_StdPeriph_Driver\src\stm32l1xx_tim.c</name>\r
+      </file>\r
     </group>\r
     <group>\r
       <name>TouchSensingDriver</name>\r
   <file>\r
     <name>$PROJ_DIR$\stm32l1xx_it.c</name>\r
   </file>\r
+  <file>\r
+    <name>$PROJ_DIR$\STM32L_low_power_tick_management.c</name>\r
+  </file>\r
   <file>\r
     <name>$PROJ_DIR$\tsl_user.c</name>\r
   </file>\r
diff --git a/FreeRTOS/Demo/CORTEX_STM32L152_Discovery_IAR/STM32L_low_power_tick_management.c b/FreeRTOS/Demo/CORTEX_STM32L152_Discovery_IAR/STM32L_low_power_tick_management.c
new file mode 100644 (file)
index 0000000..faff612
--- /dev/null
@@ -0,0 +1,385 @@
+/*\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
+/* Standard includes. */\r
+#include <limits.h>\r
+\r
+/* FreeRTOS includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+\r
+/* ST library functions. */\r
+#include "stm32l1xx.h"\r
+\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
+ *\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
+ * SysTick timer.\r
+ */\r
+#if configCREATE_LOW_POWER_DEMO == 1\r
+\r
+/* The frequency at which TIM2 should 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
+#define DBGMCU_APB1_FZ         ( * ( ( volatile unsigned long * ) 0xE0042008 ) )\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
+ */\r
+void TIM2_IRQHandler( void );\r
+\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Calculate how many clock increments make up a single tick period. */\r
+static const uint32_t ulReloadValueForOneTick = ( ( lpCLOCK_INPUT_FREQUENCY / configTICK_RATE_HZ ) - 1 );\r
+\r
+/* Holds the maximum number of ticks that can be suppressed - which is\r
+basically how far into the future an interrupt can be generated. Set during\r
+initialisation. */\r
+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
+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
+clears the interrupt, which is specific to the clock being used to generate the\r
+tick. */\r
+void TIM2_IRQHandler( void )\r
+{\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
+       ( void ) portSET_INTERRUPT_MASK_FROM_ISR();\r
+       {\r
+               if( xTaskIncrementTick() != pdFALSE )\r
+               {\r
+                       portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;\r
+               }\r
+\r
+               /* Just completely clear the interrupt mask on exit by passing 0 because\r
+               it is known that this interrupt will only ever execute with the lowest\r
+               possible interrupt priority. */\r
+       }\r
+       portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );\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
+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
+       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
+       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
+       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
+       NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;\r
+       NVIC_Init(&NVIC_InitStructure);\r
+       TIM_ITConfig( TIM2, TIM_IT_Update, ENABLE );\r
+       TIM_SetCounter( TIM2, 0 );\r
+       TIM_Cmd( TIM2, ENABLE );\r
+\r
+       /* See the comments where xMaximumPossibleSuppressedTicks is declared. */\r
+       xMaximumPossibleSuppressedTicks = ( ( unsigned long ) USHRT_MAX ) / ulReloadValueForOneTick;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+/* Override the default definition of vPortSuppressTicksAndSleep() that is\r
+weakly defined in the FreeRTOS Cortex-M3 port layer with a version that manages\r
+the TIM2 interrupt, as the tick is generated from TIM2 compare matches events. */\r
+void vPortSuppressTicksAndSleep( portTickType xExpectedIdleTime )\r
+{\r
+uint32_t ulCounterValue, ulCompleteTickPeriods;\r
+eSleepModeStatus eSleepAction;\r
+portTickType xModifiableIdleTime;\r
+const portTickType xRegulatorOffIdleTime = 30;\r
+\r
+       /* THIS FUNCTION IS CALLED WITH THE SCHEDULER SUSPENDED. */\r
+\r
+       /* Make sure the TIM2 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
+       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
+       TIM_Cmd( TIM2, DISABLE );\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
+       __asm volatile ( "dsb" );\r
+       __asm volatile ( "isb" );\r
+\r
+       /* The tick flag is set to false before sleeping.  If it is true when sleep\r
+       mode is exited then sleep mode was probably exited because the tick was\r
+       suppressed for the entire xExpectedIdleTime period. */\r
+       ulTickFlag = pdFALSE;\r
+\r
+       /* If a context switch is pending then abandon the low power entry as\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
+               TIM_Cmd( TIM2, ENABLE );\r
+\r
+               /* Re-enable interrupts - see comments above the cpsid instruction()\r
+               above. */\r
+               __asm volatile ( "cpsie i" );\r
+       }\r
+       else if( eSleepAction == eNoTasksWaitingTimeout )\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
+               PWR_EnterSTOPMode( PWR_Regulator_LowPower, PWR_SLEEPEntry_WFI );\r
+               configPOST_STOP_PROCESSING();\r
+\r
+               /* Restart tick. */\r
+               TIM_SetCounter( TIM2, 0 );\r
+               TIM_Cmd( TIM2, ENABLE );\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 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
+               configASSERT( ulCounterValue < ( uint32_t ) USHRT_MAX );\r
+               configASSERT( ulCounterValue != 0 );\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
+               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
+                       /* The sleep mode used is dependent on the expected idle time\r
+                       as the deeper the sleep the longer the wake up time. */\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
+                       {\r
+                               /* A slightly higher power sleep mode with a faster wake up\r
+                               time. */\r
+                               PWR_EnterSleepMode( PWR_Regulator_ON, PWR_SLEEPEntry_WFI );\r
+                       }\r
+               }\r
+\r
+               /* Allow the application to define some post sleep processing. */\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
+               TIM_Cmd( TIM2, DISABLE );\r
+\r
+               /* Re-enable interrupts - see comments above the cpsid instruction()\r
+               above. */\r
+               __asm volatile ( "cpsie i" );\r
+               __asm volatile ( "dsb" );\r
+               __asm volatile ( "isb" );\r
+\r
+               if( ulTickFlag != pdFALSE )\r
+               {\r
+                       /* The tick interrupt has already executed, although because this\r
+                       function is called with the scheduler suspended the actual tick\r
+                       processing will not occur until after this function has exited.\r
+                       Reset the reload value with whatever remains of this tick period. */\r
+                       configASSERT( ulReloadValueForOneTick >= ( uint32_t ) TIM_GetCounter( TIM2 ) );\r
+                       ulCounterValue = ulReloadValueForOneTick - ( uint32_t ) TIM_GetCounter( TIM2 );\r
+                       configASSERT( ulCounterValue <= ( uint32_t ) USHRT_MAX );\r
+                       configASSERT( ulCounterValue != 0 );\r
+                       TIM_SetAutoreload( TIM2, ( uint16_t ) ulCounterValue );\r
+                       TIM_SetCounter( TIM2, 0 );\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 = ( ( uint32_t ) TIM_GetCounter( TIM2 ) ) / 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
+                       {\r
+                               /* There is no fraction remaining. */\r
+                               ulCounterValue = ulReloadValueForOneTick;\r
+                               ulCompleteTickPeriods++;\r
+                       }\r
+                       TIM_SetAutoreload( TIM2, ( uint16_t ) ulCounterValue );\r
+                       TIM_SetCounter( TIM2, 0 );\r
+               }\r
+\r
+               /* Restart TIM2 so it runs up to the reload value.  The reload value\r
+               will get set to the value required to generate exactly one tick period\r
+               the next time the TIM2 interrupt executes. */\r
+               TIM_Cmd( TIM2, ENABLE );\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
+#endif /* configCREATE_LOW_POWER_DEMO == 1 */\r
+\r
index 9676838934b595faaf1e61568aadb65b621de505..2ca0c4774221a068aee36090fc00689ee0504820 100644 (file)
@@ -8,69 +8,69 @@
   *          This file contains the system clock configuration for STM32L1xx Ultra\r
   *          Low Medium-density devices, and is generated by the clock configuration\r
   *          tool "STM32L1xx_Clock_Configuration_V1.0.0.xls".\r
-  *             \r
-  * 1.  This file provides two functions and one global variable to be called from \r
+  *\r
+  * 1.  This file provides two functions and one global variable to be called from\r
   *     user application:\r
   *      - SystemInit(): Setups the system clock (System clock source, PLL Multiplier\r
   *                      and Divider factors, AHB/APBx prescalers and Flash settings),\r
-  *                      depending on the configuration made in the clock xls tool. \r
-  *                      This function is called at startup just after reset and \r
+  *                      depending on the configuration made in the clock xls tool.\r
+  *                      This function is called at startup just after reset and\r
   *                      before branch to main program. This call is made inside\r
   *                      the "startup_stm32l1xx_md.s" file.\r
-  *                        \r
+  *\r
   *      - SystemCoreClock variable: Contains the core clock (HCLK), it can be used\r
-  *                                  by the user application to setup the SysTick \r
+  *                                  by the user application to setup the SysTick\r
   *                                  timer or configure other parameters.\r
-  *                                     \r
+  *\r
   *      - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must\r
   *                                 be called whenever the core clock is changed\r
-  *                                 during program execution.   \r
-  *      \r
+  *                                 during program execution.\r
+  *\r
   * 2. After each device reset the MSI (2.1 MHz Range) is used as system clock source.\r
   *    Then SystemInit() function is called, in "startup_stm32l1xx_md.s" file, to\r
-  *    configure the system clock before to branch to main program.    \r
-  *    \r
+  *    configure the system clock before to branch to main program.\r
+  *\r
   * 3. If the system clock source selected by user fails to startup, the SystemInit()\r
-  *    function will do nothing and MSI still used as system clock source. User can \r
-  *    add some code to deal with this issue inside the SetSysClock() function.       \r
-  * \r
+  *    function will do nothing and MSI still used as system clock source. User can\r
+  *    add some code to deal with this issue inside the SetSysClock() function.\r
+  *\r
   * 4. The default value of HSE crystal is set to 8MHz, refer to "HSE_VALUE" define\r
   *    in "stm32l1xx.h" file. When HSE is used as system clock source, directly or\r
   *    through PLL, and you are using different crystal you have to adapt the HSE\r
   *    value to your own configuration.\r
-  * \r
-  * 5. This file configures the system clock as follows:  \r
+  *\r
+  * 5. This file configures the system clock as follows:\r
   *=============================================================================\r
   *                         System Clock Configuration\r
   *=============================================================================\r
   *        System clock source          | HSI\r
-  *----------------------------------------------------------------------------- \r
+  *-----------------------------------------------------------------------------\r
   *        SYSCLK                       | 16000000 Hz\r
-  *----------------------------------------------------------------------------- \r
+  *-----------------------------------------------------------------------------\r
   *        HCLK                         | 16000000 Hz\r
-  *----------------------------------------------------------------------------- \r
+  *-----------------------------------------------------------------------------\r
   *        AHB Prescaler                | 1\r
-  *----------------------------------------------------------------------------- \r
+  *-----------------------------------------------------------------------------\r
   *        APB1 Prescaler               | 1\r
-  *----------------------------------------------------------------------------- \r
+  *-----------------------------------------------------------------------------\r
   *        APB2 Prescaler               | 1\r
-  *----------------------------------------------------------------------------- \r
+  *-----------------------------------------------------------------------------\r
   *        HSE Frequency                | 8000000 Hz\r
-  *----------------------------------------------------------------------------- \r
+  *-----------------------------------------------------------------------------\r
   *        PLL DIV                      | Not Used\r
-  *----------------------------------------------------------------------------- \r
+  *-----------------------------------------------------------------------------\r
   *        PLL MUL                      | Not Used\r
-  *----------------------------------------------------------------------------- \r
+  *-----------------------------------------------------------------------------\r
   *        VDD                          | 3.3 V\r
-  *----------------------------------------------------------------------------- \r
+  *-----------------------------------------------------------------------------\r
   *        Vcore                        | 1.8 V (Range 1)\r
-  *----------------------------------------------------------------------------- \r
+  *-----------------------------------------------------------------------------\r
   *        Flash Latency                | 0 WS\r
-  *----------------------------------------------------------------------------- \r
+  *-----------------------------------------------------------------------------\r
   *        Require 48MHz for USB clock  | Disabled\r
-  *----------------------------------------------------------------------------- \r
+  *-----------------------------------------------------------------------------\r
   *=============================================================================\r
-  ****************************************************************************** \r
+  ******************************************************************************\r
   * @attention\r
   *\r
   * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS\r
@@ -81,7 +81,7 @@
   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.\r
   *\r
   * <h2><center>&copy; COPYRIGHT 2010 STMicroelectronics</center></h2>\r
-  ******************************************************************************  \r
+  ******************************************************************************\r
   */\r
 \r
 /** @addtogroup CMSIS\r
@@ -90,8 +90,8 @@
 \r
 /** @addtogroup stm32l1xx_system\r
   * @{\r
-  */  \r
-  \r
+  */\r
+\r
 /** @addtogroup STM32L1xx_System_Private_Includes\r
   * @{\r
   */\r
   * @{\r
   */\r
 /*!< Uncomment the following line if you need to relocate your vector Table in\r
-     Internal SRAM. */ \r
+     Internal SRAM. */\r
 /* #define VECT_TAB_SRAM */\r
-#define VECT_TAB_OFFSET  0x0 /*!< Vector Table base offset field. \r
+#define VECT_TAB_OFFSET  0x0 /*!< Vector Table base offset field.\r
                                   This value must be a multiple of 0x200. */\r
 /**\r
   * @}\r
@@ -145,7 +145,7 @@ __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}
   * @{\r
   */\r
 \r
-static void SetSysClock(void);\r
+void SetSysClock(void);\r
 \r
 /**\r
   * @}\r
@@ -157,7 +157,7 @@ static void SetSysClock(void);
 \r
 /**\r
   * @brief  Setup the microcontroller system.\r
-  *         Initialize the Embedded Flash Interface, the PLL and update the \r
+  *         Initialize the Embedded Flash Interface, the PLL and update the\r
   *         SystemCoreClock variable.\r
   * @param  None\r
   * @retval None\r
@@ -169,7 +169,7 @@ void SystemInit (void)
 \r
   /*!< Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], MCOSEL[2:0] and MCOPRE[2:0] bits */\r
   RCC->CFGR &= (uint32_t)0x88FFC00C;\r
-  \r
+\r
   /*!< Reset HSION, HSEON, CSSON and PLLON bits */\r
   RCC->CR &= (uint32_t)0xEEFEFFFE;\r
 \r
@@ -181,7 +181,7 @@ void SystemInit (void)
 \r
   /*!< Disable all interrupts */\r
   RCC->CIR = 0x00000000;\r
-    \r
+\r
   /* Configure the System clock frequency, AHB/APBx prescalers and Flash settings */\r
   SetSysClock();\r
 \r
@@ -194,31 +194,31 @@ void SystemInit (void)
 \r
 /**\r
   * @brief  Update SystemCoreClock according to Clock Register Values\r
-  * @note   - The system frequency computed by this function is not the real \r
-  *           frequency in the chip. It is calculated based on the predefined \r
+  * @note   - The system frequency computed by this function is not the real\r
+  *           frequency in the chip. It is calculated based on the predefined\r
   *           constant and the selected clock source:\r
-  *             \r
-  *           - If SYSCLK source is MSI, SystemCoreClock will contain the MSI \r
+  *\r
+  *           - If SYSCLK source is MSI, SystemCoreClock will contain the MSI\r
   *             value as defined by the MSI range.\r
-  *                                   \r
+  *\r
   *           - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)\r
-  *                                              \r
+  *\r
   *           - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)\r
-  *                          \r
-  *           - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) \r
+  *\r
+  *           - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)\r
   *             or HSI_VALUE(*) multiplied/divided by the PLL factors.\r
-  *         \r
+  *\r
   *         (*) HSI_VALUE is a constant defined in stm32l1xx.h file (default value\r
   *             16 MHz) but the real value may vary depending on the variations\r
-  *             in voltage and temperature.   \r
-  *    \r
+  *             in voltage and temperature.\r
+  *\r
   *         (**) HSE_VALUE is a constant defined in stm32l1xx.h file (default value\r
   *              8 MHz), user has to ensure that HSE_VALUE is same as the real\r
   *              frequency of the crystal used. Otherwise, this function may\r
   *              have wrong result.\r
-  *                \r
+  *\r
   *         - The result of this function could be not correct when using fractional\r
-  *           value for HSE crystal.  \r
+  *           value for HSE crystal.\r
   * @param  None\r
   * @retval None\r
   */\r
@@ -228,7 +228,7 @@ void SystemCoreClockUpdate (void)
 \r
   /* Get SYSCLK source -------------------------------------------------------*/\r
   tmp = RCC->CFGR & RCC_CFGR_SWS;\r
-  \r
+\r
   switch (tmp)\r
   {\r
     case 0x00:  /* MSI used as system clock */\r
@@ -247,7 +247,7 @@ void SystemCoreClockUpdate (void)
       plldiv = RCC->CFGR & RCC_CFGR_PLLDIV;\r
       pllmul = PLLMulTable[(pllmul >> 18)];\r
       plldiv = (plldiv >> 22) + 1;\r
-      \r
+\r
       pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;\r
 \r
       if (pllsource == 0x00)\r
@@ -274,21 +274,21 @@ void SystemCoreClockUpdate (void)
 }\r
 \r
 /**\r
-  * @brief  Configures the System clock frequency, AHB/APBx prescalers and Flash \r
+  * @brief  Configures the System clock frequency, AHB/APBx prescalers and Flash\r
   *         settings.\r
-  * @note   This function should be called only once the RCC clock configuration  \r
-  *         is reset to the default reset state (done in SystemInit() function).             \r
+  * @note   This function should be called only once the RCC clock configuration\r
+  *         is reset to the default reset state (done in SystemInit() function).\r
   * @param  None\r
   * @retval None\r
   */\r
-static void SetSysClock(void)\r
+void SetSysClock(void)\r
 {\r
   __IO uint32_t StartUpCounter = 0, HSIStatus = 0;\r
-  \r
+\r
   /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/\r
   /* Enable HSI */\r
   RCC->CR |= ((uint32_t)RCC_CR_HSION);\r
\r
+\r
   /* Wait till HSI is ready and if Time out is reached exit */\r
   do\r
   {\r
@@ -303,39 +303,39 @@ static void SetSysClock(void)
   {\r
     HSIStatus = (uint32_t)0x00;\r
   }\r
-    \r
+\r
   if (HSIStatus == (uint32_t)0x01)\r
   {\r
     /* Flash 0 wait state */\r
     FLASH->ACR &= ~FLASH_ACR_LATENCY;\r
-    \r
+\r
     /* Disable Prefetch Buffer */\r
     FLASH->ACR &= ~FLASH_ACR_PRFTEN;\r
 \r
     /* Disable 64-bit access */\r
     FLASH->ACR &= ~FLASH_ACR_ACC64;\r
-    \r
+\r
 \r
     /* Power enable */\r
     RCC->APB1ENR |= RCC_APB1ENR_PWREN;\r
-  \r
+\r
     /* Select the Voltage Range 1 (1.8 V) */\r
     PWR->CR = PWR_CR_VOS_0;\r
-  \r
-  \r
+\r
+\r
     /* Wait Until the Voltage Regulator is ready */\r
     while((PWR->CSR & PWR_CSR_VOSF) != RESET)\r
     {\r
     }\r
-      \r
+\r
     /* HCLK = SYSCLK /1*/\r
     RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;\r
     /* PCLK2 = HCLK /1*/\r
     RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;\r
-    \r
+\r
     /* PCLK1 = HCLK /1*/\r
     RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;\r
-    \r
+\r
     /* Select HSI as system clock source */\r
     RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));\r
     RCC->CFGR |= (uint32_t)RCC_CFGR_SW_HSI;\r
index d1adfdebb3601d73bf8dd2cdf1bbe501f0bd5554..25a4a76efea027c3f9c17e145acca009d0f34337 100644 (file)
 #ifdef __ICCARM__\r
        #include <stdint.h>\r
        extern uint32_t SystemCoreClock;\r
+       void vMainPostStopProcessing( void );\r
+       void vAssertCalled( unsigned long ulLine, const char * const pcFileName );\r
 #endif\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
+\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
+#else\r
+       #define configCPU_CLOCK_HZ                                              SystemCoreClock\r
+       #define configSYSTICK_CLOCK_HZ                                  ( SystemCoreClock >> 3UL )\r
+       #define configUSE_TICKLESS_IDLE                                 0\r
+       #define configTICK_RATE_HZ                                              ( ( portTickType ) 1000 )\r
+#endif /* configCREATE_LOW_POWER_DEMO */\r
+\r
+#define configPRE_STOP_PROCESSING()\r
+#define configPOST_STOP_PROCESSING()                           vMainPostStopProcessing()\r
+\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 configCPU_CLOCK_HZ                                             ( SystemCoreClock )\r
-#define configTICK_RATE_HZ                                             ( ( portTickType ) 1000 )\r
 #define configMAX_PRIORITIES                                   ( 5 )\r
 #define configMINIMAL_STACK_SIZE                               ( ( unsigned short ) 70 )\r
 #define configTOTAL_HEAP_SIZE                                  ( ( size_t ) ( 10 * 1024 ) )\r
@@ -119,6 +138,9 @@ to exclude the API function. */
 #define INCLUDE_vTaskDelayUntil                        1\r
 #define INCLUDE_vTaskDelay                             1\r
 \r
+/* Standard assert semantics. */\r
+#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __LINE__, __FILE__ )\r
+\r
 /* Use the system definition, if there is one */\r
 #ifdef __NVIC_PRIO_BITS\r
        #define configPRIO_BITS       __NVIC_PRIO_BITS\r
index 8fc39d7a1bda3e3d8ea691e52736d6a954b53e17..6193f1833e0cc66a07cb39d9efc2d8fe449479bb 100644 (file)
 #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
@@ -150,9 +152,6 @@ empty. */
 /* The LED used to indicate that a value has been received on the queue. */\r
 #define mainQUEUE_LED                                          ( 0 )\r
 \r
-/* The rate at which the Tx task sends to the queue. */\r
-#define mainTX_DELAY                                           ( 500UL / portTICK_RATE_MS )\r
-\r
 /* A block time of zero simply means "don't block". */\r
 #define mainDONT_BLOCK                                         ( 0 )\r
 \r
@@ -162,7 +161,7 @@ empty. */
 /* 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                           ( 20 / portTICK_RATE_MS )\r
+#define mainLED_TOGGLE_DELAY                           ( 10 / portTICK_RATE_MS )\r
 \r
 /*-----------------------------------------------------------*/\r
 \r
@@ -184,10 +183,16 @@ static void prvSetupHardware( void );
 \r
 /*-----------------------------------------------------------*/\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
 int main( void )\r
 {\r
        prvSetupHardware();\r
 \r
+       xTxSemaphore = xSemaphoreCreateBinary();\r
+\r
        /* Create the queue. */\r
        xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) );\r
        configASSERT( xQueue );\r
@@ -216,10 +221,9 @@ const unsigned long ulValueToSend = mainQUEUED_VALUE;
 \r
        for( ;; )\r
        {\r
-               /* Place this task into the blocked state until it is time to run again.\r
-               The kernel will place the MCU into the Retention low power sleep state\r
-               when the idle task next runs. */\r
-               vTaskDelay( mainTX_DELAY );\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
@@ -253,6 +257,39 @@ unsigned long ulReceivedValue;
 }\r
 /*-----------------------------------------------------------*/\r
 \r
+void EXTI0_IRQHandler(void)\r
+{\r
+static const portTickType xIncrement = 200UL / portTICK_RATE_MS;\r
+\r
+       if( xSendBlockTime == portMAX_DELAY )\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
+       }\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
+       }\r
+\r
+       EXTI_ClearITPendingBit( EXTI_Line0 );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
 static void prvSetupHardware( void )\r
 {\r
 /* GPIO, EXTI and NVIC Init structure declaration */\r
@@ -266,59 +303,57 @@ void SystemCoreClockUpdate( void );
        /* Essential on STM32 Cortex-M devices. */\r
        NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );\r
 \r
-       /* Enable HSI Clock */\r
-       RCC_HSICmd(ENABLE);\r
+       /* 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
+       /*!< 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
+//     RCC_SYSCLKConfig( RCC_SYSCLKSource_HSI );\r
 \r
-       /* Set MSI clock range to ~4.194MHz*/\r
+       /* Set MSI clock range to ~4.194MHz*/\r
        RCC_MSIRangeConfig( RCC_MSIRange_6 );\r
 \r
-       /* Enable the GPIOs clocks */\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, PWR mngt clocks */\r
-       RCC_APB1PeriphClockCmd( RCC_APB1Periph_COMP | RCC_APB1Periph_PWR,ENABLE );\r
+       /* Enable comparator clocks. */\r
+       RCC_APB1PeriphClockCmd( RCC_APB1Periph_COMPENABLE );\r
 \r
-       /* Enable ADC & SYSCFG clocks */\r
+       /* Enable SYSCFG clocks. */\r
        RCC_APB2PeriphClockCmd( RCC_APB2Periph_SYSCFG , ENABLE );\r
 \r
        /* Allow access to the RTC */\r
-       PWR_RTCAccessCmd( ENABLE );\r
+//     PWR_RTCAccessCmd( ENABLE );\r
 \r
        /* Reset RTC Backup Domain */\r
-       RCC_RTCResetCmd( ENABLE );\r
-       RCC_RTCResetCmd( DISABLE );\r
+//     RCC_RTCResetCmd( ENABLE );\r
+//     RCC_RTCResetCmd( DISABLE );\r
 \r
        /* LSE Enable */\r
-       RCC_LSEConfig( RCC_LSE_ON );\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
-       /* RTC Clock Source Selection */\r
-       RCC_RTCCLKConfig( RCC_RTCCLKSource_LSE );\r
-\r
-       /* Enable the RTC */\r
-       RCC_RTCCLKCmd( ENABLE );\r
+//     while( RCC_GetFlagStatus( RCC_FLAG_LSERDY ) == RESET );\r
 \r
        /* Disable HSE */\r
-       RCC_HSEConfig( RCC_HSE_OFF );\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
+//     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.8V */\r
-       PWR_VoltageScalingConfig( PWR_VoltageScaling_Range1 );\r
+       /* Set internal voltage regulator to 1.5V. */\r
+       PWR_VoltageScalingConfig( PWR_VoltageScaling_Range2 );\r
 \r
-       /* Wait Until the Voltage Regulator is ready */\r
+       /* Wait Until the Voltage Regulator is ready. */\r
        while( PWR_GetFlagStatus( PWR_FLAG_VOS ) != RESET );\r
 \r
        /* Configure User Button pin as input */\r
@@ -329,7 +364,7 @@ void SystemCoreClockUpdate( void );
        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
+       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
@@ -413,16 +448,36 @@ void vApplicationTickHook( void )
 }\r
 /*-----------------------------------------------------------*/\r
 \r
-void vAssertCalled( void )\r
+void vMainPostStopProcessing( void )\r
 {\r
-volatile unsigned long ul = 0;\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
+\r
+       /* Parameters are not used. */\r
+       ( void ) ulLine;\r
+       ( void ) pcFileName;\r
 \r
        taskENTER_CRITICAL();\r
        {\r
-               /* Set ul to a non-zero value using the debugger to step out of this\r
-               function. */\r
-               while( ul == 0 )\r
+               while( ulSetToNonZeroInDebuggerToContinue == 0 )\r
                {\r
+                       /* Use the debugger to set ulSetToNonZeroInDebuggerToContinue to a\r
+                       non zero value to step out of this function to the point that raised\r
+                       this assert(). */\r
+                       __asm volatile( "NOP" );\r
                        __asm volatile( "NOP" );\r
                }\r
        }\r
@@ -430,6 +485,35 @@ volatile unsigned long ul = 0;
 }\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
@@ -962,6 +1046,273 @@ void vApplicationStackOverflowHook( void )
 }\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
index 6a8e75211a692daec35f0155ade55e68edfb4469..b86a118fe0b5a342cc19bbf43c236cbdc81bb70b 100644 (file)
@@ -116,10 +116,6 @@ void DebugMon_Handler(void)
   while (1);\r
 }\r
 \r
-void EXTI0_IRQHandler(void)\r
-{\r
-  EXTI_ClearITPendingBit(EXTI_Line0);\r
-}\r
 \r
 \r
 void RTC_WKUP_IRQHandler (void)\r