Hanna
Sourcecode Batteriemanagementsystem
sysclk.c
gehe zur Dokumentation dieser Datei
1 
43 /*
44  * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
45  */
46 
47 #include <compiler.h>
48 
49 #include <sysclk.h>
50 #include <osc.h>
51 #include <pll.h>
52 
53 #if XMEGA_AU || XMEGA_B || XMEGA_C
54 //# include <nvm.h>
55 #endif
56 
57 
58 void sysclk_init(void)
59 {
60  uint8_t *reg = (uint8_t *)&PR.PRGEN;
61  uint8_t i;
62 #ifdef CONFIG_OSC_RC32_CAL
63  uint16_t cal;
64  /* avoid Cppcheck Warning */
65 // UNUSED(cal);
66  (void)(cal);
67 #endif
68  bool need_rc2mhz = false;
69 
70  /* Turn off all peripheral clocks that can be turned off. */
71  for (i = 0; i <= SYSCLK_PORT_F; i++) {
72  *(reg++) = 0xff;
73  }
74 
75  /* Set up system clock prescalers if different from defaults */
76  if ((CONFIG_SYSCLK_PSADIV != SYSCLK_PSADIV_1)
77  || (CONFIG_SYSCLK_PSBCDIV != SYSCLK_PSBCDIV_1_1)) {
78  sysclk_set_prescalers(CONFIG_SYSCLK_PSADIV,
79  CONFIG_SYSCLK_PSBCDIV);
80  }
81 #if (CONFIG_OSC_RC32_CAL==48000000UL)
82  NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc;
83  MSB(cal) = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBRCOSC));
84  LSB(cal) = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBRCOSCA));
85  NVM.CMD = NVM_CMD_NO_OPERATION_gc;
86 
87 /*
88  MSB(cal) = nvm_read_production_signature_row(
89  nvm_get_production_signature_row_offset(USBRCOSC));
90  LSB(cal) = nvm_read_production_signature_row(
91  nvm_get_production_signature_row_offset(USBRCOSCA));
92 */
93 
94 /*
95  * If a device has an uncalibrated value in the
96  * production signature row (early sample part), load a
97  * sane default calibration value.
98 */
99  if (cal == 0xFFFF) {
100  cal = 0x2340;
101  }
103 #endif
104  /*
105  * Switch to the selected initial system clock source, unless
106  * the default internal 2 MHz oscillator is selected.
107  */
108  if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_RC2MHZ) {
109  need_rc2mhz = true;
110  } else {
111  switch (CONFIG_SYSCLK_SOURCE) {
112  case SYSCLK_SRC_RC32MHZ:
113  osc_enable(OSC_ID_RC32MHZ);
114  osc_wait_ready(OSC_ID_RC32MHZ);
115 #ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC
116  if (CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC
117  != OSC_ID_USBSOF) {
118  osc_enable(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC);
119  osc_wait_ready(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC);
120  }
122  CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC);
123 #endif
124  break;
125 
126  case SYSCLK_SRC_RC32KHZ:
127  osc_enable(OSC_ID_RC32KHZ);
128  osc_wait_ready(OSC_ID_RC32KHZ);
129  break;
130 
131  case SYSCLK_SRC_XOSC:
132  osc_enable(OSC_ID_XOSC);
133  osc_wait_ready(OSC_ID_XOSC);
134  break;
135 
136 #ifdef CONFIG_PLL0_SOURCE
137  case SYSCLK_SRC_PLL:
138  if (CONFIG_PLL0_SOURCE == PLL_SRC_RC2MHZ) {
139  need_rc2mhz = true;
140  }
141  pll_enable_config_defaults(0);
142  break;
143 #endif
144 #if XMEGA_E
145  case SYSCLK_SRC_RC8MHZ:
146  osc_enable(OSC_ID_RC8MHZ);
147  osc_wait_ready(OSC_ID_RC8MHZ);
148  break;
149 #endif
150  default:
151  //unhandled_case(CONFIG_SYSCLK_SOURCE);
152  return;
153  }
154 
155  CCP = CCP_IOREG_gc;
156  CLK.CTRL = CONFIG_SYSCLK_SOURCE;
157  Assert(CLK.CTRL == CONFIG_SYSCLK_SOURCE);
158  }
159 
160  if (need_rc2mhz) {
161 #ifdef CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC
162  osc_enable(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC);
163  osc_wait_ready(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC);
165  CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC);
166 #endif
167  } else {
168  osc_disable(OSC_ID_RC2MHZ);
169  }
170 
171 #ifdef CONFIG_RTC_SOURCE
172  sysclk_rtcsrc_enable(CONFIG_RTC_SOURCE);
173 #endif
174 }
175 
176 void sysclk_enable_module(enum sysclk_port_id port, uint8_t id)
177 {
178  irqflags_t flags = cpu_irq_save();
179 
180  *((uint8_t *)&PR.PRGEN + port) &= ~id;
181 
182  cpu_irq_restore(flags);
183 }
184 
185 void sysclk_disable_module(enum sysclk_port_id port, uint8_t id)
186 {
187  irqflags_t flags = cpu_irq_save();
188 
189  *((uint8_t *)&PR.PRGEN + port) |= id;
190 
191  cpu_irq_restore(flags);
192 }
193 
194 #if XMEGA_AU || XMEGA_B || XMEGA_C || defined(__DOXYGEN__)
195 
205 void sysclk_enable_usb(uint8_t frequency)
206 {
207  uint8_t prescaler;
208 
209  Assert((frequency == 6) || (frequency == 48));
210 
211  /*
212  * Enable or disable prescaler depending on if the USB frequency is 6
213  * MHz or 48 MHz. Only 6 MHz USB frequency requires prescaling.
214  */
215  if (frequency == 6) {
216  prescaler = CLK_USBPSDIV_8_gc;
217  }
218  else {
219  prescaler = 0;
220  }
221 
222  /*
223  * Switch to the system clock selected by the user.
224  */
225  switch (CONFIG_USBCLK_SOURCE) {
226  case USBCLK_SRC_RCOSC:
227  if (!osc_is_ready(OSC_ID_RC32MHZ)) {
228  osc_enable(OSC_ID_RC32MHZ);
229  osc_wait_ready(OSC_ID_RC32MHZ);
230 #ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC
231  if (CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC
232  != OSC_ID_USBSOF) {
233  osc_enable(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC);
234  osc_wait_ready(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC);
235  }
237  CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC);
238 #endif
239  }
240  CCP = CCP_IOREG_gc;
241  CLK.USBCTRL = ((prescaler) | CLK_USBSRC_RC32M_gc | CLK_USBSEN_bm);
242 
243  break;
244 
245 #ifdef CONFIG_PLL0_SOURCE
246  case USBCLK_SRC_PLL:
247  pll_enable_config_defaults(0);
248  ccp_write_io((uint8_t *)&CLK.USBCTRL, (prescaler)
249  | CLK_USBSRC_PLL_gc
250  | CLK_USBSEN_bm);
251  break;
252 #endif
253 
254  default:
255  Assert(false);
256  break;
257  }
258 
260 }
261 
265 void sysclk_disable_usb(void)
266 {
268  CCP = CCP_IOREG_gc;
269  CLK.USBCTRL = 0;
270 }
271 #endif // XMEGA_AU || XMEGA_B || XMEGA_C
#define OSC_ID_RC32MHZ
32 MHz Internal RC Oscillator
Definition: osc.h:66
void sysclk_disable_module(enum sysclk_port_id port, uint8_t id)
Disable the clock to peripheral id on port port.
Definition: sysclk.c:185
#define SYSCLK_SRC_XOSC
External oscillator.
Definition: sysclk.h:92
Commonly used includes, types and macros.
#define Assert(expr)
This macro is used to test fatal errors.
Definition: compiler.h:46
#define SYSCLK_USB
USB Module.
Definition: sysclk.h:146
#define CONFIG_USBCLK_SOURCE
Definition: conf_clock.h:16
Chip-specific PLL management functions.
#define OSC_ID_RC2MHZ
2 MHz Internal RC Oscillator
Definition: osc.h:64
sysclk_port_id
Definition: sysclk.h:125
#define OSC_ID_XOSC
External Oscillator.
Definition: osc.h:70
static void osc_enable_autocalibration(uint8_t id, uint8_t ref_id)
Enable DFLL-based automatic calibration of an internal oscillator.
Definition: osc.h:325
static void osc_user_calibration(uint8_t id, uint16_t calib)
Load a specific calibration value for the specified oscillator.
Definition: osc.h:446
#define SYSCLK_PSADIV_1
Do not prescale.
Definition: sysclk.h:99
static void sysclk_rtcsrc_enable(uint8_t id)
Enable RTC clock with specified clock source.
Definition: sysclk.h:1236
#define SYSCLK_SRC_RC32KHZ
Internal 32 KHz RC oscillator.
Definition: sysclk.h:90
2 MHz Internal RC Oscillator
Definition: pll.h:63
Chip-specific oscillator management functions.
#define OSC_ID_RC32KHZ
32 KHz Internal RC Oscillator
Definition: osc.h:68
Devices not associated with a specific port.
Definition: sysclk.h:126
#define SYSCLK_SRC_RC2MHZ
Internal 2 MHz RC oscillator.
Definition: sysclk.h:86
#define OSC_ID_USBSOF
Reference from USB Start Of Frame.
Definition: osc.h:81
#define SYSCLK_PSBCDIV_1_1
Do not prescale.
Definition: sysclk.h:115
#define SYSCLK_SRC_RC32MHZ
Internal 32 MHz RC oscillator.
Definition: sysclk.h:88
void sysclk_enable_module(enum sysclk_port_id port, uint8_t id)
Enable the clock to peripheral id on port port.
Definition: sysclk.c:176
Chip-specific system clock management functions.
#define SYSCLK_SRC_PLL
Phase-Locked Loop.
Definition: sysclk.h:94
Devices on PORTF.
Definition: sysclk.h:132
static void sysclk_set_prescalers(uint8_t psadiv, uint8_t psbcdiv)
Set system clock prescaler configuration.
Definition: sysclk.h:1192