1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
32 33 34 35 36
37
38 package ti.sysbios.family.msp430;
39
40 import xdc.runtime.Error;
41
42 /*!
43 * ======== Power ========
44 * Power Manager Module
45 *
46 * This module provides functions that can be called to reduce MSP430 power
47 * consumption.
48 *
49 * @p(html)
50 * <h3> Calling Context </h3>
51 * <table border="1" cellpadding="3">
52 * <colgroup span="1"></colgroup> <colgroup span="5" align="center"></colgroup>
53 *
54 * <tr><th> Function </th><th> Hwi </th><th> Swi </th><th> Task </th><th> Main </th><th> Startup </th></tr>
55 * <!-- -->
56 * <tr><td> {@link #idleCPU} </td><td> N </td><td> N </td><td> N </td><td> N </td><td> N </td></tr>
57 * <tr><td> {@link #changeIdleMode} </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td><td> Y </td></tr>
58 * <tr><td> {@link #sleepCPU} </td><td> N </td><td> N </td><td> Y </td><td> N </td><td> N </td></tr>
59 * <tr><td> {@link #wakeCPU} </td><td> Y </td><td> N </td><td> N </td><td> N </td><td> N </td></tr>
60 * <tr><td colspan="6"> Definitions: <br />
61 * <ul>
62 * <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
63 * <li> <b>Swi</b>: API is callable from a Swi thread. </li>
64 * <li> <b>Task</b>: API is callable from a Task thread. </li>
65 * <li> <b>Main</b>: API is callable from main(). </li>
66 * <li> <b>Startup</b>: API is callable during any module startup. </li>
67 * </ul>
68 * </td></tr>
69 *
70 * </table>
71 * @p
72 */
73
74 module Power
75 {
76 /*!
77 * ======== SleepPrepFuncPtr ========
78 * Sleep mode preparation function type definition
79 */
80 typedef Void (*SleepPrepFuncPtr)();
81
82 /*!
83 * ======== IdleMode ========
84 * Available idle modes
85 */
86 enum IdleMode {
87 LPM0 = 0x10,
88 LPM1 = 0x50,
89 LPM2 = 0x90,
90 LPM3 = 0xD0,
91 LPM4 = 0xF0
92 };
93
94 /*!
95 * ======== SleepMode ========
96 * Available sleep modes.
97 */
98 enum SleepMode {
99 Sleep_LPM4_5 /*! Shutdown (LPM4.5) */
100 };
101
102 /*!
103 * ======== E_dynamicModeNotAllowed ========
104 * Dynamic mode not allowed error
105 *
106 * This Error is raised if there is an attempt to change idleMode at
107 * runtime, or trigger a dynamic CPU wakeup, and
108 * `{@link #allowDynamicMode}` is set to "false".
109 */
110 config Error.Id E_dynamicModeNotAllowed = {
111 msg: "E_dynamicModeNotAllowed: Dynamic mode is not enabled (allowDynamicMode=false)"
112 };
113
114 /*!
115 * ======== idle ========
116 * Idle CPU when threads blocked waiting for an interrupt?
117 */
118 config Bool idle = true;
119
120 /*!
121 * ======== idleMode ========
122 * Idle mode for CPU to enter while waiting for an interrupt
123 */
124 config IdleMode idleMode = LPM0;
125
126 /*!
127 * ======== allowDynamicMode ========
128 * Allow dynamic changes to idleMode (`{@link #changeIdleMode}`), or
129 * dynamically waking the CPU upon return from interrupt
130 * (`{@link#wakeCPU}`), at runtime?
131 */
132 config Bool allowDynamicMode = false;
133
134 /*!
135 * ======== sleepPrepFunction ========
136 * I/O preparation function to be called by Power_sleepCPU()
137 */
138 config SleepPrepFuncPtr sleepPrepFunction;
139
140 /*!
141 * ======== idleCPU ========
142 * Function to automatically idle the CPU during idle time
143 *
144 * When the `{@link #idle}` configuration parameter is set, this function
145 * will be added to the list of Idle loop functions. When called from the
146 * `Idle` loop, it will transition the CPU into the idle mode specified
147 * by the `{@link #idleMode}` configuration parameter. The CPU will stay
148 * in the corresponding low power mode until the next interrupt occurs.
149 */
150 @DirectCall
151 Void idleCPU();
152
153 /*!
154 * ======== changeIdleMode ========
155 * Change the idleMode used for idling the CPU
156 *
157 * This function does not immediately affect the state of the CPU, but
158 * defines the idleMode that will be invoked at subsequent opportunities
159 * SYS/BIOS has to idle the CPU.
160 *
161 * Changing the `idleMode` at runtime requires that `{@link #idle}` be
162 * enabled, the initial `{@link #idleMode}` is defined, and
163 * `{@link #allowDynamicMode}` is specified in the application
164 * configuration. For example:
165 *
166 * @p(code)
167 * var Power = xdc.useModule('ti.sysbios.family.msp430.Power');
168 * Power.idle = true;
169 * Power.idleMode = Power.LPM3;
170 * Power.allowDynamicMode = true;
171 * @p
172 */
173 @DirectCall
174 Void changeIdleMode(Power.IdleMode mode);
175
176 /*!
177 * ======== sleepCPU ========
178 * Function called by the application to sleep the CPU
179 *
180 * This function currently supports the `LPM4.5` sleep mode only, and
181 * only on MSP430 devices that support this mode. To be effective, the
182 * device I/Os MUST be properly configured before `LPM4.5` is activated,
183 * otherwise there may be excessive current draw, which could be higher
184 * than before this function is called. The proper configuration of I/Os
185 * is device, application, and board specific. The caller of this
186 * function has two options:
187 *
188 * 1) Prepare the device I/Os, and any (non-reset) wakeup interrupts
189 * prior to calling this function, or
190 * 2) Write a function for this purpose, and configure it as the
191 * optional `{@link sleepPrepFunction}`, that `Power_sleepCPU()`
192 * should call before transitioning to `LPM4.5`.
193 */
194 @DirectCall
195 Void sleepCPU(SleepMode sleepMode);
196
197 /*!
198 * ======== wakeCPU ========
199 * Function called to trigger a dynamic CPU wakeup upon return from
200 * interrupt
201 *
202 * An interrupt can be configured statically (at build time) to let the
203 * CPU naturally resume an LPM mode upon return from interrupt (see
204 * `{@link ti.sysbios.family.msp430 Hwi}`).
205 *
206 * This function (Power_wakeCPU()) can be called from within an ISR
207 * function to override the static configuration (where the CPU would
208 * resume an LPM mode), and force the CPU to stay awake upon return from
209 * interrupt.
210 *
211 * For the case of nested interrupts, the effect of this API is for the
212 * bottom-most (or first-preempting) interrupt, meaning that if this
213 * function is called from an ISR that has nested upon another, the CPU
214 * will be kept awake after the interrupt that first awoke the CPU.
215 *
216 * To call this function, it is required that
217 * `{@link #allowDynamicMode}` is specified as 'true' in the application
218 * configuration. For example:
219 *
220 * @p(code)
221 * var Power = xdc.useModule('ti.sysbios.family.msp430.Power');
222 * Power.allowDynamicMode = true;
223 * @p
224 *
225 */
226 @DirectCall
227 Void wakeCPU();
228
229 /*! @_nodoc
230 * ======== getModeChangeFlag ========
231 * Retrieve flag indicating whether the application changed the idleMode
232 */
233 @DirectCall
234 UInt getModeChangeFlag();
235
236 internal:
237
238 239 240 241
242 Void defaultSleepPrepFunction();
243
244 245 246 247
248 Void blockedTaskFunction();
249
250 251 252
253 struct Module_State {
254 UInt idleMode;
255 Bool newMode;
256 }
257 }
258 259 260 261
262