#ifndef __GBT_27930_2015_H__
#define __GBT_27930_2015_H__
#include "msystem.h"
#include "canJ1939.h"
#include "interface.h"

#define GTB_27930_2015_VER  0x000101

// GBT27930 can addr
#define GBT_27930_2015_CHG  0x56
#define GBT_27930_2015_BMS  0xF4

// GBT27930 GPN
#define GBT_27930_2015_CHM  0x26
#define GBT_27930_2015_BHM  0x27

#define GBT_27930_2015_CRM  0x01
#define GBT_27930_2015_BRM  0x02

#define GBT_27930_2015_BCP  0x06
#define GBT_27930_2015_CTS  0x07
#define GBT_27930_2015_CML  0x08
#define GBT_27930_2015_BRO  0x09
#define GBT_27930_2015_CRO  0x0A

#define GBT_27930_2015_BCL  0x10
#define GBT_27930_2015_BCS  0x11
#define GBT_27930_2015_CCS  0x12
#define GBT_27930_2015_BSM  0x13

#define GBT_27930_2015_BMV  0x15
#define GBT_27930_2015_BMT  0x16
#define GBT_27930_2015_BSP  0x17

#define GBT_27930_2015_BST  0x19
#define GBT_27930_2015_CST  0x1A

#define GBT_27930_2015_BSD  0x1C
#define GBT_27930_2015_CSD  0x1D

#define GBT_27930_2015_BEM  0x1E
#define GBT_27930_2015_CEM  0x1F

#define GBT_27930_2015_DM1  0x20
#define GBT_27930_2015_DM2  0x21
#define GBT_27930_2015_DM3  0x22
#define GBT_27930_2015_DM4  0x23
#define GBT_27930_2015_DM5  0x24
#define GBT_27930_2015_DM6  0x25

// GBT27930 error bits 
#define GBT_27930_2015_ERROR    -1
#define GBT_27930_2015_NORMAL   0x0
#define GBT_27930_2015_TIMEOUT  0x1
#define GBT_27930_2015_UNKNOWN  0x2
#define GBT_27930_2015_MASK     0x3

// GBT27930 BMS error bits == BEM bits
#define GBT_27930_TIMEOUT_CRM_0x00     (0)
#define GBT_27930_TIMEOUT_CRM_0xAA     (2)
#define GBT_27930_TIMEOUT_CTS_CML      (8)
#define GBT_27930_TIMEOUT_CRO          (10)
#define GBT_27930_TIMEOUT_CCS          (16)
#define GBT_27930_TIMEOUT_CST          (18)
#define GBT_27930_TIMEOUT_CSD          (24)
#define GBT_27930_TIMEOUT_OTHER        (26)

// GBT27930 CHG error bits == CEM bits
#define GBT_27930_TIMEOUT_BRM       (0)
#define GBT_27930_TIMEOUT_BCP       (8)
#define GBT_27930_TIMEOUT_BRO       (10)
#define GBT_27930_TIMEOUT_BCS       (16)
#define GBT_27930_TIMEOUT_BCL       (18)
#define GBT_27930_TIMEOUT_BST       (20)
#define GBT_27930_TIMEOUT_BSD       (24)

#define GBT_27930_STOP_SECC                 (0)
#define GBT_27930_STOP_CMD                  (2)
#define GBT_27930_STOP_FAULT                (4)
#define GBT_27930_STOP_EVCC                 (6)
#define GBT_27930_STOP_BOXOVERTEMP          (8)
#define GBT_27930_STOP_CONTACTOR            (10)
#define GBT_27930_STOP_LINEOVERTEMP         (12)
#define GBT_27930_STOP_TRANSTION            (14)
#define GBT_27930_STOP_EMERGENCY            (16)
#define GBT_27930_STOP_OTHERS               (18)
#define GBT_27930_STOP_VOLTAGE_MISTACH      (24)
#define GBT_27930_STOP_CURRENT_MISTACH      (26)



#define GBT_27930_CURRENT_OFFSET    4000

typedef struct GBT27930_SPN
{
    uint32_t SPN:19;
    uint32_t FDI:5;
    uint32_t OC:7;
    uint32_t CM:1;
}GBT27930_SPN_t;

typedef struct GBT27930_BHM
{
    uint16_t bmsMaxVoltage; //BHM最高允许充电总电压
    uint16_t resv;
}GBT27930_BHM_t;

typedef struct GBT27930_BRM
{
    uint16_t bmsRatedVoltage; //BRM 整车动力蓄电池系统额定总电压/V,0.1 V/位,0 V 偏移量 
    uint16_t bmsRatedPowerAH; //BRM 整车动力蓄电池系统额定容量/Ah,0.1 Ah/位,0 Ah 偏移量
    uint8_t bmsVIN[18];       //BRM 车辆识别码(VIN)
    uint8_t resv[2];
}GBT27930_BRM_t;

typedef struct GBT27930_BCP              //报文功能: 充电参数配置阶段 BMS 发送给充电机的动力蓄电池充电参数。 
{
    uint16_t bmsMaxUnitVoltage_charging;  //BCP 单体动力蓄电池最高允许充电电压                SPN2816 单体动力蓄电池最高允许充电电压 数据分辨率:0.01 V/位,0 V 偏移量; 数据范围:0~24 V;
    uint16_t bmsPermitttedMaxCurrent;     //BCP 最高允许充电电流                             SPN2817 最高允许充电电流 数据分辨率:0.1 A/位, -400 A 偏移量;
    uint16_t bmsNominalTotalkWH;          //BCP 动力蓄电池标称总能量                         SPN2818 动力蓄电池标称总能量 数据分辨率:0.1 kW· h/位,0 kW· h 偏移量; 数据范围:0~1 000 kW· h;
    uint16_t bmsPermitttedMaxVoltage;     //BCP 最高允许充电总电压                           SPN2819 最高允许充电总电压 数据分辨率:0.1 V/位,0 V 偏移量;

    uint8_t bmsPermitttedMaxTemp;         //BCP 最高允许温度                                 SPN2820 最高允许动力蓄电池温度 数据分辨率:1 ℃/位, -50 ℃ 偏移量; 数据范围: -50 ℃ ~+200 ℃ ;
    uint8_t resv0;
    uint16_t bmsRatio;                    //BCP 整车动力蓄电池荷电状态                        SPN2821 整车动力蓄电池荷电状态(SOC) 数据分辨率:0.1%/位,0%偏移量; 数据范围:0~100%;
    uint16_t bmsVoltage;                  //BCP 整车动力蓄电池当前电池电压                    SPN2822 整车动力蓄电池当前电池电压 数据分辨率:0.1 V/位,0 V 偏移量。
}GBT27930_BCP_t;

typedef struct GBT27930_CML              //报文功能: 充电机发送给 BMS 充电机最大输出能力, 以便估算剩余充电时间。
{
    uint16_t chgMaxOutputVoltage;       //最高输出电压(V)
    uint16_t chgMinOutputVoltage;       //最低输出电压(V)
    uint16_t chgMaxOutputCurrent;       //最大输出电流(A)
    uint16_t chgMinOutputCurrent;       //最小输出电流(A)
}GBT27930_CML_t;

typedef struct GBT27930_BRO
{
    uint8_t status;
}GBT27930_BRO_t;

typedef struct GBT27930_CRO
{
    uint8_t status;
}GBT27930_CRO_t;

typedef struct GBT27930_BCL              // 报文功能: 让充电机根据电池充电需求来调整充电电压和充电电流, 确保充电过程正常进行。 如果充电机在1 s 内没有收到该报文, 即为超时错误, 充电机应立即结束充电。
{
    uint16_t bmsVoltage_request;        //电压需求(V)
    uint16_t bmsCurrent_request;        //电流需求(A)
    uint8_t  bmsChargeMode;             //充电模式(0x01: 恒压充电;0x02: 恒流充电)
    uint8_t  resv0;
}GBT27930_BCL_t;

typedef struct GBT27930_BCS              //报文功能: 让充电机监视充电过程中电池组充电电压、 充电电流等充电状态。
{
    uint16_t chargingVoltage;           //充电电压测量值(V)
    uint16_t chargingCurrent;           //充电电流测量值(A)
    uint16_t bmsUnitMaxVoltage;         //最高单体动力蓄电池电压及其组号
    uint8_t bmsSOC;                     //当前荷电状态SOC(%)
    uint8_t resv0;
    uint16_t bmsChargingNeedMinutes;    //估算剩余充电时间(min)
}GBT27930_BCS_t;

typedef struct GBT27930_CCS              //报文功能: 让 BMS 监视充电机当前输出的充电电流、 电压值等信息。
{
    uint16_t chgOutputVoltage;          //电压输出值(V)
    uint16_t chgOutputCurrent;          //电流输出值(A)
    uint16_t chgChargedMinutes;         //累计充电时间(min)
    uint8_t  chgOutputting;             //充电允许(<00>: = 暂停; <01>: = 允许)
    uint8_t  resv0;
}GBT27930_CCS_t;

typedef struct GBT27930_BSM              //报文功能: 充电阶段 BMS 发送给充电机的动力蓄电池状态信息。 
{
    uint8_t bmsUnitID_maxVoltage;       //最高单体动力蓄电池电压所在编号
    uint8_t bmsMaxTemp;                 //最高动力蓄电池温度
    uint8_t bmsUnitID_maxTemp;          //最高温度检测点编号
    uint8_t bmsMinTemp;                 //最低动力蓄电池温度
    uint32_t bmsUnitID_minTemp:8;          //最低动力蓄电池温度检测点编号
    uint32_t bmsBatteryOverTemp:2;          //单体 动 力 蓄 电 池 电 压 过 高/过 低
    uint32_t bmsBatteryOverSOC:2;           //整车动力蓄电池荷电状态 SOC 过高/过低
    uint32_t bmsBatteryOverCurrent:2;           //动力蓄电池充电过电流
    uint32_t bmsPowerBatteryOverTemp:2;         //动力蓄电池温度过高
    uint32_t bmsPowerBatteryOverRsizder:2;      //动力蓄电池绝缘状态
    uint32_t bmsPowerBatteryConnector:2;        //动力蓄电池组输出连接器连接状态
    uint32_t bmsPowerPermitted:2;               //充电允许
    uint32_t resv0:10;
}GBT27930_BSM_t;

typedef struct GBT27930_BMV              //报文功能: 各个单体动力蓄电池电压值。 
{
    uint16_t bmsUnitVoltage[256];
}GBT27930_BMV_t;

typedef struct GBT27930_BMT              //报文功能: 动力蓄电池温度。 
{
    uint8_t bmsUnitTemp[128];
}GBT27930_BMT_t;

typedef struct GBT27930_BSP              //报文功能: 动力蓄电池预留报文。
{
    uint8_t bmsUnitResv[16];
}GBT27930_BSP_t;

typedef struct GBT27930_BST              //报文功能: 让充电机确认 BMS 将发送中止充电报文以令充电机结束充电过程以及结束充电原因。
{
    uint32_t bmsReachedSOC:2;               //达到所需求的SOC 目标值
    uint32_t bmsReachedVoltage:2;           //达到总电压的设定值
    uint32_t bmsReachedUnitVoltage:2;       //达到单体电压的设定值
    uint32_t bmsCHGTermination:2;           //充电机主动中止

    uint32_t bmsInsulationFault:2;              //绝缘故障
    uint32_t bmsOutputConnectorOverTemp:2;      //输出连接器过温故障
    uint32_t bmsUnitsOverTemp:2;                //BMS 元件、 输出连接器过温
    uint32_t bmsChargeConnectorFault:2;         //充电连接器故障

    uint32_t bmsBatteryPackOverTemp:2;          //电池组温度过高故障
    uint32_t bmsHighVolRelayFault:2;            //高压继电器故障
    uint32_t bmsCheckpoint2Fault:2;             //检测点2 电压检测故障
    uint32_t bmsOtherFault:2;                   //其他故障

    uint32_t bmsCurrentOverReqeust:2;           //电流过大
    uint32_t bmsVoltageAbnormal:2;              //电压异常
    uint32_t bmsResv0:2;
    uint32_t bmsResv1:2;
}GBT27930_BST_t;

typedef struct GBT27930_CST              //报文功能: 让 BMS 确认充电机即将结束充电以及结束充电原因。 
{
    uint32_t chgReachedDemand:2;            //达到充电机设定的条件中止
    uint32_t chgManualTermination:2;        //人工中止
    uint32_t chgFaultTermination:2;         //故障中止
    uint32_t chgBMSTermination:2;           //BMS 主动中止

    uint32_t chgBoxOverTemp:2;              //充电机过温故障
    uint32_t chgConnectorFalut:2;           //充电连接器故障
    uint32_t chgLineOverTemp:2;             //充电机内部过温故障
    uint32_t chgPowerTransmitFault:2;       //所需电量不能传送

    uint32_t chgEmergencyStop:2;            //充电机急停故障
    uint32_t chgOtherFault:2;               //其他故障
    uint32_t chgResv0:2;
    uint32_t chgResv1:2;

    uint32_t chgCurrentMismatch:2;          //电流不匹配
    uint32_t chgVoltageAbnormal:2;          //电压异常
    uint32_t chgResv3:2;
    uint32_t chgResv4:2;
}GBT27930_CST_t;

typedef struct GBT27930_BSD              //报文功能: 让充电机确认 BMS 对于本次充电过程的充电统计数据。 
{
    uint8_t bmsSOC_EOF;                 //中止荷电状态SOC(%)
    uint8_t resv0;
    uint16_t bmsUnitMaxVoltage;         //动力蓄电池单体最低电压(V)
    uint16_t bmsUnitMinVoltage;         //动力蓄电池单体最高电压(V)
    uint8_t bmsMaxUnitTemp;             //动力蓄电池最低温度(℃ )
    uint8_t bmsMinUnitTemp;             //动力蓄电池最高温度(℃ )
}GBT27930_BSD_t;

typedef struct GBT27930_CSD              //报文功能: 确认充电机本次充电过程的充电统计数据。 
{
    uint16_t chgCumulativeMintues;      //累计充电时间(min)
    uint16_t chgCumulativeKWH;          //输出能量(kW· h)
    uint32_t chgCode;                   //充电机编号
}GBT27930_CSD_t;

typedef struct GBT27930_BEM
{
    uint32_t crm_0x00_timeout:2;
    uint32_t crm_0xAA_timeout:2;
    uint32_t resv0:4;

    uint32_t cts_or_cml_timeout:2;
    uint32_t cro_timeout:2;
    uint32_t resv1:4;

    uint32_t ccs_timeout:2;
    uint32_t cst_timeout:2;
    uint32_t resv2:4;

    uint32_t csd_timeout:2;
    uint32_t others:6;
}GBT27930_BEM_t;

typedef struct GBT27930_CEM
{
    uint32_t brm_timeout:2;
    uint32_t resv0:6;
    uint32_t bcp_timeout:2;
    uint32_t bro_timeout:2;
    uint32_t resv1:4;
    uint32_t bcs_timeout:2;
    uint32_t bcl_timeout:2;
    uint32_t bst_timeout:2;
    uint32_t resv2:4;
    uint32_t bsd_timeout:2;
    uint32_t others:6;

}GBT27930_CEM_t;

#define BHM_TIMEOUT     10000
#define BRM_TIMEOUT     5000
#define BCP_TIMEOUT     5000
#define BRO_0x00_TIMEOUT     5000
#define BRO_0xAA_TIMEOUT     60000

#define BSM_TIMEOUT     5000
#define BCL_TIMEOUT     1000
#define BCS_TIMEOUT     5000

typedef struct GBT27930
{
    const char *can_name;
    can_j1939_t canJ1939;
    uint8_t DA;
    uint8_t SA;
	short frame_interval_ms;// normal frame_interval_ms = 250;
    int fd[2];

    pthread_mutex_t mutex_can;
    pthread_cond_t  cond_can;
    //-------------chm
    GBT27930_BHM_t bhm;
    //-------------crm
    GBT27930_BRM_t brm;
    GBT27930_BCP_t bcp;
    GBT27930_BRO_t bro;
    GBT27930_BRO_t bro_last;
    GBT27930_CRO_t cro;
    GBT27930_CML_t cml;
    GBT27930_BCL_t bcl;
    GBT27930_BCL_t bcl_last;
    GBT27930_BCS_t bcs;
    GBT27930_CCS_t ccs;
    GBT27930_BSM_t bsm;
    GBT27930_BSM_t bsm_last;
    GBT27930_BMV_t bmv;
    GBT27930_BMT_t bmt;
    GBT27930_BSP_t bsp;
    GBT27930_BST_t bst;
    GBT27930_CST_t cst;
    GBT27930_BSD_t bsd;
    GBT27930_CSD_t csd;
    //-------------
    GBT27930_BEM_t bem;
    GBT27930_CEM_t cem;

    int64_t last_bro_ms;
    int64_t last_bcl_ms;
    int64_t last_bsm_ms;
    
    int quit;
    int stop;
    int lastPF;

	struct can_frame frame;
    struct can_frame frameCTS;
    struct can_frame frameCCS;

    mthread_t threadRx;
    mthread_t threadTx;

    pthread_mutex_t mutex;
    pthread_cond_t  cond;

    mthread_t thread;

    //--------------------------
    ccu_port_t *ccu;
    pcu_port_t *pcu;
    secc_port_t *secc;

}GBT27930_t;

void can_GBT27930_close_pipe(GBT27930_t* dev);
void can_GBT27930_open_pipe(GBT27930_t* dev);

void* can_GBT27930_loop(void* argv);

int can_GBT27930_read(GBT27930_t* dev, int timeout);
int can_GBT27930_wait(GBT27930_t* dev, int waitPF, int timeout);

int can_GBT27930_init(GBT27930_t* dev, const char *can_name);
void can_GBT27930_exit(GBT27930_t* dev);

int can_GBT27930_send_CEM(GBT27930_t* dev, GBT27930_CEM_t *req);

int can_GBT27930_send_CHM(GBT27930_t* dev);
int can_GBT27930_wait_BHM(GBT27930_t* dev, int timeout);

int can_GBT27930_send_CRM(GBT27930_t* dev, uint8_t status, uint32_t CHG_No, uint8_t *ZoneCode);
int can_GTB27930_wait_BRM(GBT27930_t* dev, int timeout);

int can_GBT27930_wait_BCP(GBT27930_t* dev, int timeout);
int can_GBT27930_send_CTS(GBT27930_t* dev, struct tm *ptm);
int can_GBT27930_send_CML(GBT27930_t* dev, GBT27930_CML_t* info);
int can_GBT27930_wait_BRO(GBT27930_t* dev, int timeout);
int can_GBT27930_send_CRO(GBT27930_t* dev, uint8_t status);

int can_GBT27930_wait_BCL(GBT27930_t* dev, int timeout);
int can_GBT27930_wait_BCS(GBT27930_t* dev, int timeout);
int can_GBT27930_send_CCS(GBT27930_t* dev, GBT27930_CCS_t* req);
int can_GBT27930_wait_BSM(GBT27930_t* dev, int timeout);
int can_GBT27930_wait_BMV(GBT27930_t* dev, int timeout);
int can_GBT27930_wait_BMT(GBT27930_t* dev, int timeout);
int can_GBT27930_wait_BSP(GBT27930_t* dev, int timeout);
int can_GBT27930_wait_BST(GBT27930_t* dev, int timeout);
int can_GBT27930_send_CST(GBT27930_t* dev, GBT27930_CST_t* req);

int can_GBT27930_wait_BSD(GBT27930_t* dev, int timeout);
int can_GBT27930_send_CSD(GBT27930_t* dev, GBT27930_CSD_t* req);

void can_GBT27930_show_BST(GBT27930_t* can);
void can_GBT27930_show_BEM(GBT27930_t* can);

#endif//__GBT_27930_2015_H__
