1 /*******************************************************************************
\r
4 * Power Management Module Library for MSP430F5xx/6xx family
\r
7 * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
\r
10 * Redistribution and use in source and binary forms, with or without
\r
11 * modification, are permitted provided that the following conditions
\r
14 * Redistributions of source code must retain the above copyright
\r
15 * notice, this list of conditions and the following disclaimer.
\r
17 * Redistributions in binary form must reproduce the above copyright
\r
18 * notice, this list of conditions and the following disclaimer in the
\r
19 * documentation and/or other materials provided with the
\r
22 * Neither the name of Texas Instruments Incorporated nor the names of
\r
23 * its contributors may be used to endorse or promote products derived
\r
24 * from this software without specific prior written permission.
\r
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
\r
27 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
\r
28 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
\r
29 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
\r
30 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
\r
31 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
\r
32 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
\r
33 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
\r
34 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
\r
35 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
\r
36 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
38 ******************************************************************************/
\r
41 #include "HAL_PMM.h"
\r
43 /*******************************************************************************
\r
44 * \brief Increase Vcore by one level
\r
46 * \param level Level to which Vcore needs to be increased
\r
47 * \return status Success/failure
\r
48 ******************************************************************************/
\r
50 static uint16_t SetVCoreUp(uint8_t level)
\r
52 uint16_t PMMRIE_backup, SVSMHCTL_backup, SVSMLCTL_backup;
\r
54 // The code flow for increasing the Vcore has been altered to work around
\r
55 // the erratum FLASH37.
\r
56 // Please refer to the Errata sheet to know if a specific device is affected
\r
57 // DO NOT ALTER THIS FUNCTION
\r
59 // Open PMM registers for write access
\r
62 // Disable dedicated Interrupts
\r
63 // Backup all registers
\r
64 PMMRIE_backup = PMMRIE;
\r
65 PMMRIE &= ~(SVMHVLRPE | SVSHPE | SVMLVLRPE | SVSLPE | SVMHVLRIE |
\r
66 SVMHIE | SVSMHDLYIE | SVMLVLRIE | SVMLIE | SVSMLDLYIE);
\r
67 SVSMHCTL_backup = SVSMHCTL;
\r
68 SVSMLCTL_backup = SVSMLCTL;
\r
73 // Set SVM highside to new level and check if a VCore increase is possible
\r
74 SVSMHCTL = SVMHE | SVSHE | (SVSMHRRL0 * level);
\r
76 // Wait until SVM highside is settled
\r
77 while ((PMMIFG & SVSMHDLYIFG) == 0) ;
\r
80 PMMIFG &= ~SVSMHDLYIFG;
\r
82 // Check if a VCore increase is possible
\r
83 if ((PMMIFG & SVMHIFG) == SVMHIFG){ // -> Vcc is too low for a Vcore increase
\r
84 // recover the previous settings
\r
85 PMMIFG &= ~SVSMHDLYIFG;
\r
86 SVSMHCTL = SVSMHCTL_backup;
\r
88 // Wait until SVM highside is settled
\r
89 while ((PMMIFG & SVSMHDLYIFG) == 0) ;
\r
92 PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG | SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG);
\r
94 PMMRIE = PMMRIE_backup; // Restore PMM interrupt enable register
\r
95 PMMCTL0_H = 0x00; // Lock PMM registers for write access
\r
96 return PMM_STATUS_ERROR; // return: voltage not set
\r
99 // Set also SVS highside to new level
\r
100 // Vcc is high enough for a Vcore increase
\r
101 SVSMHCTL |= (SVSHRVL0 * level);
\r
103 // Wait until SVM highside is settled
\r
104 while ((PMMIFG & SVSMHDLYIFG) == 0) ;
\r
107 PMMIFG &= ~SVSMHDLYIFG;
\r
109 // Set VCore to new level
\r
110 PMMCTL0_L = PMMCOREV0 * level;
\r
112 // Set SVM, SVS low side to new level
\r
113 SVSMLCTL = SVMLE | (SVSMLRRL0 * level) | SVSLE | (SVSLRVL0 * level);
\r
115 // Wait until SVM, SVS low side is settled
\r
116 while ((PMMIFG & SVSMLDLYIFG) == 0) ;
\r
119 PMMIFG &= ~SVSMLDLYIFG;
\r
120 // SVS, SVM core and high side are now set to protect for the new core level
\r
122 // Restore Low side settings
\r
123 // Clear all other bits _except_ level settings
\r
124 SVSMLCTL &= (SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2);
\r
126 // Clear level settings in the backup register,keep all other bits
\r
127 SVSMLCTL_backup &= ~(SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2);
\r
129 // Restore low-side SVS monitor settings
\r
130 SVSMLCTL |= SVSMLCTL_backup;
\r
132 // Restore High side settings
\r
133 // Clear all other bits except level settings
\r
134 SVSMHCTL &= (SVSHRVL0 + SVSHRVL1 + SVSMHRRL0 + SVSMHRRL1 + SVSMHRRL2);
\r
136 // Clear level settings in the backup register,keep all other bits
\r
137 SVSMHCTL_backup &= ~(SVSHRVL0 + SVSHRVL1 + SVSMHRRL0 + SVSMHRRL1 + SVSMHRRL2);
\r
140 SVSMHCTL |= SVSMHCTL_backup;
\r
142 // Wait until high side, low side settled
\r
143 while (((PMMIFG & SVSMLDLYIFG) == 0) && ((PMMIFG & SVSMHDLYIFG) == 0)) ;
\r
146 PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG | SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG);
\r
148 PMMRIE = PMMRIE_backup; // Restore PMM interrupt enable register
\r
149 PMMCTL0_H = 0x00; // Lock PMM registers for write access
\r
151 return PMM_STATUS_OK;
\r
154 /*******************************************************************************
\r
155 * \brief Decrease Vcore by one level
\r
157 * \param level Level to which Vcore needs to be decreased
\r
158 * \return status Success/failure
\r
159 ******************************************************************************/
\r
161 static uint16_t SetVCoreDown(uint8_t level)
\r
163 uint16_t PMMRIE_backup, SVSMHCTL_backup, SVSMLCTL_backup;
\r
165 // The code flow for decreasing the Vcore has been altered to work around
\r
166 // the erratum FLASH37.
\r
167 // Please refer to the Errata sheet to know if a specific device is affected
\r
168 // DO NOT ALTER THIS FUNCTION
\r
170 // Open PMM registers for write access
\r
173 // Disable dedicated Interrupts
\r
174 // Backup all registers
\r
175 PMMRIE_backup = PMMRIE;
\r
176 PMMRIE &= ~(SVMHVLRPE | SVSHPE | SVMLVLRPE | SVSLPE | SVMHVLRIE |
\r
177 SVMHIE | SVSMHDLYIE | SVMLVLRIE | SVMLIE | SVSMLDLYIE);
\r
178 SVSMHCTL_backup = SVSMHCTL;
\r
179 SVSMLCTL_backup = SVSMLCTL;
\r
182 PMMIFG &= ~(SVMHIFG | SVSMHDLYIFG | SVMLIFG | SVSMLDLYIFG);
\r
184 // Set SVM, SVS high & low side to new settings in normal mode
\r
185 SVSMHCTL = SVMHE | (SVSMHRRL0 * level) | SVSHE | (SVSHRVL0 * level);
\r
186 SVSMLCTL = SVMLE | (SVSMLRRL0 * level) | SVSLE | (SVSLRVL0 * level);
\r
188 // Wait until SVM high side and SVM low side is settled
\r
189 while ((PMMIFG & SVSMHDLYIFG) == 0 || (PMMIFG & SVSMLDLYIFG) == 0) ;
\r
192 PMMIFG &= ~(SVSMHDLYIFG + SVSMLDLYIFG);
\r
193 // SVS, SVM core and high side are now set to protect for the new core level
\r
195 // Set VCore to new level
\r
196 PMMCTL0_L = PMMCOREV0 * level;
\r
198 // Restore Low side settings
\r
199 // Clear all other bits _except_ level settings
\r
200 SVSMLCTL &= (SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2);
\r
202 // Clear level settings in the backup register,keep all other bits
\r
203 SVSMLCTL_backup &= ~(SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2);
\r
205 // Restore low-side SVS monitor settings
\r
206 SVSMLCTL |= SVSMLCTL_backup;
\r
208 // Restore High side settings
\r
209 // Clear all other bits except level settings
\r
210 SVSMHCTL &= (SVSHRVL0 + SVSHRVL1 + SVSMHRRL0 + SVSMHRRL1 + SVSMHRRL2);
\r
212 // Clear level settings in the backup register, keep all other bits
\r
213 SVSMHCTL_backup &= ~(SVSHRVL0 + SVSHRVL1 + SVSMHRRL0 + SVSMHRRL1 + SVSMHRRL2);
\r
216 SVSMHCTL |= SVSMHCTL_backup;
\r
218 // Wait until high side, low side settled
\r
219 while (((PMMIFG & SVSMLDLYIFG) == 0) && ((PMMIFG & SVSMHDLYIFG) == 0)) ;
\r
222 PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG | SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG);
\r
224 PMMRIE = PMMRIE_backup; // Restore PMM interrupt enable register
\r
225 PMMCTL0_H = 0x00; // Lock PMM registers for write access
\r
226 return PMM_STATUS_OK; // Return: OK
\r
229 uint16_t SetVCore(uint8_t level)
\r
232 uint16_t status = 0;
\r
234 level &= PMMCOREV_3; // Set Mask for Max. level
\r
235 actlevel = (PMMCTL0 & PMMCOREV_3); // Get actual VCore
\r
236 // step by step increase or decrease
\r
237 while ((level != actlevel) && (status == 0)) {
\r
238 if (level > actlevel){
\r
239 status = SetVCoreUp(++actlevel);
\r
242 status = SetVCoreDown(--actlevel);
\r