Compare commits
No commits in common. 'master' and 'll' have entirely different histories.
File diff suppressed because one or more lines are too long
@ -1,50 +0,0 @@ |
|||||||
/* 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__ */ |
|
||||||
|
|
@ -1,158 +0,0 @@ |
|||||||
/**
|
|
||||||
* 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" |
|
||||||
#include "app_heater.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) { |
|
||||||
PRINTF("Screen = %p, init=%d\r\n", pScreen, 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", app_temp_read_oven(), (int) app_heater_get_target()); |
|
||||||
fb_text(3, 3, stmp, FONT_3X5, 1); |
|
||||||
|
|
||||||
float soc = app_temp_read_soc(); |
|
||||||
if (soc > 70) { |
|
||||||
SPRINTF(stmp, "! CHIP %d°C !", (int) soc); |
|
||||||
fb_text(3, 14, stmp, FONT_3X5, 1); |
|
||||||
} |
|
||||||
|
|
||||||
if (app_heater_get_state()) { |
|
||||||
fb_frame(0, 0, FBW, 11, 1, 1); |
|
||||||
|
|
||||||
float perc = app_heater_get_percent(); |
|
||||||
fb_hline(0, 12, (fbpos_t) ((float)FBW * (perc / 100.0f)), 1); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** Play input sound effect if this is an input event */ |
|
||||||
void input_sound_effect() { |
|
||||||
app_buzzer_beep(); |
|
||||||
} |
|
@ -1,88 +0,0 @@ |
|||||||
/**
|
|
||||||
* 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); |
|
||||||
void screen_pid_tuning(GuiEvent event); |
|
||||||
void screen_calib_edit(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
|
|
@ -1,38 +0,0 @@ |
|||||||
//
|
|
||||||
// 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
|
|
@ -1,217 +0,0 @@ |
|||||||
//
|
|
||||||
// Created by MightyPork on 2023/05/06
|
|
||||||
//
|
|
||||||
|
|
||||||
#include <string.h> |
|
||||||
#include "app_gui.h" |
|
||||||
#include "app_heater.h" |
|
||||||
#include "ufb/fb_text.h" |
|
||||||
#include "snprintf.h" |
|
||||||
#include "app_temp.h" |
|
||||||
|
|
||||||
static void apply_calib(bool temporary); |
|
||||||
|
|
||||||
static struct calib_tuning_state { |
|
||||||
uint8_t digits[6 * 4]; // a b l r
|
|
||||||
|
|
||||||
int cursor; // the digit under cursor (range 0-17)
|
|
||||||
bool digit_editing; // true if we are editing a digit
|
|
||||||
} s_tuning; |
|
||||||
|
|
||||||
static void draw_digit_row(int row) { |
|
||||||
fbpos_t x = (FBW - (6 * 7 - 1)) / 2; |
|
||||||
fbpos_t y = 30 + row * 10; |
|
||||||
|
|
||||||
char buf2[2] = {}; |
|
||||||
|
|
||||||
int numofs = row * 6; |
|
||||||
|
|
||||||
const char * labels[4] = {"a","b","L", "R"}; |
|
||||||
const int decimal_pos[4] = {2, 0, 3, 3}; |
|
||||||
fb_text(FBW - 4, y + 2, labels[row], FONT_3X5, 1); |
|
||||||
|
|
||||||
bool significant = row == 1; |
|
||||||
for (int i = 0; i < 6; i++) { |
|
||||||
if (i >= decimal_pos[row]) significant = 1; |
|
||||||
|
|
||||||
int val = s_tuning.digits[numofs + i]; |
|
||||||
if (val != 0) { |
|
||||||
significant = true; |
|
||||||
} |
|
||||||
|
|
||||||
buf2[0] = '0' + val; |
|
||||||
|
|
||||||
if (s_tuning.cursor == numofs + i) { |
|
||||||
if (s_tuning.digit_editing) { |
|
||||||
fb_rect(x-1, y-1, 5+2, 7+2, 1); |
|
||||||
fb_text(x, y, buf2, 0, 0); |
|
||||||
} else { |
|
||||||
fb_hline(x, y + 8, 5, 1); |
|
||||||
if (significant) fb_text(x, y, buf2, 0, 1); |
|
||||||
} |
|
||||||
} else { |
|
||||||
if (significant) fb_text(x, y, buf2, 0, 1); |
|
||||||
} |
|
||||||
|
|
||||||
x += 6; |
|
||||||
if (i == decimal_pos[row]) { |
|
||||||
fb_text(x, y, ".", 0, 1); |
|
||||||
x += 6; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void screen_calib_edit(GuiEvent event) |
|
||||||
{ |
|
||||||
float A, B, L, R; |
|
||||||
uint32_t Ai, Bi, Li, Ri; |
|
||||||
|
|
||||||
if (event == GUI_EVENT_SCREEN_INIT) { |
|
||||||
memset(&s_tuning, 0, sizeof(s_tuning)); |
|
||||||
|
|
||||||
app_temp_get_calib(&A, &B, &L, &R); |
|
||||||
app_temp_backup_calib(); |
|
||||||
|
|
||||||
Ai = (uint32_t)(A * 1000.f); |
|
||||||
Bi = (uint32_t)(B * 100000.f); |
|
||||||
Li = (uint32_t)(L * 100.f); |
|
||||||
Ri = (uint32_t)(R * 100.f); |
|
||||||
|
|
||||||
char buf[25]; |
|
||||||
SNPRINTF(buf, 25, "%06lu%06lu%06lu%06lu", Ai, Bi, Li, Ri); |
|
||||||
for(int i = 0; i < 6*4; i++) { |
|
||||||
s_tuning.digits[i] = buf[i] - '0'; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
switch (event) { |
|
||||||
case GUI_EVENT_PAINT: { |
|
||||||
fb_text(FBW / 2, 16, "Kalibrace", TEXT_CENTER, 1); |
|
||||||
|
|
||||||
draw_digit_row(0); |
|
||||||
draw_digit_row(1); |
|
||||||
draw_digit_row(2); |
|
||||||
draw_digit_row(3); |
|
||||||
|
|
||||||
//68
|
|
||||||
#define BTNS_TOP 72 |
|
||||||
|
|
||||||
if (s_tuning.cursor == 24) { |
|
||||||
fb_rect(0, BTNS_TOP, FBW, 9, 1); |
|
||||||
} |
|
||||||
fb_text(FBW / 2, BTNS_TOP + 1, "Zrušit", TEXT_CENTER, s_tuning.cursor != 24); |
|
||||||
|
|
||||||
if (s_tuning.cursor == 25) { |
|
||||||
fb_rect(0, BTNS_TOP + 9, FBW, 9, 1); |
|
||||||
} |
|
||||||
fb_text(FBW / 2, BTNS_TOP + 1 + 9, "Uložit", TEXT_CENTER, s_tuning.cursor != 25); |
|
||||||
|
|
||||||
fb_text(2, FBH - 8 * (1 + (s_tuning.cursor < 24)), s_tuning.digit_editing ? "←→Hodnota" : "←→Kurzor", 0, 1); |
|
||||||
if (s_tuning.cursor < 24) { |
|
||||||
fb_text(2, FBH - 8 * 1, s_tuning.digit_editing ? "> Potvrdit" : "> Změnit", 0, 1); |
|
||||||
} |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
case GUI_EVENT_KNOB_PLUS: { |
|
||||||
input_sound_effect(); |
|
||||||
request_paint(); |
|
||||||
|
|
||||||
if (s_tuning.digit_editing) { |
|
||||||
if (s_tuning.digits[s_tuning.cursor] == 9) { |
|
||||||
s_tuning.digits[s_tuning.cursor] = 0; |
|
||||||
} else { |
|
||||||
s_tuning.digits[s_tuning.cursor]++; |
|
||||||
} |
|
||||||
apply_calib(false); |
|
||||||
} else { |
|
||||||
// 24 - cancel
|
|
||||||
// 25 - save
|
|
||||||
s_tuning.cursor++; |
|
||||||
if (s_tuning.cursor >= 24) { |
|
||||||
s_tuning.digit_editing = false; |
|
||||||
} |
|
||||||
if (s_tuning.cursor > 25) { |
|
||||||
s_tuning.cursor = 0; |
|
||||||
} |
|
||||||
} |
|
||||||
break; |
|
||||||
} |
|
||||||
|
|
||||||
case GUI_EVENT_KNOB_MINUS: { |
|
||||||
input_sound_effect(); |
|
||||||
request_paint(); |
|
||||||
|
|
||||||
if (s_tuning.digit_editing) { |
|
||||||
if (s_tuning.digits[s_tuning.cursor] == 0) { |
|
||||||
s_tuning.digits[s_tuning.cursor] = 9; |
|
||||||
} else { |
|
||||||
s_tuning.digits[s_tuning.cursor]--; |
|
||||||
} |
|
||||||
apply_calib(false); |
|
||||||
} else { |
|
||||||
// 24 - cancel
|
|
||||||
// 25 - save
|
|
||||||
if (s_tuning.cursor == 0) { |
|
||||||
s_tuning.cursor = 25; |
|
||||||
s_tuning.digit_editing = false; |
|
||||||
} else { |
|
||||||
s_tuning.cursor--; |
|
||||||
} |
|
||||||
} |
|
||||||
break; |
|
||||||
} |
|
||||||
|
|
||||||
case GUI_EVENT_KNOB_RELEASE: { |
|
||||||
if (s_tuning.cursor < 24) { |
|
||||||
s_tuning.digit_editing = !s_tuning.digit_editing; |
|
||||||
} else if (s_tuning.cursor == 24) { |
|
||||||
// cancel
|
|
||||||
app_temp_restore_calib(); |
|
||||||
switch_screen(screen_home, true); |
|
||||||
} else if (s_tuning.cursor == 25) { |
|
||||||
// save
|
|
||||||
apply_calib(true); |
|
||||||
switch_screen(screen_home, true); |
|
||||||
} |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void apply_calib(bool temporary) { |
|
||||||
float A, B, L, R; |
|
||||||
uint32_t Ai, Bi, Li, Ri; |
|
||||||
|
|
||||||
Ai = Bi = Li = Ri = 0; |
|
||||||
|
|
||||||
for(int i = 0; i < 6; i++) { |
|
||||||
Ai *= 10; |
|
||||||
Ai += s_tuning.digits[i]; |
|
||||||
} |
|
||||||
for(int i = 6; i < 12; i++) { |
|
||||||
Bi *= 10; |
|
||||||
Bi += s_tuning.digits[i]; |
|
||||||
} |
|
||||||
for(int i = 12; i < 18; i++) { |
|
||||||
Li *= 10; |
|
||||||
Li += s_tuning.digits[i]; |
|
||||||
} |
|
||||||
for(int i = 18; i < 24; i++) { |
|
||||||
Ri *= 10; |
|
||||||
Ri += s_tuning.digits[i]; |
|
||||||
} |
|
||||||
|
|
||||||
A = ((float) Ai) / 1000.f; |
|
||||||
B = ((float) Bi) / 100000.f; |
|
||||||
L = ((float) Li) / 100.f; |
|
||||||
R = ((float) Ri) / 100.f; |
|
||||||
|
|
||||||
if (temporary) { |
|
||||||
app_temp_set_calib_temporary(A, B); |
|
||||||
app_temp_set_calib_temporary_r(L, R); |
|
||||||
} else { |
|
||||||
app_temp_set_calib_persistent(A, B); |
|
||||||
app_temp_set_calib_persistent_r(L, R); |
|
||||||
} |
|
||||||
} |
|
@ -1,242 +0,0 @@ |
|||||||
//
|
|
||||||
// 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 stop_heater() { |
|
||||||
app_heater_set_target(0); |
|
||||||
app_heater_enable(false); |
|
||||||
} |
|
||||||
|
|
||||||
static void calib_abort() { |
|
||||||
app_temp_restore_calib(); |
|
||||||
stop_heater(); |
|
||||||
switch_screen(screen_home, true); |
|
||||||
} |
|
||||||
|
|
||||||
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_set_target(100); |
|
||||||
app_heater_enable(true); |
|
||||||
break; |
|
||||||
|
|
||||||
case 1: |
|
||||||
calib_abort(); |
|
||||||
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.temp1 = 100; |
|
||||||
s_calib.sample1 = app_temp_read_oven_raw(); |
|
||||||
app_heater_enable(false); |
|
||||||
break; |
|
||||||
|
|
||||||
case 1: |
|
||||||
calib_abort(); |
|
||||||
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.temp2 = 200; |
|
||||||
s_calib.sample2 = app_temp_read_oven_raw(); |
|
||||||
app_heater_enable(false); |
|
||||||
break; |
|
||||||
|
|
||||||
case 1: |
|
||||||
calib_abort(); |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void screen_calibration(GuiEvent event) |
|
||||||
{ |
|
||||||
if (event == GUI_EVENT_SCREEN_INIT) { |
|
||||||
app_temp_backup_calib(); |
|
||||||
app_temp_set_calib_temporary(1, 0); |
|
||||||
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: |
|
||||||
if (event == GUI_EVENT_PAINT) { |
|
||||||
fb_text(FBW/2, 16, "Vyčkej", TEXT_CENTER, 1); |
|
||||||
fb_text(FBW/2, 26, "ustálení", TEXT_CENTER, 1); |
|
||||||
} |
|
||||||
screen_menu_offset(event, sample1_menu_opts, sample1_menu_cb, 30); |
|
||||||
break; |
|
||||||
|
|
||||||
case PH_SAMPLE2: |
|
||||||
if (event == GUI_EVENT_PAINT) { |
|
||||||
fb_text(FBW/2, 16, "Vyčkej", TEXT_CENTER, 1); |
|
||||||
fb_text(FBW/2, 26, "ustálení", TEXT_CENTER, 1); |
|
||||||
} |
|
||||||
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(); |
|
||||||
calib_abort(); |
|
||||||
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(); |
|
||||||
|
|
||||||
PRINTF("KNOB_REL PH %d\r\n", s_calib.phase); |
|
||||||
|
|
||||||
if (s_calib.phase == PH_DONE) { |
|
||||||
app_heater_set_target(0); |
|
||||||
app_heater_enable(false); |
|
||||||
|
|
||||||
// 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_persistent(a, b); |
|
||||||
} else if (s_calib.phase == PH_SAMPLE1) { |
|
||||||
app_heater_set_target(100); |
|
||||||
app_heater_enable(true); |
|
||||||
} else if (s_calib.phase == PH_SAMPLE2) { |
|
||||||
app_heater_set_target(200); |
|
||||||
app_heater_enable(true); |
|
||||||
} |
|
||||||
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) { |
|
||||||
stop_heater(); |
|
||||||
switch_screen(screen_home, 1); |
|
||||||
} |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
@ -1,44 +0,0 @@ |
|||||||
//
|
|
||||||
// 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", |
|
||||||
"Ladění PID", |
|
||||||
"Auto kalibrace", |
|
||||||
"Ruční kalibrace", |
|
||||||
NULL |
|
||||||
}; |
|
||||||
|
|
||||||
static void main_menu_cb(int opt) { |
|
||||||
switch (opt) { |
|
||||||
case 0: |
|
||||||
switch_screen(screen_manual, true); |
|
||||||
break; |
|
||||||
case 1: |
|
||||||
switch_screen(screen_pid_tuning, true); |
|
||||||
break; |
|
||||||
case 2: |
|
||||||
switch_screen(screen_calibration, true); |
|
||||||
break; |
|
||||||
case 3: |
|
||||||
switch_screen(screen_calib_edit, 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); |
|
||||||
} |
|
@ -1,78 +0,0 @@ |
|||||||
//
|
|
||||||
// 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(); |
|
||||||
} |
|
||||||
} |
|
@ -1,35 +0,0 @@ |
|||||||
//
|
|
||||||
// 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); |
|
||||||
} |
|
@ -1,116 +0,0 @@ |
|||||||
//
|
|
||||||
// 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(); |
|
||||||
} |
|
||||||
} |
|
@ -1,30 +0,0 @@ |
|||||||
//
|
|
||||||
// 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
|
|
@ -1,194 +0,0 @@ |
|||||||
//
|
|
||||||
// Created by MightyPork on 2023/04/09.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include <string.h> |
|
||||||
#include "app_gui.h" |
|
||||||
#include "app_heater.h" |
|
||||||
#include "ufb/fb_text.h" |
|
||||||
#include "snprintf.h" |
|
||||||
|
|
||||||
static struct calib_tuning_state { |
|
||||||
uint8_t digits[6 * 3]; |
|
||||||
|
|
||||||
// uint32_t Kp, Ki, Kd; // these are the float x 1000
|
|
||||||
|
|
||||||
int cursor; // the digit under cursor (range 0-17)
|
|
||||||
bool digit_editing; // true if we are editing a digit
|
|
||||||
} s_tuning; |
|
||||||
|
|
||||||
static void draw_digit_row(int row) { |
|
||||||
fbpos_t x = (FBW - (6 * 7 - 1)) / 2; |
|
||||||
fbpos_t y = 30 + row * 10; |
|
||||||
|
|
||||||
char buf2[2] = {}; |
|
||||||
|
|
||||||
int numofs = row * 6; |
|
||||||
|
|
||||||
const char * labels[3] = {"P","I","D"}; |
|
||||||
fb_text(FBW - 4, y + 2, labels[row], FONT_3X5, 1); |
|
||||||
|
|
||||||
bool significant = false; |
|
||||||
for (int i = 0; i < 6; i++) { |
|
||||||
if (i >= 2) significant = 1; |
|
||||||
|
|
||||||
int val = s_tuning.digits[numofs + i]; |
|
||||||
if (val != 0) { |
|
||||||
significant = true; |
|
||||||
} |
|
||||||
|
|
||||||
buf2[0] = '0' + val; |
|
||||||
|
|
||||||
if (s_tuning.cursor == numofs + i) { |
|
||||||
if (s_tuning.digit_editing) { |
|
||||||
fb_rect(x-1, y-1, 5+2, 7+2, 1); |
|
||||||
fb_text(x, y, buf2, 0, 0); |
|
||||||
} else { |
|
||||||
fb_hline(x, y + 8, 5, 1); |
|
||||||
if (significant) fb_text(x, y, buf2, 0, 1); |
|
||||||
} |
|
||||||
} else { |
|
||||||
if (significant) fb_text(x, y, buf2, 0, 1); |
|
||||||
} |
|
||||||
|
|
||||||
x += 6; |
|
||||||
if ( i == 2) { |
|
||||||
fb_text(x, y, ".", 0, 1); |
|
||||||
x += 6; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void screen_pid_tuning(GuiEvent event) |
|
||||||
{ |
|
||||||
float Kp; |
|
||||||
float Ki; |
|
||||||
float Kd; |
|
||||||
uint32_t Kp_i; |
|
||||||
uint32_t Ki_i; |
|
||||||
uint32_t Kd_i; |
|
||||||
|
|
||||||
if (event == GUI_EVENT_SCREEN_INIT) { |
|
||||||
memset(&s_tuning, 0, sizeof(s_tuning)); |
|
||||||
app_heater_get_tuning(&Kp, &Ki, &Kd); |
|
||||||
|
|
||||||
Kp_i = (uint32_t)(Kp * 1000.f); |
|
||||||
Ki_i = (uint32_t)(Ki * 1000.f); |
|
||||||
Kd_i = (uint32_t)(Kd * 1000.f); |
|
||||||
|
|
||||||
char buf[19]; |
|
||||||
SNPRINTF(buf, 19, "%06lu%06lu%06lu", Kp_i, Ki_i, Kd_i); |
|
||||||
for(int i = 0; i < 18; i++) { |
|
||||||
s_tuning.digits[i] = buf[i] - '0'; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
switch (event) { |
|
||||||
case GUI_EVENT_PAINT: { |
|
||||||
fb_text(FBW / 2, 16, "Ladění PID", TEXT_CENTER, 1); |
|
||||||
|
|
||||||
draw_digit_row(0); |
|
||||||
draw_digit_row(1); |
|
||||||
draw_digit_row(2); |
|
||||||
|
|
||||||
if (s_tuning.cursor == 18) { |
|
||||||
fb_rect(0, 68, FBW, 9, 1); |
|
||||||
} |
|
||||||
fb_text(FBW / 2, 69, "Zrušit", TEXT_CENTER, s_tuning.cursor != 18); |
|
||||||
|
|
||||||
if (s_tuning.cursor == 19) { |
|
||||||
fb_rect(0, 68 + 9, FBW, 9, 1); |
|
||||||
} |
|
||||||
fb_text(FBW / 2, 69 + 9, "Uložit", TEXT_CENTER, s_tuning.cursor != 19); |
|
||||||
|
|
||||||
fb_text(2, FBH - 8 * (1 + (s_tuning.cursor < 18)), s_tuning.digit_editing ? "←→Hodnota" : "←→Kurzor", 0, 1); |
|
||||||
if (s_tuning.cursor < 18) { |
|
||||||
fb_text(2, FBH - 8 * 1, s_tuning.digit_editing ? "> Potvrdit" : "> Změnit", 0, 1); |
|
||||||
} |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
case GUI_EVENT_KNOB_PLUS: { |
|
||||||
input_sound_effect(); |
|
||||||
request_paint(); |
|
||||||
|
|
||||||
if (s_tuning.digit_editing) { |
|
||||||
if (s_tuning.digits[s_tuning.cursor] == 9) { |
|
||||||
s_tuning.digits[s_tuning.cursor] = 0; |
|
||||||
} else { |
|
||||||
s_tuning.digits[s_tuning.cursor]++; |
|
||||||
} |
|
||||||
} else { |
|
||||||
// 18 - cancel
|
|
||||||
// 19 - save
|
|
||||||
s_tuning.cursor++; |
|
||||||
if (s_tuning.cursor > 17) { |
|
||||||
s_tuning.digit_editing = false; |
|
||||||
} |
|
||||||
if (s_tuning.cursor > 19) { |
|
||||||
s_tuning.cursor = 0; |
|
||||||
} |
|
||||||
} |
|
||||||
break; |
|
||||||
} |
|
||||||
|
|
||||||
case GUI_EVENT_KNOB_MINUS: { |
|
||||||
input_sound_effect(); |
|
||||||
request_paint(); |
|
||||||
|
|
||||||
if (s_tuning.digit_editing) { |
|
||||||
if (s_tuning.digits[s_tuning.cursor] == 0) { |
|
||||||
s_tuning.digits[s_tuning.cursor] = 9; |
|
||||||
} else { |
|
||||||
s_tuning.digits[s_tuning.cursor]--; |
|
||||||
} |
|
||||||
} else { |
|
||||||
// 18 - cancel
|
|
||||||
// 19 - save
|
|
||||||
if (s_tuning.cursor == 0) { |
|
||||||
s_tuning.cursor = 19; |
|
||||||
s_tuning.digit_editing = false; |
|
||||||
} else { |
|
||||||
s_tuning.cursor--; |
|
||||||
} |
|
||||||
} |
|
||||||
break; |
|
||||||
} |
|
||||||
|
|
||||||
case GUI_EVENT_KNOB_RELEASE: { |
|
||||||
if (s_tuning.cursor < 18) { |
|
||||||
s_tuning.digit_editing = !s_tuning.digit_editing; |
|
||||||
} else if (s_tuning.cursor == 18) { |
|
||||||
// cancel
|
|
||||||
switch_screen(screen_home, true); |
|
||||||
} else if (s_tuning.cursor == 19) { |
|
||||||
// save
|
|
||||||
|
|
||||||
Kp_i = Ki_i = Kd_i = 0; |
|
||||||
for(int i = 0; i < 6; i++) { |
|
||||||
Kp_i *= 10; |
|
||||||
Kp_i += s_tuning.digits[i]; |
|
||||||
} |
|
||||||
for(int i = 6; i < 12; i++) { |
|
||||||
Ki_i *= 10; |
|
||||||
Ki_i += s_tuning.digits[i]; |
|
||||||
} |
|
||||||
for(int i = 12; i < 18; i++) { |
|
||||||
Kd_i *= 10; |
|
||||||
Kd_i += s_tuning.digits[i]; |
|
||||||
} |
|
||||||
|
|
||||||
Kp = ((float) Kp_i) / 1000.f; |
|
||||||
Ki = ((float) Ki_i) / 1000.f; |
|
||||||
Kd = ((float) Kd_i) / 1000.f; |
|
||||||
|
|
||||||
app_heater_set_tuning(Kp, Ki, Kd); |
|
||||||
|
|
||||||
app_heater_save_tuning(); |
|
||||||
|
|
||||||
switch_screen(screen_home, true); |
|
||||||
} |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,14 @@ |
|||||||
|
/**
|
||||||
|
* 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)); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,10 @@ |
|||||||
|
/**
|
||||||
|
* TODO file description |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef BLUEPILLTROUBA_APP_GUI_H |
||||||
|
#define BLUEPILLTROUBA_APP_GUI_H |
||||||
|
|
||||||
|
void app_task_gui(void *argument); |
||||||
|
|
||||||
|
#endif //BLUEPILLTROUBA_APP_GUI_H
|
@ -1,66 +0,0 @@ |
|||||||
/**
|
|
||||||
* 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)
|
|
||||||
#define HB_FLAG_ALL (0b111110) // FIXME !!!! disabling the temp watchdog
|
|
||||||
|
|
||||||
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() { |
|
||||||
//PRINTF("\r\n*** HB FLAGS %x ***\r\n", heartbeat_flags);
|
|
||||||
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
|
|
||||||
} |
|
||||||
} |
|
@ -1,30 +0,0 @@ |
|||||||
/**
|
|
||||||
* 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
|
|
@ -1,49 +0,0 @@ |
|||||||
/* 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 */ |
|
@ -1,25 +0,0 @@ |
|||||||
//
|
|
||||||
// Created by MightyPork on 2023/04/09.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef TOASTER_OVEN_BLUEPILL_EE_ADDRESSES_H |
|
||||||
#define TOASTER_OVEN_BLUEPILL_EE_ADDRESSES_H |
|
||||||
|
|
||||||
enum EEAddresses { |
|
||||||
// 1.0
|
|
||||||
EE_ADDR_CAL_A = 1, |
|
||||||
// 0.0
|
|
||||||
EE_ADDR_CAL_B = 2, |
|
||||||
|
|
||||||
// 10.0
|
|
||||||
EE_ADDR_PID_P = 3, |
|
||||||
// 0.052
|
|
||||||
EE_ADDR_PID_I = 4, |
|
||||||
// 100.0
|
|
||||||
EE_ADDR_PID_D = 5, |
|
||||||
|
|
||||||
EE_ADDR_LEAD_R = 6, |
|
||||||
EE_ADDR_REF_R = 7, |
|
||||||
}; |
|
||||||
|
|
||||||
#endif //TOASTER_OVEN_BLUEPILL_EE_ADDRESSES_H
|
|
@ -1,15 +0,0 @@ |
|||||||
//
|
|
||||||
// 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
|
|
@ -1,52 +0,0 @@ |
|||||||
/**
|
|
||||||
* 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; |
|
||||||
} |
|
@ -1,8 +0,0 @@ |
|||||||
/**
|
|
||||||
* TODO file description |
|
||||||
*/ |
|
||||||
|
|
||||||
#ifndef BLUEPILLTROUBA_UART_STDOUT_H |
|
||||||
#define BLUEPILLTROUBA_UART_STDOUT_H |
|
||||||
|
|
||||||
#endif //BLUEPILLTROUBA_UART_STDOUT_H
|
|
@ -1,204 +0,0 @@ |
|||||||
/**
|
|
||||||
****************************************************************************** |
|
||||||
* @file stm32f1xx_ll_crc.h |
|
||||||
* @author MCD Application Team |
|
||||||
* @brief Header file of CRC LL module. |
|
||||||
****************************************************************************** |
|
||||||
* @attention |
|
||||||
* |
|
||||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics. |
|
||||||
* All rights reserved.</center></h2> |
|
||||||
* |
|
||||||
* This software component is licensed by ST under BSD 3-Clause license, |
|
||||||
* the "License"; You may not use this file except in compliance with the |
|
||||||
* License. You may obtain a copy of the License at: |
|
||||||
* opensource.org/licenses/BSD-3-Clause |
|
||||||
* |
|
||||||
****************************************************************************** |
|
||||||
*/ |
|
||||||
|
|
||||||
/* Define to prevent recursive inclusion -------------------------------------*/ |
|
||||||
#ifndef STM32F1xx_LL_CRC_H |
|
||||||
#define STM32F1xx_LL_CRC_H |
|
||||||
|
|
||||||
#ifdef __cplusplus |
|
||||||
extern "C" { |
|
||||||
#endif |
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/ |
|
||||||
#include "stm32f1xx.h" |
|
||||||
|
|
||||||
/** @addtogroup STM32F1xx_LL_Driver
|
|
||||||
* @{ |
|
||||||
*/ |
|
||||||
|
|
||||||
#if defined(CRC) |
|
||||||
|
|
||||||
/** @defgroup CRC_LL CRC
|
|
||||||
* @{ |
|
||||||
*/ |
|
||||||
|
|
||||||
/* Private types -------------------------------------------------------------*/ |
|
||||||
/* Private variables ---------------------------------------------------------*/ |
|
||||||
/* Private constants ---------------------------------------------------------*/ |
|
||||||
/* Private macros ------------------------------------------------------------*/ |
|
||||||
|
|
||||||
/* Exported types ------------------------------------------------------------*/ |
|
||||||
/* Exported constants --------------------------------------------------------*/ |
|
||||||
/** @defgroup CRC_LL_Exported_Constants CRC Exported Constants
|
|
||||||
* @{ |
|
||||||
*/ |
|
||||||
|
|
||||||
/**
|
|
||||||
* @} |
|
||||||
*/ |
|
||||||
|
|
||||||
/* Exported macro ------------------------------------------------------------*/ |
|
||||||
/** @defgroup CRC_LL_Exported_Macros CRC Exported Macros
|
|
||||||
* @{ |
|
||||||
*/ |
|
||||||
|
|
||||||
/** @defgroup CRC_LL_EM_WRITE_READ Common Write and read registers Macros
|
|
||||||
* @{ |
|
||||||
*/ |
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Write a value in CRC register |
|
||||||
* @param __INSTANCE__ CRC Instance |
|
||||||
* @param __REG__ Register to be written |
|
||||||
* @param __VALUE__ Value to be written in the register |
|
||||||
* @retval None |
|
||||||
*/ |
|
||||||
#define LL_CRC_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, __VALUE__) |
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Read a value in CRC register |
|
||||||
* @param __INSTANCE__ CRC Instance |
|
||||||
* @param __REG__ Register to be read |
|
||||||
* @retval Register value |
|
||||||
*/ |
|
||||||
#define LL_CRC_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) |
|
||||||
/**
|
|
||||||
* @} |
|
||||||
*/ |
|
||||||
|
|
||||||
/**
|
|
||||||
* @} |
|
||||||
*/ |
|
||||||
|
|
||||||
|
|
||||||
/* Exported functions --------------------------------------------------------*/ |
|
||||||
/** @defgroup CRC_LL_Exported_Functions CRC Exported Functions
|
|
||||||
* @{ |
|
||||||
*/ |
|
||||||
|
|
||||||
/** @defgroup CRC_LL_EF_Configuration CRC Configuration functions
|
|
||||||
* @{ |
|
||||||
*/ |
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Reset the CRC calculation unit. |
|
||||||
* @note If Programmable Initial CRC value feature |
|
||||||
* is available, also set the Data Register to the value stored in the |
|
||||||
* CRC_INIT register, otherwise, reset Data Register to its default value. |
|
||||||
* @rmtoll CR RESET LL_CRC_ResetCRCCalculationUnit |
|
||||||
* @param CRCx CRC Instance |
|
||||||
* @retval None |
|
||||||
*/ |
|
||||||
__STATIC_INLINE void LL_CRC_ResetCRCCalculationUnit(CRC_TypeDef *CRCx) |
|
||||||
{ |
|
||||||
SET_BIT(CRCx->CR, CRC_CR_RESET); |
|
||||||
} |
|
||||||
|
|
||||||
/**
|
|
||||||
* @} |
|
||||||
*/ |
|
||||||
|
|
||||||
/** @defgroup CRC_LL_EF_Data_Management Data_Management
|
|
||||||
* @{ |
|
||||||
*/ |
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Write given 32-bit data to the CRC calculator |
|
||||||
* @rmtoll DR DR LL_CRC_FeedData32 |
|
||||||
* @param CRCx CRC Instance |
|
||||||
* @param InData value to be provided to CRC calculator between between Min_Data=0 and Max_Data=0xFFFFFFFF |
|
||||||
* @retval None |
|
||||||
*/ |
|
||||||
__STATIC_INLINE void LL_CRC_FeedData32(CRC_TypeDef *CRCx, uint32_t InData) |
|
||||||
{ |
|
||||||
WRITE_REG(CRCx->DR, InData); |
|
||||||
} |
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Return current CRC calculation result. 32 bits value is returned. |
|
||||||
* @rmtoll DR DR LL_CRC_ReadData32 |
|
||||||
* @param CRCx CRC Instance |
|
||||||
* @retval Current CRC calculation result as stored in CRC_DR register (32 bits). |
|
||||||
*/ |
|
||||||
__STATIC_INLINE uint32_t LL_CRC_ReadData32(CRC_TypeDef *CRCx) |
|
||||||
{ |
|
||||||
return (uint32_t)(READ_REG(CRCx->DR)); |
|
||||||
} |
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Return data stored in the Independent Data(IDR) register. |
|
||||||
* @note This register can be used as a temporary storage location for one byte. |
|
||||||
* @rmtoll IDR IDR LL_CRC_Read_IDR |
|
||||||
* @param CRCx CRC Instance |
|
||||||
* @retval Value stored in CRC_IDR register (General-purpose 8-bit data register). |
|
||||||
*/ |
|
||||||
__STATIC_INLINE uint32_t LL_CRC_Read_IDR(CRC_TypeDef *CRCx) |
|
||||||
{ |
|
||||||
return (uint32_t)(READ_REG(CRCx->IDR)); |
|
||||||
} |
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Store data in the Independent Data(IDR) register. |
|
||||||
* @note This register can be used as a temporary storage location for one byte. |
|
||||||
* @rmtoll IDR IDR LL_CRC_Write_IDR |
|
||||||
* @param CRCx CRC Instance |
|
||||||
* @param InData value to be stored in CRC_IDR register (8-bit) between Min_Data=0 and Max_Data=0xFF |
|
||||||
* @retval None |
|
||||||
*/ |
|
||||||
__STATIC_INLINE void LL_CRC_Write_IDR(CRC_TypeDef *CRCx, uint32_t InData) |
|
||||||
{ |
|
||||||
*((uint8_t __IO *)(&CRCx->IDR)) = (uint8_t) InData; |
|
||||||
} |
|
||||||
/**
|
|
||||||
* @} |
|
||||||
*/ |
|
||||||
|
|
||||||
#if defined(USE_FULL_LL_DRIVER) |
|
||||||
/** @defgroup CRC_LL_EF_Init Initialization and de-initialization functions
|
|
||||||
* @{ |
|
||||||
*/ |
|
||||||
|
|
||||||
ErrorStatus LL_CRC_DeInit(CRC_TypeDef *CRCx); |
|
||||||
|
|
||||||
/**
|
|
||||||
* @} |
|
||||||
*/ |
|
||||||
#endif /* USE_FULL_LL_DRIVER */ |
|
||||||
|
|
||||||
/**
|
|
||||||
* @} |
|
||||||
*/ |
|
||||||
|
|
||||||
/**
|
|
||||||
* @} |
|
||||||
*/ |
|
||||||
|
|
||||||
#endif /* defined(CRC) */ |
|
||||||
|
|
||||||
/**
|
|
||||||
* @} |
|
||||||
*/ |
|
||||||
|
|
||||||
#ifdef __cplusplus |
|
||||||
} |
|
||||||
#endif |
|
||||||
|
|
||||||
#endif /* STM32F1xx_LL_CRC_H */ |
|
||||||
|
|
||||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
|
@ -1,108 +0,0 @@ |
|||||||
/**
|
|
||||||
****************************************************************************** |
|
||||||
* @file stm32f1xx_ll_crc.c |
|
||||||
* @author MCD Application Team |
|
||||||
* @brief CRC LL module driver. |
|
||||||
****************************************************************************** |
|
||||||
* @attention |
|
||||||
* |
|
||||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics. |
|
||||||
* All rights reserved.</center></h2> |
|
||||||
* |
|
||||||
* This software component is licensed by ST under BSD 3-Clause license, |
|
||||||
* the "License"; You may not use this file except in compliance with the |
|
||||||
* License. You may obtain a copy of the License at: |
|
||||||
* opensource.org/licenses/BSD-3-Clause |
|
||||||
* |
|
||||||
****************************************************************************** |
|
||||||
*/ |
|
||||||
#if defined(USE_FULL_LL_DRIVER) |
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/ |
|
||||||
#include "stm32f1xx_ll_crc.h" |
|
||||||
#include "stm32f1xx_ll_bus.h" |
|
||||||
|
|
||||||
#ifdef USE_FULL_ASSERT |
|
||||||
#include "stm32_assert.h" |
|
||||||
#else |
|
||||||
#define assert_param(expr) ((void)0U) |
|
||||||
#endif/* USE_FULL_ASSERT */ |
|
||||||
|
|
||||||
/** @addtogroup STM32F1xx_LL_Driver
|
|
||||||
* @{ |
|
||||||
*/ |
|
||||||
|
|
||||||
#if defined (CRC) |
|
||||||
|
|
||||||
/** @addtogroup CRC_LL
|
|
||||||
* @{ |
|
||||||
*/ |
|
||||||
|
|
||||||
/* Private types -------------------------------------------------------------*/ |
|
||||||
/* Private variables ---------------------------------------------------------*/ |
|
||||||
/* Private constants ---------------------------------------------------------*/ |
|
||||||
/* Private macros ------------------------------------------------------------*/ |
|
||||||
/* Private function prototypes -----------------------------------------------*/ |
|
||||||
|
|
||||||
/* Exported functions --------------------------------------------------------*/ |
|
||||||
/** @addtogroup CRC_LL_Exported_Functions
|
|
||||||
* @{ |
|
||||||
*/ |
|
||||||
|
|
||||||
/** @addtogroup CRC_LL_EF_Init
|
|
||||||
* @{ |
|
||||||
*/ |
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief De-initialize CRC registers (Registers restored to their default values). |
|
||||||
* @param CRCx CRC Instance |
|
||||||
* @retval An ErrorStatus enumeration value: |
|
||||||
* - SUCCESS: CRC registers are de-initialized |
|
||||||
* - ERROR: CRC registers are not de-initialized |
|
||||||
*/ |
|
||||||
ErrorStatus LL_CRC_DeInit(CRC_TypeDef *CRCx) |
|
||||||
{ |
|
||||||
ErrorStatus status = SUCCESS; |
|
||||||
|
|
||||||
/* Check the parameters */ |
|
||||||
assert_param(IS_CRC_ALL_INSTANCE(CRCx)); |
|
||||||
|
|
||||||
if (CRCx == CRC) |
|
||||||
{ |
|
||||||
|
|
||||||
/* Reset the CRC calculation unit */ |
|
||||||
LL_CRC_ResetCRCCalculationUnit(CRCx); |
|
||||||
|
|
||||||
/* Reset IDR register */ |
|
||||||
LL_CRC_Write_IDR(CRCx, 0x00U); |
|
||||||
} |
|
||||||
else |
|
||||||
{ |
|
||||||
status = ERROR; |
|
||||||
} |
|
||||||
|
|
||||||
return (status); |
|
||||||
} |
|
||||||
|
|
||||||
/**
|
|
||||||
* @} |
|
||||||
*/ |
|
||||||
|
|
||||||
/**
|
|
||||||
* @} |
|
||||||
*/ |
|
||||||
|
|
||||||
/**
|
|
||||||
* @} |
|
||||||
*/ |
|
||||||
|
|
||||||
#endif /* defined (CRC) */ |
|
||||||
|
|
||||||
/**
|
|
||||||
* @} |
|
||||||
*/ |
|
||||||
|
|
||||||
#endif /* USE_FULL_LL_DRIVER */ |
|
||||||
|
|
||||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,258 @@ |
|||||||
|
/**
|
||||||
|
****************************************************************************** |
||||||
|
* @file EEPROM_Emul/Porting/STM32C0/flash_interface.c |
||||||
|
* @author MCD Application Team |
||||||
|
* @brief This file provides all the EEPROM emulation flash interface functions. |
||||||
|
****************************************************************************** |
||||||
|
* @attention |
||||||
|
* |
||||||
|
* <h2><center>© Copyright (c) 2020 STMicroelectronics. |
||||||
|
* All rights reserved.</center></h2> |
||||||
|
* |
||||||
|
* This software component is licensed by ST under BSD 3-Clause license, |
||||||
|
* the "License"; You may not use this file except in compliance with the |
||||||
|
* License. You may obtain a copy of the License at: |
||||||
|
* opensource.org/licenses/BSD-3-Clause |
||||||
|
* |
||||||
|
****************************************************************************** |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/ |
||||||
|
#include "eeprom_emul.h" |
||||||
|
#include "flash_interface.h" |
||||||
|
|
||||||
|
/** @addtogroup EEPROM_Emulation
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Private typedef -----------------------------------------------------------*/ |
||||||
|
/* Private constants ---------------------------------------------------------*/ |
||||||
|
/* Private macro -------------------------------------------------------------*/ |
||||||
|
/* Private variables ---------------------------------------------------------*/ |
||||||
|
/* Private function prototypes -----------------------------------------------*/ |
||||||
|
#ifdef FLASH_BANK_2 |
||||||
|
static uint32_t GetBankNumber(uint32_t Address); |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Exported functions --------------------------------------------------------*/ |
||||||
|
/* Private functions ---------------------------------------------------------*/ |
||||||
|
/** @addtogroup EEPROM_Private_Functions
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Write a double word at the given address in Flash |
||||||
|
* @param Address Where to write |
||||||
|
* @param Data What to write |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE_WRITE_ERROR: if an error occurs |
||||||
|
*/ |
||||||
|
HAL_StatusTypeDef FI_WriteDoubleWord(uint32_t Address, uint64_t Data) |
||||||
|
{ |
||||||
|
return HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, Data);
|
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Erase a page in polling mode |
||||||
|
* @param Page Page number |
||||||
|
* @param NbPages Number of pages to erase |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages) |
||||||
|
{ |
||||||
|
EE_Status status = EE_OK; |
||||||
|
FLASH_EraseInitTypeDef s_eraseinit; |
||||||
|
uint32_t page_error = 0U; |
||||||
|
|
||||||
|
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; |
||||||
|
s_eraseinit.NbPages = NbPages; |
||||||
|
s_eraseinit.Page = Page; |
||||||
|
|
||||||
|
/* Erase the Page: Set Page status to ERASED status */ |
||||||
|
if (HAL_FLASHEx_Erase(&s_eraseinit, &page_error) != HAL_OK) |
||||||
|
{ |
||||||
|
status = EE_ERASE_ERROR; |
||||||
|
} |
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Erase a page with interrupt enabled |
||||||
|
* @param Page Page number |
||||||
|
* @param NbPages Number of pages to erase |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_PageErase_IT(uint32_t Page, uint16_t NbPages) |
||||||
|
{ |
||||||
|
EE_Status status = EE_OK; |
||||||
|
FLASH_EraseInitTypeDef s_eraseinit; |
||||||
|
|
||||||
|
#ifdef FLASH_BANK_2 |
||||||
|
uint32_t bank = GetBankNumber(PAGE_ADDRESS(Page)); |
||||||
|
s_eraseinit.Banks = bank; |
||||||
|
#endif |
||||||
|
|
||||||
|
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; |
||||||
|
s_eraseinit.NbPages = NbPages; |
||||||
|
s_eraseinit.Page = Page; |
||||||
|
|
||||||
|
/* Erase the Page: Set Page status to ERASED status */ |
||||||
|
if (HAL_FLASHEx_Erase_IT(&s_eraseinit) != HAL_OK) |
||||||
|
{ |
||||||
|
status = EE_ERASE_ERROR; |
||||||
|
} |
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Flush the caches if needed to keep coherency when the flash content is modified |
||||||
|
*/ |
||||||
|
void FI_CacheFlush() |
||||||
|
{ |
||||||
|
/* No flush needed. There is no D-Cache for the STM32G0x0 and STM32G0x1 products. */ |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
#ifdef FLASH_BANK_2 |
||||||
|
/**
|
||||||
|
* @brief Gets the bank of a given address |
||||||
|
* @param Address Address of the FLASH Memory |
||||||
|
* @retval Bank_Number The bank of a given address |
||||||
|
*/ |
||||||
|
static uint32_t GetBankNumber(uint32_t Address) |
||||||
|
{ |
||||||
|
uint32_t bank = 0U; |
||||||
|
|
||||||
|
if (OB_USER_DUALBANK_SWAP_DISABLE) |
||||||
|
{ |
||||||
|
/* No Bank swap */ |
||||||
|
if (Address < (FLASH_BASE + FLASH_BANK_SIZE)) |
||||||
|
{ |
||||||
|
bank = FLASH_BANK_1; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
bank = FLASH_BANK_2; |
||||||
|
} |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
/* Bank swap */ |
||||||
|
if (Address < (FLASH_BASE + FLASH_BANK_SIZE)) |
||||||
|
{ |
||||||
|
bank = FLASH_BANK_2; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
bank = FLASH_BANK_1; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return bank; |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Delete corrupted Flash address, can be called from NMI. No Timeout. |
||||||
|
* @param Address Address of the FLASH Memory to delete |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address) |
||||||
|
{ |
||||||
|
EE_Status status = EE_OK; |
||||||
|
|
||||||
|
/* Set FLASH Programmation bit */ |
||||||
|
SET_BIT(FLASH->CR, FLASH_CR_PG); |
||||||
|
|
||||||
|
/* Program double word of value 0 */ |
||||||
|
*(__IO uint32_t*)(Address) = (uint32_t)0U; |
||||||
|
*(__IO uint32_t*)(Address+4U) = (uint32_t)0U; |
||||||
|
|
||||||
|
/* Wait programmation completion */ |
||||||
|
#if defined(FLASH_DBANK_SUPPORT) |
||||||
|
uint32_t bank = GetBankNumber(Address); |
||||||
|
if(bank == FLASH_BANK_1) |
||||||
|
{ |
||||||
|
while(FLASH->SR & FLASH_SR_BSY1) |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
while(FLASH->SR & FLASH_SR_BSY2) |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
|
#else |
||||||
|
while(FLASH->SR & FLASH_SR_BSY1) |
||||||
|
{ |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Check if error occured */ |
||||||
|
if((FLASH->SR & FLASH_SR_OPERR) || (FLASH->SR & FLASH_SR_PROGERR) || |
||||||
|
(FLASH->SR & FLASH_SR_WRPERR) || (FLASH->SR & FLASH_SR_PGAERR) || |
||||||
|
(FLASH->SR & FLASH_SR_SIZERR) || (FLASH->SR & FLASH_SR_PGSERR)) |
||||||
|
{ |
||||||
|
status = EE_DELETE_ERROR; |
||||||
|
} |
||||||
|
|
||||||
|
/* Check FLASH End of Operation flag */ |
||||||
|
if (FLASH->SR & FLASH_SR_EOP) |
||||||
|
{ |
||||||
|
/* Clear FLASH End of Operation pending bit */ |
||||||
|
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); |
||||||
|
} |
||||||
|
|
||||||
|
/* Clear FLASH Programmation bit */ |
||||||
|
CLEAR_BIT(FLASH->CR, FLASH_CR_PG); |
||||||
|
|
||||||
|
|
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if the configuration is 128-bits bank or 2*64-bits bank |
||||||
|
* @param None |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_CheckBankConfig(void) |
||||||
|
{ |
||||||
|
#if defined (FLASH_DBANK_SUPPORT) |
||||||
|
EE_Status status; |
||||||
|
|
||||||
|
/* Check the value of the DBANK user option byte */ |
||||||
|
if (OB_USER_DUALBANK_ENABLE) |
||||||
|
{ |
||||||
|
status = EE_OK; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
status = EE_INVALID_BANK_CFG; |
||||||
|
} |
||||||
|
|
||||||
|
return status; |
||||||
|
#else |
||||||
|
/* No feature 128-bits single bank, so always 64-bits dual bank */ |
||||||
|
return EE_OK; |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@ -0,0 +1,125 @@ |
|||||||
|
/**
|
||||||
|
****************************************************************************** |
||||||
|
* @file EEPROM_Emul/Porting/STM32C0/flash_interface.h |
||||||
|
* @author MCD Application Team |
||||||
|
* @brief This file contains all the functions prototypes for the EEPROM |
||||||
|
* emulation flash interface. |
||||||
|
****************************************************************************** |
||||||
|
* @attention |
||||||
|
* |
||||||
|
* <h2><center>© Copyright (c) 2020 STMicroelectronics. |
||||||
|
* All rights reserved.</center></h2> |
||||||
|
* |
||||||
|
* This software component is licensed by ST under BSD 3-Clause license, |
||||||
|
* the "License"; You may not use this file except in compliance with the |
||||||
|
* License. You may obtain a copy of the License at: |
||||||
|
* opensource.org/licenses/BSD-3-Clause |
||||||
|
* |
||||||
|
****************************************************************************** |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/ |
||||||
|
#ifndef __FLASH_INTERFACE_H |
||||||
|
#define __FLASH_INTERFACE_H |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
extern "C" { |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/ |
||||||
|
#include "stm32c0xx_hal.h" |
||||||
|
#include "stm32c0xx_ll_crc.h" |
||||||
|
#include "stm32c0xx_ll_bus.h" |
||||||
|
|
||||||
|
/** @addtogroup EEPROM_Emulation
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Exported types ------------------------------------------------------------*/ |
||||||
|
/* Exported macro ------------------------------------------------------------*/ |
||||||
|
/* Exported functions ------------------------------------------------------- */ |
||||||
|
|
||||||
|
/* Private types -------------------------------------------------------------*/ |
||||||
|
/* Private constants ---------------------------------------------------------*/ |
||||||
|
/** @addtogroup EEPROM_Private_Constants
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/** @addtogroup Private_Other_Constants
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
#define BANK_SIZE FLASH_BANK_SIZE /*!< Alias to FLASH_BANK_SIZE definition from HAL STM32L4 */ |
||||||
|
#define EE_ACCESS_32BITS /*!< Enable EEPROM 32bits R/W functions, only valid for flash allowing 64bits access*/ |
||||||
|
|
||||||
|
/* Page state header */ |
||||||
|
#define EE_PAGESTAT_ERASED (uint64_t)0xFFFFFFFFFFFFFFFFU /*!< State saved in 1st,2nd,3rd,4th data type of page header */ |
||||||
|
#define EE_PAGESTAT_RECEIVE (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 1st data type of page header */ |
||||||
|
#define EE_PAGESTAT_ACTIVE (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 2nd data type of page header */ |
||||||
|
#define EE_PAGESTAT_VALID (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 3rd data type of page header */ |
||||||
|
#define EE_PAGESTAT_ERASING (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 4th data type of page header */ |
||||||
|
|
||||||
|
/* Description of the 8 Bytes (64 bits) element in flash */ |
||||||
|
/* Bit: 63 32 31 16 15 0 */ |
||||||
|
/* <--- Data Value -----> <-unused-> <-VirtAddr-> */ |
||||||
|
#define EE_ELEMENT_SIZE 8U /*!< Size of element in Bytes */ |
||||||
|
#define EE_ELEMENT_TYPE uint64_t /*!< Type of element */ |
||||||
|
#define EE_VIRTUALADDRESS_TYPE uint16_t /*!< Type of Virtual Address */ |
||||||
|
#define EE_VIRTUALADDRESS_SHIFT 0U /*!< Bits Shifting to get Virtual Address in element */ |
||||||
|
#define EE_CRC_TYPE uint16_t /*!< Type of Crc */ |
||||||
|
#define EE_CRC_SHIFT 16U /*!< Bits Shifting to get Crc in element */ |
||||||
|
#define EE_DATA_TYPE uint32_t /*!< Type of Data */ |
||||||
|
#define EE_DATA_SHIFT 32U /*!< Bits Shifting to get Data value in element */ |
||||||
|
#define EE_MASK_VIRTUALADDRESS (uint64_t)0x000000000000FFFFU |
||||||
|
#define EE_MASK_CRC (uint64_t)0x00000000FFFF0000U |
||||||
|
#define EE_MASK_DATA (uint64_t)0xFFFFFFFF00000000U |
||||||
|
#define EE_MASK_FULL (uint64_t)0xFFFFFFFFFFFFFFFFU |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Private macro -------------------------------------------------------------*/ |
||||||
|
/** @addtogroup EEPROM_Private_Macros
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Private functions ---------------------------------------------------------*/ |
||||||
|
/** @addtogroup EEPROM_Private_Functions
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
HAL_StatusTypeDef FI_WriteDoubleWord(uint32_t Address, uint64_t Data); |
||||||
|
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages); |
||||||
|
EE_Status FI_PageErase_IT(uint32_t Page, uint16_t NbPages); |
||||||
|
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address); |
||||||
|
EE_Status FI_CheckBankConfig(void); |
||||||
|
void FI_CacheFlush(void); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
#endif /* __FLASH_INTERFACE_H */ |
||||||
|
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@ -1,173 +0,0 @@ |
|||||||
/**
|
|
||||||
****************************************************************************** |
|
||||||
* @file EEPROM_Emul/Porting/STM32L4/flash_interface.c |
|
||||||
* @author MCD Application Team |
|
||||||
* @brief This file provides all the EEPROM emulation flash interface functions. |
|
||||||
****************************************************************************** |
|
||||||
* @attention |
|
||||||
* |
|
||||||
* <h2><center>© Copyright (c) 2020 STMicroelectronics. |
|
||||||
* All rights reserved.</center></h2> |
|
||||||
* |
|
||||||
* This software component is licensed by ST under BSD 3-Clause license, |
|
||||||
* the "License"; You may not use this file except in compliance with the |
|
||||||
* License. You may obtain a copy of the License at: |
|
||||||
* opensource.org/licenses/BSD-3-Clause |
|
||||||
* |
|
||||||
****************************************************************************** |
|
||||||
*/ |
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/ |
|
||||||
#include "eeprom_emul.h" |
|
||||||
#include "flash_interface.h" |
|
||||||
#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****/ |
|
@ -0,0 +1,265 @@ |
|||||||
|
/**
|
||||||
|
****************************************************************************** |
||||||
|
* @file EEPROM_Emul/Porting/STM32G0/flash_interface.c |
||||||
|
* @author MCD Application Team |
||||||
|
* @brief This file provides all the EEPROM emulation flash interface functions. |
||||||
|
****************************************************************************** |
||||||
|
* @attention |
||||||
|
* |
||||||
|
* <h2><center>© Copyright (c) 2020 STMicroelectronics. |
||||||
|
* All rights reserved.</center></h2> |
||||||
|
* |
||||||
|
* This software component is licensed by ST under BSD 3-Clause license, |
||||||
|
* the "License"; You may not use this file except in compliance with the |
||||||
|
* License. You may obtain a copy of the License at: |
||||||
|
* opensource.org/licenses/BSD-3-Clause |
||||||
|
* |
||||||
|
****************************************************************************** |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/ |
||||||
|
#include "eeprom_emul.h" |
||||||
|
#include "flash_interface.h" |
||||||
|
|
||||||
|
/** @addtogroup EEPROM_Emulation
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Private typedef -----------------------------------------------------------*/ |
||||||
|
/* Private constants ---------------------------------------------------------*/ |
||||||
|
/* Private macro -------------------------------------------------------------*/ |
||||||
|
/* Private variables ---------------------------------------------------------*/ |
||||||
|
/* Private function prototypes -----------------------------------------------*/ |
||||||
|
#ifdef FLASH_BANK_2 |
||||||
|
static uint32_t GetBankNumber(uint32_t Address); |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Exported functions --------------------------------------------------------*/ |
||||||
|
/* Private functions ---------------------------------------------------------*/ |
||||||
|
/** @addtogroup EEPROM_Private_Functions
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Write a double word at the given address in Flash |
||||||
|
* @param Address Where to write |
||||||
|
* @param Data What to write |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE_WRITE_ERROR: if an error occurs |
||||||
|
*/ |
||||||
|
HAL_StatusTypeDef FI_WriteDoubleWord(uint32_t Address, uint64_t Data) |
||||||
|
{ |
||||||
|
return HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, Data);
|
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Erase a page in polling mode |
||||||
|
* @param Page Page number |
||||||
|
* @param NbPages Number of pages to erase |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages) |
||||||
|
{ |
||||||
|
EE_Status status = EE_OK; |
||||||
|
FLASH_EraseInitTypeDef s_eraseinit; |
||||||
|
uint32_t page_error = 0U; |
||||||
|
|
||||||
|
#ifdef FLASH_BANK_2 |
||||||
|
uint32_t bank = GetBankNumber(PAGE_ADDRESS(Page)); |
||||||
|
s_eraseinit.Banks = bank; |
||||||
|
#endif |
||||||
|
|
||||||
|
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; |
||||||
|
s_eraseinit.NbPages = NbPages; |
||||||
|
s_eraseinit.Page = Page; |
||||||
|
|
||||||
|
/* Erase the Page: Set Page status to ERASED status */ |
||||||
|
if (HAL_FLASHEx_Erase(&s_eraseinit, &page_error) != HAL_OK) |
||||||
|
{ |
||||||
|
status = EE_ERASE_ERROR; |
||||||
|
} |
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Erase a page with interrupt enabled |
||||||
|
* @param Page Page number |
||||||
|
* @param NbPages Number of pages to erase |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_PageErase_IT(uint32_t Page, uint16_t NbPages) |
||||||
|
{ |
||||||
|
EE_Status status = EE_OK; |
||||||
|
FLASH_EraseInitTypeDef s_eraseinit; |
||||||
|
|
||||||
|
#ifdef FLASH_BANK_2 |
||||||
|
uint32_t bank = GetBankNumber(PAGE_ADDRESS(Page)); |
||||||
|
s_eraseinit.Banks = bank; |
||||||
|
#endif |
||||||
|
|
||||||
|
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; |
||||||
|
s_eraseinit.NbPages = NbPages; |
||||||
|
s_eraseinit.Page = Page; |
||||||
|
|
||||||
|
/* Erase the Page: Set Page status to ERASED status */ |
||||||
|
if (HAL_FLASHEx_Erase_IT(&s_eraseinit) != HAL_OK) |
||||||
|
{ |
||||||
|
status = EE_ERASE_ERROR; |
||||||
|
} |
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Flush the caches if needed to keep coherency when the flash content is modified |
||||||
|
*/ |
||||||
|
void FI_CacheFlush() |
||||||
|
{ |
||||||
|
/* No flush needed. There is no D-Cache for the STM32G0x0 and STM32G0x1 products. */ |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
#ifdef FLASH_BANK_2 |
||||||
|
/**
|
||||||
|
* @brief Gets the bank of a given address |
||||||
|
* @param Address Address of the FLASH Memory |
||||||
|
* @retval Bank_Number The bank of a given address |
||||||
|
*/ |
||||||
|
static uint32_t GetBankNumber(uint32_t Address) |
||||||
|
{ |
||||||
|
uint32_t bank = 0U; |
||||||
|
|
||||||
|
if (OB_USER_DUALBANK_SWAP_DISABLE) |
||||||
|
{ |
||||||
|
/* No Bank swap */ |
||||||
|
if (Address < (FLASH_BASE + FLASH_BANK_SIZE)) |
||||||
|
{ |
||||||
|
bank = FLASH_BANK_1; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
bank = FLASH_BANK_2; |
||||||
|
} |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
/* Bank swap */ |
||||||
|
if (Address < (FLASH_BASE + FLASH_BANK_SIZE)) |
||||||
|
{ |
||||||
|
bank = FLASH_BANK_2; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
bank = FLASH_BANK_1; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return bank; |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Delete corrupted Flash address, can be called from NMI. No Timeout. |
||||||
|
* @param Address Address of the FLASH Memory to delete |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address) |
||||||
|
{ |
||||||
|
EE_Status status = EE_OK; |
||||||
|
|
||||||
|
/* Set FLASH Programmation bit */ |
||||||
|
SET_BIT(FLASH->CR, FLASH_CR_PG); |
||||||
|
|
||||||
|
/* Program double word of value 0 */ |
||||||
|
*(__IO uint32_t*)(Address) = (uint32_t)0U; |
||||||
|
*(__IO uint32_t*)(Address+4U) = (uint32_t)0U; |
||||||
|
|
||||||
|
/* Wait programmation completion */ |
||||||
|
#if defined(FLASH_DBANK_SUPPORT) |
||||||
|
uint32_t bank = GetBankNumber(Address); |
||||||
|
if(bank == FLASH_BANK_1) |
||||||
|
{ |
||||||
|
while(FLASH->SR & FLASH_SR_BSY1) |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
while(FLASH->SR & FLASH_SR_BSY2) |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
|
#else |
||||||
|
while(FLASH->SR & FLASH_SR_BSY1) |
||||||
|
{ |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Check if error occured */ |
||||||
|
if((FLASH->SR & FLASH_SR_OPERR) || (FLASH->SR & FLASH_SR_PROGERR) || |
||||||
|
(FLASH->SR & FLASH_SR_WRPERR) || (FLASH->SR & FLASH_SR_PGAERR) || |
||||||
|
(FLASH->SR & FLASH_SR_SIZERR) || (FLASH->SR & FLASH_SR_PGSERR)) |
||||||
|
{ |
||||||
|
status = EE_DELETE_ERROR; |
||||||
|
} |
||||||
|
|
||||||
|
/* Check FLASH End of Operation flag */ |
||||||
|
if (FLASH->SR & FLASH_SR_EOP) |
||||||
|
{ |
||||||
|
/* Clear FLASH End of Operation pending bit */ |
||||||
|
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); |
||||||
|
} |
||||||
|
|
||||||
|
/* Clear FLASH Programmation bit */ |
||||||
|
CLEAR_BIT(FLASH->CR, FLASH_CR_PG); |
||||||
|
|
||||||
|
/* Clear FLASH ECCD bit */ |
||||||
|
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ECCD); |
||||||
|
|
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if the configuration is 128-bits bank or 2*64-bits bank |
||||||
|
* @param None |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_CheckBankConfig(void) |
||||||
|
{ |
||||||
|
#if defined (FLASH_DBANK_SUPPORT) |
||||||
|
EE_Status status; |
||||||
|
|
||||||
|
/* Check the value of the DBANK user option byte */ |
||||||
|
if (OB_USER_DUALBANK_ENABLE) |
||||||
|
{ |
||||||
|
status = EE_OK; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
status = EE_INVALID_BANK_CFG; |
||||||
|
} |
||||||
|
|
||||||
|
return status; |
||||||
|
#else |
||||||
|
/* No feature 128-bits single bank, so always 64-bits dual bank */ |
||||||
|
return EE_OK; |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@ -0,0 +1,125 @@ |
|||||||
|
/**
|
||||||
|
****************************************************************************** |
||||||
|
* @file EEPROM_Emul/Porting/STM32G0/flash_interface.h |
||||||
|
* @author MCD Application Team |
||||||
|
* @brief This file contains all the functions prototypes for the EEPROM |
||||||
|
* emulation flash interface. |
||||||
|
****************************************************************************** |
||||||
|
* @attention |
||||||
|
* |
||||||
|
* <h2><center>© Copyright (c) 2020 STMicroelectronics. |
||||||
|
* All rights reserved.</center></h2> |
||||||
|
* |
||||||
|
* This software component is licensed by ST under BSD 3-Clause license, |
||||||
|
* the "License"; You may not use this file except in compliance with the |
||||||
|
* License. You may obtain a copy of the License at: |
||||||
|
* opensource.org/licenses/BSD-3-Clause |
||||||
|
* |
||||||
|
****************************************************************************** |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/ |
||||||
|
#ifndef __FLASH_INTERFACE_H |
||||||
|
#define __FLASH_INTERFACE_H |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
extern "C" { |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/ |
||||||
|
#include "stm32g0xx_hal.h" |
||||||
|
#include "stm32g0xx_ll_crc.h" |
||||||
|
#include "stm32g0xx_ll_bus.h" |
||||||
|
|
||||||
|
/** @addtogroup EEPROM_Emulation
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Exported types ------------------------------------------------------------*/ |
||||||
|
/* Exported macro ------------------------------------------------------------*/ |
||||||
|
/* Exported functions ------------------------------------------------------- */ |
||||||
|
|
||||||
|
/* Private types -------------------------------------------------------------*/ |
||||||
|
/* Private constants ---------------------------------------------------------*/ |
||||||
|
/** @addtogroup EEPROM_Private_Constants
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/** @addtogroup Private_Other_Constants
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
#define BANK_SIZE FLASH_BANK_SIZE /*!< Alias to FLASH_BANK_SIZE definition from HAL STM32L4 */ |
||||||
|
#define EE_ACCESS_32BITS /*!< Enable EEPROM 32bits R/W functions, only valid for flash allowing 64bits access*/ |
||||||
|
|
||||||
|
/* Page state header */ |
||||||
|
#define EE_PAGESTAT_ERASED (uint64_t)0xFFFFFFFFFFFFFFFFU /*!< State saved in 1st,2nd,3rd,4th data type of page header */ |
||||||
|
#define EE_PAGESTAT_RECEIVE (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 1st data type of page header */ |
||||||
|
#define EE_PAGESTAT_ACTIVE (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 2nd data type of page header */ |
||||||
|
#define EE_PAGESTAT_VALID (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 3rd data type of page header */ |
||||||
|
#define EE_PAGESTAT_ERASING (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 4th data type of page header */ |
||||||
|
|
||||||
|
/* Description of the 8 Bytes (64 bits) element in flash */ |
||||||
|
/* Bit: 63 32 31 16 15 0 */ |
||||||
|
/* <--- Data Value -----> <-unused-> <-VirtAddr-> */ |
||||||
|
#define EE_ELEMENT_SIZE 8U /*!< Size of element in Bytes */ |
||||||
|
#define EE_ELEMENT_TYPE uint64_t /*!< Type of element */ |
||||||
|
#define EE_VIRTUALADDRESS_TYPE uint16_t /*!< Type of Virtual Address */ |
||||||
|
#define EE_VIRTUALADDRESS_SHIFT 0U /*!< Bits Shifting to get Virtual Address in element */ |
||||||
|
#define EE_CRC_TYPE uint16_t /*!< Type of Crc */ |
||||||
|
#define EE_CRC_SHIFT 16U /*!< Bits Shifting to get Crc in element */ |
||||||
|
#define EE_DATA_TYPE uint32_t /*!< Type of Data */ |
||||||
|
#define EE_DATA_SHIFT 32U /*!< Bits Shifting to get Data value in element */ |
||||||
|
#define EE_MASK_VIRTUALADDRESS (uint64_t)0x000000000000FFFFU |
||||||
|
#define EE_MASK_CRC (uint64_t)0x00000000FFFF0000U |
||||||
|
#define EE_MASK_DATA (uint64_t)0xFFFFFFFF00000000U |
||||||
|
#define EE_MASK_FULL (uint64_t)0xFFFFFFFFFFFFFFFFU |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Private macro -------------------------------------------------------------*/ |
||||||
|
/** @addtogroup EEPROM_Private_Macros
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Private functions ---------------------------------------------------------*/ |
||||||
|
/** @addtogroup EEPROM_Private_Functions
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
HAL_StatusTypeDef FI_WriteDoubleWord(uint32_t Address, uint64_t Data); |
||||||
|
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages); |
||||||
|
EE_Status FI_PageErase_IT(uint32_t Page, uint16_t NbPages); |
||||||
|
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address); |
||||||
|
EE_Status FI_CheckBankConfig(void); |
||||||
|
void FI_CacheFlush(void); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
#endif /* __FLASH_INTERFACE_H */ |
||||||
|
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@ -0,0 +1,280 @@ |
|||||||
|
/**
|
||||||
|
****************************************************************************** |
||||||
|
* @file EEPROM_Emul/Porting/STM32G4/flash_interface.c |
||||||
|
* @author MCD Application Team |
||||||
|
* @brief This file provides all the EEPROM emulation flash interface functions. |
||||||
|
****************************************************************************** |
||||||
|
* @attention |
||||||
|
* |
||||||
|
* <h2><center>© Copyright (c) 2020 STMicroelectronics. |
||||||
|
* All rights reserved.</center></h2> |
||||||
|
* |
||||||
|
* This software component is licensed by ST under BSD 3-Clause license, |
||||||
|
* the "License"; You may not use this file except in compliance with the |
||||||
|
* License. You may obtain a copy of the License at: |
||||||
|
* opensource.org/licenses/BSD-3-Clause |
||||||
|
* |
||||||
|
****************************************************************************** |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/ |
||||||
|
#include "eeprom_emul.h" |
||||||
|
#include "flash_interface.h" |
||||||
|
|
||||||
|
/** @addtogroup EEPROM_Emulation
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Private typedef -----------------------------------------------------------*/ |
||||||
|
/* Private constants ---------------------------------------------------------*/ |
||||||
|
/* Private macro -------------------------------------------------------------*/ |
||||||
|
/* Private variables ---------------------------------------------------------*/ |
||||||
|
/* Private function prototypes -----------------------------------------------*/ |
||||||
|
#if defined(FLASH_BANK_2) |
||||||
|
static uint32_t GetBankNumber(uint32_t Address); |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Exported functions --------------------------------------------------------*/ |
||||||
|
/* Private functions ---------------------------------------------------------*/ |
||||||
|
/** @addtogroup EEPROM_Private_Functions
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Write a double word at the given address in Flash |
||||||
|
* @param Address Where to write |
||||||
|
* @param Data What to write |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE_WRITE_ERROR: if an error occurs |
||||||
|
*/ |
||||||
|
HAL_StatusTypeDef FI_WriteDoubleWord(uint32_t Address, uint64_t Data) |
||||||
|
{ |
||||||
|
return HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, Data);
|
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Erase a page in polling mode |
||||||
|
* @param Page Page number |
||||||
|
* @param NbPages Number of pages to erase |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages) |
||||||
|
{ |
||||||
|
EE_Status status = EE_OK; |
||||||
|
FLASH_EraseInitTypeDef s_eraseinit; |
||||||
|
uint32_t bank = FLASH_BANK_1, page_error = 0U; |
||||||
|
|
||||||
|
#if defined(FLASH_BANK_2) |
||||||
|
bank = GetBankNumber(PAGE_ADDRESS(Page)); |
||||||
|
#endif |
||||||
|
|
||||||
|
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; |
||||||
|
s_eraseinit.NbPages = NbPages; |
||||||
|
s_eraseinit.Page = Page; |
||||||
|
s_eraseinit.Banks = bank; |
||||||
|
|
||||||
|
/* Erase the Page: Set Page status to ERASED status */ |
||||||
|
if (HAL_FLASHEx_Erase(&s_eraseinit, &page_error) != HAL_OK) |
||||||
|
{ |
||||||
|
status = EE_ERASE_ERROR; |
||||||
|
} |
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Erase a page with interrupt enabled |
||||||
|
* @param Page Page number |
||||||
|
* @param NbPages Number of pages to erase |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_PageErase_IT(uint32_t Page, uint16_t NbPages) |
||||||
|
{ |
||||||
|
EE_Status status = EE_OK; |
||||||
|
FLASH_EraseInitTypeDef s_eraseinit; |
||||||
|
|
||||||
|
uint32_t bank = FLASH_BANK_1; |
||||||
|
|
||||||
|
#if defined(FLASH_BANK_2) |
||||||
|
bank = GetBankNumber(PAGE_ADDRESS(Page)); |
||||||
|
#endif |
||||||
|
|
||||||
|
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; |
||||||
|
s_eraseinit.NbPages = NbPages; |
||||||
|
s_eraseinit.Page = Page; |
||||||
|
s_eraseinit.Banks = bank; |
||||||
|
|
||||||
|
/* Erase the Page: Set Page status to ERASED status */ |
||||||
|
if (HAL_FLASHEx_Erase_IT(&s_eraseinit) != HAL_OK) |
||||||
|
{ |
||||||
|
status = EE_ERASE_ERROR; |
||||||
|
} |
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Flush the caches if needed to keep coherency when the flash content is modified |
||||||
|
*/ |
||||||
|
void FI_CacheFlush() |
||||||
|
{ |
||||||
|
/* To keep its coherency, flush the D-Cache: its content is not updated after a flash erase. */ |
||||||
|
__HAL_FLASH_DATA_CACHE_DISABLE(); |
||||||
|
__HAL_FLASH_DATA_CACHE_RESET(); |
||||||
|
__HAL_FLASH_DATA_CACHE_ENABLE(); |
||||||
|
} |
||||||
|
|
||||||
|
#if defined(FLASH_BANK_2) |
||||||
|
/**
|
||||||
|
* @brief Gets the bank of a given address |
||||||
|
* @param Address Address of the FLASH Memory |
||||||
|
* @retval Bank_Number The bank of a given address |
||||||
|
*/ |
||||||
|
static uint32_t GetBankNumber(uint32_t Address) |
||||||
|
{ |
||||||
|
uint32_t bank = 0U; |
||||||
|
|
||||||
|
if (READ_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_FB_MODE) == 0U) |
||||||
|
{ |
||||||
|
/* No Bank swap */ |
||||||
|
if (Address < (FLASH_BASE + FLASH_BANK_SIZE)) |
||||||
|
{ |
||||||
|
bank = FLASH_BANK_1; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
bank = FLASH_BANK_2; |
||||||
|
} |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
/* Bank swap */ |
||||||
|
if (Address < (FLASH_BASE + FLASH_BANK_SIZE)) |
||||||
|
{ |
||||||
|
bank = FLASH_BANK_2; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
bank = FLASH_BANK_1; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return bank; |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Delete corrupted Flash address, can be called from NMI. No Timeout. |
||||||
|
* @param Address Address of the FLASH Memory to delete |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address) |
||||||
|
{ |
||||||
|
uint32_t dcachetoreactivate = 0U; |
||||||
|
EE_Status status = EE_OK; |
||||||
|
|
||||||
|
/* Deactivate the data cache if they are activated to avoid data misbehavior */ |
||||||
|
if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != RESET) |
||||||
|
{ |
||||||
|
/* Disable data cache */ |
||||||
|
__HAL_FLASH_DATA_CACHE_DISABLE(); |
||||||
|
dcachetoreactivate = 1U; |
||||||
|
} |
||||||
|
|
||||||
|
/* Set FLASH Programmation bit */ |
||||||
|
SET_BIT(FLASH->CR, FLASH_CR_PG); |
||||||
|
|
||||||
|
/* Program double word of value 0 */ |
||||||
|
*(__IO uint32_t*)(Address) = (uint32_t)0U; |
||||||
|
*(__IO uint32_t*)(Address+4U) = (uint32_t)0U; |
||||||
|
|
||||||
|
/* Wait programmation completion */ |
||||||
|
while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
/* Check if error occured */ |
||||||
|
if((__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PROGERR)) || |
||||||
|
(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR)) || |
||||||
|
(__HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGSERR))) |
||||||
|
{ |
||||||
|
status = EE_DELETE_ERROR; |
||||||
|
} |
||||||
|
|
||||||
|
/* Check FLASH End of Operation flag */ |
||||||
|
if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) |
||||||
|
{ |
||||||
|
/* Clear FLASH End of Operation pending bit */ |
||||||
|
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); |
||||||
|
} |
||||||
|
|
||||||
|
/* Clear FLASH Programmation bit */ |
||||||
|
CLEAR_BIT(FLASH->CR, FLASH_CR_PG); |
||||||
|
|
||||||
|
/* Flush the caches to be sure of the data consistency */ |
||||||
|
if(dcachetoreactivate == 1U) |
||||||
|
{ |
||||||
|
/* Reset data cache */ |
||||||
|
__HAL_FLASH_DATA_CACHE_RESET(); |
||||||
|
/* Enable data cache */ |
||||||
|
__HAL_FLASH_DATA_CACHE_ENABLE(); |
||||||
|
} |
||||||
|
|
||||||
|
/* Clear FLASH ECCD bit */ |
||||||
|
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ECCD); |
||||||
|
|
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if the configuration is 128-bits bank or 2*64-bits bank |
||||||
|
* @param None |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_CheckBankConfig(void) |
||||||
|
{ |
||||||
|
#if defined (FLASH_OPTR_DBANK) |
||||||
|
FLASH_OBProgramInitTypeDef sOBCfg; |
||||||
|
EE_Status status; |
||||||
|
|
||||||
|
/* Request the Option Byte configuration :
|
||||||
|
- User and RDP level are always returned |
||||||
|
- WRP and PCROP are not requested */ |
||||||
|
sOBCfg.WRPArea = 0xFF; |
||||||
|
sOBCfg.PCROPConfig = 0xFF; |
||||||
|
HAL_FLASHEx_OBGetConfig(&sOBCfg); |
||||||
|
|
||||||
|
/* Check the value of the DBANK user option byte */ |
||||||
|
if ((sOBCfg.USERConfig & OB_DBANK_64_BITS) != 0) |
||||||
|
{ |
||||||
|
status = EE_OK; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
status = EE_INVALID_BANK_CFG; |
||||||
|
} |
||||||
|
|
||||||
|
return status; |
||||||
|
#else |
||||||
|
/* No feature 128-bits single bank, so always 64-bits dual bank */ |
||||||
|
return EE_OK; |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@ -0,0 +1,125 @@ |
|||||||
|
/**
|
||||||
|
****************************************************************************** |
||||||
|
* @file EEPROM_Emul/Porting/STM32G4/flash_interface.h |
||||||
|
* @author MCD Application Team |
||||||
|
* @brief This file contains all the functions prototypes for the EEPROM |
||||||
|
* emulation flash interface. |
||||||
|
****************************************************************************** |
||||||
|
* @attention |
||||||
|
* |
||||||
|
* <h2><center>© Copyright (c) 2020 STMicroelectronics. |
||||||
|
* All rights reserved.</center></h2> |
||||||
|
* |
||||||
|
* This software component is licensed by ST under BSD 3-Clause license, |
||||||
|
* the "License"; You may not use this file except in compliance with the |
||||||
|
* License. You may obtain a copy of the License at: |
||||||
|
* opensource.org/licenses/BSD-3-Clause |
||||||
|
* |
||||||
|
****************************************************************************** |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/ |
||||||
|
#ifndef __FLASH_INTERFACE_H |
||||||
|
#define __FLASH_INTERFACE_H |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
extern "C" { |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/ |
||||||
|
#include "stm32g4xx_hal.h" |
||||||
|
#include "stm32g4xx_ll_crc.h" |
||||||
|
#include "stm32g4xx_ll_bus.h" |
||||||
|
|
||||||
|
/** @addtogroup EEPROM_Emulation
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Exported types ------------------------------------------------------------*/ |
||||||
|
/* Exported macro ------------------------------------------------------------*/ |
||||||
|
/* Exported functions ------------------------------------------------------- */ |
||||||
|
|
||||||
|
/* Private types -------------------------------------------------------------*/ |
||||||
|
/* Private constants ---------------------------------------------------------*/ |
||||||
|
/** @addtogroup EEPROM_Private_Constants
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/** @addtogroup Private_Other_Constants
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
#define BANK_SIZE FLASH_BANK_SIZE /*!< Alias to FLASH_BANK_SIZE definition from HAL STM32L4 */ |
||||||
|
#define EE_ACCESS_32BITS /*!< Enable EEPROM 32bits R/W functions, only valid for flash allowing 64bits access*/ |
||||||
|
|
||||||
|
/* Page state header */ |
||||||
|
#define EE_PAGESTAT_ERASED (uint64_t)0xFFFFFFFFFFFFFFFFU /*!< State saved in 1st,2nd,3rd,4th data type of page header */ |
||||||
|
#define EE_PAGESTAT_RECEIVE (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 1st data type of page header */ |
||||||
|
#define EE_PAGESTAT_ACTIVE (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 2nd data type of page header */ |
||||||
|
#define EE_PAGESTAT_VALID (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 3rd data type of page header */ |
||||||
|
#define EE_PAGESTAT_ERASING (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 4th data type of page header */ |
||||||
|
|
||||||
|
/* Description of the 8 Bytes (64 bits) element in flash */ |
||||||
|
/* Bit: 63 32 31 16 15 0 */ |
||||||
|
/* <--- Data Value -----> <-unused-> <-VirtAddr-> */ |
||||||
|
#define EE_ELEMENT_SIZE 8U /*!< Size of element in Bytes */ |
||||||
|
#define EE_ELEMENT_TYPE uint64_t /*!< Type of element */ |
||||||
|
#define EE_VIRTUALADDRESS_TYPE uint16_t /*!< Type of Virtual Address */ |
||||||
|
#define EE_VIRTUALADDRESS_SHIFT 0U /*!< Bits Shifting to get Virtual Address in element */ |
||||||
|
#define EE_CRC_TYPE uint16_t /*!< Type of Crc */ |
||||||
|
#define EE_CRC_SHIFT 16U /*!< Bits Shifting to get Crc in element */ |
||||||
|
#define EE_DATA_TYPE uint32_t /*!< Type of Data */ |
||||||
|
#define EE_DATA_SHIFT 32U /*!< Bits Shifting to get Data value in element */ |
||||||
|
#define EE_MASK_VIRTUALADDRESS (uint64_t)0x000000000000FFFFU |
||||||
|
#define EE_MASK_CRC (uint64_t)0x00000000FFFF0000U |
||||||
|
#define EE_MASK_DATA (uint64_t)0xFFFFFFFF00000000U |
||||||
|
#define EE_MASK_FULL (uint64_t)0xFFFFFFFFFFFFFFFFU |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Private macro -------------------------------------------------------------*/ |
||||||
|
/** @addtogroup EEPROM_Private_Macros
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Private functions ---------------------------------------------------------*/ |
||||||
|
/** @addtogroup EEPROM_Private_Functions
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
HAL_StatusTypeDef FI_WriteDoubleWord(uint32_t Address, uint64_t Data); |
||||||
|
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages); |
||||||
|
EE_Status FI_PageErase_IT(uint32_t Page, uint16_t NbPages); |
||||||
|
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address); |
||||||
|
EE_Status FI_CheckBankConfig(void); |
||||||
|
void FI_CacheFlush(void); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
#endif /* __FLASH_INTERFACE_H */ |
||||||
|
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@ -0,0 +1,279 @@ |
|||||||
|
/**
|
||||||
|
****************************************************************************** |
||||||
|
* @file EEPROM_Emul/Porting/STM32L4/flash_interface.c |
||||||
|
* @author MCD Application Team |
||||||
|
* @brief This file provides all the EEPROM emulation flash interface functions. |
||||||
|
****************************************************************************** |
||||||
|
* @attention |
||||||
|
* |
||||||
|
* <h2><center>© Copyright (c) 2020 STMicroelectronics. |
||||||
|
* All rights reserved.</center></h2> |
||||||
|
* |
||||||
|
* This software component is licensed by ST under BSD 3-Clause license, |
||||||
|
* the "License"; You may not use this file except in compliance with the |
||||||
|
* License. You may obtain a copy of the License at: |
||||||
|
* opensource.org/licenses/BSD-3-Clause |
||||||
|
* |
||||||
|
****************************************************************************** |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/ |
||||||
|
#include "eeprom_emul.h" |
||||||
|
#include "flash_interface.h" |
||||||
|
|
||||||
|
/** @addtogroup EEPROM_Emulation
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Private typedef -----------------------------------------------------------*/ |
||||||
|
/* Private constants ---------------------------------------------------------*/ |
||||||
|
/* Private macro -------------------------------------------------------------*/ |
||||||
|
/* Private variables ---------------------------------------------------------*/ |
||||||
|
/* Private function prototypes -----------------------------------------------*/ |
||||||
|
#if defined(FLASH_BANK_2) |
||||||
|
static uint32_t GetBankNumber(uint32_t Address); |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Exported functions --------------------------------------------------------*/ |
||||||
|
/* Private functions ---------------------------------------------------------*/ |
||||||
|
/** @addtogroup EEPROM_Private_Functions
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Write a double word at the given address in Flash |
||||||
|
* @param Address Where to write |
||||||
|
* @param Data What to write |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE_WRITE_ERROR: if an error occurs |
||||||
|
*/ |
||||||
|
HAL_StatusTypeDef FI_WriteDoubleWord(uint32_t Address, uint64_t Data) |
||||||
|
{ |
||||||
|
return HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, Data);
|
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Erase a page in polling mode |
||||||
|
* @param Page Page number |
||||||
|
* @param NbPages Number of pages to erase |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages) |
||||||
|
{ |
||||||
|
EE_Status status = EE_OK; |
||||||
|
FLASH_EraseInitTypeDef s_eraseinit; |
||||||
|
uint32_t bank = FLASH_BANK_1, page_error = 0U; |
||||||
|
|
||||||
|
#if defined(FLASH_BANK_2) |
||||||
|
bank = GetBankNumber(PAGE_ADDRESS(Page)); |
||||||
|
#endif |
||||||
|
|
||||||
|
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; |
||||||
|
s_eraseinit.NbPages = NbPages; |
||||||
|
s_eraseinit.Page = Page; |
||||||
|
s_eraseinit.Banks = bank; |
||||||
|
|
||||||
|
/* Erase the Page: Set Page status to ERASED status */ |
||||||
|
if (HAL_FLASHEx_Erase(&s_eraseinit, &page_error) != HAL_OK) |
||||||
|
{ |
||||||
|
status = EE_ERASE_ERROR; |
||||||
|
} |
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Erase a page with interrupt enabled |
||||||
|
* @param Page Page number |
||||||
|
* @param NbPages Number of pages to erase |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_PageErase_IT(uint32_t Page, uint16_t NbPages) |
||||||
|
{ |
||||||
|
EE_Status status = EE_OK; |
||||||
|
FLASH_EraseInitTypeDef s_eraseinit; |
||||||
|
uint32_t bank = FLASH_BANK_1; |
||||||
|
|
||||||
|
#if defined(FLASH_BANK_2) |
||||||
|
bank = GetBankNumber(PAGE_ADDRESS(Page)); |
||||||
|
#endif |
||||||
|
|
||||||
|
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; |
||||||
|
s_eraseinit.NbPages = NbPages; |
||||||
|
s_eraseinit.Page = Page; |
||||||
|
s_eraseinit.Banks = bank; |
||||||
|
|
||||||
|
/* Erase the Page: Set Page status to ERASED status */ |
||||||
|
if (HAL_FLASHEx_Erase_IT(&s_eraseinit) != HAL_OK) |
||||||
|
{ |
||||||
|
status = EE_ERASE_ERROR; |
||||||
|
} |
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Flush the caches if needed to keep coherency when the flash content is modified |
||||||
|
*/ |
||||||
|
void FI_CacheFlush() |
||||||
|
{ |
||||||
|
/* To keep its coherency, flush the D-Cache: its content is not updated after a flash erase. */ |
||||||
|
__HAL_FLASH_DATA_CACHE_DISABLE(); |
||||||
|
__HAL_FLASH_DATA_CACHE_RESET(); |
||||||
|
__HAL_FLASH_DATA_CACHE_ENABLE(); |
||||||
|
} |
||||||
|
|
||||||
|
#if defined(FLASH_BANK_2) |
||||||
|
/**
|
||||||
|
* @brief Gets the bank of a given address |
||||||
|
* @param Address Address of the FLASH Memory |
||||||
|
* @retval Bank_Number The bank of a given address |
||||||
|
*/ |
||||||
|
static uint32_t GetBankNumber(uint32_t Address) |
||||||
|
{ |
||||||
|
uint32_t bank = 0U; |
||||||
|
|
||||||
|
if (READ_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_FB_MODE) == 0U) |
||||||
|
{ |
||||||
|
/* No Bank swap */ |
||||||
|
if (Address < (FLASH_BASE + FLASH_BANK_SIZE)) |
||||||
|
{ |
||||||
|
bank = FLASH_BANK_1; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
bank = FLASH_BANK_2; |
||||||
|
} |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
/* Bank swap */ |
||||||
|
if (Address < (FLASH_BASE + FLASH_BANK_SIZE)) |
||||||
|
{ |
||||||
|
bank = FLASH_BANK_2; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
bank = FLASH_BANK_1; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return bank; |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Delete corrupted Flash address, can be called from NMI. No Timeout. |
||||||
|
* @param Address Address of the FLASH Memory to delete |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address) |
||||||
|
{ |
||||||
|
uint32_t dcachetoreactivate = 0U; |
||||||
|
EE_Status status = EE_OK; |
||||||
|
|
||||||
|
/* Deactivate the data cache if they are activated to avoid data misbehavior */ |
||||||
|
if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != RESET) |
||||||
|
{ |
||||||
|
/* Disable data cache */ |
||||||
|
__HAL_FLASH_DATA_CACHE_DISABLE(); |
||||||
|
dcachetoreactivate = 1U; |
||||||
|
} |
||||||
|
|
||||||
|
/* Set FLASH Programmation bit */ |
||||||
|
SET_BIT(FLASH->CR, FLASH_CR_PG); |
||||||
|
|
||||||
|
/* Program double word of value 0 */ |
||||||
|
*(__IO uint32_t*)(Address) = (uint32_t)0U; |
||||||
|
*(__IO uint32_t*)(Address+4U) = (uint32_t)0U; |
||||||
|
|
||||||
|
/* Wait programmation completion */ |
||||||
|
while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
/* Check if error occured */ |
||||||
|
if((__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PROGERR)) || |
||||||
|
(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR)) || |
||||||
|
(__HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGSERR))) |
||||||
|
{ |
||||||
|
status = EE_DELETE_ERROR; |
||||||
|
} |
||||||
|
|
||||||
|
/* Check FLASH End of Operation flag */ |
||||||
|
if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) |
||||||
|
{ |
||||||
|
/* Clear FLASH End of Operation pending bit */ |
||||||
|
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); |
||||||
|
} |
||||||
|
|
||||||
|
/* Clear FLASH Programmation bit */ |
||||||
|
CLEAR_BIT(FLASH->CR, FLASH_CR_PG); |
||||||
|
|
||||||
|
/* Flush the caches to be sure of the data consistency */ |
||||||
|
if(dcachetoreactivate == 1U) |
||||||
|
{ |
||||||
|
/* Reset data cache */ |
||||||
|
__HAL_FLASH_DATA_CACHE_RESET(); |
||||||
|
/* Enable data cache */ |
||||||
|
__HAL_FLASH_DATA_CACHE_ENABLE(); |
||||||
|
} |
||||||
|
|
||||||
|
/* Clear FLASH ECCD bit */ |
||||||
|
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ECCD); |
||||||
|
|
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if the configuration is 128-bits bank or 2*64-bits bank |
||||||
|
* @param None |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_CheckBankConfig(void) |
||||||
|
{ |
||||||
|
#if defined (FLASH_OPTR_DBANK) |
||||||
|
FLASH_OBProgramInitTypeDef sOBCfg; |
||||||
|
EE_Status status; |
||||||
|
|
||||||
|
/* Request the Option Byte configuration :
|
||||||
|
- User and RDP level are always returned |
||||||
|
- WRP and PCROP are not requested */ |
||||||
|
sOBCfg.WRPArea = 0xFF; |
||||||
|
sOBCfg.PCROPConfig = 0xFF; |
||||||
|
HAL_FLASHEx_OBGetConfig(&sOBCfg); |
||||||
|
|
||||||
|
/* Check the value of the DBANK user option byte */ |
||||||
|
if ((sOBCfg.USERConfig & OB_DBANK_64_BITS) != 0) |
||||||
|
{ |
||||||
|
status = EE_OK; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
status = EE_INVALID_BANK_CFG; |
||||||
|
} |
||||||
|
|
||||||
|
return status; |
||||||
|
#else |
||||||
|
/* No feature 128-bits single bank, so always 64-bits dual bank */ |
||||||
|
return EE_OK; |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@ -0,0 +1,267 @@ |
|||||||
|
/**
|
||||||
|
****************************************************************************** |
||||||
|
* @file EEPROM_Emul/Porting/STM32L5/flash_interface.c |
||||||
|
* @author MCD Application Team |
||||||
|
* @brief This file provides all the EEPROM emulation flash interface functions. |
||||||
|
****************************************************************************** |
||||||
|
* @attention |
||||||
|
* |
||||||
|
* <h2><center>© Copyright (c) 2020 STMicroelectronics. |
||||||
|
* All rights reserved.</center></h2> |
||||||
|
* |
||||||
|
* This software component is licensed by ST under BSD 3-Clause license, |
||||||
|
* the "License"; You may not use this file except in compliance with the |
||||||
|
* License. You may obtain a copy of the License at: |
||||||
|
* opensource.org/licenses/BSD-3-Clause |
||||||
|
* |
||||||
|
****************************************************************************** |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/ |
||||||
|
#include "eeprom_emul.h" |
||||||
|
#include "flash_interface.h" |
||||||
|
|
||||||
|
/** @addtogroup EEPROM_Emulation
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Private typedef -----------------------------------------------------------*/ |
||||||
|
/* Private constants ---------------------------------------------------------*/ |
||||||
|
/* Private macro -------------------------------------------------------------*/ |
||||||
|
/* Private variables ---------------------------------------------------------*/ |
||||||
|
/* Private function prototypes -----------------------------------------------*/ |
||||||
|
#ifdef FLASH_BANK_2 |
||||||
|
static uint32_t GetBankNumber(uint32_t Address); |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Exported functions --------------------------------------------------------*/ |
||||||
|
/* Private functions ---------------------------------------------------------*/ |
||||||
|
/** @addtogroup EEPROM_Private_Functions
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Write a double word at the given address in Flash |
||||||
|
* @param Address Where to write |
||||||
|
* @param Data What to write |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE_WRITE_ERROR: if an error occurs |
||||||
|
*/ |
||||||
|
HAL_StatusTypeDef FI_WriteDoubleWord(uint32_t Address, uint64_t Data) |
||||||
|
{ |
||||||
|
return HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, Data); |
||||||
|
/* If TrustZone secure activated -> return HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD_NS, Address, Data); */ |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Erase a page in polling mode |
||||||
|
* @param Page Page number |
||||||
|
* @param NbPages Number of pages to erase |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages) |
||||||
|
{ |
||||||
|
EE_Status status = EE_OK; |
||||||
|
FLASH_EraseInitTypeDef s_eraseinit; |
||||||
|
uint32_t bank = FLASH_BANK_1, page_error = 0U; |
||||||
|
|
||||||
|
#ifdef FLASH_BANK_2 |
||||||
|
bank = GetBankNumber(PAGE_ADDRESS(Page)); |
||||||
|
#endif |
||||||
|
|
||||||
|
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; /* if TrustZone secure activated -> FLASH_TYPEERASE_PAGES_NS; */ |
||||||
|
s_eraseinit.NbPages = NbPages; |
||||||
|
s_eraseinit.Page = Page; |
||||||
|
s_eraseinit.Banks = bank; |
||||||
|
|
||||||
|
/* Erase the Page: Set Page status to ERASED status */ |
||||||
|
if (HAL_FLASHEx_Erase(&s_eraseinit, &page_error) != HAL_OK) |
||||||
|
{ |
||||||
|
status = EE_ERASE_ERROR; |
||||||
|
} |
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Erase a page with interrupt enabled |
||||||
|
* @param Page Page number |
||||||
|
* @param NbPages Number of pages to erase |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_PageErase_IT(uint32_t Page, uint16_t NbPages) |
||||||
|
{ |
||||||
|
EE_Status status = EE_OK; |
||||||
|
FLASH_EraseInitTypeDef s_eraseinit; |
||||||
|
uint32_t bank = FLASH_BANK_1; |
||||||
|
|
||||||
|
#ifdef FLASH_BANK_2 |
||||||
|
bank = GetBankNumber(PAGE_ADDRESS(Page)); |
||||||
|
#endif |
||||||
|
|
||||||
|
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; /* if TrustZone secure activated -> FLASH_TYPEERASE_PAGES_NS; */ |
||||||
|
s_eraseinit.NbPages = NbPages; |
||||||
|
s_eraseinit.Page = Page; |
||||||
|
s_eraseinit.Banks = bank; |
||||||
|
|
||||||
|
/* Erase the Page: Set Page status to ERASED status */ |
||||||
|
if (HAL_FLASHEx_Erase_IT(&s_eraseinit) != HAL_OK) |
||||||
|
{ |
||||||
|
status = EE_ERASE_ERROR; |
||||||
|
} |
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Flush the caches if needed to keep coherency when the flash content is modified |
||||||
|
*/ |
||||||
|
void FI_CacheFlush() |
||||||
|
{ |
||||||
|
/* No flush needed. EEPROM flash area is defined as non-cacheable thanks to the MPU in main.c. */ |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
#ifdef FLASH_BANK_2 |
||||||
|
/**
|
||||||
|
* @brief Gets the bank of a given address |
||||||
|
* @param Address Address of the FLASH Memory |
||||||
|
* @retval Bank_Number The bank of a given address |
||||||
|
*/ |
||||||
|
static uint32_t GetBankNumber(uint32_t Address) |
||||||
|
{ |
||||||
|
uint32_t bank = 0U; |
||||||
|
|
||||||
|
if (READ_BIT(FLASH->OPTR, FLASH_OPTR_SWAP_BANK) == 0U) |
||||||
|
{ |
||||||
|
/* No Bank swap */ |
||||||
|
if (Address < (FLASH_BASE + FLASH_BANK_SIZE)) |
||||||
|
{ |
||||||
|
bank = FLASH_BANK_1; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
bank = FLASH_BANK_2; |
||||||
|
} |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
/* Bank swap */ |
||||||
|
if (Address < (FLASH_BASE + FLASH_BANK_SIZE)) |
||||||
|
{ |
||||||
|
bank = FLASH_BANK_2; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
bank = FLASH_BANK_1; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return bank; |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Delete corrupted Flash address, can be called from NMI. No Timeout. |
||||||
|
* @param Address Address of the FLASH Memory to delete |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address) |
||||||
|
{ |
||||||
|
EE_Status status = EE_OK; |
||||||
|
|
||||||
|
/* Wait for previous programmation completion */ |
||||||
|
while(__HAL_FLASH_GET_FLAG(FLASH_NSSR_NSBSY)) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
/* Clear previous non-secure error programming flag */ |
||||||
|
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS); |
||||||
|
|
||||||
|
/* Set FLASH Programmation bit */ |
||||||
|
SET_BIT(FLASH->NSCR, FLASH_NSCR_NSPG); |
||||||
|
|
||||||
|
/* Program double word of value 0 */ |
||||||
|
*(__IO uint32_t*)(Address) = (uint32_t)0U; |
||||||
|
*(__IO uint32_t*)(Address+4U) = (uint32_t)0U; |
||||||
|
|
||||||
|
/* Wait programmation completion */ |
||||||
|
while(__HAL_FLASH_GET_FLAG(FLASH_NSSR_NSBSY)) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
/* Check if error occured */ |
||||||
|
if((__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PROGERR)) || |
||||||
|
(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR)) || |
||||||
|
(__HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGSERR))) |
||||||
|
{ |
||||||
|
status = EE_DELETE_ERROR; |
||||||
|
} |
||||||
|
|
||||||
|
/* Check FLASH End of Operation flag */ |
||||||
|
if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) |
||||||
|
{ |
||||||
|
/* Clear FLASH End of Operation pending bit */ |
||||||
|
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); |
||||||
|
} |
||||||
|
|
||||||
|
/* Clear FLASH Programmation bit */ |
||||||
|
CLEAR_BIT(FLASH->NSCR, FLASH_NSCR_NSPG); |
||||||
|
|
||||||
|
/* Clear FLASH ECCD bit */ |
||||||
|
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ECCD); |
||||||
|
|
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if the configuration is 128-bits bank or 2*64-bits bank |
||||||
|
* @param None |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_CheckBankConfig(void) |
||||||
|
{ |
||||||
|
#if defined (FLASH_OPTR_DBANK) |
||||||
|
FLASH_OBProgramInitTypeDef sOBCfg; |
||||||
|
EE_Status status; |
||||||
|
|
||||||
|
/* Request the Option Byte configuration :
|
||||||
|
- User and RDP level are always returned |
||||||
|
- WRP and PCROP are not requested */ |
||||||
|
sOBCfg.WRPArea = 0xFF; |
||||||
|
HAL_FLASHEx_OBGetConfig(&sOBCfg); |
||||||
|
|
||||||
|
/* Check the value of the DBANK user option byte */ |
||||||
|
if ((sOBCfg.USERConfig & OB_DBANK_64_BITS) != 0) |
||||||
|
{ |
||||||
|
status = EE_OK; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
status = EE_INVALID_BANK_CFG; |
||||||
|
} |
||||||
|
|
||||||
|
return status; |
||||||
|
#else |
||||||
|
/* No feature 128-bits single bank, so always 64-bits dual bank */ |
||||||
|
return EE_OK; |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@ -0,0 +1,126 @@ |
|||||||
|
/**
|
||||||
|
****************************************************************************** |
||||||
|
* @file EEPROM_Emul/Porting/STM32L5/flash_interface.h |
||||||
|
* @author MCD Application Team |
||||||
|
* @brief This file contains all the functions prototypes for the EEPROM |
||||||
|
* emulation flash interface. |
||||||
|
****************************************************************************** |
||||||
|
* @attention |
||||||
|
* |
||||||
|
* <h2><center>© Copyright (c) 2020 STMicroelectronics. |
||||||
|
* All rights reserved.</center></h2> |
||||||
|
* |
||||||
|
* This software component is licensed by ST under BSD 3-Clause license, |
||||||
|
* the "License"; You may not use this file except in compliance with the |
||||||
|
* License. You may obtain a copy of the License at: |
||||||
|
* opensource.org/licenses/BSD-3-Clause |
||||||
|
* |
||||||
|
****************************************************************************** |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/ |
||||||
|
#ifndef __FLASH_INTERFACE_H |
||||||
|
#define __FLASH_INTERFACE_H |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
extern "C" { |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/ |
||||||
|
#include "stm32l5xx_hal.h" |
||||||
|
#include "stm32l5xx_ll_crc.h" |
||||||
|
#include "stm32l5xx_ll_bus.h" |
||||||
|
|
||||||
|
/** @addtogroup EEPROM_Emulation
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Exported types ------------------------------------------------------------*/ |
||||||
|
/* Exported macro ------------------------------------------------------------*/ |
||||||
|
/* Exported functions ------------------------------------------------------- */ |
||||||
|
|
||||||
|
/* Private types -------------------------------------------------------------*/ |
||||||
|
/* Private constants ---------------------------------------------------------*/ |
||||||
|
/** @addtogroup EEPROM_Private_Constants
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/** @addtogroup Private_Other_Constants
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
#define BANK_SIZE FLASH_BANK_SIZE /*!< Alias to FLASH_BANK_SIZE definition from HAL STM32L4 */ |
||||||
|
#define EE_ACCESS_32BITS /*!< Enable EEPROM 32bits R/W functions, only valid for flash allowing 64bits access*/ |
||||||
|
|
||||||
|
/* Page state header */ |
||||||
|
#define EE_PAGESTAT_ERASED (uint64_t)0xFFFFFFFFFFFFFFFFU /*!< State saved in 1st,2nd,3rd,4th data type of page header */ |
||||||
|
#define EE_PAGESTAT_RECEIVE (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 1st data type of page header */ |
||||||
|
#define EE_PAGESTAT_ACTIVE (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 2nd data type of page header */ |
||||||
|
#define EE_PAGESTAT_VALID (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 3rd data type of page header */ |
||||||
|
#define EE_PAGESTAT_ERASING (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 4th data type of page header */ |
||||||
|
|
||||||
|
/* Description of the 8 Bytes (64 bits) element in flash */ |
||||||
|
/* Bit: 63 32 31 16 15 0 */ |
||||||
|
/* <--- Data Value -----> <-unused-> <-VirtAddr-> */ |
||||||
|
#define EE_ELEMENT_SIZE 8U /*!< Size of element in Bytes */ |
||||||
|
#define EE_ELEMENT_TYPE uint64_t /*!< Type of element */ |
||||||
|
#define EE_VIRTUALADDRESS_TYPE uint16_t /*!< Type of Virtual Address */ |
||||||
|
#define EE_VIRTUALADDRESS_SHIFT 0U /*!< Bits Shifting to get Virtual Address in element */ |
||||||
|
#define EE_CRC_TYPE uint16_t /*!< Type of Crc */ |
||||||
|
#define EE_CRC_SHIFT 16U /*!< Bits Shifting to get Crc in element */ |
||||||
|
#define EE_DATA_TYPE uint32_t /*!< Type of Data */ |
||||||
|
#define EE_DATA_SHIFT 32U /*!< Bits Shifting to get Data value in element */ |
||||||
|
#define EE_MASK_VIRTUALADDRESS (uint64_t)0x000000000000FFFFU |
||||||
|
#define EE_MASK_CRC (uint64_t)0x00000000FFFF0000U |
||||||
|
#define EE_MASK_DATA (uint64_t)0xFFFFFFFF00000000U |
||||||
|
#define EE_MASK_FULL (uint64_t)0xFFFFFFFFFFFFFFFFU |
||||||
|
|
||||||
|
#define SECURE_FEATURE /*!< Informs the driver about the security features of the flash interface */ |
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Private macro -------------------------------------------------------------*/ |
||||||
|
/** @addtogroup EEPROM_Private_Macros
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Private functions ---------------------------------------------------------*/ |
||||||
|
/** @addtogroup EEPROM_Private_Functions
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
HAL_StatusTypeDef FI_WriteDoubleWord(uint32_t Address, uint64_t Data); |
||||||
|
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages); |
||||||
|
EE_Status FI_PageErase_IT(uint32_t Page, uint16_t NbPages); |
||||||
|
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address); |
||||||
|
EE_Status FI_CheckBankConfig(void); |
||||||
|
void FI_CacheFlush(void); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
#endif /* __FLASH_INTERFACE_H */ |
||||||
|
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@ -0,0 +1,299 @@ |
|||||||
|
/**
|
||||||
|
****************************************************************************** |
||||||
|
* @file EEPROM_Emul/Porting/STM32L5/flash_interface.c |
||||||
|
* @author MCD Application Team |
||||||
|
* @brief This file provides all the EEPROM emulation flash interface functions. |
||||||
|
****************************************************************************** |
||||||
|
* @attention |
||||||
|
* |
||||||
|
* <h2><center>© Copyright (c) 2020 STMicroelectronics. |
||||||
|
* All rights reserved.</center></h2> |
||||||
|
* |
||||||
|
* This software component is licensed by ST under BSD 3-Clause license, |
||||||
|
* the "License"; You may not use this file except in compliance with the |
||||||
|
* License. You may obtain a copy of the License at: |
||||||
|
* opensource.org/licenses/BSD-3-Clause |
||||||
|
* |
||||||
|
****************************************************************************** |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/ |
||||||
|
#include "eeprom_emul.h" |
||||||
|
#include "flash_interface.h" |
||||||
|
|
||||||
|
/** @addtogroup EEPROM_Emulation
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Private typedef -----------------------------------------------------------*/ |
||||||
|
/* Private constants ---------------------------------------------------------*/ |
||||||
|
/* Private macro -------------------------------------------------------------*/ |
||||||
|
/* Private variables ---------------------------------------------------------*/ |
||||||
|
uint64_t FlashWord[2] = |
||||||
|
{ |
||||||
|
0x0, 0x0 |
||||||
|
}; |
||||||
|
uint8_t FlashWord_status = 0; /* 0 is FlashWord is empty, 1 it is full */ |
||||||
|
const uint32_t QuadWord[4] =
|
||||||
|
{
|
||||||
|
0x00000000, |
||||||
|
0x00000000, |
||||||
|
0x00000000, |
||||||
|
0x00000000 |
||||||
|
}; |
||||||
|
/* Private function prototypes -----------------------------------------------*/ |
||||||
|
#ifdef FLASH_BANK_2 |
||||||
|
static uint32_t GetBankNumber(uint32_t Address); |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Exported functions --------------------------------------------------------*/ |
||||||
|
/* Private functions ---------------------------------------------------------*/ |
||||||
|
/** @addtogroup EEPROM_Private_Functions
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Write a quad word at the given address in Flash (function is called FI_WriteDoubleWord to respect legacy for X-CUBE-EEPROM) |
||||||
|
* @param Address Where to write |
||||||
|
* @param Data What to write |
||||||
|
* @param Write_type Type of writing on going (see EE_Write_type) |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE_WRITE_ERROR: if an error occurs |
||||||
|
* - EE_FLASH_USED: flash currently used by CPU2 |
||||||
|
*/ |
||||||
|
EE_Status FI_WriteDoubleWord(uint32_t Address, uint64_t* Data, EE_Write_type Write_type) |
||||||
|
{ |
||||||
|
EE_Status status = EE_OK; |
||||||
|
|
||||||
|
if(Write_type == EE_SET_PAGE) |
||||||
|
{
|
||||||
|
FlashWord[0] = Data[0]; |
||||||
|
FlashWord[1] = Data[0]; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
FlashWord[0] = Data[0]; |
||||||
|
FlashWord[1] = Data[1];
|
||||||
|
} |
||||||
|
|
||||||
|
if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD, Address, ((uint32_t)FlashWord)) != HAL_OK) |
||||||
|
{ |
||||||
|
status = EE_WRITE_ERROR; |
||||||
|
} |
||||||
|
|
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Erase a page in polling mode |
||||||
|
* @param Page Page number |
||||||
|
* @param NbPages Number of pages to erase |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages) |
||||||
|
{ |
||||||
|
EE_Status status = EE_OK; |
||||||
|
FLASH_EraseInitTypeDef s_eraseinit; |
||||||
|
uint32_t bank = FLASH_BANK_1, page_error = 0U; |
||||||
|
|
||||||
|
#ifdef FLASH_BANK_2 |
||||||
|
bank = GetBankNumber(PAGE_ADDRESS(Page)); |
||||||
|
#endif |
||||||
|
|
||||||
|
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; /* if TrustZone secure activated -> FLASH_TYPEERASE_PAGES_NS; */ |
||||||
|
s_eraseinit.NbPages = NbPages; |
||||||
|
s_eraseinit.Page = Page; |
||||||
|
s_eraseinit.Banks = bank; |
||||||
|
|
||||||
|
/* Erase the Page: Set Page status to ERASED status */ |
||||||
|
if (HAL_FLASHEx_Erase(&s_eraseinit, &page_error) != HAL_OK) |
||||||
|
{ |
||||||
|
status = EE_ERASE_ERROR; |
||||||
|
} |
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Erase a page with interrupt enabled |
||||||
|
* @param Page Page number |
||||||
|
* @param NbPages Number of pages to erase |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_PageErase_IT(uint32_t Page, uint16_t NbPages) |
||||||
|
{ |
||||||
|
EE_Status status = EE_OK; |
||||||
|
FLASH_EraseInitTypeDef s_eraseinit; |
||||||
|
uint32_t bank = FLASH_BANK_1; |
||||||
|
|
||||||
|
#ifdef FLASH_BANK_2 |
||||||
|
bank = GetBankNumber(PAGE_ADDRESS(Page)); |
||||||
|
#endif |
||||||
|
|
||||||
|
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; /* if TrustZone secure activated -> FLASH_TYPEERASE_PAGES_NS; */ |
||||||
|
s_eraseinit.NbPages = NbPages; |
||||||
|
s_eraseinit.Page = Page; |
||||||
|
s_eraseinit.Banks = bank; |
||||||
|
|
||||||
|
/* Erase the Page: Set Page status to ERASED status */ |
||||||
|
if (HAL_FLASHEx_Erase_IT(&s_eraseinit) != HAL_OK) |
||||||
|
{ |
||||||
|
status = EE_ERASE_ERROR; |
||||||
|
} |
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Flush the caches if needed to keep coherency when the flash content is modified |
||||||
|
*/ |
||||||
|
void FI_CacheFlush() |
||||||
|
{ |
||||||
|
/* No flush needed. EEPROM flash area is defined as non-cacheable thanks to the MPU in main.c. */ |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
#ifdef FLASH_BANK_2 |
||||||
|
/**
|
||||||
|
* @brief Gets the bank of a given address |
||||||
|
* @param Address Address of the FLASH Memory |
||||||
|
* @retval Bank_Number The bank of a given address |
||||||
|
*/ |
||||||
|
static uint32_t GetBankNumber(uint32_t Address) |
||||||
|
{ |
||||||
|
uint32_t bank = 0U; |
||||||
|
|
||||||
|
if (READ_BIT(FLASH->OPTR, FLASH_OPTR_SWAP_BANK) == 0U) |
||||||
|
{ |
||||||
|
/* No Bank swap */ |
||||||
|
if (Address < (FLASH_BASE + FLASH_BANK_SIZE)) |
||||||
|
{ |
||||||
|
bank = FLASH_BANK_1; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
bank = FLASH_BANK_2; |
||||||
|
} |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
/* Bank swap */ |
||||||
|
if (Address < (FLASH_BASE + FLASH_BANK_SIZE)) |
||||||
|
{ |
||||||
|
bank = FLASH_BANK_2; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
bank = FLASH_BANK_1; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return bank; |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Delete corrupted Flash address, can be called from NMI. No Timeout. |
||||||
|
* @param Address Address of the FLASH Memory to delete |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address) |
||||||
|
{ |
||||||
|
EE_Status status = EE_OK; |
||||||
|
|
||||||
|
/* Wait for previous programmation completion */ |
||||||
|
while(__HAL_FLASH_GET_FLAG(FLASH_NSSR_BSY)) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
/* Clear previous non-secure error programming flag */ |
||||||
|
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS); |
||||||
|
|
||||||
|
/* Set FLASH Programmation bit */ |
||||||
|
SET_BIT(FLASH->NSCR, FLASH_NSCR_PG); |
||||||
|
|
||||||
|
/* Program quad word of value 0 */ |
||||||
|
// HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD, Address, ((uint32_t)QuadWord));
|
||||||
|
*(__IO uint64_t*)(Address) = (uint64_t)0U; |
||||||
|
*(__IO uint64_t*)(Address+8U) = (uint64_t)0U; |
||||||
|
|
||||||
|
/* Wait programmation completion */ |
||||||
|
while(__HAL_FLASH_GET_FLAG(FLASH_NSSR_BSY)) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
/* Check if error occured */ |
||||||
|
if((__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PROGERR)) || |
||||||
|
(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR)) || |
||||||
|
(__HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGSERR))) |
||||||
|
{ |
||||||
|
status = EE_DELETE_ERROR; |
||||||
|
} |
||||||
|
|
||||||
|
/* Check FLASH End of Operation flag */ |
||||||
|
if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) |
||||||
|
{ |
||||||
|
/* Clear FLASH End of Operation pending bit */ |
||||||
|
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); |
||||||
|
} |
||||||
|
|
||||||
|
/* Clear FLASH Programmation bit */ |
||||||
|
CLEAR_BIT(FLASH->NSCR, FLASH_NSCR_PG); |
||||||
|
|
||||||
|
/* Clear FLASH ECCD bit */ |
||||||
|
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ECCD); |
||||||
|
|
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if the configuration is 128-bits bank or 2*64-bits bank |
||||||
|
* @param None |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_CheckBankConfig(void) |
||||||
|
{ |
||||||
|
#if defined (FLASH_OPTR_DBANK) |
||||||
|
FLASH_OBProgramInitTypeDef sOBCfg; |
||||||
|
EE_Status status; |
||||||
|
|
||||||
|
/* Request the Option Byte configuration :
|
||||||
|
- User and RDP level are always returned |
||||||
|
- WRP and PCROP are not requested */ |
||||||
|
sOBCfg.WRPArea = 0xFF; |
||||||
|
HAL_FLASHEx_OBGetConfig(&sOBCfg); |
||||||
|
|
||||||
|
/* Check the value of the DBANK user option byte */ |
||||||
|
if ((sOBCfg.USERConfig & OB_DBANK_64_BITS) != 0) |
||||||
|
{ |
||||||
|
status = EE_OK; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
status = EE_INVALID_BANK_CFG; |
||||||
|
} |
||||||
|
|
||||||
|
return status; |
||||||
|
#else |
||||||
|
/* No feature 128-bits single bank, so always 64-bits dual bank */ |
||||||
|
return EE_OK; |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@ -0,0 +1,126 @@ |
|||||||
|
/**
|
||||||
|
****************************************************************************** |
||||||
|
* @file EEPROM_Emul/Porting/STM32L5/flash_interface.h |
||||||
|
* @author MCD Application Team |
||||||
|
* @brief This file contains all the functions prototypes for the EEPROM |
||||||
|
* emulation flash interface. |
||||||
|
****************************************************************************** |
||||||
|
* @attention |
||||||
|
* |
||||||
|
* <h2><center>© Copyright (c) 2020 STMicroelectronics. |
||||||
|
* All rights reserved.</center></h2> |
||||||
|
* |
||||||
|
* This software component is licensed by ST under BSD 3-Clause license, |
||||||
|
* the "License"; You may not use this file except in compliance with the |
||||||
|
* License. You may obtain a copy of the License at: |
||||||
|
* opensource.org/licenses/BSD-3-Clause |
||||||
|
* |
||||||
|
****************************************************************************** |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/ |
||||||
|
#ifndef __FLASH_INTERFACE_H |
||||||
|
#define __FLASH_INTERFACE_H |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
extern "C" { |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/ |
||||||
|
#include "stm32u5xx_hal.h" |
||||||
|
#include "stm32u5xx_ll_crc.h" |
||||||
|
#include "stm32u5xx_ll_bus.h" |
||||||
|
|
||||||
|
/** @addtogroup EEPROM_Emulation
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Exported types ------------------------------------------------------------*/ |
||||||
|
/* Exported macro ------------------------------------------------------------*/ |
||||||
|
/* Exported functions ------------------------------------------------------- */ |
||||||
|
|
||||||
|
/* Private types -------------------------------------------------------------*/ |
||||||
|
/* Private constants ---------------------------------------------------------*/ |
||||||
|
/** @addtogroup EEPROM_Private_Constants
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/** @addtogroup Private_Other_Constants
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
#define BANK_SIZE FLASH_BANK_SIZE /*!< Alias to FLASH_BANK_SIZE definition from HAL */ |
||||||
|
#define EE_ACCESS_32BITS /*!< Enable EEPROM 32bits R/W functions */ |
||||||
|
|
||||||
|
/* Page state header */ |
||||||
|
#define EE_PAGESTAT_ERASED (uint64_t)0xFFFFFFFFFFFFFFFFU /*!< State saved in 1st,2nd,3rd,4th data type of page header */ |
||||||
|
#define EE_PAGESTAT_RECEIVE (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 1st data type of page header */ |
||||||
|
#define EE_PAGESTAT_ACTIVE (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 2nd data type of page header */ |
||||||
|
#define EE_PAGESTAT_VALID (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 3rd data type of page header */ |
||||||
|
#define EE_PAGESTAT_ERASING (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 4th data type of page header */ |
||||||
|
|
||||||
|
/* Description of the 16 Bytes (128 bits) element in flash */ |
||||||
|
/* Bit: 127 64 63 48 47 0 */ |
||||||
|
/* <--- Data Value -----> <-CRC-> <-VirtAddr-> */ |
||||||
|
#define EE_ELEMENT_SIZE 16U /*!< Size of element in Bytes */ |
||||||
|
#define EE_ELEMENT_TYPE uint64_t /*!< Type of element */ |
||||||
|
#define EE_VIRTUALADDRESS_TYPE uint64_t /*!< Type of Virtual Address */ |
||||||
|
#define EE_VIRTUALADDRESS_SHIFT 0U /*!< Bits Shifting to get Virtual Address in element */ |
||||||
|
#define EE_CRC_TYPE uint16_t /*!< Type of Crc */ |
||||||
|
#define EE_CRC_SHIFT 16U /*!< Bits Shifting to get Crc in element */ |
||||||
|
#define EE_DATA_TYPE uint64_t /*!< Type of Data */ |
||||||
|
#define EE_DATA_SHIFT 32U /*!< Bits Shifting to get Data value in element */ |
||||||
|
#define EE_MASK_VIRTUALADDRESS (uint64_t)0x000000000000FFFFU |
||||||
|
#define EE_MASK_CRC (uint64_t)0x00000000FFFF0000U |
||||||
|
#define EE_MASK_DATA (uint64_t)0xFFFFFFFFFFFFFFFFU |
||||||
|
#define EE_MASK_FULL (uint64_t)0xFFFFFFFFFFFFFFFFU |
||||||
|
|
||||||
|
#define SECURE_FEATURE /*!< Informs the driver about the security features of the flash interface */ |
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Private macro -------------------------------------------------------------*/ |
||||||
|
/** @addtogroup EEPROM_Private_Macros
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Private functions ---------------------------------------------------------*/ |
||||||
|
/** @addtogroup EEPROM_Private_Functions
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
EE_Status FI_WriteDoubleWord(uint32_t Address, uint64_t* Data, EE_Write_type Write_type); |
||||||
|
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages); |
||||||
|
EE_Status FI_PageErase_IT(uint32_t Page, uint16_t NbPages); |
||||||
|
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address); |
||||||
|
EE_Status FI_CheckBankConfig(void); |
||||||
|
void FI_CacheFlush(void); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
#endif /* __FLASH_INTERFACE_H */ |
||||||
|
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@ -0,0 +1,375 @@ |
|||||||
|
/**
|
||||||
|
****************************************************************************** |
||||||
|
* @file EEPROM_Emul/Porting/STM32WB/flash_interface.c |
||||||
|
* @author MCD Application Team |
||||||
|
* @brief This file provides all the EEPROM emulation flash interface functions. |
||||||
|
****************************************************************************** |
||||||
|
* @attention |
||||||
|
* |
||||||
|
* <h2><center>© Copyright (c) 2020 STMicroelectronics. |
||||||
|
* All rights reserved.</center></h2> |
||||||
|
* |
||||||
|
* This software component is licensed by ST under BSD 3-Clause license, |
||||||
|
* the "License"; You may not use this file except in compliance with the |
||||||
|
* License. You may obtain a copy of the License at: |
||||||
|
* opensource.org/licenses/BSD-3-Clause |
||||||
|
* |
||||||
|
****************************************************************************** |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/ |
||||||
|
#include "eeprom_emul.h" |
||||||
|
#include "flash_interface.h" |
||||||
|
#include "stm32wbxx_nucleo.h" |
||||||
|
|
||||||
|
/** @addtogroup EEPROM_Emulation
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Private typedef -----------------------------------------------------------*/ |
||||||
|
/* Private constants ---------------------------------------------------------*/ |
||||||
|
#ifdef DUALCORE_FLASH_SHARING |
||||||
|
#define HSEM_PROCESS_1 12U /* Number taken randomly to identify the process locking a semaphore in the driver context */ |
||||||
|
#endif |
||||||
|
/* Private macro -------------------------------------------------------------*/ |
||||||
|
/* Private variables ---------------------------------------------------------*/ |
||||||
|
/* Private function prototypes -----------------------------------------------*/ |
||||||
|
/* Exported functions --------------------------------------------------------*/ |
||||||
|
/* Private functions ---------------------------------------------------------*/ |
||||||
|
/** @addtogroup EEPROM_Private_Functions
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifdef DUALCORE_FLASH_SHARING |
||||||
|
/**
|
||||||
|
* @brief Write a double word at the given address in Flash |
||||||
|
* @param Address Where to write |
||||||
|
* @param Data What to write |
||||||
|
* @param Write_type Type of writing on going (see EE_Write_type) |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE_WRITE_ERROR: if an error occurs |
||||||
|
* - EE_FLASH_USED: flash currently used by CPU2 |
||||||
|
*/ |
||||||
|
EE_Status FI_WriteDoubleWord(uint32_t Address, uint64_t Data, EE_Write_type Write_type) |
||||||
|
{ |
||||||
|
EE_Status ee_status = EE_OK; |
||||||
|
|
||||||
|
/* We enter a critical section */ |
||||||
|
UTILS_ENTER_CRITICAL_SECTION(); |
||||||
|
|
||||||
|
/* When the ongoing writing operation is a direct one (no transfer is required,
|
||||||
|
we are not in init process, and we do not write the state of a page) */ |
||||||
|
if(Write_type == EE_SIMPLE_WRITE) |
||||||
|
{ |
||||||
|
/* Wait for the semaphore to be free */ |
||||||
|
while( HAL_HSEM_IsSemTaken(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID) ); |
||||||
|
|
||||||
|
/* Take the HW 7 semaphore */
|
||||||
|
if(HAL_HSEM_Take(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID, HSEM_PROCESS_1) == HAL_OK) |
||||||
|
{
|
||||||
|
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, Data) != HAL_OK) |
||||||
|
{ |
||||||
|
HAL_HSEM_Release(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID, HSEM_PROCESS_1); |
||||||
|
ee_status = EE_WRITE_ERROR; |
||||||
|
}
|
||||||
|
/* Release the HW Semaphore */
|
||||||
|
HAL_HSEM_Release(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID, HSEM_PROCESS_1); |
||||||
|
ee_status = EE_OK; |
||||||
|
} |
||||||
|
else |
||||||
|
{
|
||||||
|
/* If flash is used by CPU2, the semaphore release interrupt is activated so as to raise a notification when
|
||||||
|
the semaphore will be unlocked (user can do other operations while waiting) */ |
||||||
|
HAL_HSEM_ActivateNotification(__HAL_HSEM_SEMID_TO_MASK(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID)); |
||||||
|
ee_status = EE_FLASH_USED; |
||||||
|
} |
||||||
|
} |
||||||
|
/* This is when the function call comes from a writing operation other than a direct one */ |
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Wait for the semaphore 7 to be free and take it when it is */ |
||||||
|
while(HAL_HSEM_Take(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID, HSEM_PROCESS_1) != HAL_OK) |
||||||
|
{ |
||||||
|
while( HAL_HSEM_IsSemTaken(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID) ) ; |
||||||
|
} |
||||||
|
|
||||||
|
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, Data) != HAL_OK) |
||||||
|
{ |
||||||
|
HAL_HSEM_Release(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID, HSEM_PROCESS_1); |
||||||
|
ee_status = EE_WRITE_ERROR; |
||||||
|
}
|
||||||
|
/* Release the HW Semaphore */
|
||||||
|
HAL_HSEM_Release(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID, HSEM_PROCESS_1); |
||||||
|
ee_status = EE_OK; |
||||||
|
} |
||||||
|
|
||||||
|
/* We exit the critical section */ |
||||||
|
UTILS_EXIT_CRITICAL_SECTION(); |
||||||
|
return ee_status; |
||||||
|
} |
||||||
|
#else |
||||||
|
/**
|
||||||
|
* @brief Write a double word at the given address in Flash |
||||||
|
* @param Address Where to write |
||||||
|
* @param Data What to write |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE_WRITE_ERROR: if an error occurs |
||||||
|
*/ |
||||||
|
HAL_StatusTypeDef FI_WriteDoubleWord(uint32_t Address, uint64_t Data) |
||||||
|
{ |
||||||
|
return HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, Data);
|
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Erase a page in polling mode |
||||||
|
* @param Page Page number |
||||||
|
* @param NbPages Number of pages to erase |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages) |
||||||
|
{ |
||||||
|
EE_Status status = EE_OK; |
||||||
|
|
||||||
|
#ifdef DUALCORE_FLASH_SHARING |
||||||
|
|
||||||
|
/* Wait for last operation to be completed */ |
||||||
|
while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) ; |
||||||
|
|
||||||
|
/* Because we want to share flash between CPU1 and 2, we erase each page individually
|
||||||
|
* and we take then release the associated semaphore for each page erasings. |
||||||
|
* By doing this, we allow CPU2 to do urgent works between page erasings. */ |
||||||
|
for (uint32_t index = Page; index < (Page + NbPages); index++) |
||||||
|
{ |
||||||
|
/* We enter a critical section */ |
||||||
|
UTILS_ENTER_CRITICAL_SECTION(); |
||||||
|
|
||||||
|
/* Wait for the semaphore 7 to be free and take it when it is */ |
||||||
|
while(HAL_HSEM_Take(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID, HSEM_PROCESS_1) != HAL_OK) |
||||||
|
{ |
||||||
|
while( HAL_HSEM_IsSemTaken(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID) ) ; |
||||||
|
} |
||||||
|
|
||||||
|
/* Start erase page */ |
||||||
|
FLASH_PageErase(index); |
||||||
|
/* Release the HW Semaphore */
|
||||||
|
HAL_HSEM_Release(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID, HSEM_PROCESS_1);
|
||||||
|
/* We exit the critical section */ |
||||||
|
UTILS_EXIT_CRITICAL_SECTION(); |
||||||
|
|
||||||
|
/* Wait for last operation to be completed */ |
||||||
|
while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) ; |
||||||
|
} |
||||||
|
|
||||||
|
/* If operation is completed or interrupted, disable the Page Erase Bit */ |
||||||
|
CLEAR_BIT(FLASH->CR, (FLASH_CR_PER | FLASH_CR_PNB)); |
||||||
|
|
||||||
|
/* Flush the caches to be sure of the data consistency */ |
||||||
|
/* Flush instruction cache */ |
||||||
|
if (READ_BIT(FLASH->ACR, FLASH_ACR_ICEN) == FLASH_ACR_ICEN) |
||||||
|
{ |
||||||
|
/* Disable instruction cache */ |
||||||
|
__HAL_FLASH_INSTRUCTION_CACHE_DISABLE(); |
||||||
|
/* Reset instruction cache */ |
||||||
|
__HAL_FLASH_INSTRUCTION_CACHE_RESET(); |
||||||
|
/* Enable instruction cache */ |
||||||
|
__HAL_FLASH_INSTRUCTION_CACHE_ENABLE(); |
||||||
|
} |
||||||
|
|
||||||
|
/* Flush data cache */ |
||||||
|
if (READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) == FLASH_ACR_DCEN) |
||||||
|
{ |
||||||
|
/* Disable data cache */ |
||||||
|
__HAL_FLASH_DATA_CACHE_DISABLE(); |
||||||
|
/* Reset data cache */ |
||||||
|
__HAL_FLASH_DATA_CACHE_RESET(); |
||||||
|
/* Enable data cache */ |
||||||
|
__HAL_FLASH_DATA_CACHE_ENABLE(); |
||||||
|
} |
||||||
|
|
||||||
|
#else |
||||||
|
FLASH_EraseInitTypeDef s_eraseinit; |
||||||
|
uint32_t page_error = 0U; |
||||||
|
|
||||||
|
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; |
||||||
|
s_eraseinit.NbPages = NbPages; |
||||||
|
s_eraseinit.Page = Page; |
||||||
|
|
||||||
|
/* Erase the Page: Set Page status to ERASED status */ |
||||||
|
if (HAL_FLASHEx_Erase(&s_eraseinit, &page_error) != HAL_OK) |
||||||
|
{ |
||||||
|
status = EE_ERASE_ERROR; |
||||||
|
} |
||||||
|
#endif |
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Erase a page with interrupt enabled |
||||||
|
* @param Page Page number |
||||||
|
* @param NbPages Number of pages to erase |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_PageErase_IT(uint32_t Page, uint16_t NbPages) |
||||||
|
{ |
||||||
|
EE_Status status = EE_OK; |
||||||
|
FLASH_EraseInitTypeDef s_eraseinit; |
||||||
|
|
||||||
|
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; |
||||||
|
s_eraseinit.NbPages = NbPages; |
||||||
|
s_eraseinit.Page = Page; |
||||||
|
|
||||||
|
#ifdef DUALCORE_FLASH_SHARING |
||||||
|
/* We enter a critical section */ |
||||||
|
UTILS_ENTER_CRITICAL_SECTION(); |
||||||
|
|
||||||
|
/* Wait for the semaphore 7 to be free and take it when it is */ |
||||||
|
while(HAL_HSEM_Take(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID, HSEM_PROCESS_1) != HAL_OK) |
||||||
|
{ |
||||||
|
while( HAL_HSEM_IsSemTaken(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID) ) ; |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Erase the Page: Set Page status to ERASED status */ |
||||||
|
if (HAL_FLASHEx_Erase_IT(&s_eraseinit) != HAL_OK) |
||||||
|
{ |
||||||
|
status = EE_ERASE_ERROR; |
||||||
|
} |
||||||
|
|
||||||
|
#ifdef DUALCORE_FLASH_SHARING |
||||||
|
/* Release the HW Semaphore */
|
||||||
|
HAL_HSEM_Release(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID, HSEM_PROCESS_1); |
||||||
|
/* We exit the critical section */ |
||||||
|
UTILS_EXIT_CRITICAL_SECTION(); |
||||||
|
#endif |
||||||
|
|
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Flush the caches if needed to keep coherency when the flash content is modified |
||||||
|
*/ |
||||||
|
void FI_CacheFlush() |
||||||
|
{ |
||||||
|
/* To keep its coherency, flush the D-Cache: its content is not updated after a flash erase. */ |
||||||
|
__HAL_FLASH_DATA_CACHE_DISABLE(); |
||||||
|
__HAL_FLASH_DATA_CACHE_RESET(); |
||||||
|
__HAL_FLASH_DATA_CACHE_ENABLE(); |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Delete corrupted Flash address, can be called from NMI. No Timeout. |
||||||
|
* @param Address Address of the FLASH Memory to delete |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address) |
||||||
|
{ |
||||||
|
EE_Status status = EE_OK; |
||||||
|
|
||||||
|
/* Set FLASH Programmation bit */ |
||||||
|
SET_BIT(FLASH->CR, FLASH_CR_PG); |
||||||
|
|
||||||
|
#ifdef DUALCORE_FLASH_SHARING |
||||||
|
/* We enter a critical section */ |
||||||
|
UTILS_ENTER_CRITICAL_SECTION(); |
||||||
|
|
||||||
|
/* Wait for the semaphore 7 to be free and take it when it is */ |
||||||
|
while(HAL_HSEM_Take(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID, HSEM_PROCESS_1) != HAL_OK) |
||||||
|
{ |
||||||
|
while( HAL_HSEM_IsSemTaken(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID) ) ; |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Program double word of value 0 */ |
||||||
|
*(__IO uint32_t*)(Address) = (uint32_t)0U; |
||||||
|
*(__IO uint32_t*)(Address+4U) = (uint32_t)0U; |
||||||
|
|
||||||
|
#ifdef DUALCORE_FLASH_SHARING |
||||||
|
/* Release the HW Semaphore */
|
||||||
|
HAL_HSEM_Release(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID, HSEM_PROCESS_1);
|
||||||
|
/* We exit the critical section */ |
||||||
|
UTILS_EXIT_CRITICAL_SECTION(); |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Wait programmation completion */ |
||||||
|
while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) ; |
||||||
|
|
||||||
|
/* Check if error occured */ |
||||||
|
if((__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PROGERR)) || |
||||||
|
(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR)) || |
||||||
|
(__HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGSERR))) |
||||||
|
{ |
||||||
|
status = EE_DELETE_ERROR; |
||||||
|
} |
||||||
|
|
||||||
|
/* Check FLASH End of Operation flag */ |
||||||
|
if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) |
||||||
|
{ |
||||||
|
/* Clear FLASH End of Operation pending bit */ |
||||||
|
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); |
||||||
|
} |
||||||
|
|
||||||
|
/* Clear FLASH Programmation bit */ |
||||||
|
CLEAR_BIT(FLASH->CR, FLASH_CR_PG); |
||||||
|
|
||||||
|
/* Clear FLASH ECCD bit */ |
||||||
|
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ECCD); |
||||||
|
|
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if the configuration is 128-bits bank or 2*64-bits bank |
||||||
|
* @param None |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_CheckBankConfig(void) |
||||||
|
{ |
||||||
|
#if defined (FLASH_OPTR_DBANK) |
||||||
|
FLASH_OBProgramInitTypeDef sOBCfg; |
||||||
|
EE_Status status; |
||||||
|
|
||||||
|
/* Request the Option Byte configuration :
|
||||||
|
- User and RDP level are always returned |
||||||
|
- WRP and PCROP are not requested */ |
||||||
|
sOBCfg.WRPArea = 0xFF; |
||||||
|
sOBCfg.PCROPConfig = 0xFF; |
||||||
|
HAL_FLASHEx_OBGetConfig(&sOBCfg); |
||||||
|
|
||||||
|
/* Check the value of the DBANK user option byte */ |
||||||
|
if ((sOBCfg.USERConfig & OB_DBANK_64_BITS) != 0) |
||||||
|
{ |
||||||
|
status = EE_OK; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
status = EE_INVALID_BANK_CFG; |
||||||
|
} |
||||||
|
|
||||||
|
return status; |
||||||
|
#else |
||||||
|
/* No feature 128-bits single bank, so always 64-bits dual bank */ |
||||||
|
return EE_OK; |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@ -0,0 +1,142 @@ |
|||||||
|
/**
|
||||||
|
****************************************************************************** |
||||||
|
* @file EEPROM_Emul/Porting/STM32WB/flash_interface.h |
||||||
|
* @author MCD Application Team |
||||||
|
* @brief This file contains all the functions prototypes for the EEPROM |
||||||
|
* emulation flash interface. |
||||||
|
****************************************************************************** |
||||||
|
* @attention |
||||||
|
* |
||||||
|
* <h2><center>© Copyright (c) 2020 STMicroelectronics. |
||||||
|
* All rights reserved.</center></h2> |
||||||
|
* |
||||||
|
* This software component is licensed by ST under BSD 3-Clause license, |
||||||
|
* the "License"; You may not use this file except in compliance with the |
||||||
|
* License. You may obtain a copy of the License at: |
||||||
|
* opensource.org/licenses/BSD-3-Clause |
||||||
|
* |
||||||
|
****************************************************************************** |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/ |
||||||
|
#ifndef __FLASH_INTERFACE_H |
||||||
|
#define __FLASH_INTERFACE_H |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
extern "C" { |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/ |
||||||
|
#include "eeprom_emul.h" |
||||||
|
#include "stm32wbxx_hal.h" |
||||||
|
#include "stm32wbxx_ll_crc.h" |
||||||
|
#include "stm32wbxx_ll_bus.h" |
||||||
|
#ifdef DUALCORE_FLASH_SHARING |
||||||
|
#include "utilities_conf.h" |
||||||
|
#include "hw_conf.h" |
||||||
|
#include "shci.h" |
||||||
|
#endif |
||||||
|
|
||||||
|
/** @addtogroup EEPROM_Emulation
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Exported types ------------------------------------------------------------*/ |
||||||
|
/* Exported macro ------------------------------------------------------------*/ |
||||||
|
/* Exported functions ------------------------------------------------------- */ |
||||||
|
|
||||||
|
/* Private types -------------------------------------------------------------*/ |
||||||
|
/* Private constants ---------------------------------------------------------*/ |
||||||
|
/** @addtogroup EEPROM_Private_Constants
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/** @addtogroup Private_Other_Constants
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
#define BANK_SIZE FLASH_BANK_SIZE /*!< Alias to FLASH_BANK_SIZE definition from HAL STM32L4 */ |
||||||
|
#define EE_ACCESS_32BITS /*!< Enable EEPROM 32bits R/W functions, only valid for flash allowing 64bits access*/ |
||||||
|
|
||||||
|
/* Page state header */ |
||||||
|
#define EE_PAGESTAT_ERASED (uint64_t)0xFFFFFFFFFFFFFFFFU /*!< State saved in 1st,2nd,3rd,4th data type of page header */ |
||||||
|
#define EE_PAGESTAT_RECEIVE (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 1st data type of page header */ |
||||||
|
#define EE_PAGESTAT_ACTIVE (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 2nd data type of page header */ |
||||||
|
#define EE_PAGESTAT_VALID (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 3rd data type of page header */ |
||||||
|
#define EE_PAGESTAT_ERASING (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 4th data type of page header */ |
||||||
|
|
||||||
|
/* Description of the 8 Bytes (64 bits) element in flash */ |
||||||
|
/* Bit: 63 32 31 16 15 0 */ |
||||||
|
/* <--- Data Value -----> <-unused-> <-VirtAddr-> */ |
||||||
|
#define EE_ELEMENT_SIZE 8U /*!< Size of element in Bytes */ |
||||||
|
#define EE_ELEMENT_TYPE uint64_t /*!< Type of element */ |
||||||
|
#define EE_VIRTUALADDRESS_TYPE uint16_t /*!< Type of Virtual Address */ |
||||||
|
#define EE_VIRTUALADDRESS_SHIFT 0U /*!< Bits Shifting to get Virtual Address in element */ |
||||||
|
#define EE_CRC_TYPE uint16_t /*!< Type of Crc */ |
||||||
|
#define EE_CRC_SHIFT 16U /*!< Bits Shifting to get Crc in element */ |
||||||
|
#define EE_DATA_TYPE uint32_t /*!< Type of Data */ |
||||||
|
#define EE_DATA_SHIFT 32U /*!< Bits Shifting to get Data value in element */ |
||||||
|
#define EE_MASK_VIRTUALADDRESS (uint64_t)0x000000000000FFFFU |
||||||
|
#define EE_MASK_CRC (uint64_t)0x00000000FFFF0000U |
||||||
|
#define EE_MASK_DATA (uint64_t)0xFFFFFFFF00000000U |
||||||
|
#define EE_MASK_FULL (uint64_t)0xFFFFFFFFFFFFFFFFU |
||||||
|
|
||||||
|
#ifdef DUALCORE_FLASH_SHARING |
||||||
|
#define EE_SEM_WAIT_TIMEOUT 5000U /*!< Take semaphore attempts timeout, 5s */ |
||||||
|
#endif |
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Private macro -------------------------------------------------------------*/ |
||||||
|
/** @addtogroup EEPROM_Private_Macros
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/** @defgroup Macros_Flash Macros to access flash
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Private functions ---------------------------------------------------------*/ |
||||||
|
/** @addtogroup EEPROM_Private_Functions
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
#ifdef DUALCORE_FLASH_SHARING |
||||||
|
EE_Status FI_WriteDoubleWord(uint32_t Address, uint64_t Data, EE_Write_type Write_type); |
||||||
|
#else |
||||||
|
HAL_StatusTypeDef FI_WriteDoubleWord(uint32_t Address, uint64_t Data); |
||||||
|
#endif |
||||||
|
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages); |
||||||
|
EE_Status FI_PageErase_IT(uint32_t Page, uint16_t NbPages); |
||||||
|
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address); |
||||||
|
EE_Status FI_CheckBankConfig(void); |
||||||
|
void FI_CacheFlush(void); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
#endif /* __FLASH_INTERFACE_H */ |
||||||
|
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@ -0,0 +1,207 @@ |
|||||||
|
/**
|
||||||
|
****************************************************************************** |
||||||
|
* @file EEPROM_Emul/Porting/STM32WL/flash_interface.c |
||||||
|
* @author MCD Application Team |
||||||
|
* @brief This file provides all the EEPROM emulation flash interface functions. |
||||||
|
****************************************************************************** |
||||||
|
* @attention |
||||||
|
* |
||||||
|
* <h2><center>© Copyright (c) 2020 STMicroelectronics. |
||||||
|
* All rights reserved.</center></h2> |
||||||
|
* |
||||||
|
* This software component is licensed by ST under BSD 3-Clause license, |
||||||
|
* the "License"; You may not use this file except in compliance with the |
||||||
|
* License. You may obtain a copy of the License at: |
||||||
|
* opensource.org/licenses/BSD-3-Clause |
||||||
|
* |
||||||
|
****************************************************************************** |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/ |
||||||
|
#include "eeprom_emul.h" |
||||||
|
#include "flash_interface.h" |
||||||
|
#include "stm32wlxx_nucleo.h" |
||||||
|
|
||||||
|
/** @addtogroup EEPROM_Emulation
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Private typedef -----------------------------------------------------------*/ |
||||||
|
/* Private constants ---------------------------------------------------------*/ |
||||||
|
/* Private macro -------------------------------------------------------------*/ |
||||||
|
/* Private variables ---------------------------------------------------------*/ |
||||||
|
/* Private function prototypes -----------------------------------------------*/ |
||||||
|
/* Exported functions --------------------------------------------------------*/ |
||||||
|
/* Private functions ---------------------------------------------------------*/ |
||||||
|
/** @addtogroup EEPROM_Private_Functions
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Write a double word at the given address in Flash |
||||||
|
* @param Address Where to write |
||||||
|
* @param Data What to write |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE_WRITE_ERROR: if an error occurs |
||||||
|
*/ |
||||||
|
HAL_StatusTypeDef FI_WriteDoubleWord(uint32_t Address, uint64_t Data) |
||||||
|
{ |
||||||
|
return HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, Data);
|
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Erase a page in polling mode |
||||||
|
* @param Page Page number |
||||||
|
* @param NbPages Number of pages to erase |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages) |
||||||
|
{ |
||||||
|
EE_Status status = EE_OK; |
||||||
|
FLASH_EraseInitTypeDef s_eraseinit; |
||||||
|
uint32_t page_error = 0U; |
||||||
|
|
||||||
|
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; |
||||||
|
s_eraseinit.NbPages = NbPages; |
||||||
|
s_eraseinit.Page = Page; |
||||||
|
|
||||||
|
/* Erase the Page: Set Page status to ERASED status */ |
||||||
|
if (HAL_FLASHEx_Erase(&s_eraseinit, &page_error) != HAL_OK) |
||||||
|
{ |
||||||
|
status = EE_ERASE_ERROR; |
||||||
|
} |
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Erase a page with interrupt enabled |
||||||
|
* @param Page Page number |
||||||
|
* @param NbPages Number of pages to erase |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_PageErase_IT(uint32_t Page, uint16_t NbPages) |
||||||
|
{ |
||||||
|
EE_Status status = EE_OK; |
||||||
|
FLASH_EraseInitTypeDef s_eraseinit; |
||||||
|
|
||||||
|
s_eraseinit.TypeErase = FLASH_TYPEERASE_PAGES; |
||||||
|
s_eraseinit.NbPages = NbPages; |
||||||
|
s_eraseinit.Page = Page;
|
||||||
|
|
||||||
|
/* Erase the Page: Set Page status to ERASED status */ |
||||||
|
if (HAL_FLASHEx_Erase_IT(&s_eraseinit) != HAL_OK) |
||||||
|
{ |
||||||
|
status = EE_ERASE_ERROR; |
||||||
|
} |
||||||
|
|
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Flush the caches if needed to keep coherency when the flash content is modified |
||||||
|
*/ |
||||||
|
void FI_CacheFlush() |
||||||
|
{ |
||||||
|
/* To keep its coherency, flush the D-Cache: its content is not updated after a flash erase. */ |
||||||
|
__HAL_FLASH_DATA_CACHE_DISABLE(); |
||||||
|
__HAL_FLASH_DATA_CACHE_RESET(); |
||||||
|
__HAL_FLASH_DATA_CACHE_ENABLE(); |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Delete corrupted Flash address, can be called from NMI. No Timeout. |
||||||
|
* @param Address Address of the FLASH Memory to delete |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address) |
||||||
|
{ |
||||||
|
EE_Status status = EE_OK; |
||||||
|
|
||||||
|
/* Set FLASH Programmation bit */ |
||||||
|
SET_BIT(FLASH->CR, FLASH_CR_PG); |
||||||
|
|
||||||
|
/* Program double word of value 0 */ |
||||||
|
*(__IO uint32_t*)(Address) = (uint32_t)0U; |
||||||
|
*(__IO uint32_t*)(Address+4U) = (uint32_t)0U; |
||||||
|
|
||||||
|
/* Wait programmation completion */ |
||||||
|
while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) ; |
||||||
|
|
||||||
|
/* Check if error occured */ |
||||||
|
if((__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PROGERR)) || |
||||||
|
(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR)) || |
||||||
|
(__HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGSERR))) |
||||||
|
{ |
||||||
|
status = EE_DELETE_ERROR; |
||||||
|
} |
||||||
|
|
||||||
|
/* Check FLASH End of Operation flag */ |
||||||
|
if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) |
||||||
|
{ |
||||||
|
/* Clear FLASH End of Operation pending bit */ |
||||||
|
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); |
||||||
|
} |
||||||
|
|
||||||
|
/* Clear FLASH Programmation bit */ |
||||||
|
CLEAR_BIT(FLASH->CR, FLASH_CR_PG); |
||||||
|
|
||||||
|
/* Clear FLASH ECCD bit */ |
||||||
|
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ECCD); |
||||||
|
|
||||||
|
return status; |
||||||
|
} |
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if the configuration is 128-bits bank or 2*64-bits bank |
||||||
|
* @param None |
||||||
|
* @retval EE_Status |
||||||
|
* - EE_OK: on success |
||||||
|
* - EE error code: if an error occurs |
||||||
|
*/ |
||||||
|
EE_Status FI_CheckBankConfig(void) |
||||||
|
{ |
||||||
|
#if defined (FLASH_OPTR_DBANK) |
||||||
|
FLASH_OBProgramInitTypeDef sOBCfg; |
||||||
|
EE_Status status; |
||||||
|
|
||||||
|
/* Request the Option Byte configuration :
|
||||||
|
- User and RDP level are always returned |
||||||
|
- WRP and PCROP are not requested */ |
||||||
|
sOBCfg.WRPArea = 0xFF; |
||||||
|
sOBCfg.PCROPConfig = 0xFF; |
||||||
|
HAL_FLASHEx_OBGetConfig(&sOBCfg); |
||||||
|
|
||||||
|
/* Check the value of the DBANK user option byte */ |
||||||
|
if ((sOBCfg.USERConfig & OB_DBANK_64_BITS) != 0) |
||||||
|
{ |
||||||
|
status = EE_OK; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
status = EE_INVALID_BANK_CFG; |
||||||
|
} |
||||||
|
|
||||||
|
return status; |
||||||
|
#else |
||||||
|
/* No feature 128-bits single bank, so always 64-bits dual bank */ |
||||||
|
return EE_OK; |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
@ -0,0 +1,134 @@ |
|||||||
|
/**
|
||||||
|
****************************************************************************** |
||||||
|
* @file EEPROM_Emul/Porting/STM32WL/flash_interface.h |
||||||
|
* @author MCD Application Team |
||||||
|
* @brief This file contains all the functions prototypes for the EEPROM |
||||||
|
* emulation flash interface. |
||||||
|
****************************************************************************** |
||||||
|
* @attention |
||||||
|
* |
||||||
|
* <h2><center>© Copyright (c) 2020 STMicroelectronics. |
||||||
|
* All rights reserved.</center></h2> |
||||||
|
* |
||||||
|
* This software component is licensed by ST under BSD 3-Clause license, |
||||||
|
* the "License"; You may not use this file except in compliance with the |
||||||
|
* License. You may obtain a copy of the License at: |
||||||
|
* opensource.org/licenses/BSD-3-Clause |
||||||
|
* |
||||||
|
****************************************************************************** |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Define to prevent recursive inclusion -------------------------------------*/ |
||||||
|
#ifndef __FLASH_INTERFACE_H |
||||||
|
#define __FLASH_INTERFACE_H |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
extern "C" { |
||||||
|
#endif |
||||||
|
|
||||||
|
/* Includes ------------------------------------------------------------------*/ |
||||||
|
#include "eeprom_emul.h" |
||||||
|
#include "stm32wlxx_hal.h" |
||||||
|
#include "stm32wlxx_ll_crc.h" |
||||||
|
#include "stm32wlxx_ll_bus.h" |
||||||
|
|
||||||
|
/** @addtogroup EEPROM_Emulation
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Exported types ------------------------------------------------------------*/ |
||||||
|
/* Exported macro ------------------------------------------------------------*/ |
||||||
|
/* Exported functions ------------------------------------------------------- */ |
||||||
|
|
||||||
|
/* Private types -------------------------------------------------------------*/ |
||||||
|
/* Private constants ---------------------------------------------------------*/ |
||||||
|
/** @addtogroup EEPROM_Private_Constants
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/** @addtogroup Private_Other_Constants
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
#define BANK_SIZE FLASH_BANK_SIZE /*!< Alias to FLASH_BANK_SIZE definition from HAL STM32L4 */ |
||||||
|
#define EE_ACCESS_32BITS /*!< Enable EEPROM 32bits R/W functions, only valid for flash allowing 64bits access*/ |
||||||
|
|
||||||
|
/* Page state header */ |
||||||
|
#define EE_PAGESTAT_ERASED (uint64_t)0xFFFFFFFFFFFFFFFFU /*!< State saved in 1st,2nd,3rd,4th data type of page header */ |
||||||
|
#define EE_PAGESTAT_RECEIVE (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 1st data type of page header */ |
||||||
|
#define EE_PAGESTAT_ACTIVE (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 2nd data type of page header */ |
||||||
|
#define EE_PAGESTAT_VALID (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 3rd data type of page header */ |
||||||
|
#define EE_PAGESTAT_ERASING (uint64_t)0xAAAAAAAAAAAAAAAAU /*!< State saved in 4th data type of page header */ |
||||||
|
|
||||||
|
/* Description of the 8 Bytes (64 bits) element in flash */ |
||||||
|
/* Bit: 63 32 31 16 15 0 */ |
||||||
|
/* <--- Data Value -----> <-unused-> <-VirtAddr-> */ |
||||||
|
#define EE_ELEMENT_SIZE 8U /*!< Size of element in Bytes */ |
||||||
|
#define EE_ELEMENT_TYPE uint64_t /*!< Type of element */ |
||||||
|
#define EE_VIRTUALADDRESS_TYPE uint16_t /*!< Type of Virtual Address */ |
||||||
|
#define EE_VIRTUALADDRESS_SHIFT 0U /*!< Bits Shifting to get Virtual Address in element */ |
||||||
|
#define EE_CRC_TYPE uint16_t /*!< Type of Crc */ |
||||||
|
#define EE_CRC_SHIFT 16U /*!< Bits Shifting to get Crc in element */ |
||||||
|
#define EE_DATA_TYPE uint32_t /*!< Type of Data */ |
||||||
|
#define EE_DATA_SHIFT 32U /*!< Bits Shifting to get Data value in element */ |
||||||
|
#define EE_MASK_VIRTUALADDRESS (uint64_t)0x000000000000FFFFU |
||||||
|
#define EE_MASK_CRC (uint64_t)0x00000000FFFF0000U |
||||||
|
#define EE_MASK_DATA (uint64_t)0xFFFFFFFF00000000U |
||||||
|
#define EE_MASK_FULL (uint64_t)0xFFFFFFFFFFFFFFFFU |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Private macro -------------------------------------------------------------*/ |
||||||
|
/** @addtogroup EEPROM_Private_Macros
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/** @defgroup Macros_Flash Macros to access flash
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
/* Private functions ---------------------------------------------------------*/ |
||||||
|
/** @addtogroup EEPROM_Private_Functions
|
||||||
|
* @{ |
||||||
|
*/ |
||||||
|
#ifdef DUALCORE_FLASH_SHARING |
||||||
|
EE_Status FI_WriteDoubleWord(uint32_t Address, uint64_t Data, EE_Write_type Write_type); |
||||||
|
#else |
||||||
|
HAL_StatusTypeDef FI_WriteDoubleWord(uint32_t Address, uint64_t Data); |
||||||
|
#endif |
||||||
|
EE_Status FI_PageErase(uint32_t Page, uint16_t NbPages); |
||||||
|
EE_Status FI_PageErase_IT(uint32_t Page, uint16_t NbPages); |
||||||
|
EE_Status FI_DeleteCorruptedFlashAddress(uint32_t Address); |
||||||
|
EE_Status FI_CheckBankConfig(void); |
||||||
|
void FI_CacheFlush(void); |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifdef __cplusplus |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
/**
|
||||||
|
* @} |
||||||
|
*/ |
||||||
|
|
||||||
|
#endif /* __FLASH_INTERFACE_H */ |
||||||
|
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
File diff suppressed because it is too large
Load Diff
@ -1,44 +0,0 @@ |
|||||||
//
|
|
||||||
// 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
|
|
Loading…
Reference in new issue