big refactoring: J1939, log output, state machine bug fixes
This commit is contained in:
+1
-1
@@ -17,7 +17,7 @@ typedef enum{
|
||||
RELAY_3,
|
||||
RELAY_4,
|
||||
RELAY_5,
|
||||
|
||||
RELAY_CP,
|
||||
}relay_t;
|
||||
|
||||
typedef enum{
|
||||
|
||||
@@ -222,6 +222,7 @@ extern GBT_BSM_t GBT_BatteryStatus;
|
||||
extern GBT_CSD_t GBT_ChargerStop;
|
||||
|
||||
extern uint8_t GBT_BRO;
|
||||
extern uint8_t cc_enable;
|
||||
|
||||
extern uint8_t GBT_Charger_Enable;
|
||||
|
||||
@@ -254,6 +255,7 @@ void GBT_SendBRO(uint8_t state);
|
||||
void GBT_SendBCL(void);
|
||||
void GBT_SendBCS(void);
|
||||
void GBT_SendBSM(void);
|
||||
void GBT_SendBST(uint32_t causeCode);
|
||||
void GBT_SendBSD(void);
|
||||
|
||||
|
||||
|
||||
+23
-1
@@ -75,13 +75,35 @@ typedef struct {
|
||||
uint8_t connectorType; // 0 - NONE, 1 - GBT, 2 - CCS (для EV всегда GBT)
|
||||
} CONN_t;
|
||||
|
||||
extern CONN_t CONN;
|
||||
extern CONN_t CONN[2];
|
||||
|
||||
void CONN_Init();
|
||||
void CONN_Task();
|
||||
void CONN_SetState(CONN_State_t state);
|
||||
void CONN_CC_ReadStateFiltered(void);
|
||||
uint8_t CONN_CC_GetStateRaw();
|
||||
uint8_t CONN_CC_GetState();
|
||||
float CONN_CC_GetAdc();
|
||||
|
||||
// STM32(EV) -> EVerest (EVSE)
|
||||
// uint8_t SOC; // State of charge [%] // 2
|
||||
// uint16_t RequestedVoltage; // 1V/bit
|
||||
// uint16_t RequestedCurrent; // 0.1A/bit
|
||||
// uint16_t MeasuredVoltage; // 1V/bit
|
||||
// uint16_t MeasuredCurrent; // 0.1A/bit
|
||||
// uint8_t ContactorEnabled; // 1 - enabled, 0 - disabled (команда на замыкание контактора)
|
||||
|
||||
// cp_state
|
||||
// stop ????
|
||||
|
||||
|
||||
// EVerest (EVSE) -> STM32(EV)
|
||||
// uint16_t MeasuredVoltageSE; // 1V/bit
|
||||
// uint16_t MeasuredCurrentSE; // 0.1A/bit
|
||||
// uint8_t enableLoad; // 1 - enabled, 0 - disabled (команда на включение контактора)
|
||||
|
||||
// cp_state
|
||||
// pwm_value
|
||||
|
||||
|
||||
#endif /* INC_CONNECTOR_H_ */
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifndef INC_CP_H_
|
||||
#define INC_CP_H_
|
||||
|
||||
#include "main.h"
|
||||
|
||||
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;
|
||||
|
||||
typedef struct {
|
||||
uint32_t frequency_hz;
|
||||
uint8_t duty_percent;
|
||||
uint8_t valid;
|
||||
} CP_Measurement_t;
|
||||
|
||||
extern volatile CP_State_t cp_state;
|
||||
|
||||
void CP_Init(void);
|
||||
void CP_Task(void);
|
||||
CP_Measurement_t CP_GetMeasurement(void);
|
||||
|
||||
#endif /* INC_CP_H_ */
|
||||
+7
-3
@@ -8,9 +8,13 @@
|
||||
#ifndef SRC_DEBUG_H_
|
||||
#define SRC_DEBUG_H_
|
||||
|
||||
void debug_task();
|
||||
void debug_init();
|
||||
void debug_rx_interrupt(UART_HandleTypeDef *huart, uint16_t Size);
|
||||
#include <stdint.h>
|
||||
#include "edcan.h"
|
||||
|
||||
void debug_buffer_add(const uint8_t* data, uint16_t len);
|
||||
uint16_t debug_buffer_available(void);
|
||||
void debug_buffer_send(void);
|
||||
int log_printf(int level, const char *format, ...);
|
||||
|
||||
|
||||
#endif /* SRC_DEBUG_H_ */
|
||||
|
||||
@@ -27,11 +27,31 @@ typedef struct{
|
||||
uint32_t tick;
|
||||
}j_receive_t;
|
||||
|
||||
typedef struct{
|
||||
uint32_t ExtId;
|
||||
uint8_t DLC;
|
||||
uint8_t data[8];
|
||||
uint32_t tick;
|
||||
}j1939_rx_frame_t;
|
||||
|
||||
typedef struct{
|
||||
uint32_t ExtId;
|
||||
uint8_t DLC;
|
||||
uint8_t data[8];
|
||||
}j1939_tx_frame_t;
|
||||
|
||||
extern j_receive_t j_rx;
|
||||
|
||||
|
||||
void J_SendCTS(j_receive_t rx);
|
||||
void J_SendACK(j_receive_t rx);
|
||||
void J1939_ExchangeRxBuffer(void);
|
||||
void J1939_ExchangeTxBuffer(void);
|
||||
void J1939_InitBuffers(void);
|
||||
uint16_t J1939_GetRxBufferCount(void);
|
||||
uint16_t J1939_GetTxBufferCount(void);
|
||||
uint32_t J1939_GetRxOverflowCount(void);
|
||||
uint32_t J1939_GetTxOverflowCount(void);
|
||||
|
||||
|
||||
void GBT_CAN_ReInit();
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "main.h"
|
||||
|
||||
void LOAD_Init();
|
||||
void LOAD_Task();
|
||||
+16
-8
@@ -57,12 +57,20 @@ void Error_Handler(void);
|
||||
/* USER CODE END EFP */
|
||||
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
#define CP_STATE_F_Pin GPIO_PIN_2
|
||||
#define CP_STATE_F_GPIO_Port GPIOC
|
||||
#define CP_RELAY_Pin GPIO_PIN_3
|
||||
#define CP_RELAY_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_STATE_C_Pin GPIO_PIN_5
|
||||
#define CP_STATE_C_GPIO_Port GPIOA
|
||||
#define ADC_CC1_Pin GPIO_PIN_6
|
||||
#define ADC_CC1_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
|
||||
@@ -73,16 +81,16 @@ void Error_Handler(void);
|
||||
#define ADC_NTC2_GPIO_Port GPIOB
|
||||
#define IN0_Pin GPIO_PIN_7
|
||||
#define IN0_GPIO_Port GPIOE
|
||||
#define RELAY5_Pin GPIO_PIN_8
|
||||
#define RELAY5_GPIO_Port GPIOE
|
||||
#define RELAY4_Pin GPIO_PIN_9
|
||||
#define RELAY4_GPIO_Port GPIOE
|
||||
#define RELAY1_Pin GPIO_PIN_8
|
||||
#define RELAY1_GPIO_Port GPIOE
|
||||
#define RELAY2_Pin GPIO_PIN_9
|
||||
#define RELAY2_GPIO_Port GPIOE
|
||||
#define RELAY3_Pin GPIO_PIN_10
|
||||
#define RELAY3_GPIO_Port GPIOE
|
||||
#define RELAY2_Pin GPIO_PIN_11
|
||||
#define RELAY2_GPIO_Port GPIOE
|
||||
#define RELAY1_Pin GPIO_PIN_12
|
||||
#define RELAY1_GPIO_Port GPIOE
|
||||
#define RELAY4_Pin GPIO_PIN_11
|
||||
#define RELAY4_GPIO_Port GPIOE
|
||||
#define RELAY5_Pin GPIO_PIN_12
|
||||
#define RELAY5_GPIO_Port GPIOE
|
||||
#define AC_OK_Pin GPIO_PIN_14
|
||||
#define AC_OK_GPIO_Port GPIOE
|
||||
#define RELAY_CC_Pin GPIO_PIN_15
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
#ifndef SERIAL_CONTROL_H
|
||||
#define SERIAL_CONTROL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "main.h"
|
||||
#include "connector.h"
|
||||
|
||||
/* Read-only commands */
|
||||
#define CMD_GET_INFO 0x01
|
||||
#define CMD_ISOLATION_STATUS 0x01 /* UART5 isolation block packet */
|
||||
#define CMD_GET_GBT_STATUS 0x02
|
||||
#define CMD_GET_CCS_STATUS 0x03
|
||||
#define CMD_GET_LOG 0x50
|
||||
#define CMD_GET_LOG_CONTINUE 0x51
|
||||
|
||||
/* GBT control commands */
|
||||
#define CMD_GBT_CC_ENABLE 0x10
|
||||
#define CMD_GBT_STOP 0x11
|
||||
#define CMD_GBT_SET_SOC 0x12
|
||||
#define CMD_GBT_SET_REQUEST 0x13
|
||||
#define CMD_GBT_SET_VIN 0x18
|
||||
|
||||
/* CCS control commands */
|
||||
#define CMD_CCS_SET_STATE 0x20
|
||||
#define CMD_CCS_ENABLE_LOAD 0x24
|
||||
|
||||
/* Response codes */
|
||||
#define RESP_SUCCESS 0x12
|
||||
#define RESP_FAILED 0x13
|
||||
#define RESP_INVALID 0x14
|
||||
|
||||
#define MAX_TX_BUFFER_SIZE 256
|
||||
#define MAX_RX_BUFFER_SIZE 256
|
||||
#define CRC32_POLYNOMIAL ((uint32_t)0xEDB88320)
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t command;
|
||||
uint8_t argument_length;
|
||||
void *argument;
|
||||
} ReceivedCommand_t;
|
||||
|
||||
typedef enum {
|
||||
SC_SOURCE_UART2 = 0,
|
||||
SC_SOURCE_UART5 = 1,
|
||||
} SC_Source_t;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t isolationStatus;
|
||||
uint16_t isolationResistance;
|
||||
int16_t voltageHigh;
|
||||
int16_t voltageLow;
|
||||
int16_t voltageComm;
|
||||
} IsolationStatusPacket_t;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint16_t requestedVoltage; /* 1V/bit */
|
||||
uint16_t requestedCurrent; /* 0.1A/bit */
|
||||
} EvSetLimits_t;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint16_t measuredVoltage; /* 1V/bit */
|
||||
uint16_t measuredCurrent; /* 0.1A/bit */
|
||||
} EvSetMeasured_t;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t connector_type; /* 0x01 (GBT) */
|
||||
uint16_t requestedVoltage; /* V */
|
||||
uint16_t requestedCurrent; /* 0.1A/bit */
|
||||
uint16_t measuredVoltageSE; /* V */
|
||||
uint16_t measuredCurrentSE; /* 0.1A/bit */
|
||||
uint16_t measuredVoltage; /* 1V/bit */
|
||||
uint16_t measuredCurrent; /* 0.1A/bit */
|
||||
uint8_t cc_enabled;
|
||||
uint8_t contactorEnabled;
|
||||
CONN_Error_t chargingError;
|
||||
uint8_t EvseConnected;
|
||||
uint8_t soc; /* % */
|
||||
uint8_t vin[17];
|
||||
uint8_t cc_state;
|
||||
uint8_t logs_available;
|
||||
CONN_State_t connState;
|
||||
} GBT_MonitorPacket_t;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t connector_type; /* 0x02 (CCS) */
|
||||
uint16_t measuredVoltage; /* 1V/bit */
|
||||
uint16_t measuredCurrent; /* 0.1A/bit */
|
||||
uint8_t cp_enabled;
|
||||
uint8_t contactorEnabled;
|
||||
CONN_Error_t chargingError;
|
||||
uint8_t EvseConnected;
|
||||
uint8_t soc; /* % */
|
||||
uint8_t cp_state; /* A/B/C/D/E/... enum value */
|
||||
uint8_t cp_pwm_duty; /* % */
|
||||
CONN_State_t connState;
|
||||
} CCS_MonitorPacket_t;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint16_t serialNumber;
|
||||
uint8_t boardVersion;
|
||||
uint8_t stationType;
|
||||
uint16_t fw_version_major;
|
||||
uint16_t fw_version_minor;
|
||||
uint16_t fw_version_patch;
|
||||
} InfoPacket_t;
|
||||
|
||||
typedef struct SerialControl_t SerialControl_t;
|
||||
struct SerialControl_t {
|
||||
uint8_t tx_buffer[MAX_TX_BUFFER_SIZE];
|
||||
uint8_t rx_buffer[MAX_RX_BUFFER_SIZE];
|
||||
volatile ReceivedCommand_t received_command;
|
||||
volatile uint8_t command_ready;
|
||||
volatile uint8_t response_pending;
|
||||
volatile uint8_t response_code;
|
||||
volatile uint32_t tx_tick;
|
||||
};
|
||||
|
||||
void SC_Init(void);
|
||||
void SC_Task(void);
|
||||
void SC_SendPacket(const uint8_t *payload, uint16_t payload_len, uint8_t response_code);
|
||||
void SC_CommandHandler(ReceivedCommand_t *cmd);
|
||||
|
||||
extern SerialControl_t serial_control;
|
||||
extern GBT_MonitorPacket_t gbtMonitorPacket;
|
||||
extern CCS_MonitorPacket_t ccsMonitorPacket;
|
||||
extern InfoPacket_t infoPacket;
|
||||
extern IsolationStatusPacket_t ISO;
|
||||
extern volatile SC_Source_t g_sc_command_source;
|
||||
|
||||
#endif /* SERIAL_CONTROL_H */
|
||||
@@ -56,7 +56,9 @@ void DebugMon_Handler(void);
|
||||
void PendSV_Handler(void);
|
||||
void SysTick_Handler(void);
|
||||
void CAN1_RX0_IRQHandler(void);
|
||||
void TIM3_IRQHandler(void);
|
||||
void USART2_IRQHandler(void);
|
||||
void UART5_IRQHandler(void);
|
||||
void CAN2_TX_IRQHandler(void);
|
||||
void CAN2_RX1_IRQHandler(void);
|
||||
/* USER CODE BEGIN EFP */
|
||||
|
||||
@@ -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);
|
||||
|
||||
+4
-2
@@ -85,11 +85,12 @@ void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
/**ADC1 GPIO Configuration
|
||||
PA3 ------> ADC1_IN3
|
||||
PA4 ------> ADC1_IN4
|
||||
PA6 ------> ADC1_IN6
|
||||
PB0 ------> ADC1_IN8
|
||||
PB1 ------> ADC1_IN9
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_3|ADC_CC1_Pin;
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4|ADC_CC1_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
@@ -116,11 +117,12 @@ void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle)
|
||||
|
||||
/**ADC1 GPIO Configuration
|
||||
PA3 ------> ADC1_IN3
|
||||
PA4 ------> ADC1_IN4
|
||||
PA6 ------> ADC1_IN6
|
||||
PB0 ------> ADC1_IN8
|
||||
PB1 ------> ADC1_IN9
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_3|ADC_CC1_Pin);
|
||||
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_3|GPIO_PIN_4|ADC_CC1_Pin);
|
||||
|
||||
HAL_GPIO_DeInit(GPIOB, ADC_NTC1_Pin|ADC_NTC2_Pin);
|
||||
|
||||
|
||||
+3
-1
@@ -20,6 +20,7 @@ void RELAY_Write(relay_t num, uint8_t state){
|
||||
if(num==RELAY_4)HAL_GPIO_WritePin(RELAY4_GPIO_Port, RELAY4_Pin, state);
|
||||
if(num==RELAY_5)HAL_GPIO_WritePin(RELAY5_GPIO_Port, RELAY5_Pin, state);
|
||||
if(num==RELAY_CC)HAL_GPIO_WritePin(RELAY_CC_GPIO_Port, RELAY_CC_Pin, state);
|
||||
if(num==RELAY_CP)HAL_GPIO_WritePin(CP_RELAY_GPIO_Port, CP_RELAY_Pin, state);
|
||||
|
||||
}
|
||||
|
||||
@@ -74,7 +75,8 @@ void Init_Peripheral(){
|
||||
RELAY_Write(RELAY_3, 0);
|
||||
RELAY_Write(RELAY_4, 0);
|
||||
RELAY_Write(RELAY_5, 0);
|
||||
RELAY_Write(RELAY_CC, 1);
|
||||
RELAY_Write(RELAY_CC, 0);
|
||||
RELAY_Write(RELAY_CP, 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
+98
-43
@@ -15,6 +15,7 @@
|
||||
#include "edcan.h"
|
||||
#include "connector.h"
|
||||
#include "soft_rtc.h"
|
||||
#include "debug.h"
|
||||
|
||||
uint8_t GBT_CC_GetStateRaw();
|
||||
|
||||
@@ -49,6 +50,7 @@ GBT_CCS_t GBT_ChargerCurrentStatus;
|
||||
GBT_CSD_t GBT_ChargerStop;
|
||||
|
||||
uint8_t GBT_BRO;
|
||||
uint8_t cc_enable;
|
||||
|
||||
uint32_t GBT_TimeChargingStarted;
|
||||
|
||||
@@ -57,17 +59,28 @@ uint32_t GBT_ErrorCode;
|
||||
|
||||
GBT_StopSource_t GBT_StopSource;
|
||||
|
||||
static uint32_t GBT_EVSE_last_rx_tick;
|
||||
|
||||
#define GBT_EV_HANDSHAKE_TIMEOUT_MS 10000U
|
||||
#define GBT_EV_WAIT_READY_TIMEOUT_MS 10000U
|
||||
#define GBT_EV_CHARGING_RX_TIMEOUT_MS 3000U
|
||||
|
||||
void GBT_Init(){
|
||||
GBT_State = GBT_DISABLED;
|
||||
CONN.connControl = CMD_NONE;
|
||||
CONN[0].connControl = CMD_NONE;
|
||||
cc_enable = 0U;
|
||||
memcpy(GBT_EVInfo.EVIN, "EDISON_TEST_EVIN_", 17);
|
||||
memcpy(GBT_EVInfo.EV_SW_VER, "1.0.0", 8);
|
||||
GBT_Reset();
|
||||
}
|
||||
|
||||
|
||||
void GBT_ChargerTask(){
|
||||
RELAY_Write(RELAY_CC, cc_enable);
|
||||
|
||||
//GBT_LockTask();
|
||||
if(j_rx.state == 2){
|
||||
GBT_EVSE_last_rx_tick = HAL_GetTick();
|
||||
switch (j_rx.PGN){
|
||||
case 0x2600: // CHM EVSE->EV (старт/версия GB/T)
|
||||
GBT_CHM_recv = 1;
|
||||
@@ -93,10 +106,12 @@ void GBT_ChargerTask(){
|
||||
|
||||
case 0x1200: // CCS EVSE->EV (текущий статус зарядника)
|
||||
memcpy(&GBT_ChargerCurrentStatus, j_rx.data, sizeof(GBT_ChargerCurrentStatus));
|
||||
CONN.enableLoad = GBT_ChargerCurrentStatus.chargingPermissible;
|
||||
CONN.ChargingTime = GBT_ChargerCurrentStatus.chargingTime;
|
||||
CONN.MeasuredVoltageSE = GBT_ChargerCurrentStatus.outputVoltage / 10;
|
||||
CONN.MeasuredCurrentSE = 4000 - GBT_ChargerCurrentStatus.outputCurrent;
|
||||
if(GBT_State == GBT_EV_CHARGING) {
|
||||
CONN[0].enableLoad = GBT_ChargerCurrentStatus.chargingPermissible;
|
||||
}
|
||||
CONN[0].ChargingTime = GBT_ChargerCurrentStatus.chargingTime;
|
||||
CONN[0].MeasuredVoltageSE = GBT_ChargerCurrentStatus.outputVoltage / 10;
|
||||
CONN[0].MeasuredCurrentSE = 4000 - GBT_ChargerCurrentStatus.outputCurrent;
|
||||
break;
|
||||
|
||||
case 0x1A00: // CST EVSE->EV (остановка зарядки по инициативе EVSE)
|
||||
@@ -115,11 +130,18 @@ void GBT_ChargerTask(){
|
||||
j_rx.state = 0;
|
||||
}
|
||||
|
||||
if((connectorState == Unplugged) && (GBT_State != GBT_DISABLED)){
|
||||
log_printf(LOG_INFO, "Car unplugged, resetting charge session\n");
|
||||
CONN[0].enableLoad = 0;
|
||||
GBT_Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
if((HAL_GetTick() - GBT_delay_start) < GBT_delay){
|
||||
//waiting
|
||||
}else switch (GBT_State){
|
||||
case GBT_DISABLED:
|
||||
CONN.enableLoad = 0;
|
||||
CONN[0].enableLoad = 0;
|
||||
// if(connectorState == Preparing){
|
||||
// GBT_Reset();
|
||||
// GBT_SwitchState(GBT_EV_CONNECTING);
|
||||
@@ -133,25 +155,31 @@ void GBT_ChargerTask(){
|
||||
GBT_Delay(250);
|
||||
|
||||
if (GBT_CHM_recv) {
|
||||
log_printf(LOG_INFO, "CHM received, starting EV handshake\n");
|
||||
GBT_SwitchState(GBT_EV_HANDSHAKE);
|
||||
break;
|
||||
}
|
||||
if (GBT_StateTick() > 10000) {
|
||||
GBT_Error(0xFCF0C0FC);
|
||||
EDCAN_printf(LOG_WARN, "CHM timeout\n");
|
||||
log_printf(LOG_WARN, "CHM timeout\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case GBT_EV_HANDSHAKE:
|
||||
// 2) Постоянно шлём BHM, ждём CRM (0x0100, первый раз 0x00)
|
||||
GBT_MaxVoltage.maxOutputVoltage = 4500; // 450V
|
||||
GBT_MaxVoltage.maxOutputVoltage = CONN[0].RequestedVoltage * 10;
|
||||
if (j_rx.state == 0) GBT_SendBHM();
|
||||
GBT_Delay(250);
|
||||
|
||||
if (GBT_CRM_recv) {
|
||||
log_printf(LOG_INFO, "CRM received, sending BRM (EV identification)\n");
|
||||
GBT_SwitchState(GBT_EV_RECOGNITION);
|
||||
break;
|
||||
}
|
||||
if (GBT_StateTick() > GBT_EV_HANDSHAKE_TIMEOUT_MS) {
|
||||
GBT_Error(0xFCF0C0FD);
|
||||
log_printf(LOG_WARN, "CRM timeout in EV_HANDSHAKE\n");
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -171,19 +199,18 @@ void GBT_ChargerTask(){
|
||||
GBT_EVInfo.batteryCycleCount = 666;
|
||||
GBT_EVInfo.ownAuto = 1;
|
||||
GBT_EVInfo.rsvd0 = 0;
|
||||
memcpy(GBT_EVInfo.EVIN, "EDISON_TEST_EVIN_", 17);
|
||||
memcpy(GBT_EVInfo.EV_SW_VER, "1.0.0", 8);
|
||||
|
||||
if (j_rx.state == 0) GBT_SendBRM(); // TODO CHUNKED SEND
|
||||
GBT_Delay(250);
|
||||
|
||||
if ((GBT_CRM_recv) && (GBT_ChargerInfo.bmsIdentified == 0xAA)) {
|
||||
log_printf(LOG_INFO, "EV identified by charger, sending BCP\n");
|
||||
GBT_SwitchState(GBT_EV_CHARGING_PARAMETERS);
|
||||
break;
|
||||
}
|
||||
if (GBT_StateTick() > 5000) {
|
||||
GBT_Error(0xFCF1C0FC);
|
||||
EDCAN_printf(LOG_WARN, "CRM(0xAA) timeout (wait BCP)\n");
|
||||
log_printf(LOG_WARN, "CRM(0xAA) timeout (wait BCP)\n");
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -193,12 +220,13 @@ void GBT_ChargerTask(){
|
||||
GBT_Delay(250);
|
||||
|
||||
if (GBT_CML_recv) {
|
||||
log_printf(LOG_INFO, "CML received, starting BMS initialization\n");
|
||||
GBT_SwitchState(GBT_EV_BMS_INIT);
|
||||
break;
|
||||
}
|
||||
if (GBT_StateTick() > 5000) {
|
||||
GBT_Error(0xFCF4C0FC);
|
||||
EDCAN_printf(LOG_WARN, "CML timeout\n");
|
||||
log_printf(LOG_WARN, "CML timeout\n");
|
||||
}
|
||||
break;
|
||||
case GBT_EV_BMS_INIT:
|
||||
@@ -206,6 +234,7 @@ void GBT_ChargerTask(){
|
||||
if (j_rx.state == 0) GBT_SendBRO(0x00);
|
||||
GBT_Delay(250);
|
||||
if (GBT_StateTick() > 1500) {
|
||||
log_printf(LOG_INFO, "BMS initialized, waiting charger ready signal\n");
|
||||
GBT_SwitchState(GBT_EV_WAIT_CHARGER_READY);
|
||||
break;
|
||||
}
|
||||
@@ -219,17 +248,23 @@ void GBT_ChargerTask(){
|
||||
GBT_Delay(250);
|
||||
|
||||
if (GBT_CRO_val == 0xAA) {
|
||||
log_printf(LOG_INFO, "Charger ready, entering active charging\n");
|
||||
GBT_SwitchState(GBT_EV_CHARGING);
|
||||
GBT_TimeChargingStarted = get_Current_Time();
|
||||
GBT_EVSE_last_rx_tick = HAL_GetTick();
|
||||
break;
|
||||
}
|
||||
if (GBT_StateTick() > GBT_EV_WAIT_READY_TIMEOUT_MS) {
|
||||
GBT_Error(0xFCF2C0FD);
|
||||
log_printf(LOG_WARN, "CRO(0xAA) timeout in EV_WAIT_CHARGER_READY\n");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case GBT_EV_CHARGING:
|
||||
// Основной режим зарядки: EV периодически шлёт BCS/BSM.
|
||||
GBT_ReqPower.requestedVoltage = CONN.RequestedVoltage * 10;
|
||||
GBT_ReqPower.requestedCurrent = 4000 - CONN.RequestedCurrent;
|
||||
GBT_ReqPower.requestedVoltage = CONN[0].RequestedVoltage * 10;
|
||||
GBT_ReqPower.requestedCurrent = 4000 - CONN[0].RequestedCurrent;
|
||||
GBT_ReqPower.chargingMode = 1;
|
||||
|
||||
GBT_BATStat.maxCellVoltage = 320;
|
||||
@@ -237,23 +272,32 @@ void GBT_ChargerTask(){
|
||||
GBT_BATStat.totalEnergy = 6;
|
||||
GBT_BATStat.maxChargingVoltage = 500;
|
||||
GBT_BATStat.maxTemp = 70;
|
||||
GBT_BATStat.SOC = CONN.SOC;
|
||||
GBT_BATStat.measVoltage = CONN.MeasuredVoltage;
|
||||
GBT_BATStat.SOC = CONN[0].SOC;
|
||||
GBT_BATStat.measVoltage = CONN[0].MeasuredVoltage;
|
||||
|
||||
// Стоп по инициативе EVSE (получили CST)
|
||||
if (GBT_CST_recv) {
|
||||
log_printf(LOG_INFO, "Charging stop requested by EVSE (CST)\n");
|
||||
GBT_StopEVSE(GBT_CST_SUDDENSTOP);
|
||||
break;
|
||||
}
|
||||
// Стоп по команде с машины (EDCAN)
|
||||
if (CONN.connControl == CMD_STOP) {
|
||||
if (CONN[0].connControl == CMD_STOP) {
|
||||
CONN[0].connControl = CMD_NONE;
|
||||
log_printf(LOG_INFO, "Charging stop requested by EV command\n");
|
||||
GBT_StopEV(GBT_CST_BMS_ACTIVELY_SUSPENDS);
|
||||
break;
|
||||
}
|
||||
if (IN_ReadInput(IN_ESTOP)) {
|
||||
log_printf(LOG_INFO, "Charging stop requested by emergency input\n");
|
||||
GBT_StopEV(GBT_CST_BMS_ACTIVELY_SUSPENDS);
|
||||
break;
|
||||
}
|
||||
if ((HAL_GetTick() - GBT_EVSE_last_rx_tick) > GBT_EV_CHARGING_RX_TIMEOUT_MS) {
|
||||
log_printf(LOG_WARN, "EVSE RX timeout in EV_CHARGING\n");
|
||||
GBT_StopEVSE(GBT_CST_SUDDENSTOP);
|
||||
break;
|
||||
}
|
||||
|
||||
GBT_SendBCS();
|
||||
GBT_SendBCL();
|
||||
@@ -263,14 +307,23 @@ void GBT_ChargerTask(){
|
||||
|
||||
case GBT_STOP:
|
||||
GBT_Delay(10);
|
||||
CONN.enableLoad = 0;
|
||||
// EV шлёт BSD (Battery Stop Data), не CST (CST шлёт EVSE)
|
||||
GBT_SendBSD();
|
||||
CONN[0].enableLoad = 0;
|
||||
if (GBT_StopSource == GBT_STOP_EV) {
|
||||
// EV-инициированный stop: сначала BST, ждём ответный CST, потом BSD.
|
||||
GBT_SendBST(GBT_StopCauseCode);
|
||||
if (GBT_CST_recv) {
|
||||
GBT_SendBSD();
|
||||
}
|
||||
} else {
|
||||
// EVSE-инициированный stop: EV сразу отвечает BSD.
|
||||
GBT_SendBSD();
|
||||
}
|
||||
if (GBT_StateTick() > 10000) {
|
||||
EDCAN_printf(LOG_WARN, "CSD Timeout\n");
|
||||
log_printf(LOG_WARN, "CSD Timeout\n");
|
||||
GBT_Error(0xFCF0C0FD); // CSD timeout
|
||||
}
|
||||
if (GBT_CSD_recv) {
|
||||
log_printf(LOG_INFO, "CSD received, finalizing charge session\n");
|
||||
GBT_SwitchState(GBT_STOP_CSD);
|
||||
}
|
||||
break;
|
||||
@@ -279,6 +332,7 @@ void GBT_ChargerTask(){
|
||||
// EV не шлёт CSD (финальный отчёт шлёт EVSE). Ждём 2.5 с и завершаем.
|
||||
GBT_Delay(250);
|
||||
if (GBT_StateTick() > 2500) {
|
||||
log_printf(LOG_INFO, "Charge session completed\n");
|
||||
GBT_SwitchState(GBT_COMPLETE);
|
||||
}
|
||||
break;
|
||||
@@ -301,8 +355,8 @@ void GBT_ChargerTask(){
|
||||
default:
|
||||
GBT_SwitchState(GBT_DISABLED);
|
||||
}
|
||||
if (CONN_CC_GetState()==GBT_CC_4V) CONN.EvseConnected = 1;
|
||||
else CONN.EvseConnected = 0;
|
||||
if (CONN_CC_GetState()==GBT_CC_4V) CONN[0].EvseConnected = 1;
|
||||
else CONN[0].EvseConnected = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -311,18 +365,18 @@ void GBT_SwitchState(gbtState_t state){
|
||||
GBT_State = state;
|
||||
GBT_state_tick = HAL_GetTick();
|
||||
|
||||
if(GBT_State == GBT_DISABLED) EDCAN_printf(LOG_INFO, "GBT_DISABLED\n");
|
||||
if(GBT_State == GBT_EV_CONNECTING) EDCAN_printf(LOG_INFO, "GBT_EV_CONNECTING\n");
|
||||
if(GBT_State == GBT_EV_HANDSHAKE) EDCAN_printf(LOG_INFO, "GBT_EV_HANDSHAKE\n");
|
||||
if(GBT_State == GBT_EV_RECOGNITION) EDCAN_printf(LOG_INFO, "GBT_EV_RECOGNITION\n");
|
||||
if(GBT_State == GBT_EV_CHARGING_PARAMETERS) EDCAN_printf(LOG_INFO, "GBT_EV_CHARGING_PARAMETERS\n");
|
||||
if(GBT_State == GBT_EV_BMS_INIT) EDCAN_printf(LOG_INFO, "GBT_EV_BMS_INIT\n");
|
||||
if(GBT_State == GBT_EV_WAIT_CHARGER_READY) EDCAN_printf(LOG_INFO, "GBT_EV_WAIT_CHARGER_READY\n");
|
||||
if(GBT_State == GBT_EV_CHARGING) EDCAN_printf(LOG_INFO, "GBT_EV_CHARGING\n");
|
||||
if(GBT_State == GBT_STOP) EDCAN_printf(LOG_INFO, "GBT_STOP\n");
|
||||
if(GBT_State == GBT_STOP_CSD) EDCAN_printf(LOG_INFO, "GBT_STOP_CSD\n");
|
||||
if(GBT_State == GBT_ERROR) EDCAN_printf(LOG_WARN, "GBT_ERROR\n");
|
||||
if(GBT_State == GBT_COMPLETE) EDCAN_printf(LOG_INFO, "GBT_COMPLETE\n");
|
||||
if(GBT_State == GBT_DISABLED) log_printf(LOG_DEBUG, "DBG_STATE: GBT_DISABLED\n");
|
||||
if(GBT_State == GBT_EV_CONNECTING) log_printf(LOG_DEBUG, "DBG_STATE: GBT_EV_CONNECTING\n");
|
||||
if(GBT_State == GBT_EV_HANDSHAKE) log_printf(LOG_DEBUG, "DBG_STATE: GBT_EV_HANDSHAKE\n");
|
||||
if(GBT_State == GBT_EV_RECOGNITION) log_printf(LOG_DEBUG, "DBG_STATE: GBT_EV_RECOGNITION\n");
|
||||
if(GBT_State == GBT_EV_CHARGING_PARAMETERS) log_printf(LOG_DEBUG, "DBG_STATE: GBT_EV_CHARGING_PARAMETERS\n");
|
||||
if(GBT_State == GBT_EV_BMS_INIT) log_printf(LOG_DEBUG, "DBG_STATE: GBT_EV_BMS_INIT\n");
|
||||
if(GBT_State == GBT_EV_WAIT_CHARGER_READY) log_printf(LOG_DEBUG, "DBG_STATE: GBT_EV_WAIT_CHARGER_READY\n");
|
||||
if(GBT_State == GBT_EV_CHARGING) log_printf(LOG_DEBUG, "DBG_STATE: GBT_EV_CHARGING\n");
|
||||
if(GBT_State == GBT_STOP) log_printf(LOG_DEBUG, "DBG_STATE: GBT_STOP\n");
|
||||
if(GBT_State == GBT_STOP_CSD) log_printf(LOG_DEBUG, "DBG_STATE: GBT_STOP_CSD\n");
|
||||
if(GBT_State == GBT_COMPLETE) log_printf(LOG_DEBUG, "DBG_STATE: GBT_COMPLETE\n");
|
||||
if(GBT_State == GBT_ERROR) log_printf(LOG_WARN, "State machine entered ERROR state\n");
|
||||
|
||||
|
||||
}
|
||||
@@ -337,7 +391,7 @@ void GBT_Delay(uint32_t delay){
|
||||
}
|
||||
|
||||
void GBT_StopEV(uint32_t causecode){ // --> Suspend EV
|
||||
if (CONN.chargingError){
|
||||
if (CONN[0].chargingError){
|
||||
GBT_StopSource = GBT_STOP_EVSE;
|
||||
}else{
|
||||
GBT_StopSource = GBT_STOP_EV;
|
||||
@@ -361,13 +415,13 @@ void GBT_StopOCPP(uint32_t causecode){ // --> Finished
|
||||
void GBT_ForceStop(){ // --> Suspend EV
|
||||
GBT_StopSource = GBT_STOP_EV;
|
||||
// Отключаем силовой контактор батареи со стороны EV
|
||||
CONN.enableLoad = 0;
|
||||
CONN[0].enableLoad = 0;
|
||||
GBT_SwitchState(GBT_COMPLETE);
|
||||
}
|
||||
|
||||
void GBT_Error(uint32_t errorcode){ // --> Suspend EV
|
||||
GBT_StopSource = GBT_STOP_EV;
|
||||
EDCAN_printf(LOG_WARN, "GBT Error code: 0x%X\n", errorcode);
|
||||
log_printf(LOG_WARN, "GBT Error code: 0x%X\n", errorcode);
|
||||
GBT_ErrorCode = errorcode;
|
||||
GBT_SwitchState(GBT_ERROR);
|
||||
}
|
||||
@@ -381,11 +435,11 @@ void GBT_Reset(){
|
||||
GBT_CST_recv = 0;
|
||||
GBT_CSD_recv = 0;
|
||||
GBT_CRO_val = 0x00;
|
||||
CONN.SOC = 0;
|
||||
CONN.enableLoad = 0;
|
||||
CONN.RequestedCurrent = 1000;
|
||||
CONN.RequestedVoltage = 400;
|
||||
CONN.chargingError = 0;
|
||||
CONN[0].SOC = 0;
|
||||
CONN[0].enableLoad = 0;
|
||||
CONN[0].RequestedCurrent = 1000;
|
||||
CONN[0].RequestedVoltage = 400;
|
||||
CONN[0].chargingError = 0;
|
||||
memset(&GBT_EVInfo, 0, sizeof (GBT_EVInfo));
|
||||
memset(&GBT_BATStat, 0, sizeof (GBT_BATStat));
|
||||
memset(&GBT_ReqPower, 0, sizeof (GBT_ReqPower));
|
||||
@@ -399,4 +453,5 @@ void GBT_Reset(){
|
||||
GBT_CurrPower.requestedVoltage = 500; //50V
|
||||
GBT_TimeChargingStarted = 0;
|
||||
GBT_BRO = 0x00;
|
||||
GBT_EVSE_last_rx_tick = HAL_GetTick();
|
||||
}
|
||||
|
||||
+34
-24
@@ -7,12 +7,14 @@
|
||||
#include "connector.h"
|
||||
#include "board.h"
|
||||
#include "edcan.h"
|
||||
#include "debug.h"
|
||||
#include <string.h>
|
||||
#include <charger_gbt.h>
|
||||
|
||||
|
||||
CONN_State_t connectorState;
|
||||
CONN_t CONN;
|
||||
// CONN[0] - GB/T, CONN[1] - CCS (reserved for future use)
|
||||
CONN_t CONN[2];
|
||||
|
||||
uint8_t CC_STATE_FILTERED;
|
||||
|
||||
@@ -20,19 +22,18 @@ static void CONN_UpdateEdcanOutput(void);
|
||||
|
||||
void CONN_Init(){
|
||||
memset(&CONN, 0, sizeof(CONN));
|
||||
CONN.connControl = CMD_NONE;
|
||||
CONN[0].connControl = CMD_NONE;
|
||||
CONN_SetState(Unknown);
|
||||
}
|
||||
|
||||
void CONN_Task(){
|
||||
|
||||
switch (connectorState){
|
||||
case Unknown:
|
||||
CONN_SetState(Unplugged);
|
||||
break;
|
||||
|
||||
case Disabled:
|
||||
if(CONN.chargingError == 0) {
|
||||
if(CONN[0].chargingError == 0) {
|
||||
CONN_SetState(Unplugged);
|
||||
}
|
||||
break;
|
||||
@@ -40,10 +41,11 @@ void CONN_Task(){
|
||||
{
|
||||
// Обновляем признак физического подключения разъёма по уровню CC
|
||||
if(CONN_CC_GetState() == GBT_CC_4V){
|
||||
CONN.EvseConnected = 1;
|
||||
CONN[0].EvseConnected = 1;
|
||||
log_printf(LOG_INFO, "Charger plugged, waiting for 12V AUX\n");
|
||||
CONN_SetState(AuthRequired);
|
||||
}else{
|
||||
CONN.EvseConnected = 0;
|
||||
CONN[0].EvseConnected = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -52,6 +54,7 @@ void CONN_Task(){
|
||||
{
|
||||
// Если уровень CC вернулся к 6/12В – считаем, что коннектор выдернули
|
||||
if(CONN_CC_GetState() != GBT_CC_4V){
|
||||
log_printf(LOG_INFO, "Charger unplugged\n");
|
||||
CONN_SetState(Unplugged);
|
||||
GBT_Reset();
|
||||
break;
|
||||
@@ -59,6 +62,7 @@ void CONN_Task(){
|
||||
|
||||
// Как только появляется 12V AUX от станции – переходим в Preparing (инициализация протокола)
|
||||
if(IN_ReadInput(IN_0) == 1){
|
||||
log_printf(LOG_INFO, "12V AUX detected, starting session\n");
|
||||
CONN_SetState(Preparing);
|
||||
GBT_SwitchState(GBT_EV_CONNECTING);
|
||||
}
|
||||
@@ -69,11 +73,15 @@ void CONN_Task(){
|
||||
// Ожидаем переход стейт-машины GB/T в режим зарядки.
|
||||
// Как только GBT_State уходит в режим CHARGING – считаем, что начался заряд.
|
||||
if(GBT_State == GBT_EV_CHARGING){
|
||||
log_printf(LOG_INFO, "Charging started\n");
|
||||
CONN_SetState(Charging);
|
||||
}
|
||||
if(IN_ReadInput(IN_0) == 0){
|
||||
CONN_SetState(Unplugged);
|
||||
GBT_Reset();
|
||||
// if(IN_ReadInput(IN_0) == 0){
|
||||
// CONN_SetState(Unplugged);
|
||||
// GBT_Reset();
|
||||
// }
|
||||
if(GBT_State == GBT_DISABLED){
|
||||
CONN_SetState(Finished);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -84,6 +92,7 @@ void CONN_Task(){
|
||||
CONN_SetState(Finished);
|
||||
}
|
||||
if(IN_ReadInput(IN_0) == 0){
|
||||
log_printf(LOG_INFO, "12V AUX removed, finishing session\n");
|
||||
CONN_SetState(Finished);
|
||||
}
|
||||
break;
|
||||
@@ -91,6 +100,7 @@ void CONN_Task(){
|
||||
case Finished: // Сессия завершена, ждём окончания и возможного переподключения
|
||||
// Когда GB/T стейт-машина полностью вернулась в исходное состояние,
|
||||
// можно считать сессию закрытой и вернуться в Unplugged.
|
||||
cc_enable = 0;
|
||||
if(CONN_CC_GetState() != GBT_CC_4V){
|
||||
CONN_SetState(Unplugged);
|
||||
GBT_Reset();
|
||||
@@ -111,22 +121,22 @@ void CONN_Task(){
|
||||
|
||||
void CONN_SetState(CONN_State_t state){
|
||||
connectorState = state;
|
||||
CONN.connState = state;
|
||||
CONN[0].connState = state;
|
||||
|
||||
if(connectorState == Unknown) EDCAN_printf(LOG_INFO,"Unknown\n");
|
||||
if(connectorState == Unplugged) EDCAN_printf(LOG_INFO,"Unplugged\n");
|
||||
if(connectorState == Disabled) EDCAN_printf(LOG_INFO,"Disabled\n");
|
||||
if(connectorState == Preparing) EDCAN_printf(LOG_INFO,"Preparing\n");
|
||||
if(connectorState == AuthRequired) EDCAN_printf(LOG_INFO,"AuthRequired\n");
|
||||
if(connectorState == WaitingForEnergy) EDCAN_printf(LOG_INFO,"WaitingForEnergy\n");
|
||||
if(connectorState == ChargingPausedEV) EDCAN_printf(LOG_INFO,"ChargingPausedEV\n");
|
||||
if(connectorState == ChargingPausedEVSE) EDCAN_printf(LOG_INFO,"ChargingPausedEVSE\n");
|
||||
if(connectorState == Charging) EDCAN_printf(LOG_INFO,"Charging\n");
|
||||
if(connectorState == AuthTimeout) EDCAN_printf(LOG_INFO,"AuthTimeout\n");
|
||||
if(connectorState == Finished) EDCAN_printf(LOG_INFO,"Finished\n");
|
||||
if(connectorState == FinishedEVSE) EDCAN_printf(LOG_INFO,"FinishedEVSE\n");
|
||||
if(connectorState == FinishedEV) EDCAN_printf(LOG_INFO,"FinishedEV\n");
|
||||
if(connectorState == Replugging) EDCAN_printf(LOG_INFO,"Replugging\n");
|
||||
if(connectorState == Unknown) log_printf(LOG_DEBUG,"ConnState: Unknown\n");
|
||||
if(connectorState == Unplugged) log_printf(LOG_DEBUG,"ConnState: Unplugged\n");
|
||||
if(connectorState == Disabled) log_printf(LOG_DEBUG,"ConnState: Disabled\n");
|
||||
if(connectorState == Preparing) log_printf(LOG_DEBUG,"ConnState: Preparing\n");
|
||||
if(connectorState == AuthRequired) log_printf(LOG_DEBUG,"ConnState: AuthRequired\n");
|
||||
if(connectorState == WaitingForEnergy) log_printf(LOG_DEBUG,"ConnState: WaitingForEnergy\n");
|
||||
if(connectorState == ChargingPausedEV) log_printf(LOG_DEBUG,"ConnState: ChargingPausedEV\n");
|
||||
if(connectorState == ChargingPausedEVSE) log_printf(LOG_DEBUG,"ConnState: ChargingPausedEVSE\n");
|
||||
if(connectorState == Charging) log_printf(LOG_DEBUG,"ConnState: Charging\n");
|
||||
if(connectorState == AuthTimeout) log_printf(LOG_DEBUG,"ConnState: AuthTimeout\n");
|
||||
if(connectorState == Finished) log_printf(LOG_DEBUG,"ConnState: Finished\n");
|
||||
if(connectorState == FinishedEVSE) log_printf(LOG_DEBUG,"ConnState: FinishedEVSE\n");
|
||||
if(connectorState == FinishedEV) log_printf(LOG_DEBUG,"ConnState: FinishedEV\n");
|
||||
if(connectorState == Replugging) log_printf(LOG_DEBUG,"ConnState: Replugging\n");
|
||||
|
||||
}
|
||||
|
||||
|
||||
+194
@@ -0,0 +1,194 @@
|
||||
#include "cp.h"
|
||||
#include "tim.h"
|
||||
|
||||
#define CP_CAPTURE_TARGET_CLK_HZ 1000000U
|
||||
#define CP_INPUT_SIGNAL_INVERTED 1U
|
||||
|
||||
typedef enum {
|
||||
CP_WAIT_RISING_1 = 0,
|
||||
CP_WAIT_FALLING,
|
||||
CP_WAIT_RISING_2
|
||||
} CP_CaptureState_t;
|
||||
|
||||
static volatile CP_CaptureState_t cp_capture_state = CP_WAIT_RISING_1;
|
||||
static volatile uint32_t cp_rise_1 = 0;
|
||||
static volatile uint32_t cp_fall = 0;
|
||||
static volatile uint32_t cp_rise_2 = 0;
|
||||
static volatile uint32_t cp_last_update_ms = 0;
|
||||
static volatile CP_Measurement_t cp_measurement = {0, 0, 0};
|
||||
|
||||
static uint32_t CP_TicksDiff(uint32_t now, uint32_t prev, uint32_t arr);
|
||||
static uint32_t CP_GetTimerClockHz(void);
|
||||
static void CP_ApplyStateOutputs(void);
|
||||
static uint32_t CP_GetTim3InputClockHz(void);
|
||||
|
||||
void CP_Init(void) {
|
||||
TIM_IC_InitTypeDef sConfigIC = {0};
|
||||
uint32_t tim3_input_clk = CP_GetTim3InputClockHz();
|
||||
uint32_t target_prescaler = 0U;
|
||||
|
||||
if (tim3_input_clk > CP_CAPTURE_TARGET_CLK_HZ) {
|
||||
target_prescaler = (tim3_input_clk / CP_CAPTURE_TARGET_CLK_HZ) - 1U;
|
||||
}
|
||||
if (target_prescaler > 0xFFFFU) {
|
||||
target_prescaler = 0xFFFFU;
|
||||
}
|
||||
|
||||
__HAL_TIM_SET_PRESCALER(&htim3, (uint16_t)target_prescaler);
|
||||
__HAL_TIM_SET_COUNTER(&htim3, 0U);
|
||||
|
||||
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
|
||||
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
|
||||
sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
|
||||
sConfigIC.ICFilter = 2;
|
||||
HAL_TIM_IC_ConfigChannel(&htim3, &sConfigIC, TIM_CHANNEL_2);
|
||||
|
||||
cp_capture_state = CP_WAIT_RISING_1;
|
||||
cp_measurement.valid = 0;
|
||||
cp_last_update_ms = HAL_GetTick();
|
||||
CP_ApplyStateOutputs();
|
||||
HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_2);
|
||||
}
|
||||
|
||||
void CP_Task(void) {
|
||||
CP_ApplyStateOutputs();
|
||||
|
||||
if ((HAL_GetTick() - cp_last_update_ms) > 200U) {
|
||||
cp_measurement.valid = 0;
|
||||
cp_measurement.frequency_hz = 0;
|
||||
cp_measurement.duty_percent = 0;
|
||||
}
|
||||
}
|
||||
|
||||
CP_Measurement_t CP_GetMeasurement(void) {
|
||||
CP_Measurement_t snapshot;
|
||||
__disable_irq();
|
||||
snapshot = cp_measurement;
|
||||
__enable_irq();
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) {
|
||||
if ((htim->Instance != TIM3) || (htim->Channel != HAL_TIM_ACTIVE_CHANNEL_2)) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t captured = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2);
|
||||
uint32_t arr = __HAL_TIM_GET_AUTORELOAD(htim);
|
||||
TIM_RESET_CAPTUREPOLARITY(htim, TIM_CHANNEL_2);
|
||||
|
||||
if (cp_capture_state == CP_WAIT_RISING_1) {
|
||||
cp_rise_1 = captured;
|
||||
cp_capture_state = CP_WAIT_FALLING;
|
||||
TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_FALLING);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cp_capture_state == CP_WAIT_FALLING) {
|
||||
cp_fall = captured;
|
||||
cp_capture_state = CP_WAIT_RISING_2;
|
||||
TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_RISING);
|
||||
return;
|
||||
}
|
||||
|
||||
cp_rise_2 = captured;
|
||||
cp_capture_state = CP_WAIT_RISING_1;
|
||||
TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_RISING);
|
||||
|
||||
uint32_t period_ticks = CP_TicksDiff(cp_rise_2, cp_rise_1, arr);
|
||||
uint32_t high_ticks = CP_TicksDiff(cp_fall, cp_rise_1, arr);
|
||||
uint32_t timer_clk = CP_GetTimerClockHz();
|
||||
|
||||
if ((period_ticks == 0U) || (high_ticks > period_ticks) || (timer_clk == 0U)) {
|
||||
cp_measurement.valid = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
cp_measurement.frequency_hz = timer_clk / period_ticks;
|
||||
uint32_t duty_high = (high_ticks * 100U + (period_ticks / 2U)) / period_ticks; /* rounded */
|
||||
if (duty_high > 100U) {
|
||||
duty_high = 100U;
|
||||
}
|
||||
uint32_t duty = duty_high;
|
||||
#if CP_INPUT_SIGNAL_INVERTED
|
||||
duty = 100U - duty_high;
|
||||
#endif
|
||||
cp_measurement.duty_percent = (uint8_t)duty;
|
||||
cp_measurement.valid = 1;
|
||||
cp_last_update_ms = HAL_GetTick();
|
||||
}
|
||||
|
||||
static uint32_t CP_TicksDiff(uint32_t now, uint32_t prev, uint32_t arr) {
|
||||
if (now >= prev) {
|
||||
return now - prev;
|
||||
}
|
||||
return (arr - prev + 1U) + now;
|
||||
}
|
||||
|
||||
static uint32_t CP_GetTimerClockHz(void) {
|
||||
uint32_t timclk = CP_GetTim3InputClockHz();
|
||||
uint32_t prescaler = htim3.Instance->PSC;
|
||||
return timclk / (prescaler + 1U);
|
||||
}
|
||||
|
||||
static uint32_t CP_GetTim3InputClockHz(void) {
|
||||
RCC_ClkInitTypeDef clk_init = {0};
|
||||
uint32_t flash_latency = 0U;
|
||||
uint32_t pclk1 = HAL_RCC_GetPCLK1Freq();
|
||||
HAL_RCC_GetClockConfig(&clk_init, &flash_latency);
|
||||
|
||||
if (clk_init.APB1CLKDivider == RCC_HCLK_DIV1) {
|
||||
return pclk1;
|
||||
}
|
||||
return pclk1 * 2U;
|
||||
}
|
||||
|
||||
static void CP_ApplyStateOutputs(void) {
|
||||
static CP_State_t last_state = (CP_State_t)0xFF;
|
||||
|
||||
if (last_state == cp_state) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (cp_state) {
|
||||
case EV_STATE_A_IDLE:
|
||||
HAL_GPIO_WritePin(CP_RELAY_GPIO_Port, CP_RELAY_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(CP_STATE_C_GPIO_Port, CP_STATE_C_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(CP_STATE_F_GPIO_Port, CP_STATE_F_Pin, GPIO_PIN_RESET);
|
||||
break;
|
||||
case EV_STATE_B_CONN_PREP:
|
||||
HAL_GPIO_WritePin(CP_RELAY_GPIO_Port, CP_RELAY_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(CP_STATE_C_GPIO_Port, CP_STATE_C_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(CP_STATE_F_GPIO_Port, CP_STATE_F_Pin, GPIO_PIN_RESET);
|
||||
break;
|
||||
case EV_STATE_C_CONN_ACTIVE:
|
||||
HAL_GPIO_WritePin(CP_RELAY_GPIO_Port, CP_RELAY_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(CP_STATE_C_GPIO_Port, CP_STATE_C_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(CP_STATE_F_GPIO_Port, CP_STATE_F_Pin, GPIO_PIN_RESET);
|
||||
break;
|
||||
case EV_STATE_F_ERROR:
|
||||
HAL_GPIO_WritePin(CP_RELAY_GPIO_Port, CP_RELAY_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(CP_STATE_C_GPIO_Port, CP_STATE_C_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(CP_STATE_F_GPIO_Port, CP_STATE_F_Pin, GPIO_PIN_SET);
|
||||
break;
|
||||
|
||||
case EV_STATE_D_CONN_ACT_VENT:
|
||||
HAL_GPIO_WritePin(CP_RELAY_GPIO_Port, CP_RELAY_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(CP_STATE_C_GPIO_Port, CP_STATE_C_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(CP_STATE_F_GPIO_Port, CP_STATE_F_Pin, GPIO_PIN_RESET);
|
||||
break;
|
||||
case EV_STATE_E_NO_POWER:
|
||||
HAL_GPIO_WritePin(CP_RELAY_GPIO_Port, CP_RELAY_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(CP_STATE_C_GPIO_Port, CP_STATE_C_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(CP_STATE_F_GPIO_Port, CP_STATE_F_Pin, GPIO_PIN_SET);
|
||||
break;
|
||||
case EV_STATE_ACQUIRING:
|
||||
default:
|
||||
HAL_GPIO_WritePin(CP_RELAY_GPIO_Port, CP_RELAY_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(CP_STATE_F_GPIO_Port, CP_STATE_F_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(CP_STATE_C_GPIO_Port, CP_STATE_C_Pin, GPIO_PIN_RESET);
|
||||
break;
|
||||
}
|
||||
|
||||
last_state = cp_state;
|
||||
}
|
||||
Executable → Regular
+155
-199
@@ -1,226 +1,182 @@
|
||||
/*
|
||||
* debug.c
|
||||
*
|
||||
* Created on: Apr 16, 2024
|
||||
* Author: colorbass
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include "debug.h"
|
||||
#include "board.h"
|
||||
#include "charger_gbt.h"
|
||||
#include "serial_control.h"
|
||||
#include "usart.h"
|
||||
#include <time.h>
|
||||
#include <connector.h>
|
||||
|
||||
#define DEBUG_BUFFER_SIZE 1024
|
||||
#define DEBUG_BUFFER_MAX_COUNT 128
|
||||
#define LOG_BUFFER_SIZE 128
|
||||
|
||||
uint8_t debug_rx_buffer[256];
|
||||
uint8_t debug_cmd_received;
|
||||
uint8_t debug_rx_buffer_size = 0;
|
||||
typedef struct {
|
||||
uint8_t buffer[DEBUG_BUFFER_SIZE];
|
||||
volatile uint16_t write_index;
|
||||
volatile uint16_t read_index;
|
||||
volatile uint16_t count;
|
||||
} DebugBuffer_t;
|
||||
|
||||
extern UART_HandleTypeDef huart2;
|
||||
static DebugBuffer_t debug_buffer = {
|
||||
.buffer = {0},
|
||||
.write_index = 0,
|
||||
.read_index = 0,
|
||||
.count = 0
|
||||
};
|
||||
|
||||
static uint8_t log_buffer[LOG_BUFFER_SIZE];
|
||||
|
||||
static void debug_uart1_write(const uint8_t *data, uint16_t len)
|
||||
{
|
||||
/* Best-effort debug mirror to USART1 (PA9/PA10), safe for IRQ context. */
|
||||
for (uint16_t i = 0; i < len; i++) {
|
||||
uint32_t timeout = 10000U;
|
||||
while (((USART1->SR & USART_SR_TXE) == 0U) && (timeout > 0U)) {
|
||||
timeout--;
|
||||
}
|
||||
if (timeout == 0U) {
|
||||
return;
|
||||
}
|
||||
USART1->DR = data[i];
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__GNUC__)
|
||||
int _write(int fd, char * ptr, int len)
|
||||
{
|
||||
HAL_GPIO_WritePin(USART2_DIR_GPIO_Port, USART2_DIR_Pin, 1);
|
||||
HAL_UART_Transmit(&huart2, (uint8_t *) ptr, len, HAL_MAX_DELAY);
|
||||
HAL_GPIO_WritePin(USART2_DIR_GPIO_Port, USART2_DIR_Pin, 0);
|
||||
(void)fd;
|
||||
debug_buffer_add((const uint8_t*)ptr, (uint16_t)len);
|
||||
return len;
|
||||
}
|
||||
#endif
|
||||
|
||||
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size){
|
||||
|
||||
// if(huart->Instance == USART1){
|
||||
// mm_rx_interrupt(huart, Size);
|
||||
// }
|
||||
if(huart->Instance == USART2){
|
||||
debug_rx_interrupt(huart, Size);
|
||||
void debug_buffer_add(const uint8_t* data, uint16_t len)
|
||||
{
|
||||
debug_uart1_write(data, len);
|
||||
__disable_irq();
|
||||
for (uint16_t i = 0; i < len; i++) {
|
||||
if (debug_buffer.count >= DEBUG_BUFFER_SIZE) {
|
||||
debug_buffer.read_index = (debug_buffer.read_index + 1U) % DEBUG_BUFFER_SIZE;
|
||||
debug_buffer.count--;
|
||||
}
|
||||
debug_buffer.buffer[debug_buffer.write_index] = data[i];
|
||||
debug_buffer.write_index = (debug_buffer.write_index + 1U) % DEBUG_BUFFER_SIZE;
|
||||
debug_buffer.count++;
|
||||
}
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
void debug_rx_interrupt(UART_HandleTypeDef *huart, uint16_t Size){
|
||||
debug_rx_buffer[Size] = '\0';
|
||||
debug_rx_buffer_size = Size;
|
||||
debug_cmd_received = 1;
|
||||
uint16_t debug_buffer_available(void)
|
||||
{
|
||||
__disable_irq();
|
||||
uint16_t count = debug_buffer.count;
|
||||
__enable_irq();
|
||||
return count;
|
||||
}
|
||||
|
||||
void debug_init(){
|
||||
HAL_UARTEx_ReceiveToIdle_IT(&huart2,debug_rx_buffer,255);
|
||||
//mm_schedule_write(0x01, 0x0000, 0x0800);
|
||||
// mm_schedule_write(0x02, 0x00FF, 0xFFFF);
|
||||
//for (int i=0;i<60;i++)
|
||||
// mm_schedule_write(0x02, 0x0000, 0xFF00);
|
||||
// mm_schedule_write(0x01, 0x0000, 0x0100);
|
||||
// mm_schedule_write(0x01, 0x0000, 0x0100);
|
||||
}
|
||||
|
||||
void parse_command(uint8_t* buffer, size_t length) {
|
||||
// ignore \r \n symbols
|
||||
size_t i = 0;
|
||||
for (i = 0; i < length; i++) {
|
||||
if (buffer[i] == '\r' || buffer[i] == '\n') {
|
||||
buffer[i] = '\0';
|
||||
length = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (buffer[0] == 0) return;
|
||||
if (strncmp((const char*)buffer, "reset", length) == 0) {
|
||||
printf("Resetting...\n");
|
||||
NVIC_SystemReset();
|
||||
|
||||
} else if (strncmp((const char*)buffer, "relayaux", length) == 0) {
|
||||
printf("Relaying...\n");
|
||||
RELAY_Write(RELAY_1, 1);
|
||||
HAL_Delay(200);
|
||||
RELAY_Write(RELAY_1, 0);
|
||||
} else if (strncmp((const char*)buffer, "relaycc", length) == 0) {
|
||||
printf("Relaying...\n");
|
||||
RELAY_Write(RELAY_CC, 1);
|
||||
HAL_Delay(200);
|
||||
RELAY_Write(RELAY_CC, 0);
|
||||
|
||||
|
||||
// } else if (strncmp((const char*)buffer, "voltage", length) == 0) {
|
||||
// printf("Voltaging...\n");
|
||||
// mm_schedule_read(0x02, 0x0001);
|
||||
|
||||
} else if (strncmp((const char*)buffer, "adc", length) == 0) {
|
||||
printf("CC1=%.2f\n", CONN_CC_GetAdc());
|
||||
|
||||
// } else if (strncmp((const char*)buffer, "lock_state", length) == 0) {
|
||||
// printf("AUX/Lock state=%d\n", GBT_LockGetState());
|
||||
|
||||
} else if (strncmp((const char*)buffer, "complete", length) == 0) {
|
||||
CONN_SetState(Finished);
|
||||
|
||||
} else if (strncmp((const char*)buffer, "start", length) == 0) {
|
||||
printf("Started\n");
|
||||
GBT_SwitchState(GBT_EV_CONNECTING);
|
||||
|
||||
} else if (strncmp((const char*)buffer, "stop", length) == 0) {
|
||||
printf("Stopped\n");
|
||||
GBT_StopEVSE(GBT_CST_SUSPENDS_ARTIFICIALLY);
|
||||
|
||||
} else if (strncmp((const char*)buffer, "stop1", length) == 0) {
|
||||
printf("Stopped\n");
|
||||
GBT_ForceStop();
|
||||
|
||||
// } else if (strncmp((const char*)buffer, "force", length) == 0) {
|
||||
// printf("Stopped\n");
|
||||
// GBT_Lock(1);
|
||||
// GBT_SwitchState(GBT_S2_LOCKED);
|
||||
// GBT_Delay(500);
|
||||
|
||||
} else if (strncmp((const char*)buffer, "cc_state", length) == 0) {
|
||||
switch(CONN_CC_GetState()){
|
||||
case GBT_CC_UNKNOWN:
|
||||
printf("GBT_CC_UNKNOWN\n");
|
||||
break;
|
||||
case GBT_CC_12V:
|
||||
printf("GBT_CC_12V\n");
|
||||
break;
|
||||
case GBT_CC_6V:
|
||||
printf("GBT_CC_6V\n");
|
||||
break;
|
||||
case GBT_CC_4V:
|
||||
printf("GBT_CC_4V\n");
|
||||
break;
|
||||
case GBT_CC_2V:
|
||||
printf("GBT_CC_2V\n");
|
||||
break;
|
||||
|
||||
}
|
||||
} else if (strncmp((const char*)buffer, "temp", length) == 0) {
|
||||
printf("temp1 %d\n",GBT_ReadTemp(0));
|
||||
printf("temp2 %d\n",GBT_ReadTemp(1));
|
||||
} else if (strncmp((const char*)buffer, "info1", length) == 0) {
|
||||
printf("Battery info:\n");
|
||||
printf("maxCV %dV\n",GBT_BATStat.maxCellVoltage/100); // 0.01v/bit
|
||||
printf("maxCC %dA\n",GBT_BATStat.maxChargingCurrent/10); // 0.1A/bit
|
||||
printf("totE %dkWh\n",GBT_BATStat.totalEnergy/10); // 0.1kWh
|
||||
printf("maxCV %dV\n",GBT_BATStat.maxChargingVoltage/10); // 0.1V/ bit
|
||||
printf("maxT %dC\n",(int16_t)GBT_BATStat.maxTemp-50); // 1C/bit, -50C offset
|
||||
printf("SOC %dp\n",GBT_BATStat.SOC/10); // 0.1%/bit , 0..100%
|
||||
printf("Volt. %dV\n",GBT_BATStat.measVoltage/10); // 0.1V/bit
|
||||
|
||||
} else if (strncmp((const char*)buffer, "info2", length) == 0) {
|
||||
printf("EV info:\n");
|
||||
printf("GBT_ver V%d.%d%d\n",GBT_EVInfo.version[0],GBT_EVInfo.version[1],GBT_EVInfo.version[2]);
|
||||
printf("Battery type: %d\n",GBT_EVInfo.batteryType);
|
||||
printf("Battery capacity: %d\n", GBT_EVInfo.batteryCapacity); // 0.1Ah/bit
|
||||
printf("Battery voltage: %d\n", GBT_EVInfo.batteryVoltage); // 0.1V/bit
|
||||
printf("Battery vendor: %.4s\n", GBT_EVInfo.batteryVendor); // Battery vendor (ASCII string)
|
||||
printf("Battery SN: %lu\n", GBT_EVInfo.batterySN); // int
|
||||
printf("Battery manufacture date: %02d.%02d.%04d\n", GBT_EVInfo.batteryManuD, GBT_EVInfo.batteryManuM ,GBT_EVInfo.batteryManuY+1985); // year (offset 1985)
|
||||
printf("Battery cycles: %d\n", GBT_EVInfo.batteryCycleCount); //uint24_t
|
||||
printf("Own auto: %d\n", GBT_EVInfo.ownAuto); // 0 = lizing, 1 = own auto
|
||||
printf("EVIN: %.17s\n", GBT_EVInfo.EVIN); //EVIN
|
||||
printf("EV_SW_VER: %.8s\n", GBT_EVInfo.EV_SW_VER);
|
||||
|
||||
} else if (strncmp((const char*)buffer, "info3", length) == 0) {
|
||||
printf("GBT_MaxLoad info:\n");
|
||||
printf("Output max current: %d\n",GBT_MaxLoad.maxOutputCurrent);
|
||||
printf("Output min current: %d\n",GBT_MaxLoad.minOutputCurrent);
|
||||
printf("Output max voltage: %d\n",GBT_MaxLoad.maxOutputVoltage);
|
||||
printf("Output min voltage: %d\n",GBT_MaxLoad.minOutputVoltage);
|
||||
printf("\nGBT_ChargerInfo info:\n");
|
||||
printf("BMS Recognized: %d\n",GBT_ChargerInfo.bmsIdentified);
|
||||
printf("Charger location: %.3s\n",GBT_ChargerInfo.chargerLocation);
|
||||
printf("Charger number: %lu\n",GBT_ChargerInfo.chargerNumber);
|
||||
|
||||
|
||||
} else if (strncmp((const char*)buffer, "help", length) == 0) {
|
||||
printf("Command list:\n");
|
||||
printf("reset\n");
|
||||
printf("help\n");
|
||||
printf("cc_state\n");
|
||||
printf("lock_state\n");
|
||||
printf("adc\n");
|
||||
printf("relay(cc,aux)\n");
|
||||
printf("start\n");
|
||||
printf("stop\n");
|
||||
printf("stop1\n");
|
||||
// printf("force\n");
|
||||
printf("temp\n");
|
||||
printf("info1\n");
|
||||
printf("info2\n");
|
||||
printf("info3\n");
|
||||
printf("time\n");
|
||||
printf("cantest\n");
|
||||
|
||||
//TODO: info commands
|
||||
|
||||
} else if (strncmp((const char*)buffer, "time", length) == 0) {
|
||||
|
||||
time_t unix_time = (time_t)get_Current_Time();
|
||||
struct tm *parts = localtime(&unix_time);
|
||||
|
||||
printf("Year: %d\n", parts->tm_year + 1900);
|
||||
printf("Month: %d\n", parts->tm_mon + 1);
|
||||
printf("Day: %d\n", parts->tm_mday);
|
||||
printf("Hour: %d\n", parts->tm_hour);
|
||||
printf("Minute: %d\n", parts->tm_min);
|
||||
printf("Second: %d\n", parts->tm_sec);
|
||||
|
||||
} else if (strncmp((const char*)buffer, "cantest", length) == 0) {
|
||||
//GBT_SendCHM();
|
||||
GBT_Error(0xFDF0C0FC); //BRM Timeout
|
||||
printf("can test\n");
|
||||
|
||||
} else {
|
||||
printf("Unknown command\n");
|
||||
}
|
||||
}
|
||||
|
||||
void debug_task(){
|
||||
if(debug_cmd_received){
|
||||
parse_command(debug_rx_buffer, debug_rx_buffer_size);
|
||||
HAL_UARTEx_ReceiveToIdle_IT(&huart2,debug_rx_buffer,255);
|
||||
debug_cmd_received = 0;
|
||||
void debug_buffer_send(void)
|
||||
{
|
||||
__disable_irq();
|
||||
if (debug_buffer.count == 0U) {
|
||||
__enable_irq();
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t bytes_to_send = debug_buffer.count;
|
||||
if (bytes_to_send > DEBUG_BUFFER_MAX_COUNT) {
|
||||
bytes_to_send = DEBUG_BUFFER_MAX_COUNT;
|
||||
}
|
||||
|
||||
uint16_t bytes_to_end = DEBUG_BUFFER_SIZE - debug_buffer.read_index;
|
||||
if (bytes_to_send > bytes_to_end) {
|
||||
bytes_to_send = bytes_to_end;
|
||||
}
|
||||
|
||||
if (bytes_to_send == debug_buffer.count) {
|
||||
SC_SendPacket(&debug_buffer.buffer[debug_buffer.read_index], bytes_to_send, CMD_GET_LOG);
|
||||
} else {
|
||||
SC_SendPacket(&debug_buffer.buffer[debug_buffer.read_index], bytes_to_send, CMD_GET_LOG_CONTINUE);
|
||||
}
|
||||
|
||||
debug_buffer.read_index = (debug_buffer.read_index + bytes_to_send) % DEBUG_BUFFER_SIZE;
|
||||
debug_buffer.count -= bytes_to_send;
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
int log_printf(int level, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
int result;
|
||||
const char *tag;
|
||||
int written;
|
||||
EDCAN_LogLevel_t current_level;
|
||||
EDCAN_LogLevel_t msg_level;
|
||||
|
||||
if(level < LOG_EMERG || level > LOG_DEBUG){
|
||||
return 0;
|
||||
}
|
||||
msg_level = (EDCAN_LogLevel_t)level;
|
||||
current_level = EDCAN_GetLogLevel();
|
||||
if(msg_level > current_level){
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch(level){
|
||||
case LOG_EMERG:
|
||||
tag = "[EMR] ";
|
||||
break;
|
||||
case LOG_ALERT:
|
||||
tag = "[ALT] ";
|
||||
break;
|
||||
case LOG_CRIT:
|
||||
tag = "[CRT] ";
|
||||
break;
|
||||
case LOG_ERR:
|
||||
tag = "[ERR] ";
|
||||
break;
|
||||
case LOG_WARN:
|
||||
tag = "[WRN] ";
|
||||
break;
|
||||
case LOG_NOTICE:
|
||||
tag = "[NTC] ";
|
||||
break;
|
||||
case LOG_INFO:
|
||||
tag = "[INF] ";
|
||||
break;
|
||||
case LOG_DEBUG:
|
||||
tag = "[DBG] ";
|
||||
break;
|
||||
default:
|
||||
tag = "[LOG] ";
|
||||
break;
|
||||
}
|
||||
|
||||
log_buffer[0] = (uint8_t)level;
|
||||
written = snprintf((char*)&log_buffer[1], LOG_BUFFER_SIZE - 2, "EV %s", tag);
|
||||
if(written < 0){
|
||||
return written;
|
||||
}
|
||||
if(written >= (LOG_BUFFER_SIZE - 2)){
|
||||
written = LOG_BUFFER_SIZE - 2;
|
||||
}
|
||||
|
||||
va_start(args, format);
|
||||
result = vsnprintf((char*)&log_buffer[1 + written], LOG_BUFFER_SIZE - 2 - written, format, args);
|
||||
va_end(args);
|
||||
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
if (result >= (LOG_BUFFER_SIZE - 2 - written)) {
|
||||
result = LOG_BUFFER_SIZE - 2 - written;
|
||||
}
|
||||
|
||||
log_buffer[1 + written + result] = '\0';
|
||||
debug_buffer_add(log_buffer, (uint16_t)(2 + written + result));
|
||||
return result + written;
|
||||
}
|
||||
|
||||
@@ -50,6 +50,11 @@ void GBT_SendBSM(void){
|
||||
J_SendPacket(0x1300, 6, sizeof(GBT_BatteryStatus), (uint8_t*)&GBT_BatteryStatus);
|
||||
}
|
||||
|
||||
// BST: запрос остановки зарядки со стороны EV
|
||||
void GBT_SendBST(uint32_t causeCode){
|
||||
J_SendPacket(0x1900, 6, sizeof(causeCode), (uint8_t*)&causeCode);
|
||||
}
|
||||
|
||||
// BSD: статус батареи при завершении
|
||||
void GBT_SendBSD(void){
|
||||
J_SendPacket(0x1C00, 6, sizeof(GBT_BATStat), (uint8_t*)&GBT_BATStat);
|
||||
|
||||
+18
-18
@@ -54,14 +54,14 @@ 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, CP_STATE_F_Pin|CP_RELAY_Pin|LOCK_A_Pin|LOCK_B_Pin, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOE, RELAY5_Pin|RELAY4_Pin|RELAY3_Pin|RELAY2_Pin
|
||||
|RELAY1_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(GPIOA, CP_STATE_C_Pin|RELAY_CC_Pin, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(RELAY_CC_GPIO_Port, RELAY_CC_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(GPIOE, RELAY1_Pin|RELAY2_Pin|RELAY3_Pin|RELAY4_Pin
|
||||
|RELAY5_Pin, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOD, RELAY_DC_Pin|USART2_DIR_Pin, GPIO_PIN_RESET);
|
||||
@@ -69,18 +69,25 @@ 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 : CP_STATE_F_Pin CP_RELAY_Pin LOCK_A_Pin LOCK_B_Pin */
|
||||
GPIO_InitStruct.Pin = CP_STATE_F_Pin|CP_RELAY_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 : IN_SW0_Pin IN_SW1_Pin */
|
||||
GPIO_InitStruct.Pin = IN_SW0_Pin|IN_SW1_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : LOCK_A_Pin LOCK_B_Pin */
|
||||
GPIO_InitStruct.Pin = LOCK_A_Pin|LOCK_B_Pin;
|
||||
/*Configure GPIO pins : CP_STATE_C_Pin RELAY_CC_Pin */
|
||||
GPIO_InitStruct.Pin = CP_STATE_C_Pin|RELAY_CC_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);
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : IN0_Pin AC_OK_Pin ISO_IN_Pin */
|
||||
GPIO_InitStruct.Pin = IN0_Pin|AC_OK_Pin|ISO_IN_Pin;
|
||||
@@ -88,22 +95,15 @@ void MX_GPIO_Init(void)
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : RELAY5_Pin RELAY4_Pin RELAY3_Pin RELAY2_Pin
|
||||
RELAY1_Pin */
|
||||
GPIO_InitStruct.Pin = RELAY5_Pin|RELAY4_Pin|RELAY3_Pin|RELAY2_Pin
|
||||
|RELAY1_Pin;
|
||||
/*Configure GPIO pins : RELAY1_Pin RELAY2_Pin RELAY3_Pin RELAY4_Pin
|
||||
RELAY5_Pin */
|
||||
GPIO_InitStruct.Pin = RELAY1_Pin|RELAY2_Pin|RELAY3_Pin|RELAY4_Pin
|
||||
|RELAY5_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pin : RELAY_CC_Pin */
|
||||
GPIO_InitStruct.Pin = RELAY_CC_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(RELAY_CC_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : RELAY_DC_Pin USART2_DIR_Pin */
|
||||
GPIO_InitStruct.Pin = RELAY_DC_Pin|USART2_DIR_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
|
||||
+427
-93
@@ -11,107 +11,272 @@
|
||||
#include "string.h"
|
||||
#include "can.h"
|
||||
#include "edcan.h"
|
||||
#include "debug.h"
|
||||
#include <string.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,};
|
||||
typedef struct{
|
||||
uint8_t data[256];
|
||||
uint32_t PGN;
|
||||
uint16_t size;
|
||||
uint8_t packets;
|
||||
uint8_t next_packet;
|
||||
uint8_t step;
|
||||
uint8_t state; // 0=idle, 1=wait CTS, 2=wait ACK
|
||||
uint32_t tick;
|
||||
}j_transmit_t;
|
||||
|
||||
if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RxData) == HAL_OK)
|
||||
{
|
||||
if((RxHeader.ExtId & 0x00FFFF) == ((J_ID_EV << 8) | J_ID_SE)){ // SA, DA match
|
||||
switch ((RxHeader.ExtId>>8) & 0x00FF00){
|
||||
static j_transmit_t j_tx;
|
||||
|
||||
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;
|
||||
}
|
||||
#define J1939_BUFFER_SIZE 64U
|
||||
|
||||
//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
|
||||
*/
|
||||
typedef struct {
|
||||
j1939_rx_frame_t buffer[J1939_BUFFER_SIZE];
|
||||
uint16_t head;
|
||||
uint16_t tail;
|
||||
uint16_t count;
|
||||
uint32_t overflow;
|
||||
} j1939_rx_ring_t;
|
||||
|
||||
break;
|
||||
typedef struct {
|
||||
j1939_tx_frame_t buffer[J1939_BUFFER_SIZE];
|
||||
uint16_t head;
|
||||
uint16_t tail;
|
||||
uint16_t count;
|
||||
uint8_t busy;
|
||||
uint32_t overflow;
|
||||
} j1939_tx_ring_t;
|
||||
|
||||
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);
|
||||
static j1939_rx_ring_t j_rxbuf;
|
||||
static j1939_tx_ring_t j_txbuf;
|
||||
static uint32_t j_tx_watchdog_last_log_tick;
|
||||
|
||||
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;
|
||||
#define J1939_CRITICAL_ENTER() __disable_irq()
|
||||
#define J1939_CRITICAL_EXIT() __enable_irq()
|
||||
|
||||
case 0x1E00: //PGN BEM (ERROR)
|
||||
//Error force stop
|
||||
// --> Suspend EV
|
||||
EDCAN_printf(LOG_WARN, "BEM Received, force stopping...\n");
|
||||
EDCAN_printf(LOG_WARN, "BEM: %02X %02X %02X %02X", RxData[0], RxData[1], RxData[2], RxData[3]);
|
||||
EDCAN_printf(LOG_WARN, " %02X %02X %02X %02X\n", RxData[4], RxData[5], RxData[6], RxData[7]);
|
||||
GBT_ForceStop();
|
||||
break;
|
||||
static void J_SendTpRts(void);
|
||||
static void J_SendTpDtRange(uint8_t start_packet, uint8_t count);
|
||||
static void J_TxCheckTimeout(void);
|
||||
static void J_TxReset(void);
|
||||
static void J1939_ProcessRxFrame(const j1939_rx_frame_t *frame);
|
||||
static void J1939_RxBufferAdd(const j1939_rx_frame_t *frame);
|
||||
static uint8_t J1939_RxBufferGet(j1939_rx_frame_t *frame);
|
||||
static void J1939_TxBufferAdd(const j1939_tx_frame_t *frame);
|
||||
static uint8_t J1939_TxBufferPeek(j1939_tx_frame_t *frame);
|
||||
static void J1939_TxBufferDropFirst(void);
|
||||
static void J1939_TxQueueByPgn(uint32_t PGN, uint8_t pri, uint8_t DLC, const uint8_t *data, uint8_t pad_ff);
|
||||
|
||||
case 0x1900: //PGN BST (STOP)
|
||||
//Normal stop
|
||||
#define J1939_TP_CTS_WAIT_TIMEOUT_MS 1000U
|
||||
#define J1939_TP_ACK_WAIT_TIMEOUT_MS 1000U
|
||||
|
||||
// --> Suspend EV
|
||||
EDCAN_printf(LOG_WARN, "BST Received, stopping...\n");
|
||||
EDCAN_printf(LOG_WARN, "BST: %02X %02X %02X %02X", RxData[0], RxData[1], RxData[2], RxData[3]);
|
||||
EDCAN_printf(LOG_WARN, " %02X %02X %02X %02X\n", RxData[4], RxData[5], RxData[6], RxData[7]);
|
||||
GBT_StopEV(GBT_CST_BMS_ACTIVELY_SUSPENDS);
|
||||
static void J_TxReset(void){
|
||||
if(j_tx.state != 0){
|
||||
log_printf(LOG_WARN, "J1939 chunk send failed: TX session reset (state=%u pgn=0x%lX next=%u/%u)\n",
|
||||
j_tx.state, j_tx.PGN, j_tx.next_packet, j_tx.packets);
|
||||
}
|
||||
memset(&j_tx, 0, sizeof(j_tx));
|
||||
}
|
||||
|
||||
break;
|
||||
void J1939_InitBuffers(void){
|
||||
memset(&j_rxbuf, 0, sizeof(j_rxbuf));
|
||||
memset(&j_txbuf, 0, sizeof(j_txbuf));
|
||||
j_tx_watchdog_last_log_tick = 0U;
|
||||
J_TxReset();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
uint16_t J1939_GetRxBufferCount(void){
|
||||
uint16_t c;
|
||||
J1939_CRITICAL_ENTER();
|
||||
c = j_rxbuf.count;
|
||||
J1939_CRITICAL_EXIT();
|
||||
return c;
|
||||
}
|
||||
|
||||
uint16_t J1939_GetTxBufferCount(void){
|
||||
uint16_t c;
|
||||
J1939_CRITICAL_ENTER();
|
||||
c = j_txbuf.count;
|
||||
J1939_CRITICAL_EXIT();
|
||||
return c;
|
||||
}
|
||||
|
||||
uint32_t J1939_GetRxOverflowCount(void){
|
||||
return j_rxbuf.overflow;
|
||||
}
|
||||
|
||||
uint32_t J1939_GetTxOverflowCount(void){
|
||||
return j_txbuf.overflow;
|
||||
}
|
||||
|
||||
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan){
|
||||
j1939_rx_frame_t frame;
|
||||
CAN_RxHeaderTypeDef rx_header;
|
||||
uint8_t rx_data[8] = {0};
|
||||
|
||||
if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rx_header, rx_data) != HAL_OK) return;
|
||||
|
||||
frame.ExtId = rx_header.ExtId;
|
||||
frame.DLC = rx_header.DLC;
|
||||
frame.tick = HAL_GetTick();
|
||||
memcpy(frame.data, rx_data, sizeof(frame.data));
|
||||
J1939_RxBufferAdd(&frame);
|
||||
}
|
||||
|
||||
static void J1939_ProcessRxFrame(const j1939_rx_frame_t *frame){
|
||||
uint32_t pgn;
|
||||
|
||||
if((frame->ExtId & 0x00FFFF) != ((J_ID_EV << 8) | J_ID_SE)) return; // SA, DA match
|
||||
|
||||
switch ((frame->ExtId >> 8) & 0x00FF00){
|
||||
case 0xEC00:
|
||||
if(frame->data[0] == 16){ // RTS
|
||||
j_rx.size = frame->data[1] | (frame->data[2] << 8);
|
||||
j_rx.packet = 1;
|
||||
j_rx.packets = frame->data[3];
|
||||
j_rx.step = 2;
|
||||
j_rx.step_cts_remain = j_rx.step;
|
||||
j_rx.PGN = (frame->data[7] << 16) | (frame->data[6] << 8) | frame->data[5];
|
||||
if(j_rx.size < 256){
|
||||
J_SendCTS(j_rx);
|
||||
j_rx.state = 1;
|
||||
}
|
||||
}
|
||||
if(frame->data[0] == 17){ // CTS
|
||||
pgn = (frame->data[7] << 16) | (frame->data[6] << 8) | frame->data[5];
|
||||
if((j_tx.state == 1) && (pgn == j_tx.PGN)){
|
||||
uint8_t req_count = frame->data[1];
|
||||
uint8_t req_start_packet = frame->data[2];
|
||||
log_printf(LOG_DEBUG, "J1939 event: TP CTS received (pgn=0x%lX cnt=%u start=%u exp=%u)\n",
|
||||
pgn, req_count, req_start_packet, j_tx.next_packet);
|
||||
if(req_count == 0){
|
||||
log_printf(LOG_DEBUG, "J1939 event: TP CTS wait (pgn=0x%lX)\n", j_tx.PGN);
|
||||
}else{
|
||||
j_tx.tick = frame->tick;
|
||||
J_SendTpDtRange(req_start_packet, req_count);
|
||||
}
|
||||
}else{
|
||||
log_printf(LOG_WARN, "J1939 chunk send failed: CTS ignored (tx_state=%u tx_pgn=0x%lX rx_pgn=0x%lX)\n",
|
||||
j_tx.state, j_tx.PGN, pgn);
|
||||
}
|
||||
}
|
||||
if(frame->data[0] == 19){ // ACK
|
||||
pgn = (frame->data[7] << 16) | (frame->data[6] << 8) | frame->data[5];
|
||||
if((j_tx.state == 2) && (pgn == j_tx.PGN)){
|
||||
log_printf(LOG_DEBUG, "J1939 event: TP ACK received, TX complete (pgn=0x%lX)\n", pgn);
|
||||
j_tx.state = 0;
|
||||
}
|
||||
}
|
||||
if(frame->data[0] == 255){
|
||||
j_rx.state = 0;
|
||||
J_TxReset();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xEB00:
|
||||
if(j_rx.state != 1) return;
|
||||
if((frame->data[0] > 0) && (frame->data[0] < 35) && (j_rx.packet == frame->data[0])){
|
||||
memcpy(&j_rx.data[(frame->data[0]-1)*7], &frame->data[1], 7);
|
||||
j_rx.packet++;
|
||||
if(j_rx.packet > j_rx.packets){
|
||||
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:
|
||||
log_printf(LOG_WARN, "J1939 fault received: BEM, forcing stop (data=%02X %02X %02X %02X %02X %02X %02X %02X)\n",
|
||||
frame->data[0], frame->data[1], frame->data[2], frame->data[3],
|
||||
frame->data[4], frame->data[5], frame->data[6], frame->data[7]);
|
||||
GBT_ForceStop();
|
||||
break;
|
||||
|
||||
case 0x1900:
|
||||
/* Repeated BST frames during STOP flow are normal on the bus.
|
||||
* Handle/log only once to avoid flooding UART logs.
|
||||
*/
|
||||
if((GBT_State != GBT_STOP) && (GBT_State != GBT_STOP_CSD) && (GBT_State != GBT_COMPLETE)){
|
||||
log_printf(LOG_DEBUG, "J1939 event: BST received, initiating stop flow (data=%02X %02X %02X %02X %02X %02X %02X %02X)\n",
|
||||
frame->data[0], frame->data[1], frame->data[2], frame->data[3],
|
||||
frame->data[4], frame->data[5], frame->data[6], frame->data[7]);
|
||||
GBT_StopEV(GBT_CST_BMS_ACTIVELY_SUSPENDS);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if(j_rx.state == 0){
|
||||
j_rx.size = frame->DLC;
|
||||
j_rx.packet = 1;
|
||||
j_rx.packets = 1;
|
||||
j_rx.step = 1;
|
||||
j_rx.step_cts_remain = 0;
|
||||
j_rx.PGN = (frame->ExtId >> 8) & 0x00FF00;
|
||||
j_rx.state = 2;
|
||||
memcpy(j_rx.data, frame->data, j_rx.size);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void J1939_ExchangeRxBuffer(void){
|
||||
j1939_rx_frame_t frame;
|
||||
J_TxCheckTimeout();
|
||||
if(J1939_RxBufferGet(&frame)){
|
||||
J1939_ProcessRxFrame(&frame);
|
||||
}
|
||||
}
|
||||
|
||||
void J1939_ExchangeTxBuffer(void){
|
||||
j1939_tx_frame_t frame;
|
||||
CAN_TxHeaderTypeDef tx_header;
|
||||
uint32_t tx_mailbox;
|
||||
HAL_StatusTypeDef tx_status;
|
||||
|
||||
if(HAL_CAN_GetTxMailboxesFreeLevel(&hcan1) == 0) return;
|
||||
|
||||
/* Atomically reserve first queued frame without holding IRQ over HAL call */
|
||||
J1939_CRITICAL_ENTER();
|
||||
if(j_txbuf.busy || (j_txbuf.count == 0U)){
|
||||
J1939_CRITICAL_EXIT();
|
||||
return;
|
||||
}
|
||||
j_txbuf.busy = 1U;
|
||||
frame = j_txbuf.buffer[j_txbuf.tail];
|
||||
J1939_CRITICAL_EXIT();
|
||||
|
||||
tx_header.ExtId = frame.ExtId;
|
||||
tx_header.RTR = CAN_RTR_DATA;
|
||||
tx_header.IDE = CAN_ID_EXT;
|
||||
tx_header.DLC = frame.DLC;
|
||||
|
||||
tx_status = HAL_CAN_AddTxMessage(&hcan1, &tx_header, frame.data, &tx_mailbox);
|
||||
|
||||
J1939_CRITICAL_ENTER();
|
||||
if((tx_status == HAL_OK) && (j_txbuf.count > 0U)){
|
||||
j_txbuf.tail = (j_txbuf.tail + 1U) % J1939_BUFFER_SIZE;
|
||||
j_txbuf.count--;
|
||||
}
|
||||
j_txbuf.busy = 0U;
|
||||
J1939_CRITICAL_EXIT();
|
||||
|
||||
if(tx_status != HAL_OK){
|
||||
log_printf(LOG_WARN, "J1939 send failed: CAN TX error (st=%d extid=0x%lX dlc=%u free_mb=%lu err=0x%lX)\n",
|
||||
(int)tx_status, frame.ExtId, frame.DLC, HAL_CAN_GetTxMailboxesFreeLevel(&hcan1), HAL_CAN_GetError(&hcan1));
|
||||
if((tx_status == HAL_ERROR) && (HAL_CAN_GetError(&hcan1) & HAL_CAN_ERROR_NOT_INITIALIZED)){
|
||||
log_printf(LOG_WARN, "J1939 send failed: CAN not initialized, reinitializing\n");
|
||||
GBT_CAN_ReInit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GBT_CAN_ReInit(){
|
||||
@@ -120,24 +285,119 @@ void GBT_CAN_ReInit(){
|
||||
HAL_CAN_Start(&hcan1);
|
||||
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);
|
||||
GBT_CAN_FilterInit();
|
||||
J1939_InitBuffers();
|
||||
}
|
||||
|
||||
void J_SendPacket(uint32_t PGN, uint8_t pri, uint8_t DLC, uint8_t *data){
|
||||
J_TxCheckTimeout();
|
||||
|
||||
CAN_TxHeaderTypeDef tx_header;
|
||||
uint32_t tx_mailbox;
|
||||
if(DLC > 8){
|
||||
/* Transport protocol for multi-packet payloads */
|
||||
if(DLC > sizeof(j_tx.data)) return;
|
||||
if(j_tx.state != 0){
|
||||
log_printf(LOG_WARN, "J1939 chunk send failed: TX busy (state=%u req_pgn=0x%lX cur_pgn=0x%lX)\n",
|
||||
j_tx.state, PGN, j_tx.PGN);
|
||||
return;
|
||||
}
|
||||
|
||||
tx_header.ExtId = (pri << 26) | (PGN << 8) | (J_ID_SE << 8) | J_ID_EV;
|
||||
tx_header.RTR = CAN_RTR_DATA;
|
||||
tx_header.IDE = CAN_ID_EXT;
|
||||
tx_header.DLC = DLC;
|
||||
memset(&j_tx, 0, sizeof(j_tx));
|
||||
memcpy(j_tx.data, data, DLC);
|
||||
j_tx.PGN = PGN;
|
||||
j_tx.size = DLC;
|
||||
j_tx.packets = (DLC + 6) / 7;
|
||||
j_tx.next_packet = 1;
|
||||
j_tx.step = 2;
|
||||
j_tx.state = 1;
|
||||
j_tx.tick = HAL_GetTick();
|
||||
log_printf(LOG_DEBUG, "J1939 event: TP RTS sent (pgn=0x%lX size=%u packets=%u)\n",
|
||||
j_tx.PGN, j_tx.size, j_tx.packets);
|
||||
|
||||
//TODO buffer wait
|
||||
HAL_CAN_AddTxMessage(&hcan1, &tx_header, data, &tx_mailbox);
|
||||
//HAL_Delay(2);
|
||||
J_SendTpRts();
|
||||
return;
|
||||
}
|
||||
J1939_TxQueueByPgn(PGN, pri, DLC, data, 1);
|
||||
|
||||
}
|
||||
|
||||
static void J_TxCheckTimeout(void){
|
||||
if(j_tx.state != 0){
|
||||
uint32_t now = HAL_GetTick();
|
||||
if((now - j_tx_watchdog_last_log_tick) >= 500U){
|
||||
log_printf(LOG_DEBUG, "J1939 event: TP TX watchdog (state=%u pgn=0x%lX next=%u/%u age=%lu)\n",
|
||||
j_tx.state, j_tx.PGN, j_tx.next_packet, j_tx.packets, (now - j_tx.tick));
|
||||
j_tx_watchdog_last_log_tick = now;
|
||||
}
|
||||
}else{
|
||||
j_tx_watchdog_last_log_tick = HAL_GetTick();
|
||||
}
|
||||
|
||||
if((j_tx.state == 1) && ((HAL_GetTick() - j_tx.tick) > J1939_TP_CTS_WAIT_TIMEOUT_MS)){
|
||||
log_printf(LOG_WARN, "J1939 chunk send failed: CTS timeout (pgn=0x%lX), resetting TX session\n", j_tx.PGN);
|
||||
J_TxReset();
|
||||
}else if((j_tx.state == 2) && ((HAL_GetTick() - j_tx.tick) > J1939_TP_ACK_WAIT_TIMEOUT_MS)){
|
||||
log_printf(LOG_WARN, "J1939 chunk send failed: ACK timeout (pgn=0x%lX), resetting TX session\n", j_tx.PGN);
|
||||
J_TxReset();
|
||||
}
|
||||
}
|
||||
|
||||
static void J_SendTpRts(void){
|
||||
uint8_t data[8];
|
||||
|
||||
data[0] = 16; // CONTROL_BYTE_TP_CM_RTS
|
||||
data[1] = j_tx.size & 0xFF;
|
||||
data[2] = j_tx.size >> 8;
|
||||
data[3] = j_tx.packets;
|
||||
data[4] = j_tx.step; // max packets before next CTS
|
||||
data[5] = j_tx.PGN;
|
||||
data[6] = j_tx.PGN >> 8;
|
||||
data[7] = j_tx.PGN >> 16;
|
||||
|
||||
J1939_TxQueueByPgn(0x00EC00, 7, 8, data, 0);
|
||||
}
|
||||
|
||||
static void J_SendTpDtRange(uint8_t start_packet, uint8_t count){
|
||||
uint8_t dt[8];
|
||||
uint8_t packet;
|
||||
uint8_t i;
|
||||
uint16_t idx;
|
||||
|
||||
if(j_tx.state != 1){
|
||||
log_printf(LOG_WARN, "J1939 chunk send failed: TP DT ignored (invalid TX state=%u)\n", j_tx.state);
|
||||
return;
|
||||
}
|
||||
|
||||
if((start_packet == 0) || (start_packet > j_tx.packets)) return;
|
||||
if(count == 0) return;
|
||||
if(start_packet != j_tx.next_packet){
|
||||
log_printf(LOG_WARN, "J1939 chunk send failed: TP desync (start=%u expected=%u), resetting TX session\n", start_packet, j_tx.next_packet);
|
||||
J_TxReset();
|
||||
return;
|
||||
}
|
||||
if((start_packet + count - 1) > j_tx.packets){
|
||||
count = j_tx.packets - start_packet + 1;
|
||||
}
|
||||
|
||||
for(packet = 0; packet < count; packet++){
|
||||
uint8_t seq = start_packet + packet;
|
||||
dt[0] = seq;
|
||||
idx = (uint16_t)(seq - 1) * 7;
|
||||
for(i = 0; i < 7; i++){
|
||||
if((idx + i) < j_tx.size) dt[i + 1] = j_tx.data[idx + i];
|
||||
else dt[i + 1] = 0xFF;
|
||||
}
|
||||
J1939_TxQueueByPgn(0x00EB00, 7, 8, dt, 0);
|
||||
}
|
||||
log_printf(LOG_DEBUG, "J1939 event: TP DT sent (pgn=0x%lX start=%u cnt=%u)\n", j_tx.PGN, start_packet, count);
|
||||
|
||||
j_tx.next_packet = start_packet + count;
|
||||
j_tx.tick = HAL_GetTick();
|
||||
if(j_tx.next_packet > j_tx.packets){
|
||||
j_tx.state = 2; // wait ACK
|
||||
}else{
|
||||
j_tx.state = 1; // wait next CTS
|
||||
}
|
||||
}
|
||||
|
||||
//void J_SendPacketLong(){
|
||||
// //TODO (no need)
|
||||
//}
|
||||
@@ -195,3 +455,77 @@ void GBT_CAN_FilterInit(){
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void J1939_RxBufferAdd(const j1939_rx_frame_t *frame){
|
||||
J1939_CRITICAL_ENTER();
|
||||
j_rxbuf.buffer[j_rxbuf.head] = *frame;
|
||||
j_rxbuf.head = (j_rxbuf.head + 1U) % J1939_BUFFER_SIZE;
|
||||
if(j_rxbuf.count == J1939_BUFFER_SIZE){
|
||||
j_rxbuf.tail = (j_rxbuf.tail + 1U) % J1939_BUFFER_SIZE;
|
||||
j_rxbuf.overflow++;
|
||||
log_printf(LOG_WARN, "J1939 RX buffer overflow: dropped oldest frame, overflow_count=%lu\n", j_rxbuf.overflow);
|
||||
}else{
|
||||
j_rxbuf.count++;
|
||||
}
|
||||
J1939_CRITICAL_EXIT();
|
||||
}
|
||||
|
||||
static uint8_t J1939_RxBufferGet(j1939_rx_frame_t *frame){
|
||||
uint8_t ok = 0;
|
||||
J1939_CRITICAL_ENTER();
|
||||
if(j_rxbuf.count > 0){
|
||||
*frame = j_rxbuf.buffer[j_rxbuf.tail];
|
||||
j_rxbuf.tail = (j_rxbuf.tail + 1U) % J1939_BUFFER_SIZE;
|
||||
j_rxbuf.count--;
|
||||
ok = 1;
|
||||
}
|
||||
J1939_CRITICAL_EXIT();
|
||||
return ok;
|
||||
}
|
||||
|
||||
static void J1939_TxBufferAdd(const j1939_tx_frame_t *frame){
|
||||
J1939_CRITICAL_ENTER();
|
||||
j_txbuf.buffer[j_txbuf.head] = *frame;
|
||||
j_txbuf.head = (j_txbuf.head + 1U) % J1939_BUFFER_SIZE;
|
||||
if(j_txbuf.count == J1939_BUFFER_SIZE){
|
||||
j_txbuf.tail = (j_txbuf.tail + 1U) % J1939_BUFFER_SIZE;
|
||||
j_txbuf.overflow++;
|
||||
log_printf(LOG_WARN, "J1939 TX buffer overflow: dropped oldest frame, overflow_count=%lu\n", j_txbuf.overflow);
|
||||
}else{
|
||||
j_txbuf.count++;
|
||||
}
|
||||
J1939_CRITICAL_EXIT();
|
||||
}
|
||||
|
||||
static uint8_t J1939_TxBufferPeek(j1939_tx_frame_t *frame){
|
||||
uint8_t ok = 0;
|
||||
J1939_CRITICAL_ENTER();
|
||||
if(j_txbuf.count > 0){
|
||||
*frame = j_txbuf.buffer[j_txbuf.tail];
|
||||
ok = 1;
|
||||
}
|
||||
J1939_CRITICAL_EXIT();
|
||||
return ok;
|
||||
}
|
||||
|
||||
static void J1939_TxBufferDropFirst(void){
|
||||
J1939_CRITICAL_ENTER();
|
||||
if(j_txbuf.count > 0){
|
||||
j_txbuf.tail = (j_txbuf.tail + 1U) % J1939_BUFFER_SIZE;
|
||||
j_txbuf.count--;
|
||||
}
|
||||
J1939_CRITICAL_EXIT();
|
||||
}
|
||||
|
||||
static void J1939_TxQueueByPgn(uint32_t PGN, uint8_t pri, uint8_t DLC, const uint8_t *data, uint8_t pad_ff){
|
||||
j1939_tx_frame_t frame;
|
||||
uint8_t i;
|
||||
|
||||
frame.ExtId = (pri << 26) | (PGN << 8) | (J_ID_SE << 8) | J_ID_EV;
|
||||
frame.DLC = DLC;
|
||||
for(i = 0; i < 8; i++){
|
||||
if(i < DLC) frame.data[i] = data[i];
|
||||
else frame.data[i] = pad_ff ? 0xFF : 0x00;
|
||||
}
|
||||
J1939_TxBufferAdd(&frame);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
#include "load.h"
|
||||
#include "board.h"
|
||||
#include "debug.h"
|
||||
#include "connector.h"
|
||||
|
||||
#define COOLDOWN_TIME 60000
|
||||
|
||||
void LOAD_Init(){
|
||||
RELAY_Write(RELAY_1, 0);
|
||||
RELAY_Write(RELAY_2, 0);
|
||||
RELAY_Write(RELAY_3, 0);
|
||||
RELAY_Write(RELAY_4, 0);
|
||||
RELAY_Write(RELAY_5, 0);
|
||||
}
|
||||
|
||||
void LOAD_Task(){
|
||||
static uint32_t load_tick = 0;
|
||||
if(CONN[0].enableLoad || CONN[1].enableLoad){
|
||||
load_tick = HAL_GetTick();
|
||||
}
|
||||
|
||||
if((HAL_GetTick() - load_tick < COOLDOWN_TIME) && (load_tick!=0)){
|
||||
RELAY_Write(RELAY_1, 1);
|
||||
}else{
|
||||
RELAY_Write(RELAY_1, 0);
|
||||
}
|
||||
|
||||
|
||||
if(CONN[0].enableLoad){
|
||||
RELAY_Write(RELAY_2, 1);
|
||||
}else{
|
||||
RELAY_Write(RELAY_2, 0);
|
||||
}
|
||||
if(CONN[1].enableLoad){
|
||||
RELAY_Write(RELAY_3, 1);
|
||||
}else{
|
||||
RELAY_Write(RELAY_3, 0);
|
||||
}
|
||||
|
||||
// if(CONN[0].enableLoad && CONN[1].enableLoad){ // объединение нагрузок
|
||||
// RELAY_Write(RELAY_4, 0);
|
||||
// }else{
|
||||
// RELAY_Write(RELAY_4, 1);
|
||||
// }
|
||||
}
|
||||
+20
-9
@@ -30,13 +30,15 @@
|
||||
#include "can.h"
|
||||
#include "board.h"
|
||||
#include <stdio.h>
|
||||
#include "debug.h"
|
||||
#include "charger_gbt.h"
|
||||
#include "soft_rtc.h"
|
||||
#include "j1939.h"
|
||||
#include "connector.h"
|
||||
#include "rgb_controller.h"
|
||||
|
||||
#include "serial_control.h"
|
||||
#include "cp.h"
|
||||
#include "debug.h"
|
||||
#include "load.h"
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
@@ -60,6 +62,7 @@
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
/* USER CODE BEGIN PV */
|
||||
volatile CP_State_t cp_state = EV_STATE_B_CONN_PREP;
|
||||
|
||||
/* USER CODE END PV */
|
||||
|
||||
@@ -116,23 +119,26 @@ int main(void)
|
||||
MX_UART5_Init();
|
||||
MX_USART1_UART_Init();
|
||||
MX_USART3_UART_Init();
|
||||
MX_TIM3_Init();
|
||||
/* USER CODE BEGIN 2 */
|
||||
CAN_ReInit();
|
||||
Init_Peripheral();
|
||||
LED_Init();
|
||||
|
||||
LOAD_Init();
|
||||
HAL_Delay(300);
|
||||
GBT_Init();
|
||||
set_Time(1721651966);
|
||||
printf("Startup (type \'help\' for command list)\n");
|
||||
debug_init();
|
||||
EDCAN_Init(0x00);
|
||||
EDCAN_printf(LOG_INFO, "Startup FW %d.%d.%d\n", FWVER_MAJOR, FWVER_MINOR, FWVER_PATCH);
|
||||
// printf("Startup serial control enabled\n");
|
||||
EDCAN_Init(InfoBlock->addrEdcan);
|
||||
log_printf(LOG_INFO, "Startup FW %d.%d.%d\n", FWVER_MAJOR, FWVER_MINOR, FWVER_PATCH);
|
||||
//EDCAN_Init(0x20); //Адрес EDCAN
|
||||
GBT_CAN_ReInit();
|
||||
CAN_ReInit();
|
||||
|
||||
CONN_Init();
|
||||
SC_Init();
|
||||
CP_Init();
|
||||
|
||||
/* USER CODE END 2 */
|
||||
|
||||
/* Infinite loop */
|
||||
@@ -142,10 +148,15 @@ int main(void)
|
||||
/* USER CODE END WHILE */
|
||||
|
||||
/* USER CODE BEGIN 3 */
|
||||
// HAL_Delay(1);
|
||||
|
||||
CONN[1].MeasuredVoltage = ISO.voltageComm;
|
||||
LOAD_Task();
|
||||
EDCAN_Loop();
|
||||
//can_task();
|
||||
debug_task();
|
||||
J1939_ExchangeRxBuffer();
|
||||
J1939_ExchangeTxBuffer();
|
||||
SC_Task();
|
||||
CP_Task();
|
||||
CONN_CC_ReadStateFiltered();
|
||||
// GBT_ManageLock();
|
||||
CONN_Task();
|
||||
|
||||
@@ -90,11 +90,11 @@ RGB_Cycle_t color_error = {
|
||||
};
|
||||
|
||||
void LED_Write(){
|
||||
if(CONN.chargingError != CONN_NO_ERROR){
|
||||
if(CONN[0].chargingError != CONN_NO_ERROR){
|
||||
LED_SetColor(&color_error);
|
||||
return;
|
||||
}
|
||||
switch(CONN.connState){
|
||||
switch(CONN[0].connState){
|
||||
case Unknown:
|
||||
LED_SetColor(&color_unknown);
|
||||
break;
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
#include "serial_control.h"
|
||||
#include "usart.h"
|
||||
#include "charger_gbt.h"
|
||||
#include "edcan_config.h"
|
||||
#include "string.h"
|
||||
|
||||
static uint32_t calculate_crc32(const uint8_t *data, uint16_t length);
|
||||
static uint16_t encode_packet(const uint8_t *payload, uint16_t payload_len, uint8_t *output, uint8_t response_code);
|
||||
static uint8_t parse_packet(const uint8_t *packet_data, uint16_t packet_len, ReceivedCommand_t *out_cmd);
|
||||
static uint8_t process_received_packet(SerialControl_t *ctx, const uint8_t *packet_data, uint16_t packet_len);
|
||||
static void SC_ArmUart2Rx(void);
|
||||
|
||||
SerialControl_t serial_control;
|
||||
static SerialControl_t serial_iso;
|
||||
volatile SC_Source_t g_sc_command_source = SC_SOURCE_UART2;
|
||||
|
||||
GBT_MonitorPacket_t gbtMonitorPacket = {
|
||||
.connector_type = 0x01,
|
||||
};
|
||||
|
||||
CCS_MonitorPacket_t ccsMonitorPacket = {
|
||||
.connector_type = 0x02,
|
||||
};
|
||||
|
||||
InfoPacket_t infoPacket = {
|
||||
.serialNumber = 0,
|
||||
.boardVersion = 0,
|
||||
.stationType = 0,
|
||||
.fw_version_major = 0,
|
||||
.fw_version_minor = 0,
|
||||
.fw_version_patch = 0,
|
||||
};
|
||||
|
||||
void SC_Init(void) {
|
||||
memset(&serial_control, 0, sizeof(serial_control));
|
||||
memset(&serial_iso, 0, sizeof(serial_iso));
|
||||
}
|
||||
|
||||
void SC_Task(void) {
|
||||
SC_ArmUart2Rx();
|
||||
if ((&huart5)->RxState == HAL_UART_STATE_READY) {
|
||||
(void)HAL_UARTEx_ReceiveToIdle_IT(&huart5, serial_iso.rx_buffer, MAX_RX_BUFFER_SIZE - 1);
|
||||
}
|
||||
|
||||
if (huart2.gState == HAL_UART_STATE_BUSY_TX && serial_control.tx_tick != 0U) {
|
||||
if ((HAL_GetTick() - serial_control.tx_tick) > 100U) {
|
||||
HAL_UART_Abort_IT(&huart2);
|
||||
HAL_GPIO_WritePin(USART2_DIR_GPIO_Port, USART2_DIR_Pin, GPIO_PIN_RESET);
|
||||
serial_control.tx_tick = 0U;
|
||||
}
|
||||
}
|
||||
|
||||
if (serial_control.command_ready && (huart2.gState != HAL_UART_STATE_BUSY_TX)) {
|
||||
SC_CommandHandler((ReceivedCommand_t *)&serial_control.received_command);
|
||||
serial_control.command_ready = 0U;
|
||||
SC_ArmUart2Rx();
|
||||
}
|
||||
|
||||
if (serial_control.response_pending && (huart2.gState != HAL_UART_STATE_BUSY_TX)) {
|
||||
SC_SendPacket(NULL, 0, serial_control.response_code);
|
||||
serial_control.response_pending = 0U;
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) {
|
||||
if (huart->Instance == huart2.Instance) {
|
||||
if (!process_received_packet(&serial_control, serial_control.rx_buffer, Size)) {
|
||||
serial_control.response_pending = 1U;
|
||||
serial_control.response_code = RESP_INVALID;
|
||||
SC_ArmUart2Rx();
|
||||
} else {
|
||||
g_sc_command_source = SC_SOURCE_UART2;
|
||||
}
|
||||
} else if (huart->Instance == huart5.Instance) {
|
||||
if (process_received_packet(&serial_iso, serial_iso.rx_buffer, Size)) {
|
||||
g_sc_command_source = SC_SOURCE_UART5;
|
||||
SC_CommandHandler((ReceivedCommand_t *)&serial_iso.received_command);
|
||||
}
|
||||
(void)HAL_UARTEx_ReceiveToIdle_IT(&huart5, serial_iso.rx_buffer, MAX_RX_BUFFER_SIZE - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) {
|
||||
if (huart->Instance == huart2.Instance) {
|
||||
SC_ArmUart2Rx();
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
|
||||
if (huart->Instance == huart2.Instance) {
|
||||
HAL_GPIO_WritePin(USART2_DIR_GPIO_Port, USART2_DIR_Pin, GPIO_PIN_RESET);
|
||||
serial_control.tx_tick = 0U;
|
||||
}
|
||||
}
|
||||
|
||||
static void SC_ArmUart2Rx(void) {
|
||||
if ((&huart2)->RxState == HAL_UART_STATE_READY && serial_control.command_ready == 0U) {
|
||||
(void)HAL_UARTEx_ReceiveToIdle_IT(&huart2, serial_control.rx_buffer, MAX_RX_BUFFER_SIZE - 1);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t calculate_crc32(const uint8_t *data, uint16_t length) {
|
||||
uint32_t crc = 0xFFFFFFFFu;
|
||||
|
||||
for (uint16_t i = 0; i < length; i++) {
|
||||
crc ^= data[i];
|
||||
for (uint8_t bit = 0; bit < 8; bit++) {
|
||||
if (crc & 0x1u) {
|
||||
crc = (crc >> 1) ^ CRC32_POLYNOMIAL;
|
||||
} else {
|
||||
crc >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return crc ^ 0xFFFFFFFFu;
|
||||
}
|
||||
|
||||
static uint16_t encode_packet(const uint8_t *payload, uint16_t payload_len, uint8_t *output, uint8_t response_code) {
|
||||
uint16_t out_index = 0;
|
||||
|
||||
output[out_index++] = response_code;
|
||||
|
||||
if (payload != NULL) {
|
||||
for (uint16_t i = 0; i < payload_len; i++) {
|
||||
output[out_index++] = payload[i];
|
||||
if (out_index >= MAX_TX_BUFFER_SIZE - 5) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t crc = calculate_crc32(output, out_index);
|
||||
uint8_t *crc_bytes = (uint8_t *)&crc;
|
||||
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
output[out_index++] = crc_bytes[i];
|
||||
if (out_index >= MAX_TX_BUFFER_SIZE - 1) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return out_index;
|
||||
}
|
||||
|
||||
void SC_SendPacket(const uint8_t *payload, uint16_t payload_len, uint8_t response_code) {
|
||||
uint16_t packet_len = encode_packet(payload, payload_len, serial_control.tx_buffer, response_code);
|
||||
|
||||
if (packet_len > 0U) {
|
||||
if (huart2.gState == HAL_UART_STATE_BUSY_TX) {
|
||||
HAL_UART_Abort_IT(&huart2);
|
||||
HAL_GPIO_WritePin(USART2_DIR_GPIO_Port, USART2_DIR_Pin, GPIO_PIN_RESET);
|
||||
}
|
||||
|
||||
HAL_GPIO_WritePin(USART2_DIR_GPIO_Port, USART2_DIR_Pin, GPIO_PIN_SET);
|
||||
HAL_UART_Transmit_IT(&huart2, serial_control.tx_buffer, packet_len);
|
||||
serial_control.tx_tick = HAL_GetTick();
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t parse_packet(const uint8_t *packet_data, uint16_t packet_len, ReceivedCommand_t *out_cmd) {
|
||||
if (packet_len < 5U || packet_len > MAX_RX_BUFFER_SIZE) {
|
||||
return 0U;
|
||||
}
|
||||
|
||||
uint16_t payload_length = packet_len - 4U;
|
||||
uint32_t received_checksum =
|
||||
((uint32_t)packet_data[payload_length] << 0) |
|
||||
((uint32_t)packet_data[payload_length + 1U] << 8) |
|
||||
((uint32_t)packet_data[payload_length + 2U] << 16) |
|
||||
((uint32_t)packet_data[payload_length + 3U] << 24);
|
||||
|
||||
uint32_t calculated_checksum = calculate_crc32(packet_data, payload_length);
|
||||
if (received_checksum != calculated_checksum) {
|
||||
return 0U;
|
||||
}
|
||||
|
||||
out_cmd->command = packet_data[0];
|
||||
out_cmd->argument = (void *)&packet_data[1];
|
||||
out_cmd->argument_length = (uint8_t)(payload_length - 1U);
|
||||
return 1U;
|
||||
}
|
||||
|
||||
static uint8_t process_received_packet(SerialControl_t *ctx, const uint8_t *packet_data, uint16_t packet_len) {
|
||||
if (!parse_packet(packet_data, packet_len, (ReceivedCommand_t *)&ctx->received_command)) {
|
||||
return 0U;
|
||||
}
|
||||
|
||||
ctx->command_ready = 1U;
|
||||
return 1U;
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
#include "serial_control.h"
|
||||
#include "charger_gbt.h"
|
||||
#include "cp.h"
|
||||
#include "edcan_config.h"
|
||||
#include <string.h>
|
||||
#include "board.h"
|
||||
#include "debug.h"
|
||||
|
||||
static void SC_FillGBTMonitorPacket(void);
|
||||
static void SC_FillCCSMonitorPacket(void);
|
||||
static void SC_FillInfoPacket(void);
|
||||
|
||||
IsolationStatusPacket_t ISO = {
|
||||
.isolationResistance = 0xFFFF
|
||||
};
|
||||
|
||||
void SC_CommandHandler(ReceivedCommand_t *cmd) {
|
||||
uint8_t response_code = RESP_FAILED;
|
||||
|
||||
if (cmd->command == CMD_ISOLATION_STATUS) {
|
||||
if (cmd->argument_length == sizeof(IsolationStatusPacket_t)) {
|
||||
memcpy(&ISO, cmd->argument, sizeof(IsolationStatusPacket_t));
|
||||
if (g_sc_command_source == SC_SOURCE_UART5) {
|
||||
return;
|
||||
}
|
||||
response_code = RESP_SUCCESS;
|
||||
} else {
|
||||
response_code = RESP_FAILED;
|
||||
}
|
||||
SC_SendPacket(NULL, 0, response_code);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (cmd->command) {
|
||||
|
||||
case CMD_GET_GBT_STATUS:
|
||||
SC_FillGBTMonitorPacket();
|
||||
SC_SendPacket((const uint8_t *)&gbtMonitorPacket, sizeof(gbtMonitorPacket), CMD_GET_GBT_STATUS);
|
||||
return;
|
||||
|
||||
case CMD_GET_CCS_STATUS:
|
||||
SC_FillCCSMonitorPacket();
|
||||
SC_SendPacket((const uint8_t *)&ccsMonitorPacket, sizeof(ccsMonitorPacket), CMD_GET_CCS_STATUS);
|
||||
return;
|
||||
|
||||
case CMD_GET_INFO:
|
||||
SC_FillInfoPacket();
|
||||
SC_SendPacket((const uint8_t *)&infoPacket, sizeof(infoPacket), CMD_GET_INFO);
|
||||
return;
|
||||
|
||||
case CMD_GET_LOG:
|
||||
debug_buffer_send();
|
||||
return;
|
||||
|
||||
case CMD_GBT_CC_ENABLE:
|
||||
if (cmd->argument_length == sizeof(uint8_t)) {
|
||||
uint8_t enable = *((uint8_t *)cmd->argument);
|
||||
cc_enable = enable ? 1U : 0U;
|
||||
response_code = RESP_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_GBT_STOP:
|
||||
if (cmd->argument_length == 0U) {
|
||||
CONN[0].connControl = CMD_STOP;
|
||||
response_code = RESP_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_GBT_SET_REQUEST:
|
||||
if (cmd->argument_length == sizeof(EvSetLimits_t)) {
|
||||
EvSetLimits_t *limits = (EvSetLimits_t *)cmd->argument;
|
||||
CONN[0].RequestedVoltage = limits->requestedVoltage;
|
||||
CONN[0].RequestedCurrent = limits->requestedCurrent;
|
||||
response_code = RESP_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_GBT_SET_SOC:
|
||||
if (cmd->argument_length == sizeof(uint8_t)) {
|
||||
CONN[0].SOC = *((uint8_t *)cmd->argument);
|
||||
response_code = RESP_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_GBT_SET_VIN:
|
||||
if (cmd->argument_length == 17U) {
|
||||
memcpy(GBT_EVInfo.EVIN, cmd->argument, 17U);
|
||||
response_code = RESP_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_CCS_SET_STATE:
|
||||
if (cmd->argument_length == sizeof(uint8_t)) {
|
||||
cp_state = (CP_State_t)(*((uint8_t *)cmd->argument));
|
||||
response_code = RESP_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_CCS_ENABLE_LOAD:
|
||||
if (cmd->argument_length == sizeof(uint8_t)) {
|
||||
uint8_t enable = *((uint8_t *)cmd->argument);
|
||||
CONN[1].enableLoad = enable ? 1U : 0U;
|
||||
CONN[1].ContactorEnabled = CONN[1].enableLoad;
|
||||
response_code = RESP_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
response_code = RESP_FAILED;
|
||||
break;
|
||||
}
|
||||
|
||||
SC_SendPacket(NULL, 0, response_code);
|
||||
}
|
||||
|
||||
static void SC_FillInfoPacket(void) {
|
||||
infoPacket.serialNumber = 0;
|
||||
infoPacket.boardVersion = 0;
|
||||
infoPacket.stationType = 0;
|
||||
infoPacket.fw_version_major = FWVER_MAJOR;
|
||||
infoPacket.fw_version_minor = FWVER_MINOR;
|
||||
infoPacket.fw_version_patch = FWVER_PATCH;
|
||||
}
|
||||
|
||||
static void SC_FillGBTMonitorPacket(void) {
|
||||
gbtMonitorPacket.connector_type = 0x01;
|
||||
gbtMonitorPacket.requestedVoltage = CONN[0].RequestedVoltage;
|
||||
gbtMonitorPacket.requestedCurrent = CONN[0].RequestedCurrent;
|
||||
gbtMonitorPacket.measuredVoltageSE = CONN[0].MeasuredVoltageSE;
|
||||
gbtMonitorPacket.measuredCurrentSE = CONN[0].MeasuredCurrentSE;
|
||||
gbtMonitorPacket.measuredVoltage = CONN[0].MeasuredVoltage;
|
||||
gbtMonitorPacket.measuredCurrent = CONN[0].MeasuredCurrent;
|
||||
gbtMonitorPacket.cc_enabled = cc_enable;
|
||||
gbtMonitorPacket.contactorEnabled = CONN[0].ContactorEnabled;
|
||||
gbtMonitorPacket.chargingError = CONN[0].chargingError;
|
||||
gbtMonitorPacket.EvseConnected = CONN[0].EvseConnected;
|
||||
gbtMonitorPacket.soc = CONN[0].SOC;
|
||||
memcpy(gbtMonitorPacket.vin, GBT_EVInfo.EVIN, sizeof(gbtMonitorPacket.vin));
|
||||
gbtMonitorPacket.cc_state = CONN_CC_GetState();
|
||||
gbtMonitorPacket.logs_available = (debug_buffer_available() > 0U) ? 1U : 0U;
|
||||
gbtMonitorPacket.connState = CONN[0].connState;
|
||||
}
|
||||
|
||||
static void SC_FillCCSMonitorPacket(void) {
|
||||
CP_Measurement_t cp_meas = CP_GetMeasurement();
|
||||
|
||||
ccsMonitorPacket.connector_type = 0x02;
|
||||
ccsMonitorPacket.measuredVoltage = CONN[1].MeasuredVoltage;
|
||||
ccsMonitorPacket.measuredCurrent = CONN[1].MeasuredCurrent;
|
||||
ccsMonitorPacket.cp_enabled = (cp_state != EV_STATE_A_IDLE) ? 1U : 0U;
|
||||
ccsMonitorPacket.contactorEnabled = CONN[1].ContactorEnabled;
|
||||
ccsMonitorPacket.chargingError = CONN[1].chargingError;
|
||||
ccsMonitorPacket.EvseConnected = CONN[1].EvseConnected;
|
||||
ccsMonitorPacket.soc = CONN[1].SOC;
|
||||
ccsMonitorPacket.cp_state = (uint8_t)cp_state;
|
||||
ccsMonitorPacket.cp_pwm_duty = cp_meas.valid ? cp_meas.duty_percent : 0U;
|
||||
}
|
||||
|
||||
Executable → Regular
+30
@@ -57,6 +57,8 @@
|
||||
/* External variables --------------------------------------------------------*/
|
||||
extern CAN_HandleTypeDef hcan1;
|
||||
extern CAN_HandleTypeDef hcan2;
|
||||
extern TIM_HandleTypeDef htim3;
|
||||
extern UART_HandleTypeDef huart5;
|
||||
extern UART_HandleTypeDef huart2;
|
||||
/* USER CODE BEGIN EV */
|
||||
|
||||
@@ -214,6 +216,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 USART2 global interrupt.
|
||||
*/
|
||||
@@ -228,6 +244,20 @@ void USART2_IRQHandler(void)
|
||||
/* USER CODE END USART2_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles UART5 global interrupt.
|
||||
*/
|
||||
void UART5_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN UART5_IRQn 0 */
|
||||
|
||||
/* USER CODE END UART5_IRQn 0 */
|
||||
HAL_UART_IRQHandler(&huart5);
|
||||
/* USER CODE BEGIN UART5_IRQn 1 */
|
||||
|
||||
/* USER CODE END UART5_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles CAN2 TX interrupt.
|
||||
*/
|
||||
|
||||
+100
-2
@@ -24,8 +24,62 @@
|
||||
|
||||
/* 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_IC_InitTypeDef sConfigIC = {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_IC_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();
|
||||
}
|
||||
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
|
||||
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
|
||||
sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
|
||||
sConfigIC.ICFilter = 4;
|
||||
if (HAL_TIM_IC_ConfigChannel(&htim3, &sConfigIC, TIM_CHANNEL_2) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN TIM3_Init 2 */
|
||||
|
||||
/* USER CODE END TIM3_Init 2 */
|
||||
|
||||
}
|
||||
/* TIM4 init function */
|
||||
void MX_TIM4_Init(void)
|
||||
{
|
||||
@@ -92,7 +146,32 @@ void MX_TIM4_Init(void)
|
||||
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
|
||||
{
|
||||
|
||||
if(tim_baseHandle->Instance==TIM4)
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
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();
|
||||
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
/**TIM3 GPIO Configuration
|
||||
PA7 ------> TIM3_CH2
|
||||
*/
|
||||
GPIO_InitStruct.Pin = CP_PWM_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(CP_PWM_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/* 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 */
|
||||
|
||||
@@ -137,7 +216,26 @@ 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 GPIO Configuration
|
||||
PA7 ------> TIM3_CH2
|
||||
*/
|
||||
HAL_GPIO_DeInit(CP_PWM_GPIO_Port, CP_PWM_Pin);
|
||||
|
||||
/* 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 */
|
||||
|
||||
|
||||
+7
-2
@@ -41,7 +41,7 @@ void MX_UART5_Init(void)
|
||||
|
||||
/* USER CODE END UART5_Init 1 */
|
||||
huart5.Instance = UART5;
|
||||
huart5.Init.BaudRate = 115200;
|
||||
huart5.Init.BaudRate = 9600;
|
||||
huart5.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
huart5.Init.StopBits = UART_STOPBITS_1;
|
||||
huart5.Init.Parity = UART_PARITY_NONE;
|
||||
@@ -70,7 +70,7 @@ void MX_USART1_UART_Init(void)
|
||||
|
||||
/* USER CODE END USART1_Init 1 */
|
||||
huart1.Instance = USART1;
|
||||
huart1.Init.BaudRate = 115200;
|
||||
huart1.Init.BaudRate = 460800;
|
||||
huart1.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
huart1.Init.StopBits = UART_STOPBITS_1;
|
||||
huart1.Init.Parity = UART_PARITY_NONE;
|
||||
@@ -173,6 +173,9 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
|
||||
|
||||
/* UART5 interrupt Init */
|
||||
HAL_NVIC_SetPriority(UART5_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(UART5_IRQn);
|
||||
/* USER CODE BEGIN UART5_MspInit 1 */
|
||||
|
||||
/* USER CODE END UART5_MspInit 1 */
|
||||
@@ -286,6 +289,8 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
|
||||
|
||||
HAL_GPIO_DeInit(GPIOD, GPIO_PIN_2);
|
||||
|
||||
/* UART5 interrupt Deinit */
|
||||
HAL_NVIC_DisableIRQ(UART5_IRQn);
|
||||
/* USER CODE BEGIN UART5_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END UART5_MspDeInit 1 */
|
||||
|
||||
Reference in New Issue
Block a user