]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/MSP430X_MSP430F5438_CCS/Demo_Source/F5XX_6XX_Core_Lib/HAL_PMM.c
Add FreeRTOS-Plus directory.
[freertos] / FreeRTOS / Demo / MSP430X_MSP430F5438_CCS / Demo_Source / F5XX_6XX_Core_Lib / HAL_PMM.c
1 /*******************************************************************************\r
2  *\r
3  * HAL_PMM.c\r
4  * Power Management Module Library for MSP430F5xx/6xx family\r
5  *\r
6  *\r
7  * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/\r
8  *\r
9  *\r
10  *  Redistribution and use in source and binary forms, with or without\r
11  *  modification, are permitted provided that the following conditions\r
12  *  are met:\r
13  *\r
14  *    Redistributions of source code must retain the above copyright\r
15  *    notice, this list of conditions and the following disclaimer.\r
16  *\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
20  *    distribution.\r
21  *\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
25  *\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
37  *\r
38  ******************************************************************************/\r
39 \r
40 #include "msp430.h"\r
41 #include "HAL_PMM.h"\r
42 \r
43 /*******************************************************************************\r
44  * \brief   Increase Vcore by one level\r
45  *\r
46  * \param level     Level to which Vcore needs to be increased\r
47  * \return status   Success/failure\r
48  ******************************************************************************/\r
49 \r
50 static uint16_t SetVCoreUp(uint8_t level)\r
51 {\r
52     uint16_t PMMRIE_backup, SVSMHCTL_backup, SVSMLCTL_backup;\r
53 \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
58 \r
59     // Open PMM registers for write access\r
60     PMMCTL0_H = 0xA5;\r
61 \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
69 \r
70     // Clear flags\r
71     PMMIFG = 0;\r
72 \r
73     // Set SVM highside to new level and check if a VCore increase is possible\r
74     SVSMHCTL = SVMHE | SVSHE | (SVSMHRRL0 * level);\r
75 \r
76     // Wait until SVM highside is settled\r
77     while ((PMMIFG & SVSMHDLYIFG) == 0) ;\r
78 \r
79     // Clear flag\r
80     PMMIFG &= ~SVSMHDLYIFG;\r
81 \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
87 \r
88         // Wait until SVM highside is settled\r
89         while ((PMMIFG & SVSMHDLYIFG) == 0) ;\r
90 \r
91         // Clear all Flags\r
92         PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG | SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG);\r
93 \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
97     }\r
98 \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
102 \r
103     // Wait until SVM highside is settled\r
104     while ((PMMIFG & SVSMHDLYIFG) == 0) ;\r
105 \r
106     // Clear flag\r
107     PMMIFG &= ~SVSMHDLYIFG;\r
108 \r
109     // Set VCore to new level\r
110     PMMCTL0_L = PMMCOREV0 * level;\r
111 \r
112     // Set SVM, SVS low side to new level\r
113     SVSMLCTL = SVMLE | (SVSMLRRL0 * level) | SVSLE | (SVSLRVL0 * level);\r
114 \r
115     // Wait until SVM, SVS low side is settled\r
116     while ((PMMIFG & SVSMLDLYIFG) == 0) ;\r
117 \r
118     // Clear flag\r
119     PMMIFG &= ~SVSMLDLYIFG;\r
120     // SVS, SVM core and high side are now set to protect for the new core level\r
121 \r
122     // Restore Low side settings\r
123     // Clear all other bits _except_ level settings\r
124     SVSMLCTL &= (SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2);\r
125 \r
126     // Clear level settings in the backup register,keep all other bits\r
127     SVSMLCTL_backup &= ~(SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2);\r
128 \r
129     // Restore low-side SVS monitor settings\r
130     SVSMLCTL |= SVSMLCTL_backup;\r
131 \r
132     // Restore High side settings\r
133     // Clear all other bits except level settings\r
134     SVSMHCTL &= (SVSHRVL0 + SVSHRVL1 + SVSMHRRL0 + SVSMHRRL1 + SVSMHRRL2);\r
135 \r
136     // Clear level settings in the backup register,keep all other bits\r
137     SVSMHCTL_backup &= ~(SVSHRVL0 + SVSHRVL1 + SVSMHRRL0 + SVSMHRRL1 + SVSMHRRL2);\r
138 \r
139     // Restore backup\r
140     SVSMHCTL |= SVSMHCTL_backup;\r
141 \r
142     // Wait until high side, low side settled\r
143     while (((PMMIFG & SVSMLDLYIFG) == 0) && ((PMMIFG & SVSMHDLYIFG) == 0)) ;\r
144 \r
145     // Clear all Flags\r
146     PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG | SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG);\r
147 \r
148     PMMRIE = PMMRIE_backup;                 // Restore PMM interrupt enable register\r
149     PMMCTL0_H = 0x00;                       // Lock PMM registers for write access\r
150 \r
151     return PMM_STATUS_OK;\r
152 }\r
153 \r
154 /*******************************************************************************\r
155  * \brief  Decrease Vcore by one level\r
156  *\r
157  * \param  level    Level to which Vcore needs to be decreased\r
158  * \return status   Success/failure\r
159  ******************************************************************************/\r
160 \r
161 static uint16_t SetVCoreDown(uint8_t level)\r
162 {\r
163     uint16_t PMMRIE_backup, SVSMHCTL_backup, SVSMLCTL_backup;\r
164 \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
169 \r
170     // Open PMM registers for write access\r
171     PMMCTL0_H = 0xA5;\r
172 \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
180 \r
181     // Clear flags\r
182     PMMIFG &= ~(SVMHIFG | SVSMHDLYIFG | SVMLIFG | SVSMLDLYIFG);\r
183 \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
187 \r
188     // Wait until SVM high side and SVM low side is settled\r
189     while ((PMMIFG & SVSMHDLYIFG) == 0 || (PMMIFG & SVSMLDLYIFG) == 0) ;\r
190 \r
191     // Clear flags\r
192     PMMIFG &= ~(SVSMHDLYIFG + SVSMLDLYIFG);\r
193     // SVS, SVM core and high side are now set to protect for the new core level\r
194 \r
195     // Set VCore to new level\r
196     PMMCTL0_L = PMMCOREV0 * level;\r
197 \r
198     // Restore Low side settings\r
199     // Clear all other bits _except_ level settings\r
200     SVSMLCTL &= (SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2);\r
201 \r
202     // Clear level settings in the backup register,keep all other bits\r
203     SVSMLCTL_backup &= ~(SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2);\r
204 \r
205     // Restore low-side SVS monitor settings\r
206     SVSMLCTL |= SVSMLCTL_backup;\r
207 \r
208     // Restore High side settings\r
209     // Clear all other bits except level settings\r
210     SVSMHCTL &= (SVSHRVL0 + SVSHRVL1 + SVSMHRRL0 + SVSMHRRL1 + SVSMHRRL2);\r
211 \r
212     // Clear level settings in the backup register, keep all other bits\r
213     SVSMHCTL_backup &= ~(SVSHRVL0 + SVSHRVL1 + SVSMHRRL0 + SVSMHRRL1 + SVSMHRRL2);\r
214 \r
215     // Restore backup\r
216     SVSMHCTL |= SVSMHCTL_backup;\r
217 \r
218     // Wait until high side, low side settled\r
219     while (((PMMIFG & SVSMLDLYIFG) == 0) && ((PMMIFG & SVSMHDLYIFG) == 0)) ;\r
220 \r
221     // Clear all Flags\r
222     PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG | SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG);\r
223 \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
227 }\r
228 \r
229 uint16_t SetVCore(uint8_t level)\r
230 {\r
231     uint16_t actlevel;\r
232     uint16_t status = 0;\r
233 \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
240         }\r
241         else {\r
242             status = SetVCoreDown(--actlevel);\r
243         }\r
244     }\r
245 \r
246     return status;\r
247 }\r
248 \r