From dbe0aaf636ccb78a3cc1281b6a1ea6c662af6756 Mon Sep 17 00:00:00 2001 From: Gabriel Hart Date: Fri, 18 Dec 2020 15:23:31 -0600 Subject: Add AVR 1-Series and t1616 board and scripts --- spaghetti-monster/fsm-adc.c | 53 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) (limited to 'spaghetti-monster/fsm-adc.c') diff --git a/spaghetti-monster/fsm-adc.c b/spaghetti-monster/fsm-adc.c index 71ecf65..2818731 100644 --- a/spaghetti-monster/fsm-adc.c +++ b/spaghetti-monster/fsm-adc.c @@ -37,6 +37,9 @@ static inline void set_admux_therm() { #elif (ATTINY == 841) // FIXME: not tested ADMUXA = ADMUXA_THERM; ADMUXB = ADMUXB_THERM; + #elif defined(AVRXMEGA3) // ATTINY816, 817, etc + ADC0.MUXPOS = ADC_MUXPOS_TEMPSENSE_gc; // read temperature + ADC0.CTRLC = ADC_SAMPCAP_bm | ADC_PRESC_DIV64_gc | ADC_REFSEL_INTREF_gc; // Internal ADC reference #else #error Unrecognized MCU type #endif @@ -66,6 +69,15 @@ inline void set_admux_voltage() { ADMUXA = ADMUXA_VCC; ADMUXB = ADMUXB_VCC; #endif + #elif defined(AVRXMEGA3) // ATTINY816, 817, etc + #ifdef USE_VOLTAGE_DIVIDER // 1.1V / ADC input pin + // verify that this is correct!!! untested + ADC0.MUXPOS = ADMUX_VOLTAGE_DIVIDER; // read the requested ADC pin + ADC0.CTRLC = ADC_SAMPCAP_bm | ADC_PRESC_DIV64_gc | ADC_REFSEL_INTREF_gc; // Use internal ADC reference + #else // VCC / 1.1V reference + ADC0.MUXPOS = ADC_MUXPOS_INTREF_gc; // read internal reference + ADC0.CTRLC = ADC_SAMPCAP_bm | ADC_PRESC_DIV64_gc | ADC_REFSEL_VDDREF_gc; // Vdd (Vcc) be ADC reference + #endif #else #error Unrecognized MCU type #endif @@ -77,6 +89,9 @@ inline void set_admux_voltage() { inline void ADC_start_measurement() { #if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) || (ATTINY == 841) || (ATTINY == 1634) ADCSRA |= (1 << ADSC) | (1 << ADIE); + #elif defined(AVRXMEGA3) // ATTINY816, 817, etc + ADC0.INTCTRL |= ADC_RESRDY_bm; // enable interrupt + ADC0.COMMAND |= ADC_STCONV_bm; // Start the ADC conversions #else #error unrecognized MCU type #endif @@ -108,13 +123,22 @@ inline void ADC_on() // enable, start, auto-retrigger, prescale ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADATE) | ADC_PRSCL; //ADCSRA |= (1 << ADSC); // start measuring + #elif defined(AVRXMEGA3) // ATTINY816, 817, etc + set_admux_voltage(); + VREF.CTRLA |= VREF_ADC0REFSEL_1V1_gc; // Set Vbg ref to 1.1V + ADC0.CTRLA = ADC_ENABLE_bm | ADC_FREERUN_bm; // Enabled, free-running (aka, auto-retrigger) + ADC0.COMMAND |= ADC_STCONV_bm; // Start the ADC conversions #else #error Unrecognized MCU type #endif } inline void ADC_off() { - ADCSRA &= ~(1<>= 8; // Divide result to get Kelvin + m = (temp << 6); // left align it + } + else { m = (ADC0.RES << 6); } // voltage, force left-alignment + + #else m = ADC; + #endif adc_raw[channel] = m; // lowpass the value @@ -181,8 +228,12 @@ void adc_deferred() { // real-world entropy makes this a true random, not pseudo // Why here instead of the ISR? Because it makes the time-critical ISR // code a few cycles faster and we don't need crypto-grade randomness. + #ifdef AVRXMEGA3 // ATTINY816, 817, etc + pseudo_rand_seed += ADC0.RESL; // right aligned, not left... so should be equivalent? + #else pseudo_rand_seed += (ADCL >> 6) + (ADCH << 2); #endif + #endif // the ADC triggers repeatedly when it's on, but we only need to run the // voltage and temperature regulation stuff once in a while...so disable -- cgit v1.2.3