27 Commits
Author SHA1 Message Date
MightyPork f23f726b2d fix float formatting 2023-04-10 12:00:02 +02:00
MightyPork b6ccfd7019 fix manual override. 2023-04-09 20:09:34 +02:00
MightyPork dc445af419 fixes in calib 2023-04-09 19:53:47 +02:00
MightyPork 1331460ecb calibration mostly working 2023-04-09 19:34:32 +02:00
MightyPork 6749bb5f52 calib GUI WIP 2023-04-09 15:39:21 +02:00
MightyPork 08f1215c24 add two point calibration (no UI yet) 2023-04-09 14:32:09 +02:00
MightyPork 18655e437f ui improvements 2023-04-09 10:30:36 +02:00
MightyPork ccce0ff72f split gui file 2023-04-09 09:45:12 +02:00
MightyPork 415a6cb06c some cz unicode in 5x7 2023-04-08 21:31:29 +02:00
MightyPork 90832fd2f4 move GUI safety check to gui loop (not blit) 2023-04-08 21:15:49 +02:00
MightyPork 170be709fe menu sliding to last px 2023-04-08 21:08:49 +02:00
MightyPork 088b047b39 some comments 2023-04-08 21:02:00 +02:00
MightyPork edd003a541 fixes for partly off-screen bitmap, remove temporary debug changes 2023-04-08 20:52:15 +02:00
MightyPork 0d9565dbb7 partial fix for text drawing in wrong row 2023-04-08 20:24:47 +02:00
MightyPork fcc37515c5 menu sliding, add knob prescaller 2023-04-08 20:05:21 +02:00
MightyPork 64c7d3a94a screens cleanup, doc comments 2023-04-08 18:58:39 +02:00
MightyPork 22b1ba3921 menu fixes, add periodic tick event, add repaint-when-needed 2023-04-08 15:38:16 +02:00
MightyPork b0df411c56 menu improvements, add generic menu func 2023-04-08 15:08:01 +02:00
MightyPork 6048bdf115 base of menu system 2023-04-05 22:42:55 +02:00
MightyPork b397856366 add safety system, stub of new gui task 2023-03-17 00:41:35 +01:00
MightyPork 0a0ccf7bc3 implement EEPROM emulation 2023-03-14 23:05:43 +01:00
MightyPork 56cae1abdb events and exti 2023-03-13 00:38:06 +01:00
MightyPork 091d6c5648 timer based ADC triggering 2023-03-12 21:48:32 +01:00
MightyPork bff7f6e916 move adc sampling to DMA TC interrupt 2023-03-12 20:57:30 +01:00
MightyPork 6eb18ac72e Merge branch 'll' 2023-03-12 20:05:46 +01:00
MightyPork 8376f0b5eb fixes 2023-03-12 20:05:27 +01:00
MightyPork 7e99e2cc6c thin printf, but buggy 2023-03-12 18:42:30 +01:00
77 changed files with 4708 additions and 5488 deletions
+21 -19
View File
File diff suppressed because one or more lines are too long
+56 -31
View File
@@ -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
+2 -2
View File
@@ -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
+50
View File
@@ -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
View File
@@ -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 */
+1 -1
View File
@@ -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 */
+1
View File
@@ -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);
+147
View File
@@ -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();
}
+86
View File
@@ -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
+38
View File
@@ -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
+218
View File
@@ -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;
}
}
+38
View File
@@ -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);
}
+78
View File
@@ -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();
}
}
+35
View File
@@ -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);
}
+116
View File
@@ -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();
}
}
+30
View File
@@ -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
View File
@@ -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);
+1 -1
View File
@@ -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);
-14
View File
@@ -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));
}
}
-10
View File
@@ -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
View File
@@ -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));
} }
} }
+15
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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();
} }
} }
-5
View File
@@ -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
View File
@@ -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))
+64
View File
@@ -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
}
}
+30
View File
@@ -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
View File
@@ -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]);
} }
+8
View File
@@ -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();
+49
View File
@@ -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 */
+13
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
+15
View File
@@ -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
+52
View File
@@ -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;
}
+8
View File
@@ -0,0 +1,8 @@
/**
* TODO file description
*/
#ifndef BLUEPILLTROUBA_UART_STDOUT_H
#define BLUEPILLTROUBA_UART_STDOUT_H
#endif //BLUEPILLTROUBA_UART_STDOUT_H
+2 -16
View File
@@ -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>&copy; 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>&copy; 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****/
File diff suppressed because it is too large Load Diff
+28 -79
View File
@@ -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 */
@@ -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>&copy; 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>&copy; 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>&copy; 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****/
@@ -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>&copy; 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>&copy; 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>&copy; 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>&copy; 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>&copy; 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>&copy; 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>&copy; 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>&copy; 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>&copy; 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>&copy; 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>&copy; 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>&copy; 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>&copy; 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
+44
View File
@@ -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
+2
View File
@@ -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
View File
@@ -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++) {
+1
View File
@@ -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}}},
}; };
+6 -12
View File
@@ -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}}},
}; };
+7
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
+34 -8
View File
@@ -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
+2 -2
View File
@@ -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 */