mikrokontrollersystemer-pro.../prosjekt.X/fan_speeeed.c
Sebastian H. Gabrielli 1671476f41 Move index incrementation over storage
This avoids the problem where the current index has outdated data.
It does however mean the first piece of stored data is empty, but it is
a worthwile tradeoff.
2024-04-30 11:11:32 +02:00

125 lines
3.2 KiB
C

#include "fan_speeeed.h"
#include "uart.h"
uint16_t timer_period_ms = 1;
uint16_t fan_speed = 0;
volatile uint16_t fan1_edge_counter = 0;
volatile uint16_t fan2_edge_counter = 0;
void init_TCA0() {
TCA0.SINGLE.INTCTRL = TCA_SINGLE_OVF_bm ;
TCA0.SINGLE.CTRLA = TCA_SINGLE_ENABLE_bm | TCA_SINGLE_CLKSEL_DIV1024_gc ; /* Sysclk /1024 */
TCA0_update_period(timer_period_ms);
}
void TCA0_update_period(uint16_t timer_period) {
TCA0.SINGLE.PERBUF = (F_CPU * (1 / timer_period) / 1024); /* F_CPU * F_IRQ / TCA_prescaler */
}
// COUNTINGS / TIME = FREQUENCY
// FREQ / 2 = GIVES ACTUAL FREQ
// FREQ * SEC-IN-A-MINUTE(60) / FAN-BLADES
uint16_t RPM_calculation(uint16_t edge_counter, uint16_t time_ms) {
fan_speed = (edge_counter / time_ms);
fan_speed = fan_speed/2;
fan_speed = fan_speed * 60/5;
edge_counter = 0;
return fan_speed;
}
void init_fan_gpio() {
// CONFIGURE PINS AS ANALOG INPUTS
// PIN FOR FAN 1
PORTD.DIRSET &= ~PIN6_bm;
PORTD.PIN6CTRL &= ~ PORT_ISC_gm;
PORTD.PIN6CTRL = PORT_ISC_INPUT_DISABLE_gc;
// PIN FOR FAN 2
PORTD.DIRSET &= ~PIN4_bm;
PORTD.PIN4CTRL &= ~ PORT_ISC_gm ;
PORTD.PIN4CTRL = PORT_ISC_INPUT_DISABLE_gc;
// PIN FOR REFRENCE
PORTD.DIRSET &= PIN7_bm;
PORTD.PIN7CTRL &= ~ PORT_ISC_gm ;
PORTD.PIN7CTRL = PORT_ISC_INPUT_DISABLE_gc;
}
void init_AC0(){
//Wincontroll disabled
AC0.CTRLB = 0x00;
//SELECT POSITIVE AND NEGATIVE INPUTS FOR COMPARRISON
// FAN USE PD6 COMPARE WITH PD3
AC0.MUXCTRL = AC_MUXPOS_AINP3_gc | AC_MUXNEG_AINN2_gc;
// ENABLE AC BY WRITING 1 TO ENABLE BIT IN ACN.CTRLA
AC0.CTRLA = AC_ENABLE_bm | AC_INTMODE_NORMAL_POSEDGE_gc | AC_OUTEN_bm;
// TURN ON INTERUPT
AC0.INTCTRL = 0x01;
}
void init_AC1(){
//Wincontroll disabled
AC1.CTRLB = 0x00;
//SELECT POSITIVE AND NEGATIVE INPUTS FOR COMPARRISON
// FAN USE PD4, COMPARE WITH PD3
AC1.MUXCTRL = AC_MUXPOS_AINP2_gc | AC_MUXNEG_AINN2_gc;
// ENABLE AC BY WRITING 1 TO ENABLE BIT IN ACN.CTRLA
AC1.CTRLA = AC_ENABLE_bm | AC_INTMODE_NORMAL_POSEDGE_gc | AC_OUTEN_bm;
// TURN ON INTERUPT
AC1.INTCTRL = 0x01;
}
ISR(AC0_AC_vect){ // AC0 vec flag
cli();
fan1_edge_counter++;
AC0.STATUS |= 0x10; //CMP flag to 0
sei();
}
ISR(AC1_AC_vect){ // AC1 vec flag
cli();
fan2_edge_counter++;
AC1.STATUS |= 0x10; //CMP flag to 0
sei();
}
// TIMER INTERUPT
ISR (TCA0_OVF_vect) {
cli();
// Increment the index, or reset if it is at the top
if (fan1_history_index < 512) {
fan1_history_index++;
} else {
fan1_history_index = 0;
}
if (fan2_history_index < 512) {
fan2_history_index++;
} else {
fan2_history_index = 0;
}
// Calculate the fanspeed
fan1_history[fan1_history_index] = RPM_calculation(fan1_edge_counter,timer_period_ms);
fan2_history[fan2_history_index] = RPM_calculation(fan2_edge_counter,timer_period_ms);
// Reset the edge counter
fan1_edge_counter = 0;
fan2_edge_counter = 0;
TCA0.SINGLE.INTFLAGS = TCA_SINGLE_OVF_bm ;
sei();
}