diff options
| author | Dennis Brentjes <d.brentjes@gmail.com> | 2020-03-28 20:30:24 +0100 |
|---|---|---|
| committer | Dennis Brentjes <d.brentjes@gmail.com> | 2020-03-28 20:30:24 +0100 |
| commit | 89be54a9feb65bfbad237b79969bf3446c90eebd (patch) | |
| tree | 39213238c9c6efcbda287efe4613129fe28571a4 /picl-firmware/fan_control.c | |
| parent | 456fe72cc5b026f9168af91767af6932f6e70866 (diff) | |
| download | PiCl-89be54a9feb65bfbad237b79969bf3446c90eebd.tar.gz PiCl-89be54a9feb65bfbad237b79969bf3446c90eebd.tar.bz2 PiCl-89be54a9feb65bfbad237b79969bf3446c90eebd.zip | |
Adds initial version of the Attiny24 firmware
Diffstat (limited to 'picl-firmware/fan_control.c')
| -rw-r--r-- | picl-firmware/fan_control.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/picl-firmware/fan_control.c b/picl-firmware/fan_control.c new file mode 100644 index 0000000..9e87963 --- /dev/null +++ b/picl-firmware/fan_control.c @@ -0,0 +1,86 @@ +#include <avr/io.h> +#include <avr/interrupt.h> +#include <avr/sleep.h> + +void setup_adc() { + //enable interrupts + sei(); + // setup external reference voltage. + ADMUX &= ~(3UL << REFS0); + ADMUX |= (1UL << REFS0); + // set left adjusted ADC result so we can easily only use the upper 8 bits of the result + ADCSRB |= (1UL << ADLAR); + // enable ADC interrupt + ADCSRA |= (1UL << ADIE); +} + +void setup_timers() { + //use system clock for timers, no prescaler. + TCCR0B &= ~(7UL << CS00); + TCCR0B |= (1UL << CS00); + + //set mode 5 (PWM, phase correct, top defined by OCRA) + TCCR0A &= ~(3UL << WGM00); + TCCR0B &- ~(1UL << WGM02); + TCCR0A |= (1UL << WGM00); + TCCR0B |= (1UL << WGM02); +} + +void enable_ADC() { + PRR &= ~(1UL << PRADC); + ADCSRA |= (1UL << ADEN); +} + +void disable_ADC() { + ADCSRA &= ~(1UL << ADEN); + PRR |= (1UL << PRADC); +} + +void select_ADC_channel(int channel) { + ADMUX &= ~(7UL << MUX0); + ADMUX |= (channel << MUX0); +} + +uint8_t get_ADC_result() { + uint8_t result = ADCL; + //conversion would be blocked if we don't also read ADCH although we won't use the upper 2 bits. + uint8_t unblock = ADCH; + return result; +} + +void start_ADC() { + ADCSRA |= (1UL << ADSC); +} + +volatile uint8_t fan1; +volatile uint8_t fan2; + +void start_polling_fans() { + PRR &= ~(1UL << PRADC); + enable_ADC(); + select_ADC_channel(ADC1D); + start_ADC(); +} + +ISR(ADC_vect) { + if(ADMUX & (7UL << MUX0) == ADC1D) { + fan1 = get_ADC_result(); + select_ADC_channel(ADC2D); + start_ADC(); + return; + } + + if(ADMUX & (7UL << MUX0) == ADC2D) { + fan2 = get_ADC_result(); + disable_ADC(); + return; + } +} + +int main() { + set_sleep_mode(0); + setup_adc(); + setup_timers(); + + while(1); +} |
