/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.h
  * @brief          : Header for main.c file.
  *                   This file contains the common defines of the application.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "stm32g0xx_hal.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */

typedef enum SWITCH_MODE {SWITCH_OFF = 0, SWITCH_ON, SWITCH_AUTO} switch_mode_t;
typedef enum RELAY_STATE {RELAY_IS_OPENED = 0, RELAY_IS_CLOSED, ONLY_BA_OPENED, ONLY_AB_OPENED} relay_state_t;

/* USER CODE END ET */

/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */

/* USER CODE END EC */

/* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */

/* USER CODE END EM */

/* Exported functions prototypes ---------------------------------------------*/
void Error_Handler(void);

/* USER CODE BEGIN EFP */

//#define DISABLE_SHORTCUT_DETECTION_DURING_SWITCH_OFF

#ifdef DISABLE_SHORTCUT_DETECTION_DURING_SWITCH_OFF
void DisableShortCutDetection(void);
void EnableShortCutDetection(void);
#endif

/* USER CODE END EFP */

/* Private defines -----------------------------------------------------------*/
#define DISABLE_VBOOST_Pin GPIO_PIN_13
#define DISABLE_VBOOST_GPIO_Port GPIOC
#define TP2_Pin GPIO_PIN_14
#define TP2_GPIO_Port GPIOC
#define TP4_Pin GPIO_PIN_15
#define TP4_GPIO_Port GPIOC
#define SENSE_TEMP_Pin GPIO_PIN_0
#define SENSE_TEMP_GPIO_Port GPIOA
#define U_BAT_SENSE_Pin GPIO_PIN_1
#define U_BAT_SENSE_GPIO_Port GPIOA
#define I_PLUS_SENSE_Pin GPIO_PIN_2
#define I_PLUS_SENSE_GPIO_Port GPIOA
#define U_SW_SENSE_Pin GPIO_PIN_3
#define U_SW_SENSE_GPIO_Port GPIOA
#define DAC_A_Pin GPIO_PIN_4
#define DAC_A_GPIO_Port GPIOA
#define DAC_B_Pin GPIO_PIN_5
#define DAC_B_GPIO_Port GPIOA
#define I_MINUS_SENSE_Pin GPIO_PIN_6
#define I_MINUS_SENSE_GPIO_Port GPIOA
#define AB_SENSE_1_Pin GPIO_PIN_7
#define AB_SENSE_1_GPIO_Port GPIOA
#define LED_FUNCTION_Pin GPIO_PIN_0
#define LED_FUNCTION_GPIO_Port GPIOB
#define LED_ERROR_Pin GPIO_PIN_1
#define LED_ERROR_GPIO_Port GPIOB
#define LED_STATE_Pin GPIO_PIN_2
#define LED_STATE_GPIO_Port GPIOB
#define DIP2_Pin GPIO_PIN_10
#define DIP2_GPIO_Port GPIOB
#define DIP3_Pin GPIO_PIN_11
#define DIP3_GPIO_Port GPIOB
#define DIP4_Pin GPIO_PIN_12
#define DIP4_GPIO_Port GPIOB
#define DIP5_Pin GPIO_PIN_13
#define DIP5_GPIO_Port GPIOB
#define DIP6_Pin GPIO_PIN_14
#define DIP6_GPIO_Port GPIOB
#define DIP7_Pin GPIO_PIN_15
#define DIP7_GPIO_Port GPIOB
#define OUT_CS_Pin GPIO_PIN_8
#define OUT_CS_GPIO_Port GPIOA
#define RS485_D_Pin GPIO_PIN_9
#define RS485_D_GPIO_Port GPIOA
#define OVP_IN_Pin GPIO_PIN_6
#define OVP_IN_GPIO_Port GPIOC
#define LVP_IN_Pin GPIO_PIN_7
#define LVP_IN_GPIO_Port GPIOC
#define RS485_R_Pin GPIO_PIN_10
#define RS485_R_GPIO_Port GPIOA
#define R2_Pin GPIO_PIN_11
#define R2_GPIO_Port GPIOA
#define RS485_DE_Pin GPIO_PIN_12
#define RS485_DE_GPIO_Port GPIOA
#define BTN1_Pin GPIO_PIN_15
#define BTN1_GPIO_Port GPIOA
#define OUT_CTRL_Pin GPIO_PIN_0
#define OUT_CTRL_GPIO_Port GPIOD
#define SW_OFF_Pin GPIO_PIN_2
#define SW_OFF_GPIO_Port GPIOD
#define SW_ON_Pin GPIO_PIN_3
#define SW_ON_GPIO_Port GPIOD
#define LED_SW_ERROR_Pin GPIO_PIN_3
#define LED_SW_ERROR_GPIO_Port GPIOB
#define LED_SW_STATE_Pin GPIO_PIN_4
#define LED_SW_STATE_GPIO_Port GPIOB
#define DIP0_Pin GPIO_PIN_8
#define DIP0_GPIO_Port GPIOB
#define DIP1_Pin GPIO_PIN_9
#define DIP1_GPIO_Port GPIOB
/* USER CODE BEGIN Private defines */

#define INVERTER_CAP_PRECHARGE

#ifdef DEBUG
	#define DEVICE_TYPE_ID						201
#else
	#ifdef VARIANT_24V
		#define DEVICE_TYPE_ID					202
	#else
		#define DEVICE_TYPE_ID					201
	#endif
#endif

#define FW_VERSION_MAJOR						1
#define FW_VERSION_MINOR						0
#define FW_VERSION_REVISION						0
#ifdef VARIANT_24V
	#define DEVICE_SN							0xEC565524  // ECSGSS24 = ECS Green Smart Switch, 24V version (Must be substituted with real serial number)
#else
	#define DEVICE_SN							0xEC565512  // ECSGSS12 = ECS Green Smart Switch, 12V version (Must be substituted with real serial number)
#endif

#define MB_BAUDRATE_DEFAULT						19200     // bit pro sekunde
#define MB_PARITY_MODE_DEFAULT					'e'       // EVEN  - GERADE
#define MB_STOPBITS_DEFAULT						1
#define MB_SLAVE_ADRESS_DEFAULT					1

#define ADC_CHANNELS							6
#define TEMP_CHANNEL							0
#define U_BAT_CHANNEL							1
#define I_PLUS_CHANNEL							2
#define U_SW_CHANNEL							3
#define MOSFETS_VDROP_CHANNEL					4
#define I_MINUS_CHANNEL							5

#define ADC_RESOLUTION							12      // 12 bits
#define ADC_MAX_VALUE							0xFFF	// 4095
#define ADC_VREF								3000    // mV

//#define INA240_MAX_DIFF_2_MEASURE				75	// mV

#ifdef VARIANT_24V
	#define CONTROL_CURRENT_A					380		// [A] long-term current limit of the device.
	#define SHORTCUT_CURRENT_mV					800		// [mV] Some big value to pass test sequence
	#define INRUSH_CURRENT_mV					1100	// [mV] Some big value to pass test sequence
	#define COPPER_V_DROP_AT_CONTROL_CURRENT_mV	56		// [mV] - must be measured on the board
#else
	#define CONTROL_CURRENT_A					500		// [A] long-term current limit of the device.
    #define SHORTCUT_CURRENT_mV					1500	// [mV] Some big value to pass test sequence
	#define INRUSH_CURRENT_mV					616		// [mV] Some big value to pass test sequence
	#define COPPER_V_DROP_AT_CONTROL_CURRENT_mV	150		// [mV] - must be measured on the board
#endif
//#define COPPER_V_DROP_AT_INRUSH_CURRENT		((INRUSH_CURRENT_A * COPPER_V_DROP_AT_CONTROL_CURRENT_A)/CONTROL_CURRENT_A)	// ~391mV
//#define COPPER_V_DROP_AT_SHORTCUT_CURRENT		((SHORTCUT_CURRENT_A * COPPER_V_DROP_AT_CONTROL_CURRENT_A)/CONTROL_CURRENT_A)	// ~1176mV
//#if COPPER_V_DROP_AT_INRUSH_CURRENT > 3000 || COPPER_V_DROP_AT_SHORTCUT_CURRENT > 3000 || COPPER_V_DROP_AT_CONTROL_CURRENT_A > 3000
//#error Voltage drop cannot be greater than 1.5V. See INA281B2 datasheet.
//#endif
#define ADC_VALUE_AT_INRUSH_CURRENT				((ADC_MAX_VALUE * INRUSH_CURRENT_mV)/ADC_VREF)
//#define ADC_VALUE_DELTA_AT_SHORTCUT_CURRENT	((ADC_MAX_VALUE * COPPER_V_DROP_AT_SHORTCUT_CURRENT)/ADC_VREF)  // 1605
#define ADC_VALUE_AT_CONTROL_CURRENT			((ADC_MAX_VALUE * COPPER_V_DROP_AT_CONTROL_CURRENT_mV)/ADC_VREF)	// 140
#define CURRENT_INTEGRAL_FREQ					320000U		// (7.5cycles + 12.5cycles)*1channels + (3.5cycles + 12.5cycles)*5channels = 20 + 80 = 100cycles @ 32MHz = 320 kHz
#ifdef VARIANT_24V
	#define CURRENT_INTEGRATION_PERIOD			575			// µs
#else
	#define CURRENT_INTEGRATION_PERIOD			1700		// µs
#endif
#if CURRENT_INTEGRATION_PERIOD < 31
#error CURRENT_INTEGRATION_PERIOD cannot be less then 31 µs!
#endif
#define CURRENT_INTEGRATION_STEPS				((CURRENT_INTEGRAL_FREQ * CURRENT_INTEGRATION_PERIOD) / (1000*1000))	// 640
//#define COPPER_TEMP_COEFFICIENT				0.00393f

#define DIP_IS_OFF								GPIO_PIN_SET
#define DIP_IS_ON								GPIO_PIN_RESET

#define OVP_PRESENT								GPIO_PIN_SET
#define OVP_NOT_PRESENT							GPIO_PIN_RESET

#define LVP_PRESENT								GPIO_PIN_SET
#define LVP_NOT_PRESENT							GPIO_PIN_RESET

#define OUT_CTRL_ACTIVATE						GPIO_PIN_SET
#define OUT_CTRL_DEACTIVATE						GPIO_PIN_RESET

#ifdef VARIANT_24V
    #define R19									30000	// Ohm. See schematic page 6. Revision 62
    #define R20									30000	// Ohm. See schematic page 6. Revision 62
    #define R27									30000	// Ohm. See schematic page 6. Revision 62
    #define R23									30000	// Ohm. See schematic page 6. Revision 62
    #define R24									30000	// Ohm. See schematic page 6. Revision 62
    #define R25									30000	// Ohm. See schematic page 6. Revision 62
    #define R26									10000	// Ohm. See schematic page 6. Revision 62
    #define R33									10000	// Ohm. See schematic page 6. Revision 62
    #define R35									1000	// Ohm. See schematic page 6. Revision 62
    #define R37									100000	// Ohm. See schematic page 6. Revision 62
    #define R43									100000	// Ohm. See schematic page 6. Revision 62
    #define R42									1000	// Ohm. See schematic page 6. Revision 62
    #if (R23 + R24 + R25 + R33 != R43) || R43 != R37 || R33 != R26 || (R19 + R20 + R27 + R26 != R43) || R35 != R42
    	#error Registers values are not correct!
    #endif
	#define MAX_POSSIBLE_DIFF_TO_MEASURE		((ADC_VREF * R35 /* ((R23 + R24 + R25) + R33)*/)/(2 /* R43 */* R33))  // 150mV
#else
    #define R31									10000	// Ohm. See schematic page 6. Revision 62
    #define R37									10000	// Ohm. See schematic page 6. Revision 62
    #define R23									47000	// Ohm. See schematic page 6. Revision 62
    #define R25									47000	// Ohm. See schematic page 6. Revision 62
    #define R22									10000	// Ohm. See schematic page 6. Revision 62
    #define R24									10000	// Ohm. See schematic page 6. Revision 62
    #define R33									470000	// Ohm. See schematic page 6. Revision 62
    #define R38									470000	// Ohm. See schematic page 6. Revision 62
    #if R31 != R37 || R23 != R25 || R22 != R24 || R33 != R38 || R31 != R22
    	#error Values of these two registers must be the same!
    #endif
	#define MAX_POSSIBLE_DIFF_TO_MEASURE		((ADC_VREF * /*R31*/ (R23 + R22))/(2 * R38 /*R22*/))  // 181mV
#endif
#define MAX_ALLOWED_MOSFETS_V_DROP				30	// mV
#define MAX_ALLOWED_MOSFETS_V_DROP_DELTA		30	// mV
#define MAX_ALLOWED_MOSFETS_V_DROP_ADC			((MAX_ALLOWED_MOSFETS_V_DROP * (ADC_MAX_VALUE/2)) / MAX_POSSIBLE_DIFF_TO_MEASURE) // 409
#define POS_ALLOWED_MOSFETS_V_DROP_ADC			(MAX_ALLOWED_MOSFETS_V_DROP_ADC + (ADC_MAX_VALUE/2))	// 2456
#define NEG_ALLOWED_MOSFETS_V_DROP_ADC			((ADC_MAX_VALUE/2) - MAX_ALLOWED_MOSFETS_V_DROP_ADC)	// 1638

#define MOSFET_CHANNEL_A						DAC_CHANNEL_1   //TIM_CHANNEL_1
#define MOSFET_CHANNEL_B						DAC_CHANNEL_2   //TIM_CHANNEL_2
#define DAC_3V									0xFFF
#define DAC_0V									0x00
#define DAC_STEP								15
#if DAC_3V % DAC_STEP
   #error DAC_STEP cannot be that value!
#endif

// MODBUS commands
#define COMMAND_SAVE_CONFIG                     1
#define COMMAND_RESTART_MODBUS                  2
#define COMMAND_RESTORE_DEFAULTS                3
#define COMMAND_SAVE_LOCK_KEY					5
#define COMMAND_ON_SWITCH                       10
#define COMMAND_OFF_SWITCH                      20
#define COMMAND_AUTO_SWITCH                     30
#define COMMAND_RESTART                         500
#define COMMAND_SAVE_CONFIG_WITH_SN             50403
#define COMMAND_OFFSET_CALIBRATION				40302
#define COMMAND_CURRENT_CALIBRATION				30201
#define COMMAND_CURRENT_OFFSET_CALIBRATION		60504
#define COMMAND_TURN_OVERLOAD_DETECTION_OFF		20304
#define COMMAND_TURN_OVERLOAD_DETECTION_ON		30405

#define U_BAT_CALC_PERIOD				        5	// ms
#ifdef VARIANT_24V
#define U_BAT_CRITICAL_VOLTAGE			        20000 // mV	(If voltage on battery is lower than 10V, then there is a probability that MOSFETs will not open/close properly)
#define U_BAT_RECOVERY_VOLTAGE			        24000 // mV	(If voltage on battery is higher than 12V, then it is fully recovered from possible previous discharge)
#else
#define U_BAT_CRITICAL_VOLTAGE			        10000 // mV	(If voltage on battery is lower than 10V, then there is a probability that MOSFETs will not open/close properly)
#define U_BAT_RECOVERY_VOLTAGE			        12000 // mV	(If voltage on battery is higher than 12V, then it is fully recovered from possible previous discharge)
#endif

#define BAT_CHARGE_SIGN_V						2  // mV If voltage on side A greater than voltage on side B by this value, then charging is going on

//#define VOLTAGE_RATIO							20  // When we have ±20mV on INA240A1, the input voltage is ±1mV

#define TEMP_SENSOR_mV_AT_MINUS30		        300		// in mV (See LM61 datasheet)
#define TEMP_SENSOR_mV_AT_PLUS100		        1600	// in mV (See LM61 datasheet)
#define TEMP_SENSOR_ADC_AT_MINUS30		        ((TEMP_SENSOR_mV_AT_MINUS30 * ADC_MAX_VALUE) / ADC_VREF)
#define TEMP_SENSOR_ADC_AT_PLUS100		        ((TEMP_SENSOR_mV_AT_PLUS100 * ADC_MAX_VALUE) / ADC_VREF)
#define TEMP_SENSOR_0_OFFSET			        600		// in mV
#define MIN_TEMP						        (-300)	// Celsium degrees (See LM61 datasheet)
#define MAX_TEMP						        (1000)	// Celsium degrees (See LM61 datasheet)
#define TEMP_RECOVER_PERCENT			        25		// When temperature drops to (critical - 25%) then we remove overtemperature flag

#define BTN_IS_PRESSED							GPIO_PIN_RESET

#define LVP_OVP_EVENT_NUM						4

#define SWCLK_Port					            GPIOA
#define SWCLK_Pin					            GPIO_PIN_14
#define SWDIO_Port					            GPIOA
#define SWDIO_Pin					            GPIO_PIN_13

#define OVERTEMP_ERROR							0
#define OVERCURRENT_ERROR						1
#define OVERLOAD_ERROR							2
#define LOWBAT_ERROR							3
#define HEATER_IS_ON							4
#define ABBA_VOLTAGE_ERROR						5
//#define OFFSET_CALLIB_ERROR					4
//#define OFFSET_CALLIB_IS_ON					5
//#define OFFSET_CALLIB_SEQ_ERROR				6
//#define EEPROM_SAVE_ERROR						7
//#define CURRENT_SENSOR_CALLIB_IS_ON			8
//#define CURRENT_SENSOR_CALLIB_TEMP_ERROR		9
//#define CURRENT_SENSOR_CALLIB_ERROR			10
//#define CURRENT_SENSOR_CALLIB_SEQ_ERROR		11
//#define CURRENT_SENSOR_OFFSET_CALLIB_IS_ON	14
//#define CURRENT_SENSOR_OFFSET_CALLIB_ERROR	15

#define VBOOST_OFF_TIMER				        htim14
#define VBOOST_ON_TIMER							htim7
#define VBOOST_ENABLE					        GPIO_PIN_SET
#define VBOOST_DISABLE					        GPIO_PIN_RESET

#define ON_MODE_AUTO_OFF_TIMER					htim16

#define I_RMS_SAMPLES_COUNT				        4096
#define I_RMS_SAMPLES_SUM_COUNT			        32

#define FC_WRITE_SINGLE_REGISTER		        0x06
#define FC_WRITE_MULTIPLE_REGISTER		        0x10

#define HOUR_TIME_INTERVALL						(2UL * 60000UL)	// 2 min for DEBUG

#define DAC_HANDLE								hdac1
#define DAC_CH_A								DOR1
#define DAC_CH_B								DOR2
#define DAC_CH_A_ALIGNMENT						DAC_DHR12R1_ALIGNMENT
#define DAC_CH_B_ALIGNMENT						DAC_DHR12R2_ALIGNMENT

/* USER CODE END Private defines */

#ifdef __cplusplus
}
#endif

#endif /* __MAIN_H */
