2 Commitit 899528ab23 ... 6c2b07747a

Tekijä SHA1 Viesti Päivämäärä
  zhouw 6c2b07747a 基本完成测试项自测 1 kuukausi sitten
  zhouw e63aa1390e 一致性大部通过 还需优化一些逻辑 1 kuukausi sitten
7 muutettua tiedostoa jossa 567 lisäystä ja 194 poistoa
  1. 132 54
      src/GBT2015/GBT27930.c
  2. 119 25
      src/GBT2015/GBT27930.h
  3. 269 97
      src/GBT2015/can_SECC.c
  4. 19 0
      src/ccu_define.h
  5. 11 1
      src/ccu_port.c
  6. 1 1
      src/main.c
  7. 16 16
      src/secc_port.c

+ 132 - 54
src/GBT2015/GBT27930.c

@@ -21,11 +21,14 @@ const _27930_table_t _27930_table[] =
     {GBT_27930_2015_CST,10},
     {GBT_27930_2015_CSD,250},
     {GBT_27930_2015_CEM,250},
+    {GBT_27930_2015_BRM,0,5000},
+    {GBT_27930_2015_BCP,0,5000},
     {GBT_27930_2015_BRO,0,5000},
     {GBT_27930_2015_BCL,0,1000},
     {GBT_27930_2015_BCS,0,5000},
     {GBT_27930_2015_BSM,0,1},//国标没有超时要求
-    {GBT_27930_2015_BST,0,10},
+    {GBT_27930_2015_BST,0,5000},
+    {GBT_27930_2015_BSD,0,10000},
 };
 
 static uint16_t Can_get_27930sendtime(uint8_t pgn_hex)
@@ -146,16 +149,20 @@ int can_GBT27930_read(GBT27930_t* dev, int timeout)
                         return GBT_27930_2015_BHM; 
                     } break;
                     case GBT_27930_2015_BRO: { 
-                        dev->bro_last.status = dev->bro.status;
-                        dev->bro.status = frame.data[0];
-                        return GBT_27930_2015_BRO; 
+                        if(frame.can_id == 0x900956f4){
+                            dev->bro_last.status = dev->bro.status;
+                            dev->bro.status = frame.data[0];
+                            return GBT_27930_2015_BRO; 
+                        }
                     } break;
                     case GBT_27930_2015_BCL: { 
-                        memcpy(&dev->bcl_last, &dev->bcl, sizeof(dev->bcl));
-                        dev->bcl.bmsVoltage_request = frame.data[0]|(frame.data[1]<<8); 
-                        dev->bcl.bmsCurrent_request = GBT_27930_CURRENT_OFFSET - (frame.data[2]|(frame.data[3]<<8)); 
-                        dev->bcl.bmsChargeMode = frame.data[4];
-                        return GBT_27930_2015_BCL;
+                         if(frame.can_id == 0x981056f4){
+                            memcpy(&dev->bcl_last, &dev->bcl, sizeof(dev->bcl));
+                            dev->bcl.bmsVoltage_request = frame.data[0]|(frame.data[1]<<8); 
+                            dev->bcl.bmsCurrent_request = GBT_27930_CURRENT_OFFSET - (frame.data[2]|(frame.data[3]<<8)); 
+                            dev->bcl.bmsChargeMode = frame.data[4];
+                            return GBT_27930_2015_BCL;
+                         }
                     }break;
                     case GBT_27930_2015_BSM: { 
                         memcpy(&dev->bsm_last, &dev->bsm, 8);
@@ -163,16 +170,20 @@ int can_GBT27930_read(GBT27930_t* dev, int timeout)
                         return GBT_27930_2015_BSM;
                     }break;
                     case GBT_27930_2015_BST: { 
-                        memcpy(&dev->bst, frame.data, 4);
-                        return GBT_27930_2015_BST;
+                        if(frame.can_id == 0x901956f4){
+                            memcpy(&dev->bst, frame.data, 4);
+                            return GBT_27930_2015_BST;
+                        }
                     }break;
                     case GBT_27930_2015_BSD: { 
-                        dev->bsd.bmsSOC_EOF = frame.data[0];
-                        dev->bsd.bmsUnitMaxVoltage = frame.data[1]|(frame.data[2]<<8);
-                        dev->bsd.bmsUnitMinVoltage = frame.data[3]|(frame.data[4]<<8);
-                        dev->bsd.bmsMaxUnitTemp = frame.data[5];
-                        dev->bsd.bmsMinUnitTemp = frame.data[6];
-                        return GBT_27930_2015_BSD;
+                         if(frame.can_id == 0x981C56f4){
+                            dev->bsd.bmsSOC_EOF = frame.data[0];
+                            dev->bsd.bmsUnitMaxVoltage = frame.data[1]|(frame.data[2]<<8);
+                            dev->bsd.bmsUnitMinVoltage = frame.data[3]|(frame.data[4]<<8);
+                            dev->bsd.bmsMaxUnitTemp = frame.data[5];
+                            dev->bsd.bmsMinUnitTemp = frame.data[6];
+                            return GBT_27930_2015_BSD;
+                         }
                     }break;
                     case GBT_27930_2015_BEM: { 
                         memcpy(&dev->bem, frame.data, 4);
@@ -274,6 +285,58 @@ int can_GBT27930_wait_n(GBT27930_t* dev,int pgn)
     return 0;
 }
 
+/**
+ * @brief 等待多个事件
+ * @param num 参数个数
+ * @note 最大不超过10个
+ */ 
+int can_GBT27930_waits(GBT27930_t* dev,uint8_t num, ...)
+{
+    secc_port_t* secc = (secc_port_t*)dev->secc;
+    printd("dev->fd[0]:%d\n", dev->fd[0]);
+    if (dev->fd[0] < 0 ) return GBT_27930_2015_ERROR;
+    int PF = 0; 
+    struct timeval start_time,cur_time;
+    gettimeofday(&start_time, NULL);    
+    fd_set readfds;
+    int rv;
+
+    va_list args;          
+    int ltemp[10];
+    
+    va_start(args, num);   
+    for (uint8_t i = 0; i < num; i++) {
+        ltemp[i] = va_arg(args, int);
+    }
+    
+    FD_ZERO(&readfds);
+    FD_SET(dev->fd[0], &readfds);
+    struct timeval tv;
+    // gettimeofday(&cur_time, NULL);   
+    // if(cur_time.tv_sec>= (start_time.tv_sec+timeout/1000))break;
+    // tv.tv_sec = start_time.tv_sec+timeout/1000 -cur_time.tv_sec ;
+    // tv.tv_usec = 2000;
+    // tv.tv_usec = (timeout%1000)*1000+cur_time.tv_usec-start_time.tv_usec;
+    tv.tv_usec = 0;
+    tv.tv_sec = 0;
+    rv = select(dev->fd[0]+1, &readfds, NULL, NULL, &tv);
+    
+    if (rv > 0)
+    {
+        if(FD_ISSET(dev->fd[0], &readfds))
+        {
+            int ret = recv(dev->fd[0], &PF, sizeof(PF), 0);
+            if (ret == sizeof(PF))
+            {       
+                   for (uint8_t i = 0; i < num; i++) {
+                    if(PF == ltemp[i]){va_end(args);return PF;}    
+                }
+            }
+        }
+    }
+    va_end(args);  
+    return GBT_27930_2015_ERROR;
+}
 
 typedef struct zw_send
 {
@@ -316,10 +379,10 @@ void Can_sendpoll(void* args)
     pthread_mutex_lock(&zw_mutex);
     for(uint8_t i;i<10;i++){
         if(zw_sendOb[i].pgn != 0)
-        {           
+        {       
             if(systime_ms()> (zw_sendOb[i].lastsend_time+zw_sendOb[i].inteval_ms)){
                 int ret = write(canJ1939->fd, &zw_sendOb[i].frame, sizeof(struct can_frame));
-                usleep(2); //避免总线拥挤,
+                usleep(1); //避免总线拥挤,
                 zw_sendOb[i].lastsend_time =  systime_ms();
             }
         }
@@ -341,7 +404,7 @@ void  can_APP_add(int pgn,struct can_frame* txframe)
     }
     if(p->pgn == 0)
     {
-        p->pgn = pgn;
+        p->pgn = pgn;       
         memcpy(&p->frame, txframe, sizeof(struct can_frame));
         p->inteval_ms = Can_get_27930sendtime(pgn);
         p->lastsend_time = 0 ;    
@@ -355,20 +418,29 @@ void  can_APP_add(int pgn,struct can_frame* txframe)
 /**
  * @brief 清除发送数据
  * @param pgn: 0时清除所有数据 
+ *             0xff  清除除CSD/CST/CEM意外的所有数据
  */
 void can_APP_clear(int pgn)
 {
-   pthread_mutex_lock(&zw_mutex);
-   if(pgn != 0){
-        zw_send_t* p = find_empty(pgn,0);
-        if(p != NULL)p->pgn = 0;
-   }else{
+    pthread_mutex_lock(&zw_mutex);
+    if(pgn ==0){
         for(uint8_t i =0;i<10;i++)
         {
             zw_sendOb[i].pgn = 0;
         } 
+    }else if(pgn == 0xff){
+        for(uint8_t i =0;i<10;i++)
+        {
+           if((zw_sendOb[i].pgn != GBT_27930_2015_CSD)&&(zw_sendOb[i].pgn != GBT_27930_2015_CST)&&(zw_sendOb[i].pgn != GBT_27930_2015_CEM))
+           {zw_sendOb[i].pgn = 0;}
+        }
+    }else{
+        for(uint8_t i =0;i<10;i++)
+        {
+         if(pgn == zw_sendOb[i].pgn)zw_sendOb[i].pgn = 0;
+        }
     }
-   pthread_mutex_unlock(&zw_mutex);
+    pthread_mutex_unlock(&zw_mutex);
 }
 
 //获取一个全局时间
@@ -395,21 +467,15 @@ static void* can_GBT27930_Txloop(void* args)
     
     static uint8_t cst_cnt =0 ; //发送2次cml 发送一次CTS
 	while(dev->quitTx == 0)
-	{
+    {
         time_run();
         if (dev->stop == 0)
         {
             Can_sendpoll(args);
-            pthread_mutex_lock(&dev->mutex);
-            if(dev->last_tickcnt++ >=dev->tickcnt){
-                dev->last_tickcnt = 0;
-                can_J1939_send(canJ1939, frame);
-            }
-            pthread_mutex_unlock(&dev->mutex);
         }
         msleep(dev->frame_interval_ms);
 	}
-    printd(".quitTx = 1\n");
+    printccui(".quitTx = 1\n");
     pthread_exit(NULL);
 	return NULL;
 }
@@ -478,9 +544,10 @@ static void* can_GBT27930_Rxloop(void* args)
             send(dev->fd[1], &PF, sizeof(PF), 0);
         }
 
-        if (PF == GBT_27930_2015_BST && dev->lastPF != GBT_27930_2015_BST)
+        if (PF == GBT_27930_2015_BST)
         {
-            secc_set_state(secc, GUN_STOPPING);
+            //secc_set_state(secc, GUN_STOPPING); 
+            send(dev->fd[1], &PF, sizeof(PF), 0); 
             can_GBT27930_show_BST(dev);
         }
 
@@ -567,7 +634,7 @@ int can_GBT27930_init(GBT27930_t* dev, const char *can_name)
         dev->bsm_last.bmsPowerPermitted = 1;
         dev->cro.status = 0x00;
         dev->can_name = can_name;
-        dev->frame_interval_ms = 10; //发送间隔最小是10ms
+        dev->frame_interval_ms = 2; //发送间隔最小是10ms
         printd("CAN(%s).connectorId[%d]...\n", dev->can_name, secc->config->connectorId);
         pthread_mutex_init(&dev->mutex, NULL);
         printd("step\n");
@@ -580,7 +647,7 @@ void can_GBT27930_exit(GBT27930_t* dev)
 {
     if (dev)
     {
-        printd("step\n");
+        printccui("step\n");
         secc_port_t* secc = (secc_port_t*)dev->secc;
         if (dev->quit == 0)
         {
@@ -628,6 +695,7 @@ int can_GBT27930_send_CEM(GBT27930_t* dev, GBT27930_CEM_t *req)
         // dev->last_tickcnt = 0;
         // pthread_mutex_unlock(&dev->mutex);
         can_APP_add(GBT_27930_2015_CEM,&txframe);
+        txframe.can_id = 0 ;
         return GBT_27930_2015_NORMAL;
 
         if (can_J1939_send(&dev->canJ1939, &txframe)==sizeof(struct can_frame))
@@ -660,12 +728,14 @@ int can_GBT27930_send_CHM(GBT27930_t* dev)
         txframe.can_dlc = 3;
         dev->stop = 0;
 
-        pthread_mutex_lock(&dev->mutex);
-        memcpy(&dev->frame, &txframe, sizeof(struct can_frame));
-        dev->tickcnt = Can_get_27930sendtime(GBT_27930_2015_CHM)/10;
-        dev->last_tickcnt = 0;
-        printTxCanFrame(dev->can_name, &dev->frame);
-        pthread_mutex_unlock(&dev->mutex);
+        // pthread_mutex_lock(&dev->mutex);
+        // memcpy(&dev->frame, &txframe, sizeof(struct can_frame));
+        // dev->tickcnt = Can_get_27930sendtime(GBT_27930_2015_CHM)/10;
+        // dev->last_tickcnt = 0;
+        // printTxCanFrame(dev->can_name, &dev->frame);
+        // pthread_mutex_unlock(&dev->mutex);
+        can_APP_add(GBT_27930_2015_CHM,&txframe);
+        txframe.can_id = 0 ;
         return GBT_27930_2015_NORMAL;
 
         if (can_J1939_send(&dev->canJ1939, &txframe)==sizeof(struct can_frame))
@@ -731,12 +801,15 @@ int can_GBT27930_send_CRM(GBT27930_t* dev, uint8_t status, uint32_t CHG_No, uint
         txframe.can_dlc = 8;
         dev->stop = 0;
 
+        can_APP_clear(GBT_27930_2015_CHM);
         can_APP_clear(GBT_27930_2015_CEM); //GB2015-27930-tab.d1
-        pthread_mutex_lock(&dev->mutex);
-        memcpy(&dev->frame, &txframe, sizeof(struct can_frame));
-        dev->tickcnt = Can_get_27930sendtime(GBT_27930_2015_CRM)/10;
-        dev->last_tickcnt = 0;
-        pthread_mutex_unlock(&dev->mutex);
+        // pthread_mutex_lock(&dev->mutex);
+        // memcpy(&dev->frame, &txframe, sizeof(struct can_frame));
+        // dev->tickcnt = Can_get_27930sendtime(GBT_27930_2015_CRM)/10;
+        // dev->last_tickcnt = 0;
+        // pthread_mutex_unlock(&dev->mutex);
+        can_APP_add(GBT_27930_2015_CRM,&txframe);
+        txframe.can_id = 0;
         return GBT_27930_2015_NORMAL;
 
         if (can_J1939_send(&dev->canJ1939, &txframe)==sizeof(struct can_frame))
@@ -839,6 +912,7 @@ int can_GBT27930_send_CTS(GBT27930_t* dev, struct tm *ptm)
         // dev->CTS_last_tickcnt = 0;
         // pthread_mutex_unlock(&dev->mutex);
         can_APP_add(GBT_27930_2015_CTS,&txframe);
+        txframe.can_id = 0;
         return GBT_27930_2015_NORMAL;
 
         if (can_J1939_send(&dev->canJ1939, &txframe) == sizeof(struct can_frame))
@@ -1074,6 +1148,7 @@ int can_GBT27930_send_CCS(GBT27930_t* dev, GBT27930_CCS_t* req)
         // memcpy(&dev->frame, &txframe, sizeof(struct can_frame));
         // // memcpy(&dev->frameCCS, &txframe, sizeof(struct can_frame));
         // pthread_mutex_unlock(&dev->mutex);
+        can_APP_clear(GBT_27930_2015_CRO);
         can_APP_add(GBT_27930_2015_CCS,&txframe);
         dev->frame.can_id = 0;
         return GBT_27930_2015_NORMAL;
@@ -1291,6 +1366,7 @@ int can_GBT27930_send_CSD(GBT27930_t* dev, GBT27930_CSD_t* req)
         
         memset(&txframe, 0, sizeof(struct can_frame));
         txframe.can_id = (Priority<<26)|(GBT_27930_2015_CSD<<16)|(dev->DA<<8)|dev->SA;
+        txframe.can_id |= CAN_EFF_FLAG;
         txframe.data[0] = (req->chgCumulativeMintues>>0)&0xFF;
         txframe.data[1] = (req->chgCumulativeMintues>>8)&0xFF;
         txframe.data[2] = (req->chgCumulativeKWH>>0)&0xFF;
@@ -1302,11 +1378,13 @@ int can_GBT27930_send_CSD(GBT27930_t* dev, GBT27930_CSD_t* req)
         txframe.can_dlc = 8;
         dev->stop = 0;
 		
-        pthread_mutex_lock(&dev->mutex);
-        memcpy(&dev->frame, &txframe, sizeof(struct can_frame));
-        dev->tickcnt = Can_get_27930sendtime(GBT_27930_2015_CSD)/10;
-        dev->last_tickcnt = 0;
-        pthread_mutex_unlock(&dev->mutex);
+        // pthread_mutex_lock(&dev->mutex);
+        // memcpy(&dev->frame, &txframe, sizeof(struct can_frame));
+        // dev->tickcnt = Can_get_27930sendtime(GBT_27930_2015_CSD)/10;
+        // dev->last_tickcnt = 0;
+        // pthread_mutex_unlock(&dev->mutex);
+        can_APP_add(GBT_27930_2015_CSD,&txframe);
+        dev->frame.can_id = 0;
         return GBT_27930_2015_NORMAL;
 
         if (can_J1939_send(&dev->canJ1939, &txframe)==sizeof(struct can_frame))

+ 119 - 25
src/GBT2015/GBT27930.h

@@ -91,40 +91,132 @@
 
 #define GBT_27930_CURRENT_OFFSET    4000
 
-
+#define GBT_27930_2015_NUL   (0)
 typedef struct
 {
-    uint32_t  GBT_27930_2015_BRO_recv:1;
-    uint32_t  GBT_27930_2015_BCL_recv:1;
-    uint32_t  GBT_27930_2015_BCS_recv:1;
-    uint32_t  GBT_27930_2015_BSM_recv:1;
-    uint32_t  GBT_27930_2015_reser:28;
+    union 
+    {
+        uint32_t  data;
+        struct{    
+            uint32_t  GBT_27930_2015_NUL_recv:2;
+            uint32_t  GBT_27930_2015_BRM_recv:2;
+            uint32_t  GBT_27930_2015_BCP_recv:2;  
+            uint32_t  GBT_27930_2015_BRO_recv:2;
+            uint32_t  GBT_27930_2015_BCL_recv:2;
+            uint32_t  GBT_27930_2015_BCS_recv:2;
+            uint32_t  GBT_27930_2015_BSM_recv:2;
+            uint32_t  GBT_27930_2015_BSD_recv:2;
+            uint32_t  GBT_27930_2015_BST_recv:2;
+            uint32_t  GBT_27930_2015_BSD_timeOut:2;
+            uint32_t  GBT_27930_2015_BST_timeOut:2; 
+            uint32_t  GBT_27930_2015_reser: 10;
+        };
+    };
 }_27930_recvFlag_t;
 uint16_t Can_get_27930Recvtime(uint8_t pgn_hex);
 
-//需求满足,
-#define RECV_BMS(dev,pgn,curtime)               do{\
-                                                    if(can_GBT27930_wait_n(dev,pgn)==pgn){ \
-                                                    _27930_recvFlag.pgn##_recv=1;\
-                                                    curtime =systime_ms();}\
-                                                    else{\
-                                                     if((curtime+Can_get_27930Recvtime(pgn))< systime_ms()){\
+#define  APPLY(X)                                 long int X##_curtime = systime_ms()
+/**按照协议结合框架执行协议处理*/
+#define  TIME_OUT(dev,pgn)                          secc_port_t* secc = (secc_port_t*)dev->secc;\
+                                                    if((secc->GUN_Error != 0)&&(secc->GUN_State !=GUN_STOPPING)){\
+                                                    printccui("secc->GUN_Error =%08x\n",secc->GUN_Error);\
+                                                    if(secc->GUN_Error <BMS_STOP_BY_SOC){secc_set_state(secc, GUN_EMERGRNCY_STOP);}\
+                                                    else if(secc->GUN_Error<= BMS_STOP_BY_OYRHER){secc_set_state(secc, GUN_STOPPING);}\
+                                                    else if (secc->GUN_Error == BCP_VOL_MISMATCH){secc_set_state(secc, GUN_EMERGRNCY_STOP);}\
+                                                    else if(secc->GUN_Error < GBT_27930_2015_COM_MAX){secc_set_state(secc, GUN_STOPPING);}\
+                                                    if((secc->GUN_Error == GBT_CC1_FALUT)||(secc->GUN_Error == GUN_ELECLOCK_FAULT)){\
+                                                        dev->cst.chgOtherFault = 1;\
+                                                        can_GBT27930_send_CST(dev,&dev->cst);\
+                                                        secc_set_state(secc, GUN_EMERGRNCY_STOP);\
+                                                    }\
+                                                    if(secc->GUN_Error == CCU_BATTERY_FAULT){\
+                                                        dev->cst.chgOtherFault = 1;\
+                                                        can_GBT27930_send_CST(dev,&dev->cst);\
+                                                        secc_set_error(secc, CCU_BATTERY_FAULT);\
+                                                    }\
+                                                    if(secc->GUN_Error == CCU_BATTERY_FAULT){\
+                                                        dev->cst.chgOtherFault = 1;\
+                                                        can_GBT27930_send_CST(dev,&dev->cst);\
+                                                        secc_set_error(secc, CCU_BATTERY_FAULT);\
+                                                    }\
+                                                    return GBT_27930_2015_ERROR;\
+                                                }\
+                                                if(pgn !=0){\
+                                                    if(_27930_recvFlag.pgn##_recv != 0)break;}
+
+#define RECV_BMS_1(dev,pgn)                 do{     int recv_pgn_flag =0 ;\
+                                                    int ret = can_GBT27930_waits(dev,2,pgn,GBT_27930_2015_BST);\
+                                                    if(ret == pgn){ \
+                                                        _27930_recvFlag.pgn##_recv=1;\
+                                                        pgn##_curtime =systime_ms();\
+                                                    }else if(ret == GBT_27930_2015_BST){\
+                                                        secc_port_t* secc = (secc_port_t*)dev->secc;\
+                                                        secc_request_power(secc, POWER_REQUEST_PLACE_FREE, 0, 0);\
+                                                        _27930_recvFlag.GBT_27930_2015_BST_recv=1;}\
+                                                    if((pgn##_curtime+Can_get_27930Recvtime(pgn))< systime_ms()){\
+                                                        printf("%s_timeout\n",#pgn);\
+                                                        recv_pgn_flag = pgn;\
+                                                    }\
+                                                    exit_handle(dev,recv_pgn_flag);\
+                                                }while(0) 
+
+#define RECV_BMS_2(dev,pgn,pgn1)                do{ int recv_pgn_flag =0 ;\
+                                                    int ret = can_GBT27930_waits(dev,3,pgn,pgn1,GBT_27930_2015_BST);\
+                                                    if(ret == pgn){ \
+                                                        _27930_recvFlag.pgn##_recv=1;\
+                                                        pgn##_curtime =systime_ms();\
+                                                    }else if(ret == pgn1){ \
+                                                        _27930_recvFlag.pgn1##_recv=1;\
+                                                        pgn1##_curtime =systime_ms();}\
+                                                    else if(ret == GBT_27930_2015_BST){\
+                                                        secc_port_t* secc = (secc_port_t*)dev->secc;\
+                                                        secc_request_power(secc, POWER_REQUEST_PLACE_FREE, 0, 0);\
+                                                        _27930_recvFlag.GBT_27930_2015_BST_recv=1;\
+                                                        GBT_27930_2015_BST_curtime =systime_ms();\
+                                                    }\
+                                                    if((pgn##_curtime+Can_get_27930Recvtime(pgn))< systime_ms()){\
+                                                        printf("%s_timeout\n",#pgn);\
+                                                        recv_pgn_flag = pgn;\
+                                                    }\
+                                                     if((pgn1##_curtime+Can_get_27930Recvtime(pgn1))< systime_ms()){\
+                                                        printf("%s_timeout\n",#pgn1);\
+                                                        recv_pgn_flag = pgn1;\
+                                                    }\
+                                                     exit_handle(dev,recv_pgn_flag);\
+                                                }while(0)    
+
+
+#define RECV_BMS_3(dev,pgn,pgn1,pgn2)         do{   int recv_pgn_flag = 0;\
+                                                    int ret = can_GBT27930_waits(dev,4,pgn,pgn1,pgn2,GBT_27930_2015_BST);\
+                                                    if(ret == pgn){ \
+                                                        _27930_recvFlag.pgn##_recv |=1;\
+                                                        pgn##_curtime =systime_ms();\
+                                                    }else if(ret == pgn1){ \
+                                                        _27930_recvFlag.pgn1##_recv |=1;\
+                                                        pgn1##_curtime =systime_ms();}\
+                                                    else if(ret == pgn2){ \
+                                                        _27930_recvFlag.pgn2##_recv |=1;\
+                                                        pgn2##_curtime =systime_ms();}\
+                                                    else if(ret == GBT_27930_2015_BST){\
+                                                        secc_port_t* secc = (secc_port_t*)dev->secc;\
+                                                        secc_request_power(secc, POWER_REQUEST_PLACE_FREE, 0, 0);\
+                                                        _27930_recvFlag.GBT_27930_2015_BST_recv=1;}\
+                                                    if((pgn##_curtime+Can_get_27930Recvtime(pgn))< systime_ms()){\
                                                         printf("%s_timeout\n",#pgn);\
-                                                        can_GBT27930_send_timeout(dev, pgn);\
-                                                        secc_set_state(secc, GUN_COMFALUT);\
-                                                        secc_set_error(secc, GUN_PRECHARGE_FAULT);\
-                                                        return GBT_27930_2015_ERROR;}\
+                                                        recv_pgn_flag = pgn;\
                                                     }\
+                                                    if((pgn1##_curtime+Can_get_27930Recvtime(pgn1))< systime_ms()){\
+                                                    printf("%s_timeout\n",#pgn1);\
+                                                    recv_pgn_flag = pgn1;\
+                                                    }\
+                                                    if(pgn2 != GBT_27930_2015_BSM){\
+                                                    if((pgn2##_curtime+Can_get_27930Recvtime(pgn2))< systime_ms()){\
+                                                        printf("%s_timeout\n",#pgn2);\
+                                                        recv_pgn_flag = pgn2;\
+                                                    }}\
+                                                    exit_handle(dev,recv_pgn_flag);\
                                                 }while(0)
 
-typedef struct
-{
-    uint32_t  GBT_27930_TIMEOUT_BRO_recv :1;
-    uint32_t  time_out:31;
-}timaaaaae_t;
-
-
-
 
 typedef struct GBT27930_SPN
 {
@@ -460,5 +552,7 @@ void can_GBT27930_show_BST(GBT27930_t* can);
 void can_GBT27930_show_BEM(GBT27930_t* can);
 
 void can_APP_clear(int pgn);
+int can_GBT27930_waits(GBT27930_t* dev,uint8_t num, ...);  
 
+void  exit_handle(GBT27930_t* dev,int pgn);
 #endif//__GBT_27930_2015_H__

+ 269 - 97
src/GBT2015/can_SECC.c

@@ -1,8 +1,9 @@
 #include "secc_port.h"
 #include "GBT27930.h"
 int can_GBT27930_wait_n(GBT27930_t* dev,int pgn);
-
 static _27930_recvFlag_t _27930_recvFlag;
+
+uint8_t  Global_flaut = 0;
 static int can_GBT27930_send_stop(GBT27930_t* dev, int REASON)
 {
     ccu_port_t *ccu = (ccu_port_t*)dev->ccu;
@@ -27,6 +28,13 @@ static int can_GBT27930_send_stop(GBT27930_t* dev, int REASON)
 }
 
 
+//接收补充设置
+void  pgn_run(GBT27930_t* dev,int pgn)
+{
+  
+}
+
+
 static int can_GBT27930_send_timeout(GBT27930_t* dev, int STATE)
 {
     ccu_port_t *ccu = (ccu_port_t*)dev->ccu;
@@ -35,16 +43,15 @@ static int can_GBT27930_send_timeout(GBT27930_t* dev, int STATE)
     memset(&dev->cem, 0, sizeof(dev->cem));
     switch(STATE)
     {
-        case GBT_27930_TIMEOUT_BRM:{dev->cem.brm_timeout=1;}break;
-        case GBT_27930_TIMEOUT_BCP:{dev->cem.bcp_timeout=1;}break;
+        case GBT_27930_2015_BRM:{dev->cem.brm_timeout=1;}break;
+        case GBT_27930_2015_BCP:{dev->cem.bcp_timeout=1;}break;
         case GBT_27930_2015_BRO:{dev->cem.bro_timeout=1;}break;
         case GBT_27930_2015_BCS:{dev->cem.bcs_timeout=1;}break;
         case GBT_27930_2015_BCL:{dev->cem.bcl_timeout=1;}break;
-        case GBT_27930_TIMEOUT_BST:{dev->cem.bst_timeout=1;}break;
-        case GBT_27930_TIMEOUT_BSD:{dev->cem.bsd_timeout=1;}break;
+        case GBT_27930_2015_BST:{dev->cem.bst_timeout=1;}break;
+        case GBT_27930_2015_BSD:{dev->cem.bsd_timeout=1;}break;
         default: {dev->cem.others=1;} break;
     }
-    can_APP_clear(0);
     return can_GBT27930_send_CEM(dev, &dev->cem);
 }
 
@@ -59,6 +66,7 @@ static int can_GBT27930_TryLock(GBT27930_t* dev, int timeout)
     if (secc->set_ELock_state(secc, 1, timeout) == 1)
     {
         pcu->update_ElecLock_state(pcu, 1);
+        printd("step.\n");
         secc_request_power(secc, POWER_REQUEST_PLACE_HOLD, 0.0f, 0.0f);
         secc_set_state(secc, GUN_ELOCKED);
         return 1;
@@ -107,13 +115,28 @@ static int can_GBT27930_Handshake(GBT27930_t* dev)
     ccu_port_t *ccu = (ccu_port_t*)dev->ccu;
     pcu_port_t *pcu = (pcu_port_t*)dev->pcu;
 
+    _27930_recvFlag.data = 0;
+
     printi("SECC(%d) Handshake...\n", secc->config->connectorId);
     secc->set_Aux12V_state(secc, 1);
     can_GBT27930_send_CHM(dev);
     int ret = can_GBT27930_wait(dev, GBT_27930_2015_BHM, BHM_TIMEOUT);
     if (ret == GBT_27930_2015_BHM)
     {
-        printv("BMS->bhm.bmsMaxVoltage:%f\n", (float)(dev->bhm.bmsMaxVoltage)/10);
+        printccui("BMS->bhm.bmsMaxVoltage:%f,secc->SECC_minV=%f\n", (float)(dev->bhm.bmsMaxVoltage)/10,secc->SECC_minV);
+        if(dev->bhm.bmsMaxVoltage < secc->SECC_minV*10){
+            can_APP_clear(0);
+            secc->set_Aux12V_state(secc, 0);
+            printccui("step\n");
+            if (secc->set_ELock_state(secc, 0, 1000)==1)
+            {
+                pcu->update_ElecLock_state(pcu, 0); 
+            }else{
+                secc_set_error(secc, GUN_ELECLOCK_STALL);
+            }
+            while(1){sleep(1);}  //停在这里 等待拔枪以后自己删除线程
+
+        }
         secc_set_state(secc, GUN_INSULATION);
         return 1;
     }
@@ -143,7 +166,6 @@ static int can_GBT27930_Insulation(GBT27930_t* dev)
         secc_set_error(secc, GUN_CONTACTOR_FAULT);
         return -1;
     }
-
     for (now_ms = systime_ms(); now_ms <= end_ms; now_ms = systime_ms())
     {
         if (0.0f <= secc->VMeters && secc->VMeters < 10.0f) { break; }
@@ -160,7 +182,6 @@ static int can_GBT27930_Insulation(GBT27930_t* dev)
         }
         return -1;
     }
-
     if (secc->set_K1K2_state(secc, 1, 1000) == 1) 
     {
         pcu->update_K1K2_state(pcu, 1, 1);
@@ -168,10 +189,9 @@ static int can_GBT27930_Insulation(GBT27930_t* dev)
         secc_set_error(secc, GUN_CONTACTOR_FAULT);
         return -1;
     }
-
     float Vimd = ((float)dev->bhm.bmsMaxVoltage)/10;
-    Vimd = fminf(Vimd, 1000.0f);
-    Vimd = fmaxf(Vimd, 500.0f);
+    Vimd = fminf(Vimd, 500.0f);//取2者的小值
+   // Vimd = fmaxf(Vimd, 500.0f);
 
     secc->set_IMD_state(secc, 1);
     secc_request_power(secc, POWER_REQUEST_INSULATION, Vimd, 0);
@@ -220,6 +240,66 @@ static int can_GBT27930_Insulation(GBT27930_t* dev)
                                             XFlag = XFlag+1-systime_ms();\
                                             }while(0)      
 
+
+void  exit_handle(GBT27930_t* dev,int pgn)
+{   
+    secc_port_t *secc = (secc_port_t*)dev->secc;
+    switch (pgn)
+    {
+        case 0:
+            if(_27930_recvFlag.GBT_27930_2015_BSD_recv != 0){
+            can_APP_clear(GBT_27930_2015_CST);
+            can_GBT27930_send_CSD(dev, &dev->csd);
+            _27930_recvFlag.GBT_27930_2015_BSD_recv == 3;
+            }
+            if(_27930_recvFlag.GBT_27930_2015_BCP_recv != 0){
+                can_APP_clear(GBT_27930_2015_CRM);
+                _27930_recvFlag.GBT_27930_2015_BCP_recv == 3;       
+            }
+            if(_27930_recvFlag.GBT_27930_2015_BST_recv == 1)
+            {
+                if(dev->secc->GUN_State != GUN_STOPPING){
+                    can_APP_clear(0xff);
+                    if(dev->bst.bmsReachedSOC ==1){ secc_set_error(secc, BMS_STOP_BY_SOC);}
+                    else if(dev->bst.bmsReachedVoltage ==1){ secc_set_error(secc, BMS_STOP_BY_GLOB_VOL);}
+                    else if(dev->bst.bmsReachedUnitVoltage ==1){ secc_set_error(secc, BMS_STOP_BY_SIG_VOL);}
+                    else {secc_set_error(secc, BMS_STOP_BY_OYRHER);}
+                }
+            }
+        break;
+        case GBT_27930_2015_BRM:
+            can_GBT27930_send_timeout(dev, GBT_27930_2015_BRM);
+            secc_set_error(secc, GBT_27930_2015_BRM_TIMEOUT);
+        break;      
+        case GBT_27930_2015_BRO:
+            can_GBT27930_send_timeout(dev, GBT_27930_2015_BRO);
+            secc_set_error(secc, GBT_27930_2015_BRO_TIMEOUT);
+        break;          
+        case GBT_27930_2015_BSD:
+            can_GBT27930_send_timeout(dev, GBT_27930_2015_BSD);
+        break;
+        case GBT_27930_2015_BST:
+            _27930_recvFlag.GBT_27930_2015_BST_timeOut = 1;
+            can_GBT27930_send_timeout(dev, GBT_27930_2015_BST);
+        break;
+        case GBT_27930_2015_BCP:
+            can_GBT27930_send_timeout(dev, GBT_27930_2015_BCP);
+            secc_set_error(secc, GBT_27930_2015_BCP_TIMEOUT);
+        break;   
+        case GBT_27930_2015_BCL:
+            can_GBT27930_send_timeout(dev, GBT_27930_2015_BCL);
+            secc_set_error(secc, GBT_27930_2015_BCL_TIMEOUT);
+        break; 
+            case GBT_27930_2015_BCS:
+            can_GBT27930_send_timeout(dev, GBT_27930_2015_BCS);
+            secc_set_error(secc, GBT_27930_2015_BCS_TIMEOUT);
+        break; 
+        default:
+        break;
+        }
+   
+}
+
 static int can_GBT27930_PreCharge(GBT27930_t* dev)
 {
     int ret;
@@ -227,65 +307,75 @@ static int can_GBT27930_PreCharge(GBT27930_t* dev)
     ccu_port_t *ccu = (ccu_port_t*)dev->ccu;
     pcu_port_t *pcu = (pcu_port_t*)dev->pcu;
     printccui("PreCharge charge start\n");
+    long int wait_time ;
     //----------等待车端BRM就绪----------
     can_GBT27930_send_CRM(dev, 0x00, 0xFFFFFFFF, NULL);
-    ret = can_GBT27930_wait(dev, GBT_27930_2015_BRM, BRM_TIMEOUT);
-    if (ret != GBT_27930_2015_BRM)
+    APPLY(GBT_27930_2015_BRM);
+    WAIT_CONDI(
+        wait_time,1000000,
+        ,
+        RECV_BMS_1(dev,GBT_27930_2015_BRM);
+        TIME_OUT(dev,GBT_27930_2015_BRM);
+    );
+    printccui("step\n");
+    //----------等待车端电池电压----------
+    can_GBT27930_send_CRM(dev, 0xAA, 0xFFFFFFFF, NULL);
+    APPLY(GBT_27930_2015_BCP);
+    WAIT_CONDI(
+        wait_time,1800000,
+        ,
+        RECV_BMS_1(dev,GBT_27930_2015_BCP);
+        TIME_OUT(dev,GBT_27930_2015_BCP);
+    );
+
+    printccui("step\n");
+    printi("SECC(%d).bcp.bmsPermitttedMaxVoltage:%d, bmsPermitttedMaxCurrent:%d, bmsNominalTotalkWH:%d, bmsVoltage:%d \n", secc->config->connectorId, dev->bcp.bmsPermitttedMaxVoltage, dev->bcp.bmsPermitttedMaxCurrent, dev->bcp.bmsNominalTotalkWH, dev->bcp.bmsVoltage);
+    printd("SECC(%d) PreCharging.maxVoltage:%f,minVoltage:%f, maxCurrent:%f, minCurrent:%f\n", secc->config->connectorId, secc->SECC_maxV, secc->SECC_minV, secc->SECC_maxI, secc->SECC_minI);
+    if (dev->bcp.bmsPermitttedMaxVoltage < secc->SECC_minV) 
     {
-        printccui("BRM_TIMEOUT\n");
-        can_GBT27930_send_timeout(dev, GBT_27930_TIMEOUT_BRM);
+        can_GBT27930_send_stop(dev, GBT_27930_STOP_VOLTAGE_MISTACH);
         secc_set_error(secc, GUN_PRECHARGE_FAULT);
-        secc_set_state(secc, GUN_COMFALUT);
+        printd("SECC(%d) BMS Battery Voltage exceed the range of SECC\n", secc->config->connectorId);
         return GBT_27930_2015_ERROR;
     }
-    
-    //----------等待车端电池电压----------
-    can_GBT27930_send_CRM(dev, 0xAA, 0xFFFFFFFF, NULL);
-    ret = can_GBT27930_wait(dev, GBT_27930_2015_BCP, BCP_TIMEOUT);
-    if (ret != GBT_27930_2015_BCP)
+    //GB18487.1-2023.B.4.4
+    if(((dev->bcp.bmsVoltage*1.05) < (uint16_t)(secc->VMeters*10 + 0.5))|| ((dev->bcp.bmsVoltage*0.95) > (uint16_t)(secc->VMeters*10 + 0.5)))
     {
-        printccui("BCP_TIMEOUT\n");
-        can_GBT27930_send_timeout(dev, GBT_27930_TIMEOUT_BCP);
+        can_GBT27930_send_stop(dev, GBT_27930_STOP_VOLTAGE_MISTACH);
         secc_set_error(secc, GUN_PRECHARGE_FAULT);
-        secc_set_state(secc, GUN_COMFALUT);
+        printd("SECC(%d) BMS Battery Voltage exceed the range of SECC\n", secc->config->connectorId);
         return GBT_27930_2015_ERROR;
     }
-    
-    printi("SECC(%d).bcp.bmsPermitttedMaxVoltage:%d, bmsPermitttedMaxCurrent:%d, bmsNominalTotalkWH:%d, bmsVoltage:%d \n", secc->config->connectorId, dev->bcp.bmsPermitttedMaxVoltage, dev->bcp.bmsPermitttedMaxCurrent, dev->bcp.bmsNominalTotalkWH, dev->bcp.bmsVoltage);
-    printd("SECC(%d) PreCharging.maxVoltage:%f,minVoltage:%f, maxCurrent:%f, minCurrent:%f\n", secc->config->connectorId, secc->SECC_maxV, secc->SECC_minV, secc->SECC_maxI, secc->SECC_minI);
-    if (dev->bcp.bmsPermitttedMaxVoltage < secc->SECC_minV)
+    //GB18487.1-2023.B.4.4
+    if(((uint16_t)(secc->VMeters*10 + 0.5) >secc->SECC_maxV) ||(((uint16_t)(secc->VMeters*10 + 0.5) <secc->SECC_minV)))
     {
         can_GBT27930_send_stop(dev, GBT_27930_STOP_VOLTAGE_MISTACH);
         secc_set_error(secc, GUN_PRECHARGE_FAULT);
         printd("SECC(%d) BMS Battery Voltage exceed the range of SECC\n", secc->config->connectorId);
         return GBT_27930_2015_ERROR;
     }
+    printccui("step\n");
     //----------通知车端启动绝缘检测---------
     dev->cml.chgMaxOutputVoltage = (uint16_t)(secc->SECC_maxV*10 + 0.5);
     dev->cml.chgMinOutputVoltage = (uint16_t)(secc->SECC_minV*10 + 0.5);
     dev->cml.chgMaxOutputCurrent = (uint16_t)(secc->SECC_maxI*10 + 0.5);
     dev->cml.chgMinOutputCurrent = (uint16_t)(secc->SECC_minI*10 + 0.5);
     can_GBT27930_send_CML(dev, &dev->cml);
-    long int wait_time ;
+    can_GBT27930_send_CTS(dev, NULL); 
+    
+    APPLY(GBT_27930_2015_BRO);
     WAIT_CONDI(
         wait_time,60000,
-        SPILTE(
-            can_GBT27930_send_timeout(dev, GBT_27930_2015_BRO);
-            secc_set_state(secc, GUN_COMFALUT);
-            secc_set_error(secc, GUN_PRECHARGE_FAULT);
-            //printd("SECC(%d) BMS Insulation timeout or fault.\n", secc->config->connectorId);
-            printccui("SECC(%d) BMS Insulation timeout or fault.\n", secc->config->connectorId);
-            return GBT_27930_2015_ERROR;
-        ),
-        can_GBT27930_send_CTS(dev, NULL);        
-        ret = can_GBT27930_wait_n(dev, GBT_27930_2015_BRO);
-        if(ret == GBT_27930_2015_BRO)break;
+        , 
+        RECV_BMS_1(dev,GBT_27930_2015_BRO);
+        TIME_OUT(dev,GBT_27930_2015_BRO);         
     );
+    printccui("step\n");
     //----------等待车端绝缘检测完成----------
     can_GBT27930_send_CML(dev, &dev->cml);
     dev->bro.status = 0x00;//清零
     WAIT_CONDI(  
-          wait_time,60000,
+          wait_time,wait_time,
           SPILTE(
             can_GBT27930_send_timeout(dev, GBT_27930_2015_BRO);
             secc_set_state(secc, GUN_COMFALUT);
@@ -295,26 +385,26 @@ static int can_GBT27930_PreCharge(GBT27930_t* dev)
             return GBT_27930_2015_ERROR;
             ),  
            can_GBT27930_send_CTS(dev, NULL); 
-           if( dev->bro.status == 0xaa)
-           {
-            printf(",ambdnabdn");
-            break;
-           }
+           if( dev->bro.status == 0xaa)break;          
+           TIME_OUT(dev,GBT_27930_2015_NUL); 
+           
     );
+    printccui("step\n");
     can_APP_clear(GBT_27930_2015_CML); ////GB2015-27930-tab.d1
     can_APP_clear(GBT_27930_2015_CTS);
     //----------开始调整桩端电压----------
     can_GBT27930_send_CRO(dev, 0x00);
-   
-    long int bro_time = systime_ms();
     
     WAIT_CONDI(  
         wait_time,60000,          
         SPILTE(
+            can_GBT27930_send_stop(dev, GBT_27930_STOP_VOLTAGE_MISTACH);
             secc_set_error(secc, GUN_PRECHARGE_FAULT);
+            return GBT_27930_2015_ERROR;
         ),
      //   RECV_BMS(dev,GBT_27930_2015_BRO,bro_time);
-        RECV_BMS(dev,GBT_27930_2015_BRO,bro_time);
+        RECV_BMS_1(dev,GBT_27930_2015_BRO);
+        TIME_OUT(dev,GBT_27930_2015_NUL)
         float VBattery = ((float)dev->bcp.bmsVoltage) / 10;
         float VDelta = fabs(secc->VGround - secc->VMeters);
         //printd("SECC(%d) SECC_minV:%f, VMeters:%f, SECC_maxV:%f, VGround:%f, VDelta:%f\n", secc->config->connectorId, secc->SECC_minV, secc->VMeters, secc->SECC_maxV, secc->VGround, VDelta);
@@ -328,8 +418,14 @@ static int can_GBT27930_PreCharge(GBT27930_t* dev)
             printd("SECC(%d).VMeters:%f, VGround:%f, VBattery:%f\n", secc->config->connectorId, secc->VMeters, secc->VGround, VBattery);
             secc_request_power(secc, POWER_REQUEST_CONST_VOLTAGE, VBattery, 0.0f);
         }
+        if(dev->bro.status == 0x00){
+            Global_flaut = 'b';
+            secc_set_state(secc, GUN_EMERGRNCY_STOP);
+            return GBT_27930_2015_ERROR;
+        }
         msleep(200);
     );
+    printccui("step\n");
     secc_set_error(secc, GUN_PRECHARGE_FAULT);
     return GBT_27930_2015_ERROR;
 }
@@ -371,19 +467,21 @@ static int can_GBT27930_Charging(GBT27930_t* dev)
     printi("step\n");
     can_GBT27930_send_CRO(dev, 0xAA);
     printccui("step\n");
-    ret = can_GBT27930_wait(dev, GBT_27930_2015_BCL, BCL_TIMEOUT);
+    //ret = can_GBT27930_wait(dev, GBT_27930_2015_BCL, BCL_TIMEOUT);
     printccui("step\n");
-    long int bcs_time = systime_ms();
-    long int bcl_time = systime_ms();
+    APPLY(GBT_27930_2015_BCS);
+    APPLY(GBT_27930_2015_BCL);
+    APPLY(GBT_27930_2015_BSM);
     int start_sendCCS = 0;
     while(secc_should_stop(secc) != 1)
     {
         //int ret = can_GBT27930_wait(dev, 3<<24, 1000,GBT_27930_2015_BCS,GBT_27930_2015_BCL,GBT_27930_2015_BSM);
-        RECV_BMS(dev,GBT_27930_2015_BCL,bcl_time);
-        RECV_BMS(dev,GBT_27930_2015_BCS,bcs_time);
-        if(can_GBT27930_wait_n(dev,GBT_27930_2015_BSM)==GBT_27930_2015_BSM){
-         _27930_recvFlag.GBT_27930_2015_BSM_recv = 1;
-        }
+
+        RECV_BMS_3(dev,GBT_27930_2015_BCS,GBT_27930_2015_BCL,GBT_27930_2015_BSM);
+        TIME_OUT(dev,GBT_27930_2015_NUL)
+        // if(can_GBT27930_wait_n(dev,GBT_27930_2015_BSM)==GBT_27930_2015_BSM){
+        //  _27930_recvFlag.GBT_27930_2015_BSM_recv = 1;
+        // }
  
        if(_27930_recvFlag.GBT_27930_2015_BCL_recv==1){ 
             _27930_recvFlag.GBT_27930_2015_BCL_recv = 0 ;
@@ -394,8 +492,8 @@ static int can_GBT27930_Charging(GBT27930_t* dev)
                 float voltage = (((float)dev->bcl.bmsVoltage_request) / 10);
                 float current = (((float)dev->bcl.bmsCurrent_request) / 10);
                 //printi("SECC(%d) BCL voltage:%f, current:%f, mode:%d\n", secc->config->connectorId, voltage, current, dev->bcl.bmsChargeMode);
-                printccui("SBCL secc->VMeters:%f, secc->VGround:%f,secc->I=IMeters:%f\n",secc->VMeters, secc->VGround,secc->IMeters);
-                //printccui("SECC(%d) BCL voltage:%f, current:%f, mode:%d\n", secc->config->connectorId, voltage, current, dev->bcl.bmsChargeMode);
+                //printccui("SBCL secc->VMeters:%f, secc->VGround:%f,secc->I=IMeters:%f\n",secc->VMeters, secc->VGround,secc->IMeters);
+                printccui("SECC(%d) BCL voltage:%f, current:%f, mode:%d\n", secc->config->connectorId, voltage, current, dev->bcl.bmsChargeMode);
                 if (dev->bcl.bmsChargeMode == 1) { secc_request_power(secc, POWER_REQUEST_CONST_VOLTAGE, voltage, current); }
                 if (dev->bcl.bmsChargeMode == 2) { secc_request_power(secc, POWER_REQUEST_CONST_CURRENT, voltage, current); }
             }
@@ -403,54 +501,46 @@ static int can_GBT27930_Charging(GBT27930_t* dev)
 
         if(_27930_recvFlag.GBT_27930_2015_BCS_recv == 1){
             _27930_recvFlag.GBT_27930_2015_BCS_recv = 0;
-            start_sendCCS |= 3; 
+            start_sendCCS |= 2; 
             bcs_ms = systime_ms();
             secc->EV_Charging_current = ((float)dev->bcs.chargingCurrent) / 10;
             secc->EV_Charging_voltage = ((float)dev->bcs.chargingVoltage) / 10;
             secc->EV_Estimate_Minutes = dev->bcs.bmsChargingNeedMinutes;
             secc->SOC = dev->bcs.bmsSOC;
             //printi("SECC(%d)  BCS(%fV, %fA, %dM, %dP)\n", secc->config->connectorId, secc->EV_Charging_voltage, secc->EV_Charging_current, secc->EV_Estimate_Minutes, secc->SOC);
-            printccui("SECC(%d)  BCS(%fV, %fA, %dM, %dP)\n", secc->config->connectorId, secc->EV_Charging_voltage, secc->EV_Charging_current, secc->EV_Estimate_Minutes, secc->SOC);
+            //printccui("SECC(%d)  BCS(%fV, %fA, %dM, %dP)\n", secc->config->connectorId, secc->EV_Charging_voltage, secc->EV_Charging_current, secc->EV_Estimate_Minutes, secc->SOC);
             secc_report_MeterValues(secc);
         }
 
         if(_27930_recvFlag.GBT_27930_2015_BSM_recv == 1){
             _27930_recvFlag.GBT_27930_2015_BSM_recv  = 0;
-            bsm_ms = systime_ms();
             float voltage = (((float)dev->bcl.bmsVoltage_request) / 10);
             float current = (((float)dev->bcl.bmsCurrent_request) / 10);
             if(dev->bsm.bmsBatteryOverTemp != 0){
                 secc_set_error(secc, CCU_BATTERY_FAULT);
-                goto endhandl;
             }else if(dev->bsm.bmsBatteryOverSOC ){
                 secc_set_error(secc, CCU_BATTERY_FAULT);
-                goto endhandl;  
-            }else if(dev->bsm.bmsBatteryOverCurrent){
-                secc_set_error(secc, CCU_BATTERY_FAULT);
-                goto endhandl; 
-            }else if(dev->bsm.bmsPowerBatteryOverTemp){
+            }else if(dev->bsm.bmsBatteryOverCurrent == 1){
                 secc_set_error(secc, CCU_BATTERY_FAULT);
-                goto endhandl;  
-            }else if(dev->bsm.bmsPowerBatteryOverRsizder){
+            }else if(dev->bsm.bmsPowerBatteryOverTemp == 1){
+                secc_set_error(secc, CCU_BATTERY_FAULT); 
+            }else if(dev->bsm.bmsPowerBatteryOverRsizder == 1){
                 secc_set_error(secc, CCU_BATTERY_FAULT);
-                goto endhandl; 
-            }else if(dev->bsm.bmsPowerBatteryConnector){
+            }else if(dev->bsm.bmsPowerBatteryConnector == 1){
                 secc_set_error(secc, CCU_BATTERY_FAULT);
-                goto endhandl; 
             }
             if (dev->bsm.bmsPowerPermitted == 0x0  && dev->bsm_last.bmsPowerPermitted == 1)
             {   //暂停
-                printi("SECC(%d) BSM(%d).%s\n", secc->config->connectorId, dev->bsm.bmsPowerPermitted, "suspend");
+                printccui("SECC(%d) BSM(%d).%s\n", secc->config->connectorId, dev->bsm.bmsPowerPermitted, "suspend");
                 secc_request_power(secc, POWER_REQUEST_SHUTDOWN, voltage, current);
             }
             if (dev->bsm.bmsPowerPermitted == 0x1 && dev->bsm_last.bmsPowerPermitted == 0)
             {   //继续
-                printi("SECC(%d) BSM(%d).%s\n", secc->config->connectorId, dev->bsm.bmsPowerPermitted, "continue");
+                printccui("SECC(%d) BSM(%d).%s\n", secc->config->connectorId, dev->bsm.bmsPowerPermitted, "continue");
                 if (dev->bcl.bmsChargeMode = 0x01) { secc_request_power(secc, POWER_REQUEST_CONST_VOLTAGE, voltage, current); }
                 if (dev->bcl.bmsChargeMode = 0x02) { secc_request_power(secc, POWER_REQUEST_CONST_CURRENT, voltage, current); }
             }
         }
-        now_ms = systime_ms();
         // if ((now_ms - bcl_ms) > BCL_TIMEOUT) { printi("SECC(%d) timeout(bcl:%lld, bcs:%lld, bsm:%lld)\n", secc->config->connectorId, (now_ms - bcl_ms), (now_ms - bcs_ms), (now_ms - bsm_ms)); break;}
         // if ((now_ms - bcs_ms) > BCS_TIMEOUT) { printi("SECC(%d) timeout(bcl:%lld, bcs:%lld, bsm:%lld)\n", secc->config->connectorId, (now_ms - bcl_ms), (now_ms - bcs_ms), (now_ms - bsm_ms)); break;}
         // if ((now_ms - bsm_ms) > BSM_TIMEOUT) { printi("SECC(%d) timeout(bcl:%lld, bcs:%lld, bsm:%lld)\n", secc->config->connectorId, (now_ms - bcl_ms), (now_ms - bcs_ms), (now_ms - bsm_ms)); goto endhandl;}
@@ -463,12 +553,13 @@ static int can_GBT27930_Charging(GBT27930_t* dev)
             dev->ccs.chgChargedMinutes = (time(NULL) - secc->started_UTC + 30)/60;
             dev->ccs.chgOutputVoltage = (uint16_t)(secc->VMeters*10 + 0.5);
             dev->ccs.chgOutputCurrent = (uint16_t)(secc->IMeters*10 + 0.5);
-            if(start_sendCCS == 3)can_GBT27930_send_CCS(dev, &dev->ccs);
-            ccs_ms = systime_ms();
+            if(start_sendCCS == 3){
+                    
+                can_GBT27930_send_CCS(dev, &dev->ccs);
+            }
        // }
         usleep(2000);
     }
- endhandl:   
     printccui("step\n");
     secc_set_state(secc, GUN_STOPPING);
     return GBT_27930_2015_NORMAL;
@@ -484,6 +575,66 @@ static int can_GBT27930_ReComm(GBT27930_t* dev)
     printccui("step\n");
 }
 
+/**
+ * @brief 紧急停机
+ * @see  /GB2015-27930-tab.A5
+ */
+
+static int can_GBT27930_EMERGRNCY_STOP(GBT27930_t* dev)
+{
+    secc_port_t* secc = (secc_port_t*)dev->secc;
+    ccu_port_t *ccu = (ccu_port_t*)dev->ccu;
+    pcu_port_t *pcu = (pcu_port_t*)dev->pcu;
+    
+    long delay_time = 100000;
+
+    if(secc->GUN_Error = BCP_VOL_MISMATCH)delay_time = 1000000; //GB18487.1-2023.B.4.7.8
+    can_APP_clear(0);
+    printccui("step\n");
+    secc_request_power(secc, POWER_REQUEST_PLACE_FREE, 0, 0);
+    can_GBT27930_send_CST(dev,&dev->cst);
+    usleep(delay_time);//
+
+    if (secc->set_K1K2_state(secc, 0, 1000) == 1) 
+    {
+        pcu->update_K1K2_state(pcu, 0, 0);
+    }else {
+        secc_set_error(secc, GUN_CONTACTOR_FAULT);
+    }
+    can_APP_clear(0);
+    secc->set_Aux12V_state(secc, 0);
+
+    if (secc->set_ELock_state(secc, 0, 1000)==1)
+    {
+        pcu->update_ElecLock_state(pcu, 0); 
+    }else{
+        secc_set_error(secc, GUN_ELECLOCK_STALL);
+    }
+
+    secc->request_Minutes = 0;
+    secc->request_SOC = 0;
+    secc->request_KWh = 0;
+    secc->reserve_on = 0;
+    secc->reservationId = 0;
+    secc->started_KWh = 0;
+    secc->started_UTC = 0;
+    secc->SOC = 0;
+    secc->EV_Charging_current = 0;
+    secc->EV_Charging_voltage = 0;
+    secc->EV_Estimate_Minutes = 0;
+    secc->transactionId = 0;
+
+    printd("step\n");
+    
+    can_GBT27930_close_pipe(dev);
+
+	printd("GUN_Error:%08x, GUN_State:%08x\n", secc->GUN_Error, secc->GUN_State);
+    secc_set_state(secc, GUN_PLUGIN);
+    printd("step\n");
+    return GBT_27930_2015_NORMAL;
+}
+
+
 static int can_GBT27930_Finishing(GBT27930_t* dev)
 {
     secc_port_t* secc = (secc_port_t*)dev->secc;
@@ -493,40 +644,49 @@ static int can_GBT27930_Finishing(GBT27930_t* dev)
     //printi("SECC(%d) Finishing...\n", secc->config->connectorId);
     printccui("SECC(%d) Finishing...\n", secc->config->connectorId);
     can_GBT27930_send_stop(dev,GBT_27930_STOP_CMD);//还没区分命令
-
+    
    /************GB2015-27930-tab.A6**************/
     long int wait_time; 
+    APPLY(GBT_27930_2015_BSD);
+    APPLY(GBT_27930_2015_BST);
+    long wait_BSD_time = systime_ms();
+    printccui("step\n");
+    can_APP_clear(GBT_27930_2015_CCS);
     WAIT_CONDI(
-        wait_time,5000,
+        wait_time,1000000,
         ,
-        if(can_GBT27930_wait_n(dev,GBT_27930_2015_BST)==GBT_27930_2015_BST)
-        break;
+        RECV_BMS_2(dev,GBT_27930_2015_BSD,GBT_27930_2015_BST);
+        TIME_OUT(dev,GBT_27930_2015_BST)
     ); 
+    
+    printccui("step\n");
     secc_request_power(secc, POWER_REQUEST_PLACE_FREE, 0, 0);
     secc_stop_Transaction(secc);
     {
         dev->csd.chgCode = 0x81828385;
         dev->csd.chgCumulativeKWH = (uint16_t)((secc->EMeters - secc->started_KWh) * 10);
         dev->csd.chgCumulativeMintues = (time(NULL) - secc->started_UTC + 30)/60;
-        can_GBT27930_send_CSD(dev, &dev->csd);
-        can_GBT27930_wait(dev, GBT_27930_2015_BSD, 1000);
+        //can_GBT27930_send_CSD(dev, &dev->csd);
+        //can_GBT27930_wait(dev, GBT_27930_2015_BSD, 1000);
     }
 
     printccui("step\n");
-
     if (secc->GUN_Error == 0)
     {
         int64_t now_ms = systime_ms();
         int64_t end_ms = systime_ms() + 5000;
         for (now_ms = systime_ms(); now_ms <= end_ms; now_ms = systime_ms())
         {
+           
             float bmsA = secc->IMeters;
+            RECV_BMS_1(dev,GBT_27930_2015_BSD);
+            TIME_OUT(dev,GBT_27930_2015_NUL)         
             if (bmsA < 5.0f) { break; }
             msleep(100);
         }
     }
 
-    printd("step\n");
+    printccui("step\n");
 
     if (secc->set_K1K2_state(secc, 0, 1000) == 1) 
     {
@@ -535,14 +695,25 @@ static int can_GBT27930_Finishing(GBT27930_t* dev)
         secc_set_error(secc, GUN_CONTACTOR_FAULT);
     }
     
-    printd("step\n");
+    printccui("step\n");
     
-    msleep(100);    //临时措施,保证CEM发送
-
+    if((wait_BSD_time +10000) > systime_ms() ){
+        wait_BSD_time = wait_BSD_time +10001 -systime_ms();
+    }
+    WAIT_CONDI(
+        wait_time,wait_BSD_time,
+        can_GBT27930_send_timeout(dev, GBT_27930_2015_BSD);
+        break;
+        ,
+        RECV_BMS_1(dev,GBT_27930_2015_BSD);
+        if(_27930_recvFlag.GBT_27930_2015_BSD_recv!= 0){break;}
+        if(_27930_recvFlag.GBT_27930_2015_BST_timeOut !=0){break;}
+    );
+    usleep(500000);    //临时措施,保证CEM/CSD发送 
     can_APP_clear(0);
     secc->set_Aux12V_state(secc, 0);
 
-    printd("step\n");
+    printccui("step\n");
 
     if (secc->set_ELock_state(secc, 0, 1000)==1)
     {
@@ -594,18 +765,19 @@ void* can_GBT27930_loop(void* argv)
         if (state == 0) continue;
         switch(state)
         {
-            case GUN_STARTUP:       { can_GBT27930_TryLock(dev, 60000);printccui("step\n"); }break;
-            case GUN_ELOCKED:       { can_GBT27930_WaitAuthrized(dev, 60000);printccui("step\n"); } break;
-            case GUN_AUTHORIZED:    { can_GBT27930_Handshake(dev);printccui("step\n"); } break;
+            case GUN_STARTUP:       { can_GBT27930_TryLock(dev, 60000);}break;
+            case GUN_ELOCKED:       { can_GBT27930_WaitAuthrized(dev, 60000);} break;
+            case GUN_AUTHORIZED:    { can_GBT27930_Handshake(dev); } break;
             case GUN_INSULATION:    { can_GBT27930_Insulation(dev); } break;
             case GUN_PRECHARGE:     { can_GBT27930_PreCharge(dev); } break;
             case GUN_CHARGING:      { can_GBT27930_Charging(dev); } break;
             case GUN_SUSPEND:                                       break;
-            case GUN_STOPPING:      { can_GBT27930_Finishing(dev); } break;
+            case GUN_STOPPING:      {can_GBT27930_Finishing(dev); } break;
+            case GUN_EMERGRNCY_STOP:{can_GBT27930_EMERGRNCY_STOP(dev); break;}
             case GUN_COMFALUT:      {   }break;
             default:                { }break;
         }
-        if (secc->GUN_Error) { printi("secc->GUN_Error:%08x, %ld\n", secc->GUN_Error, secc->GUN_Error);break;}
+        //if (secc->GUN_Error) { printi("secc->GUN_Error:%08x, %ld\n", secc->GUN_Error, secc->GUN_Error);break;}
     }
     printe("Leave.\n");
     can_GBT27930_Finishing(dev);

+ 19 - 0
src/ccu_define.h

@@ -55,6 +55,7 @@ typedef enum gun_state
     GUN_SUSPEND,            // 充电挂起状态(暂停充电)
     GUN_STOPPING,           // 充电已完成,未拔枪
     GUN_COMFALUT,           // 通讯超时
+    GUN_EMERGRNCY_STOP,     // 紧急停机 
     GUN_UNKNOW,             // 其他未知状态
 
     GUN_SLACOK = GUN_ELOCKED,// PLC准备好
@@ -120,6 +121,24 @@ typedef enum alarm_state
     PCU_PWMFB6_FAULT,
     PCU_PWMFB7_FAULT,
     ERROR_MAX_NUMBER,
+
+    BMS_STOP_BY_SOC = 0x81000000,    //BMS达到SOC,主动停止
+    BMS_STOP_BY_GLOB_VOL,
+    BMS_STOP_BY_SIG_VOL,             //单体电压停止
+    BMS_STOP_BY_OYRHER,              //其他故障
+    BCP_VOL_MISMATCH = 0x81000010,   //BCP报文与实际报文不匹配
+    GBT_27930_2015_BRM_TIMEOUT,
+    GBT_27930_2015_BSM_TIMEOUT,
+    GBT_27930_2015_BCP_TIMEOUT,
+    GBT_27930_2015_BRO_TIMEOUT,
+    GBT_27930_2015_BCL_TIMEOUT,
+    GBT_27930_2015_BCS_TIMEOUT,
+    GBT_27930_2015_BSD_TIMEOUT,
+    GBT_27930_2015_BST_TIMEOUT,
+    GBT_27930_2015_COM_MAX,
+    GBT_18487_OVER_VOL, //GB18487.1-2023.B.4.7.8
+    GBT_CC1_FALUT,
+    GUN_ELECLOCK_FAULT
 }alarm_state_t;
 
 

+ 11 - 1
src/ccu_port.c

@@ -251,6 +251,13 @@ static void gunA_IO_check(ccu_port_t* ccu)
     }
     if (seccA->config->GUN_Type == GUN_TYPE_GBDC)
     {
+         if(gunA_Get_ELock(ccu) == 0)
+        {
+            if((seccA->GUN_State >=GUN_ELOCKED)&&(seccA->GUN_State <=GUN_CHARGING))
+            {
+                   secc_set_error(seccA,GUN_ELECLOCK_FAULT); 
+            }
+        }
         seccA->CC1_voltage = gunA_Get_CC1_Voltage(ccu);
         // printi("CC1_voltage:%f\n", seccA->CC1_voltage);
         if ((4.0f - 0.5f) < seccA->CC1_voltage  &&  seccA->CC1_voltage < (4.0f + 0.5f))
@@ -265,11 +272,14 @@ static void gunA_IO_check(ccu_port_t* ccu)
             }
         }else{
             printi("CC1_voltage:%f\n", seccA->CC1_voltage);
-            if (seccA->GUN_State >= GUN_PLUGIN)
+            if (seccA->GUN_State == GUN_PLUGIN)
             {
                 printi("CC1_voltage:%f\n", seccA->CC1_voltage);
                 secc_exit_can(seccA);
                 secc_set_state(seccA, GUN_PLUGOUT);
+            }else if((seccA->GUN_State > GUN_PLUGIN)&&(seccA->GUN_State <= GUN_EMERGRNCY_STOP))
+            {
+                secc_set_error(seccA,GBT_CC1_FALUT);
             } 
             printi("CC1_voltage:%f\n", seccA->CC1_voltage);
         }

+ 1 - 1
src/main.c

@@ -455,6 +455,7 @@ int main(int argc, char* argv[])
         }
     }
 
+    
 
     // 初始化 OpenSSL
     SSL_library_init();
@@ -464,7 +465,6 @@ int main(int argc, char* argv[])
     mlog_init("/home/root/app_run/log/ccu", MLOG_MAX_FILESIZE, MLOG_MAX_FILENUMB);
 	printv("\n\t%s\n", formatAppVersion());
     printv("\tMLOG_MAX_FILESIZE:%d, MLOG_MAX_FILENUMB:%d\n", MLOG_MAX_FILESIZE, MLOG_MAX_FILENUMB);
-
     mgpio_init();
 	ccu_config_init();
     ocpp16_configkey_init();

+ 16 - 16
src/secc_port.c

@@ -138,7 +138,7 @@ int secc_set_state(secc_port_t* secc, int STATE)
 {
     ccu_port_t* ccu = (ccu_port_t*)secc->ccu;
     pcu_port_t* pcu = (pcu_port_t*)secc->pcu;
-    printd("secc->fp[1]:%d, STATE:%d\n", secc->fp[1], STATE);
+    printccui("secc->fp[1]:%d, STATE:%d\n", secc->fp[1], STATE);
     if (secc->fp[1] > 0 && STATE >= GUN_PLUGIN)
     {
         send(secc->fp[1], &STATE, sizeof(STATE), 0);
@@ -154,23 +154,23 @@ int secc_set_state(secc_port_t* secc, int STATE)
 
 int secc_should_stop(secc_port_t* secc)
 {
-    if (secc->GUN_Error!=0 && secc->GUN_Error!=GUN_RESERVED) return 1;
+    //if (secc->GUN_Error!=0 && secc->GUN_Error!=GUN_RESERVED) return 1;
     if (secc->manul_stop)return 1;
 
-    if (secc->request_KWh > 0.0f)
-    {
-        float totalKWh = secc->EMeters - secc->started_KWh;
-        if (totalKWh > secc->request_KWh) return 1;
-    }
-    if (secc->request_Minutes > 0)
-    {
-        int totalMinutes = (time(NULL) - secc->started_UTC)/60;
-        if (totalMinutes > secc->request_Minutes) return 1;
-    }
-    if (secc->request_SOC > 0)
-    {
-        if (secc->SOC > secc->request_SOC ) return 1;
-    }
+    // if (secc->request_KWh > 0.0f)
+    // {
+    //     float totalKWh = secc->EMeters - secc->started_KWh;
+    //     if (totalKWh > secc->request_KWh) return 1;
+    // }
+    // if (secc->request_Minutes > 0)
+    // {
+    //     int totalMinutes = (time(NULL) - secc->started_UTC)/60;
+    //     if (totalMinutes > secc->request_Minutes) return 1;
+    // }
+    // if (secc->request_SOC > 0)
+    // {
+    //     if (secc->SOC > secc->request_SOC ) return 1;
+    // }
     return 0;
 }