/* * charger_gbt.c * * Created on: Apr 18, 2024 * Author: colorbass */ #include "charger_gbt.h" #include "main.h" #include "board.h" #include "stdio.h" #include "j1939.h" #include "string.h" #include "edcan.h" #include "lock.h" #include "connector.h" uint8_t GBT_CC_GetStateRaw(); gbtState_t GBT_State; uint32_t GBT_state_tick; //Tick after state switch uint32_t GBT_delay; uint8_t GBT_BAT_INFO_recv; uint8_t GBT_BAT_STAT_recv; uint8_t GBT_BRO_recv; uint8_t GBT_BHM_recv; uint8_t GBT_BSD_recv; uint8_t EV_ready; //uint8_t GBT_Charger_Enable; //FIX //uint8_t GBT_Charger_Permission;//FIX GBT_CML_t GBT_MaxLoad; GBT_CRM_t GBT_ChargerInfo; GBT_BHM_t GBT_MaxVoltage; GBT_BRM_t GBT_EVInfo; GBT_BCP_t GBT_BATStat; GBT_BCL_t GBT_ReqPower; GBT_BCL_t GBT_CurrPower; GBT_BCS_t GBT_ChargingStatus; GBT_BSM_t GBT_BatteryStatus; GBT_CCS_t GBT_ChargerCurrentStatus; GBT_CSD_t GBT_ChargerStop; uint8_t GBT_BRO; uint32_t GBT_TimeChargingStarted; uint32_t GBT_StopCauseCode; uint32_t GBT_ErrorCode; extern GBT_EDCAN_Output_t GBT_EDCAN_Output; extern GBT_EDCAN_Input_t GBT_EDCAN_Input; void GBT_Init(){ GBT_State = GBT_DISABLED; GBT_EDCAN_Input.chargeControl == CHARGING_NOT_ALLOWED; GBT_Reset(); } void GBT_ChargerTask(){ //GBT_LockTask(); if(j_rx.state == 2){ switch (j_rx.PGN){ case 0x2700: //PGN BHM GBT_BHM_recv = 1; memcpy (&GBT_MaxVoltage, j_rx.data, sizeof(GBT_MaxVoltage)); break; case 0x0200: //PGN BRM LONG GBT_BAT_INFO_recv = 1; memcpy (&GBT_EVInfo, j_rx.data, sizeof(GBT_EVInfo)); break; case 0x0600: //PGN BCP LONG GBT_BAT_STAT_recv = 1; memcpy (&GBT_BATStat, j_rx.data, sizeof(GBT_BATStat)); break; case 0x0900: //PGN BRO GBT_BRO_recv = 1; if(j_rx.data[0] == 0xAA) EV_ready = 1; else EV_ready = 0; GBT_BRO = j_rx.data[0]; break; case 0x1000: //PGN BCL //TODO: power block memcpy (&GBT_ReqPower, j_rx.data, sizeof(GBT_ReqPower)); uint16_t volt=GBT_ReqPower.requestedVoltage; GBT_EDCAN_Output.requestedVoltage = volt; uint16_t curr=4000-GBT_ReqPower.requestedCurrent; GBT_EDCAN_Output.requestedCurrent = curr; break; case 0x1100: //PGN BCS //TODO memcpy (&GBT_ChargingStatus, j_rx.data, sizeof(GBT_ChargingStatus)); GBT_EDCAN_Output.chargingRemainingTimeMin = GBT_ChargingStatus.estimatedRemainingChargingTime; GBT_EDCAN_Output.chargingPercentage = GBT_ChargingStatus.currentChargeState; break; case 0x1300: //PGN BSM //TODO memcpy (&GBT_BatteryStatus, j_rx.data, sizeof(GBT_BatteryStatus)); break; case 0x1500: //PGN BMV //TODO break; case 0x1600: //PGN BMT //TODO break; case 0x1700: //PGN BSP //TODO break; //this handler in j1939.c // case 0x1900: //PGN BST // break; case 0x1C00: //PGN BSD //TODO SOC Voltage Temp GBT_BSD_recv = 1; break; //this handler in j1939.c // case 0x1E00: //PGN BEM // break; //BSM BMV BMT BSP BST BSD BEM } j_rx.state = 0; } if(GBT_delay>HAL_GetTick()){ //waiting }else switch (GBT_State){ case GBT_DISABLED: RELAY_Write(RELAY_AUX, 0); if(connectorState == CONN_Occupied_charging){ GBT_Reset(); GBT_Start();//TODO IF protections (maybe not needed) } break; // case GBT_S0_UNCONNECTED: // if(!GBT_Charger_Enable){ // GBT_Stop(); // break; // } // if(GBT_CC_GetState()==GBT_CC_4V){ // // GBT_SwitchState(GBT_S1_CONNECTED); // GBT_Delay(500); // } // break; // case GBT_S1_CONNECTED: // if(!GBT_Charger_Enable){ // GBT_Stop(); // break; // } // if(GBT_CC_GetState()==GBT_CC_4V){ // // GBT_Lock(1); // GBT_SwitchState(GBT_S2_LOCKED); // GBT_Delay(500); // }else{ // GBT_SwitchState(GBT_S0_UNCONNECTED); // } // break; // case GBT_S2_LOCKED: // if(!GBT_Charger_Enable){ // GBT_Stop(); // break; // } // if(1){ //TODO: charge permission // RELAY_Write(RELAY_AUX, 1); // 13.8V AUX ON // GBT_SwitchState(GBT_S3_STARTED); // GBT_Delay(500); // } // break; case GBT_S3_STARTED: GBT_SwitchState(GBT_S4_ISOTEST); GBT_Delay(500); break; case GBT_S4_ISOTEST: if(j_rx.state == 0) GBT_SendCHM(); GBT_Delay(250); //TODO: Isolation test //if(isolation test fail) {send CST} if(GBT_BHM_recv) { //Isolation test finish GBT_SwitchState(GBT_S5_BAT_INFO); } //Timeout 10S if((GBT_BHM_recv == 0) && (GBT_StateTick()>10000)) { //BHM Timeout GBT_Error(0xFCF0C0FC); } break; case GBT_S5_BAT_INFO: if(j_rx.state == 0) GBT_SendCRM(0x00); GBT_Delay(250); if(GBT_BAT_INFO_recv){ //BRM //Got battery info GBT_SwitchState(GBT_S6_BAT_STAT); } //Timeout if((GBT_StateTick()>5000) && (GBT_BAT_INFO_recv == 0)){ GBT_Error(0xFDF0C0FC); //BRM Timeout } break; case GBT_S6_BAT_STAT: if(j_rx.state == 0) GBT_SendCRM(0xAA); GBT_Delay(250); if(GBT_BAT_STAT_recv){ //Got battery status GBT_SwitchState(GBT_S7_BMS_WAIT); } if((GBT_StateTick()>5000) && (GBT_BAT_STAT_recv == 0)){ GBT_Error(0xFCF1C0FC); //BCP Timeout } break; case GBT_S7_BMS_WAIT: if(j_rx.state == 0) GBT_SendCTS(); HAL_Delay(2); if(j_rx.state == 0) GBT_SendCML(); GBT_Delay(250); if((GBT_StateTick()>5000) && (GBT_BRO_recv == 0)){ GBT_Error(0xFCF4C0FC); //BRO Timeout } if(EV_ready){ //EV ready (AA) GBT_SwitchState(GBT_S8_INIT_CHARGER); }else{ if((GBT_StateTick()>60000) && (GBT_BRO_recv == 1)){ GBT_Error(0xFCF4C0FC); //BRO Timeout } } break; case GBT_S8_INIT_CHARGER: if(j_rx.state == 0) GBT_SendCRO(0x00); //TODO GBT_Delay(250); if(GBT_StateTick()>1500){ //Power Modules initiated GBT_SwitchState(GBT_S9_WAIT_BCL); } break; case GBT_S9_WAIT_BCL: if(j_rx.state == 0) GBT_SendCRO(0xAA); GBT_Delay(250); if(GBT_ReqPower.chargingMode != 0){ //REFACTORING //BCL power requirements received GBT_SwitchState(GBT_S10_CHARGING); CONN_SetState(CONN_Occupied_charging); uint16_t curr=4000-GBT_ReqPower.requestedCurrent; uint16_t volt=GBT_ReqPower.requestedVoltage; //TODO Limits GBT_EDCAN_Output.requestedVoltage = volt; GBT_EDCAN_Output.requestedCurrent = curr; GBT_EDCAN_Output.enablePSU = 1; GBT_TimeChargingStarted = get_Current_Time(); //TODO: EDCAN_SendPacketRead } break; case GBT_S10_CHARGING: //CHARGING //TODO BCL BCS BSM missing ERRORS if(GBT_EDCAN_Input.chargeControl == CHARGING_NOT_ALLOWED) GBT_Stop(GBT_CST_SUSPENDS_ARTIFICIALLY); if(GBT_EDCAN_Input.chargeControl == FORCE_UNLOCK) GBT_Stop(GBT_CST_SUSPENDS_ARTIFICIALLY);//GBT_ForceStop(); if(GBT_LockState.error) GBT_Stop(GBT_CST_OTHERFALUT); //GBT_ChargerCurrentStatus.chargingPermissible = 0b1111111111111100;//NOT PERMITTED GBT_ChargerCurrentStatus.chargingPermissible = 0b1111111111111101; GBT_ChargerCurrentStatus.chargingTime = (get_Current_Time() - GBT_TimeChargingStarted)/60; // GBT_ChargerCurrentStatus.outputCurrent = 4000 - GBT_EDCAN_Output.requestedCurrent; // GBT_ChargerCurrentStatus.outputVoltage = GBT_EDCAN_Output.requestedVoltage; GBT_ChargerCurrentStatus.outputCurrent = 4000 - GBT_EDCAN_Input.measuredCurrent; GBT_ChargerCurrentStatus.outputVoltage = GBT_EDCAN_Input.measuredVoltage; GBT_EDCAN_Output.chargingElapsedTimeMin = (get_Current_Time() - GBT_TimeChargingStarted)/60; GBT_EDCAN_Output.chargingElapsedTimeSec = (get_Current_Time() - GBT_TimeChargingStarted)%60; if(j_rx.state == 0) GBT_SendCCS(); GBT_Delay(50); break; case GBT_STOP: GBT_Delay(10); GBT_EDCAN_Output.enablePSU = 0; GBT_SendCST(GBT_StopCauseCode); //RELAY_Write(RELAY_OUTPUT, 0); //GBT_SwitchState(GBT_DISABLED); if(GBT_StateTick()>10000){ GBT_Error(0xFCF0C0FD); //BSD Timeout } if(GBT_BSD_recv != 0){ GBT_SwitchState(GBT_STOP_CSD); } break; case GBT_STOP_CSD: GBT_Delay(250); GBT_SendCSD(); if(GBT_StateTick()>2500){ //2.5S GBT_SwitchState(GBT_COMPLETE); // GBT_Reset(); //CONN_SetState(CONN_Occupied_complete); //if(connectorState == CONN_Occupied_charging) //PSU_Mode(0x0100); } break; case GBT_ERROR: GBT_SendCEM(GBT_ErrorCode); //2.5S GBT_SwitchState(GBT_COMPLETE); // GBT_Reset(); // break; case GBT_COMPLETE: if(connectorState != CONN_Occupied_complete) GBT_SwitchState(GBT_DISABLED); break; default: GBT_SwitchState(GBT_DISABLED); } } void GBT_SwitchState(gbtState_t state){ GBT_State = state; ED_status = state; GBT_state_tick = HAL_GetTick(); if(GBT_State == GBT_DISABLED) printf ("GBT_DISABLED\n"); // if(GBT_State == GBT_S0_UNCONNECTED) printf ("GBT_S0_UNCONNECTED\n"); // if(GBT_State == GBT_S1_CONNECTED) printf ("GBT_S1_CONNECTED\n"); // if(GBT_State == GBT_S2_LOCKED) printf ("GBT_S2_LOCKED\n"); if(GBT_State == GBT_S3_STARTED) printf ("GBT_S3_STARTED\n"); if(GBT_State == GBT_S4_ISOTEST) printf ("GBT_S4_ISOTEST\n"); if(GBT_State == GBT_S5_BAT_INFO) printf ("GBT_S5_BAT_INFO\n"); if(GBT_State == GBT_S6_BAT_STAT) printf ("GBT_S6_BAT_STAT\n"); if(GBT_State == GBT_S7_BMS_WAIT) printf ("GBT_S7_BMS_WAIT\n"); if(GBT_State == GBT_S8_INIT_CHARGER)printf ("GBT_S8_INIT_CHARGER\n"); if(GBT_State == GBT_S9_WAIT_BCL) printf ("GBT_S9_WAIT_BCL\n"); if(GBT_State == GBT_S10_CHARGING) printf ("GBT_S10_CHARGING\n"); if(GBT_State == GBT_STOP) printf ("GBT_STOP\n"); if(GBT_State == GBT_STOP_CSD) printf ("GBT_STOP_CSD\n"); if(GBT_State == GBT_ERROR) printf ("GBT_ERROR\n"); if(GBT_State == GBT_COMPLETE) printf ("GBT_COMPLETE\n"); } uint32_t GBT_StateTick(){ return HAL_GetTick() - GBT_state_tick; } void GBT_Delay(uint32_t delay){ GBT_delay = HAL_GetTick()+delay; } void GBT_Stop(uint32_t causecode){ GBT_StopCauseCode = causecode; if(GBT_State != GBT_STOP) GBT_SwitchState(GBT_STOP); } void GBT_Error(uint32_t errorcode){ GBT_ErrorCode = errorcode; GBT_SwitchState(GBT_ERROR); } void GBT_ForceStop(){ GBT_EDCAN_Output.enablePSU = 0; GBT_SwitchState(GBT_COMPLETE); GBT_Lock(0); RELAY_Write(RELAY_AUX, 0); } void GBT_Reset(){ GBT_BAT_INFO_recv = 0; GBT_BAT_STAT_recv = 0; GBT_BRO_recv = 0; GBT_BHM_recv = 0; GBT_BSD_recv = 0; EV_ready = 0; memset(&GBT_EVInfo, 0, sizeof (GBT_EVInfo)); memset(&GBT_BATStat, 0, sizeof (GBT_BATStat)); memset(&GBT_ReqPower, 0, sizeof (GBT_ReqPower)); memset(&GBT_CurrPower, 0, sizeof (GBT_CurrPower)); memset(&GBT_MaxVoltage, 0, sizeof (GBT_MaxVoltage)); memset(&GBT_ChargingStatus, 0, sizeof (GBT_ChargingStatus)); memset(&GBT_BatteryStatus, 0, sizeof (GBT_BatteryStatus)); memset(&GBT_ChargerCurrentStatus, 0, sizeof (GBT_ChargerCurrentStatus)); memset(&GBT_ChargerStop, 0, sizeof (GBT_ChargerStop)); GBT_CurrPower.requestedCurrent = 4000; //0A GBT_CurrPower.requestedVoltage = 0; //0V GBT_TimeChargingStarted = 0; GBT_BRO = 0x00; } void GBT_Start(){ RELAY_Write(RELAY_AUX, 1); GBT_SwitchState(GBT_S3_STARTED); }