Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f23f726b2d | ||
|
|
b6ccfd7019 | ||
|
|
dc445af419 | ||
|
|
1331460ecb | ||
|
|
6749bb5f52 | ||
|
|
08f1215c24 | ||
|
|
18655e437f | ||
|
|
ccce0ff72f | ||
|
|
415a6cb06c | ||
|
|
90832fd2f4 | ||
|
|
170be709fe | ||
|
|
088b047b39 | ||
|
|
edd003a541 | ||
|
|
0d9565dbb7 | ||
|
|
fcc37515c5 | ||
|
|
64c7d3a94a | ||
|
|
22b1ba3921 | ||
|
|
b0df411c56 | ||
|
|
6048bdf115 | ||
|
|
b397856366 | ||
|
|
0a0ccf7bc3 | ||
|
|
56cae1abdb | ||
|
|
091d6c5648 | ||
|
|
bff7f6e916 | ||
|
|
6eb18ac72e | ||
|
|
8376f0b5eb | ||
|
|
7e99e2cc6c |
+21
-19
File diff suppressed because one or more lines are too long
+56
-31
@@ -3,8 +3,9 @@ ADC1.Channel-0\#ChannelRegularConversion=ADC_CHANNEL_0
|
|||||||
ADC1.Channel-1\#ChannelRegularConversion=ADC_CHANNEL_1
|
ADC1.Channel-1\#ChannelRegularConversion=ADC_CHANNEL_1
|
||||||
ADC1.Channel-2\#ChannelRegularConversion=ADC_CHANNEL_TEMPSENSOR
|
ADC1.Channel-2\#ChannelRegularConversion=ADC_CHANNEL_TEMPSENSOR
|
||||||
ADC1.Channel-3\#ChannelRegularConversion=ADC_CHANNEL_VREFINT
|
ADC1.Channel-3\#ChannelRegularConversion=ADC_CHANNEL_VREFINT
|
||||||
ADC1.ContinuousConvMode=ENABLE
|
ADC1.ContinuousConvMode=DISABLE
|
||||||
ADC1.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,NbrOfConversionFlag,master,ContinuousConvMode,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,NbrOfConversion
|
ADC1.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T1_CC1
|
||||||
|
ADC1.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,NbrOfConversionFlag,master,ContinuousConvMode,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,NbrOfConversion,ExternalTrigConv
|
||||||
ADC1.NbrOfConversion=4
|
ADC1.NbrOfConversion=4
|
||||||
ADC1.NbrOfConversionFlag=1
|
ADC1.NbrOfConversionFlag=1
|
||||||
ADC1.Rank-0\#ChannelRegularConversion=1
|
ADC1.Rank-0\#ChannelRegularConversion=1
|
||||||
@@ -30,9 +31,9 @@ Dma.RequestsNb=1
|
|||||||
FREERTOS.FootprintOK=true
|
FREERTOS.FootprintOK=true
|
||||||
FREERTOS.IPParameters=Tasks01,configUSE_MALLOC_FAILED_HOOK,configCHECK_FOR_STACK_OVERFLOW,configUSE_NEWLIB_REENTRANT,FootprintOK,Mutexes01,Queues01,Timers01,configUSE_TRACE_FACILITY,configUSE_STATS_FORMATTING_FUNCTIONS,configENABLE_BACKWARD_COMPATIBILITY
|
FREERTOS.IPParameters=Tasks01,configUSE_MALLOC_FAILED_HOOK,configCHECK_FOR_STACK_OVERFLOW,configUSE_NEWLIB_REENTRANT,FootprintOK,Mutexes01,Queues01,Timers01,configUSE_TRACE_FACILITY,configUSE_STATS_FORMATTING_FUNCTIONS,configENABLE_BACKWARD_COMPATIBILITY
|
||||||
FREERTOS.Mutexes01=heaterMutex,Static,heaterMutexControlBlock
|
FREERTOS.Mutexes01=heaterMutex,Static,heaterMutexControlBlock
|
||||||
FREERTOS.Queues01=guiEventQue,16,8,1,Static,guiEventQueBuffer,guiEventQueControlBlock
|
FREERTOS.Queues01=guiEventQue,32,1,1,Static,guiEventQueBuffer,guiEventQueControlBlock
|
||||||
FREERTOS.Tasks01=mainTsk,24,256,app_task_main,As weak,NULL,Static,defaultTaskBuffer,defaultTaskControlBlock;heaterTsk,24,128,app_task_heater,As external,NULL,Static,heaterTskBuffer,heaterTskControlBlock;guiTsk,40,256,app_task_gui,As external,NULL,Static,guiTskBuffer,guiTskControlBlock
|
FREERTOS.Tasks01=mainTsk,24,256,app_task_main,As weak,NULL,Static,defaultTaskBuffer,defaultTaskControlBlock;heaterTsk,24,128,app_task_heater,As external,NULL,Static,heaterTskBuffer,heaterTskControlBlock;guiTsk,40,256,app_task_gui,As external,NULL,Static,guiTskBuffer,guiTskControlBlock
|
||||||
FREERTOS.Timers01=beepTimer,app_beep_end,osTimerOnce,As external,NULL,Static,beepTimerControlBlock
|
FREERTOS.Timers01=beepTimer,app_beep_end,osTimerOnce,As external,NULL,Static,beepTimerControlBlock;buttonPushTimer,app_push_debounce,osTimerOnce,As external,1,Static,buttonPushTimerControlBlock;buttonReleaseTimer,app_push_debounce,osTimerOnce,As external,0,Static,buttonReleaseTimerControlBlock
|
||||||
FREERTOS.configCHECK_FOR_STACK_OVERFLOW=2
|
FREERTOS.configCHECK_FOR_STACK_OVERFLOW=2
|
||||||
FREERTOS.configENABLE_BACKWARD_COMPATIBILITY=0
|
FREERTOS.configENABLE_BACKWARD_COMPATIBILITY=0
|
||||||
FREERTOS.configUSE_MALLOC_FAILED_HOOK=1
|
FREERTOS.configUSE_MALLOC_FAILED_HOOK=1
|
||||||
@@ -40,7 +41,7 @@ FREERTOS.configUSE_NEWLIB_REENTRANT=1
|
|||||||
FREERTOS.configUSE_STATS_FORMATTING_FUNCTIONS=1
|
FREERTOS.configUSE_STATS_FORMATTING_FUNCTIONS=1
|
||||||
FREERTOS.configUSE_TRACE_FACILITY=1
|
FREERTOS.configUSE_TRACE_FACILITY=1
|
||||||
File.Version=6
|
File.Version=6
|
||||||
GPIO.groupedBy=Group By Peripherals
|
GPIO.groupedBy=Show All
|
||||||
IWDG.IPParameters=Prescaler,Reload
|
IWDG.IPParameters=Prescaler,Reload
|
||||||
IWDG.Prescaler=IWDG_PRESCALER_256
|
IWDG.Prescaler=IWDG_PRESCALER_256
|
||||||
IWDG.Reload=624
|
IWDG.Reload=624
|
||||||
@@ -48,18 +49,20 @@ KeepUserPlacement=false
|
|||||||
Mcu.CPN=STM32F103C8T6
|
Mcu.CPN=STM32F103C8T6
|
||||||
Mcu.Family=STM32F1
|
Mcu.Family=STM32F1
|
||||||
Mcu.IP0=ADC1
|
Mcu.IP0=ADC1
|
||||||
Mcu.IP1=DMA
|
Mcu.IP1=CRC
|
||||||
Mcu.IP10=TIM4
|
Mcu.IP10=TIM2
|
||||||
Mcu.IP11=USART1
|
Mcu.IP11=TIM3
|
||||||
Mcu.IP2=FREERTOS
|
Mcu.IP12=TIM4
|
||||||
Mcu.IP3=IWDG
|
Mcu.IP13=USART1
|
||||||
Mcu.IP4=NVIC
|
Mcu.IP2=DMA
|
||||||
Mcu.IP5=RCC
|
Mcu.IP3=FREERTOS
|
||||||
Mcu.IP6=SPI2
|
Mcu.IP4=IWDG
|
||||||
Mcu.IP7=SYS
|
Mcu.IP5=NVIC
|
||||||
Mcu.IP8=TIM2
|
Mcu.IP6=RCC
|
||||||
Mcu.IP9=TIM3
|
Mcu.IP7=SPI2
|
||||||
Mcu.IPNb=12
|
Mcu.IP8=SYS
|
||||||
|
Mcu.IP9=TIM1
|
||||||
|
Mcu.IPNb=14
|
||||||
Mcu.Name=STM32F103C(8-B)Tx
|
Mcu.Name=STM32F103C(8-B)Tx
|
||||||
Mcu.Package=LQFP48
|
Mcu.Package=LQFP48
|
||||||
Mcu.Pin0=PC13-TAMPER-RTC
|
Mcu.Pin0=PC13-TAMPER-RTC
|
||||||
@@ -73,12 +76,15 @@ Mcu.Pin15=PB7
|
|||||||
Mcu.Pin16=PB8
|
Mcu.Pin16=PB8
|
||||||
Mcu.Pin17=VP_ADC1_TempSens_Input
|
Mcu.Pin17=VP_ADC1_TempSens_Input
|
||||||
Mcu.Pin18=VP_ADC1_Vref_Input
|
Mcu.Pin18=VP_ADC1_Vref_Input
|
||||||
Mcu.Pin19=VP_FREERTOS_VS_CMSIS_V2
|
Mcu.Pin19=VP_CRC_VS_CRC
|
||||||
Mcu.Pin2=PA1
|
Mcu.Pin2=PA1
|
||||||
Mcu.Pin20=VP_IWDG_VS_IWDG
|
Mcu.Pin20=VP_FREERTOS_VS_CMSIS_V2
|
||||||
Mcu.Pin21=VP_SYS_VS_Systick
|
Mcu.Pin21=VP_IWDG_VS_IWDG
|
||||||
Mcu.Pin22=VP_TIM2_VS_ClockSourceINT
|
Mcu.Pin22=VP_SYS_VS_Systick
|
||||||
Mcu.Pin23=VP_TIM3_VS_ClockSourceINT
|
Mcu.Pin23=VP_TIM1_VS_ClockSourceINT
|
||||||
|
Mcu.Pin24=VP_TIM1_VS_no_output1
|
||||||
|
Mcu.Pin25=VP_TIM2_VS_ClockSourceINT
|
||||||
|
Mcu.Pin26=VP_TIM3_VS_ClockSourceINT
|
||||||
Mcu.Pin3=PA6
|
Mcu.Pin3=PA6
|
||||||
Mcu.Pin4=PB0
|
Mcu.Pin4=PB0
|
||||||
Mcu.Pin5=PB1
|
Mcu.Pin5=PB1
|
||||||
@@ -86,16 +92,16 @@ Mcu.Pin6=PB10
|
|||||||
Mcu.Pin7=PB13
|
Mcu.Pin7=PB13
|
||||||
Mcu.Pin8=PB15
|
Mcu.Pin8=PB15
|
||||||
Mcu.Pin9=PA9
|
Mcu.Pin9=PA9
|
||||||
Mcu.PinsNb=24
|
Mcu.PinsNb=27
|
||||||
Mcu.ThirdPartyNb=0
|
Mcu.ThirdPartyNb=0
|
||||||
Mcu.UserConstants=
|
Mcu.UserConstants=
|
||||||
Mcu.UserName=STM32F103C8Tx
|
Mcu.UserName=STM32F103C8Tx
|
||||||
MxCube.Version=6.5.0
|
MxCube.Version=6.5.0
|
||||||
MxDb.Version=DB.6.0.50
|
MxDb.Version=DB.6.0.50
|
||||||
NVIC.ADC1_2_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
|
|
||||||
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:true
|
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:true
|
||||||
NVIC.DMA1_Channel1_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
|
NVIC.DMA1_Channel1_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
|
||||||
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:true
|
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:true
|
||||||
|
NVIC.EXTI9_5_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
|
||||||
NVIC.ForceEnableDMAVector=true
|
NVIC.ForceEnableDMAVector=true
|
||||||
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:true
|
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:true
|
||||||
NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:true
|
NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:true
|
||||||
@@ -109,13 +115,13 @@ NVIC.SavedSystickIrqHandlerGenerated=true
|
|||||||
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:true\:false\:true\:true
|
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:true\:false\:true\:true
|
||||||
NVIC.TIM4_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
|
NVIC.TIM4_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
|
||||||
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:true
|
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:true
|
||||||
PA0-WKUP.GPIOParameters=GPIO_Label
|
|
||||||
PA0-WKUP.GPIO_Label=ADC_PT100
|
|
||||||
PA0-WKUP.Signal=ADCx_IN0
|
PA0-WKUP.Signal=ADCx_IN0
|
||||||
PA1.GPIOParameters=GPIO_Label
|
PA1.GPIOParameters=GPIO_Label
|
||||||
PA1.GPIO_Label=ADC_SENSR
|
PA1.GPIO_Label=ADC_SENSR
|
||||||
PA1.Locked=true
|
PA1.Locked=true
|
||||||
PA1.Signal=ADCx_IN1
|
PA1.Signal=ADCx_IN1
|
||||||
|
PA10.GPIOParameters=GPIO_PuPd
|
||||||
|
PA10.GPIO_PuPd=GPIO_PULLUP
|
||||||
PA10.Mode=Asynchronous
|
PA10.Mode=Asynchronous
|
||||||
PA10.Signal=USART1_RX
|
PA10.Signal=USART1_RX
|
||||||
PA13.Locked=true
|
PA13.Locked=true
|
||||||
@@ -128,6 +134,8 @@ PA15.GPIOParameters=GPIO_Speed,GPIO_Label
|
|||||||
PA15.GPIO_Label=BUZZER
|
PA15.GPIO_Label=BUZZER
|
||||||
PA15.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
|
PA15.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
|
||||||
PA15.Signal=S_TIM2_CH1_ETR
|
PA15.Signal=S_TIM2_CH1_ETR
|
||||||
|
PA6.GPIOParameters=GPIO_Label
|
||||||
|
PA6.GPIO_Label=PWM_HEATER
|
||||||
PA6.Locked=true
|
PA6.Locked=true
|
||||||
PA6.Signal=S_TIM3_CH1
|
PA6.Signal=S_TIM3_CH1
|
||||||
PA9.Mode=Asynchronous
|
PA9.Mode=Asynchronous
|
||||||
@@ -158,10 +166,12 @@ PB7.GPIOParameters=GPIO_PuPd,GPIO_Label
|
|||||||
PB7.GPIO_Label=KNOB_B
|
PB7.GPIO_Label=KNOB_B
|
||||||
PB7.GPIO_PuPd=GPIO_PULLUP
|
PB7.GPIO_PuPd=GPIO_PULLUP
|
||||||
PB7.Signal=S_TIM4_CH2
|
PB7.Signal=S_TIM4_CH2
|
||||||
PB8.GPIOParameters=GPIO_Label
|
PB8.GPIOParameters=GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultEXTI
|
||||||
PB8.GPIO_Label=KNOB_PUSH
|
PB8.GPIO_Label=KNOB_PUSH
|
||||||
|
PB8.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_RISING_FALLING
|
||||||
|
PB8.GPIO_PuPd=GPIO_PULLUP
|
||||||
PB8.Locked=true
|
PB8.Locked=true
|
||||||
PB8.Signal=GPIO_Input
|
PB8.Signal=GPXTI8
|
||||||
PC13-TAMPER-RTC.GPIOParameters=GPIO_Label
|
PC13-TAMPER-RTC.GPIOParameters=GPIO_Label
|
||||||
PC13-TAMPER-RTC.GPIO_Label=LED
|
PC13-TAMPER-RTC.GPIO_Label=LED
|
||||||
PC13-TAMPER-RTC.Locked=true
|
PC13-TAMPER-RTC.Locked=true
|
||||||
@@ -194,7 +204,7 @@ ProjectManager.StackSize=0x400
|
|||||||
ProjectManager.TargetToolchain=Makefile
|
ProjectManager.TargetToolchain=Makefile
|
||||||
ProjectManager.ToolChainLocation=
|
ProjectManager.ToolChainLocation=
|
||||||
ProjectManager.UnderRoot=false
|
ProjectManager.UnderRoot=false
|
||||||
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-LL-false,2-MX_GPIO_Init-GPIO-false-LL-true,3-MX_IWDG_Init-IWDG-false-LL-true,4-MX_USART1_UART_Init-USART1-false-LL-true,5-MX_ADC1_Init-ADC1-false-LL-true,6-MX_DMA_Init-DMA-false-LL-true,7-MX_TIM4_Init-TIM4-false-LL-true,8-MX_TIM2_Init-TIM2-false-LL-true,9-MX_TIM3_Init-TIM3-false-LL-true,10-MX_SPI2_Init-SPI2-false-LL-true
|
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-LL-false,2-MX_GPIO_Init-GPIO-false-LL-true,3-MX_IWDG_Init-IWDG-false-LL-true,4-MX_USART1_UART_Init-USART1-false-LL-true,5-MX_ADC1_Init-ADC1-false-LL-true,6-MX_DMA_Init-DMA-false-LL-true,7-MX_TIM4_Init-TIM4-false-LL-true,8-MX_TIM2_Init-TIM2-false-LL-true,9-MX_TIM3_Init-TIM3-false-LL-true,10-MX_SPI2_Init-SPI2-false-LL-true,11-MX_TIM1_Init-TIM1-false-LL-true,12-MX_CRC_Init-CRC-false-LL-true
|
||||||
RCC.ADCFreqValue=8000000
|
RCC.ADCFreqValue=8000000
|
||||||
RCC.ADCPresc=RCC_ADCPCLK2_DIV8
|
RCC.ADCPresc=RCC_ADCPCLK2_DIV8
|
||||||
RCC.AHBFreq_Value=64000000
|
RCC.AHBFreq_Value=64000000
|
||||||
@@ -222,6 +232,8 @@ SH.ADCx_IN0.0=ADC1_IN0,IN0
|
|||||||
SH.ADCx_IN0.ConfNb=1
|
SH.ADCx_IN0.ConfNb=1
|
||||||
SH.ADCx_IN1.0=ADC1_IN1,IN1
|
SH.ADCx_IN1.0=ADC1_IN1,IN1
|
||||||
SH.ADCx_IN1.ConfNb=1
|
SH.ADCx_IN1.ConfNb=1
|
||||||
|
SH.GPXTI8.0=GPIO_EXTI8
|
||||||
|
SH.GPXTI8.ConfNb=1
|
||||||
SH.S_TIM2_CH1_ETR.0=TIM2_CH1,PWM Generation1 CH1
|
SH.S_TIM2_CH1_ETR.0=TIM2_CH1,PWM Generation1 CH1
|
||||||
SH.S_TIM2_CH1_ETR.ConfNb=1
|
SH.S_TIM2_CH1_ETR.ConfNb=1
|
||||||
SH.S_TIM3_CH1.0=TIM3_CH1,PWM Generation1 CH1
|
SH.S_TIM3_CH1.0=TIM3_CH1,PWM Generation1 CH1
|
||||||
@@ -236,16 +248,23 @@ SPI2.Direction=SPI_DIRECTION_2LINES
|
|||||||
SPI2.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,BaudRatePrescaler
|
SPI2.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,BaudRatePrescaler
|
||||||
SPI2.Mode=SPI_MODE_MASTER
|
SPI2.Mode=SPI_MODE_MASTER
|
||||||
SPI2.VirtualType=VM_MASTER
|
SPI2.VirtualType=VM_MASTER
|
||||||
|
TIM1.Channel-PWM\ Generation1\ No\ Output=TIM_CHANNEL_1
|
||||||
|
TIM1.IPParameters=Prescaler,Period,TIM_MasterOutputTrigger,Channel-PWM Generation1 No Output,Pulse-PWM Generation1 No Output
|
||||||
|
TIM1.Period=10
|
||||||
|
TIM1.Prescaler=64000
|
||||||
|
TIM1.Pulse-PWM\ Generation1\ No\ Output=1
|
||||||
|
TIM1.TIM_MasterOutputTrigger=TIM_TRGO_OC1REF
|
||||||
TIM2.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
|
TIM2.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
|
||||||
TIM2.IPParameters=Channel-PWM Generation1 CH1,Prescaler
|
TIM2.IPParameters=Channel-PWM Generation1 CH1,Prescaler
|
||||||
TIM2.Prescaler=2
|
TIM2.Prescaler=2
|
||||||
TIM3.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
|
TIM3.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
|
||||||
TIM3.IPParameters=Channel-PWM Generation1 CH1,Prescaler,Pulse-PWM Generation1 CH1,Period
|
TIM3.IPParameters=Channel-PWM Generation1 CH1,Prescaler,Pulse-PWM Generation1 CH1,Period
|
||||||
TIM3.Period=64000
|
TIM3.Period=64000
|
||||||
TIM3.Prescaler=2000
|
TIM3.Prescaler=1000
|
||||||
TIM3.Pulse-PWM\ Generation1\ CH1=0
|
TIM3.Pulse-PWM\ Generation1\ CH1=0
|
||||||
|
TIM4.IC1Filter=15
|
||||||
TIM4.IC2Filter=15
|
TIM4.IC2Filter=15
|
||||||
TIM4.IPParameters=IC2Filter,Prescaler
|
TIM4.IPParameters=IC2Filter,Prescaler,IC1Filter
|
||||||
TIM4.Prescaler=0
|
TIM4.Prescaler=0
|
||||||
USART1.IPParameters=VirtualMode,Mode
|
USART1.IPParameters=VirtualMode,Mode
|
||||||
USART1.Mode=MODE_TX_RX
|
USART1.Mode=MODE_TX_RX
|
||||||
@@ -254,12 +273,18 @@ VP_ADC1_TempSens_Input.Mode=IN-TempSens
|
|||||||
VP_ADC1_TempSens_Input.Signal=ADC1_TempSens_Input
|
VP_ADC1_TempSens_Input.Signal=ADC1_TempSens_Input
|
||||||
VP_ADC1_Vref_Input.Mode=IN-Vrefint
|
VP_ADC1_Vref_Input.Mode=IN-Vrefint
|
||||||
VP_ADC1_Vref_Input.Signal=ADC1_Vref_Input
|
VP_ADC1_Vref_Input.Signal=ADC1_Vref_Input
|
||||||
|
VP_CRC_VS_CRC.Mode=CRC_Activate
|
||||||
|
VP_CRC_VS_CRC.Signal=CRC_VS_CRC
|
||||||
VP_FREERTOS_VS_CMSIS_V2.Mode=CMSIS_V2
|
VP_FREERTOS_VS_CMSIS_V2.Mode=CMSIS_V2
|
||||||
VP_FREERTOS_VS_CMSIS_V2.Signal=FREERTOS_VS_CMSIS_V2
|
VP_FREERTOS_VS_CMSIS_V2.Signal=FREERTOS_VS_CMSIS_V2
|
||||||
VP_IWDG_VS_IWDG.Mode=IWDG_Activate
|
VP_IWDG_VS_IWDG.Mode=IWDG_Activate
|
||||||
VP_IWDG_VS_IWDG.Signal=IWDG_VS_IWDG
|
VP_IWDG_VS_IWDG.Signal=IWDG_VS_IWDG
|
||||||
VP_SYS_VS_Systick.Mode=SysTick
|
VP_SYS_VS_Systick.Mode=SysTick
|
||||||
VP_SYS_VS_Systick.Signal=SYS_VS_Systick
|
VP_SYS_VS_Systick.Signal=SYS_VS_Systick
|
||||||
|
VP_TIM1_VS_ClockSourceINT.Mode=Internal
|
||||||
|
VP_TIM1_VS_ClockSourceINT.Signal=TIM1_VS_ClockSourceINT
|
||||||
|
VP_TIM1_VS_no_output1.Mode=PWM Generation1 No Output
|
||||||
|
VP_TIM1_VS_no_output1.Signal=TIM1_VS_no_output1
|
||||||
VP_TIM2_VS_ClockSourceINT.Mode=Internal
|
VP_TIM2_VS_ClockSourceINT.Mode=Internal
|
||||||
VP_TIM2_VS_ClockSourceINT.Signal=TIM2_VS_ClockSourceINT
|
VP_TIM2_VS_ClockSourceINT.Signal=TIM2_VS_ClockSourceINT
|
||||||
VP_TIM3_VS_ClockSourceINT.Mode=Internal
|
VP_TIM3_VS_ClockSourceINT.Mode=Internal
|
||||||
|
|||||||
@@ -137,8 +137,8 @@ See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
|
|||||||
/* Normal assert() semantics without relying on the provision of an assert.h
|
/* Normal assert() semantics without relying on the provision of an assert.h
|
||||||
header file. */
|
header file. */
|
||||||
/* USER CODE BEGIN 1 */
|
/* USER CODE BEGIN 1 */
|
||||||
#include <stdio.h>
|
#include "snprintf.h"
|
||||||
#define configASSERT( x ) if ((x) == 0) {taskDISABLE_INTERRUPTS(); printf("configASSERT "__FILE__":%d\r\n",__LINE__); for( ;; );}
|
#define configASSERT( x ) if ((x) == 0) {taskDISABLE_INTERRUPTS(); PRINTF("FreeRTOS assert @ %s:%d\r\n", __FILE__, __LINE__); for( ;; );}
|
||||||
/* USER CODE END 1 */
|
/* USER CODE END 1 */
|
||||||
|
|
||||||
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
|
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
/* USER CODE BEGIN Header */
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file crc.h
|
||||||
|
* @brief This file contains all the function prototypes for
|
||||||
|
* the crc.c file
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* Copyright (c) 2023 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 __CRC_H__
|
||||||
|
#define __CRC_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
/* USER CODE BEGIN Includes */
|
||||||
|
|
||||||
|
/* USER CODE END Includes */
|
||||||
|
|
||||||
|
/* USER CODE BEGIN Private defines */
|
||||||
|
|
||||||
|
/* USER CODE END Private defines */
|
||||||
|
|
||||||
|
void MX_CRC_Init(void);
|
||||||
|
|
||||||
|
/* USER CODE BEGIN Prototypes */
|
||||||
|
|
||||||
|
/* USER CODE END Prototypes */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __CRC_H__ */
|
||||||
|
|
||||||
+8
-6
@@ -16,10 +16,6 @@
|
|||||||
*
|
*
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
// this is a hack needed for CLion - placed here so cubemx does not overwrite it
|
|
||||||
#ifndef USE_FULL_LL_DRIVER
|
|
||||||
#define USE_FULL_LL_DRIVER 1
|
|
||||||
#endif
|
|
||||||
/* USER CODE END Header */
|
/* USER CODE END Header */
|
||||||
|
|
||||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
@@ -33,6 +29,7 @@ extern "C" {
|
|||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "stm32f1xx_ll_adc.h"
|
#include "stm32f1xx_ll_adc.h"
|
||||||
|
#include "stm32f1xx_ll_crc.h"
|
||||||
#include "stm32f1xx_ll_dma.h"
|
#include "stm32f1xx_ll_dma.h"
|
||||||
#include "stm32f1xx_ll_iwdg.h"
|
#include "stm32f1xx_ll_iwdg.h"
|
||||||
#include "stm32f1xx_ll_rcc.h"
|
#include "stm32f1xx_ll_rcc.h"
|
||||||
@@ -54,6 +51,10 @@ extern "C" {
|
|||||||
/* Private includes ----------------------------------------------------------*/
|
/* Private includes ----------------------------------------------------------*/
|
||||||
/* USER CODE BEGIN Includes */
|
/* USER CODE BEGIN Includes */
|
||||||
|
|
||||||
|
extern void app_emergency_stop(void);
|
||||||
|
|
||||||
|
#define __weak __attribute__((weak))
|
||||||
|
|
||||||
/* USER CODE END Includes */
|
/* USER CODE END Includes */
|
||||||
|
|
||||||
/* Exported types ------------------------------------------------------------*/
|
/* Exported types ------------------------------------------------------------*/
|
||||||
@@ -81,10 +82,10 @@ void Error_Handler(void);
|
|||||||
/* Private defines -----------------------------------------------------------*/
|
/* Private defines -----------------------------------------------------------*/
|
||||||
#define LED_Pin LL_GPIO_PIN_13
|
#define LED_Pin LL_GPIO_PIN_13
|
||||||
#define LED_GPIO_Port GPIOC
|
#define LED_GPIO_Port GPIOC
|
||||||
#define ADC_PT100_Pin LL_GPIO_PIN_0
|
|
||||||
#define ADC_PT100_GPIO_Port GPIOA
|
|
||||||
#define ADC_SENSR_Pin LL_GPIO_PIN_1
|
#define ADC_SENSR_Pin LL_GPIO_PIN_1
|
||||||
#define ADC_SENSR_GPIO_Port GPIOA
|
#define ADC_SENSR_GPIO_Port GPIOA
|
||||||
|
#define PWM_HEATER_Pin LL_GPIO_PIN_6
|
||||||
|
#define PWM_HEATER_GPIO_Port GPIOA
|
||||||
#define OLED_CS_Pin LL_GPIO_PIN_0
|
#define OLED_CS_Pin LL_GPIO_PIN_0
|
||||||
#define OLED_CS_GPIO_Port GPIOB
|
#define OLED_CS_GPIO_Port GPIOB
|
||||||
#define OLED_DC_Pin LL_GPIO_PIN_1
|
#define OLED_DC_Pin LL_GPIO_PIN_1
|
||||||
@@ -99,6 +100,7 @@ void Error_Handler(void);
|
|||||||
#define KNOB_B_GPIO_Port GPIOB
|
#define KNOB_B_GPIO_Port GPIOB
|
||||||
#define KNOB_PUSH_Pin LL_GPIO_PIN_8
|
#define KNOB_PUSH_Pin LL_GPIO_PIN_8
|
||||||
#define KNOB_PUSH_GPIO_Port GPIOB
|
#define KNOB_PUSH_GPIO_Port GPIOB
|
||||||
|
#define KNOB_PUSH_EXTI_IRQn EXTI9_5_IRQn
|
||||||
#ifndef NVIC_PRIORITYGROUP_0
|
#ifndef NVIC_PRIORITYGROUP_0
|
||||||
#define NVIC_PRIORITYGROUP_0 ((uint32_t)0x00000007) /*!< 0 bit for pre-emption priority,
|
#define NVIC_PRIORITYGROUP_0 ((uint32_t)0x00000007) /*!< 0 bit for pre-emption priority,
|
||||||
4 bits for subpriority */
|
4 bits for subpriority */
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ void UsageFault_Handler(void);
|
|||||||
void DebugMon_Handler(void);
|
void DebugMon_Handler(void);
|
||||||
void SysTick_Handler(void);
|
void SysTick_Handler(void);
|
||||||
void DMA1_Channel1_IRQHandler(void);
|
void DMA1_Channel1_IRQHandler(void);
|
||||||
void ADC1_2_IRQHandler(void);
|
void EXTI9_5_IRQHandler(void);
|
||||||
void TIM4_IRQHandler(void);
|
void TIM4_IRQHandler(void);
|
||||||
/* USER CODE BEGIN EFP */
|
/* USER CODE BEGIN EFP */
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ extern "C" {
|
|||||||
|
|
||||||
/* USER CODE END Private defines */
|
/* USER CODE END Private defines */
|
||||||
|
|
||||||
|
void MX_TIM1_Init(void);
|
||||||
void MX_TIM2_Init(void);
|
void MX_TIM2_Init(void);
|
||||||
void MX_TIM3_Init(void);
|
void MX_TIM3_Init(void);
|
||||||
void MX_TIM4_Init(void);
|
void MX_TIM4_Init(void);
|
||||||
|
|||||||
@@ -0,0 +1,147 @@
|
|||||||
|
/**
|
||||||
|
* TODO file description
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "app_gui.h"
|
||||||
|
#include "app_buzzer.h"
|
||||||
|
#include "app_temp.h"
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "queue.h"
|
||||||
|
#include "ufb/framebuffer.h"
|
||||||
|
#include "ufb/fb_text.h"
|
||||||
|
#include "app_safety.h"
|
||||||
|
|
||||||
|
struct State s_app = {};
|
||||||
|
|
||||||
|
/** Get push time (while held) */
|
||||||
|
uint32_t push_time() {
|
||||||
|
return s_app.pushed ? (xTaskGetTickCount() - s_app.push_time) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Schedule paint (the screen func will be called with the PAINT event argument */
|
||||||
|
void request_paint() {
|
||||||
|
s_app.paint_needed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Draw the common overlay / HUD (with temperatures and heater status) */
|
||||||
|
static void draw_common_overlay();
|
||||||
|
|
||||||
|
char stmp[100];
|
||||||
|
|
||||||
|
/** Main loop */
|
||||||
|
void app_task_gui(void *argument) {
|
||||||
|
// Wait until inited
|
||||||
|
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||||
|
PUTS("GUI task starts\r\n");
|
||||||
|
|
||||||
|
s_app.last_tick_time = xTaskGetTickCount();
|
||||||
|
|
||||||
|
switch_screen(screen_home, true);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
uint32_t message = GUI_EVENT_NONE;
|
||||||
|
int32_t ticks_remain = (int32_t) pdMS_TO_TICKS(10) - (int32_t) (xTaskGetTickCount() - s_app.last_tick_time);
|
||||||
|
if (ticks_remain < 0) {
|
||||||
|
ticks_remain = 0;
|
||||||
|
}
|
||||||
|
osMessageQueueGet(guiEventQueHandle, &message, NULL, ticks_remain);
|
||||||
|
|
||||||
|
if (message == GUI_EVENT_KNOB_PLUS) {
|
||||||
|
if (s_app.up_prescaller) {
|
||||||
|
s_app.up_prescaller = 0;
|
||||||
|
// let this through
|
||||||
|
} else {
|
||||||
|
// consume this
|
||||||
|
s_app.down_prescaller = 0;
|
||||||
|
s_app.up_prescaller = 1;
|
||||||
|
message = GUI_EVENT_NONE;
|
||||||
|
}
|
||||||
|
} else if (message == GUI_EVENT_KNOB_MINUS) {
|
||||||
|
if (s_app.down_prescaller) {
|
||||||
|
s_app.down_prescaller = 0;
|
||||||
|
// let this through
|
||||||
|
} else {
|
||||||
|
// consume this
|
||||||
|
s_app.up_prescaller = 0;
|
||||||
|
s_app.down_prescaller = 1;
|
||||||
|
message = GUI_EVENT_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t tickNow = xTaskGetTickCount();
|
||||||
|
|
||||||
|
// 10ms tick event
|
||||||
|
if (tickNow - s_app.last_tick_time > pdMS_TO_TICKS(10)) {
|
||||||
|
s_app.screen(GUI_EVENT_SCREEN_TICK);
|
||||||
|
s_app.last_tick_time = tickNow;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tickNow - s_app.last_read_temp_time > pdMS_TO_TICKS(250)) {
|
||||||
|
s_app.oven_temp = app_temp_read_oven();
|
||||||
|
//s_app.soc_temp = app_temp_read_soc();
|
||||||
|
request_paint();
|
||||||
|
s_app.last_read_temp_time = tickNow;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (message) {
|
||||||
|
case GUI_EVENT_KNOB_PRESS:
|
||||||
|
s_app.pushed = true;
|
||||||
|
s_app.push_time = tickNow;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GUI_EVENT_KNOB_RELEASE:
|
||||||
|
s_app.pushed = false;
|
||||||
|
|
||||||
|
if (s_app.initial_pushed) {
|
||||||
|
s_app.initial_pushed = false;
|
||||||
|
message = GUI_EVENT_NONE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message != GUI_EVENT_NONE) {
|
||||||
|
s_app.screen(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
app_safety_pass_display_updating();
|
||||||
|
if (s_app.paint_needed) {
|
||||||
|
s_app.paint_needed = false;
|
||||||
|
fb_clear();
|
||||||
|
draw_common_overlay();
|
||||||
|
s_app.screen(GUI_EVENT_PAINT);
|
||||||
|
fb_blit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Switch to a different screen handler.
|
||||||
|
* If "init" is true, immediately call it with the init event. */
|
||||||
|
void switch_screen(screen_t pScreen, bool init) {
|
||||||
|
s_app.initial_pushed = s_app.pushed;
|
||||||
|
s_app.screen = pScreen;
|
||||||
|
// clear the union field
|
||||||
|
request_paint();
|
||||||
|
|
||||||
|
if (init) {
|
||||||
|
pScreen(GUI_EVENT_SCREEN_INIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Draw GUI common to all screens */
|
||||||
|
static void draw_common_overlay() {
|
||||||
|
SPRINTF(stmp, "%5.1f°C →%3d°C", s_app.oven_temp, s_app.set_temp);
|
||||||
|
fb_text(3, 3, stmp, FONT_3X5, 1);
|
||||||
|
|
||||||
|
if (s_app.heater_enabled) {
|
||||||
|
fb_frame(0, 0, FBW, 11, 1, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Play input sound effect if this is an input event */
|
||||||
|
void input_sound_effect() {
|
||||||
|
app_buzzer_beep();
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
/**
|
||||||
|
* TODO file description
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BLUEPILLTROUBA_APP_GUI_H
|
||||||
|
#define BLUEPILLTROUBA_APP_GUI_H
|
||||||
|
|
||||||
|
#include "cmsis_os2.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "gui_event.h"
|
||||||
|
|
||||||
|
extern char stmp[100];
|
||||||
|
|
||||||
|
void app_task_gui(void *argument);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Screen callback type. The event is either INIT, PAINT, or one of the input events.
|
||||||
|
*/
|
||||||
|
typedef void (*screen_t)(GuiEvent event);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** Input beep (push or knob turn) */
|
||||||
|
void input_sound_effect();
|
||||||
|
|
||||||
|
/** Switch to a different screen. Handles initial push state handling (so release
|
||||||
|
* does not cause a "click" event).
|
||||||
|
*
|
||||||
|
* @param pScreen - screen to switch to
|
||||||
|
* @param init - call the INIT event immediately after
|
||||||
|
*/
|
||||||
|
void switch_screen(screen_t pScreen, bool init);
|
||||||
|
|
||||||
|
void request_paint();
|
||||||
|
|
||||||
|
uint32_t push_time();
|
||||||
|
|
||||||
|
// prototypes for screen handlers
|
||||||
|
|
||||||
|
void screen_home(GuiEvent event);
|
||||||
|
void screen_manual(GuiEvent event);
|
||||||
|
void screen_manual_menu(GuiEvent event);
|
||||||
|
void screen_calibration(GuiEvent event);
|
||||||
|
|
||||||
|
struct State {
|
||||||
|
/// Latest oven temp readout
|
||||||
|
float oven_temp;
|
||||||
|
//float soc_temp;
|
||||||
|
|
||||||
|
// manual mode controls
|
||||||
|
|
||||||
|
/// Currently set target temp
|
||||||
|
int set_temp;
|
||||||
|
/// Heater enabled status (only visual)
|
||||||
|
bool heater_enabled;
|
||||||
|
|
||||||
|
/// Prescaller for the knob, CCW direction.
|
||||||
|
/// Event increments this counter and resets the other. Knob turn event is generated on overflow.
|
||||||
|
bool down_prescaller;
|
||||||
|
/// Prescaller for the knob, CW direction
|
||||||
|
/// See `down_prescaller`
|
||||||
|
bool up_prescaller;
|
||||||
|
|
||||||
|
/// Curent status of the push button
|
||||||
|
bool pushed;
|
||||||
|
/// Repaint was requested from the screen code
|
||||||
|
bool paint_needed;
|
||||||
|
|
||||||
|
/// Timestamp of the last GUI tick
|
||||||
|
uint32_t last_tick_time;
|
||||||
|
/// Timestamp when the button was pushed
|
||||||
|
uint32_t push_time;
|
||||||
|
/// Timestamp when we last read oven temperature for display
|
||||||
|
uint32_t last_read_temp_time;
|
||||||
|
|
||||||
|
/// true if the button is still held since init (i.e. the push action should not work as "enter")
|
||||||
|
bool initial_pushed;
|
||||||
|
|
||||||
|
/// Pointer to the currently active screen func
|
||||||
|
screen_t screen;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct State s_app;
|
||||||
|
|
||||||
|
#endif //BLUEPILLTROUBA_APP_GUI_H
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
//
|
||||||
|
// Created by MightyPork on 2023/04/09.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef TOASTER_OVEN_BLUEPILL_GUI_EVENT_H
|
||||||
|
#define TOASTER_OVEN_BLUEPILL_GUI_EVENT_H
|
||||||
|
|
||||||
|
#include "cmsis_os2.h"
|
||||||
|
|
||||||
|
extern osThreadId_t guiTskHandle;
|
||||||
|
extern osMessageQueueId_t guiEventQueHandle;
|
||||||
|
|
||||||
|
|
||||||
|
// sent through the notify queue
|
||||||
|
typedef enum GuiEvent {
|
||||||
|
/// No event, zero; This is a default value.
|
||||||
|
GUI_EVENT_NONE = 0,
|
||||||
|
/// Cause redraw
|
||||||
|
GUI_EVENT_PAINT = 0,
|
||||||
|
/// Used as the argument when initing a screen
|
||||||
|
GUI_EVENT_SCREEN_INIT = 1,
|
||||||
|
/// Time tick, used to carry timing to the screen functions.
|
||||||
|
/// This tick has 10ms interval
|
||||||
|
GUI_EVENT_SCREEN_TICK = 2,
|
||||||
|
/// Knob rotate CW
|
||||||
|
GUI_EVENT_KNOB_PLUS,
|
||||||
|
/// Knob rotate CCW
|
||||||
|
GUI_EVENT_KNOB_MINUS,
|
||||||
|
/// Knob pressed
|
||||||
|
GUI_EVENT_KNOB_PRESS,
|
||||||
|
/// Knob released
|
||||||
|
GUI_EVENT_KNOB_RELEASE,
|
||||||
|
/// Temperature readings changed.
|
||||||
|
/// Not really an input event, but it should trigger a redraw
|
||||||
|
GUI_EVENT_TEMP_CHANGE,
|
||||||
|
} GuiEvent;
|
||||||
|
|
||||||
|
#endif //TOASTER_OVEN_BLUEPILL_GUI_EVENT_H
|
||||||
@@ -0,0 +1,218 @@
|
|||||||
|
//
|
||||||
|
// Created by MightyPork on 2023/04/09.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "app_gui.h"
|
||||||
|
#include "app_heater.h"
|
||||||
|
#include "screen_menu.h"
|
||||||
|
#include "ufb/fb_text.h"
|
||||||
|
#include "app_temp.h"
|
||||||
|
#include "snprintf.h"
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
|
||||||
|
struct calib_state {
|
||||||
|
int phase;
|
||||||
|
float sample1;
|
||||||
|
float sample2;
|
||||||
|
int temp1;
|
||||||
|
int temp2;
|
||||||
|
} s_calib;
|
||||||
|
|
||||||
|
enum Phase {
|
||||||
|
PH_HELLO = 0,
|
||||||
|
PH_SAMPLE1,
|
||||||
|
PH_TEMP1,
|
||||||
|
PH_SAMPLE2,
|
||||||
|
PH_TEMP2,
|
||||||
|
PH_DONE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void next_phase() {
|
||||||
|
PUTS("Phase++\r\n");
|
||||||
|
s_calib.phase++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* hello_menu_opts[] = {
|
||||||
|
"Pokračovat",
|
||||||
|
"Zrušit",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static void hello_menu_cb(int opt) {
|
||||||
|
switch (opt) {
|
||||||
|
case 0:
|
||||||
|
// Continue
|
||||||
|
next_phase();
|
||||||
|
request_paint();
|
||||||
|
app_heater_manual_override(100);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
switch_screen(screen_home, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const char* sample1_menu_opts[] = {
|
||||||
|
"Vzorek 1",
|
||||||
|
"Zrušit",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static void sample1_menu_cb(int opt) {
|
||||||
|
switch (opt) {
|
||||||
|
case 0:
|
||||||
|
// Continue
|
||||||
|
next_phase();
|
||||||
|
request_paint();
|
||||||
|
s_calib.sample1 = app_temp_read_oven_raw();
|
||||||
|
app_heater_manual_override(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
app_heater_manual_override(-1);
|
||||||
|
switch_screen(screen_home, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* sample2_menu_opts[] = {
|
||||||
|
"Vzorek 2",
|
||||||
|
"Zrušit",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void sample2_menu_cb(int opt) {
|
||||||
|
switch (opt) {
|
||||||
|
case 0:
|
||||||
|
// Continue
|
||||||
|
next_phase();
|
||||||
|
request_paint();
|
||||||
|
s_calib.sample2 = app_temp_read_oven_raw();
|
||||||
|
app_heater_manual_override(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
app_heater_manual_override(-1);
|
||||||
|
switch_screen(screen_home, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void screen_calibration(GuiEvent event)
|
||||||
|
{
|
||||||
|
if (event == GUI_EVENT_SCREEN_INIT) {
|
||||||
|
memset(&s_calib, 0, sizeof(s_calib));
|
||||||
|
// continue to the rest - so the menu can be inited
|
||||||
|
}
|
||||||
|
|
||||||
|
int *pT;
|
||||||
|
switch (s_calib.phase) {
|
||||||
|
case PH_HELLO:
|
||||||
|
if (event == GUI_EVENT_PAINT) {
|
||||||
|
fb_text(FBW/2, 16, "Vychlaď", TEXT_CENTER, 1);
|
||||||
|
fb_text(FBW/2, 26, "troubu", TEXT_CENTER, 1);
|
||||||
|
}
|
||||||
|
screen_menu_offset(event, hello_menu_opts, hello_menu_cb, 30);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PH_SAMPLE1: // Heater is active, waiting for mark
|
||||||
|
case PH_SAMPLE2:
|
||||||
|
if (event == GUI_EVENT_PAINT) {
|
||||||
|
fb_text(FBW/2, 16, "Zapiš", TEXT_CENTER, 1);
|
||||||
|
fb_text(FBW/2, 26, "teplotu", TEXT_CENTER, 1);
|
||||||
|
}
|
||||||
|
if (s_calib.phase == PH_SAMPLE1) {
|
||||||
|
screen_menu_offset(event, sample1_menu_opts, sample1_menu_cb, 30);
|
||||||
|
} else {
|
||||||
|
screen_menu_offset(event, sample2_menu_opts, sample2_menu_cb, 30);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PH_TEMP1:
|
||||||
|
case PH_TEMP2:
|
||||||
|
if (s_calib.phase == PH_TEMP1) {
|
||||||
|
pT = &s_calib.temp1;
|
||||||
|
} else {
|
||||||
|
pT = &s_calib.temp2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (push_time() > pdMS_TO_TICKS(500)) {
|
||||||
|
input_sound_effect();
|
||||||
|
app_heater_manual_override_clear();
|
||||||
|
switch_screen(screen_home, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
case GUI_EVENT_PAINT: {
|
||||||
|
fb_text(FBW/2, 14, s_calib.phase == PH_TEMP1 ? "Teplota 1" : "Teplota 2", TEXT_CENTER, 1);
|
||||||
|
SPRINTF(stmp, "%d°C", *pT);
|
||||||
|
fb_text(FBW/2, 30, stmp, TEXT_CENTER | FONT_DOUBLE, 1);
|
||||||
|
|
||||||
|
fb_text(2, FBH - 8 * 3, "←→Nastav", 0, 1);
|
||||||
|
fb_text(2, FBH - 8 * 2, "> Potvrdit", 0, 1);
|
||||||
|
fb_text(2, FBH - 8 * 1, "» Zrušit", 0, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
case GUI_EVENT_KNOB_PLUS: {
|
||||||
|
if (*pT < 500) {
|
||||||
|
*pT += 1;
|
||||||
|
input_sound_effect();
|
||||||
|
request_paint();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case GUI_EVENT_KNOB_MINUS: {
|
||||||
|
if (*pT > 0) {
|
||||||
|
input_sound_effect();
|
||||||
|
*pT -= 1;
|
||||||
|
request_paint();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case GUI_EVENT_KNOB_RELEASE: {
|
||||||
|
next_phase();
|
||||||
|
request_paint();
|
||||||
|
|
||||||
|
if (s_calib.phase == PH_DONE) {
|
||||||
|
app_heater_manual_override(-1);
|
||||||
|
// TODO do the math
|
||||||
|
PRINTF("Sample 1 %f, T1 %d\r\n", s_calib.sample1, s_calib.temp1);
|
||||||
|
PRINTF("Sample 2 %f, T2 %d\r\n", s_calib.sample2, s_calib.temp2);
|
||||||
|
|
||||||
|
float corrected1 = c_to_val((float) s_calib.temp1);
|
||||||
|
float corrected2 = c_to_val((float) s_calib.temp2);
|
||||||
|
|
||||||
|
float a = (corrected1 - corrected2) / (s_calib.sample1 - s_calib.sample2);
|
||||||
|
float b = corrected1 - a * s_calib.sample1;
|
||||||
|
|
||||||
|
app_temp_set_calib(a, b);
|
||||||
|
} else {
|
||||||
|
// for the next phase
|
||||||
|
app_heater_manual_override(100);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PH_DONE:
|
||||||
|
if (event == GUI_EVENT_PAINT) {
|
||||||
|
fb_text(FBW/2, 14, "Hotovo", TEXT_CENTER, 1);
|
||||||
|
fb_text(FBW/2, 36, "→Hlavní menu", TEXT_CENTER, 1);
|
||||||
|
}
|
||||||
|
if (event == GUI_EVENT_KNOB_RELEASE) {
|
||||||
|
switch_screen(screen_home, 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
//
|
||||||
|
// Created by MightyPork on 2023/04/09.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "app_gui.h"
|
||||||
|
#include "app_heater.h"
|
||||||
|
#include "screen_menu.h"
|
||||||
|
|
||||||
|
|
||||||
|
static const char* main_menu_opts[] = {
|
||||||
|
"Ruční režim",
|
||||||
|
"Kalibrace",
|
||||||
|
// "Programy",
|
||||||
|
// "Diagnostika",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static void main_menu_cb(int opt) {
|
||||||
|
switch (opt) {
|
||||||
|
case 0:
|
||||||
|
switch_screen(screen_manual, true);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
switch_screen(screen_calibration, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void screen_home(GuiEvent event)
|
||||||
|
{
|
||||||
|
if (event == GUI_EVENT_SCREEN_INIT) {
|
||||||
|
app_heater_enable(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
screen_menu(event, main_menu_opts, main_menu_cb);
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
//
|
||||||
|
// Created by MightyPork on 2023/04/09.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "app_gui.h"
|
||||||
|
#include "gui_event.h"
|
||||||
|
#include "screen_menu.h"
|
||||||
|
#include "app_heater.h"
|
||||||
|
#include "ufb/fb_7seg.h"
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "ufb/fb_text.h"
|
||||||
|
|
||||||
|
|
||||||
|
void screen_manual(GuiEvent event)
|
||||||
|
{
|
||||||
|
bool temp_changed = false;
|
||||||
|
if (event == GUI_EVENT_SCREEN_INIT) {
|
||||||
|
app_heater_manual_override_clear();
|
||||||
|
app_heater_enable(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// menu is activated by long push
|
||||||
|
if (push_time() >= pdMS_TO_TICKS(500)) {
|
||||||
|
switch_screen(screen_manual_menu, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
case GUI_EVENT_PAINT:
|
||||||
|
fb_7seg_number(FBW/2 - ((12+2) * 3 - 2)/2, 36,
|
||||||
|
12, 20, 2, 2,
|
||||||
|
1,
|
||||||
|
s_app.set_temp, 3, 0
|
||||||
|
);
|
||||||
|
|
||||||
|
fb_text(FBW/2, 25, "Teplota °C", TEXT_CENTER, 1);
|
||||||
|
|
||||||
|
fb_text(FBW/2, 64, s_app.heater_enabled ? "ZAPNUTO" : "Vypnuto", TEXT_CENTER, 1);
|
||||||
|
|
||||||
|
SPRINTF(stmp, "%.1f", s_app.oven_temp);
|
||||||
|
fb_text(FBW/2, 80, stmp, TEXT_CENTER | FONT_DOUBLE, 1);
|
||||||
|
|
||||||
|
fb_text(2, FBH - 8 * 3, "←→Nastav", 0, 1);
|
||||||
|
fb_text(2, FBH - 8 * 2, "> Zap/Vyp", 0, 1);
|
||||||
|
fb_text(2, FBH - 8 * 1, "» Menu", 0, 1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GUI_EVENT_KNOB_RELEASE:
|
||||||
|
input_sound_effect();
|
||||||
|
s_app.heater_enabled ^= 1;
|
||||||
|
app_heater_enable(s_app.heater_enabled);
|
||||||
|
request_paint();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GUI_EVENT_KNOB_PLUS:
|
||||||
|
if (s_app.set_temp <= MAX_TEMP - 5) {
|
||||||
|
s_app.set_temp += 5;
|
||||||
|
temp_changed = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GUI_EVENT_KNOB_MINUS:
|
||||||
|
if (s_app.set_temp >= 5) {
|
||||||
|
s_app.set_temp -= 5;
|
||||||
|
temp_changed = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (temp_changed) {
|
||||||
|
input_sound_effect();
|
||||||
|
app_heater_set_target((float) s_app.set_temp);
|
||||||
|
request_paint();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
//
|
||||||
|
// Created by MightyPork on 2023/04/09.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "app_gui.h"
|
||||||
|
#include "app_heater.h"
|
||||||
|
#include "screen_menu.h"
|
||||||
|
|
||||||
|
static const char* manual_menu_opts[] = {
|
||||||
|
"Zrušit",
|
||||||
|
"Hlavní menu",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static void manual_menu_cb(int opt) {
|
||||||
|
switch (opt) {
|
||||||
|
case 0:
|
||||||
|
// Close menu
|
||||||
|
switch_screen(screen_manual, false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
s_app.heater_enabled = false;
|
||||||
|
app_heater_enable(false);
|
||||||
|
switch_screen(screen_home, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void screen_manual_menu(GuiEvent event)
|
||||||
|
{
|
||||||
|
screen_menu(event, manual_menu_opts, manual_menu_cb);
|
||||||
|
}
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
//
|
||||||
|
// Created by MightyPork on 2023/04/09.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "screen_menu.h"
|
||||||
|
#include "app_gui.h"
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "ufb/utf8.h"
|
||||||
|
#include "ufb/framebuffer_config.h"
|
||||||
|
#include "ufb/framebuffer.h"
|
||||||
|
#include "ufb/fb_text.h"
|
||||||
|
|
||||||
|
struct menu_state {
|
||||||
|
int pos;
|
||||||
|
int len;
|
||||||
|
uint32_t change_time;
|
||||||
|
uint32_t slide_end_time;
|
||||||
|
uint16_t text_slide;
|
||||||
|
void * last_opts;
|
||||||
|
} s_menu;
|
||||||
|
|
||||||
|
|
||||||
|
void screen_menu(GuiEvent event, const char **options, menu_callback_t cb) {
|
||||||
|
screen_menu_offset(event, options, cb, 15);
|
||||||
|
}
|
||||||
|
|
||||||
|
void screen_menu_offset(GuiEvent event, const char **options, menu_callback_t cb, fbpos_t offset) {
|
||||||
|
if (event != GUI_EVENT_SCREEN_INIT && s_menu.last_opts != (void*) options) {
|
||||||
|
// ensure the menu is properly inited when the options list changes.
|
||||||
|
screen_menu(GUI_EVENT_SCREEN_INIT, options, cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool menu_changed = false;
|
||||||
|
const uint32_t tickNow = xTaskGetTickCount();
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
case GUI_EVENT_SCREEN_INIT:
|
||||||
|
memset(&s_menu, 0, sizeof(s_menu));
|
||||||
|
s_menu.last_opts = (void*) options;
|
||||||
|
|
||||||
|
s_menu.change_time = tickNow;
|
||||||
|
|
||||||
|
// count options
|
||||||
|
const char **opt = options;
|
||||||
|
while (*opt) {
|
||||||
|
s_menu.len++;
|
||||||
|
opt++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GUI_EVENT_SCREEN_TICK:
|
||||||
|
// long text sliding animation
|
||||||
|
if (tickNow - s_menu.change_time >= pdMS_TO_TICKS(500)) {
|
||||||
|
const uint32_t textlen = utf8_strlen(options[s_menu.pos]) * 6;
|
||||||
|
if (textlen >= FBW - 2) {
|
||||||
|
if (textlen - s_menu.text_slide > FBW - 1) {
|
||||||
|
s_menu.text_slide += 1;
|
||||||
|
if (textlen - s_menu.text_slide >= FBW - 1) {
|
||||||
|
s_menu.slide_end_time = tickNow;
|
||||||
|
}
|
||||||
|
} else if (tickNow - s_menu.slide_end_time >= pdMS_TO_TICKS(500)) {
|
||||||
|
s_menu.change_time = tickNow;
|
||||||
|
s_menu.slide_end_time = 0;
|
||||||
|
s_menu.text_slide = 0;
|
||||||
|
}
|
||||||
|
request_paint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GUI_EVENT_PAINT:
|
||||||
|
for (int i = 0; i < s_menu.len; i++) {
|
||||||
|
// is the row currently rendered the selected row?
|
||||||
|
const bool is_selected = s_menu.pos == i;
|
||||||
|
const fbcolor_t color = !is_selected; // text color - black if selected, because it's inverted
|
||||||
|
const fbpos_t y = 12 + offset + i * 10 ;
|
||||||
|
fb_rect(0, y, FBW, 10, !color);
|
||||||
|
fb_text(1 - (is_selected ? s_menu.text_slide : 0), y + 1, options[i], FONT_5X7, color);
|
||||||
|
// ensure the text doesn't touch the edge (looks ugly)
|
||||||
|
fb_vline(FBW - 1, y, 10, !color);
|
||||||
|
fb_vline(0, y, 10, !color);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// the button is held! release is what activates the button
|
||||||
|
case GUI_EVENT_KNOB_RELEASE:
|
||||||
|
input_sound_effect();
|
||||||
|
cb(s_menu.pos);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GUI_EVENT_KNOB_PLUS:
|
||||||
|
if (s_menu.pos < s_menu.len - 1) {
|
||||||
|
s_menu.pos++;
|
||||||
|
menu_changed = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GUI_EVENT_KNOB_MINUS:
|
||||||
|
if (s_menu.pos > 0) {
|
||||||
|
s_menu.pos--;
|
||||||
|
menu_changed = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (menu_changed) {
|
||||||
|
s_menu.change_time = tickNow;
|
||||||
|
s_menu.text_slide = 0;
|
||||||
|
s_menu.slide_end_time = 0;
|
||||||
|
input_sound_effect();
|
||||||
|
request_paint();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
//
|
||||||
|
// Created by MightyPork on 2023/04/09.
|
||||||
|
//
|
||||||
|
// Generic menu screen
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef TOASTER_OVEN_BLUEPILL_SCREEN_MENU_H
|
||||||
|
#define TOASTER_OVEN_BLUEPILL_SCREEN_MENU_H
|
||||||
|
|
||||||
|
#include "gui_event.h"
|
||||||
|
#include "ufb/framebuffer.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Choice callback for the generic menu screen. Options are indexed from zero
|
||||||
|
*/
|
||||||
|
typedef void (*menu_callback_t)(int choice);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic menu screen (must be called from a screen function with the standard signature)
|
||||||
|
*
|
||||||
|
* @param event - currently handled event
|
||||||
|
* @param options - options for the menu (items to show, NULL terminated array of const strings)
|
||||||
|
* @param cb - choice callback
|
||||||
|
*/
|
||||||
|
void screen_menu(GuiEvent event, const char **options, menu_callback_t cb);
|
||||||
|
|
||||||
|
/** Menu with custom offset (default is 15) */
|
||||||
|
void screen_menu_offset(GuiEvent event, const char **options, menu_callback_t cb, fbpos_t offset);
|
||||||
|
|
||||||
|
#endif //TOASTER_OVEN_BLUEPILL_SCREEN_MENU_H
|
||||||
+3
-7
@@ -46,7 +46,7 @@ void MX_ADC1_Init(void)
|
|||||||
PA0-WKUP ------> ADC1_IN0
|
PA0-WKUP ------> ADC1_IN0
|
||||||
PA1 ------> ADC1_IN1
|
PA1 ------> ADC1_IN1
|
||||||
*/
|
*/
|
||||||
GPIO_InitStruct.Pin = ADC_PT100_Pin|ADC_SENSR_Pin;
|
GPIO_InitStruct.Pin = LL_GPIO_PIN_0|ADC_SENSR_Pin;
|
||||||
GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
|
GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
|
||||||
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||||
|
|
||||||
@@ -67,10 +67,6 @@ void MX_ADC1_Init(void)
|
|||||||
|
|
||||||
LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MDATAALIGN_HALFWORD);
|
LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MDATAALIGN_HALFWORD);
|
||||||
|
|
||||||
/* ADC1 interrupt Init */
|
|
||||||
NVIC_SetPriority(ADC1_2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0));
|
|
||||||
NVIC_EnableIRQ(ADC1_2_IRQn);
|
|
||||||
|
|
||||||
/* USER CODE BEGIN ADC1_Init 1 */
|
/* USER CODE BEGIN ADC1_Init 1 */
|
||||||
|
|
||||||
/* USER CODE END ADC1_Init 1 */
|
/* USER CODE END ADC1_Init 1 */
|
||||||
@@ -82,10 +78,10 @@ void MX_ADC1_Init(void)
|
|||||||
LL_ADC_Init(ADC1, &ADC_InitStruct);
|
LL_ADC_Init(ADC1, &ADC_InitStruct);
|
||||||
ADC_CommonInitStruct.Multimode = LL_ADC_MULTI_INDEPENDENT;
|
ADC_CommonInitStruct.Multimode = LL_ADC_MULTI_INDEPENDENT;
|
||||||
LL_ADC_CommonInit(__LL_ADC_COMMON_INSTANCE(ADC1), &ADC_CommonInitStruct);
|
LL_ADC_CommonInit(__LL_ADC_COMMON_INSTANCE(ADC1), &ADC_CommonInitStruct);
|
||||||
ADC_REG_InitStruct.TriggerSource = LL_ADC_REG_TRIG_SOFTWARE;
|
ADC_REG_InitStruct.TriggerSource = LL_ADC_REG_TRIG_EXT_TIM1_CH1;
|
||||||
ADC_REG_InitStruct.SequencerLength = LL_ADC_REG_SEQ_SCAN_ENABLE_4RANKS;
|
ADC_REG_InitStruct.SequencerLength = LL_ADC_REG_SEQ_SCAN_ENABLE_4RANKS;
|
||||||
ADC_REG_InitStruct.SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE;
|
ADC_REG_InitStruct.SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE;
|
||||||
ADC_REG_InitStruct.ContinuousMode = LL_ADC_REG_CONV_CONTINUOUS;
|
ADC_REG_InitStruct.ContinuousMode = LL_ADC_REG_CONV_SINGLE;
|
||||||
ADC_REG_InitStruct.DMATransfer = LL_ADC_REG_DMA_TRANSFER_UNLIMITED;
|
ADC_REG_InitStruct.DMATransfer = LL_ADC_REG_DMA_TRANSFER_UNLIMITED;
|
||||||
LL_ADC_REG_Init(ADC1, &ADC_REG_InitStruct);
|
LL_ADC_REG_Init(ADC1, &ADC_REG_InitStruct);
|
||||||
|
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ void app_buzzer_init()
|
|||||||
{
|
{
|
||||||
/* Enable buzzer PWM */
|
/* Enable buzzer PWM */
|
||||||
LL_TIM_OC_SetCompareCH1(TIM_BUZZER, 0);
|
LL_TIM_OC_SetCompareCH1(TIM_BUZZER, 0);
|
||||||
LL_TIM_EnableCounter(TIM_BUZZER);
|
|
||||||
LL_TIM_CC_EnableChannel(TIM_BUZZER, LL_TIM_CHANNEL_CH1);
|
LL_TIM_CC_EnableChannel(TIM_BUZZER, LL_TIM_CHANNEL_CH1);
|
||||||
|
LL_TIM_EnableCounter(TIM_BUZZER);
|
||||||
// HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
|
// HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
|
||||||
|
|
||||||
// s_timer = xTimerCreate("beep", 50, 0, NULL, app_beep_end);
|
// s_timer = xTimerCreate("beep", 50, 0, NULL, app_beep_end);
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
/**
|
|
||||||
* TODO file description
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "app_gui.h"
|
|
||||||
#include "cmsis_os2.h"
|
|
||||||
#include "FreeRTOS.h"
|
|
||||||
#include "task.h"
|
|
||||||
|
|
||||||
void app_task_gui(void *argument) {
|
|
||||||
while (1) {
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
/**
|
|
||||||
* TODO file description
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BLUEPILLTROUBA_APP_GUI_H
|
|
||||||
#define BLUEPILLTROUBA_APP_GUI_H
|
|
||||||
|
|
||||||
void app_task_gui(void *argument);
|
|
||||||
|
|
||||||
#endif //BLUEPILLTROUBA_APP_GUI_H
|
|
||||||
+61
-9
@@ -7,6 +7,9 @@
|
|||||||
#include "app_heater.h"
|
#include "app_heater.h"
|
||||||
#include "cmsis_os2.h"
|
#include "cmsis_os2.h"
|
||||||
#include "tim.h"
|
#include "tim.h"
|
||||||
|
#include "queue.h"
|
||||||
|
#include "app_safety.h"
|
||||||
|
#include "Gui/gui_event.h"
|
||||||
|
|
||||||
extern osMutexId_t heaterMutexHandle;
|
extern osMutexId_t heaterMutexHandle;
|
||||||
|
|
||||||
@@ -36,12 +39,15 @@ static struct {
|
|||||||
float tuning_p;
|
float tuning_p;
|
||||||
float tuning_i;
|
float tuning_i;
|
||||||
float tuning_d;
|
float tuning_d;
|
||||||
|
/// Manual PWM override (percent, -1 = override disable)
|
||||||
|
int manual_override;
|
||||||
// PID state
|
// PID state
|
||||||
struct PID pid;
|
struct PID pid;
|
||||||
} state = {
|
} state = {
|
||||||
.tuning_p = 10.0f,
|
.tuning_p = 10.0f,
|
||||||
.tuning_i = 0.052f,
|
.tuning_i = 0.052f,
|
||||||
.tuning_d = 100.0f,
|
.tuning_d = 100.0f,
|
||||||
|
.manual_override = -1,
|
||||||
.pid = {
|
.pid = {
|
||||||
.SampleTimeTicks = pdMS_TO_TICKS(1000),
|
.SampleTimeTicks = pdMS_TO_TICKS(1000),
|
||||||
.outMax = 100.0f,
|
.outMax = 100.0f,
|
||||||
@@ -59,6 +65,19 @@ static inline void heaterExitCritical() {
|
|||||||
osMutexRelease(heaterMutexHandle);
|
osMutexRelease(heaterMutexHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void app_heater_manual_override(int percent) {
|
||||||
|
PRINTF("Set manual override: %d\r\n", percent);
|
||||||
|
|
||||||
|
heaterEnterCritical();
|
||||||
|
PID_SetCtlMode(&state.pid, PID_MANUAL);
|
||||||
|
state.manual_override = percent;
|
||||||
|
heaterExitCritical();
|
||||||
|
}
|
||||||
|
|
||||||
|
void app_heater_manual_override_clear() {
|
||||||
|
app_heater_manual_override(-1);
|
||||||
|
}
|
||||||
|
|
||||||
void app_heater_set_tuning(float p, float i, float d) {
|
void app_heater_set_tuning(float p, float i, float d) {
|
||||||
heaterEnterCritical();
|
heaterEnterCritical();
|
||||||
PID_SetTunings(&state.pid, p, i, d);
|
PID_SetTunings(&state.pid, p, i, d);
|
||||||
@@ -66,21 +85,44 @@ void app_heater_set_tuning(float p, float i, float d) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void app_heater_enable(bool enable) {
|
void app_heater_enable(bool enable) {
|
||||||
printf("Set heater enabled = %d\r\n", (int) enable);
|
PRINTF("Set heater enabled = %d\r\n", (int) enable);
|
||||||
heaterEnterCritical();
|
heaterEnterCritical();
|
||||||
PID_SetCtlMode(&state.pid, enable ? PID_AUTOMATIC : PID_MANUAL);
|
PID_SetCtlMode(&state.pid, enable ? PID_AUTOMATIC : PID_MANUAL);
|
||||||
heaterExitCritical();
|
heaterExitCritical();
|
||||||
}
|
}
|
||||||
|
|
||||||
void app_heater_set_target(float target) {
|
void app_heater_set_target(float target) {
|
||||||
printf("Set heater target = %d\r\n", (int) target);
|
PRINTF("Set heater target = %d\r\n", (int) target);
|
||||||
heaterEnterCritical();
|
heaterEnterCritical();
|
||||||
PID_SetSetpoint(&state.pid, target);
|
PID_SetSetpoint(&state.pid, target);
|
||||||
heaterExitCritical();
|
heaterExitCritical();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// emergency shutdown, this must not block use RTOS since it can be called from fault handlers or interrupt
|
||||||
|
void app_heater_emergency_shutdown() {
|
||||||
|
// Stop pwm
|
||||||
|
LL_TIM_OC_SetCompareCH1(TIM_HEATER, 0);
|
||||||
|
LL_TIM_CC_DisableChannel(TIM_HEATER, LL_TIM_CHANNEL_CH1);
|
||||||
|
LL_TIM_DisableCounter(TIM_HEATER);
|
||||||
|
|
||||||
|
// Also kill the GPIO PWM output
|
||||||
|
LL_GPIO_InitTypeDef GPIO_InitStruct = {};
|
||||||
|
GPIO_InitStruct.Pin = PWM_HEATER_Pin;
|
||||||
|
GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
|
||||||
|
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
|
||||||
|
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
|
||||||
|
LL_GPIO_Init(PWM_HEATER_GPIO_Port, &GPIO_InitStruct);
|
||||||
|
|
||||||
|
// Output zero
|
||||||
|
LL_GPIO_ResetOutputPin(PWM_HEATER_GPIO_Port, PWM_HEATER_Pin);
|
||||||
|
}
|
||||||
|
|
||||||
void app_task_heater(void *argument)
|
void app_task_heater(void *argument)
|
||||||
{
|
{
|
||||||
|
// Wait until inited
|
||||||
|
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||||
|
PUTS("Heater task starts\r\n");
|
||||||
|
|
||||||
heater_pwm_init();
|
heater_pwm_init();
|
||||||
|
|
||||||
heaterEnterCritical();
|
heaterEnterCritical();
|
||||||
@@ -96,19 +138,29 @@ void app_task_heater(void *argument)
|
|||||||
state.oven_temp = app_temp_read_oven();
|
state.oven_temp = app_temp_read_oven();
|
||||||
state.soc_temp = app_temp_read_soc();
|
state.soc_temp = app_temp_read_soc();
|
||||||
|
|
||||||
|
enum GuiEvent ev = GUI_EVENT_TEMP_CHANGE;
|
||||||
|
xQueueSend(guiEventQueHandle, &ev, pdMS_TO_TICKS(100));
|
||||||
|
|
||||||
heaterEnterCritical();
|
heaterEnterCritical();
|
||||||
PID_Compute(&state.pid, state.oven_temp);
|
app_safety_pass_reg_loop_running();
|
||||||
if (state.pid.ctlMode == PID_AUTOMATIC) {
|
|
||||||
printf("temp %d, output %d\r\n", (int) state.oven_temp, (int) state.pid.Output);
|
if (state.manual_override >= 0 && state.manual_override <= 100) {
|
||||||
heater_pwm_set_perc(state.pid.Output);
|
PRINTF("manual override %d%%\r\n", state.manual_override);
|
||||||
|
heater_pwm_set_perc(state.manual_override);
|
||||||
} else {
|
} else {
|
||||||
// turn it off
|
PID_Compute(&state.pid, state.oven_temp);
|
||||||
heater_pwm_set_perc(0);
|
if (state.pid.ctlMode == PID_AUTOMATIC) {
|
||||||
|
PRINTF("temp %d, output %d\r\n", (int) state.oven_temp, (int) state.pid.Output);
|
||||||
|
heater_pwm_set_perc(state.pid.Output);
|
||||||
|
} else {
|
||||||
|
// turn it off
|
||||||
|
heater_pwm_set_perc(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
heaterExitCritical();
|
heaterExitCritical();
|
||||||
|
|
||||||
// TODO notify UI thread of the new temperature and heating percent
|
// TODO notify UI thread of the new temperature and heating percent
|
||||||
|
|
||||||
vTaskDelayUntil(&wake_time, pdMS_TO_TICKS(500));
|
vTaskDelayUntil(&wake_time, pdMS_TO_TICKS(100));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,21 @@
|
|||||||
#define BLUEPILLTROUBA_APP_HEATER_H
|
#define BLUEPILLTROUBA_APP_HEATER_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include "cmsis_os2.h"
|
||||||
|
|
||||||
|
#define MAX_TEMP 400
|
||||||
|
|
||||||
|
extern osThreadId_t heaterTskHandle;
|
||||||
|
|
||||||
void app_task_heater(void *argument);
|
void app_task_heater(void *argument);
|
||||||
|
|
||||||
|
/// Clear manual override, disable heater for normal mode.
|
||||||
|
void app_heater_manual_override_clear();
|
||||||
|
|
||||||
|
/// Set manual override PWM 0-100%.
|
||||||
|
/// Also disables heater in the normal mode.
|
||||||
|
void app_heater_manual_override(int percent);
|
||||||
|
|
||||||
/// Set heater regulator tuning.
|
/// Set heater regulator tuning.
|
||||||
/// Mutex is locked internally.
|
/// Mutex is locked internally.
|
||||||
void app_heater_set_tuning(float p, float i, float d);
|
void app_heater_set_tuning(float p, float i, float d);
|
||||||
@@ -21,4 +33,7 @@ void app_heater_enable(bool enable);
|
|||||||
/// Mutex is locked internally.
|
/// Mutex is locked internally.
|
||||||
void app_heater_set_target(float target);
|
void app_heater_set_target(float target);
|
||||||
|
|
||||||
|
/// Shutdown the heater; This function does not use mutex and just disables the PWM via register access.
|
||||||
|
void app_heater_emergency_shutdown();
|
||||||
|
|
||||||
#endif //BLUEPILLTROUBA_APP_HEATER_H
|
#endif //BLUEPILLTROUBA_APP_HEATER_H
|
||||||
|
|||||||
+63
-1
@@ -6,6 +6,14 @@
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "app_knob.h"
|
#include "app_knob.h"
|
||||||
#include "tim.h"
|
#include "tim.h"
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "queue.h"
|
||||||
|
#include "timers.h"
|
||||||
|
#include "cmsis_os2.h"
|
||||||
|
#include "Gui/gui_event.h"
|
||||||
|
|
||||||
|
extern osTimerId_t buttonPushTimerHandle;
|
||||||
|
extern osTimerId_t buttonReleaseTimerHandle;
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
uint16_t wheel;
|
uint16_t wheel;
|
||||||
@@ -18,14 +26,68 @@ void app_knob_init()
|
|||||||
LL_TIM_CC_EnableChannel(TIM_KNOB, LL_TIM_CHANNEL_CH1 | LL_TIM_CHANNEL_CH2);
|
LL_TIM_CC_EnableChannel(TIM_KNOB, LL_TIM_CHANNEL_CH1 | LL_TIM_CHANNEL_CH2);
|
||||||
LL_TIM_EnableCounter(TIM_KNOB);
|
LL_TIM_EnableCounter(TIM_KNOB);
|
||||||
|
|
||||||
// HAL_TIM_Encoder_Start(&htim4, TIM_CHANNEL_ALL);
|
// for the change interrupt
|
||||||
|
LL_TIM_EnableIT_CC1(TIM_KNOB);
|
||||||
|
LL_TIM_EnableIT_CC2(TIM_KNOB);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t app_knob_get_raw() {
|
uint16_t app_knob_get_raw() {
|
||||||
return LL_TIM_GetCounter(TIM_KNOB);
|
return LL_TIM_GetCounter(TIM_KNOB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char buf[100];
|
||||||
|
|
||||||
|
void app_knob_turn_isr()
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
uint16_t old_wheel = s_knob.wheel;
|
||||||
|
s_knob.wheel = LL_TIM_GetCounter(TIM_KNOB);
|
||||||
|
|
||||||
|
int16_t wheel_change = (int16_t)(s_knob.wheel - old_wheel);
|
||||||
|
|
||||||
|
BaseType_t yield = pdFALSE;
|
||||||
|
|
||||||
|
while (wheel_change > 0) {
|
||||||
|
wheel_change--;
|
||||||
|
enum GuiEvent ev = GUI_EVENT_KNOB_PLUS;
|
||||||
|
xQueueSendFromISR(guiEventQueHandle, &ev, &yield);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (wheel_change < 0) {
|
||||||
|
wheel_change++;
|
||||||
|
enum GuiEvent ev = GUI_EVENT_KNOB_MINUS;
|
||||||
|
xQueueSendFromISR(guiEventQueHandle, &ev, &yield);
|
||||||
|
}
|
||||||
|
|
||||||
|
portYIELD_FROM_ISR(yield);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO use EXTI for push
|
||||||
|
|
||||||
bool app_knob_pushed() {
|
bool app_knob_pushed() {
|
||||||
return 0 == LL_GPIO_IsInputPinSet(KNOB_PUSH_GPIO_Port, KNOB_PUSH_Pin);
|
return 0 == LL_GPIO_IsInputPinSet(KNOB_PUSH_GPIO_Port, KNOB_PUSH_Pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void app_knob_push_isr(bool push)
|
||||||
|
{
|
||||||
|
PUTCHAR(push ? '#' : '.');
|
||||||
|
|
||||||
|
BaseType_t yield = pdFALSE;
|
||||||
|
if (push) {
|
||||||
|
xTimerStopFromISR(buttonReleaseTimerHandle, &yield);
|
||||||
|
xTimerStopFromISR(buttonPushTimerHandle, &yield);
|
||||||
|
xTimerChangePeriodFromISR(buttonPushTimerHandle, pdMS_TO_TICKS(10), &yield);
|
||||||
|
} else {
|
||||||
|
xTimerStopFromISR(buttonPushTimerHandle, &yield);
|
||||||
|
xTimerStopFromISR(buttonReleaseTimerHandle, &yield);
|
||||||
|
xTimerChangePeriodFromISR(buttonReleaseTimerHandle, pdMS_TO_TICKS(10), &yield);
|
||||||
|
}
|
||||||
|
portYIELD_FROM_ISR(yield);
|
||||||
|
}
|
||||||
|
|
||||||
|
void app_push_debounce(void *argument) {
|
||||||
|
bool push = (bool) argument;
|
||||||
|
enum GuiEvent ev = push ? GUI_EVENT_KNOB_PRESS : GUI_EVENT_KNOB_RELEASE;
|
||||||
|
xQueueSend(guiEventQueHandle, &ev, pdMS_TO_TICKS(100));
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,9 +5,14 @@
|
|||||||
#ifndef BLUEPILLTROUBA_APP_KNOB_H
|
#ifndef BLUEPILLTROUBA_APP_KNOB_H
|
||||||
#define BLUEPILLTROUBA_APP_KNOB_H
|
#define BLUEPILLTROUBA_APP_KNOB_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
void app_knob_init();
|
void app_knob_init();
|
||||||
|
|
||||||
uint16_t app_knob_get_raw();
|
uint16_t app_knob_get_raw();
|
||||||
bool app_knob_pushed();
|
bool app_knob_pushed();
|
||||||
|
|
||||||
|
void app_knob_turn_isr();
|
||||||
|
void app_knob_push_isr(bool push);
|
||||||
|
|
||||||
#endif //BLUEPILLTROUBA_APP_KNOB_H
|
#endif //BLUEPILLTROUBA_APP_KNOB_H
|
||||||
|
|||||||
+137
-115
@@ -12,78 +12,88 @@
|
|||||||
#include "ufb/framebuffer.h"
|
#include "ufb/framebuffer.h"
|
||||||
#include "iwdg.h"
|
#include "iwdg.h"
|
||||||
#include "app_oled.h"
|
#include "app_oled.h"
|
||||||
#include "ufb/fb_text.h"
|
//#include "ufb/fb_text.h"
|
||||||
#include "ufb/fb_7seg.h"
|
//#include "ufb/fb_7seg.h"
|
||||||
#include "app_temp.h"
|
#include "app_temp.h"
|
||||||
#include "app_knob.h"
|
#include "app_knob.h"
|
||||||
#include "app_buzzer.h"
|
#include "app_buzzer.h"
|
||||||
#include "app_heater.h"
|
//#include "app_heater.h"
|
||||||
|
//#include "cmsis_os2.h"
|
||||||
|
#include "eeprom_emul.h"
|
||||||
|
#include "app_safety.h"
|
||||||
#include "cmsis_os2.h"
|
#include "cmsis_os2.h"
|
||||||
|
|
||||||
static struct App {
|
extern osThreadId_t heaterTskHandle;
|
||||||
float oven_temp;
|
extern osThreadId_t mainTskHandle;
|
||||||
int16_t set_temp;
|
extern osThreadId_t guiTskHandle;
|
||||||
int16_t wheel_normed;
|
|
||||||
uint16_t wheel;
|
|
||||||
bool run;
|
|
||||||
} s_app = {};
|
|
||||||
|
|
||||||
static void redraw_display() {
|
//static struct App {
|
||||||
fb_clear();
|
// float oven_temp;
|
||||||
|
// int16_t set_temp;
|
||||||
|
// int16_t wheel_normed;
|
||||||
|
// uint16_t wheel;
|
||||||
|
// bool run;
|
||||||
|
//} s_app = {};
|
||||||
|
|
||||||
char tmp[100];
|
//static void redraw_display() {
|
||||||
|
// fb_clear();
|
||||||
sprintf(tmp, "T=%d°C", (int) s_app.oven_temp);
|
//
|
||||||
fb_text(3, 3, tmp, FONT_5X7, 1);
|
// char tmp[100];
|
||||||
|
//
|
||||||
sprintf(tmp, "Cil=%d°C", s_app.set_temp);
|
// SPRINTF(tmp, "T=%d°C", (int) s_app.oven_temp);
|
||||||
fb_text(3, 11, tmp, FONT_5X7, 1);
|
// fb_text(3, 3, tmp, FONT_5X7, 1);
|
||||||
|
//
|
||||||
sprintf(tmp, "Stav=%s", s_app.run ? "ZAP" : "VYP");
|
// SPRINTF(tmp, "Cil=%d°C", s_app.set_temp);
|
||||||
fb_text(3, 19, tmp, FONT_5X7, 1);
|
// fb_text(3, 11, tmp, FONT_5X7, 1);
|
||||||
|
//
|
||||||
if (s_app.run) {
|
// SPRINTF(tmp, "Stav=%s", s_app.run ? "ZAP" : "VYP");
|
||||||
fb_frame(0, 0, FBW, FBH, 2, 1);
|
// fb_text(3, 19, tmp, FONT_5X7, 1);
|
||||||
}
|
//
|
||||||
|
// if (s_app.run) {
|
||||||
// some funny effects to showcase responsiveness and circle drawing
|
// fb_frame(0, 0, FBW, FBH, 2, 1);
|
||||||
|
// }
|
||||||
fb_circle(FBW / 2, 70, 18, 1, 1);
|
//
|
||||||
|
// // some funny effects to showcase responsiveness and circle drawing
|
||||||
for (int i = 0; i < 6; i++) {
|
//
|
||||||
float x = FBW / 2;
|
// fb_circle(FBW / 2, 70, 18, 1, 1);
|
||||||
float y = 70;
|
//
|
||||||
|
// for (int i = 0; i < 6; i++) {
|
||||||
int ii = i;
|
// float x = FBW / 2;
|
||||||
|
// float y = 70;
|
||||||
float angle = (float) ii * (M_PI / 3.0) - s_app.wheel_normed * (M_PI / 24);
|
//
|
||||||
|
// int ii = i;
|
||||||
x = x + sinf(angle) * 10;
|
//
|
||||||
y = y + cosf(angle) * 10;
|
// float angle = (float) ii * (M_PI / 3.0) - s_app.wheel_normed * (M_PI / 24);
|
||||||
|
//
|
||||||
fb_circle((fbpos_t) x, (fbpos_t) y, 4, i==0?4:1, 1);
|
// x = x + sinf(angle) * 10;
|
||||||
}
|
// y = y + cosf(angle) * 10;
|
||||||
|
//
|
||||||
fb_text(0, s_app.wheel_normed, ":3 :3", FONT_4X5, 1);
|
// fb_circle((fbpos_t) x, (fbpos_t) y, 4, i==0?4:1, 1);
|
||||||
|
// }
|
||||||
fb_7seg_number(
|
//
|
||||||
2, FBH - 20,
|
// fb_text(0, s_app.wheel_normed, ":3 :3", FONT_4X5, 1);
|
||||||
10, 16,
|
//
|
||||||
2, // th
|
// fb_7seg_number(
|
||||||
2, // spacing
|
// 2, FBH - 20,
|
||||||
1, // color
|
// 10, 16,
|
||||||
s_app.wheel,
|
// 2, // th
|
||||||
4, // places
|
// 2, // spacing
|
||||||
2);// decimals
|
// 1, // color
|
||||||
|
// s_app.wheel,
|
||||||
|
// 4, // places
|
||||||
|
// 2);// decimals
|
||||||
fb_blit();
|
//
|
||||||
}
|
//
|
||||||
|
//
|
||||||
|
// fb_blit();
|
||||||
|
//}
|
||||||
|
|
||||||
void app_task_main(void *argument)
|
void app_task_main(void *argument)
|
||||||
{
|
{
|
||||||
printf("Main task\r\n");
|
PUTS("Main task\r\n");
|
||||||
|
|
||||||
|
EE_Init(EE_CONDITIONAL_ERASE);
|
||||||
|
|
||||||
app_analog_init();
|
app_analog_init();
|
||||||
app_buzzer_init();
|
app_buzzer_init();
|
||||||
app_knob_init();
|
app_knob_init();
|
||||||
@@ -92,66 +102,78 @@ void app_task_main(void *argument)
|
|||||||
oled_init();
|
oled_init();
|
||||||
fb_clear();
|
fb_clear();
|
||||||
|
|
||||||
/* Infinite loop */
|
/* all inited */
|
||||||
bool old_pushed = app_knob_pushed();
|
|
||||||
|
|
||||||
bool any_change = true;
|
// notify threads that we are ready
|
||||||
uint32_t last_redraw = osKernelGetTickCount();
|
xTaskNotifyGive(guiTskHandle);
|
||||||
|
xTaskNotifyGive(heaterTskHandle);
|
||||||
|
|
||||||
printf("Loop\r\n");
|
// while(1) {
|
||||||
|
// LL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
|
||||||
|
// vTaskDelay(pdMS_TO_TICKS(250));
|
||||||
|
// LL_IWDG_ReloadCounter(IWDG);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /* Infinite loop */
|
||||||
|
// bool old_pushed = app_knob_pushed();
|
||||||
|
//
|
||||||
|
// bool any_change = true;
|
||||||
|
// uint32_t last_redraw = osKernelGetTickCount();
|
||||||
|
|
||||||
|
PUTS("Main loop\r\n");
|
||||||
for (;;) {
|
for (;;) {
|
||||||
// sampling is done in the heater loop
|
// sampling is done in the heater loop
|
||||||
|
|
||||||
s_app.oven_temp = app_temp_read_oven();
|
// s_app.oven_temp = app_temp_read_oven();
|
||||||
|
//
|
||||||
|
// uint16_t old_wheel = s_app.wheel;
|
||||||
|
// s_app.wheel = app_knob_get_raw();
|
||||||
|
//
|
||||||
|
// // TODO do this with interrupt and/or debouncing
|
||||||
|
// bool pushed = app_knob_pushed();
|
||||||
|
// if (pushed && !old_pushed) {
|
||||||
|
// s_app.run ^= 1;
|
||||||
|
// app_heater_enable(s_app.run);
|
||||||
|
// app_buzzer_beep();
|
||||||
|
// any_change = true;
|
||||||
|
// }
|
||||||
|
// old_pushed = pushed;
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// int16_t wheel_change = (int16_t)(s_app.wheel - old_wheel);
|
||||||
|
// if (wheel_change != 0) {
|
||||||
|
// s_app.wheel_normed += wheel_change;
|
||||||
|
// if (s_app.wheel_normed < 0) {
|
||||||
|
// s_app.wheel_normed = 0;
|
||||||
|
// }
|
||||||
|
// if (s_app.wheel_normed > 500) {
|
||||||
|
// s_app.wheel_normed = 500;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// int16_t old_temp = s_app.set_temp;
|
||||||
|
//
|
||||||
|
// s_app.set_temp = (s_app.wheel_normed / 2) * 5;
|
||||||
|
//
|
||||||
|
// if (old_temp != s_app.set_temp) {
|
||||||
|
// app_buzzer_beep();
|
||||||
|
// app_heater_set_target((float) s_app.set_temp);
|
||||||
|
// any_change = true;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// uint32_t now = osKernelGetTickCount();
|
||||||
|
// if (any_change || (now - last_redraw > pdMS_TO_TICKS(500))) {
|
||||||
|
// last_redraw = now;
|
||||||
|
// redraw_display();
|
||||||
|
// any_change = false;
|
||||||
|
//
|
||||||
|
// // Blink
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
uint16_t old_wheel = s_app.wheel;
|
vTaskDelay(pdMS_TO_TICKS(100));
|
||||||
s_app.wheel = app_knob_get_raw();
|
|
||||||
|
|
||||||
// TODO do this with interrupt and/or debouncing
|
|
||||||
bool pushed = app_knob_pushed();
|
|
||||||
if (pushed && !old_pushed) {
|
|
||||||
s_app.run ^= 1;
|
|
||||||
app_heater_enable(s_app.run);
|
|
||||||
app_buzzer_beep();
|
|
||||||
any_change = true;
|
|
||||||
}
|
|
||||||
old_pushed = pushed;
|
|
||||||
|
|
||||||
|
|
||||||
int16_t wheel_change = (int16_t)(s_app.wheel - old_wheel);
|
|
||||||
if (wheel_change != 0) {
|
|
||||||
s_app.wheel_normed += wheel_change;
|
|
||||||
if (s_app.wheel_normed < 0) {
|
|
||||||
s_app.wheel_normed = 0;
|
|
||||||
}
|
|
||||||
if (s_app.wheel_normed > 500) {
|
|
||||||
s_app.wheel_normed = 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
int16_t old_temp = s_app.set_temp;
|
|
||||||
|
|
||||||
s_app.set_temp = (s_app.wheel_normed / 2) * 5;
|
|
||||||
|
|
||||||
if (old_temp != s_app.set_temp) {
|
|
||||||
app_buzzer_beep();
|
|
||||||
app_heater_set_target((float) s_app.set_temp);
|
|
||||||
any_change = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t now = osKernelGetTickCount();
|
|
||||||
if (any_change || (now - last_redraw > pdMS_TO_TICKS(500))) {
|
|
||||||
last_redraw = now;
|
|
||||||
redraw_display();
|
|
||||||
any_change = false;
|
|
||||||
|
|
||||||
// Blink
|
|
||||||
LL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
|
|
||||||
}
|
|
||||||
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(10));
|
|
||||||
|
|
||||||
// feed dogs
|
// feed dogs
|
||||||
LL_IWDG_ReloadCounter(IWDG);
|
app_safety_poll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,13 +2,8 @@
|
|||||||
// Created by MightyPork on 2022/12/28.
|
// Created by MightyPork on 2022/12/28.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "ufb/framebuffer.h"
|
#include "ufb/framebuffer.h"
|
||||||
#include "gpio.h"
|
#include "gpio.h"
|
||||||
#include "spi.h"
|
|
||||||
#include "FreeRTOS.h"
|
|
||||||
|
|
||||||
#define SSD1309_HEIGHT 64
|
#define SSD1309_HEIGHT 64
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -25,7 +25,7 @@ void PID_Compute(struct PID *self, float input)
|
|||||||
uint32_t now = xTaskGetTickCount();
|
uint32_t now = xTaskGetTickCount();
|
||||||
int32_t timeChange = (now - self->lastTime);
|
int32_t timeChange = (now - self->lastTime);
|
||||||
if (timeChange >= self->SampleTimeTicks) {
|
if (timeChange >= self->SampleTimeTicks) {
|
||||||
printf("compute\r\n");
|
PUTS("compute\r\n");
|
||||||
/*Compute all the working error variables*/
|
/*Compute all the working error variables*/
|
||||||
float error = self->Setpoint - input;
|
float error = self->Setpoint - input;
|
||||||
self->ITerm += (self->ki * error);
|
self->ITerm += (self->ki * error);
|
||||||
@@ -35,7 +35,7 @@ void PID_Compute(struct PID *self, float input)
|
|||||||
float dInput = (input - self->lastInput);
|
float dInput = (input - self->lastInput);
|
||||||
|
|
||||||
|
|
||||||
printf("calc x100 %d + %d - %d\r\n",
|
PRINTF("calc x100 %d + %d - %d\r\n",
|
||||||
(int) (100 * (self->kp * error)),
|
(int) (100 * (self->kp * error)),
|
||||||
(int) (100 * (self->ITerm)),
|
(int) (100 * (self->ITerm)),
|
||||||
(int) (100 * (self->kd * dInput))
|
(int) (100 * (self->kd * dInput))
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
/**
|
||||||
|
* TODO file description
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "app_safety.h"
|
||||||
|
#include "app_heater.h"
|
||||||
|
#include "snprintf.h"
|
||||||
|
#include "stm32f1xx_ll_iwdg.h"
|
||||||
|
#include "stm32f1xx_ll_gpio.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
#define HB_FLAG_TEMP_NORMAL (1 << 0)
|
||||||
|
#define HB_FLAG_ADC_SAMPLING (1 << 1)
|
||||||
|
#define HB_FLAG_TEMP_CALCULATION (1 << 2)
|
||||||
|
#define HB_FLAG_REG_LOOP (1 << 3)
|
||||||
|
#define HB_FLAG_DISPLAY_UPDATING (1 << 4)
|
||||||
|
#define HB_FLAG_SOC_TEMP_OK (1 << 5)
|
||||||
|
|
||||||
|
#define HB_FLAG_ALL (0b111111)
|
||||||
|
|
||||||
|
static volatile uint32_t heartbeat_flags = 0;
|
||||||
|
|
||||||
|
void app_safety_pass_temp_normal() {
|
||||||
|
heartbeat_flags |= HB_FLAG_TEMP_NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void app_safety_pass_adc_sampling() {
|
||||||
|
heartbeat_flags |= HB_FLAG_ADC_SAMPLING;
|
||||||
|
}
|
||||||
|
|
||||||
|
void app_safety_pass_temp_calculation() {
|
||||||
|
heartbeat_flags |= HB_FLAG_TEMP_CALCULATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
void app_safety_pass_reg_loop_running() {
|
||||||
|
heartbeat_flags |= HB_FLAG_REG_LOOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
void app_safety_pass_display_updating() {
|
||||||
|
heartbeat_flags |= HB_FLAG_DISPLAY_UPDATING;
|
||||||
|
}
|
||||||
|
|
||||||
|
void app_safety_pass_soc_temp_ok() {
|
||||||
|
heartbeat_flags |= HB_FLAG_SOC_TEMP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void app_safety_poll() {
|
||||||
|
if ((heartbeat_flags & HB_FLAG_ALL) == HB_FLAG_ALL) {
|
||||||
|
LL_IWDG_ReloadCounter(IWDG);
|
||||||
|
LL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
|
||||||
|
heartbeat_flags = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// emergency shutdown, this must not block use RTOS since it can be called from fault handlers or interrupt
|
||||||
|
void __attribute__((noreturn)) app_emergency_stop() {
|
||||||
|
app_heater_emergency_shutdown();
|
||||||
|
|
||||||
|
PUTS("\r\n*** EMERGENCY STOP ***\r\n");
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
// wait for the watchdog to bite
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* TODO file description
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BLUEPILLTROUBA_APP_SAFETY_H
|
||||||
|
#define BLUEPILLTROUBA_APP_SAFETY_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check the pass flags. If all are set, reset the WD and clear flags.
|
||||||
|
*
|
||||||
|
* This effectively makes the WD bite when either of the subsystems fails.
|
||||||
|
*/
|
||||||
|
void app_safety_poll();
|
||||||
|
|
||||||
|
void app_emergency_stop()
|
||||||
|
__attribute__((noreturn));
|
||||||
|
|
||||||
|
void app_safety_pass_temp_normal();
|
||||||
|
|
||||||
|
void app_safety_pass_adc_sampling();
|
||||||
|
|
||||||
|
void app_safety_pass_temp_calculation();
|
||||||
|
|
||||||
|
void app_safety_pass_reg_loop_running();
|
||||||
|
|
||||||
|
void app_safety_pass_display_updating();
|
||||||
|
|
||||||
|
void app_safety_pass_soc_temp_ok();
|
||||||
|
|
||||||
|
#endif //BLUEPILLTROUBA_APP_SAFETY_H
|
||||||
+228
-120
@@ -9,6 +9,12 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "app_temp.h"
|
#include "app_temp.h"
|
||||||
#include "adc.h"
|
#include "adc.h"
|
||||||
|
#include "snprintf.h"
|
||||||
|
#include "app_safety.h"
|
||||||
|
#include "eeprom_emul_types.h"
|
||||||
|
#include "eeprom_emul.h"
|
||||||
|
#include "ee_addresses.h"
|
||||||
|
#include "transmute.h"
|
||||||
|
|
||||||
/* DMA dest */
|
/* DMA dest */
|
||||||
static volatile uint16_t adc_values[4];
|
static volatile uint16_t adc_values[4];
|
||||||
@@ -16,129 +22,176 @@ static volatile uint16_t adc_values[4];
|
|||||||
const float V_REFINT = 1.23f;
|
const float V_REFINT = 1.23f;
|
||||||
|
|
||||||
#define AVERAGEBUF_DEPTH 16
|
#define AVERAGEBUF_DEPTH 16
|
||||||
#define OVENTEMP_HISTORY_DEPTH 10
|
#define OVENTEMP_HISTORY_DEPTH 20
|
||||||
|
|
||||||
static struct App {
|
static struct App {
|
||||||
float oven_temp;
|
float oven_temp;
|
||||||
|
float oven_temp_raw;
|
||||||
float soc_temp;
|
float soc_temp;
|
||||||
float v_sensor;
|
float cal_a;
|
||||||
|
float cal_b;
|
||||||
|
float oventemp_history[OVENTEMP_HISTORY_DEPTH]; // raw temp
|
||||||
uint16_t adc_averagebuf[AVERAGEBUF_DEPTH * 4];
|
uint16_t adc_averagebuf[AVERAGEBUF_DEPTH * 4];
|
||||||
uint8_t averagebuf_ptr;
|
uint8_t averagebuf_ptr;
|
||||||
float adc_averages[4];
|
|
||||||
float oventemp_history[OVENTEMP_HISTORY_DEPTH];
|
|
||||||
uint8_t oventemp_history_ptr;
|
uint8_t oventemp_history_ptr;
|
||||||
} s_analog = {};
|
} s_analog = {
|
||||||
|
// Ax + B = y ... X = raw sample (ratio 0-1 of 3.3), Y = corrected sample
|
||||||
|
.cal_a = 1.0f, // safe default calibration constants
|
||||||
|
.cal_b = 0.0f,
|
||||||
|
};
|
||||||
|
|
||||||
#define TSENSE_LOOKUP_LEN 101
|
#define TSENSE_LOOKUP_LEN 101
|
||||||
#define TSENSE_T_STEP 5.0f
|
#define TSENSE_T_STEP 5.0f
|
||||||
#define TSENSE_T_MIN 0.0f
|
#define TSENSE_T_MIN 0.0f
|
||||||
#define TSENSE_T_MAX 500.0f
|
#define TSENSE_T_MAX 500.0f
|
||||||
static const float TSENSE_LOOKUP[TSENSE_LOOKUP_LEN] = {
|
static const float TSENSE_LOOKUP[TSENSE_LOOKUP_LEN] = {
|
||||||
0.092678405931418f,
|
0.0909090909090909f,
|
||||||
0.0943174479327356f,
|
0.0925200328471449f,
|
||||||
0.095948157844312f,
|
0.0941228958173389f,
|
||||||
0.0975706768542549f,
|
0.0957178169362106f,
|
||||||
0.0991848957506647f,
|
0.0973046872002769f,
|
||||||
0.100791037522732f,
|
0.0988837241910161f,
|
||||||
0.102388993070241f,
|
0.100454819038946f,
|
||||||
0.103978983136042f,
|
0.102018187184848f,
|
||||||
0.105560980458654f,
|
0.103573800259031f,
|
||||||
0.107135039851509f,
|
0.105121710606384f,
|
||||||
0.108701215616829f,
|
0.106661970090864f,
|
||||||
0.110259642413441f,
|
0.108194709632656f,
|
||||||
0.111810211533421f,
|
0.109719820815089f,
|
||||||
0.113353137226489f,
|
0.111237512887056f,
|
||||||
0.114888310929339f,
|
0.112747677594865f,
|
||||||
0.11641594480226f,
|
0.114250522193605f,
|
||||||
0.117936009906507f,
|
0.115746016789507f,
|
||||||
0.119448557132363f,
|
0.117234210034522f,
|
||||||
0.120953636903929f,
|
0.118715150141415f,
|
||||||
0.122451377845456f,
|
0.120188962295434f,
|
||||||
0.12394167187544f,
|
0.121655538774297f,
|
||||||
0.125424725109556f,
|
0.123115081061434f,
|
||||||
0.126900429638119f,
|
0.124567481621389f,
|
||||||
0.128368989630084f,
|
0.126012940077612f,
|
||||||
0.129830374697352f,
|
0.127451425220842f,
|
||||||
0.131284632150064f,
|
0.128882982328346f,
|
||||||
0.132731808872517f,
|
0.13030765627567f,
|
||||||
0.134172027901771f,
|
0.131725566931108f,
|
||||||
0.135605181883591f,
|
0.133136607355006f,
|
||||||
0.13703146935069f,
|
0.134540971782401f,
|
||||||
0.138450783142958f,
|
0.135938553479917f,
|
||||||
0.139863319976468f,
|
0.137329544944786f,
|
||||||
0.14126904821384f,
|
0.138713913835562f,
|
||||||
0.142668011892657f,
|
0.140091702340679f,
|
||||||
0.144060254660872f,
|
0.141462952280536f,
|
||||||
0.145445894373796f,
|
0.142827778585901f,
|
||||||
0.146824824486877f,
|
0.144186075171443f,
|
||||||
0.14819723645253f,
|
0.145538029496198f,
|
||||||
0.149563023938454f,
|
0.146883535696824f,
|
||||||
0.150922376699229f,
|
0.148222779606307f,
|
||||||
0.15227526202401f,
|
0.149555727912261f,
|
||||||
0.153621720954182f,
|
0.150882419971517f,
|
||||||
0.15496179417407f,
|
0.152202894803216f,
|
||||||
0.156295594725426f,
|
0.153517262745702f,
|
||||||
0.157623016940038f,
|
0.154825418625535f,
|
||||||
0.158944245649448f,
|
0.156127543558165f,
|
||||||
0.160259175412251f,
|
0.157423532604634f,
|
||||||
0.16156798947087f,
|
0.158713565356767f,
|
||||||
0.162870654195634f,
|
0.159997607673187f,
|
||||||
0.164167207880495f,
|
0.161275696311014f,
|
||||||
0.165457688491696f,
|
0.162547867717066f,
|
||||||
0.166742204592451f,
|
0.163814227951767f,
|
||||||
0.168020651444079f,
|
0.165074672799026f,
|
||||||
0.169293207677971f,
|
0.166329377427284f,
|
||||||
0.170559768793747f,
|
0.167578237864685f,
|
||||||
0.171820511933356f,
|
0.168821427850084f,
|
||||||
0.173075402684405f,
|
0.170058912538152f,
|
||||||
0.174324476817747f,
|
0.171290726295724f,
|
||||||
0.175567769803026f,
|
0.172516903204089f,
|
||||||
0.176805386030345f,
|
0.17373754533289f,
|
||||||
0.178037221732226f,
|
0.174952549458501f,
|
||||||
0.179263449725904f,
|
0.176162085166716f,
|
||||||
0.180483966491086f,
|
0.177366049485545f,
|
||||||
0.181698943447122f,
|
0.178564610657697f,
|
||||||
0.182908345518766f,
|
0.179757733244091f,
|
||||||
0.184112206156428f,
|
0.180945449410727f,
|
||||||
0.185310558533273f,
|
0.182127791060477f,
|
||||||
0.186503503145257f,
|
0.183304856534839f,
|
||||||
0.187690937227925f,
|
0.184476543628915f,
|
||||||
0.188873028139146f,
|
0.185643016681207f,
|
||||||
0.190049673368296f,
|
0.186804173743842f,
|
||||||
0.191221038959601f,
|
0.18796017789194f,
|
||||||
0.192387089280576f,
|
0.18911099318983f,
|
||||||
0.193547855644572f,
|
0.190256649774341f,
|
||||||
0.194703369109397f,
|
0.191397177539504f,
|
||||||
0.195853726532112f,
|
0.192532671339319f,
|
||||||
0.196998826174689f,
|
0.193663030006298f,
|
||||||
0.19813883026229f,
|
0.194788412940845f,
|
||||||
0.199273637315452f,
|
0.195908719236171f,
|
||||||
0.200403408323351f,
|
0.197024107102852f,
|
||||||
0.201528107189346f,
|
0.198134540194308f,
|
||||||
0.20264776325594f,
|
0.19924004677399f,
|
||||||
0.203762405629782f,
|
0.200340654881021f,
|
||||||
0.204872127762998f,
|
0.201436456102762f,
|
||||||
0.205976828960191f,
|
0.202527350321362f,
|
||||||
0.207076666615101f,
|
0.203613492284647f,
|
||||||
0.208171540293999f,
|
0.204694782137667f,
|
||||||
0.209261606226334f,
|
0.205771373506423f,
|
||||||
0.210346827933364f,
|
0.206843229708988f,
|
||||||
0.211427232937629f,
|
0.20791037727704f,
|
||||||
0.212502848543705f,
|
0.208972842534733f,
|
||||||
0.213573765013592f,
|
0.210030714005839f,
|
||||||
0.214639882704581f,
|
0.211083892628833f,
|
||||||
0.215701354457324f,
|
0.212132528763072f,
|
||||||
0.216758080892489f,
|
0.213176523610881f,
|
||||||
0.217810213752734f,
|
0.214216026472748f,
|
||||||
0.218857716249547f,
|
0.215251000398025f,
|
||||||
0.219900614222686f,
|
0.216281470315524f,
|
||||||
0.220938933310224f,
|
0.21730746096184f,
|
||||||
0.221972760781578f,
|
0.218329057984116f,
|
||||||
0.223001998051553f,
|
0.219346163379138f,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// if the calibration constants are zero, reset to defaults
|
||||||
|
static void correct_invalid_calib() {
|
||||||
|
if (s_analog.cal_a == 0.0f || s_analog.cal_b == 0.0f) {
|
||||||
|
PRINTF("ADC invalid calib, reset\r\n");
|
||||||
|
s_analog.cal_a = 1.0f;
|
||||||
|
s_analog.cal_b = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set and persist calibration constants
|
||||||
|
void app_temp_set_calib(float a, float b) {
|
||||||
|
s_analog.cal_a = a;
|
||||||
|
s_analog.cal_b = b;
|
||||||
|
correct_invalid_calib();
|
||||||
|
|
||||||
|
EE_Status st = EE_WriteVariable32bits(EE_ADDR_CAL_A, ((x32_t) { .f = a }).u);
|
||||||
|
if (st == EE_CLEANUP_REQUIRED) {
|
||||||
|
EE_CleanUp();
|
||||||
|
} else if (st != EE_OK) {
|
||||||
|
PRINTF("EE write err %d!\r\n", st);
|
||||||
|
}
|
||||||
|
st = EE_WriteVariable32bits(EE_ADDR_CAL_B, ((x32_t) { .f = b }).u);
|
||||||
|
if (st == EE_CLEANUP_REQUIRED) {
|
||||||
|
EE_CleanUp();
|
||||||
|
} else if (st != EE_OK) {
|
||||||
|
PRINTF("EE write err %d!\r\n", st);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void app_analog_init()
|
void app_analog_init()
|
||||||
{
|
{
|
||||||
|
// read calibration constants
|
||||||
|
uint32_t c = 0;
|
||||||
|
if (EE_OK == EE_ReadVariable32bits(EE_ADDR_CAL_A, &c)) {
|
||||||
|
s_analog.cal_a = ((x32_t) { .u = c }).f;
|
||||||
|
PRINTF("ADC calib a read from EE: %f\r\n", s_analog.cal_a);
|
||||||
|
}
|
||||||
|
if (EE_OK == EE_ReadVariable32bits(EE_ADDR_CAL_B, &c)) {
|
||||||
|
s_analog.cal_b = ((x32_t) { .u = c }).f;
|
||||||
|
PRINTF("ADC calib b read from EE: %f\r\n", s_analog.cal_b);
|
||||||
|
}
|
||||||
|
|
||||||
|
correct_invalid_calib();
|
||||||
|
|
||||||
LL_ADC_Enable(ADC_TEMP);
|
LL_ADC_Enable(ADC_TEMP);
|
||||||
|
|
||||||
LL_ADC_StartCalibration(ADC_TEMP);
|
LL_ADC_StartCalibration(ADC_TEMP);
|
||||||
@@ -152,13 +205,19 @@ void app_analog_init()
|
|||||||
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, 4);
|
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, 4);
|
||||||
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
|
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
|
||||||
|
|
||||||
LL_ADC_EnableIT_EOS(ADC_TEMP);
|
LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1);
|
||||||
|
|
||||||
LL_ADC_REG_StartConversionExtTrig(ADC_TEMP, LL_ADC_REG_TRIG_EXT_RISING);
|
LL_ADC_REG_StartConversionExtTrig(ADC_TEMP, LL_ADC_REG_TRIG_EXT_RISING);
|
||||||
LL_ADC_REG_StartConversionSWStart(ADC_TEMP);
|
// LL_ADC_REG_StartConversionSWStart(ADC_TEMP);
|
||||||
|
|
||||||
|
// this timer runs with 1 kHz clock
|
||||||
|
LL_TIM_SetTriggerOutput(TIM1, LL_TIM_TRGO_CC1IF);
|
||||||
|
LL_TIM_CC_EnableChannel(TIM1, LL_TIM_CHANNEL_CH1);
|
||||||
|
LL_TIM_EnableAllOutputs(TIM1); // TIM1 needs outputs specially enabled - it's "advanced timer"
|
||||||
|
LL_TIM_EnableCounter(TIM1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static float val_to_c(float val)
|
float val_to_c(float val)
|
||||||
{
|
{
|
||||||
// TODO use binary search.. lol
|
// TODO use binary search.. lol
|
||||||
for (int i = 1; i < TSENSE_LOOKUP_LEN; i++) {
|
for (int i = 1; i < TSENSE_LOOKUP_LEN; i++) {
|
||||||
@@ -173,6 +232,22 @@ static float val_to_c(float val)
|
|||||||
return TSENSE_T_MAX;
|
return TSENSE_T_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float c_to_val(float cf)
|
||||||
|
{
|
||||||
|
int lower = (int) (cf / TSENSE_T_STEP);
|
||||||
|
|
||||||
|
if (lower < 0) {
|
||||||
|
lower = 0;
|
||||||
|
}
|
||||||
|
if (lower >= TSENSE_LOOKUP_LEN - 1) {
|
||||||
|
lower = TSENSE_LOOKUP_LEN - 2;
|
||||||
|
}
|
||||||
|
int upper = lower + 1;
|
||||||
|
|
||||||
|
float ratio = (cf - ((float)lower * TSENSE_T_STEP)) / 5.0f;
|
||||||
|
return TSENSE_LOOKUP[lower] + (TSENSE_LOOKUP[upper] - TSENSE_LOOKUP[lower]) * ratio;
|
||||||
|
}
|
||||||
|
|
||||||
void app_temp_sample()
|
void app_temp_sample()
|
||||||
{
|
{
|
||||||
uint32_t sums[4] = {};
|
uint32_t sums[4] = {};
|
||||||
@@ -190,28 +265,38 @@ void app_temp_sample()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
s_analog.adc_averages[0] = (float) sums[0] / count;
|
float adc_averages[4];
|
||||||
s_analog.adc_averages[1] = (float) sums[1] / count;
|
|
||||||
s_analog.adc_averages[2] = (float) sums[2] / count;
|
adc_averages[0] = (float) sums[0] / count;
|
||||||
s_analog.adc_averages[3] = (float) sums[3] / count;
|
adc_averages[1] = (float) sums[1] / count;
|
||||||
|
adc_averages[2] = (float) sums[2] / count;
|
||||||
|
adc_averages[3] = (float) sums[3] / count;
|
||||||
|
|
||||||
|
// PRINTF("%f\t%f\t%f\t%f\r\n",
|
||||||
|
// adc_averages[0],
|
||||||
|
// adc_averages[1],
|
||||||
|
// adc_averages[2],
|
||||||
|
// adc_averages[3]
|
||||||
|
// );
|
||||||
|
|
||||||
/* r_pt100, r_ref, internal_temp, v_ref_int */
|
/* r_pt100, r_ref, internal_temp, v_ref_int */
|
||||||
float refint = s_analog.adc_averages[3];
|
float refint = adc_averages[3];
|
||||||
float scale = V_REFINT / refint;
|
float scale = V_REFINT / refint;
|
||||||
|
|
||||||
const float avg_slope = 4.3f * scale;
|
const float avg_slope = 4.3f * scale;
|
||||||
const float v25 = 1.43f;
|
const float v25 = 1.43f;
|
||||||
const float v_tsen = s_analog.adc_averages[2] * scale;
|
const float v_tsen = adc_averages[2] * scale;
|
||||||
|
|
||||||
s_analog.soc_temp = (v25 - v_tsen) / avg_slope + 25.f;
|
s_analog.soc_temp = (v25 - v_tsen) / avg_slope + 25.f;
|
||||||
s_analog.v_sensor = s_analog.adc_averages[0] * scale; // good for debug/tuning
|
//s_analog.v_sensor = adc_averages[0] * scale; // good for debug/tuning
|
||||||
|
|
||||||
|
|
||||||
// using a voltage divider, so assuming the reference resistor is measured well,
|
// using a voltage divider, so assuming the reference resistor is measured well,
|
||||||
// we can just use the ratio and the exact voltage value is not important.
|
// we can just use the ratio and the exact voltage value is not important.
|
||||||
float actual_temp = val_to_c(s_analog.adc_averages[0] / s_analog.adc_averages[1]);
|
|
||||||
|
|
||||||
s_analog.oventemp_history[s_analog.oventemp_history_ptr] = actual_temp;
|
float oventemp_sample = adc_averages[0] / adc_averages[1];
|
||||||
|
|
||||||
|
s_analog.oventemp_history[s_analog.oventemp_history_ptr] = oventemp_sample;
|
||||||
s_analog.oventemp_history_ptr = (s_analog.oventemp_history_ptr + 1) % OVENTEMP_HISTORY_DEPTH;
|
s_analog.oventemp_history_ptr = (s_analog.oventemp_history_ptr + 1) % OVENTEMP_HISTORY_DEPTH;
|
||||||
|
|
||||||
float sum = 0;
|
float sum = 0;
|
||||||
@@ -225,7 +310,23 @@ void app_temp_sample()
|
|||||||
if (depth > 0) {
|
if (depth > 0) {
|
||||||
sum /= depth;
|
sum /= depth;
|
||||||
}
|
}
|
||||||
s_analog.oven_temp = sum;
|
|
||||||
|
float y = s_analog.cal_a * sum + s_analog.cal_b;
|
||||||
|
float actual_temp = val_to_c(y);
|
||||||
|
PRINTF("T raw %f %f -> comp %f, temp %f°C\r\n", sum, y, actual_temp);
|
||||||
|
|
||||||
|
s_analog.oven_temp = actual_temp;
|
||||||
|
s_analog.oven_temp_raw = sum;
|
||||||
|
|
||||||
|
app_safety_pass_temp_calculation();
|
||||||
|
|
||||||
|
if (s_analog.oven_temp_raw >= 0.05 && s_analog.oven_temp_raw <= 0.22) {
|
||||||
|
app_safety_pass_temp_normal();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s_analog.soc_temp >= 2.0 && s_analog.soc_temp <= 80.0) {
|
||||||
|
app_safety_pass_soc_temp_ok();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float app_temp_read_oven()
|
float app_temp_read_oven()
|
||||||
@@ -233,6 +334,11 @@ float app_temp_read_oven()
|
|||||||
return s_analog.oven_temp;
|
return s_analog.oven_temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float app_temp_read_oven_raw()
|
||||||
|
{
|
||||||
|
return s_analog.oven_temp_raw;
|
||||||
|
}
|
||||||
|
|
||||||
float app_temp_read_soc()
|
float app_temp_read_soc()
|
||||||
{
|
{
|
||||||
return s_analog.soc_temp;
|
return s_analog.soc_temp;
|
||||||
@@ -240,6 +346,8 @@ float app_temp_read_soc()
|
|||||||
|
|
||||||
void app_temp_adc_eos()
|
void app_temp_adc_eos()
|
||||||
{
|
{
|
||||||
|
app_safety_pass_adc_sampling();
|
||||||
|
|
||||||
// notify
|
// notify
|
||||||
memcpy((void *) &s_analog.adc_averagebuf[s_analog.averagebuf_ptr * 4], (const void *) adc_values, 4 * sizeof(uint16_t));
|
memcpy((void *) &s_analog.adc_averagebuf[s_analog.averagebuf_ptr * 4], (const void *) adc_values, 4 * sizeof(uint16_t));
|
||||||
s_analog.averagebuf_ptr = (s_analog.averagebuf_ptr + 1) % AVERAGEBUF_DEPTH;
|
s_analog.averagebuf_ptr = (s_analog.averagebuf_ptr + 1) % AVERAGEBUF_DEPTH;
|
||||||
@@ -247,5 +355,5 @@ void app_temp_adc_eos()
|
|||||||
|
|
||||||
void app_temp_show_buf()
|
void app_temp_show_buf()
|
||||||
{
|
{
|
||||||
printf("%d,%d,%d,%d\r\n", adc_values[0], adc_values[1], adc_values[2], adc_values[3]);
|
PRINTF("%d,%d,%d,%d\r\n", adc_values[0], adc_values[1], adc_values[2], adc_values[3]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,11 @@
|
|||||||
|
|
||||||
void app_analog_init();
|
void app_analog_init();
|
||||||
|
|
||||||
|
float val_to_c(float val);
|
||||||
|
float c_to_val(float c);
|
||||||
|
|
||||||
|
void app_temp_set_calib(float a, float b);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update temperature measurement.
|
* Update temperature measurement.
|
||||||
*
|
*
|
||||||
@@ -20,6 +25,9 @@ void app_temp_sample();
|
|||||||
/// The value is valid after calling app_temp_sample()
|
/// The value is valid after calling app_temp_sample()
|
||||||
float app_temp_read_oven();
|
float app_temp_read_oven();
|
||||||
|
|
||||||
|
/// Get the raw ADC value (divider voltage)
|
||||||
|
float app_temp_read_oven_raw();
|
||||||
|
|
||||||
/// Read current SOC temperature (celsius)
|
/// Read current SOC temperature (celsius)
|
||||||
/// The value is valid after calling app_temp_sample()
|
/// The value is valid after calling app_temp_sample()
|
||||||
float app_temp_read_soc();
|
float app_temp_read_soc();
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/* USER CODE BEGIN Header */
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file crc.c
|
||||||
|
* @brief This file provides code for the configuration
|
||||||
|
* of the CRC instances.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* Copyright (c) 2023 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 "crc.h"
|
||||||
|
|
||||||
|
/* USER CODE BEGIN 0 */
|
||||||
|
|
||||||
|
/* USER CODE END 0 */
|
||||||
|
|
||||||
|
/* CRC init function */
|
||||||
|
void MX_CRC_Init(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* USER CODE BEGIN CRC_Init 0 */
|
||||||
|
|
||||||
|
/* USER CODE END CRC_Init 0 */
|
||||||
|
|
||||||
|
/* Peripheral clock enable */
|
||||||
|
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_CRC);
|
||||||
|
|
||||||
|
/* USER CODE BEGIN CRC_Init 1 */
|
||||||
|
|
||||||
|
/* USER CODE END CRC_Init 1 */
|
||||||
|
/* USER CODE BEGIN CRC_Init 2 */
|
||||||
|
|
||||||
|
/* USER CODE END CRC_Init 2 */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* USER CODE BEGIN 1 */
|
||||||
|
|
||||||
|
/* USER CODE END 1 */
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
//
|
||||||
|
// Created by MightyPork on 2023/04/09.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef TOASTER_OVEN_BLUEPILL_EE_ADDRESSES_H
|
||||||
|
#define TOASTER_OVEN_BLUEPILL_EE_ADDRESSES_H
|
||||||
|
|
||||||
|
enum EEAddresses {
|
||||||
|
EE_ADDR_CAL_A = 1,
|
||||||
|
EE_ADDR_CAL_B = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //TOASTER_OVEN_BLUEPILL_EE_ADDRESSES_H
|
||||||
+29
-6
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
/* Private includes ----------------------------------------------------------*/
|
/* Private includes ----------------------------------------------------------*/
|
||||||
/* USER CODE BEGIN Includes */
|
/* USER CODE BEGIN Includes */
|
||||||
#include <stdio.h>
|
#include "snprintf.h"
|
||||||
|
|
||||||
/* USER CODE END Includes */
|
/* USER CODE END Includes */
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ const osThreadAttr_t guiTsk_attributes = {
|
|||||||
};
|
};
|
||||||
/* Definitions for guiEventQue */
|
/* Definitions for guiEventQue */
|
||||||
osMessageQueueId_t guiEventQueHandle;
|
osMessageQueueId_t guiEventQueHandle;
|
||||||
uint8_t guiEventQueBuffer[ 16 * 8 ];
|
uint8_t guiEventQueBuffer[ 32 * 1 ];
|
||||||
osStaticMessageQDef_t guiEventQueControlBlock;
|
osStaticMessageQDef_t guiEventQueControlBlock;
|
||||||
const osMessageQueueAttr_t guiEventQue_attributes = {
|
const osMessageQueueAttr_t guiEventQue_attributes = {
|
||||||
.name = "guiEventQue",
|
.name = "guiEventQue",
|
||||||
@@ -107,6 +107,22 @@ const osTimerAttr_t beepTimer_attributes = {
|
|||||||
.cb_mem = &beepTimerControlBlock,
|
.cb_mem = &beepTimerControlBlock,
|
||||||
.cb_size = sizeof(beepTimerControlBlock),
|
.cb_size = sizeof(beepTimerControlBlock),
|
||||||
};
|
};
|
||||||
|
/* Definitions for buttonPushTimer */
|
||||||
|
osTimerId_t buttonPushTimerHandle;
|
||||||
|
osStaticTimerDef_t buttonPushTimerControlBlock;
|
||||||
|
const osTimerAttr_t buttonPushTimer_attributes = {
|
||||||
|
.name = "buttonPushTimer",
|
||||||
|
.cb_mem = &buttonPushTimerControlBlock,
|
||||||
|
.cb_size = sizeof(buttonPushTimerControlBlock),
|
||||||
|
};
|
||||||
|
/* Definitions for buttonReleaseTimer */
|
||||||
|
osTimerId_t buttonReleaseTimerHandle;
|
||||||
|
osStaticTimerDef_t buttonReleaseTimerControlBlock;
|
||||||
|
const osTimerAttr_t buttonReleaseTimer_attributes = {
|
||||||
|
.name = "buttonReleaseTimer",
|
||||||
|
.cb_mem = &buttonReleaseTimerControlBlock,
|
||||||
|
.cb_size = sizeof(buttonReleaseTimerControlBlock),
|
||||||
|
};
|
||||||
/* Definitions for heaterMutex */
|
/* Definitions for heaterMutex */
|
||||||
osMutexId_t heaterMutexHandle;
|
osMutexId_t heaterMutexHandle;
|
||||||
osStaticMutexDef_t heaterMutexControlBlock;
|
osStaticMutexDef_t heaterMutexControlBlock;
|
||||||
@@ -125,6 +141,7 @@ void app_task_main(void *argument);
|
|||||||
extern void app_task_heater(void *argument);
|
extern void app_task_heater(void *argument);
|
||||||
extern void app_task_gui(void *argument);
|
extern void app_task_gui(void *argument);
|
||||||
extern void app_beep_end(void *argument);
|
extern void app_beep_end(void *argument);
|
||||||
|
extern void app_push_debounce(void *argument);
|
||||||
|
|
||||||
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */
|
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */
|
||||||
|
|
||||||
@@ -135,7 +152,7 @@ void vApplicationMallocFailedHook(void);
|
|||||||
/* USER CODE BEGIN 4 */
|
/* USER CODE BEGIN 4 */
|
||||||
void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char *pcTaskName)
|
void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char *pcTaskName)
|
||||||
{
|
{
|
||||||
printf("vApplicationStackOverflowHook: %s\r\n", pcTaskName);
|
PRINTF("vApplicationStackOverflowHook: %s\r\n", pcTaskName);
|
||||||
/* Run time stack overflow checking is performed if
|
/* Run time stack overflow checking is performed if
|
||||||
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook function is
|
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook function is
|
||||||
called if a stack overflow is detected. */
|
called if a stack overflow is detected. */
|
||||||
@@ -145,7 +162,7 @@ void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char *pcTaskName)
|
|||||||
/* USER CODE BEGIN 5 */
|
/* USER CODE BEGIN 5 */
|
||||||
void vApplicationMallocFailedHook(void)
|
void vApplicationMallocFailedHook(void)
|
||||||
{
|
{
|
||||||
printf("vApplicationMallocFailedHook\r\n");
|
PUTS("vApplicationMallocFailedHook\r\n");
|
||||||
/* vApplicationMallocFailedHook() will only be called if
|
/* vApplicationMallocFailedHook() will only be called if
|
||||||
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
|
configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
|
||||||
function that will get called if a call to pvPortMalloc() fails.
|
function that will get called if a call to pvPortMalloc() fails.
|
||||||
@@ -184,13 +201,19 @@ void MX_FREERTOS_Init(void) {
|
|||||||
/* creation of beepTimer */
|
/* creation of beepTimer */
|
||||||
beepTimerHandle = osTimerNew(app_beep_end, osTimerOnce, NULL, &beepTimer_attributes);
|
beepTimerHandle = osTimerNew(app_beep_end, osTimerOnce, NULL, &beepTimer_attributes);
|
||||||
|
|
||||||
|
/* creation of buttonPushTimer */
|
||||||
|
buttonPushTimerHandle = osTimerNew(app_push_debounce, osTimerOnce, (void*) 1, &buttonPushTimer_attributes);
|
||||||
|
|
||||||
|
/* creation of buttonReleaseTimer */
|
||||||
|
buttonReleaseTimerHandle = osTimerNew(app_push_debounce, osTimerOnce, (void*) 0, &buttonReleaseTimer_attributes);
|
||||||
|
|
||||||
/* USER CODE BEGIN RTOS_TIMERS */
|
/* USER CODE BEGIN RTOS_TIMERS */
|
||||||
/* start timers, add new ones, ... */
|
/* start timers, add new ones, ... */
|
||||||
/* USER CODE END RTOS_TIMERS */
|
/* USER CODE END RTOS_TIMERS */
|
||||||
|
|
||||||
/* Create the queue(s) */
|
/* Create the queue(s) */
|
||||||
/* creation of guiEventQue */
|
/* creation of guiEventQue */
|
||||||
guiEventQueHandle = osMessageQueueNew (16, 8, &guiEventQue_attributes);
|
guiEventQueHandle = osMessageQueueNew (32, 1, &guiEventQue_attributes);
|
||||||
|
|
||||||
/* USER CODE BEGIN RTOS_QUEUES */
|
/* USER CODE BEGIN RTOS_QUEUES */
|
||||||
/* add queues, ... */
|
/* add queues, ... */
|
||||||
@@ -223,7 +246,7 @@ void MX_FREERTOS_Init(void) {
|
|||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
/* USER CODE END Header_app_task_main */
|
/* USER CODE END Header_app_task_main */
|
||||||
__attribute__((weak)) void app_task_main(void *argument)
|
__weak void app_task_main(void *argument)
|
||||||
{
|
{
|
||||||
/* USER CODE BEGIN app_task_main */
|
/* USER CODE BEGIN app_task_main */
|
||||||
/* Infinite loop */
|
/* Infinite loop */
|
||||||
|
|||||||
+20
-4
@@ -44,6 +44,7 @@
|
|||||||
void MX_GPIO_Init(void)
|
void MX_GPIO_Init(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
LL_EXTI_InitTypeDef EXTI_InitStruct = {0};
|
||||||
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
|
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||||
|
|
||||||
/* GPIO Ports Clock Enable */
|
/* GPIO Ports Clock Enable */
|
||||||
@@ -98,12 +99,27 @@ void MX_GPIO_Init(void)
|
|||||||
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
GPIO_InitStruct.Pin = KNOB_PUSH_Pin;
|
LL_GPIO_AF_EnableRemap_PD01();
|
||||||
GPIO_InitStruct.Mode = LL_GPIO_MODE_FLOATING;
|
|
||||||
LL_GPIO_Init(KNOB_PUSH_GPIO_Port, &GPIO_InitStruct);
|
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
LL_GPIO_AF_EnableRemap_PD01();
|
LL_GPIO_AF_SetEXTISource(LL_GPIO_AF_EXTI_PORTB, LL_GPIO_AF_EXTI_LINE8);
|
||||||
|
|
||||||
|
/**/
|
||||||
|
EXTI_InitStruct.Line_0_31 = LL_EXTI_LINE_8;
|
||||||
|
EXTI_InitStruct.LineCommand = ENABLE;
|
||||||
|
EXTI_InitStruct.Mode = LL_EXTI_MODE_IT;
|
||||||
|
EXTI_InitStruct.Trigger = LL_EXTI_TRIGGER_RISING_FALLING;
|
||||||
|
LL_EXTI_Init(&EXTI_InitStruct);
|
||||||
|
|
||||||
|
/**/
|
||||||
|
LL_GPIO_SetPinPull(KNOB_PUSH_GPIO_Port, KNOB_PUSH_Pin, LL_GPIO_PULL_UP);
|
||||||
|
|
||||||
|
/**/
|
||||||
|
LL_GPIO_SetPinMode(KNOB_PUSH_GPIO_Port, KNOB_PUSH_Pin, LL_GPIO_MODE_INPUT);
|
||||||
|
|
||||||
|
/* EXTI interrupt init*/
|
||||||
|
NVIC_SetPriority(EXTI9_5_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0));
|
||||||
|
NVIC_EnableIRQ(EXTI9_5_IRQn);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+94
-93
@@ -20,6 +20,7 @@
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "cmsis_os.h"
|
#include "cmsis_os.h"
|
||||||
#include "adc.h"
|
#include "adc.h"
|
||||||
|
#include "crc.h"
|
||||||
#include "dma.h"
|
#include "dma.h"
|
||||||
#include "iwdg.h"
|
#include "iwdg.h"
|
||||||
#include "spi.h"
|
#include "spi.h"
|
||||||
@@ -58,6 +59,7 @@
|
|||||||
|
|
||||||
/* Private function prototypes -----------------------------------------------*/
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
void SystemClock_Config(void);
|
void SystemClock_Config(void);
|
||||||
|
|
||||||
void MX_FREERTOS_Init(void);
|
void MX_FREERTOS_Init(void);
|
||||||
/* USER CODE BEGIN PFP */
|
/* USER CODE BEGIN PFP */
|
||||||
|
|
||||||
@@ -74,72 +76,74 @@ void MX_FREERTOS_Init(void);
|
|||||||
*/
|
*/
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
/* USER CODE BEGIN 1 */
|
/* USER CODE BEGIN 1 */
|
||||||
|
|
||||||
/* USER CODE END 1 */
|
/* USER CODE END 1 */
|
||||||
|
|
||||||
/* MCU Configuration--------------------------------------------------------*/
|
/* MCU Configuration--------------------------------------------------------*/
|
||||||
|
|
||||||
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
|
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
|
||||||
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_AFIO);
|
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_AFIO);
|
||||||
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
|
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
|
||||||
|
|
||||||
/* System interrupt init*/
|
/* System interrupt init*/
|
||||||
NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
|
NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
|
||||||
|
|
||||||
/* PendSV_IRQn interrupt configuration */
|
/* PendSV_IRQn interrupt configuration */
|
||||||
NVIC_SetPriority(PendSV_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),15, 0));
|
NVIC_SetPriority(PendSV_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0));
|
||||||
/* SysTick_IRQn interrupt configuration */
|
/* SysTick_IRQn interrupt configuration */
|
||||||
NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),15, 0));
|
NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0));
|
||||||
|
|
||||||
/** NOJTAG: JTAG-DP Disabled and SW-DP Enabled
|
/** NOJTAG: JTAG-DP Disabled and SW-DP Enabled
|
||||||
*/
|
*/
|
||||||
LL_GPIO_AF_Remap_SWJ_NOJTAG();
|
LL_GPIO_AF_Remap_SWJ_NOJTAG();
|
||||||
|
|
||||||
/* USER CODE BEGIN Init */
|
/* USER CODE BEGIN Init */
|
||||||
|
|
||||||
/* USER CODE END Init */
|
/* USER CODE END Init */
|
||||||
|
|
||||||
/* Configure the system clock */
|
/* Configure the system clock */
|
||||||
SystemClock_Config();
|
SystemClock_Config();
|
||||||
|
|
||||||
/* USER CODE BEGIN SysInit */
|
/* USER CODE BEGIN SysInit */
|
||||||
|
|
||||||
MX_DMA_Init();
|
MX_DMA_Init();
|
||||||
/* USER CODE END SysInit */
|
/* USER CODE END SysInit */
|
||||||
|
|
||||||
/* Initialize all configured peripherals */
|
/* Initialize all configured peripherals */
|
||||||
MX_GPIO_Init();
|
MX_GPIO_Init();
|
||||||
MX_IWDG_Init();
|
MX_IWDG_Init();
|
||||||
MX_USART1_UART_Init();
|
MX_USART1_UART_Init();
|
||||||
MX_ADC1_Init();
|
MX_ADC1_Init();
|
||||||
MX_DMA_Init();
|
MX_DMA_Init();
|
||||||
MX_TIM4_Init();
|
MX_TIM4_Init();
|
||||||
MX_TIM2_Init();
|
MX_TIM2_Init();
|
||||||
MX_TIM3_Init();
|
MX_TIM3_Init();
|
||||||
MX_SPI2_Init();
|
MX_SPI2_Init();
|
||||||
/* USER CODE BEGIN 2 */
|
MX_TIM1_Init();
|
||||||
|
MX_CRC_Init();
|
||||||
|
/* USER CODE BEGIN 2 */
|
||||||
|
|
||||||
printf("Start.\r\n");
|
PUTS("Start.\r\n");
|
||||||
/* USER CODE END 2 */
|
/* USER CODE END 2 */
|
||||||
|
|
||||||
/* Init scheduler */
|
/* Init scheduler */
|
||||||
osKernelInitialize(); /* Call init function for freertos objects (in freertos.c) */
|
osKernelInitialize(); /* Call init function for freertos objects (in freertos.c) */
|
||||||
MX_FREERTOS_Init();
|
MX_FREERTOS_Init();
|
||||||
|
|
||||||
/* Start scheduler */
|
/* Start scheduler */
|
||||||
osKernelStart();
|
osKernelStart();
|
||||||
|
|
||||||
/* We should never get here as control is now taken by the scheduler */
|
/* We should never get here as control is now taken by the scheduler */
|
||||||
/* Infinite loop */
|
/* Infinite loop */
|
||||||
/* USER CODE BEGIN WHILE */
|
/* USER CODE BEGIN WHILE */
|
||||||
while (1)
|
app_emergency_stop();
|
||||||
{
|
while (1) {
|
||||||
/* USER CODE END WHILE */
|
/* USER CODE END WHILE */
|
||||||
|
|
||||||
/* USER CODE BEGIN 3 */
|
/* USER CODE BEGIN 3 */
|
||||||
}
|
}
|
||||||
/* USER CODE END 3 */
|
/* USER CODE END 3 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -148,46 +152,41 @@ int main(void)
|
|||||||
*/
|
*/
|
||||||
void SystemClock_Config(void)
|
void SystemClock_Config(void)
|
||||||
{
|
{
|
||||||
LL_FLASH_SetLatency(LL_FLASH_LATENCY_2);
|
LL_FLASH_SetLatency(LL_FLASH_LATENCY_2);
|
||||||
while(LL_FLASH_GetLatency()!= LL_FLASH_LATENCY_2)
|
while (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_2) {
|
||||||
{
|
}
|
||||||
}
|
LL_RCC_HSI_SetCalibTrimming(16);
|
||||||
LL_RCC_HSI_SetCalibTrimming(16);
|
LL_RCC_HSI_Enable();
|
||||||
LL_RCC_HSI_Enable();
|
|
||||||
|
|
||||||
/* Wait till HSI is ready */
|
/* Wait till HSI is ready */
|
||||||
while(LL_RCC_HSI_IsReady() != 1)
|
while (LL_RCC_HSI_IsReady() != 1) {
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
LL_RCC_LSI_Enable();
|
LL_RCC_LSI_Enable();
|
||||||
|
|
||||||
/* Wait till LSI is ready */
|
/* Wait till LSI is ready */
|
||||||
while(LL_RCC_LSI_IsReady() != 1)
|
while (LL_RCC_LSI_IsReady() != 1) {
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI_DIV_2, LL_RCC_PLL_MUL_16);
|
LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI_DIV_2, LL_RCC_PLL_MUL_16);
|
||||||
LL_RCC_PLL_Enable();
|
LL_RCC_PLL_Enable();
|
||||||
|
|
||||||
/* Wait till PLL is ready */
|
/* Wait till PLL is ready */
|
||||||
while(LL_RCC_PLL_IsReady() != 1)
|
while (LL_RCC_PLL_IsReady() != 1) {
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
|
LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
|
||||||
LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_2);
|
LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_2);
|
||||||
LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
|
LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
|
||||||
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
|
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
|
||||||
|
|
||||||
/* Wait till System clock is ready */
|
/* Wait till System clock is ready */
|
||||||
while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
|
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) {
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
LL_Init1msTick(64000000);
|
LL_Init1msTick(64000000);
|
||||||
LL_SetSystemCoreClock(64000000);
|
LL_SetSystemCoreClock(64000000);
|
||||||
LL_RCC_SetADCClockSource(LL_RCC_ADC_CLKSRC_PCLK2_DIV_8);
|
LL_RCC_SetADCClockSource(LL_RCC_ADC_CLKSRC_PCLK2_DIV_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* USER CODE BEGIN 4 */
|
/* USER CODE BEGIN 4 */
|
||||||
@@ -200,17 +199,16 @@ void SystemClock_Config(void)
|
|||||||
*/
|
*/
|
||||||
void Error_Handler(void)
|
void Error_Handler(void)
|
||||||
{
|
{
|
||||||
/* USER CODE BEGIN Error_Handler_Debug */
|
/* USER CODE BEGIN Error_Handler_Debug */
|
||||||
/* User can add his own implementation to report the HAL error return state */
|
/* User can add his own implementation to report the HAL error return state */
|
||||||
__disable_irq();
|
__disable_irq();
|
||||||
printf("Error_Handler\r\n");
|
PUTS("Error_Handler\r\n");
|
||||||
while (1)
|
app_emergency_stop();
|
||||||
{
|
/* USER CODE END Error_Handler_Debug */
|
||||||
}
|
|
||||||
/* USER CODE END Error_Handler_Debug */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_FULL_ASSERT
|
#ifdef USE_FULL_ASSERT
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reports the name of the source file and the source line number
|
* @brief Reports the name of the source file and the source line number
|
||||||
* where the assert_param error has occurred.
|
* where the assert_param error has occurred.
|
||||||
@@ -220,9 +218,12 @@ void Error_Handler(void)
|
|||||||
*/
|
*/
|
||||||
void assert_failed(uint8_t *file, uint32_t line)
|
void assert_failed(uint8_t *file, uint32_t line)
|
||||||
{
|
{
|
||||||
/* USER CODE BEGIN 6 */
|
/* USER CODE BEGIN 6 */
|
||||||
/* User can add his own implementation to report the file name and line number,
|
PRINTF("assert_failed %s:%d", (const char *) file, (int) line);
|
||||||
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
|
app_emergency_stop();
|
||||||
/* USER CODE END 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 */
|
#endif /* USE_FULL_ASSERT */
|
||||||
|
|||||||
+93
-74
@@ -24,8 +24,8 @@
|
|||||||
#include "task.h"
|
#include "task.h"
|
||||||
/* Private includes ----------------------------------------------------------*/
|
/* Private includes ----------------------------------------------------------*/
|
||||||
/* USER CODE BEGIN Includes */
|
/* USER CODE BEGIN Includes */
|
||||||
#include <stdio.h>
|
|
||||||
#include "app_temp.h"
|
#include "app_temp.h"
|
||||||
|
#include "app_knob.h"
|
||||||
/* USER CODE END Includes */
|
/* USER CODE END Includes */
|
||||||
|
|
||||||
/* Private typedef -----------------------------------------------------------*/
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
@@ -62,6 +62,8 @@
|
|||||||
|
|
||||||
/* USER CODE BEGIN EV */
|
/* USER CODE BEGIN EV */
|
||||||
|
|
||||||
|
bool EE_NMI_Callback();
|
||||||
|
|
||||||
/* USER CODE END EV */
|
/* USER CODE END EV */
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@@ -72,14 +74,19 @@
|
|||||||
*/
|
*/
|
||||||
void NMI_Handler(void)
|
void NMI_Handler(void)
|
||||||
{
|
{
|
||||||
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
|
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
|
||||||
|
|
||||||
/* USER CODE END NonMaskableInt_IRQn 0 */
|
if (EE_NMI_Callback()) {
|
||||||
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */
|
return;
|
||||||
while (1)
|
}
|
||||||
{
|
|
||||||
}
|
app_emergency_stop();
|
||||||
/* USER CODE END NonMaskableInt_IRQn 1 */
|
|
||||||
|
/* USER CODE END NonMaskableInt_IRQn 0 */
|
||||||
|
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */
|
||||||
|
while (1) {
|
||||||
|
}
|
||||||
|
/* USER CODE END NonMaskableInt_IRQn 1 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -87,15 +94,15 @@ void NMI_Handler(void)
|
|||||||
*/
|
*/
|
||||||
void HardFault_Handler(void)
|
void HardFault_Handler(void)
|
||||||
{
|
{
|
||||||
/* USER CODE BEGIN HardFault_IRQn 0 */
|
/* USER CODE BEGIN HardFault_IRQn 0 */
|
||||||
printf("HardFault_Handler\r\n");
|
PUTS("HardFault_Handler\r\n");
|
||||||
|
app_emergency_stop();
|
||||||
|
|
||||||
/* USER CODE END HardFault_IRQn 0 */
|
/* USER CODE END HardFault_IRQn 0 */
|
||||||
while (1)
|
while (1) {
|
||||||
{
|
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
|
||||||
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
|
/* USER CODE END W1_HardFault_IRQn 0 */
|
||||||
/* USER CODE END W1_HardFault_IRQn 0 */
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -103,15 +110,15 @@ void HardFault_Handler(void)
|
|||||||
*/
|
*/
|
||||||
void MemManage_Handler(void)
|
void MemManage_Handler(void)
|
||||||
{
|
{
|
||||||
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
|
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
|
||||||
printf("MemManage_Handler\r\n");
|
PUTS("MemManage_Handler\r\n");
|
||||||
|
app_emergency_stop();
|
||||||
|
|
||||||
/* USER CODE END MemoryManagement_IRQn 0 */
|
/* USER CODE END MemoryManagement_IRQn 0 */
|
||||||
while (1)
|
while (1) {
|
||||||
{
|
/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
|
||||||
/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
|
/* USER CODE END W1_MemoryManagement_IRQn 0 */
|
||||||
/* USER CODE END W1_MemoryManagement_IRQn 0 */
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -119,15 +126,15 @@ void MemManage_Handler(void)
|
|||||||
*/
|
*/
|
||||||
void BusFault_Handler(void)
|
void BusFault_Handler(void)
|
||||||
{
|
{
|
||||||
/* USER CODE BEGIN BusFault_IRQn 0 */
|
/* USER CODE BEGIN BusFault_IRQn 0 */
|
||||||
printf("BusFault_Handler\r\n");
|
PUTS("BusFault_Handler\r\n");
|
||||||
|
app_emergency_stop();
|
||||||
|
/* USER CODE END BusFault_IRQn 0 */
|
||||||
|
|
||||||
/* USER CODE END BusFault_IRQn 0 */
|
while (1) {
|
||||||
while (1)
|
/* USER CODE BEGIN W1_BusFault_IRQn 0 */
|
||||||
{
|
/* USER CODE END W1_BusFault_IRQn 0 */
|
||||||
/* USER CODE BEGIN W1_BusFault_IRQn 0 */
|
}
|
||||||
/* USER CODE END W1_BusFault_IRQn 0 */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -135,15 +142,15 @@ void BusFault_Handler(void)
|
|||||||
*/
|
*/
|
||||||
void UsageFault_Handler(void)
|
void UsageFault_Handler(void)
|
||||||
{
|
{
|
||||||
/* USER CODE BEGIN UsageFault_IRQn 0 */
|
/* USER CODE BEGIN UsageFault_IRQn 0 */
|
||||||
printf("UsageFault_Handler\r\n");
|
PUTS("UsageFault_Handler\r\n");
|
||||||
|
app_emergency_stop();
|
||||||
|
/* USER CODE END UsageFault_IRQn 0 */
|
||||||
|
|
||||||
/* USER CODE END UsageFault_IRQn 0 */
|
while (1) {
|
||||||
while (1)
|
/* USER CODE BEGIN W1_UsageFault_IRQn 0 */
|
||||||
{
|
/* USER CODE END W1_UsageFault_IRQn 0 */
|
||||||
/* USER CODE BEGIN W1_UsageFault_IRQn 0 */
|
}
|
||||||
/* USER CODE END W1_UsageFault_IRQn 0 */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -151,12 +158,12 @@ void UsageFault_Handler(void)
|
|||||||
*/
|
*/
|
||||||
void DebugMon_Handler(void)
|
void DebugMon_Handler(void)
|
||||||
{
|
{
|
||||||
/* USER CODE BEGIN DebugMonitor_IRQn 0 */
|
/* USER CODE BEGIN DebugMonitor_IRQn 0 */
|
||||||
|
|
||||||
/* USER CODE END DebugMonitor_IRQn 0 */
|
/* USER CODE END DebugMonitor_IRQn 0 */
|
||||||
/* USER CODE BEGIN DebugMonitor_IRQn 1 */
|
/* USER CODE BEGIN DebugMonitor_IRQn 1 */
|
||||||
|
|
||||||
/* USER CODE END DebugMonitor_IRQn 1 */
|
/* USER CODE END DebugMonitor_IRQn 1 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -164,20 +171,19 @@ void DebugMon_Handler(void)
|
|||||||
*/
|
*/
|
||||||
void SysTick_Handler(void)
|
void SysTick_Handler(void)
|
||||||
{
|
{
|
||||||
/* USER CODE BEGIN SysTick_IRQn 0 */
|
/* USER CODE BEGIN SysTick_IRQn 0 */
|
||||||
|
|
||||||
/* USER CODE END SysTick_IRQn 0 */
|
/* USER CODE END SysTick_IRQn 0 */
|
||||||
#if (INCLUDE_xTaskGetSchedulerState == 1 )
|
#if (INCLUDE_xTaskGetSchedulerState == 1)
|
||||||
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
|
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||||
{
|
|
||||||
#endif /* INCLUDE_xTaskGetSchedulerState */
|
#endif /* INCLUDE_xTaskGetSchedulerState */
|
||||||
xPortSysTickHandler();
|
xPortSysTickHandler();
|
||||||
#if (INCLUDE_xTaskGetSchedulerState == 1 )
|
#if (INCLUDE_xTaskGetSchedulerState == 1)
|
||||||
}
|
}
|
||||||
#endif /* INCLUDE_xTaskGetSchedulerState */
|
#endif /* INCLUDE_xTaskGetSchedulerState */
|
||||||
/* USER CODE BEGIN SysTick_IRQn 1 */
|
/* USER CODE BEGIN SysTick_IRQn 1 */
|
||||||
|
|
||||||
/* USER CODE END SysTick_IRQn 1 */
|
/* USER CODE END SysTick_IRQn 1 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@@ -192,34 +198,40 @@ void SysTick_Handler(void)
|
|||||||
*/
|
*/
|
||||||
void DMA1_Channel1_IRQHandler(void)
|
void DMA1_Channel1_IRQHandler(void)
|
||||||
{
|
{
|
||||||
/* USER CODE BEGIN DMA1_Channel1_IRQn 0 */
|
/* USER CODE BEGIN DMA1_Channel1_IRQn 0 */
|
||||||
|
|
||||||
/* USER CODE END DMA1_Channel1_IRQn 0 */
|
if (LL_DMA_IsActiveFlag_TC1(DMA1)) {
|
||||||
|
app_temp_adc_eos();
|
||||||
|
LL_DMA_ClearFlag_TC1(DMA1);
|
||||||
|
}
|
||||||
|
|
||||||
/* USER CODE BEGIN DMA1_Channel1_IRQn 1 */
|
/* USER CODE END DMA1_Channel1_IRQn 0 */
|
||||||
|
|
||||||
/* USER CODE END DMA1_Channel1_IRQn 1 */
|
/* USER CODE BEGIN DMA1_Channel1_IRQn 1 */
|
||||||
|
|
||||||
|
/* USER CODE END DMA1_Channel1_IRQn 1 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function handles ADC1 and ADC2 global interrupts.
|
* @brief This function handles EXTI line[9:5] interrupts.
|
||||||
*/
|
*/
|
||||||
void ADC1_2_IRQHandler(void)
|
void EXTI9_5_IRQHandler(void)
|
||||||
{
|
{
|
||||||
/* USER CODE BEGIN ADC1_2_IRQn 0 */
|
/* USER CODE BEGIN EXTI9_5_IRQn 0 */
|
||||||
|
bool state = LL_GPIO_IsInputPinSet(KNOB_PUSH_GPIO_Port, KNOB_PUSH_Pin);
|
||||||
|
|
||||||
app_temp_adc_eos();
|
/* USER CODE END EXTI9_5_IRQn 0 */
|
||||||
|
if (LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_8) != RESET) {
|
||||||
|
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_8);
|
||||||
|
/* USER CODE BEGIN LL_EXTI_LINE_8 */
|
||||||
|
|
||||||
// if (LL_ADC_IsActiveFlag_EOS(ADC_TEMP)) {
|
app_knob_push_isr(0 == state);
|
||||||
// LL_ADC_ClearFlag_EOS(ADC_TEMP);
|
|
||||||
// app_temp_adc_eos();
|
|
||||||
// }
|
|
||||||
|
|
||||||
/* USER CODE END ADC1_2_IRQn 0 */
|
/* USER CODE END LL_EXTI_LINE_8 */
|
||||||
|
}
|
||||||
|
/* USER CODE BEGIN EXTI9_5_IRQn 1 */
|
||||||
|
|
||||||
/* USER CODE BEGIN ADC1_2_IRQn 1 */
|
/* USER CODE END EXTI9_5_IRQn 1 */
|
||||||
|
|
||||||
/* USER CODE END ADC1_2_IRQn 1 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -227,12 +239,19 @@ void ADC1_2_IRQHandler(void)
|
|||||||
*/
|
*/
|
||||||
void TIM4_IRQHandler(void)
|
void TIM4_IRQHandler(void)
|
||||||
{
|
{
|
||||||
/* USER CODE BEGIN TIM4_IRQn 0 */
|
/* USER CODE BEGIN TIM4_IRQn 0 */
|
||||||
|
|
||||||
/* USER CODE END TIM4_IRQn 0 */
|
if (LL_TIM_IsActiveFlag_CC1(TIM4) || LL_TIM_IsActiveFlag_CC2(TIM4)) {
|
||||||
/* USER CODE BEGIN TIM4_IRQn 1 */
|
LL_TIM_ClearFlag_CC1(TIM4);
|
||||||
|
LL_TIM_ClearFlag_CC2(TIM4);
|
||||||
|
app_knob_turn_isr();
|
||||||
|
}
|
||||||
|
|
||||||
/* USER CODE END TIM4_IRQn 1 */
|
|
||||||
|
/* USER CODE END TIM4_IRQn 0 */
|
||||||
|
/* USER CODE BEGIN TIM4_IRQn 1 */
|
||||||
|
|
||||||
|
/* USER CODE END TIM4_IRQn 1 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* USER CODE BEGIN 1 */
|
/* USER CODE BEGIN 1 */
|
||||||
|
|||||||
+64
-4
@@ -24,12 +24,68 @@
|
|||||||
|
|
||||||
/* USER CODE END 0 */
|
/* USER CODE END 0 */
|
||||||
|
|
||||||
|
/* TIM1 init function */
|
||||||
|
void MX_TIM1_Init(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* USER CODE BEGIN TIM1_Init 0 */
|
||||||
|
|
||||||
|
// --- this timer is used to time ADC sampling. ---
|
||||||
|
|
||||||
|
/* USER CODE END TIM1_Init 0 */
|
||||||
|
|
||||||
|
LL_TIM_InitTypeDef TIM_InitStruct = {0};
|
||||||
|
LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0};
|
||||||
|
LL_TIM_BDTR_InitTypeDef TIM_BDTRInitStruct = {0};
|
||||||
|
|
||||||
|
/* Peripheral clock enable */
|
||||||
|
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM1);
|
||||||
|
|
||||||
|
/* USER CODE BEGIN TIM1_Init 1 */
|
||||||
|
|
||||||
|
/* USER CODE END TIM1_Init 1 */
|
||||||
|
TIM_InitStruct.Prescaler = 64000;
|
||||||
|
TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
|
||||||
|
TIM_InitStruct.Autoreload = 10;
|
||||||
|
TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
|
||||||
|
TIM_InitStruct.RepetitionCounter = 0;
|
||||||
|
LL_TIM_Init(TIM1, &TIM_InitStruct);
|
||||||
|
LL_TIM_DisableARRPreload(TIM1);
|
||||||
|
LL_TIM_SetClockSource(TIM1, LL_TIM_CLOCKSOURCE_INTERNAL);
|
||||||
|
LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH1);
|
||||||
|
TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1;
|
||||||
|
TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE;
|
||||||
|
TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE;
|
||||||
|
TIM_OC_InitStruct.CompareValue = 1;
|
||||||
|
TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH;
|
||||||
|
TIM_OC_InitStruct.OCNPolarity = LL_TIM_OCPOLARITY_HIGH;
|
||||||
|
TIM_OC_InitStruct.OCIdleState = LL_TIM_OCIDLESTATE_LOW;
|
||||||
|
TIM_OC_InitStruct.OCNIdleState = LL_TIM_OCIDLESTATE_LOW;
|
||||||
|
LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH1, &TIM_OC_InitStruct);
|
||||||
|
LL_TIM_OC_DisableFast(TIM1, LL_TIM_CHANNEL_CH1);
|
||||||
|
LL_TIM_SetTriggerOutput(TIM1, LL_TIM_TRGO_OC1REF);
|
||||||
|
LL_TIM_DisableMasterSlaveMode(TIM1);
|
||||||
|
TIM_BDTRInitStruct.OSSRState = LL_TIM_OSSR_DISABLE;
|
||||||
|
TIM_BDTRInitStruct.OSSIState = LL_TIM_OSSI_DISABLE;
|
||||||
|
TIM_BDTRInitStruct.LockLevel = LL_TIM_LOCKLEVEL_OFF;
|
||||||
|
TIM_BDTRInitStruct.DeadTime = 0;
|
||||||
|
TIM_BDTRInitStruct.BreakState = LL_TIM_BREAK_DISABLE;
|
||||||
|
TIM_BDTRInitStruct.BreakPolarity = LL_TIM_BREAK_POLARITY_HIGH;
|
||||||
|
TIM_BDTRInitStruct.AutomaticOutput = LL_TIM_AUTOMATICOUTPUT_DISABLE;
|
||||||
|
LL_TIM_BDTR_Init(TIM1, &TIM_BDTRInitStruct);
|
||||||
|
/* USER CODE BEGIN TIM1_Init 2 */
|
||||||
|
|
||||||
|
/* USER CODE END TIM1_Init 2 */
|
||||||
|
|
||||||
|
}
|
||||||
/* TIM2 init function */
|
/* TIM2 init function */
|
||||||
void MX_TIM2_Init(void)
|
void MX_TIM2_Init(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* USER CODE BEGIN TIM2_Init 0 */
|
/* USER CODE BEGIN TIM2_Init 0 */
|
||||||
|
|
||||||
|
// --- this timer generates the buzzer PWM. The PWM parameters are adjusted on the fly ---
|
||||||
|
|
||||||
/* USER CODE END TIM2_Init 0 */
|
/* USER CODE END TIM2_Init 0 */
|
||||||
|
|
||||||
LL_TIM_InitTypeDef TIM_InitStruct = {0};
|
LL_TIM_InitTypeDef TIM_InitStruct = {0};
|
||||||
@@ -81,6 +137,8 @@ void MX_TIM3_Init(void)
|
|||||||
|
|
||||||
/* USER CODE BEGIN TIM3_Init 0 */
|
/* USER CODE BEGIN TIM3_Init 0 */
|
||||||
|
|
||||||
|
// --- this timer generates the heater PWM. The duty is set as 640 * percent ---
|
||||||
|
|
||||||
/* USER CODE END TIM3_Init 0 */
|
/* USER CODE END TIM3_Init 0 */
|
||||||
|
|
||||||
LL_TIM_InitTypeDef TIM_InitStruct = {0};
|
LL_TIM_InitTypeDef TIM_InitStruct = {0};
|
||||||
@@ -93,7 +151,7 @@ void MX_TIM3_Init(void)
|
|||||||
/* USER CODE BEGIN TIM3_Init 1 */
|
/* USER CODE BEGIN TIM3_Init 1 */
|
||||||
|
|
||||||
/* USER CODE END TIM3_Init 1 */
|
/* USER CODE END TIM3_Init 1 */
|
||||||
TIM_InitStruct.Prescaler = 2000;
|
TIM_InitStruct.Prescaler = 1000;
|
||||||
TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
|
TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
|
||||||
TIM_InitStruct.Autoreload = 64000;
|
TIM_InitStruct.Autoreload = 64000;
|
||||||
TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
|
TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
|
||||||
@@ -117,11 +175,11 @@ void MX_TIM3_Init(void)
|
|||||||
/**TIM3 GPIO Configuration
|
/**TIM3 GPIO Configuration
|
||||||
PA6 ------> TIM3_CH1
|
PA6 ------> TIM3_CH1
|
||||||
*/
|
*/
|
||||||
GPIO_InitStruct.Pin = LL_GPIO_PIN_6;
|
GPIO_InitStruct.Pin = PWM_HEATER_Pin;
|
||||||
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
|
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
|
||||||
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
|
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
|
||||||
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
|
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
|
||||||
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
LL_GPIO_Init(PWM_HEATER_GPIO_Port, &GPIO_InitStruct);
|
||||||
|
|
||||||
}
|
}
|
||||||
/* TIM4 init function */
|
/* TIM4 init function */
|
||||||
@@ -130,6 +188,8 @@ void MX_TIM4_Init(void)
|
|||||||
|
|
||||||
/* USER CODE BEGIN TIM4_Init 0 */
|
/* USER CODE BEGIN TIM4_Init 0 */
|
||||||
|
|
||||||
|
// --- This timer captures the rotary encoder. The count must be divided by 4, but it can't be done by the hardware, doesn't work well. ---
|
||||||
|
|
||||||
/* USER CODE END TIM4_Init 0 */
|
/* USER CODE END TIM4_Init 0 */
|
||||||
|
|
||||||
LL_TIM_InitTypeDef TIM_InitStruct = {0};
|
LL_TIM_InitTypeDef TIM_InitStruct = {0};
|
||||||
@@ -159,7 +219,7 @@ void MX_TIM4_Init(void)
|
|||||||
LL_TIM_SetEncoderMode(TIM4, LL_TIM_ENCODERMODE_X2_TI1);
|
LL_TIM_SetEncoderMode(TIM4, LL_TIM_ENCODERMODE_X2_TI1);
|
||||||
LL_TIM_IC_SetActiveInput(TIM4, LL_TIM_CHANNEL_CH1, LL_TIM_ACTIVEINPUT_DIRECTTI);
|
LL_TIM_IC_SetActiveInput(TIM4, LL_TIM_CHANNEL_CH1, LL_TIM_ACTIVEINPUT_DIRECTTI);
|
||||||
LL_TIM_IC_SetPrescaler(TIM4, LL_TIM_CHANNEL_CH1, LL_TIM_ICPSC_DIV1);
|
LL_TIM_IC_SetPrescaler(TIM4, LL_TIM_CHANNEL_CH1, LL_TIM_ICPSC_DIV1);
|
||||||
LL_TIM_IC_SetFilter(TIM4, LL_TIM_CHANNEL_CH1, LL_TIM_IC_FILTER_FDIV1);
|
LL_TIM_IC_SetFilter(TIM4, LL_TIM_CHANNEL_CH1, LL_TIM_IC_FILTER_FDIV32_N8);
|
||||||
LL_TIM_IC_SetPolarity(TIM4, LL_TIM_CHANNEL_CH1, LL_TIM_IC_POLARITY_RISING);
|
LL_TIM_IC_SetPolarity(TIM4, LL_TIM_CHANNEL_CH1, LL_TIM_IC_POLARITY_RISING);
|
||||||
LL_TIM_IC_SetActiveInput(TIM4, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_DIRECTTI);
|
LL_TIM_IC_SetActiveInput(TIM4, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_DIRECTTI);
|
||||||
LL_TIM_IC_SetPrescaler(TIM4, LL_TIM_CHANNEL_CH2, LL_TIM_ICPSC_DIV1);
|
LL_TIM_IC_SetPrescaler(TIM4, LL_TIM_CHANNEL_CH2, LL_TIM_ICPSC_DIV1);
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
//
|
||||||
|
// Created by MightyPork on 2023/04/09.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef TOASTER_OVEN_BLUEPILL_TRANSMUTE_H
|
||||||
|
#define TOASTER_OVEN_BLUEPILL_TRANSMUTE_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef union x32 {
|
||||||
|
uint32_t u;
|
||||||
|
float f;
|
||||||
|
} x32_t;
|
||||||
|
|
||||||
|
#endif //TOASTER_OVEN_BLUEPILL_TRANSMUTE_H
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
* TODO file description
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "uart_stdout.h"
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
#define USE_CRITICAL 0
|
||||||
|
|
||||||
|
void stdout_putchar(char c) {
|
||||||
|
#if USE_CRITICAL
|
||||||
|
portENTER_CRITICAL();
|
||||||
|
#endif
|
||||||
|
while (!LL_USART_IsActiveFlag_TXE(USART_DEBUG)) {}
|
||||||
|
LL_USART_TransmitData8(USART_DEBUG, c);
|
||||||
|
while (!LL_USART_IsActiveFlag_TC(USART_DEBUG)) {}
|
||||||
|
#if USE_CRITICAL
|
||||||
|
portEXIT_CRITICAL();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void stdout_write(const char *pcBuffer, const size_t iLength) {
|
||||||
|
#if USE_CRITICAL
|
||||||
|
portENTER_CRITICAL();
|
||||||
|
#endif
|
||||||
|
while (!LL_USART_IsActiveFlag_TXE(USART_DEBUG)) {}
|
||||||
|
int cnt = (int) iLength;
|
||||||
|
while (cnt-- > 0) {
|
||||||
|
char c = *pcBuffer++;
|
||||||
|
LL_USART_TransmitData8(USART_DEBUG, c);
|
||||||
|
while (!LL_USART_IsActiveFlag_TC(USART_DEBUG)) {}
|
||||||
|
}
|
||||||
|
#if USE_CRITICAL
|
||||||
|
portEXIT_CRITICAL();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void stdout_puts(const char *pcBuffer) {
|
||||||
|
stdout_write(pcBuffer, strlen(pcBuffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Retargets the C library printf function to the USART.
|
||||||
|
* @param None
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
int _write(int fd, const char *pcBuffer, const int iLength) {
|
||||||
|
stdout_write(pcBuffer, iLength);
|
||||||
|
return iLength;
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
/**
|
||||||
|
* TODO file description
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BLUEPILLTROUBA_UART_STDOUT_H
|
||||||
|
#define BLUEPILLTROUBA_UART_STDOUT_H
|
||||||
|
|
||||||
|
#endif //BLUEPILLTROUBA_UART_STDOUT_H
|
||||||
+2
-16
@@ -21,7 +21,6 @@
|
|||||||
#include "usart.h"
|
#include "usart.h"
|
||||||
|
|
||||||
/* USER CODE BEGIN 0 */
|
/* USER CODE BEGIN 0 */
|
||||||
#include "main.h"
|
|
||||||
/* USER CODE END 0 */
|
/* USER CODE END 0 */
|
||||||
|
|
||||||
/* USART1 init function */
|
/* USART1 init function */
|
||||||
@@ -52,7 +51,8 @@ void MX_USART1_UART_Init(void)
|
|||||||
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||||
|
|
||||||
GPIO_InitStruct.Pin = LL_GPIO_PIN_10;
|
GPIO_InitStruct.Pin = LL_GPIO_PIN_10;
|
||||||
GPIO_InitStruct.Mode = LL_GPIO_MODE_FLOATING;
|
GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT;
|
||||||
|
GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
|
||||||
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||||
|
|
||||||
/* USER CODE BEGIN USART1_Init 1 */
|
/* USER CODE BEGIN USART1_Init 1 */
|
||||||
@@ -75,18 +75,4 @@ void MX_USART1_UART_Init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* USER CODE BEGIN 1 */
|
/* USER CODE BEGIN 1 */
|
||||||
/**
|
|
||||||
* @brief Retargets the C library printf function to the USART.
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
int _write(int fd, const char *pcBuffer, const int iLength) {
|
|
||||||
int cnt = iLength;
|
|
||||||
while (cnt-- > 0) {
|
|
||||||
while (!LL_USART_IsActiveFlag_TXE(USART_DEBUG)) {}
|
|
||||||
LL_USART_TransmitData8(USART_DEBUG, *pcBuffer++);
|
|
||||||
}
|
|
||||||
return iLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* USER CODE END 1 */
|
/* USER CODE END 1 */
|
||||||
|
|||||||
@@ -0,0 +1,204 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file stm32f1xx_ll_crc.h
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @brief Header file of CRC LL module.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||||
|
* All rights reserved.</center></h2>
|
||||||
|
*
|
||||||
|
* This software component is licensed by ST under BSD 3-Clause license,
|
||||||
|
* the "License"; You may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at:
|
||||||
|
* opensource.org/licenses/BSD-3-Clause
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||||
|
#ifndef STM32F1xx_LL_CRC_H
|
||||||
|
#define STM32F1xx_LL_CRC_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "stm32f1xx.h"
|
||||||
|
|
||||||
|
/** @addtogroup STM32F1xx_LL_Driver
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(CRC)
|
||||||
|
|
||||||
|
/** @defgroup CRC_LL CRC
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Private types -------------------------------------------------------------*/
|
||||||
|
/* Private variables ---------------------------------------------------------*/
|
||||||
|
/* Private constants ---------------------------------------------------------*/
|
||||||
|
/* Private macros ------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Exported types ------------------------------------------------------------*/
|
||||||
|
/* Exported constants --------------------------------------------------------*/
|
||||||
|
/** @defgroup CRC_LL_Exported_Constants CRC Exported Constants
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Exported macro ------------------------------------------------------------*/
|
||||||
|
/** @defgroup CRC_LL_Exported_Macros CRC Exported Macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup CRC_LL_EM_WRITE_READ Common Write and read registers Macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Write a value in CRC register
|
||||||
|
* @param __INSTANCE__ CRC Instance
|
||||||
|
* @param __REG__ Register to be written
|
||||||
|
* @param __VALUE__ Value to be written in the register
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
#define LL_CRC_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, __VALUE__)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read a value in CRC register
|
||||||
|
* @param __INSTANCE__ CRC Instance
|
||||||
|
* @param __REG__ Register to be read
|
||||||
|
* @retval Register value
|
||||||
|
*/
|
||||||
|
#define LL_CRC_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__)
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Exported functions --------------------------------------------------------*/
|
||||||
|
/** @defgroup CRC_LL_Exported_Functions CRC Exported Functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup CRC_LL_EF_Configuration CRC Configuration functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reset the CRC calculation unit.
|
||||||
|
* @note If Programmable Initial CRC value feature
|
||||||
|
* is available, also set the Data Register to the value stored in the
|
||||||
|
* CRC_INIT register, otherwise, reset Data Register to its default value.
|
||||||
|
* @rmtoll CR RESET LL_CRC_ResetCRCCalculationUnit
|
||||||
|
* @param CRCx CRC Instance
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void LL_CRC_ResetCRCCalculationUnit(CRC_TypeDef *CRCx)
|
||||||
|
{
|
||||||
|
SET_BIT(CRCx->CR, CRC_CR_RESET);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup CRC_LL_EF_Data_Management Data_Management
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Write given 32-bit data to the CRC calculator
|
||||||
|
* @rmtoll DR DR LL_CRC_FeedData32
|
||||||
|
* @param CRCx CRC Instance
|
||||||
|
* @param InData value to be provided to CRC calculator between between Min_Data=0 and Max_Data=0xFFFFFFFF
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void LL_CRC_FeedData32(CRC_TypeDef *CRCx, uint32_t InData)
|
||||||
|
{
|
||||||
|
WRITE_REG(CRCx->DR, InData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return current CRC calculation result. 32 bits value is returned.
|
||||||
|
* @rmtoll DR DR LL_CRC_ReadData32
|
||||||
|
* @param CRCx CRC Instance
|
||||||
|
* @retval Current CRC calculation result as stored in CRC_DR register (32 bits).
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t LL_CRC_ReadData32(CRC_TypeDef *CRCx)
|
||||||
|
{
|
||||||
|
return (uint32_t)(READ_REG(CRCx->DR));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return data stored in the Independent Data(IDR) register.
|
||||||
|
* @note This register can be used as a temporary storage location for one byte.
|
||||||
|
* @rmtoll IDR IDR LL_CRC_Read_IDR
|
||||||
|
* @param CRCx CRC Instance
|
||||||
|
* @retval Value stored in CRC_IDR register (General-purpose 8-bit data register).
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t LL_CRC_Read_IDR(CRC_TypeDef *CRCx)
|
||||||
|
{
|
||||||
|
return (uint32_t)(READ_REG(CRCx->IDR));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Store data in the Independent Data(IDR) register.
|
||||||
|
* @note This register can be used as a temporary storage location for one byte.
|
||||||
|
* @rmtoll IDR IDR LL_CRC_Write_IDR
|
||||||
|
* @param CRCx CRC Instance
|
||||||
|
* @param InData value to be stored in CRC_IDR register (8-bit) between Min_Data=0 and Max_Data=0xFF
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void LL_CRC_Write_IDR(CRC_TypeDef *CRCx, uint32_t InData)
|
||||||
|
{
|
||||||
|
*((uint8_t __IO *)(&CRCx->IDR)) = (uint8_t) InData;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(USE_FULL_LL_DRIVER)
|
||||||
|
/** @defgroup CRC_LL_EF_Init Initialization and de-initialization functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
ErrorStatus LL_CRC_DeInit(CRC_TypeDef *CRCx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
#endif /* USE_FULL_LL_DRIVER */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif /* defined(CRC) */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* STM32F1xx_LL_CRC_H */
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file stm32f1xx_ll_crc.c
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @brief CRC LL module driver.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||||
|
* All rights reserved.</center></h2>
|
||||||
|
*
|
||||||
|
* This software component is licensed by ST under BSD 3-Clause license,
|
||||||
|
* the "License"; You may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at:
|
||||||
|
* opensource.org/licenses/BSD-3-Clause
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
#if defined(USE_FULL_LL_DRIVER)
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "stm32f1xx_ll_crc.h"
|
||||||
|
#include "stm32f1xx_ll_bus.h"
|
||||||
|
|
||||||
|
#ifdef USE_FULL_ASSERT
|
||||||
|
#include "stm32_assert.h"
|
||||||
|
#else
|
||||||
|
#define assert_param(expr) ((void)0U)
|
||||||
|
#endif/* USE_FULL_ASSERT */
|
||||||
|
|
||||||
|
/** @addtogroup STM32F1xx_LL_Driver
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined (CRC)
|
||||||
|
|
||||||
|
/** @addtogroup CRC_LL
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Private types -------------------------------------------------------------*/
|
||||||
|
/* Private variables ---------------------------------------------------------*/
|
||||||
|
/* Private constants ---------------------------------------------------------*/
|
||||||
|
/* Private macros ------------------------------------------------------------*/
|
||||||
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
|
|
||||||
|
/* Exported functions --------------------------------------------------------*/
|
||||||
|
/** @addtogroup CRC_LL_Exported_Functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup CRC_LL_EF_Init
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief De-initialize CRC registers (Registers restored to their default values).
|
||||||
|
* @param CRCx CRC Instance
|
||||||
|
* @retval An ErrorStatus enumeration value:
|
||||||
|
* - SUCCESS: CRC registers are de-initialized
|
||||||
|
* - ERROR: CRC registers are not de-initialized
|
||||||
|
*/
|
||||||
|
ErrorStatus LL_CRC_DeInit(CRC_TypeDef *CRCx)
|
||||||
|
{
|
||||||
|
ErrorStatus status = SUCCESS;
|
||||||
|
|
||||||
|
/* Check the parameters */
|
||||||
|
assert_param(IS_CRC_ALL_INSTANCE(CRCx));
|
||||||
|
|
||||||
|
if (CRCx == CRC)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Reset the CRC calculation unit */
|
||||||
|
LL_CRC_ResetCRCCalculationUnit(CRCx);
|
||||||
|
|
||||||
|
/* Reset IDR register */
|
||||||
|
LL_CRC_Write_IDR(CRCx, 0x00U);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif /* defined (CRC) */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif /* USE_FULL_LL_DRIVER */
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
|
|
||||||
+833
-1529
File diff suppressed because it is too large
Load Diff
@@ -23,29 +23,23 @@
|
|||||||
#define __EEPROM_EMUL_H
|
#define __EEPROM_EMUL_H
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#define __IO volatile
|
||||||
|
#define __weak __attribute__((weak))
|
||||||
|
|
||||||
#include "eeprom_emul_conf.h"
|
#include "eeprom_emul_conf.h"
|
||||||
#include "eeprom_emul_types.h"
|
#include "eeprom_emul_types.h"
|
||||||
#include "flash_interface.h"
|
#include "flash_interface.h"
|
||||||
|
|
||||||
/** @addtogroup EEPROM_Emulation
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Private constants ---------------------------------------------------------*/
|
|
||||||
/** @defgroup EEPROM_Private_Constants EEPROM Private Constants
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @defgroup Private_Other_Constants Private Other Constants
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Page definitions */
|
/* Page definitions */
|
||||||
#define PAGE_SIZE FLASH_PAGE_SIZE /*!< Page size */
|
#define PAGE_SIZE FLASH_PAGE_SIZE /*!< Page size */
|
||||||
#define PAGE_HEADER_SIZE EE_ELEMENT_SIZE * 4U /*!< Page Header is 4 elements to save page state */
|
#define PAGE_HEADER_SIZE (EE_ELEMENT_SIZE * 4U) /*!< Page Header is 4 elements to save page state */
|
||||||
#define NB_MAX_ELEMENTS_BY_PAGE ((PAGE_SIZE - PAGE_HEADER_SIZE) / EE_ELEMENT_SIZE) /*!< Max number of elements by page */
|
#define NB_MAX_ELEMENTS_BY_PAGE ((PAGE_SIZE - PAGE_HEADER_SIZE) / EE_ELEMENT_SIZE) /*!< Max number of elements by page */
|
||||||
#define PAGES_NUMBER (((((NB_OF_VARIABLES + NB_MAX_ELEMENTS_BY_PAGE) / NB_MAX_ELEMENTS_BY_PAGE) * 2U) * CYCLES_NUMBER) + GUARD_PAGES_NUMBER)
|
#define PAGES_NUMBER (((((NB_OF_VARIABLES + NB_MAX_ELEMENTS_BY_PAGE) / NB_MAX_ELEMENTS_BY_PAGE) * 2U) * CYCLES_NUMBER) + GUARD_PAGES_NUMBER)
|
||||||
/*!< Number of consecutives pages used by the application */
|
/*!< Number of consecutives pages used by the application */
|
||||||
#define NB_MAX_WRITTEN_ELEMENTS ((NB_MAX_ELEMENTS_BY_PAGE * PAGES_NUMBER) / 2U) /*!< Max number of elements written before triggering pages transfer */
|
#define NB_MAX_WRITTEN_ELEMENTS ((NB_MAX_ELEMENTS_BY_PAGE * PAGES_NUMBER) / 2U) /*!< Max number of elements written before triggering pages transfer */
|
||||||
#define START_PAGE PAGE(START_PAGE_ADDRESS) /*!< Page index of the 1st page used for EEPROM emul, in the bank */
|
#define START_PAGE PAGE(START_PAGE_ADDRESS) /*!< Page index of the 1st page used for EEPROM emul, in the bank */
|
||||||
#define END_EEPROM_ADDRESS (START_PAGE_ADDRESS + (PAGES_NUMBER * FLASH_PAGE_SIZE) - 1) /*!< Last address of EEPROM emulation flash pages */
|
#define END_EEPROM_ADDRESS (START_PAGE_ADDRESS + (PAGES_NUMBER * FLASH_PAGE_SIZE) - 1) /*!< Last address of EEPROM emulation flash pages */
|
||||||
@@ -53,89 +47,44 @@
|
|||||||
/* No page define */
|
/* No page define */
|
||||||
#define EE_NO_PAGE_FOUND ((uint32_t)0xFFFFFFFFU)
|
#define EE_NO_PAGE_FOUND ((uint32_t)0xFFFFFFFFU)
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Private macro -------------------------------------------------------------*/
|
|
||||||
/** @defgroup EEPROM_Private_Macros EEPROM Private Macros
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @defgroup Macros_Pages Macros to manipulate pages
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Macros to manipulate pages */
|
/* Macros to manipulate pages */
|
||||||
#ifdef SECURE_FEATURES
|
#define PAGE_ADDRESS(__PAGE__) (uint32_t)(FLASH_BASE + (__PAGE__) * PAGE_SIZE + ((START_PAGE_ADDRESS - FLASH_BASE) / BANK_SIZE) * BANK_SIZE) /*!< Get page address from page index */
|
||||||
#define PAGE_ADDRESS(__PAGE__) (uint32_t)(FLASH_BASE_NS + (__PAGE__) * PAGE_SIZE + ((START_PAGE_ADDRESS - FLASH_BASE_NS) / BANK_SIZE) * BANK_SIZE) /*!< Get page address from page index */
|
#define PAGE(__ADDRESS__) (uint32_t)((((__ADDRESS__) - FLASH_BASE) % BANK_SIZE) / FLASH_PAGE_SIZE) /*!< Get page index from page address */
|
||||||
#define PAGE(__ADDRESS__) (uint32_t)((((__ADDRESS__) - FLASH_BASE_NS) % BANK_SIZE) / FLASH_PAGE_SIZE) /*!< Get page index from page address */
|
|
||||||
#else
|
|
||||||
#define PAGE_ADDRESS(__PAGE__) (uint32_t)(FLASH_BASE + (__PAGE__) * PAGE_SIZE + ((START_PAGE_ADDRESS - FLASH_BASE) / BANK_SIZE) * BANK_SIZE) /*!< Get page address from page index */
|
|
||||||
#define PAGE(__ADDRESS__) (uint32_t)((((__ADDRESS__) - FLASH_BASE) % BANK_SIZE) / FLASH_PAGE_SIZE) /*!< Get page index from page address */
|
|
||||||
#endif
|
|
||||||
#define PREVIOUS_PAGE(__PAGE__) (uint32_t)((((__PAGE__) - START_PAGE - 1U + PAGES_NUMBER) % PAGES_NUMBER) + START_PAGE) /*!< Get page index of previous page, among circular page list */
|
#define PREVIOUS_PAGE(__PAGE__) (uint32_t)((((__PAGE__) - START_PAGE - 1U + PAGES_NUMBER) % PAGES_NUMBER) + START_PAGE) /*!< Get page index of previous page, among circular page list */
|
||||||
#define FOLLOWING_PAGE(__PAGE__) (uint32_t)((((__PAGE__) - START_PAGE + 1U) % PAGES_NUMBER) + START_PAGE) /*!< Get page index of following page, among circular page list */
|
#define FOLLOWING_PAGE(__PAGE__) (uint32_t)((((__PAGE__) - START_PAGE + 1U) % PAGES_NUMBER) + START_PAGE) /*!< Get page index of following page, among circular page list */
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @defgroup Macros_Elements Macros to manipulate elements
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Macros to manipulate elements */
|
/* Macros to manipulate elements */
|
||||||
#define EE_VIRTUALADDRESS_VALUE(__ELEMENT__) (EE_VIRTUALADDRESS_TYPE)((__ELEMENT__) & EE_MASK_VIRTUALADDRESS) /*!< Get virtual address value from element value */
|
#define EE_VIRTUALADDRESS_VALUE(__ELEMENT__) (EE_VIRTUALADDRESS_TYPE)((__ELEMENT__) & EE_MASK_VIRTUALADDRESS) /*!< Get virtual address value from element value */
|
||||||
#define EE_DATA_VALUE(__ELEMENT__) (EE_DATA_TYPE)(((__ELEMENT__) & EE_MASK_DATA) >> EE_DATA_SHIFT) /*!< Get Data value from element value */
|
#define EE_DATA_VALUE(__ELEMENT__) (EE_DATA_TYPE)(((__ELEMENT__) & EE_MASK_DATA) >> EE_DATA_SHIFT) /*!< Get Data value from element value */
|
||||||
#define EE_CRC_VALUE(__ELEMENT__) (EE_CRC_TYPE)(((__ELEMENT__) & EE_MASK_CRC) >> EE_CRC_SHIFT) /*!< Get Crc value from element value */
|
#define EE_CRC_VALUE(__ELEMENT__) (EE_CRC_TYPE)(((__ELEMENT__) & EE_MASK_CRC) >> EE_CRC_SHIFT) /*!< Get Crc value from element value */
|
||||||
#define EE_ELEMENT_VALUE(__VIRTADDR__,__DATA__,__CRC__) (((EE_ELEMENT_TYPE)(__DATA__) << EE_DATA_SHIFT) | (__CRC__) << EE_CRC_SHIFT | (__VIRTADDR__)) /*!< Get element value from virtual addr, data and crc values */
|
#define EE_ELEMENT_VALUE(__VIRTADDR__, __DATA__, __CRC__) (((EE_ELEMENT_TYPE)(__DATA__) << EE_DATA_SHIFT) | (__CRC__) << EE_CRC_SHIFT | (__VIRTADDR__)) /*!< Get element value from virtual addr, data and crc values */
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Exported constants --------------------------------------------------------*/
|
|
||||||
/* Exported types ------------------------------------------------------------*/
|
|
||||||
/* Exported macro ------------------------------------------------------------*/
|
|
||||||
/* Exported functions ------------------------------------------------------- */
|
|
||||||
/** @defgroup EEPROM_Exported_Functions EEPROM Exported Functions
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
EE_Status EE_Format(EE_Erase_type EraseType);
|
EE_Status EE_Format(EE_Erase_type EraseType);
|
||||||
|
|
||||||
EE_Status EE_Init(EE_Erase_type EraseType);
|
EE_Status EE_Init(EE_Erase_type EraseType);
|
||||||
#if defined(EE_ACCESS_32BITS)
|
|
||||||
EE_Status EE_ReadVariable32bits(uint16_t VirtAddress, uint32_t* pData);
|
EE_Status EE_ReadVariable32bits(uint16_t VirtAddress, uint32_t *pData);
|
||||||
|
|
||||||
EE_Status EE_WriteVariable32bits(uint16_t VirtAddress, uint32_t Data);
|
EE_Status EE_WriteVariable32bits(uint16_t VirtAddress, uint32_t Data);
|
||||||
#endif
|
|
||||||
#if defined(FLASH_LINES_128B)
|
EE_Status EE_ReadVariable16bits(uint16_t VirtAddress, uint16_t *pData);
|
||||||
EE_Status EE_ReadVariable96bits(uint16_t VirtAddress, uint64_t* pData);
|
|
||||||
EE_Status EE_WriteVariable96bits(uint16_t VirtAddress, uint64_t* Data);
|
|
||||||
#endif
|
|
||||||
EE_Status EE_ReadVariable16bits(uint16_t VirtAddress, uint16_t* pData);
|
|
||||||
EE_Status EE_WriteVariable16bits(uint16_t VirtAddress, uint16_t Data);
|
EE_Status EE_WriteVariable16bits(uint16_t VirtAddress, uint16_t Data);
|
||||||
EE_Status EE_ReadVariable8bits(uint16_t VirtAddress, uint8_t* pData);
|
|
||||||
|
EE_Status EE_ReadVariable8bits(uint16_t VirtAddress, uint8_t *pData);
|
||||||
|
|
||||||
EE_Status EE_WriteVariable8bits(uint16_t VirtAddress, uint8_t Data);
|
EE_Status EE_WriteVariable8bits(uint16_t VirtAddress, uint8_t Data);
|
||||||
|
|
||||||
EE_Status EE_CleanUp(void);
|
EE_Status EE_CleanUp(void);
|
||||||
EE_Status EE_CleanUp_IT(void);
|
|
||||||
EE_Status EE_DeleteCorruptedFlashAddress(uint32_t Address);
|
EE_Status EE_DeleteCorruptedFlashAddress(uint32_t Address);
|
||||||
void EE_EndOfCleanup_UserCallback(void);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* Callback from NMI.
|
||||||
*/
|
*
|
||||||
|
* @return true if handled by this library
|
||||||
/**
|
*/
|
||||||
* @}
|
bool EE_NMI_Callback();
|
||||||
*/
|
|
||||||
|
|
||||||
#endif /* __EEPROM_EMUL_H */
|
#endif /* __EEPROM_EMUL_H */
|
||||||
|
|
||||||
|
|||||||
+3
-50
@@ -27,64 +27,17 @@
|
|||||||
#ifndef __EEPROM_EMUL_CONF_H
|
#ifndef __EEPROM_EMUL_CONF_H
|
||||||
#define __EEPROM_EMUL_CONF_H
|
#define __EEPROM_EMUL_CONF_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Private constants ---------------------------------------------------------*/
|
|
||||||
/** @addtogroup EEPROM_Private_Constants
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @defgroup Private_Configuration_Constants Private Configuration Constants
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Configuration of eeprom emulation in flash, can be custom */
|
/* Configuration of eeprom emulation in flash, can be custom */
|
||||||
#define START_PAGE_ADDRESS 0x08080000U /*!< Start address of the 1st page in flash, for EEPROM emulation */
|
#define START_PAGE_ADDRESS 0x800E000U /*!< Start address of the 1st page in flash, for EEPROM emulation */
|
||||||
|
|
||||||
#define CYCLES_NUMBER 1U /*!< Number of 10Kcycles requested, minimum 1 for 10Kcycles (default),
|
#define CYCLES_NUMBER 1U /*!< Number of 10Kcycles requested, minimum 1 for 10Kcycles (default),
|
||||||
for instance 10 to reach 100Kcycles. This factor will increase
|
for instance 10 to reach 100Kcycles. This factor will increase
|
||||||
pages number */
|
pages number */
|
||||||
|
|
||||||
#define GUARD_PAGES_NUMBER 2U /*!< Number of guard pages avoiding frequent transfers (must be multiple of 2): 0,2,4.. */
|
#define GUARD_PAGES_NUMBER 2U /*!< Number of guard pages avoiding frequent transfers (must be multiple of 2): 0,2,4.. */
|
||||||
|
|
||||||
/* Configuration of crc calculation for eeprom emulation in flash */
|
|
||||||
#define CRC_POLYNOMIAL_LENGTH LL_CRC_POLYLENGTH_16B /* CRC polynomial lenght 16 bits */
|
|
||||||
#define CRC_POLYNOMIAL_VALUE 0x8005U /* Polynomial to use for CRC calculation */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Exported types ------------------------------------------------------------*/
|
|
||||||
/* Exported constants --------------------------------------------------------*/
|
|
||||||
/** @defgroup EEPROM_Exported_Constants EEPROM Exported Constants
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @defgroup Exported_Configuration_Constants Exported Configuration Constants
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
#define NB_OF_VARIABLES 1000U /*!< Number of variables to handle in eeprom */
|
#define NB_OF_VARIABLES 1000U /*!< Number of variables to handle in eeprom */
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#endif /* __EEPROM_EMUL_CONF_H */
|
#endif /* __EEPROM_EMUL_CONF_H */
|
||||||
|
|
||||||
@@ -1,258 +0,0 @@
|
|||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* @file EEPROM_Emul/Porting/STM32C0/flash_interface.c
|
|
||||||
* @author MCD Application Team
|
|
||||||
* @brief This file provides all the EEPROM emulation flash interface functions.
|
|
||||||
******************************************************************************
|
|
||||||
* @attention
|
|
||||||
*
|
|
||||||
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
|
|
||||||
* All rights reserved.</center></h2>
|
|
||||||
*
|
|
||||||
* This software component is licensed by ST under BSD 3-Clause license,
|
|
||||||
* the "License"; You may not use this file except in compliance with the
|
|
||||||
* License. You may obtain a copy of the License at:
|
|
||||||
* opensource.org/licenses/BSD-3-Clause
|
|
||||||
*
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
|
||||||
#include "eeprom_emul.h"
|
|
||||||
#include "flash_interface.h"
|
|
||||||
|
|
||||||
/** @addtogroup EEPROM_Emulation
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Private typedef -----------------------------------------------------------*/
|
|
||||||
/* Private constants ---------------------------------------------------------*/
|
|
||||||
/* Private macro -------------------------------------------------------------*/
|
|
||||||
/* Private variables ---------------------------------------------------------*/
|
|
||||||
/* Private function prototypes -----------------------------------------------*/
|
|
||||||
#ifdef FLASH_BANK_2
|
|
||||||
static uint32_t GetBankNumber(uint32_t Address);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Exported functions --------------------------------------------------------*/
|
|
||||||
/* Private functions ---------------------------------------------------------*/
|
|
||||||
/** @addtogroup EEPROM_Private_Functions
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Write a double word at the given address in Flash
|
|
||||||
* @param Address Where to write
|
|
||||||
* @param Data What to write
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE_WRITE_ERROR: if an error occurs
|
|
||||||
*/
|
|
||||||
HAL_StatusTypeDef FI_WriteDoubleWord(uint32_t Address, uint64_t Data)
|
|
||||||
{
|
|
||||||
return HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Erase a page in polling mode
|
|
||||||
* @param Page Page number
|
|
||||||
* @param NbPages Number of pages to erase
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages)
|
|
||||||
{
|
|
||||||
EE_Status status = EE_OK;
|
|
||||||
FLASH_EraseInitTypeDef s_eraseinit;
|
|
||||||
uint32_t page_error = 0U;
|
|
||||||
|
|
||||||
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES;
|
|
||||||
s_eraseinit.NbPages = NbPages;
|
|
||||||
s_eraseinit.Page = Page;
|
|
||||||
|
|
||||||
/* Erase the Page: Set Page status to ERASED status */
|
|
||||||
if (HAL_FLASHEx_Erase(&s_eraseinit, &page_error) != HAL_OK)
|
|
||||||
{
|
|
||||||
status = EE_ERASE_ERROR;
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Erase a page with interrupt enabled
|
|
||||||
* @param Page Page number
|
|
||||||
* @param NbPages Number of pages to erase
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_PageErase_IT(uint32_t Page, uint16_t NbPages)
|
|
||||||
{
|
|
||||||
EE_Status status = EE_OK;
|
|
||||||
FLASH_EraseInitTypeDef s_eraseinit;
|
|
||||||
|
|
||||||
#ifdef FLASH_BANK_2
|
|
||||||
uint32_t bank = GetBankNumber(PAGE_ADDRESS(Page));
|
|
||||||
s_eraseinit.Banks = bank;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES;
|
|
||||||
s_eraseinit.NbPages = NbPages;
|
|
||||||
s_eraseinit.Page = Page;
|
|
||||||
|
|
||||||
/* Erase the Page: Set Page status to ERASED status */
|
|
||||||
if (HAL_FLASHEx_Erase_IT(&s_eraseinit) != HAL_OK)
|
|
||||||
{
|
|
||||||
status = EE_ERASE_ERROR;
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Flush the caches if needed to keep coherency when the flash content is modified
|
|
||||||
*/
|
|
||||||
void FI_CacheFlush()
|
|
||||||
{
|
|
||||||
/* No flush needed. There is no D-Cache for the STM32G0x0 and STM32G0x1 products. */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef FLASH_BANK_2
|
|
||||||
/**
|
|
||||||
* @brief Gets the bank of a given address
|
|
||||||
* @param Address Address of the FLASH Memory
|
|
||||||
* @retval Bank_Number The bank of a given address
|
|
||||||
*/
|
|
||||||
static uint32_t GetBankNumber(uint32_t Address)
|
|
||||||
{
|
|
||||||
uint32_t bank = 0U;
|
|
||||||
|
|
||||||
if (OB_USER_DUALBANK_SWAP_DISABLE)
|
|
||||||
{
|
|
||||||
/* No Bank swap */
|
|
||||||
if (Address < (FLASH_BASE + FLASH_BANK_SIZE))
|
|
||||||
{
|
|
||||||
bank = FLASH_BANK_1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bank = FLASH_BANK_2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Bank swap */
|
|
||||||
if (Address < (FLASH_BASE + FLASH_BANK_SIZE))
|
|
||||||
{
|
|
||||||
bank = FLASH_BANK_2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bank = FLASH_BANK_1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return bank;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Delete corrupted Flash address, can be called from NMI. No Timeout.
|
|
||||||
* @param Address Address of the FLASH Memory to delete
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address)
|
|
||||||
{
|
|
||||||
EE_Status status = EE_OK;
|
|
||||||
|
|
||||||
/* Set FLASH Programmation bit */
|
|
||||||
SET_BIT(FLASH->CR, FLASH_CR_PG);
|
|
||||||
|
|
||||||
/* Program double word of value 0 */
|
|
||||||
*(__IO uint32_t*)(Address) = (uint32_t)0U;
|
|
||||||
*(__IO uint32_t*)(Address+4U) = (uint32_t)0U;
|
|
||||||
|
|
||||||
/* Wait programmation completion */
|
|
||||||
#if defined(FLASH_DBANK_SUPPORT)
|
|
||||||
uint32_t bank = GetBankNumber(Address);
|
|
||||||
if(bank == FLASH_BANK_1)
|
|
||||||
{
|
|
||||||
while(FLASH->SR & FLASH_SR_BSY1)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while(FLASH->SR & FLASH_SR_BSY2)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
while(FLASH->SR & FLASH_SR_BSY1)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Check if error occured */
|
|
||||||
if((FLASH->SR & FLASH_SR_OPERR) || (FLASH->SR & FLASH_SR_PROGERR) ||
|
|
||||||
(FLASH->SR & FLASH_SR_WRPERR) || (FLASH->SR & FLASH_SR_PGAERR) ||
|
|
||||||
(FLASH->SR & FLASH_SR_SIZERR) || (FLASH->SR & FLASH_SR_PGSERR))
|
|
||||||
{
|
|
||||||
status = EE_DELETE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check FLASH End of Operation flag */
|
|
||||||
if (FLASH->SR & FLASH_SR_EOP)
|
|
||||||
{
|
|
||||||
/* Clear FLASH End of Operation pending bit */
|
|
||||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear FLASH Programmation bit */
|
|
||||||
CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
|
|
||||||
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Check if the configuration is 128-bits bank or 2*64-bits bank
|
|
||||||
* @param None
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_CheckBankConfig(void)
|
|
||||||
{
|
|
||||||
#if defined (FLASH_DBANK_SUPPORT)
|
|
||||||
EE_Status status;
|
|
||||||
|
|
||||||
/* Check the value of the DBANK user option byte */
|
|
||||||
if (OB_USER_DUALBANK_ENABLE)
|
|
||||||
{
|
|
||||||
status = EE_OK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
status = EE_INVALID_BANK_CFG;
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
|
||||||
#else
|
|
||||||
/* No feature 128-bits single bank, so always 64-bits dual bank */
|
|
||||||
return EE_OK;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
||||||
@@ -1,125 +0,0 @@
|
|||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* @file EEPROM_Emul/Porting/STM32C0/flash_interface.h
|
|
||||||
* @author MCD Application Team
|
|
||||||
* @brief This file contains all the functions prototypes for the EEPROM
|
|
||||||
* emulation flash interface.
|
|
||||||
******************************************************************************
|
|
||||||
* @attention
|
|
||||||
*
|
|
||||||
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
|
|
||||||
* All rights reserved.</center></h2>
|
|
||||||
*
|
|
||||||
* This software component is licensed by ST under BSD 3-Clause license,
|
|
||||||
* the "License"; You may not use this file except in compliance with the
|
|
||||||
* License. You may obtain a copy of the License at:
|
|
||||||
* opensource.org/licenses/BSD-3-Clause
|
|
||||||
*
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
|
||||||
#ifndef __FLASH_INTERFACE_H
|
|
||||||
#define __FLASH_INTERFACE_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
|
||||||
#include "stm32c0xx_hal.h"
|
|
||||||
#include "stm32c0xx_ll_crc.h"
|
|
||||||
#include "stm32c0xx_ll_bus.h"
|
|
||||||
|
|
||||||
/** @addtogroup EEPROM_Emulation
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Exported types ------------------------------------------------------------*/
|
|
||||||
/* Exported macro ------------------------------------------------------------*/
|
|
||||||
/* Exported functions ------------------------------------------------------- */
|
|
||||||
|
|
||||||
/* Private types -------------------------------------------------------------*/
|
|
||||||
/* Private constants ---------------------------------------------------------*/
|
|
||||||
/** @addtogroup EEPROM_Private_Constants
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @addtogroup Private_Other_Constants
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define BANK_SIZE FLASH_BANK_SIZE /*!< Alias to FLASH_BANK_SIZE definition from HAL STM32L4 */
|
|
||||||
#define EE_ACCESS_32BITS /*!< Enable EEPROM 32bits R/W functions, only valid for flash allowing 64bits access*/
|
|
||||||
|
|
||||||
/* Page state header */
|
|
||||||
#define EE_PAGESTAT_ERASED (uint64_t)0xFFFFFFFFFFFFFFFFU /*!< State saved in 1st,2nd,3rd,4th data type of page header */
|
|
||||||
#define EE_PAGESTAT_RECEIVE (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 1st data type of page header */
|
|
||||||
#define EE_PAGESTAT_ACTIVE (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 2nd data type of page header */
|
|
||||||
#define EE_PAGESTAT_VALID (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 3rd data type of page header */
|
|
||||||
#define EE_PAGESTAT_ERASING (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 4th data type of page header */
|
|
||||||
|
|
||||||
/* Description of the 8 Bytes (64 bits) element in flash */
|
|
||||||
/* Bit: 63 32 31 16 15 0 */
|
|
||||||
/* <--- Data Value -----> <-unused-> <-VirtAddr-> */
|
|
||||||
#define EE_ELEMENT_SIZE 8U /*!< Size of element in Bytes */
|
|
||||||
#define EE_ELEMENT_TYPE uint64_t /*!< Type of element */
|
|
||||||
#define EE_VIRTUALADDRESS_TYPE uint16_t /*!< Type of Virtual Address */
|
|
||||||
#define EE_VIRTUALADDRESS_SHIFT 0U /*!< Bits Shifting to get Virtual Address in element */
|
|
||||||
#define EE_CRC_TYPE uint16_t /*!< Type of Crc */
|
|
||||||
#define EE_CRC_SHIFT 16U /*!< Bits Shifting to get Crc in element */
|
|
||||||
#define EE_DATA_TYPE uint32_t /*!< Type of Data */
|
|
||||||
#define EE_DATA_SHIFT 32U /*!< Bits Shifting to get Data value in element */
|
|
||||||
#define EE_MASK_VIRTUALADDRESS (uint64_t)0x000000000000FFFFU
|
|
||||||
#define EE_MASK_CRC (uint64_t)0x00000000FFFF0000U
|
|
||||||
#define EE_MASK_DATA (uint64_t)0xFFFFFFFF00000000U
|
|
||||||
#define EE_MASK_FULL (uint64_t)0xFFFFFFFFFFFFFFFFU
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Private macro -------------------------------------------------------------*/
|
|
||||||
/** @addtogroup EEPROM_Private_Macros
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Private functions ---------------------------------------------------------*/
|
|
||||||
/** @addtogroup EEPROM_Private_Functions
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
HAL_StatusTypeDef FI_WriteDoubleWord(uint32_t Address, uint64_t Data);
|
|
||||||
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages);
|
|
||||||
EE_Status FI_PageErase_IT(uint32_t Page, uint16_t NbPages);
|
|
||||||
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address);
|
|
||||||
EE_Status FI_CheckBankConfig(void);
|
|
||||||
void FI_CacheFlush(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#endif /* __FLASH_INTERFACE_H */
|
|
||||||
|
|
||||||
|
|
||||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
||||||
@@ -0,0 +1,173 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file EEPROM_Emul/Porting/STM32L4/flash_interface.c
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @brief This file provides all the EEPROM emulation flash interface functions.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
|
||||||
|
* All rights reserved.</center></h2>
|
||||||
|
*
|
||||||
|
* This software component is licensed by ST under BSD 3-Clause license,
|
||||||
|
* the "License"; You may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at:
|
||||||
|
* opensource.org/licenses/BSD-3-Clause
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "eeprom_emul.h"
|
||||||
|
#include "flash_interface.h"
|
||||||
|
#include "snprintf.h"
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
|
||||||
|
static inline void FI_Raw_ProgramHalfword(uint32_t Address, uint16_t value)
|
||||||
|
{
|
||||||
|
*(__IO uint16_t *) (Address) = value;
|
||||||
|
|
||||||
|
/* Wait programmation completion */
|
||||||
|
while (FLASH->SR & FLASH_SR_BSY) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void FI_Raw_ProgramWord(uint32_t Address, uint32_t value)
|
||||||
|
{
|
||||||
|
FI_Raw_ProgramHalfword(Address, value & 0xFFFF);
|
||||||
|
FI_Raw_ProgramHalfword(Address + 2, value >> 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FI_Raw_ProgramDoubleWord(uint32_t Address, uint64_t value)
|
||||||
|
{
|
||||||
|
FI_Raw_ProgramWord(Address, value & 0xFFFFFFFFUL);
|
||||||
|
FI_Raw_ProgramWord(Address + 4, value >> 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** @addtogroup EEPROM_Private_Functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void UnlockFlash()
|
||||||
|
{
|
||||||
|
FLASH->KEYR = 0x45670123;
|
||||||
|
FLASH->KEYR = 0xCDEF89AB;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void LockFlash()
|
||||||
|
{
|
||||||
|
FLASH->CR |= FLASH_CR_LOCK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Write a double word at the given address in Flash
|
||||||
|
* @param Address Where to write
|
||||||
|
* @param Data What to write
|
||||||
|
* @retval EE_Status
|
||||||
|
* - EE_OK: on success
|
||||||
|
* - EE_WRITE_ERROR: if an error occurs
|
||||||
|
*/
|
||||||
|
EE_Status FI_WriteDoubleWord(uint32_t Address, uint64_t Data)
|
||||||
|
{
|
||||||
|
PRINTF("FI wr %p, val %016"PRIx64"\r\n", (void *) Address, Data);
|
||||||
|
|
||||||
|
EE_Status status = EE_OK;
|
||||||
|
|
||||||
|
if (FLASH->CR & FLASH_CR_LOCK) {
|
||||||
|
UnlockFlash();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set FLASH Programmation bit */
|
||||||
|
FLASH->CR |= FLASH_CR_PG;
|
||||||
|
|
||||||
|
/* Program double word of value 0 */
|
||||||
|
FI_Raw_ProgramDoubleWord(Address, Data);
|
||||||
|
|
||||||
|
/* Check if error occured */
|
||||||
|
if (FLASH->SR & (FLASH_SR_WRPRTERR | FLASH_SR_PGERR)) {
|
||||||
|
PUTS("Flash write error\r\n");
|
||||||
|
status = EE_WRITE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check FLASH End of Operation flag */
|
||||||
|
if (FLASH->SR & FLASH_SR_EOP) {
|
||||||
|
/* Clear FLASH End of Operation pending bit */
|
||||||
|
FLASH->SR = FLASH_SR_EOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear FLASH Programmation bit */
|
||||||
|
FLASH->CR &= ~FLASH_CR_PG;
|
||||||
|
|
||||||
|
LockFlash();
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Erase a page in polling mode
|
||||||
|
* @param Page Page number
|
||||||
|
* @param NbPages Number of pages to erase
|
||||||
|
* @retval EE_Status
|
||||||
|
* - EE_OK: on success
|
||||||
|
* - EE error code: if an error occurs
|
||||||
|
*/
|
||||||
|
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages)
|
||||||
|
{
|
||||||
|
PRINTF("FI erase page %d, nbr %d\r\n", Page, NbPages);
|
||||||
|
|
||||||
|
EE_Status status = EE_OK;
|
||||||
|
|
||||||
|
if (FLASH->CR & FLASH_CR_LOCK) {
|
||||||
|
UnlockFlash();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set FLASH Programmation bit */
|
||||||
|
FLASH->CR |= FLASH_CR_PER;
|
||||||
|
|
||||||
|
while (NbPages-- > 0) {
|
||||||
|
FLASH->AR = Page * FLASH_PAGE_SIZE;
|
||||||
|
|
||||||
|
FLASH->CR |= FLASH_CR_STRT;
|
||||||
|
|
||||||
|
/* Wait programmation completion */
|
||||||
|
while (FLASH->SR & FLASH_SR_BSY) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Page++;
|
||||||
|
}
|
||||||
|
|
||||||
|
FLASH->CR &= ~FLASH_CR_PER;
|
||||||
|
LockFlash();
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Flush the caches if needed to keep coherency when the flash content is modified
|
||||||
|
*/
|
||||||
|
void FI_CacheFlush()
|
||||||
|
{
|
||||||
|
// f1 doesn't have cache
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Delete corrupted Flash address, can be called from NMI. No Timeout.
|
||||||
|
* @param Address Address of the FLASH Memory to delete
|
||||||
|
* @retval EE_Status
|
||||||
|
* - EE_OK: on success
|
||||||
|
* - EE error code: if an error occurs
|
||||||
|
*/
|
||||||
|
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address)
|
||||||
|
{
|
||||||
|
EE_Status rv = FI_WriteDoubleWord(Address, 0);
|
||||||
|
if (rv == EE_WRITE_ERROR) {
|
||||||
|
rv = EE_DELETE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||||
+24
-6
@@ -27,9 +27,29 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
#include "stm32l4xx_hal.h"
|
#include <stdint.h>
|
||||||
#include "stm32l4xx_ll_crc.h"
|
|
||||||
#include "stm32l4xx_ll_bus.h"
|
#include "stm32f1xx.h"
|
||||||
|
#include "stm32f103xb.h"
|
||||||
|
#include "stm32f1xx_ll_crc.h"
|
||||||
|
#include "stm32f1xx_ll_bus.h"
|
||||||
|
|
||||||
|
|
||||||
|
/** @defgroup FLASHEx_Page_Size Page Size
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#if (defined(STM32F101x6) || defined(STM32F102x6) || defined(STM32F103x6) || defined(STM32F100xB) || defined(STM32F101xB) || defined(STM32F102xB) || defined(STM32F103xB))
|
||||||
|
#define FLASH_PAGE_SIZE 0x400U
|
||||||
|
#endif /* STM32F101x6 || STM32F102x6 || STM32F103x6 */
|
||||||
|
/* STM32F100xB || STM32F101xB || STM32F102xB || STM32F103xB */
|
||||||
|
|
||||||
|
#if (defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG) || defined(STM32F105xC) || defined(STM32F107xC))
|
||||||
|
#define FLASH_PAGE_SIZE 0x800U
|
||||||
|
#endif /* STM32F100xB || STM32F101xB || STM32F102xB || STM32F103xB */
|
||||||
|
/* STM32F101xG || STM32F103xG */
|
||||||
|
/* STM32F105xC || STM32F107xC */
|
||||||
|
|
||||||
|
#define FLASH_BANK_SIZE (FLASH_BANK1_END - FLASH_BASE)
|
||||||
|
|
||||||
/** @addtogroup EEPROM_Emulation
|
/** @addtogroup EEPROM_Emulation
|
||||||
* @{
|
* @{
|
||||||
@@ -100,11 +120,9 @@
|
|||||||
/** @addtogroup EEPROM_Private_Functions
|
/** @addtogroup EEPROM_Private_Functions
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
HAL_StatusTypeDef FI_WriteDoubleWord(uint32_t Address, uint64_t Data);
|
EE_Status FI_WriteDoubleWord(uint32_t Address, uint64_t Data);
|
||||||
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages);
|
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages);
|
||||||
EE_Status FI_PageErase_IT(uint32_t Page, uint16_t NbPages);
|
|
||||||
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address);
|
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address);
|
||||||
EE_Status FI_CheckBankConfig(void);
|
|
||||||
void FI_CacheFlush(void);
|
void FI_CacheFlush(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1,265 +0,0 @@
|
|||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* @file EEPROM_Emul/Porting/STM32G0/flash_interface.c
|
|
||||||
* @author MCD Application Team
|
|
||||||
* @brief This file provides all the EEPROM emulation flash interface functions.
|
|
||||||
******************************************************************************
|
|
||||||
* @attention
|
|
||||||
*
|
|
||||||
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
|
|
||||||
* All rights reserved.</center></h2>
|
|
||||||
*
|
|
||||||
* This software component is licensed by ST under BSD 3-Clause license,
|
|
||||||
* the "License"; You may not use this file except in compliance with the
|
|
||||||
* License. You may obtain a copy of the License at:
|
|
||||||
* opensource.org/licenses/BSD-3-Clause
|
|
||||||
*
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
|
||||||
#include "eeprom_emul.h"
|
|
||||||
#include "flash_interface.h"
|
|
||||||
|
|
||||||
/** @addtogroup EEPROM_Emulation
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Private typedef -----------------------------------------------------------*/
|
|
||||||
/* Private constants ---------------------------------------------------------*/
|
|
||||||
/* Private macro -------------------------------------------------------------*/
|
|
||||||
/* Private variables ---------------------------------------------------------*/
|
|
||||||
/* Private function prototypes -----------------------------------------------*/
|
|
||||||
#ifdef FLASH_BANK_2
|
|
||||||
static uint32_t GetBankNumber(uint32_t Address);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Exported functions --------------------------------------------------------*/
|
|
||||||
/* Private functions ---------------------------------------------------------*/
|
|
||||||
/** @addtogroup EEPROM_Private_Functions
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Write a double word at the given address in Flash
|
|
||||||
* @param Address Where to write
|
|
||||||
* @param Data What to write
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE_WRITE_ERROR: if an error occurs
|
|
||||||
*/
|
|
||||||
HAL_StatusTypeDef FI_WriteDoubleWord(uint32_t Address, uint64_t Data)
|
|
||||||
{
|
|
||||||
return HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Erase a page in polling mode
|
|
||||||
* @param Page Page number
|
|
||||||
* @param NbPages Number of pages to erase
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages)
|
|
||||||
{
|
|
||||||
EE_Status status = EE_OK;
|
|
||||||
FLASH_EraseInitTypeDef s_eraseinit;
|
|
||||||
uint32_t page_error = 0U;
|
|
||||||
|
|
||||||
#ifdef FLASH_BANK_2
|
|
||||||
uint32_t bank = GetBankNumber(PAGE_ADDRESS(Page));
|
|
||||||
s_eraseinit.Banks = bank;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES;
|
|
||||||
s_eraseinit.NbPages = NbPages;
|
|
||||||
s_eraseinit.Page = Page;
|
|
||||||
|
|
||||||
/* Erase the Page: Set Page status to ERASED status */
|
|
||||||
if (HAL_FLASHEx_Erase(&s_eraseinit, &page_error) != HAL_OK)
|
|
||||||
{
|
|
||||||
status = EE_ERASE_ERROR;
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Erase a page with interrupt enabled
|
|
||||||
* @param Page Page number
|
|
||||||
* @param NbPages Number of pages to erase
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_PageErase_IT(uint32_t Page, uint16_t NbPages)
|
|
||||||
{
|
|
||||||
EE_Status status = EE_OK;
|
|
||||||
FLASH_EraseInitTypeDef s_eraseinit;
|
|
||||||
|
|
||||||
#ifdef FLASH_BANK_2
|
|
||||||
uint32_t bank = GetBankNumber(PAGE_ADDRESS(Page));
|
|
||||||
s_eraseinit.Banks = bank;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES;
|
|
||||||
s_eraseinit.NbPages = NbPages;
|
|
||||||
s_eraseinit.Page = Page;
|
|
||||||
|
|
||||||
/* Erase the Page: Set Page status to ERASED status */
|
|
||||||
if (HAL_FLASHEx_Erase_IT(&s_eraseinit) != HAL_OK)
|
|
||||||
{
|
|
||||||
status = EE_ERASE_ERROR;
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Flush the caches if needed to keep coherency when the flash content is modified
|
|
||||||
*/
|
|
||||||
void FI_CacheFlush()
|
|
||||||
{
|
|
||||||
/* No flush needed. There is no D-Cache for the STM32G0x0 and STM32G0x1 products. */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef FLASH_BANK_2
|
|
||||||
/**
|
|
||||||
* @brief Gets the bank of a given address
|
|
||||||
* @param Address Address of the FLASH Memory
|
|
||||||
* @retval Bank_Number The bank of a given address
|
|
||||||
*/
|
|
||||||
static uint32_t GetBankNumber(uint32_t Address)
|
|
||||||
{
|
|
||||||
uint32_t bank = 0U;
|
|
||||||
|
|
||||||
if (OB_USER_DUALBANK_SWAP_DISABLE)
|
|
||||||
{
|
|
||||||
/* No Bank swap */
|
|
||||||
if (Address < (FLASH_BASE + FLASH_BANK_SIZE))
|
|
||||||
{
|
|
||||||
bank = FLASH_BANK_1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bank = FLASH_BANK_2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Bank swap */
|
|
||||||
if (Address < (FLASH_BASE + FLASH_BANK_SIZE))
|
|
||||||
{
|
|
||||||
bank = FLASH_BANK_2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bank = FLASH_BANK_1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return bank;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Delete corrupted Flash address, can be called from NMI. No Timeout.
|
|
||||||
* @param Address Address of the FLASH Memory to delete
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address)
|
|
||||||
{
|
|
||||||
EE_Status status = EE_OK;
|
|
||||||
|
|
||||||
/* Set FLASH Programmation bit */
|
|
||||||
SET_BIT(FLASH->CR, FLASH_CR_PG);
|
|
||||||
|
|
||||||
/* Program double word of value 0 */
|
|
||||||
*(__IO uint32_t*)(Address) = (uint32_t)0U;
|
|
||||||
*(__IO uint32_t*)(Address+4U) = (uint32_t)0U;
|
|
||||||
|
|
||||||
/* Wait programmation completion */
|
|
||||||
#if defined(FLASH_DBANK_SUPPORT)
|
|
||||||
uint32_t bank = GetBankNumber(Address);
|
|
||||||
if(bank == FLASH_BANK_1)
|
|
||||||
{
|
|
||||||
while(FLASH->SR & FLASH_SR_BSY1)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while(FLASH->SR & FLASH_SR_BSY2)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
while(FLASH->SR & FLASH_SR_BSY1)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Check if error occured */
|
|
||||||
if((FLASH->SR & FLASH_SR_OPERR) || (FLASH->SR & FLASH_SR_PROGERR) ||
|
|
||||||
(FLASH->SR & FLASH_SR_WRPERR) || (FLASH->SR & FLASH_SR_PGAERR) ||
|
|
||||||
(FLASH->SR & FLASH_SR_SIZERR) || (FLASH->SR & FLASH_SR_PGSERR))
|
|
||||||
{
|
|
||||||
status = EE_DELETE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check FLASH End of Operation flag */
|
|
||||||
if (FLASH->SR & FLASH_SR_EOP)
|
|
||||||
{
|
|
||||||
/* Clear FLASH End of Operation pending bit */
|
|
||||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear FLASH Programmation bit */
|
|
||||||
CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
|
|
||||||
|
|
||||||
/* Clear FLASH ECCD bit */
|
|
||||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ECCD);
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Check if the configuration is 128-bits bank or 2*64-bits bank
|
|
||||||
* @param None
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_CheckBankConfig(void)
|
|
||||||
{
|
|
||||||
#if defined (FLASH_DBANK_SUPPORT)
|
|
||||||
EE_Status status;
|
|
||||||
|
|
||||||
/* Check the value of the DBANK user option byte */
|
|
||||||
if (OB_USER_DUALBANK_ENABLE)
|
|
||||||
{
|
|
||||||
status = EE_OK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
status = EE_INVALID_BANK_CFG;
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
|
||||||
#else
|
|
||||||
/* No feature 128-bits single bank, so always 64-bits dual bank */
|
|
||||||
return EE_OK;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
||||||
@@ -1,125 +0,0 @@
|
|||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* @file EEPROM_Emul/Porting/STM32G0/flash_interface.h
|
|
||||||
* @author MCD Application Team
|
|
||||||
* @brief This file contains all the functions prototypes for the EEPROM
|
|
||||||
* emulation flash interface.
|
|
||||||
******************************************************************************
|
|
||||||
* @attention
|
|
||||||
*
|
|
||||||
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
|
|
||||||
* All rights reserved.</center></h2>
|
|
||||||
*
|
|
||||||
* This software component is licensed by ST under BSD 3-Clause license,
|
|
||||||
* the "License"; You may not use this file except in compliance with the
|
|
||||||
* License. You may obtain a copy of the License at:
|
|
||||||
* opensource.org/licenses/BSD-3-Clause
|
|
||||||
*
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
|
||||||
#ifndef __FLASH_INTERFACE_H
|
|
||||||
#define __FLASH_INTERFACE_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
|
||||||
#include "stm32g0xx_hal.h"
|
|
||||||
#include "stm32g0xx_ll_crc.h"
|
|
||||||
#include "stm32g0xx_ll_bus.h"
|
|
||||||
|
|
||||||
/** @addtogroup EEPROM_Emulation
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Exported types ------------------------------------------------------------*/
|
|
||||||
/* Exported macro ------------------------------------------------------------*/
|
|
||||||
/* Exported functions ------------------------------------------------------- */
|
|
||||||
|
|
||||||
/* Private types -------------------------------------------------------------*/
|
|
||||||
/* Private constants ---------------------------------------------------------*/
|
|
||||||
/** @addtogroup EEPROM_Private_Constants
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @addtogroup Private_Other_Constants
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define BANK_SIZE FLASH_BANK_SIZE /*!< Alias to FLASH_BANK_SIZE definition from HAL STM32L4 */
|
|
||||||
#define EE_ACCESS_32BITS /*!< Enable EEPROM 32bits R/W functions, only valid for flash allowing 64bits access*/
|
|
||||||
|
|
||||||
/* Page state header */
|
|
||||||
#define EE_PAGESTAT_ERASED (uint64_t)0xFFFFFFFFFFFFFFFFU /*!< State saved in 1st,2nd,3rd,4th data type of page header */
|
|
||||||
#define EE_PAGESTAT_RECEIVE (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 1st data type of page header */
|
|
||||||
#define EE_PAGESTAT_ACTIVE (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 2nd data type of page header */
|
|
||||||
#define EE_PAGESTAT_VALID (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 3rd data type of page header */
|
|
||||||
#define EE_PAGESTAT_ERASING (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 4th data type of page header */
|
|
||||||
|
|
||||||
/* Description of the 8 Bytes (64 bits) element in flash */
|
|
||||||
/* Bit: 63 32 31 16 15 0 */
|
|
||||||
/* <--- Data Value -----> <-unused-> <-VirtAddr-> */
|
|
||||||
#define EE_ELEMENT_SIZE 8U /*!< Size of element in Bytes */
|
|
||||||
#define EE_ELEMENT_TYPE uint64_t /*!< Type of element */
|
|
||||||
#define EE_VIRTUALADDRESS_TYPE uint16_t /*!< Type of Virtual Address */
|
|
||||||
#define EE_VIRTUALADDRESS_SHIFT 0U /*!< Bits Shifting to get Virtual Address in element */
|
|
||||||
#define EE_CRC_TYPE uint16_t /*!< Type of Crc */
|
|
||||||
#define EE_CRC_SHIFT 16U /*!< Bits Shifting to get Crc in element */
|
|
||||||
#define EE_DATA_TYPE uint32_t /*!< Type of Data */
|
|
||||||
#define EE_DATA_SHIFT 32U /*!< Bits Shifting to get Data value in element */
|
|
||||||
#define EE_MASK_VIRTUALADDRESS (uint64_t)0x000000000000FFFFU
|
|
||||||
#define EE_MASK_CRC (uint64_t)0x00000000FFFF0000U
|
|
||||||
#define EE_MASK_DATA (uint64_t)0xFFFFFFFF00000000U
|
|
||||||
#define EE_MASK_FULL (uint64_t)0xFFFFFFFFFFFFFFFFU
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Private macro -------------------------------------------------------------*/
|
|
||||||
/** @addtogroup EEPROM_Private_Macros
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Private functions ---------------------------------------------------------*/
|
|
||||||
/** @addtogroup EEPROM_Private_Functions
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
HAL_StatusTypeDef FI_WriteDoubleWord(uint32_t Address, uint64_t Data);
|
|
||||||
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages);
|
|
||||||
EE_Status FI_PageErase_IT(uint32_t Page, uint16_t NbPages);
|
|
||||||
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address);
|
|
||||||
EE_Status FI_CheckBankConfig(void);
|
|
||||||
void FI_CacheFlush(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#endif /* __FLASH_INTERFACE_H */
|
|
||||||
|
|
||||||
|
|
||||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
||||||
@@ -1,280 +0,0 @@
|
|||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* @file EEPROM_Emul/Porting/STM32G4/flash_interface.c
|
|
||||||
* @author MCD Application Team
|
|
||||||
* @brief This file provides all the EEPROM emulation flash interface functions.
|
|
||||||
******************************************************************************
|
|
||||||
* @attention
|
|
||||||
*
|
|
||||||
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
|
|
||||||
* All rights reserved.</center></h2>
|
|
||||||
*
|
|
||||||
* This software component is licensed by ST under BSD 3-Clause license,
|
|
||||||
* the "License"; You may not use this file except in compliance with the
|
|
||||||
* License. You may obtain a copy of the License at:
|
|
||||||
* opensource.org/licenses/BSD-3-Clause
|
|
||||||
*
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
|
||||||
#include "eeprom_emul.h"
|
|
||||||
#include "flash_interface.h"
|
|
||||||
|
|
||||||
/** @addtogroup EEPROM_Emulation
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Private typedef -----------------------------------------------------------*/
|
|
||||||
/* Private constants ---------------------------------------------------------*/
|
|
||||||
/* Private macro -------------------------------------------------------------*/
|
|
||||||
/* Private variables ---------------------------------------------------------*/
|
|
||||||
/* Private function prototypes -----------------------------------------------*/
|
|
||||||
#if defined(FLASH_BANK_2)
|
|
||||||
static uint32_t GetBankNumber(uint32_t Address);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Exported functions --------------------------------------------------------*/
|
|
||||||
/* Private functions ---------------------------------------------------------*/
|
|
||||||
/** @addtogroup EEPROM_Private_Functions
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Write a double word at the given address in Flash
|
|
||||||
* @param Address Where to write
|
|
||||||
* @param Data What to write
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE_WRITE_ERROR: if an error occurs
|
|
||||||
*/
|
|
||||||
HAL_StatusTypeDef FI_WriteDoubleWord(uint32_t Address, uint64_t Data)
|
|
||||||
{
|
|
||||||
return HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Erase a page in polling mode
|
|
||||||
* @param Page Page number
|
|
||||||
* @param NbPages Number of pages to erase
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages)
|
|
||||||
{
|
|
||||||
EE_Status status = EE_OK;
|
|
||||||
FLASH_EraseInitTypeDef s_eraseinit;
|
|
||||||
uint32_t bank = FLASH_BANK_1, page_error = 0U;
|
|
||||||
|
|
||||||
#if defined(FLASH_BANK_2)
|
|
||||||
bank = GetBankNumber(PAGE_ADDRESS(Page));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES;
|
|
||||||
s_eraseinit.NbPages = NbPages;
|
|
||||||
s_eraseinit.Page = Page;
|
|
||||||
s_eraseinit.Banks = bank;
|
|
||||||
|
|
||||||
/* Erase the Page: Set Page status to ERASED status */
|
|
||||||
if (HAL_FLASHEx_Erase(&s_eraseinit, &page_error) != HAL_OK)
|
|
||||||
{
|
|
||||||
status = EE_ERASE_ERROR;
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Erase a page with interrupt enabled
|
|
||||||
* @param Page Page number
|
|
||||||
* @param NbPages Number of pages to erase
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_PageErase_IT(uint32_t Page, uint16_t NbPages)
|
|
||||||
{
|
|
||||||
EE_Status status = EE_OK;
|
|
||||||
FLASH_EraseInitTypeDef s_eraseinit;
|
|
||||||
|
|
||||||
uint32_t bank = FLASH_BANK_1;
|
|
||||||
|
|
||||||
#if defined(FLASH_BANK_2)
|
|
||||||
bank = GetBankNumber(PAGE_ADDRESS(Page));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES;
|
|
||||||
s_eraseinit.NbPages = NbPages;
|
|
||||||
s_eraseinit.Page = Page;
|
|
||||||
s_eraseinit.Banks = bank;
|
|
||||||
|
|
||||||
/* Erase the Page: Set Page status to ERASED status */
|
|
||||||
if (HAL_FLASHEx_Erase_IT(&s_eraseinit) != HAL_OK)
|
|
||||||
{
|
|
||||||
status = EE_ERASE_ERROR;
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Flush the caches if needed to keep coherency when the flash content is modified
|
|
||||||
*/
|
|
||||||
void FI_CacheFlush()
|
|
||||||
{
|
|
||||||
/* To keep its coherency, flush the D-Cache: its content is not updated after a flash erase. */
|
|
||||||
__HAL_FLASH_DATA_CACHE_DISABLE();
|
|
||||||
__HAL_FLASH_DATA_CACHE_RESET();
|
|
||||||
__HAL_FLASH_DATA_CACHE_ENABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(FLASH_BANK_2)
|
|
||||||
/**
|
|
||||||
* @brief Gets the bank of a given address
|
|
||||||
* @param Address Address of the FLASH Memory
|
|
||||||
* @retval Bank_Number The bank of a given address
|
|
||||||
*/
|
|
||||||
static uint32_t GetBankNumber(uint32_t Address)
|
|
||||||
{
|
|
||||||
uint32_t bank = 0U;
|
|
||||||
|
|
||||||
if (READ_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_FB_MODE) == 0U)
|
|
||||||
{
|
|
||||||
/* No Bank swap */
|
|
||||||
if (Address < (FLASH_BASE + FLASH_BANK_SIZE))
|
|
||||||
{
|
|
||||||
bank = FLASH_BANK_1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bank = FLASH_BANK_2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Bank swap */
|
|
||||||
if (Address < (FLASH_BASE + FLASH_BANK_SIZE))
|
|
||||||
{
|
|
||||||
bank = FLASH_BANK_2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bank = FLASH_BANK_1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return bank;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Delete corrupted Flash address, can be called from NMI. No Timeout.
|
|
||||||
* @param Address Address of the FLASH Memory to delete
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address)
|
|
||||||
{
|
|
||||||
uint32_t dcachetoreactivate = 0U;
|
|
||||||
EE_Status status = EE_OK;
|
|
||||||
|
|
||||||
/* Deactivate the data cache if they are activated to avoid data misbehavior */
|
|
||||||
if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != RESET)
|
|
||||||
{
|
|
||||||
/* Disable data cache */
|
|
||||||
__HAL_FLASH_DATA_CACHE_DISABLE();
|
|
||||||
dcachetoreactivate = 1U;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set FLASH Programmation bit */
|
|
||||||
SET_BIT(FLASH->CR, FLASH_CR_PG);
|
|
||||||
|
|
||||||
/* Program double word of value 0 */
|
|
||||||
*(__IO uint32_t*)(Address) = (uint32_t)0U;
|
|
||||||
*(__IO uint32_t*)(Address+4U) = (uint32_t)0U;
|
|
||||||
|
|
||||||
/* Wait programmation completion */
|
|
||||||
while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if error occured */
|
|
||||||
if((__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PROGERR)) ||
|
|
||||||
(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR)) ||
|
|
||||||
(__HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGSERR)))
|
|
||||||
{
|
|
||||||
status = EE_DELETE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check FLASH End of Operation flag */
|
|
||||||
if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
|
|
||||||
{
|
|
||||||
/* Clear FLASH End of Operation pending bit */
|
|
||||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear FLASH Programmation bit */
|
|
||||||
CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
|
|
||||||
|
|
||||||
/* Flush the caches to be sure of the data consistency */
|
|
||||||
if(dcachetoreactivate == 1U)
|
|
||||||
{
|
|
||||||
/* Reset data cache */
|
|
||||||
__HAL_FLASH_DATA_CACHE_RESET();
|
|
||||||
/* Enable data cache */
|
|
||||||
__HAL_FLASH_DATA_CACHE_ENABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear FLASH ECCD bit */
|
|
||||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ECCD);
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Check if the configuration is 128-bits bank or 2*64-bits bank
|
|
||||||
* @param None
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_CheckBankConfig(void)
|
|
||||||
{
|
|
||||||
#if defined (FLASH_OPTR_DBANK)
|
|
||||||
FLASH_OBProgramInitTypeDef sOBCfg;
|
|
||||||
EE_Status status;
|
|
||||||
|
|
||||||
/* Request the Option Byte configuration :
|
|
||||||
- User and RDP level are always returned
|
|
||||||
- WRP and PCROP are not requested */
|
|
||||||
sOBCfg.WRPArea = 0xFF;
|
|
||||||
sOBCfg.PCROPConfig = 0xFF;
|
|
||||||
HAL_FLASHEx_OBGetConfig(&sOBCfg);
|
|
||||||
|
|
||||||
/* Check the value of the DBANK user option byte */
|
|
||||||
if ((sOBCfg.USERConfig & OB_DBANK_64_BITS) != 0)
|
|
||||||
{
|
|
||||||
status = EE_OK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
status = EE_INVALID_BANK_CFG;
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
|
||||||
#else
|
|
||||||
/* No feature 128-bits single bank, so always 64-bits dual bank */
|
|
||||||
return EE_OK;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
||||||
@@ -1,125 +0,0 @@
|
|||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* @file EEPROM_Emul/Porting/STM32G4/flash_interface.h
|
|
||||||
* @author MCD Application Team
|
|
||||||
* @brief This file contains all the functions prototypes for the EEPROM
|
|
||||||
* emulation flash interface.
|
|
||||||
******************************************************************************
|
|
||||||
* @attention
|
|
||||||
*
|
|
||||||
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
|
|
||||||
* All rights reserved.</center></h2>
|
|
||||||
*
|
|
||||||
* This software component is licensed by ST under BSD 3-Clause license,
|
|
||||||
* the "License"; You may not use this file except in compliance with the
|
|
||||||
* License. You may obtain a copy of the License at:
|
|
||||||
* opensource.org/licenses/BSD-3-Clause
|
|
||||||
*
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
|
||||||
#ifndef __FLASH_INTERFACE_H
|
|
||||||
#define __FLASH_INTERFACE_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
|
||||||
#include "stm32g4xx_hal.h"
|
|
||||||
#include "stm32g4xx_ll_crc.h"
|
|
||||||
#include "stm32g4xx_ll_bus.h"
|
|
||||||
|
|
||||||
/** @addtogroup EEPROM_Emulation
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Exported types ------------------------------------------------------------*/
|
|
||||||
/* Exported macro ------------------------------------------------------------*/
|
|
||||||
/* Exported functions ------------------------------------------------------- */
|
|
||||||
|
|
||||||
/* Private types -------------------------------------------------------------*/
|
|
||||||
/* Private constants ---------------------------------------------------------*/
|
|
||||||
/** @addtogroup EEPROM_Private_Constants
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @addtogroup Private_Other_Constants
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define BANK_SIZE FLASH_BANK_SIZE /*!< Alias to FLASH_BANK_SIZE definition from HAL STM32L4 */
|
|
||||||
#define EE_ACCESS_32BITS /*!< Enable EEPROM 32bits R/W functions, only valid for flash allowing 64bits access*/
|
|
||||||
|
|
||||||
/* Page state header */
|
|
||||||
#define EE_PAGESTAT_ERASED (uint64_t)0xFFFFFFFFFFFFFFFFU /*!< State saved in 1st,2nd,3rd,4th data type of page header */
|
|
||||||
#define EE_PAGESTAT_RECEIVE (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 1st data type of page header */
|
|
||||||
#define EE_PAGESTAT_ACTIVE (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 2nd data type of page header */
|
|
||||||
#define EE_PAGESTAT_VALID (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 3rd data type of page header */
|
|
||||||
#define EE_PAGESTAT_ERASING (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 4th data type of page header */
|
|
||||||
|
|
||||||
/* Description of the 8 Bytes (64 bits) element in flash */
|
|
||||||
/* Bit: 63 32 31 16 15 0 */
|
|
||||||
/* <--- Data Value -----> <-unused-> <-VirtAddr-> */
|
|
||||||
#define EE_ELEMENT_SIZE 8U /*!< Size of element in Bytes */
|
|
||||||
#define EE_ELEMENT_TYPE uint64_t /*!< Type of element */
|
|
||||||
#define EE_VIRTUALADDRESS_TYPE uint16_t /*!< Type of Virtual Address */
|
|
||||||
#define EE_VIRTUALADDRESS_SHIFT 0U /*!< Bits Shifting to get Virtual Address in element */
|
|
||||||
#define EE_CRC_TYPE uint16_t /*!< Type of Crc */
|
|
||||||
#define EE_CRC_SHIFT 16U /*!< Bits Shifting to get Crc in element */
|
|
||||||
#define EE_DATA_TYPE uint32_t /*!< Type of Data */
|
|
||||||
#define EE_DATA_SHIFT 32U /*!< Bits Shifting to get Data value in element */
|
|
||||||
#define EE_MASK_VIRTUALADDRESS (uint64_t)0x000000000000FFFFU
|
|
||||||
#define EE_MASK_CRC (uint64_t)0x00000000FFFF0000U
|
|
||||||
#define EE_MASK_DATA (uint64_t)0xFFFFFFFF00000000U
|
|
||||||
#define EE_MASK_FULL (uint64_t)0xFFFFFFFFFFFFFFFFU
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Private macro -------------------------------------------------------------*/
|
|
||||||
/** @addtogroup EEPROM_Private_Macros
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Private functions ---------------------------------------------------------*/
|
|
||||||
/** @addtogroup EEPROM_Private_Functions
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
HAL_StatusTypeDef FI_WriteDoubleWord(uint32_t Address, uint64_t Data);
|
|
||||||
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages);
|
|
||||||
EE_Status FI_PageErase_IT(uint32_t Page, uint16_t NbPages);
|
|
||||||
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address);
|
|
||||||
EE_Status FI_CheckBankConfig(void);
|
|
||||||
void FI_CacheFlush(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#endif /* __FLASH_INTERFACE_H */
|
|
||||||
|
|
||||||
|
|
||||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
||||||
@@ -1,279 +0,0 @@
|
|||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* @file EEPROM_Emul/Porting/STM32L4/flash_interface.c
|
|
||||||
* @author MCD Application Team
|
|
||||||
* @brief This file provides all the EEPROM emulation flash interface functions.
|
|
||||||
******************************************************************************
|
|
||||||
* @attention
|
|
||||||
*
|
|
||||||
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
|
|
||||||
* All rights reserved.</center></h2>
|
|
||||||
*
|
|
||||||
* This software component is licensed by ST under BSD 3-Clause license,
|
|
||||||
* the "License"; You may not use this file except in compliance with the
|
|
||||||
* License. You may obtain a copy of the License at:
|
|
||||||
* opensource.org/licenses/BSD-3-Clause
|
|
||||||
*
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
|
||||||
#include "eeprom_emul.h"
|
|
||||||
#include "flash_interface.h"
|
|
||||||
|
|
||||||
/** @addtogroup EEPROM_Emulation
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Private typedef -----------------------------------------------------------*/
|
|
||||||
/* Private constants ---------------------------------------------------------*/
|
|
||||||
/* Private macro -------------------------------------------------------------*/
|
|
||||||
/* Private variables ---------------------------------------------------------*/
|
|
||||||
/* Private function prototypes -----------------------------------------------*/
|
|
||||||
#if defined(FLASH_BANK_2)
|
|
||||||
static uint32_t GetBankNumber(uint32_t Address);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Exported functions --------------------------------------------------------*/
|
|
||||||
/* Private functions ---------------------------------------------------------*/
|
|
||||||
/** @addtogroup EEPROM_Private_Functions
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Write a double word at the given address in Flash
|
|
||||||
* @param Address Where to write
|
|
||||||
* @param Data What to write
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE_WRITE_ERROR: if an error occurs
|
|
||||||
*/
|
|
||||||
HAL_StatusTypeDef FI_WriteDoubleWord(uint32_t Address, uint64_t Data)
|
|
||||||
{
|
|
||||||
return HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Erase a page in polling mode
|
|
||||||
* @param Page Page number
|
|
||||||
* @param NbPages Number of pages to erase
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages)
|
|
||||||
{
|
|
||||||
EE_Status status = EE_OK;
|
|
||||||
FLASH_EraseInitTypeDef s_eraseinit;
|
|
||||||
uint32_t bank = FLASH_BANK_1, page_error = 0U;
|
|
||||||
|
|
||||||
#if defined(FLASH_BANK_2)
|
|
||||||
bank = GetBankNumber(PAGE_ADDRESS(Page));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES;
|
|
||||||
s_eraseinit.NbPages = NbPages;
|
|
||||||
s_eraseinit.Page = Page;
|
|
||||||
s_eraseinit.Banks = bank;
|
|
||||||
|
|
||||||
/* Erase the Page: Set Page status to ERASED status */
|
|
||||||
if (HAL_FLASHEx_Erase(&s_eraseinit, &page_error) != HAL_OK)
|
|
||||||
{
|
|
||||||
status = EE_ERASE_ERROR;
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Erase a page with interrupt enabled
|
|
||||||
* @param Page Page number
|
|
||||||
* @param NbPages Number of pages to erase
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_PageErase_IT(uint32_t Page, uint16_t NbPages)
|
|
||||||
{
|
|
||||||
EE_Status status = EE_OK;
|
|
||||||
FLASH_EraseInitTypeDef s_eraseinit;
|
|
||||||
uint32_t bank = FLASH_BANK_1;
|
|
||||||
|
|
||||||
#if defined(FLASH_BANK_2)
|
|
||||||
bank = GetBankNumber(PAGE_ADDRESS(Page));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES;
|
|
||||||
s_eraseinit.NbPages = NbPages;
|
|
||||||
s_eraseinit.Page = Page;
|
|
||||||
s_eraseinit.Banks = bank;
|
|
||||||
|
|
||||||
/* Erase the Page: Set Page status to ERASED status */
|
|
||||||
if (HAL_FLASHEx_Erase_IT(&s_eraseinit) != HAL_OK)
|
|
||||||
{
|
|
||||||
status = EE_ERASE_ERROR;
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Flush the caches if needed to keep coherency when the flash content is modified
|
|
||||||
*/
|
|
||||||
void FI_CacheFlush()
|
|
||||||
{
|
|
||||||
/* To keep its coherency, flush the D-Cache: its content is not updated after a flash erase. */
|
|
||||||
__HAL_FLASH_DATA_CACHE_DISABLE();
|
|
||||||
__HAL_FLASH_DATA_CACHE_RESET();
|
|
||||||
__HAL_FLASH_DATA_CACHE_ENABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(FLASH_BANK_2)
|
|
||||||
/**
|
|
||||||
* @brief Gets the bank of a given address
|
|
||||||
* @param Address Address of the FLASH Memory
|
|
||||||
* @retval Bank_Number The bank of a given address
|
|
||||||
*/
|
|
||||||
static uint32_t GetBankNumber(uint32_t Address)
|
|
||||||
{
|
|
||||||
uint32_t bank = 0U;
|
|
||||||
|
|
||||||
if (READ_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_FB_MODE) == 0U)
|
|
||||||
{
|
|
||||||
/* No Bank swap */
|
|
||||||
if (Address < (FLASH_BASE + FLASH_BANK_SIZE))
|
|
||||||
{
|
|
||||||
bank = FLASH_BANK_1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bank = FLASH_BANK_2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Bank swap */
|
|
||||||
if (Address < (FLASH_BASE + FLASH_BANK_SIZE))
|
|
||||||
{
|
|
||||||
bank = FLASH_BANK_2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bank = FLASH_BANK_1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return bank;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Delete corrupted Flash address, can be called from NMI. No Timeout.
|
|
||||||
* @param Address Address of the FLASH Memory to delete
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address)
|
|
||||||
{
|
|
||||||
uint32_t dcachetoreactivate = 0U;
|
|
||||||
EE_Status status = EE_OK;
|
|
||||||
|
|
||||||
/* Deactivate the data cache if they are activated to avoid data misbehavior */
|
|
||||||
if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != RESET)
|
|
||||||
{
|
|
||||||
/* Disable data cache */
|
|
||||||
__HAL_FLASH_DATA_CACHE_DISABLE();
|
|
||||||
dcachetoreactivate = 1U;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set FLASH Programmation bit */
|
|
||||||
SET_BIT(FLASH->CR, FLASH_CR_PG);
|
|
||||||
|
|
||||||
/* Program double word of value 0 */
|
|
||||||
*(__IO uint32_t*)(Address) = (uint32_t)0U;
|
|
||||||
*(__IO uint32_t*)(Address+4U) = (uint32_t)0U;
|
|
||||||
|
|
||||||
/* Wait programmation completion */
|
|
||||||
while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if error occured */
|
|
||||||
if((__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PROGERR)) ||
|
|
||||||
(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR)) ||
|
|
||||||
(__HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGSERR)))
|
|
||||||
{
|
|
||||||
status = EE_DELETE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check FLASH End of Operation flag */
|
|
||||||
if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
|
|
||||||
{
|
|
||||||
/* Clear FLASH End of Operation pending bit */
|
|
||||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear FLASH Programmation bit */
|
|
||||||
CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
|
|
||||||
|
|
||||||
/* Flush the caches to be sure of the data consistency */
|
|
||||||
if(dcachetoreactivate == 1U)
|
|
||||||
{
|
|
||||||
/* Reset data cache */
|
|
||||||
__HAL_FLASH_DATA_CACHE_RESET();
|
|
||||||
/* Enable data cache */
|
|
||||||
__HAL_FLASH_DATA_CACHE_ENABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear FLASH ECCD bit */
|
|
||||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ECCD);
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Check if the configuration is 128-bits bank or 2*64-bits bank
|
|
||||||
* @param None
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_CheckBankConfig(void)
|
|
||||||
{
|
|
||||||
#if defined (FLASH_OPTR_DBANK)
|
|
||||||
FLASH_OBProgramInitTypeDef sOBCfg;
|
|
||||||
EE_Status status;
|
|
||||||
|
|
||||||
/* Request the Option Byte configuration :
|
|
||||||
- User and RDP level are always returned
|
|
||||||
- WRP and PCROP are not requested */
|
|
||||||
sOBCfg.WRPArea = 0xFF;
|
|
||||||
sOBCfg.PCROPConfig = 0xFF;
|
|
||||||
HAL_FLASHEx_OBGetConfig(&sOBCfg);
|
|
||||||
|
|
||||||
/* Check the value of the DBANK user option byte */
|
|
||||||
if ((sOBCfg.USERConfig & OB_DBANK_64_BITS) != 0)
|
|
||||||
{
|
|
||||||
status = EE_OK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
status = EE_INVALID_BANK_CFG;
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
|
||||||
#else
|
|
||||||
/* No feature 128-bits single bank, so always 64-bits dual bank */
|
|
||||||
return EE_OK;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
||||||
@@ -1,267 +0,0 @@
|
|||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* @file EEPROM_Emul/Porting/STM32L5/flash_interface.c
|
|
||||||
* @author MCD Application Team
|
|
||||||
* @brief This file provides all the EEPROM emulation flash interface functions.
|
|
||||||
******************************************************************************
|
|
||||||
* @attention
|
|
||||||
*
|
|
||||||
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
|
|
||||||
* All rights reserved.</center></h2>
|
|
||||||
*
|
|
||||||
* This software component is licensed by ST under BSD 3-Clause license,
|
|
||||||
* the "License"; You may not use this file except in compliance with the
|
|
||||||
* License. You may obtain a copy of the License at:
|
|
||||||
* opensource.org/licenses/BSD-3-Clause
|
|
||||||
*
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
|
||||||
#include "eeprom_emul.h"
|
|
||||||
#include "flash_interface.h"
|
|
||||||
|
|
||||||
/** @addtogroup EEPROM_Emulation
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Private typedef -----------------------------------------------------------*/
|
|
||||||
/* Private constants ---------------------------------------------------------*/
|
|
||||||
/* Private macro -------------------------------------------------------------*/
|
|
||||||
/* Private variables ---------------------------------------------------------*/
|
|
||||||
/* Private function prototypes -----------------------------------------------*/
|
|
||||||
#ifdef FLASH_BANK_2
|
|
||||||
static uint32_t GetBankNumber(uint32_t Address);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Exported functions --------------------------------------------------------*/
|
|
||||||
/* Private functions ---------------------------------------------------------*/
|
|
||||||
/** @addtogroup EEPROM_Private_Functions
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Write a double word at the given address in Flash
|
|
||||||
* @param Address Where to write
|
|
||||||
* @param Data What to write
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE_WRITE_ERROR: if an error occurs
|
|
||||||
*/
|
|
||||||
HAL_StatusTypeDef FI_WriteDoubleWord(uint32_t Address, uint64_t Data)
|
|
||||||
{
|
|
||||||
return HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, Data);
|
|
||||||
/* If TrustZone secure activated -> return HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD_NS, Address, Data); */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Erase a page in polling mode
|
|
||||||
* @param Page Page number
|
|
||||||
* @param NbPages Number of pages to erase
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages)
|
|
||||||
{
|
|
||||||
EE_Status status = EE_OK;
|
|
||||||
FLASH_EraseInitTypeDef s_eraseinit;
|
|
||||||
uint32_t bank = FLASH_BANK_1, page_error = 0U;
|
|
||||||
|
|
||||||
#ifdef FLASH_BANK_2
|
|
||||||
bank = GetBankNumber(PAGE_ADDRESS(Page));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; /* if TrustZone secure activated -> FLASH_TYPEERASE_PAGES_NS; */
|
|
||||||
s_eraseinit.NbPages = NbPages;
|
|
||||||
s_eraseinit.Page = Page;
|
|
||||||
s_eraseinit.Banks = bank;
|
|
||||||
|
|
||||||
/* Erase the Page: Set Page status to ERASED status */
|
|
||||||
if (HAL_FLASHEx_Erase(&s_eraseinit, &page_error) != HAL_OK)
|
|
||||||
{
|
|
||||||
status = EE_ERASE_ERROR;
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Erase a page with interrupt enabled
|
|
||||||
* @param Page Page number
|
|
||||||
* @param NbPages Number of pages to erase
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_PageErase_IT(uint32_t Page, uint16_t NbPages)
|
|
||||||
{
|
|
||||||
EE_Status status = EE_OK;
|
|
||||||
FLASH_EraseInitTypeDef s_eraseinit;
|
|
||||||
uint32_t bank = FLASH_BANK_1;
|
|
||||||
|
|
||||||
#ifdef FLASH_BANK_2
|
|
||||||
bank = GetBankNumber(PAGE_ADDRESS(Page));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; /* if TrustZone secure activated -> FLASH_TYPEERASE_PAGES_NS; */
|
|
||||||
s_eraseinit.NbPages = NbPages;
|
|
||||||
s_eraseinit.Page = Page;
|
|
||||||
s_eraseinit.Banks = bank;
|
|
||||||
|
|
||||||
/* Erase the Page: Set Page status to ERASED status */
|
|
||||||
if (HAL_FLASHEx_Erase_IT(&s_eraseinit) != HAL_OK)
|
|
||||||
{
|
|
||||||
status = EE_ERASE_ERROR;
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Flush the caches if needed to keep coherency when the flash content is modified
|
|
||||||
*/
|
|
||||||
void FI_CacheFlush()
|
|
||||||
{
|
|
||||||
/* No flush needed. EEPROM flash area is defined as non-cacheable thanks to the MPU in main.c. */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef FLASH_BANK_2
|
|
||||||
/**
|
|
||||||
* @brief Gets the bank of a given address
|
|
||||||
* @param Address Address of the FLASH Memory
|
|
||||||
* @retval Bank_Number The bank of a given address
|
|
||||||
*/
|
|
||||||
static uint32_t GetBankNumber(uint32_t Address)
|
|
||||||
{
|
|
||||||
uint32_t bank = 0U;
|
|
||||||
|
|
||||||
if (READ_BIT(FLASH->OPTR, FLASH_OPTR_SWAP_BANK) == 0U)
|
|
||||||
{
|
|
||||||
/* No Bank swap */
|
|
||||||
if (Address < (FLASH_BASE + FLASH_BANK_SIZE))
|
|
||||||
{
|
|
||||||
bank = FLASH_BANK_1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bank = FLASH_BANK_2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Bank swap */
|
|
||||||
if (Address < (FLASH_BASE + FLASH_BANK_SIZE))
|
|
||||||
{
|
|
||||||
bank = FLASH_BANK_2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bank = FLASH_BANK_1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return bank;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Delete corrupted Flash address, can be called from NMI. No Timeout.
|
|
||||||
* @param Address Address of the FLASH Memory to delete
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address)
|
|
||||||
{
|
|
||||||
EE_Status status = EE_OK;
|
|
||||||
|
|
||||||
/* Wait for previous programmation completion */
|
|
||||||
while(__HAL_FLASH_GET_FLAG(FLASH_NSSR_NSBSY))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear previous non-secure error programming flag */
|
|
||||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
|
|
||||||
|
|
||||||
/* Set FLASH Programmation bit */
|
|
||||||
SET_BIT(FLASH->NSCR, FLASH_NSCR_NSPG);
|
|
||||||
|
|
||||||
/* Program double word of value 0 */
|
|
||||||
*(__IO uint32_t*)(Address) = (uint32_t)0U;
|
|
||||||
*(__IO uint32_t*)(Address+4U) = (uint32_t)0U;
|
|
||||||
|
|
||||||
/* Wait programmation completion */
|
|
||||||
while(__HAL_FLASH_GET_FLAG(FLASH_NSSR_NSBSY))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if error occured */
|
|
||||||
if((__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PROGERR)) ||
|
|
||||||
(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR)) ||
|
|
||||||
(__HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGSERR)))
|
|
||||||
{
|
|
||||||
status = EE_DELETE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check FLASH End of Operation flag */
|
|
||||||
if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
|
|
||||||
{
|
|
||||||
/* Clear FLASH End of Operation pending bit */
|
|
||||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear FLASH Programmation bit */
|
|
||||||
CLEAR_BIT(FLASH->NSCR, FLASH_NSCR_NSPG);
|
|
||||||
|
|
||||||
/* Clear FLASH ECCD bit */
|
|
||||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ECCD);
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Check if the configuration is 128-bits bank or 2*64-bits bank
|
|
||||||
* @param None
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_CheckBankConfig(void)
|
|
||||||
{
|
|
||||||
#if defined (FLASH_OPTR_DBANK)
|
|
||||||
FLASH_OBProgramInitTypeDef sOBCfg;
|
|
||||||
EE_Status status;
|
|
||||||
|
|
||||||
/* Request the Option Byte configuration :
|
|
||||||
- User and RDP level are always returned
|
|
||||||
- WRP and PCROP are not requested */
|
|
||||||
sOBCfg.WRPArea = 0xFF;
|
|
||||||
HAL_FLASHEx_OBGetConfig(&sOBCfg);
|
|
||||||
|
|
||||||
/* Check the value of the DBANK user option byte */
|
|
||||||
if ((sOBCfg.USERConfig & OB_DBANK_64_BITS) != 0)
|
|
||||||
{
|
|
||||||
status = EE_OK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
status = EE_INVALID_BANK_CFG;
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
|
||||||
#else
|
|
||||||
/* No feature 128-bits single bank, so always 64-bits dual bank */
|
|
||||||
return EE_OK;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
||||||
@@ -1,126 +0,0 @@
|
|||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* @file EEPROM_Emul/Porting/STM32L5/flash_interface.h
|
|
||||||
* @author MCD Application Team
|
|
||||||
* @brief This file contains all the functions prototypes for the EEPROM
|
|
||||||
* emulation flash interface.
|
|
||||||
******************************************************************************
|
|
||||||
* @attention
|
|
||||||
*
|
|
||||||
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
|
|
||||||
* All rights reserved.</center></h2>
|
|
||||||
*
|
|
||||||
* This software component is licensed by ST under BSD 3-Clause license,
|
|
||||||
* the "License"; You may not use this file except in compliance with the
|
|
||||||
* License. You may obtain a copy of the License at:
|
|
||||||
* opensource.org/licenses/BSD-3-Clause
|
|
||||||
*
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
|
||||||
#ifndef __FLASH_INTERFACE_H
|
|
||||||
#define __FLASH_INTERFACE_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
|
||||||
#include "stm32l5xx_hal.h"
|
|
||||||
#include "stm32l5xx_ll_crc.h"
|
|
||||||
#include "stm32l5xx_ll_bus.h"
|
|
||||||
|
|
||||||
/** @addtogroup EEPROM_Emulation
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Exported types ------------------------------------------------------------*/
|
|
||||||
/* Exported macro ------------------------------------------------------------*/
|
|
||||||
/* Exported functions ------------------------------------------------------- */
|
|
||||||
|
|
||||||
/* Private types -------------------------------------------------------------*/
|
|
||||||
/* Private constants ---------------------------------------------------------*/
|
|
||||||
/** @addtogroup EEPROM_Private_Constants
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @addtogroup Private_Other_Constants
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define BANK_SIZE FLASH_BANK_SIZE /*!< Alias to FLASH_BANK_SIZE definition from HAL STM32L4 */
|
|
||||||
#define EE_ACCESS_32BITS /*!< Enable EEPROM 32bits R/W functions, only valid for flash allowing 64bits access*/
|
|
||||||
|
|
||||||
/* Page state header */
|
|
||||||
#define EE_PAGESTAT_ERASED (uint64_t)0xFFFFFFFFFFFFFFFFU /*!< State saved in 1st,2nd,3rd,4th data type of page header */
|
|
||||||
#define EE_PAGESTAT_RECEIVE (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 1st data type of page header */
|
|
||||||
#define EE_PAGESTAT_ACTIVE (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 2nd data type of page header */
|
|
||||||
#define EE_PAGESTAT_VALID (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 3rd data type of page header */
|
|
||||||
#define EE_PAGESTAT_ERASING (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 4th data type of page header */
|
|
||||||
|
|
||||||
/* Description of the 8 Bytes (64 bits) element in flash */
|
|
||||||
/* Bit: 63 32 31 16 15 0 */
|
|
||||||
/* <--- Data Value -----> <-unused-> <-VirtAddr-> */
|
|
||||||
#define EE_ELEMENT_SIZE 8U /*!< Size of element in Bytes */
|
|
||||||
#define EE_ELEMENT_TYPE uint64_t /*!< Type of element */
|
|
||||||
#define EE_VIRTUALADDRESS_TYPE uint16_t /*!< Type of Virtual Address */
|
|
||||||
#define EE_VIRTUALADDRESS_SHIFT 0U /*!< Bits Shifting to get Virtual Address in element */
|
|
||||||
#define EE_CRC_TYPE uint16_t /*!< Type of Crc */
|
|
||||||
#define EE_CRC_SHIFT 16U /*!< Bits Shifting to get Crc in element */
|
|
||||||
#define EE_DATA_TYPE uint32_t /*!< Type of Data */
|
|
||||||
#define EE_DATA_SHIFT 32U /*!< Bits Shifting to get Data value in element */
|
|
||||||
#define EE_MASK_VIRTUALADDRESS (uint64_t)0x000000000000FFFFU
|
|
||||||
#define EE_MASK_CRC (uint64_t)0x00000000FFFF0000U
|
|
||||||
#define EE_MASK_DATA (uint64_t)0xFFFFFFFF00000000U
|
|
||||||
#define EE_MASK_FULL (uint64_t)0xFFFFFFFFFFFFFFFFU
|
|
||||||
|
|
||||||
#define SECURE_FEATURE /*!< Informs the driver about the security features of the flash interface */
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Private macro -------------------------------------------------------------*/
|
|
||||||
/** @addtogroup EEPROM_Private_Macros
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Private functions ---------------------------------------------------------*/
|
|
||||||
/** @addtogroup EEPROM_Private_Functions
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
HAL_StatusTypeDef FI_WriteDoubleWord(uint32_t Address, uint64_t Data);
|
|
||||||
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages);
|
|
||||||
EE_Status FI_PageErase_IT(uint32_t Page, uint16_t NbPages);
|
|
||||||
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address);
|
|
||||||
EE_Status FI_CheckBankConfig(void);
|
|
||||||
void FI_CacheFlush(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#endif /* __FLASH_INTERFACE_H */
|
|
||||||
|
|
||||||
|
|
||||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
||||||
@@ -1,299 +0,0 @@
|
|||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* @file EEPROM_Emul/Porting/STM32L5/flash_interface.c
|
|
||||||
* @author MCD Application Team
|
|
||||||
* @brief This file provides all the EEPROM emulation flash interface functions.
|
|
||||||
******************************************************************************
|
|
||||||
* @attention
|
|
||||||
*
|
|
||||||
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
|
|
||||||
* All rights reserved.</center></h2>
|
|
||||||
*
|
|
||||||
* This software component is licensed by ST under BSD 3-Clause license,
|
|
||||||
* the "License"; You may not use this file except in compliance with the
|
|
||||||
* License. You may obtain a copy of the License at:
|
|
||||||
* opensource.org/licenses/BSD-3-Clause
|
|
||||||
*
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
|
||||||
#include "eeprom_emul.h"
|
|
||||||
#include "flash_interface.h"
|
|
||||||
|
|
||||||
/** @addtogroup EEPROM_Emulation
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Private typedef -----------------------------------------------------------*/
|
|
||||||
/* Private constants ---------------------------------------------------------*/
|
|
||||||
/* Private macro -------------------------------------------------------------*/
|
|
||||||
/* Private variables ---------------------------------------------------------*/
|
|
||||||
uint64_t FlashWord[2] =
|
|
||||||
{
|
|
||||||
0x0, 0x0
|
|
||||||
};
|
|
||||||
uint8_t FlashWord_status = 0; /* 0 is FlashWord is empty, 1 it is full */
|
|
||||||
const uint32_t QuadWord[4] =
|
|
||||||
{
|
|
||||||
0x00000000,
|
|
||||||
0x00000000,
|
|
||||||
0x00000000,
|
|
||||||
0x00000000
|
|
||||||
};
|
|
||||||
/* Private function prototypes -----------------------------------------------*/
|
|
||||||
#ifdef FLASH_BANK_2
|
|
||||||
static uint32_t GetBankNumber(uint32_t Address);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Exported functions --------------------------------------------------------*/
|
|
||||||
/* Private functions ---------------------------------------------------------*/
|
|
||||||
/** @addtogroup EEPROM_Private_Functions
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Write a quad word at the given address in Flash (function is called FI_WriteDoubleWord to respect legacy for X-CUBE-EEPROM)
|
|
||||||
* @param Address Where to write
|
|
||||||
* @param Data What to write
|
|
||||||
* @param Write_type Type of writing on going (see EE_Write_type)
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE_WRITE_ERROR: if an error occurs
|
|
||||||
* - EE_FLASH_USED: flash currently used by CPU2
|
|
||||||
*/
|
|
||||||
EE_Status FI_WriteDoubleWord(uint32_t Address, uint64_t* Data, EE_Write_type Write_type)
|
|
||||||
{
|
|
||||||
EE_Status status = EE_OK;
|
|
||||||
|
|
||||||
if(Write_type == EE_SET_PAGE)
|
|
||||||
{
|
|
||||||
FlashWord[0] = Data[0];
|
|
||||||
FlashWord[1] = Data[0];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FlashWord[0] = Data[0];
|
|
||||||
FlashWord[1] = Data[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD, Address, ((uint32_t)FlashWord)) != HAL_OK)
|
|
||||||
{
|
|
||||||
status = EE_WRITE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Erase a page in polling mode
|
|
||||||
* @param Page Page number
|
|
||||||
* @param NbPages Number of pages to erase
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages)
|
|
||||||
{
|
|
||||||
EE_Status status = EE_OK;
|
|
||||||
FLASH_EraseInitTypeDef s_eraseinit;
|
|
||||||
uint32_t bank = FLASH_BANK_1, page_error = 0U;
|
|
||||||
|
|
||||||
#ifdef FLASH_BANK_2
|
|
||||||
bank = GetBankNumber(PAGE_ADDRESS(Page));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; /* if TrustZone secure activated -> FLASH_TYPEERASE_PAGES_NS; */
|
|
||||||
s_eraseinit.NbPages = NbPages;
|
|
||||||
s_eraseinit.Page = Page;
|
|
||||||
s_eraseinit.Banks = bank;
|
|
||||||
|
|
||||||
/* Erase the Page: Set Page status to ERASED status */
|
|
||||||
if (HAL_FLASHEx_Erase(&s_eraseinit, &page_error) != HAL_OK)
|
|
||||||
{
|
|
||||||
status = EE_ERASE_ERROR;
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Erase a page with interrupt enabled
|
|
||||||
* @param Page Page number
|
|
||||||
* @param NbPages Number of pages to erase
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_PageErase_IT(uint32_t Page, uint16_t NbPages)
|
|
||||||
{
|
|
||||||
EE_Status status = EE_OK;
|
|
||||||
FLASH_EraseInitTypeDef s_eraseinit;
|
|
||||||
uint32_t bank = FLASH_BANK_1;
|
|
||||||
|
|
||||||
#ifdef FLASH_BANK_2
|
|
||||||
bank = GetBankNumber(PAGE_ADDRESS(Page));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; /* if TrustZone secure activated -> FLASH_TYPEERASE_PAGES_NS; */
|
|
||||||
s_eraseinit.NbPages = NbPages;
|
|
||||||
s_eraseinit.Page = Page;
|
|
||||||
s_eraseinit.Banks = bank;
|
|
||||||
|
|
||||||
/* Erase the Page: Set Page status to ERASED status */
|
|
||||||
if (HAL_FLASHEx_Erase_IT(&s_eraseinit) != HAL_OK)
|
|
||||||
{
|
|
||||||
status = EE_ERASE_ERROR;
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Flush the caches if needed to keep coherency when the flash content is modified
|
|
||||||
*/
|
|
||||||
void FI_CacheFlush()
|
|
||||||
{
|
|
||||||
/* No flush needed. EEPROM flash area is defined as non-cacheable thanks to the MPU in main.c. */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef FLASH_BANK_2
|
|
||||||
/**
|
|
||||||
* @brief Gets the bank of a given address
|
|
||||||
* @param Address Address of the FLASH Memory
|
|
||||||
* @retval Bank_Number The bank of a given address
|
|
||||||
*/
|
|
||||||
static uint32_t GetBankNumber(uint32_t Address)
|
|
||||||
{
|
|
||||||
uint32_t bank = 0U;
|
|
||||||
|
|
||||||
if (READ_BIT(FLASH->OPTR, FLASH_OPTR_SWAP_BANK) == 0U)
|
|
||||||
{
|
|
||||||
/* No Bank swap */
|
|
||||||
if (Address < (FLASH_BASE + FLASH_BANK_SIZE))
|
|
||||||
{
|
|
||||||
bank = FLASH_BANK_1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bank = FLASH_BANK_2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Bank swap */
|
|
||||||
if (Address < (FLASH_BASE + FLASH_BANK_SIZE))
|
|
||||||
{
|
|
||||||
bank = FLASH_BANK_2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bank = FLASH_BANK_1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return bank;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Delete corrupted Flash address, can be called from NMI. No Timeout.
|
|
||||||
* @param Address Address of the FLASH Memory to delete
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address)
|
|
||||||
{
|
|
||||||
EE_Status status = EE_OK;
|
|
||||||
|
|
||||||
/* Wait for previous programmation completion */
|
|
||||||
while(__HAL_FLASH_GET_FLAG(FLASH_NSSR_BSY))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear previous non-secure error programming flag */
|
|
||||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
|
|
||||||
|
|
||||||
/* Set FLASH Programmation bit */
|
|
||||||
SET_BIT(FLASH->NSCR, FLASH_NSCR_PG);
|
|
||||||
|
|
||||||
/* Program quad word of value 0 */
|
|
||||||
// HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD, Address, ((uint32_t)QuadWord));
|
|
||||||
*(__IO uint64_t*)(Address) = (uint64_t)0U;
|
|
||||||
*(__IO uint64_t*)(Address+8U) = (uint64_t)0U;
|
|
||||||
|
|
||||||
/* Wait programmation completion */
|
|
||||||
while(__HAL_FLASH_GET_FLAG(FLASH_NSSR_BSY))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if error occured */
|
|
||||||
if((__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PROGERR)) ||
|
|
||||||
(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR)) ||
|
|
||||||
(__HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGSERR)))
|
|
||||||
{
|
|
||||||
status = EE_DELETE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check FLASH End of Operation flag */
|
|
||||||
if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
|
|
||||||
{
|
|
||||||
/* Clear FLASH End of Operation pending bit */
|
|
||||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear FLASH Programmation bit */
|
|
||||||
CLEAR_BIT(FLASH->NSCR, FLASH_NSCR_PG);
|
|
||||||
|
|
||||||
/* Clear FLASH ECCD bit */
|
|
||||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ECCD);
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Check if the configuration is 128-bits bank or 2*64-bits bank
|
|
||||||
* @param None
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_CheckBankConfig(void)
|
|
||||||
{
|
|
||||||
#if defined (FLASH_OPTR_DBANK)
|
|
||||||
FLASH_OBProgramInitTypeDef sOBCfg;
|
|
||||||
EE_Status status;
|
|
||||||
|
|
||||||
/* Request the Option Byte configuration :
|
|
||||||
- User and RDP level are always returned
|
|
||||||
- WRP and PCROP are not requested */
|
|
||||||
sOBCfg.WRPArea = 0xFF;
|
|
||||||
HAL_FLASHEx_OBGetConfig(&sOBCfg);
|
|
||||||
|
|
||||||
/* Check the value of the DBANK user option byte */
|
|
||||||
if ((sOBCfg.USERConfig & OB_DBANK_64_BITS) != 0)
|
|
||||||
{
|
|
||||||
status = EE_OK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
status = EE_INVALID_BANK_CFG;
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
|
||||||
#else
|
|
||||||
/* No feature 128-bits single bank, so always 64-bits dual bank */
|
|
||||||
return EE_OK;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
||||||
@@ -1,126 +0,0 @@
|
|||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* @file EEPROM_Emul/Porting/STM32L5/flash_interface.h
|
|
||||||
* @author MCD Application Team
|
|
||||||
* @brief This file contains all the functions prototypes for the EEPROM
|
|
||||||
* emulation flash interface.
|
|
||||||
******************************************************************************
|
|
||||||
* @attention
|
|
||||||
*
|
|
||||||
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
|
|
||||||
* All rights reserved.</center></h2>
|
|
||||||
*
|
|
||||||
* This software component is licensed by ST under BSD 3-Clause license,
|
|
||||||
* the "License"; You may not use this file except in compliance with the
|
|
||||||
* License. You may obtain a copy of the License at:
|
|
||||||
* opensource.org/licenses/BSD-3-Clause
|
|
||||||
*
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
|
||||||
#ifndef __FLASH_INTERFACE_H
|
|
||||||
#define __FLASH_INTERFACE_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
|
||||||
#include "stm32u5xx_hal.h"
|
|
||||||
#include "stm32u5xx_ll_crc.h"
|
|
||||||
#include "stm32u5xx_ll_bus.h"
|
|
||||||
|
|
||||||
/** @addtogroup EEPROM_Emulation
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Exported types ------------------------------------------------------------*/
|
|
||||||
/* Exported macro ------------------------------------------------------------*/
|
|
||||||
/* Exported functions ------------------------------------------------------- */
|
|
||||||
|
|
||||||
/* Private types -------------------------------------------------------------*/
|
|
||||||
/* Private constants ---------------------------------------------------------*/
|
|
||||||
/** @addtogroup EEPROM_Private_Constants
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @addtogroup Private_Other_Constants
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define BANK_SIZE FLASH_BANK_SIZE /*!< Alias to FLASH_BANK_SIZE definition from HAL */
|
|
||||||
#define EE_ACCESS_32BITS /*!< Enable EEPROM 32bits R/W functions */
|
|
||||||
|
|
||||||
/* Page state header */
|
|
||||||
#define EE_PAGESTAT_ERASED (uint64_t)0xFFFFFFFFFFFFFFFFU /*!< State saved in 1st,2nd,3rd,4th data type of page header */
|
|
||||||
#define EE_PAGESTAT_RECEIVE (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 1st data type of page header */
|
|
||||||
#define EE_PAGESTAT_ACTIVE (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 2nd data type of page header */
|
|
||||||
#define EE_PAGESTAT_VALID (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 3rd data type of page header */
|
|
||||||
#define EE_PAGESTAT_ERASING (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 4th data type of page header */
|
|
||||||
|
|
||||||
/* Description of the 16 Bytes (128 bits) element in flash */
|
|
||||||
/* Bit: 127 64 63 48 47 0 */
|
|
||||||
/* <--- Data Value -----> <-CRC-> <-VirtAddr-> */
|
|
||||||
#define EE_ELEMENT_SIZE 16U /*!< Size of element in Bytes */
|
|
||||||
#define EE_ELEMENT_TYPE uint64_t /*!< Type of element */
|
|
||||||
#define EE_VIRTUALADDRESS_TYPE uint64_t /*!< Type of Virtual Address */
|
|
||||||
#define EE_VIRTUALADDRESS_SHIFT 0U /*!< Bits Shifting to get Virtual Address in element */
|
|
||||||
#define EE_CRC_TYPE uint16_t /*!< Type of Crc */
|
|
||||||
#define EE_CRC_SHIFT 16U /*!< Bits Shifting to get Crc in element */
|
|
||||||
#define EE_DATA_TYPE uint64_t /*!< Type of Data */
|
|
||||||
#define EE_DATA_SHIFT 32U /*!< Bits Shifting to get Data value in element */
|
|
||||||
#define EE_MASK_VIRTUALADDRESS (uint64_t)0x000000000000FFFFU
|
|
||||||
#define EE_MASK_CRC (uint64_t)0x00000000FFFF0000U
|
|
||||||
#define EE_MASK_DATA (uint64_t)0xFFFFFFFFFFFFFFFFU
|
|
||||||
#define EE_MASK_FULL (uint64_t)0xFFFFFFFFFFFFFFFFU
|
|
||||||
|
|
||||||
#define SECURE_FEATURE /*!< Informs the driver about the security features of the flash interface */
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Private macro -------------------------------------------------------------*/
|
|
||||||
/** @addtogroup EEPROM_Private_Macros
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Private functions ---------------------------------------------------------*/
|
|
||||||
/** @addtogroup EEPROM_Private_Functions
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
EE_Status FI_WriteDoubleWord(uint32_t Address, uint64_t* Data, EE_Write_type Write_type);
|
|
||||||
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages);
|
|
||||||
EE_Status FI_PageErase_IT(uint32_t Page, uint16_t NbPages);
|
|
||||||
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address);
|
|
||||||
EE_Status FI_CheckBankConfig(void);
|
|
||||||
void FI_CacheFlush(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#endif /* __FLASH_INTERFACE_H */
|
|
||||||
|
|
||||||
|
|
||||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
||||||
@@ -1,375 +0,0 @@
|
|||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* @file EEPROM_Emul/Porting/STM32WB/flash_interface.c
|
|
||||||
* @author MCD Application Team
|
|
||||||
* @brief This file provides all the EEPROM emulation flash interface functions.
|
|
||||||
******************************************************************************
|
|
||||||
* @attention
|
|
||||||
*
|
|
||||||
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
|
|
||||||
* All rights reserved.</center></h2>
|
|
||||||
*
|
|
||||||
* This software component is licensed by ST under BSD 3-Clause license,
|
|
||||||
* the "License"; You may not use this file except in compliance with the
|
|
||||||
* License. You may obtain a copy of the License at:
|
|
||||||
* opensource.org/licenses/BSD-3-Clause
|
|
||||||
*
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
|
||||||
#include "eeprom_emul.h"
|
|
||||||
#include "flash_interface.h"
|
|
||||||
#include "stm32wbxx_nucleo.h"
|
|
||||||
|
|
||||||
/** @addtogroup EEPROM_Emulation
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Private typedef -----------------------------------------------------------*/
|
|
||||||
/* Private constants ---------------------------------------------------------*/
|
|
||||||
#ifdef DUALCORE_FLASH_SHARING
|
|
||||||
#define HSEM_PROCESS_1 12U /* Number taken randomly to identify the process locking a semaphore in the driver context */
|
|
||||||
#endif
|
|
||||||
/* Private macro -------------------------------------------------------------*/
|
|
||||||
/* Private variables ---------------------------------------------------------*/
|
|
||||||
/* Private function prototypes -----------------------------------------------*/
|
|
||||||
/* Exported functions --------------------------------------------------------*/
|
|
||||||
/* Private functions ---------------------------------------------------------*/
|
|
||||||
/** @addtogroup EEPROM_Private_Functions
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef DUALCORE_FLASH_SHARING
|
|
||||||
/**
|
|
||||||
* @brief Write a double word at the given address in Flash
|
|
||||||
* @param Address Where to write
|
|
||||||
* @param Data What to write
|
|
||||||
* @param Write_type Type of writing on going (see EE_Write_type)
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE_WRITE_ERROR: if an error occurs
|
|
||||||
* - EE_FLASH_USED: flash currently used by CPU2
|
|
||||||
*/
|
|
||||||
EE_Status FI_WriteDoubleWord(uint32_t Address, uint64_t Data, EE_Write_type Write_type)
|
|
||||||
{
|
|
||||||
EE_Status ee_status = EE_OK;
|
|
||||||
|
|
||||||
/* We enter a critical section */
|
|
||||||
UTILS_ENTER_CRITICAL_SECTION();
|
|
||||||
|
|
||||||
/* When the ongoing writing operation is a direct one (no transfer is required,
|
|
||||||
we are not in init process, and we do not write the state of a page) */
|
|
||||||
if(Write_type == EE_SIMPLE_WRITE)
|
|
||||||
{
|
|
||||||
/* Wait for the semaphore to be free */
|
|
||||||
while( HAL_HSEM_IsSemTaken(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID) );
|
|
||||||
|
|
||||||
/* Take the HW 7 semaphore */
|
|
||||||
if(HAL_HSEM_Take(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID, HSEM_PROCESS_1) == HAL_OK)
|
|
||||||
{
|
|
||||||
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, Data) != HAL_OK)
|
|
||||||
{
|
|
||||||
HAL_HSEM_Release(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID, HSEM_PROCESS_1);
|
|
||||||
ee_status = EE_WRITE_ERROR;
|
|
||||||
}
|
|
||||||
/* Release the HW Semaphore */
|
|
||||||
HAL_HSEM_Release(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID, HSEM_PROCESS_1);
|
|
||||||
ee_status = EE_OK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* If flash is used by CPU2, the semaphore release interrupt is activated so as to raise a notification when
|
|
||||||
the semaphore will be unlocked (user can do other operations while waiting) */
|
|
||||||
HAL_HSEM_ActivateNotification(__HAL_HSEM_SEMID_TO_MASK(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID));
|
|
||||||
ee_status = EE_FLASH_USED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* This is when the function call comes from a writing operation other than a direct one */
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Wait for the semaphore 7 to be free and take it when it is */
|
|
||||||
while(HAL_HSEM_Take(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID, HSEM_PROCESS_1) != HAL_OK)
|
|
||||||
{
|
|
||||||
while( HAL_HSEM_IsSemTaken(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID) ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, Data) != HAL_OK)
|
|
||||||
{
|
|
||||||
HAL_HSEM_Release(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID, HSEM_PROCESS_1);
|
|
||||||
ee_status = EE_WRITE_ERROR;
|
|
||||||
}
|
|
||||||
/* Release the HW Semaphore */
|
|
||||||
HAL_HSEM_Release(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID, HSEM_PROCESS_1);
|
|
||||||
ee_status = EE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We exit the critical section */
|
|
||||||
UTILS_EXIT_CRITICAL_SECTION();
|
|
||||||
return ee_status;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
/**
|
|
||||||
* @brief Write a double word at the given address in Flash
|
|
||||||
* @param Address Where to write
|
|
||||||
* @param Data What to write
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE_WRITE_ERROR: if an error occurs
|
|
||||||
*/
|
|
||||||
HAL_StatusTypeDef FI_WriteDoubleWord(uint32_t Address, uint64_t Data)
|
|
||||||
{
|
|
||||||
return HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, Data);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Erase a page in polling mode
|
|
||||||
* @param Page Page number
|
|
||||||
* @param NbPages Number of pages to erase
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages)
|
|
||||||
{
|
|
||||||
EE_Status status = EE_OK;
|
|
||||||
|
|
||||||
#ifdef DUALCORE_FLASH_SHARING
|
|
||||||
|
|
||||||
/* Wait for last operation to be completed */
|
|
||||||
while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) ;
|
|
||||||
|
|
||||||
/* Because we want to share flash between CPU1 and 2, we erase each page individually
|
|
||||||
* and we take then release the associated semaphore for each page erasings.
|
|
||||||
* By doing this, we allow CPU2 to do urgent works between page erasings. */
|
|
||||||
for (uint32_t index = Page; index < (Page + NbPages); index++)
|
|
||||||
{
|
|
||||||
/* We enter a critical section */
|
|
||||||
UTILS_ENTER_CRITICAL_SECTION();
|
|
||||||
|
|
||||||
/* Wait for the semaphore 7 to be free and take it when it is */
|
|
||||||
while(HAL_HSEM_Take(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID, HSEM_PROCESS_1) != HAL_OK)
|
|
||||||
{
|
|
||||||
while( HAL_HSEM_IsSemTaken(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID) ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Start erase page */
|
|
||||||
FLASH_PageErase(index);
|
|
||||||
/* Release the HW Semaphore */
|
|
||||||
HAL_HSEM_Release(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID, HSEM_PROCESS_1);
|
|
||||||
/* We exit the critical section */
|
|
||||||
UTILS_EXIT_CRITICAL_SECTION();
|
|
||||||
|
|
||||||
/* Wait for last operation to be completed */
|
|
||||||
while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If operation is completed or interrupted, disable the Page Erase Bit */
|
|
||||||
CLEAR_BIT(FLASH->CR, (FLASH_CR_PER | FLASH_CR_PNB));
|
|
||||||
|
|
||||||
/* Flush the caches to be sure of the data consistency */
|
|
||||||
/* Flush instruction cache */
|
|
||||||
if (READ_BIT(FLASH->ACR, FLASH_ACR_ICEN) == FLASH_ACR_ICEN)
|
|
||||||
{
|
|
||||||
/* Disable instruction cache */
|
|
||||||
__HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
|
|
||||||
/* Reset instruction cache */
|
|
||||||
__HAL_FLASH_INSTRUCTION_CACHE_RESET();
|
|
||||||
/* Enable instruction cache */
|
|
||||||
__HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Flush data cache */
|
|
||||||
if (READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) == FLASH_ACR_DCEN)
|
|
||||||
{
|
|
||||||
/* Disable data cache */
|
|
||||||
__HAL_FLASH_DATA_CACHE_DISABLE();
|
|
||||||
/* Reset data cache */
|
|
||||||
__HAL_FLASH_DATA_CACHE_RESET();
|
|
||||||
/* Enable data cache */
|
|
||||||
__HAL_FLASH_DATA_CACHE_ENABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
FLASH_EraseInitTypeDef s_eraseinit;
|
|
||||||
uint32_t page_error = 0U;
|
|
||||||
|
|
||||||
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES;
|
|
||||||
s_eraseinit.NbPages = NbPages;
|
|
||||||
s_eraseinit.Page = Page;
|
|
||||||
|
|
||||||
/* Erase the Page: Set Page status to ERASED status */
|
|
||||||
if (HAL_FLASHEx_Erase(&s_eraseinit, &page_error) != HAL_OK)
|
|
||||||
{
|
|
||||||
status = EE_ERASE_ERROR;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Erase a page with interrupt enabled
|
|
||||||
* @param Page Page number
|
|
||||||
* @param NbPages Number of pages to erase
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_PageErase_IT(uint32_t Page, uint16_t NbPages)
|
|
||||||
{
|
|
||||||
EE_Status status = EE_OK;
|
|
||||||
FLASH_EraseInitTypeDef s_eraseinit;
|
|
||||||
|
|
||||||
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES;
|
|
||||||
s_eraseinit.NbPages = NbPages;
|
|
||||||
s_eraseinit.Page = Page;
|
|
||||||
|
|
||||||
#ifdef DUALCORE_FLASH_SHARING
|
|
||||||
/* We enter a critical section */
|
|
||||||
UTILS_ENTER_CRITICAL_SECTION();
|
|
||||||
|
|
||||||
/* Wait for the semaphore 7 to be free and take it when it is */
|
|
||||||
while(HAL_HSEM_Take(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID, HSEM_PROCESS_1) != HAL_OK)
|
|
||||||
{
|
|
||||||
while( HAL_HSEM_IsSemTaken(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID) ) ;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Erase the Page: Set Page status to ERASED status */
|
|
||||||
if (HAL_FLASHEx_Erase_IT(&s_eraseinit) != HAL_OK)
|
|
||||||
{
|
|
||||||
status = EE_ERASE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DUALCORE_FLASH_SHARING
|
|
||||||
/* Release the HW Semaphore */
|
|
||||||
HAL_HSEM_Release(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID, HSEM_PROCESS_1);
|
|
||||||
/* We exit the critical section */
|
|
||||||
UTILS_EXIT_CRITICAL_SECTION();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Flush the caches if needed to keep coherency when the flash content is modified
|
|
||||||
*/
|
|
||||||
void FI_CacheFlush()
|
|
||||||
{
|
|
||||||
/* To keep its coherency, flush the D-Cache: its content is not updated after a flash erase. */
|
|
||||||
__HAL_FLASH_DATA_CACHE_DISABLE();
|
|
||||||
__HAL_FLASH_DATA_CACHE_RESET();
|
|
||||||
__HAL_FLASH_DATA_CACHE_ENABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Delete corrupted Flash address, can be called from NMI. No Timeout.
|
|
||||||
* @param Address Address of the FLASH Memory to delete
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address)
|
|
||||||
{
|
|
||||||
EE_Status status = EE_OK;
|
|
||||||
|
|
||||||
/* Set FLASH Programmation bit */
|
|
||||||
SET_BIT(FLASH->CR, FLASH_CR_PG);
|
|
||||||
|
|
||||||
#ifdef DUALCORE_FLASH_SHARING
|
|
||||||
/* We enter a critical section */
|
|
||||||
UTILS_ENTER_CRITICAL_SECTION();
|
|
||||||
|
|
||||||
/* Wait for the semaphore 7 to be free and take it when it is */
|
|
||||||
while(HAL_HSEM_Take(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID, HSEM_PROCESS_1) != HAL_OK)
|
|
||||||
{
|
|
||||||
while( HAL_HSEM_IsSemTaken(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID) ) ;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Program double word of value 0 */
|
|
||||||
*(__IO uint32_t*)(Address) = (uint32_t)0U;
|
|
||||||
*(__IO uint32_t*)(Address+4U) = (uint32_t)0U;
|
|
||||||
|
|
||||||
#ifdef DUALCORE_FLASH_SHARING
|
|
||||||
/* Release the HW Semaphore */
|
|
||||||
HAL_HSEM_Release(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID, HSEM_PROCESS_1);
|
|
||||||
/* We exit the critical section */
|
|
||||||
UTILS_EXIT_CRITICAL_SECTION();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Wait programmation completion */
|
|
||||||
while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) ;
|
|
||||||
|
|
||||||
/* Check if error occured */
|
|
||||||
if((__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PROGERR)) ||
|
|
||||||
(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR)) ||
|
|
||||||
(__HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGSERR)))
|
|
||||||
{
|
|
||||||
status = EE_DELETE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check FLASH End of Operation flag */
|
|
||||||
if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
|
|
||||||
{
|
|
||||||
/* Clear FLASH End of Operation pending bit */
|
|
||||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear FLASH Programmation bit */
|
|
||||||
CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
|
|
||||||
|
|
||||||
/* Clear FLASH ECCD bit */
|
|
||||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ECCD);
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Check if the configuration is 128-bits bank or 2*64-bits bank
|
|
||||||
* @param None
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_CheckBankConfig(void)
|
|
||||||
{
|
|
||||||
#if defined (FLASH_OPTR_DBANK)
|
|
||||||
FLASH_OBProgramInitTypeDef sOBCfg;
|
|
||||||
EE_Status status;
|
|
||||||
|
|
||||||
/* Request the Option Byte configuration :
|
|
||||||
- User and RDP level are always returned
|
|
||||||
- WRP and PCROP are not requested */
|
|
||||||
sOBCfg.WRPArea = 0xFF;
|
|
||||||
sOBCfg.PCROPConfig = 0xFF;
|
|
||||||
HAL_FLASHEx_OBGetConfig(&sOBCfg);
|
|
||||||
|
|
||||||
/* Check the value of the DBANK user option byte */
|
|
||||||
if ((sOBCfg.USERConfig & OB_DBANK_64_BITS) != 0)
|
|
||||||
{
|
|
||||||
status = EE_OK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
status = EE_INVALID_BANK_CFG;
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
|
||||||
#else
|
|
||||||
/* No feature 128-bits single bank, so always 64-bits dual bank */
|
|
||||||
return EE_OK;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
||||||
@@ -1,142 +0,0 @@
|
|||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* @file EEPROM_Emul/Porting/STM32WB/flash_interface.h
|
|
||||||
* @author MCD Application Team
|
|
||||||
* @brief This file contains all the functions prototypes for the EEPROM
|
|
||||||
* emulation flash interface.
|
|
||||||
******************************************************************************
|
|
||||||
* @attention
|
|
||||||
*
|
|
||||||
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
|
|
||||||
* All rights reserved.</center></h2>
|
|
||||||
*
|
|
||||||
* This software component is licensed by ST under BSD 3-Clause license,
|
|
||||||
* the "License"; You may not use this file except in compliance with the
|
|
||||||
* License. You may obtain a copy of the License at:
|
|
||||||
* opensource.org/licenses/BSD-3-Clause
|
|
||||||
*
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
|
||||||
#ifndef __FLASH_INTERFACE_H
|
|
||||||
#define __FLASH_INTERFACE_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
|
||||||
#include "eeprom_emul.h"
|
|
||||||
#include "stm32wbxx_hal.h"
|
|
||||||
#include "stm32wbxx_ll_crc.h"
|
|
||||||
#include "stm32wbxx_ll_bus.h"
|
|
||||||
#ifdef DUALCORE_FLASH_SHARING
|
|
||||||
#include "utilities_conf.h"
|
|
||||||
#include "hw_conf.h"
|
|
||||||
#include "shci.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** @addtogroup EEPROM_Emulation
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Exported types ------------------------------------------------------------*/
|
|
||||||
/* Exported macro ------------------------------------------------------------*/
|
|
||||||
/* Exported functions ------------------------------------------------------- */
|
|
||||||
|
|
||||||
/* Private types -------------------------------------------------------------*/
|
|
||||||
/* Private constants ---------------------------------------------------------*/
|
|
||||||
/** @addtogroup EEPROM_Private_Constants
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @addtogroup Private_Other_Constants
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define BANK_SIZE FLASH_BANK_SIZE /*!< Alias to FLASH_BANK_SIZE definition from HAL STM32L4 */
|
|
||||||
#define EE_ACCESS_32BITS /*!< Enable EEPROM 32bits R/W functions, only valid for flash allowing 64bits access*/
|
|
||||||
|
|
||||||
/* Page state header */
|
|
||||||
#define EE_PAGESTAT_ERASED (uint64_t)0xFFFFFFFFFFFFFFFFU /*!< State saved in 1st,2nd,3rd,4th data type of page header */
|
|
||||||
#define EE_PAGESTAT_RECEIVE (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 1st data type of page header */
|
|
||||||
#define EE_PAGESTAT_ACTIVE (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 2nd data type of page header */
|
|
||||||
#define EE_PAGESTAT_VALID (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 3rd data type of page header */
|
|
||||||
#define EE_PAGESTAT_ERASING (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 4th data type of page header */
|
|
||||||
|
|
||||||
/* Description of the 8 Bytes (64 bits) element in flash */
|
|
||||||
/* Bit: 63 32 31 16 15 0 */
|
|
||||||
/* <--- Data Value -----> <-unused-> <-VirtAddr-> */
|
|
||||||
#define EE_ELEMENT_SIZE 8U /*!< Size of element in Bytes */
|
|
||||||
#define EE_ELEMENT_TYPE uint64_t /*!< Type of element */
|
|
||||||
#define EE_VIRTUALADDRESS_TYPE uint16_t /*!< Type of Virtual Address */
|
|
||||||
#define EE_VIRTUALADDRESS_SHIFT 0U /*!< Bits Shifting to get Virtual Address in element */
|
|
||||||
#define EE_CRC_TYPE uint16_t /*!< Type of Crc */
|
|
||||||
#define EE_CRC_SHIFT 16U /*!< Bits Shifting to get Crc in element */
|
|
||||||
#define EE_DATA_TYPE uint32_t /*!< Type of Data */
|
|
||||||
#define EE_DATA_SHIFT 32U /*!< Bits Shifting to get Data value in element */
|
|
||||||
#define EE_MASK_VIRTUALADDRESS (uint64_t)0x000000000000FFFFU
|
|
||||||
#define EE_MASK_CRC (uint64_t)0x00000000FFFF0000U
|
|
||||||
#define EE_MASK_DATA (uint64_t)0xFFFFFFFF00000000U
|
|
||||||
#define EE_MASK_FULL (uint64_t)0xFFFFFFFFFFFFFFFFU
|
|
||||||
|
|
||||||
#ifdef DUALCORE_FLASH_SHARING
|
|
||||||
#define EE_SEM_WAIT_TIMEOUT 5000U /*!< Take semaphore attempts timeout, 5s */
|
|
||||||
#endif
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Private macro -------------------------------------------------------------*/
|
|
||||||
/** @addtogroup EEPROM_Private_Macros
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @defgroup Macros_Flash Macros to access flash
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Private functions ---------------------------------------------------------*/
|
|
||||||
/** @addtogroup EEPROM_Private_Functions
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
#ifdef DUALCORE_FLASH_SHARING
|
|
||||||
EE_Status FI_WriteDoubleWord(uint32_t Address, uint64_t Data, EE_Write_type Write_type);
|
|
||||||
#else
|
|
||||||
HAL_StatusTypeDef FI_WriteDoubleWord(uint32_t Address, uint64_t Data);
|
|
||||||
#endif
|
|
||||||
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages);
|
|
||||||
EE_Status FI_PageErase_IT(uint32_t Page, uint16_t NbPages);
|
|
||||||
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address);
|
|
||||||
EE_Status FI_CheckBankConfig(void);
|
|
||||||
void FI_CacheFlush(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#endif /* __FLASH_INTERFACE_H */
|
|
||||||
|
|
||||||
|
|
||||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
||||||
@@ -1,207 +0,0 @@
|
|||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* @file EEPROM_Emul/Porting/STM32WL/flash_interface.c
|
|
||||||
* @author MCD Application Team
|
|
||||||
* @brief This file provides all the EEPROM emulation flash interface functions.
|
|
||||||
******************************************************************************
|
|
||||||
* @attention
|
|
||||||
*
|
|
||||||
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
|
|
||||||
* All rights reserved.</center></h2>
|
|
||||||
*
|
|
||||||
* This software component is licensed by ST under BSD 3-Clause license,
|
|
||||||
* the "License"; You may not use this file except in compliance with the
|
|
||||||
* License. You may obtain a copy of the License at:
|
|
||||||
* opensource.org/licenses/BSD-3-Clause
|
|
||||||
*
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
|
||||||
#include "eeprom_emul.h"
|
|
||||||
#include "flash_interface.h"
|
|
||||||
#include "stm32wlxx_nucleo.h"
|
|
||||||
|
|
||||||
/** @addtogroup EEPROM_Emulation
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Private typedef -----------------------------------------------------------*/
|
|
||||||
/* Private constants ---------------------------------------------------------*/
|
|
||||||
/* Private macro -------------------------------------------------------------*/
|
|
||||||
/* Private variables ---------------------------------------------------------*/
|
|
||||||
/* Private function prototypes -----------------------------------------------*/
|
|
||||||
/* Exported functions --------------------------------------------------------*/
|
|
||||||
/* Private functions ---------------------------------------------------------*/
|
|
||||||
/** @addtogroup EEPROM_Private_Functions
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Write a double word at the given address in Flash
|
|
||||||
* @param Address Where to write
|
|
||||||
* @param Data What to write
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE_WRITE_ERROR: if an error occurs
|
|
||||||
*/
|
|
||||||
HAL_StatusTypeDef FI_WriteDoubleWord(uint32_t Address, uint64_t Data)
|
|
||||||
{
|
|
||||||
return HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Erase a page in polling mode
|
|
||||||
* @param Page Page number
|
|
||||||
* @param NbPages Number of pages to erase
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages)
|
|
||||||
{
|
|
||||||
EE_Status status = EE_OK;
|
|
||||||
FLASH_EraseInitTypeDef s_eraseinit;
|
|
||||||
uint32_t page_error = 0U;
|
|
||||||
|
|
||||||
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES;
|
|
||||||
s_eraseinit.NbPages = NbPages;
|
|
||||||
s_eraseinit.Page = Page;
|
|
||||||
|
|
||||||
/* Erase the Page: Set Page status to ERASED status */
|
|
||||||
if (HAL_FLASHEx_Erase(&s_eraseinit, &page_error) != HAL_OK)
|
|
||||||
{
|
|
||||||
status = EE_ERASE_ERROR;
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Erase a page with interrupt enabled
|
|
||||||
* @param Page Page number
|
|
||||||
* @param NbPages Number of pages to erase
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_PageErase_IT(uint32_t Page, uint16_t NbPages)
|
|
||||||
{
|
|
||||||
EE_Status status = EE_OK;
|
|
||||||
FLASH_EraseInitTypeDef s_eraseinit;
|
|
||||||
|
|
||||||
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES;
|
|
||||||
s_eraseinit.NbPages = NbPages;
|
|
||||||
s_eraseinit.Page = Page;
|
|
||||||
|
|
||||||
/* Erase the Page: Set Page status to ERASED status */
|
|
||||||
if (HAL_FLASHEx_Erase_IT(&s_eraseinit) != HAL_OK)
|
|
||||||
{
|
|
||||||
status = EE_ERASE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Flush the caches if needed to keep coherency when the flash content is modified
|
|
||||||
*/
|
|
||||||
void FI_CacheFlush()
|
|
||||||
{
|
|
||||||
/* To keep its coherency, flush the D-Cache: its content is not updated after a flash erase. */
|
|
||||||
__HAL_FLASH_DATA_CACHE_DISABLE();
|
|
||||||
__HAL_FLASH_DATA_CACHE_RESET();
|
|
||||||
__HAL_FLASH_DATA_CACHE_ENABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Delete corrupted Flash address, can be called from NMI. No Timeout.
|
|
||||||
* @param Address Address of the FLASH Memory to delete
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address)
|
|
||||||
{
|
|
||||||
EE_Status status = EE_OK;
|
|
||||||
|
|
||||||
/* Set FLASH Programmation bit */
|
|
||||||
SET_BIT(FLASH->CR, FLASH_CR_PG);
|
|
||||||
|
|
||||||
/* Program double word of value 0 */
|
|
||||||
*(__IO uint32_t*)(Address) = (uint32_t)0U;
|
|
||||||
*(__IO uint32_t*)(Address+4U) = (uint32_t)0U;
|
|
||||||
|
|
||||||
/* Wait programmation completion */
|
|
||||||
while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) ;
|
|
||||||
|
|
||||||
/* Check if error occured */
|
|
||||||
if((__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PROGERR)) ||
|
|
||||||
(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR)) ||
|
|
||||||
(__HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGSERR)))
|
|
||||||
{
|
|
||||||
status = EE_DELETE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check FLASH End of Operation flag */
|
|
||||||
if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
|
|
||||||
{
|
|
||||||
/* Clear FLASH End of Operation pending bit */
|
|
||||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear FLASH Programmation bit */
|
|
||||||
CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
|
|
||||||
|
|
||||||
/* Clear FLASH ECCD bit */
|
|
||||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ECCD);
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Check if the configuration is 128-bits bank or 2*64-bits bank
|
|
||||||
* @param None
|
|
||||||
* @retval EE_Status
|
|
||||||
* - EE_OK: on success
|
|
||||||
* - EE error code: if an error occurs
|
|
||||||
*/
|
|
||||||
EE_Status FI_CheckBankConfig(void)
|
|
||||||
{
|
|
||||||
#if defined (FLASH_OPTR_DBANK)
|
|
||||||
FLASH_OBProgramInitTypeDef sOBCfg;
|
|
||||||
EE_Status status;
|
|
||||||
|
|
||||||
/* Request the Option Byte configuration :
|
|
||||||
- User and RDP level are always returned
|
|
||||||
- WRP and PCROP are not requested */
|
|
||||||
sOBCfg.WRPArea = 0xFF;
|
|
||||||
sOBCfg.PCROPConfig = 0xFF;
|
|
||||||
HAL_FLASHEx_OBGetConfig(&sOBCfg);
|
|
||||||
|
|
||||||
/* Check the value of the DBANK user option byte */
|
|
||||||
if ((sOBCfg.USERConfig & OB_DBANK_64_BITS) != 0)
|
|
||||||
{
|
|
||||||
status = EE_OK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
status = EE_INVALID_BANK_CFG;
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
|
||||||
#else
|
|
||||||
/* No feature 128-bits single bank, so always 64-bits dual bank */
|
|
||||||
return EE_OK;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* @file EEPROM_Emul/Porting/STM32WL/flash_interface.h
|
|
||||||
* @author MCD Application Team
|
|
||||||
* @brief This file contains all the functions prototypes for the EEPROM
|
|
||||||
* emulation flash interface.
|
|
||||||
******************************************************************************
|
|
||||||
* @attention
|
|
||||||
*
|
|
||||||
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
|
|
||||||
* All rights reserved.</center></h2>
|
|
||||||
*
|
|
||||||
* This software component is licensed by ST under BSD 3-Clause license,
|
|
||||||
* the "License"; You may not use this file except in compliance with the
|
|
||||||
* License. You may obtain a copy of the License at:
|
|
||||||
* opensource.org/licenses/BSD-3-Clause
|
|
||||||
*
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
|
||||||
#ifndef __FLASH_INTERFACE_H
|
|
||||||
#define __FLASH_INTERFACE_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
|
||||||
#include "eeprom_emul.h"
|
|
||||||
#include "stm32wlxx_hal.h"
|
|
||||||
#include "stm32wlxx_ll_crc.h"
|
|
||||||
#include "stm32wlxx_ll_bus.h"
|
|
||||||
|
|
||||||
/** @addtogroup EEPROM_Emulation
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Exported types ------------------------------------------------------------*/
|
|
||||||
/* Exported macro ------------------------------------------------------------*/
|
|
||||||
/* Exported functions ------------------------------------------------------- */
|
|
||||||
|
|
||||||
/* Private types -------------------------------------------------------------*/
|
|
||||||
/* Private constants ---------------------------------------------------------*/
|
|
||||||
/** @addtogroup EEPROM_Private_Constants
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @addtogroup Private_Other_Constants
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define BANK_SIZE FLASH_BANK_SIZE /*!< Alias to FLASH_BANK_SIZE definition from HAL STM32L4 */
|
|
||||||
#define EE_ACCESS_32BITS /*!< Enable EEPROM 32bits R/W functions, only valid for flash allowing 64bits access*/
|
|
||||||
|
|
||||||
/* Page state header */
|
|
||||||
#define EE_PAGESTAT_ERASED (uint64_t)0xFFFFFFFFFFFFFFFFU /*!< State saved in 1st,2nd,3rd,4th data type of page header */
|
|
||||||
#define EE_PAGESTAT_RECEIVE (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 1st data type of page header */
|
|
||||||
#define EE_PAGESTAT_ACTIVE (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 2nd data type of page header */
|
|
||||||
#define EE_PAGESTAT_VALID (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 3rd data type of page header */
|
|
||||||
#define EE_PAGESTAT_ERASING (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 4th data type of page header */
|
|
||||||
|
|
||||||
/* Description of the 8 Bytes (64 bits) element in flash */
|
|
||||||
/* Bit: 63 32 31 16 15 0 */
|
|
||||||
/* <--- Data Value -----> <-unused-> <-VirtAddr-> */
|
|
||||||
#define EE_ELEMENT_SIZE 8U /*!< Size of element in Bytes */
|
|
||||||
#define EE_ELEMENT_TYPE uint64_t /*!< Type of element */
|
|
||||||
#define EE_VIRTUALADDRESS_TYPE uint16_t /*!< Type of Virtual Address */
|
|
||||||
#define EE_VIRTUALADDRESS_SHIFT 0U /*!< Bits Shifting to get Virtual Address in element */
|
|
||||||
#define EE_CRC_TYPE uint16_t /*!< Type of Crc */
|
|
||||||
#define EE_CRC_SHIFT 16U /*!< Bits Shifting to get Crc in element */
|
|
||||||
#define EE_DATA_TYPE uint32_t /*!< Type of Data */
|
|
||||||
#define EE_DATA_SHIFT 32U /*!< Bits Shifting to get Data value in element */
|
|
||||||
#define EE_MASK_VIRTUALADDRESS (uint64_t)0x000000000000FFFFU
|
|
||||||
#define EE_MASK_CRC (uint64_t)0x00000000FFFF0000U
|
|
||||||
#define EE_MASK_DATA (uint64_t)0xFFFFFFFF00000000U
|
|
||||||
#define EE_MASK_FULL (uint64_t)0xFFFFFFFFFFFFFFFFU
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Private macro -------------------------------------------------------------*/
|
|
||||||
/** @addtogroup EEPROM_Private_Macros
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @defgroup Macros_Flash Macros to access flash
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Private functions ---------------------------------------------------------*/
|
|
||||||
/** @addtogroup EEPROM_Private_Functions
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
#ifdef DUALCORE_FLASH_SHARING
|
|
||||||
EE_Status FI_WriteDoubleWord(uint32_t Address, uint64_t Data, EE_Write_type Write_type);
|
|
||||||
#else
|
|
||||||
HAL_StatusTypeDef FI_WriteDoubleWord(uint32_t Address, uint64_t Data);
|
|
||||||
#endif
|
|
||||||
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages);
|
|
||||||
EE_Status FI_PageErase_IT(uint32_t Page, uint16_t NbPages);
|
|
||||||
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address);
|
|
||||||
EE_Status FI_CheckBankConfig(void);
|
|
||||||
void FI_CacheFlush(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#endif /* __FLASH_INTERFACE_H */
|
|
||||||
|
|
||||||
|
|
||||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,44 @@
|
|||||||
|
//
|
||||||
|
// Created by MightyPork on 2017/11/09.
|
||||||
|
//
|
||||||
|
// Small sprintf/snprintf implementation, used instead of the newlib one.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef GEX_SNPRINTF_H
|
||||||
|
#define GEX_SNPRINTF_H
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
int fixup_vsnprintf(char *str, size_t count, const char *fmt, va_list args);
|
||||||
|
int fixup_snprintf(char *str, size_t count,const char *fmt,...);
|
||||||
|
int fixup_vasprintf(char **ptr, const char *format, va_list ap);
|
||||||
|
int fixup_asprintf(char **ptr, const char *format, ...);
|
||||||
|
int fixup_sprintf(char *ptr, const char *format, ...);
|
||||||
|
int fixup_printf(const char *format, ...);
|
||||||
|
int fixup_vprintf(const char *format, va_list ap);
|
||||||
|
|
||||||
|
#define VSNPRINTF(...) fixup_vsnprintf(__VA_ARGS__)
|
||||||
|
#define SNPRINTF(...) fixup_snprintf(__VA_ARGS__)
|
||||||
|
#define VASPRINTF(...) fixup_vasprintf(__VA_ARGS__)
|
||||||
|
#define ASPRINTF(...) fixup_asprintf(__VA_ARGS__)
|
||||||
|
#define SPRINTF(...) fixup_sprintf(__VA_ARGS__)
|
||||||
|
#define PRINTF(...) fixup_printf(__VA_ARGS__)
|
||||||
|
#define VPRINTF(...) fixup_vprintf(__VA_ARGS__)
|
||||||
|
|
||||||
|
// for debug
|
||||||
|
//#include <stdio.h>
|
||||||
|
//#define PRINTF(...) printf(__VA_ARGS__)
|
||||||
|
//#define SPRINTF(...) sprintf(__VA_ARGS__)
|
||||||
|
|
||||||
|
// extern
|
||||||
|
|
||||||
|
extern void stdout_puts(const char *s);
|
||||||
|
extern void stdout_putchar(char c);
|
||||||
|
extern void stdout_write(const char *s, size_t len);
|
||||||
|
|
||||||
|
#define PUTS(s) stdout_puts((s))
|
||||||
|
#define PUTCHAR(c) stdout_putchar((c))
|
||||||
|
#define WRITE(s, n) stdout_write((s), (n))
|
||||||
|
|
||||||
|
#endif //GEX_SNPRINTF_H
|
||||||
@@ -20,6 +20,8 @@
|
|||||||
/// Print characters 2x wider and taller
|
/// Print characters 2x wider and taller
|
||||||
#define FONT_DOUBLE (FONT_DOUBLEW | FONT_DOUBLEH)
|
#define FONT_DOUBLE (FONT_DOUBLEW | FONT_DOUBLEH)
|
||||||
|
|
||||||
|
#define TEXT_CENTER 32
|
||||||
|
|
||||||
/// Print text stored in flash
|
/// Print text stored in flash
|
||||||
void fb_text_P(fbpos_t x, fbpos_t y, const char *text, uint8_t flags, fbcolor_t color);
|
void fb_text_P(fbpos_t x, fbpos_t y, const char *text, uint8_t flags, fbcolor_t color);
|
||||||
|
|
||||||
|
|||||||
+15
-2
@@ -27,6 +27,21 @@ void fb_text_P_or_RAM(fbpos_t x, fbpos_t y, const char *text, uint8_t flags, fbc
|
|||||||
symh = 7;
|
symh = 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uint8_t pxw = (flags & FONT_DOUBLEW) ? 2 : 1;
|
||||||
|
const uint8_t pxh = (flags & FONT_DOUBLEH) ? 2 : 1;
|
||||||
|
|
||||||
|
if (flags & TEXT_CENTER) {
|
||||||
|
size_t len = utf8_strlen(text);
|
||||||
|
if (len == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint8_t charw = (symw + 1 + ((flags & FONT_BOLD) ? 1 : 0)) * pxw;
|
||||||
|
len *= charw;
|
||||||
|
len -= pxw;
|
||||||
|
|
||||||
|
x -= (fbpos_t) (len / 2);
|
||||||
|
}
|
||||||
|
|
||||||
while ((uchar = Utf8Iterator_Next(&iter)).uint) {
|
while ((uchar = Utf8Iterator_Next(&iter)).uint) {
|
||||||
const uint8_t *data;
|
const uint8_t *data;
|
||||||
if (flags & FONT_4X5) {
|
if (flags & FONT_4X5) {
|
||||||
@@ -64,8 +79,6 @@ void fb_text_P_or_RAM(fbpos_t x, fbpos_t y, const char *text, uint8_t flags, fbc
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// slow, pixel-by-pixel drawing
|
// slow, pixel-by-pixel drawing
|
||||||
const uint8_t pxw = (flags & FONT_DOUBLEW) ? 2 : 1;
|
|
||||||
const uint8_t pxh = (flags & FONT_DOUBLEH) ? 2 : 1;
|
|
||||||
for(fbpos_t xx = 0; xx < symw; xx++) {
|
for(fbpos_t xx = 0; xx < symw; xx++) {
|
||||||
uint8_t column = pgm_read_byte(&data[xx]);
|
uint8_t column = pgm_read_byte(&data[xx]);
|
||||||
for(fbpos_t yy = 0; yy < symh; yy++) {
|
for(fbpos_t yy = 0; yy < symh; yy++) {
|
||||||
|
|||||||
@@ -99,4 +99,5 @@ static const font3x_bitmap_t PROGMEM font35_ascii[] = {
|
|||||||
static const struct utf_glyph3x PROGMEM font35_extra[] = {
|
static const struct utf_glyph3x PROGMEM font35_extra[] = {
|
||||||
{.utf={.symbol="�"}, {{0x1f, 0x1f, 0x1f}}},
|
{.utf={.symbol="�"}, {{0x1f, 0x1f, 0x1f}}},
|
||||||
{.utf={.symbol="°"}, {{0x07, 0x05, 0x07}}},
|
{.utf={.symbol="°"}, {{0x07, 0x05, 0x07}}},
|
||||||
|
{.utf={.symbol="→"}, {{0x15, 0x0e, 0x04}}},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -98,19 +98,13 @@ static const font5x_bitmap_t PROGMEM font57_ascii[] = {
|
|||||||
|
|
||||||
static const struct utf_glyph5x PROGMEM font57_extra[] = {
|
static const struct utf_glyph5x PROGMEM font57_extra[] = {
|
||||||
{.utf={.symbol="�"}, {{0x7f, 0x41, 0x41, 0x41, 0x7f}}},
|
{.utf={.symbol="�"}, {{0x7f, 0x41, 0x41, 0x41, 0x7f}}},
|
||||||
{.utf={.symbol="×"}, {{0x22, 0x14, 0x08, 0x14, 0x22}}},
|
|
||||||
{.utf={.symbol="↑"}, {{0x08, 0x04, 0x3e, 0x04, 0x08}}},
|
|
||||||
{.utf={.symbol="↓"}, {{0x08, 0x10, 0x3e, 0x10, 0x08}}},
|
|
||||||
{.utf={.symbol="←"}, {{0x08, 0x1c, 0x2a, 0x08, 0x08}}},
|
{.utf={.symbol="←"}, {{0x08, 0x1c, 0x2a, 0x08, 0x08}}},
|
||||||
{.utf={.symbol="→"}, {{0x08, 0x08, 0x2a, 0x1c, 0x08}}},
|
{.utf={.symbol="→"}, {{0x08, 0x08, 0x2a, 0x1c, 0x08}}},
|
||||||
{.utf={.symbol="⏰"}, {{0x1c, 0x22, 0x2e, 0x2a, 0x1c}}},
|
|
||||||
{.utf={.symbol="⌛"}, {{0x63, 0x55, 0x4d, 0x55, 0x63}}},
|
|
||||||
{.utf={.symbol="☸"}, {{0x1c, 0x22, 0x2a, 0x22, 0x1c}}},
|
|
||||||
{.utf={.symbol="⏎"}, {{0x10, 0x38, 0x54, 0x10, 0x1e}}},
|
|
||||||
{.utf={.symbol="🌡"}, {{0x20, 0x7e, 0x79, 0x7e, 0x2a}}},
|
|
||||||
{.utf={.symbol="°"}, {{0x00, 0x07, 0x05, 0x07, 0x00}}},
|
{.utf={.symbol="°"}, {{0x00, 0x07, 0x05, 0x07, 0x00}}},
|
||||||
{.utf={.symbol="μ"}, {{0x7c, 0x20, 0x20, 0x10, 0x3c}}},
|
{.utf={.symbol="č"}, {{0x38, 0x45, 0x46, 0x45, 0x20}}},
|
||||||
{.utf={.symbol="🔙"}, {{0x04, 0x4e, 0x55, 0x44, 0x38}}},
|
{.utf={.symbol="š"}, {{0x48, 0x55, 0x56, 0x55, 0x20}}},
|
||||||
{.utf={.symbol="▶"}, {{0x7f, 0x3e, 0x1c, 0x08, 0x00}}},
|
{.utf={.symbol="í"}, {{0x00, 0x44, 0x7d, 0x41, 0x00}}},
|
||||||
{.utf={.symbol="◀"}, {{0x00, 0x08, 0x1c, 0x3e, 0x7f}}},
|
{.utf={.symbol="ž"}, {{0x44, 0x65, 0x56, 0x4d, 0x44}}},
|
||||||
|
{.utf={.symbol="ď"}, {{0x38, 0x44, 0x45, 0x48, 0x7f}}},
|
||||||
|
{.utf={.symbol="»"}, {{0x22, 0x14, 0x2a, 0x14, 0x08}}},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -588,11 +588,18 @@ const char *font_extras[] = {
|
|||||||
"xxx",
|
"xxx",
|
||||||
" ",
|
" ",
|
||||||
" ",
|
" ",
|
||||||
|
// Extra 2 "→"
|
||||||
|
"x ",
|
||||||
|
" x ",
|
||||||
|
"xxx",
|
||||||
|
" x ",
|
||||||
|
"x ",
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *font_extras_utf[] = {
|
const char *font_extras_utf[] = {
|
||||||
"�",
|
"�",
|
||||||
"°",
|
"°",
|
||||||
|
"→",
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "fontedit_render.inc.c"
|
#include "fontedit_render.inc.c"
|
||||||
|
|||||||
+157
-103
@@ -775,30 +775,30 @@ const char *font_extras[] = {
|
|||||||
"# #",
|
"# #",
|
||||||
"# #",
|
"# #",
|
||||||
"#####",
|
"#####",
|
||||||
// Extra 1
|
// // Extra 1
|
||||||
" ",
|
// " ",
|
||||||
"# #",
|
// "# #",
|
||||||
" # # ",
|
// " # # ",
|
||||||
" # ",
|
// " # ",
|
||||||
" # # ",
|
// " # # ",
|
||||||
"# #",
|
// "# #",
|
||||||
" ",
|
// " ",
|
||||||
// Extra 2
|
// // Extra 2
|
||||||
" ",
|
// " ",
|
||||||
" # ",
|
// " # ",
|
||||||
" ### ",
|
// " ### ",
|
||||||
"# # #",
|
// "# # #",
|
||||||
" # ",
|
// " # ",
|
||||||
" # ",
|
// " # ",
|
||||||
" ",
|
// " ",
|
||||||
// Extra 3
|
// // Extra 3
|
||||||
" ",
|
// " ",
|
||||||
" # ",
|
// " # ",
|
||||||
" # ",
|
// " # ",
|
||||||
"# # #",
|
// "# # #",
|
||||||
" ### ",
|
// " ### ",
|
||||||
" # ",
|
// " # ",
|
||||||
" ",
|
// " ",
|
||||||
// Extra 4
|
// Extra 4
|
||||||
" ",
|
" ",
|
||||||
" # ",
|
" # ",
|
||||||
@@ -815,46 +815,46 @@ const char *font_extras[] = {
|
|||||||
" # ",
|
" # ",
|
||||||
" # ",
|
" # ",
|
||||||
" ",
|
" ",
|
||||||
// Extra 6
|
// // Extra 6
|
||||||
" ",
|
// " ",
|
||||||
" ### ",
|
// " ### ",
|
||||||
"# # #",
|
// "# # #",
|
||||||
"# ###",
|
// "# ###",
|
||||||
"# #",
|
// "# #",
|
||||||
" ### ",
|
// " ### ",
|
||||||
" ",
|
// " ",
|
||||||
// Extra 7
|
// // Extra 7
|
||||||
"#####",
|
// "#####",
|
||||||
"# #",
|
// "# #",
|
||||||
" ### ",
|
// " ### ",
|
||||||
" # ",
|
// " # ",
|
||||||
" # # ",
|
// " # # ",
|
||||||
"# #",
|
// "# #",
|
||||||
"#####",
|
// "#####",
|
||||||
// Extra 8
|
// // Extra 8
|
||||||
" ",
|
// " ",
|
||||||
" ### ",
|
// " ### ",
|
||||||
"# #",
|
// "# #",
|
||||||
"# # #",
|
// "# # #",
|
||||||
"# #",
|
// "# #",
|
||||||
" ### ",
|
// " ### ",
|
||||||
" ",
|
// " ",
|
||||||
// Extra 9
|
// // Extra 9
|
||||||
" ",
|
// " ",
|
||||||
" #",
|
// " #",
|
||||||
" # #",
|
// " # #",
|
||||||
" # #",
|
// " # #",
|
||||||
"#####",
|
// "#####",
|
||||||
" # ",
|
// " # ",
|
||||||
" # ",
|
// " # ",
|
||||||
// Extra 10
|
// // Extra 10
|
||||||
" # ",
|
// " # ",
|
||||||
" # ##",
|
// " # ##",
|
||||||
" # # ",
|
// " # # ",
|
||||||
" ####",
|
// " ####",
|
||||||
" ### ",
|
// " ### ",
|
||||||
"#####",
|
// "#####",
|
||||||
" ### ",
|
// " ### ",
|
||||||
// Extra 11
|
// Extra 11
|
||||||
" ### ",
|
" ### ",
|
||||||
" # # ",
|
" # # ",
|
||||||
@@ -863,57 +863,111 @@ const char *font_extras[] = {
|
|||||||
" ",
|
" ",
|
||||||
" ",
|
" ",
|
||||||
" ",
|
" ",
|
||||||
// Extra 12
|
// // Extra 12
|
||||||
" ",
|
// " ",
|
||||||
" ",
|
// " ",
|
||||||
"# #",
|
// "# #",
|
||||||
"# #",
|
// "# #",
|
||||||
"# ##",
|
// "# ##",
|
||||||
"### #",
|
// "### #",
|
||||||
|
// "# ",
|
||||||
|
// // Extra 13
|
||||||
|
// " # ",
|
||||||
|
// " # ",
|
||||||
|
// "#### ",
|
||||||
|
// " # #",
|
||||||
|
// " # #",
|
||||||
|
// " #",
|
||||||
|
// " ### ",
|
||||||
|
// // Extra 14
|
||||||
|
// "# ",
|
||||||
|
// "## ",
|
||||||
|
// "### ",
|
||||||
|
// "#### ",
|
||||||
|
// "### ",
|
||||||
|
// "## ",
|
||||||
|
// "# ",
|
||||||
|
// // Extra 15
|
||||||
|
// " #",
|
||||||
|
// " ##",
|
||||||
|
// " ###",
|
||||||
|
// " ####",
|
||||||
|
// " ###",
|
||||||
|
// " ##",
|
||||||
|
// " #",
|
||||||
|
// 99 "č"
|
||||||
|
" x x ",
|
||||||
|
" x ",
|
||||||
|
" ### ",
|
||||||
"# ",
|
"# ",
|
||||||
// Extra 13
|
"# ",
|
||||||
|
"# #",
|
||||||
|
" ### ",
|
||||||
|
// 115 "š"
|
||||||
|
" x x ",
|
||||||
|
" x ",
|
||||||
|
" ### ",
|
||||||
|
"# ",
|
||||||
|
" ### ",
|
||||||
|
" #",
|
||||||
|
"#### ",
|
||||||
|
// 105 "i"
|
||||||
|
" #x ",
|
||||||
|
" ",
|
||||||
|
" ## ",
|
||||||
|
" # ",
|
||||||
|
" # ",
|
||||||
|
" # ",
|
||||||
|
" ### ",
|
||||||
|
// 122 "z"
|
||||||
|
" x x ",
|
||||||
|
" x ",
|
||||||
|
"#####",
|
||||||
|
" # ",
|
||||||
" # ",
|
" # ",
|
||||||
" # ",
|
" # ",
|
||||||
"#### ",
|
"#####",
|
||||||
" # #",
|
// 100 "d"
|
||||||
" # #",
|
" x #",
|
||||||
" #",
|
" #",
|
||||||
" ### ",
|
" ## #",
|
||||||
// Extra 14
|
"# ##",
|
||||||
"# ",
|
"# #",
|
||||||
"## ",
|
"# #",
|
||||||
"### ",
|
|
||||||
"#### ",
|
|
||||||
"### ",
|
|
||||||
"## ",
|
|
||||||
"# ",
|
|
||||||
// Extra 15
|
|
||||||
" #",
|
|
||||||
" ##",
|
|
||||||
" ###",
|
|
||||||
" ####",
|
" ####",
|
||||||
" ###",
|
// »
|
||||||
" ##",
|
" ",
|
||||||
" #",
|
"x x ",
|
||||||
|
" x x ",
|
||||||
|
" x x",
|
||||||
|
" x x ",
|
||||||
|
"x x ",
|
||||||
|
" ",
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *font_extras_utf[] = {
|
const char *font_extras_utf[] = {
|
||||||
"�",
|
"�",
|
||||||
"×",
|
// "×",
|
||||||
"↑",
|
// "↑",
|
||||||
"↓",
|
// "↓",
|
||||||
"←",
|
"←",
|
||||||
"→",
|
"→",
|
||||||
"⏰", // clock
|
// "⏱", // clock
|
||||||
"⌛",
|
// "⌛",
|
||||||
"☸",
|
// "☸",
|
||||||
"⏎",
|
// "⏎",
|
||||||
"🌡",
|
// "🌡",
|
||||||
"°",
|
"°",
|
||||||
"μ",
|
// "μ",
|
||||||
"🔙", // back
|
// "⎌", // back
|
||||||
"▶",
|
// "▶",
|
||||||
"◀",
|
// "◀",
|
||||||
|
"č",
|
||||||
|
"š",
|
||||||
|
"í",
|
||||||
|
"ž",
|
||||||
|
"ď",
|
||||||
|
"»",
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "fontedit_render.inc.c"
|
#include "fontedit_render.inc.c"
|
||||||
|
|||||||
+12
-12
@@ -57,7 +57,7 @@ void fb_px(fbpos_t x, fbpos_t y, fbcolor_t color)
|
|||||||
|
|
||||||
uint8_t fb_getpx(fbpos_t x, fbpos_t y)
|
uint8_t fb_getpx(fbpos_t x, fbpos_t y)
|
||||||
{
|
{
|
||||||
if (x >= FBW || y >= FBH) { return 0; }
|
if (x >= FBW || y >= FBH || x < 0 || y < 0) { return 0; }
|
||||||
const fbpos_t row = y / 8;
|
const fbpos_t row = y / 8;
|
||||||
const fbpos_t rowrem = y % 8;
|
const fbpos_t rowrem = y % 8;
|
||||||
const fbsize_t cell = (fbsize_t) x + (fbsize_t) row * FBW;
|
const fbsize_t cell = (fbsize_t) x + (fbsize_t) row * FBW;
|
||||||
@@ -70,7 +70,7 @@ uint8_t fb_getpx(fbpos_t x, fbpos_t y)
|
|||||||
|
|
||||||
void fb_hline(fbpos_t x, fbpos_t y, fbpos_t w, fbcolor_t color)
|
void fb_hline(fbpos_t x, fbpos_t y, fbpos_t w, fbcolor_t color)
|
||||||
{
|
{
|
||||||
if (x >= FBW || y >= FBH) { return; }
|
if (x >= FBW || y >= FBH || x < -w || y < 0) { return; }
|
||||||
w = MIN(FBW - x, w);
|
w = MIN(FBW - x, w);
|
||||||
const fbpos_t row = y / 8;
|
const fbpos_t row = y / 8;
|
||||||
const fbpos_t rowrem = y % 8;
|
const fbpos_t rowrem = y % 8;
|
||||||
@@ -83,7 +83,7 @@ void fb_hline(fbpos_t x, fbpos_t y, fbpos_t w, fbcolor_t color)
|
|||||||
|
|
||||||
void fb_vline(fbpos_t x, fbpos_t y, fbpos_t h, fbcolor_t color)
|
void fb_vline(fbpos_t x, fbpos_t y, fbpos_t h, fbcolor_t color)
|
||||||
{
|
{
|
||||||
if (x >= FBW || y >= FBH) { return; }
|
if (x >= FBW || y >= FBH || x < 0 || y < -h) { return; }
|
||||||
h = MIN(FBH - y - 1, h);
|
h = MIN(FBH - y - 1, h);
|
||||||
const fbpos_t row = y / 8;
|
const fbpos_t row = y / 8;
|
||||||
const fbpos_t rowrem = y % 8;
|
const fbpos_t rowrem = y % 8;
|
||||||
@@ -116,7 +116,7 @@ void fb_vline(fbpos_t x, fbpos_t y, fbpos_t h, fbcolor_t color)
|
|||||||
|
|
||||||
void fb_rect(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, fbcolor_t color)
|
void fb_rect(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, fbcolor_t color)
|
||||||
{
|
{
|
||||||
if (x >= FBW || y >= FBH) { return; }
|
if (x >= FBW || y >= FBH || x < -w || y < -h) { return; }
|
||||||
w = MIN(FBW - x, w);
|
w = MIN(FBW - x, w);
|
||||||
h = MIN(FBH - y, h);
|
h = MIN(FBH - y, h);
|
||||||
const fbpos_t row = y / 8;
|
const fbpos_t row = y / 8;
|
||||||
@@ -232,19 +232,19 @@ void fb_circle(fbpos_t x0, fbpos_t y0, fbpos_t radius, uint8_t thickness, fbcolo
|
|||||||
#if IS_AVR
|
#if IS_AVR
|
||||||
void fb_bitmap_ex_P(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, const uint8_t *map, fbcolor_t color)
|
void fb_bitmap_ex_P(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, const uint8_t *map, fbcolor_t color)
|
||||||
#else
|
#else
|
||||||
void fb_bitmap_ex(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, const uint8_t *map, fbcolor_t color)
|
void fb_bitmap_ex(const fbpos_t x, const fbpos_t y, const fbpos_t w0, const fbpos_t h0, const uint8_t *map, fbcolor_t color)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if (x >= FBW || y >= FBH) { return; }
|
if (x >= FBW || y >= FBH || x < -w0 || y < -h0) { return; }
|
||||||
const fbpos_t w0 = w;
|
const fbpos_t w = MIN(FBW - x, w0);
|
||||||
w = MIN(FBW - x - 1, w);
|
fbpos_t h = MIN(FBH - y - 1, h0); // h is used as counter for rows
|
||||||
h = MIN(FBH - y - 1, h);
|
|
||||||
const fbpos_t row = y / 8;
|
const fbpos_t row = y / 8;
|
||||||
const fbpos_t rowrem = y % 8;
|
const fbpos_t rowrem = y % 8;
|
||||||
fbsize_t cell = (fbsize_t) x + (fbsize_t) row * FBW;
|
fbsize_t cell = (fbsize_t) x + (fbsize_t) row * FBW;
|
||||||
|
const fbpos_t xskip = (x >= 0) ? 0 : (-x);
|
||||||
|
|
||||||
if (rowrem + h <= 8) {
|
if (rowrem + h <= 8) {
|
||||||
for (fbpos_t i = 0; i < w; i++) {
|
for (fbpos_t i = xskip; i < w; i++) {
|
||||||
// all within one cell
|
// all within one cell
|
||||||
const uint8_t mask = (pgm_read_byte(&map[i]) & (0xFF >> (8 - h))) << rowrem;
|
const uint8_t mask = (pgm_read_byte(&map[i]) & (0xFF >> (8 - h))) << rowrem;
|
||||||
draw_mask(cell + i, mask, color);
|
draw_mask(cell + i, mask, color);
|
||||||
@@ -256,7 +256,7 @@ void fb_bitmap_ex(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, const uint8_t *map
|
|||||||
// Draw the bitmap slice-by-slice based on how rows of the bitmap intersect with rows of the canvas.
|
// Draw the bitmap slice-by-slice based on how rows of the bitmap intersect with rows of the canvas.
|
||||||
// This could be optimized to walk each row of the canvas only once, but the code would get bigger.
|
// This could be optimized to walk each row of the canvas only once, but the code would get bigger.
|
||||||
while (h > 0) {
|
while (h > 0) {
|
||||||
for (fbpos_t i = 0; i < w; i++) {
|
for (fbpos_t i = xskip; i < w; i++) {
|
||||||
const uint8_t mask = (pgm_read_byte(&map[i + mapc0]) & (0xFF >> rowrem)) << rowrem;
|
const uint8_t mask = (pgm_read_byte(&map[i + mapc0]) & (0xFF >> rowrem)) << rowrem;
|
||||||
draw_mask(cell + i, mask, color);
|
draw_mask(cell + i, mask, color);
|
||||||
}
|
}
|
||||||
@@ -264,7 +264,7 @@ void fb_bitmap_ex(fbpos_t x, fbpos_t y, fbpos_t w, fbpos_t h, const uint8_t *map
|
|||||||
cell += FBW;
|
cell += FBW;
|
||||||
|
|
||||||
if (rowrem != 0) {
|
if (rowrem != 0) {
|
||||||
for (fbpos_t i = 0; i < w; i++) {
|
for (fbpos_t i = xskip; i < w; i++) {
|
||||||
const uint8_t mask = (pgm_read_byte(&map[i + mapc0]) & (0xFF << (8 - rowrem))) >> (8 - rowrem);
|
const uint8_t mask = (pgm_read_byte(&map[i + mapc0]) & (0xFF << (8 - rowrem))) >> (8 - rowrem);
|
||||||
draw_mask(cell + i, mask, color);
|
draw_mask(cell + i, mask, color);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -100,7 +100,7 @@ void main() {
|
|||||||
fb_text(40, 15, "MEOW", FONT_DOUBLEW, 1);
|
fb_text(40, 15, "MEOW", FONT_DOUBLEW, 1);
|
||||||
fb_text(40, 23, "MEOW", FONT_BOLD, 1);
|
fb_text(40, 23, "MEOW", FONT_BOLD, 1);
|
||||||
|
|
||||||
fb_text(5, 5, "Tiny 3x5", FONT_3X5, 1);
|
fb_text(5, 5, "Tiny 3x5→", FONT_3X5, 1);
|
||||||
fb_text(40, 5, "Tiny 4x5 MEOW", FONT_4X5, 1);
|
fb_text(40, 5, "Tiny 4x5 MEOW", FONT_4X5, 1);
|
||||||
|
|
||||||
fb_frame(12,12,80,20,1,1);
|
fb_frame(12,12,80,20,1,1);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
##########################################################################################################################
|
##########################################################################################################################
|
||||||
# File automatically-generated by tool: [projectgenerator] version: [3.16.0] date: [Sun Mar 12 14:42:27 CET 2023]
|
# File automatically-generated by tool: [projectgenerator] version: [3.16.0] date: [Tue Mar 14 20:49:50 CET 2023]
|
||||||
##########################################################################################################################
|
##########################################################################################################################
|
||||||
|
|
||||||
# ------------------------------------------------
|
# ------------------------------------------------
|
||||||
@@ -47,11 +47,18 @@ Core/Src/usart.c \
|
|||||||
Core/Src/app_oled.c \
|
Core/Src/app_oled.c \
|
||||||
Core/Src/app_main.c \
|
Core/Src/app_main.c \
|
||||||
Core/Src/app_pid.c \
|
Core/Src/app_pid.c \
|
||||||
Core/Src/app_gui.c \
|
Core/Src/Gui/app_gui.c \
|
||||||
|
Core/Src/Gui/screen_menu.c \
|
||||||
|
Core/Src/Gui/screen_home.c \
|
||||||
|
Core/Src/Gui/screen_manual.c \
|
||||||
|
Core/Src/Gui/screen_calibration.c \
|
||||||
|
Core/Src/Gui/screen_manual_menu.c \
|
||||||
Core/Src/app_temp.c \
|
Core/Src/app_temp.c \
|
||||||
Core/Src/app_knob.c \
|
Core/Src/app_knob.c \
|
||||||
Core/Src/app_buzzer.c \
|
Core/Src/app_buzzer.c \
|
||||||
Core/Src/app_heater.c \
|
Core/Src/app_heater.c \
|
||||||
|
Core/Src/app_safety.c \
|
||||||
|
Core/Src/uart_stdout.c \
|
||||||
Core/Src/stm32f1xx_it.c \
|
Core/Src/stm32f1xx_it.c \
|
||||||
Core/Src/system_stm32f1xx.c \
|
Core/Src/system_stm32f1xx.c \
|
||||||
Middlewares/Third_Party/FreeRTOS/Source/croutine.c \
|
Middlewares/Third_Party/FreeRTOS/Source/croutine.c \
|
||||||
@@ -64,8 +71,15 @@ Middlewares/Third_Party/FreeRTOS/Source/timers.c \
|
|||||||
Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c \
|
Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.c \
|
||||||
Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c \
|
Middlewares/Third_Party/FreeRTOS/Source/portable/MemMang/heap_4.c \
|
||||||
Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c \
|
Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c \
|
||||||
Lib/ufb/Src/framebuffer.c Lib/ufb/Src/utf8.c Lib/ufb/Src/font.c Lib/ufb/Src/fb_7seg.c Lib/ufb/Src/fb_text.c \
|
Lib/ufb/Src/framebuffer.c \
|
||||||
|
Lib/ufb/Src/utf8.c \
|
||||||
|
Lib/ufb/Src/font.c \
|
||||||
|
Lib/ufb/Src/fb_7seg.c \
|
||||||
|
Lib/ufb/Src/fb_text.c \
|
||||||
|
Lib/snprintf/snprintf.c \
|
||||||
Core/Src/dma.c \
|
Core/Src/dma.c \
|
||||||
|
Lib/EEPROM_Emul/Core/eeprom_emul.c \
|
||||||
|
Lib/EEPROM_Emul/Porting/STM32F1/flash_interface.c \
|
||||||
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_gpio.c \
|
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_gpio.c \
|
||||||
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_adc.c \
|
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_adc.c \
|
||||||
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_dma.c \
|
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_dma.c \
|
||||||
@@ -75,7 +89,9 @@ Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_exti.c \
|
|||||||
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_spi.c \
|
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_spi.c \
|
||||||
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_tim.c \
|
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_tim.c \
|
||||||
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_usart.c \
|
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_usart.c \
|
||||||
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_pwr.c
|
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_pwr.c \
|
||||||
|
Core/Src/crc.c \
|
||||||
|
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_crc.c
|
||||||
|
|
||||||
# ASM sources
|
# ASM sources
|
||||||
ASM_SOURCES = \
|
ASM_SOURCES = \
|
||||||
@@ -143,13 +159,17 @@ AS_INCLUDES = \
|
|||||||
# C includes
|
# C includes
|
||||||
C_INCLUDES = \
|
C_INCLUDES = \
|
||||||
-ICore/Inc \
|
-ICore/Inc \
|
||||||
|
-ICore/Src \
|
||||||
-IDrivers/STM32F1xx_HAL_Driver/Inc \
|
-IDrivers/STM32F1xx_HAL_Driver/Inc \
|
||||||
-IMiddlewares/Third_Party/FreeRTOS/Source/include \
|
-IMiddlewares/Third_Party/FreeRTOS/Source/include \
|
||||||
-IMiddlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 \
|
-IMiddlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 \
|
||||||
-IMiddlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM3 \
|
-IMiddlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM3 \
|
||||||
-IDrivers/CMSIS/Device/ST/STM32F1xx/Include \
|
-IDrivers/CMSIS/Device/ST/STM32F1xx/Include \
|
||||||
-IDrivers/CMSIS/Include \
|
-IDrivers/CMSIS/Include \
|
||||||
-ILib/ufb/Inc
|
-ILib/ufb/Inc \
|
||||||
|
-ILib/snprintf \
|
||||||
|
-ILib/EEPROM_Emul/Core \
|
||||||
|
-ILib/EEPROM_Emul/Porting/STM32F1
|
||||||
|
|
||||||
|
|
||||||
# compile gcc flags
|
# compile gcc flags
|
||||||
@@ -211,7 +231,7 @@ $(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
|
|||||||
$(BUILD_DIR):
|
$(BUILD_DIR):
|
||||||
mkdir -p $@
|
mkdir -p $@
|
||||||
|
|
||||||
.PHONY: all build flash clean flash flash-stlink analyze
|
.PHONY: all flash clean flash-stlink analyze size fonts
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
# clean up
|
# clean up
|
||||||
@@ -228,11 +248,17 @@ clean:
|
|||||||
|
|
||||||
build: all
|
build: all
|
||||||
|
|
||||||
flash-stlink: $(BUILD_DIR)/$(TARGET).bin
|
size: $(BUILD_DIR)/$(TARGET).elf
|
||||||
st-flash write $< 0x8000000
|
$(SZ) $<
|
||||||
|
|
||||||
flash: $(BUILD_DIR)/$(TARGET).bin
|
flash: $(BUILD_DIR)/$(TARGET).bin
|
||||||
|
st-flash write $< 0x8000000
|
||||||
|
|
||||||
|
flash-pico: $(BUILD_DIR)/$(TARGET).bin
|
||||||
pico-openocd -f target/stm32f1x.cfg -c "program $< 0x08000000 verify reset exit"
|
pico-openocd -f target/stm32f1x.cfg -c "program $< 0x08000000 verify reset exit"
|
||||||
|
|
||||||
analyze: $(BUILD_DIR)/$(TARGET).elf
|
analyze: $(BUILD_DIR)/$(TARGET).elf
|
||||||
python -m elf_size_analyze --rom $<
|
python -m elf_size_analyze --rom $<
|
||||||
|
|
||||||
|
fonts:
|
||||||
|
make -C Lib/ufb fonts
|
||||||
@@ -62,8 +62,8 @@ _Min_Stack_Size = 0x400; /* required amount of stack */
|
|||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
|
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
|
||||||
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 48K
|
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 56K
|
||||||
EEPROM_EMU (rx) : ORIGIN = ORIGIN(FLASH) + LENGTH(FLASH), LENGTH = 16K
|
EEPROM_EMU (rx) : ORIGIN = 0x800E000, LENGTH = 8K
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Define output sections */
|
/* Define output sections */
|
||||||
|
|||||||
Reference in New Issue
Block a user