@@ -272,146 +272,49 @@ void init()
272272 // this needs to be called before setup() or some functions won't
273273 // work there
274274
275- /*************************** GET VCC & FUSE SETTING ***************************/
276-
277-
278- /* Measure VDD using ADC */
279- uint8_t supply_voltage ;
280-
281- /* Initialize AC reference (what we are measuring) - 1.5V known */
282- VREF .CTRLA |= VREF_AC0REFSEL_1V5_gc ;
283-
284- /* Enable AC reference */
285- VREF .CTRLB |= VREF_AC0REFEN_bm ;
286-
287- /* DAC to max -- output reference voltage */
288- AC0 .DACREF = 0xFF ;
289-
290- /* Enable DAC REF by selecting it as input and enabling AC */
291- AC0 .MUXCTRLA |= AC_MUXNEG_DACREF_gc ;
292- AC0 .CTRLA |= ADC_ENABLE_bm ;
293-
294- /* Initialize ADC reference (VDD) */
295- ADC0 .CTRLC = ADC_REFSEL_VDDREF_gc ;
296-
297- /* Initialize MUX (DAC/AC reference from VREF) */
298- ADC0 .MUXPOS = ADC_MUXPOS_DACREF_gc ;
299-
300- /* Enable ADC */
301- ADC0 .CTRLA |= ADC_ENABLE_bm ;
302-
303- /* Start a conversion */
304- ADC0 .COMMAND |= ADC_STCONV_bm ;
305-
306- /* Wait until result is ready */
307- while (!(ADC0 .INTFLAGS & ADC_RESRDY_bm ));
308-
309- /* Result ready */
310- /* supply_voltage = (VIN * 1024)/result where VIN = 1.5V from VREF */
311- uint16_t adc_result = ADC0 .RES ;
312-
313- uint16_t voltage = (15 * 1024 ) / adc_result ; /* using 1.5 << 1 to avoid using float */
314-
315- /* Only for the purposes of staying within safe operating range -- approximate */
316- if (voltage >= 48 ){ /* 4.8V+ -> 5V */
317- supply_voltage = VCC_5V0 ;
318- } else if (voltage >= 30 ){ /* 3V-4V7 -> 3V3 */
319- supply_voltage = VCC_3V3 ;
320- } else { /* < 3V -> 1V8 */
321- supply_voltage = VCC_1V8 ;
322- }
323-
324- /* Fuse setting for 16/20MHz oscillator */
325- uint8_t fuse_setting = FUSE .OSCCFG & FUSE_FREQSEL_gm ;
326-
327- /* Deinitialize ADC, AC & VREF */
328- ADC0 .CTRLA = 0x00 ;
329- ADC0 .MUXPOS = 0x00 ;
330- ADC0 .CTRLC = 0x00 ;
331-
332- AC0 .CTRLA = 0x00 ;
333- AC0 .MUXCTRLA = 0x00 ;
334- AC0 .DACREF = 0xFF ;
335-
336- VREF .CTRLB = 0x00 ;
337- VREF .CTRLA = 0x00 ;
338-
339275/******************************** CLOCK STUFF *********************************/
340276
277+ /* We assume 5V operating frequency and FUSE.OSCCFG -> 16MHz */
278+
341279 int64_t cpu_freq ;
342280
343- #if (PERFORM_SIGROW_CORRECTION_F_CPU == 1 )
344- int8_t sigrow_val = 0 ;
345- #endif
346-
347- /* Initialize clock divider to stay within safe operating area */
348-
349- if (supply_voltage >= VCC_5V0 ){
350-
351- /* Disable system clock prescaler - F_CPU should now be ~16/20MHz */
352- _PROTECTED_WRITE (CLKCTRL_MCLKCTRLB , 0x00 );
353-
354- /* Assign cpu_freq value and sigrow_val depending on fuse setting */
355- if (fuse_setting == FREQSEL_20MHZ_gc ){
356- cpu_freq = 20000000 ;
357-
358- #if (PERFORM_SIGROW_CORRECTION_F_CPU == 1 )
359- sigrow_val = SIGROW .OSC20ERR5V ;
360- #endif
361-
362- } else { /* fuse_setting == FREQSEL_16MHZ_gc */
363- cpu_freq = 16000000 ;
364-
365- #if (PERFORM_SIGROW_CORRECTION_F_CPU == 1 )
366- sigrow_val = SIGROW .OSC16ERR5V ;
367- #endif
368-
369- }
370-
371- } else if (supply_voltage == VCC_3V3 ) {
372-
373- /* Enable system clock prescaler to DIV2 - F_CPU should now be ~8/10MHz */
374- _PROTECTED_WRITE (CLKCTRL_MCLKCTRLB , (CLKCTRL_PEN_bm | CLKCTRL_PDIV_2X_gc ));
375-
376- /* Assign cpu_freq value and sigrow_val depending on fuse setting */
377- if (fuse_setting == FREQSEL_20MHZ_gc ){
378- cpu_freq = 10000000 ;
379-
380- #if (PERFORM_SIGROW_CORRECTION_F_CPU == 1 )
381- sigrow_val = SIGROW .OSC20ERR3V ;
382- #endif
383-
384- } else { /* fuse_setting == FREQSEL_16MHZ_gc */
385- cpu_freq = 8000000 ;
386-
387- #if (PERFORM_SIGROW_CORRECTION_F_CPU == 1 )
388- sigrow_val = SIGROW .OSC16ERR3V ;
389- #endif
390- }
391-
392- } else {
393- /* Shouldn't get here but just in case... */
394-
395- /* Enable system clock prescaler to DIV4 - F_CPU should now be ~4/5MHz */
396- _PROTECTED_WRITE (CLKCTRL_MCLKCTRLB , (CLKCTRL_PEN_bm | CLKCTRL_PDIV_4X_gc ));
397-
398-
399- if (fuse_setting == FREQSEL_20MHZ_gc ){
400- cpu_freq = 5000000 ;
401- #if (PERFORM_SIGROW_CORRECTION_F_CPU == 1 )
402- sigrow_val = SIGROW .OSC20ERR3V ;
403- #endif
404-
405- } else { /* fuse_setting == FREQSEL_16MHZ_gc */
406- cpu_freq = 4000000 ;
407- #if (PERFORM_SIGROW_CORRECTION_F_CPU == 1 )
408- sigrow_val = SIGROW .OSC16ERR3V ;
409- #endif
410- }
411- }
281+ #if (F_CPU == 16000000 )
282+ cpu_freq = 16000000 ;
283+
284+ /* No division on clock */
285+ _PROTECTED_WRITE (CLKCTRL_MCLKCTRLB , 0x00 );
286+
287+ #elif (F_CPU == 8000000 )
288+ cpu_freq = 8000000 ;
289+
290+ /* Clock DIV2 */
291+ _PROTECTED_WRITE (CLKCTRL_MCLKCTRLB , (CLKCTRL_PEN_bm | CLKCTRL_PDIV_2X_gc ));
292+
293+ #elif (F_CPU == 4000000 )
294+ cpu_freq = 4000000 ;
295+
296+ /* Clock DIV4 */
297+ _PROTECTED_WRITE (CLKCTRL_MCLKCTRLB , (CLKCTRL_PEN_bm | CLKCTRL_PDIV_4X_gc ))
298+
299+ #elif (F_CPU == 2000000 )
300+ cpu_freq = 2000000 ;
301+
302+ /* Clock DIV8 */
303+ _PROTECTED_WRITE (CLKCTRL_MCLKCTRLB , (CLKCTRL_PEN_bm | CLKCTRL_PDIV_8X_gc ))
304+ #else
305+ # warning "F_CPU not defined OR defined as an invalid value"
306+
307+ //#define F_CPU 16000000
308+ cpu_freq = 16000000 ;
309+
310+ /* No division on clock */
311+ _PROTECTED_WRITE (CLKCTRL_MCLKCTRLB , 0x00 );
312+ #endif
313+
412314
413315 #if (PERFORM_SIGROW_CORRECTION_F_CPU == 1 )
414316 /* Calculate actual F_CPU with error values from signature row */
317+ uint8_t sigrow_val = SIGROW .OSC16ERR5V ;
415318 cpu_freq *= (1024 + sigrow_val );
416319 cpu_freq /= 1024 ;
417320 #endif /* (CORRECT_F_CPU == 1) */
0 commit comments