@@ -272,146 +272,49 @@ void init()
272
272
// this needs to be called before setup() or some functions won't
273
273
// work there
274
274
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
-
339
275
/******************************** CLOCK STUFF *********************************/
340
276
277
+ /* We assume 5V operating frequency and FUSE.OSCCFG -> 16MHz */
278
+
341
279
int64_t cpu_freq ;
342
280
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
+
412
314
413
315
#if (PERFORM_SIGROW_CORRECTION_F_CPU == 1 )
414
316
/* Calculate actual F_CPU with error values from signature row */
317
+ uint8_t sigrow_val = SIGROW .OSC16ERR5V ;
415
318
cpu_freq *= (1024 + sigrow_val );
416
319
cpu_freq /= 1024 ;
417
320
#endif /* (CORRECT_F_CPU == 1) */
0 commit comments