Binary files /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/.DS_Store and /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/.DS_Store differ diff -ruN /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Inc/adc.h /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Inc/adc.h --- /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Inc/adc.h 2024-07-12 12:59:02 +++ /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Inc/adc.h 2026-05-04 19:45:24 @@ -1,52 +1,63 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file adc.h - * @brief This file contains all the function prototypes for - * the adc.c file - ****************************************************************************** - * @attention - * - * Copyright (c) 2024 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ -/* USER CODE END Header */ -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __ADC_H__ -#define __ADC_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" - -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -extern ADC_HandleTypeDef hadc1; - -/* USER CODE BEGIN Private defines */ - -/* USER CODE END Private defines */ - -void MX_ADC1_Init(void); - -/* USER CODE BEGIN Prototypes */ - -/* USER CODE END Prototypes */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ADC_H__ */ - +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file adc.h + * @brief This file contains all the function prototypes for + * the adc.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __ADC_H__ +#define __ADC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ +#include + +/* 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 */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ADC_H__ */ + diff -ruN /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Inc/board.h /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Inc/board.h --- /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Inc/board.h 2026-04-28 19:15:10 +++ /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Inc/board.h 2026-04-03 18:20:51 @@ -55,8 +55,7 @@ uint8_t stationType; // Байт 4: тип станции uint8_t boardVersion; // Байт 5: версия платы uint8_t addrEdcan; // Байт 6: адрес EDCAN - uint8_t maxPower; // Байт 7: максимальная мощность станции (5кВт/bit) - uint8_t reserved[56]; // Байты 8-63: зарезервированы + uint8_t reserved[57]; // Байты 7-63: зарезервированы } InfoBlock_t; extern InfoBlock_t *InfoBlock; diff -ruN /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Inc/dma.h /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Inc/dma.h --- /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Inc/dma.h 1970-01-01 03:00:00 +++ /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Inc/dma.h 2026-05-04 17:27:13 @@ -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__ */ + diff -ruN /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Inc/main.h /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Inc/main.h --- /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Inc/main.h 2026-04-08 12:11:02 +++ /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Inc/main.h 2026-05-04 20:04:46 @@ -43,7 +43,7 @@ /* USER CODE BEGIN EC */ #define FW_VERSION_MAJOR 1 #define FW_VERSION_MINOR 0 -#define FW_VERSION_PATCH 10 +#define FW_VERSION_PATCH 15 /* USER CODE END EC */ /* Exported macro ------------------------------------------------------------*/ @@ -59,6 +59,8 @@ /* 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 @@ #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 @@ #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 diff -ruN /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Inc/psu_control.h /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Inc/psu_control.h --- /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Inc/psu_control.h 2026-04-10 11:09:25 +++ /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Inc/psu_control.h 2026-04-03 18:20:51 @@ -88,7 +88,6 @@ // Дополнительные параметры для одного модуля DC30 uint32_t power_limit; // лимит мощности [кВт] uint8_t hv_mode; // HV-режим (ограничение напряжения) - uint32_t hv_tick; // таймер для задержки входа в HV-режим uint32_t tempAmbient; // температура окружающего воздуха (из PSU_04) union { uint8_t raw; PSU_Status0_t bits; } status0; // modularForm0 diff -ruN /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Inc/serial.h /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Inc/serial.h --- /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Inc/serial.h 2026-04-13 20:01:45 +++ /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Inc/serial.h 2026-04-26 21:15:56 @@ -11,15 +11,14 @@ void CCS_SendEmergencyStop(void); void CCS_SendStart(void); void CCS_RxEventCallback(UART_HandleTypeDef *huart, uint16_t size); -void CCS_RxArm(void); +void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart); typedef enum { - CCS_UNKNOWN = 0, - CCS_DISABLED = 1, - CCS_UNPLUGGED = 2, - CCS_AUTH_REQUIRED = 3, - CCS_CONNECTED = 4, - CCS_REPLUGGING = 5, + CCS_DISABLED = 0, + CCS_UNPLUGGED = 1, + CCS_AUTH_REQUIRED = 2, + CCS_CONNECTED = 3, + CCS_REPLUGGING = 4, } CCS_ConnectorState_t; typedef enum { diff -ruN /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Inc/serial_control.h /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Inc/serial_control.h --- /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Inc/serial_control.h 2026-04-13 19:38:22 +++ /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Inc/serial_control.h 2026-05-04 19:45:25 @@ -4,6 +4,7 @@ #include "main.h" #include #include "charger_control.h" +#include "isr_opt.h" #define USE_WEB_INTERFACE @@ -159,10 +160,6 @@ // Переменные для передачи команды 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,7 @@ // Публичные методы 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); // Внешняя функция обработки команд (определена в serial_handler.c) extern void SC_CommandHandler(ReceivedCommand_t* cmd); diff -ruN /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Inc/stm32f1xx_hal_conf.h /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Inc/stm32f1xx_hal_conf.h --- /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Inc/stm32f1xx_hal_conf.h 2025-12-02 18:39:36 +++ /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Inc/stm32f1xx_hal_conf.h 2026-05-04 17:27:16 @@ -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 diff -ruN /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Inc/stm32f1xx_it.h /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Inc/stm32f1xx_it.h --- /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Inc/stm32f1xx_it.h 2026-03-19 02:09:09 +++ /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Inc/stm32f1xx_it.h 2026-05-04 17:46:02 @@ -55,6 +55,8 @@ void DebugMon_Handler(void); void PendSV_Handler(void); void SysTick_Handler(void); +void DMA1_Channel1_IRQHandler(void); +void ADC1_2_IRQHandler(void); void CAN1_RX0_IRQHandler(void); void TIM3_IRQHandler(void); void USART1_IRQHandler(void); diff -ruN /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Src/adc.c /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Src/adc.c --- /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Src/adc.c 2026-03-17 20:01:20 +++ /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Src/adc.c 2026-05-04 19:45:24 @@ -1,135 +1,234 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file adc.c - * @brief This file provides code for the configuration - * of the ADC instances. - ****************************************************************************** - * @attention - * - * Copyright (c) 2024 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ -/* USER CODE END Header */ -/* Includes ------------------------------------------------------------------*/ -#include "adc.h" - -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -ADC_HandleTypeDef hadc1; - -/* ADC1 init function */ -void MX_ADC1_Init(void) -{ - - /* USER CODE BEGIN ADC1_Init 0 */ - - /* USER CODE END ADC1_Init 0 */ - - ADC_ChannelConfTypeDef sConfig = {0}; - - /* USER CODE BEGIN ADC1_Init 1 */ - - /* USER CODE END ADC1_Init 1 */ - - /** Common config - */ - hadc1.Instance = ADC1; - hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE; - hadc1.Init.ContinuousConvMode = DISABLE; - hadc1.Init.DiscontinuousConvMode = DISABLE; - hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; - hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; - hadc1.Init.NbrOfConversion = 1; - if (HAL_ADC_Init(&hadc1) != HAL_OK) - { - Error_Handler(); - } - - /** Configure Regular Channel - */ - sConfig.Channel = ADC_CHANNEL_8; - sConfig.Rank = ADC_REGULAR_RANK_1; - sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5; - if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) - { - Error_Handler(); - } - /* USER CODE BEGIN ADC1_Init 2 */ - - /* USER CODE END ADC1_Init 2 */ - -} - -void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle) -{ - - GPIO_InitTypeDef GPIO_InitStruct = {0}; - if(adcHandle->Instance==ADC1) - { - /* USER CODE BEGIN ADC1_MspInit 0 */ - - /* USER CODE END ADC1_MspInit 0 */ - /* ADC1 clock enable */ - __HAL_RCC_ADC1_CLK_ENABLE(); - - __HAL_RCC_GPIOA_CLK_ENABLE(); - __HAL_RCC_GPIOB_CLK_ENABLE(); - /**ADC1 GPIO Configuration - PA3 ------> ADC1_IN3 - PA4 ------> ADC1_IN4 - PB0 ------> ADC1_IN8 - PB1 ------> ADC1_IN9 - */ - GPIO_InitStruct.Pin = GPIO_PIN_3|CP_ADC_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; - HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); - - GPIO_InitStruct.Pin = ADC_NTC1_Pin|ADC_NTC2_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; - HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); - - /* USER CODE BEGIN ADC1_MspInit 1 */ - - /* USER CODE END ADC1_MspInit 1 */ - } -} - -void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle) -{ - - if(adcHandle->Instance==ADC1) - { - /* USER CODE BEGIN ADC1_MspDeInit 0 */ - - /* USER CODE END ADC1_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_ADC1_CLK_DISABLE(); - - /**ADC1 GPIO Configuration - PA3 ------> ADC1_IN3 - PA4 ------> ADC1_IN4 - PB0 ------> ADC1_IN8 - PB1 ------> ADC1_IN9 - */ - HAL_GPIO_DeInit(GPIOA, GPIO_PIN_3|CP_ADC_Pin); - - HAL_GPIO_DeInit(GPIOB, ADC_NTC1_Pin|ADC_NTC2_Pin); - - /* USER CODE BEGIN ADC1_MspDeInit 1 */ - - /* USER CODE END ADC1_MspDeInit 1 */ - } -} - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file adc.c + * @brief This file provides code for the configuration + * of the ADC instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "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) +{ + + /* USER CODE BEGIN ADC1_Init 0 */ + + /* USER CODE END ADC1_Init 0 */ + + ADC_ChannelConfTypeDef sConfig = {0}; + + /* USER CODE BEGIN ADC1_Init 1 */ + + /* USER CODE END ADC1_Init 1 */ + + /** Common config + */ + hadc1.Instance = ADC1; + hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE; + hadc1.Init.ContinuousConvMode = DISABLE; + hadc1.Init.DiscontinuousConvMode = DISABLE; + hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T3_TRGO; + hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; + hadc1.Init.NbrOfConversion = 6; + if (HAL_ADC_Init(&hadc1) != HAL_OK) + { + Error_Handler(); + } + + /** Configure Regular Channel + */ + sConfig.Channel = ADC_CHANNEL_3; + sConfig.Rank = ADC_REGULAR_RANK_1; + 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(); + } + /* USER CODE BEGIN ADC1_Init 2 */ + + /* USER CODE END ADC1_Init 2 */ + +} + +void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle) +{ + + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(adcHandle->Instance==ADC1) + { + /* USER CODE BEGIN ADC1_MspInit 0 */ + + /* USER CODE END ADC1_MspInit 0 */ + /* ADC1 clock enable */ + __HAL_RCC_ADC1_CLK_ENABLE(); + + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**ADC1 GPIO Configuration + PA3 ------> ADC1_IN3 + PA4 ------> ADC1_IN4 + PB0 ------> ADC1_IN8 + PB1 ------> ADC1_IN9 + */ + GPIO_InitStruct.Pin = GPIO_PIN_3|CP_ADC_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = ADC_NTC1_Pin|ADC_NTC2_Pin; + 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_HIGH; + 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, 0, 0); + HAL_NVIC_EnableIRQ(ADC1_2_IRQn); + /* USER CODE BEGIN ADC1_MspInit 1 */ + + /* USER CODE END ADC1_MspInit 1 */ + } +} + +void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle) +{ + + if(adcHandle->Instance==ADC1) + { + /* USER CODE BEGIN ADC1_MspDeInit 0 */ + + /* USER CODE END ADC1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_ADC1_CLK_DISABLE(); + + /**ADC1 GPIO Configuration + PA3 ------> ADC1_IN3 + PA4 ------> ADC1_IN4 + PB0 ------> ADC1_IN8 + PB1 ------> ADC1_IN9 + */ + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_3|CP_ADC_Pin); + + 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 */ + } +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff -ruN /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Src/board.c /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Src/board.c --- /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Src/board.c 2026-04-07 18:10:34 +++ /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Src/board.c 2026-05-04 19:40:26 @@ -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,14 +88,15 @@ void Init_Peripheral(){ HAL_ADCEx_Calibration_Start(&hadc1); + ADC_ScanStart(); RELAY_Write(RELAY_AUX0, 0); RELAY_Write(RELAY_AUX1, 0); RELAY_Write(RELAY3, 0); RELAY_Write(RELAY_DC, 0); RELAY_Write(RELAY_AC, 0); - RELAY_Write(RELAY_CP, 0); - RELAY_Write(RELAY_CC, 0); + RELAY_Write(RELAY_CP, 1); + RELAY_Write(RELAY_CC, 1); RELAY_Write(RELAY_DC1, 0); SMAFilter_Init(&conn_temp_adc_filter[0]); @@ -130,27 +130,11 @@ } int16_t CONN_ReadTemp(uint8_t ch){ - ADC_LockBlocking(); + uint32_t adcValue = 0u; + adcValue = ch ? adc_data.ntc2_raw : adc_data.ntc1_raw; - //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); - 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 @@ float temp = pt1000_to_temperature(calculate_NTC_resistance((int)adc_filtered, Vref, Vin, R)); - ADC_Unlock(); return (int16_t)temp; } diff -ruN /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Src/charger_control.c /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Src/charger_control.c --- /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Src/charger_control.c 2026-04-13 19:38:22 +++ /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Src/charger_control.c 2026-04-03 18:20:51 @@ -7,6 +7,7 @@ ChargingConnector_t CONN; CONN_State_t connectorState; +extern uint8_t config_initialized; void CONN_Init(){ @@ -42,7 +43,16 @@ /* CCS state machine is handled in serial.c. * Keep this task lightweight for scheduler compatibility. */ - return; + if (CONN.chargingError != CONN_NO_ERROR) { + CONN_SetState(Disabled); + return; + } + + if (connectorState == Unknown && config_initialized) { + CONN_SetState(Unplugged); + } else if (connectorState == Disabled && CONN.chargingError == CONN_NO_ERROR) { + CONN_SetState(Unplugged); + } } void CONN_SetState(CONN_State_t state){ diff -ruN /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Src/cp.c /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Src/cp.c --- /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Src/cp.c 2026-04-26 21:15:56 +++ /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Src/cp.c 2026-05-04 18:41:45 @@ -3,6 +3,7 @@ #include "board.h" #include "tim.h" #include +#include #define MAX_DUTY 450 @@ -10,29 +11,22 @@ static uint8_t cp_duty = 0; CP_State_t fake_cp_state = EV_STATE_ACQUIRING; -static uint32_t CP_ReadAdcChannel(uint32_t ch) { - uint32_t adc = 0; - - ADC_Select_Channel(ch); - HAL_ADC_Start(&hadc1); - HAL_ADC_PollForConversion(&hadc1, 10); - adc = HAL_ADC_GetValue(&hadc1); - HAL_ADC_Stop(&hadc1); - - return adc; -} #define VREFINT_CAL_ADDR ((uint16_t*)0x1FFFF7BA) // для STM32F1! static int32_t CP_ReadVoltageMv(void) { - uint32_t adc = 0; - int32_t v_adc_mv = 0; - int32_t v_out_mv = 0; + 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 +44,7 @@ #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 +65,12 @@ } 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; @@ -100,16 +95,5 @@ void CP_Loop(void) { (void)CP_GetState(); -} - -void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim) -{ - if (htim->Instance == TIM3 && htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) { - if (ADC_TryLock() == 0u) { - return; - } - cp_voltage_mv = CP_ReadVoltageMv(); - ADC_Unlock(); - } } diff -ruN /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Src/debug.c /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Src/debug.c --- /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Src/debug.c 2026-04-10 11:21:13 +++ /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Src/debug.c 2026-05-04 19:45:25 @@ -148,3 +148,220 @@ return result; } +#ifndef USE_WEB_INTERFACE + +#include "isr_opt.h" + +extern UART_HandleTypeDef huart2; + + +uint8_t debug_rx_buffer[256]; +uint8_t debug_cmd_received; +uint8_t debug_rx_buffer_size = 0; + + +ISR_FAST void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size){ + +// if(huart->Instance == USART1){ +// mm_rx_interrupt(huart, Size); +// } + if(huart->Instance == USART2){ + debug_rx_interrupt(huart, Size); + } +} + +ISR_FAST void debug_rx_interrupt(UART_HandleTypeDef *huart, uint16_t Size){ + debug_rx_buffer[Size] = '\0'; + debug_rx_buffer_size = Size; + debug_cmd_received = 1; +} + +void debug_init(){ + HAL_UARTEx_ReceiveToIdle_IT(&huart2,debug_rx_buffer,255); +} + +void parse_command(uint8_t* buffer, size_t length) { + // ignore \r \n symbols + size_t i = 0; + for (i = 0; i < length; i++) { + if (buffer[i] == '\r' || buffer[i] == '\n') { + buffer[i] = '\0'; + length = i; + break; + } + } + if (buffer[0] == 0) return; + if (strncmp((const char*)buffer, "reset", length) == 0) { + log_printf(LOG_INFO, "Resetting...\n"); + NVIC_SystemReset(); + + } else if (strncmp((const char*)buffer, "relayaux", length) == 0) { + log_printf(LOG_INFO, "Relaying...\n"); + RELAY_Write(RELAY_AUX, 1); + HAL_Delay(2000); + RELAY_Write(RELAY_AUX, 0); + } else if (strncmp((const char*)buffer, "relaycc", length) == 0) { + log_printf(LOG_INFO, "Relaying...\n"); + RELAY_Write(RELAY_CC, 1); + HAL_Delay(200); + RELAY_Write(RELAY_CC, 0); + } else if (strncmp((const char*)buffer, "relaydc", length) == 0) { + log_printf(LOG_INFO, "Relaying...\n"); + RELAY_Write(RELAY_DC, 1); + HAL_Delay(200); + RELAY_Write(RELAY_DC, 0); + } else if (strncmp((const char*)buffer, "relayac", length) == 0) { + log_printf(LOG_INFO, "Relaying...\n"); + RELAY_Write(RELAY_AC, 1); + HAL_Delay(200); + RELAY_Write(RELAY_AC, 0); + + } else if (strncmp((const char*)buffer, "adc", length) == 0) { + log_printf(LOG_INFO, "CC1=%.2f\n", CONN_CC_GetAdc()); + + } else if (strncmp((const char*)buffer, "lock_state", length) == 0) { + log_printf(LOG_INFO, "Lock state=%d\n", GBT_LockGetState()); + + } else if (strncmp((const char*)buffer, "lock_lock", length) == 0) { + log_printf(LOG_INFO, "Locked\n"); + GBT_Lock(1); + + } else if (strncmp((const char*)buffer, "lock_unlock", length) == 0) { + log_printf(LOG_INFO, "Unlocked\n"); + GBT_Lock(0); + + } else if (strncmp((const char*)buffer, "complete", length) == 0) { + CONN_SetState(Finished); + + } else if (strncmp((const char*)buffer, "start", length) == 0) { + log_printf(LOG_INFO, "Started\n"); + GBT_Start(); + + } else if (strncmp((const char*)buffer, "stop", length) == 0) { + log_printf(LOG_INFO, "Stopped\n"); + GBT_StopEVSE(GBT_CST_SUSPENDS_ARTIFICIALLY); + + } else if (strncmp((const char*)buffer, "stop1", length) == 0) { + log_printf(LOG_INFO, "Stopped\n"); + GBT_ForceStop(); + +// } else if (strncmp((const char*)buffer, "force", length) == 0) { +// log_printf(LOG_INFO, "Stopped\n"); +// GBT_Lock(1); +// GBT_SwitchState(GBT_S2_LOCKED); +// GBT_Delay(500); + + } else if (strncmp((const char*)buffer, "cc_state", length) == 0) { + switch(CONN_CC_GetState()){ + case GBT_CC_UNKNOWN: + log_printf(LOG_INFO, "GBT_CC_UNKNOWN\n"); + break; + case GBT_CC_12V: + log_printf(LOG_INFO, "GBT_CC_12V\n"); + break; + case GBT_CC_6V: + log_printf(LOG_INFO, "GBT_CC_6V\n"); + break; + case GBT_CC_4V: + log_printf(LOG_INFO, "GBT_CC_4V\n"); + break; + case GBT_CC_2V: + log_printf(LOG_INFO, "GBT_CC_2V\n"); + break; + + } + } else if (strncmp((const char*)buffer, "temp", length) == 0) { + log_printf(LOG_INFO, "temp1 %d\n",GBT_ReadTemp(0)); + log_printf(LOG_INFO, "temp2 %d\n",GBT_ReadTemp(1)); + } else if (strncmp((const char*)buffer, "info1", length) == 0) { + log_printf(LOG_INFO, "Battery info:\n"); + log_printf(LOG_INFO, "maxCV %dV\n",GBT_BATStat.maxCellVoltage/100); // 0.01v/bit + log_printf(LOG_INFO, "maxCC %dA\n",GBT_BATStat.maxChargingCurrent/10); // 0.1A/bit + log_printf(LOG_INFO, "totE %dkWh\n",GBT_BATStat.totalEnergy/10); // 0.1kWh + log_printf(LOG_INFO, "maxCV %dV\n",GBT_BATStat.maxChargingVoltage/10); // 0.1V/ bit + log_printf(LOG_INFO, "maxT %dC\n",(int16_t)GBT_BATStat.maxTemp-50); // 1C/bit, -50C offset + log_printf(LOG_INFO, "SOC %dp\n",GBT_BATStat.SOC/10); // 0.1%/bit , 0..100% + log_printf(LOG_INFO, "Volt. %dV\n",GBT_BATStat.measVoltage/10); // 0.1V/bit + + } else if (strncmp((const char*)buffer, "info2", length) == 0) { + log_printf(LOG_INFO, "EV info:\n"); + log_printf(LOG_INFO, "GBT_ver V%d.%d%d\n",GBT_EVInfo.version[0],GBT_EVInfo.version[1],GBT_EVInfo.version[2]); + log_printf(LOG_INFO, "Battery type: %d\n",GBT_EVInfo.batteryType); + log_printf(LOG_INFO, "Battery capacity: %d\n", GBT_EVInfo.batteryCapacity); // 0.1Ah/bit + log_printf(LOG_INFO, "Battery voltage: %d\n", GBT_EVInfo.batteryVoltage); // 0.1V/bit + log_printf(LOG_INFO, "Battery vendor: %.4s\n", GBT_EVInfo.batteryVendor); // Battery vendor (ASCII string) + log_printf(LOG_INFO, "Battery SN: %lu\n", GBT_EVInfo.batterySN); // int + log_printf(LOG_INFO, "Battery manufacture date: %02d.%02d.%04d\n", GBT_EVInfo.batteryManuD, GBT_EVInfo.batteryManuM ,GBT_EVInfo.batteryManuY+1985); // year (offset 1985) + log_printf(LOG_INFO, "Battery cycles: %d\n", GBT_EVInfo.batteryCycleCount); //uint24_t + log_printf(LOG_INFO, "Own auto: %d\n", GBT_EVInfo.ownAuto); // 0 = lizing, 1 = own auto + log_printf(LOG_INFO, "EVIN: %.17s\n", GBT_EVInfo.EVIN); //EVIN + log_printf(LOG_INFO, "EV_SW_VER: %.8s\n", GBT_EVInfo.EV_SW_VER); + + } else if (strncmp((const char*)buffer, "info3", length) == 0) { + log_printf(LOG_INFO, "GBT_MaxLoad info:\n"); + log_printf(LOG_INFO, "Output max current: %d\n",GBT_MaxLoad.maxOutputCurrent); + log_printf(LOG_INFO, "Output min current: %d\n",GBT_MaxLoad.minOutputCurrent); + log_printf(LOG_INFO, "Output max voltage: %d\n",GBT_MaxLoad.maxOutputVoltage); + log_printf(LOG_INFO, "Output min voltage: %d\n",GBT_MaxLoad.minOutputVoltage); + log_printf(LOG_INFO, "\nGBT_ChargerInfo info:\n"); + log_printf(LOG_INFO, "BMS Recognized: %d\n",GBT_ChargerInfo.bmsIdentified); + log_printf(LOG_INFO, "Charger location: %.3s\n",GBT_ChargerInfo.chargerLocation); + log_printf(LOG_INFO, "Charger number: %lu\n",GBT_ChargerInfo.chargerNumber); + + + } else if (strncmp((const char*)buffer, "help", length) == 0) { + log_printf(LOG_INFO, "Command list:\n"); + log_printf(LOG_INFO, "reset\n"); + log_printf(LOG_INFO, "help\n"); + log_printf(LOG_INFO, "cc_state\n"); + log_printf(LOG_INFO, "lock_lock\n"); + log_printf(LOG_INFO, "lock_unlock\n"); + log_printf(LOG_INFO, "lock_state\n"); + log_printf(LOG_INFO, "adc\n"); + log_printf(LOG_INFO, "relay(cc,aux,ac,dc)\n"); + log_printf(LOG_INFO, "start\n"); + log_printf(LOG_INFO, "stop\n"); + log_printf(LOG_INFO, "stop1\n"); +// log_printf(LOG_INFO, "force\n"); + log_printf(LOG_INFO, "temp\n"); + log_printf(LOG_INFO, "info1\n"); + log_printf(LOG_INFO, "info2\n"); + log_printf(LOG_INFO, "info3\n"); + log_printf(LOG_INFO, "time\n"); + log_printf(LOG_INFO, "cantest\n"); + + //TODO: info commands + + } else if (strncmp((const char*)buffer, "time", length) == 0) { + + time_t unix_time = (time_t)get_Current_Time(); + struct tm *parts = localtime(&unix_time); + + log_printf(LOG_INFO, "Year: %d\n", parts->tm_year + 1900); + log_printf(LOG_INFO, "Month: %d\n", parts->tm_mon + 1); + log_printf(LOG_INFO, "Day: %d\n", parts->tm_mday); + log_printf(LOG_INFO, "Hour: %d\n", parts->tm_hour); + log_printf(LOG_INFO, "Minute: %d\n", parts->tm_min); + log_printf(LOG_INFO, "Second: %d\n", parts->tm_sec); + + } else if (strncmp((const char*)buffer, "cantest", length) == 0) { + //GBT_SendCHM(); + GBT_Error(0xFDF0C0FC); //BRM Timeout + log_printf(LOG_INFO, "can test\n"); + + } else { + log_printf(LOG_INFO, "Unknown command\n"); + } +} + +void debug_task(){ + if(debug_cmd_received){ + parse_command(debug_rx_buffer, debug_rx_buffer_size); + HAL_UARTEx_ReceiveToIdle_IT(&huart2,debug_rx_buffer,255); + debug_cmd_received = 0; + } +} + +#else + +#endif // USE_WEB_INTERFACE diff -ruN /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Src/dma.c /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Src/dma.c --- /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Src/dma.c 1970-01-01 03:00:00 +++ /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Src/dma.c 2026-05-04 17:27:13 @@ -0,0 +1,55 @@ +/* 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, 0, 0); + HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn); + +} + +/* USER CODE BEGIN 2 */ + +/* USER CODE END 2 */ + diff -ruN /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Src/gpio.c /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Src/gpio.c --- /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Src/gpio.c 2026-03-19 00:22:07 +++ /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Src/gpio.c 2026-05-04 16:27:39 @@ -54,20 +54,27 @@ __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 @@ 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; @@ -102,6 +116,13 @@ GPIO_InitStruct.Pull = GPIO_NOPULL; 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; diff -ruN /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Src/main.c /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Src/main.c --- /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Src/main.c 2026-04-26 21:15:56 +++ /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Src/main.c 2026-05-04 18:58:41 @@ -1,332 +1,304 @@ -/* 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 -#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 +#include "debug.h" +#include "soft_rtc.h" +#include "connector.h" +#include "serial_control.h" +#include "charger_config.h" +#include "serial.h" +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN PTD */ + +/* USER CODE END PTD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ + +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +void SystemClock_Config(void); +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ + +/** + * @brief Vector base address configuration. It should no longer be at the start of + * flash memory but moved forward because the first part of flash is + * reserved for the bootloader. Note that this is already done by the + * bootloader before starting this program. Unfortunately, function + * SystemInit() overwrites this change again. + * @return none. + */ +static void VectorBase_Config(void) +{ + /* The constant array with vectors of the vector table is declared externally in the + * c-startup code. + */ + extern const unsigned long g_pfnVectors[]; + + /* Remap the vector table to where the vector table is located for this program. */ + SCB->VTOR = (unsigned long)&g_pfnVectors[0]; +} + +uint8_t ED_TraceWarning(uint8_t flag, uint8_t id){ + static uint8_t memory[32]; + if(id > 31) return 0; + uint8_t result = 0; + if(memory[id] != flag){ + result = 1; + } + memory[id] = flag; + return result; +} + + +void ED_Delay(uint32_t Delay) +{ + uint32_t tickstart = HAL_GetTick(); + uint32_t wait = Delay; + + if (wait < HAL_MAX_DELAY) + { + wait += (uint32_t)(uwTickFreq); + } + + while ((HAL_GetTick() - tickstart) < wait){ + CCS_SerialLoop(); +// CP_Loop(); + CONN_Task(); + LED_Task(); + SC_Task(); + } +} + +void StopButtonControl(){ + + //Charging do nothing + if(!IN_ReadInput(IN_ESTOP)){ + CONN.connControl = CMD_STOP; + } + +} + +uint8_t temp0, temp1; + +static void CAN1_MinimalReInit(void) +{ + HAL_CAN_Stop(&hcan1); + MX_CAN1_Init(); + if (HAL_CAN_Start(&hcan1) != HAL_OK) { + Error_Handler(); + } + if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK) { + Error_Handler(); + } +} + +/* USER CODE END 0 */ + +/** + * @brief The application entry point. + * @retval int + */ +int main(void) +{ + + /* USER CODE BEGIN 1 */ + + VectorBase_Config(); + /* USER CODE END 1 */ + + /* MCU Configuration--------------------------------------------------------*/ + + /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ + HAL_Init(); + + /* USER CODE BEGIN Init */ + HAL_RCC_DeInit(); + /* USER CODE END Init */ + + /* Configure the system clock */ + SystemClock_Config(); + + /* USER CODE BEGIN SysInit */ + + /* USER CODE END SysInit */ + + /* Initialize all configured peripherals */ + MX_GPIO_Init(); + MX_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); + StopButtonControl(); + ED_Delay(50); + + } + /* USER CODE END 3 */ +} + +/** + * @brief System Clock Configuration + * @retval None + */ +void SystemClock_Config(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; + + /** Initializes the RCC Oscillators according to the specified parameters + * in the RCC_OscInitTypeDef structure. + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE|RCC_OSCILLATORTYPE_LSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV5; + RCC_OscInitStruct.LSEState = RCC_LSE_ON; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.Prediv1Source = RCC_PREDIV1_SOURCE_PLL2; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; + RCC_OscInitStruct.PLL2.PLL2State = RCC_PLL2_ON; + RCC_OscInitStruct.PLL2.PLL2MUL = RCC_PLL2_MUL8; + RCC_OscInitStruct.PLL2.HSEPrediv2Value = RCC_HSE_PREDIV2_DIV5; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + Error_Handler(); + } + + /** Initializes the CPU, AHB and APB buses clocks + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK + |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) + { + Error_Handler(); + } + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_ADC; + PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; + PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) + { + Error_Handler(); + } + + /** Configure the Systick interrupt time + */ + __HAL_RCC_PLLI2S_ENABLE(); +} + +/* USER CODE BEGIN 4 */ + +/* USER CODE END 4 */ + +/** + * @brief This function is executed in case of error occurrence. + * @retval None + */ +void Error_Handler(void) +{ + /* USER CODE BEGIN Error_Handler_Debug */ + /* User can add his own implementation to report the HAL error return state */ + __disable_irq(); + while (1) + { + } + /* USER CODE END Error_Handler_Debug */ +} +#ifdef USE_FULL_ASSERT +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ +void assert_failed(uint8_t *file, uint32_t line) +{ + /* USER CODE BEGIN 6 */ + /* User can add his own implementation to report the file name and line number, + ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ + /* USER CODE END 6 */ +} +#endif /* USE_FULL_ASSERT */ diff -ruN /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Src/psu_control.c /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Src/psu_control.c --- /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Src/psu_control.c 2026-04-10 11:09:38 +++ /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Src/psu_control.c 2026-05-04 19:45:24 @@ -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 @@ 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,}; @@ -149,7 +150,6 @@ PSU0.power_limit = PSU_MAX_POWER; // kW PSU0.hv_mode = 0; - PSU0.hv_tick = 0; PSU_Enable(0, 0); } @@ -262,19 +262,14 @@ } CONN.RequestedPower = CONN.RequestedCurrent * CONN.RequestedVoltage / 10; - if(PSU0.ready){ - PSU_SetVoltageCurrent(0, CONN.RequestedVoltage, CONN.RequestedCurrent); // Normal mode - ED_Delay(CAN_DELAY); - if(CONN.MeasuredVoltage > 490){ - if(PSU0.hv_tick == 0){ - PSU0.hv_tick = HAL_GetTick(); - }else if((HAL_GetTick() - PSU0.hv_tick) >= 10000){ - PSU0.hv_mode = 1; - } + if (CONN.RequestedVoltage == 500) { // fake + PSU_SetVoltageCurrent(0, 300, 10); // Normal mode }else{ - PSU0.hv_tick = 0; + PSU_SetVoltageCurrent(0, CONN.RequestedVoltage, CONN.RequestedCurrent); // Normal mode } + ED_Delay(CAN_DELAY); + if(CONN.MeasuredVoltage>490) PSU0.hv_mode = 1; } // PSU_SetHVMode(0, PSU0.hv_mode); // auto set, no need @@ -348,7 +343,6 @@ case PSU_READY: // модуль готов, но выключен PSU0.hv_mode = 0; - PSU0.hv_tick = 0; RELAY_Write(RELAY_DC, 0); if(!PSU0.ready){ diff -ruN /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Src/rgb_controller.c /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Src/rgb_controller.c --- /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Src/rgb_controller.c 2026-04-10 14:37:04 +++ /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Src/rgb_controller.c 2026-04-03 18:20:51 @@ -2,7 +2,6 @@ #include "main.h" #include "string.h" #include "charger_control.h" -#include "board.h" #include "tim.h" @@ -11,22 +10,13 @@ RGB_Cycle_t color_estop = { .Color1 = { .R = 250, .G = 0, .B = 0 }, - .Color2 = { .R = 0, .G = 0, .B = 0 }, - .Tr = 10, - .Th = 5, - .Tf = 10, - .Tl = 5, + .Color2 = { .R = 250, .G = 0, .B = 0 }, + .Tr = 50, + .Th = 50, + .Tf = 50, + .Tl = 50, }; - RGB_Cycle_t color_unlock = { - .Color1 = { .R = 255, .G = 0, .B = 0 }, - .Color2 = { .R = 0, .G = 0, .B = 0 }, - .Tr = 10, - .Th = 10, - .Tf = 10, - .Tl = 10, - }; - RGB_Cycle_t color_unknown = { .Color1 = { .R = 64, .G = 0, .B = 0 }, .Color2 = { .R = 64, .G = 0, .B = 0 }, @@ -64,12 +54,12 @@ }; RGB_Cycle_t color_preparing = { - .Color1 = { .R = 0, .G = 0, .B = 255 }, - .Color2 = { .R = 0, .G = 0, .B = 0 }, - .Tr = 10, + .Color1 = { .R = 0, .G = 0, .B = 250 }, + .Color2 = { .R = 0, .G = 0, .B = 250 }, + .Tr = 50, .Th = 10, - .Tf = 10, - .Tl = 10, + .Tf = 50, + .Tl = 0, }; RGB_Cycle_t color_charging = { @@ -102,14 +92,6 @@ void LED_Write(){ if(CONN.chargingError != CONN_NO_ERROR){ LED_SetColor(&color_error); - return; - } - if(CONN.connControl == CMD_FORCE_UNLOCK){ - LED_SetColor(&color_unlock); - return; - } - if(CONN.connControl == CMD_STOP){ - LED_SetColor(&color_estop); return; } switch(CONN.connState){ diff -ruN /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Src/serial.c /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Src/serial.c --- /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Src/serial.c 2026-05-01 17:52:54 +++ /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Src/serial.c 2026-05-04 19:56:33 @@ -3,6 +3,7 @@ #include "connector.h" #include "board.h" #include "debug.h" +#include "isr_opt.h" #include #include #include "charger_config.h" @@ -28,12 +29,9 @@ #define CMD_INTERVAL 10 #define MAX_TX_BUFFER_SIZE 256 #define MAX_RX_BUFFER_SIZE 256 +#define EVEREST_TIMEOUT_MS 5000u +#define UART3_REINIT_TIMEOUT_MS 1500u -/* Everest requests 500 V → БП реально 300 V / 1 A, в STATE отдаём 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]; @@ -44,66 +42,111 @@ 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 uint8_t everest_timed_out = 0; +static uint32_t last_everest_timeout_log_tick = 0; +static uint32_t uart3_last_packet_tick = 0; +static uint32_t uart3_last_reinit_tick = 0; static CP_State_t cp_state_buffer = EV_STATE_ACQUIRING; CCS_State_t CCS_State; CCS_EvInfo_t CCS_EvInfo; CONN_State_t CCS_EvseState; -CCS_ConnectorState_t CCS_ConnectorState = CCS_UNKNOWN; +CCS_ConnectorState_t CCS_ConnectorState = CCS_UNPLUGGED; -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); -void CCS_RxEventCallback(UART_HandleTypeDef *huart, uint16_t size) { +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; + } + 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_IT(&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); + if (err_after != HAL_UART_ERROR_NONE) { + (void)HAL_UART_Abort_IT(&huart3); + } +} + +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 > 0 && size <= sizeof(rx_buffer)) { - process_received_packet(rx_buffer, size); + 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"); } -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 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_Abort_IT(huart); + if (huart == &huart3) { + uart3_arm_rx_or_log("ErrorCallback"); } } + + void CCS_SerialLoop(void) { static uint32_t replug_tick = 0; static uint32_t replug_watchdog_tick = 0; static uint32_t replug_watchdog1_tick = 0; static uint32_t last_state_sent = 0; - static uint32_t force_unlock_tick = 0; - static uint32_t stop_tick = 0; - CCS_RxArm(); + if ((&huart3)->RxState == HAL_UART_STATE_READY) { + uart3_arm_rx_or_log("SerialLoop"); + } + CCS_UART3_Watchdog(); + /* Read CP once per loop and use buffered value below. */ cp_state_buffer = CP_GetState(); - if (CONN.connControl == CMD_FORCE_UNLOCK) { - if (force_unlock_tick == 0) { - force_unlock_tick = HAL_GetTick(); - } else if ((HAL_GetTick() - force_unlock_tick) >= 10000) { - CONN.connControl = CMD_NONE; - force_unlock_tick = 0; - } - } else { - force_unlock_tick = 0; - } - - if (CONN.connControl == CMD_STOP) { - if (stop_tick == 0) { - stop_tick = HAL_GetTick(); - } else if ((HAL_GetTick() - stop_tick) >= 1000) { - CONN.connControl = CMD_NONE; - stop_tick = 0; - } - } else { - stop_tick = 0; - } - if (CONN.connControl != CMD_NONE) { last_cmd = CONN.connControl; } @@ -121,14 +164,10 @@ } if (((CONN.connControl == CMD_STOP) || - (CONN.connControl == CMD_FORCE_UNLOCK) || (CONN.chargingError != CONN_NO_ERROR)) && ((HAL_GetTick() - last_stop_sent) > 1000)) { last_stop_sent = HAL_GetTick(); log_printf(LOG_WARN, "Stopping charging...\n"); - if (CONN.connControl == CMD_FORCE_UNLOCK) { - CP_SetDuty(100); - } CCS_SendEmergencyStop(); } @@ -143,101 +182,102 @@ (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); + if (!config_initialized) { + // Keep connector in Unknown until host sends valid SET_CONFIG. + RELAY_Write(RELAY_CP, 1); + CONN_SetState(Unknown); + } else { + switch(CCS_ConnectorState){ + case CCS_DISABLED: + RELAY_Write(RELAY_CP, 0); + CONN_SetState(Disabled); + if (CONN.chargingError == CONN_NO_ERROR){ + CCS_ConnectorState = CCS_UNPLUGGED; + } + break; + case CCS_UNPLUGGED: + RELAY_Write(RELAY_CP, 1); + CONN_SetState(Unplugged); + if ((cp_state_buffer == EV_STATE_B_CONN_PREP) || (cp_state_buffer == EV_STATE_C_CONN_ACTIVE)){ + CCS_ConnectorState = CCS_AUTH_REQUIRED; + } + if (CONN.chargingError != CONN_NO_ERROR){ + log_printf(LOG_ERR, "Charging error %d, state -> disabled\n", CONN.chargingError); + CCS_ConnectorState = CCS_DISABLED; + } - 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--; + 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 { - log_printf(LOG_INFO, "Replugging finished, but car unplugged\n"); + CONN_SetState(CCS_EvseState); + } + if (cp_state_buffer == EV_STATE_A_IDLE){ + log_printf(LOG_INFO, "Car unplugged\n"); CCS_ConnectorState = CCS_UNPLUGGED; } - } + if(REPLUG > 0){ + log_printf(LOG_INFO, "Replugging...\n"); + CCS_ConnectorState = CCS_REPLUGGING; + } + break; + case CCS_REPLUGGING: + RELAY_Write(RELAY_CP, 0); + CONN_SetState(Replugging); + if((HAL_GetTick() - replug_tick) > 1000){ + replug_tick = HAL_GetTick(); + if(REPLUG > 0){ + if (REPLUG != 0xFF) REPLUG--; + } else { + log_printf(LOG_INFO, "Replugging finished, but car unplugged\n"); + CCS_ConnectorState = CCS_UNPLUGGED; + } + } - if(REPLUG == 0){ - if(cp_state_buffer == EV_STATE_B_CONN_PREP){ - log_printf(LOG_INFO, "Replugging finished, car plugged, state -> auth required\n"); - CCS_ConnectorState = CCS_AUTH_REQUIRED; + 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; + 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 Everest timeout happened, keep safe-state and limit log frequency. + // The safe-state must remain until we receive a valid packet from the host. + if (everest_timed_out) { + if (last_everest_timeout_log_tick == 0 || + (HAL_GetTick() - last_everest_timeout_log_tick) >= EVEREST_TIMEOUT_MS) { + log_printf(LOG_ERR, "Everest timeout\n"); + last_everest_timeout_log_tick = HAL_GetTick(); + } + CONN.EnableOutput = 0; + CCS_EvseState = Unknown; + CP_SetDuty(100); + } else if (last_host_seen > 0 && (HAL_GetTick() - last_host_seen) > EVEREST_TIMEOUT_MS) { + log_printf(LOG_ERR, "Everest timeout\n"); + everest_timed_out = 1; + last_host_seen = HAL_GetTick(); // reset after the first timeout + last_everest_timeout_log_tick = HAL_GetTick(); - if (host_timed_out) { 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 { if (last_cmd == CMD_STOP) { CONN.EnableOutput = 0; @@ -266,11 +306,13 @@ 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; 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 +346,7 @@ 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); + HAL_UART_Transmit_IT(&huart3, tx_buffer, len); } last_cmd_sent = HAL_GetTick(); } @@ -342,9 +384,7 @@ CCS_State.DutyCycle = CP_GetDuty(); CCS_State.OutputEnabled = PSU0.CONT_enabled; CCS_State.MeasuredVoltage = (uint16_t)CONN.MeasuredVoltage; - if (fake_500_voltage_mode) { - CCS_State.MeasuredVoltage = FAKE_EVREQ_VOLTAGE_V; - } + if (CONN.RequestedVoltage == 500) CCS_State.MeasuredVoltage = 500; // fake CCS_State.MeasuredCurrent = (uint16_t)CONN.MeasuredCurrent; CCS_State.Power = CCS_Power; CCS_State.Energy = CCS_Energy; @@ -366,7 +406,7 @@ 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,18 +422,18 @@ } } -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; + last_everest_timeout_log_tick = 0; switch (cmd) { case CMD_E2M_PWM_DUTY: { const e2m_pwm_duty_t* p = (const e2m_pwm_duty_t*)payload; uint8_t duty = p->pwm_duty_percent; if (duty > 100) duty = 100; pwm_duty_percent = duty; - if (CONN.connControl != CMD_FORCE_UNLOCK) { - CP_SetDuty(duty); - } + CP_SetDuty(duty); break; } case CMD_E2M_ENABLE_OUTPUT: { @@ -405,9 +445,9 @@ 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; } @@ -419,15 +459,8 @@ } case CMD_E2M_SET_OUTPUT_VOLTAGE: { const e2m_set_output_t* p = (const e2m_set_output_t*)payload; - if (p->voltage_V == FAKE_EVREQ_VOLTAGE_V) { - fake_500_voltage_mode = 1u; - CONN.RequestedVoltage = FAKE_PSU_VOLTAGE_V; - CONN.WantedCurrent = FAKE_PSU_CURRENT_0P1A; - } else { - fake_500_voltage_mode = 0u; - CONN.RequestedVoltage = p->voltage_V; - CONN.WantedCurrent = p->current_0p1A; - } + CONN.RequestedVoltage = p->voltage_V; + CONN.WantedCurrent = p->current_0p1A; break; } case CMD_E2M_ISOLATION_CONTROL: { @@ -454,32 +487,54 @@ 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; } @@ -490,5 +545,22 @@ } return 1; +} + +static void CCS_UART3_Watchdog(void) { + const uint32_t now = HAL_GetTick(); + const uint32_t since_last_packet = now - uart3_last_packet_tick; + + if ((since_last_packet >= UART3_REINIT_TIMEOUT_MS) && + ((now - uart3_last_reinit_tick) >= UART3_REINIT_TIMEOUT_MS)) { + (void)HAL_UART_Abort_IT(&huart3); + (void)HAL_UART_DeInit(&huart3); + (void)HAL_UART_Init(&huart3); + (void)HAL_UARTEx_ReceiveToIdle_IT(&huart3, rx_buffer, sizeof(rx_buffer)); + log_printf(LOG_ERR, + "UART3 RX recover: stalled (no RxEvent data for %ums), hard reinit\n", + (unsigned)UART3_REINIT_TIMEOUT_MS); + uart3_last_reinit_tick = now; + } } diff -ruN /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Src/serial_control.c /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Src/serial_control.c --- /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Src/serial_control.c 2026-05-01 17:54:34 +++ /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Src/serial_control.c 2026-05-04 19:49:47 @@ -3,14 +3,14 @@ #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); uint8_t test_crc_invalid = 0; @@ -18,7 +18,15 @@ // Контекст для приема пакетов по 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_reinit_tick = 0; +/** Событие приёма по UART2 при активной передаче (см. HAL_UARTEx_RxEventCallback / SC_UART2_Watchdog). */ +static volatile uint8_t sc_uart2_rx_during_tx = 0; +#define SC_UART2_REINIT_TIMEOUT_MS 500u +#define SC_UART2_PACKET_TIMEOUT_MS 5000u + StatusPacket_t statusPacket = { .SOC = 0, .Energy = 0, @@ -75,12 +83,28 @@ // Обнуляем структуру 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_reinit_tick = sc_uart2_last_packet_tick; + sc_uart2_rx_during_tx = 0; } void SC_Task() { + SC_UART2_Watchdog(); + // Запуск приема в режиме прерывания с ожиданием idle - SC_ArmUart2Rx(); - SC_ArmUart5Rx(); + if ((huart2.RxState == HAL_UART_STATE_READY) && (serial_control.command_ready == 0)) { + if ((HAL_UARTEx_ReceiveToIdle_IT(&huart2, serial_control.rx_buffer, MAX_RX_BUFFER_SIZE - 1) != HAL_OK) && + (HAL_UART_GetError(&huart2) != HAL_UART_ERROR_NONE)) { + (void)HAL_UART_Abort_IT(&huart2); + } + } + if (huart5.RxState == HAL_UART_STATE_READY) { + if ((HAL_UARTEx_ReceiveToIdle_IT(&huart5, serial_iso.rx_buffer, MAX_RX_BUFFER_SIZE - 1) != HAL_OK) && + (HAL_UART_GetError(&huart5) != HAL_UART_ERROR_NONE)) { + (void)HAL_UART_Abort_IT(&huart5); + } + } // Проверка таймаута отправки пакета (больше 100 мс) if (huart2.gState == HAL_UART_STATE_BUSY_TX && serial_control.tx_tick != 0) { @@ -95,80 +119,51 @@ // Проверка наличия принятой команды для обработки if (serial_control.command_ready && (huart2.gState != HAL_UART_STATE_BUSY_TX)) { - g_sc_command_source = SC_SOURCE_UART2; +// HAL_Delay(2); SC_CommandHandler(&serial_control.received_command); + if ((HAL_UARTEx_ReceiveToIdle_IT(&huart2, serial_control.rx_buffer, MAX_RX_BUFFER_SIZE - 1) != HAL_OK) && + (HAL_UART_GetError(&huart2) != HAL_UART_ERROR_NONE)) { + (void)HAL_UART_Abort_IT(&huart2); + } 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(); - } } -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 (huart2.gState == HAL_UART_STATE_BUSY_TX) { + sc_uart2_rx_during_tx = 1u; } + sc_uart2_last_packet_tick = HAL_GetTick(); + sc_uart2_last_reinit_tick = sc_uart2_last_packet_tick; + sc_uart2_timed_out = 0; + if(!process_received_packet(&serial_control, serial_control.rx_buffer, Size)){ + SC_SendPacket(NULL, 0, RESP_INVALID); + } + g_sc_command_source = SC_SOURCE_UART2; + HAL_UARTEx_ReceiveToIdle_IT(&huart2, serial_control.rx_buffer, MAX_RX_BUFFER_SIZE - 1); } else if (huart->Instance == huart5.Instance) { - if (!process_received_packet(&serial_iso, serial_iso.rx_buffer, Size)) { - SC_ArmUart5Rx(); + 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); } + HAL_UARTEx_ReceiveToIdle_IT(&huart5, serial_iso.rx_buffer, MAX_RX_BUFFER_SIZE - 1); } 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); - } -} - // Приватные функции реализации // Полностью программная реализация 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 +180,7 @@ 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,7 +213,7 @@ 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) { @@ -229,13 +224,15 @@ HAL_GPIO_WritePin(USART2_DIR_GPIO_Port, USART2_DIR_Pin, GPIO_PIN_SET); + sc_uart2_rx_during_tx = 0u; + 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,12 +265,50 @@ 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; } ctx->command_ready = 1; return 1; +} + +static void SC_UART2_Watchdog(void) { + const uint32_t now = HAL_GetTick(); + const uint32_t since_last_packet = now - sc_uart2_last_packet_tick; + + if ((huart2.gState == HAL_UART_STATE_BUSY_TX) && (sc_uart2_rx_during_tx != 0u)) { + HAL_GPIO_WritePin(USART2_DIR_GPIO_Port, USART2_DIR_Pin, GPIO_PIN_RESET); + (void)HAL_UART_Abort_IT(&huart2); + (void)HAL_UART_DeInit(&huart2); + (void)HAL_UART_Init(&huart2); + (void)HAL_UARTEx_ReceiveToIdle_IT(&huart2, serial_control.rx_buffer, MAX_RX_BUFFER_SIZE - 1); + serial_control.tx_tick = 0; + sc_uart2_rx_during_tx = 0u; + sc_uart2_last_reinit_tick = now; + log_printf(LOG_ERR, "USART2 BUSY_TX: hard reinit\n"); + return; + } + + if (since_last_packet >= SC_UART2_PACKET_TIMEOUT_MS) { + if (sc_uart2_timed_out == 0u) { + serial_control.command_ready = 0; + } + sc_uart2_timed_out = 1; + } else { + sc_uart2_timed_out = 0; + } + + if ((since_last_packet >= SC_UART2_REINIT_TIMEOUT_MS) && + ((now - sc_uart2_last_reinit_tick) >= SC_UART2_REINIT_TIMEOUT_MS)) { + HAL_GPIO_WritePin(USART2_DIR_GPIO_Port, USART2_DIR_Pin, GPIO_PIN_RESET); + (void)HAL_UART_Abort_IT(&huart2); + (void)HAL_UART_DeInit(&huart2); + (void)HAL_UART_Init(&huart2); + (void)HAL_UARTEx_ReceiveToIdle_IT(&huart2, serial_control.rx_buffer, MAX_RX_BUFFER_SIZE - 1); + sc_uart2_last_reinit_tick = now; + log_printf(LOG_ERR, "USART2 stalled: hard reinit\n"); + } } diff -ruN /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Src/stm32f1xx_it.c /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Src/stm32f1xx_it.c --- /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Src/stm32f1xx_it.c 2026-03-19 02:08:31 +++ /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Src/stm32f1xx_it.c 2026-05-04 19:45:24 @@ -1,321 +1,354 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file stm32f1xx_it.c - * @brief Interrupt Service Routines. - ****************************************************************************** - * @attention - * - * Copyright (c) 2024 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" -#include "stm32f1xx_it.h" -/* Private includes ----------------------------------------------------------*/ -/* USER CODE BEGIN Includes */ -/* USER CODE END Includes */ - -/* Private typedef -----------------------------------------------------------*/ -/* USER CODE BEGIN TD */ - -/* USER CODE END TD */ - -/* 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 -----------------------------------------------*/ -/* USER CODE BEGIN PFP */ - -/* USER CODE END PFP */ - -/* Private user code ---------------------------------------------------------*/ -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -/* External variables --------------------------------------------------------*/ -extern CAN_HandleTypeDef hcan1; -extern CAN_HandleTypeDef hcan2; -extern TIM_HandleTypeDef htim3; -extern UART_HandleTypeDef huart5; -extern UART_HandleTypeDef huart1; -extern UART_HandleTypeDef huart2; -extern UART_HandleTypeDef huart3; -/* USER CODE BEGIN EV */ - -/* USER CODE END EV */ - -/******************************************************************************/ -/* Cortex-M3 Processor Interruption and Exception Handlers */ -/******************************************************************************/ -/** - * @brief This function handles Non maskable interrupt. - */ -void NMI_Handler(void) -{ - /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ - - /* USER CODE END NonMaskableInt_IRQn 0 */ - /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ - while (1) - { - } - /* USER CODE END NonMaskableInt_IRQn 1 */ -} - -/** - * @brief This function handles Hard fault interrupt. - */ -void HardFault_Handler(void) -{ - /* USER CODE BEGIN HardFault_IRQn 0 */ - - /* USER CODE END HardFault_IRQn 0 */ - while (1) - { - /* USER CODE BEGIN W1_HardFault_IRQn 0 */ - /* USER CODE END W1_HardFault_IRQn 0 */ - } -} - -/** - * @brief This function handles Memory management fault. - */ -void MemManage_Handler(void) -{ - /* USER CODE BEGIN MemoryManagement_IRQn 0 */ - - /* USER CODE END MemoryManagement_IRQn 0 */ - while (1) - { - /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */ - /* USER CODE END W1_MemoryManagement_IRQn 0 */ - } -} - -/** - * @brief This function handles Prefetch fault, memory access fault. - */ -void BusFault_Handler(void) -{ - /* USER CODE BEGIN BusFault_IRQn 0 */ - - /* USER CODE END BusFault_IRQn 0 */ - while (1) - { - /* USER CODE BEGIN W1_BusFault_IRQn 0 */ - /* USER CODE END W1_BusFault_IRQn 0 */ - } -} - -/** - * @brief This function handles Undefined instruction or illegal state. - */ -void UsageFault_Handler(void) -{ - /* USER CODE BEGIN UsageFault_IRQn 0 */ - - /* USER CODE END UsageFault_IRQn 0 */ - while (1) - { - /* USER CODE BEGIN W1_UsageFault_IRQn 0 */ - /* USER CODE END W1_UsageFault_IRQn 0 */ - } -} - -/** - * @brief This function handles System service call via SWI instruction. - */ -void SVC_Handler(void) -{ - /* USER CODE BEGIN SVCall_IRQn 0 */ - - /* USER CODE END SVCall_IRQn 0 */ - /* USER CODE BEGIN SVCall_IRQn 1 */ - - /* USER CODE END SVCall_IRQn 1 */ -} - -/** - * @brief This function handles Debug monitor. - */ -void DebugMon_Handler(void) -{ - /* USER CODE BEGIN DebugMonitor_IRQn 0 */ - - /* USER CODE END DebugMonitor_IRQn 0 */ - /* USER CODE BEGIN DebugMonitor_IRQn 1 */ - - /* USER CODE END DebugMonitor_IRQn 1 */ -} - -/** - * @brief This function handles Pendable request for system service. - */ -void PendSV_Handler(void) -{ - /* USER CODE BEGIN PendSV_IRQn 0 */ - - /* USER CODE END PendSV_IRQn 0 */ - /* USER CODE BEGIN PendSV_IRQn 1 */ - - /* USER CODE END PendSV_IRQn 1 */ -} - -/** - * @brief This function handles System tick timer. - */ -void SysTick_Handler(void) -{ - /* USER CODE BEGIN SysTick_IRQn 0 */ - - /* USER CODE END SysTick_IRQn 0 */ - HAL_IncTick(); - /* USER CODE BEGIN SysTick_IRQn 1 */ - - /* USER CODE END SysTick_IRQn 1 */ -} - -/******************************************************************************/ -/* STM32F1xx Peripheral Interrupt Handlers */ -/* Add here the Interrupt Handlers for the used peripherals. */ -/* For the available peripheral interrupt handler names, */ -/* please refer to the startup file (startup_stm32f1xx.s). */ -/******************************************************************************/ - -/** - * @brief This function handles CAN1 RX0 interrupt. - */ -void CAN1_RX0_IRQHandler(void) -{ - /* USER CODE BEGIN CAN1_RX0_IRQn 0 */ - - /* USER CODE END CAN1_RX0_IRQn 0 */ - HAL_CAN_IRQHandler(&hcan1); - /* USER CODE BEGIN CAN1_RX0_IRQn 1 */ - - /* USER CODE END CAN1_RX0_IRQn 1 */ -} - -/** - * @brief This function handles TIM3 global interrupt. - */ -void TIM3_IRQHandler(void) -{ - /* USER CODE BEGIN TIM3_IRQn 0 */ - - /* USER CODE END TIM3_IRQn 0 */ - HAL_TIM_IRQHandler(&htim3); - /* USER CODE BEGIN TIM3_IRQn 1 */ - - /* USER CODE END TIM3_IRQn 1 */ -} - -/** - * @brief This function handles USART1 global interrupt. - */ -void USART1_IRQHandler(void) -{ - /* USER CODE BEGIN USART1_IRQn 0 */ - - /* USER CODE END USART1_IRQn 0 */ - HAL_UART_IRQHandler(&huart1); - /* USER CODE BEGIN USART1_IRQn 1 */ - - /* USER CODE END USART1_IRQn 1 */ -} - -/** - * @brief This function handles USART2 global interrupt. - */ -void USART2_IRQHandler(void) -{ - /* USER CODE BEGIN USART2_IRQn 0 */ - - /* USER CODE END USART2_IRQn 0 */ - HAL_UART_IRQHandler(&huart2); - /* USER CODE BEGIN USART2_IRQn 1 */ - - /* USER CODE END USART2_IRQn 1 */ -} - -/** - * @brief This function handles USART3 global interrupt. - */ -void USART3_IRQHandler(void) -{ - /* USER CODE BEGIN USART3_IRQn 0 */ - - /* USER CODE END USART3_IRQn 0 */ - HAL_UART_IRQHandler(&huart3); - /* USER CODE BEGIN USART3_IRQn 1 */ - - /* USER CODE END USART3_IRQn 1 */ -} - -/** - * @brief This function handles UART5 global interrupt. - */ -void UART5_IRQHandler(void) -{ - /* USER CODE BEGIN UART5_IRQn 0 */ - - /* USER CODE END UART5_IRQn 0 */ - HAL_UART_IRQHandler(&huart5); - /* USER CODE BEGIN UART5_IRQn 1 */ - - /* USER CODE END UART5_IRQn 1 */ -} - -/** - * @brief This function handles CAN2 TX interrupt. - */ -void CAN2_TX_IRQHandler(void) -{ - /* USER CODE BEGIN CAN2_TX_IRQn 0 */ - - /* USER CODE END CAN2_TX_IRQn 0 */ - HAL_CAN_IRQHandler(&hcan2); - /* USER CODE BEGIN CAN2_TX_IRQn 1 */ - - /* USER CODE END CAN2_TX_IRQn 1 */ -} - -/** - * @brief This function handles CAN2 RX1 interrupt. - */ -void CAN2_RX1_IRQHandler(void) -{ - /* USER CODE BEGIN CAN2_RX1_IRQn 0 */ - - /* USER CODE END CAN2_RX1_IRQn 0 */ - HAL_CAN_IRQHandler(&hcan2); - /* USER CODE BEGIN CAN2_RX1_IRQn 1 */ - - /* USER CODE END CAN2_RX1_IRQn 1 */ -} - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32f1xx_it.c + * @brief Interrupt Service Routines. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "stm32f1xx_it.h" +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +#if defined(__GNUC__) +#pragma GCC optimize("Ofast") +#endif +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN TD */ + +/* USER CODE END TD */ + +/* 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 -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ + +/* 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 UART_HandleTypeDef huart5; +extern UART_HandleTypeDef huart1; +extern UART_HandleTypeDef huart2; +extern UART_HandleTypeDef huart3; +/* USER CODE BEGIN EV */ + +/* USER CODE END EV */ + +/******************************************************************************/ +/* Cortex-M3 Processor Interruption and Exception Handlers */ +/******************************************************************************/ +/** + * @brief This function handles Non maskable interrupt. + */ +void NMI_Handler(void) +{ + /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ + + /* USER CODE END NonMaskableInt_IRQn 0 */ + /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ + while (1) + { + } + /* USER CODE END NonMaskableInt_IRQn 1 */ +} + +/** + * @brief This function handles Hard fault interrupt. + */ +void HardFault_Handler(void) +{ + /* USER CODE BEGIN HardFault_IRQn 0 */ + + /* USER CODE END HardFault_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_HardFault_IRQn 0 */ + /* USER CODE END W1_HardFault_IRQn 0 */ + } +} + +/** + * @brief This function handles Memory management fault. + */ +void MemManage_Handler(void) +{ + /* USER CODE BEGIN MemoryManagement_IRQn 0 */ + + /* USER CODE END MemoryManagement_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */ + /* USER CODE END W1_MemoryManagement_IRQn 0 */ + } +} + +/** + * @brief This function handles Prefetch fault, memory access fault. + */ +void BusFault_Handler(void) +{ + /* USER CODE BEGIN BusFault_IRQn 0 */ + + /* USER CODE END BusFault_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_BusFault_IRQn 0 */ + /* USER CODE END W1_BusFault_IRQn 0 */ + } +} + +/** + * @brief This function handles Undefined instruction or illegal state. + */ +void UsageFault_Handler(void) +{ + /* USER CODE BEGIN UsageFault_IRQn 0 */ + + /* USER CODE END UsageFault_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_UsageFault_IRQn 0 */ + /* USER CODE END W1_UsageFault_IRQn 0 */ + } +} + +/** + * @brief This function handles System service call via SWI instruction. + */ +void SVC_Handler(void) +{ + /* USER CODE BEGIN SVCall_IRQn 0 */ + + /* USER CODE END SVCall_IRQn 0 */ + /* USER CODE BEGIN SVCall_IRQn 1 */ + + /* USER CODE END SVCall_IRQn 1 */ +} + +/** + * @brief This function handles Debug monitor. + */ +void DebugMon_Handler(void) +{ + /* USER CODE BEGIN DebugMonitor_IRQn 0 */ + + /* USER CODE END DebugMonitor_IRQn 0 */ + /* USER CODE BEGIN DebugMonitor_IRQn 1 */ + + /* USER CODE END DebugMonitor_IRQn 1 */ +} + +/** + * @brief This function handles Pendable request for system service. + */ +void PendSV_Handler(void) +{ + /* USER CODE BEGIN PendSV_IRQn 0 */ + + /* USER CODE END PendSV_IRQn 0 */ + /* USER CODE BEGIN PendSV_IRQn 1 */ + + /* USER CODE END PendSV_IRQn 1 */ +} + +/** + * @brief This function handles System tick timer. + */ +void SysTick_Handler(void) +{ + /* USER CODE BEGIN SysTick_IRQn 0 */ + + /* USER CODE END SysTick_IRQn 0 */ + HAL_IncTick(); + /* USER CODE BEGIN SysTick_IRQn 1 */ + + /* USER CODE END SysTick_IRQn 1 */ +} + +/******************************************************************************/ +/* STM32F1xx Peripheral Interrupt Handlers */ +/* Add here the Interrupt Handlers for the used peripherals. */ +/* For the available peripheral interrupt handler names, */ +/* 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 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 */ +} + +/** + * @brief This function handles TIM3 global interrupt. + */ +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 */ +} + +/** + * @brief This function handles USART1 global interrupt. + */ +void USART1_IRQHandler(void) +{ + /* USER CODE BEGIN USART1_IRQn 0 */ + + /* USER CODE END USART1_IRQn 0 */ + HAL_UART_IRQHandler(&huart1); + /* USER CODE BEGIN USART1_IRQn 1 */ + + /* USER CODE END USART1_IRQn 1 */ +} + +/** + * @brief This function handles USART2 global interrupt. + */ +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 */ +} + +/** + * @brief This function handles USART3 global interrupt. + */ +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 */ +} + +/** + * @brief This function handles UART5 global interrupt. + */ +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 */ +} + +/** + * @brief This function handles CAN2 TX interrupt. + */ +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 */ +} + +/** + * @brief This function handles CAN2 RX1 interrupt. + */ +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 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff -ruN /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Src/tim.c /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Src/tim.c --- /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Src/tim.c 2026-03-19 02:09:51 +++ /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Src/tim.c 2026-05-04 17:59:57 @@ -57,31 +57,31 @@ { Error_Handler(); } - if (HAL_TIM_PWM_Init(&htim3) != HAL_OK) + if (HAL_TIM_OC_Init(&htim3) != HAL_OK) { Error_Handler(); } - if (HAL_TIM_OC_Init(&htim3) != HAL_OK) + if (HAL_TIM_PWM_Init(&htim3) != HAL_OK) { Error_Handler(); } - sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + 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(); } diff -ruN /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Startup/startup_stm32f107vctx.s /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Startup/startup_stm32f107vctx.s --- /Users/colorbass/STM32CubeIDE/workspace_1.12.0/CCSModuleSW30Web/Core/Startup/startup_stm32f107vctx.s 2025-12-12 01:47:25 +++ /Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web/Core/Startup/startup_stm32f107vctx.s 2026-04-27 17:45:55 @@ -59,7 +59,6 @@ .weak Reset_Handler .type Reset_Handler, %function Reset_Handler: - ldr sp, =_estack /* set stack pointer */ /* Call the clock system initialization function.*/ bl SystemInit