if it breaks, I’m in the mountains

This commit is contained in:
2026-03-24 04:38:40 +03:00
parent 8574ffadc9
commit 14b4f0595f
64 changed files with 38499 additions and 39958 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>GbTModuleSW30Web</name>
<name>CCSModuleSW30Web</name>
<comment></comment>
<projects>
</projects>

View File

@@ -37,70 +37,77 @@ Mcu.CPN=STM32F107VCT6
Mcu.Family=STM32F1
Mcu.IP0=ADC1
Mcu.IP1=CAN1
Mcu.IP10=USART1
Mcu.IP11=USART2
Mcu.IP12=USART3
Mcu.IP10=UART5
Mcu.IP11=USART1
Mcu.IP12=USART2
Mcu.IP13=USART3
Mcu.IP2=CAN2
Mcu.IP3=CRC
Mcu.IP4=NVIC
Mcu.IP5=RCC
Mcu.IP6=RTC
Mcu.IP7=SYS
Mcu.IP8=TIM4
Mcu.IP9=UART5
Mcu.IPNb=13
Mcu.IP8=TIM3
Mcu.IP9=TIM4
Mcu.IPNb=14
Mcu.Name=STM32F107V(B-C)Tx
Mcu.Package=LQFP100
Mcu.Pin0=PC14-OSC32_IN
Mcu.Pin1=PC15-OSC32_OUT
Mcu.Pin10=PB1
Mcu.Pin11=PE7
Mcu.Pin12=PE8
Mcu.Pin13=PE9
Mcu.Pin14=PE10
Mcu.Pin15=PE11
Mcu.Pin16=PE12
Mcu.Pin17=PE14
Mcu.Pin18=PD13
Mcu.Pin19=PD14
Mcu.Pin10=PC4
Mcu.Pin11=PC5
Mcu.Pin12=PB0
Mcu.Pin13=PB1
Mcu.Pin14=PE7
Mcu.Pin15=PE8
Mcu.Pin16=PE9
Mcu.Pin17=PE10
Mcu.Pin18=PE11
Mcu.Pin19=PE12
Mcu.Pin2=OSC_IN
Mcu.Pin20=PD15
Mcu.Pin21=PA9
Mcu.Pin22=PA10
Mcu.Pin23=PA13
Mcu.Pin24=PA14
Mcu.Pin25=PA15
Mcu.Pin26=PC10
Mcu.Pin27=PC11
Mcu.Pin28=PC12
Mcu.Pin29=PD0
Mcu.Pin20=PE14
Mcu.Pin21=PD13
Mcu.Pin22=PD14
Mcu.Pin23=PD15
Mcu.Pin24=PA9
Mcu.Pin25=PA10
Mcu.Pin26=PA13
Mcu.Pin27=PA14
Mcu.Pin28=PA15
Mcu.Pin29=PC10
Mcu.Pin3=OSC_OUT
Mcu.Pin30=PD1
Mcu.Pin31=PD2
Mcu.Pin32=PD3
Mcu.Pin33=PD4
Mcu.Pin34=PD5
Mcu.Pin35=PD6
Mcu.Pin36=PD7
Mcu.Pin37=PB3
Mcu.Pin38=PB4
Mcu.Pin39=PB5
Mcu.Pin4=PA1
Mcu.Pin40=PB6
Mcu.Pin41=PB7
Mcu.Pin42=PB8
Mcu.Pin43=PB9
Mcu.Pin44=PE1
Mcu.Pin45=VP_CRC_VS_CRC
Mcu.Pin46=VP_RTC_VS_RTC_Activate
Mcu.Pin47=VP_SYS_VS_Systick
Mcu.Pin48=VP_TIM4_VS_ClockSourceINT
Mcu.Pin5=PA2
Mcu.Pin6=PA3
Mcu.Pin7=PC4
Mcu.Pin8=PC5
Mcu.Pin9=PB0
Mcu.PinsNb=49
Mcu.Pin30=PC11
Mcu.Pin31=PC12
Mcu.Pin32=PD0
Mcu.Pin33=PD1
Mcu.Pin34=PD2
Mcu.Pin35=PD3
Mcu.Pin36=PD4
Mcu.Pin37=PD5
Mcu.Pin38=PD6
Mcu.Pin39=PD7
Mcu.Pin4=PC3
Mcu.Pin40=PB3
Mcu.Pin41=PB4
Mcu.Pin42=PB5
Mcu.Pin43=PB6
Mcu.Pin44=PB7
Mcu.Pin45=PB8
Mcu.Pin46=PB9
Mcu.Pin47=PE1
Mcu.Pin48=VP_ADC1_TempSens_Input
Mcu.Pin49=VP_ADC1_Vref_Input
Mcu.Pin5=PA1
Mcu.Pin50=VP_CRC_VS_CRC
Mcu.Pin51=VP_RTC_VS_RTC_Activate
Mcu.Pin52=VP_SYS_VS_Systick
Mcu.Pin53=VP_TIM3_VS_ClockSourceINT
Mcu.Pin54=VP_TIM4_VS_ClockSourceINT
Mcu.Pin6=PA2
Mcu.Pin7=PA3
Mcu.Pin8=PA4
Mcu.Pin9=PA7
Mcu.PinsNb=55
Mcu.ThirdPartyNb=0
Mcu.UserConstants=
Mcu.UserName=STM32F107VCTx
@@ -119,6 +126,7 @@ NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false
NVIC.TIM3_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.UART5_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.USART1_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.USART2_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
@@ -150,6 +158,14 @@ PA2.Locked=true
PA2.Signal=GPIO_Input
PA3.Locked=true
PA3.Signal=ADCx_IN3
PA4.GPIOParameters=GPIO_Label
PA4.GPIO_Label=CP_ADC
PA4.Locked=true
PA4.Signal=ADCx_IN4
PA7.GPIOParameters=GPIO_Label
PA7.GPIO_Label=CP_PWM
PA7.Locked=true
PA7.Signal=S_TIM3_CH2
PA9.Locked=true
PA9.Mode=Asynchronous
PA9.Signal=USART1_TX
@@ -195,6 +211,10 @@ PC14-OSC32_IN.Mode=LSE-External-Oscillator
PC14-OSC32_IN.Signal=RCC_OSC32_IN
PC15-OSC32_OUT.Mode=LSE-External-Oscillator
PC15-OSC32_OUT.Signal=RCC_OSC32_OUT
PC3.GPIOParameters=GPIO_Label
PC3.GPIO_Label=RELAY_CP
PC3.Locked=true
PC3.Signal=GPIO_Output
PC4.GPIOParameters=GPIO_Label
PC4.GPIO_Label=LOCK_A
PC4.Locked=true
@@ -284,14 +304,14 @@ ProjectManager.FreePins=false
ProjectManager.HalAssertFull=false
ProjectManager.HeapSize=0x200
ProjectManager.KeepUserCode=true
ProjectManager.LastFirmware=true
ProjectManager.LastFirmware=false
ProjectManager.LibraryCopy=1
ProjectManager.MainLocation=Core/Src
ProjectManager.NoMain=false
ProjectManager.PreviousToolchain=
ProjectManager.ProjectBuild=false
ProjectManager.ProjectFileName=GbTModuleSW30Web.ioc
ProjectManager.ProjectName=GbTModuleSW30Web
ProjectManager.ProjectFileName=CCSModuleSW30Web.ioc
ProjectManager.ProjectName=CCSModuleSW30Web
ProjectManager.ProjectStructure=
ProjectManager.RegisterCallBack=
ProjectManager.StackSize=0x400
@@ -300,7 +320,7 @@ ProjectManager.ToolChainLocation=
ProjectManager.UAScriptAfterPath=
ProjectManager.UAScriptBeforePath=
ProjectManager.UnderRoot=true
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_ADC1_Init-ADC1-false-HAL-true,4-MX_CAN1_Init-CAN1-false-HAL-true,5-MX_CAN2_Init-CAN2-false-HAL-true,6-MX_RTC_Init-RTC-false-HAL-true,7-MX_TIM4_Init-TIM4-false-HAL-true,8-MX_USART2_UART_Init-USART2-false-HAL-true,9-MX_CRC_Init-CRC-false-HAL-true,10-MX_UART5_Init-UART5-false-HAL-true,11-MX_USART1_UART_Init-USART1-false-HAL-true,12-MX_USART3_UART_Init-USART3-false-HAL-true
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_ADC1_Init-ADC1-false-HAL-true,4-MX_CAN1_Init-CAN1-false-HAL-true,5-MX_CAN2_Init-CAN2-false-HAL-true,6-MX_RTC_Init-RTC-false-HAL-true,7-MX_TIM4_Init-TIM4-false-HAL-true,8-MX_USART2_UART_Init-USART2-false-HAL-true,9-MX_CRC_Init-CRC-false-HAL-true,10-MX_UART5_Init-UART5-false-HAL-true,11-MX_USART1_UART_Init-USART1-false-HAL-true,12-MX_USART3_UART_Init-USART3-false-HAL-true,13-MX_TIM3_Init-TIM3-false-HAL-true
RCC.ADCFreqValue=12000000
RCC.ADCPresc=RCC_ADCPCLK2_DIV6
RCC.AHBFreq_Value=72000000
@@ -337,16 +357,22 @@ RCC.USBFreq_Value=48000000
RCC.VCOOutput2Freq_Value=8000000
SH.ADCx_IN3.0=ADC1_IN3,IN3
SH.ADCx_IN3.ConfNb=1
SH.ADCx_IN4.0=ADC1_IN4,IN4
SH.ADCx_IN4.ConfNb=1
SH.ADCx_IN8.0=ADC1_IN8,IN8
SH.ADCx_IN8.ConfNb=1
SH.ADCx_IN9.0=ADC1_IN9,IN9
SH.ADCx_IN9.ConfNb=1
SH.S_TIM3_CH2.0=TIM3_CH2,PWM Generation2 CH2
SH.S_TIM3_CH2.ConfNb=1
SH.S_TIM4_CH2.0=TIM4_CH2,PWM Generation2 CH2
SH.S_TIM4_CH2.ConfNb=1
SH.S_TIM4_CH3.0=TIM4_CH3,PWM Generation3 CH3
SH.S_TIM4_CH3.ConfNb=1
SH.S_TIM4_CH4.0=TIM4_CH4,PWM Generation4 CH4
SH.S_TIM4_CH4.ConfNb=1
TIM3.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2
TIM3.IPParameters=Channel-PWM Generation2 CH2
TIM4.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2
TIM4.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3
TIM4.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4
@@ -362,12 +388,18 @@ USART2.IPParameters=VirtualMode
USART2.VirtualMode=VM_ASYNC
USART3.IPParameters=VirtualMode
USART3.VirtualMode=VM_ASYNC
VP_ADC1_TempSens_Input.Mode=IN-TempSens
VP_ADC1_TempSens_Input.Signal=ADC1_TempSens_Input
VP_ADC1_Vref_Input.Mode=IN-Vrefint
VP_ADC1_Vref_Input.Signal=ADC1_Vref_Input
VP_CRC_VS_CRC.Mode=CRC_Activate
VP_CRC_VS_CRC.Signal=CRC_VS_CRC
VP_RTC_VS_RTC_Activate.Mode=RTC_Enabled
VP_RTC_VS_RTC_Activate.Signal=RTC_VS_RTC_Activate
VP_SYS_VS_Systick.Mode=SysTick
VP_SYS_VS_Systick.Signal=SYS_VS_Systick
VP_TIM3_VS_ClockSourceINT.Mode=Internal
VP_TIM3_VS_ClockSourceINT.Signal=TIM3_VS_ClockSourceINT
VP_TIM4_VS_ClockSourceINT.Mode=Internal
VP_TIM4_VS_ClockSourceINT.Signal=TIM4_VS_ClockSourceINT
board=custom

View File

@@ -16,6 +16,7 @@ typedef enum{
RELAY3,
RELAY_DC,
RELAY_AC,
RELAY_CP,
RELAY_CC,
RELAY_DC1,
//
@@ -28,7 +29,11 @@ uint8_t GBT_LockGetState();
void GBT_Lock(uint8_t state);
uint8_t SW_GetAddr();
void ADC_Select_Channel(uint32_t ch);
uint8_t ADC_TryLock(void);
void ADC_LockBlocking(void);
void ADC_Unlock(void);
int16_t GBT_ReadTemp(uint8_t ch);
int16_t CONN_ReadTemp(uint8_t ch);
typedef enum{
IN_SW0 = 0,

View File

@@ -3,7 +3,7 @@
#define PSU_MAX_VOLTAGE 1000 //1V/bit
#define PSU_MIN_VOLTAGE 150 //1V/bit
#define PSU_MAX_CURRENT 100 //1A/bit
#define PSU_MAX_CURRENT 133 //1A/bit
#define PSU_MIN_CURRENT 1 //1A/bit
#define PSU_MAX_POWER 30000 //1W/bit

View File

@@ -1,238 +0,0 @@
/*
* charger_gbt.h
*
* Created on: Apr 18, 2024
* Author: colorbass
*/
#ifndef INC_CHARGER_GBT_H_
#define INC_CHARGER_GBT_H_
#include "main.h"
#include "connector.h"
#include "charger_control.h"
#define GBT_CST_NO_REASON 0x0000F0F0 // Без причины
#define GBT_CST_CONDITION_REACHED 0x0100F0F0 // Заряд завершен
#define GBT_CST_SUSPENDS_ARTIFICIALLY 0x0400F0F0 // Искуственная остановка
#define GBT_CST_FAULT_SUSPENSION 0x1000F0F0 // Приостановка из за неисправности
#define GBT_CST_BMS_ACTIVELY_SUSPENDS 0x4000F0F0 // завершение по инициативе BMS
#define GBT_CST_CONNECTOR_OVER_TEMP 0x0001F0F0 // Перегрев коннектора
#define GBT_CST_INT_PART_OVER_TEMP 0x0010F0F0 // Перегрев внутренних частей
#define GBT_CST_CANNOT_SUPPLY_REQ_ELQ 0x0040F0F0 // Неполучится обеспечить столько энергии
#define GBT_CST_SUDDENSTOP 0x0000F1F0 // Внезапная остановка
#define GBT_CST_OTHERFALUT 0x0000F4F0 // Прочая ошибка
#define GBT_CST_CURRENT_MISMATCH 0x0000F0F1 // Неправильный ток
#define GBT_CST_ABNORMALVOLTAGEERROR 0x0000F0F4 // Ненормальное напряжение
typedef enum {
GBT_STOP_EVSE = 0,
GBT_STOP_EV = 1,
GBT_STOP_OCPP = 2,
}GBT_StopSource_t;
typedef enum{
GBT_CC_UNKNOWN,
GBT_CC_12V,
GBT_CC_6V,
GBT_CC_4V,
GBT_CC_2V,
}gbtCcState_t;
typedef enum{
GBT_DISABLED = 0x10,
// GBT_S0_UNCONNECTED = 0x10, //СС1 12V/6V СС2 12V
// GBT_S1_CONNECTED = 0x11, //СС1 4V СС2 4V (6V)
// GBT_S2_LOCKED = 0x12, //
GBT_S3_STARTED = 0x13, // 12V AUX
GBT_S31_WAIT_BHM = 0x14, // testing isolation, send CHM receive BHM
GBT_S4_WAIT_PSU_READY = 0x15, // wait for PSU to be ready
GBT_S4_WAIT_PSU_ON = 0x16, // PSU is on, wait for isolation test
GBT_S4_ISOTEST = 0x17, // testing isolation, send CHM receive BHM
GBT_S4_WAIT_PSU_OFF = 0x18, // PSU is off, wait for battery info
GBT_S5_BAT_INFO = 0x19, // identifying BMS, send CRM receive BRM (long)
GBT_S6_BAT_STAT = 0x1A, // send CRM(AA), receive BCP (long)
GBT_S7_BMS_WAIT = 0x1B, // wait for BMS, send CTS+CML receive BRO(00), next BRO(AA)
GBT_S8_INIT_CHARGER = 0x1C,// starting power modules, send CRO(00)
GBT_S9_WAIT_BCL = 0x1D, // waiting for BCL (requested voltage), send CRO(00)
GBT_S10_CHARGING = 0x1E, // charging, contactor ON, send CCS, receiving BCL+BCS+BSM
GBT_STOP = 0x1F, // normal stop
GBT_STOP_CSD = 0x20, // normal stop
GBT_ERROR = 0x21, // Error
GBT_COMPLETE = 0x22,
}gbtState_t;
#pragma pack(push, 1)
typedef struct {
uint16_t maxOutputVoltage;
}GBT_BHM_t;
typedef struct {
uint8_t bmsIdentified;
uint32_t chargerNumber;
char chargerLocation[3];
}GBT_CRM_t;
typedef struct {
uint16_t maxOutputVoltage;
uint16_t minOutputVoltage;
uint16_t maxOutputCurrent;
uint16_t minOutputCurrent;
}GBT_CML_t;
typedef struct{
uint8_t version[3]; //GB/T version
uint8_t batteryType; //battery type
uint16_t batteryCapacity; // 0.1Ah/bit
uint16_t batteryVoltage; // 0.1V/bit
uint8_t batteryVendor[4]; // Battery vendor (ASCII string)
uint32_t batterySN; // int
uint8_t batteryManuY; // year (offset 1985)
uint8_t batteryManuM; // month
uint8_t batteryManuD; // day
uint32_t batteryCycleCount:24; //uint24_t
uint8_t ownAuto; // 0 = lizing, 1 = own auto
uint8_t rsvd0;
uint8_t EVIN[17]; //EVIN
uint8_t EV_SW_VER[8];
}GBT_BRM_t;
typedef struct {
uint16_t maxCellVoltage; // 0.01v/bit
uint16_t maxChargingCurrent; // 0.1A/bit
uint16_t totalEnergy; // 0.1kWh
uint16_t maxChargingVoltage; // 0.1V/ bit
uint8_t maxTemp; // 1C/bit, -50C offset
uint16_t SOC; // 0.1%/bit , 0..100%
uint16_t measVoltage; // 0.1V/bit
}GBT_BCP_t;
typedef struct {
uint16_t requestedVoltage; // 0.1V/bit
uint16_t requestedCurrent; // 0.1A/bit
uint8_t chargingMode; // 0x01 - CV, 0x02 - CC
}GBT_BCL_t;
typedef struct {
uint16_t measuredChargingVoltage;
uint16_t measuredChargingCurrent;
uint16_t highestVoltageOfBatteryCell;
//uint8_t groupNrOfCellWithHighestVoltage;
uint8_t currentChargeState;
uint16_t estimatedRemainingChargingTime;
}GBT_BCS_t;
typedef struct {
uint8_t singleBatteryHighestVoltageSerNo;// SINGLE_BATTERY_HIGHEST_VOLTAGE_SER_NO
uint8_t batteryHighestTemp; //BATTERY_HIGHEST_TEMP
uint8_t batteryHighestTempSerNo;//BATTERY_HIGHEST_TEMP_SER_NO
uint8_t batteryLowestTemp;//BATTERY_LOWEST_TEMP
uint8_t batteryLowestTempSerNo;//BATTERY_LOWEST_TEMP_SER_NO
uint8_t batteryCellVoltageState;//BATTERY_CELL_VOLTAGE_STATE
uint8_t batteryStatus;//BATTERY_STATUS[bit-mask];
}GBT_BSM_t;
typedef struct {
uint16_t outputVoltage;
uint16_t outputCurrent;
uint16_t chargingTime;
uint16_t chargingPermissible;
}GBT_CCS_t;
typedef struct {
uint16_t chargingTime;
uint16_t outputEnergy;
uint32_t chargerNumber;
}GBT_CSD_t;
/* 500 - Power Supply
TX
* PSU_ENABLE
* BMS_STATUS
* BMS_ERRORS
* PSU_REQUESTED_VOLTAGE[2]
* PSU_REQUESTED_CURRENT[2]
* BMS_CHARGE_PERCENTAGE
// BMS_MIN_CURRENT
* CHARGE_REMAINING_TIME_MIN
* CHARGE_REMAINING_TIME_SEC
* CHARGE_ELAPSED_TIME[1]
RX
* MEASURED_VOLTAGE[2]
* MEASURED_CURRENT[2]
// MAX_VOLTAGE[2]
// MAX_CURRENT[2]
// MAX_POWER[2]
* PSU_STATUS
*
*/
#pragma pack(pop)
extern gbtState_t GBT_State;
extern ADC_HandleTypeDef hadc1;
extern GBT_BRM_t GBT_EVInfo;
extern GBT_BCP_t GBT_BATStat;
extern GBT_BCS_t GBT_ChargingStatus;
extern GBT_BCL_t GBT_ReqPower;
extern GBT_CML_t GBT_MaxLoad;
extern GBT_CCS_t GBT_ChargerCurrentStatus;
extern GBT_CRM_t GBT_ChargerInfo;
extern GBT_BSM_t GBT_BatteryStatus;
extern GBT_CSD_t GBT_ChargerStop;
extern uint8_t GBT_BRO;
extern uint8_t GBT_Charger_Enable;
extern GBT_StopSource_t GBT_StopSource;
void GBT_Init();
void GBT_Start();
void GBT_Reset();
//void GBT_Stop(uint32_t causecode);
void GBT_StopEV(uint32_t causecode);
void GBT_StopEVSE(uint32_t causecode);
void GBT_StopOCPP(uint32_t causecode);
void GBT_ForceStop();
void GBT_ChargerTask();
void GBT_Error(uint32_t errorcode);
//float GBT_CC_GetAdc();
//uint8_t GBT_CC_GetState();
void GBT_SwitchState(gbtState_t state);
void GBT_Delay(uint32_t delay);
uint32_t GBT_StateTick();
void J_SendPacket(uint32_t PGN, uint8_t pri, uint8_t DLC, uint8_t *data);
void GBT_SendCCS();
void GBT_SendCST(uint32_t Cause);
void GBT_SendCRO(uint8_t state);
void GBT_SendCML();
void GBT_SendCTS();
void GBT_SendCHM();
void GBT_SendCRM(uint8_t state);
void GBT_SendCSD();
void GBT_SendCEM(uint32_t ErrorCode);
#endif /* INC_CHARGER_GBT_H_ */

View File

@@ -9,8 +9,6 @@
#define INC_CONNECTOR_H_
#include "main.h"
#include "charger_gbt.h"
#include "charger_control.h"
@@ -19,8 +17,5 @@ extern CONN_State_t connectorState;
void CONN_Init();
void CONN_Task();
void CONN_SetState(CONN_State_t state);
uint8_t CONN_CC_GetStateRaw();
uint8_t CONN_CC_GetState();
float CONN_CC_GetAdc();
#endif /* INC_CONNECTOR_H_ */

27
Core/Inc/cp.h Normal file
View File

@@ -0,0 +1,27 @@
#ifndef __CP_H
#define __CP_H
#include "main.h"
#include <stdint.h>
#define DUTY_INVERT 0
typedef enum {
EV_STATE_A_IDLE = 0,
EV_STATE_B_CONN_PREP = 1,
EV_STATE_C_CONN_ACTIVE = 2,
EV_STATE_D_CONN_ACT_VENT = 3,
EV_STATE_E_NO_POWER = 4,
EV_STATE_F_ERROR = 5,
EV_STATE_ACQUIRING = 6,
} CP_State_t;
void CP_Init(void);
void CP_SetDuty(uint8_t percentage);
uint8_t CP_GetDuty(void);
int32_t CP_GetVoltage(void);
CP_State_t CP_GetState(void);
void CP_Loop(void);
#endif

View File

@@ -1,40 +0,0 @@
/*
* j1939.h
*
* Created on: May 3, 2024
* Author: colorbass
*/
#ifndef INC_J1939_H_
#define INC_J1939_H_
#define J_ID_SE 0x56
#define J_ID_EV 0xF4
#include "main.h"
extern CAN_HandleTypeDef hcan1;
typedef struct{
uint8_t data[256]; //data array
uint32_t PGN; //received PGN
uint16_t size;
uint8_t packets;
uint8_t packet;
uint8_t step;
uint8_t step_cts_remain;
uint8_t state; //(0 = standby, 1= receiving)
uint32_t tick;
}j_receive_t;
extern j_receive_t j_rx;
void J_SendCTS(j_receive_t rx);
void J_SendACK(j_receive_t rx);
void GBT_CAN_ReInit();
void GBT_CAN_FilterInit();
#endif /* INC_J1939_H_ */

View File

@@ -1,35 +0,0 @@
/*
* lock.h
*
* Created on: Jul 31, 2024
* Author: colorbass
*/
#ifndef INC_LOCK_H_
#define INC_LOCK_H_
#include "main.h"
#include "stdbool.h"
void GBT_Lock(uint8_t state);
void GBT_ManageLockSolenoid();
void GBT_ManageLockMotor();
uint8_t GBT_LockGetState();
void GBT_ForceLock(uint8_t state);
void GBT_ResetErrorTimeout();
typedef struct {
// uint8_t state;
uint8_t demand;
uint8_t error;
uint8_t action_requested; // 0 = unlock, 1 = lock, 255 = no action
uint8_t motor_state; // 0 = idle, 1 = motor_on, 2 = waiting_off
uint32_t last_action_time; // время последнего изменения состояния мотора
uint8_t retry_count; // счетчик попыток
uint32_t error_tick; // время установки ошибки (для таймаута сброса)
} GBT_LockState_t;
extern GBT_LockState_t GBT_LockState;
#endif /* INC_LOCK_H_ */

View File

@@ -43,7 +43,7 @@ extern "C" {
/* USER CODE BEGIN EC */
#define FW_VERSION_MAJOR 0x01
#define FW_VERSION_MINOR 0x00
#define FW_VERSION_PATCH 0x01
#define FW_VERSION_PATCH 0x02
/* USER CODE END EC */
/* Exported macro ------------------------------------------------------------*/
@@ -59,10 +59,16 @@ void Error_Handler(void);
/* USER CODE END EFP */
/* Private defines -----------------------------------------------------------*/
#define RELAY_CP_Pin GPIO_PIN_3
#define RELAY_CP_GPIO_Port GPIOC
#define IN_SW0_Pin GPIO_PIN_1
#define IN_SW0_GPIO_Port GPIOA
#define IN_SW1_Pin GPIO_PIN_2
#define IN_SW1_GPIO_Port GPIOA
#define CP_ADC_Pin GPIO_PIN_4
#define CP_ADC_GPIO_Port GPIOA
#define CP_PWM_Pin GPIO_PIN_7
#define CP_PWM_GPIO_Port GPIOA
#define LOCK_A_Pin GPIO_PIN_4
#define LOCK_A_GPIO_Port GPIOC
#define LOCK_B_Pin GPIO_PIN_5

127
Core/Inc/serial.h Normal file
View File

@@ -0,0 +1,127 @@
#ifndef __SERIAL_H
#define __SERIAL_H
#include "main.h"
#include "charger_control.h"
#include "usart.h"
#include "cp.h"
void CCS_SerialLoop(void);
void CCS_Init(void);
void CCS_SendEmergencyStop(void);
void CCS_SendStart(void);
void CCS_RxEventCallback(UART_HandleTypeDef *huart, uint16_t size);
typedef enum {
CCS_DISABLED = 0,
CCS_UNPLUGGED = 1,
CCS_AUTH_REQUIRED = 2,
CCS_CONNECTED = 3,
CCS_REPLUGGING = 4,
} CCS_ConnectorState_t;
typedef enum {
PSU_OFF = 0,
PSU_ON = 1,
PSU_PREPARE = 2,
} EnablePSU_t;
typedef struct {
uint16_t maxVoltage;
uint16_t minVoltage;
uint16_t maxCurrent;
uint16_t minCurrent;
uint32_t maxPower;
} CCS_MaxLoad_t;
/* Commands Everest -> module. */
#define CMD_E2M_PWM_DUTY 0x40
#define CMD_E2M_ENABLE_OUTPUT 0x41
#define CMD_E2M_RESET 0x42
#define CMD_E2M_ENABLE 0x43
#define CMD_E2M_REPLUG 0x44
#define CMD_E2M_SET_OUTPUT_VOLTAGE 0x45
#define CMD_E2M_ISOLATION_CONTROL 0x46
#define CMD_E2M_EV_INFO 0x47
#define CMD_E2M_EVSE_STATE 0x48
#define CMD_E2M_KEEP_ALIVE 0x49
/* Commands module -> Everest. */
#define CMD_M2E_STATE 0x50
#define CMD_M2E_RESET 0x52
#define CMD_M2E_ESTOP 0x53
#define CMD_M2E_START 0x54
typedef struct __attribute__((packed)) {
uint8_t pwm_duty_percent;
} e2m_pwm_duty_t;
typedef struct __attribute__((packed)) {
uint8_t enable_output;
} e2m_enable_output_t;
typedef struct __attribute__((packed)) {
uint8_t reset;
} e2m_reset_t;
typedef struct __attribute__((packed)) {
uint8_t enable;
} e2m_enable_t;
typedef struct __attribute__((packed)) {
uint8_t replug;
} e2m_replug_t;
typedef struct __attribute__((packed)) {
uint16_t voltage_V;
uint16_t current_0p1A;
} e2m_set_output_t;
typedef struct __attribute__((packed)) {
uint8_t command;
} e2m_isolation_control_t;
typedef struct __attribute__((packed)) {
uint16_t valid_mask;
uint16_t soc;
uint16_t present_voltage;
uint16_t present_current;
uint16_t target_voltage;
uint16_t target_current;
uint16_t max_current;
uint16_t min_current;
uint16_t max_voltage;
uint32_t max_power;
uint32_t remaining_energy;
uint16_t battery_capacity;
uint16_t battery_full_soc;
uint16_t battery_bulk_soc;
uint32_t estimated_time_full;
uint32_t departure_time;
uint32_t estimated_time_bulk;
} CCS_EvInfo_t;
typedef struct __attribute__((packed)) {
uint8_t DutyCycle;
uint8_t OutputEnabled;
uint16_t MeasuredVoltage;
uint16_t MeasuredCurrent;
uint32_t Power;
uint32_t Energy;
uint32_t IsolationResistance;
uint8_t IsolationValid;
uint8_t CpState;
uint16_t MaxVoltage;
uint16_t MinVoltage;
uint16_t MaxCurrent;
uint16_t MinCurrent;
uint32_t MaxPower;
} CCS_State_t;
extern CCS_MaxLoad_t CCS_MaxLoad;
extern CCS_EvInfo_t CCS_EvInfo;
extern CONN_State_t CCS_EvseState;
extern uint8_t REPLUG;
#endif

23
Core/Inc/sma_filter.h Normal file
View File

@@ -0,0 +1,23 @@
#ifndef SMA_FILTER_H
#define SMA_FILTER_H
#include <stdint.h>
// Простая скользящая SMA (simple moving average) для целых значений.
// Окно фиксировано и задается макросом.
#ifndef SMA_FILTER_WINDOW
#define SMA_FILTER_WINDOW 8
#endif
typedef struct {
int32_t sum;
uint16_t idx;
uint16_t count;
int32_t buffer[SMA_FILTER_WINDOW];
} SMAFilter_t;
void SMAFilter_Init(SMAFilter_t* f);
int32_t SMAFilter_Update(SMAFilter_t* f, int32_t x);
#endif // SMA_FILTER_H

View File

@@ -56,6 +56,7 @@ void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
void CAN1_RX0_IRQHandler(void);
void TIM3_IRQHandler(void);
void USART1_IRQHandler(void);
void USART2_IRQHandler(void);
void USART3_IRQHandler(void);

View File

@@ -32,12 +32,15 @@ extern "C" {
/* USER CODE END Includes */
extern TIM_HandleTypeDef htim3;
extern TIM_HandleTypeDef htim4;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_TIM3_Init(void);
void MX_TIM4_Init(void);
void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);

BIN
Core/Src/.DS_Store vendored

Binary file not shown.

View File

@@ -85,10 +85,11 @@ void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
__HAL_RCC_GPIOB_CLK_ENABLE();
/**ADC1 GPIO Configuration
PA3 ------> ADC1_IN3
PA4 ------> ADC1_IN4
PB0 ------> ADC1_IN8
PB1 ------> ADC1_IN9
*/
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Pin = GPIO_PIN_3|CP_ADC_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
@@ -115,10 +116,11 @@ void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle)
/**ADC1 GPIO Configuration
PA3 ------> ADC1_IN3
PA4 ------> ADC1_IN4
PB0 ------> ADC1_IN8
PB1 ------> ADC1_IN9
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_3);
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_3|CP_ADC_Pin);
HAL_GPIO_DeInit(GPIOB, ADC_NTC1_Pin|ADC_NTC2_Pin);

View File

@@ -2,16 +2,19 @@
#include "main.h"
#include "board.h"
#include "tim.h"
#include "sma_filter.h"
extern ADC_HandleTypeDef hadc1;
//TODO:
//TEMP READ
//GBT_TEMP_SENSORS
// Connector temperature sensors
InfoBlock_t *InfoBlock = (InfoBlock_t *)(VERSION_OFFSET);
uint8_t RELAY_State[RELAY_COUNT];
static volatile uint8_t adc_lock = 0;
static SMAFilter_t conn_temp_adc_filter[2];
void RELAY_Write(relay_t num, uint8_t state){
switch (num) {
@@ -30,6 +33,9 @@ void RELAY_Write(relay_t num, uint8_t state){
case RELAY_AC:
HAL_GPIO_WritePin(RELAY5_GPIO_Port, RELAY5_Pin, state);
break;
case RELAY_CP:
HAL_GPIO_WritePin(RELAY_CP_GPIO_Port, RELAY_CP_Pin, state);
break;
case RELAY_CC:
HAL_GPIO_WritePin(RELAY_CC_GPIO_Port, RELAY_CC_Pin, state);
break;
@@ -89,8 +95,12 @@ void Init_Peripheral(){
RELAY_Write(RELAY3, 0);
RELAY_Write(RELAY_DC, 0);
RELAY_Write(RELAY_AC, 0);
RELAY_Write(RELAY_CP, 1);
RELAY_Write(RELAY_CC, 1);
RELAY_Write(RELAY_DC1, 0);
SMAFilter_Init(&conn_temp_adc_filter[0]);
SMAFilter_Init(&conn_temp_adc_filter[1]);
}
float pt1000_to_temperature(float resistance) {
@@ -119,7 +129,9 @@ float calculate_NTC_resistance(int adc_value, float Vref, float Vin, float R) {
return R_NTC;
}
int16_t GBT_ReadTemp(uint8_t ch){
int16_t CONN_ReadTemp(uint8_t ch){
ADC_LockBlocking();
//TODO
if(ch)ADC_Select_Channel(ADC_CHANNEL_8);
else ADC_Select_Channel(ADC_CHANNEL_9);
@@ -136,19 +148,28 @@ int16_t GBT_ReadTemp(uint8_t ch){
// Остановка АЦП (по желанию)
HAL_ADC_Stop(&hadc1);
if(adcValue>4000) return 20; //Термодатчик не подключен
int32_t adc_filtered = SMAFilter_Update(&conn_temp_adc_filter[ch ? 1u : 0u], (int32_t)adcValue);
if((uint32_t)adc_filtered > 4000u) {
ADC_Unlock();
return 20; //Термодатчик не подключен
}
// int adc_value = 2048; // Пример значения АЦП
float Vref = 3.3; // Напряжение опорное
float Vin = 5.0; // Входное напряжение
float R = 1000; // Сопротивление резистора в Омах
float temp = pt1000_to_temperature(calculate_NTC_resistance(adcValue, Vref, Vin, R));
float temp = pt1000_to_temperature(calculate_NTC_resistance((int)adc_filtered, Vref, Vin, R));
ADC_Unlock();
return (int16_t)temp;
}
int16_t GBT_ReadTemp(uint8_t ch){
return CONN_ReadTemp(ch);
}
void ADC_Select_Channel(uint32_t ch) {
ADC_ChannelConfTypeDef conf = {
.Channel = ch,
@@ -159,3 +180,34 @@ void ADC_Select_Channel(uint32_t ch) {
Error_Handler();
}
}
uint8_t ADC_TryLock(void) {
uint32_t primask = __get_PRIMASK();
__disable_irq();
if (adc_lock != 0u) {
if (primask == 0u) {
__enable_irq();
}
return 0u;
}
adc_lock = 1u;
if (primask == 0u) {
__enable_irq();
}
return 1u;
}
void ADC_LockBlocking(void) {
while (ADC_TryLock() == 0u) {
/* wait in main context until ADC is free */
}
}
void ADC_Unlock(void) {
uint32_t primask = __get_PRIMASK();
__disable_irq();
adc_lock = 0u;
if (primask == 0u) {
__enable_irq();
}
}

View File

@@ -1,10 +1,12 @@
#include "charger_control.h"
#include "charger_config.h"
#include "lock.h"
#include "psu_control.h"
#include "connector.h"
#include "debug.h"
ChargingConnector_t CONN;
CONN_State_t connectorState;
void CONN_Init(){
@@ -21,9 +23,7 @@ void CONN_Loop(){
CONN.connControl = CMD_NONE;
}
if(GBT_LockState.error){
CONN.chargingError = CONN_ERR_LOCK;
} else if(PSU0.cont_fault){
if(PSU0.cont_fault){
CONN.chargingError = CONN_ERR_CONTACTOR;
} else if(PSU0.psu_fault){
CONN.chargingError = CONN_ERR_PSU_FAULT;
@@ -38,6 +38,48 @@ void CONN_Loop(){
}
void CONN_Task(){
/* CCS state machine is handled in serial.c.
* Keep this task lightweight for scheduler compatibility.
*/
if (CONN.chargingError != CONN_NO_ERROR) {
CONN_SetState(Disabled);
return;
}
if (connectorState == Unknown) {
CONN_SetState(Unplugged);
} else if (connectorState == Disabled && CONN.chargingError == CONN_NO_ERROR) {
CONN_SetState(Unplugged);
}
}
void CONN_SetState(CONN_State_t state){
if (connectorState == state) {
CONN.connState = state;
return;
}
connectorState = state;
if(connectorState == Unknown) log_printf(LOG_INFO, "Connector: Unknown\n");
if(connectorState == Unplugged) log_printf(LOG_INFO, "Connector: Unplugged\n");
if(connectorState == Disabled) log_printf(LOG_INFO, "Connector: Disabled\n");
if(connectorState == Preparing) log_printf(LOG_INFO, "Connector: Preparing\n");
if(connectorState == AuthRequired) log_printf(LOG_INFO, "Connector: AuthRequired\n");
if(connectorState == WaitingForEnergy) log_printf(LOG_INFO, "Connector: WaitingForEnergy\n");
if(connectorState == ChargingPausedEV) log_printf(LOG_INFO, "Connector: ChargingPausedEV\n");
if(connectorState == ChargingPausedEVSE) log_printf(LOG_INFO, "Connector: ChargingPausedEVSE\n");
if(connectorState == Charging) log_printf(LOG_INFO, "Connector: Charging\n");
if(connectorState == AuthTimeout) log_printf(LOG_INFO, "Connector: AuthTimeout\n");
if(connectorState == Finished) log_printf(LOG_INFO, "Connector: Finished\n");
if(connectorState == FinishedEVSE) log_printf(LOG_INFO, "Connector: FinishedEVSE\n");
if(connectorState == FinishedEV) log_printf(LOG_INFO, "Connector: FinishedEV\n");
if(connectorState == Replugging) log_printf(LOG_INFO, "Connector: Replugging\n");
CONN.connState = state;
}
void CONN_PrintChargingTotal(){
printf("CONN%d Charging Finished:\n", 0);
// printf("Charging Time: %d\n", CONN.chargingTime);

View File

@@ -1,593 +0,0 @@
/*
* 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 "lock.h"
#include "connector.h"
#include "soft_rtc.h"
#include "debug.h"
#include "charger_config.h"
#include "serial_control.h"
#include "lock.h"
#include "psu_control.h"
uint8_t GBT_CC_GetStateRaw();
gbtState_t GBT_State;
uint32_t GBT_state_tick; //Tick after state switch
uint32_t GBT_delay_start;
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;
/** Время последнего приёма любого из PGN BCL/BCS/BSM; общий таймаут в GBT_S10_CHARGING */
uint32_t GBT_last_BCL_BCS_BSM_tick;
#define GBT_BCL_BCS_BSM_TIMEOUT_MS 2000
uint32_t GBT_StopCauseCode;
uint32_t GBT_ErrorCode;
GBT_StopSource_t GBT_StopSource;
extern ConfigBlock_t config;
void GBT_Init(){
GBT_State = GBT_DISABLED;
GBT_Reset();
GBT_MaxLoad.maxOutputVoltage = PSU_MAX_VOLTAGE*10; // 1000V
GBT_MaxLoad.minOutputVoltage = PSU_MIN_VOLTAGE*10; //150V
GBT_MaxLoad.maxOutputCurrent = 4000 - (PSU_MAX_CURRENT*10); //100A
GBT_MaxLoad.minOutputCurrent = 4000 - (PSU_MIN_CURRENT*10); //1A
}
void GBT_SetConfig(){
set_Time(config.unixTime);
GBT_ChargerInfo.chargerLocation[0] = config.location[0];
GBT_ChargerInfo.chargerLocation[1] = config.location[1];
GBT_ChargerInfo.chargerLocation[2] = config.location[2];
GBT_ChargerInfo.chargerNumber = config.chargerNumber;
}
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
GBT_last_BCL_BCS_BSM_tick = HAL_GetTick();
//TODO: power block
memcpy (&GBT_ReqPower, j_rx.data, sizeof(GBT_ReqPower));
uint16_t volt = GBT_ReqPower.requestedVoltage; // 0.1V/bit
uint16_t curr = 4000 - GBT_ReqPower.requestedCurrent; // 0.1A/bit
CONN.RequestedVoltage = volt / 10; // В
CONN.WantedCurrent = curr; // 0.1A
break;
case 0x1100: //PGN BCS
GBT_last_BCL_BCS_BSM_tick = HAL_GetTick();
//TODO
memcpy (&GBT_ChargingStatus, j_rx.data, sizeof(GBT_ChargingStatus));
CONN.SOC = GBT_ChargingStatus.currentChargeState;
break;
case 0x1300: //PGN BSM
GBT_last_BCL_BCS_BSM_tick = HAL_GetTick();
//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((HAL_GetTick() - GBT_delay_start) < GBT_delay){
//waiting
}else switch (GBT_State){
case GBT_DISABLED:
RELAY_Write(RELAY_AUX0, 0);
RELAY_Write(RELAY_AUX1, 0);
if(connectorState == Preparing){
GBT_Reset();
GBT_Start();//TODO IF protections (maybe not needed)
}
break;
case GBT_S3_STARTED:
GBT_SwitchState(GBT_S31_WAIT_BHM);
GBT_Delay(500);
break;
case GBT_S31_WAIT_BHM:
if(j_rx.state == 0) GBT_SendCHM();
GBT_Delay(250);
if(GBT_BHM_recv) {
GBT_SwitchState(GBT_S4_WAIT_PSU_READY);
}
//Timeout 10S
if((GBT_BHM_recv == 0) && (GBT_StateTick()>10000)) { //BHM Timeout
GBT_Error(0xFCF0C0FC);
CONN.chargingError = CONN_ERR_EV_COMM;
log_printf(LOG_ERR, "BHM Timeout\n");
}
break;
case GBT_S4_WAIT_PSU_READY:
if(j_rx.state == 0) GBT_SendCHM();
GBT_Delay(250);
if(PSU0.ready){
GBT_SwitchState(GBT_S4_WAIT_PSU_ON);
}
if(GBT_StateTick()>10000){
GBT_StopEVSE(GBT_CST_OTHERFALUT);
CONN.chargingError = CONN_ERR_PSU_FAULT;
log_printf(LOG_ERR, "PSU ready timeout, stopping...\n");
break;
}
break;
case GBT_S4_WAIT_PSU_ON:
if(j_rx.state == 0) GBT_SendCHM();
GBT_Delay(250);
CONN.RequestedVoltage = GBT_MaxVoltage.maxOutputVoltage / 10; // 0.1V -> V
CONN.WantedCurrent = 10; // 1A max (0.1A units)
CONN.EnableOutput = 1;
if(PSU0.state == PSU_CONNECTED){
GBT_SwitchState(GBT_S4_ISOTEST);
}
if(GBT_StateTick()>10000){
GBT_StopEVSE(GBT_CST_OTHERFALUT);
CONN.chargingError = CONN_ERR_PSU_FAULT;
log_printf(LOG_ERR, "PSU on timeout, stopping...\n");
break;
}
break;
case GBT_S4_ISOTEST:
if(j_rx.state == 0) GBT_SendCHM();
GBT_Delay(250);
//TODO: Isolation test trigger
if(CONN.chargingError != CONN_NO_ERROR){
GBT_StopEVSE(GBT_CST_OTHERFALUT);
}
if(GBT_StateTick()>5000){
GBT_SwitchState(GBT_S4_WAIT_PSU_OFF);
}
if(ISO.isolationResistance < (ISO.voltageComm/2)){ // *100/1000
CONN.chargingError = CONN_ERR_INSULATION;
log_printf(LOG_WARN, "Isolation warning\n");
} // 500 Ohm/V
if(ISO.isolationResistance < (ISO.voltageComm/10)){ // *100/1000
CONN.chargingError = CONN_ERR_INSULATION;
log_printf(LOG_WARN, "Current leakage, insulation error, stopping...\n");
GBT_StopEVSE(GBT_CST_OTHERFALUT);
} // 100 Ohm/V
break;
case GBT_S4_WAIT_PSU_OFF:
CONN.RequestedVoltage = 0;
CONN.WantedCurrent = 0;
CONN.EnableOutput = 0;
if(GBT_StateTick()>5000){
GBT_StopEVSE(GBT_CST_OTHERFALUT);
CONN.chargingError = CONN_ERR_PSU_FAULT;
log_printf(LOG_ERR, "PSU off timeout, stopping...\n");
break;
}
if(PSU0.PSU_enabled == 0){
GBT_SwitchState(GBT_S5_BAT_INFO);
}
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);
log_printf(LOG_INFO, "EV info:\n");
log_printf(LOG_INFO, "GBT_ver V%d.%d%d\n",GBT_EVInfo.version[0],GBT_EVInfo.version[1],GBT_EVInfo.version[2]);
log_printf(LOG_INFO, "Battery type: %d\n",GBT_EVInfo.batteryType);
log_printf(LOG_INFO, "Battery capacity: %d\n", GBT_EVInfo.batteryCapacity); // 0.1Ah/bit
log_printf(LOG_INFO, "Battery voltage: %d\n", GBT_EVInfo.batteryVoltage); // 0.1V/bit
log_printf(LOG_INFO, "Battery vendor: %.4s\n", GBT_EVInfo.batteryVendor); // Battery vendor (ASCII string)
log_printf(LOG_INFO, "Battery SN: %lu\n", GBT_EVInfo.batterySN); // int
log_printf(LOG_INFO, "Battery manufacture date: %02d.%02d.%04d\n", GBT_EVInfo.batteryManuD, GBT_EVInfo.batteryManuM ,GBT_EVInfo.batteryManuY+1985); // year (offset 1985)
log_printf(LOG_INFO, "Battery cycles: %d\n", GBT_EVInfo.batteryCycleCount); //uint24_t
log_printf(LOG_INFO, "Own auto: %d\n", GBT_EVInfo.ownAuto); // 0 = lizing, 1 = own auto
log_printf(LOG_INFO, "EVIN: %.17s\n", GBT_EVInfo.EVIN); //EVIN
log_printf(LOG_INFO, "EV_SW_VER: %.8s\n", GBT_EVInfo.EV_SW_VER);
}
//Timeout
if((GBT_StateTick()>5000) && (GBT_BAT_INFO_recv == 0)){
CONN.chargingError = CONN_ERR_EV_COMM;
GBT_Error(0xFDF0C0FC); //BRM Timeout
log_printf(LOG_ERR, "BRM Timeout\n");
}
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);
log_printf(LOG_INFO, "Battery info:\n");
log_printf(LOG_INFO, "maxCV %dV\n",GBT_BATStat.maxCellVoltage/100); // 0.01v/bit
log_printf(LOG_INFO, "maxCC %dA\n",GBT_BATStat.maxChargingCurrent/10); // 0.1A/bit
log_printf(LOG_INFO, "totE %dkWh\n",GBT_BATStat.totalEnergy/10); // 0.1kWh
log_printf(LOG_INFO, "maxCV %dV\n",GBT_BATStat.maxChargingVoltage/10); // 0.1V/ bit
log_printf(LOG_INFO, "maxT %dC\n",(int16_t)GBT_BATStat.maxTemp-50); // 1C/bit, -50C offset
log_printf(LOG_INFO, "SOC %dp\n",GBT_BATStat.SOC/10); // 0.1%/bit , 0..100%
log_printf(LOG_INFO, "Volt. %dV\n",GBT_BATStat.measVoltage/10); // 0.1V/bit
}
if((GBT_StateTick()>5000) && (GBT_BAT_STAT_recv == 0)){
CONN.chargingError = CONN_ERR_EV_COMM;
GBT_Error(0xFCF1C0FC); //BCP Timeout
log_printf(LOG_ERR, "BCP Timeout\n");
}
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)){
CONN.chargingError = CONN_ERR_EV_COMM;
GBT_Error(0xFCF4C0FC); //BRO Timeout
log_printf(LOG_ERR, "BRO Timeout\n");
}
if(EV_ready){
//EV ready (AA)
GBT_SwitchState(GBT_S8_INIT_CHARGER);
}else{
if((GBT_StateTick()>60000) && (GBT_BRO_recv == 1)){
CONN.chargingError = CONN_ERR_EV_COMM;
GBT_Error(0xFCF4C0FC); //BRO Timeout
log_printf(LOG_ERR, "EV not ready for a 60s\n");
}
}
break;
case GBT_S8_INIT_CHARGER:
if(j_rx.state == 0) GBT_SendCRO(0x00);
//TODO
GBT_Delay(250);
// if(GBT_StateTick()>1500){
if(PSU0.ready){
//Power Modules initiated
GBT_SwitchState(GBT_S9_WAIT_BCL);
}
if((GBT_StateTick()>6000) && (PSU0.ready == 0)){
GBT_StopEVSE(GBT_CST_OTHERFALUT);
CONN.chargingError = CONN_ERR_PSU_FAULT;
log_printf(LOG_ERR, "PSU not ready, stopping...\n");
}
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);
GBT_last_BCL_BCS_BSM_tick = HAL_GetTick();
CONN_SetState(Charging);
uint16_t curr = 4000 - GBT_ReqPower.requestedCurrent;
uint16_t volt = GBT_ReqPower.requestedVoltage;
//TODO Limits
CONN.RequestedVoltage = volt / 10; // В
CONN.WantedCurrent = curr; // 0.1A
CONN.EnableOutput = 1;
GBT_TimeChargingStarted = get_Current_Time();
}
break;
case GBT_S10_CHARGING:
//CHARGING
if((HAL_GetTick() - GBT_last_BCL_BCS_BSM_tick) > GBT_BCL_BCS_BSM_TIMEOUT_MS){
GBT_StopEVSE(GBT_CST_OTHERFALUT);
CONN.chargingError = CONN_ERR_EV_COMM;
log_printf(LOG_WARN, "BCL/BCS/BSM timeout, stopping...\n");
break;
}
if(CONN.connControl == CMD_STOP) GBT_StopOCPP(GBT_CST_SUSPENDS_ARTIFICIALLY);
if(CONN.connControl == CMD_FORCE_UNLOCK) GBT_StopOCPP(GBT_CST_SUSPENDS_ARTIFICIALLY); // --> Finished
if(GBT_LockState.error) {
GBT_StopEVSE(GBT_CST_OTHERFALUT); // --> Suspend EVSE
CONN.chargingError = CONN_ERR_LOCK;
log_printf(LOG_WARN, "Lock error, stopping...\n");
break;
}
if(CONN_CC_GetState()!=GBT_CC_4V){
GBT_StopEVSE(GBT_CST_OTHERFALUT);
CONN.chargingError = CONN_ERR_HOTPLUG;
log_printf(LOG_WARN, "Hotplug detected, stopping...\n");
break;
}
if((GBT_ReadTemp(0) > 90) || (GBT_ReadTemp(1) > 90)) {
GBT_StopEVSE(GBT_CST_CONNECTOR_OVER_TEMP);
CONN.chargingError = CONN_ERR_CONN_TEMP;
log_printf(LOG_WARN, "Connector overheat %d %d, stopping...\n", GBT_ReadTemp(0), GBT_ReadTemp(1));
break;
}
if(ISO.isolationResistance < (ISO.voltageComm/10)){ // *100/1000
CONN.chargingError = CONN_ERR_INSULATION;
log_printf(LOG_WARN, "Current leakage, insulation error, stopping...\n");
} // 100 Ohm/V
if(CONN.chargingError != CONN_NO_ERROR){ // --> Suspend EVSE
GBT_StopEVSE(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 - CONN.MeasuredCurrent; // 0.1A
GBT_ChargerCurrentStatus.outputVoltage = CONN.MeasuredVoltage * 10; // V -> 0.1V
if(j_rx.state == 0) {
GBT_SendCCS();
GBT_Delay(49);
}else{
GBT_Delay(10); // Resend packet if not sent
}
//TODO: снижение тока если перегрев контактов
break;
case GBT_STOP:
GBT_Delay(10);
CONN.EnableOutput = 0;
GBT_SendCST(GBT_StopCauseCode);
//RELAY_Write(RELAY_OUTPUT, 0);
//GBT_SwitchState(GBT_DISABLED);
if(GBT_StateTick()>10000){
log_printf(LOG_ERR, "BSD Timeout\n");
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);
}
break;
case GBT_ERROR:
GBT_SendCEM(GBT_ErrorCode); //2.5S
GBT_SwitchState(GBT_COMPLETE);
break;
case GBT_COMPLETE:
if(connectorState != Finished) {
GBT_SwitchState(GBT_DISABLED);
GBT_Reset();//CHECK
}
break;
default:
GBT_SwitchState(GBT_DISABLED);
}
if (CONN_CC_GetState()==GBT_CC_4V) CONN.EvConnected = 1;
else CONN.EvConnected = 0;
}
void GBT_SwitchState(gbtState_t state){
GBT_State = state;
GBT_state_tick = HAL_GetTick();
if(GBT_State == GBT_DISABLED) log_printf(LOG_INFO, "Disabled\n");
if(GBT_State == GBT_S3_STARTED) log_printf(LOG_INFO, "Charging started\n");
if(GBT_State == GBT_S31_WAIT_BHM) log_printf(LOG_INFO, "Waiting for BHM\n");
if(GBT_State == GBT_S4_WAIT_PSU_READY) log_printf(LOG_INFO, "Waiting for PSU ready\n");
if(GBT_State == GBT_S4_ISOTEST) log_printf(LOG_INFO, "Isolation test\n");
if(GBT_State == GBT_S5_BAT_INFO) log_printf(LOG_INFO, "Waiting for battery info\n");
if(GBT_State == GBT_S6_BAT_STAT) log_printf(LOG_INFO, "Waiting for battery status\n");
if(GBT_State == GBT_S7_BMS_WAIT) log_printf(LOG_INFO, "Waiting for BMS\n");
if(GBT_State == GBT_S8_INIT_CHARGER)log_printf(LOG_INFO, "Initializing charger\n");
if(GBT_State == GBT_S9_WAIT_BCL) log_printf(LOG_INFO, "Waiting for BCL\n");
if(GBT_State == GBT_S10_CHARGING) log_printf(LOG_INFO, "Charging in progress\n");
if(GBT_State == GBT_STOP) log_printf(LOG_INFO, "Charging Stopped\n");
if(GBT_State == GBT_STOP_CSD) log_printf(LOG_INFO, "Charging Stopped with CSD\n");
if(GBT_State == GBT_ERROR) log_printf(LOG_INFO, "Charging Error\n");
if(GBT_State == GBT_COMPLETE) log_printf(LOG_INFO, "Charging Finished\n");
}
uint32_t GBT_StateTick(){
return HAL_GetTick() - GBT_state_tick;
}
void GBT_Delay(uint32_t delay){
GBT_delay_start = HAL_GetTick();
GBT_delay = delay;
}
void GBT_StopEV(uint32_t causecode){ // --> Suspend EV
if (CONN.chargingError){
GBT_StopSource = GBT_STOP_EVSE;
}else{
GBT_StopSource = GBT_STOP_EV;
}
GBT_StopCauseCode = causecode;
if(GBT_State != GBT_STOP) GBT_SwitchState(GBT_STOP);
}
void GBT_StopEVSE(uint32_t causecode){ // --> Suspend EVSE
GBT_StopSource = GBT_STOP_EVSE;
GBT_StopCauseCode = causecode;
if(GBT_State != GBT_STOP) GBT_SwitchState(GBT_STOP);
}
void GBT_StopOCPP(uint32_t causecode){ // --> Finished
GBT_StopSource = GBT_STOP_OCPP;
GBT_StopCauseCode = causecode;
if(GBT_State != GBT_STOP) GBT_SwitchState(GBT_STOP);
}
void GBT_ForceStop(){ // --> Suspend EV
GBT_StopSource = GBT_STOP_EV;
CONN.EnableOutput = 0;
GBT_SwitchState(GBT_COMPLETE);
GBT_Lock(0);
RELAY_Write(RELAY_AUX0, 0);
RELAY_Write(RELAY_AUX1, 0);
}
void GBT_Error(uint32_t errorcode){ // --> Suspend EV
GBT_StopSource = GBT_STOP_EV;
log_printf(LOG_ERR, "GBT Error code: 0x%X\n", errorcode);
GBT_ErrorCode = errorcode;
GBT_SwitchState(GBT_ERROR);
}
void GBT_Reset(){
GBT_last_BCL_BCS_BSM_tick = HAL_GetTick();
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;
CONN.SOC = 0;
CONN.EnableOutput = 0;
CONN.WantedCurrent = 0;
CONN.RequestedVoltage = 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 = 500; //50V
GBT_TimeChargingStarted = 0;
GBT_BRO = 0x00;
GBT_LockResetError();
}
void GBT_Start(){
RELAY_Write(RELAY_AUX0, 1);
RELAY_Write(RELAY_AUX1, 1);
GBT_SwitchState(GBT_S3_STARTED);
}

View File

@@ -1,221 +0,0 @@
/*
* connector.c
*
* All initialization before 12v_aux
*/
#include "connector.h"
#include "lock.h"
#include "board.h"
#include "debug.h"
CONN_State_t connectorState;
extern uint8_t config_initialized;
gbtCcState_t CC_STATE_FILTERED;
// name - уникальный идентификатор таймера для данного места использования
// cond - условие, которое должно непрерывно держаться delay_ms мс
// delay_ms - задержка в миллисекундах
#define DELAYED_HOLD_MS(name, cond, delay_ms) \
({ \
static uint32_t name = 0; \
uint8_t __hold_result = 0; \
if (cond) { \
if (name == 0) { \
name = HAL_GetTick(); \
} else if ((HAL_GetTick() - name) >= (uint32_t)(delay_ms)) {\
__hold_result = 1; \
name = 0; \
} \
} else { \
name = 0; \
} \
__hold_result; \
})
void CONN_Task(){
switch (connectorState){
case Unknown: // unlocked, waiting for config
GBT_Lock(0);
if (config_initialized) {
CONN_SetState(Unplugged);
}
break;
case Disabled: // faulted, unlocked
GBT_Lock(0);
if(CONN.chargingError == 0) CONN_SetState(Unplugged);
if(CONN.connControl == CMD_FORCE_UNLOCK) GBT_ForceLock(0);
break;
case Unplugged: // unlocked, waiting to connect
GBT_Lock(0);
if(CONN.chargingError != 0) CONN_SetState(Disabled);
if(CONN.connControl == CMD_FORCE_UNLOCK) GBT_ForceLock(0);
if((CONN_CC_GetState()==GBT_CC_4V) && (CONN.connControl != CMD_FORCE_UNLOCK)){
CONN_SetState(AuthRequired);
GBT_Lock(0);
}
break;
case AuthRequired: // plugged, waiting to start charge
GBT_Lock(0);
if(CONN.connControl == CMD_FORCE_UNLOCK) GBT_ForceLock(0);
if(CONN_CC_GetState()==GBT_CC_4V){
if(CONN.connControl == CMD_START){
CONN_SetState(Preparing);
}
if(CONN.connControl == CMD_FORCE_UNLOCK){
CONN_SetState(Unplugged);
}
// if CHARGING_NOT_ALLOWED — stay here
}else{
CONN_SetState(Unplugged);
}
break;
case Preparing: // charging, locked
GBT_Lock(1);
if(GBT_State == GBT_COMPLETE){
if(GBT_StopSource == GBT_STOP_EVSE){
CONN_SetState(FinishedEVSE);
}else if(GBT_StopSource == GBT_STOP_EV){
CONN_SetState(FinishedEV);
}else if(GBT_StopSource == GBT_STOP_OCPP){
CONN_SetState(Finished);
}else{
CONN_SetState(FinishedEVSE);
}
}
if(GBT_State == GBT_S10_CHARGING){
CONN_SetState(Charging);
}
break;
case Charging: // charging, locked
GBT_Lock(1);
if(GBT_State == GBT_COMPLETE){
if(GBT_StopSource == GBT_STOP_EVSE){
CONN_SetState(FinishedEVSE);
}else if(GBT_StopSource == GBT_STOP_EV){
CONN_SetState(FinishedEV);
}else if(GBT_StopSource == GBT_STOP_OCPP){
CONN_SetState(Finished);
}else{
CONN_SetState(FinishedEVSE);
}
}
break;
case FinishedEV: // charging completed by EV, waiting to transaction stop
GBT_Lock(0);
CONN_SetState(Finished);
break;
case FinishedEVSE: // charging completed by EVSE, waiting to transaction stop
GBT_Lock(0);
CONN_SetState(Finished);
break;
case Finished: // charging completed, waiting to disconnect, unlocked
GBT_Lock(0);
//TODO Force unlock time limit
if(CONN.connControl == CMD_FORCE_UNLOCK) GBT_ForceLock(0);
if(DELAYED_HOLD_MS(cc6v_hold_tick, CONN_CC_GetState()==GBT_CC_6V, 5000)){
GBT_Lock(0);
CONN_SetState(Unplugged);
}
break;
default:
CONN_SetState(Unknown);
}
}
//external
//CONN_SetState(Disabled);
void CONN_SetState(CONN_State_t state){
connectorState = state;
if(connectorState == Unknown) log_printf(LOG_INFO, "Connector: Unknown\n");
if(connectorState == Unplugged) log_printf(LOG_INFO, "Connector: Unplugged\n");
if(connectorState == Disabled) log_printf(LOG_INFO, "Connector: Disabled\n");
if(connectorState == Preparing) log_printf(LOG_INFO, "Connector: Preparing\n");
if(connectorState == AuthRequired) log_printf(LOG_INFO, "Connector: AuthRequired\n");
if(connectorState == WaitingForEnergy) log_printf(LOG_INFO, "Connector: WaitingForEnergy\n");
if(connectorState == ChargingPausedEV) log_printf(LOG_INFO, "Connector: ChargingPausedEV\n");
if(connectorState == ChargingPausedEVSE) log_printf(LOG_INFO, "Connector: ChargingPausedEVSE\n");
if(connectorState == Charging) log_printf(LOG_INFO, "Connector: Charging\n");
if(connectorState == AuthTimeout) log_printf(LOG_INFO, "Connector: AuthTimeout\n");
if(connectorState == Finished) log_printf(LOG_INFO, "Connector: Finished\n");
if(connectorState == FinishedEVSE) log_printf(LOG_INFO, "Connector: FinishedEVSE\n");
if(connectorState == FinishedEV) log_printf(LOG_INFO, "Connector: FinishedEV\n");
if(connectorState == Replugging) log_printf(LOG_INFO, "Connector: Replugging\n");
CONN.connState = state;
}
void CONN_CC_ReadStateFiltered() {
static uint32_t last_change_time = 0;
static uint32_t last_check_time = 0;
static uint8_t prev_state = 0;
if((HAL_GetTick()-last_check_time)<100) return;
last_check_time = HAL_GetTick();
uint8_t new_state = CONN_CC_GetStateRaw();
if (new_state != prev_state) {
last_change_time = HAL_GetTick();
prev_state = new_state;
} else if ((HAL_GetTick() - last_change_time) >= 300) {
CC_STATE_FILTERED = prev_state;
}
}
uint8_t CONN_CC_GetState(){
return CC_STATE_FILTERED;
}
uint8_t CONN_CC_GetStateRaw(){
float volt = CONN_CC_GetAdc();
// if((volt<12.6f) && (volt>11.4f)) return GBT_CC_12V;
// if((volt<6.8f) && (volt>5.2f)) return GBT_CC_6V;
// if((volt<4.8f) && (volt>3.2f)) return GBT_CC_4V;
// if((volt<2.8f) && (volt>1.2f)) return GBT_CC_2V;
if((volt<13.0f) && (volt>11.0f)) return GBT_CC_12V;
if((volt<7.2f) && (volt>4.8f)) return GBT_CC_6V;
if((volt<4.8f) && (volt>3.0f)) return GBT_CC_4V;
if((volt<3.0f) && (volt>1.0f)) return GBT_CC_2V;
return GBT_CC_UNKNOWN;
}
float CONN_CC_GetAdc(){
//TODO: Filters
//Vref=3.3v = 4095
//k=1/11
//Vin = 12v
//Vin*k= 1.09v
//12vin = 1353 ADC
uint32_t adc;
float volt;
ADC_Select_Channel(ADC_CHANNEL_3);
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, 100);
adc = HAL_ADC_GetValue(&hadc1);
HAL_ADC_Stop(&hadc1);
volt = (float)adc/113.4f;
return volt;
}

115
Core/Src/cp.c Normal file
View File

@@ -0,0 +1,115 @@
#include "cp.h"
#include "adc.h"
#include "board.h"
#include "tim.h"
#include <stdint.h>
#define MAX_DUTY 450
static int32_t cp_voltage_mv = 0;
static uint8_t cp_duty = 0;
CP_State_t fake_cp_state = EV_STATE_ACQUIRING;
static uint32_t CP_ReadAdcChannel(uint32_t ch) {
uint32_t adc = 0;
ADC_Select_Channel(ch);
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, 10);
adc = HAL_ADC_GetValue(&hadc1);
HAL_ADC_Stop(&hadc1);
return adc;
}
#define VREFINT_CAL_ADDR ((uint16_t*)0x1FFFF7BA) // для STM32F1!
static int32_t CP_ReadVoltageMv(void)
{
uint32_t adc = 0;
int32_t v_adc_mv = 0;
int32_t v_out_mv = 0;
adc = CP_ReadAdcChannel((uint32_t)4u);
v_adc_mv = (int32_t)((adc * 3300u) / 4095u);
v_out_mv = ((v_adc_mv - 1723) * 1000) / 130;
return v_out_mv;
}
void CP_Init(void) {
/* TIM3_CH2 (PA7): set 1kHz PWM like original CCS logic. */
htim3.Instance->PSC = 160 - 1;
htim3.Instance->ARR = MAX_DUTY - 1;
#if DUTY_INVERT == 0
htim3.Instance->CCR2 = MAX_DUTY;
htim3.Instance->CCR1 = MAX_DUTY + 5;
#else
htim3.Instance->CCR2 = 0;
htim3.Instance->CCR1 = 0;
#endif
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);
HAL_TIM_OC_Start_IT(&htim3, TIM_CHANNEL_1);
}
void CP_SetDuty(uint8_t percentage) {
uint32_t pwmduty = MAX_DUTY * percentage / 100;
cp_duty = percentage;
#if DUTY_INVERT == 0
htim3.Instance->CCR2 = pwmduty;
htim3.Instance->CCR1 = 0 + 1;
#else
htim3.Instance->CCR2 = MAX_DUTY - pwmduty;
htim3.Instance->CCR1 = MAX_DUTY - pwmduty + 5;
#endif
}
uint8_t CP_GetDuty(void) {
return cp_duty;
}
int32_t CP_GetVoltage(void) {
return cp_voltage_mv;
}
CP_State_t CP_GetState(void) {
int32_t voltage_real = cp_voltage_mv;
if(fake_cp_state != EV_STATE_ACQUIRING) {
return fake_cp_state;
}
if (voltage_real >= (12000-1000)) {
return EV_STATE_A_IDLE;
} else if (voltage_real >= (9000-1000) && voltage_real <= (9000+1000)) {
return EV_STATE_B_CONN_PREP;
} else if (voltage_real >= (6000-1000) && voltage_real <= (6000+1000)) {
return EV_STATE_C_CONN_ACTIVE;
} else if (voltage_real >= (3000-1000) && voltage_real <= (3000 + 1000)) {
return EV_STATE_D_CONN_ACT_VENT;
} else if (voltage_real >= (0-1000) && voltage_real <= (0+2000)){
return EV_STATE_E_NO_POWER;
} else if (voltage_real <= (-12000+1000)) {
return EV_STATE_F_ERROR;
} else {
return EV_STATE_ACQUIRING;
}
}
void CP_Loop(void) {
(void)CP_GetState();
}
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM3 && htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) {
if (ADC_TryLock() == 0u) {
return;
}
cp_voltage_mv = CP_ReadVoltageMv();
ADC_Unlock();
}
}

View File

@@ -12,7 +12,6 @@
#include <stdarg.h>
#include "debug.h"
#include "board.h"
#include "charger_gbt.h"
#include "usart.h"
#include <time.h>
#include <connector.h>

View File

@@ -1,120 +0,0 @@
/*
* gbt_packet.c
*
* Created on: Jul 23, 2024
* Author: colorbass
*/
// GB/T Time Synchronization Packet
#include "main.h"
#include "soft_rtc.h"
#include "charger_gbt.h"
void GBT_SendCTS(){
uint8_t data[7];
unix_to_bcd(get_Current_Time(), data);
// data[0] = 0x00; //seconds
// data[1] = 0x30; //minutes
// data[2] = 0x23; //hours
// data[3] = 0x05; //days
// data[4] = 0x05; //month
// data[5] = 0x24; //years
// data[6] = 0x20; //centuries
J_SendPacket(0x000700, 6, 7, data);
}
//GB/T Max Load Packet
void GBT_SendCML(){
// uint8_t data[8];
// data[0] = 0x94; //450V max output voltage
// data[1] = 0x11; //
// data[2] = 0xB0; //120V min output voltage
// data[3] = 0x04; //
// data[4] = 0xC4; //-150A maximum output current
// data[5] = 0x09; //
// data[6] = 0x8C; //-2A minimum output current
// data[7] = 0x0F; //
J_SendPacket(0x000800, 6, 8, (uint8_t*)&GBT_MaxLoad);
}
//GB/T Version packet
void GBT_SendCHM(){
uint8_t data[3];
data[0] = 0x01;
data[1] = 0x01;
data[2] = 0x00;
J_SendPacket(0x2600, 6, 3, data);
}
//GB/T CRM Packet (state=BMS identified)
void GBT_SendCRM(uint8_t state){
// uint8_t data[8];
// data[0] = state; // 0x00 / 0xAA
// data[1] = 0x40; //TODO: Charger Number 123456
// data[2] = 0xE2;
// data[3] = 0x01;
// data[4] = 0x00;
// data[5] = 0x42; //TODO: location BFG
// data[6] = 0x46;
// data[7] = 0x47;
GBT_ChargerInfo.bmsIdentified = state;
J_SendPacket(0x100, 6, 8, (uint8_t *)&GBT_ChargerInfo);
}
//GB/T CRO packet (Charger ready)
void GBT_SendCRO(uint8_t state){
uint8_t data[1];
data[0] = state;
J_SendPacket(0xA00, 4, 1, data);
}
//GB/T CCS packet (Charger current status)
void GBT_SendCCS(){
// uint8_t data[8];
// data[0] = GBT_CurrPower.requestedVoltage; //
// data[1] = GBT_CurrPower.requestedVoltage>>8; //output voltage
// data[2] = GBT_CurrPower.requestedCurrent; //смещение 400а, границы
// //-400A = 0
// // 0A = 4000
// // -100A = 3000
// data[3] = GBT_CurrPower.requestedCurrent>>8; //TODO: current
// data[4] = GBT_StateTick()/60000; //charging time (min)
// data[5] = 0; //TODO: 255 min+
// data[6] = 0b11111101; //charging not permitted
// data[7] = 0xFF;
J_SendPacket(0x1200, 6, 8, (uint8_t *)&GBT_ChargerCurrentStatus);
}
// GB/T Charging Stop packet
void GBT_SendCST(uint32_t Cause){
uint8_t data[8];
data[0] = (Cause>>24) & 0xFF; // Error
data[1] = (Cause>>16) & 0xFF; //
data[2] = (Cause>>8) & 0xFF; //
data[3] = Cause & 0xFF; //
J_SendPacket(0x1A00, 4, 4, data);
}
void GBT_SendCSD(){
GBT_ChargerStop.chargerNumber = GBT_ChargerInfo.chargerNumber;
GBT_ChargerStop.outputEnergy = 0; //TODO Energy meters
GBT_ChargerStop.chargingTime = GBT_ChargerCurrentStatus.chargingTime;
J_SendPacket(0x1D00, 6, 7, (uint8_t *)&GBT_ChargerStop);
}
void GBT_SendCEM(uint32_t ErrorCode){
uint8_t data[8];
data[0] = (ErrorCode>>24) & 0xFF; // Error
data[1] = (ErrorCode>>16) & 0xFF; //
data[2] = (ErrorCode>>8) & 0xFF; //
data[3] = ErrorCode & 0xFF; //
J_SendPacket(0x1F00, 4, 4, data);
}

View File

@@ -54,7 +54,7 @@ void MX_GPIO_Init(void)
__HAL_RCC_GPIOD_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC, LOCK_A_Pin|LOCK_B_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOC, RELAY_CP_Pin|LOCK_A_Pin|LOCK_B_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOE, RELAY1_Pin|RELAY2_Pin|RELAY3_Pin|RELAY4_Pin
@@ -69,6 +69,13 @@ void MX_GPIO_Init(void)
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(EE_WP_GPIO_Port, EE_WP_Pin, GPIO_PIN_RESET);
/*Configure GPIO pins : RELAY_CP_Pin LOCK_A_Pin LOCK_B_Pin */
GPIO_InitStruct.Pin = RELAY_CP_Pin|LOCK_A_Pin|LOCK_B_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pin : IN_SW0_Pin */
GPIO_InitStruct.Pin = IN_SW0_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
@@ -81,13 +88,6 @@ void MX_GPIO_Init(void)
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
HAL_GPIO_Init(IN_SW1_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : LOCK_A_Pin LOCK_B_Pin */
GPIO_InitStruct.Pin = LOCK_A_Pin|LOCK_B_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pins : IN0_Pin AC_OK_Pin ISO_IN_Pin */
GPIO_InitStruct.Pin = IN0_Pin|AC_OK_Pin|ISO_IN_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;

View File

@@ -1,197 +0,0 @@
/*
* j1939.c
*
* Created on: May 3, 2024
* Author: colorbass
*/
#include "main.h"
#include "j1939.h"
#include "charger_gbt.h"
#include "string.h"
#include "can.h"
#include "debug.h"
extern GBT_BCL_t GBT_ReqPower;
extern GBT_BCL_t GBT_CurrPower;
j_receive_t j_rx;
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
CAN_RxHeaderTypeDef RxHeader;
uint8_t RxData[8] = {0,};
if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RxData) == HAL_OK)
{
if((RxHeader.ExtId & 0x00FFFF) == ((J_ID_SE << 8) | J_ID_EV)){ // SA, DA match
switch ((RxHeader.ExtId>>8) & 0x00FF00){
case 0xEC00: //PGN Connection Management Message
if(RxData[0] == 16){ //Request to Send
/* Set the RTS values */
j_rx.size = RxData[1] | (RxData[2]<<8);
j_rx.packet = 1;
j_rx.packets = RxData[3];
j_rx.step = 2; //TODO
j_rx.step_cts_remain = j_rx.step;
j_rx.PGN = (RxData[7] << 16) | (RxData[6] << 8) | RxData[5];
if(j_rx.size<256) { //TODO: valid check
J_SendCTS(j_rx);
j_rx.state = 1;
}
}
if(RxData[0] == 255){ //Connection Abort
j_rx.state = 0;
}
//if(RxData[0] == 32){}//Broadcast Announce Message
/*
* 1CEC56F4 10 31 00 07 07 00 02 00
* 1CECF456 11 02 01 FF FF 00 02 00
* 1CEB56F4 01 01 01 00 03 46 05 40
* 1CEC56F4 FF FF FF FF FF 00 00 00
*/
break;
case 0xEB00: //PGN Data Message
if(j_rx.state != 1) break;
if((RxData[0]>0) && (RxData[0]<35)){ //Array limit check
if(j_rx.packet == RxData[0]){ //step check
memcpy (&j_rx.data[(RxData[0]-1)*7], &RxData[1],7);
j_rx.packet++;
if(j_rx.packet > j_rx.packets){
//End of transmission
J_SendACK(j_rx);
j_rx.state = 2;
}else{
if(j_rx.step_cts_remain > 0) j_rx.step_cts_remain--;
if(j_rx.step_cts_remain == 0){
J_SendCTS(j_rx);
j_rx.step_cts_remain = 2;
}
}
}
}
break;
case 0x1E00: //PGN BEM (ERROR)
//Error force stop
// --> Suspend EV
log_printf(LOG_ERR, "BEM Received, force stopping...\n");
log_printf(LOG_ERR, "BEM: %02X %02X %02X %02X", RxData[0], RxData[1], RxData[2], RxData[3]);
log_printf(LOG_ERR, " %02X %02X %02X %02X\n", RxData[4], RxData[5], RxData[6], RxData[7]);
GBT_ForceStop();
break;
case 0x1900: //PGN BST (STOP)
//Normal stop
// --> Suspend EV
log_printf(LOG_INFO, "BST Received, stopping...\n");
log_printf(LOG_INFO, "BST: %02X %02X %02X %02X", RxData[0], RxData[1], RxData[2], RxData[3]);
log_printf(LOG_INFO, " %02X %02X %02X %02X\n", RxData[4], RxData[5], RxData[6], RxData[7]);
GBT_StopEV(GBT_CST_BMS_ACTIVELY_SUSPENDS);
break;
default:
if(j_rx.state == 0){//TODO protections
//Short packet
j_rx.size = RxHeader.DLC;
j_rx.packet = 1;
j_rx.packets = 1;
j_rx.step = 1;
j_rx.step_cts_remain = 0;
j_rx.PGN = (RxHeader.ExtId>>8) & 0x00FF00;
j_rx.state = 2;
memcpy (j_rx.data, RxData, j_rx.size);
}
}
}
}
}
void GBT_CAN_ReInit(){
HAL_CAN_Stop(&hcan1);
MX_CAN1_Init();
GBT_CAN_FilterInit();
HAL_CAN_Start(&hcan1);
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);
}
void J_SendPacket(uint32_t PGN, uint8_t pri, uint8_t DLC, uint8_t *data){
CAN_TxHeaderTypeDef tx_header;
uint32_t tx_mailbox;
tx_header.ExtId = (pri << 26) | (PGN << 8) | (J_ID_EV << 8) | J_ID_SE;
tx_header.RTR = CAN_RTR_DATA;
tx_header.IDE = CAN_ID_EXT;
tx_header.DLC = DLC;
//TODO buffer wait
HAL_CAN_AddTxMessage(&hcan1, &tx_header, data, &tx_mailbox);
//HAL_Delay(2);
}
//void J_SendPacketLong(){
// //TODO (no need)
//}
// J1939 sequence Clear To Send packet
void J_SendCTS(j_receive_t rx){
//if(rx.packets <= rx.packet) return; TODO
uint8_t data[8];
data[0] = 17; //CONTROL_BYTE_TP_CM_CTS
data[1] = rx.step;//total_number_of_packages_transmitted
if (rx.step > (rx.packets - rx.packet+1)) data[1] = rx.packets - rx.packet+1;
data[2] = rx.packet;//next_packet_number_transmitted
data[3] = 0xFF; /* Reserved */
data[4] = 0xFF;
data[5] = rx.PGN;
data[6] = rx.PGN >> 8;
data[7] = rx.PGN >> 16;
J_SendPacket(0x00EC00, 7, 8, data);
}
// J1939 sequence ACK packet
void J_SendACK(j_receive_t rx){//uint32_t PGN, uint8_t step, uint8_t packet){
uint8_t data[8];
data[0] = 19; //CONTROL_BYTE_TP_CM_ACK
data[1] = j_rx.size;
data[2] = j_rx.size>>8;
data[3] = j_rx.packets;
data[4] = 0xFF;//TODO
data[5] = rx.PGN;
data[6] = rx.PGN >> 8;
data[7] = rx.PGN >> 16;
J_SendPacket(0x00EC00, 7, 8, data);
}
void GBT_CAN_FilterInit(){
CAN_FilterTypeDef sFilterConfig;
sFilterConfig.FilterBank = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
sFilterConfig.FilterActivation = ENABLE;
//sFilterConfig.SlaveStartFilterBank = 14;
if(HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
}

View File

@@ -1,169 +0,0 @@
/*
* lock.c
*
* Created on: Jul 31, 2024
* Author: colorbass
*/
#include "lock.h"
#include "debug.h"
uint8_t LOCK_POLARITY = 1; // 1 for v1
uint8_t LOCK_MOTOR_POLARITY = 1;
uint16_t LOCK_DELAY = 100;
GBT_LockState_t GBT_LockState = {
.demand = 0,
.error = 0,
.action_requested = 255, // нет запрошенного действия
.motor_state = 0, // idle
.last_action_time = 0,
.retry_count = 0,
.error_tick = 0
};
void GBT_ForceLock(uint8_t state){
// Устанавливаем флаг для выполнения действия
GBT_LockState.action_requested = state ? 1 : 0;
GBT_LockState.retry_count = 0;
}
uint8_t GBT_LockGetState(){
//1 = locked
//0 = unlocked
if(LOCK_POLARITY){
return HAL_GPIO_ReadPin(IN0_GPIO_Port, IN0_Pin);
}else{
return !HAL_GPIO_ReadPin(IN0_GPIO_Port, IN0_Pin);
}
}
void GBT_Lock(uint8_t state){
GBT_LockState.demand = state;
}
void GBT_ManageLockSolenoid(){
static uint32_t tick;
if(HAL_GetTick() - tick < 50) return;
tick = HAL_GetTick();
HAL_GPIO_WritePin(LOCK_B_GPIO_Port, LOCK_B_Pin, GBT_LockState.demand ? 1 : 0);
}
void GBT_ManageLockMotor(){
static const uint8_t MAX_RETRIES = 5;
uint32_t current_tick = HAL_GetTick();
// Проверяем таймаут сброса ошибки (до проверки error, чтобы можно было сбросить)
GBT_ResetErrorTimeout();
if (GBT_LockState.error) {
return;
}
// Проверяем, нужно ли выполнить действие
bool lock_is_open = GBT_LockGetState() == 0;
bool lock_should_be_open = GBT_LockState.demand == 0;
// Если есть запрошенное действие или состояние не соответствует требуемому
if (GBT_LockState.action_requested != 255 || (lock_is_open != lock_should_be_open)) {
// Если действие еще не запрошено, запрашиваем его
if (GBT_LockState.action_requested == 255) {
GBT_LockState.action_requested = lock_should_be_open ? 0 : 1;
GBT_LockState.retry_count = 0;
}
// Управление мотором через машину состояний
switch (GBT_LockState.motor_state) {
case 0: // idle - мотор выключен
// Определяем, какой пин нужно включить
if (LOCK_MOTOR_POLARITY) {
if (GBT_LockState.action_requested == 1) { // LOCK
HAL_GPIO_WritePin(LOCK_B_GPIO_Port, LOCK_B_Pin, 1);
} else { // UNLOCK
HAL_GPIO_WritePin(LOCK_A_GPIO_Port, LOCK_A_Pin, 1);
}
} else {
if (GBT_LockState.action_requested == 1) { // LOCK
HAL_GPIO_WritePin(LOCK_A_GPIO_Port, LOCK_A_Pin, 1);
} else { // UNLOCK
HAL_GPIO_WritePin(LOCK_B_GPIO_Port, LOCK_B_Pin, 1);
}
}
GBT_LockState.motor_state = 1; // motor_on
GBT_LockState.last_action_time = current_tick;
break;
case 1: // motor_on - мотор включен, ждем LOCK_DELAY
if (current_tick - GBT_LockState.last_action_time >= LOCK_DELAY) {
// Выключаем оба пина
HAL_GPIO_WritePin(LOCK_A_GPIO_Port, LOCK_A_Pin, 0);
HAL_GPIO_WritePin(LOCK_B_GPIO_Port, LOCK_B_Pin, 0);
GBT_LockState.motor_state = 2; // waiting_off
GBT_LockState.last_action_time = current_tick;
}
break;
case 2: // waiting_off - ждем немного перед проверкой состояния
// Небольшая задержка перед проверкой состояния (например, 50мс)
if (current_tick - GBT_LockState.last_action_time >= 50) {
// Проверяем, достигнуто ли требуемое состояние
lock_is_open = GBT_LockGetState() == 0;
bool action_success = (lock_is_open == (GBT_LockState.action_requested == 0));
if (action_success) {
// Действие выполнено успешно
GBT_LockState.action_requested = 255; // сбрасываем флаг
GBT_LockState.motor_state = 0; // idle
GBT_LockState.retry_count = 0;
} else {
// Действие не выполнено, повторяем попытку
GBT_LockState.retry_count++;
if (GBT_LockState.retry_count >= MAX_RETRIES) {
// Превышено количество попыток
GBT_LockState.error = 1;
GBT_LockState.error_tick = current_tick; // сохраняем время установки ошибки
GBT_LockState.action_requested = 0; // пытаемся разблокировать
GBT_LockState.motor_state = 0;
GBT_LockState.retry_count = 0;
log_printf(LOG_ERR, "Lock error\n");
} else {
// Повторяем попытку
GBT_LockState.motor_state = 0; // возвращаемся к началу
}
}
}
break;
}
} else {
// Состояние соответствует требуемому, сбрасываем флаги
if (GBT_LockState.motor_state != 0) {
HAL_GPIO_WritePin(LOCK_A_GPIO_Port, LOCK_A_Pin, 0);
HAL_GPIO_WritePin(LOCK_B_GPIO_Port, LOCK_B_Pin, 0);
GBT_LockState.motor_state = 0;
}
GBT_LockState.action_requested = 255;
GBT_LockState.retry_count = 0;
}
}
void GBT_LockResetError(){
GBT_LockState.error = 0;
GBT_LockState.error_tick = 0;
log_printf(LOG_INFO, "Lock error reset\n");
}
void GBT_ResetErrorTimeout(){
static const uint32_t ERROR_TIMEOUT_MS = 300000; // 5 минут
if (GBT_LockState.error && GBT_LockState.error_tick != 0) {
if ((HAL_GetTick()-GBT_LockState.error_tick) >= ERROR_TIMEOUT_MS) {
// Прошло 5 минут, сбрасываем ошибку
GBT_LockResetError();
}
}
}

View File

@@ -1,295 +1,301 @@
/* USER CODE BEGIN Header */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "can.h"
#include "crc.h"
#include "rtc.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "can.h"
#include "board.h"
#include <stdio.h>
#include "debug.h"
#include "charger_gbt.h"
#include "soft_rtc.h"
#include "j1939.h"
#include "lock.h"
#include "connector.h"
#include "serial_control.h"
#include "charger_config.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/**
* @brief Vector base address configuration. It should no longer be at the start of
* flash memory but moved forward because the first part of flash is
* reserved for the bootloader. Note that this is already done by the
* bootloader before starting this program. Unfortunately, function
* SystemInit() overwrites this change again.
* @return none.
*/
static void VectorBase_Config(void)
{
/* The constant array with vectors of the vector table is declared externally in the
* c-startup code.
*/
extern const unsigned long g_pfnVectors[];
/* Remap the vector table to where the vector table is located for this program. */
SCB->VTOR = (unsigned long)&g_pfnVectors[0];
}
uint8_t ED_TraceWarning(uint8_t flag, uint8_t id){
static uint8_t memory[32];
if(id > 31) return 0;
uint8_t result = 0;
if(memory[id] != flag){
result = 1;
}
memory[id] = flag;
return result;
}
void ED_Delay(uint32_t Delay)
{
uint32_t tickstart = HAL_GetTick();
uint32_t wait = Delay;
/* Add a freq to guarantee minimum wait */
if (wait < HAL_MAX_DELAY)
{
wait += (uint32_t)(uwTickFreq);
}
while ((HAL_GetTick() - tickstart) < wait){
CONN_CC_ReadStateFiltered();
GBT_ManageLockMotor();
CONN_Task();
GBT_ChargerTask();
LED_Task();
SC_Task();
// if(huart2.gState != HAL_UART_STATE_BUSY_TX) debug_buffer_send(); // TEST
}
}
void StopButtonControl(){
//Charging do nothing
if(!IN_ReadInput(IN_ESTOP)){
CONN.connControl = CMD_STOP;
}
}
uint8_t temp0, temp1;
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
VectorBase_Config();
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
HAL_RCC_DeInit();
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_ADC1_Init();
MX_CAN1_Init();
MX_CAN2_Init();
MX_RTC_Init();
MX_TIM4_Init();
MX_USART2_UART_Init();
MX_CRC_Init();
MX_UART5_Init();
MX_USART1_UART_Init();
MX_USART3_UART_Init();
/* USER CODE BEGIN 2 */
Init_Peripheral();
LED_Init();
HAL_Delay(300);
GBT_Init();
SC_Init();
log_printf(LOG_INFO, "GBT Charger v%d.%d\n", GBT_CH_VER_MAJOR, GBT_CH_VER_MINOR);
ReadVersion();
log_printf(LOG_INFO, "Serial number: %d\n", infoPacket.serialNumber);
log_printf(LOG_INFO, "Board revision: %d\n", infoPacket.boardVersion);
log_printf(LOG_INFO, "FW version: %d.%d.%d\n", infoPacket.fw_version_major, infoPacket.fw_version_minor, infoPacket.fw_version_patch);
GBT_SetConfig();
GBT_CAN_ReInit();
PSU_Init();
CONN_Init();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
PSU_ReadWrite();
PSU_Task();
ED_Delay(10);
METER_CalculateEnergy();
CONN_Loop();
LED_Write();
ED_Delay(10);
StopButtonControl();
ED_Delay(50);
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE|RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV5;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.Prediv1Source = RCC_PREDIV1_SOURCE_PLL2;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
RCC_OscInitStruct.PLL2.PLL2State = RCC_PLL2_ON;
RCC_OscInitStruct.PLL2.PLL2MUL = RCC_PLL2_MUL8;
RCC_OscInitStruct.PLL2.HSEPrediv2Value = RCC_HSE_PREDIV2_DIV5;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_ADC;
PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
/** Configure the Systick interrupt time
*/
__HAL_RCC_PLLI2S_ENABLE();
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
/* USER CODE BEGIN Header */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "can.h"
#include "crc.h"
#include "rtc.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "can.h"
#include "board.h"
#include <stdio.h>
#include "debug.h"
#include "soft_rtc.h"
#include "connector.h"
#include "serial_control.h"
#include "charger_config.h"
#include "serial.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/**
* @brief Vector base address configuration. It should no longer be at the start of
* flash memory but moved forward because the first part of flash is
* reserved for the bootloader. Note that this is already done by the
* bootloader before starting this program. Unfortunately, function
* SystemInit() overwrites this change again.
* @return none.
*/
static void VectorBase_Config(void)
{
/* The constant array with vectors of the vector table is declared externally in the
* c-startup code.
*/
extern const unsigned long g_pfnVectors[];
/* Remap the vector table to where the vector table is located for this program. */
SCB->VTOR = (unsigned long)&g_pfnVectors[0];
}
uint8_t ED_TraceWarning(uint8_t flag, uint8_t id){
static uint8_t memory[32];
if(id > 31) return 0;
uint8_t result = 0;
if(memory[id] != flag){
result = 1;
}
memory[id] = flag;
return result;
}
void ED_Delay(uint32_t Delay)
{
uint32_t tickstart = HAL_GetTick();
uint32_t wait = Delay;
if (wait < HAL_MAX_DELAY)
{
wait += (uint32_t)(uwTickFreq);
}
while ((HAL_GetTick() - tickstart) < wait){
CCS_SerialLoop();
// CP_Loop();
CONN_Task();
LED_Task();
SC_Task();
}
}
void StopButtonControl(){
//Charging do nothing
if(!IN_ReadInput(IN_ESTOP)){
CONN.connControl = CMD_STOP;
}
}
uint8_t temp0, temp1;
static void CAN1_MinimalReInit(void)
{
HAL_CAN_Stop(&hcan1);
MX_CAN1_Init();
if (HAL_CAN_Start(&hcan1) != HAL_OK) {
Error_Handler();
}
if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK) {
Error_Handler();
}
}
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
VectorBase_Config();
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
HAL_RCC_DeInit();
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_ADC1_Init();
MX_CAN1_Init();
MX_CAN2_Init();
MX_RTC_Init();
MX_TIM4_Init();
MX_USART2_UART_Init();
MX_CRC_Init();
MX_UART5_Init();
MX_USART1_UART_Init();
MX_USART3_UART_Init();
MX_TIM3_Init();
/* USER CODE BEGIN 2 */
Init_Peripheral();
LED_Init();
HAL_Delay(300);
CCS_Init();
SC_Init();
log_printf(LOG_INFO, "CCS module start\n");
ReadVersion();
log_printf(LOG_INFO, "Serial number: %d\n", infoPacket.serialNumber);
log_printf(LOG_INFO, "Board revision: %d\n", infoPacket.boardVersion);
log_printf(LOG_INFO, "FW version: %d.%d.%d\n", infoPacket.fw_version_major, infoPacket.fw_version_minor, infoPacket.fw_version_patch);
CAN1_MinimalReInit();
PSU_Init();
CONN_Init();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
PSU_ReadWrite();
PSU_Task();
ED_Delay(10);
METER_CalculateEnergy();
CONN_Loop();
LED_Write();
ED_Delay(10);
StopButtonControl();
ED_Delay(50);
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE|RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV5;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.Prediv1Source = RCC_PREDIV1_SOURCE_PLL2;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
RCC_OscInitStruct.PLL2.PLL2State = RCC_PLL2_ON;
RCC_OscInitStruct.PLL2.PLL2MUL = RCC_PLL2_MUL8;
RCC_OscInitStruct.PLL2.HSEPrediv2Value = RCC_HSE_PREDIV2_DIV5;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_ADC;
PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
/** Configure the Systick interrupt time
*/
__HAL_RCC_PLLI2S_ENABLE();
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

View File

@@ -6,7 +6,6 @@
#include "stdio.h"
#include "charger_config.h"
#include "charger_control.h"
#include "charger_gbt.h"
#include "board.h"
#include "debug.h"

427
Core/Src/serial.c Normal file
View File

@@ -0,0 +1,427 @@
#include "serial.h"
#include "cp.h"
#include "connector.h"
#include "board.h"
#include "debug.h"
#include <stdint.h>
#include <string.h>
#include "charger_config.h"
#include "psu_control.h"
extern UART_HandleTypeDef huart3;
static void send_state(void);
static void CCS_SendResetReason(void);
CCS_MaxLoad_t CCS_MaxLoad;
uint32_t CCS_Power = 0;
uint32_t CCS_EnergyWs = 0;
uint32_t CCS_Energy = 0;
uint32_t last_cmd_sent = 0;
uint32_t last_stop_sent = 0;
CONN_Control_t last_cmd = CMD_NONE;
uint8_t ev_enable_output = 0;
#define CMD_INTERVAL 10
#define MAX_TX_BUFFER_SIZE 256
#define MAX_RX_BUFFER_SIZE 256
static uint8_t rx_buffer[MAX_RX_BUFFER_SIZE];
static uint8_t tx_buffer[MAX_TX_BUFFER_SIZE];
static uint8_t rx_armed = 0;
uint8_t ESTOP = 0;
uint8_t REPLUG = 0;
static uint8_t enabled = 0;
static uint8_t pwm_duty_percent = 100;
uint8_t isolation_enable = 0;
static uint32_t last_host_seen = 0;
static CP_State_t cp_state_buffer = EV_STATE_ACQUIRING;
CCS_State_t CCS_State;
CCS_EvInfo_t CCS_EvInfo;
CONN_State_t CCS_EvseState;
CCS_ConnectorState_t CCS_ConnectorState = CCS_UNPLUGGED;
static uint8_t process_received_packet(const uint8_t* packet, uint16_t packet_len);
void CCS_RxEventCallback(UART_HandleTypeDef *huart, uint16_t size) {
if (huart != &huart3) {
return;
}
rx_armed = 0;
if (size > 0 && size <= sizeof(rx_buffer)) {
process_received_packet(rx_buffer, size);
}
}
void CCS_SerialLoop(void) {
static uint32_t replug_tick = 0;
static uint32_t replug_watchdog_tick = 0;
static uint32_t replug_watchdog1_tick = 0;
static uint32_t last_state_sent = 0;
if (!rx_armed && HAL_UART_GetState(&huart3) == HAL_UART_STATE_READY) {
if (HAL_UARTEx_ReceiveToIdle_IT(&huart3, rx_buffer, sizeof(rx_buffer)) == HAL_OK) {
rx_armed = 1;
}
}
/* Read CP once per loop and use buffered value below. */
cp_state_buffer = CP_GetState();
if (CONN.connControl != CMD_NONE) {
last_cmd = CONN.connControl;
}
if((HAL_GetTick() - last_cmd_sent) > CMD_INTERVAL){
if ((HAL_GetTick() - last_state_sent) >= 200) {
send_state();
last_state_sent = HAL_GetTick();
}
if (ESTOP) {
log_printf(LOG_ERR, "ESTOP triggered\n");
CCS_SendEmergencyStop();
ESTOP = 0;
}
if (((CONN.connControl == CMD_STOP) ||
(CONN.chargingError != CONN_NO_ERROR)) &&
((HAL_GetTick() - last_stop_sent) > 1000)) {
last_stop_sent = HAL_GetTick();
log_printf(LOG_WARN, "Stopping charging...\n");
CCS_SendEmergencyStop();
}
if (((CCS_EvseState == FinishedEV) || (CCS_EvseState == FinishedEVSE)) &&
((HAL_GetTick() - last_stop_sent) > 1000)) {
last_stop_sent = HAL_GetTick();
log_printf(LOG_WARN, "FinishedEV, stopping...\n");
CCS_SendEmergencyStop();
}
}
(void)replug_watchdog_tick;
(void)replug_watchdog1_tick;
switch(CCS_ConnectorState){
case CCS_DISABLED:
RELAY_Write(RELAY_CP, 0);
CONN_SetState(Disabled);
if (CONN.chargingError == CONN_NO_ERROR){
CCS_ConnectorState = CCS_UNPLUGGED;
}
break;
case CCS_UNPLUGGED:
RELAY_Write(RELAY_CP, 1);
CONN_SetState(Unplugged);
if ((cp_state_buffer == EV_STATE_B_CONN_PREP) || (cp_state_buffer == EV_STATE_C_CONN_ACTIVE)){
CCS_ConnectorState = CCS_AUTH_REQUIRED;
}
if (CONN.chargingError != CONN_NO_ERROR){
log_printf(LOG_ERR, "Charging error %d, state -> disabled\n", CONN.chargingError);
CCS_ConnectorState = CCS_DISABLED;
}
break;
case CCS_AUTH_REQUIRED:
RELAY_Write(RELAY_CP, 1);
CONN_SetState(AuthRequired);
if(CONN.connControl == CMD_START){
log_printf(LOG_INFO, "Charging permitted, start charging\n");
CCS_ConnectorState = CCS_CONNECTED;
}
if (cp_state_buffer == EV_STATE_A_IDLE){
log_printf(LOG_INFO, "Car unplugged\n");
CCS_ConnectorState = CCS_UNPLUGGED;
}
break;
case CCS_CONNECTED:
RELAY_Write(RELAY_CP, 1);
if(CCS_EvseState < Preparing) {
CONN_SetState(Preparing);
} else {
CONN_SetState(CCS_EvseState);
}
if (cp_state_buffer == EV_STATE_A_IDLE){
log_printf(LOG_INFO, "Car unplugged\n");
CCS_ConnectorState = CCS_UNPLUGGED;
}
if(REPLUG > 0){
log_printf(LOG_INFO, "Replugging...\n");
CCS_ConnectorState = CCS_REPLUGGING;
}
break;
case CCS_REPLUGGING:
RELAY_Write(RELAY_CP, 0);
CONN_SetState(Replugging);
if((HAL_GetTick() - replug_tick) > 1000){
replug_tick = HAL_GetTick();
if(REPLUG > 0){
if (REPLUG != 0xFF) REPLUG--;
} else {
log_printf(LOG_INFO, "Replugging finished, but car unplugged\n");
CCS_ConnectorState = CCS_UNPLUGGED;
}
}
if(REPLUG == 0){
if(cp_state_buffer == EV_STATE_B_CONN_PREP){
log_printf(LOG_INFO, "Replugging finished, car plugged, state -> auth required\n");
CCS_ConnectorState = CCS_AUTH_REQUIRED;
}
}
break;
}
if (last_host_seen > 0 && (HAL_GetTick() - last_host_seen) > 500) {
CONN.EnableOutput = 0;
CCS_EvseState = Unknown;
CP_SetDuty(100);
log_printf(LOG_ERR, "Everest timeout\n");
} else {
if (last_cmd == CMD_STOP) {
CONN.EnableOutput = 0;
} else {
CONN.EnableOutput = ev_enable_output ? 1 : 0;
if((CONN.EnableOutput == 0) && (CONN.connState == Preparing)){
CONN.EnableOutput = 0;
}
}
}
if ((cp_state_buffer == EV_STATE_B_CONN_PREP) ||
(cp_state_buffer == EV_STATE_C_CONN_ACTIVE) ||
(cp_state_buffer == EV_STATE_D_CONN_ACT_VENT)) {
CONN.EvConnected = 1;
} else {
CONN.EvConnected = 0;
}
}
void CCS_Init(void){
CP_Init();
CP_SetDuty(100);
CCS_MaxLoad.maxVoltage = PSU_MAX_VOLTAGE; // 1000V
CCS_MaxLoad.minVoltage = PSU_MIN_VOLTAGE; //150V
CCS_MaxLoad.maxCurrent = PSU_MAX_CURRENT*10; //100A
CCS_MaxLoad.minCurrent = PSU_MIN_CURRENT*10; //1A
CCS_MaxLoad.maxPower = PSU_MAX_POWER; //30000W
CCS_SendResetReason();
log_printf(LOG_INFO, "CCS init\n");
}
static uint16_t crc16_ibm(const uint8_t* data, uint16_t length) {
uint16_t crc = 0xFFFFu;
for (uint16_t i = 0; i < length; i++) {
crc ^= data[i];
for (uint8_t j = 0; j < 8; j++) {
if (crc & 1u) {
crc = (crc >> 1) ^ 0xA001u;
} else {
crc >>= 1;
}
}
}
return crc;
}
static uint16_t CCS_BuildPacket(uint8_t cmd, const void* payload, uint16_t payload_len, uint8_t* out, uint16_t out_max) {
uint16_t total_len = (uint16_t)(1u + payload_len + 2u);
if (total_len > out_max) return 0;
out[0] = cmd;
if (payload_len && payload != NULL) {
memcpy(&out[1], payload, payload_len);
}
uint16_t crc = crc16_ibm(out, (uint16_t)(1u + payload_len));
out[1u + payload_len] = (uint8_t)(crc & 0xFFu);
out[1u + payload_len + 1u] = (uint8_t)((crc >> 8) & 0xFFu);
return total_len;
}
static void CCS_SendPacket(uint8_t cmd, const void* payload, uint16_t payload_len) {
uint16_t len = CCS_BuildPacket(cmd, payload, payload_len, tx_buffer, sizeof(tx_buffer));
if (len > 0) {
HAL_UART_Transmit(&huart3, tx_buffer, len, 1000);
}
last_cmd_sent = HAL_GetTick();
}
static void CCS_SendResetReason(void) {
CCS_SendPacket(CMD_M2E_RESET, NULL, 0);
}
void CCS_SendEmergencyStop(void) {
CCS_SendPacket(CMD_M2E_ESTOP, NULL, 0);
}
void CCS_SendStart(void) {
CCS_SendPacket(CMD_M2E_START, NULL, 0);
}
static void CCS_CalculateEnergy(void) {
static uint32_t lastTick = 0;
uint32_t currentTick = HAL_GetTick();
uint32_t elapsedTimeMs = currentTick - lastTick;
lastTick = currentTick;
CCS_Power = CONN.MeasuredVoltage * CONN.MeasuredCurrent / 10;
CCS_EnergyWs += (CCS_Power * elapsedTimeMs) / 1000;
if(CCS_EvseState == Unplugged) {
CCS_EnergyWs = 0;
}
CCS_Energy = CCS_EnergyWs / 3600;
}
static void send_state(void) {
CCS_CalculateEnergy();
CCS_State.DutyCycle = CP_GetDuty();
CCS_State.OutputEnabled = PSU0.CONT_enabled;
CCS_State.MeasuredVoltage = (uint16_t)CONN.MeasuredVoltage;
CCS_State.MeasuredCurrent = (uint16_t)CONN.MeasuredCurrent;
CCS_State.Power = CCS_Power;
CCS_State.Energy = CCS_Energy;
if(CCS_ConnectorState == CCS_CONNECTED){
CCS_State.CpState = cp_state_buffer;
} else {
CCS_State.CpState = EV_STATE_A_IDLE;
}
CCS_State.MaxVoltage = CCS_MaxLoad.maxVoltage;
CCS_State.MinVoltage = CCS_MaxLoad.minVoltage;
CCS_State.MaxCurrent = CCS_MaxLoad.maxCurrent;
CCS_State.MinCurrent = CCS_MaxLoad.minCurrent;
CCS_State.MaxPower = CCS_MaxLoad.maxPower;
CCS_State.IsolationValid = isolation_enable;
CCS_State.IsolationResistance = 900000;
CCS_SendPacket(CMD_M2E_STATE, &CCS_State, sizeof(CCS_State));
}
static uint16_t expected_payload_len(uint8_t cmd) {
switch (cmd) {
case CMD_E2M_PWM_DUTY: return sizeof(e2m_pwm_duty_t);
case CMD_E2M_ENABLE_OUTPUT: return sizeof(e2m_enable_output_t);
case CMD_E2M_RESET: return sizeof(e2m_reset_t);
case CMD_E2M_ENABLE: return sizeof(e2m_enable_t);
case CMD_E2M_REPLUG: return sizeof(e2m_replug_t);
case CMD_E2M_SET_OUTPUT_VOLTAGE: return sizeof(e2m_set_output_t);
case CMD_E2M_ISOLATION_CONTROL: return sizeof(e2m_isolation_control_t);
case CMD_E2M_EV_INFO: return sizeof(CCS_EvInfo_t);
case CMD_E2M_EVSE_STATE: return sizeof(CONN_State_t);
case CMD_E2M_KEEP_ALIVE: return 0;
default: return 0xFFFFu;
}
}
static void apply_command(uint8_t cmd, const uint8_t* payload, uint16_t payload_len) {
(void)payload_len;
last_host_seen = HAL_GetTick();
switch (cmd) {
case CMD_E2M_PWM_DUTY: {
const e2m_pwm_duty_t* p = (const e2m_pwm_duty_t*)payload;
uint8_t duty = p->pwm_duty_percent;
if (duty > 100) duty = 100;
pwm_duty_percent = duty;
CP_SetDuty(duty);
break;
}
case CMD_E2M_ENABLE_OUTPUT: {
const e2m_enable_output_t* p = (const e2m_enable_output_t*)payload;
ev_enable_output = (p->enable_output != 0);
break;
}
case CMD_E2M_RESET: {
const e2m_reset_t* p = (const e2m_reset_t*)payload;
if (p->reset) {
log_printf(LOG_WARN, "Everest reset command\n");
CCS_SendResetReason();
HAL_Delay(10);
NVIC_SystemReset();
}
break;
}
case CMD_E2M_ENABLE: {
const e2m_enable_t* p = (const e2m_enable_t*)payload;
enabled = (p->enable != 0);
(void)enabled;
break;
}
case CMD_E2M_SET_OUTPUT_VOLTAGE: {
const e2m_set_output_t* p = (const e2m_set_output_t*)payload;
CONN.RequestedVoltage = p->voltage_V;
CONN.WantedCurrent = p->current_0p1A;
break;
}
case CMD_E2M_ISOLATION_CONTROL: {
const e2m_isolation_control_t* p = (const e2m_isolation_control_t*)payload;
isolation_enable = p->command;
break;
}
case CMD_E2M_EV_INFO: {
memcpy(&CCS_EvInfo, payload, sizeof(CCS_EvInfo_t));
CONN.SOC = (uint8_t)(CCS_EvInfo.soc / 10);
break;
}
case CMD_E2M_EVSE_STATE: {
CCS_EvseState = (CONN_State_t)payload[0];
break;
}
case CMD_E2M_REPLUG: {
(void)payload;
CP_SetDuty(pwm_duty_percent);
break;
}
case CMD_E2M_KEEP_ALIVE: {
last_host_seen = HAL_GetTick();
break;
}
default:
break;
}
}
static uint8_t process_received_packet(const uint8_t* packet, uint16_t packet_len) {
if (packet_len < 3) return 0;
uint8_t cmd = packet[0];
uint16_t payload_len = (uint16_t)(packet_len - 3);
uint16_t received_crc = (uint16_t)packet[packet_len - 2u] |
(uint16_t)packet[packet_len - 1u] << 8;
uint16_t calculated_crc = crc16_ibm(packet, (uint16_t)(1 + payload_len));
if (received_crc != calculated_crc) {
log_printf(LOG_ERR, "Packet CRC error\n");
return 0;
}
uint16_t expected_len = expected_payload_len(cmd);
if (expected_len == 0xFFFF) {
log_printf(LOG_WARN, "Unknown cmd 0x%02x\n", cmd);
return 0;
}
if (expected_len != payload_len) {
log_printf(LOG_ERR, "Packet len mismatch cmd=0x%02x\n", cmd);
return 0;
}
if (payload_len > 0) {
apply_command(cmd, &packet[1], payload_len);
} else {
apply_command(cmd, NULL, 0);
}
return 1;
}

View File

@@ -1,6 +1,7 @@
#include "serial_control.h"
#include "usart.h"
#include "board.h"
#include "serial.h"
// Приватные функции
static uint32_t calculate_crc32(const uint8_t* data, uint16_t length);
@@ -111,6 +112,8 @@ void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) {
SC_CommandHandler((ReceivedCommand_t*)&serial_iso.received_command);
}
HAL_UARTEx_ReceiveToIdle_IT(&huart5, serial_iso.rx_buffer, MAX_RX_BUFFER_SIZE - 1);
} else if (huart->Instance == huart3.Instance) {
CCS_RxEventCallback(huart, Size);
}
}

View File

@@ -1,15 +1,13 @@
#include "serial_control.h"
#include "charger_gbt.h"
#include "usart.h"
#include "charger_control.h"
#include "charger_gbt.h"
#include "board.h"
#include "psu_control.h"
#include "debug.h"
#include <string.h>
#ifdef USE_WEB_INTERFACE
extern uint8_t GBT_BAT_STAT_recv;
extern volatile SC_Source_t g_sc_command_source;
IsolationStatusPacket_t ISO = {
@@ -52,10 +50,7 @@ void SC_CommandHandler(ReceivedCommand_t* cmd) {
case CMD_SET_CONFIG:
if (cmd->argument_length == sizeof(ConfigBlock_t)) {
memcpy(&config, cmd->argument, sizeof(ConfigBlock_t));
GBT_SetConfig();
config_initialized = 1;
GBT_SetConfig();
// CONN.connState = CONN_Available; //
log_printf(LOG_INFO, "Set Config: %s %d\n", config.location, config.chargerNumber);
response_code = RESP_SUCCESS;
break;
@@ -147,38 +142,40 @@ void monitoring_data_callback() {
statusPacket.relayAC = RELAY_Read(RELAY_AC);
statusPacket.relayDC = RELAY_Read(RELAY_DC);
statusPacket.relayAUX = RELAY_Read(RELAY_AUX0);
statusPacket.lockState = GBT_LockGetState();
statusPacket.lockState = 0;
statusPacket.stopButton = !IN_ReadInput(IN_ESTOP);
statusPacket.logAvailable = (debug_buffer_available()>0)?1:0;
statusPacket.evInfoAvailable = GBT_BAT_STAT_recv;
statusPacket.evInfoAvailable = 0;
statusPacket.psuOnline = PSU0.online;
statusPacket.tempConnector0 = GBT_ReadTemp(0); // температура коннектора
statusPacket.tempConnector1 = GBT_ReadTemp(1);
statusPacket.tempConnector0 = CONN_ReadTemp(0); // температура коннектора
statusPacket.tempConnector1 = CONN_ReadTemp(1);
statusPacket.tempAmbient = PSU0.tempAmbient; // температура окружающего воздуха
statusPacket.tempBatteryMax = GBT_BatteryStatus.batteryHighestTemp; // максимальная температура батареи
statusPacket.tempBatteryMin = GBT_BatteryStatus.batteryLowestTemp; // минимальная температура батареи
statusPacket.tempBatteryMax = 0;
statusPacket.tempBatteryMin = 0;
statusPacket.highestVoltageOfBatteryCell = GBT_ChargingStatus.highestVoltageOfBatteryCell;
statusPacket.batteryStatus = GBT_BatteryStatus.batteryStatus;
statusPacket.highestVoltageOfBatteryCell = 0;
statusPacket.batteryStatus = 0;
statusPacket.phaseVoltageAB = PSU_06.VAB;
statusPacket.phaseVoltageBC = PSU_06.VBC;
statusPacket.phaseVoltageCA = PSU_06.VCA;
memcpy(statusPacket.VIN, GBT_EVInfo.EVIN, sizeof(GBT_EVInfo.EVIN));
// GBT TODO
memset(statusPacket.VIN, 0, sizeof(statusPacket.VIN));
statusPacket.batteryType = GBT_EVInfo.batteryType;
statusPacket.batteryCapacity = GBT_EVInfo.batteryCapacity;
statusPacket.batteryVoltage = GBT_EVInfo.batteryVoltage;
memcpy(statusPacket.batteryVendor, GBT_EVInfo.batteryVendor, sizeof(statusPacket.batteryVendor));
statusPacket.batterySN = GBT_EVInfo.batterySN;
statusPacket.batteryManuD = GBT_EVInfo.batteryManuD;
statusPacket.batteryManuM = GBT_EVInfo.batteryManuM;
statusPacket.batteryManuY = GBT_EVInfo.batteryManuY;
statusPacket.batteryCycleCount = GBT_EVInfo.batteryCycleCount;
statusPacket.ownAuto = GBT_EVInfo.ownAuto;
memcpy(statusPacket.EV_SW_VER, GBT_EVInfo.EV_SW_VER, sizeof(statusPacket.EV_SW_VER));
// 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;

40
Core/Src/sma_filter.c Normal file
View File

@@ -0,0 +1,40 @@
#include "sma_filter.h"
void SMAFilter_Init(SMAFilter_t* f)
{
if (f == 0) return;
f->sum = 0;
f->idx = 0;
f->count = 0;
for (uint16_t i = 0; i < SMA_FILTER_WINDOW; i++) {
f->buffer[i] = 0;
}
}
int32_t SMAFilter_Update(SMAFilter_t* f, int32_t x)
{
if (f == 0) return x;
// Пока окно не заполнено полностью, делим по фактическому count.
if (f->count < SMA_FILTER_WINDOW) {
f->buffer[f->idx] = x;
f->sum += x;
f->idx++;
if (f->idx >= SMA_FILTER_WINDOW) f->idx = 0;
f->count++;
return (int32_t)(f->sum / (int32_t)f->count);
}
// Окно заполнено: "вычитаем старое + добавляем новое".
int32_t old = f->buffer[f->idx];
f->buffer[f->idx] = x;
f->sum += (x - old);
f->idx++;
if (f->idx >= SMA_FILTER_WINDOW) f->idx = 0;
return (int32_t)(f->sum / (int32_t)SMA_FILTER_WINDOW);
}

View File

@@ -57,6 +57,7 @@
/* External variables --------------------------------------------------------*/
extern CAN_HandleTypeDef hcan1;
extern CAN_HandleTypeDef hcan2;
extern TIM_HandleTypeDef htim3;
extern UART_HandleTypeDef huart5;
extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart2;
@@ -217,6 +218,20 @@ void CAN1_RX0_IRQHandler(void)
/* USER CODE END CAN1_RX0_IRQn 1 */
}
/**
* @brief This function handles TIM3 global interrupt.
*/
void TIM3_IRQHandler(void)
{
/* USER CODE BEGIN TIM3_IRQn 0 */
/* USER CODE END TIM3_IRQn 0 */
HAL_TIM_IRQHandler(&htim3);
/* USER CODE BEGIN TIM3_IRQn 1 */
/* USER CODE END TIM3_IRQn 1 */
}
/**
* @brief This function handles USART1 global interrupt.
*/

View File

@@ -24,8 +24,73 @@
/* USER CODE END 0 */
TIM_HandleTypeDef htim3;
TIM_HandleTypeDef htim4;
/* TIM3 init function */
void MX_TIM3_Init(void)
{
/* USER CODE BEGIN TIM3_Init 0 */
/* USER CODE END TIM3_Init 0 */
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
/* USER CODE BEGIN TIM3_Init 1 */
/* USER CODE END TIM3_Init 1 */
htim3.Instance = TIM3;
htim3.Init.Prescaler = 0;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 65535;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_OC_Init(&htim3) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_TIMING;
sConfigOC.Pulse = 1;
if (HAL_TIM_OC_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM3_Init 2 */
/* USER CODE END TIM3_Init 2 */
HAL_TIM_MspPostInit(&htim3);
}
/* TIM4 init function */
void MX_TIM4_Init(void)
{
@@ -92,7 +157,22 @@ void MX_TIM4_Init(void)
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
{
if(tim_baseHandle->Instance==TIM4)
if(tim_baseHandle->Instance==TIM3)
{
/* USER CODE BEGIN TIM3_MspInit 0 */
/* USER CODE END TIM3_MspInit 0 */
/* TIM3 clock enable */
__HAL_RCC_TIM3_CLK_ENABLE();
/* TIM3 interrupt Init */
HAL_NVIC_SetPriority(TIM3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM3_IRQn);
/* USER CODE BEGIN TIM3_MspInit 1 */
/* USER CODE END TIM3_MspInit 1 */
}
else if(tim_baseHandle->Instance==TIM4)
{
/* USER CODE BEGIN TIM4_MspInit 0 */
@@ -108,7 +188,25 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(timHandle->Instance==TIM4)
if(timHandle->Instance==TIM3)
{
/* USER CODE BEGIN TIM3_MspPostInit 0 */
/* USER CODE END TIM3_MspPostInit 0 */
__HAL_RCC_GPIOA_CLK_ENABLE();
/**TIM3 GPIO Configuration
PA7 ------> TIM3_CH2
*/
GPIO_InitStruct.Pin = CP_PWM_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(CP_PWM_GPIO_Port, &GPIO_InitStruct);
/* USER CODE BEGIN TIM3_MspPostInit 1 */
/* USER CODE END TIM3_MspPostInit 1 */
}
else if(timHandle->Instance==TIM4)
{
/* USER CODE BEGIN TIM4_MspPostInit 0 */
@@ -137,7 +235,21 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle)
void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle)
{
if(tim_baseHandle->Instance==TIM4)
if(tim_baseHandle->Instance==TIM3)
{
/* USER CODE BEGIN TIM3_MspDeInit 0 */
/* USER CODE END TIM3_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_TIM3_CLK_DISABLE();
/* TIM3 interrupt Deinit */
HAL_NVIC_DisableIRQ(TIM3_IRQn);
/* USER CODE BEGIN TIM3_MspDeInit 1 */
/* USER CODE END TIM3_MspDeInit 1 */
}
else if(tim_baseHandle->Instance==TIM4)
{
/* USER CODE BEGIN TIM4_MspDeInit 0 */

BIN
Debug/.DS_Store vendored

Binary file not shown.

BIN
Debug/CCSModuleSW30Web.bin Executable file

Binary file not shown.

33115
Debug/CCSModuleSW30Web.list Normal file

File diff suppressed because it is too large Load Diff

3683
Debug/CCSModuleSW30Web.srec Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,3 @@
../Core/Src/adc.c:30:6:MX_ADC1_Init 3
../Core/Src/adc.c:72:6:HAL_ADC_MspInit 2
../Core/Src/adc.c:105:6:HAL_ADC_MspDeInit 2
../Core/Src/adc.c:106:6:HAL_ADC_MspDeInit 2

View File

@@ -1,9 +1,13 @@
../Core/Src/board.c:16:6:RELAY_Write 8
../Core/Src/board.c:46:9:RELAY_Read 1
../Core/Src/board.c:51:9:IN_ReadInput 8
../Core/Src/board.c:72:9:GetBoardTemp 1
../Core/Src/board.c:84:6:Init_Peripheral 1
../Core/Src/board.c:96:7:pt1000_to_temperature 1
../Core/Src/board.c:107:7:calculate_NTC_resistance 2
../Core/Src/board.c:122:9:GBT_ReadTemp 3
../Core/Src/board.c:152:6:ADC_Select_Channel 2
../Core/Src/board.c:19:6:RELAY_Write 9
../Core/Src/board.c:52:9:RELAY_Read 1
../Core/Src/board.c:57:9:IN_ReadInput 8
../Core/Src/board.c:78:9:GetBoardTemp 1
../Core/Src/board.c:90:6:Init_Peripheral 1
../Core/Src/board.c:106:7:pt1000_to_temperature 1
../Core/Src/board.c:117:7:calculate_NTC_resistance 2
../Core/Src/board.c:132:9:CONN_ReadTemp 4
../Core/Src/board.c:169:9:GBT_ReadTemp 1
../Core/Src/board.c:173:6:ADC_Select_Channel 2
../Core/Src/board.c:184:9:ADC_TryLock 4
../Core/Src/board.c:200:6:ADC_LockBlocking 2
../Core/Src/board.c:206:6:ADC_Unlock 2

View File

@@ -1,3 +1,5 @@
../Core/Src/charger_control.c:9:6:CONN_Init 1
../Core/Src/charger_control.c:17:6:CONN_Loop 7
../Core/Src/charger_control.c:41:6:CONN_PrintChargingTotal 1
../Core/Src/charger_control.c:11:6:CONN_Init 1
../Core/Src/charger_control.c:19:6:CONN_Loop 6
../Core/Src/charger_control.c:41:6:CONN_Task 5
../Core/Src/charger_control.c:57:6:CONN_SetState 16
../Core/Src/charger_control.c:83:6:CONN_PrintChargingTotal 1

View File

@@ -1,13 +0,0 @@
../Core/Src/charger_gbt.c:71:6:GBT_Init 1
../Core/Src/charger_gbt.c:82:6:GBT_SetConfig 1
../Core/Src/charger_gbt.c:91:6:GBT_ChargerTask 95
../Core/Src/charger_gbt.c:492:6:GBT_SwitchState 16
../Core/Src/charger_gbt.c:513:10:GBT_StateTick 1
../Core/Src/charger_gbt.c:517:6:GBT_Delay 1
../Core/Src/charger_gbt.c:522:6:GBT_StopEV 3
../Core/Src/charger_gbt.c:532:6:GBT_StopEVSE 2
../Core/Src/charger_gbt.c:538:6:GBT_StopOCPP 2
../Core/Src/charger_gbt.c:544:6:GBT_ForceStop 1
../Core/Src/charger_gbt.c:553:6:GBT_Error 1
../Core/Src/charger_gbt.c:561:6:GBT_Reset 1
../Core/Src/charger_gbt.c:588:6:GBT_Start 1

View File

@@ -1,6 +1,2 @@
../Core/Src/connector.c:39:6:CONN_Task 35
../Core/Src/connector.c:146:6:CONN_SetState 15
../Core/Src/connector.c:167:6:CONN_CC_ReadStateFiltered 4
../Core/Src/connector.c:186:9:CONN_CC_GetState 1
../Core/Src/connector.c:189:9:CONN_CC_GetStateRaw 9
../Core/Src/connector.c:202:7:CONN_CC_GetAdc 1
../Core/Src/connector.c:12:6:CONN_Task 5
../Core/Src/connector.c:28:6:CONN_SetState 16

9
Debug/Core/Src/cp.cyclo Normal file
View File

@@ -0,0 +1,9 @@
../Core/Src/cp.c:13:17:CP_ReadAdcChannel 1
../Core/Src/cp.c:26:16:CP_ReadVoltageMv 1
../Core/Src/cp.c:39:6:CP_Init 1
../Core/Src/cp.c:56:6:CP_SetDuty 1
../Core/Src/cp.c:69:9:CP_GetDuty 1
../Core/Src/cp.c:73:9:CP_GetVoltage 1
../Core/Src/cp.c:77:12:CP_GetState 12
../Core/Src/cp.c:101:6:CP_Loop 1
../Core/Src/cp.c:105:6:HAL_TIM_OC_DelayElapsedCallback 4

View File

@@ -1,5 +1,5 @@
../Core/Src/debug.c:43:5:_write 1
../Core/Src/debug.c:51:6:debug_buffer_add 3
../Core/Src/debug.c:71:10:debug_buffer_available 1
../Core/Src/debug.c:80:6:debug_buffer_send 5
../Core/Src/debug.c:120:5:log_printf 3
../Core/Src/debug.c:42:5:_write 1
../Core/Src/debug.c:50:6:debug_buffer_add 3
../Core/Src/debug.c:70:10:debug_buffer_available 1
../Core/Src/debug.c:79:6:debug_buffer_send 5
../Core/Src/debug.c:119:5:log_printf 3

View File

@@ -1,9 +0,0 @@
../Core/Src/gbt_packet.c:14:6:GBT_SendCTS 1
../Core/Src/gbt_packet.c:30:6:GBT_SendCML 1
../Core/Src/gbt_packet.c:46:6:GBT_SendCHM 1
../Core/Src/gbt_packet.c:55:6:GBT_SendCRM 1
../Core/Src/gbt_packet.c:70:6:GBT_SendCRO 1
../Core/Src/gbt_packet.c:77:6:GBT_SendCCS 1
../Core/Src/gbt_packet.c:94:6:GBT_SendCST 1
../Core/Src/gbt_packet.c:104:6:GBT_SendCSD 1
../Core/Src/gbt_packet.c:112:6:GBT_SendCEM 1

View File

@@ -1,6 +0,0 @@
../Core/Src/j1939.c:20:6:HAL_CAN_RxFifo0MsgPendingCallback 20
../Core/Src/j1939.c:117:6:GBT_CAN_ReInit 1
../Core/Src/j1939.c:125:6:J_SendPacket 1
../Core/Src/j1939.c:146:6:J_SendCTS 2
../Core/Src/j1939.c:164:6:J_SendACK 1
../Core/Src/j1939.c:179:6:GBT_CAN_FilterInit 2

View File

@@ -1,7 +0,0 @@
../Core/Src/lock.c:26:6:GBT_ForceLock 1
../Core/Src/lock.c:32:9:GBT_LockGetState 2
../Core/Src/lock.c:43:6:GBT_Lock 1
../Core/Src/lock.c:47:6:GBT_ManageLockSolenoid 2
../Core/Src/lock.c:56:6:GBT_ManageLockMotor 17
../Core/Src/lock.c:153:6:GBT_LockResetError 1
../Core/Src/lock.c:159:6:GBT_ResetErrorTimeout 4

View File

@@ -1,7 +1,8 @@
../Core/Src/main.c:67:13:VectorBase_Config 1
../Core/Src/main.c:78:9:ED_TraceWarning 3
../Core/Src/main.c:90:6:ED_Delay 3
../Core/Src/main.c:112:6:StopButtonControl 2
../Core/Src/main.c:129:5:main 1
../Core/Src/main.c:210:6:SystemClock_Config 4
../Core/Src/main.c:270:6:Error_Handler 1
../Core/Src/main.c:64:13:VectorBase_Config 1
../Core/Src/main.c:75:9:ED_TraceWarning 3
../Core/Src/main.c:87:6:ED_Delay 3
../Core/Src/main.c:106:6:StopButtonControl 2
../Core/Src/main.c:117:13:CAN1_MinimalReInit 3
../Core/Src/main.c:135:5:main 1
../Core/Src/main.c:216:6:SystemClock_Config 4
../Core/Src/main.c:276:6:Error_Handler 1

View File

@@ -1,12 +1,12 @@
../Core/Src/psu_control.c:34:13:PSU_SwitchState 1
../Core/Src/psu_control.c:39:17:PSU_StateTime 1
../Core/Src/psu_control.c:43:6:HAL_CAN_RxFifo1MsgPendingCallback 9
../Core/Src/psu_control.c:117:6:PSU_CAN_FilterInit 2
../Core/Src/psu_control.c:140:6:PSU_Init 1
../Core/Src/psu_control.c:157:6:PSU_Enable 3
../Core/Src/psu_control.c:169:6:PSU_SetHVMode 2
../Core/Src/psu_control.c:176:6:PSU_SetVoltageCurrent 5
../Core/Src/psu_control.c:203:6:PSU_SendCmd 4
../Core/Src/psu_control.c:239:10:max 2
../Core/Src/psu_control.c:244:6:PSU_ReadWrite 5
../Core/Src/psu_control.c:277:6:PSU_Task 41
../Core/Src/psu_control.c:33:13:PSU_SwitchState 1
../Core/Src/psu_control.c:38:17:PSU_StateTime 1
../Core/Src/psu_control.c:42:6:HAL_CAN_RxFifo1MsgPendingCallback 9
../Core/Src/psu_control.c:116:6:PSU_CAN_FilterInit 2
../Core/Src/psu_control.c:139:6:PSU_Init 1
../Core/Src/psu_control.c:156:6:PSU_Enable 3
../Core/Src/psu_control.c:168:6:PSU_SetHVMode 2
../Core/Src/psu_control.c:175:6:PSU_SetVoltageCurrent 5
../Core/Src/psu_control.c:202:6:PSU_SendCmd 4
../Core/Src/psu_control.c:238:10:max 2
../Core/Src/psu_control.c:243:6:PSU_ReadWrite 5
../Core/Src/psu_control.c:276:6:PSU_Task 41

View File

@@ -0,0 +1,15 @@
../Drivers/CMSIS/Include/core_cm3.h:1762:34:__NVIC_SystemReset 1
../Core/Src/serial.c:51:6:CCS_RxEventCallback 4
../Core/Src/serial.c:61:6:CCS_SerialLoop 41
../Core/Src/serial.c:206:6:CCS_Init 1
../Core/Src/serial.c:218:17:crc16_ibm 4
../Core/Src/serial.c:233:17:CCS_BuildPacket 4
../Core/Src/serial.c:249:13:CCS_SendPacket 2
../Core/Src/serial.c:257:13:CCS_SendResetReason 1
../Core/Src/serial.c:261:6:CCS_SendEmergencyStop 1
../Core/Src/serial.c:265:6:CCS_SendStart 1
../Core/Src/serial.c:269:13:CCS_CalculateEnergy 2
../Core/Src/serial.c:284:13:send_state 2
../Core/Src/serial.c:311:17:expected_payload_len 11
../Core/Src/serial.c:327:13:apply_command 13
../Core/Src/serial.c:394:16:process_received_packet 6

View File

@@ -1,10 +1,10 @@
../Core/Src/serial_control.c:58:6:ReadVersion 1
../Core/Src/serial_control.c:70:6:SC_Init 1
../Core/Src/serial_control.c:76:6:SC_Task 9
../Core/Src/serial_control.c:101:6:HAL_UARTEx_RxEventCallback 5
../Core/Src/serial_control.c:117:6:HAL_UART_TxCpltCallback 2
../Core/Src/serial_control.c:127:17:calculate_crc32 4
../Core/Src/serial_control.c:144:17:encode_packet 6
../Core/Src/serial_control.c:177:6:SC_SendPacket 3
../Core/Src/serial_control.c:194:16:parse_packet 4
../Core/Src/serial_control.c:227:16:process_received_packet 2
../Core/Src/serial_control.c:59:6:ReadVersion 1
../Core/Src/serial_control.c:71:6:SC_Init 1
../Core/Src/serial_control.c:77:6:SC_Task 9
../Core/Src/serial_control.c:102:6:HAL_UARTEx_RxEventCallback 6
../Core/Src/serial_control.c:120:6:HAL_UART_TxCpltCallback 2
../Core/Src/serial_control.c:130:17:calculate_crc32 4
../Core/Src/serial_control.c:147:17:encode_packet 6
../Core/Src/serial_control.c:180:6:SC_SendPacket 3
../Core/Src/serial_control.c:197:16:parse_packet 4
../Core/Src/serial_control.c:230:16:process_received_packet 2

View File

@@ -1,3 +1,3 @@
../Drivers/CMSIS/Include/core_cm3.h:1762:34:__NVIC_SystemReset 1
../Core/Src/serial_handler.c:28:6:SC_CommandHandler 19
../Core/Src/serial_handler.c:130:6:monitoring_data_callback 1
../Core/Src/serial_handler.c:26:6:SC_CommandHandler 19
../Core/Src/serial_handler.c:125:6:monitoring_data_callback 1

View File

@@ -0,0 +1,2 @@
../Core/Src/sma_filter.c:3:6:SMAFilter_Init 3
../Core/Src/sma_filter.c:16:9:SMAFilter_Update 6

View File

@@ -1,16 +1,17 @@
../Core/Src/stm32f1xx_it.c:74:6:NMI_Handler 1
../Core/Src/stm32f1xx_it.c:89:6:HardFault_Handler 1
../Core/Src/stm32f1xx_it.c:104:6:MemManage_Handler 1
../Core/Src/stm32f1xx_it.c:119:6:BusFault_Handler 1
../Core/Src/stm32f1xx_it.c:134:6:UsageFault_Handler 1
../Core/Src/stm32f1xx_it.c:149:6:SVC_Handler 1
../Core/Src/stm32f1xx_it.c:162:6:DebugMon_Handler 1
../Core/Src/stm32f1xx_it.c:175:6:PendSV_Handler 1
../Core/Src/stm32f1xx_it.c:188:6:SysTick_Handler 1
../Core/Src/stm32f1xx_it.c:209:6:CAN1_RX0_IRQHandler 1
../Core/Src/stm32f1xx_it.c:223:6:USART1_IRQHandler 1
../Core/Src/stm32f1xx_it.c:237:6:USART2_IRQHandler 1
../Core/Src/stm32f1xx_it.c:251:6:USART3_IRQHandler 1
../Core/Src/stm32f1xx_it.c:265:6:UART5_IRQHandler 1
../Core/Src/stm32f1xx_it.c:279:6:CAN2_TX_IRQHandler 1
../Core/Src/stm32f1xx_it.c:293:6:CAN2_RX1_IRQHandler 1
../Core/Src/stm32f1xx_it.c:75:6:NMI_Handler 1
../Core/Src/stm32f1xx_it.c:90:6:HardFault_Handler 1
../Core/Src/stm32f1xx_it.c:105:6:MemManage_Handler 1
../Core/Src/stm32f1xx_it.c:120:6:BusFault_Handler 1
../Core/Src/stm32f1xx_it.c:135:6:UsageFault_Handler 1
../Core/Src/stm32f1xx_it.c:150:6:SVC_Handler 1
../Core/Src/stm32f1xx_it.c:163:6:DebugMon_Handler 1
../Core/Src/stm32f1xx_it.c:176:6:PendSV_Handler 1
../Core/Src/stm32f1xx_it.c:189:6:SysTick_Handler 1
../Core/Src/stm32f1xx_it.c:210:6:CAN1_RX0_IRQHandler 1
../Core/Src/stm32f1xx_it.c:224:6:TIM3_IRQHandler 1
../Core/Src/stm32f1xx_it.c:238:6:USART1_IRQHandler 1
../Core/Src/stm32f1xx_it.c:252:6:USART2_IRQHandler 1
../Core/Src/stm32f1xx_it.c:266:6:USART3_IRQHandler 1
../Core/Src/stm32f1xx_it.c:280:6:UART5_IRQHandler 1
../Core/Src/stm32f1xx_it.c:294:6:CAN2_TX_IRQHandler 1
../Core/Src/stm32f1xx_it.c:308:6:CAN2_RX1_IRQHandler 1

View File

@@ -9,21 +9,19 @@ C_SRCS += \
../Core/Src/board.c \
../Core/Src/can.c \
../Core/Src/charger_control.c \
../Core/Src/charger_gbt.c \
../Core/Src/connector.c \
../Core/Src/cp.c \
../Core/Src/crc.c \
../Core/Src/debug.c \
../Core/Src/gbt_packet.c \
../Core/Src/gpio.c \
../Core/Src/j1939.c \
../Core/Src/lock.c \
../Core/Src/main.c \
../Core/Src/meter.c \
../Core/Src/psu_control.c \
../Core/Src/rgb_controller.c \
../Core/Src/rtc.c \
../Core/Src/serial.c \
../Core/Src/serial_control.c \
../Core/Src/serial_handler.c \
../Core/Src/sma_filter.c \
../Core/Src/soft_rtc.c \
../Core/Src/stm32f1xx_hal_msp.c \
../Core/Src/stm32f1xx_it.c \
@@ -38,21 +36,19 @@ C_DEPS += \
./Core/Src/board.d \
./Core/Src/can.d \
./Core/Src/charger_control.d \
./Core/Src/charger_gbt.d \
./Core/Src/connector.d \
./Core/Src/cp.d \
./Core/Src/crc.d \
./Core/Src/debug.d \
./Core/Src/gbt_packet.d \
./Core/Src/gpio.d \
./Core/Src/j1939.d \
./Core/Src/lock.d \
./Core/Src/main.d \
./Core/Src/meter.d \
./Core/Src/psu_control.d \
./Core/Src/rgb_controller.d \
./Core/Src/rtc.d \
./Core/Src/serial.d \
./Core/Src/serial_control.d \
./Core/Src/serial_handler.d \
./Core/Src/sma_filter.d \
./Core/Src/soft_rtc.d \
./Core/Src/stm32f1xx_hal_msp.d \
./Core/Src/stm32f1xx_it.d \
@@ -67,21 +63,19 @@ OBJS += \
./Core/Src/board.o \
./Core/Src/can.o \
./Core/Src/charger_control.o \
./Core/Src/charger_gbt.o \
./Core/Src/connector.o \
./Core/Src/cp.o \
./Core/Src/crc.o \
./Core/Src/debug.o \
./Core/Src/gbt_packet.o \
./Core/Src/gpio.o \
./Core/Src/j1939.o \
./Core/Src/lock.o \
./Core/Src/main.o \
./Core/Src/meter.o \
./Core/Src/psu_control.o \
./Core/Src/rgb_controller.o \
./Core/Src/rtc.o \
./Core/Src/serial.o \
./Core/Src/serial_control.o \
./Core/Src/serial_handler.o \
./Core/Src/sma_filter.o \
./Core/Src/soft_rtc.o \
./Core/Src/stm32f1xx_hal_msp.o \
./Core/Src/stm32f1xx_it.o \
@@ -99,7 +93,7 @@ Core/Src/%.o Core/Src/%.su Core/Src/%.cyclo: ../Core/Src/%.c Core/Src/subdir.mk
clean: 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/charger_gbt.cyclo ./Core/Src/charger_gbt.d ./Core/Src/charger_gbt.o ./Core/Src/charger_gbt.su ./Core/Src/connector.cyclo ./Core/Src/connector.d ./Core/Src/connector.o ./Core/Src/connector.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/gbt_packet.cyclo ./Core/Src/gbt_packet.d ./Core/Src/gbt_packet.o ./Core/Src/gbt_packet.su ./Core/Src/gpio.cyclo ./Core/Src/gpio.d ./Core/Src/gpio.o ./Core/Src/gpio.su ./Core/Src/j1939.cyclo ./Core/Src/j1939.d ./Core/Src/j1939.o ./Core/Src/j1939.su ./Core/Src/lock.cyclo ./Core/Src/lock.d ./Core/Src/lock.o ./Core/Src/lock.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_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/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/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

View File

@@ -1,4 +1,5 @@
../Core/Src/tim.c:30:6:MX_TIM4_Init 8
../Core/Src/tim.c:92:6:HAL_TIM_Base_MspInit 2
../Core/Src/tim.c:107:6:HAL_TIM_MspPostInit 2
../Core/Src/tim.c:137:6:HAL_TIM_Base_MspDeInit 2
../Core/Src/tim.c:31:6:MX_TIM3_Init 8
../Core/Src/tim.c:95:6:MX_TIM4_Init 8
../Core/Src/tim.c:157:6:HAL_TIM_Base_MspInit 3
../Core/Src/tim.c:187:6:HAL_TIM_MspPostInit 3
../Core/Src/tim.c:235:6:HAL_TIM_Base_MspDeInit 3

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -2,21 +2,19 @@
"./Core/Src/board.o"
"./Core/Src/can.o"
"./Core/Src/charger_control.o"
"./Core/Src/charger_gbt.o"
"./Core/Src/connector.o"
"./Core/Src/cp.o"
"./Core/Src/crc.o"
"./Core/Src/debug.o"
"./Core/Src/gbt_packet.o"
"./Core/Src/gpio.o"
"./Core/Src/j1939.o"
"./Core/Src/lock.o"
"./Core/Src/main.o"
"./Core/Src/meter.o"
"./Core/Src/psu_control.o"
"./Core/Src/rgb_controller.o"
"./Core/Src/rtc.o"
"./Core/Src/serial.o"
"./Core/Src/serial_control.o"
"./Core/Src/serial_handler.o"
"./Core/Src/sma_filter.o"
"./Core/Src/soft_rtc.o"
"./Core/Src/stm32f1xx_hal_msp.o"
"./Core/Src/stm32f1xx_it.o"

View File

@@ -1,14 +0,0 @@
{
"folders": [
{
"path": "."
}
],
"settings": {
"files.associations": {
"charger_config.h": "c",
"connector.h": "c",
"serial_control.h": "c"
}
}
}

146
plan.md Normal file
View File

@@ -0,0 +1,146 @@
---
name: gbt-to-ccs-port
overview: Перенос прошивки модуля GBT на CCS с сохранением логики силовой части и веб-интерфейса, интеграцией готового CCS-стека из проекта CS60DC_CCS_STM32 и разделением двух независимых UART-протоколов.
todos:
- id: analyze-gbt-project
content: Просмотреть проект `GbTModuleSW30Web` (main, PSU, CONN, LED, веб/диагностика) и зафиксировать все места, где используется GBT-логика (функции GBT_*, структуры, CAN2 и т.п.).
status: completed
- id: extract-ccs-modules
content: Выделить из `CS60DC_CCS_STM32` полный набор CCS-модулей (cp, serial, charger_ccs, структуры CCS_EDCAN_*) и их зависимости (EDCAN, board, adc_filter) для переноса.
status: completed
- id: wire-cp-and-uart3
content: Спланировать привязку CP (ADC1_IN4 и PWM на PA7) и перенастройку CCS-протокола на USART3 в проекте модуля, учитывая текущую конфигурацию таймеров и UART в `GbTModuleSW30Web`.
status: completed
- id: rewrite-main-loop
content: Спроектировать новое содержимое `main()` и `ED_Delay()` в `GbTModuleSW30Web`, убрав GBT-задачи и интегрировав CCS_SerialLoop, CP_Loop, EDCAN_Loop и существующие PSU/METER/CONN/LED/StopButton задачи.
status: completed
- id: clean-gbt-and-keep-can1
content: Определить, какие файлы/части кода GBT можно удалить или заглушить, при этом оставив инициализацию CAN1 и минимально необходимый код для корректной работы bootloader и EDCAN.
status: completed
- id: adapt-web-diagnostics
content: "Наметить изменения веб-интерфейса и диагностического протокола: заменить источники данных с GBT на CCS-структуры, сохранив максимально существующую функциональность."
status: in_progress
- id: define-test-plan
content: Уточнить и зафиксировать подробный тест-план для стендовой проверки новой CCS-прошивки (переходы состояний CP/EVSE, обмен по USART3, защитные сценарии и регрессия веб/диагностики).
status: pending
isProject: false
---
## Цель
Сделать новую прошивку для платы модуля, основанную на проекте `GbTModuleSW30Web`, которая:
- **полностью избавлена от GBT-логики и GBT-протоколов**,
- **использует CCS-алгоритмы и протокол** из проекта `[CS60DC_CCS_STM32](CS60DC_CCS_STM32/Core/Src/main.c)`,
- **сохраняет силовую часть и веб/диагностический функционал** существующей GBT-прошивки,
- использует **два независимых UART**: существующий (как в GBT) + новый `USART3` под CCS-протокол,
- сохраняет **инициализацию CAN1 как заглушку**, но не использует старый GBTCAN.
## Архитектура на целевом проекте
- **Базовый проект**: берем за основу прошивку модуля GBT — `[GbTModuleSW30Web](GbTModuleSW30Web/Core/Src/main.c)`.
- **Источник CCS-логики**: переносим state machine и протокол CCS из `[CS60DC_CCS_STM32](CS60DC_CCS_STM32/Core/Src/main.c)` и связанных файлов:
- `[Core/Src/serial.c](CS60DC_CCS_STM32/Core/Src/serial.c)` — протокол MCU↔Everest (через UART, сейчас `huart1`),
- `[Core/Src/cp.c](CS60DC_CCS_STM32/Core/Src/cp.c)` — формирование и измерение CP (PWM+ADC),
- `[Core/Src/charger_ccs.c](CS60DC_CCS_STM32/Core/Src/charger_ccs.c)` + соответствующие заголовки и типы `CCS_*` и `CCS_EDCAN_*`.
- **Распределение UART**:
- существующий UART из GBTпрошивки **оставляем без изменений** (диагностика / веб / что используется сейчас),
- **добавляем `USART3` для CCSпротокола**, берём настройки (baud, parity и т.п.) из `CS60DC_CCS_STM32` (там CCS сейчас сидит на `USART1`, но параметры переносим на `USART3`).
- **CAN1**:
- оставляем `MX_CAN1_Init()` и базовую инициализацию как заглушку (по требованию),
- старые GBTобработчики CAN и `GBT_CAN_ReInit()` удаляем или заменяем пустыми/адаптированными вызовами к EDCAN при необходимости.
- **Силовая часть, реле, измерения**:
- логика `PSU_*`, `METER_*`, `CONN_*`, `LED_*` и Stop/EStop остаётся из GBTпроекта,
- управление главным DCконтактором остаётся как в `[GbTModuleSW30Web](GbTModuleSW30Web/Core/Src/main.c)` и связанных файлах, но команды/состояния будут приходить из CCSлогики.
## План изменения `main.c` и ядра логики
- **Инициализация (startup)**:
- в `[GbTModuleSW30Web/Core/Src/main.c](GbTModuleSW30Web/Core/Src/main.c)` сохраняем логику OpenBLT/VectorBase (`VectorBase_Config()` и т.п.);
- после стандартной HALинициализации (`HAL_Init`, `HAL_RCC_DeInit`, `SystemClock_Config`, `MX_GPIO_Init` и т.д.)
- оставляем инициализацию общих периферий: `GPIO`, `ADC1`, `CAN1`, `RTC`, `TIM4` (если используется для других задач), существующие UART (2/5/1) и `USART3`;
- **убираем GBTспецифичные инициализации**: `GBT_Init()`, `GBT_SetConfig()`, `GBT_CAN_ReInit()`, прямые вызовы `charger_gbt.h`, `j1939.h` и т.п.;
- **добавляем CCSинициализации** по образцу из `CS60DC_CCS_STM32/Core/Src/main.c`:
- `ADC_Init()` (если в проект переносится фильтрация АЦП / `adc_filter.c`),
- `CP_Init()` и первоначальное `CP_SetDuty(100);`,
- `CCS_Init();`,
- инициализацию EDCAN/адреса: `EDCAN_Init(SW_GetAddr());` и возможный `CAN_ReInit();`, если EDCAN используется.
- **Главный цикл**:
- исходно в GBTпрошивке основной цикл делает:
- `PSU_ReadWrite();`, `PSU_Task();`, `METER_CalculateEnergy();`, `CONN_Loop();`, `LED_Write();`, `StopButtonControl();` и несколько `ED_Delay(...)`, в которых вызываются GBTтаски (`GBT_ChargerTask()`, `GBT_ManageLockMotor()`, `CONN_CC_ReadStateFiltered()` и т.п.);
- **заменяем содержимое `ED_Delay()` и цикла `while(1)` так, чтобы:**
- в основном цикле выполнялись:
- `CCS_SerialLoop();` (как в `[CS60DC_CCS_STM32/Core/Src/main.c](CS60DC_CCS_STM32/Core/Src/main.c)`),
- `EDCAN_Loop();` (если EDCAN используется для обмена с главным контроллером),
- `CP_Loop();` (обновление состояния CP и заполнение `CCS_EDCAN_Output.cpState`),
- существующие `PSU_*`, `METER_*`, `CONN_Loop()`, `LED_Write()`, `StopButtonControl()`;
- `ED_Delay()` больше **не опирается на GBTтаски**, а, при необходимости, просто крутит `CCS_SerialLoop()` / `CP_Loop()` и необязательные сервисные задачи.
## Интеграция CCSпротокола в проект модуля
- **Перенос файлов CCS**:
- добавляем в проект модуля исходники и заголовки из `CS60DC_CCS_STM32`:
- `[Core/Src/cp.c](CS60DC_CCS_STM32/Core/Src/cp.c)` + `Core/Inc/cp.h`,
- `[Core/Src/serial.c](CS60DC_CCS_STM32/Core/Src/serial.c)` + `Core/Inc/serial.h`,
- `[Core/Src/charger_ccs.c](CS60DC_CCS_STM32/Core/Src/charger_ccs.c)` + `Core/Inc/charger_ccs.h`,
- необходимые типы `CCS_*` и `CCS_EDCAN_*` (структуры состояний, входов/выходов, команд).
- подправляем includeпути и зависимости под структуру каталогов `GbTModuleSW30Web`.
- **Привязка к `USART3`**:
- в перенесённом `serial.c` заменяем все использования `huart1` на `huart3`:
- глобальный `extern UART_HandleTypeDef huart1;``huart3;`,
- `HAL_UARTEx_ReceiveToIdle_IT(&huart1, ...)``&huart3`,
- `HAL_UART_Transmit(&huart1, ...)``&huart3`;
- обновляем `HAL_UARTEx_RxEventCallback` так, чтобы он реагировал на `huart3`;
- убеждаемся, что `MX_USART3_UART_Init()` в `GbTModuleSW30Web/Core/Src/usart.c` настроен на тот же baud/формат, что и `USART1` в `CS60DC_CCS_STM32`.
- **CPцепь (CP ADC + PWM на PA7)**:
- в переносимом `cp.c` уже есть логика расчёта напряжения CP по `ADC_CP_CHANNEL` и управление PWM через `TIM2`;
- на целевой плате:
- настраиваем канал ADC, соответствующий `ADC1_IN4`, как `ADC_CP_CHANNEL` в конфигурационных файлах/enumах ADC;
- убеждаемся, что ножка `PA7` привязана к нужному таймеру (по CubeMXконфигу) и совпадает с тем, что ожидает `cp.c` (сейчас TIM2/CH1/CH2) — при необходимости в план добавим правку конфигурации таймера и каналов;
- оставляем границы состояний CP (A/B/C/D/E/F) и формулы из текущего `cp.c` без изменений, чтобы поведение соответствовало проверенной CCSпрошивке.
- **Связка CCS ↔ силовая часть/EDCAN**:
- `CCS_SerialLoop()` управляет структурами `CCS_EDCAN_Output` и читает `CCS_EDCAN_Input`;
- в коде модуля (там, где сейчас GBTлогика связывает CAN/силовую часть с протоколом) заменяем связь на работу с `CCS_EDCAN_*`:
- измеренные ток/напряжение из силовой части кладём в `CCS_EDCAN_Input.measuredVoltage` и `measuredCurrent`,
- команды включения/отключения питания (`PSU_ON/OFF/PREPARE`) и ошибки записываем в `CCS_EDCAN_Input.*`,
- из `CCS_EDCAN_Output` читаем:
- `enablePSU`/`requestedVoltage`/`requestedCurrent` — для управления источником питания,
- `connectorState`, `cpState`, `chargingPercentage` — для индикации, логов и веб‑интерфейса.
## Удаление GBT и чистка кода
- **Удаление GBTзависимостей**:
- в `GbTModuleSW30Web` находим и удаляем/отключаем:
- `#include "charger_gbt.h"`, `j1939.h`, GBTспецифические модули блокировки/замка, если они не используются механически;
- функции `GBT_Init()`, `GBT_ChargerTask()`, `GBT_ManageLockMotor()`, `GBT_SetConfig()`, `GBT_CAN_ReInit()` и т.п.;
- оставляем общий код, не завязанный именно на GBT (питание, измерения, коннектор, индикация, веб‑сервер, логирование).
- **CAN**:
- инициализация `CAN1` (`MX_CAN1_Init()`) должна остаться, чтобы bootloader/система не сломались;
- если от GBT остался `CAN2`, его можно выключить из конфигурации, если он аппаратно не используется в CCSварианте;
- при необходимости добавляем простую заглушку вместо старых GBTобработчиков, чтобы сборка прошла без ошибок.
## Сохранение веб‑/диагностического функционала
- **Веб‑интерфейс и диагностика**:
- по вашему требованию **сохраняем весь существующий веб‑функционал `GbTModuleSW30Web`**, только:
- удаляем/переписываем поля и страницы, завязанные на GBTсостояния/параметры,
- вместо GBTпеременных и структур подставляем данные из `CCS_EDCAN_Output`, `CCS_State`, `CCS_EvInfo` и т.п.;
- протокол диагностики через существующий UART не меняем по формату, только отключаем GBTкоманды/состояния и, при необходимости, добавляем новые поля/команды под CCS (по согласованию).
## Тестирование и критерии приёмки
- **Юнит‑/модульные проверки на стенде**:
- запуск прошивки без подключенного EV — проверка, что станция в состоянии `Unplugged`/`EV_STATE_A_IDLE`, нет перезагрузок и ошибок;
- подключение EV/эмулятора:
- проверка переходов CPсостояний A→B→C, корректных значений напряжения CP,
- проверка, что `CCS_ConnectorState` и `CCS_EvseState` меняются ожидаемо (Preparing, Charging, Finished и т.п.);
- проверка обмена по `USART3`:
- корректный приём/передача пакетов с CRC16,
- реакция на команды Everest (ENABLE, START/STOP, PWM_DUTY, SET_OUTPUT_VOLTAGE, EV_INFO, EVSE_STATE, KEEP_ALIVE);
- проверка защиты:
- ESTOP/StopButton — немедленное отключение выхода и отправка `CCS_SendEmergencyStop()`;
- таймаут связи с хостом (`last_host_seen`) — перевод в безопасное состояние (отключение PSU, CP duty = 100%, лог `Everest timeout`).
- **Регрессионные проверки существующей функциональности**:
- веб‑страницы открываются, основные параметры (напряжение, ток, энергии, состояния коннектора) отображаются корректно;
- сохранены привычные логи/формат сообщений (насколько возможно) для удобства отладки.