/* Reflow Oven Controller
 *
 * Copyright (C) 2020  Mario Hüttel <mario.huettel@gmx.net>
 *
 * This file is part of the Reflow Oven Controller Project.
 *
 * The reflow oven controller is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * The Reflow Oven Control Firmware 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 the reflow oven controller project.
 * If not, see <http://www.gnu.org/licenses/>.
 */

#include <reflow-controller/temp-converter.h>
#include <reflow-controller/temp-converter-data.h>
#include <helper-macros/helper-macros.h>

static const float temp_lookup[(TEMP_CONVERSION_MAX_RES-TEMP_CONVERSION_MIN_RES) / TEMP_CONVERSION_RES_STEP+1] = {TEMP_CONVERSION_ARRAY_DATA};

int temp_converter_convert_resistance_to_temp(float resistance, float *temp_out)
{
	int ret_val;
	unsigned int i;
	unsigned int lower_idx = COUNT_OF(temp_lookup) - 1;
	float diff_to_low_resistance;
	float diff_high_low;
	float low;

	/* Check pointer */
	if (!temp_out)
		return -1000;

	if (resistance < TEMP_CONVERSION_MIN_RES) {
		*temp_out = temp_lookup[0];
		ret_val = -1;
		goto return_ret_val;
	} else if (resistance > TEMP_CONVERSION_MAX_RES) {
		*temp_out = temp_lookup[COUNT_OF(temp_lookup)-1];
		ret_val = 1;
		goto return_ret_val;
	}

	/* Resistance is in range */
	ret_val = 0;

	/* Calculate lower index for given reistance */
	for (i = 1; i < COUNT_OF(temp_lookup); i++) {
		if (resistance <= TEMP_CONVERSION_MIN_RES + TEMP_CONVERSION_RES_STEP * i) {
			lower_idx = i - 1;
			break;
		}
	}

	/* Get the lower temperature limit of the current range */
	low = temp_lookup[lower_idx];

	/* Difference to higher limit */
	diff_high_low = temp_lookup[lower_idx+1] - low;

	/* Resistance difference to lower limit's resistance value */
	diff_to_low_resistance = resistance - (float)(TEMP_CONVERSION_MIN_RES + TEMP_CONVERSION_RES_STEP * lower_idx);

	/* Calculate output temperature */
	*temp_out = (diff_to_low_resistance / TEMP_CONVERSION_RES_STEP) * diff_high_low + low;

return_ret_val:
	return ret_val;
}
