// ==========================================================================
// sensors.c
// (c) 2022, Aurel Dumitru
//
// Description:
// Sensors operations
// =========================================================================

#include <stdlib.h>
#include <string.h>
#include "sensors.h"
#include "main.h"
#include "sensor_raing.h"
#include "sensor_analog.h"
#include "sensor_rs485.h"
#include "sensor_shtc3.h"
#include "rgbled.h"
#include "rtc.h"
#include "file.h"
#include "devstatus.h"
#include "utils.h"

uint32_t Sensors_Timestamp;
uint32_t Sensors_Shtc3_MeasDone;
uint32_t Sensors_Analog_MeasDone;
uint32_t Sensors_Raing_MeasDone;
uint32_t Sensors_RS485_MeasDone;
char	 Sensor_ReturnValues[2048];


// Public operations
void Sensors_Init(void)
{
	if (DevStatus_GetBoardType())
	{
		if ((DevStatus[DEVSTATUS_SENSORS_VALID_KEY1_IDX] != 0xBADEDACE) ||
			(DevStatus[DEVSTATUS_SENSORS_VALID_KEY2_IDX] != 0xDADADADA))
		{
			Rgbled_SetColor(100, 0x0000FF);
			Sensor_Raing_Init();
			Sensor_RS485_Init();
			Sensor_Analog_Init();
			while (1)
			{
				(void)HAL_IWDG_Refresh(&hiwdg1);
				if ((Sensor_Raing_GetStatus() 		!= SENSOR_RAING_NOT_CHECKED) &&
					(Sensor_RS485_GetGlobalStatus() != SENSOR_RS485_NOT_CHECKED) &&
					(Sensor_Analog_GetStatus() 		!= SENSOR_ANALOG_NOT_CHECKED))
					break;
				Sensor_Raing_InitServer();
				Sensor_RS485_InitServer();
				Sensor_Analog_InitServer();
			}
			Rgbled_SetColor(0, 0x000000);
		}
	}
	// Set as valid sensors presence table
	DevStatus[DEVSTATUS_SENSORS_VALID_KEY1_IDX] = 0xBADEDACE;
	DevStatus[DEVSTATUS_SENSORS_VALID_KEY2_IDX] = 0xDADADADA;
	if (Sensor_Raing_GetStatus() != SENSOR_RAING_PRESENT)
		HAL_GPIO_WritePin(EN_3V3S_GPIO_Port, EN_3V3S_Pin, GPIO_PIN_RESET);	// Disable the 3V3S power supply
}


void Sensors_GetValues(char* Time)
{
	char* Dest = Sensor_ReturnValues;
	char* Src;
	char* DestValues;

	Dest = Utils_CopyString("Time: ", Dest);
	Dest = Utils_CopyString(Time,     Dest); Dest--; *Dest++ = '\n';
	DestValues = Dest;
	Sensor_ReturnValues[10] = '/'; Sensor_ReturnValues[13] = '/'; Sensor_ReturnValues[16] = ' ';
	Sensor_ReturnValues[19] = ':'; Sensor_ReturnValues[22] = ':';

	if ((Src = Sensor_Shtc3_GetValues()))
		{Dest = Utils_CopyString(Src, Dest); *Dest++ = '\n';}
	if (Sensor_Raing_GetStatus() == SENSOR_RAING_PRESENT)
		if ((Src = Sensor_Raing_GetValues()))
			{Dest = Utils_CopyString(Src, Dest); *Dest++ = '\n';}
	if (Sensor_Analog_GetStatus() == SENSOR_ANALOG_PRESENT)
		{Dest = Utils_CopyString(Sensor_Analog_GetValues(), Dest); *Dest++ = '\n';}
	if (Sensor_RS485_GetGlobalStatus() == SENSOR_RS485_PRESENT)
		if ((Src = Sensor_RS485_GetValues()))
			{Dest = Utils_CopyString(Src, Dest); *Dest++ = '\n';}
	// Check if at least one sensor is present; if not, save nothing
	if (Dest != DestValues)
		File_WriteFileAppend("Sensors.log", (const uint8_t*)Sensor_ReturnValues, Dest-Sensor_ReturnValues);
}


void Sensors_StartMeasurement(void)
{
	Sensors_Shtc3_MeasDone = 0;	Sensors_Analog_MeasDone = 0; Sensors_Raing_MeasDone = 0; Sensors_RS485_MeasDone = 0;
	Sensor_Shtc3_StartMeasurement();
	if (Sensor_Analog_GetStatus()		== SENSOR_ANALOG_PRESENT)	Sensor_Analog_StartMeasurement();
	else															Sensors_Analog_MeasDone = 1;
	if (Sensor_Raing_GetStatus()		== SENSOR_RAING_PRESENT)	Sensor_Raing_StartMeasurement();
	else															Sensors_Raing_MeasDone = 1;
	if (Sensor_RS485_GetGlobalStatus()	== SENSOR_RS485_PRESENT)	Sensor_RS485_StartMeasurement();
	else															Sensors_RS485_MeasDone = 1;
}


uint32_t Sensors_MeasurementServer(void)
{
	if (Sensors_Shtc3_MeasDone == 0)		Sensors_Shtc3_MeasDone	= Sensor_Shtc3_GetMeasurementStatus();
	if (Sensors_Analog_MeasDone == 0)		Sensors_Analog_MeasDone = Sensor_Analog_GetMeasurementStatus();
	if (Sensors_Raing_MeasDone == 0)		Sensors_Raing_MeasDone	= Sensor_Raing_GetMeasurementStatus();
	if (Sensors_RS485_MeasDone == 0)		Sensors_RS485_MeasDone	= Sensor_RS485_GetMeasurementStatus();

	uint32_t Ret = Sensors_Shtc3_MeasDone & Sensors_Analog_MeasDone & Sensors_Raing_MeasDone & Sensors_RS485_MeasDone;
	if (Ret)
	{
		HAL_GPIO_WritePin(EN_12V_GPIO_Port, EN_12V_Pin, GPIO_PIN_RESET);	// Disable the 12V main supply
		HAL_GPIO_WritePin(EN_12V_SW_GPIO_Port, EN_12V_SW_Pin, GPIO_PIN_RESET);	// Disable the 12V SW supply
		if (Sensor_Raing_GetStatus() != SENSOR_RAING_PRESENT)
			HAL_GPIO_WritePin(EN_3V3S_GPIO_Port, EN_3V3S_Pin, GPIO_PIN_RESET);	// Disable the 3V3S power supply
	}
	return Ret;
}
