LCM — CH32V003 Light Control Module
Light Control Module, I2C slave
Loading...
Searching...
No Matches
user_data.h
Go to the documentation of this file.
1/********************************** (C) COPYRIGHT *******************************
2 * File Name : user_data.h
3 * Description : Интерфейс доступа к энергонезависимой «пользовательской»
4 * памяти CH32V003F4P6.
5 *
6 * Аппаратная область: User Option Bytes, 64 байта по адресу 0x1FFFF800.
7 * Данные сохраняются при отключении питания (во flash option page).
8 *
9 * Важно (ограничения железа):
10 * — Страница 64 байта, но первые 16 байт заняты служебными option bytes
11 * (защита чтения/записи, USER, Data0/1, WRPR0/1).
12 * — Каждый сохраняемый байт занимает 16-битное слово: младший байт = данные,
13 * старший = побитовая инверсия (контроль целостности при загрузке).
14 * — Запись возможна только после стирания всей 64-байтной страницы целиком.
15 *
16 * Полезная ёмкость для приложения: USER_DATA_CAPACITY (26 байт).
17 * Официально WCH выделяет Data0 и Data1 (2 байта); остальное — «Reserved»
18 * в зоне 0x1FFFF80C…0x1FFFF83F, используется по той же схеме data/~data.
19 *
20 * Рекомендуемый порядок работы:
21 * UserData_Init() → Read/Write в RAM-кэш → UserData_Commit().
22 *********************************************************************************/
23
24#ifndef __USER_DATA_H
25#define __USER_DATA_H
26
27#include <stdint.h>
28#include <stddef.h>
29
30/* Базовый адрес 64-байтной страницы User Option Bytes в памяти. */
31#define USER_DATA_FLASH_BASE ((uint32_t)0x1FFFF800U)
32
33/* Размер всей аппаратной страницы (байт). */
34#define USER_DATA_FLASH_PAGE_SIZE 64U
35
36/* Доступный объём пользовательских данных (байт полезной нагрузки). */
37#define USER_DATA_CAPACITY 26U
38
39/* Смещения в логическом массиве пользователя (индексы 0…25). */
40#define USER_DATA_OFF_DATA0 0U /* официальный байт Data0 */
41#define USER_DATA_OFF_DATA1 1U /* официальный байт Data1 */
42#define USER_DATA_OFF_EXT_BASE 2U /* начало расширенной области (Reserved) */
43
44typedef enum {
45 USER_DATA_OK = 0, /* операция успешна */
46 USER_DATA_ERR_PARAM, /* NULL-указатель или некорректный параметр */
47 USER_DATA_ERR_RANGE, /* offset/len выходят за USER_DATA_CAPACITY */
48 USER_DATA_ERR_FLASH, /* ошибка программирования/стирания flash */
49 USER_DATA_ERR_BUSY /* flash занят (редко, при вложенных вызовах) */
51
52/*********************************************************************
53 * @fn UserData_Init
54 *
55 * @brief Загрузить содержимое энергонезависимой области в RAM-кэш.
56 *
57 * @details Вызывать один раз при старте (до Read/Write). Чтение из flash
58 * не требует разблокировки. Проверяется целостность полей data/~data
59 * в option page; при сбое кэш заполняется 0xFF (как после erase).
60 * После Init можно работать с кэшем; запись во flash — Commit().
61 *
62 * @return USER_DATA_OK — загрузка успешна;
63 * USER_DATA_ERR_BUSY — flash занят (BSY);
64 * USER_DATA_ERR_FLASH — повреждены option bytes (несовпадение data/~data).
65 */
67
68/*********************************************************************
69 * @fn UserData_Capacity
70 *
71 * @brief Вернуть размер доступной пользовательской области (26).
72 */
73uint8_t UserData_Capacity(void);
74
75/*********************************************************************
76 * @fn UserData_Read
77 *
78 * @brief Прочитать len байт из RAM-кэша, начиная с offset.
79 *
80 * @param offset — смещение 0 … USER_DATA_CAPACITY-1.
81 * @param buf — буфер приёмника.
82 * @param len — число байт для чтения.
83 */
84UserData_Status UserData_Read(uint8_t offset, uint8_t *buf, uint8_t len);
85
86/*********************************************************************
87 * @fn UserData_Write
88 *
89 * @brief Записать len байт в RAM-кэш (не во flash!).
90 *
91 * @details Помечает кэш «грязным»; для сохранения после сброса питания
92 * вызвать UserData_Commit().
93 */
94UserData_Status UserData_Write(uint8_t offset, const uint8_t *buf, uint8_t len);
95
96/*********************************************************************
97 * @fn UserData_ReadByte / UserData_WriteByte
98 *
99 * @brief Чтение/запись одного байта по индексу в кэше.
100 */
101UserData_Status UserData_ReadByte(uint8_t offset, uint8_t *value);
102UserData_Status UserData_WriteByte(uint8_t offset, uint8_t value);
103
104/*********************************************************************
105 * @fn UserData_Fill
106 *
107 * @brief Заполнить диапазон кэша одним значением (например 0xFF).
108 */
109UserData_Status UserData_Fill(uint8_t offset, uint8_t len, uint8_t value);
110
111/*********************************************************************
112 * @fn UserData_Erase
113 *
114 * @brief Установить весь пользовательский кэш в 0xFF (логическое «стирание»).
115 *
116 * @details Во flash изменения появятся только после Commit.
117 */
119
120/*********************************************************************
121 * @fn UserData_Commit
122 *
123 * @brief Записать RAM-кэш в User Option Bytes (flash).
124 *
125 * @details Алгоритм:
126 * 1) Сохранить служебные option bytes (RDPR, USER, WRPR*).
127 * 2) Стереть всю 64-байтную страницу.
128 * 3) Восстановить служебные байты и записать пользовательские.
129 *
130 * Операция занимает несколько миллисекунд; не вызывать из ISR.
131 * При ошибке flash служебные байты восстанавливаются из снимка,
132 * сделанного перед стиранием.
133 *
134 * @return USER_DATA_OK если не было изменений или запись успешна.
135 */
137
138/*********************************************************************
139 * @fn UserData_IsDirty
140 *
141 * @brief true, если кэш изменён и не сохранён в flash.
142 */
143uint8_t UserData_IsDirty(void);
144
145/*********************************************************************
146 * @fn UserData_Buffer
147 *
148 * @brief Прямой доступ к RAM-кэшу (USER_DATA_CAPACITY байт).
149 *
150 * @details Любая модификация через указатель помечает кэш «грязным».
151 * Не выходить за границы массива.
152 */
153uint8_t *UserData_Buffer(void);
154const uint8_t *UserData_ConstBuffer(void);
155
156/*********************************************************************
157 * @fn UserData_ReadFlashPageRaw
158 *
159 * @brief Прочитать всю 64-байтную страницу option bytes «как в silicon».
160 *
161 * @param page — буфер не менее USER_DATA_FLASH_PAGE_SIZE байт.
162 *
163 * @details Для отладки/диагностики. В page будут и служебные, и пользовательские
164 * байты с инверсными половинами слов.
165 */
167
168#endif /* __USER_DATA_H */
UserData_Status UserData_Write(uint8_t offset, const uint8_t *buf, uint8_t len)
Definition user_data.c:509
uint8_t UserData_Capacity(void)
Definition user_data.c:458
UserData_Status UserData_Commit(void)
Definition user_data.c:355
uint8_t * UserData_Buffer(void)
Definition user_data.c:572
UserData_Status UserData_Init(void)
Definition user_data.c:437
UserData_Status UserData_Fill(uint8_t offset, uint8_t len, uint8_t value)
Definition user_data.c:544
UserData_Status UserData_Erase(void)
Definition user_data.c:562
uint8_t UserData_IsDirty(void)
Definition user_data.c:567
UserData_Status UserData_ReadByte(uint8_t offset, uint8_t *value)
Definition user_data.c:531
UserData_Status UserData_Read(uint8_t offset, uint8_t *buf, uint8_t len)
Definition user_data.c:488
UserData_Status
Definition user_data.h:44
@ USER_DATA_ERR_PARAM
Definition user_data.h:46
@ USER_DATA_OK
Definition user_data.h:45
@ USER_DATA_ERR_BUSY
Definition user_data.h:49
@ USER_DATA_ERR_RANGE
Definition user_data.h:47
@ USER_DATA_ERR_FLASH
Definition user_data.h:48
UserData_Status UserData_WriteByte(uint8_t offset, uint8_t value)
Definition user_data.c:539
const uint8_t * UserData_ConstBuffer(void)
Definition user_data.c:577
UserData_Status UserData_ReadFlashPageRaw(uint8_t *page)
Definition user_data.c:582