2020-2021 Sunseeker Telemetry and Lighting System
ucs.c
Go to the documentation of this file.
1 //*****************************************************************************
2 //
3 // ucs.c - Driver for the ucs Module.
4 //
5 //*****************************************************************************
6 
7 //*****************************************************************************
8 //
11 //
12 //*****************************************************************************
13 
14 #include "inc/hw_memmap.h"
15 
16 #if defined(__MSP430_HAS_UCS__) || defined(__MSP430_HAS_UCS_RF__)
17 #include "ucs.h"
18 
19 #include <assert.h>
20 
21 #ifdef __GNUC__
22 #define __extension__(x)
23 __extension__(#define __delay_cycles(x) \
24 ({ \
25  volatile unsigned int j; \
26  for (j=0;j<x;j++) \
27  { \
28  __no_operation(); \
29  } \
30 })
31 );
32 
33 #endif
34 
35 #define CC430_DEVICE (defined (__CC430F5133__) || defined(__CC430F5135__) || defined(__CC430F5137__) || \
36  defined(__CC430F6125__) || defined(__CC430F6126__) || defined(__CC430F6127__) || \
37  defined(__CC430F6135__) || defined(__CC430F6137__) || defined(__CC430F5123__) || \
38  defined(__CC430F5125__) || defined(__CC430F5143__) || defined(__CC430F5145__) || \
39  defined(__CC430F5147__) || defined(__CC430F6143__) || defined(__CC430F6145__) || \
40  defined(__CC430F6147__))
41 
42 #define NOT_CC430_DEVICE (!defined (__CC430F5133__) && !defined(__CC430F5135__) && !defined(__CC430F5137__) && \
43  !defined(__CC430F6125__) && !defined(__CC430F6126__) && !defined(__CC430F6127__) && \
44  !defined(__CC430F6135__) && !defined(__CC430F6137__) && !defined(__CC430F5123__) && \
45  !defined(__CC430F5125__) && !defined(__CC430F5143__) && !defined(__CC430F5145__) && \
46  !defined(__CC430F5147__) && !defined(__CC430F6143__) && !defined(__CC430F6145__) && \
47  !defined(__CC430F6147__))
48 //******************************************************************************
49 //
50 // The XT1 crystal frequency. Should be set with
51 // UCS_setExternalClockSource if XT1 is used and user intends to
52 // invoke UCS_getSMCLK, UCS_getMCLK or UCS_getACLK
53 //
54 //******************************************************************************
55 static uint32_t privateXT1ClockFrequency = 0;
56 
57 //******************************************************************************
58 //
59 // The XT2 crystal frequency. Should be set with
60 // UCS_setExternalClockSource if XT1 is used and user intends to invoke
61 // UCS_getSMCLK, UCS_getMCLK or UCS_getACLK
62 //
63 //******************************************************************************
64 static uint32_t privateXT2ClockFrequency = 0;
65 
66 static uint32_t privateUCSSourceClockFromDCO (uint16_t FLLRefCLKSource
67  )
68 {
69  assert((SELM__DCOCLKDIV == FLLRefCLKSource) ||
70  (SELM__DCOCLK == FLLRefCLKSource)
71  );
72  uint16_t D_value = 1;
73  uint16_t N_value;
74  uint16_t n_value = 1;
75  uint32_t Fref_value;
76  uint8_t i;
77 
78  N_value = (HWREG16(UCS_BASE + OFS_UCSCTL2)) & 0x03FF;
79  uint16_t tempDivider = HWREG8(UCS_BASE + OFS_UCSCTL3) & FLLREFDIV_7;
80 
81  if (tempDivider < 4) {
82  n_value <<= tempDivider;
83  }
84  else if (tempDivider == 4) {
85  n_value = 12;
86  }
87  else if (tempDivider == 5) {
88  n_value = 16;
89  }
90 
91  switch ( (HWREG8(UCS_BASE + OFS_UCSCTL3)) & SELREF_7){
92  case SELREF__XT1CLK:
93  Fref_value = privateXT1ClockFrequency;
94 
95  if(XTS != (HWREG16(UCS_BASE + OFS_UCSCTL6) & XTS)) {
96  if (HWREG8(UCS_BASE + OFS_UCSCTL7) & XT1LFOFFG){
97  HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT1LFOFFG);
98  //Clear OFIFG fault flag
99  HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
100 
101  if (HWREG8(UCS_BASE + OFS_UCSCTL7) & XT1LFOFFG){
102  Fref_value = UCS_REFOCLK_FREQUENCY;
103  }
104  }
105  }
106  else {
107  if (HWREG8(UCS_BASE + OFS_UCSCTL7) & XT1HFOFFG){
108  HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT1HFOFFG);
109  //Clear OFIFG fault flag
110  HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
111 
112  if (HWREG8(UCS_BASE + OFS_UCSCTL7) & XT1HFOFFG){
113  Fref_value = UCS_REFOCLK_FREQUENCY;
114  }
115  }
116  }
117 
118  break;
119  case SELREF__REFOCLK:
120  Fref_value = UCS_REFOCLK_FREQUENCY;
121  break;
122  case SELREF__XT2CLK:
123  Fref_value = privateXT2ClockFrequency;
124 
125  if (HWREG8(UCS_BASE + OFS_UCSCTL7) & XT2OFFG){
126  HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT2OFFG);
127 
128  //Clear OFIFG fault flag
129  HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
130 
131  if (HWREG8(UCS_BASE + OFS_UCSCTL7) & XT2OFFG){
132  Fref_value = UCS_REFOCLK_FREQUENCY;
133  }
134  }
135 
136  break;
137  default: assert(0);
138  }
139 
140  uint32_t CLKFrequency = Fref_value * ( N_value + 1) / n_value;
141 
142  if (SELM__DCOCLK == FLLRefCLKSource){
143  tempDivider = (HWREG16(UCS_BASE + OFS_UCSCTL2)) & FLLD_7;
144  tempDivider = tempDivider >> 12;
145 
146  for (i = 0; i < tempDivider; i++){
147  D_value = D_value * 2;
148  }
149 
150  CLKFrequency *= D_value;
151  }
152  return ( CLKFrequency) ;
153 }
154 
155 static uint32_t privateUCSComputeCLKFrequency (uint16_t CLKSource,
156  uint16_t CLKSourceDivider
157  )
158 {
159  uint32_t CLKFrequency;
160  uint8_t CLKSourceFrequencyDivider = 1;
161  uint8_t i = 0;
162 
163  for ( i = 0; i < CLKSourceDivider; i++){
164  CLKSourceFrequencyDivider *= 2;
165  }
166 
167  switch (CLKSource){
168  case SELM__XT1CLK:
169  CLKFrequency = (privateXT1ClockFrequency /
170  CLKSourceFrequencyDivider);
171 
172  if(XTS != (HWREG16(UCS_BASE + OFS_UCSCTL6) & XTS)) {
173  if (HWREG8(UCS_BASE + OFS_UCSCTL7) & XT1LFOFFG){
174  HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT1LFOFFG);
175  //Clear OFIFG fault flag
176  HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
177 
178  if (HWREG8(UCS_BASE + OFS_UCSCTL7) & XT1LFOFFG){
179  CLKFrequency = UCS_REFOCLK_FREQUENCY;
180  }
181  }
182  }
183  else {
184  if (HWREG8(UCS_BASE + OFS_UCSCTL7) & XT1HFOFFG){
185  HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT1HFOFFG);
186  //Clear OFIFG fault flag
187  HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
188 
189  if (HWREG8(UCS_BASE + OFS_UCSCTL7) & XT1HFOFFG){
190  CLKFrequency = UCS_REFOCLK_FREQUENCY;
191  }
192  }
193  }
194  break;
195 
196  case SELM__VLOCLK:
197  CLKFrequency =
198  (UCS_VLOCLK_FREQUENCY / CLKSourceFrequencyDivider);
199  break;
200  case SELM__REFOCLK:
201  CLKFrequency =
202  (UCS_REFOCLK_FREQUENCY / CLKSourceFrequencyDivider);
203  break;
204  case SELM__XT2CLK:
205  CLKFrequency =
206  (privateXT2ClockFrequency / CLKSourceFrequencyDivider);
207 
208  if (HWREG8(UCS_BASE + OFS_UCSCTL7) & XT2OFFG){
209 
210  HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~XT2OFFG;
211  //Clear OFIFG fault flag
212  HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
213  }
214 
215  if (HWREG8(UCS_BASE + OFS_UCSCTL7) & XT2OFFG){
216  CLKFrequency =
217  privateUCSSourceClockFromDCO( SELM__DCOCLKDIV);
218  }
219  break;
220  case SELM__DCOCLK:
221  case SELM__DCOCLKDIV:
222  CLKFrequency = privateUCSSourceClockFromDCO(
223  CLKSource) / CLKSourceFrequencyDivider;
224  break;
225  }
226 
227  return ( CLKFrequency) ;
228 }
229 
230 void UCS_setExternalClockSource (uint32_t XT1CLK_frequency,
231  uint32_t XT2CLK_frequency
232  )
233 {
234  privateXT1ClockFrequency = XT1CLK_frequency;
235  privateXT2ClockFrequency = XT2CLK_frequency;
236 }
237 
238 void UCS_initClockSignal (uint8_t selectedClockSignal,
239  uint16_t clockSource,
240  uint16_t clockSourceDivider
241  )
242 {
243  assert(
244  (UCS_XT1CLK_SELECT == clockSource) ||
245  (UCS_VLOCLK_SELECT == clockSource) ||
246  (UCS_REFOCLK_SELECT == clockSource) ||
247  (UCS_DCOCLK_SELECT == clockSource) ||
248  (UCS_DCOCLKDIV_SELECT == clockSource) ||
249  (UCS_XT2CLK_SELECT == clockSource)
250  );
251 
252  assert(
253  (UCS_CLOCK_DIVIDER_1 == clockSourceDivider) ||
254  (UCS_CLOCK_DIVIDER_2 == clockSourceDivider) ||
255  (UCS_CLOCK_DIVIDER_4 == clockSourceDivider) ||
256  (UCS_CLOCK_DIVIDER_8 == clockSourceDivider) ||
257  (UCS_CLOCK_DIVIDER_16 == clockSourceDivider) ||
258  (UCS_CLOCK_DIVIDER_32 == clockSourceDivider)
259  );
260 
261  uint16_t temp = HWREG16(UCS_BASE + OFS_UCSCTL5);
262  switch (selectedClockSignal){
263  case UCS_ACLK:
264  HWREG16(UCS_BASE + OFS_UCSCTL4) &= ~(SELA_7);
265  clockSource = clockSource << 8;
266  HWREG16(UCS_BASE + OFS_UCSCTL4) |= (clockSource);
267 
268  clockSourceDivider = clockSourceDivider << 8;
269  HWREG16(UCS_BASE + OFS_UCSCTL5) = temp & ~(DIVA_7) | clockSourceDivider;
270  break;
271  case UCS_SMCLK:
272  HWREG16(UCS_BASE + OFS_UCSCTL4) &= ~(SELS_7);
273  clockSource = clockSource << 4;
274  HWREG16(UCS_BASE + OFS_UCSCTL4) |= (clockSource);
275 
276  clockSourceDivider = clockSourceDivider << 4;
277  HWREG16(UCS_BASE + OFS_UCSCTL5) = temp & ~(DIVS_7) | clockSourceDivider;
278  break;
279  case UCS_MCLK:
280  HWREG16(UCS_BASE + OFS_UCSCTL4) &= ~(SELM_7);
281  HWREG16(UCS_BASE + OFS_UCSCTL4) |= (clockSource);
282 
283  HWREG16(UCS_BASE + OFS_UCSCTL5) = temp & ~(DIVM_7) | clockSourceDivider;
284  break;
285  case UCS_FLLREF:
286  assert(clockSource <= SELA_5);
287  HWREG8(UCS_BASE + OFS_UCSCTL3) &= ~(SELREF_7);
288 
289  clockSource = clockSource << 4;
290  HWREG8(UCS_BASE + OFS_UCSCTL3) |= (clockSource);
291 
292  temp = HWREG8(UCS_BASE + OFS_UCSCTL3) & 0x00FF;
293  //Note that dividers for FLLREF are slightly different
294  //Hence handled differently from other CLK signals
295  switch(clockSourceDivider)
296  {
297  case UCS_CLOCK_DIVIDER_12:
298  HWREG8(UCS_BASE + OFS_UCSCTL3) = temp & ~(FLLREFDIV_7) | FLLREFDIV__12;
299  break;
300  case UCS_CLOCK_DIVIDER_16:
301  HWREG8(UCS_BASE + OFS_UCSCTL3) = temp & ~(FLLREFDIV_7) | FLLREFDIV__16;
302  break;
303  default:
304  HWREG8(UCS_BASE + OFS_UCSCTL3) = temp & ~(FLLREFDIV_7) | clockSourceDivider;
305  break;
306  }
307 
308  break;
309  }
310 }
311 
312 void UCS_turnOnLFXT1 (uint16_t xt1drive,
313  uint8_t xcap
314  )
315 {
316  assert((xcap == UCS_XCAP_0) ||
317  (xcap == UCS_XCAP_1) ||
318  (xcap == UCS_XCAP_2) ||
319  (xcap == UCS_XCAP_3) );
320 
321  assert((xt1drive == UCS_XT1_DRIVE_0 ) ||
322  (xt1drive == UCS_XT1_DRIVE_1 ) ||
323  (xt1drive == UCS_XT1_DRIVE_2 ) ||
324  (xt1drive == UCS_XT1_DRIVE_3 ));
325 
326  //Switch ON XT1 oscillator
327  HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XT1OFF;
328 
329  //Highest drive setting for XT1startup
330  HWREG16(UCS_BASE + OFS_UCSCTL6_L) |= XT1DRIVE1_L + XT1DRIVE0_L;
331 
332  //Enable LF mode and clear xcap and bypass
333  HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~(XTS + XCAP_3 + XT1BYPASS);
334  HWREG16(UCS_BASE + OFS_UCSCTL6) |= xcap;
335 
336  while (HWREG8(UCS_BASE + OFS_UCSCTL7) & XT1LFOFFG)
337  {
338  //Clear OSC flaut Flags fault flags
339  HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT1LFOFFG);
340 
341  //Clear OFIFG fault flag
342  HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
343  }
344 
345  //set requested Drive mode
346  HWREG16(UCS_BASE + OFS_UCSCTL6) = ( HWREG16(UCS_BASE + OFS_UCSCTL6) &
347  ~(XT1DRIVE_3)
348  ) |
349  (xt1drive);
350 
351 }
352 
353 void UCS_turnOnHFXT1(uint16_t xt1drive
354  )
355 {
356  //Switch ON XT1 oscillator
357  HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XT1OFF;
358 
359  //Check if drive value is the expected one
360  if ((HWREG16(UCS_BASE + OFS_UCSCTL6) & XT1DRIVE_3) != xt1drive){
361  //Clear XT1drive field
362  HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XT1DRIVE_3;
363 
364  //Set requested value
365  HWREG16(UCS_BASE + OFS_UCSCTL6) |= xt1drive;
366  }
367 
368  //Enable HF mode
369  HWREG16(UCS_BASE + OFS_UCSCTL6) |= XTS;
370 
371  HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XT1BYPASS;
372 
373  // Check XT1 fault flags
374  while((HWREG8(UCS_BASE + OFS_UCSCTL7) & (XT1HFOFFG))){
375  //Clear OSC flaut Flags fault flags
376  HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT1HFOFFG);
377 
378  //Clear OFIFG fault flag
379  HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
380  }
381 }
382 
383 void UCS_bypassXT1 (uint8_t highOrLowFrequency
384  )
385 {
386  assert((UCS_XT1_LOW_FREQUENCY == highOrLowFrequency) ||
387  (UCS_XT1_HIGH_FREQUENCY == highOrLowFrequency )
388  );
389 
390  //Enable HF/LF mode
391  HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XTS;
392  HWREG16(UCS_BASE + OFS_UCSCTL6) |= highOrLowFrequency;
393 
394  //Switch OFF XT1 oscillator and enable BYPASS mode
395  HWREG16(UCS_BASE + OFS_UCSCTL6) |= (XT1BYPASS + XT1OFF);
396 
397  if (UCS_XT1_LOW_FREQUENCY == highOrLowFrequency){
398  while (HWREG8(UCS_BASE + OFS_UCSCTL7) & (XT1LFOFFG)) {
399  //Clear OSC flaut Flags fault flags
400  HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT1LFOFFG);
401 
402  // Clear the global fault flag. In case the XT1 caused the global fault
403  // flag to get set this will clear the global error condition. If any
404  // error condition persists, global flag will get again.
405  HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
406  }
407  } else {
408  while (HWREG8(UCS_BASE + OFS_UCSCTL7) & (XT1HFOFFG)) {
409  //Clear OSC flaut Flags fault flags
410  HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT1HFOFFG);
411 
412  //Clear the global fault flag. In case the XT1 caused the global fault
413  //flag to get set this will clear the global error condition. If any
414  //error condition persists, global flag will get again.
415  HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
416  }
417  }
418 
419 }
420 
421 bool UCS_turnOnLFXT1WithTimeout(uint16_t xt1drive,
422  uint8_t xcap,
423  uint16_t timeout
424  )
425 {
426  assert((xcap == UCS_XCAP_0) ||
427  (xcap == UCS_XCAP_1) ||
428  (xcap == UCS_XCAP_2) ||
429  (xcap == UCS_XCAP_3) );
430 
431  assert((xt1drive == UCS_XT1_DRIVE_0 ) ||
432  (xt1drive == UCS_XT1_DRIVE_1 ) ||
433  (xt1drive == UCS_XT1_DRIVE_2 ) ||
434  (xt1drive == UCS_XT1_DRIVE_3 ));
435 
436  assert(timeout > 0);
437 
438  //Switch ON XT1 oscillator
439  HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XT1OFF;
440 
441  //Highest drive setting for XT1startup
442  HWREG16(UCS_BASE + OFS_UCSCTL6_L) |= XT1DRIVE1_L + XT1DRIVE0_L;
443 
444  //Enable LF mode and clear xcap and bypass
445  HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~(XTS + XCAP_3 + XT1BYPASS);
446  HWREG16(UCS_BASE + OFS_UCSCTL6) |= xcap;
447 
448  do
449  {
450  HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT1LFOFFG);
451 
452  //Clear OFIFG fault flag
453  HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
454  }while ((HWREG8(UCS_BASE + OFS_UCSCTL7) & XT1LFOFFG) && --timeout);
455 
456  if (timeout){
457  //set requested Drive mode
458  HWREG16(UCS_BASE + OFS_UCSCTL6) = ( HWREG16(UCS_BASE + OFS_UCSCTL6) &
459  ~(XT1DRIVE_3)
460  ) |
461  (xt1drive);
462 
463  return (STATUS_SUCCESS);
464  } else {
465  return (STATUS_FAIL);
466  }
467 }
468 
469 bool UCS_turnOnHFXT1WithTimeout (uint16_t xt1drive,
470  uint16_t timeout
471  )
472 {
473  assert((xt1drive == UCS_XT1_DRIVE_0 ) ||
474  (xt1drive == UCS_XT1_DRIVE_1 ) ||
475  (xt1drive == UCS_XT1_DRIVE_2 ) ||
476  (xt1drive == UCS_XT1_DRIVE_3 ));
477 
478  assert(timeout > 0);
479 
480  //Switch ON XT1 oscillator
481  HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XT1OFF;
482 
483  //Check if drive value is the expected one
484  if ((HWREG16(UCS_BASE + OFS_UCSCTL6) & XT1DRIVE_3) != xt1drive){
485  //Clear XT1drive field
486  HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XT1DRIVE_3;
487 
488  //Set requested value
489  HWREG16(UCS_BASE + OFS_UCSCTL6) |= xt1drive;
490  }
491 
492  //Enable HF mode
493  HWREG16(UCS_BASE + OFS_UCSCTL6) |= XTS;
494 
495  HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XT1BYPASS;
496 
497  // Check XT1 fault flags
498  do
499  {
500  HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT1HFOFFG);
501 
502  //Clear OFIFG fault flag
503  HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
504  }while ((HWREG8(UCS_BASE + OFS_UCSCTL7) & ( XT1HFOFFG))
505  && --timeout);
506 
507  if (timeout){
508  return (STATUS_SUCCESS);
509  } else {
510  return (STATUS_FAIL);
511  }
512 }
513 
514 bool UCS_bypassXT1WithTimeout (uint8_t highOrLowFrequency,
515  uint16_t timeout
516  )
517 {
518  assert((UCS_XT1_LOW_FREQUENCY == highOrLowFrequency) ||
519  (UCS_XT1_HIGH_FREQUENCY == highOrLowFrequency )
520  );
521 
522  assert(timeout > 0);
523 
524  //Enable HF/LF mode
525  HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XTS;
526  HWREG16(UCS_BASE + OFS_UCSCTL6) |= highOrLowFrequency;
527 
528  //Switch OFF XT1 oscillator and enable bypass
529  HWREG16(UCS_BASE + OFS_UCSCTL6) |= (XT1BYPASS + XT1OFF);
530 
531  if (UCS_XT1_LOW_FREQUENCY == highOrLowFrequency){
532  do {
533  //Clear OSC flaut Flags fault flags
534  HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT1LFOFFG);
535 
536  // Clear the global fault flag. In case the XT1 caused the global fault
537  // flag to get set this will clear the global error condition. If any
538  // error condition persists, global flag will get again.
539  HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
540  }while ((HWREG8(UCS_BASE + OFS_UCSCTL7) & (XT1LFOFFG)) && --timeout);
541 
542  } else {
543  do {
544  //Clear OSC flaut Flags fault flags
545  HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT1HFOFFG);
546 
547  //Clear the global fault flag. In case the XT1 caused the global fault
548  //flag to get set this will clear the global error condition. If any
549  //error condition persists, global flag will get again.
550  HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
551  }while ((HWREG8(UCS_BASE + OFS_UCSCTL7) & (XT1HFOFFG))&& --timeout);
552  }
553 
554  if (timeout){
555  return (STATUS_SUCCESS);
556  } else {
557  return (STATUS_FAIL);
558  }
559 }
560 
561 void UCS_turnOffXT1 (void)
562 {
563  //Switch off XT1 oscillator
564  HWREG16(UCS_BASE + OFS_UCSCTL6) |= XT1OFF;
565 }
566 
567 void UCS_turnOnXT2 (uint16_t xt2drive
568  )
569 {
570 #if NOT_CC430_DEVICE
571 
572  //Check if drive value is the expected one
573  if ((HWREG16(UCS_BASE + OFS_UCSCTL6) & XT2DRIVE_3) != xt2drive){
574  //Clear XT2drive field
575  HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XT2DRIVE_3;
576 
577  //Set requested value
578  HWREG16(UCS_BASE + OFS_UCSCTL6) |= xt2drive;
579  }
580 
581  HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XT2BYPASS;
582 #endif
583 
584  //Enable XT2 and Switch on XT2 oscillator
585  HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XT2OFF;
586 
587  while (HWREG8(UCS_BASE + OFS_UCSCTL7) & XT2OFFG){
588  //Clear OSC flaut Flags
589  HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT2OFFG);
590 
591 #if CC430_DEVICE
592  // CC430 uses a different fault mechanism. It requires 3 VLO clock
593  // cycles delay.If 20MHz CPU, 5000 clock cycles are required in worst
594  // case.
595  __delay_cycles(5000);
596 #endif
597 
598  //Clear OFIFG fault flag
599  HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
600  }
601 }
602 
603 void UCS_bypassXT2 (void)
604 {
605  //Switch on XT2 oscillator
606 #if NOT_CC430_DEVICE
607  HWREG16(UCS_BASE + OFS_UCSCTL6) |= XT2BYPASS;
608 #endif
609  HWREG16(UCS_BASE + OFS_UCSCTL6) |= XT2OFF;
610 
611  while (HWREG8(UCS_BASE + OFS_UCSCTL7) & XT2OFFG){
612  //Clear OSC flaut Flags
613  HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT2OFFG);
614 
615 #if CC430_DEVICE
616  // CC430 uses a different fault mechanism. It requires 3 VLO clock
617  // cycles delay.If 20MHz CPU, 5000 clock cycles are required in worst
618  // case.
619  __delay_cycles(5000);
620 #endif
621 
622  //Clear OFIFG fault flag
623  HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
624  }
625 }
626 
627 bool UCS_turnOnXT2WithTimeout (uint16_t xt2drive,
628  uint16_t timeout
629  )
630 {
631  assert(timeout > 0);
632 
633 #if NOT_CC430_DEVICE
634  //Check if drive value is the expected one
635  if ((HWREG16(UCS_BASE + OFS_UCSCTL6) & XT2DRIVE_3) != xt2drive){
636  //Clear XT2drive field
637  HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XT2DRIVE_3;
638 
639  //Set requested value
640  HWREG16(UCS_BASE + OFS_UCSCTL6) |= xt2drive;
641  }
642 
643  HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XT2BYPASS;
644 #endif
645 
646  //Switch on XT2 oscillator
647  HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~XT2OFF;
648 
649  do{
650  //Clear OSC flaut Flags
651  HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT2OFFG);
652 
653 #if CC430_DEVICE
654  // CC430 uses a different fault mechanism. It requires 3 VLO clock
655  // cycles delay.If 20MHz CPU, 5000 clock cycles are required in worst
656  // case.
657  __delay_cycles(5000);
658 #endif
659 
660  //Clear OFIFG fault flag
661  HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
662  }while ((HWREG8(UCS_BASE + OFS_UCSCTL7) & XT2OFFG) && --timeout);
663 
664  if (timeout){
665  return (STATUS_SUCCESS);
666  } else {
667  return (STATUS_FAIL);
668  }
669 }
670 
671 bool UCS_bypassXT2WithTimeout (uint16_t timeout
672  )
673 {
674  assert(timeout > 0);
675 
676  //Switch off XT2 oscillator and enable BYPASS mode
677 #if NOT_CC430_DEVICE
678  HWREG16(UCS_BASE + OFS_UCSCTL6) |= XT2BYPASS;
679 #endif
680  HWREG16(UCS_BASE + OFS_UCSCTL6) |= XT2OFF;
681 
682  do{
683  //Clear OSC flaut Flags
684  HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(XT2OFFG);
685 
686 #if CC430_DEVICE
687  // CC430 uses a different fault mechanism. It requires 3 VLO clock
688  // cycles delay.If 20MHz CPU, 5000 clock cycles are required in worst
689  // case.
690  __delay_cycles(5000);
691 #endif
692 
693  //Clear OFIFG fault flag
694  HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
695  }while ((HWREG8(UCS_BASE + OFS_UCSCTL7) & XT2OFFG) && --timeout);
696 
697  if (timeout){
698  return (STATUS_SUCCESS);
699  } else {
700  return (STATUS_FAIL);
701  }
702 }
703 
704 void UCS_turnOffXT2 (void)
705 {
706  //Switch off XT2 oscillator
707  HWREG16(UCS_BASE + OFS_UCSCTL6) |= XT2OFF;
708 }
709 
710 void UCS_initFLLSettle (uint16_t fsystem,
711  uint16_t ratio
712  )
713 {
714  volatile uint16_t x = ratio * 32;
715 
716  UCS_initFLL(fsystem, ratio);
717 
718  while (x--)
719  {
720  __delay_cycles(30);
721  }
722 }
723 
724 void UCS_initFLL (uint16_t fsystem,
725  uint16_t ratio
726  )
727 {
728  uint16_t d, dco_div_bits;
729  uint16_t mode = 0;
730 
731  //Save actual state of FLL loop control, then disable it. This is needed to
732  //prevent the FLL from acting as we are making fundamental modifications to
733  //the clock setup.
734  uint16_t srRegisterState = __get_SR_register() & SCG0;
735 
736  d = ratio;
737  //Have at least a divider of 2
738  dco_div_bits = FLLD__2;
739 
740  if (fsystem > 16000){
741  d >>= 1 ;
742  mode = 1;
743  } else {
744  //fsystem = fsystem * 2
745  fsystem <<= 1;
746  }
747 
748  while (d > 512)
749  {
750  //Set next higher div level
751  dco_div_bits = dco_div_bits + FLLD0;
752  d >>= 1;
753  }
754 
755  // Disable FLL
756  __bis_SR_register(SCG0);
757 
758  //Set DCO to lowest Tap
759  HWREG8(UCS_BASE + OFS_UCSCTL0_H) = 0x0000;
760 
761  //Reset FN bits
762  HWREG16(UCS_BASE + OFS_UCSCTL2) &= ~(0x03FF);
763  HWREG16(UCS_BASE + OFS_UCSCTL2) = dco_div_bits | (d - 1);
764 
765  if (fsystem <= 630){ //fsystem < 0.63MHz
766  HWREG8(UCS_BASE + OFS_UCSCTL1) = DCORSEL_0;
767  } else if (fsystem < 1250){ //0.63MHz < fsystem < 1.25MHz
768  HWREG8(UCS_BASE + OFS_UCSCTL1) = DCORSEL_1;
769  } else if (fsystem < 2500){ //1.25MHz < fsystem < 2.5MHz
770  HWREG8(UCS_BASE + OFS_UCSCTL1) = DCORSEL_2;
771  } else if (fsystem < 5000){ //2.5MHz < fsystem < 5MHz
772  HWREG8(UCS_BASE + OFS_UCSCTL1) = DCORSEL_3;
773  } else if (fsystem < 10000){ //5MHz < fsystem < 10MHz
774  HWREG8(UCS_BASE + OFS_UCSCTL1) = DCORSEL_4;
775  } else if (fsystem < 20000){ //10MHz < fsystem < 20MHz
776  HWREG8(UCS_BASE + OFS_UCSCTL1) = DCORSEL_5;
777  } else if (fsystem < 40000){ //20MHz < fsystem < 40MHz
778  HWREG8(UCS_BASE + OFS_UCSCTL1) = DCORSEL_6;
779  } else {
780  HWREG8(UCS_BASE + OFS_UCSCTL1) = DCORSEL_7;
781  }
782 
783  // Re-enable FLL
784  __bic_SR_register(SCG0);
785 
786  while (HWREG8(UCS_BASE + OFS_UCSCTL7_L) & DCOFFG)
787  {
788  //Clear OSC flaut Flags
789  HWREG8(UCS_BASE + OFS_UCSCTL7_L) &= ~(DCOFFG);
790 
791  //Clear OFIFG fault flag
792  HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
793  }
794 
795  // Restore previous SCG0
796  __bis_SR_register(srRegisterState);
797 
798  if (mode == 1){
799  //fsystem > 16000
800  //Select DCOCLK
801  HWREG16(UCS_BASE + OFS_UCSCTL4) &= ~(SELM_7 + SELS_7);
802  HWREG16(UCS_BASE + OFS_UCSCTL4) |= SELM__DCOCLK + SELS__DCOCLK;
803  } else {
804  //Select DCODIVCLK
805  HWREG16(UCS_BASE + OFS_UCSCTL4) &= ~(SELM_7 + SELS_7);
806  HWREG16(UCS_BASE + OFS_UCSCTL4) |= SELM__DCOCLKDIV + SELS__DCOCLKDIV;
807  }
808 
809 }
810 
811 void UCS_enableClockRequest (uint8_t selectClock
812  )
813 {
814  HWREG8(UCS_BASE + OFS_UCSCTL8) |= selectClock;
815 }
816 
817 void UCS_disableClockRequest (uint8_t selectClock
818  )
819 {
820  HWREG8(UCS_BASE + OFS_UCSCTL8) &= ~selectClock;
821 }
822 
823 uint8_t UCS_getFaultFlagStatus (uint8_t mask
824  )
825 {
826  assert(mask <= UCS_XT2OFFG );
827  return (HWREG8(UCS_BASE + OFS_UCSCTL7) & mask);
828 }
829 
830 void UCS_clearFaultFlag (uint8_t mask
831  )
832 {
833  assert(mask <= UCS_XT2OFFG );
834  HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~mask;
835 }
836 
837 void UCS_turnOffSMCLK (void)
838 {
839  HWREG16(UCS_BASE + OFS_UCSCTL6) |= SMCLKOFF;
840 }
841 
842 void UCS_turnOnSMCLK (void)
843 {
844  HWREG16(UCS_BASE + OFS_UCSCTL6) &= ~SMCLKOFF;
845 }
846 
847 uint32_t UCS_getACLK (void)
848 {
849  //Find ACLK source
850  uint16_t ACLKSource = (HWREG16(UCS_BASE + OFS_UCSCTL4) & SELA_7);
851 
852  ACLKSource = ACLKSource >> 8;
853 
854  uint16_t ACLKSourceDivider = HWREG16(UCS_BASE + OFS_UCSCTL5) & DIVA_7;
855  ACLKSourceDivider = ACLKSourceDivider >> 8;
856 
857  return (privateUCSComputeCLKFrequency(
858  ACLKSource,
859  ACLKSourceDivider
860  ));
861 }
862 
863 uint32_t UCS_getSMCLK (void)
864 {
865  uint16_t SMCLKSource = HWREG8(UCS_BASE + OFS_UCSCTL4_L) & SELS_7;
866 
867  SMCLKSource = SMCLKSource >> 4;
868 
869  uint16_t SMCLKSourceDivider =
870  HWREG16(UCS_BASE + OFS_UCSCTL5) & DIVS_7;
871  SMCLKSourceDivider = SMCLKSourceDivider >> 4;
872 
873  return (privateUCSComputeCLKFrequency(
874  SMCLKSource,
875  SMCLKSourceDivider )
876  );
877 }
878 
879 uint32_t UCS_getMCLK (void)
880 {
881  //Find AMCLK source
882  uint16_t MCLKSource = (HWREG16(UCS_BASE + OFS_UCSCTL4) & SELM_7);
883 
884  uint16_t MCLKSourceDivider = HWREG16(UCS_BASE + OFS_UCSCTL5) & DIVM_7;
885 
886  return (privateUCSComputeCLKFrequency(
887  MCLKSource,
888  MCLKSourceDivider )
889  );
890 }
891 
892 uint16_t UCS_clearAllOscFlagsWithTimeout(uint16_t timeout
893  )
894 {
895  assert(timeout > 0);
896 
897  do {
898  // Clear all osc fault flags
899  HWREG8(UCS_BASE + OFS_UCSCTL7) &= ~(DCOFFG +
900  XT1LFOFFG +
901  XT1HFOFFG +
902  XT2OFFG
903  );
904 
905 #if CC430_DEVICE
906  // CC430 uses a different fault mechanism. It requires 3 VLO clock
907  // cycles delay.If 20MHz CPU, 5000 clock cycles are required in worst
908  // case.
909  __delay_cycles(5000);
910 #endif
911 
912  // Clear the global osc fault flag.
913  HWREG8(SFR_BASE + OFS_SFRIFG1) &= ~OFIFG;
914 
915  // Check XT1 fault flags
916  } while ((HWREG8(SFR_BASE + OFS_SFRIFG1) & OFIFG) && --timeout);
917 
918  return (HWREG8(UCS_BASE + OFS_UCSCTL7) & (DCOFFG +
919  XT1LFOFFG +
920  XT1HFOFFG +
921  XT2OFFG)
922  );
923 }
924 
925 #endif
926 //*****************************************************************************
927 //
930 //
931 //*****************************************************************************
long temp
#define HWREG8(x)
Definition: hw_memmap.h:41
#define HWREG16(x)
Definition: hw_memmap.h:39
#define STATUS_FAIL
Definition: hw_memmap.h:23
#define STATUS_SUCCESS
Definition: hw_memmap.h:22
__delay_cycles(500000)