/**
 * temp_sense.c
 *
 * Does the math on the temperature sensing thermistor for the display driver chip.
 * 
 * Copyright (c) 2022 Bigscreen, Inc.
 */

#include "asf.h"
#include <math.h>
#include "temp_sense.h"

uint16_t current_adc_reading;
float current_temperature;

uint16_t history_of_adc_readings[256];
uint8_t history_location = 0;

void temp_sense_update_adc_value(uint16_t newval) {
	current_adc_reading = newval;
	history_of_adc_readings[history_location++] = newval;
}
float pin_ratio;
float resistance;

void temp_sense_calc_temperature(void) {
	// Determine resistance by voltage reading
	// pin_ratio = pin_voltage / reference_voltage
	pin_ratio = ((float)current_adc_reading) / (MAX_ADC_COUNTS_F);
	// pin_voltage = ref_voltage * Rtherm / (Rtherm + Rfixed)
	// Rtherm = pinv / refv * (Rtherm+Rfixed)
	// Rtherm = pinv/refv * Rtherm + pinv/refv * Rfixed
	// Rtherm (1-pinv/refv) = (pinv/refv)* Rfixed
	// Rtherm = (pinv/refv)/(1-pinv/refv) * Rfixed
	resistance = pin_ratio / (1-pin_ratio) * FIXED_RESISTANCE_F;
	
	// Determine temperature from the resistance
	// B = (T2*T1) / (T2-T1) * ln(R1/R2)
	// B*(T2-T1) = T2*T1*ln(R1/R2)
	// T2*B - T2*T1*ln(R1/R2) = T1*B
	// T2*(B-T1*ln(R1/R2)) = T1*B
	// T2 = T1*B/(B-T1*ln(R1/R2))
	
	current_temperature = TEMP_SENSE_T25 * TEMP_SENSE_B25_100  /(TEMP_SENSE_B25_100 - TEMP_SENSE_T25 * logf(TEMP_SENSE_R25/resistance));	
}

float temp_sense_get_temperature(void) {
	float temp;
	// Memory barriers to help thread safety
	// current_temperature gets updated in an interrupt, so we don't
	// want to have a weird glitchy read because it was updated
	// just at the moment it's being read
	__DMB();
	temp = current_temperature;
	__DMB();
	
	return temp;
}
