diff options
Diffstat (limited to 'table-fan/fan.c')
-rw-r--r-- | table-fan/fan.c | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/table-fan/fan.c b/table-fan/fan.c new file mode 100644 index 0000000..daa33f4 --- /dev/null +++ b/table-fan/fan.c @@ -0,0 +1,93 @@ +/* + * spreadspace avr utils + * + * + * Copyright (C) 2021 Christian Pointner <equinox@spreadspace.org> + * + * This file is part of spreadspace avr utils. + * + * spreadspace avr utils is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * spreadspace avr utils is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with spreadspace avr utils. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <avr/io.h> +#include <avr/interrupt.h> + +#include <stdio.h> + + +#define PWM_VAL_MAX 160 + +void fan_init(void) +{ + // timer for tacho + DDRD &= ~(1<<PD4); + PORTD |= (1<<PD4); + TCCR1B = 0; // make sure timer is stopped + + TCCR1A = 0; + TCNT1 = 0; + TIMSK1 = (1<<ICIE1); + + TCCR1B = (1<<CS12); // start timer + + // PWM for speed control + DDRB |= (1<<PB6); + TCCR4B = 0; // make sure timer is stopped + + TCCR4A = (1<<COM4B1) | (1<<PWM4B); + TCCR4D = (1<<WGM40); + TCNT4 = 0; + OCR4C = PWM_VAL_MAX; + + OCR4B = PWM_VAL_MAX/2; // set duty cycle to 50:50 + TCCR4B = (1<<CS41); // start timer +} + +void fan_speed_set(uint8_t val) +{ + OCR4B = (val > PWM_VAL_MAX) ? PWM_VAL_MAX : val; +} + +uint8_t fan_speed_get(void) +{ + return OCR4B; +} + +void fan_speed_inc(void) +{ + if(OCR4B < PWM_VAL_MAX) + OCR4B++; +} + +void fan_speed_dec(void) +{ + if(OCR4B > 0) + OCR4B--; +} + +ISR(TIMER1_CAPT_vect) +{ + static uint16_t tacho_last_ts = 0; + uint16_t current = ICR1; + uint16_t diff = 0; + if(current > tacho_last_ts) { + diff = current - tacho_last_ts; + } else { + diff = (UINT16_MAX - tacho_last_ts) + current; + } + tacho_last_ts = current; + + uint16_t rpm = 1875000 / diff; + printf("\rspeed: %6d rpm", rpm); +} |