AVR1631 - Energy Meter Reference Design with ATxmega32A4  Rev 1.0
 All Data Structures Files Functions Variables Typedefs Macros
clksys_driver.c
Go to the documentation of this file.
1 /* This file has been prepared for Doxygen automatic documentation generation.*/
67 #include "clksys_driver.h"
68 
77 void CCPWrite( volatile uint8_t * address, uint8_t value )
78 {
79 #ifdef __ICCAVR__
80 
81  // Store global interrupt setting in scratch register and disable interrupts.
82  asm("in R1, 0x3F \n"
83  "cli"
84  );
85 
86  // Move destination address pointer to Z pointer registers.
87  asm("movw r30, r16");
88 #ifdef RAMPZ
89  asm("ldi R16, 0 \n"
90  "out 0x3B, R16"
91  );
92 
93 #endif
94  asm("ldi r16, 0xD8 \n"
95  "out 0x34, r16 \n"
96 #if (__MEMORY_MODEL__ == 1)
97  "st Z, r17 \n");
98 #elif (__MEMORY_MODEL__ == 2)
99  "st Z, r18 \n");
100 #else /* (__MEMORY_MODEL__ == 3) || (__MEMORY_MODEL__ == 5) */
101  "st Z, r19 \n");
102 #endif /* __MEMORY_MODEL__ */
103 
104  // Restore global interrupt setting from scratch register.
105  asm("out 0x3F, R1");
106 
107 #elif defined __GNUC__
109  volatile uint8_t * tmpAddr = address;
110 #ifdef RAMPZ
111  RAMPZ = 0;
112 #endif
113  asm volatile(
114  "movw r30, %0" "\n\t"
115  "ldi r16, %2" "\n\t"
116  "out %3, r16" "\n\t"
117  "st Z, %1" "\n\t"
118  :
119  : "r" (tmpAddr), "r" (value), "M" (CCP_IOREG_gc), "i" (&CCP)
120  : "r16", "r30", "r31"
121  );
122 
124 #endif
125 }
126 
141 void CLKSYS_XOSC_Config( OSC_FRQRANGE_t freqRange,
142  bool lowPower32kHz,
143  OSC_XOSCSEL_t xoscModeSelection )
144 {
145  OSC.XOSCCTRL = (uint8_t) freqRange |
146  ( lowPower32kHz ? OSC_X32KLPM_bm : 0 ) |
147  xoscModeSelection;
148 }
149 
150 
167 void CLKSYS_PLL_Config( OSC_PLLSRC_t clockSource, uint8_t factor )
168 {
169  factor &= OSC_PLLFAC_gm;
170  OSC.PLLCTRL = (uint8_t) clockSource | ( factor << OSC_PLLFAC_gp );
171 }
172 
173 
187 uint8_t CLKSYS_Disable( uint8_t oscSel )
188 {
189  OSC.CTRL &= ~oscSel;
190  uint8_t clkEnabled = OSC.CTRL & oscSel;
191  return clkEnabled;
192 }
193 
194 
206 void CLKSYS_Prescalers_Config( CLK_PSADIV_t PSAfactor,
207  CLK_PSBCDIV_t PSBCfactor )
208 {
209  uint8_t PSconfig = (uint8_t) PSAfactor | PSBCfactor;
210  CCPWrite( &CLK.PSCTRL, PSconfig );
211 }
212 
213 
225 uint8_t CLKSYS_Main_ClockSource_Select( CLK_SCLKSEL_t clockSource )
226 {
227  uint8_t clkCtrl = ( CLK.CTRL & ~CLK_SCLKSEL_gm ) | clockSource;
228  CCPWrite( &CLK.CTRL, clkCtrl );
229  clkCtrl = ( CLK.CTRL & clockSource );
230  return clkCtrl;
231 }
232 
233 
241 void CLKSYS_RTC_ClockSource_Enable( CLK_RTCSRC_t clockSource )
242 {
243  CLK.RTCCTRL = ( CLK.RTCCTRL & ~CLK_RTCSRC_gm ) |
244  clockSource |
245  CLK_RTCEN_bm;
246 }
247 
248 
260 void CLKSYS_AutoCalibration_Enable( uint8_t clkSource, bool extReference )
261 {
262  OSC.DFLLCTRL = ( OSC.DFLLCTRL & ~clkSource ) |
263  ( extReference ? clkSource : 0 );
264  if (clkSource == OSC_RC2MCREF_bm) {
265  DFLLRC2M.CTRL |= DFLL_ENABLE_bm;
266  } else if (clkSource == OSC_RC32MCREF_gm) {
267  DFLLRC32M.CTRL |= DFLL_ENABLE_bm;
268  }
269 }
270 
271 
281 {
282  CCPWrite( &OSC.XOSCFAIL, ( OSC_XOSCFDIF_bm | OSC_XOSCFDEN_bm ) );
283 }
284 
285 
293 {
294  CCPWrite( &CLK.LOCK, CLK_LOCK_bm );
295 }
296