Skip to content

Commit fcab97e

Browse files
committed
Merge branch 'api-avr4809' of github.com:bcmi-labs/ArduinoCore-avr-api into api-avr4809
2 parents cd0e121 + 1c0717c commit fcab97e

File tree

1 file changed

+42
-133
lines changed

1 file changed

+42
-133
lines changed

cores/arduino/wiring.c

Lines changed: 42 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -273,146 +273,55 @@ void init()
273273
// this needs to be called before setup() or some functions won't
274274
// work there
275275

276-
/*************************** GET VCC & FUSE SETTING ***************************/
277-
278-
279-
/* Measure VDD using ADC */
280-
uint8_t supply_voltage;
281-
282-
/* Initialize AC reference (what we are measuring) - 1.5V known */
283-
VREF.CTRLA |= VREF_AC0REFSEL_1V5_gc;
284-
285-
/* Enable AC reference */
286-
VREF.CTRLB |= VREF_AC0REFEN_bm;
287-
288-
/* DAC to max -- output reference voltage */
289-
AC0.DACREF = 0xFF;
290-
291-
/* Enable DAC REF by selecting it as input and enabling AC */
292-
AC0.MUXCTRLA |= AC_MUXNEG_DACREF_gc;
293-
AC0.CTRLA |= ADC_ENABLE_bm;
294-
295-
/* Initialize ADC reference (VDD) */
296-
ADC0.CTRLC = ADC_REFSEL_VDDREF_gc;
297-
298-
/* Initialize MUX (DAC/AC reference from VREF) */
299-
ADC0.MUXPOS = ADC_MUXPOS_DACREF_gc;
300-
301-
/* Enable ADC */
302-
ADC0.CTRLA |= ADC_ENABLE_bm;
303-
304-
/* Start a conversion */
305-
ADC0.COMMAND |= ADC_STCONV_bm;
306-
307-
/* Wait until result is ready */
308-
while(!(ADC0.INTFLAGS & ADC_RESRDY_bm));
309-
310-
/* Result ready */
311-
/* supply_voltage = (VIN * 1024)/result where VIN = 1.5V from VREF */
312-
uint16_t adc_result = ADC0.RES;
313-
314-
uint16_t voltage = (15 * 1024) / adc_result; /* using 1.5 << 1 to avoid using float */
315-
316-
/* Only for the purposes of staying within safe operating range -- approximate */
317-
if(voltage >= 48){ /* 4.8V+ -> 5V */
318-
supply_voltage = VCC_5V0;
319-
} else if (voltage >= 30){ /* 3V-4V7 -> 3V3 */
320-
supply_voltage = VCC_3V3;
321-
} else { /* < 3V -> 1V8 */
322-
supply_voltage = VCC_1V8;
323-
}
324-
325-
/* Fuse setting for 16/20MHz oscillator */
326-
uint8_t fuse_setting = FUSE.OSCCFG & FUSE_FREQSEL_gm;
327-
328-
/* Deinitialize ADC, AC & VREF */
329-
ADC0.CTRLA = 0x00;
330-
ADC0.MUXPOS = 0x00;
331-
ADC0.CTRLC = 0x00;
332-
333-
AC0.CTRLA = 0x00;
334-
AC0.MUXCTRLA = 0x00;
335-
AC0.DACREF = 0xFF;
336-
337-
VREF.CTRLB = 0x00;
338-
VREF.CTRLA = 0x00;
339-
340276
/******************************** CLOCK STUFF *********************************/
341277

278+
/* We assume 5V operating frequency and FUSE.OSCCFG -> 16MHz */
279+
342280
int64_t cpu_freq;
343281

344-
#if (PERFORM_SIGROW_CORRECTION_F_CPU == 1)
345-
int8_t sigrow_val = 0;
346-
#endif
347-
348-
/* Initialize clock divider to stay within safe operating area */
349-
350-
if(supply_voltage >= VCC_5V0){
351-
352-
/* Disable system clock prescaler - F_CPU should now be ~16/20MHz */
353-
_PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, 0x00);
354-
355-
/* Assign cpu_freq value and sigrow_val depending on fuse setting */
356-
if(fuse_setting == FREQSEL_20MHZ_gc){
357-
cpu_freq = 20000000;
358-
359-
#if (PERFORM_SIGROW_CORRECTION_F_CPU == 1)
360-
sigrow_val = SIGROW.OSC20ERR5V;
361-
#endif
362-
363-
} else { /* fuse_setting == FREQSEL_16MHZ_gc */
364-
cpu_freq = 16000000;
365-
366-
#if (PERFORM_SIGROW_CORRECTION_F_CPU == 1)
367-
sigrow_val = SIGROW.OSC16ERR5V;
368-
#endif
369-
370-
}
371-
372-
} else if (supply_voltage == VCC_3V3) {
373-
374-
/* Enable system clock prescaler to DIV2 - F_CPU should now be ~8/10MHz */
375-
_PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, (CLKCTRL_PEN_bm | CLKCTRL_PDIV_2X_gc));
376-
377-
/* Assign cpu_freq value and sigrow_val depending on fuse setting */
378-
if(fuse_setting == FREQSEL_20MHZ_gc){
379-
cpu_freq = 10000000;
380-
381-
#if (PERFORM_SIGROW_CORRECTION_F_CPU == 1)
382-
sigrow_val = SIGROW.OSC20ERR3V;
383-
#endif
384-
385-
} else { /* fuse_setting == FREQSEL_16MHZ_gc */
386-
cpu_freq = 8000000;
387-
388-
#if (PERFORM_SIGROW_CORRECTION_F_CPU == 1)
389-
sigrow_val = SIGROW.OSC16ERR3V;
390-
#endif
391-
}
392-
393-
} else {
394-
/* Shouldn't get here but just in case... */
395-
396-
/* Enable system clock prescaler to DIV4 - F_CPU should now be ~4/5MHz */
397-
_PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, (CLKCTRL_PEN_bm | CLKCTRL_PDIV_4X_gc));
398-
399-
400-
if(fuse_setting == FREQSEL_20MHZ_gc){
401-
cpu_freq = 5000000;
402-
#if (PERFORM_SIGROW_CORRECTION_F_CPU == 1)
403-
sigrow_val = SIGROW.OSC20ERR3V;
404-
#endif
405-
406-
} else { /* fuse_setting == FREQSEL_16MHZ_gc */
407-
cpu_freq = 4000000;
408-
#if (PERFORM_SIGROW_CORRECTION_F_CPU == 1)
409-
sigrow_val = SIGROW.OSC16ERR3V;
410-
#endif
411-
}
412-
}
282+
#if (F_CPU == 16000000)
283+
cpu_freq = 16000000;
284+
285+
/* No division on clock */
286+
_PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, 0x00);
287+
288+
#elif (F_CPU == 8000000)
289+
cpu_freq = 8000000;
290+
291+
/* Clock DIV2 */
292+
_PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, (CLKCTRL_PEN_bm | CLKCTRL_PDIV_2X_gc));
293+
294+
#elif (F_CPU == 4000000)
295+
cpu_freq = 4000000;
296+
297+
/* Clock DIV4 */
298+
_PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, (CLKCTRL_PEN_bm | CLKCTRL_PDIV_4X_gc))
299+
300+
#elif (F_CPU == 2000000)
301+
cpu_freq = 2000000;
302+
303+
/* Clock DIV8 */
304+
_PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, (CLKCTRL_PEN_bm | CLKCTRL_PDIV_8X_gc))
305+
#else
306+
307+
#ifndef F_CPU
308+
# warning "F_CPU not defined"
309+
#define F_CPU 16000000
310+
#endif
311+
312+
# warning "F_CPU defined as an invalid value - may cause undefined behavior"
313+
314+
/* Default value is 16MHz */
315+
cpu_freq = 16000000;
316+
317+
/* No division on clock */
318+
_PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, 0x00);
319+
#endif
320+
413321

414322
#if (PERFORM_SIGROW_CORRECTION_F_CPU == 1)
415323
/* Calculate actual F_CPU with error values from signature row */
324+
uint8_t sigrow_val = SIGROW.OSC16ERR5V;
416325
cpu_freq *= (1024 + sigrow_val);
417326
cpu_freq /= 1024;
418327
#endif /* (CORRECT_F_CPU == 1) */

0 commit comments

Comments
 (0)