1 /*******************************************************************************
4 * Power Management Module Library for MSP430F5xx/6xx family
7 * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
14 * Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
17 * Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the
22 * Neither the name of Texas Instruments Incorporated nor the names of
23 * its contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 * Created: Version 1.0 11/24/2009
39 * Updated: Version 2.0 12/15/2010
40 * Modified SetVcoreUp() and SetVcoreDown() functions
42 ******************************************************************************/
47 #define _HAL_PMM_DISABLE_SVML_
48 #define _HAL_PMM_DISABLE_SVSL_
49 #define _HAL_PMM_DISABLE_FULL_PERFORMANCE_
51 #ifdef _HAL_PMM_DISABLE_SVML_
52 #define _HAL_PMM_SVMLE SVMLE
54 #define _HAL_PMM_SVMLE 0
57 #ifdef _HAL_PMM_DISABLE_SVSL_
58 #define _HAL_PMM_SVSLE SVSLE
60 #define _HAL_PMM_SVSLE 0
63 #ifdef _HAL_PMM_DISABLE_FULL_PERFORMANCE_
64 #define _HAL_PMM_SVSFP SVSLFP
65 #define _HAL_PMM_SVMFP SVMLFP
67 #define _HAL_PMM_SVSFP 0
68 #define _HAL_PMM_SVMFP 0
71 /*******************************************************************************
72 * \brief Increase Vcore by one level
74 * \param level Level to which Vcore needs to be increased
75 * \return status Success/failure
76 ******************************************************************************/
77 static unsigned int SetVCoreUp(unsigned char level)
79 unsigned int PMMRIE_backup, SVSMHCTL_backup, SVSMLCTL_backup;
81 // The code flow for increasing the Vcore has been altered to work around
82 // the erratum FLASH37.
83 // Please refer to the Errata sheet to know if a specific device is affected
84 // DO NOT ALTER THIS FUNCTION
86 // Open PMM registers for write access
89 // Disable dedicated Interrupts
90 // Backup all registers
91 PMMRIE_backup = PMMRIE;
92 PMMRIE &= ~(SVMHVLRPE | SVSHPE | SVMLVLRPE | SVSLPE | SVMHVLRIE |
93 SVMHIE | SVSMHDLYIE | SVMLVLRIE | SVMLIE | SVSMLDLYIE );
94 SVSMHCTL_backup = SVSMHCTL;
95 SVSMLCTL_backup = SVSMLCTL;
100 // Set SVM highside to new level and check if a VCore increase is possible
101 SVSMHCTL = SVMHE | SVSHE | (SVSMHRRL0 * level);
103 // Wait until SVM highside is settled
104 while ((PMMIFG & SVSMHDLYIFG) == 0);
107 PMMIFG &= ~SVSMHDLYIFG;
109 // Check if a VCore increase is possible
110 if ((PMMIFG & SVMHIFG) == SVMHIFG) { // -> Vcc is too low for a Vcore increase
111 // recover the previous settings
112 PMMIFG &= ~SVSMHDLYIFG;
113 SVSMHCTL = SVSMHCTL_backup;
115 // Wait until SVM highside is settled
116 while ((PMMIFG & SVSMHDLYIFG) == 0);
119 PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG | SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG);
121 PMMRIE = PMMRIE_backup; // Restore PMM interrupt enable register
122 PMMCTL0_H = 0x00; // Lock PMM registers for write access
123 return PMM_STATUS_ERROR; // return: voltage not set
126 // Set also SVS highside to new level
127 // Vcc is high enough for a Vcore increase
128 SVSMHCTL |= (SVSHRVL0 * level);
130 // Wait until SVM highside is settled
131 while ((PMMIFG & SVSMHDLYIFG) == 0);
134 PMMIFG &= ~SVSMHDLYIFG;
136 // Set VCore to new level
137 PMMCTL0_L = PMMCOREV0 * level;
139 // Set SVM, SVS low side to new level
140 SVSMLCTL = SVMLE | (SVSMLRRL0 * level) | SVSLE | (SVSLRVL0 * level);
142 // Wait until SVM, SVS low side is settled
143 while ((PMMIFG & SVSMLDLYIFG) == 0);
146 PMMIFG &= ~SVSMLDLYIFG;
147 // SVS, SVM core and high side are now set to protect for the new core level
149 // Restore Low side settings
150 // Clear all other bits _except_ level settings
151 SVSMLCTL &= (SVSLRVL0+SVSLRVL1+SVSMLRRL0+SVSMLRRL1+SVSMLRRL2);
153 // Clear level settings in the backup register,keep all other bits
154 SVSMLCTL_backup &= ~(SVSLRVL0+SVSLRVL1+SVSMLRRL0+SVSMLRRL1+SVSMLRRL2);
156 // Restore low-side SVS monitor settings
157 SVSMLCTL |= SVSMLCTL_backup;
159 // Restore High side settings
160 // Clear all other bits except level settings
161 SVSMHCTL &= (SVSHRVL0+SVSHRVL1+SVSMHRRL0+SVSMHRRL1+SVSMHRRL2);
163 // Clear level settings in the backup register,keep all other bits
164 SVSMHCTL_backup &= ~(SVSHRVL0+SVSHRVL1+SVSMHRRL0+SVSMHRRL1+SVSMHRRL2);
167 SVSMHCTL |= SVSMHCTL_backup;
169 // Wait until high side, low side settled
170 while (((PMMIFG & SVSMLDLYIFG) == 0) && ((PMMIFG & SVSMHDLYIFG) == 0));
173 PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG | SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG);
175 PMMRIE = PMMRIE_backup; // Restore PMM interrupt enable register
176 PMMCTL0_H = 0x00; // Lock PMM registers for write access
178 return PMM_STATUS_OK;
181 /*******************************************************************************
182 * \brief Decrease Vcore by one level
184 * \param level Level to which Vcore needs to be decreased
185 * \return status Success/failure
186 ******************************************************************************/
187 static unsigned int SetVCoreDown(unsigned char level)
189 unsigned int PMMRIE_backup, SVSMHCTL_backup, SVSMLCTL_backup;
191 // The code flow for decreasing the Vcore has been altered to work around
192 // the erratum FLASH37.
193 // Please refer to the Errata sheet to know if a specific device is affected
194 // DO NOT ALTER THIS FUNCTION
196 // Open PMM registers for write access
199 // Disable dedicated Interrupts
200 // Backup all registers
201 PMMRIE_backup = PMMRIE;
202 PMMRIE &= ~(SVMHVLRPE | SVSHPE | SVMLVLRPE | SVSLPE | SVMHVLRIE |
203 SVMHIE | SVSMHDLYIE | SVMLVLRIE | SVMLIE | SVSMLDLYIE );
204 SVSMHCTL_backup = SVSMHCTL;
205 SVSMLCTL_backup = SVSMLCTL;
208 PMMIFG &= ~(SVMHIFG | SVSMHDLYIFG | SVMLIFG | SVSMLDLYIFG);
210 // Set SVM, SVS high & low side to new settings in normal mode
211 SVSMHCTL = SVMHE | (SVSMHRRL0 * level) | SVSHE | (SVSHRVL0 * level);
212 SVSMLCTL = SVMLE | (SVSMLRRL0 * level) | SVSLE | (SVSLRVL0 * level);
214 // Wait until SVM high side and SVM low side is settled
215 while ((PMMIFG & SVSMHDLYIFG) == 0 || (PMMIFG & SVSMLDLYIFG) == 0);
218 PMMIFG &= ~(SVSMHDLYIFG + SVSMLDLYIFG);
219 // SVS, SVM core and high side are now set to protect for the new core level
221 // Set VCore to new level
222 PMMCTL0_L = PMMCOREV0 * level;
224 // Restore Low side settings
225 // Clear all other bits _except_ level settings
226 SVSMLCTL &= (SVSLRVL0+SVSLRVL1+SVSMLRRL0+SVSMLRRL1+SVSMLRRL2);
228 // Clear level settings in the backup register,keep all other bits
229 SVSMLCTL_backup &= ~(SVSLRVL0+SVSLRVL1+SVSMLRRL0+SVSMLRRL1+SVSMLRRL2);
231 // Restore low-side SVS monitor settings
232 SVSMLCTL |= SVSMLCTL_backup;
234 // Restore High side settings
235 // Clear all other bits except level settings
236 SVSMHCTL &= (SVSHRVL0+SVSHRVL1+SVSMHRRL0+SVSMHRRL1+SVSMHRRL2);
238 // Clear level settings in the backup register, keep all other bits
239 SVSMHCTL_backup &= ~(SVSHRVL0+SVSHRVL1+SVSMHRRL0+SVSMHRRL1+SVSMHRRL2);
242 SVSMHCTL |= SVSMHCTL_backup;
244 // Wait until high side, low side settled
245 while (((PMMIFG & SVSMLDLYIFG) == 0) && ((PMMIFG & SVSMHDLYIFG) == 0));
248 PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG | SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG);
250 PMMRIE = PMMRIE_backup; // Restore PMM interrupt enable register
251 PMMCTL0_H = 0x00; // Lock PMM registers for write access
252 return PMM_STATUS_OK; // Return: OK
255 unsigned int SetVCore(unsigned char level)
257 unsigned int actlevel;
261 level &= PMMCOREV_3; // Set Mask for Max. level
262 actlevel = (PMMCTL0 & PMMCOREV_3); // Get actual VCore
263 // step by step increase or decrease
264 while (((level != actlevel) && (status == 0)) || (level < actlevel)) {
265 if (level > actlevel) {
266 status = SetVCoreUp(++actlevel);
269 status = SetVCoreDown(--actlevel);