</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
<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
--- /dev/null
+/*\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
* 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
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.\r
*\r
* <h2><center>© COPYRIGHT 2010 STMicroelectronics</center></h2>\r
- ****************************************************************************** \r
+ ******************************************************************************\r
*/\r
\r
/** @addtogroup CMSIS\r
\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
* @{\r
*/\r
\r
-static void SetSysClock(void);\r
+void SetSysClock(void);\r
\r
/**\r
* @}\r
\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
\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
\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
\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
\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
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
}\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
{\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
#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
#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
#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
/* 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
/* 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
\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
\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
}\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
/* 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_COMP, ENABLE );\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
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
}\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
}\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
}\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
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