Skip to content

Commit 431b0b6

Browse files
Roy, ElizabethRoy, Elizabeth
authored andcommitted
Changed approach to F_CPU to be user-defined
1 parent 9420621 commit 431b0b6

File tree

1 file changed

+36
-133
lines changed

1 file changed

+36
-133
lines changed

cores/arduino/wiring.c

Lines changed: 36 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)