diff --git a/Core/Inc/charger_gbt.h b/Core/Inc/charger_gbt.h index 97881b6..2c034f8 100755 --- a/Core/Inc/charger_gbt.h +++ b/Core/Inc/charger_gbt.h @@ -230,6 +230,9 @@ extern GBT_StopSource_t GBT_StopSource; void GBT_Init(); void GBT_Reset(); + +/** Немедленная обработка однокадровых сообщений EVSE→EV (не через j_rx TP). */ +void GBT_ApplyShortPacket(uint32_t pgn, const uint8_t *data, uint8_t dlc); //void GBT_Stop(uint32_t causecode); void GBT_StopEV(uint32_t causecode); void GBT_StopEVSE(uint32_t causecode); diff --git a/Core/Inc/connector.h b/Core/Inc/connector.h index 9665825..bebc68b 100755 --- a/Core/Inc/connector.h +++ b/Core/Inc/connector.h @@ -9,6 +9,7 @@ #define INC_CONNECTOR_H_ #include "main.h" +#include typedef enum __attribute__((packed)) { Unknown, diff --git a/Core/Src/charger_gbt.c b/Core/Src/charger_gbt.c index 457be06..264ba29 100755 --- a/Core/Src/charger_gbt.c +++ b/Core/Src/charger_gbt.c @@ -64,11 +64,95 @@ static uint32_t GBT_EVSE_last_rx_tick; #define GBT_EV_HANDSHAKE_TIMEOUT_MS 10000U #define GBT_EV_WAIT_READY_TIMEOUT_MS 10000U #define GBT_EV_CHARGING_RX_TIMEOUT_MS 3000U +#define GBT_EV_ENABLE_LOAD_DELAY_MS 10000U + +static void GBT_HandleEvseRxPacket(const j_receive_t *rx){ + GBT_EVSE_last_rx_tick = HAL_GetTick(); + switch (rx->PGN){ + case 0x2600: // CHM EVSE->EV (старт/версия GB/T) + GBT_CHM_recv = 1; + break; + + case 0x0100: // CRM EVSE->EV (идентификация зарядника, 0x00 или 0xAA) + memcpy(&GBT_ChargerInfo, rx->data, sizeof(GBT_ChargerInfo)); + GBT_CRM_recv = 1; + break; + + case 0x0800: // CML EVSE->EV (макс. параметры зарядника) + memcpy(&GBT_MaxLoad, rx->data, sizeof(GBT_MaxLoad)); + GBT_CML_recv = 1; + break; + + case 0x0700: // CTS EVSE->EV (time sync) + break; + + case 0x0A00: // CRO EVSE->EV (0x00 = инициализация, 0xAA = готов к зарядке) + GBT_CRO_val = (rx->data[0] & 0xFF); + break; + + case 0x1200: // CCS EVSE->EV (текущий статус зарядника) + memcpy(&GBT_ChargerCurrentStatus, rx->data, sizeof(GBT_ChargerCurrentStatus)); + CONN[0].ChargingTime = GBT_ChargerCurrentStatus.chargingTime; + CONN[0].MeasuredVoltageSE = GBT_ChargerCurrentStatus.outputVoltage / 10; + CONN[0].MeasuredCurrentSE = 4000 - GBT_ChargerCurrentStatus.outputCurrent; + break; + + case 0x1A00: // CST EVSE->EV (остановка зарядки по инициативе EVSE) + GBT_CST_recv = 1; + break; + + case 0x1D00: // CSD EVSE->EV (финальный отчёт зарядника) + memcpy(&GBT_ChargerStop, rx->data, sizeof(GBT_ChargerStop)); + GBT_CSD_recv = 1; + break; + + case 0x1F00: // CEM EVSE->EV (сообщение об ошибке) + memcpy(&GBT_ErrorCode, rx->data, sizeof(GBT_ErrorCode)); + break; + + default: + break; + } +} + +void GBT_ApplyShortPacket(uint32_t pgn, const uint8_t *data, uint8_t dlc){ + j_receive_t rx; + memset(&rx, 0, sizeof(rx)); + rx.PGN = pgn; + rx.size = dlc; + if(data != NULL){ + uint8_t n = (dlc > 8U) ? 8U : dlc; + memcpy(rx.data, data, n); + } + GBT_HandleEvseRxPacket(&rx); +} void GBT_Init(){ GBT_State = GBT_DISABLED; CONN[0].connControl = CMD_NONE; cc_enable = 0U; + /* BRM defaults are initialized once after boot and kept unchanged. */ + GBT_EVInfo.version[0] = 2; + GBT_EVInfo.version[1] = 0; + GBT_EVInfo.version[2] = 0; + GBT_EVInfo.batteryType = 1; + GBT_EVInfo.batteryCapacity = 700; + GBT_EVInfo.batteryVoltage = 3990; + memcpy(GBT_EVInfo.batteryVendor, "TEST", 4); + GBT_EVInfo.batterySN = 666666; + GBT_EVInfo.batteryManuY = 30; + GBT_EVInfo.batteryManuM = 2; + GBT_EVInfo.batteryManuD = 20; + GBT_EVInfo.batteryCycleCount = 666; + GBT_EVInfo.ownAuto = 1; + GBT_EVInfo.rsvd0 = 0; + GBT_BATStat.maxCellVoltage = 320; + GBT_BATStat.maxChargingCurrent = 40; + GBT_BATStat.totalEnergy = 6; + GBT_BATStat.maxChargingVoltage = 500; + GBT_BATStat.maxTemp = 70; + GBT_BATStat.SOC = CONN[0].SOC; + GBT_BATStat.measVoltage = CONN[0].MeasuredVoltage; memcpy(GBT_EVInfo.EVIN, "EDISON_TEST_EVIN_", 17); memcpy(GBT_EVInfo.EV_SW_VER, "1.0.0", 8); GBT_Reset(); @@ -80,53 +164,7 @@ void GBT_ChargerTask(){ //GBT_LockTask(); if(j_rx.state == 2){ - GBT_EVSE_last_rx_tick = HAL_GetTick(); - switch (j_rx.PGN){ - case 0x2600: // CHM EVSE->EV (старт/версия GB/T) - GBT_CHM_recv = 1; - break; - - case 0x0100: // CRM EVSE->EV (идентификация зарядника, 0x00 или 0xAA) - memcpy(&GBT_ChargerInfo, j_rx.data, sizeof(GBT_ChargerInfo)); - GBT_CRM_recv = 1; - break; - - case 0x0800: // CML EVSE->EV (макс. параметры зарядника) - memcpy(&GBT_MaxLoad, j_rx.data, sizeof(GBT_MaxLoad)); - GBT_CML_recv = 1; - break; - - case 0x0700: // CTS EVSE->EV (time sync) - // Пока не используем, но можем сохранить время при необходимости - break; - - case 0x0A00: // CRO EVSE->EV (0x00 = инициализация, 0xAA = готов к зарядке) - GBT_CRO_val = (j_rx.data[0] & 0xFF); - break; - - case 0x1200: // CCS EVSE->EV (текущий статус зарядника) - memcpy(&GBT_ChargerCurrentStatus, j_rx.data, sizeof(GBT_ChargerCurrentStatus)); - if(GBT_State == GBT_EV_CHARGING) { - CONN[0].enableLoad = GBT_ChargerCurrentStatus.chargingPermissible; - } - CONN[0].ChargingTime = GBT_ChargerCurrentStatus.chargingTime; - CONN[0].MeasuredVoltageSE = GBT_ChargerCurrentStatus.outputVoltage / 10; - CONN[0].MeasuredCurrentSE = 4000 - GBT_ChargerCurrentStatus.outputCurrent; - break; - - case 0x1A00: // CST EVSE->EV (остановка зарядки по инициативе EVSE) - GBT_CST_recv = 1; - break; - - case 0x1D00: // CSD EVSE->EV (финальный отчёт зарядника) - memcpy(&GBT_ChargerStop, j_rx.data, sizeof(GBT_ChargerStop)); - GBT_CSD_recv = 1; - break; - - case 0x1F00: // CEM EVSE->EV (сообщение об ошибке) - memcpy(&GBT_ErrorCode, j_rx.data, sizeof(GBT_ErrorCode)); - break; - } + GBT_HandleEvseRxPacket(&j_rx); j_rx.state = 0; } @@ -185,21 +223,6 @@ void GBT_ChargerTask(){ case GBT_EV_RECOGNITION: // 3) Постоянно шлём BRM, ждём CRM (0x0100, 0xAA) - GBT_EVInfo.version[0] = 2; - GBT_EVInfo.version[1] = 0; - GBT_EVInfo.version[2] = 0; - GBT_EVInfo.batteryType = 1; - GBT_EVInfo.batteryCapacity = 700; - GBT_EVInfo.batteryVoltage = 3990; - memcpy(GBT_EVInfo.batteryVendor, "TEST", 4); - GBT_EVInfo.batterySN = 666666; - GBT_EVInfo.batteryManuY = 30; - GBT_EVInfo.batteryManuM = 2; - GBT_EVInfo.batteryManuD = 20; - GBT_EVInfo.batteryCycleCount = 666; - GBT_EVInfo.ownAuto = 1; - GBT_EVInfo.rsvd0 = 0; - if (j_rx.state == 0) GBT_SendBRM(); // TODO CHUNKED SEND GBT_Delay(250); @@ -267,13 +290,15 @@ void GBT_ChargerTask(){ GBT_ReqPower.requestedCurrent = 4000 - CONN[0].RequestedCurrent; GBT_ReqPower.chargingMode = 1; - GBT_BATStat.maxCellVoltage = 320; - GBT_BATStat.maxChargingCurrent = 40; - GBT_BATStat.totalEnergy = 6; - GBT_BATStat.maxChargingVoltage = 500; - GBT_BATStat.maxTemp = 70; GBT_BATStat.SOC = CONN[0].SOC; GBT_BATStat.measVoltage = CONN[0].MeasuredVoltage; + + /* Enable load only after delayed start in charging state. */ + if (GBT_StateTick() >= GBT_EV_ENABLE_LOAD_DELAY_MS) { + CONN[0].enableLoad = GBT_ChargerCurrentStatus.chargingPermissible; + } else { + CONN[0].enableLoad = 0; + } // Стоп по инициативе EVSE (получили CST) if (GBT_CST_recv) { @@ -435,13 +460,8 @@ void GBT_Reset(){ GBT_CST_recv = 0; GBT_CSD_recv = 0; GBT_CRO_val = 0x00; - CONN[0].SOC = 0; CONN[0].enableLoad = 0; - CONN[0].RequestedCurrent = 1000; - CONN[0].RequestedVoltage = 400; CONN[0].chargingError = 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)); diff --git a/Core/Src/connector.c b/Core/Src/connector.c index 2093225..9ebda69 100755 --- a/Core/Src/connector.c +++ b/Core/Src/connector.c @@ -23,6 +23,19 @@ static void CONN_UpdateEdcanOutput(void); void CONN_Init(){ memset(&CONN, 0, sizeof(CONN)); CONN[0].connControl = CMD_NONE; + CONN[1].connControl = CMD_NONE; + /* Default requested limits are initialized once here for all connectors. + * They can be changed later only by external commands. + */ + CONN[0].RequestedCurrent = 1000; + CONN[0].RequestedVoltage = 400; + CONN[1].RequestedCurrent = 1000; + CONN[1].RequestedVoltage = 400; + /* Keep non-zero runtime defaults until external commands/measurements arrive. */ + CONN[0].SOC = 50; + CONN[1].SOC = 50; + CONN[0].MeasuredVoltage = 400; + CONN[1].MeasuredVoltage = 400; CONN_SetState(Unknown); } diff --git a/Core/Src/debug.c b/Core/Src/debug.c index 931abe3..4eb6986 100644 --- a/Core/Src/debug.c +++ b/Core/Src/debug.c @@ -156,27 +156,26 @@ int log_printf(int level, const char *format, ...) break; } - log_buffer[0] = (uint8_t)level; - written = snprintf((char*)&log_buffer[1], LOG_BUFFER_SIZE - 2, "EV %s", tag); + written = snprintf((char*)&log_buffer[0], LOG_BUFFER_SIZE - 1, "EV %s", tag); if(written < 0){ return written; } - if(written >= (LOG_BUFFER_SIZE - 2)){ - written = LOG_BUFFER_SIZE - 2; + if(written >= (LOG_BUFFER_SIZE - 1)){ + written = LOG_BUFFER_SIZE - 1; } va_start(args, format); - result = vsnprintf((char*)&log_buffer[1 + written], LOG_BUFFER_SIZE - 2 - written, format, args); + result = vsnprintf((char*)&log_buffer[written], LOG_BUFFER_SIZE - 1 - written, format, args); va_end(args); if (result < 0) { return result; } - if (result >= (LOG_BUFFER_SIZE - 2 - written)) { - result = LOG_BUFFER_SIZE - 2 - written; + if (result >= (LOG_BUFFER_SIZE - 1 - written)) { + result = LOG_BUFFER_SIZE - 1 - written; } - log_buffer[1 + written + result] = '\0'; - debug_buffer_add(log_buffer, (uint16_t)(2 + written + result)); + log_buffer[written + result] = '\0'; + debug_buffer_add(log_buffer, (uint16_t)(written + result)); return result + written; } diff --git a/Core/Src/j1939.c b/Core/Src/j1939.c index 73a58b6..56e0d58 100755 --- a/Core/Src/j1939.c +++ b/Core/Src/j1939.c @@ -213,19 +213,15 @@ static void J1939_ProcessRxFrame(const j1939_rx_frame_t *frame){ } break; - default: - if(j_rx.state == 0){ - j_rx.size = frame->DLC; - j_rx.packet = 1; - j_rx.packets = 1; - j_rx.step = 1; - j_rx.step_cts_remain = 0; - j_rx.PGN = (frame->ExtId >> 8) & 0x00FF00; - j_rx.state = 2; - memcpy(j_rx.data, frame->data, j_rx.size); + default:{ + uint32_t short_pgn = (frame->ExtId >> 8) & 0x00FF00U; + /* Однокадровые PGN обрабатываем сразу; j_rx зарезервирован только под TP RX. */ + if((short_pgn != 0xEC00U) && (short_pgn != 0xEB00U)){ + GBT_ApplyShortPacket(short_pgn, frame->data, frame->DLC); } break; } + } } void J1939_ExchangeRxBuffer(void){ diff --git a/Core/Src/load.c b/Core/Src/load.c index 578f242..75480dd 100644 --- a/Core/Src/load.c +++ b/Core/Src/load.c @@ -5,6 +5,28 @@ #define COOLDOWN_TIME 60000 +static void LOAD_LogEnableChanges(void){ + static uint8_t inited = 0U; + static uint8_t prev_enable_0 = 0U; + static uint8_t prev_enable_1 = 0U; + + if(!inited){ + prev_enable_0 = CONN[0].enableLoad; + prev_enable_1 = CONN[1].enableLoad; + inited = 1U; + return; + } + + if(prev_enable_0 != CONN[0].enableLoad){ + log_printf(LOG_INFO, "GBT Load %s\n", CONN[0].enableLoad ? "enabled" : "disabled"); + prev_enable_0 = CONN[0].enableLoad; + } + if(prev_enable_1 != CONN[1].enableLoad){ + log_printf(LOG_INFO, "CCS Load %s\n", CONN[1].enableLoad ? "enabled" : "disabled"); + prev_enable_1 = CONN[1].enableLoad; + } +} + void LOAD_Init(){ RELAY_Write(RELAY_1, 0); RELAY_Write(RELAY_2, 0); @@ -15,6 +37,8 @@ void LOAD_Init(){ void LOAD_Task(){ static uint32_t load_tick = 0; + LOAD_LogEnableChanges(); + if(CONN[0].enableLoad || CONN[1].enableLoad){ load_tick = HAL_GetTick(); } diff --git a/Core/Src/main.c b/Core/Src/main.c index d0deecf..47c8b46 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -149,6 +149,7 @@ int main(void) /* USER CODE BEGIN 3 */ + if(CONN[0].connState == Unplugged) CONN[0].connControl = CMD_NONE; CONN[1].MeasuredVoltage = ISO.voltageComm; LOAD_Task(); EDCAN_Loop(); diff --git a/Debug/Core/Src/charger_gbt.cyclo b/Debug/Core/Src/charger_gbt.cyclo index 142cd70..3ec6fad 100644 --- a/Debug/Core/Src/charger_gbt.cyclo +++ b/Debug/Core/Src/charger_gbt.cyclo @@ -1,11 +1,13 @@ -../Core/Src/charger_gbt.c:68:6:GBT_Init 1 -../Core/Src/charger_gbt.c:78:6:GBT_ChargerTask 61 -../Core/Src/charger_gbt.c:364:6:GBT_SwitchState 13 -../Core/Src/charger_gbt.c:384:10:GBT_StateTick 1 -../Core/Src/charger_gbt.c:388:6:GBT_Delay 1 -../Core/Src/charger_gbt.c:393:6:GBT_StopEV 3 -../Core/Src/charger_gbt.c:403:6:GBT_StopEVSE 2 -../Core/Src/charger_gbt.c:409:6:GBT_StopOCPP 2 -../Core/Src/charger_gbt.c:415:6:GBT_ForceStop 1 -../Core/Src/charger_gbt.c:422:6:GBT_Error 1 -../Core/Src/charger_gbt.c:430:6:GBT_Reset 1 +../Core/Src/charger_gbt.c:69:13:GBT_HandleEvseRxPacket 17 +../Core/Src/charger_gbt.c:118:6:GBT_ApplyShortPacket 2 +../Core/Src/charger_gbt.c:130:6:GBT_Init 1 +../Core/Src/charger_gbt.c:162:6:GBT_ChargerTask 46 +../Core/Src/charger_gbt.c:389:6:GBT_SwitchState 13 +../Core/Src/charger_gbt.c:409:10:GBT_StateTick 1 +../Core/Src/charger_gbt.c:413:6:GBT_Delay 1 +../Core/Src/charger_gbt.c:418:6:GBT_StopEV 3 +../Core/Src/charger_gbt.c:428:6:GBT_StopEVSE 2 +../Core/Src/charger_gbt.c:434:6:GBT_StopOCPP 2 +../Core/Src/charger_gbt.c:440:6:GBT_ForceStop 1 +../Core/Src/charger_gbt.c:447:6:GBT_Error 1 +../Core/Src/charger_gbt.c:455:6:GBT_Reset 1 diff --git a/Debug/Core/Src/connector.cyclo b/Debug/Core/Src/connector.cyclo index 3aa85ef..3c7ba8b 100644 --- a/Debug/Core/Src/connector.cyclo +++ b/Debug/Core/Src/connector.cyclo @@ -1,7 +1,7 @@ ../Core/Src/connector.c:23:6:CONN_Init 1 -../Core/Src/connector.c:29:6:CONN_Task 18 -../Core/Src/connector.c:122:6:CONN_SetState 15 -../Core/Src/connector.c:144:6:CONN_CC_ReadStateFiltered 4 -../Core/Src/connector.c:163:9:CONN_CC_GetState 1 -../Core/Src/connector.c:166:9:CONN_CC_GetStateRaw 9 -../Core/Src/connector.c:193:7:CONN_CC_GetAdc 1 +../Core/Src/connector.c:42:6:CONN_Task 18 +../Core/Src/connector.c:135:6:CONN_SetState 15 +../Core/Src/connector.c:157:6:CONN_CC_ReadStateFiltered 4 +../Core/Src/connector.c:176:9:CONN_CC_GetState 1 +../Core/Src/connector.c:179:9:CONN_CC_GetStateRaw 9 +../Core/Src/connector.c:206:7:CONN_CC_GetAdc 1 diff --git a/Debug/Core/Src/j1939.cyclo b/Debug/Core/Src/j1939.cyclo index ad130d3..fc5ad42 100644 --- a/Debug/Core/Src/j1939.cyclo +++ b/Debug/Core/Src/j1939.cyclo @@ -5,20 +5,20 @@ ../Core/Src/j1939.c:107:10:J1939_GetRxOverflowCount 1 ../Core/Src/j1939.c:111:10:J1939_GetTxOverflowCount 1 ../Core/Src/j1939.c:115:6:HAL_CAN_RxFifo0MsgPendingCallback 2 -../Core/Src/j1939.c:129:13:J1939_ProcessRxFrame 29 -../Core/Src/j1939.c:231:6:J1939_ExchangeRxBuffer 2 -../Core/Src/j1939.c:239:6:J1939_ExchangeTxBuffer 9 -../Core/Src/j1939.c:282:6:GBT_CAN_ReInit 1 -../Core/Src/j1939.c:291:6:J_SendPacket 3 -../Core/Src/j1939.c:322:13:J_TxCheckTimeout 7 -../Core/Src/j1939.c:343:13:J_SendTpRts 1 -../Core/Src/j1939.c:358:13:J_SendTpDtRange 11 -../Core/Src/j1939.c:406:6:J_SendCTS 2 -../Core/Src/j1939.c:424:6:J_SendACK 1 -../Core/Src/j1939.c:439:6:GBT_CAN_FilterInit 2 -../Core/Src/j1939.c:459:13:J1939_RxBufferAdd 2 -../Core/Src/j1939.c:473:16:J1939_RxBufferGet 2 -../Core/Src/j1939.c:486:13:J1939_TxBufferAdd 2 -../Core/Src/j1939.c:500:16:J1939_TxBufferPeek 2 -../Core/Src/j1939.c:511:13:J1939_TxBufferDropFirst 2 -../Core/Src/j1939.c:520:13:J1939_TxQueueByPgn 4 +../Core/Src/j1939.c:129:13:J1939_ProcessRxFrame 30 +../Core/Src/j1939.c:227:6:J1939_ExchangeRxBuffer 2 +../Core/Src/j1939.c:235:6:J1939_ExchangeTxBuffer 9 +../Core/Src/j1939.c:278:6:GBT_CAN_ReInit 1 +../Core/Src/j1939.c:287:6:J_SendPacket 3 +../Core/Src/j1939.c:318:13:J_TxCheckTimeout 7 +../Core/Src/j1939.c:339:13:J_SendTpRts 1 +../Core/Src/j1939.c:354:13:J_SendTpDtRange 11 +../Core/Src/j1939.c:402:6:J_SendCTS 2 +../Core/Src/j1939.c:420:6:J_SendACK 1 +../Core/Src/j1939.c:435:6:GBT_CAN_FilterInit 2 +../Core/Src/j1939.c:455:13:J1939_RxBufferAdd 2 +../Core/Src/j1939.c:469:16:J1939_RxBufferGet 2 +../Core/Src/j1939.c:482:13:J1939_TxBufferAdd 2 +../Core/Src/j1939.c:496:16:J1939_TxBufferPeek 2 +../Core/Src/j1939.c:507:13:J1939_TxBufferDropFirst 2 +../Core/Src/j1939.c:516:13:J1939_TxQueueByPgn 4 diff --git a/Debug/Core/Src/main.cyclo b/Debug/Core/Src/main.cyclo index 44aad39..ba13d4e 100644 --- a/Debug/Core/Src/main.cyclo +++ b/Debug/Core/Src/main.cyclo @@ -38,6 +38,6 @@ /Users/colorbass/STM32CubeIDE/workspace_1.12.0/lib_EDCAN/edcan_log.c:26:6:EDCAN_printf 2 /Users/colorbass/STM32CubeIDE/workspace_1.12.0/lib_EDCAN/edcan_log.c:51:6:EDCAN_Log 2 /Users/colorbass/STM32CubeIDE/workspace_1.12.0/lib_EDCAN/edcan_log.c:76:6:EDCAN_SendPacketLog 1 -../Core/Src/main.c:84:5:main 1 -../Core/Src/main.c:180:6:SystemClock_Config 4 -../Core/Src/main.c:240:6:Error_Handler 1 +../Core/Src/main.c:84:5:main 2 +../Core/Src/main.c:181:6:SystemClock_Config 4 +../Core/Src/main.c:241:6:Error_Handler 1