ACwing FC firmware
STM32WB55: attitude IEKF, altitude Kalman filter, flight core, protocol v2
Loading...
Searching...
No Matches
cfg_flash_wb.c
Go to the documentation of this file.
1
23#include "cfg_store.h"
24#include "main.h"
25#include "cmsis_os2.h"
26#include "hw_conf.h"
27#include <string.h>
28
29#if defined(__has_include)
30#if __has_include("shci.h")
31#include "shci.h"
32#define CFG_HAVE_SHCI 1
33#endif
34#endif
35
36#define CFG_PAGE0_ADDR 0x0807E000u
37#define CFG_PAGE_SIZE 0x1000u
38
39volatile uint8_t g_cpu2_ready; /* set when the wireless stack is running */
40
41const void *cfg_flash_page(int page)
42{
43 if (page < 0 || page >= CFG_PAGES) return NULL;
44 return (const void *)(uintptr_t)(CFG_PAGE0_ADDR + (uint32_t)page * CFG_PAGE_SIZE);
45}
46
47typedef enum { OP_ERASE, OP_PROGRAM } op_t;
48
49static int single_op(op_t op, uint32_t addr, uint64_t dw)
50{
51 for (int attempt = 0; attempt < 2000; ++attempt) { /* ~2 s worst case */
52 while (HAL_HSEM_FastTake(CFG_HW_FLASH_SEMID) != HAL_OK) osDelay(1);
53 HAL_FLASH_Unlock();
54 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
55 HAL_StatusTypeDef st = HAL_BUSY;
56 const uint32_t pm = __get_PRIMASK();
57 __disable_irq();
58 if (!HAL_HSEM_IsSemTaken(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID)) {
59 if (op == OP_ERASE) {
60 FLASH_EraseInitTypeDef e = { .TypeErase = FLASH_TYPEERASE_PAGES,
61 .Page = (addr - FLASH_BASE) / FLASH_PAGE_SIZE,
62 .NbPages = 1 };
63 uint32_t bad = 0;
64 st = HAL_FLASHEx_Erase(&e, &bad);
65 } else {
66 st = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, addr, dw);
67 }
68 }
69 if (!pm) __enable_irq();
70 HAL_FLASH_Lock();
71 HAL_HSEM_Release(CFG_HW_FLASH_SEMID, 0);
72 if (st == HAL_OK) return 0;
73 if (st != HAL_BUSY) return -1; /* real flash error */
74 osDelay(1); /* CPU2 busy: retry */
75 }
76 return -1;
77}
78
79int cfg_flash_write(int page, const void *data, uint32_t len)
80{
81 if (page < 0 || page >= CFG_PAGES || len > CFG_PAGE_SIZE) return -1;
82 const uint32_t base = (uint32_t)(uintptr_t)cfg_flash_page(page);
83 int rc = 0;
84#ifdef CFG_HAVE_SHCI
85 if (g_cpu2_ready) {
86 (void)SHCI_C2_SetFlashActivityControl(FLASH_ACTIVITY_CONTROL_SEM7);
87 (void)SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_ON);
88 }
89#endif
90 rc = single_op(OP_ERASE, base, 0);
91 const uint8_t *p = (const uint8_t *)data;
92 for (uint32_t off = 0; rc == 0 && off < len; off += 8u) {
93 uint64_t dw = 0xFFFFFFFFFFFFFFFFull;
94 memcpy(&dw, p + off, (len - off) < 8u ? (len - off) : 8u);
95 rc = single_op(OP_PROGRAM, base + off, dw);
96 }
97#ifdef CFG_HAVE_SHCI
98 if (g_cpu2_ready) (void)SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_OFF);
99#endif
100 return rc;
101}
#define CFG_PAGE_SIZE
static int single_op(op_t op, uint32_t addr, uint64_t dw)
const void * cfg_flash_page(int page)
memory-mapped page
int cfg_flash_write(int page, const void *data, uint32_t len)
erase + program; 0 = ok
#define CFG_PAGE0_ADDR
volatile uint8_t g_cpu2_ready
op_t
@ OP_PROGRAM
@ OP_ERASE
Persistent configuration: parameters, drone name, calibrations and one backup per calibration type (H...
#define CFG_PAGES
Definition cfg_store.h:55
static uint32_t addr(uint16_t sect)
Definition log_store.c:49
uint32_t off
Definition log_task.c:50
static USBD_StatusTypeDef st(HAL_StatusTypeDef h)
Definition usbd_conf.c:86