forked from achamaikin/CCSModuleSW30Web
Overwrite repository contents with fork state.
Replace outdated files with the latest working tree from fork/CCSModuleSW30Web to align source and generated artifacts. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Vendored
BIN
Binary file not shown.
Executable → Regular
+11
@@ -29,18 +29,29 @@ extern "C" {
|
||||
#include "main.h"
|
||||
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include <stdint.h>
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
extern ADC_HandleTypeDef hadc1;
|
||||
|
||||
/* USER CODE BEGIN Private defines */
|
||||
typedef struct {
|
||||
uint16_t in3_raw; /* Rank1: ADC_CHANNEL_3 */
|
||||
uint16_t cp_raw; /* Rank2: ADC_CHANNEL_4 */
|
||||
uint16_t ntc1_raw; /* Rank3: ADC_CHANNEL_8 */
|
||||
uint16_t ntc2_raw; /* Rank4: ADC_CHANNEL_9 */
|
||||
uint16_t temp_sensor_raw; /* Rank5: ADC_CHANNEL_TEMPSENSOR */
|
||||
uint16_t vrefint_raw; /* Rank6: ADC_CHANNEL_VREFINT */
|
||||
} ADC_ScanData_t;
|
||||
extern volatile ADC_ScanData_t adc_data;
|
||||
|
||||
/* USER CODE END Private defines */
|
||||
|
||||
void MX_ADC1_Init(void);
|
||||
|
||||
/* USER CODE BEGIN Prototypes */
|
||||
void ADC_ScanStart(void);
|
||||
|
||||
/* USER CODE END Prototypes */
|
||||
|
||||
|
||||
+1
-1
@@ -55,7 +55,7 @@ typedef struct __attribute__((packed)) {
|
||||
uint8_t stationType; // Байт 4: тип станции
|
||||
uint8_t boardVersion; // Байт 5: версия платы
|
||||
uint8_t addrEdcan; // Байт 6: адрес EDCAN
|
||||
uint8_t maxPower; // Байт 7: максимальная мощность станции (5кВт/bit)
|
||||
uint8_t maxPower; // Байт 7: максимальная мощность станции (5кВт/bit)
|
||||
uint8_t reserved[56]; // Байты 8-63: зарезервированы
|
||||
} InfoBlock_t;
|
||||
|
||||
|
||||
@@ -16,11 +16,15 @@ typedef enum {
|
||||
EV_STATE_ACQUIRING = 6,
|
||||
} CP_State_t;
|
||||
|
||||
extern CP_State_t cp_state_buffer;
|
||||
|
||||
void CP_Init(void);
|
||||
void CP_SetDuty(uint8_t percentage);
|
||||
uint8_t CP_GetDuty(void);
|
||||
int32_t CP_GetVoltage(void);
|
||||
CP_State_t CP_GetState(void);
|
||||
CP_State_t CP_GetFilteredState(void);
|
||||
void CP_FilterState(void);
|
||||
void CP_Loop(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file dma.h
|
||||
* @brief This file contains all the function prototypes for
|
||||
* the dma.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 __DMA_H__
|
||||
#define __DMA_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
|
||||
/* DMA memory to memory transfer handles -------------------------------------*/
|
||||
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* USER CODE BEGIN Private defines */
|
||||
|
||||
/* USER CODE END Private defines */
|
||||
|
||||
void MX_DMA_Init(void);
|
||||
|
||||
/* USER CODE BEGIN Prototypes */
|
||||
|
||||
/* USER CODE END Prototypes */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __DMA_H__ */
|
||||
|
||||
+11
-1
@@ -43,7 +43,7 @@ extern "C" {
|
||||
/* USER CODE BEGIN EC */
|
||||
#define FW_VERSION_MAJOR 1
|
||||
#define FW_VERSION_MINOR 0
|
||||
#define FW_VERSION_PATCH 10
|
||||
#define FW_VERSION_PATCH 17
|
||||
/* USER CODE END EC */
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
@@ -59,6 +59,8 @@ void Error_Handler(void);
|
||||
/* USER CODE END EFP */
|
||||
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
#define DBG1_Pin GPIO_PIN_2
|
||||
#define DBG1_GPIO_Port GPIOC
|
||||
#define RELAY_CP_Pin GPIO_PIN_3
|
||||
#define RELAY_CP_GPIO_Port GPIOC
|
||||
#define IN_SW0_Pin GPIO_PIN_1
|
||||
@@ -67,6 +69,10 @@ void Error_Handler(void);
|
||||
#define IN_SW1_GPIO_Port GPIOA
|
||||
#define CP_ADC_Pin GPIO_PIN_4
|
||||
#define CP_ADC_GPIO_Port GPIOA
|
||||
#define DBG2_Pin GPIO_PIN_5
|
||||
#define DBG2_GPIO_Port GPIOA
|
||||
#define DBG3_Pin GPIO_PIN_6
|
||||
#define DBG3_GPIO_Port GPIOA
|
||||
#define CP_PWM_Pin GPIO_PIN_7
|
||||
#define CP_PWM_GPIO_Port GPIOA
|
||||
#define LOCK_A_Pin GPIO_PIN_4
|
||||
@@ -91,6 +97,10 @@ void Error_Handler(void);
|
||||
#define RELAY5_GPIO_Port GPIOE
|
||||
#define AC_OK_Pin GPIO_PIN_14
|
||||
#define AC_OK_GPIO_Port GPIOE
|
||||
#define DBG5_Pin GPIO_PIN_10
|
||||
#define DBG5_GPIO_Port GPIOB
|
||||
#define DBG4_Pin GPIO_PIN_11
|
||||
#define DBG4_GPIO_Port GPIOB
|
||||
#define RELAY_CC_Pin GPIO_PIN_15
|
||||
#define RELAY_CC_GPIO_Port GPIOA
|
||||
#define RELAY_DC_Pin GPIO_PIN_3
|
||||
|
||||
+2
-1
@@ -11,7 +11,8 @@ void CCS_Init(void);
|
||||
void CCS_SendEmergencyStop(void);
|
||||
void CCS_SendStart(void);
|
||||
void CCS_RxEventCallback(UART_HandleTypeDef *huart, uint16_t size);
|
||||
void CCS_RxArm(void);
|
||||
void CCS_TxCpltCallback(UART_HandleTypeDef *huart);
|
||||
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart);
|
||||
|
||||
typedef enum {
|
||||
CCS_UNKNOWN = 0,
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "main.h"
|
||||
#include <string.h>
|
||||
#include "charger_control.h"
|
||||
#include "isr_opt.h"
|
||||
|
||||
#define USE_WEB_INTERFACE
|
||||
|
||||
@@ -159,10 +160,6 @@ struct SerialControl_t {
|
||||
// Переменные для передачи команды
|
||||
volatile ReceivedCommand_t received_command;
|
||||
volatile uint8_t command_ready;
|
||||
volatile uint8_t response_pending;
|
||||
volatile uint8_t response_code;
|
||||
volatile uint8_t rx_error_pending;
|
||||
volatile uint32_t rx_error_code;
|
||||
|
||||
// Время отправки последнего пакета
|
||||
volatile uint32_t tx_tick;
|
||||
@@ -172,7 +169,8 @@ struct SerialControl_t {
|
||||
// Публичные методы
|
||||
void SC_Init();
|
||||
void SC_Task();
|
||||
void SC_SendPacket(const uint8_t* payload, uint16_t payload_len, uint8_t response_code);
|
||||
ISR_FAST void SC_SendPacket(const uint8_t* payload, uint16_t payload_len, uint8_t response_code);
|
||||
void SC_RecoverUartDma(UART_HandleTypeDef *huart);
|
||||
|
||||
// Внешняя функция обработки команд (определена в serial_handler.c)
|
||||
extern void SC_CommandHandler(ReceivedCommand_t* cmd);
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
/*#define HAL_CORTEX_MODULE_ENABLED */
|
||||
#define HAL_CRC_MODULE_ENABLED
|
||||
/*#define HAL_DAC_MODULE_ENABLED */
|
||||
/*#define HAL_DMA_MODULE_ENABLED */
|
||||
#define HAL_DMA_MODULE_ENABLED
|
||||
/*#define HAL_ETH_MODULE_ENABLED */
|
||||
/*#define HAL_FLASH_MODULE_ENABLED */
|
||||
#define HAL_GPIO_MODULE_ENABLED
|
||||
|
||||
@@ -55,6 +55,12 @@ void SVC_Handler(void);
|
||||
void DebugMon_Handler(void);
|
||||
void PendSV_Handler(void);
|
||||
void SysTick_Handler(void);
|
||||
void DMA1_Channel1_IRQHandler(void);
|
||||
void DMA1_Channel2_IRQHandler(void);
|
||||
void DMA1_Channel3_IRQHandler(void);
|
||||
void DMA1_Channel6_IRQHandler(void);
|
||||
void DMA1_Channel7_IRQHandler(void);
|
||||
void ADC1_2_IRQHandler(void);
|
||||
void CAN1_RX0_IRQHandler(void);
|
||||
void TIM3_IRQHandler(void);
|
||||
void USART1_IRQHandler(void);
|
||||
|
||||
+104
-5
@@ -21,10 +21,39 @@
|
||||
#include "adc.h"
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
#include "isr_opt.h"
|
||||
static volatile uint16_t adc_dma_raw[6];
|
||||
volatile ADC_ScanData_t adc_data = {0};
|
||||
static volatile uint8_t adc_scan_data_ready = 0u;
|
||||
|
||||
void ADC_ScanStart(void)
|
||||
{
|
||||
if (HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adc_dma_raw, 6u) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
}
|
||||
|
||||
ISR_FAST void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
|
||||
{
|
||||
if (hadc->Instance != ADC1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
adc_data.in3_raw = adc_dma_raw[0];
|
||||
adc_data.cp_raw = adc_dma_raw[1];
|
||||
adc_data.ntc1_raw = adc_dma_raw[2];
|
||||
adc_data.ntc2_raw = adc_dma_raw[3];
|
||||
adc_data.temp_sensor_raw = adc_dma_raw[4];
|
||||
adc_data.vrefint_raw = adc_dma_raw[5];
|
||||
adc_scan_data_ready = 1u;
|
||||
}
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
ADC_HandleTypeDef hadc1;
|
||||
DMA_HandleTypeDef hdma_adc1;
|
||||
|
||||
/* ADC1 init function */
|
||||
void MX_ADC1_Init(void)
|
||||
@@ -43,12 +72,12 @@ void MX_ADC1_Init(void)
|
||||
/** Common config
|
||||
*/
|
||||
hadc1.Instance = ADC1;
|
||||
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
|
||||
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
|
||||
hadc1.Init.ContinuousConvMode = DISABLE;
|
||||
hadc1.Init.DiscontinuousConvMode = DISABLE;
|
||||
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
|
||||
hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T3_TRGO;
|
||||
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
|
||||
hadc1.Init.NbrOfConversion = 1;
|
||||
hadc1.Init.NbrOfConversion = 6;
|
||||
if (HAL_ADC_Init(&hadc1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
@@ -56,9 +85,54 @@ void MX_ADC1_Init(void)
|
||||
|
||||
/** Configure Regular Channel
|
||||
*/
|
||||
sConfig.Channel = ADC_CHANNEL_8;
|
||||
sConfig.Channel = ADC_CHANNEL_3;
|
||||
sConfig.Rank = ADC_REGULAR_RANK_1;
|
||||
sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
|
||||
sConfig.SamplingTime = ADC_SAMPLETIME_41CYCLES_5;
|
||||
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Configure Regular Channel
|
||||
*/
|
||||
sConfig.Channel = ADC_CHANNEL_4;
|
||||
sConfig.Rank = ADC_REGULAR_RANK_2;
|
||||
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Configure Regular Channel
|
||||
*/
|
||||
sConfig.Channel = ADC_CHANNEL_8;
|
||||
sConfig.Rank = ADC_REGULAR_RANK_3;
|
||||
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Configure Regular Channel
|
||||
*/
|
||||
sConfig.Channel = ADC_CHANNEL_9;
|
||||
sConfig.Rank = ADC_REGULAR_RANK_4;
|
||||
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Configure Regular Channel
|
||||
*/
|
||||
sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
|
||||
sConfig.Rank = ADC_REGULAR_RANK_5;
|
||||
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Configure Regular Channel
|
||||
*/
|
||||
sConfig.Channel = ADC_CHANNEL_VREFINT;
|
||||
sConfig.Rank = ADC_REGULAR_RANK_6;
|
||||
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
@@ -97,6 +171,26 @@ void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/* ADC1 DMA Init */
|
||||
/* ADC1 Init */
|
||||
hdma_adc1.Instance = DMA1_Channel1;
|
||||
hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
|
||||
hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
|
||||
hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
|
||||
hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
|
||||
hdma_adc1.Init.Mode = DMA_CIRCULAR;
|
||||
hdma_adc1.Init.Priority = DMA_PRIORITY_MEDIUM;
|
||||
if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
__HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc1);
|
||||
|
||||
/* ADC1 interrupt Init */
|
||||
HAL_NVIC_SetPriority(ADC1_2_IRQn, 7, 0);
|
||||
HAL_NVIC_EnableIRQ(ADC1_2_IRQn);
|
||||
/* USER CODE BEGIN ADC1_MspInit 1 */
|
||||
|
||||
/* USER CODE END ADC1_MspInit 1 */
|
||||
@@ -124,6 +218,11 @@ void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle)
|
||||
|
||||
HAL_GPIO_DeInit(GPIOB, ADC_NTC1_Pin|ADC_NTC2_Pin);
|
||||
|
||||
/* ADC1 DMA DeInit */
|
||||
HAL_DMA_DeInit(adcHandle->DMA_Handle);
|
||||
|
||||
/* ADC1 interrupt Deinit */
|
||||
HAL_NVIC_DisableIRQ(ADC1_2_IRQn);
|
||||
/* USER CODE BEGIN ADC1_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END ADC1_MspDeInit 1 */
|
||||
|
||||
+4
-21
@@ -1,11 +1,10 @@
|
||||
|
||||
#include "main.h"
|
||||
#include "board.h"
|
||||
#include "adc.h"
|
||||
#include "tim.h"
|
||||
#include "sma_filter.h"
|
||||
|
||||
extern ADC_HandleTypeDef hadc1;
|
||||
|
||||
//TODO:
|
||||
//TEMP READ
|
||||
// Connector temperature sensors
|
||||
@@ -89,6 +88,7 @@ uint8_t GetBoardTemp(){
|
||||
|
||||
void Init_Peripheral(){
|
||||
HAL_ADCEx_Calibration_Start(&hadc1);
|
||||
ADC_ScanStart();
|
||||
|
||||
RELAY_Write(RELAY_AUX0, 0);
|
||||
RELAY_Write(RELAY_AUX1, 0);
|
||||
@@ -130,27 +130,11 @@ float calculate_NTC_resistance(int adc_value, float Vref, float Vin, float R) {
|
||||
}
|
||||
|
||||
int16_t CONN_ReadTemp(uint8_t ch){
|
||||
ADC_LockBlocking();
|
||||
|
||||
//TODO
|
||||
if(ch)ADC_Select_Channel(ADC_CHANNEL_8);
|
||||
else ADC_Select_Channel(ADC_CHANNEL_9);
|
||||
// Начало конверсии
|
||||
HAL_ADC_Start(&hadc1);
|
||||
|
||||
|
||||
// Ожидание окончания конверсии
|
||||
HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
|
||||
|
||||
// Получение значения
|
||||
uint32_t adcValue = HAL_ADC_GetValue(&hadc1);
|
||||
|
||||
// Остановка АЦП (по желанию)
|
||||
HAL_ADC_Stop(&hadc1);
|
||||
uint32_t adcValue = 0u;
|
||||
adcValue = ch ? adc_data.ntc2_raw : adc_data.ntc1_raw;
|
||||
|
||||
int32_t adc_filtered = SMAFilter_Update(&conn_temp_adc_filter[ch ? 1u : 0u], (int32_t)adcValue);
|
||||
if((uint32_t)adc_filtered > 4000u) {
|
||||
ADC_Unlock();
|
||||
return 20; //Термодатчик не подключен
|
||||
}
|
||||
|
||||
@@ -161,7 +145,6 @@ int16_t CONN_ReadTemp(uint8_t ch){
|
||||
|
||||
float temp = pt1000_to_temperature(calculate_NTC_resistance((int)adc_filtered, Vref, Vin, R));
|
||||
|
||||
ADC_Unlock();
|
||||
return (int16_t)temp;
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -127,7 +127,7 @@ void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
|
||||
__HAL_AFIO_REMAP_CAN1_3();
|
||||
|
||||
/* CAN1 interrupt Init */
|
||||
HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 0, 0);
|
||||
HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 3, 0);
|
||||
HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
|
||||
/* USER CODE BEGIN CAN1_MspInit 1 */
|
||||
|
||||
@@ -165,7 +165,7 @@ void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
|
||||
/* CAN2 interrupt Init */
|
||||
HAL_NVIC_SetPriority(CAN2_TX_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(CAN2_TX_IRQn);
|
||||
HAL_NVIC_SetPriority(CAN2_RX1_IRQn, 0, 0);
|
||||
HAL_NVIC_SetPriority(CAN2_RX1_IRQn, 3, 0);
|
||||
HAL_NVIC_EnableIRQ(CAN2_RX1_IRQn);
|
||||
/* USER CODE BEGIN CAN2_MspInit 1 */
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
ChargingConnector_t CONN;
|
||||
CONN_State_t connectorState;
|
||||
extern uint8_t config_initialized;
|
||||
|
||||
void CONN_Init(){
|
||||
|
||||
|
||||
+75
-29
@@ -1,37 +1,34 @@
|
||||
#include "cp.h"
|
||||
#include "adc.h"
|
||||
#include "board.h"
|
||||
#include "debug.h"
|
||||
#include "tim.h"
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MAX_DUTY 450
|
||||
#define FILTER_ORDER 100
|
||||
|
||||
static int32_t cp_voltage_mv = 0;
|
||||
static uint8_t cp_duty = 0;
|
||||
CP_State_t fake_cp_state = EV_STATE_ACQUIRING;
|
||||
CP_State_t cp_state_buffer = EV_STATE_ACQUIRING;
|
||||
|
||||
static uint32_t CP_ReadAdcChannel(uint32_t ch) {
|
||||
uint32_t adc = 0;
|
||||
|
||||
ADC_Select_Channel(ch);
|
||||
HAL_ADC_Start(&hadc1);
|
||||
HAL_ADC_PollForConversion(&hadc1, 10);
|
||||
adc = HAL_ADC_GetValue(&hadc1);
|
||||
HAL_ADC_Stop(&hadc1);
|
||||
|
||||
return adc;
|
||||
}
|
||||
#define VREFINT_CAL_ADDR ((uint16_t*)0x1FFFF7BA) // для STM32F1!
|
||||
|
||||
static int32_t CP_ReadVoltageMv(void)
|
||||
{
|
||||
uint32_t adc = 0;
|
||||
int32_t v_adc_mv = 0;
|
||||
int32_t v_out_mv = 0;
|
||||
uint32_t adc_cp = adc_data.cp_raw;
|
||||
uint32_t adc_vref = adc_data.vrefint_raw; // нужно измерять!
|
||||
|
||||
adc = CP_ReadAdcChannel((uint32_t)4u);
|
||||
v_adc_mv = (int32_t)((adc * 3300u) / 4095u);
|
||||
v_out_mv = ((v_adc_mv - 1723) * 1000) / 130;
|
||||
// VREFINT в мВ (берётся из даташита или калибровки MCU)
|
||||
const int32_t VREFINT_MV = 1210;
|
||||
|
||||
// напряжение на входе АЦП
|
||||
int32_t v_adc_mv = (adc_cp * VREFINT_MV) / adc_vref;
|
||||
|
||||
// дальше твоя формула
|
||||
int32_t v_out_mv = ((v_adc_mv - 1723) * 7704) / 1000;
|
||||
|
||||
return v_out_mv;
|
||||
}
|
||||
@@ -50,7 +47,7 @@ void CP_Init(void) {
|
||||
#endif
|
||||
|
||||
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);
|
||||
HAL_TIM_OC_Start_IT(&htim3, TIM_CHANNEL_1);
|
||||
HAL_TIM_OC_Start(&htim3, TIM_CHANNEL_1);
|
||||
}
|
||||
|
||||
void CP_SetDuty(uint8_t percentage) {
|
||||
@@ -71,11 +68,12 @@ uint8_t CP_GetDuty(void) {
|
||||
}
|
||||
|
||||
int32_t CP_GetVoltage(void) {
|
||||
cp_voltage_mv = CP_ReadVoltageMv();
|
||||
return cp_voltage_mv;
|
||||
}
|
||||
|
||||
CP_State_t CP_GetState(void) {
|
||||
int32_t voltage_real = cp_voltage_mv;
|
||||
int32_t voltage_real = CP_GetVoltage();
|
||||
|
||||
if(fake_cp_state != EV_STATE_ACQUIRING) {
|
||||
return fake_cp_state;
|
||||
@@ -98,18 +96,66 @@ CP_State_t CP_GetState(void) {
|
||||
}
|
||||
}
|
||||
|
||||
void CP_Loop(void) {
|
||||
(void)CP_GetState();
|
||||
CP_State_t CP_GetFilteredState(void) {
|
||||
return cp_state_buffer;
|
||||
}
|
||||
|
||||
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
if (htim->Instance == TIM3 && htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) {
|
||||
if (ADC_TryLock() == 0u) {
|
||||
return;
|
||||
}
|
||||
cp_voltage_mv = CP_ReadVoltageMv();
|
||||
ADC_Unlock();
|
||||
void CP_FilterState(void) {
|
||||
|
||||
static CP_State_t pending_state = EV_STATE_ACQUIRING;
|
||||
static uint8_t stable_count = 0u;
|
||||
CP_State_t current_state = CP_GetState();
|
||||
|
||||
/* Keep last accepted state while CP is still acquiring. */
|
||||
if (current_state == EV_STATE_ACQUIRING) {
|
||||
pending_state = EV_STATE_ACQUIRING;
|
||||
stable_count = 0u;
|
||||
return;
|
||||
}
|
||||
|
||||
if (current_state != pending_state) {
|
||||
pending_state = current_state;
|
||||
stable_count = 1u;
|
||||
return;
|
||||
}
|
||||
|
||||
if (stable_count < FILTER_ORDER) {
|
||||
stable_count++;
|
||||
}
|
||||
|
||||
if (stable_count >= FILTER_ORDER) {
|
||||
cp_state_buffer = pending_state;
|
||||
}
|
||||
}
|
||||
|
||||
void CP_Loop(void) {
|
||||
static uint32_t tick;
|
||||
if ((int32_t)(HAL_GetTick() - tick) < 1) return;
|
||||
tick = HAL_GetTick();
|
||||
static uint8_t initialized = 0;
|
||||
static CP_State_t prev_state = EV_STATE_ACQUIRING;
|
||||
static uint8_t prev_duty = 0;
|
||||
|
||||
CP_FilterState();
|
||||
|
||||
CP_State_t current_state = CP_GetFilteredState();
|
||||
uint8_t current_duty = cp_duty;
|
||||
|
||||
if (!initialized) {
|
||||
prev_state = current_state;
|
||||
prev_duty = current_duty;
|
||||
initialized = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (current_state != prev_state) {
|
||||
log_printf(LOG_INFO, "CP state changed: %d -> %d\n", prev_state, current_state);
|
||||
prev_state = current_state;
|
||||
}
|
||||
|
||||
if (current_duty != prev_duty) {
|
||||
log_printf(LOG_INFO, "CP duty changed: %u -> %u\n", prev_duty, current_duty);
|
||||
prev_duty = current_duty;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file dma.c
|
||||
* @brief This file provides code for the configuration
|
||||
* of all the requested memory to memory DMA transfers.
|
||||
******************************************************************************
|
||||
* @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 "dma.h"
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Configure DMA */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
|
||||
/**
|
||||
* Enable DMA controller clock
|
||||
*/
|
||||
void MX_DMA_Init(void)
|
||||
{
|
||||
|
||||
/* DMA controller clock enable */
|
||||
__HAL_RCC_DMA1_CLK_ENABLE();
|
||||
|
||||
/* DMA interrupt init */
|
||||
/* DMA1_Channel1_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 1, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
|
||||
/* DMA1_Channel2_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(DMA1_Channel2_IRQn, 4, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA1_Channel2_IRQn);
|
||||
/* DMA1_Channel3_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(DMA1_Channel3_IRQn, 1, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA1_Channel3_IRQn);
|
||||
/* DMA1_Channel6_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 1, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn);
|
||||
/* DMA1_Channel7_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(DMA1_Channel7_IRQn, 4, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA1_Channel7_IRQn);
|
||||
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 2 */
|
||||
|
||||
/* USER CODE END 2 */
|
||||
|
||||
+25
-4
@@ -54,20 +54,27 @@ void MX_GPIO_Init(void)
|
||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOC, RELAY_CP_Pin|LOCK_A_Pin|LOCK_B_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(GPIOC, DBG1_Pin|RELAY_CP_Pin|LOCK_A_Pin|LOCK_B_Pin, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOA, DBG2_Pin|DBG3_Pin|RELAY_CC_Pin, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOE, RELAY1_Pin|RELAY2_Pin|RELAY3_Pin|RELAY4_Pin
|
||||
|RELAY5_Pin, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(RELAY_CC_GPIO_Port, RELAY_CC_Pin, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(GPIOB, DBG5_Pin|DBG4_Pin|EE_WP_Pin, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOD, RELAY_DC_Pin|USART2_DIR_Pin, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(EE_WP_GPIO_Port, EE_WP_Pin, GPIO_PIN_RESET);
|
||||
/*Configure GPIO pin : DBG1_Pin */
|
||||
GPIO_InitStruct.Pin = DBG1_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(DBG1_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : RELAY_CP_Pin LOCK_A_Pin LOCK_B_Pin */
|
||||
GPIO_InitStruct.Pin = RELAY_CP_Pin|LOCK_A_Pin|LOCK_B_Pin;
|
||||
@@ -88,6 +95,13 @@ void MX_GPIO_Init(void)
|
||||
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
|
||||
HAL_GPIO_Init(IN_SW1_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : DBG2_Pin DBG3_Pin */
|
||||
GPIO_InitStruct.Pin = DBG2_Pin|DBG3_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : IN0_Pin AC_OK_Pin ISO_IN_Pin */
|
||||
GPIO_InitStruct.Pin = IN0_Pin|AC_OK_Pin|ISO_IN_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
@@ -103,6 +117,13 @@ void MX_GPIO_Init(void)
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : DBG5_Pin DBG4_Pin */
|
||||
GPIO_InitStruct.Pin = DBG5_Pin|DBG4_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pin : RELAY_CC_Pin */
|
||||
GPIO_InitStruct.Pin = RELAY_CC_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
|
||||
+335
-332
@@ -1,332 +1,335 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/* USER CODE END Header */
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
#include "adc.h"
|
||||
#include "can.h"
|
||||
#include "crc.h"
|
||||
#include "rtc.h"
|
||||
#include "tim.h"
|
||||
#include "usart.h"
|
||||
#include "gpio.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include "can.h"
|
||||
#include "board.h"
|
||||
#include <stdio.h>
|
||||
#include "debug.h"
|
||||
#include "soft_rtc.h"
|
||||
#include "connector.h"
|
||||
#include "serial_control.h"
|
||||
#include "charger_config.h"
|
||||
#include "serial.h"
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PTD */
|
||||
|
||||
/* USER CODE END PTD */
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PD */
|
||||
|
||||
/* USER CODE END PD */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PM */
|
||||
|
||||
/* USER CODE END PM */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
/* USER CODE BEGIN PV */
|
||||
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
void SystemClock_Config(void);
|
||||
/* USER CODE BEGIN PFP */
|
||||
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* Private user code ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/**
|
||||
* @brief Vector base address configuration. It should no longer be at the start of
|
||||
* flash memory but moved forward because the first part of flash is
|
||||
* reserved for the bootloader. Note that this is already done by the
|
||||
* bootloader before starting this program. Unfortunately, function
|
||||
* SystemInit() overwrites this change again.
|
||||
* @return none.
|
||||
*/
|
||||
static void VectorBase_Config(void)
|
||||
{
|
||||
/* The constant array with vectors of the vector table is declared externally in the
|
||||
* c-startup code.
|
||||
*/
|
||||
extern const unsigned long g_pfnVectors[];
|
||||
|
||||
/* Remap the vector table to where the vector table is located for this program. */
|
||||
SCB->VTOR = (unsigned long)&g_pfnVectors[0];
|
||||
}
|
||||
|
||||
uint8_t ED_TraceWarning(uint8_t flag, uint8_t id){
|
||||
static uint8_t memory[32];
|
||||
if(id > 31) return 0;
|
||||
uint8_t result = 0;
|
||||
if(memory[id] != flag){
|
||||
result = 1;
|
||||
}
|
||||
memory[id] = flag;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void ED_Delay(uint32_t Delay)
|
||||
{
|
||||
uint32_t tickstart = HAL_GetTick();
|
||||
uint32_t wait = Delay;
|
||||
|
||||
if (wait < HAL_MAX_DELAY)
|
||||
{
|
||||
wait += (uint32_t)(uwTickFreq);
|
||||
}
|
||||
|
||||
while ((HAL_GetTick() - tickstart) < wait){
|
||||
CCS_SerialLoop();
|
||||
StopButtonControl();
|
||||
// CP_Loop();
|
||||
CONN_Task();
|
||||
LED_Task();
|
||||
SC_Task();
|
||||
}
|
||||
}
|
||||
|
||||
void StopButtonControl(){
|
||||
static uint32_t tick;
|
||||
static uint32_t hold_time;
|
||||
static uint8_t stop_btn_fault = 1;
|
||||
uint32_t now = HAL_GetTick();
|
||||
|
||||
/* Run no faster than once per 10 ms. */
|
||||
if((now - tick) < 10){
|
||||
return;
|
||||
}
|
||||
tick = now;
|
||||
|
||||
uint8_t pressed = !IN_ReadInput(IN_ESTOP);
|
||||
if(!pressed){
|
||||
stop_btn_fault = 0;
|
||||
}
|
||||
|
||||
if(stop_btn_fault){
|
||||
return;
|
||||
}
|
||||
|
||||
if(pressed){
|
||||
if(hold_time == 0){
|
||||
CONN.connControl = CMD_STOP;
|
||||
}
|
||||
hold_time += 10;
|
||||
if(hold_time == 5000){
|
||||
CONN.connControl = CMD_FORCE_UNLOCK;
|
||||
}
|
||||
if(hold_time > 40000){
|
||||
SC_SendPacket(NULL, 0, RESP_SUCCESS);
|
||||
while(huart2.gState == HAL_UART_STATE_BUSY_TX);
|
||||
HAL_Delay(10);
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
}
|
||||
else{
|
||||
hold_time = 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t temp0, temp1;
|
||||
|
||||
static void CAN1_MinimalReInit(void)
|
||||
{
|
||||
HAL_CAN_Stop(&hcan1);
|
||||
MX_CAN1_Init();
|
||||
if (HAL_CAN_Start(&hcan1) != HAL_OK) {
|
||||
Error_Handler();
|
||||
}
|
||||
if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK) {
|
||||
Error_Handler();
|
||||
}
|
||||
}
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
/**
|
||||
* @brief The application entry point.
|
||||
* @retval int
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
VectorBase_Config();
|
||||
/* USER CODE END 1 */
|
||||
|
||||
/* MCU Configuration--------------------------------------------------------*/
|
||||
|
||||
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
|
||||
HAL_Init();
|
||||
|
||||
/* USER CODE BEGIN Init */
|
||||
HAL_RCC_DeInit();
|
||||
/* USER CODE END Init */
|
||||
|
||||
/* Configure the system clock */
|
||||
SystemClock_Config();
|
||||
|
||||
/* USER CODE BEGIN SysInit */
|
||||
|
||||
/* USER CODE END SysInit */
|
||||
|
||||
/* Initialize all configured peripherals */
|
||||
MX_GPIO_Init();
|
||||
MX_ADC1_Init();
|
||||
MX_CAN1_Init();
|
||||
MX_CAN2_Init();
|
||||
MX_RTC_Init();
|
||||
MX_TIM4_Init();
|
||||
MX_USART2_UART_Init();
|
||||
MX_CRC_Init();
|
||||
MX_UART5_Init();
|
||||
MX_USART1_UART_Init();
|
||||
MX_USART3_UART_Init();
|
||||
MX_TIM3_Init();
|
||||
/* USER CODE BEGIN 2 */
|
||||
Init_Peripheral();
|
||||
LED_Init();
|
||||
|
||||
HAL_Delay(300);
|
||||
CCS_Init();
|
||||
SC_Init();
|
||||
log_printf(LOG_INFO, "CCS module start\n");
|
||||
ReadVersion();
|
||||
log_printf(LOG_INFO, "Serial number: %d\n", infoPacket.serialNumber);
|
||||
log_printf(LOG_INFO, "Board revision: %d\n", infoPacket.boardVersion);
|
||||
log_printf(LOG_INFO, "FW version: %d.%d.%d\n", infoPacket.fw_version_major, infoPacket.fw_version_minor, infoPacket.fw_version_patch);
|
||||
CAN1_MinimalReInit();
|
||||
PSU_Init();
|
||||
CONN_Init();
|
||||
|
||||
/* USER CODE END 2 */
|
||||
|
||||
/* Infinite loop */
|
||||
/* USER CODE BEGIN WHILE */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE END WHILE */
|
||||
|
||||
/* USER CODE BEGIN 3 */
|
||||
|
||||
|
||||
PSU_ReadWrite();
|
||||
PSU_Task();
|
||||
ED_Delay(10);
|
||||
METER_CalculateEnergy();
|
||||
CONN_Loop();
|
||||
LED_Write();
|
||||
ED_Delay(10);
|
||||
|
||||
}
|
||||
/* USER CODE END 3 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief System Clock Configuration
|
||||
* @retval None
|
||||
*/
|
||||
void SystemClock_Config(void)
|
||||
{
|
||||
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
|
||||
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
|
||||
|
||||
/** Initializes the RCC Oscillators according to the specified parameters
|
||||
* in the RCC_OscInitTypeDef structure.
|
||||
*/
|
||||
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE|RCC_OSCILLATORTYPE_LSE;
|
||||
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
|
||||
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV5;
|
||||
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
|
||||
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
|
||||
RCC_OscInitStruct.Prediv1Source = RCC_PREDIV1_SOURCE_PLL2;
|
||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
||||
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
|
||||
RCC_OscInitStruct.PLL2.PLL2State = RCC_PLL2_ON;
|
||||
RCC_OscInitStruct.PLL2.PLL2MUL = RCC_PLL2_MUL8;
|
||||
RCC_OscInitStruct.PLL2.HSEPrediv2Value = RCC_HSE_PREDIV2_DIV5;
|
||||
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Initializes the CPU, AHB and APB buses clocks
|
||||
*/
|
||||
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|
||||
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
|
||||
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
|
||||
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
|
||||
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
|
||||
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
|
||||
|
||||
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_ADC;
|
||||
PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
|
||||
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Configure the Systick interrupt time
|
||||
*/
|
||||
__HAL_RCC_PLLI2S_ENABLE();
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 4 */
|
||||
|
||||
/* USER CODE END 4 */
|
||||
|
||||
/**
|
||||
* @brief This function is executed in case of error occurrence.
|
||||
* @retval None
|
||||
*/
|
||||
void Error_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN Error_Handler_Debug */
|
||||
/* User can add his own implementation to report the HAL error return state */
|
||||
__disable_irq();
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
/* USER CODE END Error_Handler_Debug */
|
||||
}
|
||||
#ifdef USE_FULL_ASSERT
|
||||
/**
|
||||
* @brief Reports the name of the source file and the source line number
|
||||
* where the assert_param error has occurred.
|
||||
* @param file: pointer to the source file name
|
||||
* @param line: assert_param error line source number
|
||||
* @retval None
|
||||
*/
|
||||
void assert_failed(uint8_t *file, uint32_t line)
|
||||
{
|
||||
/* USER CODE BEGIN 6 */
|
||||
/* User can add his own implementation to report the file name and line number,
|
||||
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
|
||||
/* USER CODE END 6 */
|
||||
}
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
/* USER CODE BEGIN Header */
|
||||
/* USER CODE END Header */
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
#include "adc.h"
|
||||
#include "can.h"
|
||||
#include "crc.h"
|
||||
#include "dma.h"
|
||||
#include "rtc.h"
|
||||
#include "tim.h"
|
||||
#include "usart.h"
|
||||
#include "gpio.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include "can.h"
|
||||
#include "board.h"
|
||||
#include <stdio.h>
|
||||
#include "debug.h"
|
||||
#include "soft_rtc.h"
|
||||
#include "connector.h"
|
||||
#include "serial_control.h"
|
||||
#include "charger_config.h"
|
||||
#include "serial.h"
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PTD */
|
||||
|
||||
/* USER CODE END PTD */
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PD */
|
||||
|
||||
/* USER CODE END PD */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PM */
|
||||
|
||||
/* USER CODE END PM */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
/* USER CODE BEGIN PV */
|
||||
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
void SystemClock_Config(void);
|
||||
/* USER CODE BEGIN PFP */
|
||||
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* Private user code ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/**
|
||||
* @brief Vector base address configuration. It should no longer be at the start of
|
||||
* flash memory but moved forward because the first part of flash is
|
||||
* reserved for the bootloader. Note that this is already done by the
|
||||
* bootloader before starting this program. Unfortunately, function
|
||||
* SystemInit() overwrites this change again.
|
||||
* @return none.
|
||||
*/
|
||||
static void VectorBase_Config(void)
|
||||
{
|
||||
/* The constant array with vectors of the vector table is declared externally in the
|
||||
* c-startup code.
|
||||
*/
|
||||
extern const unsigned long g_pfnVectors[];
|
||||
|
||||
/* Remap the vector table to where the vector table is located for this program. */
|
||||
SCB->VTOR = (unsigned long)&g_pfnVectors[0];
|
||||
}
|
||||
|
||||
uint8_t ED_TraceWarning(uint8_t flag, uint8_t id){
|
||||
static uint8_t memory[32];
|
||||
if(id > 31) return 0;
|
||||
uint8_t result = 0;
|
||||
if(memory[id] != flag){
|
||||
result = 1;
|
||||
}
|
||||
memory[id] = flag;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void ED_Delay(uint32_t Delay)
|
||||
{
|
||||
uint32_t tickstart = HAL_GetTick();
|
||||
uint32_t wait = Delay;
|
||||
|
||||
if (wait < HAL_MAX_DELAY)
|
||||
{
|
||||
wait += (uint32_t)(uwTickFreq);
|
||||
}
|
||||
|
||||
while ((HAL_GetTick() - tickstart) < wait){
|
||||
CCS_SerialLoop();
|
||||
StopButtonControl();
|
||||
CP_Loop();
|
||||
CONN_Task();
|
||||
LED_Task();
|
||||
SC_Task();
|
||||
}
|
||||
}
|
||||
|
||||
void StopButtonControl(){
|
||||
static uint32_t tick;
|
||||
static uint32_t hold_time;
|
||||
static uint8_t stop_btn_fault = 1;
|
||||
uint32_t now = HAL_GetTick();
|
||||
|
||||
/* Run no faster than once per 10 ms. */
|
||||
if((now - tick) < 10){
|
||||
return;
|
||||
}
|
||||
tick = now;
|
||||
|
||||
uint8_t pressed = !IN_ReadInput(IN_ESTOP);
|
||||
if(!pressed){
|
||||
stop_btn_fault = 0;
|
||||
}
|
||||
|
||||
if(stop_btn_fault){
|
||||
return;
|
||||
}
|
||||
|
||||
if(pressed){
|
||||
if(hold_time == 0){
|
||||
CONN.connControl = CMD_STOP;
|
||||
}
|
||||
hold_time += 10;
|
||||
if(hold_time == 5000){
|
||||
CONN.connControl = CMD_FORCE_UNLOCK;
|
||||
}
|
||||
if(hold_time > 40000){
|
||||
SC_SendPacket(NULL, 0, RESP_SUCCESS);
|
||||
while(huart2.gState == HAL_UART_STATE_BUSY_TX);
|
||||
HAL_Delay(10);
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
}
|
||||
else{
|
||||
hold_time = 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t temp0, temp1;
|
||||
|
||||
static void CAN1_MinimalReInit(void)
|
||||
{
|
||||
HAL_CAN_Stop(&hcan1);
|
||||
MX_CAN1_Init();
|
||||
if (HAL_CAN_Start(&hcan1) != HAL_OK) {
|
||||
Error_Handler();
|
||||
}
|
||||
if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK) {
|
||||
Error_Handler();
|
||||
}
|
||||
}
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
/**
|
||||
* @brief The application entry point.
|
||||
* @retval int
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
VectorBase_Config();
|
||||
/* USER CODE END 1 */
|
||||
|
||||
/* MCU Configuration--------------------------------------------------------*/
|
||||
|
||||
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
|
||||
HAL_Init();
|
||||
|
||||
/* USER CODE BEGIN Init */
|
||||
HAL_RCC_DeInit();
|
||||
/* USER CODE END Init */
|
||||
|
||||
/* Configure the system clock */
|
||||
SystemClock_Config();
|
||||
|
||||
/* USER CODE BEGIN SysInit */
|
||||
|
||||
/* USER CODE END SysInit */
|
||||
|
||||
/* Initialize all configured peripherals */
|
||||
MX_GPIO_Init();
|
||||
MX_DMA_Init();
|
||||
MX_ADC1_Init();
|
||||
MX_CAN1_Init();
|
||||
MX_CAN2_Init();
|
||||
MX_RTC_Init();
|
||||
MX_TIM4_Init();
|
||||
MX_USART2_UART_Init();
|
||||
MX_CRC_Init();
|
||||
MX_UART5_Init();
|
||||
MX_USART1_UART_Init();
|
||||
MX_USART3_UART_Init();
|
||||
MX_TIM3_Init();
|
||||
/* USER CODE BEGIN 2 */
|
||||
Init_Peripheral();
|
||||
LED_Init();
|
||||
|
||||
HAL_Delay(300);
|
||||
CCS_Init();
|
||||
SC_Init();
|
||||
log_printf(LOG_INFO, "CCS module start\n");
|
||||
ReadVersion();
|
||||
log_printf(LOG_INFO, "Serial number: %d\n", infoPacket.serialNumber);
|
||||
log_printf(LOG_INFO, "Board revision: %d\n", infoPacket.boardVersion);
|
||||
log_printf(LOG_INFO, "FW version: %d.%d.%d\n", infoPacket.fw_version_major, infoPacket.fw_version_minor, infoPacket.fw_version_patch);
|
||||
CAN1_MinimalReInit();
|
||||
PSU_Init();
|
||||
CONN_Init();
|
||||
|
||||
/* USER CODE END 2 */
|
||||
|
||||
/* Infinite loop */
|
||||
/* USER CODE BEGIN WHILE */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE END WHILE */
|
||||
|
||||
/* USER CODE BEGIN 3 */
|
||||
|
||||
|
||||
PSU_ReadWrite();
|
||||
PSU_Task();
|
||||
ED_Delay(10);
|
||||
METER_CalculateEnergy();
|
||||
CONN_Loop();
|
||||
LED_Write();
|
||||
ED_Delay(10);
|
||||
|
||||
}
|
||||
/* 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 */
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "charger_control.h"
|
||||
#include "board.h"
|
||||
#include "debug.h"
|
||||
#include "isr_opt.h"
|
||||
|
||||
PSU_02_t PSU_02;
|
||||
PSU_04_t PSU_04;
|
||||
@@ -39,7 +40,7 @@ static uint32_t PSU_StateTime(void){
|
||||
return HAL_GetTick() - PSU0.statetick;
|
||||
}
|
||||
|
||||
void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan){
|
||||
ISR_FAST void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan){
|
||||
|
||||
static CAN_RxHeaderTypeDef RxHeader;
|
||||
static uint8_t RxData[8] = {0,};
|
||||
@@ -262,9 +263,12 @@ void PSU_ReadWrite(){
|
||||
}
|
||||
CONN.RequestedPower = CONN.RequestedCurrent * CONN.RequestedVoltage / 10;
|
||||
|
||||
|
||||
if(PSU0.ready){
|
||||
PSU_SetVoltageCurrent(0, CONN.RequestedVoltage, CONN.RequestedCurrent); // Normal mode
|
||||
if (CONN.RequestedVoltage == 500) { // fake
|
||||
PSU_SetVoltageCurrent(0, 300, 10); // Normal mode
|
||||
}else{
|
||||
PSU_SetVoltageCurrent(0, CONN.RequestedVoltage, CONN.RequestedCurrent); // Normal mode
|
||||
}
|
||||
ED_Delay(CAN_DELAY);
|
||||
if(CONN.MeasuredVoltage > 490){
|
||||
if(PSU0.hv_tick == 0){
|
||||
|
||||
@@ -18,7 +18,7 @@ RGB_Cycle_t color_estop = {
|
||||
.Tl = 5,
|
||||
};
|
||||
|
||||
RGB_Cycle_t color_unlock = {
|
||||
RGB_Cycle_t color_unlock = {
|
||||
.Color1 = { .R = 255, .G = 0, .B = 0 },
|
||||
.Color2 = { .R = 0, .G = 0, .B = 0 },
|
||||
.Tr = 10,
|
||||
|
||||
+283
-120
@@ -3,10 +3,12 @@
|
||||
#include "connector.h"
|
||||
#include "board.h"
|
||||
#include "debug.h"
|
||||
#include "isr_opt.h"
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "charger_config.h"
|
||||
#include "psu_control.h"
|
||||
#include "serial_control.h"
|
||||
|
||||
extern UART_HandleTypeDef huart3;
|
||||
extern uint8_t config_initialized;
|
||||
@@ -28,14 +30,19 @@ uint8_t ev_enable_output = 0;
|
||||
#define CMD_INTERVAL 10
|
||||
#define MAX_TX_BUFFER_SIZE 256
|
||||
#define MAX_RX_BUFFER_SIZE 256
|
||||
|
||||
/* Everest requests 500 V → БП реально 300 V / 1 A, в STATE отдаём 500 V. */
|
||||
#define EVEREST_TIMEOUT_WARN_MS 5000u
|
||||
#define EVEREST_TIMEOUT_STOP_MS 10000u
|
||||
#define UART3_REINIT_TIMEOUT_MS 1500u
|
||||
/* Everest requests 500 V -> PSU really gets 300 V / 1 A, state still reports 500 V. */
|
||||
#define FAKE_EVREQ_VOLTAGE_V 500u
|
||||
#define FAKE_PSU_VOLTAGE_V 300u
|
||||
#define FAKE_PSU_CURRENT_0P1A 10u
|
||||
|
||||
static uint8_t rx_buffer[MAX_RX_BUFFER_SIZE];
|
||||
static uint8_t tx_buffer[MAX_TX_BUFFER_SIZE];
|
||||
static uint8_t tx_pending_buffer[MAX_TX_BUFFER_SIZE];
|
||||
static uint16_t tx_pending_len = 0;
|
||||
static uint8_t uart3_tx_busy = 0;
|
||||
|
||||
uint8_t ESTOP = 0;
|
||||
uint8_t REPLUG = 0;
|
||||
@@ -45,31 +52,121 @@ static uint8_t pwm_duty_percent = 100;
|
||||
uint8_t isolation_enable = 0;
|
||||
static uint32_t last_host_seen = 0;
|
||||
static uint8_t fake_500_voltage_mode = 0;
|
||||
static CP_State_t cp_state_buffer = EV_STATE_ACQUIRING;
|
||||
static uint8_t everest_timed_out = 0;
|
||||
static uint8_t everest_timeout_warn_latched = 0;
|
||||
static uint8_t everest_timeout_stop_latched = 0;
|
||||
static uint32_t uart3_last_packet_tick = 0;
|
||||
static uint32_t uart3_last_reinit_tick = 0;
|
||||
|
||||
CCS_State_t CCS_State;
|
||||
CCS_EvInfo_t CCS_EvInfo;
|
||||
CONN_State_t CCS_EvseState;
|
||||
CCS_ConnectorState_t CCS_ConnectorState = CCS_UNKNOWN;
|
||||
|
||||
static uint8_t process_received_packet(const uint8_t* packet, uint16_t packet_len);
|
||||
ISR_FAST static uint8_t process_received_packet(const uint8_t* packet, uint16_t packet_len);
|
||||
static void CCS_UART3_Watchdog(void);
|
||||
static void CCS_LogUart3Error(const char *tag);
|
||||
|
||||
void CCS_RxEventCallback(UART_HandleTypeDef *huart, uint16_t size) {
|
||||
if (huart != &huart3) {
|
||||
ISR_FAST static void uart3_log_hal_error(uint8_t uart_num, uint32_t err) {
|
||||
if (err == HAL_UART_ERROR_NONE) {
|
||||
log_printf(LOG_ERR, "UART%u HAL error decode: NONE\n", uart_num);
|
||||
return;
|
||||
}
|
||||
if (size > 0 && size <= sizeof(rx_buffer)) {
|
||||
process_received_packet(rx_buffer, size);
|
||||
log_printf(LOG_ERR, "UART%u HAL error decode: %s%s%s%s%s%s raw=0x%08lx\n",
|
||||
uart_num,
|
||||
(err & HAL_UART_ERROR_PE) ? "PE " : "",
|
||||
(err & HAL_UART_ERROR_NE) ? "NE " : "",
|
||||
(err & HAL_UART_ERROR_FE) ? "FE " : "",
|
||||
(err & HAL_UART_ERROR_ORE) ? "ORE " : "",
|
||||
(err & HAL_UART_ERROR_DMA) ? "DMA " : "",
|
||||
#ifdef HAL_UART_ERROR_INVALID_CALLBACK
|
||||
(err & HAL_UART_ERROR_INVALID_CALLBACK) ? "INV_CB " : "",
|
||||
#else
|
||||
"",
|
||||
#endif
|
||||
(unsigned long)err);
|
||||
}
|
||||
|
||||
ISR_FAST static void uart3_arm_rx_or_log(const char *where) {
|
||||
HAL_StatusTypeDef st = HAL_UARTEx_ReceiveToIdle_DMA(&huart3, rx_buffer, sizeof(rx_buffer));
|
||||
if (st == HAL_OK) {
|
||||
return;
|
||||
}
|
||||
uint32_t err_after = HAL_UART_GetError(&huart3);
|
||||
log_printf(LOG_ERR,
|
||||
"UART3 RX arm failed (%s): HAL_Status=%d err_after=0x%08lx\n",
|
||||
where, (int)st, (unsigned long)err_after);
|
||||
uart3_log_hal_error(3u, err_after);
|
||||
CCS_LogUart3Error("UART3 RX arm failed details");
|
||||
if (err_after != HAL_UART_ERROR_NONE) {
|
||||
(void)HAL_UART_AbortReceive(&huart3);
|
||||
}
|
||||
}
|
||||
|
||||
void CCS_RxArm(void) {
|
||||
if ((&huart3)->RxState == HAL_UART_STATE_READY) {
|
||||
(void)HAL_UARTEx_ReceiveToIdle_IT(&huart3, rx_buffer, sizeof(rx_buffer));
|
||||
ISR_FAST void CCS_RxEventCallback(UART_HandleTypeDef *huart, uint16_t size) {
|
||||
if (huart != &huart3) {
|
||||
log_printf(LOG_WARN, "UART3 RX drop: wrong huart in RxEventCallback (size=%u)\n",
|
||||
(unsigned)size);
|
||||
return;
|
||||
}
|
||||
if (size == 0u) {
|
||||
log_printf(LOG_WARN, "UART3 RX drop: RxEvent size=0 (idle, no payload)\n");
|
||||
uart3_arm_rx_or_log("RxEventCallback");
|
||||
return;
|
||||
}
|
||||
if (size > sizeof(rx_buffer)) {
|
||||
log_printf(LOG_ERR, "UART3 RX drop: size=%u > rx_buffer %u (overflow, not parsed)\n",
|
||||
(unsigned)size, (unsigned)sizeof(rx_buffer));
|
||||
uart3_arm_rx_or_log("RxEventCallback");
|
||||
return;
|
||||
}
|
||||
uart3_last_packet_tick = HAL_GetTick();
|
||||
uart3_last_reinit_tick = uart3_last_packet_tick;
|
||||
process_received_packet(rx_buffer, size);
|
||||
uart3_arm_rx_or_log("RxEventCallback");
|
||||
}
|
||||
|
||||
ISR_FAST void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) {
|
||||
uint32_t error = HAL_UART_GetError(huart);
|
||||
uint8_t uart_num =
|
||||
(huart == &huart2) ? 2 :
|
||||
(huart == &huart3) ? 3 :
|
||||
(huart == &huart5) ? 5 : 0;
|
||||
log_printf(LOG_ERR,
|
||||
"UART%u HAL error (ISR): raw=0x%08lx — RX may be corrupted until re-arm\n",
|
||||
uart_num, (unsigned long)error);
|
||||
uart3_log_hal_error(uart_num, error);
|
||||
(void)HAL_UART_AbortReceive(huart);
|
||||
(void)HAL_UART_AbortTransmit(huart);
|
||||
if (huart == &huart3) {
|
||||
uart3_tx_busy = 0;
|
||||
uart3_arm_rx_or_log("ErrorCallback");
|
||||
} else {
|
||||
SC_RecoverUartDma(huart);
|
||||
}
|
||||
}
|
||||
|
||||
void CCS_TxCpltCallback(UART_HandleTypeDef *huart) {
|
||||
if (huart != &huart3) {
|
||||
return;
|
||||
}
|
||||
uart3_tx_busy = 0;
|
||||
if (tx_pending_len > 0) {
|
||||
memcpy(tx_buffer, tx_pending_buffer, tx_pending_len);
|
||||
uart3_tx_busy = 1;
|
||||
if (HAL_UART_Transmit_DMA(&huart3, tx_buffer, tx_pending_len) != HAL_OK) {
|
||||
uart3_tx_busy = 0;
|
||||
CCS_LogUart3Error("UART3 TX DMA resend failed");
|
||||
}
|
||||
tx_pending_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CCS_SerialLoop(void) {
|
||||
static uint32_t tick;
|
||||
if ((int32_t)(HAL_GetTick() - tick) < 1) return;
|
||||
tick = HAL_GetTick();
|
||||
|
||||
static uint32_t replug_tick = 0;
|
||||
static uint32_t replug_watchdog_tick = 0;
|
||||
static uint32_t replug_watchdog1_tick = 0;
|
||||
@@ -77,15 +174,16 @@ void CCS_SerialLoop(void) {
|
||||
static uint32_t force_unlock_tick = 0;
|
||||
static uint32_t stop_tick = 0;
|
||||
|
||||
CCS_RxArm();
|
||||
CCS_UART3_Watchdog();
|
||||
|
||||
/* Read CP once per loop and use buffered value below. */
|
||||
cp_state_buffer = CP_GetState();
|
||||
if (CONN.connControl != CMD_NONE) {
|
||||
last_cmd = CONN.connControl;
|
||||
}
|
||||
|
||||
if (CONN.connControl == CMD_FORCE_UNLOCK) {
|
||||
if (force_unlock_tick == 0) {
|
||||
force_unlock_tick = HAL_GetTick();
|
||||
} else if ((HAL_GetTick() - force_unlock_tick) >= 10000) {
|
||||
} else if ((int32_t)(HAL_GetTick() - force_unlock_tick) >= 10000) {
|
||||
CONN.connControl = CMD_NONE;
|
||||
force_unlock_tick = 0;
|
||||
}
|
||||
@@ -96,7 +194,7 @@ void CCS_SerialLoop(void) {
|
||||
if (CONN.connControl == CMD_STOP) {
|
||||
if (stop_tick == 0) {
|
||||
stop_tick = HAL_GetTick();
|
||||
} else if ((HAL_GetTick() - stop_tick) >= 1000) {
|
||||
} else if ((int32_t)(HAL_GetTick() - stop_tick) >= 1000) {
|
||||
CONN.connControl = CMD_NONE;
|
||||
stop_tick = 0;
|
||||
}
|
||||
@@ -104,12 +202,8 @@ void CCS_SerialLoop(void) {
|
||||
stop_tick = 0;
|
||||
}
|
||||
|
||||
if (CONN.connControl != CMD_NONE) {
|
||||
last_cmd = CONN.connControl;
|
||||
}
|
||||
|
||||
if((HAL_GetTick() - last_cmd_sent) > CMD_INTERVAL){
|
||||
if ((HAL_GetTick() - last_state_sent) >= 200) {
|
||||
if((int32_t)(HAL_GetTick() - last_cmd_sent) > (int32_t)CMD_INTERVAL){
|
||||
if ((int32_t)(HAL_GetTick() - last_state_sent) >= 200) {
|
||||
send_state();
|
||||
last_state_sent = HAL_GetTick();
|
||||
}
|
||||
@@ -123,7 +217,7 @@ void CCS_SerialLoop(void) {
|
||||
if (((CONN.connControl == CMD_STOP) ||
|
||||
(CONN.connControl == CMD_FORCE_UNLOCK) ||
|
||||
(CONN.chargingError != CONN_NO_ERROR)) &&
|
||||
((HAL_GetTick() - last_stop_sent) > 1000)) {
|
||||
((int32_t)(HAL_GetTick() - last_stop_sent) > 1000)) {
|
||||
last_stop_sent = HAL_GetTick();
|
||||
log_printf(LOG_WARN, "Stopping charging...\n");
|
||||
if (CONN.connControl == CMD_FORCE_UNLOCK) {
|
||||
@@ -133,7 +227,7 @@ void CCS_SerialLoop(void) {
|
||||
}
|
||||
|
||||
if (((CCS_EvseState == FinishedEV) || (CCS_EvseState == FinishedEVSE)) &&
|
||||
((HAL_GetTick() - last_stop_sent) > 1000)) {
|
||||
((int32_t)(HAL_GetTick() - last_stop_sent) > 1000)) {
|
||||
last_stop_sent = HAL_GetTick();
|
||||
log_printf(LOG_WARN, "FinishedEV, stopping...\n");
|
||||
CCS_SendEmergencyStop();
|
||||
@@ -143,99 +237,109 @@ void CCS_SerialLoop(void) {
|
||||
(void)replug_watchdog_tick;
|
||||
(void)replug_watchdog1_tick;
|
||||
|
||||
uint8_t host_timed_out = (last_host_seen > 0 && (HAL_GetTick() - last_host_seen) > 5000u);
|
||||
uint8_t has_charging_error = 0;//(CONN.chargingError != CONN_NO_ERROR);
|
||||
uint8_t host_timeout_warn = (last_host_seen > 0u) && ((int32_t)(HAL_GetTick() - last_host_seen) > (int32_t)EVEREST_TIMEOUT_WARN_MS);
|
||||
uint8_t host_timeout_stop = (last_host_seen > 0u) && ((int32_t)(HAL_GetTick() - last_host_seen) > (int32_t)EVEREST_TIMEOUT_STOP_MS);
|
||||
uint8_t host_timed_out = host_timeout_stop;
|
||||
|
||||
if (host_timeout_warn && !everest_timeout_warn_latched) {
|
||||
log_printf(LOG_ERR, "Everest timeout\n");
|
||||
everest_timeout_warn_latched = 1;
|
||||
}
|
||||
|
||||
if (host_timeout_stop && !everest_timeout_stop_latched) {
|
||||
log_printf(LOG_ERR, "Everest timeout, stopping charging...\n");
|
||||
everest_timeout_stop_latched = 1;
|
||||
}
|
||||
|
||||
if (!host_timeout_warn) {
|
||||
everest_timeout_warn_latched = 0;
|
||||
everest_timeout_stop_latched = 0;
|
||||
}
|
||||
|
||||
everest_timed_out = host_timeout_stop;
|
||||
switch(CCS_ConnectorState){
|
||||
case CCS_UNKNOWN:
|
||||
RELAY_Write(RELAY_CP, 0);
|
||||
CONN_SetState(Unknown);
|
||||
if (config_initialized && !host_timed_out) {
|
||||
CCS_ConnectorState = CCS_UNPLUGGED;
|
||||
}
|
||||
break;
|
||||
case CCS_DISABLED:
|
||||
RELAY_Write(RELAY_CP, 0);
|
||||
CONN_SetState(Disabled);
|
||||
if ((CONN.chargingError == CONN_NO_ERROR) && !host_timed_out){
|
||||
CCS_ConnectorState = CCS_UNPLUGGED;
|
||||
}
|
||||
break;
|
||||
case CCS_UNPLUGGED:
|
||||
RELAY_Write(RELAY_CP, 1);
|
||||
CONN_SetState(Unplugged);
|
||||
if ((cp_state_buffer == EV_STATE_B_CONN_PREP) || (cp_state_buffer == EV_STATE_C_CONN_ACTIVE)){
|
||||
CCS_ConnectorState = CCS_AUTH_REQUIRED;
|
||||
}
|
||||
if (CONN.chargingError != CONN_NO_ERROR){
|
||||
log_printf(LOG_ERR, "Charging error %d, state -> disabled\n", CONN.chargingError);
|
||||
CCS_ConnectorState = CCS_DISABLED;
|
||||
}
|
||||
|
||||
break;
|
||||
case CCS_AUTH_REQUIRED:
|
||||
RELAY_Write(RELAY_CP, 1);
|
||||
CONN_SetState(AuthRequired);
|
||||
if(CONN.connControl == CMD_START){
|
||||
log_printf(LOG_INFO, "Charging permitted, start charging\n");
|
||||
CCS_ConnectorState = CCS_CONNECTED;
|
||||
}
|
||||
if (cp_state_buffer == EV_STATE_A_IDLE){
|
||||
log_printf(LOG_INFO, "Car unplugged\n");
|
||||
CCS_ConnectorState = CCS_UNPLUGGED;
|
||||
}
|
||||
break;
|
||||
case CCS_CONNECTED:
|
||||
RELAY_Write(RELAY_CP, 1);
|
||||
if(CCS_EvseState < Preparing) {
|
||||
CONN_SetState(Preparing);
|
||||
} else {
|
||||
CONN_SetState(CCS_EvseState);
|
||||
}
|
||||
if (cp_state_buffer == EV_STATE_A_IDLE){
|
||||
log_printf(LOG_INFO, "Car unplugged\n");
|
||||
CCS_ConnectorState = CCS_UNPLUGGED;
|
||||
}
|
||||
if(REPLUG > 0){
|
||||
log_printf(LOG_INFO, "Replugging...\n");
|
||||
CCS_ConnectorState = CCS_REPLUGGING;
|
||||
}
|
||||
break;
|
||||
case CCS_REPLUGGING:
|
||||
RELAY_Write(RELAY_CP, 0);
|
||||
CONN_SetState(Replugging);
|
||||
if((HAL_GetTick() - replug_tick) > 1000){
|
||||
replug_tick = HAL_GetTick();
|
||||
if(REPLUG > 0){
|
||||
if (REPLUG != 0xFF) REPLUG--;
|
||||
} else {
|
||||
log_printf(LOG_INFO, "Replugging finished, but car unplugged\n");
|
||||
case CCS_UNKNOWN:
|
||||
RELAY_Write(RELAY_CP, 0);
|
||||
CONN_SetState(Unknown);
|
||||
if (config_initialized && !host_timed_out) {
|
||||
CCS_ConnectorState = CCS_UNPLUGGED;
|
||||
}
|
||||
}
|
||||
|
||||
if(REPLUG == 0){
|
||||
if(cp_state_buffer == EV_STATE_B_CONN_PREP){
|
||||
log_printf(LOG_INFO, "Replugging finished, car plugged, state -> auth required\n");
|
||||
break;
|
||||
case CCS_DISABLED:
|
||||
RELAY_Write(RELAY_CP, 0);
|
||||
CONN_SetState(Disabled);
|
||||
if ((CONN.chargingError == CONN_NO_ERROR) && !host_timed_out){
|
||||
CCS_ConnectorState = CCS_UNPLUGGED;
|
||||
}
|
||||
break;
|
||||
case CCS_UNPLUGGED:
|
||||
RELAY_Write(RELAY_CP, 1);
|
||||
CONN_SetState(Unplugged);
|
||||
if ((cp_state_buffer == EV_STATE_B_CONN_PREP) || (cp_state_buffer == EV_STATE_C_CONN_ACTIVE)){
|
||||
CCS_ConnectorState = CCS_AUTH_REQUIRED;
|
||||
}
|
||||
}
|
||||
break;
|
||||
if (CONN.chargingError != CONN_NO_ERROR){
|
||||
log_printf(LOG_ERR, "Charging error %d, state -> disabled\n", CONN.chargingError);
|
||||
CCS_ConnectorState = CCS_DISABLED;
|
||||
}
|
||||
|
||||
break;
|
||||
case CCS_AUTH_REQUIRED:
|
||||
RELAY_Write(RELAY_CP, 1);
|
||||
CONN_SetState(AuthRequired);
|
||||
if(CONN.connControl == CMD_START){
|
||||
log_printf(LOG_INFO, "Charging permitted, start charging\n");
|
||||
CCS_ConnectorState = CCS_CONNECTED;
|
||||
}
|
||||
if (cp_state_buffer == EV_STATE_A_IDLE){
|
||||
log_printf(LOG_INFO, "Car unplugged\n");
|
||||
CCS_ConnectorState = CCS_UNPLUGGED;
|
||||
}
|
||||
break;
|
||||
case CCS_CONNECTED:
|
||||
RELAY_Write(RELAY_CP, 1);
|
||||
if((CCS_EvseState < Preparing) || (CCS_EvseState == AuthRequired)) {
|
||||
CONN_SetState(Preparing);
|
||||
} else {
|
||||
CONN_SetState(CCS_EvseState);
|
||||
}
|
||||
if (cp_state_buffer == EV_STATE_A_IDLE){
|
||||
log_printf(LOG_INFO, "Car unplugged\n");
|
||||
CCS_ConnectorState = CCS_UNPLUGGED;
|
||||
}
|
||||
if(REPLUG > 0){
|
||||
log_printf(LOG_INFO, "Replugging...\n");
|
||||
CCS_ConnectorState = CCS_REPLUGGING;
|
||||
}
|
||||
break;
|
||||
case CCS_REPLUGGING:
|
||||
RELAY_Write(RELAY_CP, 0);
|
||||
CONN_SetState(Replugging);
|
||||
if((int32_t)(HAL_GetTick() - replug_tick) > 1000){
|
||||
replug_tick = HAL_GetTick();
|
||||
if(REPLUG > 0){
|
||||
if (REPLUG != 0xFF) REPLUG--;
|
||||
} else {
|
||||
log_printf(LOG_INFO, "Replugging finished, but car unplugged\n");
|
||||
CCS_ConnectorState = CCS_UNPLUGGED;
|
||||
}
|
||||
}
|
||||
|
||||
if(REPLUG == 0){
|
||||
if(cp_state_buffer == EV_STATE_B_CONN_PREP){
|
||||
log_printf(LOG_INFO, "Replugging finished, car plugged, state -> auth required\n");
|
||||
CCS_ConnectorState = CCS_AUTH_REQUIRED;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (has_charging_error &&
|
||||
CCS_ConnectorState != CCS_DISABLED &&
|
||||
CCS_ConnectorState != CCS_UNKNOWN) {
|
||||
log_printf(LOG_ERR, "Charging error %d, state -> disabled\n", CONN.chargingError);
|
||||
CCS_ConnectorState = CCS_DISABLED;
|
||||
}
|
||||
|
||||
if (host_timed_out) {
|
||||
// 10s timeout: enforce safe-state until host communication recovers.
|
||||
if (host_timeout_stop) {
|
||||
CONN.EnableOutput = 0;
|
||||
CCS_EvseState = Unknown;
|
||||
CP_SetDuty(100);
|
||||
if (CCS_ConnectorState != CCS_DISABLED && CCS_ConnectorState != CCS_UNKNOWN) {
|
||||
log_printf(LOG_ERR, "Everest timeout\n");
|
||||
CCS_ConnectorState = CCS_DISABLED;
|
||||
}
|
||||
} else {
|
||||
@@ -266,11 +370,14 @@ void CCS_Init(void){
|
||||
CCS_MaxLoad.maxCurrent = PSU_MAX_CURRENT*10; //100A
|
||||
CCS_MaxLoad.minCurrent = PSU_MIN_CURRENT*10; //1A
|
||||
CCS_MaxLoad.maxPower = PSU_MAX_POWER; //30000W
|
||||
uart3_last_packet_tick = HAL_GetTick();
|
||||
uart3_last_reinit_tick = uart3_last_packet_tick;
|
||||
uart3_arm_rx_or_log("Init");
|
||||
CCS_SendResetReason();
|
||||
log_printf(LOG_INFO, "CCS init\n");
|
||||
}
|
||||
|
||||
static uint16_t crc16_ibm(const uint8_t* data, uint16_t length) {
|
||||
ISR_FAST static uint16_t crc16_ibm(const uint8_t* data, uint16_t length) {
|
||||
uint16_t crc = 0xFFFFu;
|
||||
for (uint16_t i = 0; i < length; i++) {
|
||||
crc ^= data[i];
|
||||
@@ -304,7 +411,16 @@ static uint16_t CCS_BuildPacket(uint8_t cmd, const void* payload, uint16_t paylo
|
||||
static void CCS_SendPacket(uint8_t cmd, const void* payload, uint16_t payload_len) {
|
||||
uint16_t len = CCS_BuildPacket(cmd, payload, payload_len, tx_buffer, sizeof(tx_buffer));
|
||||
if (len > 0) {
|
||||
HAL_UART_Transmit(&huart3, tx_buffer, len, 1000);
|
||||
if (uart3_tx_busy) {
|
||||
memcpy(tx_pending_buffer, tx_buffer, len);
|
||||
tx_pending_len = len;
|
||||
} else {
|
||||
uart3_tx_busy = 1;
|
||||
if (HAL_UART_Transmit_DMA(&huart3, tx_buffer, len) != HAL_OK) {
|
||||
uart3_tx_busy = 0;
|
||||
CCS_LogUart3Error("UART3 TX DMA start failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
last_cmd_sent = HAL_GetTick();
|
||||
}
|
||||
@@ -366,7 +482,7 @@ static void send_state(void) {
|
||||
CCS_SendPacket(CMD_M2E_STATE, &CCS_State, sizeof(CCS_State));
|
||||
}
|
||||
|
||||
static uint16_t expected_payload_len(uint8_t cmd) {
|
||||
ISR_FAST static uint16_t expected_payload_len(uint8_t cmd) {
|
||||
switch (cmd) {
|
||||
case CMD_E2M_PWM_DUTY: return sizeof(e2m_pwm_duty_t);
|
||||
case CMD_E2M_ENABLE_OUTPUT: return sizeof(e2m_enable_output_t);
|
||||
@@ -382,9 +498,12 @@ static uint16_t expected_payload_len(uint8_t cmd) {
|
||||
}
|
||||
}
|
||||
|
||||
static void apply_command(uint8_t cmd, const uint8_t* payload, uint16_t payload_len) {
|
||||
ISR_FAST static void apply_command(uint8_t cmd, const uint8_t* payload, uint16_t payload_len) {
|
||||
(void)payload_len;
|
||||
last_host_seen = HAL_GetTick();
|
||||
everest_timed_out = 0;
|
||||
everest_timeout_warn_latched = 0;
|
||||
everest_timeout_stop_latched = 0;
|
||||
switch (cmd) {
|
||||
case CMD_E2M_PWM_DUTY: {
|
||||
const e2m_pwm_duty_t* p = (const e2m_pwm_duty_t*)payload;
|
||||
@@ -405,9 +524,9 @@ static void apply_command(uint8_t cmd, const uint8_t* payload, uint16_t payload_
|
||||
const e2m_reset_t* p = (const e2m_reset_t*)payload;
|
||||
if (p->reset) {
|
||||
log_printf(LOG_WARN, "Everest reset command\n");
|
||||
CCS_SendResetReason();
|
||||
HAL_Delay(10);
|
||||
NVIC_SystemReset();
|
||||
// CCS_SendResetReason();
|
||||
// HAL_Delay(10);
|
||||
// NVIC_SystemReset();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -454,32 +573,54 @@ static void apply_command(uint8_t cmd, const uint8_t* payload, uint16_t payload_
|
||||
break;
|
||||
}
|
||||
default:
|
||||
log_printf(LOG_WARN,
|
||||
"UART3 RX warn: cmd 0x%02x CRC/len OK but no switch case (expected_payload vs apply_command)\n",
|
||||
cmd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t process_received_packet(const uint8_t* packet, uint16_t packet_len) {
|
||||
if (packet_len < 3) return 0;
|
||||
ISR_FAST static uint8_t process_received_packet(const uint8_t* packet, uint16_t packet_len) {
|
||||
if (packet_len < 3u) {
|
||||
if (packet_len == 0u) {
|
||||
log_printf(LOG_WARN, "UART3 RX drop: too_short len=0 (empty chunk)\n");
|
||||
} else if (packet_len == 1u) {
|
||||
log_printf(LOG_WARN, "UART3 RX drop: too_short len=1 b0=0x%02x\n", packet[0]);
|
||||
} else {
|
||||
log_printf(LOG_WARN, "UART3 RX drop: too_short len=2 b0=0x%02x b1=0x%02x\n",
|
||||
packet[0], packet[1]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t cmd = packet[0];
|
||||
uint16_t payload_len = (uint16_t)(packet_len - 3);
|
||||
uint16_t payload_len = (uint16_t)(packet_len - 3u);
|
||||
|
||||
uint16_t received_crc = (uint16_t)packet[packet_len - 2u] |
|
||||
(uint16_t)packet[packet_len - 1u] << 8;
|
||||
|
||||
uint16_t calculated_crc = crc16_ibm(packet, (uint16_t)(1 + payload_len));
|
||||
uint16_t calculated_crc = crc16_ibm(packet, (uint16_t)(1u + payload_len));
|
||||
if (received_crc != calculated_crc) {
|
||||
log_printf(LOG_ERR, "Packet CRC error\n");
|
||||
log_printf(LOG_ERR,
|
||||
"UART3 RX drop: crc_mismatch cmd=0x%02x total_len=%u payload_len=%u "
|
||||
"crc_rx=0x%04x crc_calc=0x%04x\n",
|
||||
cmd, (unsigned)packet_len, (unsigned)payload_len,
|
||||
(unsigned)received_crc, (unsigned)calculated_crc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t expected_len = expected_payload_len(cmd);
|
||||
if (expected_len == 0xFFFF) {
|
||||
log_printf(LOG_WARN, "Unknown cmd 0x%02x\n", cmd);
|
||||
if (expected_len == 0xFFFFu) {
|
||||
log_printf(LOG_WARN,
|
||||
"UART3 RX drop: unknown_cmd cmd=0x%02x total_len=%u payload_len=%u\n",
|
||||
cmd, (unsigned)packet_len, (unsigned)payload_len);
|
||||
return 0;
|
||||
}
|
||||
if (expected_len != payload_len) {
|
||||
log_printf(LOG_ERR, "Packet len mismatch cmd=0x%02x\n", cmd);
|
||||
log_printf(LOG_ERR,
|
||||
"UART3 RX drop: len_mismatch cmd=0x%02x expected_payload=%u got_payload=%u "
|
||||
"total_len=%u\n",
|
||||
cmd, (unsigned)expected_len, (unsigned)payload_len, (unsigned)packet_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -492,3 +633,25 @@ static uint8_t process_received_packet(const uint8_t* packet, uint16_t packet_le
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void CCS_UART3_Watchdog(void) {
|
||||
const int32_t since_last_packet = (int32_t)(HAL_GetTick() - uart3_last_packet_tick);
|
||||
const int32_t since_last_reinit = (int32_t)(HAL_GetTick() - uart3_last_reinit_tick);
|
||||
|
||||
if ((since_last_packet >= (int32_t)UART3_REINIT_TIMEOUT_MS) &&
|
||||
(since_last_reinit >= (int32_t)UART3_REINIT_TIMEOUT_MS) &&
|
||||
(huart3.RxState == HAL_UART_STATE_READY)) {
|
||||
uart3_arm_rx_or_log("Watchdog");
|
||||
CCS_LogUart3Error("UART3 watchdog rearm");
|
||||
uart3_last_reinit_tick = HAL_GetTick();
|
||||
}
|
||||
}
|
||||
|
||||
static void CCS_LogUart3Error(const char *tag) {
|
||||
log_printf(LOG_ERR, "%s: err=0x%08lx g=%lu rx=%lu tx_busy=%u\n",
|
||||
tag,
|
||||
(unsigned long)HAL_UART_GetError(&huart3),
|
||||
(unsigned long)huart3.gState,
|
||||
(unsigned long)huart3.RxState,
|
||||
(unsigned)uart3_tx_busy);
|
||||
}
|
||||
|
||||
|
||||
+134
-77
@@ -3,14 +3,17 @@
|
||||
#include "board.h"
|
||||
#include "serial.h"
|
||||
#include "debug.h"
|
||||
#include "isr_opt.h"
|
||||
|
||||
// Приватные функции
|
||||
static uint32_t calculate_crc32(const uint8_t* data, uint16_t length);
|
||||
static uint16_t encode_packet(const uint8_t* payload, uint16_t payload_len, uint8_t* output, uint8_t response_code);
|
||||
static uint8_t parse_packet(const uint8_t* packet_data, uint16_t packet_len, ReceivedCommand_t* out_cmd);
|
||||
static uint8_t process_received_packet(SerialControl_t *ctx, const uint8_t* packet_data, uint16_t packet_len);
|
||||
static void SC_ArmUart2Rx(void);
|
||||
static void SC_ArmUart5Rx(void);
|
||||
ISR_FAST static uint32_t calculate_crc32(const uint8_t* data, uint16_t length);
|
||||
ISR_FAST static uint16_t encode_packet(const uint8_t* payload, uint16_t payload_len, uint8_t* output, uint8_t response_code);
|
||||
ISR_FAST static uint8_t parse_packet(const uint8_t* packet_data, uint16_t packet_len, ReceivedCommand_t* out_cmd);
|
||||
ISR_FAST static uint8_t process_received_packet(SerialControl_t *ctx, const uint8_t* packet_data, uint16_t packet_len);
|
||||
static void SC_UART2_Watchdog(void);
|
||||
static void SC_ArmUart2RxDma(void);
|
||||
static void SC_ArmUart5RxDma(void);
|
||||
static void SC_LogUartError(const char *tag, UART_HandleTypeDef *huart);
|
||||
|
||||
uint8_t test_crc_invalid = 0;
|
||||
|
||||
@@ -18,6 +21,12 @@ SerialControl_t serial_control;
|
||||
// Контекст для приема пакетов по UART5 (однонаправленный UART)
|
||||
static SerialControl_t serial_iso;
|
||||
volatile SC_Source_t g_sc_command_source = SC_SOURCE_UART2;
|
||||
static volatile uint8_t sc_uart2_timed_out = 0;
|
||||
static uint32_t sc_uart2_last_packet_tick = 0;
|
||||
static uint32_t sc_uart2_last_recover_tick = 0;
|
||||
|
||||
#define SC_UART2_RECOVER_GUARD_MS 200u
|
||||
#define SC_UART2_PACKET_TIMEOUT_MS 5000u
|
||||
|
||||
StatusPacket_t statusPacket = {
|
||||
.SOC = 0,
|
||||
@@ -75,100 +84,83 @@ void SC_Init() {
|
||||
// Обнуляем структуру
|
||||
memset(&serial_control, 0, sizeof(SerialControl_t));
|
||||
memset(&serial_iso, 0, sizeof(serial_iso));
|
||||
sc_uart2_timed_out = 0;
|
||||
sc_uart2_last_packet_tick = HAL_GetTick();
|
||||
sc_uart2_last_recover_tick = sc_uart2_last_packet_tick;
|
||||
SC_ArmUart2RxDma();
|
||||
SC_ArmUart5RxDma();
|
||||
}
|
||||
|
||||
void SC_Task() {
|
||||
// Запуск приема в режиме прерывания с ожиданием idle
|
||||
SC_ArmUart2Rx();
|
||||
SC_ArmUart5Rx();
|
||||
static uint32_t tick;
|
||||
if ((int32_t)(HAL_GetTick() - tick) < 1) return;
|
||||
tick = HAL_GetTick();
|
||||
SC_UART2_Watchdog();
|
||||
|
||||
// Запуск приема в режиме DMA + idle
|
||||
SC_ArmUart2RxDma();
|
||||
SC_ArmUart5RxDma();
|
||||
|
||||
// Проверка таймаута отправки пакета (больше 100 мс)
|
||||
if (huart2.gState == HAL_UART_STATE_BUSY_TX && serial_control.tx_tick != 0) {
|
||||
if ((HAL_GetTick() - serial_control.tx_tick) > 100) {
|
||||
if ((int32_t)(HAL_GetTick() - serial_control.tx_tick) > 100) {
|
||||
// Таймаут: принудительно сбрасываем передачу
|
||||
HAL_UART_Abort_IT(&huart2);
|
||||
// Выключаем DIR при сбросе передачи
|
||||
HAL_GPIO_WritePin(USART2_DIR_GPIO_Port, USART2_DIR_Pin, GPIO_PIN_RESET);
|
||||
(void)HAL_UART_AbortTransmit(&huart2);
|
||||
serial_control.tx_tick = 0; // Сбрасываем tick
|
||||
}
|
||||
}
|
||||
|
||||
// Проверка наличия принятой команды для обработки
|
||||
if (serial_control.command_ready && (huart2.gState != HAL_UART_STATE_BUSY_TX)) {
|
||||
g_sc_command_source = SC_SOURCE_UART2;
|
||||
SC_CommandHandler(&serial_control.received_command);
|
||||
// HAL_Delay(2);
|
||||
SC_CommandHandler((ReceivedCommand_t*)&serial_control.received_command);
|
||||
serial_control.command_ready = 0; // Сбрасываем флаг
|
||||
SC_ArmUart2Rx();
|
||||
}
|
||||
|
||||
if (serial_control.response_pending && (huart2.gState != HAL_UART_STATE_BUSY_TX)) {
|
||||
SC_SendPacket(NULL, 0, serial_control.response_code);
|
||||
serial_control.response_pending = 0;
|
||||
}
|
||||
|
||||
if (serial_iso.command_ready) {
|
||||
g_sc_command_source = SC_SOURCE_UART5;
|
||||
SC_CommandHandler((ReceivedCommand_t*)&serial_iso.received_command);
|
||||
serial_iso.command_ready = 0;
|
||||
SC_ArmUart5Rx();
|
||||
SC_ArmUart2RxDma();
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) {
|
||||
ISR_FAST void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) {
|
||||
if (huart->Instance == huart2.Instance) {
|
||||
if (!process_received_packet(&serial_control, serial_control.rx_buffer, Size)) {
|
||||
serial_control.response_pending = 1;
|
||||
serial_control.response_code = RESP_INVALID;
|
||||
SC_ArmUart2Rx();
|
||||
if (Size == 0u) {
|
||||
log_printf(LOG_WARN, "UART2 RX idle event with zero size\n");
|
||||
}
|
||||
sc_uart2_last_packet_tick = HAL_GetTick();
|
||||
sc_uart2_last_recover_tick = sc_uart2_last_packet_tick;
|
||||
sc_uart2_timed_out = 0;
|
||||
if(!process_received_packet(&serial_control, serial_control.rx_buffer, Size)){
|
||||
log_printf(LOG_WARN, "UART2 RX invalid packet len=%u\n", (unsigned)Size);
|
||||
SC_SendPacket(NULL, 0, RESP_INVALID);
|
||||
}
|
||||
g_sc_command_source = SC_SOURCE_UART2;
|
||||
SC_ArmUart2RxDma();
|
||||
} else if (huart->Instance == huart5.Instance) {
|
||||
if (!process_received_packet(&serial_iso, serial_iso.rx_buffer, Size)) {
|
||||
SC_ArmUart5Rx();
|
||||
if (Size == 0u) {
|
||||
log_printf(LOG_WARN, "UART5 RX idle event with zero size\n");
|
||||
}
|
||||
if (process_received_packet(&serial_iso, serial_iso.rx_buffer, Size)) {
|
||||
g_sc_command_source = SC_SOURCE_UART5;
|
||||
SC_CommandHandler((ReceivedCommand_t*)&serial_iso.received_command);
|
||||
} else {
|
||||
log_printf(LOG_WARN, "UART5 RX invalid packet len=%u\n", (unsigned)Size);
|
||||
}
|
||||
SC_ArmUart5RxDma();
|
||||
} else if (huart->Instance == huart3.Instance) {
|
||||
CCS_RxEventCallback(huart, Size);
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) {
|
||||
ISR_FAST void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
|
||||
if (huart->Instance == huart2.Instance) {
|
||||
uint32_t uart_error = HAL_UART_GetError(huart);
|
||||
log_printf(LOG_WARN, "USART2 rx error: 0x%08lx\n", uart_error);
|
||||
SC_ArmUart2Rx();
|
||||
} else if (huart->Instance == huart5.Instance) {
|
||||
uint32_t uart_error = HAL_UART_GetError(huart);
|
||||
log_printf(LOG_WARN, "UART5 rx error: 0x%08lx\n", uart_error);
|
||||
SC_ArmUart5Rx();
|
||||
} else if (huart->Instance == huart3.Instance) {
|
||||
uint32_t uart_error = HAL_UART_GetError(huart);
|
||||
log_printf(LOG_WARN, "USART3 rx error: 0x%08lx\n", uart_error);
|
||||
CCS_RxArm();
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
|
||||
if (huart->Instance == huart2.Instance) {
|
||||
HAL_GPIO_WritePin(USART2_DIR_GPIO_Port, USART2_DIR_Pin, GPIO_PIN_RESET);
|
||||
serial_control.tx_tick = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void SC_ArmUart2Rx(void) {
|
||||
if ((&huart2)->RxState == HAL_UART_STATE_READY && serial_control.command_ready == 0) {
|
||||
(void)HAL_UARTEx_ReceiveToIdle_IT(&huart2, serial_control.rx_buffer, MAX_RX_BUFFER_SIZE - 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void SC_ArmUart5Rx(void) {
|
||||
if ((&huart5)->RxState == HAL_UART_STATE_READY && serial_iso.command_ready == 0) {
|
||||
(void)HAL_UARTEx_ReceiveToIdle_IT(&huart5, serial_iso.rx_buffer, MAX_RX_BUFFER_SIZE - 1);
|
||||
} else if (huart->Instance == huart3.Instance) {
|
||||
CCS_TxCpltCallback(huart);
|
||||
}
|
||||
}
|
||||
|
||||
// Приватные функции реализации
|
||||
|
||||
// Полностью программная реализация CRC-32 (полином CRC32_POLYNOMIAL, порядок little-endian)
|
||||
static uint32_t calculate_crc32(const uint8_t* data, uint16_t length) {
|
||||
ISR_FAST static uint32_t calculate_crc32(const uint8_t* data, uint16_t length) {
|
||||
uint32_t crc = 0xFFFFFFFFu;
|
||||
|
||||
for (uint16_t i = 0; i < length; i++) {
|
||||
@@ -185,7 +177,7 @@ static uint32_t calculate_crc32(const uint8_t* data, uint16_t length) {
|
||||
return crc ^ 0xFFFFFFFFu;
|
||||
}
|
||||
|
||||
static uint16_t encode_packet(const uint8_t* payload, uint16_t payload_len, uint8_t* output, uint8_t response_code) {
|
||||
ISR_FAST static uint16_t encode_packet(const uint8_t* payload, uint16_t payload_len, uint8_t* output, uint8_t response_code) {
|
||||
uint16_t out_index = 0;
|
||||
|
||||
output[out_index++] = response_code;
|
||||
@@ -218,24 +210,24 @@ static uint16_t encode_packet(const uint8_t* payload, uint16_t payload_len, uint
|
||||
return out_index;
|
||||
}
|
||||
|
||||
void SC_SendPacket(const uint8_t* payload, uint16_t payload_len, uint8_t response_code) {
|
||||
ISR_FAST void SC_SendPacket(const uint8_t* payload, uint16_t payload_len, uint8_t response_code) {
|
||||
uint16_t packet_len = encode_packet(payload, payload_len, serial_control.tx_buffer, response_code);
|
||||
|
||||
if (packet_len > 0) {
|
||||
if (huart2.gState == HAL_UART_STATE_BUSY_TX) {
|
||||
HAL_UART_Abort_IT(&huart2);
|
||||
HAL_GPIO_WritePin(USART2_DIR_GPIO_Port, USART2_DIR_Pin, GPIO_PIN_RESET);
|
||||
if (huart2.gState != HAL_UART_STATE_READY) {
|
||||
(void)HAL_UART_AbortTransmit(&huart2);
|
||||
log_printf(LOG_WARN, "UART2 TX busy, abort transmit before resend\n");
|
||||
}
|
||||
if (HAL_UART_Transmit_DMA(&huart2, serial_control.tx_buffer, packet_len) != HAL_OK) {
|
||||
SC_LogUartError("UART2 TX DMA start failed", &huart2);
|
||||
return;
|
||||
}
|
||||
|
||||
HAL_GPIO_WritePin(USART2_DIR_GPIO_Port, USART2_DIR_Pin, GPIO_PIN_SET);
|
||||
|
||||
HAL_UART_Transmit_IT(&huart2, serial_control.tx_buffer, packet_len);
|
||||
|
||||
serial_control.tx_tick = HAL_GetTick();
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t parse_packet(const uint8_t* packet_data, uint16_t packet_len, ReceivedCommand_t* out_cmd) {
|
||||
ISR_FAST static uint8_t parse_packet(const uint8_t* packet_data, uint16_t packet_len, ReceivedCommand_t* out_cmd) {
|
||||
// if (test_crc_invalid && (packet_data[1] != CMD_GET_STATUS)) {
|
||||
// test_crc_invalid--;
|
||||
// return 0;
|
||||
@@ -268,7 +260,7 @@ static uint8_t parse_packet(const uint8_t* packet_data, uint16_t packet_len, Rec
|
||||
return 1;
|
||||
}
|
||||
|
||||
static uint8_t process_received_packet(SerialControl_t *ctx, const uint8_t* packet_data, uint16_t packet_len) {
|
||||
ISR_FAST static uint8_t process_received_packet(SerialControl_t *ctx, const uint8_t* packet_data, uint16_t packet_len) {
|
||||
if (!parse_packet(packet_data, packet_len, (ReceivedCommand_t *)&ctx->received_command)) {
|
||||
return 0;
|
||||
}
|
||||
@@ -277,3 +269,68 @@ static uint8_t process_received_packet(SerialControl_t *ctx, const uint8_t* pack
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void SC_UART2_Watchdog(void) {
|
||||
const uint32_t now = HAL_GetTick();
|
||||
const int32_t since_last_packet = (int32_t)(now - sc_uart2_last_packet_tick);
|
||||
|
||||
if (since_last_packet >= (int32_t)SC_UART2_PACKET_TIMEOUT_MS) {
|
||||
if (sc_uart2_timed_out == 0u) {
|
||||
serial_control.command_ready = 0;
|
||||
log_printf(LOG_WARN, "UART2 RX packet timeout (%u ms)\n", (unsigned)SC_UART2_PACKET_TIMEOUT_MS);
|
||||
}
|
||||
sc_uart2_timed_out = 1;
|
||||
} else {
|
||||
sc_uart2_timed_out = 0;
|
||||
}
|
||||
|
||||
if ((huart2.RxState == HAL_UART_STATE_READY) &&
|
||||
((int32_t)(now - sc_uart2_last_recover_tick) >= (int32_t)SC_UART2_RECOVER_GUARD_MS)) {
|
||||
SC_ArmUart2RxDma();
|
||||
sc_uart2_last_recover_tick = now;
|
||||
}
|
||||
}
|
||||
|
||||
static void SC_ArmUart2RxDma(void) {
|
||||
if ((huart2.RxState == HAL_UART_STATE_READY) && (serial_control.command_ready == 0)) {
|
||||
if (HAL_UARTEx_ReceiveToIdle_DMA(&huart2, serial_control.rx_buffer, MAX_RX_BUFFER_SIZE - 1) != HAL_OK) {
|
||||
SC_LogUartError("UART2 RX DMA arm failed", &huart2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void SC_ArmUart5RxDma(void) {
|
||||
if (huart5.RxState == HAL_UART_STATE_READY) {
|
||||
if (HAL_UARTEx_ReceiveToIdle_IT(&huart5, serial_iso.rx_buffer, MAX_RX_BUFFER_SIZE - 1) == HAL_OK) {
|
||||
return;
|
||||
}
|
||||
SC_LogUartError("UART5 RX IT arm failed", &huart5);
|
||||
}
|
||||
}
|
||||
|
||||
void SC_RecoverUartDma(UART_HandleTypeDef *huart) {
|
||||
if (huart == &huart2) {
|
||||
SC_LogUartError("UART2 recover start", &huart2);
|
||||
(void)HAL_UART_AbortReceive(&huart2);
|
||||
(void)HAL_UART_AbortTransmit(&huart2);
|
||||
serial_control.tx_tick = 0;
|
||||
SC_ArmUart2RxDma();
|
||||
sc_uart2_last_recover_tick = HAL_GetTick();
|
||||
} else if (huart == &huart5) {
|
||||
SC_LogUartError("UART5 recover start", &huart5);
|
||||
(void)HAL_UART_AbortReceive(&huart5);
|
||||
SC_ArmUart5RxDma();
|
||||
}
|
||||
}
|
||||
|
||||
static void SC_LogUartError(const char *tag, UART_HandleTypeDef *huart) {
|
||||
if (tag == NULL || huart == NULL) {
|
||||
return;
|
||||
}
|
||||
log_printf(LOG_ERR, "%s: instance=0x%08lx err=0x%08lx g=%lu rx=%lu\n",
|
||||
tag,
|
||||
(unsigned long)huart->Instance,
|
||||
(unsigned long)HAL_UART_GetError(huart),
|
||||
(unsigned long)huart->gState,
|
||||
(unsigned long)huart->RxState);
|
||||
}
|
||||
|
||||
|
||||
+107
-14
@@ -22,6 +22,9 @@
|
||||
#include "stm32f1xx_it.h"
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC optimize("Ofast")
|
||||
#endif
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
@@ -55,9 +58,15 @@
|
||||
/* USER CODE END 0 */
|
||||
|
||||
/* External variables --------------------------------------------------------*/
|
||||
extern DMA_HandleTypeDef hdma_adc1;
|
||||
extern ADC_HandleTypeDef hadc1;
|
||||
extern CAN_HandleTypeDef hcan1;
|
||||
extern CAN_HandleTypeDef hcan2;
|
||||
extern TIM_HandleTypeDef htim3;
|
||||
extern DMA_HandleTypeDef hdma_usart2_rx;
|
||||
extern DMA_HandleTypeDef hdma_usart2_tx;
|
||||
extern DMA_HandleTypeDef hdma_usart3_rx;
|
||||
extern DMA_HandleTypeDef hdma_usart3_tx;
|
||||
extern UART_HandleTypeDef huart5;
|
||||
extern UART_HandleTypeDef huart1;
|
||||
extern UART_HandleTypeDef huart2;
|
||||
@@ -204,17 +213,101 @@ void SysTick_Handler(void)
|
||||
/* please refer to the startup file (startup_stm32f1xx.s). */
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief This function handles DMA1 channel1 global interrupt.
|
||||
*/
|
||||
void DMA1_Channel1_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN DMA1_Channel1_IRQn 0 */
|
||||
HAL_GPIO_WritePin(DBG4_GPIO_Port, DBG4_Pin, GPIO_PIN_SET);
|
||||
/* USER CODE END DMA1_Channel1_IRQn 0 */
|
||||
HAL_DMA_IRQHandler(&hdma_adc1);
|
||||
/* USER CODE BEGIN DMA1_Channel1_IRQn 1 */
|
||||
HAL_GPIO_WritePin(DBG4_GPIO_Port, DBG4_Pin, GPIO_PIN_RESET);
|
||||
/* USER CODE END DMA1_Channel1_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles DMA1 channel2 global interrupt.
|
||||
*/
|
||||
void DMA1_Channel2_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN DMA1_Channel2_IRQn 0 */
|
||||
|
||||
/* USER CODE END DMA1_Channel2_IRQn 0 */
|
||||
HAL_DMA_IRQHandler(&hdma_usart3_tx);
|
||||
/* USER CODE BEGIN DMA1_Channel2_IRQn 1 */
|
||||
|
||||
/* USER CODE END DMA1_Channel2_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles DMA1 channel3 global interrupt.
|
||||
*/
|
||||
void DMA1_Channel3_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN DMA1_Channel3_IRQn 0 */
|
||||
|
||||
/* USER CODE END DMA1_Channel3_IRQn 0 */
|
||||
HAL_DMA_IRQHandler(&hdma_usart3_rx);
|
||||
/* USER CODE BEGIN DMA1_Channel3_IRQn 1 */
|
||||
|
||||
/* USER CODE END DMA1_Channel3_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles DMA1 channel6 global interrupt.
|
||||
*/
|
||||
void DMA1_Channel6_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN DMA1_Channel6_IRQn 0 */
|
||||
|
||||
/* USER CODE END DMA1_Channel6_IRQn 0 */
|
||||
HAL_DMA_IRQHandler(&hdma_usart2_rx);
|
||||
/* USER CODE BEGIN DMA1_Channel6_IRQn 1 */
|
||||
|
||||
/* USER CODE END DMA1_Channel6_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles DMA1 channel7 global interrupt.
|
||||
*/
|
||||
void DMA1_Channel7_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN DMA1_Channel7_IRQn 0 */
|
||||
|
||||
/* USER CODE END DMA1_Channel7_IRQn 0 */
|
||||
HAL_DMA_IRQHandler(&hdma_usart2_tx);
|
||||
/* USER CODE BEGIN DMA1_Channel7_IRQn 1 */
|
||||
|
||||
/* USER CODE END DMA1_Channel7_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles ADC1 and ADC2 global interrupts.
|
||||
*/
|
||||
void ADC1_2_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN ADC1_2_IRQn 0 */
|
||||
HAL_GPIO_WritePin(DBG4_GPIO_Port, DBG4_Pin, GPIO_PIN_SET);
|
||||
/* USER CODE END ADC1_2_IRQn 0 */
|
||||
HAL_ADC_IRQHandler(&hadc1);
|
||||
/* USER CODE BEGIN ADC1_2_IRQn 1 */
|
||||
HAL_GPIO_WritePin(DBG4_GPIO_Port, DBG4_Pin, GPIO_PIN_RESET);
|
||||
/* USER CODE END ADC1_2_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles CAN1 RX0 interrupt.
|
||||
*/
|
||||
void CAN1_RX0_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN CAN1_RX0_IRQn 0 */
|
||||
|
||||
HAL_GPIO_WritePin(DBG5_GPIO_Port, DBG5_Pin, GPIO_PIN_SET);
|
||||
/* USER CODE END CAN1_RX0_IRQn 0 */
|
||||
HAL_CAN_IRQHandler(&hcan1);
|
||||
/* USER CODE BEGIN CAN1_RX0_IRQn 1 */
|
||||
|
||||
HAL_GPIO_WritePin(DBG5_GPIO_Port, DBG5_Pin, GPIO_PIN_RESET);
|
||||
/* USER CODE END CAN1_RX0_IRQn 1 */
|
||||
}
|
||||
|
||||
@@ -224,11 +317,11 @@ void CAN1_RX0_IRQHandler(void)
|
||||
void TIM3_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN TIM3_IRQn 0 */
|
||||
|
||||
HAL_GPIO_WritePin(DBG4_GPIO_Port, DBG4_Pin, GPIO_PIN_SET);
|
||||
/* USER CODE END TIM3_IRQn 0 */
|
||||
HAL_TIM_IRQHandler(&htim3);
|
||||
/* USER CODE BEGIN TIM3_IRQn 1 */
|
||||
|
||||
HAL_GPIO_WritePin(DBG4_GPIO_Port, DBG4_Pin, GPIO_PIN_RESET);
|
||||
/* USER CODE END TIM3_IRQn 1 */
|
||||
}
|
||||
|
||||
@@ -252,11 +345,11 @@ void USART1_IRQHandler(void)
|
||||
void USART2_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN USART2_IRQn 0 */
|
||||
|
||||
HAL_GPIO_WritePin(DBG2_GPIO_Port, DBG2_Pin, GPIO_PIN_SET);
|
||||
/* USER CODE END USART2_IRQn 0 */
|
||||
HAL_UART_IRQHandler(&huart2);
|
||||
/* USER CODE BEGIN USART2_IRQn 1 */
|
||||
|
||||
HAL_GPIO_WritePin(DBG2_GPIO_Port, DBG2_Pin, GPIO_PIN_RESET);
|
||||
/* USER CODE END USART2_IRQn 1 */
|
||||
}
|
||||
|
||||
@@ -266,11 +359,11 @@ void USART2_IRQHandler(void)
|
||||
void USART3_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN USART3_IRQn 0 */
|
||||
|
||||
HAL_GPIO_WritePin(DBG3_GPIO_Port, DBG3_Pin, GPIO_PIN_SET);
|
||||
/* USER CODE END USART3_IRQn 0 */
|
||||
HAL_UART_IRQHandler(&huart3);
|
||||
/* USER CODE BEGIN USART3_IRQn 1 */
|
||||
|
||||
HAL_GPIO_WritePin(DBG3_GPIO_Port, DBG3_Pin, GPIO_PIN_RESET);
|
||||
/* USER CODE END USART3_IRQn 1 */
|
||||
}
|
||||
|
||||
@@ -280,11 +373,11 @@ void USART3_IRQHandler(void)
|
||||
void UART5_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN UART5_IRQn 0 */
|
||||
|
||||
HAL_GPIO_WritePin(DBG1_GPIO_Port, DBG1_Pin, GPIO_PIN_SET);
|
||||
/* USER CODE END UART5_IRQn 0 */
|
||||
HAL_UART_IRQHandler(&huart5);
|
||||
/* USER CODE BEGIN UART5_IRQn 1 */
|
||||
|
||||
HAL_GPIO_WritePin(DBG1_GPIO_Port, DBG1_Pin, GPIO_PIN_RESET);
|
||||
/* USER CODE END UART5_IRQn 1 */
|
||||
}
|
||||
|
||||
@@ -294,11 +387,11 @@ void UART5_IRQHandler(void)
|
||||
void CAN2_TX_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN CAN2_TX_IRQn 0 */
|
||||
|
||||
HAL_GPIO_WritePin(DBG5_GPIO_Port, DBG5_Pin, GPIO_PIN_SET);
|
||||
/* USER CODE END CAN2_TX_IRQn 0 */
|
||||
HAL_CAN_IRQHandler(&hcan2);
|
||||
/* USER CODE BEGIN CAN2_TX_IRQn 1 */
|
||||
|
||||
HAL_GPIO_WritePin(DBG5_GPIO_Port, DBG5_Pin, GPIO_PIN_RESET);
|
||||
/* USER CODE END CAN2_TX_IRQn 1 */
|
||||
}
|
||||
|
||||
@@ -308,11 +401,11 @@ void CAN2_TX_IRQHandler(void)
|
||||
void CAN2_RX1_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN CAN2_RX1_IRQn 0 */
|
||||
|
||||
HAL_GPIO_WritePin(DBG5_GPIO_Port, DBG5_Pin, GPIO_PIN_SET);
|
||||
/* USER CODE END CAN2_RX1_IRQn 0 */
|
||||
HAL_CAN_IRQHandler(&hcan2);
|
||||
/* USER CODE BEGIN CAN2_RX1_IRQn 1 */
|
||||
|
||||
HAL_GPIO_WritePin(DBG5_GPIO_Port, DBG5_Pin, GPIO_PIN_RESET);
|
||||
/* USER CODE END CAN2_RX1_IRQn 1 */
|
||||
}
|
||||
|
||||
|
||||
+12
-12
@@ -57,31 +57,31 @@ void MX_TIM3_Init(void)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
if (HAL_TIM_OC_Init(&htim3) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
|
||||
if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC1;
|
||||
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
|
||||
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sConfigOC.OCMode = TIM_OCMODE_PWM1;
|
||||
sConfigOC.Pulse = 0;
|
||||
sConfigOC.OCMode = TIM_OCMODE_TIMING;
|
||||
sConfigOC.Pulse = 1;
|
||||
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
|
||||
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
|
||||
if (HAL_TIM_OC_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sConfigOC.OCMode = TIM_OCMODE_TIMING;
|
||||
sConfigOC.Pulse = 1;
|
||||
if (HAL_TIM_OC_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
|
||||
sConfigOC.OCMode = TIM_OCMODE_PWM1;
|
||||
sConfigOC.Pulse = 0;
|
||||
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
@@ -166,7 +166,7 @@ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
|
||||
__HAL_RCC_TIM3_CLK_ENABLE();
|
||||
|
||||
/* TIM3 interrupt Init */
|
||||
HAL_NVIC_SetPriority(TIM3_IRQn, 0, 0);
|
||||
HAL_NVIC_SetPriority(TIM3_IRQn, 6, 0);
|
||||
HAL_NVIC_EnableIRQ(TIM3_IRQn);
|
||||
/* USER CODE BEGIN TIM3_MspInit 1 */
|
||||
|
||||
|
||||
+82
-4
@@ -28,6 +28,10 @@ UART_HandleTypeDef huart5;
|
||||
UART_HandleTypeDef huart1;
|
||||
UART_HandleTypeDef huart2;
|
||||
UART_HandleTypeDef huart3;
|
||||
DMA_HandleTypeDef hdma_usart2_rx;
|
||||
DMA_HandleTypeDef hdma_usart2_tx;
|
||||
DMA_HandleTypeDef hdma_usart3_rx;
|
||||
DMA_HandleTypeDef hdma_usart3_tx;
|
||||
|
||||
/* UART5 init function */
|
||||
void MX_UART5_Init(void)
|
||||
@@ -174,7 +178,7 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
|
||||
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
|
||||
|
||||
/* UART5 interrupt Init */
|
||||
HAL_NVIC_SetPriority(UART5_IRQn, 0, 0);
|
||||
HAL_NVIC_SetPriority(UART5_IRQn, 5, 0);
|
||||
HAL_NVIC_EnableIRQ(UART5_IRQn);
|
||||
/* USER CODE BEGIN UART5_MspInit 1 */
|
||||
|
||||
@@ -204,7 +208,7 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/* USART1 interrupt Init */
|
||||
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
|
||||
HAL_NVIC_SetPriority(USART1_IRQn, 5, 0);
|
||||
HAL_NVIC_EnableIRQ(USART1_IRQn);
|
||||
/* USER CODE BEGIN USART1_MspInit 1 */
|
||||
|
||||
@@ -235,8 +239,41 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
|
||||
|
||||
__HAL_AFIO_REMAP_USART2_ENABLE();
|
||||
|
||||
/* USART2 DMA Init */
|
||||
/* USART2_RX Init */
|
||||
hdma_usart2_rx.Instance = DMA1_Channel6;
|
||||
hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
|
||||
hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
|
||||
hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||
hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||
hdma_usart2_rx.Init.Mode = DMA_NORMAL;
|
||||
hdma_usart2_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
|
||||
if (HAL_DMA_Init(&hdma_usart2_rx) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
__HAL_LINKDMA(uartHandle,hdmarx,hdma_usart2_rx);
|
||||
|
||||
/* USART2_TX Init */
|
||||
hdma_usart2_tx.Instance = DMA1_Channel7;
|
||||
hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
|
||||
hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
|
||||
hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||
hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||
hdma_usart2_tx.Init.Mode = DMA_NORMAL;
|
||||
hdma_usart2_tx.Init.Priority = DMA_PRIORITY_HIGH;
|
||||
if (HAL_DMA_Init(&hdma_usart2_tx) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
__HAL_LINKDMA(uartHandle,hdmatx,hdma_usart2_tx);
|
||||
|
||||
/* USART2 interrupt Init */
|
||||
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
|
||||
HAL_NVIC_SetPriority(USART2_IRQn, 2, 0);
|
||||
HAL_NVIC_EnableIRQ(USART2_IRQn);
|
||||
/* USER CODE BEGIN USART2_MspInit 1 */
|
||||
|
||||
@@ -267,8 +304,41 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
|
||||
|
||||
__HAL_AFIO_REMAP_USART3_PARTIAL();
|
||||
|
||||
/* USART3 DMA Init */
|
||||
/* USART3_RX Init */
|
||||
hdma_usart3_rx.Instance = DMA1_Channel3;
|
||||
hdma_usart3_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
|
||||
hdma_usart3_rx.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
hdma_usart3_rx.Init.MemInc = DMA_MINC_ENABLE;
|
||||
hdma_usart3_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||
hdma_usart3_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||
hdma_usart3_rx.Init.Mode = DMA_NORMAL;
|
||||
hdma_usart3_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
|
||||
if (HAL_DMA_Init(&hdma_usart3_rx) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
__HAL_LINKDMA(uartHandle,hdmarx,hdma_usart3_rx);
|
||||
|
||||
/* USART3_TX Init */
|
||||
hdma_usart3_tx.Instance = DMA1_Channel2;
|
||||
hdma_usart3_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
|
||||
hdma_usart3_tx.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
hdma_usart3_tx.Init.MemInc = DMA_MINC_ENABLE;
|
||||
hdma_usart3_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
|
||||
hdma_usart3_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
|
||||
hdma_usart3_tx.Init.Mode = DMA_NORMAL;
|
||||
hdma_usart3_tx.Init.Priority = DMA_PRIORITY_HIGH;
|
||||
if (HAL_DMA_Init(&hdma_usart3_tx) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
__HAL_LINKDMA(uartHandle,hdmatx,hdma_usart3_tx);
|
||||
|
||||
/* USART3 interrupt Init */
|
||||
HAL_NVIC_SetPriority(USART3_IRQn, 0, 0);
|
||||
HAL_NVIC_SetPriority(USART3_IRQn, 2, 0);
|
||||
HAL_NVIC_EnableIRQ(USART3_IRQn);
|
||||
/* USER CODE BEGIN USART3_MspInit 1 */
|
||||
|
||||
@@ -335,6 +405,10 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOD, GPIO_PIN_5|GPIO_PIN_6);
|
||||
|
||||
/* USART2 DMA DeInit */
|
||||
HAL_DMA_DeInit(uartHandle->hdmarx);
|
||||
HAL_DMA_DeInit(uartHandle->hdmatx);
|
||||
|
||||
/* USART2 interrupt Deinit */
|
||||
HAL_NVIC_DisableIRQ(USART2_IRQn);
|
||||
/* USER CODE BEGIN USART2_MspDeInit 1 */
|
||||
@@ -355,6 +429,10 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_10|GPIO_PIN_11);
|
||||
|
||||
/* USART3 DMA DeInit */
|
||||
HAL_DMA_DeInit(uartHandle->hdmarx);
|
||||
HAL_DMA_DeInit(uartHandle->hdmatx);
|
||||
|
||||
/* USART3 interrupt Deinit */
|
||||
HAL_NVIC_DisableIRQ(USART3_IRQn);
|
||||
/* USER CODE BEGIN USART3_MspDeInit 1 */
|
||||
|
||||
@@ -59,7 +59,6 @@ defined in linker script */
|
||||
.weak Reset_Handler
|
||||
.type Reset_Handler, %function
|
||||
Reset_Handler:
|
||||
ldr sp, =_estack /* set stack pointer */
|
||||
|
||||
/* Call the clock system initialization function.*/
|
||||
bl SystemInit
|
||||
|
||||
Reference in New Issue
Block a user