CLEON  Version 1
Cloud-Offloaded GPS Receiver
hal_pmm.c
Go to the documentation of this file.
1 
7 #include "cleon_conf.h"
8 #include "app_define.h"
9 #include "sys_define.h"
10 #include "hal_define.h"
11 #include "fs_define.h"
12 
13 // Variable for storing SYSRSTIV
14 volatile unsigned int SysRstIv = 0;
15 
16 /*----------------------------------------------------------------------------*/
24 void HAL_PMM_Init(void)
25 {
26  SysRstIv = SYSRSTIV;
27 
28  // Set Vcore voltage to level 2 in order to support 12MHz MCLK
29  // SVSH enabled
30  // SVSHRVL = 2 (2.04V), SVSMHRRL = 2 (2.14V)
31  SetVCore(2);
32 
33  // Enable SYSH and SVMH
35 
36  // Enable SVSH reset
38 
39  // SVS is enabled in LPM as normal performance
41 
42  // Clear existing interrupt flags
44 }
45 
47 /*******************************************************************************
48  *
49  * HAL_PMM.c
50  * Power Management Module Library for MSP430F5xx/6xx family
51  *
52  *
53  * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
54  *
55  *
56  * Redistribution and use in source and binary forms, with or without
57  * modification, are permitted provided that the following conditions
58  * are met:
59  *
60  * Redistributions of source code must retain the above copyright
61  * notice, this list of conditions and the following disclaimer.
62  *
63  * Redistributions in binary form must reproduce the above copyright
64  * notice, this list of conditions and the following disclaimer in the
65  * documentation and/or other materials provided with the
66  * distribution.
67  *
68  * Neither the name of Texas Instruments Incorporated nor the names of
69  * its contributors may be used to endorse or promote products derived
70  * from this software without specific prior written permission.
71  *
72  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
73  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
74  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
75  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
76  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
77  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
78  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
79  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
80  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
81  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
82  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
83  *
84  ******************************************************************************/
85 
86 /*******************************************************************************
87  * \brief Increase Vcore by one level
88  *
89  * \param level Level to which Vcore needs to be increased
90  * \return status Success/failure
91  ******************************************************************************/
92 
93 static uint16_t SetVCoreUp(uint8_t level)
94 {
95  uint16_t PMMRIE_backup, SVSMHCTL_backup, SVSMLCTL_backup;
96 
97  // The code flow for increasing the Vcore has been altered to work around
98  // the erratum FLASH37.
99  // Please refer to the Errata sheet to know if a specific device is affected
100  // DO NOT ALTER THIS FUNCTION
101 
102  // Open PMM registers for write access
103  PMMCTL0_H = 0xA5;
104 
105  // Disable dedicated Interrupts
106  // Backup all registers
107  PMMRIE_backup = PMMRIE;
108  PMMRIE &= ~(SVMHVLRPE | SVSHPE | SVMLVLRPE | SVSLPE | SVMHVLRIE |
109  SVMHIE | SVSMHDLYIE | SVMLVLRIE | SVMLIE | SVSMLDLYIE);
110  SVSMHCTL_backup = SVSMHCTL;
111  SVSMLCTL_backup = SVSMLCTL;
112 
113  // Clear flags
114  PMMIFG = 0;
115 
116  // Set SVM highside to new level and check if a VCore increase is possible
117  SVSMHCTL = SVMHE | SVSHE | (SVSMHRRL0 * level);
118 
119  // Wait until SVM highside is settled
120  while ((PMMIFG & SVSMHDLYIFG) == 0) ;
121 
122  // Clear flag
123  PMMIFG &= ~SVSMHDLYIFG;
124 
125  // Check if a VCore increase is possible
126  if ((PMMIFG & SVMHIFG) == SVMHIFG){ // -> Vcc is too low for a Vcore increase
127  // recover the previous settings
128  PMMIFG &= ~SVSMHDLYIFG;
129  SVSMHCTL = SVSMHCTL_backup;
130 
131  // Wait until SVM highside is settled
132  while ((PMMIFG & SVSMHDLYIFG) == 0) ;
133 
134  // Clear all Flags
135  PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG | SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG);
136 
137  PMMRIE = PMMRIE_backup; // Restore PMM interrupt enable register
138  PMMCTL0_H = 0x00; // Lock PMM registers for write access
139  return PMM_STATUS_ERROR; // return: voltage not set
140  }
141 
142  // Set also SVS highside to new level
143  // Vcc is high enough for a Vcore increase
144  SVSMHCTL |= (SVSHRVL0 * level);
145 
146  // Wait until SVM highside is settled
147  while ((PMMIFG & SVSMHDLYIFG) == 0) ;
148 
149  // Clear flag
150  PMMIFG &= ~SVSMHDLYIFG;
151 
152  // Set VCore to new level
153  PMMCTL0_L = PMMCOREV0 * level;
154 
155  // Set SVM, SVS low side to new level
156  SVSMLCTL = SVMLE | (SVSMLRRL0 * level) | SVSLE | (SVSLRVL0 * level);
157 
158  // Wait until SVM, SVS low side is settled
159  while ((PMMIFG & SVSMLDLYIFG) == 0) ;
160 
161  // Clear flag
162  PMMIFG &= ~SVSMLDLYIFG;
163  // SVS, SVM core and high side are now set to protect for the new core level
164 
165  // Restore Low side settings
166  // Clear all other bits _except_ level settings
167  SVSMLCTL &= (SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2);
168 
169  // Clear level settings in the backup register,keep all other bits
170  SVSMLCTL_backup &= ~(SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2);
171 
172  // Restore low-side SVS monitor settings
173  SVSMLCTL |= SVSMLCTL_backup;
174 
175  // Restore High side settings
176  // Clear all other bits except level settings
177  SVSMHCTL &= (SVSHRVL0 + SVSHRVL1 + SVSMHRRL0 + SVSMHRRL1 + SVSMHRRL2);
178 
179  // Clear level settings in the backup register,keep all other bits
180  SVSMHCTL_backup &= ~(SVSHRVL0 + SVSHRVL1 + SVSMHRRL0 + SVSMHRRL1 + SVSMHRRL2);
181 
182  // Restore backup
183  SVSMHCTL |= SVSMHCTL_backup;
184 
185  // Wait until high side, low side settled
186  while (((PMMIFG & SVSMLDLYIFG) == 0) && ((PMMIFG & SVSMHDLYIFG) == 0)) ;
187 
188  // Clear all Flags
189  PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG | SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG);
190 
191  PMMRIE = PMMRIE_backup; // Restore PMM interrupt enable register
192  PMMCTL0_H = 0x00; // Lock PMM registers for write access
193 
194  return PMM_STATUS_OK;
195 }
196 
197 /*******************************************************************************
198  * \brief Decrease Vcore by one level
199  *
200  * \param level Level to which Vcore needs to be decreased
201  * \return status Success/failure
202  ******************************************************************************/
203 
204 static uint16_t SetVCoreDown(uint8_t level)
205 {
206  uint16_t PMMRIE_backup, SVSMHCTL_backup, SVSMLCTL_backup;
207 
208  // The code flow for decreasing the Vcore has been altered to work around
209  // the erratum FLASH37.
210  // Please refer to the Errata sheet to know if a specific device is affected
211  // DO NOT ALTER THIS FUNCTION
212 
213  // Open PMM registers for write access
214  PMMCTL0_H = 0xA5;
215 
216  // Disable dedicated Interrupts
217  // Backup all registers
218  PMMRIE_backup = PMMRIE;
219  PMMRIE &= ~(SVMHVLRPE | SVSHPE | SVMLVLRPE | SVSLPE | SVMHVLRIE |
220  SVMHIE | SVSMHDLYIE | SVMLVLRIE | SVMLIE | SVSMLDLYIE);
221  SVSMHCTL_backup = SVSMHCTL;
222  SVSMLCTL_backup = SVSMLCTL;
223 
224  // Clear flags
225  PMMIFG &= ~(SVMHIFG | SVSMHDLYIFG | SVMLIFG | SVSMLDLYIFG);
226 
227  // Set SVM, SVS high & low side to new settings in normal mode
228  SVSMHCTL = SVMHE | (SVSMHRRL0 * level) | SVSHE | (SVSHRVL0 * level);
229  SVSMLCTL = SVMLE | (SVSMLRRL0 * level) | SVSLE | (SVSLRVL0 * level);
230 
231  // Wait until SVM high side and SVM low side is settled
232  while ((PMMIFG & SVSMHDLYIFG) == 0 || (PMMIFG & SVSMLDLYIFG) == 0) ;
233 
234  // Clear flags
235  PMMIFG &= ~(SVSMHDLYIFG + SVSMLDLYIFG);
236  // SVS, SVM core and high side are now set to protect for the new core level
237 
238  // Set VCore to new level
239  PMMCTL0_L = PMMCOREV0 * level;
240 
241  // Restore Low side settings
242  // Clear all other bits _except_ level settings
243  SVSMLCTL &= (SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2);
244 
245  // Clear level settings in the backup register,keep all other bits
246  SVSMLCTL_backup &= ~(SVSLRVL0 + SVSLRVL1 + SVSMLRRL0 + SVSMLRRL1 + SVSMLRRL2);
247 
248  // Restore low-side SVS monitor settings
249  SVSMLCTL |= SVSMLCTL_backup;
250 
251  // Restore High side settings
252  // Clear all other bits except level settings
253  SVSMHCTL &= (SVSHRVL0 + SVSHRVL1 + SVSMHRRL0 + SVSMHRRL1 + SVSMHRRL2);
254 
255  // Clear level settings in the backup register, keep all other bits
256  SVSMHCTL_backup &= ~(SVSHRVL0 + SVSHRVL1 + SVSMHRRL0 + SVSMHRRL1 + SVSMHRRL2);
257 
258  // Restore backup
259  SVSMHCTL |= SVSMHCTL_backup;
260 
261  // Wait until high side, low side settled
262  while (((PMMIFG & SVSMLDLYIFG) == 0) && ((PMMIFG & SVSMHDLYIFG) == 0)) ;
263 
264  // Clear all Flags
265  PMMIFG &= ~(SVMHVLRIFG | SVMHIFG | SVSMHDLYIFG | SVMLVLRIFG | SVMLIFG | SVSMLDLYIFG);
266 
267  PMMRIE = PMMRIE_backup; // Restore PMM interrupt enable register
268  PMMCTL0_H = 0x00; // Lock PMM registers for write access
269  return PMM_STATUS_OK; // Return: OK
270 }
271 
272 uint16_t SetVCore(uint8_t level)
273 {
274  uint16_t actlevel;
275  uint16_t status = 0;
276 
277  level &= PMMCOREV_3; // Set Mask for Max. level
278  actlevel = (PMMCTL0 & PMMCOREV_3); // Get actual VCore
279  // step by step increase or decrease
280  while ((level != actlevel) && (status == 0)) {
281  if (level > actlevel){
282  status = SetVCoreUp(++actlevel);
283  }
284  else {
285  status = SetVCoreDown(--actlevel);
286  }
287  }
288 
289  return status;
290 }
292