#ifndef _CP_DETECTION_H
#define _CP_DETECTION_H
/**
  ******************************************************************************
  * @file    cp_detection.h
  * @author  Edward Lien
  * @brief   This file provides Control Pilot Voltage detection with filter algorithm.
  * @Version    D0.01
  * @Date       2019/13/11
  ******************************************************************************
  */

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "cmsis_os.h"
#include "main.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
typedef struct
{
	uint8_t	State;
	uint32_t PositiveValue;
	uint32_t NegativeValue;
    uint8_t  MaxPTB;
    uint16_t MaxPTBCount;
    uint8_t  MaxNTB;
    uint16_t MaxNTBCount;
}sCPModuleResult_t;

typedef struct
{
	uint16_t CpP12VHigh;
	uint16_t CpP12VLow;
	uint16_t CpP9VHigh;
	uint16_t CpP9VLow;
	uint16_t CpP6VHigh;
	uint16_t CpP6VLow;
	uint16_t CpP3VHigh;
	uint16_t CpP3VLow;
	uint16_t Cp0VHigh;
	uint16_t Cp0VLow;
	uint16_t CpN12VHigh;
	uint16_t CpN12VLow;
}sCPVoltageBoundary_t;

typedef struct
{
	uint16_t HysteresisP12VHigh;
	uint16_t HysteresisP12VLow;
	uint16_t HysteresisP9VHigh;
	uint16_t HysteresisP9VLow;
	uint16_t HysteresisP6VHigh;
	uint16_t HysteresisP6VLow;
	uint16_t HysteresisP3VHigh;
	uint16_t HysteresisP3VLow;
	uint16_t Hysteresis0VHigh;
	uint16_t Hysteresis0VLow;
	uint16_t HysteresisN12VHigh;
	uint16_t HysteresisN12VLow;
}sCPVoltageHysteresis_t;

//typedef struct
//{
//	uint16_t *TB_P12V;
//	uint16_t *TB_P9V;
//	uint16_t *TB_P6V;
//	uint16_t *TB_P3V;
//	uint16_t *TB_0V;
//	uint16_t *TB_N12V;
//	uint16_t *TB_UD;
//
//}sCPTempBuffer_t;

//******************************************************************

#define FUNC_CP_ADC_MODIFY    //Hao@20210113: To avoid hard-coding in cp_detection.h/.c

#ifdef FUNC_CP_ADC_MODIFY

//#define FUNC_CP_ADC_MODIFY_DEBUG //Comment this line to DISABLE debug function
//#define TRACE_CP //Hao@20210120: Test

#define NEW_CP_SPEC

#ifdef NEW_CP_SPEC
#define NEW_CP_SPEC_20210525
#endif //NEW_CP_SPEC

#define FUNC_CP_CLASSIFY_TO_OV_RANGE
#define MODIFY_UNKNOWN_TO_STATE_E
#define MODIFY_STATE_F_HYSTERESIS
#define MODIFY_STATE_UNKNOWN_HYSTERESIS

#ifdef MODIFY_CP_DETECTION_STATE_F
#define MODIFY_UNKNOWN_TO_STATE_F
#endif

/*
                     _______(Rf)________
                     |                 |
                     |                 |
   (CP)              |     |\          |
   VinN______(RinN)__|_____|-\         |
                           |  \________|____Vout (to MCU ADC pin)
                           |  /
   VinP___(RinP)___(VopP)__|+/
                 |         |/
                 |
                (Rg)
                 |
                ////
*/

#define CP_ADC_REFVOLT      (3.343)		//AW
//#define CP_ADC_REFVOLT      (3.37)	//AX
#define CP_ADC_MIN_COUNT    (0)
#define CP_ADC_MAX_COUNT    (4096 - 1)
#define CP_ADC_RESOLUTION   (CP_ADC_REFVOLT / (CP_ADC_MAX_COUNT - CP_ADC_MIN_COUNT))

#define CP_ADC_OPA_RIN_P    (113.0)
#define CP_ADC_OPA_RIN_N    (475.0)
#define CP_ADC_OPA_RG       (15.0 + 0.287)
#define CP_ADC_OPA_RF       (53.6)

#define CP_ADC_OPA_VIN_P    (12.0)
#define CP_ADC_OPA_VOP_P    ((CP_ADC_OPA_VIN_P * CP_ADC_OPA_RG) / (CP_ADC_OPA_RIN_P + CP_ADC_OPA_RG))

#define CP_ADC_OPA_GAIN                 (CP_ADC_OPA_RF / CP_ADC_OPA_RIN_N)
#define CP_ADC_OPA_GAIN_RECIPROCAL      (CP_ADC_OPA_RIN_N / CP_ADC_OPA_RF)

#define CP_ADC_OPA_CALC_OPA_VOUT_SLOP   ((-1) * CP_ADC_OPA_GAIN)
#define CP_ADC_OPA_CALC_OPA_VOUT_OFFS   ((1 + CP_ADC_OPA_GAIN) * CP_ADC_OPA_VOP_P)

#define CP_ADC_OPA_CALC_OPA_VIN_SLOP    ((-1) * CP_ADC_OPA_GAIN_RECIPROCAL)
#define CP_ADC_OPA_CALC_OPA_VIN_OFFS    ((1 + CP_ADC_OPA_GAIN_RECIPROCAL) * CP_ADC_OPA_VOP_P)

#define CP_GET_OPA_VOUT(Vin)            (((Vin) * CP_ADC_OPA_CALC_OPA_VOUT_SLOP) + CP_ADC_OPA_CALC_OPA_VOUT_OFFS)
#define CP_GET_OPA_VOUT_ADC(Vin)        ((uint32_t)(CP_GET_OPA_VOUT(Vin) / CP_ADC_RESOLUTION))

#define CP_GET_OPA_VOLT_DIFF_ADC(VoltDiff)  (CP_GET_OPA_VOUT_ADC(0) - CP_GET_OPA_VOUT_ADC(VoltDiff))

#define CP_GET_OPA_VIN(Vout)                (((Vout) * CP_ADC_OPA_CALC_OPA_VIN_SLOP) + CP_ADC_OPA_CALC_OPA_VIN_OFFS)
#define CP_GET_OPA_VIN_USE_ADC(AdcCount)    (CP_GET_OPA_VIN(CP_ADC_RESOLUTION * (AdcCount)))


#ifdef FUNC_CP_ADC_MODIFY_DEBUG
void CP_ADC_OPA_PrintParam(void);
void CP_ADC_OPA_TestFormula(void);
void CP_ADC_OPA_TestBoundaryValue(void);
#endif

#ifdef TRACE_CP
void TRACE_CP_Print_CPModuleResult(sCPModuleResult_t *p, uint8_t bOK, long EQ_Sum, long EQ_NG1, long EQ_NG2);
#endif

#endif //FUNC_CP_ADC_MODIFY

//******************************************************************


/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define SYSTEM_STATE_UNKNOWN	            0x00
#define SYSTEM_STATE_A				        0x01
#define SYSTEM_STATE_B				        0x02
#define SYSTEM_STATE_C				        0x03
#define SYSTEM_STATE_D				        0x04
#define SYSTEM_STATE_E				        0x05
#define SYSTEM_STATE_F				        0x06

#define MAX_CLASSIFY_SECTION                8
#define MAX_SECTION_COUNT                   1000

#define MAX_STATE_COUNTER                   1

//******************************************************************

#ifdef FUNC_CP_ADC_MODIFY
#ifdef NEW_CP_SPEC
extern void CpDetectModuleInitialize(char SafetyRegulationCode);
#endif //NEW_CP_SPEC
#endif //FUNC_CP_ADC_MODIFY
extern void CpCalculate(uint32_t * adc_value, uint16_t sample_times, sCPModuleResult_t * result);
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */
#endif //_CP_DETECTION_H