Files
CCSModuleSW30Web/Core/Src/serial_handler.c

206 lines
7.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "serial_control.h"
#include "usart.h"
#include "charger_control.h"
#include "board.h"
#include "psu_control.h"
#include "debug.h"
#include <string.h>
#ifdef USE_WEB_INTERFACE
extern volatile SC_Source_t g_sc_command_source;
IsolationStatusPacket_t ISO = {
.isolationResistance = 0xFFFF
};
uint8_t config_initialized = 0;
ConfigBlock_t config = {
.location = "RUS",
.chargerNumber = 00001,
.unixTime = 1721651966,
};
// Единая функция-обработчик всех команд со switch-case
void SC_CommandHandler(ReceivedCommand_t* cmd) {
uint8_t response_code = RESP_FAILED;
switch (cmd->command) {
// Команды БЕЗ аргументов
case CMD_GET_STATUS:
// Логика получения информации
monitoring_data_callback();
// Отправляем с нормальным приоритетом
SC_SendPacket((uint8_t*)&statusPacket, sizeof(statusPacket), CMD_GET_STATUS);
return; // Специальный ответ уже отправлен
case CMD_GET_INFO:
SC_SendPacket((uint8_t*)&infoPacket, sizeof(infoPacket), CMD_GET_INFO);
return;
case CMD_GET_LOG:
debug_buffer_send();
return; // Ответ формируется внутри debug_buffer_send
// Команды С аргументами
case CMD_SET_CONFIG:
if (cmd->argument_length == sizeof(ConfigBlock_t)) {
memcpy(&config, cmd->argument, sizeof(ConfigBlock_t));
config_initialized = 1;
log_printf(LOG_INFO, "Set Config: %s %d\n", config.location, config.chargerNumber);
response_code = RESP_SUCCESS;
break;
}
response_code = RESP_FAILED;
break;
case CMD_SET_POWER_LIMIT:
if (cmd->argument_length == 1) {
PSU0.power_limit = ((uint8_t*)cmd->argument)[0] * 1000;
log_printf(LOG_INFO, "Power limit: %d\n", PSU0.power_limit);
//CONN.connState = (((uint8_t*)cmd->argument)[0])/4;
response_code = RESP_SUCCESS;
break;
}
response_code = RESP_FAILED;
break;
case CMD_CHARGE_PERMIT:
if (cmd->argument_length == 1) {
CONN.connControl = ((uint8_t*)cmd->argument)[0];
log_printf(LOG_INFO, "Charge permit: %d\n", CONN.connControl);
response_code = RESP_SUCCESS;
break;
}
response_code = RESP_FAILED;
break;
case CMD_TEST_PSU:
// if (cmd->argument_length == sizeof(PSU_TestMode_t)) {
// memcpy(&PSU_TestMode, cmd->argument, sizeof(PSU_TestMode_t));
// log_printf(LOG_INFO, "Test PSU: %d %d %d\n", PSU_TestMode.enable, PSU_TestMode.voltage, PSU_TestMode.current);
// response_code = RESP_SUCCESS;
// break;
// }
response_code = RESP_FAILED;
break;
case CMD_DEVICE_RESET:
// 2. Отправляем SUCCESS (хост может успеть получить его перед ребутом)
SC_SendPacket(NULL, 0, RESP_SUCCESS);
while(huart2.gState == HAL_UART_STATE_BUSY_TX); // Ожидание завершения передачи
HAL_Delay(10);
// 3. Выполняем программный сброс
NVIC_SystemReset();
return; // Сюда код уже не дойдет, но для компилятора нxужно
case CMD_ISOLATION_STATUS:
if (cmd->argument_length == sizeof(IsolationStatusPacket_t)) {
memcpy(&ISO, cmd->argument, sizeof(IsolationStatusPacket_t));
// Для однонаправленного UART5 ответ не нужен
if (g_sc_command_source == SC_SOURCE_UART5) {
return;
}
response_code = RESP_SUCCESS;
break;
}
response_code = RESP_FAILED;
break;
default:
// Неизвестная команда
response_code = RESP_FAILED;
break;
}
// Отправляем финальный ответ (для команд без собственного ответа)
SC_SendPacket(NULL, 0, response_code);
}
// Колбэк для заполнения данных мониторинга
void monitoring_data_callback() {
// Информация о зарядной сессии
statusPacket.SOC = CONN.SOC;
statusPacket.Energy = CONN.Energy;
statusPacket.RequestedVoltage = CONN.RequestedVoltage;
statusPacket.RequestedCurrent = CONN.WantedCurrent;
statusPacket.MeasuredVoltage = CONN.MeasuredVoltage;
statusPacket.MeasuredCurrent = CONN.MeasuredCurrent;
statusPacket.outputEnabled = CONN.outputEnabled;
statusPacket.chargingError = CONN.chargingError;
statusPacket.connState = CONN.connState;
statusPacket.chargingElapsedTimeMin = 0;
statusPacket.chargingElapsedTimeSec = 0;
statusPacket.estimatedRemainingChargingTime = 0;
// состояние зарядной станции
statusPacket.relayAC = RELAY_Read(RELAY_AC);
statusPacket.relayDC = RELAY_Read(RELAY_DC);
statusPacket.relayAUX = RELAY_Read(RELAY_AUX0);
statusPacket.lockState = 0;
statusPacket.stopButton = !IN_ReadInput(IN_ESTOP);
statusPacket.logAvailable = (debug_buffer_available()>0)?1:0;
statusPacket.evInfoAvailable = 0;
statusPacket.psuOnline = PSU0.online;
statusPacket.tempConnector0 = CONN_ReadTemp(0); // температура коннектора
statusPacket.tempConnector1 = CONN_ReadTemp(1);
statusPacket.tempAmbient = PSU0.tempAmbient; // температура окружающего воздуха
statusPacket.tempBatteryMax = 0;
statusPacket.tempBatteryMin = 0;
statusPacket.highestVoltageOfBatteryCell = 0;
statusPacket.batteryStatus = 0;
statusPacket.phaseVoltageAB = PSU_06.VAB;
statusPacket.phaseVoltageBC = PSU_06.VBC;
statusPacket.phaseVoltageCA = PSU_06.VCA;
// GBT TODO
memset(statusPacket.VIN, 0, sizeof(statusPacket.VIN));
// GBT TODO
statusPacket.batteryType = 0;
statusPacket.batteryCapacity = 0;
statusPacket.batteryVoltage = 0;
memset(statusPacket.batteryVendor, 0, sizeof(statusPacket.batteryVendor));
statusPacket.batterySN = 0;
statusPacket.batteryManuD = 0;
statusPacket.batteryManuM = 0;
statusPacket.batteryManuY = 0;
statusPacket.batteryCycleCount = 0;
statusPacket.ownAuto = 0;
memset(statusPacket.EV_SW_VER, 0, sizeof(statusPacket.EV_SW_VER));
statusPacket.testMode = 0;
statusPacket.testVoltage = 0;
statusPacket.testCurrent = 0;
// Информация о тачке
// --- Информация об EV (из команды info2) ---
// memcpy(statusPacket.version, GBT_EVInfo.version, sizeof(statusPacket.version));
// --- Состояние Hardware и GBT (различные команды) ---
//statusPacket.lockState = GBT_LockGetState(); // Из команды lock_state
//statusPacket.ccState = CONN_CC_GetState(); // Из команды cc_state
//statusPacket.ccAdc = CONN_CC_GetAdc(); // Из команды adc
// --- Поля, требующие внимания (неявные геттеры) ---
// 1. Состояние соединения (ConnState)
// В debug.c есть CONN_SetState, предполагаем наличие CONN_GetState()
// Если такой функции нет, закомментируйте следующую строку:
// statusPacket.connState = CONN_GetState();
}
#endif