
// Wie LVP||OVP Modul
// Jedoch hier nur LVP



#include "stdio.h"
#include "mode_lvp.h"
#include "button.h"
#include "relais.h"
#include "main.h"
#include "leds.h"
#include "buzzer.h"
#include "chip_temperature.h"


typedef enum LVP_State_enum 
{
  LVP_OFF, 
  LVP_ON,
  LVP_MANUAL_ON, 
  LVP_ERROR
} LVP_state_t;


static LVP_state_t smState;


static void LVP_SM_Off(void)
{
  int faultInput;


  if (HAL_GPIO_ReadPin(GPIO_INPUT_FAULT_GPIO_Port, GPIO_INPUT_FAULT_Pin) == GPIO_PIN_RESET)       
  {
    faultInput = 1;
  }
  else
  {
    faultInput = 0;
  }


  


  //Prüfe auf Wechsel des Modus AUTO / SM ON
  if (BUTTON_GetMode() == BUTTON_AUTO)
  {
    if (faultInput == 0) 
    {
      RELAIS_SetPuls();
      BUZZER_Beep(BUZZER_ON_TIME_CONFIRM);
      LEDS_GN_Blink_Start(LED_GN_ON_TIME_ON_MODE, LED_GN_OFF_TIME);
      printf("LVP_SM_Off: NEW_STATE: LVP_ON\n");
      smState = LVP_ON;

    }
    else   
    {
      //Wechsel nicht möglich. Fehler Eingang aktiv
      BUZZER_Beep(BUZZER_ON_TIME_REJECT);
      BUTTON_SetModeOff();
      //LEDS_RT_Blink_Start(LED_RT_ON_TIME_WARN_FAULT_INPUT, LED_GN_OFF_TIME); //Fehler Anzeigen
	  LEDS_RT_BlinkCode_Start(BLINK_CODE_ERROR_FAULT_INPUT, LED_RT_ON_TIME_WARN_FAULT_INPUT, LED_RT_OFF_TIME, LED_RT_OFF_TIME *5); //Fehler Anzeigen
      printf("LVP_SM_Off: NEW_STATE: LVP_ERROR_FAULT_INPUT\n");
      smState =LVP_ERROR;
    }
  }


  //Prüfe auf Wechsel in MANUAL ON Mode
  //Keine Fehlerüberprüfungen. In diesem Modus werdem alle Alarme ignoriert.
  if (BUTTON_GetMode() == BUTTON_MANUAL_ON)
  {
      
      RELAIS_SetPuls();
      BUZZER_Alarm_Start(BUZZER_ON_TIME_ALARM_MANUAL_MODE, BUZZER_OFF_TIME);
      LEDS_GN_On();
      LEDS_RT_BlinkCode_Start(BLINK_CODE_WARN_MANUAL, LED_RT_ON_TIME_WARN_MANUAL_MODE, LED_RT_OFF_TIME, LED_RT_OFF_TIME * 5); //Fehler Anzeigen
      printf("NEW_STATE: LVP_MANUAL_ON\n");
      smState = LVP_MANUAL_ON;
  }



}

static void LVP_SM_On(void)
{
  int faultInput = 0;
  static int lvpInput = 0;
  static int lvpTimeCounter = 0;
  static int oldtime;

  if (HAL_GPIO_ReadPin(GPIO_INPUT_FAULT_GPIO_Port, GPIO_INPUT_FAULT_Pin) == GPIO_PIN_RESET)       
  {
    faultInput = 1;
  }
  else
  {
    faultInput = 0;
  }
  
  if ((HAL_GPIO_ReadPin(GPIO_INPUT_LVP_GPIO_Port, GPIO_INPUT_LVP_Pin) == GPIO_PIN_SET) ||  (HAL_GPIO_ReadPin(GPIO_INPUT_OVP_GPIO_Port, GPIO_INPUT_OVP_Pin) == GPIO_PIN_SET))
  {
    if (HAL_GetTick() != oldtime)
    {
      if (lvpTimeCounter < 5000) lvpTimeCounter++;
      if (lvpTimeCounter >= 5000)
      {
        lvpInput = 1;
        lvpTimeCounter=0;
      }
      oldtime = HAL_GetTick();
    }
  }

  if (HAL_GPIO_ReadPin(GPIO_INPUT_LVP_GPIO_Port, GPIO_INPUT_LVP_Pin) == GPIO_PIN_RESET) 
  {
//    if (HAL_GetTick() != oldtime)
//    {
//      lvpAndOvpInputTimeCounter++;
//      if (lvpAndOvpInputTimeCounter > 30000)
//      {
        lvpInput = 0;
        lvpTimeCounter=0;
//      }
//      oldtime = HAL_GetTick();
//    }
  }

  


  //Prüfe auf Fehlermode
  if (faultInput == 1)
  {
    RELAIS_ResetPuls();
    BUZZER_Beep(BUZZER_ON_TIME_REJECT); //Warnung
    LEDS_GN_Off();
    LEDS_RT_BlinkCode_Start(BLINK_CODE_ERROR_FAULT_INPUT, LED_RT_ON_TIME_WARN_FAULT_INPUT, LED_RT_OFF_TIME, LED_RT_OFF_TIME *5); //Fehler Anzeigen
    BUTTON_SetModeOff(); //Damit nicht von alleine wieder eingeschaltet wird
    printf("FAULT INPUT EVENT DETECTED!\n");
    printf("NEW_STATE: LVP_ERROR\n");
    smState = LVP_ERROR;
  }

    if (CHIP_TEMPERATURE_GetTemp() > 80)
  {
	RELAIS_ResetPuls();
	BUZZER_Beep(BUZZER_ON_TIME_REJECT); //Warnung
	LEDS_GN_Off();
	LEDS_RT_BlinkCode_Start(BLINK_CODE_ERROR_TEMP, LED_RT_ON_TIME_WARN_TEMP, LED_GN_OFF_TIME, LED_GN_OFF_TIME *5); //Fehler Anzeigen
	BUTTON_SetModeOff(); //Damit nicht von alleine wieder eingeschaltet wird
	printf("NEW_STATE: MAINSWITCH_ERROR, Temp too high\n");
	smState = LVP_ERROR;          
  }


  //LVP oder OVP hat stattgefunden, und Relais ist ein, dann aus
  if ((lvpInput == 1) && (RELAIS_GetState() == 1)) 
  {
    RELAIS_ResetPuls();
    BUZZER_Beep(BUZZER_ON_TIME_REJECT); //Warnung
    LEDS_GN_Off();
    LEDS_RT_BlinkCode_Start(BLINK_CODE_ERROR_OVP_LVP, LED_RT_ON_TIME_WARN_OVP_AND_LVP_INPUT, LED_RT_OFF_TIME, LED_RT_OFF_TIME *5); //Fehler Anzeigen
    printf("LVP OFF!\n");
    printf("NEW_STATE: LVP_Auto On, Relais off\n");
    
  }

  //KEIN LVP und keine OVP Abschaltung, Relais ist aber noch aus, dann einschalten
  if ((lvpInput == 0) && (RELAIS_GetState() == 0))
  {
    RELAIS_SetPuls();
    BUZZER_Beep(BUZZER_ON_TIME_CONFIRM); //Warnung
    LEDS_GN_Off();
    LEDS_GN_Blink_Start(LED_GN_ON_TIME_ON_MODE, LED_GN_OFF_TIME);
    printf("LVP ON!\n");
    printf("NEW_STATE: LVP_OVP_Auto On, Relais on\n");
    
  }

  // Prüfe Wechsel in off mode
  if (BUTTON_GetMode() == BUTTON_OFF)
  {
    //Ausschalten muss immer möglich sein
    RELAIS_ResetPuls();
    BUZZER_Beep(BUZZER_ON_TIME_CONFIRM); //Bestätigung
    LEDS_GN_Off();
    LEDS_RT_Off();
    printf("NEW_STATE: LVP_OFF\n");
    smState = LVP_OFF;
	//Damit beim drücken auf on erstmal eingeschaltet wird
	lvpTimeCounter=0;
	lvpInput = 0;
  }


}

static void LVP_SM_ManualOn(void)
{
  // Prüfe Wechsel in off mode
  if (BUTTON_GetMode() == BUTTON_OFF)
  {
    //Ausschalten muss immer möglich sein
    RELAIS_ResetPuls();
    BUZZER_Alarm_Stop();
    LEDS_GN_Off();
    LEDS_RT_Off();
    printf("NEW_STATE: LVP_OFF\n");
    smState = LVP_OFF;
  }

}

static void LVP_SM_Error(void)
{
  int faultInput;
  int lvpAndOvpInput;

  if (HAL_GPIO_ReadPin(GPIO_INPUT_FAULT_GPIO_Port, GPIO_INPUT_FAULT_Pin) == GPIO_PIN_RESET)       
  {
    faultInput = 1;
  }
  else
  {
    faultInput = 0;
  }



  //Prüfe auf Wechsel des Modus AUTO / SM ON
  if (BUTTON_GetMode() == BUTTON_AUTO)
  {
    if (faultInput == 0) 
    {
      RELAIS_SetPuls();
      BUZZER_Beep(BUZZER_ON_TIME_CONFIRM);
      LEDS_GN_Blink_Start(LED_GN_ON_TIME_ON_MODE, LED_GN_OFF_TIME);
      LEDS_RT_Off(); //Fehler löschen
      printf("NEW_STATE: LVP_ON\n");
      smState = LVP_ON;
    }
    else
    {
      //Wechsel nicht möglich. Fehler Eingang weiterhin aktiv
      BUZZER_Beep(BUZZER_ON_TIME_REJECT);
      BUTTON_SetModeOff();
    }
  }

  //Prüfe auf Wechsel in MANUAL ON Mode
  //Keine Fehlerüberprüfungen. In diesem Modus werdem alle Alarme ignoriert.
  if (BUTTON_GetMode() == BUTTON_MANUAL_ON)
  {
      
      RELAIS_SetPuls();
      BUZZER_Alarm_Start(BUZZER_ON_TIME_ALARM_MANUAL_MODE, BUZZER_OFF_TIME);
      LEDS_GN_On();
      LEDS_RT_Off();
      LEDS_RT_BlinkCode_Start(BLINK_CODE_WARN_MANUAL, LED_RT_ON_TIME_WARN_MANUAL_MODE, LED_RT_OFF_TIME, LED_RT_OFF_TIME *5); //Fehler Anzeigen
      printf("NEW_STATE: LVP_MANUAL_ON\n");
      smState = LVP_MANUAL_ON;
  }



}



void MODE_LVP_Exec(void)
{

  

  switch (smState)
  {
    case LVP_OFF:
     LVP_SM_Off();
    break;

    case LVP_ON:
      LVP_SM_On();
    break;

    case LVP_MANUAL_ON:
      LVP_SM_ManualOn();
    break;

    case LVP_ERROR:
      LVP_SM_Error();
    break;

    default:
    break;
  }
}


