latest version
This commit is contained in:
@@ -11,18 +11,31 @@
|
||||
void GBT_Lock(uint8_t state);
|
||||
|
||||
typedef enum{
|
||||
RELAY_AUX,
|
||||
RELAY_CC,
|
||||
RELAY_1,
|
||||
RELAY_2,
|
||||
RELAY_3,
|
||||
RELAY_4,
|
||||
RELAY_5,
|
||||
|
||||
}relay_t;
|
||||
|
||||
typedef enum{
|
||||
IN_ISO,
|
||||
IN_ESTOP,
|
||||
IN_FB1,
|
||||
IN_FB2,
|
||||
IN_SW0,
|
||||
IN_SW1,
|
||||
IN_0,
|
||||
IN_ACOK,
|
||||
}inputNum_t;
|
||||
|
||||
void RELAY_Write(relay_t num, uint8_t state);
|
||||
void Init_Peripheral();
|
||||
uint8_t GBT_LockGetState();
|
||||
void GBT_Lock(uint8_t state);
|
||||
uint8_t SW_GetAddr();
|
||||
void ADC_Select_Channel(uint32_t ch);
|
||||
int16_t GBT_ReadTemp(uint8_t ch);
|
||||
|
||||
uint8_t IN_ReadInput(inputNum_t input_n);
|
||||
|
||||
#endif /* SRC_BOARD_H_ */
|
||||
|
||||
@@ -41,34 +41,21 @@ typedef enum{
|
||||
|
||||
}gbtCcState_t;
|
||||
|
||||
typedef enum __attribute__((packed)){
|
||||
CONN_NO_ERROR = 0,
|
||||
CONN_ERR_INSULATION = 1,
|
||||
CONN_ERR_EMERGENCY = 2,
|
||||
CONN_ERR_DOOR_OPEN = 3,
|
||||
CONN_ERR_LOCK = 4,
|
||||
CONN_ERR_CONN_TEMP = 5,
|
||||
|
||||
}CONN_Error_t;
|
||||
|
||||
/* Стейты GB/T со стороны EV: постоянно шлём свой пакет, ждём ответ → переход, шлём другой пакет */
|
||||
typedef enum{
|
||||
GBT_DISABLED = 0x10,
|
||||
// GBT_S0_UNCONNECTED = 0x10, //СС1 12V/6V СС2 12V
|
||||
// GBT_S1_CONNECTED = 0x11, //СС1 4V СС2 4V (6V)
|
||||
// GBT_S2_LOCKED = 0x12, //
|
||||
GBT_S3_STARTED = 0x13, // 12V AUX
|
||||
GBT_S31_WAIT_BHM = 0x14, // testing isolation, send CHM receive BHM
|
||||
GBT_S4_ISOTEST = 0x15, // testing isolation, send CHM receive BHM
|
||||
GBT_S5_BAT_INFO = 0x16, // identifying BMS, send CRM receive BRM (long)
|
||||
GBT_S6_BAT_STAT = 0x17, // send CRM(AA), receive BCP (long)
|
||||
GBT_S7_BMS_WAIT = 0x18, // wait for BMS, send CTS+CML receive BRO(00), next BRO(AA)
|
||||
GBT_S8_INIT_CHARGER = 0x19,// starting power modules, send CRO(00)
|
||||
GBT_S9_WAIT_BCL = 0x20, // waiting for BCL (requested voltage), send CRO(00)
|
||||
GBT_S10_CHARGING = 0x21, // charging, contactor ON, send CCS, receiving BCL+BCS+BSM
|
||||
GBT_STOP = 0x22, // normal stop
|
||||
GBT_STOP_CSD = 0x23, // normal stop
|
||||
GBT_ERROR = 0x24, // Error
|
||||
GBT_COMPLETE = 0x25,
|
||||
GBT_DISABLED = 0x10, // сессия выключена
|
||||
GBT_EV_CONNECTING = 0x13, // ждём CHM (ничего не шлём), получили → шлём BHM, переход
|
||||
GBT_EV_SEND_BHM_WAIT_CRM = 0x14, // шлём BHM, ждём CRM(0x00)
|
||||
GBT_EV_HANDSHAKE = 0x15, // изотест на EV не делаем → сразу дальше
|
||||
GBT_EV_RECOGNITION = 0x16, // шлём BRM, ждём CRM(0xAA)
|
||||
GBT_EV_CHARGING_PARAMETERS = 0x17, // шлём BCP, ждём CML → шлём BRO(0x00), BRO(0xAA)
|
||||
GBT_EV_BMS_INIT = 0x18, // пауза 1.5 с (инициализация зарядника)
|
||||
GBT_EV_WAIT_CHARGER_READY = 0x19, // ждём CRO(0xAA) или 500 мс → шлём BCL
|
||||
GBT_EV_CHARGING = 0x20, // шлём BCL (запрос U/I) → зарядка
|
||||
GBT_STOP = 0x30, // остановка: EV/EVSE запросили стоп
|
||||
GBT_STOP_CSD = 0x31, // ожидание CSD от EVSE
|
||||
GBT_ERROR = 0x32, // ошибка
|
||||
GBT_COMPLETE = 0x33, // сессия завершена
|
||||
|
||||
}gbtState_t;
|
||||
|
||||
@@ -166,31 +153,32 @@ typedef struct {
|
||||
}GBT_CSD_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t enablePSU;
|
||||
uint16_t requestedVoltage; // 0.1V/bit
|
||||
uint16_t requestedCurrent; // 0.1A/bit
|
||||
uint8_t chargingMode; // 0x01 - CV, 0x02 - CC
|
||||
uint8_t chargingPercentage; //
|
||||
uint16_t chargingRemainingTimeMin; //
|
||||
uint16_t chargingElapsedTimeMin; //
|
||||
uint8_t chargingElapsedTimeSec; //
|
||||
// typedef struct {
|
||||
// uint8_t enablePSU;
|
||||
// uint16_t requestedVoltage; // 0.1V/bit
|
||||
// uint16_t requestedCurrent; // 0.1A/bit
|
||||
// uint8_t chargingMode; // 0x01 - CV, 0x02 - CC
|
||||
// uint8_t chargingPercentage; //
|
||||
// uint16_t chargingRemainingTimeMin; //
|
||||
// uint16_t chargingElapsedTimeMin; //
|
||||
// uint8_t chargingElapsedTimeSec; //
|
||||
|
||||
CONN_State_t connectorState;
|
||||
CONN_Error_t outputError; // 0 if okay
|
||||
// CONN_State_t connectorState;
|
||||
// CONN_Error_t outputError; // 0 if okay
|
||||
// uint8_t EvConnected;
|
||||
|
||||
|
||||
}GBT_EDCAN_Output_t;
|
||||
// }GBT_EDCAN_Output_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t PSU_Status;
|
||||
uint16_t measuredVoltage; // 0.1V/bit
|
||||
uint16_t measuredCurrent; // 0.1A/bit
|
||||
// typedef struct {
|
||||
// uint8_t PSU_Status;
|
||||
// uint16_t measuredVoltage; // 0.1V/bit
|
||||
// uint16_t measuredCurrent; // 0.1A/bit
|
||||
|
||||
CONN_Control_t chargeControl;
|
||||
CONN_Error_t chargingError; // 0 if okay
|
||||
// CONN_Control_t chargeControl;
|
||||
// CONN_Error_t chargingError; // 0 if okay
|
||||
|
||||
}GBT_EDCAN_Input_t;
|
||||
// }GBT_EDCAN_Input_t;
|
||||
|
||||
|
||||
/* 500 - Power Supply
|
||||
@@ -222,6 +210,7 @@ extern gbtState_t GBT_State;
|
||||
|
||||
extern ADC_HandleTypeDef hadc1;
|
||||
|
||||
extern GBT_BHM_t GBT_MaxVoltage;
|
||||
extern GBT_BRM_t GBT_EVInfo;
|
||||
extern GBT_BCP_t GBT_BATStat;
|
||||
extern GBT_BCS_t GBT_ChargingStatus;
|
||||
@@ -239,7 +228,6 @@ extern uint8_t GBT_Charger_Enable;
|
||||
extern GBT_StopSource_t GBT_StopSource;
|
||||
|
||||
void GBT_Init();
|
||||
void GBT_Start();
|
||||
void GBT_Reset();
|
||||
//void GBT_Stop(uint32_t causecode);
|
||||
void GBT_StopEV(uint32_t causecode);
|
||||
@@ -258,15 +246,15 @@ void GBT_Delay(uint32_t delay);
|
||||
uint32_t GBT_StateTick();
|
||||
void J_SendPacket(uint32_t PGN, uint8_t pri, uint8_t DLC, uint8_t *data);
|
||||
|
||||
void GBT_SendCCS();
|
||||
void GBT_SendCST(uint32_t Cause);
|
||||
void GBT_SendCRO(uint8_t state);
|
||||
void GBT_SendCML();
|
||||
void GBT_SendCTS();
|
||||
void GBT_SendCHM();
|
||||
void GBT_SendCRM(uint8_t state);
|
||||
void GBT_SendCSD();
|
||||
void GBT_SendCEM(uint32_t ErrorCode);
|
||||
// EV-side GB/T packets (EV->EVSE)
|
||||
void GBT_SendBHM(void);
|
||||
void GBT_SendBRM(void);
|
||||
void GBT_SendBCP(void);
|
||||
void GBT_SendBRO(uint8_t state);
|
||||
void GBT_SendBCL(void);
|
||||
void GBT_SendBCS(void);
|
||||
void GBT_SendBSM(void);
|
||||
void GBT_SendBSD(void);
|
||||
|
||||
|
||||
#endif /* INC_CHARGER_GBT_H_ */
|
||||
|
||||
@@ -10,37 +10,73 @@
|
||||
|
||||
#include "main.h"
|
||||
|
||||
|
||||
|
||||
// Статус
|
||||
// статус подключения к автомобилю
|
||||
|
||||
typedef enum __attribute__((packed)) {
|
||||
CONN_Initializing = 1,
|
||||
CONN_Faulted = 2,
|
||||
CONN_Available = 3,
|
||||
CONN_Preparing = 4,// to charge
|
||||
CONN_Charging = 5,
|
||||
CONN_Finishing = 6,//, waiting to disconnect
|
||||
CONN_Suspended_EV = 7,
|
||||
CONN_Suspended_EVSE = 8,
|
||||
//Reserved
|
||||
Unknown,
|
||||
Unplugged,
|
||||
Disabled,
|
||||
Preparing,
|
||||
AuthRequired,
|
||||
WaitingForEnergy,
|
||||
ChargingPausedEV,
|
||||
ChargingPausedEVSE,
|
||||
Charging,
|
||||
AuthTimeout,
|
||||
Finished,
|
||||
FinishedEVSE,
|
||||
FinishedEV,
|
||||
Replugging
|
||||
} CONN_State_t;
|
||||
|
||||
// Управление
|
||||
// Разрешение на зарядку
|
||||
|
||||
typedef enum __attribute__((packed)) {
|
||||
CHARGING_NOT_ALLOWED = 1,
|
||||
CHARGING_ALLOWED = 2,
|
||||
FORCE_UNLOCK = 3,
|
||||
|
||||
typedef enum __attribute__((packed)){
|
||||
CMD_NONE = 0,
|
||||
CMD_STOP = 1,
|
||||
CMD_START = 2,
|
||||
CMD_FORCE_UNLOCK = 3,
|
||||
CMD_REPLUG = 4,
|
||||
} CONN_Control_t;
|
||||
#include "charger_gbt.h"
|
||||
|
||||
typedef enum __attribute__((packed)){
|
||||
CONN_NO_ERROR = 0,
|
||||
CONN_ERR_INSULATION = 1,
|
||||
CONN_ERR_EMERGENCY = 2,
|
||||
CONN_ERR_DOOR_OPEN = 3,
|
||||
CONN_ERR_LOCK = 4,
|
||||
CONN_ERR_CONN_TEMP = 5,
|
||||
} CONN_Error_t;
|
||||
|
||||
extern CONN_State_t connectorState;
|
||||
|
||||
// Глобальная структура состояния коннектора и зарядки со стороны тачки (EV),
|
||||
// по возможности совместимая по именам полей с ChargingConnector_t на стороне станции.
|
||||
typedef struct {
|
||||
CONN_Control_t connControl; // 0
|
||||
CONN_State_t connState; // 1
|
||||
|
||||
uint8_t SOC; // State of charge [%] // 2
|
||||
uint32_t Power; // Power [W] // 3..6
|
||||
uint32_t Energy; // Energy [Wh] // 7..10
|
||||
|
||||
uint16_t RequestedVoltage; // 1V/bit
|
||||
uint16_t RequestedCurrent; // 0.1A/bit
|
||||
|
||||
uint16_t MeasuredVoltage; // 1V/bit
|
||||
uint16_t MeasuredCurrent; // 0.1A/bit
|
||||
|
||||
uint16_t MeasuredVoltageSE; // 1V/bit
|
||||
uint16_t MeasuredCurrentSE; // 0.1A/bit
|
||||
|
||||
uint8_t ContactorEnabled; // 1 - enabled, 0 - disabled (команда на замыкание контактора)
|
||||
|
||||
CONN_Error_t chargingError; // 0 если ок
|
||||
uint8_t EvseConnected;
|
||||
uint32_t ChargingTime; // seconds
|
||||
uint8_t enableLoad; // 1 - enabled, 0 - disabled (команда на включение контактора)
|
||||
|
||||
uint8_t connectorType; // 0 - NONE, 1 - GBT, 2 - CCS (для EV всегда GBT)
|
||||
} CONN_t;
|
||||
|
||||
extern CONN_t CONN;
|
||||
|
||||
void CONN_Init();
|
||||
void CONN_Task();
|
||||
void CONN_SetState(CONN_State_t state);
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
#define EDCAN_CONFIG_H
|
||||
|
||||
#define DEVICE_ID 0x20
|
||||
#define FWVER 1
|
||||
#define FWVER_MAJOR 1
|
||||
#define FWVER_MINOR 0
|
||||
#define FWVER_PATCH 0
|
||||
|
||||
//если используется STM32 с одним каном
|
||||
//#define ED_CANx
|
||||
@@ -22,4 +24,6 @@ extern CAN_HandleTypeDef hcan2;
|
||||
//можно уменьшать для уменьшения объема потребляемой памяти
|
||||
#define BUFFER_SIZE 256
|
||||
|
||||
#define EDCAN_BOOTLOADER_MAGIC_ADDR 0x2000FF00u
|
||||
|
||||
#endif //EDCAN_CONFIG_H
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* lock.h
|
||||
*
|
||||
* Created on: Jul 31, 2024
|
||||
* Author: colorbass
|
||||
*/
|
||||
|
||||
#ifndef INC_LOCK_H_
|
||||
#define INC_LOCK_H_
|
||||
|
||||
#include "main.h"
|
||||
#include "stdbool.h"
|
||||
|
||||
|
||||
void GBT_Lock(uint8_t state);
|
||||
void GBT_ManageLockSolenoid();
|
||||
void GBT_ManageLockMotor();
|
||||
uint8_t GBT_LockGetState();
|
||||
void GBT_ForceLock(uint8_t state);
|
||||
void GBT_ResetErrorTimeout();
|
||||
|
||||
typedef struct {
|
||||
// uint8_t state;
|
||||
uint8_t demand;
|
||||
uint8_t error;
|
||||
uint8_t action_requested; // 0 = unlock, 1 = lock, 255 = no action
|
||||
uint8_t motor_state; // 0 = idle, 1 = motor_on, 2 = waiting_off
|
||||
uint32_t last_action_time; // время последнего изменения состояния мотора
|
||||
uint8_t retry_count; // счетчик попыток
|
||||
uint32_t error_tick; // время установки ошибки (для таймаута сброса)
|
||||
} GBT_LockState_t;
|
||||
|
||||
extern GBT_LockState_t GBT_LockState;
|
||||
|
||||
#endif /* INC_LOCK_H_ */
|
||||
|
||||
40
Core/Inc/main.h
Executable file → Normal file
40
Core/Inc/main.h
Executable file → Normal file
@@ -57,6 +57,10 @@ void Error_Handler(void);
|
||||
/* USER CODE END EFP */
|
||||
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
#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 ADC_CC1_Pin GPIO_PIN_6
|
||||
#define ADC_CC1_GPIO_Port GPIOA
|
||||
#define LOCK_A_Pin GPIO_PIN_4
|
||||
@@ -67,18 +71,36 @@ void Error_Handler(void);
|
||||
#define ADC_NTC1_GPIO_Port GPIOB
|
||||
#define ADC_NTC2_Pin GPIO_PIN_1
|
||||
#define ADC_NTC2_GPIO_Port GPIOB
|
||||
#define LOCK_FB_Pin GPIO_PIN_9
|
||||
#define LOCK_FB_GPIO_Port GPIOE
|
||||
#define ADDR_0_Pin GPIO_PIN_10
|
||||
#define ADDR_0_GPIO_Port GPIOE
|
||||
#define ADDR_1_Pin GPIO_PIN_11
|
||||
#define ADDR_1_GPIO_Port GPIOE
|
||||
#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 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 AC_OK_Pin GPIO_PIN_14
|
||||
#define AC_OK_GPIO_Port GPIOE
|
||||
#define RELAY_CC_Pin GPIO_PIN_15
|
||||
#define RELAY_CC_GPIO_Port GPIOE
|
||||
#define RELAY_CC_GPIO_Port GPIOA
|
||||
#define RELAY_DC_Pin GPIO_PIN_3
|
||||
#define RELAY_DC_GPIO_Port GPIOD
|
||||
#define USART2_DIR_Pin GPIO_PIN_4
|
||||
#define USART2_DIR_GPIO_Port GPIOD
|
||||
#define RELAY_AUX_Pin GPIO_PIN_4
|
||||
#define RELAY_AUX_GPIO_Port GPIOB
|
||||
#define IN_ESTOP_Pin GPIO_PIN_7
|
||||
#define IN_ESTOP_GPIO_Port GPIOD
|
||||
#define IN_FB2_Pin GPIO_PIN_3
|
||||
#define IN_FB2_GPIO_Port GPIOB
|
||||
#define IN_FB1_Pin GPIO_PIN_4
|
||||
#define IN_FB1_GPIO_Port GPIOB
|
||||
#define EE_WP_Pin GPIO_PIN_7
|
||||
#define EE_WP_GPIO_Port GPIOB
|
||||
#define ISO_IN_Pin GPIO_PIN_1
|
||||
#define ISO_IN_GPIO_Port GPIOE
|
||||
|
||||
/* USER CODE BEGIN Private defines */
|
||||
|
||||
|
||||
54
Core/Inc/rgb_controller.h
Normal file
54
Core/Inc/rgb_controller.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* rgb_controller.h
|
||||
*
|
||||
* Created on: Jul 25, 2024
|
||||
* Author: colorbass
|
||||
*/
|
||||
|
||||
#ifndef INC_RGB_CONTROLLER_H_
|
||||
#define INC_RGB_CONTROLLER_H_
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
typedef struct{
|
||||
uint8_t R;
|
||||
uint8_t G;
|
||||
uint8_t B;
|
||||
|
||||
}RGB_t;
|
||||
|
||||
typedef struct{
|
||||
RGB_t Color1;
|
||||
uint8_t Tr; //20ms/step, 5.1s max
|
||||
uint8_t Th; //20ms/step, 5.1s max
|
||||
uint8_t Tf; //20ms/step, 5.1s max
|
||||
uint8_t Tl; //20ms/step, 5.1s max
|
||||
RGB_t Color2;
|
||||
//uint8_t rsvd[6]; // 6 bytes reserved
|
||||
}RGB_Cycle_t;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
typedef enum{
|
||||
LED_RISING,
|
||||
LED_HIGH,
|
||||
LED_FALLING,
|
||||
LED_LOW,
|
||||
}RGB_Phase_t;
|
||||
|
||||
typedef struct{
|
||||
uint8_t state; // 0 1 2 3
|
||||
uint16_t tick;
|
||||
RGB_t color;
|
||||
uint8_t phasesync;
|
||||
}RGB_State_t;
|
||||
|
||||
void LED_Task();
|
||||
void LED_Write();
|
||||
void LED_Init();
|
||||
|
||||
|
||||
#endif /* INC_RGB_CONTROLLER_H_ */
|
||||
|
||||
2
Core/Inc/stm32f1xx_hal_conf.h
Executable file → Normal file
2
Core/Inc/stm32f1xx_hal_conf.h
Executable file → Normal file
@@ -64,7 +64,7 @@
|
||||
/*#define HAL_SMARTCARD_MODULE_ENABLED */
|
||||
/*#define HAL_SPI_MODULE_ENABLED */
|
||||
/*#define HAL_SRAM_MODULE_ENABLED */
|
||||
/*#define HAL_TIM_MODULE_ENABLED */
|
||||
#define HAL_TIM_MODULE_ENABLED
|
||||
#define HAL_UART_MODULE_ENABLED
|
||||
/*#define HAL_USART_MODULE_ENABLED */
|
||||
/*#define HAL_WWDG_MODULE_ENABLED */
|
||||
|
||||
2
Core/Inc/stm32f1xx_it.h
Executable file → Normal file
2
Core/Inc/stm32f1xx_it.h
Executable file → Normal file
@@ -22,7 +22,7 @@
|
||||
#define __STM32F1xx_IT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
|
||||
54
Core/Inc/tim.h
Normal file
54
Core/Inc/tim.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file tim.h
|
||||
* @brief This file contains all the function prototypes for
|
||||
* the tim.c file
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2026 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __TIM_H__
|
||||
#define __TIM_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
extern TIM_HandleTypeDef htim4;
|
||||
|
||||
/* USER CODE BEGIN Private defines */
|
||||
|
||||
/* USER CODE END Private defines */
|
||||
|
||||
void MX_TIM4_Init(void);
|
||||
|
||||
void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
|
||||
|
||||
/* USER CODE BEGIN Prototypes */
|
||||
|
||||
/* USER CODE END Prototypes */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __TIM_H__ */
|
||||
|
||||
9
Core/Inc/usart.h
Executable file → Normal file
9
Core/Inc/usart.h
Executable file → Normal file
@@ -32,13 +32,22 @@ extern "C" {
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
extern UART_HandleTypeDef huart5;
|
||||
|
||||
extern UART_HandleTypeDef huart1;
|
||||
|
||||
extern UART_HandleTypeDef huart2;
|
||||
|
||||
extern UART_HandleTypeDef huart3;
|
||||
|
||||
/* USER CODE BEGIN Private defines */
|
||||
|
||||
/* USER CODE END Private defines */
|
||||
|
||||
void MX_UART5_Init(void);
|
||||
void MX_USART1_UART_Init(void);
|
||||
void MX_USART2_UART_Init(void);
|
||||
void MX_USART3_UART_Init(void);
|
||||
|
||||
/* USER CODE BEGIN Prototypes */
|
||||
|
||||
|
||||
8
Core/Src/adc.c
Executable file → Normal file
8
Core/Src/adc.c
Executable file → Normal file
@@ -84,13 +84,14 @@ void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
/**ADC1 GPIO Configuration
|
||||
PA3 ------> ADC1_IN3
|
||||
PA6 ------> ADC1_IN6
|
||||
PB0 ------> ADC1_IN8
|
||||
PB1 ------> ADC1_IN9
|
||||
*/
|
||||
GPIO_InitStruct.Pin = ADC_CC1_Pin;
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_3|ADC_CC1_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
|
||||
HAL_GPIO_Init(ADC_CC1_GPIO_Port, &GPIO_InitStruct);
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = ADC_NTC1_Pin|ADC_NTC2_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
|
||||
@@ -114,11 +115,12 @@ void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle)
|
||||
__HAL_RCC_ADC1_CLK_DISABLE();
|
||||
|
||||
/**ADC1 GPIO Configuration
|
||||
PA3 ------> ADC1_IN3
|
||||
PA6 ------> ADC1_IN6
|
||||
PB0 ------> ADC1_IN8
|
||||
PB1 ------> ADC1_IN9
|
||||
*/
|
||||
HAL_GPIO_DeInit(ADC_CC1_GPIO_Port, ADC_CC1_Pin);
|
||||
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_3|ADC_CC1_Pin);
|
||||
|
||||
HAL_GPIO_DeInit(GPIOB, ADC_NTC1_Pin|ADC_NTC2_Pin);
|
||||
|
||||
|
||||
@@ -14,11 +14,47 @@ extern ADC_HandleTypeDef hadc1;
|
||||
//GBT_TEMP_SENSORS
|
||||
|
||||
void RELAY_Write(relay_t num, uint8_t state){
|
||||
if(num==RELAY_AUX)HAL_GPIO_WritePin(RELAY_AUX_GPIO_Port, RELAY_AUX_Pin, state);
|
||||
if(num==RELAY_1)HAL_GPIO_WritePin(RELAY1_GPIO_Port, RELAY1_Pin, state);
|
||||
if(num==RELAY_2)HAL_GPIO_WritePin(RELAY2_GPIO_Port, RELAY2_Pin, state);
|
||||
if(num==RELAY_3)HAL_GPIO_WritePin(RELAY3_GPIO_Port, RELAY3_Pin, 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);
|
||||
|
||||
}
|
||||
|
||||
uint8_t IN_ReadInput(inputNum_t input_n){
|
||||
switch(input_n){
|
||||
case IN_ISO:
|
||||
return HAL_GPIO_ReadPin(ISO_IN_GPIO_Port, ISO_IN_Pin);
|
||||
break;
|
||||
case IN_ESTOP:
|
||||
return HAL_GPIO_ReadPin(IN_ESTOP_GPIO_Port, IN_ESTOP_Pin);
|
||||
break;
|
||||
case IN_FB1:
|
||||
return HAL_GPIO_ReadPin(IN_FB1_GPIO_Port, IN_FB1_Pin);
|
||||
break;
|
||||
case IN_FB2:
|
||||
return HAL_GPIO_ReadPin(IN_FB2_GPIO_Port, IN_FB2_Pin);
|
||||
break;
|
||||
case IN_SW0:
|
||||
return HAL_GPIO_ReadPin(IN_SW0_GPIO_Port, IN_SW0_Pin);
|
||||
break;
|
||||
case IN_SW1:
|
||||
return HAL_GPIO_ReadPin(IN_SW1_GPIO_Port, IN_SW1_Pin);
|
||||
break;
|
||||
case IN_0:
|
||||
return HAL_GPIO_ReadPin(IN0_GPIO_Port, IN0_Pin);
|
||||
break;
|
||||
case IN_ACOK:
|
||||
return HAL_GPIO_ReadPin(AC_OK_GPIO_Port, AC_OK_Pin);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t GetBoardTemp(){
|
||||
//TODO
|
||||
// HAL_ADC_Start(&hadc1); // start the adc
|
||||
@@ -33,7 +69,11 @@ uint8_t GetBoardTemp(){
|
||||
|
||||
void Init_Peripheral(){
|
||||
HAL_ADCEx_Calibration_Start(&hadc1);
|
||||
RELAY_Write(RELAY_AUX, 0);
|
||||
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);
|
||||
RELAY_Write(RELAY_CC, 1);
|
||||
|
||||
}
|
||||
@@ -114,21 +154,21 @@ void ADC_Select_Channel(uint32_t ch) {
|
||||
Error_Handler();
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t SW_GetAddr(){
|
||||
if(!HAL_GPIO_ReadPin(ADDR_0_GPIO_Port, ADDR_0_Pin)){
|
||||
if(!HAL_GPIO_ReadPin(ADDR_1_GPIO_Port, ADDR_1_Pin)){
|
||||
return 0x23;
|
||||
}else{
|
||||
return 0x21;
|
||||
}
|
||||
|
||||
}else{
|
||||
if(!HAL_GPIO_ReadPin(ADDR_1_GPIO_Port, ADDR_1_Pin)){
|
||||
return 0x22;
|
||||
}else{
|
||||
return 0x20;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
//
|
||||
//uint8_t SW_GetAddr(){
|
||||
// if(!HAL_GPIO_ReadPin(ADDR_0_GPIO_Port, ADDR_0_Pin)){
|
||||
// if(!HAL_GPIO_ReadPin(ADDR_1_GPIO_Port, ADDR_1_Pin)){
|
||||
// return 0x23;
|
||||
// }else{
|
||||
// return 0x21;
|
||||
// }
|
||||
//
|
||||
// }else{
|
||||
// if(!HAL_GPIO_ReadPin(ADDR_1_GPIO_Port, ADDR_1_Pin)){
|
||||
// return 0x22;
|
||||
// }else{
|
||||
// return 0x20;
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//}
|
||||
|
||||
2
Core/Src/can.c
Executable file → Normal file
2
Core/Src/can.c
Executable file → Normal file
@@ -47,7 +47,7 @@ void MX_CAN1_Init(void)
|
||||
hcan1.Init.TimeTriggeredMode = DISABLE;
|
||||
hcan1.Init.AutoBusOff = ENABLE;
|
||||
hcan1.Init.AutoWakeUp = ENABLE;
|
||||
hcan1.Init.AutoRetransmission = DISABLE;
|
||||
hcan1.Init.AutoRetransmission = ENABLE;
|
||||
hcan1.Init.ReceiveFifoLocked = DISABLE;
|
||||
hcan1.Init.TransmitFifoPriority = ENABLE;
|
||||
if (HAL_CAN_Init(&hcan1) != HAL_OK)
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include "j1939.h"
|
||||
#include "string.h"
|
||||
#include "edcan.h"
|
||||
#include "lock.h"
|
||||
#include "connector.h"
|
||||
#include "soft_rtc.h"
|
||||
|
||||
@@ -23,14 +22,14 @@ gbtState_t GBT_State;
|
||||
uint32_t GBT_state_tick; //Tick after state switch
|
||||
uint32_t GBT_delay_start;
|
||||
uint32_t GBT_delay;
|
||||
uint8_t GBT_BAT_INFO_recv;
|
||||
uint8_t GBT_BAT_STAT_recv;
|
||||
uint8_t GBT_BRO_recv;
|
||||
uint8_t GBT_BHM_recv;
|
||||
uint8_t GBT_BSD_recv;
|
||||
uint8_t EV_ready;
|
||||
//uint8_t GBT_Charger_Enable; //FIX
|
||||
//uint8_t GBT_Charger_Permission;//FIX
|
||||
/* Флаги приёма пакетов от EVSE (EV получает) */
|
||||
uint8_t GBT_CHM_recv; // CHM получен (0x2600) → отвечаем BHM
|
||||
uint8_t GBT_CRM_recv; // CRM получен (0x0100) → отвечаем BRM или BCP
|
||||
uint8_t GBT_CML_recv; // CML получен (0x0800) → отвечаем BRO
|
||||
uint8_t GBT_CST_recv; // CST получен (0x1A00) → EVSE запросил стоп, переходим в STOP
|
||||
uint8_t GBT_CSD_recv; // CSD получен (0x1D00) → финальный отчёт EVSE, переходим в STOP_CSD
|
||||
|
||||
uint8_t GBT_CRO_val; // последнее значение CRO от EVSE (0x0A00)
|
||||
|
||||
GBT_CML_t GBT_MaxLoad;
|
||||
GBT_CRM_t GBT_ChargerInfo;
|
||||
@@ -58,28 +57,10 @@ uint32_t GBT_ErrorCode;
|
||||
|
||||
GBT_StopSource_t GBT_StopSource;
|
||||
|
||||
extern GBT_EDCAN_Output_t GBT_EDCAN_Output;
|
||||
extern GBT_EDCAN_Input_t GBT_EDCAN_Input;
|
||||
|
||||
|
||||
void GBT_Init(){
|
||||
GBT_State = GBT_DISABLED;
|
||||
GBT_EDCAN_Input.chargeControl = CHARGING_NOT_ALLOWED;
|
||||
CONN.connControl = CMD_NONE;
|
||||
GBT_Reset();
|
||||
|
||||
|
||||
GBT_MaxLoad.maxOutputVoltage = 1000*10;
|
||||
GBT_MaxLoad.minOutputVoltage = 1500; //150V
|
||||
//GBT_MaxLoad[conn].maxOutputCurrent = 4000 - (GBT_MAX_CURRENT*10); //250A
|
||||
GBT_MaxLoad.maxOutputCurrent = 4000 - (100*10*2); //200A
|
||||
GBT_MaxLoad.minOutputCurrent = 3990; //400 - 1A
|
||||
|
||||
//TODO Linux registers
|
||||
GBT_ChargerInfo.chargerLocation[0] = 'R';
|
||||
GBT_ChargerInfo.chargerLocation[1] = 'U';
|
||||
GBT_ChargerInfo.chargerLocation[2] = 'S';
|
||||
GBT_ChargerInfo.chargerNumber = 00001;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -88,78 +69,48 @@ void GBT_ChargerTask(){
|
||||
//GBT_LockTask();
|
||||
if(j_rx.state == 2){
|
||||
switch (j_rx.PGN){
|
||||
case 0x2700: //PGN BHM
|
||||
GBT_BHM_recv = 1;
|
||||
memcpy (&GBT_MaxVoltage, j_rx.data, sizeof(GBT_MaxVoltage));
|
||||
|
||||
case 0x2600: // CHM EVSE->EV (старт/версия GB/T)
|
||||
GBT_CHM_recv = 1;
|
||||
break;
|
||||
|
||||
case 0x0200: //PGN BRM LONG
|
||||
GBT_BAT_INFO_recv = 1;
|
||||
memcpy (&GBT_EVInfo, j_rx.data, sizeof(GBT_EVInfo));
|
||||
|
||||
break;
|
||||
|
||||
case 0x0600: //PGN BCP LONG
|
||||
GBT_BAT_STAT_recv = 1;
|
||||
memcpy (&GBT_BATStat, j_rx.data, sizeof(GBT_BATStat));
|
||||
case 0x0100: // CRM EVSE->EV (идентификация зарядника, 0x00 или 0xAA)
|
||||
memcpy(&GBT_ChargerInfo, j_rx.data, sizeof(GBT_ChargerInfo));
|
||||
GBT_CRM_recv = 1;
|
||||
break;
|
||||
|
||||
case 0x0900: //PGN BRO
|
||||
GBT_BRO_recv = 1;
|
||||
if(j_rx.data[0] == 0xAA) EV_ready = 1;
|
||||
else EV_ready = 0;
|
||||
GBT_BRO = j_rx.data[0];
|
||||
case 0x0800: // CML EVSE->EV (макс. параметры зарядника)
|
||||
memcpy(&GBT_MaxLoad, j_rx.data, sizeof(GBT_MaxLoad));
|
||||
GBT_CML_recv = 1;
|
||||
break;
|
||||
|
||||
case 0x1000: //PGN BCL
|
||||
//TODO: power block
|
||||
memcpy (&GBT_ReqPower, j_rx.data, sizeof(GBT_ReqPower));
|
||||
uint16_t volt=GBT_ReqPower.requestedVoltage;
|
||||
GBT_EDCAN_Output.requestedVoltage = volt;
|
||||
uint16_t curr=4000-GBT_ReqPower.requestedCurrent;
|
||||
GBT_EDCAN_Output.requestedCurrent = curr;
|
||||
case 0x0700: // CTS EVSE->EV (time sync)
|
||||
// Пока не используем, но можем сохранить время при необходимости
|
||||
break;
|
||||
|
||||
case 0x1100: //PGN BCS
|
||||
//TODO
|
||||
memcpy (&GBT_ChargingStatus, j_rx.data, sizeof(GBT_ChargingStatus));
|
||||
GBT_EDCAN_Output.chargingRemainingTimeMin = GBT_ChargingStatus.estimatedRemainingChargingTime;
|
||||
GBT_EDCAN_Output.chargingPercentage = GBT_ChargingStatus.currentChargeState;
|
||||
case 0x0A00: // CRO EVSE->EV (0x00 = инициализация, 0xAA = готов к зарядке)
|
||||
GBT_CRO_val = (j_rx.data[0] & 0xFF);
|
||||
break;
|
||||
|
||||
case 0x1300: //PGN BSM
|
||||
//TODO
|
||||
memcpy (&GBT_BatteryStatus, j_rx.data, sizeof(GBT_BatteryStatus));
|
||||
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;
|
||||
break;
|
||||
|
||||
case 0x1500: //PGN BMV
|
||||
//TODO
|
||||
case 0x1A00: // CST EVSE->EV (остановка зарядки по инициативе EVSE)
|
||||
GBT_CST_recv = 1;
|
||||
break;
|
||||
|
||||
case 0x1600: //PGN BMT
|
||||
//TODO
|
||||
case 0x1D00: // CSD EVSE->EV (финальный отчёт зарядника)
|
||||
memcpy(&GBT_ChargerStop, j_rx.data, sizeof(GBT_ChargerStop));
|
||||
GBT_CSD_recv = 1;
|
||||
break;
|
||||
|
||||
case 0x1700: //PGN BSP
|
||||
//TODO
|
||||
case 0x1F00: // CEM EVSE->EV (сообщение об ошибке)
|
||||
memcpy(&GBT_ErrorCode, j_rx.data, sizeof(GBT_ErrorCode));
|
||||
break;
|
||||
|
||||
//this handler in j1939.c
|
||||
// case 0x1900: //PGN BST
|
||||
// break;
|
||||
|
||||
case 0x1C00: //PGN BSD
|
||||
//TODO SOC Voltage Temp
|
||||
GBT_BSD_recv = 1;
|
||||
break;
|
||||
|
||||
//this handler in j1939.c
|
||||
// case 0x1E00: //PGN BEM
|
||||
// break;
|
||||
|
||||
//BSM BMV BMT BSP BST BSD BEM
|
||||
|
||||
}
|
||||
j_rx.state = 0;
|
||||
}
|
||||
@@ -168,272 +119,180 @@ void GBT_ChargerTask(){
|
||||
//waiting
|
||||
}else switch (GBT_State){
|
||||
case GBT_DISABLED:
|
||||
RELAY_Write(RELAY_AUX, 0);
|
||||
if(connectorState == CONN_Charging){
|
||||
GBT_Reset();
|
||||
GBT_Start();//TODO IF protections (maybe not needed)
|
||||
}
|
||||
break;
|
||||
// case GBT_S0_UNCONNECTED:
|
||||
// if(!GBT_Charger_Enable){
|
||||
// GBT_Stop();
|
||||
// break;
|
||||
// }
|
||||
// if(GBT_CC_GetState()==GBT_CC_4V){
|
||||
//
|
||||
// GBT_SwitchState(GBT_S1_CONNECTED);
|
||||
// GBT_Delay(500);
|
||||
// }
|
||||
// break;
|
||||
// case GBT_S1_CONNECTED:
|
||||
// if(!GBT_Charger_Enable){
|
||||
// GBT_Stop();
|
||||
// break;
|
||||
// }
|
||||
// if(GBT_CC_GetState()==GBT_CC_4V){
|
||||
//
|
||||
// GBT_Lock(1);
|
||||
// GBT_SwitchState(GBT_S2_LOCKED);
|
||||
// GBT_Delay(500);
|
||||
// }else{
|
||||
// GBT_SwitchState(GBT_S0_UNCONNECTED);
|
||||
// }
|
||||
// break;
|
||||
// case GBT_S2_LOCKED:
|
||||
// if(!GBT_Charger_Enable){
|
||||
// GBT_Stop();
|
||||
// break;
|
||||
// }
|
||||
// if(1){ //TODO: charge permission
|
||||
// RELAY_Write(RELAY_AUX, 1); // 13.8V AUX ON
|
||||
// GBT_SwitchState(GBT_S3_STARTED);
|
||||
// GBT_Delay(500);
|
||||
// }
|
||||
// break;
|
||||
|
||||
case GBT_S3_STARTED:
|
||||
GBT_SwitchState(GBT_S31_WAIT_BHM);
|
||||
GBT_Delay(500);
|
||||
CONN.enableLoad = 0;
|
||||
// if(connectorState == Preparing){
|
||||
// GBT_Reset();
|
||||
// GBT_SwitchState(GBT_EV_CONNECTING);
|
||||
// }
|
||||
break;
|
||||
|
||||
case GBT_S31_WAIT_BHM:
|
||||
if(j_rx.state == 0) GBT_SendCHM();
|
||||
/* --- Строгая последовательность GB/T EV: приём от EVSE → ответ EV --- */
|
||||
|
||||
case GBT_EV_CONNECTING:
|
||||
// 1) Ждём CHM (0x2600), ничего не шлём. Получили → переход в GBT_EV_HANDSHAKE
|
||||
GBT_Delay(250);
|
||||
|
||||
if(GBT_BHM_recv) {
|
||||
GBT_SwitchState(GBT_S4_ISOTEST);
|
||||
if (GBT_CHM_recv) {
|
||||
GBT_SwitchState(GBT_EV_HANDSHAKE);
|
||||
break;
|
||||
}
|
||||
|
||||
//Timeout 10S
|
||||
if((GBT_BHM_recv == 0) && (GBT_StateTick()>10000)) { //BHM Timeout
|
||||
if (GBT_StateTick() > 10000) {
|
||||
GBT_Error(0xFCF0C0FC);
|
||||
EDCAN_printf(LOG_WARN, "BHM Timeout\n");
|
||||
EDCAN_printf(LOG_WARN, "CHM timeout\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case GBT_S4_ISOTEST:
|
||||
if(j_rx.state == 0) GBT_SendCHM();
|
||||
case GBT_EV_HANDSHAKE:
|
||||
// 2) Постоянно шлём BHM, ждём CRM (0x0100, первый раз 0x00)
|
||||
GBT_MaxVoltage.maxOutputVoltage = 4500; // 450V
|
||||
if (j_rx.state == 0) GBT_SendBHM();
|
||||
GBT_Delay(250);
|
||||
|
||||
GBT_EDCAN_Output.requestedVoltage = GBT_MaxVoltage.maxOutputVoltage;
|
||||
GBT_EDCAN_Output.requestedCurrent = 10; // 1A max
|
||||
GBT_EDCAN_Output.enablePSU = 1;
|
||||
|
||||
//TODO: Isolation test trigger
|
||||
if(GBT_EDCAN_Input.chargingError != CONN_NO_ERROR){
|
||||
GBT_StopEVSE(GBT_CST_OTHERFALUT);
|
||||
if (GBT_CRM_recv) {
|
||||
GBT_SwitchState(GBT_EV_RECOGNITION);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
if(GBT_StateTick()>5000){
|
||||
GBT_SwitchState(GBT_S5_BAT_INFO);
|
||||
GBT_EDCAN_Output.requestedVoltage = 50;
|
||||
GBT_EDCAN_Output.requestedCurrent = 10; // 1A max
|
||||
GBT_EDCAN_Output.enablePSU = 0;
|
||||
|
||||
case GBT_EV_RECOGNITION:
|
||||
// 3) Постоянно шлём BRM, ждём CRM (0x0100, 0xAA)
|
||||
GBT_EVInfo.version[0] = 2;
|
||||
GBT_EVInfo.version[1] = 0;
|
||||
GBT_EVInfo.version[2] = 0;
|
||||
GBT_EVInfo.batteryType = 1;
|
||||
GBT_EVInfo.batteryCapacity = 700;
|
||||
GBT_EVInfo.batteryVoltage = 3990;
|
||||
memcpy(GBT_EVInfo.batteryVendor, "TEST", 4);
|
||||
GBT_EVInfo.batterySN = 666666;
|
||||
GBT_EVInfo.batteryManuY = 30;
|
||||
GBT_EVInfo.batteryManuM = 2;
|
||||
GBT_EVInfo.batteryManuD = 20;
|
||||
GBT_EVInfo.batteryCycleCount = 666;
|
||||
GBT_EVInfo.ownAuto = 1;
|
||||
GBT_EVInfo.rsvd0 = 0;
|
||||
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)) {
|
||||
GBT_SwitchState(GBT_EV_CHARGING_PARAMETERS);
|
||||
break;
|
||||
}
|
||||
if (GBT_StateTick() > 5000) {
|
||||
GBT_Error(0xFCF1C0FC);
|
||||
EDCAN_printf(LOG_WARN, "CRM(0xAA) timeout (wait BCP)\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case GBT_EV_CHARGING_PARAMETERS:
|
||||
// 4) Постоянно шлём BCP, ждём CML (0x0800) → шлём BRO(0xAA)
|
||||
if (j_rx.state == 0) GBT_SendBCP();
|
||||
GBT_Delay(250);
|
||||
|
||||
if (GBT_CML_recv) {
|
||||
GBT_SwitchState(GBT_EV_BMS_INIT);
|
||||
break;
|
||||
}
|
||||
if (GBT_StateTick() > 5000) {
|
||||
GBT_Error(0xFCF4C0FC);
|
||||
EDCAN_printf(LOG_WARN, "CML timeout\n");
|
||||
}
|
||||
break;
|
||||
case GBT_EV_BMS_INIT:
|
||||
// 5) Постоянно шлём BRO(0x00) и ждем инициализацию CRO(0xAA)
|
||||
if (j_rx.state == 0) GBT_SendBRO(0x00);
|
||||
GBT_Delay(250);
|
||||
if (GBT_StateTick() > 1500) {
|
||||
GBT_SwitchState(GBT_EV_WAIT_CHARGER_READY);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case GBT_S5_BAT_INFO:
|
||||
if(j_rx.state == 0) GBT_SendCRM(0x00);
|
||||
case GBT_EV_WAIT_CHARGER_READY:
|
||||
// 5) Постоянно шлём BRO(0xAA) и ждем инициализацию CRO(0xAA)
|
||||
if (j_rx.state == 0) GBT_SendBRO(0xAA);
|
||||
|
||||
GBT_Delay(250);
|
||||
if(GBT_BAT_INFO_recv){ //BRM
|
||||
//Got battery info
|
||||
GBT_SwitchState(GBT_S6_BAT_STAT);
|
||||
EDCAN_printf(LOG_INFO, "EV info:\n");
|
||||
EDCAN_printf(LOG_INFO, "GBT_ver V%d.%d%d\n",GBT_EVInfo.version[0],GBT_EVInfo.version[1],GBT_EVInfo.version[2]);
|
||||
EDCAN_printf(LOG_INFO, "Battery type: %d\n",GBT_EVInfo.batteryType);
|
||||
EDCAN_printf(LOG_INFO, "Battery capacity: %d\n", GBT_EVInfo.batteryCapacity); // 0.1Ah/bit
|
||||
EDCAN_printf(LOG_INFO, "Battery voltage: %d\n", GBT_EVInfo.batteryVoltage); // 0.1V/bit
|
||||
EDCAN_printf(LOG_INFO, "Battery vendor: %.4s\n", GBT_EVInfo.batteryVendor); // Battery vendor (ASCII string)
|
||||
EDCAN_printf(LOG_INFO, "Battery SN: %lu\n", GBT_EVInfo.batterySN); // int
|
||||
EDCAN_printf(LOG_INFO, "Battery manufacture date: %02d.%02d.%04d\n", GBT_EVInfo.batteryManuD, GBT_EVInfo.batteryManuM ,GBT_EVInfo.batteryManuY+1985); // year (offset 1985)
|
||||
EDCAN_printf(LOG_INFO, "Battery cycles: %d\n", GBT_EVInfo.batteryCycleCount); //uint24_t
|
||||
EDCAN_printf(LOG_INFO, "Own auto: %d\n", GBT_EVInfo.ownAuto); // 0 = lizing, 1 = own auto
|
||||
EDCAN_printf(LOG_INFO, "EVIN: %.17s\n", GBT_EVInfo.EVIN); //EVIN
|
||||
EDCAN_printf(LOG_INFO, "EV_SW_VER: %.8s\n", GBT_EVInfo.EV_SW_VER);
|
||||
|
||||
}
|
||||
//Timeout
|
||||
if((GBT_StateTick()>5000) && (GBT_BAT_INFO_recv == 0)){
|
||||
GBT_Error(0xFDF0C0FC); //BRM Timeout
|
||||
EDCAN_printf(LOG_WARN, "BRM Timeout\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case GBT_S6_BAT_STAT:
|
||||
if(j_rx.state == 0) GBT_SendCRM(0xAA);
|
||||
GBT_Delay(250);
|
||||
if(GBT_BAT_STAT_recv){
|
||||
//Got battery status
|
||||
GBT_SwitchState(GBT_S7_BMS_WAIT);
|
||||
EDCAN_printf(LOG_INFO, "Battery info:\n");
|
||||
EDCAN_printf(LOG_INFO, "maxCV %dV\n",GBT_BATStat.maxCellVoltage/100); // 0.01v/bit
|
||||
EDCAN_printf(LOG_INFO, "maxCC %dA\n",GBT_BATStat.maxChargingCurrent/10); // 0.1A/bit
|
||||
EDCAN_printf(LOG_INFO, "totE %dkWh\n",GBT_BATStat.totalEnergy/10); // 0.1kWh
|
||||
EDCAN_printf(LOG_INFO, "maxCV %dV\n",GBT_BATStat.maxChargingVoltage/10); // 0.1V/ bit
|
||||
EDCAN_printf(LOG_INFO, "maxT %dC\n",(int16_t)GBT_BATStat.maxTemp-50); // 1C/bit, -50C offset
|
||||
EDCAN_printf(LOG_INFO, "SOC %dp\n",GBT_BATStat.SOC/10); // 0.1%/bit , 0..100%
|
||||
EDCAN_printf(LOG_INFO, "Volt. %dV\n",GBT_BATStat.measVoltage/10); // 0.1V/bit
|
||||
|
||||
}
|
||||
if((GBT_StateTick()>5000) && (GBT_BAT_STAT_recv == 0)){
|
||||
GBT_Error(0xFCF1C0FC); //BCP Timeout
|
||||
EDCAN_printf(LOG_WARN, "BCP Timeout\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case GBT_S7_BMS_WAIT:
|
||||
if(j_rx.state == 0) GBT_SendCTS();
|
||||
HAL_Delay(2);
|
||||
if(j_rx.state == 0) GBT_SendCML();
|
||||
GBT_Delay(250);
|
||||
if((GBT_StateTick()>5000) && (GBT_BRO_recv == 0)){
|
||||
GBT_Error(0xFCF4C0FC); //BRO Timeout
|
||||
EDCAN_printf(LOG_WARN, "BRO Timeout\n");
|
||||
}
|
||||
if(EV_ready){
|
||||
//EV ready (AA)
|
||||
GBT_SwitchState(GBT_S8_INIT_CHARGER);
|
||||
}else{
|
||||
if((GBT_StateTick()>60000) && (GBT_BRO_recv == 1)){
|
||||
GBT_Error(0xFCF4C0FC); //BRO Timeout
|
||||
EDCAN_printf(LOG_WARN, "BRO Timeout\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GBT_S8_INIT_CHARGER:
|
||||
if(j_rx.state == 0) GBT_SendCRO(0x00);
|
||||
//TODO
|
||||
GBT_Delay(250);
|
||||
if(GBT_StateTick()>1500){
|
||||
//Power Modules initiated
|
||||
GBT_SwitchState(GBT_S9_WAIT_BCL);
|
||||
}
|
||||
break;
|
||||
|
||||
case GBT_S9_WAIT_BCL:
|
||||
if(j_rx.state == 0) GBT_SendCRO(0xAA);
|
||||
GBT_Delay(250);
|
||||
if(GBT_ReqPower.chargingMode != 0){ //REFACTORING
|
||||
//BCL power requirements received
|
||||
|
||||
GBT_SwitchState(GBT_S10_CHARGING);
|
||||
CONN_SetState(CONN_Charging);
|
||||
uint16_t curr=4000-GBT_ReqPower.requestedCurrent;
|
||||
uint16_t volt=GBT_ReqPower.requestedVoltage;
|
||||
//TODO Limits
|
||||
|
||||
GBT_EDCAN_Output.requestedVoltage = volt;
|
||||
GBT_EDCAN_Output.requestedCurrent = curr;
|
||||
GBT_EDCAN_Output.enablePSU = 1;
|
||||
if (GBT_CRO_val == 0xAA) {
|
||||
GBT_SwitchState(GBT_EV_CHARGING);
|
||||
GBT_TimeChargingStarted = get_Current_Time();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case GBT_S10_CHARGING:
|
||||
//CHARGING
|
||||
//TODO BCL BCS BSM missing ERRORS
|
||||
if(GBT_EDCAN_Input.chargeControl == CHARGING_NOT_ALLOWED) GBT_StopOCPP(GBT_CST_SUSPENDS_ARTIFICIALLY);
|
||||
if(GBT_EDCAN_Input.chargeControl == FORCE_UNLOCK) GBT_StopOCPP(GBT_CST_SUSPENDS_ARTIFICIALLY); // --> Finished
|
||||
if(GBT_LockState.error) {
|
||||
GBT_StopEVSE(GBT_CST_OTHERFALUT); // --> Suspend EVSE
|
||||
GBT_EDCAN_Output.outputError = CONN_ERR_LOCK;
|
||||
case GBT_EV_CHARGING:
|
||||
// Основной режим зарядки: EV периодически шлёт BCS/BSM.
|
||||
GBT_ReqPower.requestedVoltage = CONN.RequestedVoltage * 10;
|
||||
GBT_ReqPower.requestedCurrent = 4000 - CONN.RequestedCurrent;
|
||||
GBT_ReqPower.chargingMode = 1;
|
||||
|
||||
GBT_BATStat.maxCellVoltage = 320;
|
||||
GBT_BATStat.maxChargingCurrent = 40;
|
||||
GBT_BATStat.totalEnergy = 6;
|
||||
GBT_BATStat.maxChargingVoltage = 500;
|
||||
GBT_BATStat.maxTemp = 70;
|
||||
GBT_BATStat.SOC = CONN.SOC;
|
||||
GBT_BATStat.measVoltage = CONN.MeasuredVoltage;
|
||||
|
||||
// Стоп по инициативе EVSE (получили CST)
|
||||
if (GBT_CST_recv) {
|
||||
GBT_StopEVSE(GBT_CST_SUDDENSTOP);
|
||||
break;
|
||||
}
|
||||
if((GBT_ReadTemp(0) > 90) || (GBT_ReadTemp(1) > 90)) {
|
||||
GBT_StopEVSE(GBT_CST_CONNECTOR_OVER_TEMP);
|
||||
GBT_EDCAN_Output.outputError = CONN_ERR_CONN_TEMP;
|
||||
EDCAN_printf(LOG_WARN, "Connector overheat %d %d\n", GBT_ReadTemp(0), GBT_ReadTemp(1));
|
||||
// Стоп по команде с машины (EDCAN)
|
||||
if (CONN.connControl == CMD_STOP) {
|
||||
GBT_StopEV(GBT_CST_BMS_ACTIVELY_SUSPENDS);
|
||||
break;
|
||||
}
|
||||
if(GBT_EDCAN_Input.chargingError != CONN_NO_ERROR){ // --> Suspend EVSE
|
||||
GBT_StopEVSE(GBT_CST_OTHERFALUT);
|
||||
// EDCAN_printf(LOG_WARN, "Isolation error\n");
|
||||
if (IN_ReadInput(IN_ESTOP)) {
|
||||
GBT_StopEV(GBT_CST_BMS_ACTIVELY_SUSPENDS);
|
||||
break;
|
||||
}
|
||||
|
||||
//GBT_ChargerCurrentStatus.chargingPermissible = 0b1111111111111100;//NOT PERMITTED
|
||||
GBT_ChargerCurrentStatus.chargingPermissible = 0b1111111111111101;
|
||||
GBT_ChargerCurrentStatus.chargingTime = (get_Current_Time() - GBT_TimeChargingStarted)/60;
|
||||
// GBT_ChargerCurrentStatus.outputCurrent = 4000 - GBT_EDCAN_Output.requestedCurrent;
|
||||
// GBT_ChargerCurrentStatus.outputVoltage = GBT_EDCAN_Output.requestedVoltage;
|
||||
GBT_ChargerCurrentStatus.outputCurrent = 4000 - GBT_EDCAN_Input.measuredCurrent;
|
||||
GBT_ChargerCurrentStatus.outputVoltage = GBT_EDCAN_Input.measuredVoltage;
|
||||
GBT_EDCAN_Output.chargingElapsedTimeMin = (get_Current_Time() - GBT_TimeChargingStarted)/60;
|
||||
GBT_EDCAN_Output.chargingElapsedTimeSec = (get_Current_Time() - GBT_TimeChargingStarted)%60;
|
||||
|
||||
if(j_rx.state == 0) GBT_SendCCS();
|
||||
|
||||
if(j_rx.state == 0) {
|
||||
GBT_SendCCS();
|
||||
GBT_Delay(49);
|
||||
}else{
|
||||
GBT_Delay(10); // Resend packet if not sent
|
||||
// log_printf(LOG_WARN, "Resend packet\n");
|
||||
}
|
||||
|
||||
//TODO: снижение тока если перегрев контактов
|
||||
|
||||
GBT_SendBCS();
|
||||
GBT_SendBCL();
|
||||
GBT_SendBSM();
|
||||
GBT_Delay(250);
|
||||
break;
|
||||
|
||||
case GBT_STOP:
|
||||
GBT_Delay(10);
|
||||
GBT_EDCAN_Output.enablePSU = 0;
|
||||
GBT_SendCST(GBT_StopCauseCode);
|
||||
//RELAY_Write(RELAY_OUTPUT, 0);
|
||||
//GBT_SwitchState(GBT_DISABLED);
|
||||
if(GBT_StateTick()>10000){
|
||||
EDCAN_printf(LOG_WARN, "BSD Timeout\n");
|
||||
GBT_Error(0xFCF0C0FD); //BSD Timeout
|
||||
|
||||
CONN.enableLoad = 0;
|
||||
// EV шлёт BSD (Battery Stop Data), не CST (CST шлёт EVSE)
|
||||
GBT_SendBSD();
|
||||
if (GBT_StateTick() > 10000) {
|
||||
EDCAN_printf(LOG_WARN, "CSD Timeout\n");
|
||||
GBT_Error(0xFCF0C0FD); // CSD timeout
|
||||
}
|
||||
|
||||
if(GBT_BSD_recv != 0){
|
||||
if (GBT_CSD_recv) {
|
||||
GBT_SwitchState(GBT_STOP_CSD);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case GBT_STOP_CSD:
|
||||
// EV не шлёт CSD (финальный отчёт шлёт EVSE). Ждём 2.5 с и завершаем.
|
||||
GBT_Delay(250);
|
||||
GBT_SendCSD();
|
||||
if(GBT_StateTick()>2500){ //2.5S
|
||||
if (GBT_StateTick() > 2500) {
|
||||
GBT_SwitchState(GBT_COMPLETE);
|
||||
// GBT_Reset();
|
||||
//CONN_SetState(CONN_Occupied_complete);
|
||||
//if(connectorState == CONN_Occupied_charging)
|
||||
//PSU_Mode(0x0100);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case GBT_ERROR:
|
||||
GBT_SendCEM(GBT_ErrorCode); //2.5S
|
||||
//GBT_SendBEM(GBT_ErrorCode); //2.5S TODO
|
||||
GBT_SwitchState(GBT_COMPLETE);
|
||||
// GBT_Reset();
|
||||
//
|
||||
break;
|
||||
|
||||
case GBT_COMPLETE:
|
||||
if(connectorState != CONN_Finishing) {
|
||||
if(connectorState != Finished) {
|
||||
GBT_SwitchState(GBT_DISABLED);
|
||||
GBT_Reset();//CHECK
|
||||
}
|
||||
@@ -442,46 +301,28 @@ void GBT_ChargerTask(){
|
||||
default:
|
||||
GBT_SwitchState(GBT_DISABLED);
|
||||
}
|
||||
if (CONN_CC_GetState()==GBT_CC_4V) CONN.EvseConnected = 1;
|
||||
else CONN.EvseConnected = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GBT_SwitchState(gbtState_t state){
|
||||
GBT_State = state;
|
||||
ED_status = state;
|
||||
GBT_state_tick = HAL_GetTick();
|
||||
// if(GBT_State == GBT_DISABLED) printf ("GBT_DISABLED\n");
|
||||
// if(GBT_State == GBT_S0_UNCONNECTED) printf ("GBT_S0_UNCONNECTED\n");
|
||||
// if(GBT_State == GBT_S1_CONNECTED) printf ("GBT_S1_CONNECTED\n");
|
||||
// if(GBT_State == GBT_S2_LOCKED) printf ("GBT_S2_LOCKED\n");
|
||||
// if(GBT_State == GBT_S3_STARTED) printf ("GBT_S3_STARTED\n");
|
||||
// if(GBT_State == GBT_S31_WAIT_BHM) printf ("GBT_S31_WAIT_BHM\n");
|
||||
// if(GBT_State == GBT_S4_ISOTEST) printf ("GBT_S4_ISOTEST\n");
|
||||
// if(GBT_State == GBT_S5_BAT_INFO) printf ("GBT_S5_BAT_INFO\n");
|
||||
// if(GBT_State == GBT_S6_BAT_STAT) printf ("GBT_S6_BAT_STAT\n");
|
||||
// if(GBT_State == GBT_S7_BMS_WAIT) printf ("GBT_S7_BMS_WAIT\n");
|
||||
// if(GBT_State == GBT_S8_INIT_CHARGER)printf ("GBT_S8_INIT_CHARGER\n");
|
||||
// if(GBT_State == GBT_S9_WAIT_BCL) printf ("GBT_S9_WAIT_BCL\n");
|
||||
// if(GBT_State == GBT_S10_CHARGING) printf ("GBT_S10_CHARGING\n");
|
||||
// if(GBT_State == GBT_STOP) printf ("GBT_STOP\n");
|
||||
// if(GBT_State == GBT_STOP_CSD) printf ("GBT_STOP_CSD\n");
|
||||
// if(GBT_State == GBT_ERROR) printf ("GBT_ERROR\n");
|
||||
// if(GBT_State == GBT_COMPLETE) printf ("GBT_COMPLETE\n");
|
||||
|
||||
if(GBT_State == GBT_DISABLED) EDCAN_printf(LOG_INFO, "GBT_DISABLED\n");
|
||||
if(GBT_State == GBT_S3_STARTED) EDCAN_printf(LOG_INFO, "GBT_S3_STARTED\n");
|
||||
if(GBT_State == GBT_S31_WAIT_BHM) EDCAN_printf(LOG_INFO, "GBT_S31_WAIT_BHM\n");
|
||||
if(GBT_State == GBT_S4_ISOTEST) EDCAN_printf(LOG_INFO, "GBT_S4_ISOTEST\n");
|
||||
if(GBT_State == GBT_S5_BAT_INFO) EDCAN_printf(LOG_INFO, "GBT_S5_BAT_INFO\n");
|
||||
if(GBT_State == GBT_S6_BAT_STAT) EDCAN_printf(LOG_INFO, "GBT_S6_BAT_STAT\n");
|
||||
if(GBT_State == GBT_S7_BMS_WAIT) EDCAN_printf(LOG_INFO, "GBT_S7_BMS_WAIT\n");
|
||||
if(GBT_State == GBT_S8_INIT_CHARGER)EDCAN_printf(LOG_INFO, "GBT_S8_INIT_CHARGER\n");
|
||||
if(GBT_State == GBT_S9_WAIT_BCL) EDCAN_printf(LOG_INFO, "GBT_S9_WAIT_BCL\n");
|
||||
if(GBT_State == GBT_S10_CHARGING) EDCAN_printf(LOG_INFO, "GBT_S10_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) 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");
|
||||
|
||||
|
||||
}
|
||||
@@ -496,7 +337,7 @@ void GBT_Delay(uint32_t delay){
|
||||
}
|
||||
|
||||
void GBT_StopEV(uint32_t causecode){ // --> Suspend EV
|
||||
if (GBT_EDCAN_Input.chargingError || GBT_EDCAN_Output.outputError){
|
||||
if (CONN.chargingError){
|
||||
GBT_StopSource = GBT_STOP_EVSE;
|
||||
}else{
|
||||
GBT_StopSource = GBT_STOP_EV;
|
||||
@@ -519,10 +360,9 @@ void GBT_StopOCPP(uint32_t causecode){ // --> Finished
|
||||
|
||||
void GBT_ForceStop(){ // --> Suspend EV
|
||||
GBT_StopSource = GBT_STOP_EV;
|
||||
GBT_EDCAN_Output.enablePSU = 0;
|
||||
// Отключаем силовой контактор батареи со стороны EV
|
||||
CONN.enableLoad = 0;
|
||||
GBT_SwitchState(GBT_COMPLETE);
|
||||
GBT_Lock(0);
|
||||
RELAY_Write(RELAY_AUX, 0);
|
||||
}
|
||||
|
||||
void GBT_Error(uint32_t errorcode){ // --> Suspend EV
|
||||
@@ -534,17 +374,18 @@ void GBT_Error(uint32_t errorcode){ // --> Suspend EV
|
||||
|
||||
|
||||
void GBT_Reset(){
|
||||
GBT_BAT_INFO_recv = 0;
|
||||
GBT_BAT_STAT_recv = 0;
|
||||
GBT_BRO_recv = 0;
|
||||
GBT_BHM_recv = 0;
|
||||
GBT_BSD_recv = 0;
|
||||
EV_ready = 0;
|
||||
GBT_EDCAN_Output.chargingPercentage = 0;
|
||||
GBT_EDCAN_Output.enablePSU = 0;
|
||||
GBT_EDCAN_Output.requestedCurrent = 0;
|
||||
GBT_EDCAN_Output.requestedVoltage = 500;
|
||||
GBT_EDCAN_Output.outputError = 0;
|
||||
GBT_SwitchState(GBT_DISABLED);
|
||||
GBT_CHM_recv = 0;
|
||||
GBT_CRM_recv = 0;
|
||||
GBT_CML_recv = 0;
|
||||
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;
|
||||
memset(&GBT_EVInfo, 0, sizeof (GBT_EVInfo));
|
||||
memset(&GBT_BATStat, 0, sizeof (GBT_BATStat));
|
||||
memset(&GBT_ReqPower, 0, sizeof (GBT_ReqPower));
|
||||
@@ -559,7 +400,3 @@ void GBT_Reset(){
|
||||
GBT_TimeChargingStarted = 0;
|
||||
GBT_BRO = 0x00;
|
||||
}
|
||||
void GBT_Start(){
|
||||
RELAY_Write(RELAY_AUX, 1);
|
||||
GBT_SwitchState(GBT_S3_STARTED);
|
||||
}
|
||||
|
||||
@@ -5,139 +5,137 @@
|
||||
*/
|
||||
|
||||
#include "connector.h"
|
||||
#include "lock.h"
|
||||
#include "board.h"
|
||||
#include "edcan.h"
|
||||
#include <string.h>
|
||||
#include <charger_gbt.h>
|
||||
|
||||
|
||||
CONN_State_t connectorState;
|
||||
extern GBT_EDCAN_Output_t GBT_EDCAN_Output;
|
||||
extern GBT_EDCAN_Input_t GBT_EDCAN_Input;
|
||||
CONN_t CONN;
|
||||
|
||||
uint8_t CC_STATE_FILTERED;
|
||||
|
||||
static void CONN_UpdateEdcanOutput(void);
|
||||
|
||||
void CONN_Init(){
|
||||
CONN_SetState(CONN_Initializing);
|
||||
memset(&CONN, 0, sizeof(CONN));
|
||||
CONN.connControl = CMD_NONE;
|
||||
CONN_SetState(Unknown);
|
||||
}
|
||||
|
||||
void CONN_Task(){
|
||||
|
||||
switch (connectorState){
|
||||
case CONN_Initializing: // unlocked
|
||||
GBT_Lock(0);
|
||||
CONN_SetState(CONN_Available);
|
||||
case Unknown:
|
||||
CONN_SetState(Unplugged);
|
||||
break;
|
||||
|
||||
case CONN_Faulted: //unlocked
|
||||
GBT_Lock(0);
|
||||
if(GBT_EDCAN_Input.chargingError == 0) CONN_SetState(CONN_Available);
|
||||
if(GBT_EDCAN_Input.chargeControl == FORCE_UNLOCK) GBT_ForceLock(0);
|
||||
|
||||
break;
|
||||
case CONN_Available: //unlocked, waiting to connect
|
||||
GBT_Lock(0);
|
||||
if(GBT_EDCAN_Input.chargingError != 0) CONN_SetState(CONN_Faulted);
|
||||
if(GBT_EDCAN_Input.chargeControl == FORCE_UNLOCK) GBT_ForceLock(0);
|
||||
|
||||
if((CONN_CC_GetState()==GBT_CC_4V) && (GBT_EDCAN_Input.chargeControl != FORCE_UNLOCK)){ // Исправить
|
||||
CONN_SetState(CONN_Preparing);
|
||||
GBT_Lock(1);
|
||||
case Disabled:
|
||||
if(CONN.chargingError == 0) {
|
||||
CONN_SetState(Unplugged);
|
||||
}
|
||||
break;
|
||||
|
||||
// Выйти из двух состояний в Finished если force unlock
|
||||
case CONN_Preparing: //unlocked, waiting to charge
|
||||
GBT_Lock(0);
|
||||
if(GBT_EDCAN_Input.chargeControl == FORCE_UNLOCK) GBT_ForceLock(0);
|
||||
if(CONN_CC_GetState()==GBT_CC_4V){
|
||||
if(GBT_EDCAN_Input.chargeControl == CHARGING_ALLOWED){
|
||||
// RELAY_Write(RELAY_AUX, 1);
|
||||
// GBT_Start();
|
||||
CONN_SetState(CONN_Charging);
|
||||
}
|
||||
if(GBT_EDCAN_Input.chargeControl == FORCE_UNLOCK){
|
||||
CONN_SetState(CONN_Available);//TODO: CONN_Occupied_complete
|
||||
}
|
||||
//if (CHARGING_NOT_ALLOWED) stay here
|
||||
case Unplugged: // Ожидание подключения и начала сессии
|
||||
{
|
||||
// Обновляем признак физического подключения разъёма по уровню CC
|
||||
if(CONN_CC_GetState() == GBT_CC_4V){
|
||||
CONN.EvseConnected = 1;
|
||||
CONN_SetState(AuthRequired);
|
||||
}else{
|
||||
CONN_SetState(CONN_Available);
|
||||
CONN.EvseConnected = 0;
|
||||
}
|
||||
break;
|
||||
case CONN_Charging://charging, locked
|
||||
GBT_Lock(1);
|
||||
}
|
||||
|
||||
case AuthRequired:
|
||||
{
|
||||
// Если уровень CC вернулся к 6/12В – считаем, что коннектор выдернули
|
||||
if(CONN_CC_GetState() != GBT_CC_4V){
|
||||
CONN_SetState(Unplugged);
|
||||
GBT_Reset();
|
||||
break;
|
||||
}
|
||||
|
||||
// Как только появляется 12V AUX от станции – переходим в Preparing (инициализация протокола)
|
||||
if(IN_ReadInput(IN_0) == 1){
|
||||
CONN_SetState(Preparing);
|
||||
GBT_SwitchState(GBT_EV_CONNECTING);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Preparing:
|
||||
// Ожидаем переход стейт-машины GB/T в режим зарядки.
|
||||
// Как только GBT_State уходит в режим CHARGING – считаем, что начался заряд.
|
||||
if(GBT_State == GBT_EV_CHARGING){
|
||||
CONN_SetState(Charging);
|
||||
}
|
||||
if(IN_ReadInput(IN_0) == 0){
|
||||
CONN_SetState(Unplugged);
|
||||
GBT_Reset();
|
||||
}
|
||||
break;
|
||||
|
||||
case Charging: // Активная зарядка
|
||||
// Завершение по окончанию GB/T-сессии или при падении тока/отключении AUX можно
|
||||
// добавить позже. Пока ориентируемся только на завершение GB/T.
|
||||
if(GBT_State == GBT_COMPLETE){
|
||||
if(GBT_StopSource == GBT_STOP_EVSE){
|
||||
CONN_SetState(CONN_Suspended_EVSE);
|
||||
}else if(GBT_StopSource == GBT_STOP_EV){
|
||||
CONN_SetState(CONN_Suspended_EV);
|
||||
}else if(GBT_StopSource == GBT_STOP_OCPP){
|
||||
CONN_SetState(CONN_Finishing);
|
||||
}else{
|
||||
CONN_SetState(CONN_Suspended_EVSE);
|
||||
}
|
||||
|
||||
}//FIXME
|
||||
//
|
||||
break;
|
||||
|
||||
case CONN_Suspended_EV://charging completed by EV, waiting to transaction stop
|
||||
GBT_Lock(0);
|
||||
if(GBT_EDCAN_Input.chargeControl == CHARGING_NOT_ALLOWED) CONN_SetState(CONN_Finishing);
|
||||
if(GBT_EDCAN_Input.chargeControl == FORCE_UNLOCK) CONN_SetState(CONN_Finishing); // --> Finished
|
||||
break;
|
||||
|
||||
case CONN_Suspended_EVSE://charging completed by EVSE, waiting to transaction stop
|
||||
GBT_Lock(0);
|
||||
if(GBT_EDCAN_Input.chargeControl == CHARGING_NOT_ALLOWED) CONN_SetState(CONN_Finishing);
|
||||
if(GBT_EDCAN_Input.chargeControl == FORCE_UNLOCK) CONN_SetState(CONN_Finishing); // --> Finished
|
||||
|
||||
break;
|
||||
|
||||
case CONN_Finishing://charging completed, waiting to disconnect, unlocked
|
||||
GBT_Lock(0);
|
||||
|
||||
//TODO Force unlock time limit
|
||||
if(GBT_EDCAN_Input.chargeControl == FORCE_UNLOCK) GBT_ForceLock(0);
|
||||
|
||||
if(CONN_CC_GetState()==GBT_CC_6V){
|
||||
GBT_Lock(0);
|
||||
CONN_SetState(CONN_Available);
|
||||
CONN_SetState(Finished);
|
||||
}
|
||||
if(IN_ReadInput(IN_0) == 0){
|
||||
CONN_SetState(Finished);
|
||||
}
|
||||
break;
|
||||
|
||||
case Finished: // Сессия завершена, ждём окончания и возможного переподключения
|
||||
// Когда GB/T стейт-машина полностью вернулась в исходное состояние,
|
||||
// можно считать сессию закрытой и вернуться в Unplugged.
|
||||
if(CONN_CC_GetState() != GBT_CC_4V){
|
||||
CONN_SetState(Unplugged);
|
||||
GBT_Reset();
|
||||
}
|
||||
break;
|
||||
|
||||
case FinishedEV:
|
||||
case FinishedEVSE:
|
||||
CONN_SetState(Finished);
|
||||
break;
|
||||
default:
|
||||
CONN_SetState(CONN_Initializing);
|
||||
CONN_SetState(Unknown);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
//external
|
||||
//CONN_SetState(CONN_Error);
|
||||
//CONN_SetState(CONN_Occupied_charging);
|
||||
//CONN_SetState(CONN_Occupied_Complete);
|
||||
|
||||
|
||||
void CONN_SetState(CONN_State_t state){
|
||||
connectorState = state;
|
||||
if(connectorState == CONN_Initializing) EDCAN_printf(LOG_INFO,"CONN_Initializing\n");
|
||||
if(connectorState == CONN_Faulted) EDCAN_printf(LOG_INFO,"CONN_Faulted\n");
|
||||
if(connectorState == CONN_Available) EDCAN_printf(LOG_INFO,"CONN_Available\n");
|
||||
if(connectorState == CONN_Preparing) EDCAN_printf(LOG_INFO,"CONN_Preparing\n");
|
||||
if(connectorState == CONN_Charging) EDCAN_printf(LOG_INFO,"CONN_Charging\n");
|
||||
if(connectorState == CONN_Finishing) EDCAN_printf(LOG_INFO,"CONN_Finishing\n");
|
||||
if(connectorState == CONN_Suspended_EV) EDCAN_printf(LOG_INFO,"CONN_Suspended_EV\n");
|
||||
if(connectorState == CONN_Suspended_EVSE) EDCAN_printf(LOG_INFO,"CONN_Suspended_EVSE\n");
|
||||
CONN.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");
|
||||
|
||||
GBT_EDCAN_Output.connectorState = state;
|
||||
}
|
||||
|
||||
|
||||
void CONN_CC_ReadStateFiltered() {
|
||||
static uint32_t last_change_time;
|
||||
static uint32_t last_check_time;
|
||||
static uint8_t prev_state;
|
||||
|
||||
// if((last_check_time+100)>HAL_GetTick()) return;
|
||||
if((HAL_GetTick()-last_check_time)<100) return;
|
||||
|
||||
last_check_time = HAL_GetTick();
|
||||
@@ -150,43 +148,6 @@ void CONN_CC_ReadStateFiltered() {
|
||||
} else if ((HAL_GetTick() - last_change_time) >= 300) {
|
||||
CC_STATE_FILTERED = prev_state;
|
||||
}
|
||||
|
||||
// switch(new_state){
|
||||
// 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;
|
||||
//
|
||||
// }
|
||||
// switch(CONN_CC_GetState()){
|
||||
// case GBT_CC_UNKNOWN:
|
||||
// printf("FGBT_CC_UNKNOWN\n");
|
||||
// break;
|
||||
// case GBT_CC_12V:
|
||||
// printf("FGBT_CC_12V\n");
|
||||
// break;
|
||||
// case GBT_CC_6V:
|
||||
// printf("FGBT_CC_6V\n");
|
||||
// break;
|
||||
// case GBT_CC_4V:
|
||||
// printf("FGBT_CC_4V\n");
|
||||
// break;
|
||||
// case GBT_CC_2V:
|
||||
// printf("FGBT_CC_2V\n");
|
||||
// break;
|
||||
//
|
||||
// }
|
||||
}
|
||||
|
||||
uint8_t CONN_CC_GetState(){
|
||||
@@ -201,7 +162,7 @@ uint8_t CONN_CC_GetStateRaw(){
|
||||
//TODO: Filter 100ms
|
||||
uint32_t adc;
|
||||
float volt;
|
||||
ADC_Select_Channel(ADC_CHANNEL_6);
|
||||
ADC_Select_Channel(ADC_CHANNEL_3);
|
||||
HAL_ADC_Start(&hadc1);
|
||||
HAL_ADC_PollForConversion(&hadc1, 100);
|
||||
adc = HAL_ADC_GetValue(&hadc1);
|
||||
@@ -229,7 +190,7 @@ float CONN_CC_GetAdc(){
|
||||
|
||||
uint32_t adc;
|
||||
float volt;
|
||||
ADC_Select_Channel(ADC_CHANNEL_6);
|
||||
ADC_Select_Channel(ADC_CHANNEL_3);
|
||||
HAL_ADC_Start(&hadc1);
|
||||
HAL_ADC_PollForConversion(&hadc1, 100);
|
||||
adc = HAL_ADC_GetValue(&hadc1);
|
||||
|
||||
@@ -75,9 +75,9 @@ void parse_command(uint8_t* buffer, size_t length) {
|
||||
|
||||
} else if (strncmp((const char*)buffer, "relayaux", length) == 0) {
|
||||
printf("Relaying...\n");
|
||||
RELAY_Write(RELAY_AUX, 1);
|
||||
RELAY_Write(RELAY_1, 1);
|
||||
HAL_Delay(200);
|
||||
RELAY_Write(RELAY_AUX, 0);
|
||||
RELAY_Write(RELAY_1, 0);
|
||||
} else if (strncmp((const char*)buffer, "relaycc", length) == 0) {
|
||||
printf("Relaying...\n");
|
||||
RELAY_Write(RELAY_CC, 1);
|
||||
@@ -92,23 +92,15 @@ void parse_command(uint8_t* buffer, size_t length) {
|
||||
} 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("Lock state=%d\n", GBT_LockGetState());
|
||||
|
||||
} else if (strncmp((const char*)buffer, "lock_lock", length) == 0) {
|
||||
printf("Locked\n");
|
||||
GBT_Lock(1);
|
||||
|
||||
} else if (strncmp((const char*)buffer, "lock_unlock", length) == 0) {
|
||||
printf("Unlocked\n");
|
||||
GBT_Lock(0);
|
||||
// } 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(CONN_Finishing);
|
||||
CONN_SetState(Finished);
|
||||
|
||||
} else if (strncmp((const char*)buffer, "start", length) == 0) {
|
||||
printf("Started\n");
|
||||
GBT_Start();
|
||||
GBT_SwitchState(GBT_EV_CONNECTING);
|
||||
|
||||
} else if (strncmp((const char*)buffer, "stop", length) == 0) {
|
||||
printf("Stopped\n");
|
||||
@@ -187,8 +179,6 @@ void parse_command(uint8_t* buffer, size_t length) {
|
||||
printf("reset\n");
|
||||
printf("help\n");
|
||||
printf("cc_state\n");
|
||||
printf("lock_lock\n");
|
||||
printf("lock_unlock\n");
|
||||
printf("lock_state\n");
|
||||
printf("adc\n");
|
||||
printf("relay(cc,aux)\n");
|
||||
|
||||
@@ -52,17 +52,6 @@
|
||||
#define EDCAN_REG_BSM 0x380
|
||||
|
||||
|
||||
#define EDCAN_REG_OUTPUT 0x500
|
||||
|
||||
GBT_EDCAN_Output_t GBT_EDCAN_Output;
|
||||
|
||||
|
||||
#define EDCAN_REG_INPUT 0x580
|
||||
|
||||
GBT_EDCAN_Input_t GBT_EDCAN_Input;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Handler for incoming Read packet
|
||||
* Another device reply value of its registers
|
||||
@@ -154,10 +143,6 @@ void EDCAN_WriteUserRegister(uint16_t addr, uint8_t value){
|
||||
((uint8_t*)&GBT_ChargerInfo)[addr - EDCAN_REG_CHARGER_INFO] = value;
|
||||
break;
|
||||
|
||||
//0x580
|
||||
case EDCAN_REG_INPUT ... (EDCAN_REG_INPUT+sizeof(GBT_EDCAN_Input_t)):
|
||||
((uint8_t*)&GBT_EDCAN_Input)[addr - EDCAN_REG_INPUT] = value;
|
||||
|
||||
//TODO
|
||||
//GBT_EDCAN_Input.measuredCurrent;
|
||||
break;
|
||||
@@ -223,15 +208,6 @@ uint8_t EDCAN_GetUserRegisterValue(uint16_t addr){
|
||||
return ((uint8_t*)&GBT_BatteryStatus)[addr - EDCAN_REG_BSM];
|
||||
|
||||
|
||||
//0x500
|
||||
case EDCAN_REG_OUTPUT ... (EDCAN_REG_OUTPUT+sizeof(GBT_EDCAN_Output_t)):
|
||||
return ((uint8_t*)&GBT_EDCAN_Output)[addr - EDCAN_REG_OUTPUT];
|
||||
|
||||
//0x580
|
||||
case EDCAN_REG_INPUT ... (EDCAN_REG_INPUT+sizeof(GBT_EDCAN_Input_t)):
|
||||
return ((uint8_t*)&GBT_EDCAN_Input)[addr - EDCAN_REG_INPUT];
|
||||
|
||||
|
||||
default:
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
@@ -6,115 +6,51 @@
|
||||
*/
|
||||
|
||||
|
||||
// GB/T Time Synchronization Packet
|
||||
// GB/T Time Synchronization Packet (CTS EVSE->EV)
|
||||
#include "main.h"
|
||||
#include "soft_rtc.h"
|
||||
#include "charger_gbt.h"
|
||||
|
||||
void GBT_SendCTS(){
|
||||
// --- EV side GB/T packets (EV->EVSE) ---
|
||||
|
||||
uint8_t data[7];
|
||||
unix_to_bcd(get_Current_Time(), data);
|
||||
// data[0] = 0x00; //seconds
|
||||
// data[1] = 0x30; //minutes
|
||||
// data[2] = 0x23; //hours
|
||||
// data[3] = 0x05; //days
|
||||
// data[4] = 0x05; //month
|
||||
// data[5] = 0x24; //years
|
||||
// data[6] = 0x20; //centuries
|
||||
|
||||
J_SendPacket(0x000700, 6, 7, data);
|
||||
// BHM: максимальное напряжение батареи/запрос зарядного напряжения
|
||||
void GBT_SendBHM(void){
|
||||
J_SendPacket(0x2700, 6, sizeof(GBT_MaxVoltage), (uint8_t*)&GBT_MaxVoltage);
|
||||
}
|
||||
|
||||
//GB/T Max Load Packet
|
||||
void GBT_SendCML(){
|
||||
// uint8_t data[8];
|
||||
// data[0] = 0x94; //450V max output voltage
|
||||
// data[1] = 0x11; //
|
||||
// data[2] = 0xB0; //120V min output voltage
|
||||
// data[3] = 0x04; //
|
||||
// data[4] = 0xC4; //-150A maximum output current
|
||||
// data[5] = 0x09; //
|
||||
// data[6] = 0x8C; //-2A minimum output current
|
||||
// data[7] = 0x0F; //
|
||||
|
||||
J_SendPacket(0x000800, 6, 8, (uint8_t*)&GBT_MaxLoad);
|
||||
|
||||
// BRM: базовая информация о батарее/EV
|
||||
void GBT_SendBRM(void){
|
||||
J_SendPacket(0x0200, 6, sizeof(GBT_EVInfo), (uint8_t*)&GBT_EVInfo);
|
||||
}
|
||||
|
||||
//GB/T Version packet
|
||||
void GBT_SendCHM(){
|
||||
uint8_t data[3];
|
||||
data[0] = 0x01;
|
||||
data[1] = 0x01;
|
||||
data[2] = 0x00;
|
||||
J_SendPacket(0x2600, 6, 3, data);
|
||||
// BCP: ограничения и статусы батареи
|
||||
void GBT_SendBCP(void){
|
||||
J_SendPacket(0x0600, 6, sizeof(GBT_BATStat), (uint8_t*)&GBT_BATStat);
|
||||
}
|
||||
|
||||
//GB/T CRM Packet (state=BMS identified)
|
||||
void GBT_SendCRM(uint8_t state){
|
||||
// uint8_t data[8];
|
||||
// data[0] = state; // 0x00 / 0xAA
|
||||
// data[1] = 0x40; //TODO: Charger Number 123456
|
||||
// data[2] = 0xE2;
|
||||
// data[3] = 0x01;
|
||||
// data[4] = 0x00;
|
||||
// data[5] = 0x42; //TODO: location BFG
|
||||
// data[6] = 0x46;
|
||||
// data[7] = 0x47;
|
||||
GBT_ChargerInfo.bmsIdentified = state;
|
||||
J_SendPacket(0x100, 6, 8, (uint8_t *)&GBT_ChargerInfo);
|
||||
// BRO: ответ готовности EV (0x00 / 0xAA)
|
||||
void GBT_SendBRO(uint8_t state){
|
||||
uint8_t data[1];
|
||||
data[0] = state;
|
||||
J_SendPacket(0x0900, 6, 1, data);
|
||||
}
|
||||
|
||||
//GB/T CRO packet (Charger ready)
|
||||
void GBT_SendCRO(uint8_t state){
|
||||
uint8_t data[1];
|
||||
data[0] = state;
|
||||
J_SendPacket(0xA00, 4, 1, data);
|
||||
// BCL: запрос по напряжению/току от EV
|
||||
void GBT_SendBCL(void){
|
||||
J_SendPacket(0x1000, 6, sizeof(GBT_ReqPower), (uint8_t*)&GBT_ReqPower);
|
||||
}
|
||||
|
||||
//GB/T CCS packet (Charger current status)
|
||||
void GBT_SendCCS(){
|
||||
// uint8_t data[8];
|
||||
// data[0] = GBT_CurrPower.requestedVoltage; //
|
||||
// data[1] = GBT_CurrPower.requestedVoltage>>8; //output voltage
|
||||
// data[2] = GBT_CurrPower.requestedCurrent; //смещение 400а, границы
|
||||
// //-400A = 0
|
||||
// // 0A = 4000
|
||||
// // -100A = 3000
|
||||
// data[3] = GBT_CurrPower.requestedCurrent>>8; //TODO: current
|
||||
// data[4] = GBT_StateTick()/60000; //charging time (min)
|
||||
// data[5] = 0; //TODO: 255 min+
|
||||
// data[6] = 0b11111101; //charging not permitted
|
||||
// data[7] = 0xFF;
|
||||
J_SendPacket(0x1200, 6, 8, (uint8_t *)&GBT_ChargerCurrentStatus);
|
||||
// BCS: текущий статус заряда с точки зрения EV
|
||||
void GBT_SendBCS(void){
|
||||
J_SendPacket(0x1100, 6, sizeof(GBT_ChargingStatus), (uint8_t*)&GBT_ChargingStatus);
|
||||
}
|
||||
|
||||
// GB/T Charging Stop packet
|
||||
void GBT_SendCST(uint32_t Cause){
|
||||
uint8_t data[8];
|
||||
data[0] = (Cause>>24) & 0xFF; // Error
|
||||
data[1] = (Cause>>16) & 0xFF; //
|
||||
data[2] = (Cause>>8) & 0xFF; //
|
||||
data[3] = Cause & 0xFF; //
|
||||
|
||||
J_SendPacket(0x1A00, 4, 4, data);
|
||||
// BSM: дополнительные статусы батареи
|
||||
void GBT_SendBSM(void){
|
||||
J_SendPacket(0x1300, 6, sizeof(GBT_BatteryStatus), (uint8_t*)&GBT_BatteryStatus);
|
||||
}
|
||||
|
||||
void GBT_SendCSD(){
|
||||
GBT_ChargerStop.chargerNumber = GBT_ChargerInfo.chargerNumber;
|
||||
GBT_ChargerStop.outputEnergy = 0; //TODO Energy meters
|
||||
GBT_ChargerStop.chargingTime = GBT_ChargerCurrentStatus.chargingTime;
|
||||
J_SendPacket(0x1D00, 6, 7, (uint8_t *)&GBT_ChargerStop);
|
||||
|
||||
}
|
||||
|
||||
void GBT_SendCEM(uint32_t ErrorCode){
|
||||
uint8_t data[8];
|
||||
data[0] = (ErrorCode>>24) & 0xFF; // Error
|
||||
data[1] = (ErrorCode>>16) & 0xFF; //
|
||||
data[2] = (ErrorCode>>8) & 0xFF; //
|
||||
data[3] = ErrorCode & 0xFF; //
|
||||
|
||||
J_SendPacket(0x1F00, 4, 4, data);
|
||||
// BSD: статус батареи при завершении
|
||||
void GBT_SendBSD(void){
|
||||
J_SendPacket(0x1C00, 6, sizeof(GBT_BATStat), (uint8_t*)&GBT_BATStat);
|
||||
}
|
||||
|
||||
72
Core/Src/gpio.c
Executable file → Normal file
72
Core/Src/gpio.c
Executable file → Normal file
@@ -38,6 +38,8 @@
|
||||
* Output
|
||||
* EVENT_OUT
|
||||
* EXTI
|
||||
PB8 ------> I2C1_SCL
|
||||
PB9 ------> I2C1_SDA
|
||||
*/
|
||||
void MX_GPIO_Init(void)
|
||||
{
|
||||
@@ -54,54 +56,88 @@ void MX_GPIO_Init(void)
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOC, 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);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(RELAY_CC_GPIO_Port, RELAY_CC_Pin, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(USART2_DIR_GPIO_Port, USART2_DIR_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(GPIOD, RELAY_DC_Pin|USART2_DIR_Pin, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(RELAY_AUX_GPIO_Port, RELAY_AUX_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(EE_WP_GPIO_Port, EE_WP_Pin, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pins : PCPin PCPin */
|
||||
/*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;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pin : PtPin */
|
||||
GPIO_InitStruct.Pin = LOCK_FB_Pin;
|
||||
/*Configure GPIO pins : IN0_Pin AC_OK_Pin ISO_IN_Pin */
|
||||
GPIO_InitStruct.Pin = IN0_Pin|AC_OK_Pin|ISO_IN_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(LOCK_FB_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : PEPin PEPin */
|
||||
GPIO_InitStruct.Pin = ADDR_0_Pin|ADDR_1_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pin : PtPin */
|
||||
/*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;
|
||||
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 pin : PtPin */
|
||||
GPIO_InitStruct.Pin = USART2_DIR_Pin;
|
||||
/*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;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(USART2_DIR_GPIO_Port, &GPIO_InitStruct);
|
||||
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pin : PtPin */
|
||||
GPIO_InitStruct.Pin = RELAY_AUX_Pin;
|
||||
/*Configure GPIO pin : IN_ESTOP_Pin */
|
||||
GPIO_InitStruct.Pin = IN_ESTOP_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(IN_ESTOP_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : IN_FB2_Pin IN_FB1_Pin */
|
||||
GPIO_InitStruct.Pin = IN_FB2_Pin|IN_FB1_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pin : EE_WP_Pin */
|
||||
GPIO_InitStruct.Pin = EE_WP_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(RELAY_AUX_GPIO_Port, &GPIO_InitStruct);
|
||||
HAL_GPIO_Init(EE_WP_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : PB8 PB9 */
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/*Configure peripheral I/O remapping */
|
||||
__HAL_AFIO_REMAP_I2C1_ENABLE();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
|
||||
|
||||
if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RxData) == HAL_OK)
|
||||
{
|
||||
if((RxHeader.ExtId & 0x00FFFF) == ((J_ID_SE << 8) | J_ID_EV)){ // SA, DA match
|
||||
if((RxHeader.ExtId & 0x00FFFF) == ((J_ID_EV << 8) | J_ID_SE)){ // SA, DA match
|
||||
switch ((RxHeader.ExtId>>8) & 0x00FF00){
|
||||
|
||||
case 0xEC00: //PGN Connection Management Message
|
||||
@@ -127,7 +127,7 @@ void J_SendPacket(uint32_t PGN, uint8_t pri, uint8_t DLC, uint8_t *data){
|
||||
CAN_TxHeaderTypeDef tx_header;
|
||||
uint32_t tx_mailbox;
|
||||
|
||||
tx_header.ExtId = (pri << 26) | (PGN << 8) | (J_ID_EV << 8) | J_ID_SE;
|
||||
tx_header.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;
|
||||
|
||||
166
Core/Src/lock.c
166
Core/Src/lock.c
@@ -1,166 +0,0 @@
|
||||
/*
|
||||
* lock.c
|
||||
*
|
||||
* Created on: Jul 31, 2024
|
||||
* Author: colorbass
|
||||
*/
|
||||
#include "lock.h"
|
||||
#include "debug.h"
|
||||
#include "edcan.h"
|
||||
|
||||
|
||||
uint8_t LOCK_POLARITY = 0; // 1 for v1
|
||||
uint8_t LOCK_MOTOR_POLARITY = 1;
|
||||
uint16_t LOCK_DELAY = 100;
|
||||
|
||||
GBT_LockState_t GBT_LockState = {
|
||||
.demand = 0,
|
||||
.error = 0,
|
||||
.action_requested = 255, // нет запрошенного действия
|
||||
.motor_state = 0, // idle
|
||||
.last_action_time = 0,
|
||||
.retry_count = 0,
|
||||
.error_tick = 0
|
||||
};
|
||||
|
||||
|
||||
void GBT_ForceLock(uint8_t state){
|
||||
// Устанавливаем флаг для выполнения действия
|
||||
GBT_LockState.action_requested = state ? 1 : 0;
|
||||
GBT_LockState.retry_count = 0;
|
||||
}
|
||||
|
||||
uint8_t GBT_LockGetState(){
|
||||
//1 = locked
|
||||
//0 = unlocked
|
||||
if(LOCK_POLARITY){
|
||||
return HAL_GPIO_ReadPin(LOCK_FB_GPIO_Port, LOCK_FB_Pin);
|
||||
}else{
|
||||
return !HAL_GPIO_ReadPin(LOCK_FB_GPIO_Port, LOCK_FB_Pin);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void GBT_Lock(uint8_t state){
|
||||
GBT_LockState.demand = state;
|
||||
}
|
||||
|
||||
void GBT_ManageLockSolenoid(){
|
||||
static uint32_t tick;
|
||||
|
||||
if(HAL_GetTick() - tick < 50) return;
|
||||
tick = HAL_GetTick();
|
||||
|
||||
HAL_GPIO_WritePin(LOCK_B_GPIO_Port, LOCK_B_Pin, GBT_LockState.demand ? 1 : 0);
|
||||
}
|
||||
|
||||
void GBT_ManageLockMotor(){
|
||||
static const uint8_t MAX_RETRIES = 5;
|
||||
uint32_t current_tick = HAL_GetTick();
|
||||
|
||||
// Проверяем таймаут сброса ошибки (до проверки error, чтобы можно было сбросить)
|
||||
GBT_ResetErrorTimeout();
|
||||
|
||||
if (GBT_LockState.error) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Проверяем, нужно ли выполнить действие
|
||||
bool lock_is_open = GBT_LockGetState() == 0;
|
||||
bool lock_should_be_open = GBT_LockState.demand == 0;
|
||||
|
||||
// Если есть запрошенное действие или состояние не соответствует требуемому
|
||||
if (GBT_LockState.action_requested != 255 || (lock_is_open != lock_should_be_open)) {
|
||||
// Если действие еще не запрошено, запрашиваем его
|
||||
if (GBT_LockState.action_requested == 255) {
|
||||
GBT_LockState.action_requested = lock_should_be_open ? 0 : 1;
|
||||
GBT_LockState.retry_count = 0;
|
||||
}
|
||||
|
||||
// Управление мотором через машину состояний
|
||||
switch (GBT_LockState.motor_state) {
|
||||
case 0: // idle - мотор выключен
|
||||
// Определяем, какой пин нужно включить
|
||||
if (LOCK_MOTOR_POLARITY) {
|
||||
if (GBT_LockState.action_requested == 1) { // LOCK
|
||||
HAL_GPIO_WritePin(LOCK_B_GPIO_Port, LOCK_B_Pin, 1);
|
||||
} else { // UNLOCK
|
||||
HAL_GPIO_WritePin(LOCK_A_GPIO_Port, LOCK_A_Pin, 1);
|
||||
}
|
||||
} else {
|
||||
if (GBT_LockState.action_requested == 1) { // LOCK
|
||||
HAL_GPIO_WritePin(LOCK_A_GPIO_Port, LOCK_A_Pin, 1);
|
||||
} else { // UNLOCK
|
||||
HAL_GPIO_WritePin(LOCK_B_GPIO_Port, LOCK_B_Pin, 1);
|
||||
}
|
||||
}
|
||||
GBT_LockState.motor_state = 1; // motor_on
|
||||
GBT_LockState.last_action_time = current_tick;
|
||||
break;
|
||||
|
||||
case 1: // motor_on - мотор включен, ждем LOCK_DELAY
|
||||
if (current_tick - GBT_LockState.last_action_time >= LOCK_DELAY) {
|
||||
// Выключаем оба пина
|
||||
HAL_GPIO_WritePin(LOCK_A_GPIO_Port, LOCK_A_Pin, 0);
|
||||
HAL_GPIO_WritePin(LOCK_B_GPIO_Port, LOCK_B_Pin, 0);
|
||||
GBT_LockState.motor_state = 2; // waiting_off
|
||||
GBT_LockState.last_action_time = current_tick;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // waiting_off - ждем немного перед проверкой состояния
|
||||
// Небольшая задержка перед проверкой состояния (например, 50мс)
|
||||
if (current_tick - GBT_LockState.last_action_time >= 50) {
|
||||
// Проверяем, достигнуто ли требуемое состояние
|
||||
lock_is_open = GBT_LockGetState() == 0;
|
||||
bool action_success = (lock_is_open == (GBT_LockState.action_requested == 0));
|
||||
|
||||
if (action_success) {
|
||||
// Действие выполнено успешно
|
||||
GBT_LockState.action_requested = 255; // сбрасываем флаг
|
||||
GBT_LockState.motor_state = 0; // idle
|
||||
GBT_LockState.retry_count = 0;
|
||||
} else {
|
||||
// Действие не выполнено, повторяем попытку
|
||||
GBT_LockState.retry_count++;
|
||||
if (GBT_LockState.retry_count >= MAX_RETRIES) {
|
||||
// Превышено количество попыток
|
||||
GBT_LockState.error = 1;
|
||||
GBT_LockState.error_tick = current_tick; // сохраняем время установки ошибки
|
||||
GBT_LockState.action_requested = 0; // пытаемся разблокировать
|
||||
GBT_LockState.motor_state = 0;
|
||||
GBT_LockState.retry_count = 0;
|
||||
EDCAN_printf(LOG_ERR, "Lock error\n");
|
||||
} else {
|
||||
// Повторяем попытку
|
||||
GBT_LockState.motor_state = 0; // возвращаемся к началу
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Состояние соответствует требуемому, сбрасываем флаги
|
||||
if (GBT_LockState.motor_state != 0) {
|
||||
HAL_GPIO_WritePin(LOCK_A_GPIO_Port, LOCK_A_Pin, 0);
|
||||
HAL_GPIO_WritePin(LOCK_B_GPIO_Port, LOCK_B_Pin, 0);
|
||||
GBT_LockState.motor_state = 0;
|
||||
}
|
||||
GBT_LockState.action_requested = 255;
|
||||
GBT_LockState.retry_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void GBT_ResetErrorTimeout(){
|
||||
static const uint32_t ERROR_TIMEOUT_MS = 300000; // 5 минут
|
||||
|
||||
if (GBT_LockState.error && GBT_LockState.error_tick != 0) {
|
||||
|
||||
if ((HAL_GetTick()-GBT_LockState.error_tick) >= ERROR_TIMEOUT_MS) {
|
||||
// Прошло 5 минут, сбрасываем ошибку
|
||||
GBT_LockState.error = 0;
|
||||
GBT_LockState.error_tick = 0;
|
||||
EDCAN_printf(LOG_WARN, "Lock error timeout reset\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
495
Core/Src/main.c
Executable file → Normal file
495
Core/Src/main.c
Executable file → Normal file
@@ -1,241 +1,254 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : main.c
|
||||
* @brief : Main program body
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
#include "adc.h"
|
||||
#include "can.h"
|
||||
#include "rtc.h"
|
||||
#include "usart.h"
|
||||
#include "gpio.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include "can.h"
|
||||
#include "board.h"
|
||||
#include <stdio.h>
|
||||
#include "debug.h"
|
||||
#include "charger_gbt.h"
|
||||
#include "soft_rtc.h"
|
||||
#include "j1939.h"
|
||||
#include "lock.h"
|
||||
#include "connector.h"
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PTD */
|
||||
|
||||
/* USER CODE END PTD */
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PD */
|
||||
|
||||
#include "edcan_config.h"
|
||||
#include "edcan_defines.h"
|
||||
/* USER CODE END PD */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PM */
|
||||
|
||||
/* USER CODE END PM */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
/* USER CODE BEGIN PV */
|
||||
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
void SystemClock_Config(void);
|
||||
/* USER CODE BEGIN PFP */
|
||||
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* Private user code ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
/**
|
||||
* @brief The application entry point.
|
||||
* @retval int
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
/* USER CODE BEGIN 1 */
|
||||
uint32_t lasttick;
|
||||
/* USER CODE END 1 */
|
||||
|
||||
/* MCU Configuration--------------------------------------------------------*/
|
||||
|
||||
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
|
||||
HAL_Init();
|
||||
|
||||
/* USER CODE BEGIN Init */
|
||||
|
||||
/* USER CODE END Init */
|
||||
|
||||
/* Configure the system clock */
|
||||
SystemClock_Config();
|
||||
|
||||
/* USER CODE BEGIN SysInit */
|
||||
|
||||
/* USER CODE END SysInit */
|
||||
|
||||
/* Initialize all configured peripherals */
|
||||
MX_GPIO_Init();
|
||||
MX_ADC1_Init();
|
||||
MX_CAN1_Init();
|
||||
MX_CAN2_Init();
|
||||
MX_USART2_UART_Init();
|
||||
MX_RTC_Init();
|
||||
/* USER CODE BEGIN 2 */
|
||||
CAN_ReInit();
|
||||
Init_Peripheral();
|
||||
|
||||
HAL_Delay(300);
|
||||
GBT_Init();
|
||||
set_Time(1721651966);
|
||||
printf("Startup (type \'help\' for command list)\n");
|
||||
debug_init();
|
||||
EDCAN_Init(SW_GetAddr()); //0x20..0x23
|
||||
EDCAN_printf(LOG_INFO, "Startup FWVER = %d\n", FWVER);
|
||||
//EDCAN_Init(0x20); //Адрес EDCAN
|
||||
GBT_CAN_ReInit();
|
||||
CAN_ReInit();
|
||||
|
||||
CONN_Init();
|
||||
/* USER CODE END 2 */
|
||||
|
||||
/* Infinite loop */
|
||||
/* USER CODE BEGIN WHILE */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE END WHILE */
|
||||
|
||||
/* USER CODE BEGIN 3 */
|
||||
// HAL_Delay(1);
|
||||
EDCAN_Loop();
|
||||
//can_task();
|
||||
debug_task();
|
||||
CONN_CC_ReadStateFiltered();
|
||||
// GBT_ManageLock();
|
||||
CONN_Task();
|
||||
GBT_ChargerTask();
|
||||
|
||||
// if((HAL_GetTick() - lasttick)>100){
|
||||
// lasttick = HAL_GetTick();
|
||||
// EDCAN_printf(LOG_INFO, "Temp %d %d\n", GBT_ReadTemp(0), GBT_ReadTemp(0));
|
||||
// }
|
||||
|
||||
}
|
||||
/* USER CODE END 3 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief System Clock Configuration
|
||||
* @retval None
|
||||
*/
|
||||
void SystemClock_Config(void)
|
||||
{
|
||||
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
|
||||
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
|
||||
|
||||
/** Initializes the RCC Oscillators according to the specified parameters
|
||||
* in the RCC_OscInitTypeDef structure.
|
||||
*/
|
||||
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE|RCC_OSCILLATORTYPE_LSE;
|
||||
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
|
||||
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV5;
|
||||
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
|
||||
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
|
||||
RCC_OscInitStruct.Prediv1Source = RCC_PREDIV1_SOURCE_PLL2;
|
||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
||||
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
|
||||
RCC_OscInitStruct.PLL2.PLL2State = RCC_PLL2_ON;
|
||||
RCC_OscInitStruct.PLL2.PLL2MUL = RCC_PLL2_MUL8;
|
||||
RCC_OscInitStruct.PLL2.HSEPrediv2Value = RCC_HSE_PREDIV2_DIV5;
|
||||
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Initializes the CPU, AHB and APB buses clocks
|
||||
*/
|
||||
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|
||||
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
|
||||
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
|
||||
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
|
||||
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
|
||||
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
|
||||
|
||||
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_ADC;
|
||||
PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
|
||||
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Configure the Systick interrupt time
|
||||
*/
|
||||
__HAL_RCC_PLLI2S_ENABLE();
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 4 */
|
||||
|
||||
/* USER CODE END 4 */
|
||||
|
||||
/**
|
||||
* @brief This function is executed in case of error occurrence.
|
||||
* @retval None
|
||||
*/
|
||||
void Error_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN Error_Handler_Debug */
|
||||
/* User can add his own implementation to report the HAL error return state */
|
||||
__disable_irq();
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
/* USER CODE END Error_Handler_Debug */
|
||||
}
|
||||
|
||||
#ifdef USE_FULL_ASSERT
|
||||
/**
|
||||
* @brief Reports the name of the source file and the source line number
|
||||
* where the assert_param error has occurred.
|
||||
* @param file: pointer to the source file name
|
||||
* @param line: assert_param error line source number
|
||||
* @retval None
|
||||
*/
|
||||
void assert_failed(uint8_t *file, uint32_t line)
|
||||
{
|
||||
/* USER CODE BEGIN 6 */
|
||||
/* User can add his own implementation to report the file name and line number,
|
||||
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
|
||||
/* USER CODE END 6 */
|
||||
}
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : main.c
|
||||
* @brief : Main program body
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2024 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
#include "adc.h"
|
||||
#include "can.h"
|
||||
#include "rtc.h"
|
||||
#include "tim.h"
|
||||
#include "usart.h"
|
||||
#include "gpio.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include "can.h"
|
||||
#include "board.h"
|
||||
#include <stdio.h>
|
||||
#include "debug.h"
|
||||
#include "charger_gbt.h"
|
||||
#include "soft_rtc.h"
|
||||
#include "j1939.h"
|
||||
#include "connector.h"
|
||||
#include "rgb_controller.h"
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PTD */
|
||||
|
||||
/* USER CODE END PTD */
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PD */
|
||||
|
||||
#include "edcan_config.h"
|
||||
#include "edcan_defines.h"
|
||||
#include "edcan.h"
|
||||
/* USER CODE END PD */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PM */
|
||||
|
||||
/* USER CODE END PM */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
/* USER CODE BEGIN PV */
|
||||
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
void SystemClock_Config(void);
|
||||
/* USER CODE BEGIN PFP */
|
||||
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* Private user code ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
/**
|
||||
* @brief The application entry point.
|
||||
* @retval int
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
uint32_t lasttick;
|
||||
|
||||
/* OpenBLT: Configure vector table base address before HAL_Init() */
|
||||
EDCAN_VectorBaseConfigF1();
|
||||
/* USER CODE END 1 */
|
||||
|
||||
/* MCU Configuration--------------------------------------------------------*/
|
||||
|
||||
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
|
||||
HAL_Init();
|
||||
|
||||
/* USER CODE BEGIN Init */
|
||||
/* OpenBLT: Reset RCC configuration (bootloader may have changed it) */
|
||||
HAL_RCC_DeInit();
|
||||
/* USER CODE END Init */
|
||||
|
||||
/* Configure the system clock */
|
||||
SystemClock_Config();
|
||||
|
||||
/* USER CODE BEGIN SysInit */
|
||||
|
||||
/* USER CODE END SysInit */
|
||||
|
||||
/* Initialize all configured peripherals */
|
||||
MX_GPIO_Init();
|
||||
MX_ADC1_Init();
|
||||
MX_CAN1_Init();
|
||||
MX_CAN2_Init();
|
||||
MX_RTC_Init();
|
||||
MX_TIM4_Init();
|
||||
MX_USART2_UART_Init();
|
||||
MX_UART5_Init();
|
||||
MX_USART1_UART_Init();
|
||||
MX_USART3_UART_Init();
|
||||
/* USER CODE BEGIN 2 */
|
||||
CAN_ReInit();
|
||||
Init_Peripheral();
|
||||
LED_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);
|
||||
//EDCAN_Init(0x20); //Адрес EDCAN
|
||||
GBT_CAN_ReInit();
|
||||
CAN_ReInit();
|
||||
|
||||
CONN_Init();
|
||||
/* USER CODE END 2 */
|
||||
|
||||
/* Infinite loop */
|
||||
/* USER CODE BEGIN WHILE */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE END WHILE */
|
||||
|
||||
/* USER CODE BEGIN 3 */
|
||||
// HAL_Delay(1);
|
||||
EDCAN_Loop();
|
||||
//can_task();
|
||||
debug_task();
|
||||
CONN_CC_ReadStateFiltered();
|
||||
// GBT_ManageLock();
|
||||
CONN_Task();
|
||||
GBT_ChargerTask();
|
||||
LED_Write();
|
||||
LED_Task();
|
||||
|
||||
// if((HAL_GetTick() - lasttick)>100){
|
||||
// lasttick = HAL_GetTick();
|
||||
// EDCAN_printf(LOG_INFO, "Temp %d %d\n", GBT_ReadTemp(0), GBT_ReadTemp(0));
|
||||
// }
|
||||
|
||||
}
|
||||
/* USER CODE END 3 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief System Clock Configuration
|
||||
* @retval None
|
||||
*/
|
||||
void SystemClock_Config(void)
|
||||
{
|
||||
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
|
||||
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
|
||||
|
||||
/** Initializes the RCC Oscillators according to the specified parameters
|
||||
* in the RCC_OscInitTypeDef structure.
|
||||
*/
|
||||
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE|RCC_OSCILLATORTYPE_LSE;
|
||||
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
|
||||
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV5;
|
||||
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
|
||||
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
|
||||
RCC_OscInitStruct.Prediv1Source = RCC_PREDIV1_SOURCE_PLL2;
|
||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
||||
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
|
||||
RCC_OscInitStruct.PLL2.PLL2State = RCC_PLL2_ON;
|
||||
RCC_OscInitStruct.PLL2.PLL2MUL = RCC_PLL2_MUL8;
|
||||
RCC_OscInitStruct.PLL2.HSEPrediv2Value = RCC_HSE_PREDIV2_DIV5;
|
||||
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Initializes the CPU, AHB and APB buses clocks
|
||||
*/
|
||||
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|
||||
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
|
||||
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
|
||||
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
|
||||
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
|
||||
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
|
||||
|
||||
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_ADC;
|
||||
PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
|
||||
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Configure the Systick interrupt time
|
||||
*/
|
||||
__HAL_RCC_PLLI2S_ENABLE();
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 4 */
|
||||
|
||||
/* USER CODE END 4 */
|
||||
|
||||
/**
|
||||
* @brief This function is executed in case of error occurrence.
|
||||
* @retval None
|
||||
*/
|
||||
void Error_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN Error_Handler_Debug */
|
||||
/* User can add his own implementation to report the HAL error return state */
|
||||
__disable_irq();
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
/* USER CODE END Error_Handler_Debug */
|
||||
}
|
||||
#ifdef USE_FULL_ASSERT
|
||||
/**
|
||||
* @brief Reports the name of the source file and the source line number
|
||||
* where the assert_param error has occurred.
|
||||
* @param file: pointer to the source file name
|
||||
* @param line: assert_param error line source number
|
||||
* @retval None
|
||||
*/
|
||||
void assert_failed(uint8_t *file, uint32_t line)
|
||||
{
|
||||
/* USER CODE BEGIN 6 */
|
||||
/* User can add his own implementation to report the file name and line number,
|
||||
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
|
||||
/* USER CODE END 6 */
|
||||
}
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
|
||||
228
Core/Src/rgb_controller.c
Normal file
228
Core/Src/rgb_controller.c
Normal file
@@ -0,0 +1,228 @@
|
||||
#include "rgb_controller.h"
|
||||
#include "main.h"
|
||||
#include "string.h"
|
||||
#include "connector.h"
|
||||
|
||||
#include "tim.h"
|
||||
|
||||
RGB_State_t LED_State;
|
||||
RGB_Cycle_t LED_Cycle;
|
||||
|
||||
RGB_Cycle_t color_estop = {
|
||||
.Color1 = { .R = 250, .G = 0, .B = 0 },
|
||||
.Color2 = { .R = 250, .G = 0, .B = 0 },
|
||||
.Tr = 50,
|
||||
.Th = 50,
|
||||
.Tf = 50,
|
||||
.Tl = 50,
|
||||
};
|
||||
|
||||
RGB_Cycle_t color_unknown = {
|
||||
.Color1 = { .R = 64, .G = 0, .B = 0 },
|
||||
.Color2 = { .R = 64, .G = 0, .B = 0 },
|
||||
.Tr = 50,
|
||||
.Th = 10,
|
||||
.Tf = 50,
|
||||
.Tl = 0,
|
||||
};
|
||||
|
||||
RGB_Cycle_t color_light = {
|
||||
.Color1 = { .R = 0, .G = 255, .B = 0 },
|
||||
.Color2 = { .R = 0, .G = 255, .B = 0 },
|
||||
.Tr = 50,
|
||||
.Th = 10,
|
||||
.Tf = 50,
|
||||
.Tl = 0,
|
||||
};
|
||||
|
||||
RGB_Cycle_t color_disabled = {
|
||||
.Color1 = { .R = 250, .G = 0, .B = 0 },
|
||||
.Color2 = { .R = 32, .G = 0, .B = 0 },
|
||||
.Tr = 50,
|
||||
.Th = 10,
|
||||
.Tf = 50,
|
||||
.Tl = 0,
|
||||
};
|
||||
|
||||
RGB_Cycle_t color_unplugged = {
|
||||
.Color1 = { .R = 0, .G = 128, .B = 0 },
|
||||
.Color2 = { .R = 0, .G = 128, .B = 0 },
|
||||
.Tr = 50,
|
||||
.Th = 10,
|
||||
.Tf = 50,
|
||||
.Tl = 0,
|
||||
};
|
||||
|
||||
RGB_Cycle_t color_preparing = {
|
||||
.Color1 = { .R = 0, .G = 0, .B = 250 },
|
||||
.Color2 = { .R = 0, .G = 0, .B = 250 },
|
||||
.Tr = 50,
|
||||
.Th = 10,
|
||||
.Tf = 50,
|
||||
.Tl = 0,
|
||||
};
|
||||
|
||||
RGB_Cycle_t color_charging = {
|
||||
.Color1 = { .R = 0, .G = 255, .B = 0 },
|
||||
.Color2 = { .R = 0, .G = 32, .B = 0 },
|
||||
.Tr = 50,
|
||||
.Th = 10,
|
||||
.Tf = 50,
|
||||
.Tl = 0,
|
||||
};
|
||||
|
||||
RGB_Cycle_t color_finished = {
|
||||
.Color1 = { .R = 255, .G = 255, .B = 255 },
|
||||
.Color2 = { .R = 255, .G = 255, .B = 255 },
|
||||
.Tr = 50,
|
||||
.Th = 10,
|
||||
.Tf = 50,
|
||||
.Tl = 0,
|
||||
};
|
||||
|
||||
RGB_Cycle_t color_error = {
|
||||
.Color1 = { .R = 255, .G = 0, .B = 0 },
|
||||
.Color2 = { .R = 32, .G = 0, .B = 0 },
|
||||
.Tr = 50,
|
||||
.Th = 10,
|
||||
.Tf = 50,
|
||||
.Tl = 0,
|
||||
};
|
||||
|
||||
void LED_Write(){
|
||||
if(CONN.chargingError != CONN_NO_ERROR){
|
||||
LED_SetColor(&color_error);
|
||||
return;
|
||||
}
|
||||
switch(CONN.connState){
|
||||
case Unknown:
|
||||
LED_SetColor(&color_unknown);
|
||||
break;
|
||||
case Unplugged:
|
||||
LED_SetColor(&color_unplugged);
|
||||
break;
|
||||
case Disabled:
|
||||
LED_SetColor(&color_disabled);
|
||||
break;
|
||||
case Preparing:
|
||||
LED_SetColor(&color_preparing);
|
||||
break;
|
||||
case AuthRequired:
|
||||
LED_SetColor(&color_preparing);
|
||||
break;
|
||||
case WaitingForEnergy:
|
||||
LED_SetColor(&color_charging);
|
||||
break;
|
||||
case ChargingPausedEV:
|
||||
LED_SetColor(&color_charging);
|
||||
break;
|
||||
case ChargingPausedEVSE:
|
||||
LED_SetColor(&color_charging);
|
||||
break;
|
||||
case Charging:
|
||||
LED_SetColor(&color_charging);
|
||||
break;
|
||||
case AuthTimeout:
|
||||
LED_SetColor(&color_finished);
|
||||
break;
|
||||
case Finished:
|
||||
LED_SetColor(&color_finished);
|
||||
break;
|
||||
case FinishedEVSE:
|
||||
LED_SetColor(&color_finished);
|
||||
break;
|
||||
case FinishedEV:
|
||||
LED_SetColor(&color_finished);
|
||||
break;
|
||||
case Replugging:
|
||||
LED_SetColor(&color_preparing);
|
||||
break;
|
||||
default:
|
||||
LED_SetColor(&color_unknown);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void interpolateColors(RGB_t* color1, RGB_t* color2, uint16_t a, uint16_t b, RGB_t *result) {
|
||||
|
||||
// Проверяем, чтобы a не выходила за пределы диапазона
|
||||
if (a > b) a = b;
|
||||
|
||||
if(b==0) b = 1;
|
||||
|
||||
// Вычисляем коэффициент смешивания в виде целого числа
|
||||
uint16_t t = (a * 255) / b; // t будет от 0 до 255
|
||||
|
||||
// Линейная интерполяция с использованием целых чисел
|
||||
result->R = (color1->R * (255 - t) + color2->R * t) / 255;
|
||||
result->G = (color1->G * (255 - t) + color2->G * t) / 255;
|
||||
result->B = (color1->B * (255 - t) + color2->B * t) / 255;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void RGB_SetColor(RGB_t *color){
|
||||
htim4.Instance->CCR2 = color->R * 100 / 255;
|
||||
htim4.Instance->CCR3 = color->G * 100 / 255;
|
||||
htim4.Instance->CCR4 = color->B * 100 / 255;
|
||||
}
|
||||
|
||||
void LED_SetColor(RGB_Cycle_t *color){
|
||||
memcpy(&LED_Cycle, color, sizeof(RGB_Cycle_t));
|
||||
}
|
||||
|
||||
|
||||
void LED_Init(){
|
||||
RGB_t color = {.R=0, .G=0, .B=0};
|
||||
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_2);
|
||||
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_3);
|
||||
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_4);
|
||||
RGB_SetColor(&color);
|
||||
}
|
||||
|
||||
|
||||
void LED_Task(){
|
||||
static uint32_t led_tick;
|
||||
if((HAL_GetTick() - led_tick) > 20){
|
||||
led_tick = HAL_GetTick();
|
||||
LED_State.tick++;
|
||||
switch(LED_State.state){
|
||||
case LED_RISING:
|
||||
interpolateColors(&LED_Cycle.Color2, &LED_Cycle.Color1, LED_State.tick, LED_Cycle.Tr, &LED_State.color);
|
||||
|
||||
if(LED_State.tick>LED_Cycle.Tr){
|
||||
LED_State.state = LED_HIGH;
|
||||
LED_State.tick = 0;
|
||||
}
|
||||
break;
|
||||
case LED_HIGH:
|
||||
memcpy(&LED_State.color, &LED_Cycle.Color1, sizeof(RGB_t));
|
||||
|
||||
if(LED_State.tick>LED_Cycle.Th){
|
||||
LED_State.state = LED_FALLING;
|
||||
LED_State.tick = 0;
|
||||
}
|
||||
break;
|
||||
case LED_FALLING:
|
||||
interpolateColors(&LED_Cycle.Color1, &LED_Cycle.Color2, LED_State.tick, LED_Cycle.Tf, &LED_State.color);
|
||||
|
||||
if(LED_State.tick>LED_Cycle.Tf){
|
||||
LED_State.state = LED_LOW;
|
||||
LED_State.tick = 0;
|
||||
}
|
||||
break;
|
||||
case LED_LOW:
|
||||
memcpy(&LED_State.color, &LED_Cycle.Color2, sizeof(RGB_t));
|
||||
|
||||
if(LED_State.tick>LED_Cycle.Tl){
|
||||
LED_State.state = LED_RISING;
|
||||
LED_State.tick = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LED_State.state = LED_RISING;
|
||||
}
|
||||
RGB_SetColor(&LED_State.color);
|
||||
}
|
||||
}
|
||||
|
||||
1
Core/Src/stm32f1xx_hal_msp.c
Executable file → Normal file
1
Core/Src/stm32f1xx_hal_msp.c
Executable file → Normal file
@@ -62,6 +62,7 @@
|
||||
*/
|
||||
void HAL_MspInit(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN MspInit 0 */
|
||||
|
||||
/* USER CODE END MspInit 0 */
|
||||
|
||||
155
Core/Src/tim.c
Normal file
155
Core/Src/tim.c
Normal file
@@ -0,0 +1,155 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file tim.c
|
||||
* @brief This file provides code for the configuration
|
||||
* of the TIM instances.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2026 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "tim.h"
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
TIM_HandleTypeDef htim4;
|
||||
|
||||
/* TIM4 init function */
|
||||
void MX_TIM4_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN TIM4_Init 0 */
|
||||
|
||||
/* USER CODE END TIM4_Init 0 */
|
||||
|
||||
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
|
||||
TIM_MasterConfigTypeDef sMasterConfig = {0};
|
||||
TIM_OC_InitTypeDef sConfigOC = {0};
|
||||
|
||||
/* USER CODE BEGIN TIM4_Init 1 */
|
||||
|
||||
/* USER CODE END TIM4_Init 1 */
|
||||
htim4.Instance = TIM4;
|
||||
htim4.Init.Prescaler = 720;
|
||||
htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
htim4.Init.Period = 100;
|
||||
htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||
htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||
if (HAL_TIM_Base_Init(&htim4) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
|
||||
if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
if (HAL_TIM_PWM_Init(&htim4) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
|
||||
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
|
||||
if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sConfigOC.OCMode = TIM_OCMODE_PWM1;
|
||||
sConfigOC.Pulse = 0;
|
||||
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
|
||||
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN TIM4_Init 2 */
|
||||
|
||||
/* USER CODE END TIM4_Init 2 */
|
||||
HAL_TIM_MspPostInit(&htim4);
|
||||
|
||||
}
|
||||
|
||||
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
|
||||
{
|
||||
|
||||
if(tim_baseHandle->Instance==TIM4)
|
||||
{
|
||||
/* USER CODE BEGIN TIM4_MspInit 0 */
|
||||
|
||||
/* USER CODE END TIM4_MspInit 0 */
|
||||
/* TIM4 clock enable */
|
||||
__HAL_RCC_TIM4_CLK_ENABLE();
|
||||
/* USER CODE BEGIN TIM4_MspInit 1 */
|
||||
|
||||
/* USER CODE END TIM4_MspInit 1 */
|
||||
}
|
||||
}
|
||||
void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle)
|
||||
{
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
if(timHandle->Instance==TIM4)
|
||||
{
|
||||
/* USER CODE BEGIN TIM4_MspPostInit 0 */
|
||||
|
||||
/* USER CODE END TIM4_MspPostInit 0 */
|
||||
|
||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||
/**TIM4 GPIO Configuration
|
||||
PD13 ------> TIM4_CH2
|
||||
PD14 ------> TIM4_CH3
|
||||
PD15 ------> TIM4_CH4
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
|
||||
|
||||
__HAL_AFIO_REMAP_TIM4_ENABLE();
|
||||
|
||||
/* USER CODE BEGIN TIM4_MspPostInit 1 */
|
||||
|
||||
/* USER CODE END TIM4_MspPostInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle)
|
||||
{
|
||||
|
||||
if(tim_baseHandle->Instance==TIM4)
|
||||
{
|
||||
/* USER CODE BEGIN TIM4_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END TIM4_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_TIM4_CLK_DISABLE();
|
||||
/* USER CODE BEGIN TIM4_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END TIM4_MspDeInit 1 */
|
||||
}
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
233
Core/Src/usart.c
Executable file → Normal file
233
Core/Src/usart.c
Executable file → Normal file
@@ -24,8 +24,68 @@
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
UART_HandleTypeDef huart5;
|
||||
UART_HandleTypeDef huart1;
|
||||
UART_HandleTypeDef huart2;
|
||||
UART_HandleTypeDef huart3;
|
||||
|
||||
/* UART5 init function */
|
||||
void MX_UART5_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN UART5_Init 0 */
|
||||
|
||||
/* USER CODE END UART5_Init 0 */
|
||||
|
||||
/* USER CODE BEGIN UART5_Init 1 */
|
||||
|
||||
/* USER CODE END UART5_Init 1 */
|
||||
huart5.Instance = UART5;
|
||||
huart5.Init.BaudRate = 115200;
|
||||
huart5.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
huart5.Init.StopBits = UART_STOPBITS_1;
|
||||
huart5.Init.Parity = UART_PARITY_NONE;
|
||||
huart5.Init.Mode = UART_MODE_RX;
|
||||
huart5.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||
huart5.Init.OverSampling = UART_OVERSAMPLING_16;
|
||||
if (HAL_UART_Init(&huart5) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN UART5_Init 2 */
|
||||
|
||||
/* USER CODE END UART5_Init 2 */
|
||||
|
||||
}
|
||||
/* USART1 init function */
|
||||
|
||||
void MX_USART1_UART_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN USART1_Init 0 */
|
||||
|
||||
/* USER CODE END USART1_Init 0 */
|
||||
|
||||
/* USER CODE BEGIN USART1_Init 1 */
|
||||
|
||||
/* USER CODE END USART1_Init 1 */
|
||||
huart1.Instance = USART1;
|
||||
huart1.Init.BaudRate = 115200;
|
||||
huart1.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
huart1.Init.StopBits = UART_STOPBITS_1;
|
||||
huart1.Init.Parity = UART_PARITY_NONE;
|
||||
huart1.Init.Mode = UART_MODE_TX_RX;
|
||||
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
|
||||
if (HAL_UART_Init(&huart1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN USART1_Init 2 */
|
||||
|
||||
/* USER CODE END USART1_Init 2 */
|
||||
|
||||
}
|
||||
/* USART2 init function */
|
||||
|
||||
void MX_USART2_UART_Init(void)
|
||||
@@ -54,13 +114,97 @@ void MX_USART2_UART_Init(void)
|
||||
|
||||
/* USER CODE END USART2_Init 2 */
|
||||
|
||||
}
|
||||
/* USART3 init function */
|
||||
|
||||
void MX_USART3_UART_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN USART3_Init 0 */
|
||||
|
||||
/* USER CODE END USART3_Init 0 */
|
||||
|
||||
/* USER CODE BEGIN USART3_Init 1 */
|
||||
|
||||
/* USER CODE END USART3_Init 1 */
|
||||
huart3.Instance = USART3;
|
||||
huart3.Init.BaudRate = 115200;
|
||||
huart3.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
huart3.Init.StopBits = UART_STOPBITS_1;
|
||||
huart3.Init.Parity = UART_PARITY_NONE;
|
||||
huart3.Init.Mode = UART_MODE_TX_RX;
|
||||
huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||
huart3.Init.OverSampling = UART_OVERSAMPLING_16;
|
||||
if (HAL_UART_Init(&huart3) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN USART3_Init 2 */
|
||||
|
||||
/* USER CODE END USART3_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
|
||||
{
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
if(uartHandle->Instance==USART2)
|
||||
if(uartHandle->Instance==UART5)
|
||||
{
|
||||
/* USER CODE BEGIN UART5_MspInit 0 */
|
||||
|
||||
/* USER CODE END UART5_MspInit 0 */
|
||||
/* UART5 clock enable */
|
||||
__HAL_RCC_UART5_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||
/**UART5 GPIO Configuration
|
||||
PC12 ------> UART5_TX
|
||||
PD2 ------> UART5_RX
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_12;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_2;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
|
||||
|
||||
/* USER CODE BEGIN UART5_MspInit 1 */
|
||||
|
||||
/* USER CODE END UART5_MspInit 1 */
|
||||
}
|
||||
else if(uartHandle->Instance==USART1)
|
||||
{
|
||||
/* USER CODE BEGIN USART1_MspInit 0 */
|
||||
|
||||
/* USER CODE END USART1_MspInit 0 */
|
||||
/* USART1 clock enable */
|
||||
__HAL_RCC_USART1_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
/**USART1 GPIO Configuration
|
||||
PA9 ------> USART1_TX
|
||||
PA10 ------> USART1_RX
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_9;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_10;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/* USER CODE BEGIN USART1_MspInit 1 */
|
||||
|
||||
/* USER CODE END USART1_MspInit 1 */
|
||||
}
|
||||
else if(uartHandle->Instance==USART2)
|
||||
{
|
||||
/* USER CODE BEGIN USART2_MspInit 0 */
|
||||
|
||||
@@ -92,12 +236,79 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
|
||||
|
||||
/* USER CODE END USART2_MspInit 1 */
|
||||
}
|
||||
else if(uartHandle->Instance==USART3)
|
||||
{
|
||||
/* USER CODE BEGIN USART3_MspInit 0 */
|
||||
|
||||
/* USER CODE END USART3_MspInit 0 */
|
||||
/* USART3 clock enable */
|
||||
__HAL_RCC_USART3_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||
/**USART3 GPIO Configuration
|
||||
PC10 ------> USART3_TX
|
||||
PC11 ------> USART3_RX
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_10;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_11;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
|
||||
|
||||
__HAL_AFIO_REMAP_USART3_PARTIAL();
|
||||
|
||||
/* USER CODE BEGIN USART3_MspInit 1 */
|
||||
|
||||
/* USER CODE END USART3_MspInit 1 */
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
|
||||
{
|
||||
|
||||
if(uartHandle->Instance==USART2)
|
||||
if(uartHandle->Instance==UART5)
|
||||
{
|
||||
/* USER CODE BEGIN UART5_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END UART5_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_UART5_CLK_DISABLE();
|
||||
|
||||
/**UART5 GPIO Configuration
|
||||
PC12 ------> UART5_TX
|
||||
PD2 ------> UART5_RX
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_12);
|
||||
|
||||
HAL_GPIO_DeInit(GPIOD, GPIO_PIN_2);
|
||||
|
||||
/* USER CODE BEGIN UART5_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END UART5_MspDeInit 1 */
|
||||
}
|
||||
else if(uartHandle->Instance==USART1)
|
||||
{
|
||||
/* USER CODE BEGIN USART1_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END USART1_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_USART1_CLK_DISABLE();
|
||||
|
||||
/**USART1 GPIO Configuration
|
||||
PA9 ------> USART1_TX
|
||||
PA10 ------> USART1_RX
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
|
||||
|
||||
/* USER CODE BEGIN USART1_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END USART1_MspDeInit 1 */
|
||||
}
|
||||
else if(uartHandle->Instance==USART2)
|
||||
{
|
||||
/* USER CODE BEGIN USART2_MspDeInit 0 */
|
||||
|
||||
@@ -117,6 +328,24 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
|
||||
|
||||
/* USER CODE END USART2_MspDeInit 1 */
|
||||
}
|
||||
else if(uartHandle->Instance==USART3)
|
||||
{
|
||||
/* USER CODE BEGIN USART3_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END USART3_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_USART3_CLK_DISABLE();
|
||||
|
||||
/**USART3 GPIO Configuration
|
||||
PC10 ------> USART3_TX
|
||||
PC11 ------> USART3_RX
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_10|GPIO_PIN_11);
|
||||
|
||||
/* USER CODE BEGIN USART3_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END USART3_MspDeInit 1 */
|
||||
}
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
@@ -253,6 +253,9 @@ g_pfnVectors:
|
||||
.word BootRAM /* @0x1E0. This is for boot in RAM mode for
|
||||
STM32F10x Connectivity line Devices. */
|
||||
|
||||
/* BOOT_FLASH_VECTOR_TABLE_CS_OFFSET (0x1E4): сюда bootloader запишет checksum */
|
||||
.word 0x66666666
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Provide weak aliases for each Exception handler to the Default_Handler.
|
||||
|
||||
Reference in New Issue
Block a user