11 Commits

56 changed files with 36100 additions and 28017 deletions
Vendored
BIN
View File
Binary file not shown.
+17 -15
View File
File diff suppressed because one or more lines are too long
+186 -75
View File
@@ -1,9 +1,26 @@
#MicroXplorer Configuration settings - do not modify #MicroXplorer Configuration settings - do not modify
ADC1.Channel-0\#ChannelRegularConversion=ADC_CHANNEL_8 ADC1.Channel-0\#ChannelRegularConversion=ADC_CHANNEL_3
ADC1.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,NbrOfConversionFlag,master ADC1.Channel-1\#ChannelRegularConversion=ADC_CHANNEL_4
ADC1.Channel-2\#ChannelRegularConversion=ADC_CHANNEL_8
ADC1.Channel-3\#ChannelRegularConversion=ADC_CHANNEL_9
ADC1.Channel-4\#ChannelRegularConversion=ADC_CHANNEL_TEMPSENSOR
ADC1.Channel-5\#ChannelRegularConversion=ADC_CHANNEL_VREFINT
ADC1.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T3_TRGO
ADC1.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,NbrOfConversionFlag,master,Rank-1\#ChannelRegularConversion,Channel-1\#ChannelRegularConversion,SamplingTime-1\#ChannelRegularConversion,Rank-2\#ChannelRegularConversion,Channel-2\#ChannelRegularConversion,SamplingTime-2\#ChannelRegularConversion,Rank-3\#ChannelRegularConversion,Channel-3\#ChannelRegularConversion,SamplingTime-3\#ChannelRegularConversion,Rank-4\#ChannelRegularConversion,Channel-4\#ChannelRegularConversion,SamplingTime-4\#ChannelRegularConversion,Rank-5\#ChannelRegularConversion,Channel-5\#ChannelRegularConversion,SamplingTime-5\#ChannelRegularConversion,NbrOfConversion,ExternalTrigConv
ADC1.NbrOfConversion=6
ADC1.NbrOfConversionFlag=1 ADC1.NbrOfConversionFlag=1
ADC1.Rank-0\#ChannelRegularConversion=1 ADC1.Rank-0\#ChannelRegularConversion=1
ADC1.SamplingTime-0\#ChannelRegularConversion=ADC_SAMPLETIME_1CYCLE_5 ADC1.Rank-1\#ChannelRegularConversion=2
ADC1.Rank-2\#ChannelRegularConversion=3
ADC1.Rank-3\#ChannelRegularConversion=4
ADC1.Rank-4\#ChannelRegularConversion=5
ADC1.Rank-5\#ChannelRegularConversion=6
ADC1.SamplingTime-0\#ChannelRegularConversion=ADC_SAMPLETIME_41CYCLES_5
ADC1.SamplingTime-1\#ChannelRegularConversion=ADC_SAMPLETIME_41CYCLES_5
ADC1.SamplingTime-2\#ChannelRegularConversion=ADC_SAMPLETIME_41CYCLES_5
ADC1.SamplingTime-3\#ChannelRegularConversion=ADC_SAMPLETIME_41CYCLES_5
ADC1.SamplingTime-4\#ChannelRegularConversion=ADC_SAMPLETIME_41CYCLES_5
ADC1.SamplingTime-5\#ChannelRegularConversion=ADC_SAMPLETIME_41CYCLES_5
ADC1.master=1 ADC1.master=1
CAD.formats= CAD.formats=
CAD.pinconfig= CAD.pinconfig=
@@ -30,6 +47,57 @@ CAN2.IPParameters=CalculateTimeQuantum,CalculateTimeBit,CalculateBaudRate,Presca
CAN2.NART=ENABLE CAN2.NART=ENABLE
CAN2.Prescaler=16 CAN2.Prescaler=16
CAN2.TXFP=ENABLE CAN2.TXFP=ENABLE
Dma.ADC1.0.Direction=DMA_PERIPH_TO_MEMORY
Dma.ADC1.0.Instance=DMA1_Channel1
Dma.ADC1.0.MemDataAlignment=DMA_MDATAALIGN_HALFWORD
Dma.ADC1.0.MemInc=DMA_MINC_ENABLE
Dma.ADC1.0.Mode=DMA_CIRCULAR
Dma.ADC1.0.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD
Dma.ADC1.0.PeriphInc=DMA_PINC_DISABLE
Dma.ADC1.0.Priority=DMA_PRIORITY_MEDIUM
Dma.ADC1.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority
Dma.Request0=ADC1
Dma.Request1=USART2_RX
Dma.Request2=USART2_TX
Dma.Request3=USART3_RX
Dma.Request4=USART3_TX
Dma.RequestsNb=5
Dma.USART2_RX.1.Direction=DMA_PERIPH_TO_MEMORY
Dma.USART2_RX.1.Instance=DMA1_Channel6
Dma.USART2_RX.1.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART2_RX.1.MemInc=DMA_MINC_ENABLE
Dma.USART2_RX.1.Mode=DMA_NORMAL
Dma.USART2_RX.1.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART2_RX.1.PeriphInc=DMA_PINC_DISABLE
Dma.USART2_RX.1.Priority=DMA_PRIORITY_VERY_HIGH
Dma.USART2_RX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority
Dma.USART2_TX.2.Direction=DMA_MEMORY_TO_PERIPH
Dma.USART2_TX.2.Instance=DMA1_Channel7
Dma.USART2_TX.2.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART2_TX.2.MemInc=DMA_MINC_ENABLE
Dma.USART2_TX.2.Mode=DMA_NORMAL
Dma.USART2_TX.2.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART2_TX.2.PeriphInc=DMA_PINC_DISABLE
Dma.USART2_TX.2.Priority=DMA_PRIORITY_HIGH
Dma.USART2_TX.2.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority
Dma.USART3_RX.3.Direction=DMA_PERIPH_TO_MEMORY
Dma.USART3_RX.3.Instance=DMA1_Channel3
Dma.USART3_RX.3.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART3_RX.3.MemInc=DMA_MINC_ENABLE
Dma.USART3_RX.3.Mode=DMA_NORMAL
Dma.USART3_RX.3.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART3_RX.3.PeriphInc=DMA_PINC_DISABLE
Dma.USART3_RX.3.Priority=DMA_PRIORITY_VERY_HIGH
Dma.USART3_RX.3.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority
Dma.USART3_TX.4.Direction=DMA_MEMORY_TO_PERIPH
Dma.USART3_TX.4.Instance=DMA1_Channel2
Dma.USART3_TX.4.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART3_TX.4.MemInc=DMA_MINC_ENABLE
Dma.USART3_TX.4.Mode=DMA_NORMAL
Dma.USART3_TX.4.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART3_TX.4.PeriphInc=DMA_PINC_DISABLE
Dma.USART3_TX.4.Priority=DMA_PRIORITY_HIGH
Dma.USART3_TX.4.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority
File.Version=6 File.Version=6
GPIO.groupedBy=Group By Peripherals GPIO.groupedBy=Group By Peripherals
KeepUserPlacement=false KeepUserPlacement=false
@@ -37,86 +105,99 @@ Mcu.CPN=STM32F107VCT6
Mcu.Family=STM32F1 Mcu.Family=STM32F1
Mcu.IP0=ADC1 Mcu.IP0=ADC1
Mcu.IP1=CAN1 Mcu.IP1=CAN1
Mcu.IP10=UART5 Mcu.IP10=TIM4
Mcu.IP11=USART1 Mcu.IP11=UART5
Mcu.IP12=USART2 Mcu.IP12=USART1
Mcu.IP13=USART3 Mcu.IP13=USART2
Mcu.IP14=USART3
Mcu.IP2=CAN2 Mcu.IP2=CAN2
Mcu.IP3=CRC Mcu.IP3=CRC
Mcu.IP4=NVIC Mcu.IP4=DMA
Mcu.IP5=RCC Mcu.IP5=NVIC
Mcu.IP6=RTC Mcu.IP6=RCC
Mcu.IP7=SYS Mcu.IP7=RTC
Mcu.IP8=TIM3 Mcu.IP8=SYS
Mcu.IP9=TIM4 Mcu.IP9=TIM3
Mcu.IPNb=14 Mcu.IPNb=15
Mcu.Name=STM32F107V(B-C)Tx Mcu.Name=STM32F107V(B-C)Tx
Mcu.Package=LQFP100 Mcu.Package=LQFP100
Mcu.Pin0=PC14-OSC32_IN Mcu.Pin0=PC14-OSC32_IN
Mcu.Pin1=PC15-OSC32_OUT Mcu.Pin1=PC15-OSC32_OUT
Mcu.Pin10=PC4 Mcu.Pin10=PA5
Mcu.Pin11=PC5 Mcu.Pin11=PA6
Mcu.Pin12=PB0 Mcu.Pin12=PA7
Mcu.Pin13=PB1 Mcu.Pin13=PC4
Mcu.Pin14=PE7 Mcu.Pin14=PC5
Mcu.Pin15=PE8 Mcu.Pin15=PB0
Mcu.Pin16=PE9 Mcu.Pin16=PB1
Mcu.Pin17=PE10 Mcu.Pin17=PE7
Mcu.Pin18=PE11 Mcu.Pin18=PE8
Mcu.Pin19=PE12 Mcu.Pin19=PE9
Mcu.Pin2=OSC_IN Mcu.Pin2=OSC_IN
Mcu.Pin20=PE14 Mcu.Pin20=PE10
Mcu.Pin21=PD13 Mcu.Pin21=PE11
Mcu.Pin22=PD14 Mcu.Pin22=PE12
Mcu.Pin23=PD15 Mcu.Pin23=PE14
Mcu.Pin24=PA9 Mcu.Pin24=PB10
Mcu.Pin25=PA10 Mcu.Pin25=PB11
Mcu.Pin26=PA13 Mcu.Pin26=PD13
Mcu.Pin27=PA14 Mcu.Pin27=PD14
Mcu.Pin28=PA15 Mcu.Pin28=PD15
Mcu.Pin29=PC10 Mcu.Pin29=PA9
Mcu.Pin3=OSC_OUT Mcu.Pin3=OSC_OUT
Mcu.Pin30=PC11 Mcu.Pin30=PA10
Mcu.Pin31=PC12 Mcu.Pin31=PA13
Mcu.Pin32=PD0 Mcu.Pin32=PA14
Mcu.Pin33=PD1 Mcu.Pin33=PA15
Mcu.Pin34=PD2 Mcu.Pin34=PC10
Mcu.Pin35=PD3 Mcu.Pin35=PC11
Mcu.Pin36=PD4 Mcu.Pin36=PC12
Mcu.Pin37=PD5 Mcu.Pin37=PD0
Mcu.Pin38=PD6 Mcu.Pin38=PD1
Mcu.Pin39=PD7 Mcu.Pin39=PD2
Mcu.Pin4=PC3 Mcu.Pin4=PC2
Mcu.Pin40=PB3 Mcu.Pin40=PD3
Mcu.Pin41=PB4 Mcu.Pin41=PD4
Mcu.Pin42=PB5 Mcu.Pin42=PD5
Mcu.Pin43=PB6 Mcu.Pin43=PD6
Mcu.Pin44=PB7 Mcu.Pin44=PD7
Mcu.Pin45=PB8 Mcu.Pin45=PB3
Mcu.Pin46=PB9 Mcu.Pin46=PB4
Mcu.Pin47=PE1 Mcu.Pin47=PB5
Mcu.Pin48=VP_ADC1_TempSens_Input Mcu.Pin48=PB6
Mcu.Pin49=VP_ADC1_Vref_Input Mcu.Pin49=PB7
Mcu.Pin5=PA1 Mcu.Pin5=PC3
Mcu.Pin50=VP_CRC_VS_CRC Mcu.Pin50=PB8
Mcu.Pin51=VP_RTC_VS_RTC_Activate Mcu.Pin51=PB9
Mcu.Pin52=VP_SYS_VS_Systick Mcu.Pin52=PE1
Mcu.Pin53=VP_TIM3_VS_ClockSourceINT Mcu.Pin53=VP_ADC1_TempSens_Input
Mcu.Pin54=VP_TIM4_VS_ClockSourceINT Mcu.Pin54=VP_ADC1_Vref_Input
Mcu.Pin6=PA2 Mcu.Pin55=VP_CRC_VS_CRC
Mcu.Pin7=PA3 Mcu.Pin56=VP_RTC_VS_RTC_Activate
Mcu.Pin8=PA4 Mcu.Pin57=VP_SYS_VS_Systick
Mcu.Pin9=PA7 Mcu.Pin58=VP_TIM3_VS_ClockSourceINT
Mcu.PinsNb=55 Mcu.Pin59=VP_TIM3_VS_no_output1
Mcu.Pin6=PA1
Mcu.Pin60=VP_TIM4_VS_ClockSourceINT
Mcu.Pin7=PA2
Mcu.Pin8=PA3
Mcu.Pin9=PA4
Mcu.PinsNb=61
Mcu.ThirdPartyNb=0 Mcu.ThirdPartyNb=0
Mcu.UserConstants= Mcu.UserConstants=
Mcu.UserName=STM32F107VCTx Mcu.UserName=STM32F107VCTx
MxCube.Version=6.15.0 MxCube.Version=6.15.0
MxDb.Version=DB.6.0.150 MxDb.Version=DB.6.0.150
NVIC.ADC1_2_IRQn=true\:7\:0\:true\:false\:true\:true\:true\:true
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.CAN1_RX0_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true NVIC.CAN1_RX0_IRQn=true\:3\:0\:true\:false\:true\:true\:true\:true
NVIC.CAN2_RX1_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true NVIC.CAN2_RX1_IRQn=true\:3\:0\:true\:false\:true\:true\:true\:true
NVIC.CAN2_TX_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true NVIC.CAN2_TX_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.DMA1_Channel1_IRQn=true\:1\:0\:true\:false\:true\:false\:true\:true
NVIC.DMA1_Channel2_IRQn=true\:4\:0\:true\:false\:true\:false\:true\:true
NVIC.DMA1_Channel3_IRQn=true\:1\:0\:true\:false\:true\:false\:true\:true
NVIC.DMA1_Channel6_IRQn=true\:1\:0\:true\:false\:true\:false\:true\:true
NVIC.DMA1_Channel7_IRQn=true\:4\:0\:true\:false\:true\:false\:true\:true
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.ForceEnableDMAVector=true NVIC.ForceEnableDMAVector=true
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
@@ -126,11 +207,11 @@ NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false
NVIC.TIM3_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true NVIC.TIM3_IRQn=true\:6\:0\:true\:false\:true\:true\:true\:true
NVIC.UART5_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true NVIC.UART5_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true
NVIC.USART1_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true NVIC.USART1_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true
NVIC.USART2_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true NVIC.USART2_IRQn=true\:2\:0\:true\:false\:true\:true\:true\:true
NVIC.USART3_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true NVIC.USART3_IRQn=true\:2\:0\:true\:false\:true\:true\:true\:true
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
OSC_IN.Mode=HSE-External-Oscillator OSC_IN.Mode=HSE-External-Oscillator
OSC_IN.Signal=RCC_OSC_IN OSC_IN.Signal=RCC_OSC_IN
@@ -162,6 +243,16 @@ PA4.GPIOParameters=GPIO_Label
PA4.GPIO_Label=CP_ADC PA4.GPIO_Label=CP_ADC
PA4.Locked=true PA4.Locked=true
PA4.Signal=ADCx_IN4 PA4.Signal=ADCx_IN4
PA5.GPIOParameters=GPIO_Speed,GPIO_Label
PA5.GPIO_Label=DBG2
PA5.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
PA5.Locked=true
PA5.Signal=GPIO_Output
PA6.GPIOParameters=GPIO_Speed,GPIO_Label
PA6.GPIO_Label=DBG3
PA6.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
PA6.Locked=true
PA6.Signal=GPIO_Output
PA7.GPIOParameters=GPIO_Label PA7.GPIOParameters=GPIO_Label
PA7.GPIO_Label=CP_PWM PA7.GPIO_Label=CP_PWM
PA7.Locked=true PA7.Locked=true
@@ -177,6 +268,16 @@ PB1.GPIOParameters=GPIO_Label
PB1.GPIO_Label=ADC_NTC2 PB1.GPIO_Label=ADC_NTC2
PB1.Locked=true PB1.Locked=true
PB1.Signal=ADCx_IN9 PB1.Signal=ADCx_IN9
PB10.GPIOParameters=GPIO_Speed,GPIO_Label
PB10.GPIO_Label=DBG5
PB10.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
PB10.Locked=true
PB10.Signal=GPIO_Output
PB11.GPIOParameters=GPIO_Speed,GPIO_Label
PB11.GPIO_Label=DBG4
PB11.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
PB11.Locked=true
PB11.Signal=GPIO_Output
PB3.GPIOParameters=GPIO_Label PB3.GPIOParameters=GPIO_Label
PB3.GPIO_Label=IN_FB2 PB3.GPIO_Label=IN_FB2
PB3.Locked=true PB3.Locked=true
@@ -211,6 +312,11 @@ PC14-OSC32_IN.Mode=LSE-External-Oscillator
PC14-OSC32_IN.Signal=RCC_OSC32_IN PC14-OSC32_IN.Signal=RCC_OSC32_IN
PC15-OSC32_OUT.Mode=LSE-External-Oscillator PC15-OSC32_OUT.Mode=LSE-External-Oscillator
PC15-OSC32_OUT.Signal=RCC_OSC32_OUT PC15-OSC32_OUT.Signal=RCC_OSC32_OUT
PC2.GPIOParameters=GPIO_Speed,GPIO_Label
PC2.GPIO_Label=DBG1
PC2.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
PC2.Locked=true
PC2.Signal=GPIO_Output
PC3.GPIOParameters=GPIO_Label PC3.GPIOParameters=GPIO_Label
PC3.GPIO_Label=RELAY_CP PC3.GPIO_Label=RELAY_CP
PC3.Locked=true PC3.Locked=true
@@ -320,7 +426,7 @@ ProjectManager.ToolChainLocation=
ProjectManager.UAScriptAfterPath= ProjectManager.UAScriptAfterPath=
ProjectManager.UAScriptBeforePath= ProjectManager.UAScriptBeforePath=
ProjectManager.UnderRoot=true ProjectManager.UnderRoot=true
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_ADC1_Init-ADC1-false-HAL-true,4-MX_CAN1_Init-CAN1-false-HAL-true,5-MX_CAN2_Init-CAN2-false-HAL-true,6-MX_RTC_Init-RTC-false-HAL-true,7-MX_TIM4_Init-TIM4-false-HAL-true,8-MX_USART2_UART_Init-USART2-false-HAL-true,9-MX_CRC_Init-CRC-false-HAL-true,10-MX_UART5_Init-UART5-false-HAL-true,11-MX_USART1_UART_Init-USART1-false-HAL-true,12-MX_USART3_UART_Init-USART3-false-HAL-true,13-MX_TIM3_Init-TIM3-false-HAL-true ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_ADC1_Init-ADC1-false-HAL-true,5-MX_CAN1_Init-CAN1-false-HAL-true,6-MX_CAN2_Init-CAN2-false-HAL-true,7-MX_RTC_Init-RTC-false-HAL-true,8-MX_TIM4_Init-TIM4-false-HAL-true,9-MX_USART2_UART_Init-USART2-false-HAL-true,10-MX_CRC_Init-CRC-false-HAL-true,11-MX_UART5_Init-UART5-false-HAL-true,12-MX_USART1_UART_Init-USART1-false-HAL-true,13-MX_USART3_UART_Init-USART3-false-HAL-true,14-MX_TIM3_Init-TIM3-false-HAL-true
RCC.ADCFreqValue=12000000 RCC.ADCFreqValue=12000000
RCC.ADCPresc=RCC_ADCPCLK2_DIV6 RCC.ADCPresc=RCC_ADCPCLK2_DIV6
RCC.AHBFreq_Value=72000000 RCC.AHBFreq_Value=72000000
@@ -371,8 +477,11 @@ SH.S_TIM4_CH3.0=TIM4_CH3,PWM Generation3 CH3
SH.S_TIM4_CH3.ConfNb=1 SH.S_TIM4_CH3.ConfNb=1
SH.S_TIM4_CH4.0=TIM4_CH4,PWM Generation4 CH4 SH.S_TIM4_CH4.0=TIM4_CH4,PWM Generation4 CH4
SH.S_TIM4_CH4.ConfNb=1 SH.S_TIM4_CH4.ConfNb=1
TIM3.Channel-Output\ Compare1\ No\ Output=TIM_CHANNEL_1
TIM3.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2 TIM3.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2
TIM3.IPParameters=Channel-PWM Generation2 CH2 TIM3.IPParameters=Channel-PWM Generation2 CH2,TIM_MasterOutputTrigger,Channel-Output Compare1 No Output,Pulse-Output Compare1 No Output
TIM3.Pulse-Output\ Compare1\ No\ Output=1
TIM3.TIM_MasterOutputTrigger=TIM_TRGO_OC1
TIM4.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2 TIM4.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2
TIM4.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3 TIM4.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3
TIM4.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4 TIM4.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4
@@ -400,6 +509,8 @@ VP_SYS_VS_Systick.Mode=SysTick
VP_SYS_VS_Systick.Signal=SYS_VS_Systick VP_SYS_VS_Systick.Signal=SYS_VS_Systick
VP_TIM3_VS_ClockSourceINT.Mode=Internal VP_TIM3_VS_ClockSourceINT.Mode=Internal
VP_TIM3_VS_ClockSourceINT.Signal=TIM3_VS_ClockSourceINT VP_TIM3_VS_ClockSourceINT.Signal=TIM3_VS_ClockSourceINT
VP_TIM3_VS_no_output1.Mode=Output Compare1 No Output
VP_TIM3_VS_no_output1.Signal=TIM3_VS_no_output1
VP_TIM4_VS_ClockSourceINT.Mode=Internal VP_TIM4_VS_ClockSourceINT.Mode=Internal
VP_TIM4_VS_ClockSourceINT.Signal=TIM4_VS_ClockSourceINT VP_TIM4_VS_ClockSourceINT.Signal=TIM4_VS_ClockSourceINT
board=custom board=custom
+133
View File
@@ -0,0 +1,133 @@
# Журнал изменений (сессия чата): `fork/CCSModuleSW30Web`
Документ фиксирует доработки проекта **CCSModuleSW30Web** в ветке/каталоге форка
`/Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web`, обсуждавшиеся и вносившиеся в рамках описанной сессии (UART, ADC/DMA, CP, отладка IRQ, оптимизация `-Ofast` для кода из прерываний).
---
## 1. UART и протокол
### 1.1. UART3 (Everest / `serial.c`)
- Таймаут «нет связи с хостом»:** `EVEREST_TIMEOUT_MS` = **5000** мс.
- Жёсткий реинициал при отсутствии RX:** `UART3_REINIT_TIMEOUT_MS` = **1500** мс (с защитой от слишком частых реинициалов через `uart3_last_reinit_tick`).
- Расширено логирование путей сброса/ошибок приёма и ошибок HAL для диагностики «таймаут без остановки UART3».
- Колбэки и вспомогательные функции, вызываемые из контекста прерывания, помечены **`ISR_FAST`** (см. раздел 6):
`CCS_RxEventCallback`, `HAL_UART_ErrorCallback`, `uart3_log_hal_error`, `uart3_arm_rx_or_log`, цепочка разбора пакета (`process_received_packet`, `crc16_ibm`, `expected_payload_len`, `apply_command`).
### 1.2. UART2 / `serial_control.c`
- Отдельная логика **`SC_UART2_Watchdog()`**, вызывается из **`SC_Task()`** (не из IRQ).
- Константы:
- **`SC_UART2_REINIT_TIMEOUT_MS`** = **500** мс — порог для жёсткого реинициала при отсутствии пакетов;
- **`SC_UART2_PACKET_TIMEOUT_MS`** = **5000** мс — таймаут коммуникации.
- Сценарий **новый пакет при `BUSY_TX`**: при необходимости **`Abort_IT`**, сброс направления RS-485, затем повторная инициализация UART и приём `ReceiveToIdle_IT` (защита от обрыва TX из-за агрессивного watchdog).
- Отдельная ветка **жёсткого реинициала при `BUSY_TX`** с логом `USART2 BUSY_TX: hard reinit` (отслеживание `sc_uart2_last_busy_tx_reinit_packet_tick`).
- HAL-колбэки **`HAL_UARTEx_RxEventCallback`**, **`HAL_UART_TxCpltCallback`** помечены **`ISR_FAST`**.
### 1.3. `SC_SendPacket` и стек CRC/кодирования
- Для единообразной оптимизации пути «IRQ → ответ» на функции **`calculate_crc32`**, **`encode_packet`**, **`parse_packet`**, **`process_received_packet`** и публичную **`SC_SendPacket`** добавлен **`ISR_FAST`**.
- В **`Core/Inc/serial_control.h`**: подключение **`isr_opt.h`**, прототип **`ISR_FAST void SC_SendPacket(...)`** (согласованность с определением в `.c`).
**Замечание:** `SC_SendPacket` вызывается и из основного потока; для GCC вся функция компилируется с `-Ofast`. При необходимости строгого разделения можно вынести отдельную версию «только из IRQ».
---
## 2. Отладочные линии DBG в `stm32f1xx_it.c`
На время входа/выхода из выбранных обработчиков прерываний поднимается/опускается соответствующий GPIO — удобно для осциллографа (длительность IRQ).
| Линия | Обработчик |
|--------|------------|
| **DBG1** | `UART5_IRQHandler` |
| **DBG2** | `USART2_IRQHandler` |
| **DBG3** | `USART3_IRQHandler` |
| **DBG4** | `DMA1_Channel1_IRQHandler`, `ADC1_2_IRQHandler`, `TIM3_IRQHandler` |
| **DBG5** | `CAN1_RX0_IRQHandler`, `CAN2_TX_IRQHandler`, `CAN2_RX1_IRQHandler` |
| — | `USART1_IRQHandler` — без обёртки DBG (по согласованию) |
В **`DMA1_Channel1_IRQHandler`** вызывается **`HAL_DMA_IRQHandler(&hdma_adc1)`** для цепочки ADC+DMA.
Для всего файла **`stm32f1xx_it.c`** под GCC добавлено:
```c
#pragma GCC optimize("Ofast")
```
(в блоке `USER CODE BEGIN Includes`).
---
## 3. ADC: DMA, глобальные данные, колбэк
- Файлы **`adc.c` / `adc.h`**: структура **`ADC_ScanData_t`**, глобально **`volatile ADC_ScanData_t adc_data`** с полями сырых каналов (`in3_raw`, `cp_raw`, `ntc1_raw`, `ntc2_raw`, `temp_sensor_raw`, `vrefint_raw` и т.д. по фактическому объявлению в заголовке).
- **`HAL_ADC_ConvCpltCallback`**: копирование из буфера DMA в **`adc_data`**, помечен **`ISR_FAST`**.
- Публичная **`ADC_ScanStart()`** — запуск сканирования (после калибровки вызывается из инициализации платы).
- **`board.c`**: после **`HAL_ADCEx_Calibration_Start`** вызывается **`ADC_ScanStart()`**; **`CONN_ReadTemp`** читает **`adc_data.ntc1_raw` / `ntc2_raw`** вместо блокирующего опроса ADC.
**Диагностика (из обсуждения):** если не вызываются **`HAL_ADC_ConvCpltCallback`** / **`HAL_DMA_IRQHandler`**, проверять: срабатывание триггера ADC (например, **TIM3 TRGO**), работу TIM3, порядок инициализации DMA/NVIC, срабатывание **`DMA1_Channel1_IRQHandler`**.
---
## 4. CP (`cp.c` / `cp.h`)
- Измерение опоры на **`adc_data.cp_raw`** (и при необходимости **`vrefint_raw`** по текущей реализации в коде).
- Логика классификации/порогов приведена к варианту, согласованному с основным **CCSModuleSW30Web** (не форк).
- Сэмпл по таймеру: уход от тяжёлой работы в IRQ OC — использование **`HAL_TIM_OC_Start`** без прерывания по сравнению, обновление напряжения в **`CP_GetVoltage()`** / основном цикле (**`CP_Loop`** опирается на **`CP_GetState()`** и т.п. по фактическому коду).
---
## 5. Отладочный UART (`debug.c`)
При **`#ifndef USE_WEB_INTERFACE`** (или эквивалентной ветке сборки в файле): колбэк **`HAL_UARTEx_RxEventCallback`** и **`debug_rx_interrupt`** помечены **`ISR_FAST`**.
---
## 6. Оптимизация `-Ofast` для кода из прерываний
### 6.1. Макрос `ISR_FAST`
Файл **`Core/Inc/isr_opt.h`**:
- **GCC:** `#define ISR_FAST __attribute__((optimize("Ofast")))`
- **Иное:** пустой макрос.
### 6.2. Где используется (по состоянию репозитория)
| Файл | Элементы с `ISR_FAST` / pragma |
|------|--------------------------------|
| `stm32f1xx_it.c` | `#pragma GCC optimize("Ofast")` на весь файл (GCC) |
| `adc.c` | `HAL_ADC_ConvCpltCallback` |
| `serial.c` | `CCS_RxEventCallback`, `HAL_UART_ErrorCallback`, `uart3_log_hal_error`, `uart3_arm_rx_or_log`, `process_received_packet`, `crc16_ibm`, `expected_payload_len`, `apply_command` |
| `serial_control.c` | `HAL_UARTEx_RxEventCallback`, `HAL_UART_TxCpltCallback`, `calculate_crc32`, `encode_packet`, `parse_packet`, `process_received_packet`, `SC_SendPacket` |
| `serial_control.h` | прототип `SC_SendPacket` + `#include "isr_opt.h"` |
| `psu_control.c` | `HAL_CAN_RxFifo1MsgPendingCallback` |
| `debug.c` | см. раздел 5 |
---
## 7. Ограничения и переносимость
- **`ISR_FAST`** и pragma в **`stm32f1xx_it.c`** рассчитаны на **GCC** (STM32CubeIDE по умолчанию). Для **IAR / ARM Compiler 6** потребуется отдельная стратегия (прагмы/ключи проекта).
- **`-Ofast`** допускает агрессивные преобразования с плавающей точкой и перестановки, влияющие на строго воспроизводимую арифметику; для критичных вычислений вне IRQ при необходимости ограничивайте область оптимизации.
---
## 8. Затронутые пути (краткий список)
- `Core/Inc/isr_opt.h` — новый/центральный заголовок оптимизации IRQ.
- `Core/Inc/serial_control.h``isr_opt.h`, `ISR_FAST` у `SC_SendPacket`.
- `Core/Src/stm32f1xx_it.c` — DBG, DMA ADC, pragma `Ofast`.
- `Core/Src/adc.c`, `Core/Inc/adc.h` — DMA, `adc_data`, `ADC_ScanStart`, колбэк.
- `Core/Src/board.c` — калибровка, старт скана, температура из `adc_data`.
- `Core/Src/cp.c`, `Core/Inc/cp.h` — CP и ADC.
- `Core/Src/serial.c` — UART3, таймауты, логи, `ISR_FAST`.
- `Core/Src/serial_control.c` — UART2, watchdog, `ISR_FAST`.
- `Core/Src/psu_control.c` — CAN RX callback.
- `Core/Src/debug.c` — отладочный UART под условием сборки.
- `Core/Src/dma.c`, `gpio.c`, `main.h` — по необходимости для DMA1 Ch1 и DBG-пинов.
---
*Документ сгенерирован для фиксации контекста сессии; при дальнейших правках кода имеет смысл обновлять соответствующие разделы вручную.*
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Executable → Regular
+11
View File
@@ -29,18 +29,29 @@ extern "C" {
#include "main.h" #include "main.h"
/* USER CODE BEGIN Includes */ /* USER CODE BEGIN Includes */
#include <stdint.h>
/* USER CODE END Includes */ /* USER CODE END Includes */
extern ADC_HandleTypeDef hadc1; extern ADC_HandleTypeDef hadc1;
/* USER CODE BEGIN Private defines */ /* 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 */ /* USER CODE END Private defines */
void MX_ADC1_Init(void); void MX_ADC1_Init(void);
/* USER CODE BEGIN Prototypes */ /* USER CODE BEGIN Prototypes */
void ADC_ScanStart(void);
/* USER CODE END Prototypes */ /* USER CODE END Prototypes */
+2 -1
View File
@@ -55,7 +55,8 @@ typedef struct __attribute__((packed)) {
uint8_t stationType; // Байт 4: тип станции uint8_t stationType; // Байт 4: тип станции
uint8_t boardVersion; // Байт 5: версия платы uint8_t boardVersion; // Байт 5: версия платы
uint8_t addrEdcan; // Байт 6: адрес EDCAN uint8_t addrEdcan; // Байт 6: адрес EDCAN
uint8_t reserved[57]; // Байты 7-63: зарезервированы uint8_t maxPower; // Байт 7: максимальная мощность станции (5кВт/bit)
uint8_t reserved[56]; // Байты 8-63: зарезервированы
} InfoBlock_t; } InfoBlock_t;
extern InfoBlock_t *InfoBlock; extern InfoBlock_t *InfoBlock;
+4
View File
@@ -16,11 +16,15 @@ typedef enum {
EV_STATE_ACQUIRING = 6, EV_STATE_ACQUIRING = 6,
} CP_State_t; } CP_State_t;
extern CP_State_t cp_state_buffer;
void CP_Init(void); void CP_Init(void);
void CP_SetDuty(uint8_t percentage); void CP_SetDuty(uint8_t percentage);
uint8_t CP_GetDuty(void); uint8_t CP_GetDuty(void);
int32_t CP_GetVoltage(void); int32_t CP_GetVoltage(void);
CP_State_t CP_GetState(void); CP_State_t CP_GetState(void);
CP_State_t CP_GetFilteredState(void);
void CP_FilterState(void);
void CP_Loop(void); void CP_Loop(void);
#endif #endif
+52
View File
@@ -0,0 +1,52 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file dma.h
* @brief This file contains all the function prototypes for
* the dma.c file
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __DMA_H__
#define __DMA_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* DMA memory to memory transfer handles -------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_DMA_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __DMA_H__ */
+11
View File
@@ -0,0 +1,11 @@
#ifndef ISR_OPT_H
#define ISR_OPT_H
/* GCC: быстрые функции, вызываемые из IRQ / из HAL из IRQ-контекста */
#if defined(__GNUC__)
#define ISR_FAST __attribute__((optimize("Ofast")))
#else
#define ISR_FAST
#endif
#endif /* ISR_OPT_H */
+13 -3
View File
@@ -41,9 +41,9 @@ extern "C" {
/* Exported constants --------------------------------------------------------*/ /* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */ /* USER CODE BEGIN EC */
#define FW_VERSION_MAJOR 0x01 #define FW_VERSION_MAJOR 1
#define FW_VERSION_MINOR 0x00 #define FW_VERSION_MINOR 0
#define FW_VERSION_PATCH 0x02 #define FW_VERSION_PATCH 17
/* USER CODE END EC */ /* USER CODE END EC */
/* Exported macro ------------------------------------------------------------*/ /* Exported macro ------------------------------------------------------------*/
@@ -59,6 +59,8 @@ void Error_Handler(void);
/* USER CODE END EFP */ /* USER CODE END EFP */
/* Private defines -----------------------------------------------------------*/ /* Private defines -----------------------------------------------------------*/
#define DBG1_Pin GPIO_PIN_2
#define DBG1_GPIO_Port GPIOC
#define RELAY_CP_Pin GPIO_PIN_3 #define RELAY_CP_Pin GPIO_PIN_3
#define RELAY_CP_GPIO_Port GPIOC #define RELAY_CP_GPIO_Port GPIOC
#define IN_SW0_Pin GPIO_PIN_1 #define IN_SW0_Pin GPIO_PIN_1
@@ -67,6 +69,10 @@ void Error_Handler(void);
#define IN_SW1_GPIO_Port GPIOA #define IN_SW1_GPIO_Port GPIOA
#define CP_ADC_Pin GPIO_PIN_4 #define CP_ADC_Pin GPIO_PIN_4
#define CP_ADC_GPIO_Port GPIOA #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_Pin GPIO_PIN_7
#define CP_PWM_GPIO_Port GPIOA #define CP_PWM_GPIO_Port GPIOA
#define LOCK_A_Pin GPIO_PIN_4 #define LOCK_A_Pin GPIO_PIN_4
@@ -91,6 +97,10 @@ void Error_Handler(void);
#define RELAY5_GPIO_Port GPIOE #define RELAY5_GPIO_Port GPIOE
#define AC_OK_Pin GPIO_PIN_14 #define AC_OK_Pin GPIO_PIN_14
#define AC_OK_GPIO_Port GPIOE #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_Pin GPIO_PIN_15
#define RELAY_CC_GPIO_Port GPIOA #define RELAY_CC_GPIO_Port GPIOA
#define RELAY_DC_Pin GPIO_PIN_3 #define RELAY_DC_Pin GPIO_PIN_3
+1
View File
@@ -88,6 +88,7 @@ typedef struct {
// Дополнительные параметры для одного модуля DC30 // Дополнительные параметры для одного модуля DC30
uint32_t power_limit; // лимит мощности [кВт] uint32_t power_limit; // лимит мощности [кВт]
uint8_t hv_mode; // HV-режим (ограничение напряжения) uint8_t hv_mode; // HV-режим (ограничение напряжения)
uint32_t hv_tick; // таймер для задержки входа в HV-режим
uint32_t tempAmbient; // температура окружающего воздуха (из PSU_04) uint32_t tempAmbient; // температура окружающего воздуха (из PSU_04)
union { uint8_t raw; PSU_Status0_t bits; } status0; // modularForm0 union { uint8_t raw; PSU_Status0_t bits; } status0; // modularForm0
+8 -5
View File
@@ -11,13 +11,16 @@ void CCS_Init(void);
void CCS_SendEmergencyStop(void); void CCS_SendEmergencyStop(void);
void CCS_SendStart(void); void CCS_SendStart(void);
void CCS_RxEventCallback(UART_HandleTypeDef *huart, uint16_t size); void CCS_RxEventCallback(UART_HandleTypeDef *huart, uint16_t size);
void CCS_TxCpltCallback(UART_HandleTypeDef *huart);
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart);
typedef enum { typedef enum {
CCS_DISABLED = 0, CCS_UNKNOWN = 0,
CCS_UNPLUGGED = 1, CCS_DISABLED = 1,
CCS_AUTH_REQUIRED = 2, CCS_UNPLUGGED = 2,
CCS_CONNECTED = 3, CCS_AUTH_REQUIRED = 3,
CCS_REPLUGGING = 4, CCS_CONNECTED = 4,
CCS_REPLUGGING = 5,
} CCS_ConnectorState_t; } CCS_ConnectorState_t;
typedef enum { typedef enum {
+3 -1
View File
@@ -4,6 +4,7 @@
#include "main.h" #include "main.h"
#include <string.h> #include <string.h>
#include "charger_control.h" #include "charger_control.h"
#include "isr_opt.h"
#define USE_WEB_INTERFACE #define USE_WEB_INTERFACE
@@ -168,7 +169,8 @@ struct SerialControl_t {
// Публичные методы // Публичные методы
void SC_Init(); void SC_Init();
void SC_Task(); void SC_Task();
void SC_SendPacket(const uint8_t* payload, uint16_t payload_len, uint8_t response_code); ISR_FAST void SC_SendPacket(const uint8_t* payload, uint16_t payload_len, uint8_t response_code);
void SC_RecoverUartDma(UART_HandleTypeDef *huart);
// Внешняя функция обработки команд (определена в serial_handler.c) // Внешняя функция обработки команд (определена в serial_handler.c)
extern void SC_CommandHandler(ReceivedCommand_t* cmd); extern void SC_CommandHandler(ReceivedCommand_t* cmd);
+1 -1
View File
@@ -42,7 +42,7 @@
/*#define HAL_CORTEX_MODULE_ENABLED */ /*#define HAL_CORTEX_MODULE_ENABLED */
#define HAL_CRC_MODULE_ENABLED #define HAL_CRC_MODULE_ENABLED
/*#define HAL_DAC_MODULE_ENABLED */ /*#define HAL_DAC_MODULE_ENABLED */
/*#define HAL_DMA_MODULE_ENABLED */ #define HAL_DMA_MODULE_ENABLED
/*#define HAL_ETH_MODULE_ENABLED */ /*#define HAL_ETH_MODULE_ENABLED */
/*#define HAL_FLASH_MODULE_ENABLED */ /*#define HAL_FLASH_MODULE_ENABLED */
#define HAL_GPIO_MODULE_ENABLED #define HAL_GPIO_MODULE_ENABLED
+6
View File
@@ -55,6 +55,12 @@ void SVC_Handler(void);
void DebugMon_Handler(void); void DebugMon_Handler(void);
void PendSV_Handler(void); void PendSV_Handler(void);
void SysTick_Handler(void); void SysTick_Handler(void);
void DMA1_Channel1_IRQHandler(void);
void DMA1_Channel2_IRQHandler(void);
void DMA1_Channel3_IRQHandler(void);
void DMA1_Channel6_IRQHandler(void);
void DMA1_Channel7_IRQHandler(void);
void ADC1_2_IRQHandler(void);
void CAN1_RX0_IRQHandler(void); void CAN1_RX0_IRQHandler(void);
void TIM3_IRQHandler(void); void TIM3_IRQHandler(void);
void USART1_IRQHandler(void); void USART1_IRQHandler(void);
BIN
View File
Binary file not shown.
+104 -5
View File
@@ -21,10 +21,39 @@
#include "adc.h" #include "adc.h"
/* USER CODE BEGIN 0 */ /* 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 */ /* USER CODE END 0 */
ADC_HandleTypeDef hadc1; ADC_HandleTypeDef hadc1;
DMA_HandleTypeDef hdma_adc1;
/* ADC1 init function */ /* ADC1 init function */
void MX_ADC1_Init(void) void MX_ADC1_Init(void)
@@ -43,12 +72,12 @@ void MX_ADC1_Init(void)
/** Common config /** Common config
*/ */
hadc1.Instance = ADC1; hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE; hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc1.Init.ContinuousConvMode = DISABLE; hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE; hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T3_TRGO;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1; hadc1.Init.NbrOfConversion = 6;
if (HAL_ADC_Init(&hadc1) != HAL_OK) if (HAL_ADC_Init(&hadc1) != HAL_OK)
{ {
Error_Handler(); Error_Handler();
@@ -56,9 +85,54 @@ void MX_ADC1_Init(void)
/** Configure Regular Channel /** Configure Regular Channel
*/ */
sConfig.Channel = ADC_CHANNEL_8; sConfig.Channel = ADC_CHANNEL_3;
sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5; sConfig.SamplingTime = ADC_SAMPLETIME_41CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_4;
sConfig.Rank = ADC_REGULAR_RANK_2;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_8;
sConfig.Rank = ADC_REGULAR_RANK_3;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_9;
sConfig.Rank = ADC_REGULAR_RANK_4;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
sConfig.Rank = ADC_REGULAR_RANK_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_VREFINT;
sConfig.Rank = ADC_REGULAR_RANK_6;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{ {
Error_Handler(); Error_Handler();
@@ -97,6 +171,26 @@ void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* ADC1 DMA Init */
/* ADC1 Init */
hdma_adc1.Instance = DMA1_Channel1;
hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_adc1.Init.Mode = DMA_CIRCULAR;
hdma_adc1.Init.Priority = DMA_PRIORITY_MEDIUM;
if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc1);
/* ADC1 interrupt Init */
HAL_NVIC_SetPriority(ADC1_2_IRQn, 7, 0);
HAL_NVIC_EnableIRQ(ADC1_2_IRQn);
/* USER CODE BEGIN ADC1_MspInit 1 */ /* USER CODE BEGIN ADC1_MspInit 1 */
/* USER CODE END ADC1_MspInit 1 */ /* USER CODE END ADC1_MspInit 1 */
@@ -124,6 +218,11 @@ void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle)
HAL_GPIO_DeInit(GPIOB, ADC_NTC1_Pin|ADC_NTC2_Pin); 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 BEGIN ADC1_MspDeInit 1 */
/* USER CODE END ADC1_MspDeInit 1 */ /* USER CODE END ADC1_MspDeInit 1 */
+6 -23
View File
@@ -1,11 +1,10 @@
#include "main.h" #include "main.h"
#include "board.h" #include "board.h"
#include "adc.h"
#include "tim.h" #include "tim.h"
#include "sma_filter.h" #include "sma_filter.h"
extern ADC_HandleTypeDef hadc1;
//TODO: //TODO:
//TEMP READ //TEMP READ
// Connector temperature sensors // Connector temperature sensors
@@ -89,14 +88,15 @@ uint8_t GetBoardTemp(){
void Init_Peripheral(){ void Init_Peripheral(){
HAL_ADCEx_Calibration_Start(&hadc1); HAL_ADCEx_Calibration_Start(&hadc1);
ADC_ScanStart();
RELAY_Write(RELAY_AUX0, 0); RELAY_Write(RELAY_AUX0, 0);
RELAY_Write(RELAY_AUX1, 0); RELAY_Write(RELAY_AUX1, 0);
RELAY_Write(RELAY3, 0); RELAY_Write(RELAY3, 0);
RELAY_Write(RELAY_DC, 0); RELAY_Write(RELAY_DC, 0);
RELAY_Write(RELAY_AC, 0); RELAY_Write(RELAY_AC, 0);
RELAY_Write(RELAY_CP, 1); RELAY_Write(RELAY_CP, 0);
RELAY_Write(RELAY_CC, 1); RELAY_Write(RELAY_CC, 0);
RELAY_Write(RELAY_DC1, 0); RELAY_Write(RELAY_DC1, 0);
SMAFilter_Init(&conn_temp_adc_filter[0]); SMAFilter_Init(&conn_temp_adc_filter[0]);
@@ -130,27 +130,11 @@ float calculate_NTC_resistance(int adc_value, float Vref, float Vin, float R) {
} }
int16_t CONN_ReadTemp(uint8_t ch){ 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); int32_t adc_filtered = SMAFilter_Update(&conn_temp_adc_filter[ch ? 1u : 0u], (int32_t)adcValue);
if((uint32_t)adc_filtered > 4000u) { if((uint32_t)adc_filtered > 4000u) {
ADC_Unlock();
return 20; //Термодатчик не подключен return 20; //Термодатчик не подключен
} }
@@ -161,7 +145,6 @@ int16_t CONN_ReadTemp(uint8_t ch){
float temp = pt1000_to_temperature(calculate_NTC_resistance((int)adc_filtered, Vref, Vin, R)); float temp = pt1000_to_temperature(calculate_NTC_resistance((int)adc_filtered, Vref, Vin, R));
ADC_Unlock();
return (int16_t)temp; return (int16_t)temp;
} }
+2 -2
View File
@@ -127,7 +127,7 @@ void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
__HAL_AFIO_REMAP_CAN1_3(); __HAL_AFIO_REMAP_CAN1_3();
/* CAN1 interrupt Init */ /* CAN1 interrupt Init */
HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 0, 0); HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 3, 0);
HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn); HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
/* USER CODE BEGIN CAN1_MspInit 1 */ /* USER CODE BEGIN CAN1_MspInit 1 */
@@ -165,7 +165,7 @@ void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
/* CAN2 interrupt Init */ /* CAN2 interrupt Init */
HAL_NVIC_SetPriority(CAN2_TX_IRQn, 0, 0); HAL_NVIC_SetPriority(CAN2_TX_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(CAN2_TX_IRQn); HAL_NVIC_EnableIRQ(CAN2_TX_IRQn);
HAL_NVIC_SetPriority(CAN2_RX1_IRQn, 0, 0); HAL_NVIC_SetPriority(CAN2_RX1_IRQn, 3, 0);
HAL_NVIC_EnableIRQ(CAN2_RX1_IRQn); HAL_NVIC_EnableIRQ(CAN2_RX1_IRQn);
/* USER CODE BEGIN CAN2_MspInit 1 */ /* USER CODE BEGIN CAN2_MspInit 1 */
+2 -10
View File
@@ -7,6 +7,7 @@
ChargingConnector_t CONN; ChargingConnector_t CONN;
CONN_State_t connectorState; CONN_State_t connectorState;
extern uint8_t config_initialized;
void CONN_Init(){ void CONN_Init(){
@@ -42,16 +43,7 @@ void CONN_Task(){
/* CCS state machine is handled in serial.c. /* CCS state machine is handled in serial.c.
* Keep this task lightweight for scheduler compatibility. * Keep this task lightweight for scheduler compatibility.
*/ */
if (CONN.chargingError != CONN_NO_ERROR) { return;
CONN_SetState(Disabled);
return;
}
if (connectorState == Unknown) {
CONN_SetState(Unplugged);
} else if (connectorState == Disabled && CONN.chargingError == CONN_NO_ERROR) {
CONN_SetState(Unplugged);
}
} }
void CONN_SetState(CONN_State_t state){ void CONN_SetState(CONN_State_t state){
+75 -29
View File
@@ -1,37 +1,34 @@
#include "cp.h" #include "cp.h"
#include "adc.h" #include "adc.h"
#include "board.h" #include "board.h"
#include "debug.h"
#include "tim.h" #include "tim.h"
#include <stdint.h> #include <stdint.h>
#include <stdlib.h>
#define MAX_DUTY 450 #define MAX_DUTY 450
#define FILTER_ORDER 100
static int32_t cp_voltage_mv = 0; static int32_t cp_voltage_mv = 0;
static uint8_t cp_duty = 0; static uint8_t cp_duty = 0;
CP_State_t fake_cp_state = EV_STATE_ACQUIRING; CP_State_t fake_cp_state = EV_STATE_ACQUIRING;
CP_State_t cp_state_buffer = EV_STATE_ACQUIRING;
static uint32_t CP_ReadAdcChannel(uint32_t ch) {
uint32_t adc = 0;
ADC_Select_Channel(ch);
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, 10);
adc = HAL_ADC_GetValue(&hadc1);
HAL_ADC_Stop(&hadc1);
return adc;
}
#define VREFINT_CAL_ADDR ((uint16_t*)0x1FFFF7BA) // для STM32F1! #define VREFINT_CAL_ADDR ((uint16_t*)0x1FFFF7BA) // для STM32F1!
static int32_t CP_ReadVoltageMv(void) static int32_t CP_ReadVoltageMv(void)
{ {
uint32_t adc = 0; uint32_t adc_cp = adc_data.cp_raw;
int32_t v_adc_mv = 0; uint32_t adc_vref = adc_data.vrefint_raw; // нужно измерять!
int32_t v_out_mv = 0;
adc = CP_ReadAdcChannel((uint32_t)4u); // VREFINT в мВ (берётся из даташита или калибровки MCU)
v_adc_mv = (int32_t)((adc * 3300u) / 4095u); const int32_t VREFINT_MV = 1210;
v_out_mv = ((v_adc_mv - 1723) * 1000) / 130;
// напряжение на входе АЦП
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; return v_out_mv;
} }
@@ -50,7 +47,7 @@ void CP_Init(void) {
#endif #endif
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2); 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) { void CP_SetDuty(uint8_t percentage) {
@@ -71,11 +68,12 @@ uint8_t CP_GetDuty(void) {
} }
int32_t CP_GetVoltage(void) { int32_t CP_GetVoltage(void) {
cp_voltage_mv = CP_ReadVoltageMv();
return cp_voltage_mv; return cp_voltage_mv;
} }
CP_State_t CP_GetState(void) { 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) { if(fake_cp_state != EV_STATE_ACQUIRING) {
return fake_cp_state; return fake_cp_state;
@@ -98,18 +96,66 @@ CP_State_t CP_GetState(void) {
} }
} }
void CP_Loop(void) { CP_State_t CP_GetFilteredState(void) {
(void)CP_GetState(); return cp_state_buffer;
} }
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim) void CP_FilterState(void) {
{
if (htim->Instance == TIM3 && htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) { static CP_State_t pending_state = EV_STATE_ACQUIRING;
if (ADC_TryLock() == 0u) { static uint8_t stable_count = 0u;
return; CP_State_t current_state = CP_GetState();
}
cp_voltage_mv = CP_ReadVoltageMv(); /* Keep last accepted state while CP is still acquiring. */
ADC_Unlock(); if (current_state == EV_STATE_ACQUIRING) {
pending_state = EV_STATE_ACQUIRING;
stable_count = 0u;
return;
}
if (current_state != pending_state) {
pending_state = current_state;
stable_count = 1u;
return;
}
if (stable_count < FILTER_ORDER) {
stable_count++;
}
if (stable_count >= FILTER_ORDER) {
cp_state_buffer = pending_state;
}
}
void CP_Loop(void) {
static uint32_t tick;
if ((int32_t)(HAL_GetTick() - tick) < 1) return;
tick = HAL_GetTick();
static uint8_t initialized = 0;
static CP_State_t prev_state = EV_STATE_ACQUIRING;
static uint8_t prev_duty = 0;
CP_FilterState();
CP_State_t current_state = CP_GetFilteredState();
uint8_t current_duty = cp_duty;
if (!initialized) {
prev_state = current_state;
prev_duty = current_duty;
initialized = 1;
return;
}
if (current_state != prev_state) {
log_printf(LOG_INFO, "CP state changed: %d -> %d\n", prev_state, current_state);
prev_state = current_state;
}
if (current_duty != prev_duty) {
log_printf(LOG_INFO, "CP duty changed: %u -> %u\n", prev_duty, current_duty);
prev_duty = current_duty;
} }
} }
-215
View File
@@ -148,218 +148,3 @@ int log_printf(LogLevel_t level, const char *format, ...)
return result; return result;
} }
#ifndef USE_WEB_INTERFACE
extern UART_HandleTypeDef huart2;
uint8_t debug_rx_buffer[256];
uint8_t debug_cmd_received;
uint8_t debug_rx_buffer_size = 0;
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size){
// if(huart->Instance == USART1){
// mm_rx_interrupt(huart, Size);
// }
if(huart->Instance == USART2){
debug_rx_interrupt(huart, Size);
}
}
void debug_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
+67
View File
@@ -0,0 +1,67 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file dma.c
* @brief This file provides code for the configuration
* of all the requested memory to memory DMA transfers.
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "dma.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/*----------------------------------------------------------------------------*/
/* Configure DMA */
/*----------------------------------------------------------------------------*/
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/**
* Enable DMA controller clock
*/
void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Channel1_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
/* DMA1_Channel2_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel2_IRQn, 4, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel2_IRQn);
/* DMA1_Channel3_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel3_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel3_IRQn);
/* DMA1_Channel6_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn);
/* DMA1_Channel7_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel7_IRQn, 4, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel7_IRQn);
}
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
+25 -4
View File
@@ -54,20 +54,27 @@ void MX_GPIO_Init(void)
__HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE();
/*Configure GPIO pin Output Level */ /*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 */ /*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOE, RELAY1_Pin|RELAY2_Pin|RELAY3_Pin|RELAY4_Pin HAL_GPIO_WritePin(GPIOE, RELAY1_Pin|RELAY2_Pin|RELAY3_Pin|RELAY4_Pin
|RELAY5_Pin, GPIO_PIN_RESET); |RELAY5_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */ /*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 */ /*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOD, RELAY_DC_Pin|USART2_DIR_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOD, RELAY_DC_Pin|USART2_DIR_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */ /*Configure GPIO pin : DBG1_Pin */
HAL_GPIO_WritePin(EE_WP_GPIO_Port, EE_WP_Pin, GPIO_PIN_RESET); 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 */ /*Configure GPIO pins : RELAY_CP_Pin LOCK_A_Pin LOCK_B_Pin */
GPIO_InitStruct.Pin = RELAY_CP_Pin|LOCK_A_Pin|LOCK_B_Pin; GPIO_InitStruct.Pin = RELAY_CP_Pin|LOCK_A_Pin|LOCK_B_Pin;
@@ -88,6 +95,13 @@ void MX_GPIO_Init(void)
GPIO_InitStruct.Pull = GPIO_PULLDOWN; GPIO_InitStruct.Pull = GPIO_PULLDOWN;
HAL_GPIO_Init(IN_SW1_GPIO_Port, &GPIO_InitStruct); 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 */ /*Configure GPIO pins : IN0_Pin AC_OK_Pin ISO_IN_Pin */
GPIO_InitStruct.Pin = IN0_Pin|AC_OK_Pin|ISO_IN_Pin; GPIO_InitStruct.Pin = IN0_Pin|AC_OK_Pin|ISO_IN_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
@@ -103,6 +117,13 @@ void MX_GPIO_Init(void)
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); 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 */ /*Configure GPIO pin : RELAY_CC_Pin */
GPIO_InitStruct.Pin = RELAY_CC_Pin; GPIO_InitStruct.Pin = RELAY_CC_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+335 -301
View File
@@ -1,301 +1,335 @@
/* USER CODE BEGIN Header */ /* USER CODE BEGIN Header */
/* USER CODE END Header */ /* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/ /* Includes ------------------------------------------------------------------*/
#include "main.h" #include "main.h"
#include "adc.h" #include "adc.h"
#include "can.h" #include "can.h"
#include "crc.h" #include "crc.h"
#include "rtc.h" #include "dma.h"
#include "tim.h" #include "rtc.h"
#include "usart.h" #include "tim.h"
#include "gpio.h" #include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */ /* Private includes ----------------------------------------------------------*/
#include "can.h" /* USER CODE BEGIN Includes */
#include "board.h" #include "can.h"
#include <stdio.h> #include "board.h"
#include "debug.h" #include <stdio.h>
#include "soft_rtc.h" #include "debug.h"
#include "connector.h" #include "soft_rtc.h"
#include "serial_control.h" #include "connector.h"
#include "charger_config.h" #include "serial_control.h"
#include "serial.h" #include "charger_config.h"
/* USER CODE END Includes */ #include "serial.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */ /* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */ /* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */ /* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void); /* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */ void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */ /* 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 * @brief Vector base address configuration. It should no longer be at the start of
* reserved for the bootloader. Note that this is already done by the * flash memory but moved forward because the first part of flash is
* bootloader before starting this program. Unfortunately, function * reserved for the bootloader. Note that this is already done by the
* SystemInit() overwrites this change again. * bootloader before starting this program. Unfortunately, function
* @return none. * SystemInit() overwrites this change again.
*/ * @return none.
static void VectorBase_Config(void) */
{ static void VectorBase_Config(void)
/* The constant array with vectors of the vector table is declared externally in the {
* c-startup code. /* The constant array with vectors of the vector table is declared externally in the
*/ * c-startup code.
extern const unsigned long g_pfnVectors[]; */
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]; /* 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]; uint8_t ED_TraceWarning(uint8_t flag, uint8_t id){
if(id > 31) return 0; static uint8_t memory[32];
uint8_t result = 0; if(id > 31) return 0;
if(memory[id] != flag){ uint8_t result = 0;
result = 1; if(memory[id] != flag){
} result = 1;
memory[id] = flag; }
return result; memory[id] = flag;
} return result;
}
void ED_Delay(uint32_t Delay)
{ void ED_Delay(uint32_t Delay)
uint32_t tickstart = HAL_GetTick(); {
uint32_t wait = Delay; uint32_t tickstart = HAL_GetTick();
uint32_t wait = Delay;
if (wait < HAL_MAX_DELAY)
{ if (wait < HAL_MAX_DELAY)
wait += (uint32_t)(uwTickFreq); {
} wait += (uint32_t)(uwTickFreq);
}
while ((HAL_GetTick() - tickstart) < wait){
CCS_SerialLoop(); while ((HAL_GetTick() - tickstart) < wait){
// CP_Loop(); CCS_SerialLoop();
CONN_Task(); StopButtonControl();
LED_Task(); CP_Loop();
SC_Task(); CONN_Task();
} LED_Task();
} SC_Task();
}
void StopButtonControl(){ }
//Charging do nothing void StopButtonControl(){
if(!IN_ReadInput(IN_ESTOP)){ static uint32_t tick;
CONN.connControl = CMD_STOP; 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. */
uint8_t temp0, temp1; if((now - tick) < 10){
return;
static void CAN1_MinimalReInit(void) }
{ tick = now;
HAL_CAN_Stop(&hcan1);
MX_CAN1_Init(); uint8_t pressed = !IN_ReadInput(IN_ESTOP);
if (HAL_CAN_Start(&hcan1) != HAL_OK) { if(!pressed){
Error_Handler(); stop_btn_fault = 0;
} }
if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK) {
Error_Handler(); if(stop_btn_fault){
} return;
} }
/* USER CODE END 0 */ if(pressed){
if(hold_time == 0){
/** CONN.connControl = CMD_STOP;
* @brief The application entry point. }
* @retval int hold_time += 10;
*/ if(hold_time == 5000){
int main(void) CONN.connControl = CMD_FORCE_UNLOCK;
{ }
if(hold_time > 40000){
/* USER CODE BEGIN 1 */ SC_SendPacket(NULL, 0, RESP_SUCCESS);
VectorBase_Config(); while(huart2.gState == HAL_UART_STATE_BUSY_TX);
/* USER CODE END 1 */ HAL_Delay(10);
NVIC_SystemReset();
/* MCU Configuration--------------------------------------------------------*/ }
}
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */ else{
HAL_Init(); hold_time = 0;
}
/* USER CODE BEGIN Init */ }
HAL_RCC_DeInit();
/* USER CODE END Init */ uint8_t temp0, temp1;
/* Configure the system clock */ static void CAN1_MinimalReInit(void)
SystemClock_Config(); {
HAL_CAN_Stop(&hcan1);
/* USER CODE BEGIN SysInit */ MX_CAN1_Init();
if (HAL_CAN_Start(&hcan1) != HAL_OK) {
/* USER CODE END SysInit */ Error_Handler();
}
/* Initialize all configured peripherals */ if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK) {
MX_GPIO_Init(); Error_Handler();
MX_ADC1_Init(); }
MX_CAN1_Init(); }
MX_CAN2_Init();
MX_RTC_Init(); /* USER CODE END 0 */
MX_TIM4_Init();
MX_USART2_UART_Init(); /**
MX_CRC_Init(); * @brief The application entry point.
MX_UART5_Init(); * @retval int
MX_USART1_UART_Init(); */
MX_USART3_UART_Init(); int main(void)
MX_TIM3_Init(); {
/* USER CODE BEGIN 2 */
Init_Peripheral(); /* USER CODE BEGIN 1 */
LED_Init();
VectorBase_Config();
HAL_Delay(300); /* USER CODE END 1 */
CCS_Init();
SC_Init(); /* MCU Configuration--------------------------------------------------------*/
log_printf(LOG_INFO, "CCS module start\n");
ReadVersion(); /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
log_printf(LOG_INFO, "Serial number: %d\n", infoPacket.serialNumber); HAL_Init();
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); /* USER CODE BEGIN Init */
CAN1_MinimalReInit(); HAL_RCC_DeInit();
PSU_Init(); /* USER CODE END Init */
CONN_Init();
/* Configure the system clock */
/* USER CODE END 2 */ SystemClock_Config();
/* Infinite loop */ /* USER CODE BEGIN SysInit */
/* USER CODE BEGIN WHILE */
while (1) /* USER CODE END SysInit */
{
/* USER CODE END WHILE */ /* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 3 */ MX_DMA_Init();
MX_ADC1_Init();
MX_CAN1_Init();
PSU_ReadWrite(); MX_CAN2_Init();
PSU_Task(); MX_RTC_Init();
ED_Delay(10); MX_TIM4_Init();
METER_CalculateEnergy(); MX_USART2_UART_Init();
CONN_Loop(); MX_CRC_Init();
LED_Write(); MX_UART5_Init();
ED_Delay(10); MX_USART1_UART_Init();
StopButtonControl(); MX_USART3_UART_Init();
ED_Delay(50); MX_TIM3_Init();
/* USER CODE BEGIN 2 */
} Init_Peripheral();
/* USER CODE END 3 */ LED_Init();
}
HAL_Delay(300);
/** CCS_Init();
* @brief System Clock Configuration SC_Init();
* @retval None log_printf(LOG_INFO, "CCS module start\n");
*/ ReadVersion();
void SystemClock_Config(void) log_printf(LOG_INFO, "Serial number: %d\n", infoPacket.serialNumber);
{ log_printf(LOG_INFO, "Board revision: %d\n", infoPacket.boardVersion);
RCC_OscInitTypeDef RCC_OscInitStruct = {0}; log_printf(LOG_INFO, "FW version: %d.%d.%d\n", infoPacket.fw_version_major, infoPacket.fw_version_minor, infoPacket.fw_version_patch);
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; CAN1_MinimalReInit();
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; PSU_Init();
CONN_Init();
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure. /* USER CODE END 2 */
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE|RCC_OSCILLATORTYPE_LSE; /* Infinite loop */
RCC_OscInitStruct.HSEState = RCC_HSE_ON; /* USER CODE BEGIN WHILE */
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV5; while (1)
RCC_OscInitStruct.LSEState = RCC_LSE_ON; {
RCC_OscInitStruct.HSIState = RCC_HSI_ON; /* USER CODE END WHILE */
RCC_OscInitStruct.Prediv1Source = RCC_PREDIV1_SOURCE_PLL2;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; /* USER CODE BEGIN 3 */
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
RCC_OscInitStruct.PLL2.PLL2State = RCC_PLL2_ON; PSU_ReadWrite();
RCC_OscInitStruct.PLL2.PLL2MUL = RCC_PLL2_MUL8; PSU_Task();
RCC_OscInitStruct.PLL2.HSEPrediv2Value = RCC_HSE_PREDIV2_DIV5; ED_Delay(10);
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) METER_CalculateEnergy();
{ CONN_Loop();
Error_Handler(); LED_Write();
} ED_Delay(10);
/** Initializes the CPU, AHB and APB buses clocks }
*/ /* USER CODE END 3 */
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; * @brief System Clock Configuration
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; * @retval None
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; */
void SystemClock_Config(void)
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) {
{ RCC_OscInitTypeDef RCC_OscInitStruct = {0};
Error_Handler(); RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
} RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_ADC;
PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; /** Initializes the RCC Oscillators according to the specified parameters
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6; * in the RCC_OscInitTypeDef structure.
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) */
{ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE|RCC_OSCILLATORTYPE_LSE;
Error_Handler(); RCC_OscInitStruct.HSEState = RCC_HSE_ON;
} RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV5;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
/** Configure the Systick interrupt time RCC_OscInitStruct.HSIState = RCC_HSI_ON;
*/ RCC_OscInitStruct.Prediv1Source = RCC_PREDIV1_SOURCE_PLL2;
__HAL_RCC_PLLI2S_ENABLE(); RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
} RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
/* USER CODE BEGIN 4 */ RCC_OscInitStruct.PLL2.PLL2State = RCC_PLL2_ON;
RCC_OscInitStruct.PLL2.PLL2MUL = RCC_PLL2_MUL8;
/* USER CODE END 4 */ RCC_OscInitStruct.PLL2.HSEPrediv2Value = RCC_HSE_PREDIV2_DIV5;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
/** {
* @brief This function is executed in case of error occurrence. Error_Handler();
* @retval None }
*/
void Error_Handler(void) /** Initializes the CPU, AHB and APB buses clocks
{ */
/* USER CODE BEGIN Error_Handler_Debug */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
/* User can add his own implementation to report the HAL error return state */ |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
__disable_irq(); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
while (1) RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
{ RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
} RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
/* USER CODE END Error_Handler_Debug */
} if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
#ifdef USE_FULL_ASSERT {
/** Error_Handler();
* @brief Reports the name of the source file and the source line number }
* where the assert_param error has occurred. PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_ADC;
* @param file: pointer to the source file name PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
* @param line: assert_param error line source number PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
* @retval None if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
*/ {
void assert_failed(uint8_t *file, uint32_t line) Error_Handler();
{ }
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number, /** Configure the Systick interrupt time
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ */
/* USER CODE END 6 */ __HAL_RCC_PLLI2S_ENABLE();
} }
#endif /* USE_FULL_ASSERT */
/* 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 */
+18 -4
View File
@@ -8,6 +8,7 @@
#include "charger_control.h" #include "charger_control.h"
#include "board.h" #include "board.h"
#include "debug.h" #include "debug.h"
#include "isr_opt.h"
PSU_02_t PSU_02; PSU_02_t PSU_02;
PSU_04_t PSU_04; PSU_04_t PSU_04;
@@ -39,7 +40,7 @@ static uint32_t PSU_StateTime(void){
return HAL_GetTick() - PSU0.statetick; 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 CAN_RxHeaderTypeDef RxHeader;
static uint8_t RxData[8] = {0,}; static uint8_t RxData[8] = {0,};
@@ -149,6 +150,7 @@ void PSU_Init(){
PSU0.power_limit = PSU_MAX_POWER; // kW PSU0.power_limit = PSU_MAX_POWER; // kW
PSU0.hv_mode = 0; PSU0.hv_mode = 0;
PSU0.hv_tick = 0;
PSU_Enable(0, 0); PSU_Enable(0, 0);
} }
@@ -261,11 +263,22 @@ void PSU_ReadWrite(){
} }
CONN.RequestedPower = CONN.RequestedCurrent * CONN.RequestedVoltage / 10; CONN.RequestedPower = CONN.RequestedCurrent * CONN.RequestedVoltage / 10;
if(PSU0.ready){ if(PSU0.ready){
PSU_SetVoltageCurrent(0, CONN.RequestedVoltage, CONN.RequestedCurrent); // Normal mode if (CONN.RequestedVoltage == 500) { // fake
PSU_SetVoltageCurrent(0, 300, 10); // Normal mode
}else{
PSU_SetVoltageCurrent(0, CONN.RequestedVoltage, CONN.RequestedCurrent); // Normal mode
}
ED_Delay(CAN_DELAY); ED_Delay(CAN_DELAY);
if(CONN.MeasuredVoltage>490) PSU0.hv_mode = 1; 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;
}
}else{
PSU0.hv_tick = 0;
}
} }
// PSU_SetHVMode(0, PSU0.hv_mode); // auto set, no need // PSU_SetHVMode(0, PSU0.hv_mode); // auto set, no need
@@ -339,6 +352,7 @@ void PSU_Task(void){
case PSU_READY: case PSU_READY:
// модуль готов, но выключен // модуль готов, но выключен
PSU0.hv_mode = 0; PSU0.hv_mode = 0;
PSU0.hv_tick = 0;
RELAY_Write(RELAY_DC, 0); RELAY_Write(RELAY_DC, 0);
if(!PSU0.ready){ if(!PSU0.ready){
+28 -10
View File
@@ -2,6 +2,7 @@
#include "main.h" #include "main.h"
#include "string.h" #include "string.h"
#include "charger_control.h" #include "charger_control.h"
#include "board.h"
#include "tim.h" #include "tim.h"
@@ -10,11 +11,20 @@ RGB_Cycle_t LED_Cycle;
RGB_Cycle_t color_estop = { RGB_Cycle_t color_estop = {
.Color1 = { .R = 250, .G = 0, .B = 0 }, .Color1 = { .R = 250, .G = 0, .B = 0 },
.Color2 = { .R = 250, .G = 0, .B = 0 }, .Color2 = { .R = 0, .G = 0, .B = 0 },
.Tr = 50, .Tr = 10,
.Th = 50, .Th = 5,
.Tf = 50, .Tf = 10,
.Tl = 50, .Tl = 5,
};
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 = { RGB_Cycle_t color_unknown = {
@@ -54,12 +64,12 @@ RGB_Cycle_t color_unplugged = {
}; };
RGB_Cycle_t color_preparing = { RGB_Cycle_t color_preparing = {
.Color1 = { .R = 0, .G = 0, .B = 250 }, .Color1 = { .R = 0, .G = 0, .B = 255 },
.Color2 = { .R = 0, .G = 0, .B = 250 }, .Color2 = { .R = 0, .G = 0, .B = 0 },
.Tr = 50, .Tr = 10,
.Th = 10, .Th = 10,
.Tf = 50, .Tf = 10,
.Tl = 0, .Tl = 10,
}; };
RGB_Cycle_t color_charging = { RGB_Cycle_t color_charging = {
@@ -94,6 +104,14 @@ void LED_Write(){
LED_SetColor(&color_error); LED_SetColor(&color_error);
return; 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){ switch(CONN.connState){
case Unknown: case Unknown:
LED_SetColor(&color_unknown); LED_SetColor(&color_unknown);
+337 -107
View File
@@ -3,12 +3,15 @@
#include "connector.h" #include "connector.h"
#include "board.h" #include "board.h"
#include "debug.h" #include "debug.h"
#include "isr_opt.h"
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include "charger_config.h" #include "charger_config.h"
#include "psu_control.h" #include "psu_control.h"
#include "serial_control.h"
extern UART_HandleTypeDef huart3; extern UART_HandleTypeDef huart3;
extern uint8_t config_initialized;
static void send_state(void); static void send_state(void);
static void CCS_SendResetReason(void); static void CCS_SendResetReason(void);
@@ -27,10 +30,19 @@ uint8_t ev_enable_output = 0;
#define CMD_INTERVAL 10 #define CMD_INTERVAL 10
#define MAX_TX_BUFFER_SIZE 256 #define MAX_TX_BUFFER_SIZE 256
#define MAX_RX_BUFFER_SIZE 256 #define MAX_RX_BUFFER_SIZE 256
#define EVEREST_TIMEOUT_WARN_MS 5000u
#define EVEREST_TIMEOUT_STOP_MS 10000u
#define UART3_REINIT_TIMEOUT_MS 1500u
/* Everest requests 500 V -> PSU really gets 300 V / 1 A, state still reports 500 V. */
#define FAKE_EVREQ_VOLTAGE_V 500u
#define FAKE_PSU_VOLTAGE_V 300u
#define FAKE_PSU_CURRENT_0P1A 10u
static uint8_t rx_buffer[MAX_RX_BUFFER_SIZE]; static uint8_t rx_buffer[MAX_RX_BUFFER_SIZE];
static uint8_t tx_buffer[MAX_TX_BUFFER_SIZE]; static uint8_t tx_buffer[MAX_TX_BUFFER_SIZE];
static uint8_t rx_armed = 0; static uint8_t tx_pending_buffer[MAX_TX_BUFFER_SIZE];
static uint16_t tx_pending_len = 0;
static uint8_t uart3_tx_busy = 0;
uint8_t ESTOP = 0; uint8_t ESTOP = 0;
uint8_t REPLUG = 0; uint8_t REPLUG = 0;
@@ -39,46 +51,159 @@ static uint8_t enabled = 0;
static uint8_t pwm_duty_percent = 100; static uint8_t pwm_duty_percent = 100;
uint8_t isolation_enable = 0; uint8_t isolation_enable = 0;
static uint32_t last_host_seen = 0; static uint32_t last_host_seen = 0;
static CP_State_t cp_state_buffer = EV_STATE_ACQUIRING; static uint8_t fake_500_voltage_mode = 0;
static uint8_t everest_timed_out = 0;
static uint8_t everest_timeout_warn_latched = 0;
static uint8_t everest_timeout_stop_latched = 0;
static uint32_t uart3_last_packet_tick = 0;
static uint32_t uart3_last_reinit_tick = 0;
CCS_State_t CCS_State; CCS_State_t CCS_State;
CCS_EvInfo_t CCS_EvInfo; CCS_EvInfo_t CCS_EvInfo;
CONN_State_t CCS_EvseState; CONN_State_t CCS_EvseState;
CCS_ConnectorState_t CCS_ConnectorState = CCS_UNPLUGGED; CCS_ConnectorState_t CCS_ConnectorState = CCS_UNKNOWN;
static uint8_t process_received_packet(const uint8_t* packet, uint16_t packet_len); ISR_FAST static uint8_t process_received_packet(const uint8_t* packet, uint16_t packet_len);
static void CCS_UART3_Watchdog(void);
static void CCS_LogUart3Error(const char *tag);
void CCS_RxEventCallback(UART_HandleTypeDef *huart, uint16_t size) { 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_DMA(&huart3, rx_buffer, sizeof(rx_buffer));
if (st == HAL_OK) {
return;
}
uint32_t err_after = HAL_UART_GetError(&huart3);
log_printf(LOG_ERR,
"UART3 RX arm failed (%s): HAL_Status=%d err_after=0x%08lx\n",
where, (int)st, (unsigned long)err_after);
uart3_log_hal_error(3u, err_after);
CCS_LogUart3Error("UART3 RX arm failed details");
if (err_after != HAL_UART_ERROR_NONE) {
(void)HAL_UART_AbortReceive(&huart3);
}
}
ISR_FAST void CCS_RxEventCallback(UART_HandleTypeDef *huart, uint16_t size) {
if (huart != &huart3) {
log_printf(LOG_WARN, "UART3 RX drop: wrong huart in RxEventCallback (size=%u)\n",
(unsigned)size);
return;
}
if (size == 0u) {
log_printf(LOG_WARN, "UART3 RX drop: RxEvent size=0 (idle, no payload)\n");
uart3_arm_rx_or_log("RxEventCallback");
return;
}
if (size > sizeof(rx_buffer)) {
log_printf(LOG_ERR, "UART3 RX drop: size=%u > rx_buffer %u (overflow, not parsed)\n",
(unsigned)size, (unsigned)sizeof(rx_buffer));
uart3_arm_rx_or_log("RxEventCallback");
return;
}
uart3_last_packet_tick = HAL_GetTick();
uart3_last_reinit_tick = uart3_last_packet_tick;
process_received_packet(rx_buffer, size);
uart3_arm_rx_or_log("RxEventCallback");
}
ISR_FAST void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) {
uint32_t error = HAL_UART_GetError(huart);
uint8_t uart_num =
(huart == &huart2) ? 2 :
(huart == &huart3) ? 3 :
(huart == &huart5) ? 5 : 0;
log_printf(LOG_ERR,
"UART%u HAL error (ISR): raw=0x%08lx — RX may be corrupted until re-arm\n",
uart_num, (unsigned long)error);
uart3_log_hal_error(uart_num, error);
(void)HAL_UART_AbortReceive(huart);
(void)HAL_UART_AbortTransmit(huart);
if (huart == &huart3) {
uart3_tx_busy = 0;
uart3_arm_rx_or_log("ErrorCallback");
} else {
SC_RecoverUartDma(huart);
}
}
void CCS_TxCpltCallback(UART_HandleTypeDef *huart) {
if (huart != &huart3) { if (huart != &huart3) {
return; return;
} }
rx_armed = 0; uart3_tx_busy = 0;
if (size > 0 && size <= sizeof(rx_buffer)) { if (tx_pending_len > 0) {
process_received_packet(rx_buffer, size); memcpy(tx_buffer, tx_pending_buffer, tx_pending_len);
uart3_tx_busy = 1;
if (HAL_UART_Transmit_DMA(&huart3, tx_buffer, tx_pending_len) != HAL_OK) {
uart3_tx_busy = 0;
CCS_LogUart3Error("UART3 TX DMA resend failed");
}
tx_pending_len = 0;
} }
} }
void CCS_SerialLoop(void) { void CCS_SerialLoop(void) {
static uint32_t tick;
if ((int32_t)(HAL_GetTick() - tick) < 1) return;
tick = HAL_GetTick();
static uint32_t replug_tick = 0; static uint32_t replug_tick = 0;
static uint32_t replug_watchdog_tick = 0; static uint32_t replug_watchdog_tick = 0;
static uint32_t replug_watchdog1_tick = 0; static uint32_t replug_watchdog1_tick = 0;
static uint32_t last_state_sent = 0; static uint32_t last_state_sent = 0;
static uint32_t force_unlock_tick = 0;
static uint32_t stop_tick = 0;
if (!rx_armed && HAL_UART_GetState(&huart3) == HAL_UART_STATE_READY) { CCS_UART3_Watchdog();
if (HAL_UARTEx_ReceiveToIdle_IT(&huart3, rx_buffer, sizeof(rx_buffer)) == HAL_OK) {
rx_armed = 1;
}
}
/* Read CP once per loop and use buffered value below. */
cp_state_buffer = CP_GetState();
if (CONN.connControl != CMD_NONE) { if (CONN.connControl != CMD_NONE) {
last_cmd = CONN.connControl; last_cmd = CONN.connControl;
} }
if((HAL_GetTick() - last_cmd_sent) > CMD_INTERVAL){ if (CONN.connControl == CMD_FORCE_UNLOCK) {
if ((HAL_GetTick() - last_state_sent) >= 200) { if (force_unlock_tick == 0) {
force_unlock_tick = HAL_GetTick();
} else if ((int32_t)(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 ((int32_t)(HAL_GetTick() - stop_tick) >= 1000) {
CONN.connControl = CMD_NONE;
stop_tick = 0;
}
} else {
stop_tick = 0;
}
if((int32_t)(HAL_GetTick() - last_cmd_sent) > (int32_t)CMD_INTERVAL){
if ((int32_t)(HAL_GetTick() - last_state_sent) >= 200) {
send_state(); send_state();
last_state_sent = HAL_GetTick(); last_state_sent = HAL_GetTick();
} }
@@ -90,15 +215,19 @@ void CCS_SerialLoop(void) {
} }
if (((CONN.connControl == CMD_STOP) || if (((CONN.connControl == CMD_STOP) ||
(CONN.connControl == CMD_FORCE_UNLOCK) ||
(CONN.chargingError != CONN_NO_ERROR)) && (CONN.chargingError != CONN_NO_ERROR)) &&
((HAL_GetTick() - last_stop_sent) > 1000)) { ((int32_t)(HAL_GetTick() - last_stop_sent) > 1000)) {
last_stop_sent = HAL_GetTick(); last_stop_sent = HAL_GetTick();
log_printf(LOG_WARN, "Stopping charging...\n"); log_printf(LOG_WARN, "Stopping charging...\n");
if (CONN.connControl == CMD_FORCE_UNLOCK) {
CP_SetDuty(100);
}
CCS_SendEmergencyStop(); CCS_SendEmergencyStop();
} }
if (((CCS_EvseState == FinishedEV) || (CCS_EvseState == FinishedEVSE)) && if (((CCS_EvseState == FinishedEV) || (CCS_EvseState == FinishedEVSE)) &&
((HAL_GetTick() - last_stop_sent) > 1000)) { ((int32_t)(HAL_GetTick() - last_stop_sent) > 1000)) {
last_stop_sent = HAL_GetTick(); last_stop_sent = HAL_GetTick();
log_printf(LOG_WARN, "FinishedEV, stopping...\n"); log_printf(LOG_WARN, "FinishedEV, stopping...\n");
CCS_SendEmergencyStop(); CCS_SendEmergencyStop();
@@ -108,81 +237,111 @@ void CCS_SerialLoop(void) {
(void)replug_watchdog_tick; (void)replug_watchdog_tick;
(void)replug_watchdog1_tick; (void)replug_watchdog1_tick;
switch(CCS_ConnectorState){ uint8_t host_timeout_warn = (last_host_seen > 0u) && ((int32_t)(HAL_GetTick() - last_host_seen) > (int32_t)EVEREST_TIMEOUT_WARN_MS);
case CCS_DISABLED: uint8_t host_timeout_stop = (last_host_seen > 0u) && ((int32_t)(HAL_GetTick() - last_host_seen) > (int32_t)EVEREST_TIMEOUT_STOP_MS);
RELAY_Write(RELAY_CP, 0); uint8_t host_timed_out = host_timeout_stop;
CONN_SetState(Disabled);
if (CONN.chargingError == CONN_NO_ERROR){
CCS_ConnectorState = CCS_UNPLUGGED;
}
break;
case CCS_UNPLUGGED:
RELAY_Write(RELAY_CP, 1);
CONN_SetState(Unplugged);
if ((cp_state_buffer == EV_STATE_B_CONN_PREP) || (cp_state_buffer == EV_STATE_C_CONN_ACTIVE)){
CCS_ConnectorState = CCS_AUTH_REQUIRED;
}
if (CONN.chargingError != CONN_NO_ERROR){
log_printf(LOG_ERR, "Charging error %d, state -> disabled\n", CONN.chargingError);
CCS_ConnectorState = CCS_DISABLED;
}
break; if (host_timeout_warn && !everest_timeout_warn_latched) {
case CCS_AUTH_REQUIRED: log_printf(LOG_ERR, "Everest timeout\n");
RELAY_Write(RELAY_CP, 1); everest_timeout_warn_latched = 1;
CONN_SetState(AuthRequired);
if(CONN.connControl == CMD_START){
log_printf(LOG_INFO, "Charging permitted, start charging\n");
CCS_ConnectorState = CCS_CONNECTED;
}
if (cp_state_buffer == EV_STATE_A_IDLE){
log_printf(LOG_INFO, "Car unplugged\n");
CCS_ConnectorState = CCS_UNPLUGGED;
}
break;
case CCS_CONNECTED:
RELAY_Write(RELAY_CP, 1);
if(CCS_EvseState < Preparing) {
CONN_SetState(Preparing);
} else {
CONN_SetState(CCS_EvseState);
}
if (cp_state_buffer == EV_STATE_A_IDLE){
log_printf(LOG_INFO, "Car unplugged\n");
CCS_ConnectorState = CCS_UNPLUGGED;
}
if(REPLUG > 0){
log_printf(LOG_INFO, "Replugging...\n");
CCS_ConnectorState = CCS_REPLUGGING;
}
break;
case CCS_REPLUGGING:
RELAY_Write(RELAY_CP, 0);
CONN_SetState(Replugging);
if((HAL_GetTick() - replug_tick) > 1000){
replug_tick = HAL_GetTick();
if(REPLUG > 0){
if (REPLUG != 0xFF) REPLUG--;
} else {
log_printf(LOG_INFO, "Replugging finished, but car unplugged\n");
CCS_ConnectorState = CCS_UNPLUGGED;
}
}
if(REPLUG == 0){
if(cp_state_buffer == EV_STATE_B_CONN_PREP){
log_printf(LOG_INFO, "Replugging finished, car plugged, state -> auth required\n");
CCS_ConnectorState = CCS_AUTH_REQUIRED;
}
}
break;
} }
if (last_host_seen > 0 && (HAL_GetTick() - last_host_seen) > 500) { if (host_timeout_stop && !everest_timeout_stop_latched) {
log_printf(LOG_ERR, "Everest timeout, stopping charging...\n");
everest_timeout_stop_latched = 1;
}
if (!host_timeout_warn) {
everest_timeout_warn_latched = 0;
everest_timeout_stop_latched = 0;
}
everest_timed_out = host_timeout_stop;
switch(CCS_ConnectorState){
case CCS_UNKNOWN:
RELAY_Write(RELAY_CP, 0);
CONN_SetState(Unknown);
if (config_initialized && !host_timed_out) {
CCS_ConnectorState = CCS_UNPLUGGED;
}
break;
case CCS_DISABLED:
RELAY_Write(RELAY_CP, 0);
CONN_SetState(Disabled);
if ((CONN.chargingError == CONN_NO_ERROR) && !host_timed_out){
CCS_ConnectorState = CCS_UNPLUGGED;
}
break;
case CCS_UNPLUGGED:
RELAY_Write(RELAY_CP, 1);
CONN_SetState(Unplugged);
if ((cp_state_buffer == EV_STATE_B_CONN_PREP) || (cp_state_buffer == EV_STATE_C_CONN_ACTIVE)){
CCS_ConnectorState = CCS_AUTH_REQUIRED;
}
if (CONN.chargingError != CONN_NO_ERROR){
log_printf(LOG_ERR, "Charging error %d, state -> disabled\n", CONN.chargingError);
CCS_ConnectorState = CCS_DISABLED;
}
break;
case CCS_AUTH_REQUIRED:
RELAY_Write(RELAY_CP, 1);
CONN_SetState(AuthRequired);
if(CONN.connControl == CMD_START){
log_printf(LOG_INFO, "Charging permitted, start charging\n");
CCS_ConnectorState = CCS_CONNECTED;
}
if (cp_state_buffer == EV_STATE_A_IDLE){
log_printf(LOG_INFO, "Car unplugged\n");
CCS_ConnectorState = CCS_UNPLUGGED;
}
break;
case CCS_CONNECTED:
RELAY_Write(RELAY_CP, 1);
if((CCS_EvseState < Preparing) || (CCS_EvseState == AuthRequired)) {
CONN_SetState(Preparing);
} else {
CONN_SetState(CCS_EvseState);
}
if (cp_state_buffer == EV_STATE_A_IDLE){
log_printf(LOG_INFO, "Car unplugged\n");
CCS_ConnectorState = CCS_UNPLUGGED;
}
if(REPLUG > 0){
log_printf(LOG_INFO, "Replugging...\n");
CCS_ConnectorState = CCS_REPLUGGING;
}
break;
case CCS_REPLUGGING:
RELAY_Write(RELAY_CP, 0);
CONN_SetState(Replugging);
if((int32_t)(HAL_GetTick() - replug_tick) > 1000){
replug_tick = HAL_GetTick();
if(REPLUG > 0){
if (REPLUG != 0xFF) REPLUG--;
} else {
log_printf(LOG_INFO, "Replugging finished, but car unplugged\n");
CCS_ConnectorState = CCS_UNPLUGGED;
}
}
if(REPLUG == 0){
if(cp_state_buffer == EV_STATE_B_CONN_PREP){
log_printf(LOG_INFO, "Replugging finished, car plugged, state -> auth required\n");
CCS_ConnectorState = CCS_AUTH_REQUIRED;
}
}
break;
}
// 10s timeout: enforce safe-state until host communication recovers.
if (host_timeout_stop) {
CONN.EnableOutput = 0; CONN.EnableOutput = 0;
CCS_EvseState = Unknown; CCS_EvseState = Unknown;
CP_SetDuty(100); CP_SetDuty(100);
log_printf(LOG_ERR, "Everest timeout\n"); if (CCS_ConnectorState != CCS_DISABLED && CCS_ConnectorState != CCS_UNKNOWN) {
CCS_ConnectorState = CCS_DISABLED;
}
} else { } else {
if (last_cmd == CMD_STOP) { if (last_cmd == CMD_STOP) {
CONN.EnableOutput = 0; CONN.EnableOutput = 0;
@@ -211,11 +370,14 @@ void CCS_Init(void){
CCS_MaxLoad.maxCurrent = PSU_MAX_CURRENT*10; //100A CCS_MaxLoad.maxCurrent = PSU_MAX_CURRENT*10; //100A
CCS_MaxLoad.minCurrent = PSU_MIN_CURRENT*10; //1A CCS_MaxLoad.minCurrent = PSU_MIN_CURRENT*10; //1A
CCS_MaxLoad.maxPower = PSU_MAX_POWER; //30000W CCS_MaxLoad.maxPower = PSU_MAX_POWER; //30000W
uart3_last_packet_tick = HAL_GetTick();
uart3_last_reinit_tick = uart3_last_packet_tick;
uart3_arm_rx_or_log("Init");
CCS_SendResetReason(); CCS_SendResetReason();
log_printf(LOG_INFO, "CCS init\n"); 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; uint16_t crc = 0xFFFFu;
for (uint16_t i = 0; i < length; i++) { for (uint16_t i = 0; i < length; i++) {
crc ^= data[i]; crc ^= data[i];
@@ -249,7 +411,16 @@ static uint16_t CCS_BuildPacket(uint8_t cmd, const void* payload, uint16_t paylo
static void CCS_SendPacket(uint8_t cmd, const void* payload, uint16_t payload_len) { 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)); uint16_t len = CCS_BuildPacket(cmd, payload, payload_len, tx_buffer, sizeof(tx_buffer));
if (len > 0) { if (len > 0) {
HAL_UART_Transmit(&huart3, tx_buffer, len, 1000); if (uart3_tx_busy) {
memcpy(tx_pending_buffer, tx_buffer, len);
tx_pending_len = len;
} else {
uart3_tx_busy = 1;
if (HAL_UART_Transmit_DMA(&huart3, tx_buffer, len) != HAL_OK) {
uart3_tx_busy = 0;
CCS_LogUart3Error("UART3 TX DMA start failed");
}
}
} }
last_cmd_sent = HAL_GetTick(); last_cmd_sent = HAL_GetTick();
} }
@@ -287,6 +458,9 @@ static void send_state(void) {
CCS_State.DutyCycle = CP_GetDuty(); CCS_State.DutyCycle = CP_GetDuty();
CCS_State.OutputEnabled = PSU0.CONT_enabled; CCS_State.OutputEnabled = PSU0.CONT_enabled;
CCS_State.MeasuredVoltage = (uint16_t)CONN.MeasuredVoltage; CCS_State.MeasuredVoltage = (uint16_t)CONN.MeasuredVoltage;
if (fake_500_voltage_mode) {
CCS_State.MeasuredVoltage = FAKE_EVREQ_VOLTAGE_V;
}
CCS_State.MeasuredCurrent = (uint16_t)CONN.MeasuredCurrent; CCS_State.MeasuredCurrent = (uint16_t)CONN.MeasuredCurrent;
CCS_State.Power = CCS_Power; CCS_State.Power = CCS_Power;
CCS_State.Energy = CCS_Energy; CCS_State.Energy = CCS_Energy;
@@ -308,7 +482,7 @@ static void send_state(void) {
CCS_SendPacket(CMD_M2E_STATE, &CCS_State, sizeof(CCS_State)); 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) { switch (cmd) {
case CMD_E2M_PWM_DUTY: return sizeof(e2m_pwm_duty_t); case CMD_E2M_PWM_DUTY: return sizeof(e2m_pwm_duty_t);
case CMD_E2M_ENABLE_OUTPUT: return sizeof(e2m_enable_output_t); case CMD_E2M_ENABLE_OUTPUT: return sizeof(e2m_enable_output_t);
@@ -324,16 +498,21 @@ static uint16_t expected_payload_len(uint8_t cmd) {
} }
} }
static void apply_command(uint8_t cmd, const uint8_t* payload, uint16_t payload_len) { ISR_FAST static void apply_command(uint8_t cmd, const uint8_t* payload, uint16_t payload_len) {
(void)payload_len; (void)payload_len;
last_host_seen = HAL_GetTick(); last_host_seen = HAL_GetTick();
everest_timed_out = 0;
everest_timeout_warn_latched = 0;
everest_timeout_stop_latched = 0;
switch (cmd) { switch (cmd) {
case CMD_E2M_PWM_DUTY: { case CMD_E2M_PWM_DUTY: {
const e2m_pwm_duty_t* p = (const e2m_pwm_duty_t*)payload; const e2m_pwm_duty_t* p = (const e2m_pwm_duty_t*)payload;
uint8_t duty = p->pwm_duty_percent; uint8_t duty = p->pwm_duty_percent;
if (duty > 100) duty = 100; if (duty > 100) duty = 100;
pwm_duty_percent = duty; pwm_duty_percent = duty;
CP_SetDuty(duty); if (CONN.connControl != CMD_FORCE_UNLOCK) {
CP_SetDuty(duty);
}
break; break;
} }
case CMD_E2M_ENABLE_OUTPUT: { case CMD_E2M_ENABLE_OUTPUT: {
@@ -345,9 +524,9 @@ static void apply_command(uint8_t cmd, const uint8_t* payload, uint16_t payload_
const e2m_reset_t* p = (const e2m_reset_t*)payload; const e2m_reset_t* p = (const e2m_reset_t*)payload;
if (p->reset) { if (p->reset) {
log_printf(LOG_WARN, "Everest reset command\n"); log_printf(LOG_WARN, "Everest reset command\n");
CCS_SendResetReason(); // CCS_SendResetReason();
HAL_Delay(10); // HAL_Delay(10);
NVIC_SystemReset(); // NVIC_SystemReset();
} }
break; break;
} }
@@ -359,8 +538,15 @@ static void apply_command(uint8_t cmd, const uint8_t* payload, uint16_t payload_
} }
case CMD_E2M_SET_OUTPUT_VOLTAGE: { case CMD_E2M_SET_OUTPUT_VOLTAGE: {
const e2m_set_output_t* p = (const e2m_set_output_t*)payload; const e2m_set_output_t* p = (const e2m_set_output_t*)payload;
CONN.RequestedVoltage = p->voltage_V; if (p->voltage_V == FAKE_EVREQ_VOLTAGE_V) {
CONN.WantedCurrent = p->current_0p1A; 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;
}
break; break;
} }
case CMD_E2M_ISOLATION_CONTROL: { case CMD_E2M_ISOLATION_CONTROL: {
@@ -387,32 +573,54 @@ static void apply_command(uint8_t cmd, const uint8_t* payload, uint16_t payload_
break; break;
} }
default: 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; break;
} }
} }
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) {
if (packet_len < 3) return 0; 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]; 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 received_crc = (uint16_t)packet[packet_len - 2u] |
(uint16_t)packet[packet_len - 1u] << 8; (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) { 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; return 0;
} }
uint16_t expected_len = expected_payload_len(cmd); uint16_t expected_len = expected_payload_len(cmd);
if (expected_len == 0xFFFF) { if (expected_len == 0xFFFFu) {
log_printf(LOG_WARN, "Unknown cmd 0x%02x\n", cmd); 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; return 0;
} }
if (expected_len != payload_len) { 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; return 0;
} }
@@ -425,3 +633,25 @@ static uint8_t process_received_packet(const uint8_t* packet, uint16_t packet_le
return 1; return 1;
} }
static void CCS_UART3_Watchdog(void) {
const int32_t since_last_packet = (int32_t)(HAL_GetTick() - uart3_last_packet_tick);
const int32_t since_last_reinit = (int32_t)(HAL_GetTick() - uart3_last_reinit_tick);
if ((since_last_packet >= (int32_t)UART3_REINIT_TIMEOUT_MS) &&
(since_last_reinit >= (int32_t)UART3_REINIT_TIMEOUT_MS) &&
(huart3.RxState == HAL_UART_STATE_READY)) {
uart3_arm_rx_or_log("Watchdog");
CCS_LogUart3Error("UART3 watchdog rearm");
uart3_last_reinit_tick = HAL_GetTick();
}
}
static void CCS_LogUart3Error(const char *tag) {
log_printf(LOG_ERR, "%s: err=0x%08lx g=%lu rx=%lu tx_busy=%u\n",
tag,
(unsigned long)HAL_UART_GetError(&huart3),
(unsigned long)huart3.gState,
(unsigned long)huart3.RxState,
(unsigned)uart3_tx_busy);
}
+128 -30
View File
@@ -2,12 +2,18 @@
#include "usart.h" #include "usart.h"
#include "board.h" #include "board.h"
#include "serial.h" #include "serial.h"
#include "debug.h"
#include "isr_opt.h"
// Приватные функции // Приватные функции
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);
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);
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);
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);
static void SC_UART2_Watchdog(void);
static void SC_ArmUart2RxDma(void);
static void SC_ArmUart5RxDma(void);
static void SC_LogUartError(const char *tag, UART_HandleTypeDef *huart);
uint8_t test_crc_invalid = 0; uint8_t test_crc_invalid = 0;
@@ -15,6 +21,12 @@ SerialControl_t serial_control;
// Контекст для приема пакетов по UART5 (однонаправленный UART) // Контекст для приема пакетов по UART5 (однонаправленный UART)
static SerialControl_t serial_iso; static SerialControl_t serial_iso;
volatile SC_Source_t g_sc_command_source = SC_SOURCE_UART2; volatile SC_Source_t g_sc_command_source = SC_SOURCE_UART2;
static volatile uint8_t sc_uart2_timed_out = 0;
static uint32_t sc_uart2_last_packet_tick = 0;
static uint32_t sc_uart2_last_recover_tick = 0;
#define SC_UART2_RECOVER_GUARD_MS 200u
#define SC_UART2_PACKET_TIMEOUT_MS 5000u
StatusPacket_t statusPacket = { StatusPacket_t statusPacket = {
.SOC = 0, .SOC = 0,
@@ -72,20 +84,28 @@ void SC_Init() {
// Обнуляем структуру // Обнуляем структуру
memset(&serial_control, 0, sizeof(SerialControl_t)); memset(&serial_control, 0, sizeof(SerialControl_t));
memset(&serial_iso, 0, sizeof(serial_iso)); memset(&serial_iso, 0, sizeof(serial_iso));
sc_uart2_timed_out = 0;
sc_uart2_last_packet_tick = HAL_GetTick();
sc_uart2_last_recover_tick = sc_uart2_last_packet_tick;
SC_ArmUart2RxDma();
SC_ArmUart5RxDma();
} }
void SC_Task() { void SC_Task() {
// Запуск приема в режиме прерывания с ожиданием idle static uint32_t tick;
if((huart2.RxState == HAL_UART_STATE_READY) && (serial_control.command_ready == 0)) HAL_UARTEx_ReceiveToIdle_IT(&huart2, serial_control.rx_buffer, MAX_RX_BUFFER_SIZE - 1); if ((int32_t)(HAL_GetTick() - tick) < 1) return;
if((huart5.RxState == HAL_UART_STATE_READY)) HAL_UARTEx_ReceiveToIdle_IT(&huart5, serial_iso.rx_buffer, MAX_RX_BUFFER_SIZE - 1); tick = HAL_GetTick();
SC_UART2_Watchdog();
// Запуск приема в режиме DMA + idle
SC_ArmUart2RxDma();
SC_ArmUart5RxDma();
// Проверка таймаута отправки пакета (больше 100 мс) // Проверка таймаута отправки пакета (больше 100 мс)
if (huart2.gState == HAL_UART_STATE_BUSY_TX && serial_control.tx_tick != 0) { if (huart2.gState == HAL_UART_STATE_BUSY_TX && serial_control.tx_tick != 0) {
if ((HAL_GetTick() - serial_control.tx_tick) > 100) { if ((int32_t)(HAL_GetTick() - serial_control.tx_tick) > 100) {
// Таймаут: принудительно сбрасываем передачу // Таймаут: принудительно сбрасываем передачу
HAL_UART_Abort_IT(&huart2); (void)HAL_UART_AbortTransmit(&huart2);
// Выключаем DIR при сбросе передачи
HAL_GPIO_WritePin(USART2_DIR_GPIO_Port, USART2_DIR_Pin, GPIO_PIN_RESET);
serial_control.tx_tick = 0; // Сбрасываем tick serial_control.tx_tick = 0; // Сбрасываем tick
} }
} }
@@ -93,41 +113,54 @@ void SC_Task() {
// Проверка наличия принятой команды для обработки // Проверка наличия принятой команды для обработки
if (serial_control.command_ready && (huart2.gState != HAL_UART_STATE_BUSY_TX)) { if (serial_control.command_ready && (huart2.gState != HAL_UART_STATE_BUSY_TX)) {
// HAL_Delay(2); // HAL_Delay(2);
SC_CommandHandler(&serial_control.received_command); SC_CommandHandler((ReceivedCommand_t*)&serial_control.received_command);
HAL_UARTEx_ReceiveToIdle_IT(&huart2, serial_control.rx_buffer, MAX_RX_BUFFER_SIZE - 1);
serial_control.command_ready = 0; // Сбрасываем флаг serial_control.command_ready = 0; // Сбрасываем флаг
SC_ArmUart2RxDma();
} }
} }
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) { ISR_FAST void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) {
if (huart->Instance == huart2.Instance) { if (huart->Instance == huart2.Instance) {
if (Size == 0u) {
log_printf(LOG_WARN, "UART2 RX idle event with zero size\n");
}
sc_uart2_last_packet_tick = HAL_GetTick();
sc_uart2_last_recover_tick = sc_uart2_last_packet_tick;
sc_uart2_timed_out = 0;
if(!process_received_packet(&serial_control, serial_control.rx_buffer, Size)){ if(!process_received_packet(&serial_control, serial_control.rx_buffer, Size)){
log_printf(LOG_WARN, "UART2 RX invalid packet len=%u\n", (unsigned)Size);
SC_SendPacket(NULL, 0, RESP_INVALID); SC_SendPacket(NULL, 0, RESP_INVALID);
} }
g_sc_command_source = SC_SOURCE_UART2; g_sc_command_source = SC_SOURCE_UART2;
HAL_UARTEx_ReceiveToIdle_IT(&huart2, serial_control.rx_buffer, MAX_RX_BUFFER_SIZE - 1); SC_ArmUart2RxDma();
} else if (huart->Instance == huart5.Instance) { } else if (huart->Instance == huart5.Instance) {
if (Size == 0u) {
log_printf(LOG_WARN, "UART5 RX idle event with zero size\n");
}
if (process_received_packet(&serial_iso, serial_iso.rx_buffer, Size)) { if (process_received_packet(&serial_iso, serial_iso.rx_buffer, Size)) {
g_sc_command_source = SC_SOURCE_UART5; g_sc_command_source = SC_SOURCE_UART5;
SC_CommandHandler((ReceivedCommand_t*)&serial_iso.received_command); SC_CommandHandler((ReceivedCommand_t*)&serial_iso.received_command);
} else {
log_printf(LOG_WARN, "UART5 RX invalid packet len=%u\n", (unsigned)Size);
} }
HAL_UARTEx_ReceiveToIdle_IT(&huart5, serial_iso.rx_buffer, MAX_RX_BUFFER_SIZE - 1); SC_ArmUart5RxDma();
} else if (huart->Instance == huart3.Instance) { } else if (huart->Instance == huart3.Instance) {
CCS_RxEventCallback(huart, Size); CCS_RxEventCallback(huart, Size);
} }
} }
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) { ISR_FAST void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
if (huart->Instance == huart2.Instance) { if (huart->Instance == huart2.Instance) {
HAL_GPIO_WritePin(USART2_DIR_GPIO_Port, USART2_DIR_Pin, GPIO_PIN_RESET);
serial_control.tx_tick = 0; serial_control.tx_tick = 0;
} else if (huart->Instance == huart3.Instance) {
CCS_TxCpltCallback(huart);
} }
} }
// Приватные функции реализации // Приватные функции реализации
// Полностью программная реализация CRC-32 (полином CRC32_POLYNOMIAL, порядок little-endian) // Полностью программная реализация 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; uint32_t crc = 0xFFFFFFFFu;
for (uint16_t i = 0; i < length; i++) { for (uint16_t i = 0; i < length; i++) {
@@ -144,7 +177,7 @@ static uint32_t calculate_crc32(const uint8_t* data, uint16_t length) {
return crc ^ 0xFFFFFFFFu; 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; uint16_t out_index = 0;
output[out_index++] = response_code; output[out_index++] = response_code;
@@ -177,24 +210,24 @@ static uint16_t encode_packet(const uint8_t* payload, uint16_t payload_len, uint
return out_index; 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); uint16_t packet_len = encode_packet(payload, payload_len, serial_control.tx_buffer, response_code);
if (packet_len > 0) { if (packet_len > 0) {
if (huart2.gState == HAL_UART_STATE_BUSY_TX) { if (huart2.gState != HAL_UART_STATE_READY) {
HAL_UART_Abort_IT(&huart2); (void)HAL_UART_AbortTransmit(&huart2);
HAL_GPIO_WritePin(USART2_DIR_GPIO_Port, USART2_DIR_Pin, GPIO_PIN_RESET); log_printf(LOG_WARN, "UART2 TX busy, abort transmit before resend\n");
}
if (HAL_UART_Transmit_DMA(&huart2, serial_control.tx_buffer, packet_len) != HAL_OK) {
SC_LogUartError("UART2 TX DMA start failed", &huart2);
return;
} }
HAL_GPIO_WritePin(USART2_DIR_GPIO_Port, USART2_DIR_Pin, GPIO_PIN_SET);
HAL_UART_Transmit_IT(&huart2, serial_control.tx_buffer, packet_len);
serial_control.tx_tick = HAL_GetTick(); 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)) { // if (test_crc_invalid && (packet_data[1] != CMD_GET_STATUS)) {
// test_crc_invalid--; // test_crc_invalid--;
// return 0; // return 0;
@@ -227,7 +260,7 @@ static uint8_t parse_packet(const uint8_t* packet_data, uint16_t packet_len, Rec
return 1; 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)) { if (!parse_packet(packet_data, packet_len, (ReceivedCommand_t *)&ctx->received_command)) {
return 0; return 0;
} }
@@ -236,3 +269,68 @@ static uint8_t process_received_packet(SerialControl_t *ctx, const uint8_t* pack
return 1; return 1;
} }
static void SC_UART2_Watchdog(void) {
const uint32_t now = HAL_GetTick();
const int32_t since_last_packet = (int32_t)(now - sc_uart2_last_packet_tick);
if (since_last_packet >= (int32_t)SC_UART2_PACKET_TIMEOUT_MS) {
if (sc_uart2_timed_out == 0u) {
serial_control.command_ready = 0;
log_printf(LOG_WARN, "UART2 RX packet timeout (%u ms)\n", (unsigned)SC_UART2_PACKET_TIMEOUT_MS);
}
sc_uart2_timed_out = 1;
} else {
sc_uart2_timed_out = 0;
}
if ((huart2.RxState == HAL_UART_STATE_READY) &&
((int32_t)(now - sc_uart2_last_recover_tick) >= (int32_t)SC_UART2_RECOVER_GUARD_MS)) {
SC_ArmUart2RxDma();
sc_uart2_last_recover_tick = now;
}
}
static void SC_ArmUart2RxDma(void) {
if ((huart2.RxState == HAL_UART_STATE_READY) && (serial_control.command_ready == 0)) {
if (HAL_UARTEx_ReceiveToIdle_DMA(&huart2, serial_control.rx_buffer, MAX_RX_BUFFER_SIZE - 1) != HAL_OK) {
SC_LogUartError("UART2 RX DMA arm failed", &huart2);
}
}
}
static void SC_ArmUart5RxDma(void) {
if (huart5.RxState == HAL_UART_STATE_READY) {
if (HAL_UARTEx_ReceiveToIdle_IT(&huart5, serial_iso.rx_buffer, MAX_RX_BUFFER_SIZE - 1) == HAL_OK) {
return;
}
SC_LogUartError("UART5 RX IT arm failed", &huart5);
}
}
void SC_RecoverUartDma(UART_HandleTypeDef *huart) {
if (huart == &huart2) {
SC_LogUartError("UART2 recover start", &huart2);
(void)HAL_UART_AbortReceive(&huart2);
(void)HAL_UART_AbortTransmit(&huart2);
serial_control.tx_tick = 0;
SC_ArmUart2RxDma();
sc_uart2_last_recover_tick = HAL_GetTick();
} else if (huart == &huart5) {
SC_LogUartError("UART5 recover start", &huart5);
(void)HAL_UART_AbortReceive(&huart5);
SC_ArmUart5RxDma();
}
}
static void SC_LogUartError(const char *tag, UART_HandleTypeDef *huart) {
if (tag == NULL || huart == NULL) {
return;
}
log_printf(LOG_ERR, "%s: instance=0x%08lx err=0x%08lx g=%lu rx=%lu\n",
tag,
(unsigned long)huart->Instance,
(unsigned long)HAL_UART_GetError(huart),
(unsigned long)huart->gState,
(unsigned long)huart->RxState);
}
+107 -14
View File
@@ -22,6 +22,9 @@
#include "stm32f1xx_it.h" #include "stm32f1xx_it.h"
/* Private includes ----------------------------------------------------------*/ /* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */ /* USER CODE BEGIN Includes */
#if defined(__GNUC__)
#pragma GCC optimize("Ofast")
#endif
/* USER CODE END Includes */ /* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/ /* Private typedef -----------------------------------------------------------*/
@@ -55,9 +58,15 @@
/* USER CODE END 0 */ /* USER CODE END 0 */
/* External variables --------------------------------------------------------*/ /* External variables --------------------------------------------------------*/
extern DMA_HandleTypeDef hdma_adc1;
extern ADC_HandleTypeDef hadc1;
extern CAN_HandleTypeDef hcan1; extern CAN_HandleTypeDef hcan1;
extern CAN_HandleTypeDef hcan2; extern CAN_HandleTypeDef hcan2;
extern TIM_HandleTypeDef htim3; extern TIM_HandleTypeDef htim3;
extern DMA_HandleTypeDef hdma_usart2_rx;
extern DMA_HandleTypeDef hdma_usart2_tx;
extern DMA_HandleTypeDef hdma_usart3_rx;
extern DMA_HandleTypeDef hdma_usart3_tx;
extern UART_HandleTypeDef huart5; extern UART_HandleTypeDef huart5;
extern UART_HandleTypeDef huart1; extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart2; extern UART_HandleTypeDef huart2;
@@ -204,17 +213,101 @@ void SysTick_Handler(void)
/* please refer to the startup file (startup_stm32f1xx.s). */ /* please refer to the startup file (startup_stm32f1xx.s). */
/******************************************************************************/ /******************************************************************************/
/**
* @brief This function handles DMA1 channel1 global interrupt.
*/
void DMA1_Channel1_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel1_IRQn 0 */
HAL_GPIO_WritePin(DBG4_GPIO_Port, DBG4_Pin, GPIO_PIN_SET);
/* USER CODE END DMA1_Channel1_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_adc1);
/* USER CODE BEGIN DMA1_Channel1_IRQn 1 */
HAL_GPIO_WritePin(DBG4_GPIO_Port, DBG4_Pin, GPIO_PIN_RESET);
/* USER CODE END DMA1_Channel1_IRQn 1 */
}
/**
* @brief This function handles DMA1 channel2 global interrupt.
*/
void DMA1_Channel2_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel2_IRQn 0 */
/* USER CODE END DMA1_Channel2_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart3_tx);
/* USER CODE BEGIN DMA1_Channel2_IRQn 1 */
/* USER CODE END DMA1_Channel2_IRQn 1 */
}
/**
* @brief This function handles DMA1 channel3 global interrupt.
*/
void DMA1_Channel3_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel3_IRQn 0 */
/* USER CODE END DMA1_Channel3_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart3_rx);
/* USER CODE BEGIN DMA1_Channel3_IRQn 1 */
/* USER CODE END DMA1_Channel3_IRQn 1 */
}
/**
* @brief This function handles DMA1 channel6 global interrupt.
*/
void DMA1_Channel6_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel6_IRQn 0 */
/* USER CODE END DMA1_Channel6_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart2_rx);
/* USER CODE BEGIN DMA1_Channel6_IRQn 1 */
/* USER CODE END DMA1_Channel6_IRQn 1 */
}
/**
* @brief This function handles DMA1 channel7 global interrupt.
*/
void DMA1_Channel7_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel7_IRQn 0 */
/* USER CODE END DMA1_Channel7_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart2_tx);
/* USER CODE BEGIN DMA1_Channel7_IRQn 1 */
/* USER CODE END DMA1_Channel7_IRQn 1 */
}
/**
* @brief This function handles ADC1 and ADC2 global interrupts.
*/
void ADC1_2_IRQHandler(void)
{
/* USER CODE BEGIN ADC1_2_IRQn 0 */
HAL_GPIO_WritePin(DBG4_GPIO_Port, DBG4_Pin, GPIO_PIN_SET);
/* USER CODE END ADC1_2_IRQn 0 */
HAL_ADC_IRQHandler(&hadc1);
/* USER CODE BEGIN ADC1_2_IRQn 1 */
HAL_GPIO_WritePin(DBG4_GPIO_Port, DBG4_Pin, GPIO_PIN_RESET);
/* USER CODE END ADC1_2_IRQn 1 */
}
/** /**
* @brief This function handles CAN1 RX0 interrupt. * @brief This function handles CAN1 RX0 interrupt.
*/ */
void CAN1_RX0_IRQHandler(void) void CAN1_RX0_IRQHandler(void)
{ {
/* USER CODE BEGIN CAN1_RX0_IRQn 0 */ /* 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 */ /* USER CODE END CAN1_RX0_IRQn 0 */
HAL_CAN_IRQHandler(&hcan1); HAL_CAN_IRQHandler(&hcan1);
/* USER CODE BEGIN CAN1_RX0_IRQn 1 */ /* 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 */ /* USER CODE END CAN1_RX0_IRQn 1 */
} }
@@ -224,11 +317,11 @@ void CAN1_RX0_IRQHandler(void)
void TIM3_IRQHandler(void) void TIM3_IRQHandler(void)
{ {
/* USER CODE BEGIN TIM3_IRQn 0 */ /* USER CODE BEGIN TIM3_IRQn 0 */
HAL_GPIO_WritePin(DBG4_GPIO_Port, DBG4_Pin, GPIO_PIN_SET);
/* USER CODE END TIM3_IRQn 0 */ /* USER CODE END TIM3_IRQn 0 */
HAL_TIM_IRQHandler(&htim3); HAL_TIM_IRQHandler(&htim3);
/* USER CODE BEGIN TIM3_IRQn 1 */ /* USER CODE BEGIN TIM3_IRQn 1 */
HAL_GPIO_WritePin(DBG4_GPIO_Port, DBG4_Pin, GPIO_PIN_RESET);
/* USER CODE END TIM3_IRQn 1 */ /* USER CODE END TIM3_IRQn 1 */
} }
@@ -252,11 +345,11 @@ void USART1_IRQHandler(void)
void USART2_IRQHandler(void) void USART2_IRQHandler(void)
{ {
/* USER CODE BEGIN USART2_IRQn 0 */ /* USER CODE BEGIN USART2_IRQn 0 */
HAL_GPIO_WritePin(DBG2_GPIO_Port, DBG2_Pin, GPIO_PIN_SET);
/* USER CODE END USART2_IRQn 0 */ /* USER CODE END USART2_IRQn 0 */
HAL_UART_IRQHandler(&huart2); HAL_UART_IRQHandler(&huart2);
/* USER CODE BEGIN USART2_IRQn 1 */ /* USER CODE BEGIN USART2_IRQn 1 */
HAL_GPIO_WritePin(DBG2_GPIO_Port, DBG2_Pin, GPIO_PIN_RESET);
/* USER CODE END USART2_IRQn 1 */ /* USER CODE END USART2_IRQn 1 */
} }
@@ -266,11 +359,11 @@ void USART2_IRQHandler(void)
void USART3_IRQHandler(void) void USART3_IRQHandler(void)
{ {
/* USER CODE BEGIN USART3_IRQn 0 */ /* USER CODE BEGIN USART3_IRQn 0 */
HAL_GPIO_WritePin(DBG3_GPIO_Port, DBG3_Pin, GPIO_PIN_SET);
/* USER CODE END USART3_IRQn 0 */ /* USER CODE END USART3_IRQn 0 */
HAL_UART_IRQHandler(&huart3); HAL_UART_IRQHandler(&huart3);
/* USER CODE BEGIN USART3_IRQn 1 */ /* USER CODE BEGIN USART3_IRQn 1 */
HAL_GPIO_WritePin(DBG3_GPIO_Port, DBG3_Pin, GPIO_PIN_RESET);
/* USER CODE END USART3_IRQn 1 */ /* USER CODE END USART3_IRQn 1 */
} }
@@ -280,11 +373,11 @@ void USART3_IRQHandler(void)
void UART5_IRQHandler(void) void UART5_IRQHandler(void)
{ {
/* USER CODE BEGIN UART5_IRQn 0 */ /* USER CODE BEGIN UART5_IRQn 0 */
HAL_GPIO_WritePin(DBG1_GPIO_Port, DBG1_Pin, GPIO_PIN_SET);
/* USER CODE END UART5_IRQn 0 */ /* USER CODE END UART5_IRQn 0 */
HAL_UART_IRQHandler(&huart5); HAL_UART_IRQHandler(&huart5);
/* USER CODE BEGIN UART5_IRQn 1 */ /* USER CODE BEGIN UART5_IRQn 1 */
HAL_GPIO_WritePin(DBG1_GPIO_Port, DBG1_Pin, GPIO_PIN_RESET);
/* USER CODE END UART5_IRQn 1 */ /* USER CODE END UART5_IRQn 1 */
} }
@@ -294,11 +387,11 @@ void UART5_IRQHandler(void)
void CAN2_TX_IRQHandler(void) void CAN2_TX_IRQHandler(void)
{ {
/* USER CODE BEGIN CAN2_TX_IRQn 0 */ /* 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 */ /* USER CODE END CAN2_TX_IRQn 0 */
HAL_CAN_IRQHandler(&hcan2); HAL_CAN_IRQHandler(&hcan2);
/* USER CODE BEGIN CAN2_TX_IRQn 1 */ /* 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 */ /* USER CODE END CAN2_TX_IRQn 1 */
} }
@@ -308,11 +401,11 @@ void CAN2_TX_IRQHandler(void)
void CAN2_RX1_IRQHandler(void) void CAN2_RX1_IRQHandler(void)
{ {
/* USER CODE BEGIN CAN2_RX1_IRQn 0 */ /* 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 */ /* USER CODE END CAN2_RX1_IRQn 0 */
HAL_CAN_IRQHandler(&hcan2); HAL_CAN_IRQHandler(&hcan2);
/* USER CODE BEGIN CAN2_RX1_IRQn 1 */ /* 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 END CAN2_RX1_IRQn 1 */
} }
+12 -12
View File
@@ -57,31 +57,31 @@ void MX_TIM3_Init(void)
{ {
Error_Handler(); Error_Handler();
} }
if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_OC_Init(&htim3) != HAL_OK) if (HAL_TIM_OC_Init(&htim3) != HAL_OK)
{ {
Error_Handler(); Error_Handler();
} }
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC1;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK) if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
{ {
Error_Handler(); Error_Handler();
} }
sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.OCMode = TIM_OCMODE_TIMING;
sConfigOC.Pulse = 0; sConfigOC.Pulse = 1;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; 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(); Error_Handler();
} }
sConfigOC.OCMode = TIM_OCMODE_TIMING; sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 1; sConfigOC.Pulse = 0;
if (HAL_TIM_OC_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
{ {
Error_Handler(); Error_Handler();
} }
@@ -166,7 +166,7 @@ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
__HAL_RCC_TIM3_CLK_ENABLE(); __HAL_RCC_TIM3_CLK_ENABLE();
/* TIM3 interrupt Init */ /* TIM3 interrupt Init */
HAL_NVIC_SetPriority(TIM3_IRQn, 0, 0); HAL_NVIC_SetPriority(TIM3_IRQn, 6, 0);
HAL_NVIC_EnableIRQ(TIM3_IRQn); HAL_NVIC_EnableIRQ(TIM3_IRQn);
/* USER CODE BEGIN TIM3_MspInit 1 */ /* USER CODE BEGIN TIM3_MspInit 1 */
+82 -4
View File
@@ -28,6 +28,10 @@ UART_HandleTypeDef huart5;
UART_HandleTypeDef huart1; UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2; UART_HandleTypeDef huart2;
UART_HandleTypeDef huart3; UART_HandleTypeDef huart3;
DMA_HandleTypeDef hdma_usart2_rx;
DMA_HandleTypeDef hdma_usart2_tx;
DMA_HandleTypeDef hdma_usart3_rx;
DMA_HandleTypeDef hdma_usart3_tx;
/* UART5 init function */ /* UART5 init function */
void MX_UART5_Init(void) void MX_UART5_Init(void)
@@ -174,7 +178,7 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* UART5 interrupt Init */ /* UART5 interrupt Init */
HAL_NVIC_SetPriority(UART5_IRQn, 0, 0); HAL_NVIC_SetPriority(UART5_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(UART5_IRQn); HAL_NVIC_EnableIRQ(UART5_IRQn);
/* USER CODE BEGIN UART5_MspInit 1 */ /* USER CODE BEGIN UART5_MspInit 1 */
@@ -204,7 +208,7 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART1 interrupt Init */ /* USART1 interrupt Init */
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0); HAL_NVIC_SetPriority(USART1_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn); HAL_NVIC_EnableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspInit 1 */ /* USER CODE BEGIN USART1_MspInit 1 */
@@ -235,8 +239,41 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
__HAL_AFIO_REMAP_USART2_ENABLE(); __HAL_AFIO_REMAP_USART2_ENABLE();
/* USART2 DMA Init */
/* USART2_RX Init */
hdma_usart2_rx.Instance = DMA1_Channel6;
hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_rx.Init.Mode = DMA_NORMAL;
hdma_usart2_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
if (HAL_DMA_Init(&hdma_usart2_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmarx,hdma_usart2_rx);
/* USART2_TX Init */
hdma_usart2_tx.Instance = DMA1_Channel7;
hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_tx.Init.Mode = DMA_NORMAL;
hdma_usart2_tx.Init.Priority = DMA_PRIORITY_HIGH;
if (HAL_DMA_Init(&hdma_usart2_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmatx,hdma_usart2_tx);
/* USART2 interrupt Init */ /* USART2 interrupt Init */
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0); HAL_NVIC_SetPriority(USART2_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn); HAL_NVIC_EnableIRQ(USART2_IRQn);
/* USER CODE BEGIN USART2_MspInit 1 */ /* USER CODE BEGIN USART2_MspInit 1 */
@@ -267,8 +304,41 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
__HAL_AFIO_REMAP_USART3_PARTIAL(); __HAL_AFIO_REMAP_USART3_PARTIAL();
/* USART3 DMA Init */
/* USART3_RX Init */
hdma_usart3_rx.Instance = DMA1_Channel3;
hdma_usart3_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart3_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart3_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart3_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart3_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart3_rx.Init.Mode = DMA_NORMAL;
hdma_usart3_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
if (HAL_DMA_Init(&hdma_usart3_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmarx,hdma_usart3_rx);
/* USART3_TX Init */
hdma_usart3_tx.Instance = DMA1_Channel2;
hdma_usart3_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart3_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart3_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart3_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart3_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart3_tx.Init.Mode = DMA_NORMAL;
hdma_usart3_tx.Init.Priority = DMA_PRIORITY_HIGH;
if (HAL_DMA_Init(&hdma_usart3_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmatx,hdma_usart3_tx);
/* USART3 interrupt Init */ /* USART3 interrupt Init */
HAL_NVIC_SetPriority(USART3_IRQn, 0, 0); HAL_NVIC_SetPriority(USART3_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(USART3_IRQn); HAL_NVIC_EnableIRQ(USART3_IRQn);
/* USER CODE BEGIN USART3_MspInit 1 */ /* USER CODE BEGIN USART3_MspInit 1 */
@@ -335,6 +405,10 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
*/ */
HAL_GPIO_DeInit(GPIOD, GPIO_PIN_5|GPIO_PIN_6); HAL_GPIO_DeInit(GPIOD, GPIO_PIN_5|GPIO_PIN_6);
/* USART2 DMA DeInit */
HAL_DMA_DeInit(uartHandle->hdmarx);
HAL_DMA_DeInit(uartHandle->hdmatx);
/* USART2 interrupt Deinit */ /* USART2 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART2_IRQn); HAL_NVIC_DisableIRQ(USART2_IRQn);
/* USER CODE BEGIN USART2_MspDeInit 1 */ /* USER CODE BEGIN USART2_MspDeInit 1 */
@@ -355,6 +429,10 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
*/ */
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_10|GPIO_PIN_11); HAL_GPIO_DeInit(GPIOC, GPIO_PIN_10|GPIO_PIN_11);
/* USART3 DMA DeInit */
HAL_DMA_DeInit(uartHandle->hdmarx);
HAL_DMA_DeInit(uartHandle->hdmatx);
/* USART3 interrupt Deinit */ /* USART3 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART3_IRQn); HAL_NVIC_DisableIRQ(USART3_IRQn);
/* USER CODE BEGIN USART3_MspDeInit 1 */ /* USER CODE BEGIN USART3_MspDeInit 1 */
-1
View File
@@ -59,7 +59,6 @@ defined in linker script */
.weak Reset_Handler .weak Reset_Handler
.type Reset_Handler, %function .type Reset_Handler, %function
Reset_Handler: Reset_Handler:
ldr sp, =_estack /* set stack pointer */
/* Call the clock system initialization function.*/ /* Call the clock system initialization function.*/
bl SystemInit bl SystemInit
BIN
View File
Binary file not shown.
Binary file not shown.
+26739 -23683
View File
File diff suppressed because it is too large Load Diff
+3767 -3360
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
+5 -3
View File
@@ -1,3 +1,5 @@
../Core/Src/adc.c:30:6:MX_ADC1_Init 3 ../Core/Src/adc.c:29:6:ADC_ScanStart 2
../Core/Src/adc.c:72:6:HAL_ADC_MspInit 2 ../Core/Src/adc.c:37:15:HAL_ADC_ConvCpltCallback 2
../Core/Src/adc.c:106:6:HAL_ADC_MspDeInit 2 ../Core/Src/adc.c:59:6:MX_ADC1_Init 8
../Core/Src/adc.c:146:6:HAL_ADC_MspInit 3
../Core/Src/adc.c:200:6:HAL_ADC_MspDeInit 2
+10 -10
View File
@@ -1,13 +1,13 @@
../Core/Src/board.c:19:6:RELAY_Write 9 ../Core/Src/board.c:18:6:RELAY_Write 9
../Core/Src/board.c:52:9:RELAY_Read 1 ../Core/Src/board.c:51:9:RELAY_Read 1
../Core/Src/board.c:57:9:IN_ReadInput 8 ../Core/Src/board.c:56:9:IN_ReadInput 8
../Core/Src/board.c:78:9:GetBoardTemp 1 ../Core/Src/board.c:77:9:GetBoardTemp 1
../Core/Src/board.c:90:6:Init_Peripheral 1 ../Core/Src/board.c:89:6:Init_Peripheral 1
../Core/Src/board.c:106:7:pt1000_to_temperature 1 ../Core/Src/board.c:106:7:pt1000_to_temperature 1
../Core/Src/board.c:117:7:calculate_NTC_resistance 2 ../Core/Src/board.c:117:7:calculate_NTC_resistance 2
../Core/Src/board.c:132:9:CONN_ReadTemp 4 ../Core/Src/board.c:132:9:CONN_ReadTemp 4
../Core/Src/board.c:169:9:GBT_ReadTemp 1 ../Core/Src/board.c:152:9:GBT_ReadTemp 1
../Core/Src/board.c:173:6:ADC_Select_Channel 2 ../Core/Src/board.c:156:6:ADC_Select_Channel 2
../Core/Src/board.c:184:9:ADC_TryLock 4 ../Core/Src/board.c:167:9:ADC_TryLock 4
../Core/Src/board.c:200:6:ADC_LockBlocking 2 ../Core/Src/board.c:183:6:ADC_LockBlocking 2
../Core/Src/board.c:206:6:ADC_Unlock 2 ../Core/Src/board.c:189:6:ADC_Unlock 2
+5 -5
View File
@@ -1,5 +1,5 @@
../Core/Src/charger_control.c:11:6:CONN_Init 1 ../Core/Src/charger_control.c:12:6:CONN_Init 1
../Core/Src/charger_control.c:19:6:CONN_Loop 6 ../Core/Src/charger_control.c:20:6:CONN_Loop 6
../Core/Src/charger_control.c:41:6:CONN_Task 5 ../Core/Src/charger_control.c:42:6:CONN_Task 1
../Core/Src/charger_control.c:57:6:CONN_SetState 16 ../Core/Src/charger_control.c:49:6:CONN_SetState 16
../Core/Src/charger_control.c:83:6:CONN_PrintChargingTotal 1 ../Core/Src/charger_control.c:75:6:CONN_PrintChargingTotal 1
+9 -9
View File
@@ -1,9 +1,9 @@
../Core/Src/cp.c:13:17:CP_ReadAdcChannel 1 ../Core/Src/cp.c:19:16:CP_ReadVoltageMv 1
../Core/Src/cp.c:26:16:CP_ReadVoltageMv 1 ../Core/Src/cp.c:36:6:CP_Init 1
../Core/Src/cp.c:39:6:CP_Init 1 ../Core/Src/cp.c:53:6:CP_SetDuty 1
../Core/Src/cp.c:56:6:CP_SetDuty 1 ../Core/Src/cp.c:66:9:CP_GetDuty 1
../Core/Src/cp.c:69:9:CP_GetDuty 1 ../Core/Src/cp.c:70:9:CP_GetVoltage 1
../Core/Src/cp.c:73:9:CP_GetVoltage 1 ../Core/Src/cp.c:75:12:CP_GetState 12
../Core/Src/cp.c:77:12:CP_GetState 12 ../Core/Src/cp.c:99:12:CP_GetFilteredState 1
../Core/Src/cp.c:101:6:CP_Loop 1 ../Core/Src/cp.c:103:6:CP_FilterState 5
../Core/Src/cp.c:105:6:HAL_TIM_OC_DelayElapsedCallback 4 ../Core/Src/cp.c:131:6:CP_Loop 5
+1
View File
@@ -0,0 +1 @@
../Core/Src/dma.c:39:6:MX_DMA_Init 1
+9 -8
View File
@@ -1,8 +1,9 @@
../Core/Src/main.c:64:13:VectorBase_Config 1 ../Drivers/CMSIS/Include/core_cm3.h:1762:34:__NVIC_SystemReset 1
../Core/Src/main.c:75:9:ED_TraceWarning 3 ../Core/Src/main.c:65:13:VectorBase_Config 1
../Core/Src/main.c:87:6:ED_Delay 3 ../Core/Src/main.c:76:9:ED_TraceWarning 3
../Core/Src/main.c:106:6:StopButtonControl 2 ../Core/Src/main.c:88:6:ED_Delay 3
../Core/Src/main.c:117:13:CAN1_MinimalReInit 3 ../Core/Src/main.c:108:6:StopButtonControl 8
../Core/Src/main.c:135:5:main 1 ../Core/Src/main.c:151:13:CAN1_MinimalReInit 3
../Core/Src/main.c:216:6:SystemClock_Config 4 ../Core/Src/main.c:169:5:main 1
../Core/Src/main.c:276:6:Error_Handler 1 ../Core/Src/main.c:250:6:SystemClock_Config 4
../Core/Src/main.c:310:6:Error_Handler 1
+12 -12
View File
@@ -1,12 +1,12 @@
../Core/Src/psu_control.c:33:13:PSU_SwitchState 1 ../Core/Src/psu_control.c:34:13:PSU_SwitchState 1
../Core/Src/psu_control.c:38:17:PSU_StateTime 1 ../Core/Src/psu_control.c:39:17:PSU_StateTime 1
../Core/Src/psu_control.c:42:6:HAL_CAN_RxFifo1MsgPendingCallback 9 ../Core/Src/psu_control.c:43:15:HAL_CAN_RxFifo1MsgPendingCallback 9
../Core/Src/psu_control.c:116:6:PSU_CAN_FilterInit 2 ../Core/Src/psu_control.c:117:6:PSU_CAN_FilterInit 2
../Core/Src/psu_control.c:139:6:PSU_Init 1 ../Core/Src/psu_control.c:140:6:PSU_Init 1
../Core/Src/psu_control.c:156:6:PSU_Enable 3 ../Core/Src/psu_control.c:158:6:PSU_Enable 3
../Core/Src/psu_control.c:168:6:PSU_SetHVMode 2 ../Core/Src/psu_control.c:170:6:PSU_SetHVMode 2
../Core/Src/psu_control.c:175:6:PSU_SetVoltageCurrent 5 ../Core/Src/psu_control.c:177:6:PSU_SetVoltageCurrent 5
../Core/Src/psu_control.c:202:6:PSU_SendCmd 4 ../Core/Src/psu_control.c:204:6:PSU_SendCmd 4
../Core/Src/psu_control.c:238:10:max 2 ../Core/Src/psu_control.c:240:10:max 2
../Core/Src/psu_control.c:243:6:PSU_ReadWrite 5 ../Core/Src/psu_control.c:245:6:PSU_ReadWrite 8
../Core/Src/psu_control.c:276:6:PSU_Task 41 ../Core/Src/psu_control.c:289:6:PSU_Task 41
+6 -6
View File
@@ -1,6 +1,6 @@
../Core/Src/rgb_controller.c:92:6:LED_Write 16 ../Core/Src/rgb_controller.c:102:6:LED_Write 18
../Core/Src/rgb_controller.c:146:6:interpolateColors 3 ../Core/Src/rgb_controller.c:164:6:interpolateColors 3
../Core/Src/rgb_controller.c:164:6:RGB_SetColor 1 ../Core/Src/rgb_controller.c:182:6:RGB_SetColor 1
../Core/Src/rgb_controller.c:170:6:LED_SetColor 1 ../Core/Src/rgb_controller.c:188:6:LED_SetColor 1
../Core/Src/rgb_controller.c:175:6:LED_Init 1 ../Core/Src/rgb_controller.c:193:6:LED_Init 1
../Core/Src/rgb_controller.c:207:6:LED_Task 10 ../Core/Src/rgb_controller.c:225:6:LED_Task 10
+20 -15
View File
@@ -1,15 +1,20 @@
../Drivers/CMSIS/Include/core_cm3.h:1762:34:__NVIC_SystemReset 1 ../Core/Src/serial.c:70:22:uart3_log_hal_error 3
../Core/Src/serial.c:51:6:CCS_RxEventCallback 4 ../Core/Src/serial.c:90:22:uart3_arm_rx_or_log 3
../Core/Src/serial.c:61:6:CCS_SerialLoop 41 ../Core/Src/serial.c:106:15:CCS_RxEventCallback 4
../Core/Src/serial.c:206:6:CCS_Init 1 ../Core/Src/serial.c:129:15:HAL_UART_ErrorCallback 5
../Core/Src/serial.c:218:17:crc16_ibm 4 ../Core/Src/serial.c:149:6:CCS_TxCpltCallback 4
../Core/Src/serial.c:233:17:CCS_BuildPacket 4 ../Core/Src/serial.c:165:6:CCS_SerialLoop 62
../Core/Src/serial.c:249:13:CCS_SendPacket 2 ../Core/Src/serial.c:365:6:CCS_Init 1
../Core/Src/serial.c:257:13:CCS_SendResetReason 1 ../Core/Src/serial.c:380:26:crc16_ibm 3
../Core/Src/serial.c:261:6:CCS_SendEmergencyStop 1 ../Core/Src/serial.c:395:17:CCS_BuildPacket 4
../Core/Src/serial.c:265:6:CCS_SendStart 1 ../Core/Src/serial.c:411:13:CCS_SendPacket 4
../Core/Src/serial.c:269:13:CCS_CalculateEnergy 2 ../Core/Src/serial.c:428:13:CCS_SendResetReason 1
../Core/Src/serial.c:284:13:send_state 2 ../Core/Src/serial.c:432:6:CCS_SendEmergencyStop 1
../Core/Src/serial.c:311:17:expected_payload_len 11 ../Core/Src/serial.c:436:6:CCS_SendStart 1
../Core/Src/serial.c:327:13:apply_command 13 ../Core/Src/serial.c:440:13:CCS_CalculateEnergy 2
../Core/Src/serial.c:394:16:process_received_packet 6 ../Core/Src/serial.c:455:13:send_state 3
../Core/Src/serial.c:485:26:expected_payload_len 2
../Core/Src/serial.c:501:22:apply_command 15
../Core/Src/serial.c:583:25:process_received_packet 8
../Core/Src/serial.c:636:13:CCS_UART3_Watchdog 4
../Core/Src/serial.c:649:13:CCS_LogUart3Error 1
+15 -10
View File
@@ -1,10 +1,15 @@
../Core/Src/serial_control.c:59:6:ReadVersion 1 ../Core/Src/serial_control.c:71:6:ReadVersion 1
../Core/Src/serial_control.c:71:6:SC_Init 1 ../Core/Src/serial_control.c:83:6:SC_Init 1
../Core/Src/serial_control.c:77:6:SC_Task 9 ../Core/Src/serial_control.c:94:6:SC_Task 7
../Core/Src/serial_control.c:102:6:HAL_UARTEx_RxEventCallback 6 ../Core/Src/serial_control.c:122:15:HAL_UARTEx_RxEventCallback 8
../Core/Src/serial_control.c:120:6:HAL_UART_TxCpltCallback 2 ../Core/Src/serial_control.c:152:15:HAL_UART_TxCpltCallback 3
../Core/Src/serial_control.c:130:17:calculate_crc32 4 ../Core/Src/serial_control.c:163:26:calculate_crc32 3
../Core/Src/serial_control.c:147:17:encode_packet 6 ../Core/Src/serial_control.c:180:26:encode_packet 5
../Core/Src/serial_control.c:180:6:SC_SendPacket 3 ../Core/Src/serial_control.c:213:15:SC_SendPacket 4
../Core/Src/serial_control.c:197:16:parse_packet 4 ../Core/Src/serial_control.c:230:25:parse_packet 3
../Core/Src/serial_control.c:230:16:process_received_packet 2 ../Core/Src/serial_control.c:263:25:process_received_packet 2
../Core/Src/serial_control.c:272:13:SC_UART2_Watchdog 5
../Core/Src/serial_control.c:293:13:SC_ArmUart2RxDma 4
../Core/Src/serial_control.c:301:13:SC_ArmUart5RxDma 3
../Core/Src/serial_control.c:310:6:SC_RecoverUartDma 3
../Core/Src/serial_control.c:325:13:SC_LogUartError 3
+23 -17
View File
@@ -1,17 +1,23 @@
../Core/Src/stm32f1xx_it.c:75:6:NMI_Handler 1 ../Core/Src/stm32f1xx_it.c:84:6:NMI_Handler 1
../Core/Src/stm32f1xx_it.c:90:6:HardFault_Handler 1 ../Core/Src/stm32f1xx_it.c:99:6:HardFault_Handler 1
../Core/Src/stm32f1xx_it.c:105:6:MemManage_Handler 1 ../Core/Src/stm32f1xx_it.c:114:6:MemManage_Handler 1
../Core/Src/stm32f1xx_it.c:120:6:BusFault_Handler 1 ../Core/Src/stm32f1xx_it.c:129:6:BusFault_Handler 1
../Core/Src/stm32f1xx_it.c:135:6:UsageFault_Handler 1 ../Core/Src/stm32f1xx_it.c:144:6:UsageFault_Handler 1
../Core/Src/stm32f1xx_it.c:150:6:SVC_Handler 1 ../Core/Src/stm32f1xx_it.c:159:6:SVC_Handler 1
../Core/Src/stm32f1xx_it.c:163:6:DebugMon_Handler 1 ../Core/Src/stm32f1xx_it.c:172:6:DebugMon_Handler 1
../Core/Src/stm32f1xx_it.c:176:6:PendSV_Handler 1 ../Core/Src/stm32f1xx_it.c:185:6:PendSV_Handler 1
../Core/Src/stm32f1xx_it.c:189:6:SysTick_Handler 1 ../Core/Src/stm32f1xx_it.c:198:6:SysTick_Handler 1
../Core/Src/stm32f1xx_it.c:210:6:CAN1_RX0_IRQHandler 1 ../Core/Src/stm32f1xx_it.c:219:6:DMA1_Channel1_IRQHandler 1
../Core/Src/stm32f1xx_it.c:224:6:TIM3_IRQHandler 1 ../Core/Src/stm32f1xx_it.c:233:6:DMA1_Channel2_IRQHandler 1
../Core/Src/stm32f1xx_it.c:238:6:USART1_IRQHandler 1 ../Core/Src/stm32f1xx_it.c:247:6:DMA1_Channel3_IRQHandler 1
../Core/Src/stm32f1xx_it.c:252:6:USART2_IRQHandler 1 ../Core/Src/stm32f1xx_it.c:261:6:DMA1_Channel6_IRQHandler 1
../Core/Src/stm32f1xx_it.c:266:6:USART3_IRQHandler 1 ../Core/Src/stm32f1xx_it.c:275:6:DMA1_Channel7_IRQHandler 1
../Core/Src/stm32f1xx_it.c:280:6:UART5_IRQHandler 1 ../Core/Src/stm32f1xx_it.c:289:6:ADC1_2_IRQHandler 1
../Core/Src/stm32f1xx_it.c:294:6:CAN2_TX_IRQHandler 1 ../Core/Src/stm32f1xx_it.c:303:6:CAN1_RX0_IRQHandler 1
../Core/Src/stm32f1xx_it.c:308:6:CAN2_RX1_IRQHandler 1 ../Core/Src/stm32f1xx_it.c:317:6:TIM3_IRQHandler 1
../Core/Src/stm32f1xx_it.c:331:6:USART1_IRQHandler 1
../Core/Src/stm32f1xx_it.c:345:6:USART2_IRQHandler 1
../Core/Src/stm32f1xx_it.c:359:6:USART3_IRQHandler 1
../Core/Src/stm32f1xx_it.c:373:6:UART5_IRQHandler 1
../Core/Src/stm32f1xx_it.c:387:6:CAN2_TX_IRQHandler 1
../Core/Src/stm32f1xx_it.c:401:6:CAN2_RX1_IRQHandler 1
+4 -1
View File
@@ -12,6 +12,7 @@ C_SRCS += \
../Core/Src/cp.c \ ../Core/Src/cp.c \
../Core/Src/crc.c \ ../Core/Src/crc.c \
../Core/Src/debug.c \ ../Core/Src/debug.c \
../Core/Src/dma.c \
../Core/Src/gpio.c \ ../Core/Src/gpio.c \
../Core/Src/main.c \ ../Core/Src/main.c \
../Core/Src/meter.c \ ../Core/Src/meter.c \
@@ -39,6 +40,7 @@ C_DEPS += \
./Core/Src/cp.d \ ./Core/Src/cp.d \
./Core/Src/crc.d \ ./Core/Src/crc.d \
./Core/Src/debug.d \ ./Core/Src/debug.d \
./Core/Src/dma.d \
./Core/Src/gpio.d \ ./Core/Src/gpio.d \
./Core/Src/main.d \ ./Core/Src/main.d \
./Core/Src/meter.d \ ./Core/Src/meter.d \
@@ -66,6 +68,7 @@ OBJS += \
./Core/Src/cp.o \ ./Core/Src/cp.o \
./Core/Src/crc.o \ ./Core/Src/crc.o \
./Core/Src/debug.o \ ./Core/Src/debug.o \
./Core/Src/dma.o \
./Core/Src/gpio.o \ ./Core/Src/gpio.o \
./Core/Src/main.o \ ./Core/Src/main.o \
./Core/Src/meter.o \ ./Core/Src/meter.o \
@@ -93,7 +96,7 @@ Core/Src/%.o Core/Src/%.su Core/Src/%.cyclo: ../Core/Src/%.c Core/Src/subdir.mk
clean: clean-Core-2f-Src clean: clean-Core-2f-Src
clean-Core-2f-Src: clean-Core-2f-Src:
-$(RM) ./Core/Src/adc.cyclo ./Core/Src/adc.d ./Core/Src/adc.o ./Core/Src/adc.su ./Core/Src/board.cyclo ./Core/Src/board.d ./Core/Src/board.o ./Core/Src/board.su ./Core/Src/can.cyclo ./Core/Src/can.d ./Core/Src/can.o ./Core/Src/can.su ./Core/Src/charger_control.cyclo ./Core/Src/charger_control.d ./Core/Src/charger_control.o ./Core/Src/charger_control.su ./Core/Src/cp.cyclo ./Core/Src/cp.d ./Core/Src/cp.o ./Core/Src/cp.su ./Core/Src/crc.cyclo ./Core/Src/crc.d ./Core/Src/crc.o ./Core/Src/crc.su ./Core/Src/debug.cyclo ./Core/Src/debug.d ./Core/Src/debug.o ./Core/Src/debug.su ./Core/Src/gpio.cyclo ./Core/Src/gpio.d ./Core/Src/gpio.o ./Core/Src/gpio.su ./Core/Src/main.cyclo ./Core/Src/main.d ./Core/Src/main.o ./Core/Src/main.su ./Core/Src/meter.cyclo ./Core/Src/meter.d ./Core/Src/meter.o ./Core/Src/meter.su ./Core/Src/psu_control.cyclo ./Core/Src/psu_control.d ./Core/Src/psu_control.o ./Core/Src/psu_control.su ./Core/Src/rgb_controller.cyclo ./Core/Src/rgb_controller.d ./Core/Src/rgb_controller.o ./Core/Src/rgb_controller.su ./Core/Src/rtc.cyclo ./Core/Src/rtc.d ./Core/Src/rtc.o ./Core/Src/rtc.su ./Core/Src/serial.cyclo ./Core/Src/serial.d ./Core/Src/serial.o ./Core/Src/serial.su ./Core/Src/serial_control.cyclo ./Core/Src/serial_control.d ./Core/Src/serial_control.o ./Core/Src/serial_control.su ./Core/Src/serial_handler.cyclo ./Core/Src/serial_handler.d ./Core/Src/serial_handler.o ./Core/Src/serial_handler.su ./Core/Src/sma_filter.cyclo ./Core/Src/sma_filter.d ./Core/Src/sma_filter.o ./Core/Src/sma_filter.su ./Core/Src/soft_rtc.cyclo ./Core/Src/soft_rtc.d ./Core/Src/soft_rtc.o ./Core/Src/soft_rtc.su ./Core/Src/stm32f1xx_hal_msp.cyclo ./Core/Src/stm32f1xx_hal_msp.d ./Core/Src/stm32f1xx_hal_msp.o ./Core/Src/stm32f1xx_hal_msp.su ./Core/Src/stm32f1xx_it.cyclo ./Core/Src/stm32f1xx_it.d ./Core/Src/stm32f1xx_it.o ./Core/Src/stm32f1xx_it.su ./Core/Src/syscalls.cyclo ./Core/Src/syscalls.d ./Core/Src/syscalls.o ./Core/Src/syscalls.su ./Core/Src/sysmem.cyclo ./Core/Src/sysmem.d ./Core/Src/sysmem.o ./Core/Src/sysmem.su ./Core/Src/system_stm32f1xx.cyclo ./Core/Src/system_stm32f1xx.d ./Core/Src/system_stm32f1xx.o ./Core/Src/system_stm32f1xx.su ./Core/Src/tim.cyclo ./Core/Src/tim.d ./Core/Src/tim.o ./Core/Src/tim.su ./Core/Src/usart.cyclo ./Core/Src/usart.d ./Core/Src/usart.o ./Core/Src/usart.su -$(RM) ./Core/Src/adc.cyclo ./Core/Src/adc.d ./Core/Src/adc.o ./Core/Src/adc.su ./Core/Src/board.cyclo ./Core/Src/board.d ./Core/Src/board.o ./Core/Src/board.su ./Core/Src/can.cyclo ./Core/Src/can.d ./Core/Src/can.o ./Core/Src/can.su ./Core/Src/charger_control.cyclo ./Core/Src/charger_control.d ./Core/Src/charger_control.o ./Core/Src/charger_control.su ./Core/Src/cp.cyclo ./Core/Src/cp.d ./Core/Src/cp.o ./Core/Src/cp.su ./Core/Src/crc.cyclo ./Core/Src/crc.d ./Core/Src/crc.o ./Core/Src/crc.su ./Core/Src/debug.cyclo ./Core/Src/debug.d ./Core/Src/debug.o ./Core/Src/debug.su ./Core/Src/dma.cyclo ./Core/Src/dma.d ./Core/Src/dma.o ./Core/Src/dma.su ./Core/Src/gpio.cyclo ./Core/Src/gpio.d ./Core/Src/gpio.o ./Core/Src/gpio.su ./Core/Src/main.cyclo ./Core/Src/main.d ./Core/Src/main.o ./Core/Src/main.su ./Core/Src/meter.cyclo ./Core/Src/meter.d ./Core/Src/meter.o ./Core/Src/meter.su ./Core/Src/psu_control.cyclo ./Core/Src/psu_control.d ./Core/Src/psu_control.o ./Core/Src/psu_control.su ./Core/Src/rgb_controller.cyclo ./Core/Src/rgb_controller.d ./Core/Src/rgb_controller.o ./Core/Src/rgb_controller.su ./Core/Src/rtc.cyclo ./Core/Src/rtc.d ./Core/Src/rtc.o ./Core/Src/rtc.su ./Core/Src/serial.cyclo ./Core/Src/serial.d ./Core/Src/serial.o ./Core/Src/serial.su ./Core/Src/serial_control.cyclo ./Core/Src/serial_control.d ./Core/Src/serial_control.o ./Core/Src/serial_control.su ./Core/Src/serial_handler.cyclo ./Core/Src/serial_handler.d ./Core/Src/serial_handler.o ./Core/Src/serial_handler.su ./Core/Src/sma_filter.cyclo ./Core/Src/sma_filter.d ./Core/Src/sma_filter.o ./Core/Src/sma_filter.su ./Core/Src/soft_rtc.cyclo ./Core/Src/soft_rtc.d ./Core/Src/soft_rtc.o ./Core/Src/soft_rtc.su ./Core/Src/stm32f1xx_hal_msp.cyclo ./Core/Src/stm32f1xx_hal_msp.d ./Core/Src/stm32f1xx_hal_msp.o ./Core/Src/stm32f1xx_hal_msp.su ./Core/Src/stm32f1xx_it.cyclo ./Core/Src/stm32f1xx_it.d ./Core/Src/stm32f1xx_it.o ./Core/Src/stm32f1xx_it.su ./Core/Src/syscalls.cyclo ./Core/Src/syscalls.d ./Core/Src/syscalls.o ./Core/Src/syscalls.su ./Core/Src/sysmem.cyclo ./Core/Src/sysmem.d ./Core/Src/sysmem.o ./Core/Src/sysmem.su ./Core/Src/system_stm32f1xx.cyclo ./Core/Src/system_stm32f1xx.d ./Core/Src/system_stm32f1xx.o ./Core/Src/system_stm32f1xx.su ./Core/Src/tim.cyclo ./Core/Src/tim.d ./Core/Src/tim.o ./Core/Src/tim.su ./Core/Src/usart.cyclo ./Core/Src/usart.d ./Core/Src/usart.o ./Core/Src/usart.su
.PHONY: clean-Core-2f-Src .PHONY: clean-Core-2f-Src
+6 -6
View File
@@ -1,6 +1,6 @@
../Core/Src/usart.c:33:6:MX_UART5_Init 2 ../Core/Src/usart.c:37:6:MX_UART5_Init 2
../Core/Src/usart.c:62:6:MX_USART1_UART_Init 2 ../Core/Src/usart.c:66:6:MX_USART1_UART_Init 2
../Core/Src/usart.c:91:6:MX_USART2_UART_Init 2 ../Core/Src/usart.c:95:6:MX_USART2_UART_Init 2
../Core/Src/usart.c:120:6:MX_USART3_UART_Init 2 ../Core/Src/usart.c:124:6:MX_USART3_UART_Init 2
../Core/Src/usart.c:148:6:HAL_UART_MspInit 5 ../Core/Src/usart.c:152:6:HAL_UART_MspInit 9
../Core/Src/usart.c:279:6:HAL_UART_MspDeInit 5 ../Core/Src/usart.c:349:6:HAL_UART_MspDeInit 5
+1
View File
@@ -5,6 +5,7 @@
"./Core/Src/cp.o" "./Core/Src/cp.o"
"./Core/Src/crc.o" "./Core/Src/crc.o"
"./Core/Src/debug.o" "./Core/Src/debug.o"
"./Core/Src/dma.o"
"./Core/Src/gpio.o" "./Core/Src/gpio.o"
"./Core/Src/main.o" "./Core/Src/main.o"
"./Core/Src/meter.o" "./Core/Src/meter.o"
+3559
View File
File diff suppressed because it is too large Load Diff
+133
View File
@@ -0,0 +1,133 @@
# Журнал изменений (сессия чата): `fork/CCSModuleSW30Web`
Документ фиксирует доработки проекта **CCSModuleSW30Web** в ветке/каталоге форка
`/Users/colorbass/STM32CubeIDE/workspace_1.12.0/fork/CCSModuleSW30Web`, обсуждавшиеся и вносившиеся в рамках описанной сессии (UART, ADC/DMA, CP, отладка IRQ, оптимизация `-Ofast` для кода из прерываний).
---
## 1. UART и протокол
### 1.1. UART3 (Everest / `serial.c`)
- Таймаут «нет связи с хостом»:** `EVEREST_TIMEOUT_MS` = **5000** мс.
- Жёсткий реинициал при отсутствии RX:** `UART3_REINIT_TIMEOUT_MS` = **1500** мс (с защитой от слишком частых реинициалов через `uart3_last_reinit_tick`).
- Расширено логирование путей сброса/ошибок приёма и ошибок HAL для диагностики «таймаут без остановки UART3».
- Колбэки и вспомогательные функции, вызываемые из контекста прерывания, помечены **`ISR_FAST`** (см. раздел 6):
`CCS_RxEventCallback`, `HAL_UART_ErrorCallback`, `uart3_log_hal_error`, `uart3_arm_rx_or_log`, цепочка разбора пакета (`process_received_packet`, `crc16_ibm`, `expected_payload_len`, `apply_command`).
### 1.2. UART2 / `serial_control.c`
- Отдельная логика **`SC_UART2_Watchdog()`**, вызывается из **`SC_Task()`** (не из IRQ).
- Константы:
- **`SC_UART2_REINIT_TIMEOUT_MS`** = **500** мс — порог для жёсткого реинициала при отсутствии пакетов;
- **`SC_UART2_PACKET_TIMEOUT_MS`** = **5000** мс — таймаут коммуникации.
- Сценарий **новый пакет при `BUSY_TX`**: при необходимости **`Abort_IT`**, сброс направления RS-485, затем повторная инициализация UART и приём `ReceiveToIdle_IT` (защита от обрыва TX из-за агрессивного watchdog).
- Отдельная ветка **жёсткого реинициала при `BUSY_TX`** с логом `USART2 BUSY_TX: hard reinit` (отслеживание `sc_uart2_last_busy_tx_reinit_packet_tick`).
- HAL-колбэки **`HAL_UARTEx_RxEventCallback`**, **`HAL_UART_TxCpltCallback`** помечены **`ISR_FAST`**.
### 1.3. `SC_SendPacket` и стек CRC/кодирования
- Для единообразной оптимизации пути «IRQ → ответ» на функции **`calculate_crc32`**, **`encode_packet`**, **`parse_packet`**, **`process_received_packet`** и публичную **`SC_SendPacket`** добавлен **`ISR_FAST`**.
- В **`Core/Inc/serial_control.h`**: подключение **`isr_opt.h`**, прототип **`ISR_FAST void SC_SendPacket(...)`** (согласованность с определением в `.c`).
**Замечание:** `SC_SendPacket` вызывается и из основного потока; для GCC вся функция компилируется с `-Ofast`. При необходимости строгого разделения можно вынести отдельную версию «только из IRQ».
---
## 2. Отладочные линии DBG в `stm32f1xx_it.c`
На время входа/выхода из выбранных обработчиков прерываний поднимается/опускается соответствующий GPIO — удобно для осциллографа (длительность IRQ).
| Линия | Обработчик |
|--------|------------|
| **DBG1** | `UART5_IRQHandler` |
| **DBG2** | `USART2_IRQHandler` |
| **DBG3** | `USART3_IRQHandler` |
| **DBG4** | `DMA1_Channel1_IRQHandler`, `ADC1_2_IRQHandler`, `TIM3_IRQHandler` |
| **DBG5** | `CAN1_RX0_IRQHandler`, `CAN2_TX_IRQHandler`, `CAN2_RX1_IRQHandler` |
| — | `USART1_IRQHandler` — без обёртки DBG (по согласованию) |
В **`DMA1_Channel1_IRQHandler`** вызывается **`HAL_DMA_IRQHandler(&hdma_adc1)`** для цепочки ADC+DMA.
Для всего файла **`stm32f1xx_it.c`** под GCC добавлено:
```c
#pragma GCC optimize("Ofast")
```
(в блоке `USER CODE BEGIN Includes`).
---
## 3. ADC: DMA, глобальные данные, колбэк
- Файлы **`adc.c` / `adc.h`**: структура **`ADC_ScanData_t`**, глобально **`volatile ADC_ScanData_t adc_data`** с полями сырых каналов (`in3_raw`, `cp_raw`, `ntc1_raw`, `ntc2_raw`, `temp_sensor_raw`, `vrefint_raw` и т.д. по фактическому объявлению в заголовке).
- **`HAL_ADC_ConvCpltCallback`**: копирование из буфера DMA в **`adc_data`**, помечен **`ISR_FAST`**.
- Публичная **`ADC_ScanStart()`** — запуск сканирования (после калибровки вызывается из инициализации платы).
- **`board.c`**: после **`HAL_ADCEx_Calibration_Start`** вызывается **`ADC_ScanStart()`**; **`CONN_ReadTemp`** читает **`adc_data.ntc1_raw` / `ntc2_raw`** вместо блокирующего опроса ADC.
**Диагностика (из обсуждения):** если не вызываются **`HAL_ADC_ConvCpltCallback`** / **`HAL_DMA_IRQHandler`**, проверять: срабатывание триггера ADC (например, **TIM3 TRGO**), работу TIM3, порядок инициализации DMA/NVIC, срабатывание **`DMA1_Channel1_IRQHandler`**.
---
## 4. CP (`cp.c` / `cp.h`)
- Измерение опоры на **`adc_data.cp_raw`** (и при необходимости **`vrefint_raw`** по текущей реализации в коде).
- Логика классификации/порогов приведена к варианту, согласованному с основным **CCSModuleSW30Web** (не форк).
- Сэмпл по таймеру: уход от тяжёлой работы в IRQ OC — использование **`HAL_TIM_OC_Start`** без прерывания по сравнению, обновление напряжения в **`CP_GetVoltage()`** / основном цикле (**`CP_Loop`** опирается на **`CP_GetState()`** и т.п. по фактическому коду).
---
## 5. Отладочный UART (`debug.c`)
При **`#ifndef USE_WEB_INTERFACE`** (или эквивалентной ветке сборки в файле): колбэк **`HAL_UARTEx_RxEventCallback`** и **`debug_rx_interrupt`** помечены **`ISR_FAST`**.
---
## 6. Оптимизация `-Ofast` для кода из прерываний
### 6.1. Макрос `ISR_FAST`
Файл **`Core/Inc/isr_opt.h`**:
- **GCC:** `#define ISR_FAST __attribute__((optimize("Ofast")))`
- **Иное:** пустой макрос.
### 6.2. Где используется (по состоянию репозитория)
| Файл | Элементы с `ISR_FAST` / pragma |
|------|--------------------------------|
| `stm32f1xx_it.c` | `#pragma GCC optimize("Ofast")` на весь файл (GCC) |
| `adc.c` | `HAL_ADC_ConvCpltCallback` |
| `serial.c` | `CCS_RxEventCallback`, `HAL_UART_ErrorCallback`, `uart3_log_hal_error`, `uart3_arm_rx_or_log`, `process_received_packet`, `crc16_ibm`, `expected_payload_len`, `apply_command` |
| `serial_control.c` | `HAL_UARTEx_RxEventCallback`, `HAL_UART_TxCpltCallback`, `calculate_crc32`, `encode_packet`, `parse_packet`, `process_received_packet`, `SC_SendPacket` |
| `serial_control.h` | прототип `SC_SendPacket` + `#include "isr_opt.h"` |
| `psu_control.c` | `HAL_CAN_RxFifo1MsgPendingCallback` |
| `debug.c` | см. раздел 5 |
---
## 7. Ограничения и переносимость
- **`ISR_FAST`** и pragma в **`stm32f1xx_it.c`** рассчитаны на **GCC** (STM32CubeIDE по умолчанию). Для **IAR / ARM Compiler 6** потребуется отдельная стратегия (прагмы/ключи проекта).
- **`-Ofast`** допускает агрессивные преобразования с плавающей точкой и перестановки, влияющие на строго воспроизводимую арифметику; для критичных вычислений вне IRQ при необходимости ограничивайте область оптимизации.
---
## 8. Затронутые пути (краткий список)
- `Core/Inc/isr_opt.h` — новый/центральный заголовок оптимизации IRQ.
- `Core/Inc/serial_control.h``isr_opt.h`, `ISR_FAST` у `SC_SendPacket`.
- `Core/Src/stm32f1xx_it.c` — DBG, DMA ADC, pragma `Ofast`.
- `Core/Src/adc.c`, `Core/Inc/adc.h` — DMA, `adc_data`, `ADC_ScanStart`, колбэк.
- `Core/Src/board.c` — калибровка, старт скана, температура из `adc_data`.
- `Core/Src/cp.c`, `Core/Inc/cp.h` — CP и ADC.
- `Core/Src/serial.c` — UART3, таймауты, логи, `ISR_FAST`.
- `Core/Src/serial_control.c` — UART2, watchdog, `ISR_FAST`.
- `Core/Src/psu_control.c` — CAN RX callback.
- `Core/Src/debug.c` — отладочный UART под условием сборки.
- `Core/Src/dma.c`, `gpio.c`, `main.h` — по необходимости для DMA1 Ch1 и DBG-пинов.
---
*Документ сгенерирован для фиксации контекста сессии; при дальнейших правках кода имеет смысл обновлять соответствующие разделы вручную.*