129template <
class SectorLookup>
class Stm32Flash :
public SectorLookup {
131 template <
typename... Args>
133 : SectorLookup(std::forward<Args>(args)...)
136void read(uint32_t addr, uint32_t size, uint8_t *dst)
138 memcpy(dst, (
void *)addr, size);
141void write(uint32_t addr, uint32_t size, uint8_t *src)
151 if ((addr % 4) && ((addr % 4) + size) < 4)
155 ww.data_word = 0xFFFFFFFF;
157 memcpy(ww.data + (addr % 4), src, size);
158 ww.data_word &= *((uint32_t*)(addr & (~0x3)));
161 FLASH_TYPEPROGRAM_WORD, addr & (~0x3), ww.data_word));
167 int misaligned = (addr + size) % 4;
172 ww.data_word = 0xFFFFFFFF;
174 memcpy(&ww.data_word, src + size - misaligned, misaligned);
175 ww.data_word &= *((uint32_t*)((addr + size) & (~0x3)));
178 FLASH_TYPEPROGRAM_WORD, (addr + size) & (~0x3), ww.data_word));
183 misaligned = addr % 4;
184 if (size && misaligned != 0)
188 ww.data_word = 0xFFFFFFFF;
190 memcpy(ww.data + misaligned, src, 4 - misaligned);
191 ww.data_word &= *((uint32_t*)(addr & (~0x3)));
194 FLASH_TYPEPROGRAM_WORD, addr & (~0x3), ww.data_word));
195 addr += 4 - misaligned;
196 size -= 4 - misaligned;
197 src += 4 - misaligned;
206 uint8_t *flash = (uint8_t *)addr;
207 for (uint32_t i = 0; i < size; i += 4)
209 src[i + 0] &= flash[i + 0];
210 src[i + 1] &= flash[i + 1];
211 src[i + 2] &= flash[i + 2];
212 src[i + 3] &= flash[i + 3];
214 HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, addr + i,
215 *(
unsigned long *)(src + i)));
222void erase(uint32_t addr, uint32_t size)
224 FLASH_EraseInitTypeDef erase_init;
225 memset(&erase_init, 0,
sizeof(erase_init));
227 erase_init.TypeErase = TYPEERASE_SECTORS;
229 auto sa = this->lookup_sector(addr);
231 erase_init.Sector = sa.first;
237 sa = this->lookup_sector(sa.second + 1);
238 }
while (sa.second < addr + size);
240 HASSERT(sa.second == addr + size || sa.second == FLASH_EOF);
242 erase_init.NbSectors = count;
243 erase_init.VoltageRange = FLASH_VOLTAGE_RANGE_3;
245 uint32_t sector_error;
246 HASSERT(HAL_OK == HAL_FLASHEx_Erase(&erase_init, §or_error));