13 Commits
Author SHA1 Message Date
raduetandCursor ae813f3764 Merge achamaikin/CCSModuleSW30Web upstream with fire alarm retained.
Take upstream board rev2, heater, and project cleanup; preserve fire alarm latch, CMD_FIRE_ALARM, and ESTOP maintenance logic.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-11 13:45:40 +02:00
raduetandCursor fb766dfa66 Add fire alarm handling for DC30 CCS main controller.
Latch fire alarm until reboot, block recovery commands, and send periodic Everest ESTOP while active.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-10 16:01:22 +02:00
achamaikin 1be17330fa almost done dma 2026-05-07 16:03:01 +03:00
achamaikin ea8663e247 last version before dma 2026-05-07 12:26:13 +03:00
achamaikin 910811df1d Enhance board and PSU control structures; update connector state handling and stop button logic. Adjust LED color cycles for better visual feedback. Refactor serial communication to improve state management and error handling. 2026-05-05 17:52:14 +03:00
achamaikin 944952689e add cp filter 2026-05-05 17:05:21 +03:00
achamaikin 92c33b2f46 latest version before merge 2026-05-05 12:25:24 +03:00
achamaikin 01c43840a5 v1.0.10, fake 500v 2026-04-09 12:40:18 +03:00
raduet f8daf17c6f Update to 1.0.6. Init ready 2026-03-26 17:46:42 +03:00
raduet 68903fe860 Update to version 1.0.5. Controller initalization added 2026-03-26 16:45:21 +03:00
raduet 878d425417 Update version to 1.0.4. Everest timeout flood fixed 2026-03-25 17:19:50 +03:00
raduet fad2a8ba18 Added post build options for correct output files list 2026-03-25 12:09:18 +03:00
raduet 317e418111 Update version to 1.0.3. Everest timeout changed to 2000ms. CP Line improved, added hysteresis, debounce and EMA filtering 2026-03-25 11:09:55 +03:00
32 changed files with 36138 additions and 37376 deletions
+1 -2
View File
@@ -332,9 +332,8 @@ PC5.GPIOParameters=GPIO_Label
PC5.GPIO_Label=LOCK_B PC5.GPIO_Label=LOCK_B
PC5.Locked=true PC5.Locked=true
PC5.Signal=GPIO_Output PC5.Signal=GPIO_Output
PC9.GPIOParameters=GPIO_Speed,GPIO_Label PC9.GPIOParameters=GPIO_Label
PC9.GPIO_Label=LED_DATA PC9.GPIO_Label=LED_DATA
PC9.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
PC9.Locked=true PC9.Locked=true
PC9.Signal=GPIO_Output PC9.Signal=GPIO_Output
PD0.Locked=true PD0.Locked=true
+133
View File
@@ -0,0 +1,133 @@
# Журнал изменений (сессия чата): `fork/CCSModuleSW30Web`
Документ фиксирует доработки проекта **CCSModuleSW30Web** в ветке/каталоге форка
`/Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web`, обсуждавшиеся и вносившиеся в рамках описанной сессии (UART, ADC/DMA, CP, отладка IRQ, оптимизация `-Ofast` для кода из прерываний).
---
## 1. UART и протокол
### 1.1. UART3 (Everest / `serial.c`)
- Таймаут «нет связи с хостом»:** `EVEREST_TIMEOUT_MS` = **5000** мс.
- Жёсткий реинициал при отсутствии RX:** `UART3_REINIT_TIMEOUT_MS` = **1500** мс (с защитой от слишком частых реинициалов через `uart3_last_reinit_tick`).
- Расширено логирование путей сброса/ошибок приёма и ошибок HAL для диагностики «таймаут без остановки UART3».
- Колбэки и вспомогательные функции, вызываемые из контекста прерывания, помечены **`ISR_FAST`** (см. раздел 6):
`CCS_RxEventCallback`, `HAL_UART_ErrorCallback`, `uart3_log_hal_error`, `uart3_arm_rx_or_log`, цепочка разбора пакета (`process_received_packet`, `crc16_ibm`, `expected_payload_len`, `apply_command`).
### 1.2. UART2 / `serial_control.c`
- Отдельная логика **`SC_UART2_Watchdog()`**, вызывается из **`SC_Task()`** (не из IRQ).
- Константы:
- **`SC_UART2_REINIT_TIMEOUT_MS`** = **500** мс — порог для жёсткого реинициала при отсутствии пакетов;
- **`SC_UART2_PACKET_TIMEOUT_MS`** = **5000** мс — таймаут коммуникации.
- Сценарий **новый пакет при `BUSY_TX`**: при необходимости **`Abort_IT`**, сброс направления RS-485, затем повторная инициализация UART и приём `ReceiveToIdle_IT` (защита от обрыва TX из-за агрессивного watchdog).
- Отдельная ветка **жёсткого реинициала при `BUSY_TX`** с логом `USART2 BUSY_TX: hard reinit` (отслеживание `sc_uart2_last_busy_tx_reinit_packet_tick`).
- HAL-колбэки **`HAL_UARTEx_RxEventCallback`**, **`HAL_UART_TxCpltCallback`** помечены **`ISR_FAST`**.
### 1.3. `SC_SendPacket` и стек CRC/кодирования
- Для единообразной оптимизации пути «IRQ → ответ» на функции **`calculate_crc32`**, **`encode_packet`**, **`parse_packet`**, **`process_received_packet`** и публичную **`SC_SendPacket`** добавлен **`ISR_FAST`**.
- В **`Core/Inc/serial_control.h`**: подключение **`isr_opt.h`**, прототип **`ISR_FAST void SC_SendPacket(...)`** (согласованность с определением в `.c`).
**Замечание:** `SC_SendPacket` вызывается и из основного потока; для GCC вся функция компилируется с `-Ofast`. При необходимости строгого разделения можно вынести отдельную версию «только из IRQ».
---
## 2. Отладочные линии DBG в `stm32f1xx_it.c`
На время входа/выхода из выбранных обработчиков прерываний поднимается/опускается соответствующий GPIO — удобно для осциллографа (длительность IRQ).
| Линия | Обработчик |
|--------|------------|
| **DBG1** | `UART5_IRQHandler` |
| **DBG2** | `USART2_IRQHandler` |
| **DBG3** | `USART3_IRQHandler` |
| **DBG4** | `DMA1_Channel1_IRQHandler`, `ADC1_2_IRQHandler`, `TIM3_IRQHandler` |
| **DBG5** | `CAN1_RX0_IRQHandler`, `CAN2_TX_IRQHandler`, `CAN2_RX1_IRQHandler` |
| — | `USART1_IRQHandler` — без обёртки DBG (по согласованию) |
В **`DMA1_Channel1_IRQHandler`** вызывается **`HAL_DMA_IRQHandler(&hdma_adc1)`** для цепочки ADC+DMA.
Для всего файла **`stm32f1xx_it.c`** под GCC добавлено:
```c
#pragma GCC optimize("Ofast")
```
(в блоке `USER CODE BEGIN Includes`).
---
## 3. ADC: DMA, глобальные данные, колбэк
- Файлы **`adc.c` / `adc.h`**: структура **`ADC_ScanData_t`**, глобально **`volatile ADC_ScanData_t adc_data`** с полями сырых каналов (`in3_raw`, `cp_raw`, `ntc1_raw`, `ntc2_raw`, `temp_sensor_raw`, `vrefint_raw` и т.д. по фактическому объявлению в заголовке).
- **`HAL_ADC_ConvCpltCallback`**: копирование из буфера DMA в **`adc_data`**, помечен **`ISR_FAST`**.
- Публичная **`ADC_ScanStart()`** — запуск сканирования (после калибровки вызывается из инициализации платы).
- **`board.c`**: после **`HAL_ADCEx_Calibration_Start`** вызывается **`ADC_ScanStart()`**; **`CONN_ReadTemp`** читает **`adc_data.ntc1_raw` / `ntc2_raw`** вместо блокирующего опроса ADC.
**Диагностика (из обсуждения):** если не вызываются **`HAL_ADC_ConvCpltCallback`** / **`HAL_DMA_IRQHandler`**, проверять: срабатывание триггера ADC (например, **TIM3 TRGO**), работу TIM3, порядок инициализации DMA/NVIC, срабатывание **`DMA1_Channel1_IRQHandler`**.
---
## 4. CP (`cp.c` / `cp.h`)
- Измерение опоры на **`adc_data.cp_raw`** (и при необходимости **`vrefint_raw`** по текущей реализации в коде).
- Логика классификации/порогов приведена к варианту, согласованному с основным **CCSModuleSW30Web** (не форк).
- Сэмпл по таймеру: уход от тяжёлой работы в IRQ OC — использование **`HAL_TIM_OC_Start`** без прерывания по сравнению, обновление напряжения в **`CP_GetVoltage()`** / основном цикле (**`CP_Loop`** опирается на **`CP_GetState()`** и т.п. по фактическому коду).
---
## 5. Отладочный UART (`debug.c`)
При **`#ifndef USE_WEB_INTERFACE`** (или эквивалентной ветке сборки в файле): колбэк **`HAL_UARTEx_RxEventCallback`** и **`debug_rx_interrupt`** помечены **`ISR_FAST`**.
---
## 6. Оптимизация `-Ofast` для кода из прерываний
### 6.1. Макрос `ISR_FAST`
Файл **`Core/Inc/isr_opt.h`**:
- **GCC:** `#define ISR_FAST __attribute__((optimize("Ofast")))`
- **Иное:** пустой макрос.
### 6.2. Где используется (по состоянию репозитория)
| Файл | Элементы с `ISR_FAST` / pragma |
|------|--------------------------------|
| `stm32f1xx_it.c` | `#pragma GCC optimize("Ofast")` на весь файл (GCC) |
| `adc.c` | `HAL_ADC_ConvCpltCallback` |
| `serial.c` | `CCS_RxEventCallback`, `HAL_UART_ErrorCallback`, `uart3_log_hal_error`, `uart3_arm_rx_or_log`, `process_received_packet`, `crc16_ibm`, `expected_payload_len`, `apply_command` |
| `serial_control.c` | `HAL_UARTEx_RxEventCallback`, `HAL_UART_TxCpltCallback`, `calculate_crc32`, `encode_packet`, `parse_packet`, `process_received_packet`, `SC_SendPacket` |
| `serial_control.h` | прототип `SC_SendPacket` + `#include "isr_opt.h"` |
| `psu_control.c` | `HAL_CAN_RxFifo1MsgPendingCallback` |
| `debug.c` | см. раздел 5 |
---
## 7. Ограничения и переносимость
- **`ISR_FAST`** и pragma в **`stm32f1xx_it.c`** рассчитаны на **GCC** (STM32CubeIDE по умолчанию). Для **IAR / ARM Compiler 6** потребуется отдельная стратегия (прагмы/ключи проекта).
- **`-Ofast`** допускает агрессивные преобразования с плавающей точкой и перестановки, влияющие на строго воспроизводимую арифметику; для критичных вычислений вне IRQ при необходимости ограничивайте область оптимизации.
---
## 8. Затронутые пути (краткий список)
- `Core/Inc/isr_opt.h` — новый/центральный заголовок оптимизации IRQ.
- `Core/Inc/serial_control.h``isr_opt.h`, `ISR_FAST` у `SC_SendPacket`.
- `Core/Src/stm32f1xx_it.c` — DBG, DMA ADC, pragma `Ofast`.
- `Core/Src/adc.c`, `Core/Inc/adc.h` — DMA, `adc_data`, `ADC_ScanStart`, колбэк.
- `Core/Src/board.c` — калибровка, старт скана, температура из `adc_data`.
- `Core/Src/cp.c`, `Core/Inc/cp.h` — CP и ADC.
- `Core/Src/serial.c` — UART3, таймауты, логи, `ISR_FAST`.
- `Core/Src/serial_control.c` — UART2, watchdog, `ISR_FAST`.
- `Core/Src/psu_control.c` — CAN RX callback.
- `Core/Src/debug.c` — отладочный UART под условием сборки.
- `Core/Src/dma.c`, `gpio.c`, `main.h` — по необходимости для DMA1 Ch1 и DBG-пинов.
---
*Документ сгенерирован для фиксации контекста сессии; при дальнейших правках кода имеет смысл обновлять соответствующие разделы вручную.*
+4 -21
View File
@@ -9,24 +9,7 @@
#define PSU_NUM 1 #define PSU_NUM 1
/* Dynamic LV clamp (CS60 hv_limit): active only on overload at low bus voltage. */ /* Everest / стенд: запрос «500 В» на шине — реально на PSU задаются U/I ниже; статус может оставаться 500 В (serial.c). */
#define PSU_LV_CLAMP_V 499u #define FAKE_EVREQ_VOLTAGE_V 500u
#define PSU_HV_LIMIT_ON_THRESHOLD 480u #define FAKE_PSU_VOLTAGE_V 300u
#define PSU_HV_LIMIT_OFF_THRESHOLD 495u #define FAKE_PSU_CURRENT_0P1A 10u
#define PSU_HV_SWITCH_DELAY_MS 1000u
#define PSU_HV_LOAD_CURRENT 300u /* 30.0 A, MeasuredCurrent is 0.1 A/bit */
#define PSU_HV_LIMIT_MAX_COUNT 3u
/* Fast discharge: PSU off/on cycle on step-down setpoint (unloaded bus). */
#define PSD_ENABLE 1u
#define PSD_MAX_CMD_CURRENT_0P1A 20u /* 2.0 A */
#define PSD_MAX_MEASURED_CURRENT_0P1A 30u /* 3.0 A */
#define PSD_MEASURED_LATCH_MS 500u
#define PSD_MIN_VOLTAGE_STEP_V 50u
#define PSD_DISCHARGE_MARGIN_V 15u
#define PSD_DEBOUNCE_MS 2000u
#define PSD_MAX_PER_SESSION 4u
#define PSD_OFF_TIMEOUT_MS 10000u /* как PSU_WAIT_ACK_OFF */
#define PSD_ON_TIMEOUT_MS 10000u
#define PSD_ON_RETRY_MS 500u /* повтор SET+ON в ON_WAIT */
#define PSD_PRECHARGE_TOLERANCE_V 40u /* ~±10% for 350 V precharge window */
-5
View File
@@ -68,10 +68,6 @@ typedef struct{
uint16_t WantedCurrent; //0.1A/bit uint16_t WantedCurrent; //0.1A/bit
CONN_Error_t chargingError; // 0 if okay CONN_Error_t chargingError; // 0 if okay
uint8_t EvConnected; uint8_t EvConnected;
uint32_t ChargingTime; // seconds of active charging in current session
uint8_t hv_limit; // Limits PSU voltage to LV range when set
uint32_t hv_tick; // Timer for delayed HV limit switching
uint8_t hv_limit_count; // Anti-chatter counter for LV limit switching
} ChargingConnector_t; } ChargingConnector_t;
@@ -83,4 +79,3 @@ extern ChargingConnector_t CONN;
void CONN_Init(); void CONN_Init();
void CONN_Loop(); void CONN_Loop();
void CONN_GetElapsedForMonitoring(uint16_t *min, uint8_t *sec);
+2
View File
@@ -4,6 +4,8 @@
#include <stdint.h> #include <stdint.h>
uint8_t FireAlarm_IsLatched(void); uint8_t FireAlarm_IsLatched(void);
uint8_t FireAlarm_IsBlockingCommand(uint8_t command_code);
void FireAlarm_Activate(void); void FireAlarm_Activate(void);
void FireAlarm_Maintain(void);
#endif /* INC_FIRE_ALARM_H_ */ #endif /* INC_FIRE_ALARM_H_ */
+1 -1
View File
@@ -27,7 +27,7 @@ extern "C" {
/* USER CODE BEGIN EC */ /* USER CODE BEGIN EC */
#define FW_VERSION_MAJOR 1 #define FW_VERSION_MAJOR 1
#define FW_VERSION_MINOR 0 #define FW_VERSION_MINOR 0
#define FW_VERSION_PATCH 27 #define FW_VERSION_PATCH 18
/* USER CODE END EC */ /* USER CODE END EC */
/* Exported macro ------------------------------------------------------------*/ /* Exported macro ------------------------------------------------------------*/
-21
View File
@@ -1,21 +0,0 @@
#pragma once
#include <stdint.h>
#include "power_setpoint_policy.h"
typedef enum {
PSD_TRY_IDLE = 0,
PSD_TRY_APPLIED_NORMAL,
PSD_TRY_START_FAST_DISCHARGE,
} PowerSetpointTryResult_t;
void PowerSetpoint_Init(void);
void PowerSetpoint_OnCommand(uint16_t voltage_V, uint16_t current_0p1A);
void PowerSetpoint_UpdateDeliveryLatch(void);
uint8_t PowerSetpoint_HasPending(void);
uint8_t PowerSetpoint_IsBusy(void);
PowerSetpointTryResult_t PowerSetpoint_TryApply(void);
void PowerSetpoint_GetFastDischargeTarget(PowerSetpoint_t *target);
void PowerSetpoint_OnFastDischargeComplete(void);
void PowerSetpoint_OnFastDischargeAbort(void);
-35
View File
@@ -1,35 +0,0 @@
#pragma once
#include <stdint.h>
#include "charger_config.h"
typedef struct {
uint16_t voltage_V;
uint16_t current_0p1A;
} PowerSetpoint_t;
typedef enum {
POWER_SETPOINT_NORMAL,
POWER_SETPOINT_FAST_DISCHARGE,
} PowerSetpointAction_t;
typedef struct {
uint8_t dc_contactor_closed;
uint8_t psu_hv_enabled;
uint16_t measured_voltage_V;
uint16_t measured_current_0p1A;
uint8_t power_delivery_active;
uint8_t enable_output;
uint8_t psu_state_connected;
uint8_t psu_cont_fault;
uint8_t psu_fault;
uint8_t fast_discharge_count;
uint32_t last_fast_discharge_ms;
uint32_t now_ms;
} PowerPathContext_t;
PowerSetpointAction_t PowerSetpoint_Decide(
const PowerSetpoint_t *applied,
const PowerSetpoint_t *next,
const PowerPathContext_t *ctx);
+2 -6
View File
@@ -5,7 +5,6 @@
void PSU_Init(); void PSU_Init();
void PSU_Enable(uint8_t addr, uint8_t enable); void PSU_Enable(uint8_t addr, uint8_t enable);
void PSU_SetVoltageCurrent(uint8_t addr, uint16_t voltage, uint16_t current);
void PSU_ReadWrite(void); void PSU_ReadWrite(void);
// --- Состояние силового модуля (DC30, один PSU) --- // --- Состояние силового модуля (DC30, один PSU) ---
@@ -17,11 +16,6 @@ typedef enum{
PSU_WAIT_ACK_ON, // ждём подтверждение включения модуля (напряжение выше порога) PSU_WAIT_ACK_ON, // ждём подтверждение включения модуля (напряжение выше порога)
PSU_CONT_WAIT_ACK_ON, // включаем DC-контактор и ждём подтверждение PSU_CONT_WAIT_ACK_ON, // включаем DC-контактор и ждём подтверждение
PSU_CONNECTED, // модуль включён, DC-контактор замкнут PSU_CONNECTED, // модуль включён, DC-контактор замкнут
PSU_FAST_DISCHARGE_OFF,
PSU_FAST_DISCHARGE_WAIT, /* ждём подтверждение выключения (как PSU_WAIT_ACK_OFF) */
PSU_FAST_DISCHARGE_SET, /* задать целевое U/I при выключенном модуле */
PSU_FAST_DISCHARGE_ON, /* команда включения после set */
PSU_FAST_DISCHARGE_ON_WAIT, /* ждём подтверждение включения (как PSU_WAIT_ACK_ON) */
PSU_CURRENT_DROP, // снижение тока перед отключением PSU_CURRENT_DROP, // снижение тока перед отключением
PSU_WAIT_ACK_OFF, // ждём подтверждение выключения модуля (напряжение ниже порога) PSU_WAIT_ACK_OFF, // ждём подтверждение выключения модуля (напряжение ниже порога)
PSU_CONT_WAIT_ACK_OFF, // выключаем DC-контактор и ждём подтверждение PSU_CONT_WAIT_ACK_OFF, // выключаем DC-контактор и ждём подтверждение
@@ -84,6 +78,8 @@ typedef struct {
// Дополнительные параметры для одного модуля DC30 // Дополнительные параметры для одного модуля DC30
uint32_t power_limit; // лимит мощности [кВт] uint32_t power_limit; // лимит мощности [кВт]
uint8_t hv_mode; // HV-режим (ограничение напряжения)
uint32_t hv_tick; // таймер для задержки входа в HV-режим
uint32_t tempAmbient; // температура окружающего воздуха (из PSU_04) uint32_t tempAmbient; // температура окружающего воздуха (из PSU_04)
union { uint8_t raw; PSU_Status0_t bits; } status0; // modularForm0 union { uint8_t raw; PSU_Status0_t bits; } status0; // modularForm0
-2
View File
@@ -41,5 +41,3 @@ void LED_Task();
void LED_Write(); void LED_Write();
void LED_Init(); void LED_Init();
void LED_SetColor(RGB_Cycle_t *color); void LED_SetColor(RGB_Cycle_t *color);
void RGB_SetColor(RGB_t *color);
void WS2812_SetColor(RGB_t *color);
+8 -27
View File
@@ -13,24 +13,24 @@ void CONN_Init(){
CONN.connControl = CMD_NONE; CONN.connControl = CMD_NONE;
CONN.connState = Unknown; CONN.connState = Unknown;
CONN.RequestedVoltage = PSU_MIN_VOLTAGE; CONN.RequestedVoltage = PSU_MIN_VOLTAGE;
CONN.ChargingTime = 0;
CONN.hv_limit = 0u;
CONN.hv_tick = 0u;
CONN.hv_limit_count = 0u;
} }
void CONN_Loop(){ void CONN_Loop(){
static uint32_t charging_time_tick = 0;
static CONN_State_t last_connState = Unknown; static CONN_State_t last_connState = Unknown;
if (FireAlarm_IsLatched()) {
CONN.chargingError = CONN_ERR_FIRE_ALARM;
CONN.EnableOutput = 0;
return;
}
if(last_connState != CONN.connState){ if(last_connState != CONN.connState){
last_connState = CONN.connState; last_connState = CONN.connState;
CONN.connControl = CMD_NONE; CONN.connControl = CMD_NONE;
} }
if (FireAlarm_IsLatched()) { if(PSU0.cont_fault){
CONN.chargingError = CONN_ERR_FIRE_ALARM;
} else if(PSU0.cont_fault){
CONN.chargingError = CONN_ERR_CONTACTOR; CONN.chargingError = CONN_ERR_CONTACTOR;
} else if(PSU0.psu_fault){ } else if(PSU0.psu_fault){
CONN.chargingError = CONN_ERR_PSU_FAULT; CONN.chargingError = CONN_ERR_PSU_FAULT;
@@ -42,25 +42,6 @@ void CONN_Loop(){
log_printf(LOG_WARN, "CONN0 Error: %d\n", (int)CONN.chargingError); log_printf(LOG_WARN, "CONN0 Error: %d\n", (int)CONN.chargingError);
} }
if (HAL_GetTick() - charging_time_tick >= 1000U) {
charging_time_tick += 1000U;
if (CONN.connState == Charging) {
CONN.ChargingTime++;
}
if (CONN.connState == Unplugged) {
CONN.ChargingTime = 0;
}
}
}
void CONN_GetElapsedForMonitoring(uint16_t *min, uint8_t *sec) {
uint32_t elapsed_sec = CONN.ChargingTime;
if (min != NULL) {
*min = (uint16_t)(elapsed_sec / 60U);
}
if (sec != NULL) {
*sec = (uint8_t)(elapsed_sec % 60U);
}
} }
void CONN_SetState(CONN_State_t state){ void CONN_SetState(CONN_State_t state){
+56 -2
View File
@@ -1,20 +1,74 @@
#include "fire_alarm.h" #include "fire_alarm.h"
#include "serial_control.h"
#include "charger_control.h" #include "charger_control.h"
#include "debug.h" #include "connector.h"
#include "serial.h" #include "serial.h"
#include "cp.h"
#include "debug.h"
static uint8_t fire_alarm_latched = 0; static uint8_t fire_alarm_latched = 0;
static uint32_t fire_alarm_last_estop_tick = 0;
extern CCS_ConnectorState_t CCS_ConnectorState;
uint8_t FireAlarm_IsLatched(void) { uint8_t FireAlarm_IsLatched(void) {
return fire_alarm_latched; return fire_alarm_latched;
} }
uint8_t FireAlarm_IsBlockingCommand(uint8_t command_code) {
if (!fire_alarm_latched) {
return 0;
}
switch (command_code) {
case CMD_GET_STATUS:
case CMD_GET_INFO:
case CMD_GET_LOG:
case CMD_DEVICE_RESET:
return 0;
default:
return 1;
}
}
void FireAlarm_Activate(void) { void FireAlarm_Activate(void) {
if (fire_alarm_latched) { if (fire_alarm_latched) {
return; return;
} }
fire_alarm_latched = 1; fire_alarm_latched = 1;
CONN.chargingError = CONN_ERR_FIRE_ALARM;
CONN.connControl = CMD_STOP;
CONN.EnableOutput = 0;
log_printf(LOG_ERR, "FIRE ALARM activated\n"); log_printf(LOG_ERR, "FIRE ALARM activated\n");
CCS_SendEmergencyStop();
fire_alarm_last_estop_tick = HAL_GetTick();
CP_SetDuty(100);
CCS_ConnectorState = CCS_DISABLED;
CONN_SetState(Disabled);
}
void FireAlarm_Maintain(void) {
if (!fire_alarm_latched) {
return;
}
CONN.chargingError = CONN_ERR_FIRE_ALARM;
CONN.EnableOutput = 0;
CP_SetDuty(100);
if ((int32_t)(HAL_GetTick() - fire_alarm_last_estop_tick) >= 1000) {
CCS_SendEmergencyStop();
fire_alarm_last_estop_tick = HAL_GetTick();
}
if (CCS_ConnectorState != CCS_DISABLED && CCS_ConnectorState != CCS_UNKNOWN) {
CCS_ConnectorState = CCS_DISABLED;
}
if (CONN.connState != Disabled) {
CONN_SetState(Disabled);
}
} }
+5 -5
View File
@@ -54,15 +54,15 @@ void MX_GPIO_Init(void)
/*Configure GPIO pin Output Level */ /*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOD, RELAY_DC_Pin|USART2_DIR_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOD, RELAY_DC_Pin|USART2_DIR_Pin, GPIO_PIN_RESET);
/*Configure GPIO pins : DBG1_Pin LED_DATA_Pin */ /*Configure GPIO pin : DBG1_Pin */
GPIO_InitStruct.Pin = DBG1_Pin|LED_DATA_Pin; GPIO_InitStruct.Pin = DBG1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); HAL_GPIO_Init(DBG1_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : RELAY_CP_Pin LOCK_A_Pin LOCK_B_Pin */ /*Configure GPIO pins : RELAY_CP_Pin LOCK_A_Pin LOCK_B_Pin LED_DATA_Pin */
GPIO_InitStruct.Pin = RELAY_CP_Pin|LOCK_A_Pin|LOCK_B_Pin; GPIO_InitStruct.Pin = RELAY_CP_Pin|LOCK_A_Pin|LOCK_B_Pin|LED_DATA_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
-196
View File
@@ -1,196 +0,0 @@
#include "power_setpoint_executor.h"
#include "charger_config.h"
#include "charger_control.h"
#include "debug.h"
#include "psu_control.h"
#include "serial.h"
static PowerSetpoint_t applied;
static PowerSetpoint_t pending;
static PowerSetpoint_t fd_target;
static uint8_t setpoint_dirty;
static uint8_t fd_active;
static uint8_t power_delivery_latched;
static uint8_t fast_discharge_count;
static uint32_t last_fast_discharge_ms;
static uint32_t measured_high_current_since_ms;
static uint8_t session_ended_state(CONN_State_t state)
{
return (state == Unknown) || (state == Unplugged) || (state == Finished) ||
(state == FinishedEV) || (state == FinishedEVSE);
}
void PowerSetpoint_Init(void)
{
applied.voltage_V = PSU_MIN_VOLTAGE;
applied.current_0p1A = 0u;
pending = applied;
fd_target = applied;
setpoint_dirty = 0u;
fd_active = 0u;
power_delivery_latched = 0u;
fast_discharge_count = 0u;
last_fast_discharge_ms = 0u;
measured_high_current_since_ms = 0u;
}
void PowerSetpoint_OnCommand(uint16_t voltage_V, uint16_t current_0p1A)
{
#if PSD_ENABLE
pending.voltage_V = voltage_V;
pending.current_0p1A = current_0p1A;
setpoint_dirty = 1u;
#else
(void)voltage_V;
(void)current_0p1A;
#endif
}
void PowerSetpoint_UpdateDeliveryLatch(void)
{
#if PSD_ENABLE
uint32_t now = HAL_GetTick();
if (!CONN.EnableOutput || !CONN.EvConnected || session_ended_state(CCS_EvseState)) {
power_delivery_latched = 0u;
fast_discharge_count = 0u;
last_fast_discharge_ms = 0u;
measured_high_current_since_ms = 0u;
return;
}
if (CONN.WantedCurrent > PSD_MAX_CMD_CURRENT_0P1A) {
power_delivery_latched = 1u;
}
if (CCS_EvseState == Charging) {
power_delivery_latched = 1u;
}
if (CONN.MeasuredCurrent >= PSD_MAX_MEASURED_CURRENT_0P1A) {
if (measured_high_current_since_ms == 0u) {
measured_high_current_since_ms = now;
} else if ((now - measured_high_current_since_ms) >= PSD_MEASURED_LATCH_MS) {
power_delivery_latched = 1u;
}
} else {
measured_high_current_since_ms = 0u;
}
#endif
}
uint8_t PowerSetpoint_HasPending(void)
{
#if PSD_ENABLE
return setpoint_dirty;
#else
return 0u;
#endif
}
uint8_t PowerSetpoint_IsBusy(void)
{
#if PSD_ENABLE
if (!fd_active) {
return 0u;
}
switch (PSU0.state) {
case PSU_FAST_DISCHARGE_OFF:
case PSU_FAST_DISCHARGE_WAIT:
case PSU_FAST_DISCHARGE_SET:
case PSU_FAST_DISCHARGE_ON:
case PSU_FAST_DISCHARGE_ON_WAIT:
return 1u;
default:
return 0u;
}
#else
return 0u;
#endif
}
static PowerPathContext_t build_context(void)
{
PowerPathContext_t ctx;
ctx.dc_contactor_closed = PSU0.CONT_enabled;
ctx.psu_hv_enabled = PSU0.PSU_enabled;
ctx.measured_voltage_V = CONN.MeasuredVoltage;
ctx.measured_current_0p1A = (uint16_t)CONN.MeasuredCurrent;
ctx.power_delivery_active = power_delivery_latched;
ctx.enable_output = CONN.EnableOutput;
ctx.psu_state_connected = (PSU0.state == PSU_CONNECTED) ? 1u : 0u;
ctx.psu_cont_fault = PSU0.cont_fault;
ctx.psu_fault = PSU0.psu_fault;
ctx.fast_discharge_count = fast_discharge_count;
ctx.last_fast_discharge_ms = last_fast_discharge_ms;
ctx.now_ms = HAL_GetTick();
return ctx;
}
PowerSetpointTryResult_t PowerSetpoint_TryApply(void)
{
#if PSD_ENABLE
PowerPathContext_t ctx;
PowerSetpointAction_t action;
if (!setpoint_dirty || fd_active) {
return PSD_TRY_IDLE;
}
ctx = build_context();
action = PowerSetpoint_Decide(&applied, &pending, &ctx);
if (action == POWER_SETPOINT_FAST_DISCHARGE) {
fd_target = pending;
fd_active = 1u;
setpoint_dirty = 0u;
log_printf(LOG_INFO, "Fast discharge trigger %u->%u I=%u\n",
(unsigned)applied.voltage_V,
(unsigned)fd_target.voltage_V,
(unsigned)fd_target.current_0p1A);
return PSD_TRY_START_FAST_DISCHARGE;
}
if (!PSU0.ready) {
return PSD_TRY_IDLE;
}
PSU_SetVoltageCurrent(0, pending.voltage_V, pending.current_0p1A);
applied = pending;
setpoint_dirty = 0u;
return PSD_TRY_APPLIED_NORMAL;
#else
return PSD_TRY_IDLE;
#endif
}
void PowerSetpoint_GetFastDischargeTarget(PowerSetpoint_t *target)
{
if (target != 0) {
*target = fd_target;
}
}
void PowerSetpoint_OnFastDischargeComplete(void)
{
#if PSD_ENABLE
applied = fd_target;
fd_active = 0u;
fast_discharge_count++;
last_fast_discharge_ms = HAL_GetTick();
log_printf(LOG_INFO, "Fast discharge complete, V=%u\n", (unsigned)CONN.MeasuredVoltage);
#endif
}
void PowerSetpoint_OnFastDischargeAbort(void)
{
#if PSD_ENABLE
fd_active = 0u;
pending = fd_target;
setpoint_dirty = 1u;
log_printf(LOG_WARN, "Fast discharge aborted, V=%u\n", (unsigned)CONN.MeasuredVoltage);
#endif
}
-77
View File
@@ -1,77 +0,0 @@
#include "power_setpoint_policy.h"
PowerSetpointAction_t PowerSetpoint_Decide(
const PowerSetpoint_t *applied,
const PowerSetpoint_t *next,
const PowerPathContext_t *ctx)
{
#if !PSD_ENABLE
(void)applied;
(void)next;
(void)ctx;
return POWER_SETPOINT_NORMAL;
#else
uint16_t delta_v;
if (applied == 0 || next == 0 || ctx == 0) {
return POWER_SETPOINT_NORMAL;
}
if (next->voltage_V >= applied->voltage_V) {
return POWER_SETPOINT_NORMAL;
}
delta_v = (uint16_t)(applied->voltage_V - next->voltage_V);
if (delta_v < PSD_MIN_VOLTAGE_STEP_V) {
return POWER_SETPOINT_NORMAL;
}
if (applied->current_0p1A > PSD_MAX_CMD_CURRENT_0P1A ||
next->current_0p1A > PSD_MAX_CMD_CURRENT_0P1A) {
return POWER_SETPOINT_NORMAL;
}
if (ctx->measured_current_0p1A >= PSD_MAX_MEASURED_CURRENT_0P1A) {
return POWER_SETPOINT_NORMAL;
}
if (ctx->measured_voltage_V <= (uint16_t)(next->voltage_V + PSD_DISCHARGE_MARGIN_V)) {
return POWER_SETPOINT_NORMAL;
}
if (ctx->power_delivery_active) {
return POWER_SETPOINT_NORMAL;
}
if (!ctx->enable_output) {
return POWER_SETPOINT_NORMAL;
}
if (!ctx->psu_state_connected) {
return POWER_SETPOINT_NORMAL;
}
if (!ctx->dc_contactor_closed) {
return POWER_SETPOINT_NORMAL;
}
if (!ctx->psu_hv_enabled) {
return POWER_SETPOINT_NORMAL;
}
if (ctx->psu_cont_fault || ctx->psu_fault) {
return POWER_SETPOINT_NORMAL;
}
if (ctx->fast_discharge_count >= PSD_MAX_PER_SESSION) {
return POWER_SETPOINT_NORMAL;
}
if (ctx->last_fast_discharge_ms != 0u &&
(ctx->now_ms - ctx->last_fast_discharge_ms) < PSD_DEBOUNCE_MS) {
return POWER_SETPOINT_NORMAL;
}
return POWER_SETPOINT_FAST_DISCHARGE;
#endif
}
+21 -305
View File
@@ -6,7 +6,6 @@
#include "charger_control.h" #include "charger_control.h"
#include "debug.h" #include "debug.h"
#include "isr_opt.h" #include "isr_opt.h"
#include "power_setpoint_executor.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@@ -26,165 +25,14 @@ PSU_t PSU0;
#define PSU_VOLTAGE_THRESHOLD 20 // Порог напряжения для определения состояния (В) #define PSU_VOLTAGE_THRESHOLD 20 // Порог напряжения для определения состояния (В)
#define PSU_ONLINE_TIMEOUT 500 // Таймаут для определения состояния (мс) #define PSU_ONLINE_TIMEOUT 500 // Таймаут для определения состояния (мс)
#define PSU_STARTUP_DELAY 4000 // Задержка 2 секунды перед включением #define PSU_STARTUP_DELAY 4000 // Задержка 2 секунды перед включением
#define PSU_DIAG_LOG_MS 2000u
uint32_t can_lastpacket; uint32_t can_lastpacket;
extern CAN_HandleTypeDef hcan2; extern CAN_HandleTypeDef hcan2;
static uint16_t psu_last_can_v;
static uint16_t psu_last_can_i_0p1A;
static void PSU_SendCmd(uint8_t source, uint8_t destination, uint8_t cmd, void *data); static void PSU_SendCmd(uint8_t source, uint8_t destination, uint8_t cmd, void *data);
static const char *PSU_StateName(PSU_State_t state)
{
switch (state) {
case PSU_UNREADY: return "UNREADY";
case PSU_INITIALIZING: return "INIT";
case PSU_READY: return "READY";
case PSU_WAIT_ACK_ON: return "WAIT_ON";
case PSU_CONT_WAIT_ACK_ON: return "CONT_ON";
case PSU_CONNECTED: return "CONNECTED";
case PSU_FAST_DISCHARGE_OFF: return "FD_OFF";
case PSU_FAST_DISCHARGE_WAIT: return "FD_WAIT";
case PSU_FAST_DISCHARGE_SET: return "FD_SET";
case PSU_FAST_DISCHARGE_ON: return "FD_ON";
case PSU_FAST_DISCHARGE_ON_WAIT: return "FD_ON_WAIT";
case PSU_CURRENT_DROP: return "CUR_DROP";
case PSU_CONT_WAIT_ACK_OFF: return "CONT_OFF";
case PSU_WAIT_ACK_OFF: return "WAIT_OFF";
case PSU_OFF_PAUSE: return "OFF_PAUSE";
default: return "?";
}
}
static void PSU_LogPeriodicDiag(void)
{
static uint32_t last_log_ms;
uint32_t now = HAL_GetTick();
uint8_t block_setpoint;
if ((now - last_log_ms) < PSU_DIAG_LOG_MS) {
return;
}
last_log_ms = now;
#if PSD_ENABLE
block_setpoint = PowerSetpoint_HasPending() || PowerSetpoint_IsBusy();
#else
block_setpoint = 0u;
#endif
log_printf(LOG_INFO,
"PSU diag st=%s req=%uV/%u.%uA want=%uV/%u.%uA "
"can=%uV/%u.%uA meas=%uV/%d.%uA "
"enOut=%u out=%u rdy=%u on=%u cont=%u ac=%u hv=%u psd_blk=%u "
"err=%u s0=0x%02x s1=0x%02x s2=0x%02x can_age=%lums\n",
PSU_StateName(PSU0.state),
(unsigned)CONN.RequestedVoltage,
(unsigned)(CONN.RequestedCurrent / 10u),
(unsigned)(CONN.RequestedCurrent % 10u),
(unsigned)CONN.RequestedVoltage,
(unsigned)(CONN.WantedCurrent / 10u),
(unsigned)(CONN.WantedCurrent % 10u),
(unsigned)psu_last_can_v,
(unsigned)(psu_last_can_i_0p1A / 10u),
(unsigned)(psu_last_can_i_0p1A % 10u),
(unsigned)CONN.MeasuredVoltage,
(int)(CONN.MeasuredCurrent / 10),
(unsigned)(((CONN.MeasuredCurrent < 0) ?
-CONN.MeasuredCurrent : CONN.MeasuredCurrent) % 10),
(unsigned)CONN.EnableOutput,
(unsigned)CONN.outputEnabled,
(unsigned)PSU0.ready,
(unsigned)PSU0.PSU_enabled,
(unsigned)PSU0.CONT_enabled,
(unsigned)PSU0.enableAC,
(unsigned)CONN.hv_limit,
(unsigned)block_setpoint,
(unsigned)CONN.chargingError,
(unsigned)PSU0.status0.raw,
(unsigned)PSU0.status1.raw,
(unsigned)PSU0.status2.raw,
(unsigned long)(can_lastpacket ? (now - can_lastpacket) : 9999u));
}
static void PSU_HvControl(void)
{
if (CONN.EnableOutput == 0u) {
if ((CONN.hv_limit != 0u) || (CONN.hv_limit_count != 0u)) {
log_printf(LOG_INFO, "HV limit reset output off\n");
}
CONN.hv_limit = 0u;
CONN.hv_tick = 0u;
CONN.hv_limit_count = 0u;
return;
}
if (!PSU0.online) {
if ((CONN.hv_limit != 0u) || (CONN.hv_limit_count != 0u)) {
log_printf(LOG_INFO, "HV limit reset no PSU\n");
}
CONN.hv_limit = 0u;
CONN.hv_tick = 0u;
CONN.hv_limit_count = 0u;
return;
}
if (CONN.hv_limit == 0u) {
if ((CONN.hv_limit_count < PSU_HV_LIMIT_MAX_COUNT) &&
(CONN.MeasuredVoltage < PSU_HV_LIMIT_ON_THRESHOLD) &&
(CONN.MeasuredCurrent > PSU_HV_LOAD_CURRENT)) {
if (CONN.hv_tick == 0u) {
CONN.hv_tick = HAL_GetTick();
} else if ((HAL_GetTick() - CONN.hv_tick) >= PSU_HV_SWITCH_DELAY_MS) {
CONN.hv_limit = 1u;
CONN.hv_limit_count++;
CONN.hv_tick = 0u;
log_printf(LOG_WARN, "HV limit ON V=%d I=%d cnt=%d\n",
(int)CONN.MeasuredVoltage,
(int)CONN.MeasuredCurrent,
(int)CONN.hv_limit_count);
if (CONN.hv_limit_count >= PSU_HV_LIMIT_MAX_COUNT) {
log_printf(LOG_WARN, "HV limit locked cnt=%d\n",
(int)CONN.hv_limit_count);
}
}
} else {
CONN.hv_tick = 0u;
}
} else {
if ((CONN.MeasuredVoltage > PSU_HV_LIMIT_OFF_THRESHOLD) ||
(CONN.MeasuredCurrent <= PSU_HV_LOAD_CURRENT)) {
if (CONN.hv_tick == 0u) {
CONN.hv_tick = HAL_GetTick();
} else if ((HAL_GetTick() - CONN.hv_tick) >= PSU_HV_SWITCH_DELAY_MS) {
CONN.hv_limit = 0u;
CONN.hv_tick = 0u;
log_printf(LOG_INFO, "HV limit OFF V=%d I=%d cnt=%d\n",
(int)CONN.MeasuredVoltage,
(int)CONN.MeasuredCurrent,
(int)CONN.hv_limit_count);
}
} else {
CONN.hv_tick = 0u;
}
}
}
static void PSU_SwitchState(PSU_State_t state){ static void PSU_SwitchState(PSU_State_t state){
if (PSU0.state != state) {
log_printf(LOG_INFO,
"PSU st %s->%s enOut=%u rdy=%u on=%u cont=%u err=%u\n",
PSU_StateName(PSU0.state),
PSU_StateName(state),
(unsigned)CONN.EnableOutput,
(unsigned)PSU0.ready,
(unsigned)PSU0.PSU_enabled,
(unsigned)PSU0.CONT_enabled,
(unsigned)CONN.chargingError);
}
PSU0.state = state; PSU0.state = state;
PSU0.statetick = HAL_GetTick(); PSU0.statetick = HAL_GetTick();
} }
@@ -193,24 +41,6 @@ static uint32_t PSU_StateTime(void){
return HAL_GetTick() - PSU0.statetick; return HAL_GetTick() - PSU0.statetick;
} }
static void PSU_FastDischarge_PushTarget(void)
{
PowerSetpoint_t fd_sp;
PowerSetpoint_GetFastDischargeTarget(&fd_sp);
PSU_SetVoltageCurrent(0, fd_sp.voltage_V, fd_sp.current_0p1A);
PSU_Enable(0, 1);
}
static void PSU_FastDischarge_AbortToConnected(void)
{
PowerSetpoint_OnFastDischargeAbort();
if (!PSU0.PSU_enabled) {
PSU_FastDischarge_PushTarget();
}
PSU_SwitchState(PSU_CONNECTED);
}
ISR_FAST void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan){ ISR_FAST void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan){
static CAN_RxHeaderTypeDef RxHeader; static CAN_RxHeaderTypeDef RxHeader;
@@ -320,9 +150,10 @@ void PSU_Init(){
PSU0.statetick = HAL_GetTick(); PSU0.statetick = HAL_GetTick();
PSU0.power_limit = PSU_MAX_POWER; // kW PSU0.power_limit = PSU_MAX_POWER; // kW
PSU0.hv_mode = 0;
PSU0.hv_tick = 0;
PSU_Enable(0, 0); PSU_Enable(0, 0);
PowerSetpoint_Init();
} }
void PSU_Enable(uint8_t addr, uint8_t enable){ void PSU_Enable(uint8_t addr, uint8_t enable){
@@ -352,9 +183,7 @@ void PSU_SetVoltageCurrent(uint8_t addr, uint16_t voltage, uint16_t current){
if(voltage<PSU_MIN_VOLTAGE) voltage = PSU_MIN_VOLTAGE; if(voltage<PSU_MIN_VOLTAGE) voltage = PSU_MIN_VOLTAGE;
if((CONN.hv_limit != 0u) && (voltage > PSU_LV_CLAMP_V)){ if((PSU0.hv_mode==0) && voltage>499) voltage = 499;
voltage = PSU_LV_CLAMP_V;
}
uint32_t current_ma = current * 100; uint32_t current_ma = current * 100;
uint32_t voltage_mv = voltage * 1000; uint32_t voltage_mv = voltage * 1000;
@@ -369,8 +198,6 @@ void PSU_SetVoltageCurrent(uint8_t addr, uint16_t voltage, uint16_t current){
data.moduleVoltage[2] = (voltage_mv >> 8) & 0xFF; data.moduleVoltage[2] = (voltage_mv >> 8) & 0xFF;
data.moduleVoltage[3] = (voltage_mv >> 0) & 0xFF; data.moduleVoltage[3] = (voltage_mv >> 0) & 0xFF;
psu_last_can_v = voltage;
psu_last_can_i_0p1A = current;
PSU_SendCmd(0xF0, addr, 0x1C, &data); PSU_SendCmd(0xF0, addr, 0x1C, &data);
} }
@@ -431,50 +258,35 @@ void PSU_ReadWrite(){
} }
CONN.RequestedPower = CONN.RequestedCurrent * CONN.RequestedVoltage / 10; CONN.RequestedPower = CONN.RequestedCurrent * CONN.RequestedVoltage / 10;
#if PSD_ENABLE if(PSU0.ready){
{ if (CONN.RequestedVoltage == FAKE_EVREQ_VOLTAGE_V) {
uint8_t block_setpoint = PowerSetpoint_HasPending() || PowerSetpoint_IsBusy(); PSU_SetVoltageCurrent(0, (uint16_t)FAKE_PSU_VOLTAGE_V, (uint16_t)FAKE_PSU_CURRENT_0P1A);
}else{
if (PSU0.ready && !block_setpoint) {
PSU_SetVoltageCurrent(0, CONN.RequestedVoltage, CONN.RequestedCurrent);
ED_Delay(CAN_DELAY);
}
}
#else
if (PSU0.ready) {
PSU_SetVoltageCurrent(0, CONN.RequestedVoltage, CONN.RequestedCurrent); // Normal mode PSU_SetVoltageCurrent(0, CONN.RequestedVoltage, CONN.RequestedCurrent); // Normal mode
}
ED_Delay(CAN_DELAY); ED_Delay(CAN_DELAY);
if(CONN.MeasuredVoltage > 490){
if(PSU0.hv_tick == 0){
PSU0.hv_tick = HAL_GetTick();
}else if((HAL_GetTick() - PSU0.hv_tick) >= 10000){
PSU0.hv_mode = 1;
}
}else{
PSU0.hv_tick = 0;
}
} }
#endif
if (PSU0.ready) { // PSU_SetHVMode(0, PSU0.hv_mode); // auto set, no need
PSU_HvControl(); // ED_Delay(CAN_DELAY);
}
} }
void PSU_Task(void){ void PSU_Task(void){
static uint32_t psu_on_tick = 0; static uint32_t psu_on_tick = 0;
static uint32_t cont_ok_tick = 0; static uint32_t cont_ok_tick = 0;
static uint32_t fd_on_last_cmd_ms = 0;
PowerSetpointTryResult_t psd_result;
#if PSD_ENABLE
PowerSetpoint_UpdateDeliveryLatch();
if (PowerSetpoint_HasPending()) {
psd_result = PowerSetpoint_TryApply();
if (psd_result == PSD_TRY_START_FAST_DISCHARGE) {
PSU_SwitchState(PSU_FAST_DISCHARGE_OFF);
}
}
#endif
// Обновляем ONLINE/READY по таймауту // Обновляем ONLINE/READY по таймауту
if((HAL_GetTick() - can_lastpacket) > PSU_ONLINE_TIMEOUT){ if((HAL_GetTick() - can_lastpacket) > PSU_ONLINE_TIMEOUT){
if (PSU0.online) {
log_printf(LOG_WARN, "PSU CAN timeout age=%lums -> offline\n",
(unsigned long)(HAL_GetTick() - can_lastpacket));
}
PSU0.online = 0; PSU0.online = 0;
PSU0.PSU_enabled = 0; PSU0.PSU_enabled = 0;
PSU_04.moduleTemperature = 0; PSU_04.moduleTemperature = 0;
@@ -533,9 +345,8 @@ void PSU_Task(void){
case PSU_READY: case PSU_READY:
// модуль готов, но выключен // модуль готов, но выключен
CONN.hv_limit = 0u; PSU0.hv_mode = 0;
CONN.hv_tick = 0u; PSU0.hv_tick = 0;
CONN.hv_limit_count = 0u;
RELAY_Write(RELAY_DC, 0); RELAY_Write(RELAY_DC, 0);
if(!PSU0.ready){ if(!PSU0.ready){
@@ -592,99 +403,6 @@ void PSU_Task(void){
} }
break; break;
case PSU_FAST_DISCHARGE_OFF:
if (!CONN.EnableOutput || !PSU0.ready || PSU0.cont_fault || PSU0.psu_fault) {
log_printf(LOG_WARN, "Fast discharge abort -> stop\n");
PowerSetpoint_OnFastDischargeAbort();
PSU_SwitchState(PSU_CURRENT_DROP);
break;
}
PSU_Enable(0, 0);
PSU_SwitchState(PSU_FAST_DISCHARGE_WAIT);
break;
case PSU_FAST_DISCHARGE_WAIT: {
PowerSetpoint_t fd_sp;
if (!CONN.EnableOutput || !PSU0.ready || PSU0.cont_fault || PSU0.psu_fault) {
log_printf(LOG_WARN, "Fast discharge abort -> stop\n");
PowerSetpoint_OnFastDischargeAbort();
PSU_SwitchState(PSU_CURRENT_DROP);
break;
}
/* Как PSU_WAIT_ACK_OFF: 020 V на телеметрии = модуль выключен */
if (!PSU0.PSU_enabled) {
PowerSetpoint_GetFastDischargeTarget(&fd_sp);
log_printf(LOG_INFO, "Fast discharge off ack, V=%u -> set %u\n",
(unsigned)CONN.MeasuredVoltage, (unsigned)fd_sp.voltage_V);
PSU_SwitchState(PSU_FAST_DISCHARGE_SET);
} else if (PSU_StateTime() > PSD_OFF_TIMEOUT_MS) {
log_printf(LOG_WARN, "Fast discharge off timeout, V=%u\n",
(unsigned)CONN.MeasuredVoltage);
PSU_FastDischarge_AbortToConnected();
}
break;
}
case PSU_FAST_DISCHARGE_SET: {
PowerSetpoint_t fd_sp;
if (!CONN.EnableOutput || !PSU0.ready || PSU0.cont_fault || PSU0.psu_fault) {
log_printf(LOG_WARN, "Fast discharge abort -> stop\n");
PowerSetpoint_OnFastDischargeAbort();
PSU_SwitchState(PSU_CURRENT_DROP);
break;
}
PowerSetpoint_GetFastDischargeTarget(&fd_sp);
PSU_SetVoltageCurrent(0, fd_sp.voltage_V, fd_sp.current_0p1A);
PSU_SwitchState(PSU_FAST_DISCHARGE_ON);
break;
}
case PSU_FAST_DISCHARGE_ON:
if (!CONN.EnableOutput || !PSU0.ready || PSU0.cont_fault || PSU0.psu_fault) {
log_printf(LOG_WARN, "Fast discharge abort -> stop\n");
PowerSetpoint_OnFastDischargeAbort();
PSU_SwitchState(PSU_CURRENT_DROP);
break;
}
PSU_Enable(0, 1);
fd_on_last_cmd_ms = HAL_GetTick();
PSU_SwitchState(PSU_FAST_DISCHARGE_ON_WAIT);
break;
case PSU_FAST_DISCHARGE_ON_WAIT: {
PowerSetpoint_t fd_sp;
uint16_t v_low;
if (!CONN.EnableOutput || !PSU0.ready || PSU0.cont_fault || PSU0.psu_fault) {
log_printf(LOG_WARN, "Fast discharge abort -> stop\n");
PowerSetpoint_OnFastDischargeAbort();
PSU_SwitchState(PSU_CURRENT_DROP);
break;
}
PowerSetpoint_GetFastDischargeTarget(&fd_sp);
v_low = (fd_sp.voltage_V > PSD_PRECHARGE_TOLERANCE_V) ?
(uint16_t)(fd_sp.voltage_V - PSD_PRECHARGE_TOLERANCE_V) : 0u;
if (PSU0.PSU_enabled && CONN.MeasuredVoltage >= v_low) {
PowerSetpoint_OnFastDischargeComplete();
PSU_SwitchState(PSU_CONNECTED);
} else {
if ((HAL_GetTick() - fd_on_last_cmd_ms) >= PSD_ON_RETRY_MS) {
PSU_FastDischarge_PushTarget();
fd_on_last_cmd_ms = HAL_GetTick();
}
if (PSU_StateTime() > PSD_ON_TIMEOUT_MS) {
log_printf(LOG_WARN, "Fast discharge on timeout, V=%u (target %u)\n",
(unsigned)CONN.MeasuredVoltage, (unsigned)fd_sp.voltage_V);
PSU_FastDischarge_AbortToConnected();
}
}
break;
}
case PSU_CURRENT_DROP: case PSU_CURRENT_DROP:
// снижаем ток до нуля перед отключением DC // снижаем ток до нуля перед отключением DC
CONN.RequestedCurrent = 0; CONN.RequestedCurrent = 0;
@@ -731,8 +449,6 @@ void PSU_Task(void){
PSU_SwitchState(PSU_UNREADY); PSU_SwitchState(PSU_UNREADY);
break; break;
} }
PSU_LogPeriodicDiag();
} }
+5 -149
View File
@@ -2,19 +2,11 @@
#include "board.h" #include "board.h"
#include "charger_control.h" #include "charger_control.h"
#include "fire_alarm.h"
#include "main.h" #include "main.h"
#include "tim.h" #include "tim.h"
#include <string.h> #include <string.h>
/* Второй светодиод в цепочке WS2812 */
static RGB_t ws2812_led1 = { .R = 0, .G = 0, .B = 0 };
#define WS2812_ERROR_BLINK_MS 100
#define WS2812_ERROR_BLINK_PAUSE 30
/* Яркость обоих WS2812 на плате, 0..255 */
#define WS2812_BRIGHTNESS 60
RGB_State_t LED_State; RGB_State_t LED_State;
RGB_Cycle_t LED_Cycle; RGB_Cycle_t LED_Cycle;
@@ -109,6 +101,10 @@ RGB_Cycle_t color_error = {
}; };
void LED_Write(){ void LED_Write(){
if(FireAlarm_IsLatched() || CONN.chargingError == CONN_ERR_FIRE_ALARM){
LED_SetColor(&color_error);
return;
}
if(CONN.chargingError != CONN_NO_ERROR){ if(CONN.chargingError != CONN_NO_ERROR){
LED_SetColor(&color_error); LED_SetColor(&color_error);
return; return;
@@ -188,149 +184,12 @@ void interpolateColors(RGB_t* color1, RGB_t* color2, uint16_t a, uint16_t b, RGB
} }
#pragma GCC push_options
#pragma GCC optimize("O2")
#define WS2812_T0H_NOP 25
#define WS2812_T0L_NOP 52
#define WS2812_T1H_NOP 52
#define WS2812_T1L_NOP 25
#define _WS2812_DELAY_NOPS(n) __asm volatile(".rept " #n "\nnop\n.endr" ::: "memory")
#define WS2812_DELAY_NOPS(n) _WS2812_DELAY_NOPS(n)
static void ws2812_send_pixel(uint8_t r, uint8_t g, uint8_t b)
{
uint32_t tmp = ~(((uint32_t)g << 16) | ((uint32_t)r << 8) | (uint32_t)b);
for (int i = 0; i < 24; i++) {
LED_DATA_GPIO_Port->BSRR = LED_DATA_Pin;
if (tmp & (1U << 23)) {
WS2812_DELAY_NOPS(WS2812_T0H_NOP);
LED_DATA_GPIO_Port->BRR = LED_DATA_Pin;
WS2812_DELAY_NOPS(WS2812_T0L_NOP);
} else {
WS2812_DELAY_NOPS(WS2812_T1H_NOP);
LED_DATA_GPIO_Port->BRR = LED_DATA_Pin;
WS2812_DELAY_NOPS(WS2812_T1L_NOP);
}
tmp <<= 1;
}
}
static void ws2812_update(RGB_t *led0, RGB_t *led1)
{
uint32_t primask = __get_PRIMASK();
__disable_irq();
ws2812_send_pixel(led0->R, led0->G, led0->B);
ws2812_send_pixel(led1->R, led1->G, led1->B);
__set_PRIMASK(primask);
}
#pragma GCC pop_options
static RGB_t RGB_ScaleBrightness(const RGB_t *color)
{
RGB_t out = {
.R = (uint8_t)((uint16_t)color->R * WS2812_BRIGHTNESS / 255),
.G = (uint8_t)((uint16_t)color->G * WS2812_BRIGHTNESS / 255),
.B = (uint8_t)((uint16_t)color->B * WS2812_BRIGHTNESS / 255),
};
return out;
}
/*
* Моргание красным на втором WS2812 при chargingError > 0.
* Логика как Slave-LB24 LED_Task: N вспышек = код ошибки, пауза 30×100 ms.
* Вызывается из LED_Task каждые 20 ms; шаг FSM — 100 ms.
*/
static void LED_Ws2812ErrorBlinkUpdate(void)
{
static uint8_t err_counter;
static uint8_t led_state;
static uint8_t led_pause;
static uint32_t blink_tick;
static uint32_t flash_until;
static CONN_Error_t last_error = CONN_NO_ERROR;
const CONN_Error_t err = CONN.chargingError;
const uint32_t now = HAL_GetTick();
if (err == CONN_NO_ERROR) {
err_counter = 0;
led_state = 0;
led_pause = 0;
flash_until = 0;
last_error = CONN_NO_ERROR;
ws2812_led1.R = 0;
ws2812_led1.G = 0;
ws2812_led1.B = 0;
return;
}
if (err != last_error) {
err_counter = 0;
led_state = 0;
led_pause = 0;
flash_until = 0;
last_error = err;
}
if (now < flash_until) {
ws2812_led1.R = 255;
ws2812_led1.G = 0;
ws2812_led1.B = 0;
return;
}
ws2812_led1.R = 0;
ws2812_led1.G = 0;
ws2812_led1.B = 0;
if ((now - blink_tick) < WS2812_ERROR_BLINK_MS) {
return;
}
blink_tick = now;
uint8_t led_flash = 0;
if (led_pause > 0) {
led_pause--;
} else if (err_counter < (uint8_t)err) {
if (led_state == 0) {
led_state = 1;
} else {
led_flash = 1;
led_state = 0;
err_counter++;
}
} else {
err_counter = 0;
led_pause = WS2812_ERROR_BLINK_PAUSE;
}
if (led_flash) {
flash_until = now + WS2812_ERROR_BLINK_MS;
ws2812_led1.R = 255;
ws2812_led1.G = 0;
ws2812_led1.B = 0;
}
}
void RGB_SetColor(RGB_t *color){ void RGB_SetColor(RGB_t *color){
htim4.Instance->CCR2 = color->R * 100 / 255; htim4.Instance->CCR2 = color->R * 100 / 255;
htim4.Instance->CCR3 = color->G * 100 / 255; htim4.Instance->CCR3 = color->G * 100 / 255;
htim4.Instance->CCR4 = color->B * 100 / 255; htim4.Instance->CCR4 = color->B * 100 / 255;
} }
void WS2812_SetColor(RGB_t *color){
RGB_t led0 = RGB_ScaleBrightness(color);
RGB_t led1 = RGB_ScaleBrightness(&ws2812_led1);
ws2812_update(&led0, &led1);
}
void LED_SetColor(RGB_Cycle_t *color){ void LED_SetColor(RGB_Cycle_t *color){
memcpy(&LED_Cycle, color, sizeof(RGB_Cycle_t)); memcpy(&LED_Cycle, color, sizeof(RGB_Cycle_t));
} }
@@ -342,7 +201,6 @@ void LED_Init(){
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_3); HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_3);
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_4); HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_4);
RGB_SetColor(&color); RGB_SetColor(&color);
WS2812_SetColor(&color);
} }
void LED_Task(){ void LED_Task(){
@@ -386,8 +244,6 @@ void LED_Task(){
default: default:
LED_State.state = LED_RISING; LED_State.state = LED_RISING;
} }
LED_Ws2812ErrorBlinkUpdate();
RGB_SetColor(&LED_State.color); RGB_SetColor(&LED_State.color);
WS2812_SetColor(&LED_State.color);
} }
} }
+43 -24
View File
@@ -6,8 +6,8 @@
#include "cp.h" #include "cp.h"
#include "debug.h" #include "debug.h"
#include "isr_opt.h" #include "isr_opt.h"
#include "fire_alarm.h"
#include "psu_control.h" #include "psu_control.h"
#include "power_setpoint_executor.h"
#include "serial_control.h" #include "serial_control.h"
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
@@ -47,6 +47,7 @@ static uint8_t enabled = 0;
static uint8_t pwm_duty_percent = 100; static uint8_t pwm_duty_percent = 100;
uint8_t isolation_enable = 0; uint8_t isolation_enable = 0;
static uint32_t last_host_seen = 0; static uint32_t last_host_seen = 0;
static uint8_t fake_500_voltage_mode = 0;
static uint8_t everest_timed_out = 0; static uint8_t everest_timed_out = 0;
static uint8_t everest_timeout_warn_latched = 0; static uint8_t everest_timeout_warn_latched = 0;
static uint8_t everest_timeout_stop_latched = 0; static uint8_t everest_timeout_stop_latched = 0;
@@ -170,6 +171,7 @@ void CCS_SerialLoop(void) {
static uint32_t stop_tick = 0; static uint32_t stop_tick = 0;
CCS_UART3_Watchdog(); CCS_UART3_Watchdog();
FireAlarm_Maintain();
if (CONN.connControl != CMD_NONE) { if (CONN.connControl != CMD_NONE) {
last_cmd = CONN.connControl; last_cmd = CONN.connControl;
@@ -211,7 +213,8 @@ void CCS_SerialLoop(void) {
if (((CONN.connControl == CMD_STOP) || if (((CONN.connControl == CMD_STOP) ||
(CONN.connControl == CMD_FORCE_UNLOCK) || (CONN.connControl == CMD_FORCE_UNLOCK) ||
(CONN.chargingError != CONN_NO_ERROR)) && (CONN.chargingError != CONN_NO_ERROR) ||
FireAlarm_IsLatched()) &&
((int32_t)(HAL_GetTick() - last_stop_sent) > 1000)) { ((int32_t)(HAL_GetTick() - last_stop_sent) > 1000)) {
last_stop_sent = HAL_GetTick(); last_stop_sent = HAL_GetTick();
log_printf(LOG_WARN, "Stopping charging...\n"); log_printf(LOG_WARN, "Stopping charging...\n");
@@ -254,6 +257,10 @@ void CCS_SerialLoop(void) {
everest_timed_out = host_timeout_stop; everest_timed_out = host_timeout_stop;
switch(CCS_ConnectorState){ switch(CCS_ConnectorState){
case CCS_UNKNOWN: case CCS_UNKNOWN:
if (FireAlarm_IsLatched()) {
CCS_ConnectorState = CCS_DISABLED;
break;
}
RELAY_Write(RELAY_CP, 0); RELAY_Write(RELAY_CP, 0);
CONN_SetState(Unknown); CONN_SetState(Unknown);
if (config_initialized && !host_timed_out) { if (config_initialized && !host_timed_out) {
@@ -263,11 +270,15 @@ void CCS_SerialLoop(void) {
case CCS_DISABLED: case CCS_DISABLED:
RELAY_Write(RELAY_CP, 0); RELAY_Write(RELAY_CP, 0);
CONN_SetState(Disabled); CONN_SetState(Disabled);
if ((CONN.chargingError == CONN_NO_ERROR) && !host_timed_out){ if (!FireAlarm_IsLatched() && (CONN.chargingError == CONN_NO_ERROR) && !host_timed_out){
CCS_ConnectorState = CCS_UNPLUGGED; CCS_ConnectorState = CCS_UNPLUGGED;
} }
break; break;
case CCS_UNPLUGGED: case CCS_UNPLUGGED:
if (FireAlarm_IsLatched()) {
CCS_ConnectorState = CCS_DISABLED;
break;
}
RELAY_Write(RELAY_CP, 1); RELAY_Write(RELAY_CP, 1);
CONN_SetState(Unplugged); CONN_SetState(Unplugged);
if ((cp_state_buffer == EV_STATE_B_CONN_PREP) || (cp_state_buffer == EV_STATE_C_CONN_ACTIVE)){ if ((cp_state_buffer == EV_STATE_B_CONN_PREP) || (cp_state_buffer == EV_STATE_C_CONN_ACTIVE)){
@@ -280,6 +291,10 @@ void CCS_SerialLoop(void) {
break; break;
case CCS_AUTH_REQUIRED: case CCS_AUTH_REQUIRED:
if (FireAlarm_IsLatched()) {
CCS_ConnectorState = CCS_DISABLED;
break;
}
RELAY_Write(RELAY_CP, 1); RELAY_Write(RELAY_CP, 1);
CONN_SetState(AuthRequired); CONN_SetState(AuthRequired);
if(CONN.connControl == CMD_START){ if(CONN.connControl == CMD_START){
@@ -292,6 +307,10 @@ void CCS_SerialLoop(void) {
} }
break; break;
case CCS_CONNECTED: case CCS_CONNECTED:
if (FireAlarm_IsLatched()) {
CCS_ConnectorState = CCS_DISABLED;
break;
}
RELAY_Write(RELAY_CP, 1); RELAY_Write(RELAY_CP, 1);
if((CCS_EvseState < Preparing) || (CCS_EvseState == AuthRequired)) { if((CCS_EvseState < Preparing) || (CCS_EvseState == AuthRequired)) {
CONN_SetState(Preparing); CONN_SetState(Preparing);
@@ -308,6 +327,10 @@ void CCS_SerialLoop(void) {
} }
break; break;
case CCS_REPLUGGING: case CCS_REPLUGGING:
if (FireAlarm_IsLatched()) {
CCS_ConnectorState = CCS_DISABLED;
break;
}
RELAY_Write(RELAY_CP, 0); RELAY_Write(RELAY_CP, 0);
CONN_SetState(Replugging); CONN_SetState(Replugging);
if((int32_t)(HAL_GetTick() - replug_tick) > 1000){ if((int32_t)(HAL_GetTick() - replug_tick) > 1000){
@@ -330,18 +353,19 @@ void CCS_SerialLoop(void) {
} }
// 10s timeout: enforce safe-state until host communication recovers. // 10s timeout: enforce safe-state until host communication recovers.
{ if (FireAlarm_IsLatched()) {
static uint8_t prev_enable_output = 0xFFu; CONN.EnableOutput = 0;
uint8_t new_enable_output; CP_SetDuty(100);
if (CCS_ConnectorState != CCS_DISABLED && CCS_ConnectorState != CCS_UNKNOWN) {
if (host_timeout_stop) { CCS_ConnectorState = CCS_DISABLED;
}
} else if (host_timeout_stop) {
CONN.EnableOutput = 0; CONN.EnableOutput = 0;
CCS_EvseState = Unknown; CCS_EvseState = Unknown;
CP_SetDuty(100); CP_SetDuty(100);
if (CCS_ConnectorState != CCS_DISABLED && CCS_ConnectorState != CCS_UNKNOWN) { if (CCS_ConnectorState != CCS_DISABLED && CCS_ConnectorState != CCS_UNKNOWN) {
CCS_ConnectorState = CCS_DISABLED; CCS_ConnectorState = CCS_DISABLED;
} }
new_enable_output = 0u;
} else { } else {
if (last_cmd == CMD_STOP) { if (last_cmd == CMD_STOP) {
CONN.EnableOutput = 0; CONN.EnableOutput = 0;
@@ -351,20 +375,6 @@ void CCS_SerialLoop(void) {
CONN.EnableOutput = 0; CONN.EnableOutput = 0;
} }
} }
new_enable_output = CONN.EnableOutput;
}
if (prev_enable_output != 0xFFu && prev_enable_output != new_enable_output) {
log_printf(LOG_INFO,
"EnableOutput %u->%u ev=%u stop=%u host_to=%u err=%u\n",
(unsigned)prev_enable_output,
(unsigned)new_enable_output,
(unsigned)ev_enable_output,
(unsigned)(last_cmd == CMD_STOP),
(unsigned)host_timeout_stop,
(unsigned)CONN.chargingError);
}
prev_enable_output = new_enable_output;
} }
if ((cp_state_buffer == EV_STATE_B_CONN_PREP) || if ((cp_state_buffer == EV_STATE_B_CONN_PREP) ||
@@ -472,6 +482,9 @@ static void send_state(void) {
CCS_State.DutyCycle = CP_GetDuty(); CCS_State.DutyCycle = CP_GetDuty();
CCS_State.OutputEnabled = PSU0.CONT_enabled; CCS_State.OutputEnabled = PSU0.CONT_enabled;
CCS_State.MeasuredVoltage = (uint16_t)CONN.MeasuredVoltage; CCS_State.MeasuredVoltage = (uint16_t)CONN.MeasuredVoltage;
if (fake_500_voltage_mode) {
CCS_State.MeasuredVoltage = FAKE_EVREQ_VOLTAGE_V;
}
CCS_State.MeasuredCurrent = (uint16_t)CONN.MeasuredCurrent; CCS_State.MeasuredCurrent = (uint16_t)CONN.MeasuredCurrent;
CCS_State.Power = CCS_Power; CCS_State.Power = CCS_Power;
CCS_State.Energy = CCS_Energy; CCS_State.Energy = CCS_Energy;
@@ -549,9 +562,15 @@ ISR_FAST static void apply_command(uint8_t cmd, const uint8_t* payload, uint16_t
} }
case CMD_E2M_SET_OUTPUT_VOLTAGE: { case CMD_E2M_SET_OUTPUT_VOLTAGE: {
const e2m_set_output_t* p = (const e2m_set_output_t*)payload; const e2m_set_output_t* p = (const e2m_set_output_t*)payload;
if (p->voltage_V == FAKE_EVREQ_VOLTAGE_V) {
fake_500_voltage_mode = 1u;
CONN.RequestedVoltage = FAKE_PSU_VOLTAGE_V;
CONN.WantedCurrent = FAKE_PSU_CURRENT_0P1A;
} else {
fake_500_voltage_mode = 0u;
CONN.RequestedVoltage = p->voltage_V; CONN.RequestedVoltage = p->voltage_V;
CONN.WantedCurrent = p->current_0p1A; CONN.WantedCurrent = p->current_0p1A;
PowerSetpoint_OnCommand(p->voltage_V, p->current_0p1A); }
break; break;
} }
case CMD_E2M_ISOLATION_CONTROL: { case CMD_E2M_ISOLATION_CONTROL: {
+8 -3
View File
@@ -28,6 +28,11 @@ void SC_CommandHandler(ReceivedCommand_t* cmd) {
uint8_t response_code = RESP_FAILED; uint8_t response_code = RESP_FAILED;
if (FireAlarm_IsBlockingCommand(cmd->command)) {
SC_SendPacket(NULL, 0, RESP_FAILED);
return;
}
switch (cmd->command) { switch (cmd->command) {
// Команды БЕЗ аргументов // Команды БЕЗ аргументов
case CMD_GET_STATUS: case CMD_GET_STATUS:
@@ -91,6 +96,7 @@ void SC_CommandHandler(ReceivedCommand_t* cmd) {
FireAlarm_Activate(); FireAlarm_Activate();
response_code = RESP_SUCCESS; response_code = RESP_SUCCESS;
break; break;
case CMD_DEVICE_RESET: case CMD_DEVICE_RESET:
// 2. Отправляем SUCCESS (хост может успеть получить его перед ребутом) // 2. Отправляем SUCCESS (хост может успеть получить его перед ребутом)
SC_SendPacket(NULL, 0, RESP_SUCCESS); SC_SendPacket(NULL, 0, RESP_SUCCESS);
@@ -139,9 +145,8 @@ static void monitoring_data_callback(void) {
statusPacket.outputEnabled = CONN.outputEnabled; statusPacket.outputEnabled = CONN.outputEnabled;
statusPacket.chargingError = CONN.chargingError; statusPacket.chargingError = CONN.chargingError;
statusPacket.connState = CONN.connState; statusPacket.connState = CONN.connState;
CONN_GetElapsedForMonitoring( statusPacket.chargingElapsedTimeMin = 0;
&statusPacket.chargingElapsedTimeMin, statusPacket.chargingElapsedTimeSec = 0;
&statusPacket.chargingElapsedTimeSec);
statusPacket.estimatedRemainingChargingTime = 0; statusPacket.estimatedRemainingChargingTime = 0;
// состояние зарядной станции // состояние зарядной станции
Binary file not shown.
Binary file not shown.
+3676 -4037
View File
File diff suppressed because it is too large Load Diff
+22867 -25784
View File
File diff suppressed because it is too large Load Diff
+2022 -2579
View File
File diff suppressed because it is too large Load Diff
+3676 -4037
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
+3 -4
View File
@@ -1,4 +1,3 @@
../Core/Src/charger_control.c:11:6:CONN_Init 1 ../Core/Src/charger_control.c:10:6:CONN_Init 1
../Core/Src/charger_control.c:23:6:CONN_Loop 10 ../Core/Src/charger_control.c:18:6:CONN_Loop 6
../Core/Src/charger_control.c:56:6:CONN_GetElapsedForMonitoring 3 ../Core/Src/charger_control.c:39:6:CONN_SetState 16
../Core/Src/charger_control.c:66:6:CONN_SetState 16
+4
View File
@@ -0,0 +1,4 @@
../Core/Src/fire_alarm.c:14:9:FireAlarm_IsLatched 1
../Core/Src/fire_alarm.c:18:9:FireAlarm_IsBlockingCommand 8
../Core/Src/fire_alarm.c:34:6:FireAlarm_Activate 2
../Core/Src/fire_alarm.c:53:6:FireAlarm_Maintain 6
+6 -11
View File
@@ -1,11 +1,6 @@
../Core/Src/rgb_controller.c:111:6:LED_Write 18 ../Core/Src/rgb_controller.c:102:6:LED_Write 18
../Core/Src/rgb_controller.c:173:6:interpolateColors 3 ../Core/Src/rgb_controller.c:164:6:interpolateColors 3
../Core/Src/rgb_controller.c:203:13:ws2812_send_pixel 3 ../Core/Src/rgb_controller.c:182:6:RGB_SetColor 1
../Core/Src/rgb_controller.c:222:13:ws2812_update 1 ../Core/Src/rgb_controller.c:188:6:LED_SetColor 1
../Core/Src/rgb_controller.c:234:14:RGB_ScaleBrightness 1 ../Core/Src/rgb_controller.c:193:6:LED_Init 1
../Core/Src/rgb_controller.c:249:13:LED_Ws2812ErrorBlinkUpdate 9 ../Core/Src/rgb_controller.c:201:6:LED_Task 10
../Core/Src/rgb_controller.c:322:6:RGB_SetColor 1
../Core/Src/rgb_controller.c:328:6:WS2812_SetColor 1
../Core/Src/rgb_controller.c:334:6:LED_SetColor 1
../Core/Src/rgb_controller.c:339:6:LED_Init 1
../Core/Src/rgb_controller.c:348:6:LED_Task 10
+2 -2
View File
@@ -1,3 +1,3 @@
../Drivers/CMSIS/Include/core_cm3.h:1762:34:__NVIC_SystemReset 1 ../Drivers/CMSIS/Include/core_cm3.h:1762:34:__NVIC_SystemReset 1
../Core/Src/serial_handler.c:27:6:SC_CommandHandler 20 ../Core/Src/serial_handler.c:26:6:SC_CommandHandler 19
../Core/Src/serial_handler.c:130:13:monitoring_data_callback 1 ../Core/Src/serial_handler.c:125:13:monitoring_data_callback 1
+1 -8
View File
@@ -17,8 +17,6 @@ C_SRCS += \
../Core/Src/gpio.c \ ../Core/Src/gpio.c \
../Core/Src/main.c \ ../Core/Src/main.c \
../Core/Src/meter.c \ ../Core/Src/meter.c \
../Core/Src/power_setpoint_executor.c \
../Core/Src/power_setpoint_policy.c \
../Core/Src/psu_control.c \ ../Core/Src/psu_control.c \
../Core/Src/rgb_controller.c \ ../Core/Src/rgb_controller.c \
../Core/Src/rtc.c \ ../Core/Src/rtc.c \
@@ -48,8 +46,6 @@ C_DEPS += \
./Core/Src/gpio.d \ ./Core/Src/gpio.d \
./Core/Src/main.d \ ./Core/Src/main.d \
./Core/Src/meter.d \ ./Core/Src/meter.d \
./Core/Src/power_setpoint_executor.d \
./Core/Src/power_setpoint_policy.d \
./Core/Src/psu_control.d \ ./Core/Src/psu_control.d \
./Core/Src/rgb_controller.d \ ./Core/Src/rgb_controller.d \
./Core/Src/rtc.d \ ./Core/Src/rtc.d \
@@ -75,12 +71,9 @@ OBJS += \
./Core/Src/crc.o \ ./Core/Src/crc.o \
./Core/Src/debug.o \ ./Core/Src/debug.o \
./Core/Src/dma.o \ ./Core/Src/dma.o \
./Core/Src/fire_alarm.o \
./Core/Src/gpio.o \ ./Core/Src/gpio.o \
./Core/Src/main.o \ ./Core/Src/main.o \
./Core/Src/meter.o \ ./Core/Src/meter.o \
./Core/Src/power_setpoint_executor.o \
./Core/Src/power_setpoint_policy.o \
./Core/Src/psu_control.o \ ./Core/Src/psu_control.o \
./Core/Src/rgb_controller.o \ ./Core/Src/rgb_controller.o \
./Core/Src/rtc.o \ ./Core/Src/rtc.o \
@@ -105,7 +98,7 @@ Core/Src/%.o Core/Src/%.su Core/Src/%.cyclo: ../Core/Src/%.c Core/Src/subdir.mk
clean: clean-Core-2f-Src clean: clean-Core-2f-Src
clean-Core-2f-Src: clean-Core-2f-Src:
-$(RM) ./Core/Src/adc.cyclo ./Core/Src/adc.d ./Core/Src/adc.o ./Core/Src/adc.su ./Core/Src/board.cyclo ./Core/Src/board.d ./Core/Src/board.o ./Core/Src/board.su ./Core/Src/can.cyclo ./Core/Src/can.d ./Core/Src/can.o ./Core/Src/can.su ./Core/Src/charger_control.cyclo ./Core/Src/charger_control.d ./Core/Src/charger_control.o ./Core/Src/charger_control.su ./Core/Src/cp.cyclo ./Core/Src/cp.d ./Core/Src/cp.o ./Core/Src/cp.su ./Core/Src/crc.cyclo ./Core/Src/crc.d ./Core/Src/crc.o ./Core/Src/crc.su ./Core/Src/debug.cyclo ./Core/Src/debug.d ./Core/Src/debug.o ./Core/Src/debug.su ./Core/Src/dma.cyclo ./Core/Src/dma.d ./Core/Src/dma.o ./Core/Src/dma.su ./Core/Src/fire_alarm.cyclo ./Core/Src/fire_alarm.d ./Core/Src/fire_alarm.o ./Core/Src/fire_alarm.su ./Core/Src/gpio.cyclo ./Core/Src/gpio.d ./Core/Src/gpio.o ./Core/Src/gpio.su ./Core/Src/main.cyclo ./Core/Src/main.d ./Core/Src/main.o ./Core/Src/main.su ./Core/Src/meter.cyclo ./Core/Src/meter.d ./Core/Src/meter.o ./Core/Src/meter.su ./Core/Src/power_setpoint_executor.cyclo ./Core/Src/power_setpoint_executor.d ./Core/Src/power_setpoint_executor.o ./Core/Src/power_setpoint_executor.su ./Core/Src/power_setpoint_policy.cyclo ./Core/Src/power_setpoint_policy.d ./Core/Src/power_setpoint_policy.o ./Core/Src/power_setpoint_policy.su ./Core/Src/psu_control.cyclo ./Core/Src/psu_control.d ./Core/Src/psu_control.o ./Core/Src/psu_control.su ./Core/Src/rgb_controller.cyclo ./Core/Src/rgb_controller.d ./Core/Src/rgb_controller.o ./Core/Src/rgb_controller.su ./Core/Src/rtc.cyclo ./Core/Src/rtc.d ./Core/Src/rtc.o ./Core/Src/rtc.su ./Core/Src/serial.cyclo ./Core/Src/serial.d ./Core/Src/serial.o ./Core/Src/serial.su ./Core/Src/serial_control.cyclo ./Core/Src/serial_control.d ./Core/Src/serial_control.o ./Core/Src/serial_control.su ./Core/Src/serial_handler.cyclo ./Core/Src/serial_handler.d ./Core/Src/serial_handler.o ./Core/Src/serial_handler.su ./Core/Src/sma_filter.cyclo ./Core/Src/sma_filter.d ./Core/Src/sma_filter.o ./Core/Src/sma_filter.su ./Core/Src/soft_rtc.cyclo ./Core/Src/soft_rtc.d ./Core/Src/soft_rtc.o ./Core/Src/soft_rtc.su ./Core/Src/stm32f1xx_hal_msp.cyclo ./Core/Src/stm32f1xx_hal_msp.d ./Core/Src/stm32f1xx_hal_msp.o ./Core/Src/stm32f1xx_hal_msp.su ./Core/Src/stm32f1xx_it.cyclo ./Core/Src/stm32f1xx_it.d ./Core/Src/stm32f1xx_it.o ./Core/Src/stm32f1xx_it.su ./Core/Src/syscalls.cyclo ./Core/Src/syscalls.d ./Core/Src/syscalls.o ./Core/Src/syscalls.su ./Core/Src/sysmem.cyclo ./Core/Src/sysmem.d ./Core/Src/sysmem.o ./Core/Src/sysmem.su ./Core/Src/system_stm32f1xx.cyclo ./Core/Src/system_stm32f1xx.d ./Core/Src/system_stm32f1xx.o ./Core/Src/system_stm32f1xx.su ./Core/Src/tim.cyclo ./Core/Src/tim.d ./Core/Src/tim.o ./Core/Src/tim.su ./Core/Src/usart.cyclo ./Core/Src/usart.d ./Core/Src/usart.o ./Core/Src/usart.su -$(RM) ./Core/Src/adc.cyclo ./Core/Src/adc.d ./Core/Src/adc.o ./Core/Src/adc.su ./Core/Src/board.cyclo ./Core/Src/board.d ./Core/Src/board.o ./Core/Src/board.su ./Core/Src/can.cyclo ./Core/Src/can.d ./Core/Src/can.o ./Core/Src/can.su ./Core/Src/charger_control.cyclo ./Core/Src/charger_control.d ./Core/Src/charger_control.o ./Core/Src/charger_control.su ./Core/Src/cp.cyclo ./Core/Src/cp.d ./Core/Src/cp.o ./Core/Src/cp.su ./Core/Src/crc.cyclo ./Core/Src/crc.d ./Core/Src/crc.o ./Core/Src/crc.su ./Core/Src/debug.cyclo ./Core/Src/debug.d ./Core/Src/debug.o ./Core/Src/debug.su ./Core/Src/dma.cyclo ./Core/Src/dma.d ./Core/Src/dma.o ./Core/Src/dma.su ./Core/Src/gpio.cyclo ./Core/Src/gpio.d ./Core/Src/gpio.o ./Core/Src/gpio.su ./Core/Src/main.cyclo ./Core/Src/main.d ./Core/Src/main.o ./Core/Src/main.su ./Core/Src/meter.cyclo ./Core/Src/meter.d ./Core/Src/meter.o ./Core/Src/meter.su ./Core/Src/psu_control.cyclo ./Core/Src/psu_control.d ./Core/Src/psu_control.o ./Core/Src/psu_control.su ./Core/Src/rgb_controller.cyclo ./Core/Src/rgb_controller.d ./Core/Src/rgb_controller.o ./Core/Src/rgb_controller.su ./Core/Src/rtc.cyclo ./Core/Src/rtc.d ./Core/Src/rtc.o ./Core/Src/rtc.su ./Core/Src/serial.cyclo ./Core/Src/serial.d ./Core/Src/serial.o ./Core/Src/serial.su ./Core/Src/serial_control.cyclo ./Core/Src/serial_control.d ./Core/Src/serial_control.o ./Core/Src/serial_control.su ./Core/Src/serial_handler.cyclo ./Core/Src/serial_handler.d ./Core/Src/serial_handler.o ./Core/Src/serial_handler.su ./Core/Src/sma_filter.cyclo ./Core/Src/sma_filter.d ./Core/Src/sma_filter.o ./Core/Src/sma_filter.su ./Core/Src/soft_rtc.cyclo ./Core/Src/soft_rtc.d ./Core/Src/soft_rtc.o ./Core/Src/soft_rtc.su ./Core/Src/stm32f1xx_hal_msp.cyclo ./Core/Src/stm32f1xx_hal_msp.d ./Core/Src/stm32f1xx_hal_msp.o ./Core/Src/stm32f1xx_hal_msp.su ./Core/Src/stm32f1xx_it.cyclo ./Core/Src/stm32f1xx_it.d ./Core/Src/stm32f1xx_it.o ./Core/Src/stm32f1xx_it.su ./Core/Src/syscalls.cyclo ./Core/Src/syscalls.d ./Core/Src/syscalls.o ./Core/Src/syscalls.su ./Core/Src/sysmem.cyclo ./Core/Src/sysmem.d ./Core/Src/sysmem.o ./Core/Src/sysmem.su ./Core/Src/system_stm32f1xx.cyclo ./Core/Src/system_stm32f1xx.d ./Core/Src/system_stm32f1xx.o ./Core/Src/system_stm32f1xx.su ./Core/Src/tim.cyclo ./Core/Src/tim.d ./Core/Src/tim.o ./Core/Src/tim.su ./Core/Src/usart.cyclo ./Core/Src/usart.d ./Core/Src/usart.o ./Core/Src/usart.su
.PHONY: clean-Core-2f-Src .PHONY: clean-Core-2f-Src
+3559
View File
File diff suppressed because it is too large Load Diff