From 3d12b7066d27b591e0283e20ed066bc66e29fbe4 Mon Sep 17 00:00:00 2001 From: Selene ToyKeeper Date: Fri, 10 Nov 2023 21:34:40 -0700 Subject: refactor checkpoint: splitting MCU-specific code into arch/$MCU.[ch] Phew, that's a lot of changes! And there's still a lot more to do... --- arch/attiny85.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 arch/attiny85.c (limited to 'arch/attiny85.c') diff --git a/arch/attiny85.c b/arch/attiny85.c new file mode 100644 index 0000000..40cbcfe --- /dev/null +++ b/arch/attiny85.c @@ -0,0 +1,167 @@ +// arch/attiny85.c: attiny85 support functions +// Copyright (C) 2014-2023 Selene ToyKeeper +// SPDX-License-Identifier: GPL-3.0-or-later +#pragma once + +#include "arch/attiny85.h" + +////////// clock speed / delay stuff ////////// + +///// clock dividers + +////////// 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() { + // configure PWM channels + #if PWM_CHANNELS >= 1 + DDRB |= (1 << PWM1_PIN); + TCCR0B = 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...) + TCCR0A = PHASE; + #if (PWM1_PIN == PB4) // Second PWM counter is ... weird + TCCR1 = _BV (CS10); + GTCCR = _BV (COM1B1) | _BV (PWM1B); + OCR1C = 255; // Set ceiling value to maximum + #endif + #endif + // tint ramping needs second channel enabled, + // despite PWM_CHANNELS being only 1 + #if (PWM_CHANNELS >= 2) || defined(USE_TINT_RAMPING) + DDRB |= (1 << PWM2_PIN); + #if (PWM2_PIN == PB4) // Second PWM counter is ... weird + TCCR1 = _BV (CS10); + GTCCR = _BV (COM1B1) | _BV (PWM1B); + OCR1C = 255; // Set ceiling value to maximum + #endif + #endif + #if PWM_CHANNELS >= 3 + DDRB |= (1 << PWM3_PIN); + #if (PWM3_PIN == PB4) // Second PWM counter is ... weird + TCCR1 = _BV (CS10); + GTCCR = _BV (COM1B1) | _BV (PWM1B); + OCR1C = 255; // Set ceiling value to maximum + #endif + #endif + #if PWM_CHANNELS >= 4 + // 4th PWM channel is ... not actually supported in hardware :( + DDRB |= (1 << PWM4_PIN); + //OCR1C = 255; // Set ceiling value to maximum + TCCR1 = 1<> 6) + (ADCH << 2); } + + +////////// WDT ////////// + +inline void mcu_wdt_active() { + // interrupt every 16ms + //cli(); // Disable interrupts + wdt_reset(); // Reset the WDT + WDTCR |= (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 ////////// -- cgit v1.2.3