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-2\#ChannelRegularConversion=ADC_CHANNEL_TEMPSENSOR
ADC1.Channel-3\#ChannelRegularConversion=ADC_CHANNEL_VREFINT
ADC1.ContinuousConvMode=ENABLE
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.ContinuousConvMode=DISABLE
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.NbrOfConversionFlag=1
ADC1.Rank-0\#ChannelRegularConversion=1
@@ -30,9 +31,9 @@ Dma.RequestsNb=1
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.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.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.configENABLE_BACKWARD_COMPATIBILITY=0
FREERTOS.configUSE_MALLOC_FAILED_HOOK=1
@@ -40,7 +41,7 @@ FREERTOS.configUSE_NEWLIB_REENTRANT=1
FREERTOS.configUSE_STATS_FORMATTING_FUNCTIONS=1
FREERTOS.configUSE_TRACE_FACILITY=1
File.Version=6
GPIO.groupedBy=Group By Peripherals
GPIO.groupedBy=Show All
IWDG.IPParameters=Prescaler,Reload
IWDG.Prescaler=IWDG_PRESCALER_256
IWDG.Reload=624
@@ -48,18 +49,20 @@ KeepUserPlacement=false
Mcu.CPN=STM32F103C8T6
Mcu.Family=STM32F1
Mcu.IP0=ADC1
Mcu.IP1=DMA
Mcu.IP10=TIM4
Mcu.IP11=USART1
Mcu.IP2=FREERTOS
Mcu.IP3=IWDG
Mcu.IP4=NVIC
Mcu.IP5=RCC
Mcu.IP6=SPI2
Mcu.IP7=SYS
Mcu.IP8=TIM2
Mcu.IP9=TIM3
Mcu.IPNb=12
Mcu.IP1=CRC
Mcu.IP10=TIM2
Mcu.IP11=TIM3
Mcu.IP12=TIM4
Mcu.IP13=USART1
Mcu.IP2=DMA
Mcu.IP3=FREERTOS
Mcu.IP4=IWDG
Mcu.IP5=NVIC
Mcu.IP6=RCC
Mcu.IP7=SPI2
Mcu.IP8=SYS
Mcu.IP9=TIM1
Mcu.IPNb=14
Mcu.Name=STM32F103C(8-B)Tx
Mcu.Package=LQFP48
Mcu.Pin0=PC13-TAMPER-RTC
@@ -73,12 +76,15 @@ Mcu.Pin15=PB7
Mcu.Pin16=PB8
Mcu.Pin17=VP_ADC1_TempSens_Input
Mcu.Pin18=VP_ADC1_Vref_Input
Mcu.Pin19=VP_FREERTOS_VS_CMSIS_V2
Mcu.Pin19=VP_CRC_VS_CRC
Mcu.Pin2=PA1
Mcu.Pin20=VP_IWDG_VS_IWDG
Mcu.Pin21=VP_SYS_VS_Systick
Mcu.Pin22=VP_TIM2_VS_ClockSourceINT
Mcu.Pin23=VP_TIM3_VS_ClockSourceINT
Mcu.Pin20=VP_FREERTOS_VS_CMSIS_V2
Mcu.Pin21=VP_IWDG_VS_IWDG
Mcu.Pin22=VP_SYS_VS_Systick
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.Pin4=PB0
Mcu.Pin5=PB1
@@ -86,16 +92,16 @@ Mcu.Pin6=PB10
Mcu.Pin7=PB13
Mcu.Pin8=PB15
Mcu.Pin9=PA9
Mcu.PinsNb=24
Mcu.PinsNb=27
Mcu.ThirdPartyNb=0
Mcu.UserConstants=
Mcu.UserName=STM32F103C8Tx
MxCube.Version=6.5.0
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.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.EXTI9_5_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.ForceEnableDMAVector=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
@@ -109,13 +115,13 @@ NVIC.SavedSystickIrqHandlerGenerated=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.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
PA1.GPIOParameters=GPIO_Label
PA1.GPIO_Label=ADC_SENSR
PA1.Locked=true
PA1.Signal=ADCx_IN1
PA10.GPIOParameters=GPIO_PuPd
PA10.GPIO_PuPd=GPIO_PULLUP
PA10.Mode=Asynchronous
PA10.Signal=USART1_RX
PA13.Locked=true
@@ -128,6 +134,8 @@ PA15.GPIOParameters=GPIO_Speed,GPIO_Label
PA15.GPIO_Label=BUZZER
PA15.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
PA15.Signal=S_TIM2_CH1_ETR
PA6.GPIOParameters=GPIO_Label
PA6.GPIO_Label=PWM_HEATER
PA6.Locked=true
PA6.Signal=S_TIM3_CH1
PA9.Mode=Asynchronous
@@ -158,10 +166,12 @@ PB7.GPIOParameters=GPIO_PuPd,GPIO_Label
PB7.GPIO_Label=KNOB_B
PB7.GPIO_PuPd=GPIO_PULLUP
PB7.Signal=S_TIM4_CH2
PB8.GPIOParameters=GPIO_Label
PB8.GPIOParameters=GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultEXTI
PB8.GPIO_Label=KNOB_PUSH
PB8.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_RISING_FALLING
PB8.GPIO_PuPd=GPIO_PULLUP
PB8.Locked=true
PB8.Signal=GPIO_Input
PB8.Signal=GPXTI8
PC13-TAMPER-RTC.GPIOParameters=GPIO_Label
PC13-TAMPER-RTC.GPIO_Label=LED
PC13-TAMPER-RTC.Locked=true
@@ -194,7 +204,7 @@ ProjectManager.StackSize=0x400
ProjectManager.TargetToolchain=Makefile
ProjectManager.ToolChainLocation=
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.ADCPresc=RCC_ADCPCLK2_DIV8
RCC.AHBFreq_Value=64000000
@@ -222,6 +232,8 @@ SH.ADCx_IN0.0=ADC1_IN0,IN0
SH.ADCx_IN0.ConfNb=1
SH.ADCx_IN1.0=ADC1_IN1,IN1
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.ConfNb=1
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.Mode=SPI_MODE_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.IPParameters=Channel-PWM Generation1 CH1,Prescaler
TIM2.Prescaler=2
TIM3.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
TIM3.IPParameters=Channel-PWM Generation1 CH1,Prescaler,Pulse-PWM Generation1 CH1,Period
TIM3.Period=64000
TIM3.Prescaler=2000
TIM3.Prescaler=1000
TIM3.Pulse-PWM\ Generation1\ CH1=0
TIM4.IC1Filter=15
TIM4.IC2Filter=15
TIM4.IPParameters=IC2Filter,Prescaler
TIM4.IPParameters=IC2Filter,Prescaler,IC1Filter
TIM4.Prescaler=0
USART1.IPParameters=VirtualMode,Mode
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_Vref_Input.Mode=IN-Vrefint
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.Signal=FREERTOS_VS_CMSIS_V2
VP_IWDG_VS_IWDG.Mode=IWDG_Activate
VP_IWDG_VS_IWDG.Signal=IWDG_VS_IWDG
VP_SYS_VS_Systick.Mode=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.Signal=TIM2_VS_ClockSourceINT
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
header file. */
/* USER CODE BEGIN 1 */
#include <stdio.h>
#define configASSERT( x ) if ((x) == 0) {taskDISABLE_INTERRUPTS(); printf("configASSERT "__FILE__":%d\r\n",__LINE__); for( ;; );}
#include "snprintf.h"
#define configASSERT( x ) if ((x) == 0) {taskDISABLE_INTERRUPTS(); PRINTF("FreeRTOS assert @ %s:%d\r\n", __FILE__, __LINE__); for( ;; );}
/* USER CODE END 1 */
/* 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 */
/* Define to prevent recursive inclusion -------------------------------------*/
@@ -33,6 +29,7 @@ extern "C" {
/* Includes ------------------------------------------------------------------*/
#include "stm32f1xx_ll_adc.h"
#include "stm32f1xx_ll_crc.h"
#include "stm32f1xx_ll_dma.h"
#include "stm32f1xx_ll_iwdg.h"
#include "stm32f1xx_ll_rcc.h"
@@ -54,6 +51,10 @@ extern "C" {
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
extern void app_emergency_stop(void);
#define __weak __attribute__((weak))
/* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/
@@ -81,10 +82,10 @@ void Error_Handler(void);
/* Private defines -----------------------------------------------------------*/
#define LED_Pin LL_GPIO_PIN_13
#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_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_GPIO_Port GPIOB
#define OLED_DC_Pin LL_GPIO_PIN_1
@@ -99,6 +100,7 @@ void Error_Handler(void);
#define KNOB_B_GPIO_Port GPIOB
#define KNOB_PUSH_Pin LL_GPIO_PIN_8
#define KNOB_PUSH_GPIO_Port GPIOB
#define KNOB_PUSH_EXTI_IRQn EXTI9_5_IRQn
#ifndef NVIC_PRIORITYGROUP_0
#define NVIC_PRIORITYGROUP_0 ((uint32_t)0x00000007) /*!< 0 bit for pre-emption priority,
4 bits for subpriority */
+1 -1
View File
@@ -54,7 +54,7 @@ void UsageFault_Handler(void);
void DebugMon_Handler(void);
void SysTick_Handler(void);
void DMA1_Channel1_IRQHandler(void);
void ADC1_2_IRQHandler(void);
void EXTI9_5_IRQHandler(void);
void TIM4_IRQHandler(void);
/* USER CODE BEGIN EFP */
+1
View File
@@ -36,6 +36,7 @@ extern "C" {
/* USER CODE END Private defines */
void MX_TIM1_Init(void);
void MX_TIM2_Init(void);
void MX_TIM3_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
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;
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);
/* 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 END ADC1_Init 1 */
@@ -82,10 +78,10 @@ void MX_ADC1_Init(void)
LL_ADC_Init(ADC1, &ADC_InitStruct);
ADC_CommonInitStruct.Multimode = LL_ADC_MULTI_INDEPENDENT;
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.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;
LL_ADC_REG_Init(ADC1, &ADC_REG_InitStruct);
+1 -1
View File
@@ -19,8 +19,8 @@ void app_buzzer_init()
{
/* Enable buzzer PWM */
LL_TIM_OC_SetCompareCH1(TIM_BUZZER, 0);
LL_TIM_EnableCounter(TIM_BUZZER);
LL_TIM_CC_EnableChannel(TIM_BUZZER, LL_TIM_CHANNEL_CH1);
LL_TIM_EnableCounter(TIM_BUZZER);
// HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
// 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 "cmsis_os2.h"
#include "tim.h"
#include "queue.h"
#include "app_safety.h"
#include "Gui/gui_event.h"
extern osMutexId_t heaterMutexHandle;
@@ -36,12 +39,15 @@ static struct {
float tuning_p;
float tuning_i;
float tuning_d;
/// Manual PWM override (percent, -1 = override disable)
int manual_override;
// PID state
struct PID pid;
} state = {
.tuning_p = 10.0f,
.tuning_i = 0.052f,
.tuning_d = 100.0f,
.manual_override = -1,
.pid = {
.SampleTimeTicks = pdMS_TO_TICKS(1000),
.outMax = 100.0f,
@@ -59,6 +65,19 @@ static inline void heaterExitCritical() {
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) {
heaterEnterCritical();
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) {
printf("Set heater enabled = %d\r\n", (int) enable);
PRINTF("Set heater enabled = %d\r\n", (int) enable);
heaterEnterCritical();
PID_SetCtlMode(&state.pid, enable ? PID_AUTOMATIC : PID_MANUAL);
heaterExitCritical();
}
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();
PID_SetSetpoint(&state.pid, target);
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)
{
// Wait until inited
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
PUTS("Heater task starts\r\n");
heater_pwm_init();
heaterEnterCritical();
@@ -96,19 +138,29 @@ void app_task_heater(void *argument)
state.oven_temp = app_temp_read_oven();
state.soc_temp = app_temp_read_soc();
enum GuiEvent ev = GUI_EVENT_TEMP_CHANGE;
xQueueSend(guiEventQueHandle, &ev, pdMS_TO_TICKS(100));
heaterEnterCritical();
PID_Compute(&state.pid, state.oven_temp);
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);
app_safety_pass_reg_loop_running();
if (state.manual_override >= 0 && state.manual_override <= 100) {
PRINTF("manual override %d%%\r\n", state.manual_override);
heater_pwm_set_perc(state.manual_override);
} else {
// turn it off
heater_pwm_set_perc(0);
PID_Compute(&state.pid, state.oven_temp);
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();
// 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
#include <stdbool.h>
#include "cmsis_os2.h"
#define MAX_TEMP 400
extern osThreadId_t heaterTskHandle;
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.
/// Mutex is locked internally.
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.
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
+63 -1
View File
@@ -6,6 +6,14 @@
#include "main.h"
#include "app_knob.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 {
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_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() {
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() {
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
#define BLUEPILLTROUBA_APP_KNOB_H
#include <stdbool.h>
void app_knob_init();
uint16_t app_knob_get_raw();
bool app_knob_pushed();
void app_knob_turn_isr();
void app_knob_push_isr(bool push);
#endif //BLUEPILLTROUBA_APP_KNOB_H
+137 -115
View File
@@ -12,78 +12,88 @@
#include "ufb/framebuffer.h"
#include "iwdg.h"
#include "app_oled.h"
#include "ufb/fb_text.h"
#include "ufb/fb_7seg.h"
//#include "ufb/fb_text.h"
//#include "ufb/fb_7seg.h"
#include "app_temp.h"
#include "app_knob.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"
static struct App {
float oven_temp;
int16_t set_temp;
int16_t wheel_normed;
uint16_t wheel;
bool run;
} s_app = {};
extern osThreadId_t heaterTskHandle;
extern osThreadId_t mainTskHandle;
extern osThreadId_t guiTskHandle;
static void redraw_display() {
fb_clear();
//static struct App {
// float oven_temp;
// int16_t set_temp;
// int16_t wheel_normed;
// uint16_t wheel;
// bool run;
//} s_app = {};
char tmp[100];
sprintf(tmp, "T=%d°C", (int) s_app.oven_temp);
fb_text(3, 3, tmp, FONT_5X7, 1);
sprintf(tmp, "Cil=%d°C", s_app.set_temp);
fb_text(3, 11, tmp, FONT_5X7, 1);
sprintf(tmp, "Stav=%s", s_app.run ? "ZAP" : "VYP");
fb_text(3, 19, tmp, FONT_5X7, 1);
if (s_app.run) {
fb_frame(0, 0, FBW, FBH, 2, 1);
}
// some funny effects to showcase responsiveness and circle drawing
fb_circle(FBW / 2, 70, 18, 1, 1);
for (int i = 0; i < 6; i++) {
float x = FBW / 2;
float y = 70;
int ii = i;
float angle = (float) ii * (M_PI / 3.0) - s_app.wheel_normed * (M_PI / 24);
x = x + sinf(angle) * 10;
y = y + cosf(angle) * 10;
fb_circle((fbpos_t) x, (fbpos_t) y, 4, i==0?4:1, 1);
}
fb_text(0, s_app.wheel_normed, ":3 :3", FONT_4X5, 1);
fb_7seg_number(
2, FBH - 20,
10, 16,
2, // th
2, // spacing
1, // color
s_app.wheel,
4, // places
2);// decimals
fb_blit();
}
//static void redraw_display() {
// fb_clear();
//
// char tmp[100];
//
// SPRINTF(tmp, "T=%d°C", (int) s_app.oven_temp);
// fb_text(3, 3, tmp, FONT_5X7, 1);
//
// SPRINTF(tmp, "Cil=%d°C", s_app.set_temp);
// fb_text(3, 11, tmp, FONT_5X7, 1);
//
// SPRINTF(tmp, "Stav=%s", s_app.run ? "ZAP" : "VYP");
// fb_text(3, 19, tmp, FONT_5X7, 1);
//
// if (s_app.run) {
// fb_frame(0, 0, FBW, FBH, 2, 1);
// }
//
// // some funny effects to showcase responsiveness and circle drawing
//
// fb_circle(FBW / 2, 70, 18, 1, 1);
//
// for (int i = 0; i < 6; i++) {
// float x = FBW / 2;
// float y = 70;
//
// int ii = i;
//
// float angle = (float) ii * (M_PI / 3.0) - s_app.wheel_normed * (M_PI / 24);
//
// x = x + sinf(angle) * 10;
// y = y + cosf(angle) * 10;
//
// fb_circle((fbpos_t) x, (fbpos_t) y, 4, i==0?4:1, 1);
// }
//
// fb_text(0, s_app.wheel_normed, ":3 :3", FONT_4X5, 1);
//
// fb_7seg_number(
// 2, FBH - 20,
// 10, 16,
// 2, // th
// 2, // spacing
// 1, // color
// s_app.wheel,
// 4, // places
// 2);// decimals
//
//
//
// fb_blit();
//}
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_buzzer_init();
app_knob_init();
@@ -92,66 +102,78 @@ void app_task_main(void *argument)
oled_init();
fb_clear();
/* Infinite loop */
bool old_pushed = app_knob_pushed();
/* all inited */
bool any_change = true;
uint32_t last_redraw = osKernelGetTickCount();
// notify threads that we are ready
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 (;;) {
// 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;
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));
vTaskDelay(pdMS_TO_TICKS(100));
// feed dogs
LL_IWDG_ReloadCounter(IWDG);
app_safety_poll();
}
}
-5
View File
@@ -2,13 +2,8 @@
// Created by MightyPork on 2022/12/28.
//
#include <stdio.h>
#include <string.h>
#include "ufb/framebuffer.h"
#include "gpio.h"
#include "spi.h"
#include "FreeRTOS.h"
#define SSD1309_HEIGHT 64
+2 -2
View File
@@ -25,7 +25,7 @@ void PID_Compute(struct PID *self, float input)
uint32_t now = xTaskGetTickCount();
int32_t timeChange = (now - self->lastTime);
if (timeChange >= self->SampleTimeTicks) {
printf("compute\r\n");
PUTS("compute\r\n");
/*Compute all the working error variables*/
float error = self->Setpoint - input;
self->ITerm += (self->ki * error);
@@ -35,7 +35,7 @@ void PID_Compute(struct PID *self, float input)
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->ITerm)),
(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 "app_temp.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 */
static volatile uint16_t adc_values[4];
@@ -16,129 +22,176 @@ static volatile uint16_t adc_values[4];
const float V_REFINT = 1.23f;
#define AVERAGEBUF_DEPTH 16
#define OVENTEMP_HISTORY_DEPTH 10
#define OVENTEMP_HISTORY_DEPTH 20
static struct App {
float oven_temp;
float oven_temp_raw;
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];
uint8_t averagebuf_ptr;
float adc_averages[4];
float oventemp_history[OVENTEMP_HISTORY_DEPTH];
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_T_STEP 5.0f
#define TSENSE_T_MIN 0.0f
#define TSENSE_T_MAX 500.0f
static const float TSENSE_LOOKUP[TSENSE_LOOKUP_LEN] = {
0.092678405931418f,
0.0943174479327356f,
0.095948157844312f,
0.0975706768542549f,
0.0991848957506647f,
0.100791037522732f,
0.102388993070241f,
0.103978983136042f,
0.105560980458654f,
0.107135039851509f,
0.108701215616829f,
0.110259642413441f,
0.111810211533421f,
0.113353137226489f,
0.114888310929339f,
0.11641594480226f,
0.117936009906507f,
0.119448557132363f,
0.120953636903929f,
0.122451377845456f,
0.12394167187544f,
0.125424725109556f,
0.126900429638119f,
0.128368989630084f,
0.129830374697352f,
0.131284632150064f,
0.132731808872517f,
0.134172027901771f,
0.135605181883591f,
0.13703146935069f,
0.138450783142958f,
0.139863319976468f,
0.14126904821384f,
0.142668011892657f,
0.144060254660872f,
0.145445894373796f,
0.146824824486877f,
0.14819723645253f,
0.149563023938454f,
0.150922376699229f,
0.15227526202401f,
0.153621720954182f,
0.15496179417407f,
0.156295594725426f,
0.157623016940038f,
0.158944245649448f,
0.160259175412251f,
0.16156798947087f,
0.162870654195634f,
0.164167207880495f,
0.165457688491696f,
0.166742204592451f,
0.168020651444079f,
0.169293207677971f,
0.170559768793747f,
0.171820511933356f,
0.173075402684405f,
0.174324476817747f,
0.175567769803026f,
0.176805386030345f,
0.178037221732226f,
0.179263449725904f,
0.180483966491086f,
0.181698943447122f,
0.182908345518766f,
0.184112206156428f,
0.185310558533273f,
0.186503503145257f,
0.187690937227925f,
0.188873028139146f,
0.190049673368296f,
0.191221038959601f,
0.192387089280576f,
0.193547855644572f,
0.194703369109397f,
0.195853726532112f,
0.196998826174689f,
0.19813883026229f,
0.199273637315452f,
0.200403408323351f,
0.201528107189346f,
0.20264776325594f,
0.203762405629782f,
0.204872127762998f,
0.205976828960191f,
0.207076666615101f,
0.208171540293999f,
0.209261606226334f,
0.210346827933364f,
0.211427232937629f,
0.212502848543705f,
0.213573765013592f,
0.214639882704581f,
0.215701354457324f,
0.216758080892489f,
0.217810213752734f,
0.218857716249547f,
0.219900614222686f,
0.220938933310224f,
0.221972760781578f,
0.223001998051553f,
0.0909090909090909f,
0.0925200328471449f,
0.0941228958173389f,
0.0957178169362106f,
0.0973046872002769f,
0.0988837241910161f,
0.100454819038946f,
0.102018187184848f,
0.103573800259031f,
0.105121710606384f,
0.106661970090864f,
0.108194709632656f,
0.109719820815089f,
0.111237512887056f,
0.112747677594865f,
0.114250522193605f,
0.115746016789507f,
0.117234210034522f,
0.118715150141415f,
0.120188962295434f,
0.121655538774297f,
0.123115081061434f,
0.124567481621389f,
0.126012940077612f,
0.127451425220842f,
0.128882982328346f,
0.13030765627567f,
0.131725566931108f,
0.133136607355006f,
0.134540971782401f,
0.135938553479917f,
0.137329544944786f,
0.138713913835562f,
0.140091702340679f,
0.141462952280536f,
0.142827778585901f,
0.144186075171443f,
0.145538029496198f,
0.146883535696824f,
0.148222779606307f,
0.149555727912261f,
0.150882419971517f,
0.152202894803216f,
0.153517262745702f,
0.154825418625535f,
0.156127543558165f,
0.157423532604634f,
0.158713565356767f,
0.159997607673187f,
0.161275696311014f,
0.162547867717066f,
0.163814227951767f,
0.165074672799026f,
0.166329377427284f,
0.167578237864685f,
0.168821427850084f,
0.170058912538152f,
0.171290726295724f,
0.172516903204089f,
0.17373754533289f,
0.174952549458501f,
0.176162085166716f,
0.177366049485545f,
0.178564610657697f,
0.179757733244091f,
0.180945449410727f,
0.182127791060477f,
0.183304856534839f,
0.184476543628915f,
0.185643016681207f,
0.186804173743842f,
0.18796017789194f,
0.18911099318983f,
0.190256649774341f,
0.191397177539504f,
0.192532671339319f,
0.193663030006298f,
0.194788412940845f,
0.195908719236171f,
0.197024107102852f,
0.198134540194308f,
0.19924004677399f,
0.200340654881021f,
0.201436456102762f,
0.202527350321362f,
0.203613492284647f,
0.204694782137667f,
0.205771373506423f,
0.206843229708988f,
0.20791037727704f,
0.208972842534733f,
0.210030714005839f,
0.211083892628833f,
0.212132528763072f,
0.213176523610881f,
0.214216026472748f,
0.215251000398025f,
0.216281470315524f,
0.21730746096184f,
0.218329057984116f,
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()
{
// 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_StartCalibration(ADC_TEMP);
@@ -152,13 +205,19 @@ void app_analog_init()
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, 4);
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_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
for (int i = 1; i < TSENSE_LOOKUP_LEN; i++) {
@@ -173,6 +232,22 @@ static float val_to_c(float val)
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()
{
uint32_t sums[4] = {};
@@ -190,28 +265,38 @@ void app_temp_sample()
return;
}
s_analog.adc_averages[0] = (float) sums[0] / count;
s_analog.adc_averages[1] = (float) sums[1] / count;
s_analog.adc_averages[2] = (float) sums[2] / count;
s_analog.adc_averages[3] = (float) sums[3] / count;
float adc_averages[4];
adc_averages[0] = (float) sums[0] / 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 */
float refint = s_analog.adc_averages[3];
float refint = adc_averages[3];
float scale = V_REFINT / refint;
const float avg_slope = 4.3f * scale;
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.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,
// 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;
float sum = 0;
@@ -225,7 +310,23 @@ void app_temp_sample()
if (depth > 0) {
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()
@@ -233,6 +334,11 @@ float app_temp_read_oven()
return s_analog.oven_temp;
}
float app_temp_read_oven_raw()
{
return s_analog.oven_temp_raw;
}
float app_temp_read_soc()
{
return s_analog.soc_temp;
@@ -240,6 +346,8 @@ float app_temp_read_soc()
void app_temp_adc_eos()
{
app_safety_pass_adc_sampling();
// notify
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;
@@ -247,5 +355,5 @@ void app_temp_adc_eos()
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();
float val_to_c(float val);
float c_to_val(float c);
void app_temp_set_calib(float a, float b);
/**
* Update temperature measurement.
*
@@ -20,6 +25,9 @@ void app_temp_sample();
/// The value is valid after calling app_temp_sample()
float app_temp_read_oven();
/// Get the raw ADC value (divider voltage)
float app_temp_read_oven_raw();
/// Read current SOC temperature (celsius)
/// The value is valid after calling app_temp_sample()
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 ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include "snprintf.h"
/* USER CODE END Includes */
@@ -90,7 +90,7 @@ const osThreadAttr_t guiTsk_attributes = {
};
/* Definitions for guiEventQue */
osMessageQueueId_t guiEventQueHandle;
uint8_t guiEventQueBuffer[ 16 * 8 ];
uint8_t guiEventQueBuffer[ 32 * 1 ];
osStaticMessageQDef_t guiEventQueControlBlock;
const osMessageQueueAttr_t guiEventQue_attributes = {
.name = "guiEventQue",
@@ -107,6 +107,22 @@ const osTimerAttr_t beepTimer_attributes = {
.cb_mem = &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 */
osMutexId_t heaterMutexHandle;
osStaticMutexDef_t heaterMutexControlBlock;
@@ -125,6 +141,7 @@ void app_task_main(void *argument);
extern void app_task_heater(void *argument);
extern void app_task_gui(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) */
@@ -135,7 +152,7 @@ void vApplicationMallocFailedHook(void);
/* USER CODE BEGIN 4 */
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
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook function is
called if a stack overflow is detected. */
@@ -145,7 +162,7 @@ void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char *pcTaskName)
/* USER CODE BEGIN 5 */
void vApplicationMallocFailedHook(void)
{
printf("vApplicationMallocFailedHook\r\n");
PUTS("vApplicationMallocFailedHook\r\n");
/* vApplicationMallocFailedHook() will only be called if
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.
@@ -184,13 +201,19 @@ void MX_FREERTOS_Init(void) {
/* creation of beepTimer */
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 */
/* start timers, add new ones, ... */
/* USER CODE END RTOS_TIMERS */
/* Create the queue(s) */
/* creation of guiEventQue */
guiEventQueHandle = osMessageQueueNew (16, 8, &guiEventQue_attributes);
guiEventQueHandle = osMessageQueueNew (32, 1, &guiEventQue_attributes);
/* USER CODE BEGIN RTOS_QUEUES */
/* add queues, ... */
@@ -223,7 +246,7 @@ void MX_FREERTOS_Init(void) {
* @retval None
*/
/* 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 */
/* Infinite loop */
+20 -4
View File
@@ -44,6 +44,7 @@
void MX_GPIO_Init(void)
{
LL_EXTI_InitTypeDef EXTI_InitStruct = {0};
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
@@ -98,12 +99,27 @@ void MX_GPIO_Init(void)
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/**/
GPIO_InitStruct.Pin = KNOB_PUSH_Pin;
GPIO_InitStruct.Mode = LL_GPIO_MODE_FLOATING;
LL_GPIO_Init(KNOB_PUSH_GPIO_Port, &GPIO_InitStruct);
LL_GPIO_AF_EnableRemap_PD01();
/**/
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 "cmsis_os.h"
#include "adc.h"
#include "crc.h"
#include "dma.h"
#include "iwdg.h"
#include "spi.h"
@@ -58,6 +59,7 @@
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void MX_FREERTOS_Init(void);
/* USER CODE BEGIN PFP */
@@ -74,72 +76,74 @@ void MX_FREERTOS_Init(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. */
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_AFIO);
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_AFIO);
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
/* System interrupt init*/
NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
/* System interrupt init*/
NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
/* PendSV_IRQn interrupt configuration */
NVIC_SetPriority(PendSV_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),15, 0));
/* SysTick_IRQn interrupt configuration */
NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),15, 0));
/* PendSV_IRQn interrupt configuration */
NVIC_SetPriority(PendSV_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0));
/* SysTick_IRQn interrupt configuration */
NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0));
/** NOJTAG: JTAG-DP Disabled and SW-DP Enabled
*/
LL_GPIO_AF_Remap_SWJ_NOJTAG();
/** NOJTAG: JTAG-DP Disabled and SW-DP Enabled
*/
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 */
SystemClock_Config();
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE BEGIN SysInit */
MX_DMA_Init();
/* USER CODE END SysInit */
MX_DMA_Init();
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_IWDG_Init();
MX_USART1_UART_Init();
MX_ADC1_Init();
MX_DMA_Init();
MX_TIM4_Init();
MX_TIM2_Init();
MX_TIM3_Init();
MX_SPI2_Init();
/* USER CODE BEGIN 2 */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_IWDG_Init();
MX_USART1_UART_Init();
MX_ADC1_Init();
MX_DMA_Init();
MX_TIM4_Init();
MX_TIM2_Init();
MX_TIM3_Init();
MX_SPI2_Init();
MX_TIM1_Init();
MX_CRC_Init();
/* USER CODE BEGIN 2 */
printf("Start.\r\n");
/* USER CODE END 2 */
PUTS("Start.\r\n");
/* USER CODE END 2 */
/* Init scheduler */
osKernelInitialize(); /* Call init function for freertos objects (in freertos.c) */
MX_FREERTOS_Init();
/* Init scheduler */
osKernelInitialize(); /* Call init function for freertos objects (in freertos.c) */
MX_FREERTOS_Init();
/* Start scheduler */
osKernelStart();
/* Start scheduler */
osKernelStart();
/* We should never get here as control is now taken by the scheduler */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* We should never get here as control is now taken by the scheduler */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
app_emergency_stop();
while (1) {
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
@@ -148,46 +152,41 @@ int main(void)
*/
void SystemClock_Config(void)
{
LL_FLASH_SetLatency(LL_FLASH_LATENCY_2);
while(LL_FLASH_GetLatency()!= LL_FLASH_LATENCY_2)
{
}
LL_RCC_HSI_SetCalibTrimming(16);
LL_RCC_HSI_Enable();
LL_FLASH_SetLatency(LL_FLASH_LATENCY_2);
while (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_2) {
}
LL_RCC_HSI_SetCalibTrimming(16);
LL_RCC_HSI_Enable();
/* Wait till HSI is ready */
while(LL_RCC_HSI_IsReady() != 1)
{
/* Wait till HSI is ready */
while (LL_RCC_HSI_IsReady() != 1) {
}
LL_RCC_LSI_Enable();
}
LL_RCC_LSI_Enable();
/* Wait till LSI is ready */
while(LL_RCC_LSI_IsReady() != 1)
{
/* Wait till LSI is ready */
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_Enable();
}
LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI_DIV_2, LL_RCC_PLL_MUL_16);
LL_RCC_PLL_Enable();
/* Wait till PLL is ready */
while(LL_RCC_PLL_IsReady() != 1)
{
/* Wait till PLL is ready */
while (LL_RCC_PLL_IsReady() != 1) {
}
LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_2);
LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
}
LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_2);
LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
/* Wait till System clock is ready */
while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
{
/* Wait till System clock is ready */
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) {
}
LL_Init1msTick(64000000);
LL_SetSystemCoreClock(64000000);
LL_RCC_SetADCClockSource(LL_RCC_ADC_CLKSRC_PCLK2_DIV_8);
}
LL_Init1msTick(64000000);
LL_SetSystemCoreClock(64000000);
LL_RCC_SetADCClockSource(LL_RCC_ADC_CLKSRC_PCLK2_DIV_8);
}
/* USER CODE BEGIN 4 */
@@ -200,17 +199,16 @@ void SystemClock_Config(void)
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
printf("Error_Handler\r\n");
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
PUTS("Error_Handler\r\n");
app_emergency_stop();
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
@@ -220,9 +218,12 @@ void Error_Handler(void)
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
/* USER CODE BEGIN 6 */
PRINTF("assert_failed %s:%d", (const char *) file, (int) line);
app_emergency_stop();
/* 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 */
+93 -74
View File
@@ -24,8 +24,8 @@
#include "task.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include "app_temp.h"
#include "app_knob.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
@@ -62,6 +62,8 @@
/* USER CODE BEGIN EV */
bool EE_NMI_Callback();
/* USER CODE END EV */
/******************************************************************************/
@@ -72,14 +74,19 @@
*/
void NMI_Handler(void)
{
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
/* USER CODE END NonMaskableInt_IRQn 0 */
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */
while (1)
{
}
/* USER CODE END NonMaskableInt_IRQn 1 */
if (EE_NMI_Callback()) {
return;
}
app_emergency_stop();
/* 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)
{
/* USER CODE BEGIN HardFault_IRQn 0 */
printf("HardFault_Handler\r\n");
/* USER CODE BEGIN HardFault_IRQn 0 */
PUTS("HardFault_Handler\r\n");
app_emergency_stop();
/* USER CODE END HardFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
/* USER CODE END W1_HardFault_IRQn 0 */
}
/* USER CODE END HardFault_IRQn 0 */
while (1) {
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
/* USER CODE END W1_HardFault_IRQn 0 */
}
}
/**
@@ -103,15 +110,15 @@ void HardFault_Handler(void)
*/
void MemManage_Handler(void)
{
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
printf("MemManage_Handler\r\n");
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
PUTS("MemManage_Handler\r\n");
app_emergency_stop();
/* USER CODE END MemoryManagement_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
/* USER CODE END W1_MemoryManagement_IRQn 0 */
}
/* USER CODE END MemoryManagement_IRQn 0 */
while (1) {
/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
/* USER CODE END W1_MemoryManagement_IRQn 0 */
}
}
/**
@@ -119,15 +126,15 @@ void MemManage_Handler(void)
*/
void BusFault_Handler(void)
{
/* USER CODE BEGIN BusFault_IRQn 0 */
printf("BusFault_Handler\r\n");
/* USER CODE BEGIN BusFault_IRQn 0 */
PUTS("BusFault_Handler\r\n");
app_emergency_stop();
/* USER CODE END BusFault_IRQn 0 */
/* USER CODE END BusFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_BusFault_IRQn 0 */
/* USER CODE END W1_BusFault_IRQn 0 */
}
while (1) {
/* 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)
{
/* USER CODE BEGIN UsageFault_IRQn 0 */
printf("UsageFault_Handler\r\n");
/* USER CODE BEGIN UsageFault_IRQn 0 */
PUTS("UsageFault_Handler\r\n");
app_emergency_stop();
/* USER CODE END UsageFault_IRQn 0 */
/* USER CODE END UsageFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_UsageFault_IRQn 0 */
/* USER CODE END W1_UsageFault_IRQn 0 */
}
while (1) {
/* 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)
{
/* USER CODE BEGIN DebugMonitor_IRQn 0 */
/* USER CODE BEGIN DebugMonitor_IRQn 0 */
/* USER CODE END DebugMonitor_IRQn 0 */
/* USER CODE BEGIN DebugMonitor_IRQn 1 */
/* USER CODE END DebugMonitor_IRQn 0 */
/* 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)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
/* USER CODE BEGIN SysTick_IRQn 0 */
/* USER CODE END SysTick_IRQn 0 */
#if (INCLUDE_xTaskGetSchedulerState == 1 )
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
{
/* USER CODE END SysTick_IRQn 0 */
#if (INCLUDE_xTaskGetSchedulerState == 1)
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
#endif /* INCLUDE_xTaskGetSchedulerState */
xPortSysTickHandler();
#if (INCLUDE_xTaskGetSchedulerState == 1 )
}
xPortSysTickHandler();
#if (INCLUDE_xTaskGetSchedulerState == 1)
}
#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)
{
/* 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)) {
// LL_ADC_ClearFlag_EOS(ADC_TEMP);
// app_temp_adc_eos();
// }
app_knob_push_isr(0 == state);
/* 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 ADC1_2_IRQn 1 */
/* USER CODE END EXTI9_5_IRQn 1 */
}
/**
@@ -227,12 +239,19 @@ void ADC1_2_IRQHandler(void)
*/
void TIM4_IRQHandler(void)
{
/* USER CODE BEGIN TIM4_IRQn 0 */
/* USER CODE BEGIN TIM4_IRQn 0 */
/* USER CODE END TIM4_IRQn 0 */
/* USER CODE BEGIN TIM4_IRQn 1 */
if (LL_TIM_IsActiveFlag_CC1(TIM4) || LL_TIM_IsActiveFlag_CC2(TIM4)) {
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 */
+64 -4
View File
@@ -24,12 +24,68 @@
/* 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 */
void MX_TIM2_Init(void)
{
/* 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 */
LL_TIM_InitTypeDef TIM_InitStruct = {0};
@@ -81,6 +137,8 @@ void MX_TIM3_Init(void)
/* 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 */
LL_TIM_InitTypeDef TIM_InitStruct = {0};
@@ -93,7 +151,7 @@ void MX_TIM3_Init(void)
/* USER CODE BEGIN 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.Autoreload = 64000;
TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
@@ -117,11 +175,11 @@ void MX_TIM3_Init(void)
/**TIM3 GPIO Configuration
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.Speed = LL_GPIO_SPEED_FREQ_LOW;
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 */
@@ -130,6 +188,8 @@ void MX_TIM4_Init(void)
/* 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 */
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_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_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_SetActiveInput(TIM4, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_DIRECTTI);
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"
/* USER CODE BEGIN 0 */
#include "main.h"
/* USER CODE END 0 */
/* USART1 init function */
@@ -52,7 +51,8 @@ void MX_USART1_UART_Init(void)
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
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);
/* USER CODE BEGIN USART1_Init 1 */
@@ -75,18 +75,4 @@ void MX_USART1_UART_Init(void)
}
/* 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 */
@@ -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
/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
#include <stdbool.h>
#define __IO volatile
#define __weak __attribute__((weak))
#include "eeprom_emul_conf.h"
#include "eeprom_emul_types.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 */
#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 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 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 */
@@ -53,89 +47,44 @@
/* No page define */
#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 */
#ifdef SECURE_FEATURES
#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_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 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 */
#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 */
/**
* @}
*/
/** @defgroup Macros_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_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_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_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);
#endif
#if defined(FLASH_LINES_128B)
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_ReadVariable16bits(uint16_t VirtAddress, uint16_t *pData);
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_CleanUp(void);
EE_Status EE_CleanUp_IT(void);
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 */
@@ -27,64 +27,17 @@
#ifndef __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 */
#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),
for instance 10 to reach 100Kcycles. This factor will increase
pages number */
#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 */
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
/**
* @}
*/
#endif /* __EEPROM_EMUL_CONF_H */
+2 -2
View File
@@ -17,7 +17,7 @@
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __EEPROM_EMUL_TYPES_H
#define __EEPROM_EMUL_TYPES_H
@@ -67,7 +67,7 @@ typedef enum {
/* External return code : action required */
EE_CLEANUP_REQUIRED = 0x100U,
#ifdef DUALCORE_FLASH_SHARING
/* Value returned when a program or erase operation is requested but
* the flash is already used by CPU2 */
@@ -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
/* Includes ------------------------------------------------------------------*/
#include "stm32l4xx_hal.h"
#include "stm32l4xx_ll_crc.h"
#include "stm32l4xx_ll_bus.h"
#include <stdint.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
* @{
@@ -100,11 +120,9 @@
/** @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_IT(uint32_t Page, uint16_t NbPages);
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address);
EE_Status FI_CheckBankConfig(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
#define FONT_DOUBLE (FONT_DOUBLEW | FONT_DOUBLEH)
#define TEXT_CENTER 32
/// Print text stored in flash
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;
}
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) {
const uint8_t *data;
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 {
// 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++) {
uint8_t column = pgm_read_byte(&data[xx]);
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[] = {
{.utf={.symbol=""}, {{0x1f, 0x1f, 0x1f}}},
{.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[] = {
{.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, 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="μ"}, {{0x7c, 0x20, 0x20, 0x10, 0x3c}}},
{.utf={.symbol="🔙"}, {{0x04, 0x4e, 0x55, 0x44, 0x38}}},
{.utf={.symbol=""}, {{0x7f, 0x3e, 0x1c, 0x08, 0x00}}},
{.utf={.symbol=""}, {{0x00, 0x08, 0x1c, 0x3e, 0x7f}}},
{.utf={.symbol="č"}, {{0x38, 0x45, 0x46, 0x45, 0x20}}},
{.utf={.symbol="š"}, {{0x48, 0x55, 0x56, 0x55, 0x20}}},
{.utf={.symbol="í"}, {{0x00, 0x44, 0x7d, 0x41, 0x00}}},
{.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",
" ",
" ",
// Extra 2 "→"
"x ",
" x ",
"xxx",
" x ",
"x ",
};
const char *font_extras_utf[] = {
"",
"°",
"",
};
#include "fontedit_render.inc.c"
+157 -103
View File
@@ -775,30 +775,30 @@ const char *font_extras[] = {
"# #",
"# #",
"#####",
// Extra 1
" ",
"# #",
" # # ",
" # ",
" # # ",
"# #",
" ",
// Extra 2
" ",
" # ",
" ### ",
"# # #",
" # ",
" # ",
" ",
// Extra 3
" ",
" # ",
" # ",
"# # #",
" ### ",
" # ",
" ",
// // Extra 1
// " ",
// "# #",
// " # # ",
// " # ",
// " # # ",
// "# #",
// " ",
// // Extra 2
// " ",
// " # ",
// " ### ",
// "# # #",
// " # ",
// " # ",
// " ",
// // Extra 3
// " ",
// " # ",
// " # ",
// "# # #",
// " ### ",
// " # ",
// " ",
// Extra 4
" ",
" # ",
@@ -815,46 +815,46 @@ const char *font_extras[] = {
" # ",
" # ",
" ",
// Extra 6
" ",
" ### ",
"# # #",
"# ###",
"# #",
" ### ",
" ",
// Extra 7
"#####",
"# #",
" ### ",
" # ",
" # # ",
"# #",
"#####",
// Extra 8
" ",
" ### ",
"# #",
"# # #",
"# #",
" ### ",
" ",
// Extra 9
" ",
" #",
" # #",
" # #",
"#####",
" # ",
" # ",
// Extra 10
" # ",
" # ##",
" # # ",
" ####",
" ### ",
"#####",
" ### ",
// // Extra 6
// " ",
// " ### ",
// "# # #",
// "# ###",
// "# #",
// " ### ",
// " ",
// // Extra 7
// "#####",
// "# #",
// " ### ",
// " # ",
// " # # ",
// "# #",
// "#####",
// // Extra 8
// " ",
// " ### ",
// "# #",
// "# # #",
// "# #",
// " ### ",
// " ",
// // Extra 9
// " ",
// " #",
// " # #",
// " # #",
// "#####",
// " # ",
// " # ",
// // Extra 10
// " # ",
// " # ##",
// " # # ",
// " ####",
// " ### ",
// "#####",
// " ### ",
// 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[] = {
"",
"×",
"",
"",
// "×",
// "↑",
// "↓",
"",
"",
"", // clock
"",
"",
"",
"🌡",
// "⏱", // clock
// "⌛",
// "☸",
// "⏎",
// "🌡",
"°",
"μ",
"🔙", // back
"",
"",
// "μ",
// "⎌", // back
// "▶",
// "◀",
"č",
"š",
"í",
"ž",
"ď",
"»",
};
#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)
{
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 rowrem = y % 8;
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)
{
if (x >= FBW || y >= FBH) { return; }
if (x >= FBW || y >= FBH || x < -w || y < 0) { return; }
w = MIN(FBW - x, w);
const fbpos_t row = 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)
{
if (x >= FBW || y >= FBH) { return; }
if (x >= FBW || y >= FBH || x < 0 || y < -h) { return; }
h = MIN(FBH - y - 1, h);
const fbpos_t row = 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)
{
if (x >= FBW || y >= FBH) { return; }
if (x >= FBW || y >= FBH || x < -w || y < -h) { return; }
w = MIN(FBW - x, w);
h = MIN(FBH - y, h);
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
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
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
{
if (x >= FBW || y >= FBH) { return; }
const fbpos_t w0 = w;
w = MIN(FBW - x - 1, w);
h = MIN(FBH - y - 1, h);
if (x >= FBW || y >= FBH || x < -w0 || y < -h0) { return; }
const fbpos_t w = MIN(FBW - x, w0);
fbpos_t h = MIN(FBH - y - 1, h0); // h is used as counter for rows
const fbpos_t row = y / 8;
const fbpos_t rowrem = y % 8;
fbsize_t cell = (fbsize_t) x + (fbsize_t) row * FBW;
const fbpos_t xskip = (x >= 0) ? 0 : (-x);
if (rowrem + h <= 8) {
for (fbpos_t i = 0; i < w; i++) {
for (fbpos_t i = xskip; i < w; i++) {
// all within one cell
const uint8_t mask = (pgm_read_byte(&map[i]) & (0xFF >> (8 - h))) << rowrem;
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.
// This could be optimized to walk each row of the canvas only once, but the code would get bigger.
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;
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;
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);
draw_mask(cell + i, mask, color);
}
+3 -3
View File
@@ -99,10 +99,10 @@ void main() {
fb_text(15, 15, "MEOW", FONT_DOUBLEH, 1);
fb_text(40, 15, "MEOW", FONT_DOUBLEW, 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_frame(12,12,80,20,1,1);
// fb_text(36, 5, "-123456789.0 CPM°", FONT_TINY, 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_main.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_knob.c \
Core/Src/app_buzzer.c \
Core/Src/app_heater.c \
Core/Src/app_safety.c \
Core/Src/uart_stdout.c \
Core/Src/stm32f1xx_it.c \
Core/Src/system_stm32f1xx.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/portable/MemMang/heap_4.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 \
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_adc.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_tim.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 = \
@@ -143,13 +159,17 @@ AS_INCLUDES = \
# C includes
C_INCLUDES = \
-ICore/Inc \
-ICore/Src \
-IDrivers/STM32F1xx_HAL_Driver/Inc \
-IMiddlewares/Third_Party/FreeRTOS/Source/include \
-IMiddlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2 \
-IMiddlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM3 \
-IDrivers/CMSIS/Device/ST/STM32F1xx/Include \
-IDrivers/CMSIS/Include \
-ILib/ufb/Inc
-ILib/ufb/Inc \
-ILib/snprintf \
-ILib/EEPROM_Emul/Core \
-ILib/EEPROM_Emul/Porting/STM32F1
# compile gcc flags
@@ -211,7 +231,7 @@ $(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
$(BUILD_DIR):
mkdir -p $@
.PHONY: all build flash clean flash flash-stlink analyze
.PHONY: all flash clean flash-stlink analyze size fonts
#######################################
# clean up
@@ -228,11 +248,17 @@ clean:
build: all
flash-stlink: $(BUILD_DIR)/$(TARGET).bin
st-flash write $< 0x8000000
size: $(BUILD_DIR)/$(TARGET).elf
$(SZ) $<
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"
analyze: $(BUILD_DIR)/$(TARGET).elf
python -m elf_size_analyze --rom $<
fonts:
make -C Lib/ufb fonts
+5 -5
View File
@@ -62,8 +62,8 @@ _Min_Stack_Size = 0x400; /* required amount of stack */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 48K
EEPROM_EMU (rx) : ORIGIN = ORIGIN(FLASH) + LENGTH(FLASH), LENGTH = 16K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 56K
EEPROM_EMU (rx) : ORIGIN = 0x800E000, LENGTH = 8K
}
/* Define output sections */
@@ -135,7 +135,7 @@ SECTIONS
_sidata = LOADADDR(.data);
/* Initialized data sections goes into RAM, load LMA copy after code */
.data :
.data :
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
@@ -146,7 +146,7 @@ SECTIONS
_edata = .; /* define a global symbol at data end */
} >RAM AT> FLASH
/* Uninitialized data section */
. = ALIGN(4);
.bss :
@@ -174,7 +174,7 @@ SECTIONS
. = ALIGN(8);
} >RAM
/* Remove information from the standard libraries */
/DISCARD/ :