ISF  2.1
Intelligent Sensing Framework for Kinetis with Processor Expert
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
pm.c
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2013, Freescale Semiconductor, Inc.
4  *
5  */
6 
7 /*!
8  * @file pm.c
9  * @brief Implements the ISF power management.
10  *
11  */
12 
13 #include "isf_target.h"
14 #include "isf.h"
15 #include "lwevent.h"
16 #include "lwsem.h"
17 #include "mutex.h"
18 #include "lwmem.h"
19 
20 // TODO: Include your component header files.
21 #include "isf_bm.h"
22 #include "isf_pm.h"
23 #include "pm_internal.h"
24 #include "cortex.h"
25 #include "Cpu.h"
26 
27 static LWSEM_STRUCT sema_pm_access;
28 static volatile power_level_t pm_desired_power_level = ISF_POWER_NORMAL;
29 
30 
31 void isr_pm_callback_sof (pointer dummy);
32 void task_idle(uint32 initial_data);
33 isf_status_t pm_init(void);
34 
35 // From bsp...its timer rollover count.
36 extern volatile uint_32 bsptimer_counter32;
37 
38 
39 
40 
41 
42 
43 
45 {
47 
48  // Create semaphore for access to pm power level.
49  if (_lwsem_create(&sema_pm_access, 1) != MQX_OK)
50  ret = ISF_ERR_LIB_INIT;
51 
52  return ret;
53 }
54 
55 
56 
58 {
59 
60  _lwsem_wait_ticks(&sema_pm_access, 0);
61 
62  pm_desired_power_level = aLevel;
63 
64 
65 #if 0
66  switch(aLevel)
67  {
68 
69  case ISF_POWER_NORMAL:
70  // NOTE: Don't need to do anything. This will keep our idle
71  // loop running to prevent mqx lite idle task from running because
72  // we do not know how the user has configured mqx idle task to run.
73  // This way we maintain control of how power mode is handled.
74  pm_desired_power_level = aLevel;
75 
76  break;
77 
78  case ISF_POWER_LOW:
79  case ISF_POWER_SLEEP:
80 
81  pm_desired_power_level = aLevel;
82 
83  if (aLevel == ISF_POWER_SLEEP)
84  {
85 
86 #if (defined CPU_MKL25Z128VLK4)
87  POWER_SET_SLEEP_MODE(SLEEP_MODE_DEEP);
88 #endif
89 
90 
91  // Make preparation for sleep mode.
92 
93  // The following conditions apply to when you are using the clock module's
94  // PEE mode. The problem with turning off PLL during sleep is that when
95  // an interrupt occurs, the clock module will be in PBE mode (PLL enabled
96  // buy bypassed because it needs to stablelized), the irq will be running
97  // at a slower cpu clock. And worst is that the kernel may switch to a higher
98  // priority task after servicing the irq with the slower cpu clock.
99  //POWER_SLEEP_PREPARE(PLL_SLEEP_DISABLED) // PLL disabled during deep sleep
100 
101  // Keep PLL on during deep sleep. This cost about ~1.8mA on KL25Z. When
102  // coming out of deep sleep, the clock module will be in PEE mode and run
103  // at same speed before deep sleep mode.
104 #if (defined CPU_MKL25Z128VLK4)
105  POWER_SLEEP_PREPARE(PLL_SLEEP_ENABLED) // PLL enabled during deep sleep
106 #endif
107 
108  // Enter sleep mode.
109  POWER_ENTER_IDLE_MODE()
110 
111  // Go back to normal. Note below that we set sleep mode back to normal.
112  pm_desired_power_level = ISF_POWER_NORMAL;
113 
114  // Sleep mode exit. If system was in PEE mode before sleep entry,
115  // then it will exit sleep in PBE mode. This macro will transition
116  // from PBE mode to PEE mode if it detects that the clock module is
117  // currently in PBE mode.
118 #if (defined CPU_MKL25Z128VLK4)
119  POWER_SLEEP_EXIT()
120 #endif
121 
122  }
123 
124  // In all cases, set to normal sleep. If deep sleep was entered above and
125  // system woke up, we'll set it back to normal. This is a safeguard so that
126  // if user executes idle mode on their own they don't end up in deep sleep.
127  // This is not a guarantee that this situation won't happen because a higher
128  // priority task could execute just after exiting sleep mode above and executes
129  // its own idle mode and enter deep sleep.
130 #if (defined CPU_MKL25Z128VLK4)
131  POWER_SET_SLEEP_MODE(SLEEP_MODE_NORMAL)
132 #endif
133 
134 
135  break;
136  default:
137  // Error: New power level not recognized.
138  // No change to power level.
139  break;
140  }
141 #endif
142 
143  _lwsem_post(&sema_pm_access);
144 
145  return pm_desired_power_level;
146 }
147 
148 
150 {
151  return pm_desired_power_level;
152 }
153 
154 
155 
156 void task_idle(uint32 initial_data)
157 {
158 
159  while(1)
160  {
161 
162  switch(pm_desired_power_level)
163  {
164  case ISF_POWER_LOW:
165  Cpu_SetOperationMode(DOM_WAIT, NULL, NULL);
166 #if 0
167  // For LOW, the user would have called isf_power_set()and the
168  // sleep mode would have been set to SLEEP_MODE_NORMAL.
169  POWER_ENTER_IDLE_MODE()
170 
171  // Sleep mode exit.
172 #if (defined CPU_MKL25Z128VLK4)
173  POWER_SLEEP_EXIT()
174 #endif
175 #endif
176  break;
177 
178  case ISF_POWER_SLEEP:
179  Cpu_SetOperationMode(DOM_SLEEP, NULL, NULL);
180  Cpu_SetOperationMode(DOM_RUN, NULL, NULL);
181  break;
182 
183  case ISF_POWER_NORMAL:
184  // Don't block. Just do nothing here otherwise if we block the
185  // mqx idle task will run.
186  PE_NOP();
187  //Cpu_SetOperationMode(DOM_RUN, NULL, NULL);
188  break;
189  }
190 
191  }
192 
193 }
194 
195 
196 
197 
198 
199 
200 
201 
202 
203 
204 
205 
206 
ISF board support header files.
pm_power_level_enum
ISF power management settings.
Definition: isf_pm.h:34
API definitions, types, and macros for the Intelligent Sensing Framework (ISF) Bus Manager (BM)...
void isr_pm_callback_sof(pointer dummy)
unsigned long uint32
This defines uint32 as unsigned long.
Definition: isf_types.h:36
isf_pm.h describes the API definitions, types, and macros for the Intelligent Sensing Framework (ISF)...
void task_idle(uint32 initial_data)
Definition: pm.c:156
Main ISF header file. Contains code common to all ISF components.
General library initialization failure status.
Definition: isf.h:36
volatile uint_32 bsptimer_counter32
int32 isf_status_t
ISF return status type.
Definition: isf.h:51
Power management header file.
power_level_t isf_power_get(void)
This API returns the current power level for power management.
Definition: pm.c:149
isf_status_t pm_init(void)
This API initializes the Power Manager.
Definition: pm.c:44
power_level_t isf_power_set(power_level_t aLevel)
This API sets the requested power level for power management.
Definition: pm.c:57