libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
LibXR::CH32Flash Class Reference

CH32 闪存驱动实现 / CH32 flash driver implementation. More...

#include <ch32_flash.hpp>

Inheritance diagram for LibXR::CH32Flash:
[legend]
Collaboration diagram for LibXR::CH32Flash:
[legend]

Public Member Functions

 CH32Flash (const FlashSector *sectors, size_t sector_count, size_t start_sector)
 构造闪存对象 / Construct flash object
 
 CH32Flash (const FlashSector *sectors, size_t sector_count)
 构造并使用默认起始扇区 / Construct with default start sector
 
ErrorCode Erase (size_t offset, size_t size) override
 Erases a section of the flash memory. 擦除闪存的指定区域。
 
ErrorCode Write (size_t offset, ConstRawData data) override
 Writes data to the flash memory. 向闪存写入数据。
 
- Public Member Functions inherited from LibXR::Flash
 Flash (size_t min_erase_size, size_t min_write_size, RawData flash_area)
 Constructs a Flash object with specified properties. 构造函数,初始化闪存属性。
 
virtual ErrorCode Read (size_t offset, RawData data)
 Reads data from the flash memory. 从闪存中读取数据。
 
size_t MinEraseSize () const
 Returns the minimum erasable block size in bytes. 获取最小可擦除块大小(字节)。
 
size_t MinWriteSize () const
 Returns the minimum writable block size in bytes. 获取最小可写块大小(字节)。
 
size_t Size () const
 Returns the size of the flash memory area. 获取闪存存储区域的大小。
 

Static Public Member Functions

static constexpr size_t MinWriteSize ()
 最小写入粒度(半字) / Minimum write size (half-word)
 
static constexpr uint32_t PageSize ()
 Page erase size in fast erase mode / 快速擦除页大小
 

Private Member Functions

bool IsInRange (uint32_t addr, size_t size) const
 

Static Private Member Functions

static void ClearFlashFlagsOnce ()
 

Private Attributes

const FlashSectorsectors_
 
uint32_t base_address_
 
size_t sector_count_
 

Detailed Description

CH32 闪存驱动实现 / CH32 flash driver implementation.

Definition at line 23 of file ch32_flash.hpp.

Constructor & Destructor Documentation

◆ CH32Flash() [1/2]

CH32Flash::CH32Flash ( const FlashSector * sectors,
size_t sector_count,
size_t start_sector )

构造闪存对象 / Construct flash object

Definition at line 69 of file ch32_flash.cpp.

70 : Flash(sectors[start_sector - 1].size, MinWriteSize(),
71 {reinterpret_cast<void*>(sectors[start_sector - 1].address),
72 sectors[sector_count - 1].address - sectors[start_sector - 1].address +
73 sectors[sector_count - 1].size}),
74 sectors_(sectors),
75 base_address_(sectors[start_sector - 1].address),
76 sector_count_(sector_count)
77{
78}
static constexpr size_t MinWriteSize()
最小写入粒度(半字) / Minimum write size (half-word)
Flash(size_t min_erase_size, size_t min_write_size, RawData flash_area)
Constructs a Flash object with specified properties. 构造函数,初始化闪存属性。
Definition flash.cpp:5
uint32_t address
扇区起始地址 / Sector base address

◆ CH32Flash() [2/2]

LibXR::CH32Flash::CH32Flash ( const FlashSector * sectors,
size_t sector_count )
inline

构造并使用默认起始扇区 / Construct with default start sector

Definition at line 33 of file ch32_flash.hpp.

34 : CH32Flash(sectors, sector_count, sector_count - 1)
35 {
36 }
CH32Flash(const FlashSector *sectors, size_t sector_count, size_t start_sector)
构造闪存对象 / Construct flash object

Member Function Documentation

◆ ClearFlashFlagsOnce()

void CH32Flash::ClearFlashFlagsOnce ( )
inlinestaticprivate

Definition at line 60 of file ch32_flash.cpp.

61{
62#ifdef FLASH_FLAG_BSY
63 FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_WRPRTERR);
64#else
65 FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_WRPRTERR);
66#endif
67}

◆ Erase()

ErrorCode CH32Flash::Erase ( size_t offset,
size_t size )
overridevirtual

Erases a section of the flash memory. 擦除闪存的指定区域。

Parameters
offsetThe starting offset of the section to erase. 要擦除的起始偏移地址。
sizeThe size of the section to erase. 要擦除的区域大小。
Returns
ErrorCode indicating success or failure. 返回操作结果的错误码。

Implements LibXR::Flash.

Definition at line 80 of file ch32_flash.cpp.

81{
82 if (size == 0)
83 {
84 return ErrorCode::ARG_ERR;
85 }
86
87 ASSERT(SystemCoreClock <= 120000000);
88
89 const uint32_t START_ADDR = base_address_ + static_cast<uint32_t>(offset);
90 if (!IsInRange(START_ADDR, size))
91 {
92 return ErrorCode::OUT_OF_RANGE;
93 }
94 const uint32_t END_ADDR = START_ADDR + static_cast<uint32_t>(size);
95
96 // 1) 退出增强读模式
97 flash_exit_enhanced_read_if_enabled(); // 进入擦写前必须退出 EHMOD
98
99 // 2) 访问时钟降为 SYSCLK/2(SCKMOD=0)
100 flash_set_access_clock_half_sysclk();
101
102 // 3) 解锁:常规 + 快速模式
103 flash_fast_unlock();
104 ClearFlashFlagsOnce();
105
106 // 4) 计算 256B 对齐区间
107 const uint32_t FAST_SZ = 256u;
108 const uint32_t ERASE_BEGIN = START_ADDR & ~(FAST_SZ - 1u);
109 const uint32_t ERASE_END = (END_ADDR + FAST_SZ - 1u) & ~(FAST_SZ - 1u);
110 if (ERASE_END <= ERASE_BEGIN)
111 {
112 flash_fast_lock();
113 flash_set_access_clock_sysclk();
114 return ErrorCode::OK;
115 }
116
117 // 5) 开启快速页擦除:CTLR.FTER=1
118 FLASH->CTLR |= (1u << 17);
119
120 // 6) 逐页(256B)擦除
121 for (uint32_t adr = ERASE_BEGIN; adr < ERASE_END; adr += FAST_SZ)
122 {
123 // 写入页首地址
124 FLASH->ADDR = adr;
125
126 // 触发 STRT
127 FLASH->CTLR |= (1u << 6);
128
129 // 等待 BSY=0
130 if (!flash_wait_busy_clear())
131 {
132 // 关闭 FTER & 复锁 & 还原时钟后返回
133 FLASH->CTLR &= ~(1u << 17);
134 flash_fast_lock();
135 flash_set_access_clock_sysclk();
136 return ErrorCode::FAILED;
137 }
138
139 // 检查错误并清标志
140 if (FLASH->STATR & (1u << 4))
141 { // WRPRTERR
142 FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_WRPRTERR);
143 FLASH->CTLR &= ~(1u << 17);
144 flash_fast_lock();
145 flash_set_access_clock_sysclk();
146 return ErrorCode::FAILED;
147 }
148
149 // 成功:清 EOP
150 FLASH_ClearFlag(FLASH_FLAG_EOP);
151 }
152
153 // 7) 关闭快速页擦除位,复锁快速模式与常规锁,并恢复访问时钟
154 FLASH->CTLR &= ~(1u << 17); // FTER=0
155 flash_fast_lock();
156 flash_set_access_clock_sysclk();
157
158 return ErrorCode::OK;
159}

◆ IsInRange()

bool CH32Flash::IsInRange ( uint32_t addr,
size_t size ) const
private

Definition at line 244 of file ch32_flash.cpp.

245{
246 const uint32_t BEGIN = base_address_;
247 const uint32_t LIMIT =
248 sectors_[sector_count_ - 1].address + sectors_[sector_count_ - 1].size;
249 const uint32_t END = addr + static_cast<uint32_t>(size);
250 return (addr >= BEGIN) && (END <= LIMIT) && (END >= addr);
251}
uint32_t size
扇区大小(字节) / Sector size in bytes

◆ MinWriteSize()

static constexpr size_t LibXR::CH32Flash::MinWriteSize ( )
inlinestaticconstexpr

最小写入粒度(半字) / Minimum write size (half-word)

Definition at line 41 of file ch32_flash.hpp.

◆ PageSize()

static constexpr uint32_t LibXR::CH32Flash::PageSize ( )
inlinestaticconstexpr

Page erase size in fast erase mode / 快速擦除页大小

Definition at line 46 of file ch32_flash.hpp.

◆ Write()

ErrorCode CH32Flash::Write ( size_t offset,
ConstRawData data )
overridevirtual

Writes data to the flash memory. 向闪存写入数据。

Parameters
offsetThe starting offset to write data. 数据写入的起始偏移地址。
dataThe data to be written. 需要写入的数据。
Returns
ErrorCode indicating success or failure. 返回操作结果的错误码。

Implements LibXR::Flash.

Definition at line 161 of file ch32_flash.cpp.

162{
163 ASSERT(SystemCoreClock <= 120000000);
164
165 // 退出增强读模式 → 减少失败风险(手册要求在编程/擦除前退出)
166 flash_exit_enhanced_read_if_enabled();
167
168 // 访问时钟切半(SCKMOD=0)
169 flash_set_access_clock_half_sysclk();
170
171 if (!data.addr_ || data.size_ == 0)
172 {
173 flash_set_access_clock_sysclk();
174 ASSERT(false);
175 return ErrorCode::ARG_ERR;
176 }
177
178 const uint32_t START_ADDR = base_address_ + static_cast<uint32_t>(offset);
179 if (!IsInRange(START_ADDR, data.size_))
180 {
181 flash_set_access_clock_sysclk();
182 ASSERT(false);
183 return ErrorCode::OUT_OF_RANGE;
184 }
185
186 const uint8_t* src = reinterpret_cast<const uint8_t*>(data.addr_);
187 const uint32_t END_ADDR = START_ADDR + static_cast<uint32_t>(data.size_);
188
189 FLASH_Unlock();
190 ClearFlashFlagsOnce();
191
192 const uint32_t HW_BEGIN = START_ADDR & ~1u;
193 const uint32_t HW_END = (END_ADDR + 1u) & ~1u; // 向上取整到半字
194
195 for (uint32_t hw = HW_BEGIN; hw < HW_END; hw += 2u)
196 {
197 volatile uint16_t* p = reinterpret_cast<volatile uint16_t*>(hw);
198 volatile uint16_t orig = *p;
199 volatile uint16_t val = orig;
200
201 if (hw >= START_ADDR && hw < END_ADDR)
202 {
203 uint8_t b0 = src[hw - START_ADDR];
204 val = static_cast<uint16_t>((val & 0xFF00u) | b0);
205 }
206 if ((hw + 1u) >= START_ADDR && (hw + 1u) < END_ADDR)
207 {
208 uint8_t b1 = src[(hw + 1u) - START_ADDR];
209 val = static_cast<uint16_t>((val & 0x00FFu) | (static_cast<uint16_t>(b1) << 8));
210 }
211
212 if (val == orig)
213 {
214 continue; // 无变化
215 }
216
217 // 未擦除单元禁止 0->1 抬位
218 if (((~orig) & val) != 0u && orig != 0xE339u)
219 {
220 FLASH_Lock();
221 flash_set_access_clock_sysclk();
222 ASSERT(false);
223 return ErrorCode::FAILED;
224 }
225
226 if (FLASH_ProgramHalfWord(hw, val) != FLASH_COMPLETE)
227 {
228 FLASH_Lock();
229 flash_set_access_clock_sysclk();
230 ASSERT(false);
231 return ErrorCode::FAILED;
232 }
233
234 ASSERT(*p == val);
235
236 FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_WRPRTERR);
237 }
238
239 FLASH_Lock();
240 flash_set_access_clock_sysclk();
241 return ErrorCode::OK;
242}
size_t size_
数据大小(字节)。 The size of the data (in bytes).
const void * addr_
数据存储地址(常量)。 The storage address of the data (constant).

Field Documentation

◆ base_address_

uint32_t LibXR::CH32Flash::base_address_
private

Definition at line 53 of file ch32_flash.hpp.

◆ sector_count_

size_t LibXR::CH32Flash::sector_count_
private

Definition at line 54 of file ch32_flash.hpp.

◆ sectors_

const FlashSector* LibXR::CH32Flash::sectors_
private

Definition at line 52 of file ch32_flash.hpp.


The documentation for this class was generated from the following files: