/*
 * File: Core1_LED_Enable.c
 *
 * Created: Created: Wednesday August 2025 21:56:20
 *   Author: Chris
 */
#include "Core1_LED_Enable.h"


// ============================================================================================
// Includes
#include "Core1_ADC.h"
#include "Command_Definition.h"

#include "hardware/gpio.h"


// ============================================================================================
// Defines
///////////////////////////////////////////
// LED Defines only for testing purposes //
///////////////////////////////////////////
#define LEDG_PIN 				12
#define LEDG_CONFIG      		gpio_init(LEDG_PIN); gpio_set_dir(LEDG_PIN, GPIO_OUT)
#define LEDG_ON 				gpio_put(LEDG_PIN, 0)
#define LEDG_OFF 				gpio_put(LEDG_PIN, 1)



#define LED_PWR_EN_GPIO         0
#define INA260_ALERT_GPIO       13

#define ENABLE_LED_POWER()      gpio_put(LED_PWR_EN_GPIO, 1);	LEDG_ON;	_Power_Was_Enabled_Before = true
#define DISABLE_LED_POWER()     gpio_put(LED_PWR_EN_GPIO, 0);	LEDG_OFF


// ============================================================================================
// Variables
static LED_Power_Error 	_LED_Power_Error;
static bool				_Power_Was_Enabled_Before;
static bool 			_INA260_Alert_Last_State;
static uint16_t 		_Analog_BusVoltage_mV;
static uint16_t 		_INA260_BusVoltage_mV;


// ============================================================================================
// Function Declarations
void Core1_LED_Enable_Update_Alert_Status();
void Core1_LED_Enable_Set_Error(LED_Power_Error error);


/*******************************************************************
    Functions
*******************************************************************/
void Core1_LED_Enable_Init()
{
    gpio_set_dir(LED_PWR_EN_GPIO, GPIO_OUT);
    DISABLE_LED_POWER();

    gpio_set_dir(INA260_ALERT_GPIO, GPIO_IN);

    _LED_Power_Error = UNDEFINED;
	_Power_Was_Enabled_Before = false;
   Core1_LED_Enable_Update_Alert_Status();
}

void Core1_LED_Enable_Tick()
{
    Core1_LED_Enable_Update_Alert_Status();

	_Analog_BusVoltage_mV = Core1_ADC_Get_Result_mV();

	if(abs(_Analog_BusVoltage_mV - _INA260_BusVoltage_mV) > THRESHOLD_MEASUREMENT_MAX_DEVIATION_mV) {
		Core1_LED_Enable_Set_Error(BUS_VOLTAGE_MEASUREMENT);
	}
	else if(_Analog_BusVoltage_mV < THRESHOLD_NO_SUPPLY_mV || _INA260_BusVoltage_mV < THRESHOLD_NO_SUPPLY_mV) {
		Core1_LED_Enable_Set_Error(BUS_NO_SUPPLY);
	}
	else if (_Analog_BusVoltage_mV < THRESHOLD_UNDERVOLTAGE_mV || _INA260_BusVoltage_mV < THRESHOLD_UNDERVOLTAGE_mV) {
		Core1_LED_Enable_Set_Error(BUS_UNDERVOLTAGE);
	}
	else if (_Analog_BusVoltage_mV > THRESHOLD_OVERVOLTAGE_mV || _INA260_BusVoltage_mV > THRESHOLD_OVERVOLTAGE_mV) {
		Core1_LED_Enable_Set_Error(BUS_OVERVOLTAGE);
	}
	else {
		Core1_LED_Enable_Set_Error(NO_ERROR);
	}
}

void Core1_LED_Enable_Update_INA260_BusVoltage(uint16_t voltage_mV)
{
	_INA260_BusVoltage_mV = voltage_mV;
}

bool Core1_LED_Enable_Get_Status()
{
    return gpio_get(LED_PWR_EN_GPIO);
}

LED_Power_Error Core1_LED_Enable_Get_Error()
{
    return _LED_Power_Error;
}


/*******************************************************************
    Internal Functions
*******************************************************************/
void Core1_LED_Enable_Update_Alert_Status()
{
    if(_INA260_Alert_Last_State == true && gpio_get(LED_PWR_EN_GPIO) == false) {
		Core1_LED_Enable_Set_Error(OVERCURRENT);
    }
    
    _INA260_Alert_Last_State = gpio_get(LED_PWR_EN_GPIO);
}

void Core1_LED_Enable_Set_Error(LED_Power_Error error)
{
    if(error == NO_ERROR && _Power_Was_Enabled_Before == false) {
        ENABLE_LED_POWER();
		_LED_Power_Error = error;
    }
	else if(error != UNDEFINED && error != NO_ERROR) {
		DISABLE_LED_POWER();
		_LED_Power_Error = error;
	}
}