From 37feeae1ac48ae9b70c99b768943648fd6c354ff Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Mon, 27 Nov 2023 08:47:37 -0700 Subject: fixed ADC on attiny85 and related builds (also enabled smooth steps on BLF GT, but had to remove stuff to make room) --- arch/attiny85.c | 67 ++++++++++++++++++++++++++++++++++---------- arch/attiny85.h | 13 ++++++--- hw/lumintop/blf-gt/anduril.h | 7 +++++ hw/lumintop/blf-gt/hwdef.h | 8 ++++-- hw/mateminco/mf01s/hwdef.h | 8 ++++-- 5 files changed, 80 insertions(+), 23 deletions(-) diff --git a/arch/attiny85.c b/arch/attiny85.c index 0d2d7fe..9e298cc 100644 --- a/arch/attiny85.c +++ b/arch/attiny85.c @@ -64,14 +64,21 @@ static inline void hwdef_setup() { ////////// ADC voltage / temperature ////////// inline void mcu_set_admux_therm() { + // put the ADC in temperature mode ADMUX = ADMUX_THERM | (1 << ADLAR); } inline void mcu_set_admux_voltage() { + // put the ADC in battery voltage measurement mode + // TODO: avr datasheet references #ifdef USE_VOLTAGE_DIVIDER // 1.1V / pin7 ADMUX = ADMUX_VOLTAGE_DIVIDER | (1 << ADLAR); + // disable digital input on divider pin to reduce power consumption + VOLTAGE_ADC_DIDR |= (1 << VOLTAGE_ADC); #else // VCC / 1.1V reference ADMUX = ADMUX_VCC | (1 << ADLAR); + // disable digital input on VCC pin to reduce power consumption + //VOLTAGE_ADC_DIDR |= (1 << VOLTAGE_ADC); // FIXME: unsure how to handle for VCC pin #endif } @@ -80,29 +87,59 @@ inline void mcu_adc_sleep_mode() { } inline void mcu_adc_start_measurement() { - ADCSRA |= (1 << ADSC) | (1 << ADIE); -} - -inline void mcu_adc_on() { - hwdef_set_admux_voltage(); - #ifdef USE_VOLTAGE_DIVIDER - // disable digital input on divider pin to reduce power consumption - VOLTAGE_ADC_DIDR |= (1 << VOLTAGE_ADC); - #else - // disable digital input on VCC pin to reduce power consumption - //VOLTAGE_ADC_DIDR |= (1 << VOLTAGE_ADC); // FIXME: unsure how to handle for VCC pin - #endif - // enable, start, auto-retrigger, prescale - ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADATE) | ADC_PRSCL; + ADCSRA = (1 << ADEN) // enable + | (1 << ADSC) // start + | (1 << ADATE) // auto-retrigger + | (1 << ADIE) // interrupt enable + | ADC_PRSCL; // prescale } inline void mcu_adc_off() { ADCSRA &= ~(1<> 6) + (ADCH << 2); } +inline uint8_t mcu_vdd_raw2cooked(uint16_t measurement) { + // In : 65535 * 1.1 / Vbat + // Out: uint8_t: Vbat * 40 + // 1.1 = ADC Vref + // 1024 = how much ADC resolution we're using (10 bits) + // (12 bits available, but it costs an extra 84 bytes of ROM to calculate) + uint8_t vbat40 = (uint16_t)(40 * 1.1 * 1024) / (measurement >> 6); + return vbat40; +} + + +#ifdef USE_VOLTAGE_DIVIDER +inline uint8_t mcu_vdivider_raw2cooked(uint16_t measurement) { + // In : 4095 * Vdiv / 1.1V + // Out: uint8_t: Vbat * 40 + // Vdiv = Vbat / 4.3 (typically) + // 1.1 = ADC Vref + const uint16_t adc_per_volt = + (((uint16_t)ADC_44 << 4) - ((uint16_t)ADC_22 << 4)) + / (4 * (44-22)); + uint8_t result = measurement / adc_per_volt; + return result; +} +#endif + +inline uint16_t mcu_temp_raw2cooked(uint16_t measurement) { + // convert raw ADC values to calibrated temperature + // In: ADC raw temperature (16-bit, or left-aligned) + // Out: Kelvin << 6 + // Precision: 1/64th Kelvin (but noisy) + // attiny1634 datasheet section 19.12 + // nothing to do; input value is already "cooked" + return measurement; +} + +inline uint8_t mcu_adc_lsb() { + // left-adjusted mode: + return (ADCL >> 6) + (ADCH << 2); +} ////////// WDT ////////// diff --git a/arch/attiny85.h b/arch/attiny85.h index 2753fd7..3f6ffcb 100644 --- a/arch/attiny85.h +++ b/arch/attiny85.h @@ -21,8 +21,6 @@ ////////// default hw_setup() ////////// -// FIXME: fsm/main should call hwdef_setup(), not hw_setup, -// and this function should be hwdef_setup #ifdef USE_GENERIC_HWDEF_SETUP static inline void hwdef_setup(); #endif @@ -48,8 +46,6 @@ inline void mcu_adc_sleep_mode(); inline void mcu_adc_start_measurement(); -inline void mcu_adc_on(); - inline void mcu_adc_off(); // NOP because interrupt flag clears itself @@ -57,6 +53,15 @@ inline void mcu_adc_off(); inline uint16_t mcu_adc_result(); +// return Volts * 40, range 0 to 6.375V +#define voltage_raw2cooked mcu_vdd_raw2cooked +inline uint8_t mcu_vdd_raw2cooked(uint16_t measurement); +inline uint8_t mcu_vdivider_raw2cooked(uint16_t measurement); + +// return (temp in Kelvin << 6) +#define temp_raw2cooked mcu_temp_raw2cooked +inline uint16_t mcu_temp_raw2cooked(uint16_t measurement); + inline uint8_t mcu_adc_lsb(); diff --git a/hw/lumintop/blf-gt/anduril.h b/hw/lumintop/blf-gt/anduril.h index 2fc359e..cc2f940 100644 --- a/hw/lumintop/blf-gt/anduril.h +++ b/hw/lumintop/blf-gt/anduril.h @@ -54,7 +54,14 @@ #undef BLINK_AT_RAMP_MIDDLE #undef BLINK_AT_RAMP_FLOOR +#define USE_SMOOTH_STEPS + // too big, turn off extra features //#undef USE_TACTICAL_MODE #undef USE_SOS_MODE +#undef USE_BEACON_MODE +#undef USE_RAMP_AFTER_MOON_CONFIG +//#undef USE_RAMP_SPEED_CONFIG +//#undef USE_VOLTAGE_CORRECTION +#undef USE_2C_STYLE_CONFIG diff --git a/hw/lumintop/blf-gt/hwdef.h b/hw/lumintop/blf-gt/hwdef.h index dbaf18e..68197ac 100644 --- a/hw/lumintop/blf-gt/hwdef.h +++ b/hw/lumintop/blf-gt/hwdef.h @@ -67,14 +67,18 @@ enum CHANNEL_MODES { //#define ADMUX_VOLTAGE_DIVIDER ((1 << V_REF) | (1 << ADLAR) | VOLTAGE_CHANNEL) // 1.1V reference, no left-adjust, ADC1/PB2 #define ADMUX_VOLTAGE_DIVIDER ((1 << V_REF) | VOLTAGE_CHANNEL) + +#undef voltage_raw2cooked +#define voltage_raw2cooked mcu_vdivider_raw2cooked + #define ADC_PRSCL 0x07 // clk/128 // Raw ADC readings at 4.4V and 2.2V (in-between, we assume values form a straight line) #ifndef ADC_44 -#define ADC_44 (184*4) +#define ADC_44 (184*4*4) #endif #ifndef ADC_22 -#define ADC_22 (92*4) +#define ADC_22 (92*4*4) #endif #define FAST 0xA3 // fast PWM both channels diff --git a/hw/mateminco/mf01s/hwdef.h b/hw/mateminco/mf01s/hwdef.h index fef5050..21ea1fd 100644 --- a/hw/mateminco/mf01s/hwdef.h +++ b/hw/mateminco/mf01s/hwdef.h @@ -67,14 +67,18 @@ enum CHANNEL_MODES { // 1.1V reference, no left-adjust, ADC1/PB2 #define ADMUX_VOLTAGE_DIVIDER ((1 << V_REF) | VOLTAGE_CHANNEL) #endif + +#undef voltage_raw2cooked +#define voltage_raw2cooked mcu_vdivider_raw2cooked + #define ADC_PRSCL 0x07 // clk/128 // Raw ADC readings at 4.4V and 2.2V (in-between, we assume values form a straight line) #ifndef ADC_44 -#define ADC_44 (234*4) +#define ADC_44 (234*4*4) #endif #ifndef ADC_22 -#define ADC_22 (117*4) +#define ADC_22 (117*4*4) #endif #define FAST 0xA3 // fast PWM both channels -- cgit v1.2.3