rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
Functions
flash_int.cpp File Reference

Detailed Description

Lower-level code related to internal flash memory.

http://www.chibios.com/forum/viewtopic.php?f=8&t=820 https://github.com/tegesoft/flash-stm32f407

Definition in file flash_int.cpp.

Functions

flashaddr_t intFlashSectorBegin (flashsector_t sector)
 
flashaddr_t intFlashSectorEnd (flashsector_t sector)
 
flashsector_t intFlashSectorAt (flashaddr_t address)
 
static void intFlashClearErrors ()
 
static int intFlashCheckErrors ()
 
static bool intFlashUnlock (void)
 Unlock the flash memory for write access.
 
static bool isDualBank (void)
 
static int intFlashSectorErase (flashsector_t sector)
 Erase the flash sector.
 
int intFlashErase (flashaddr_t address, size_t size)
 Erase the sectors containing the span of size bytes starting at address.
 
bool intFlashIsErased (flashaddr_t address, size_t size)
 Check if the size bytes of flash memory starting at address are erased.
 
bool intFlashCompare (flashaddr_t address, const char *buffer, size_t size)
 Check if the data in buffer are identical to the one in flash memory.
 
int intFlashRead (flashaddr_t source, char *destination, size_t size)
 Copy data from the flash memory to a destination.
 
int intFlashWrite (flashaddr_t address, const char *buffer, size_t size)
 Copy data from a buffer to the flash memory.
 
static int intFlashWriteData (flashaddr_t address, const flashdata_t data)
 

Function Documentation

◆ intFlashCheckErrors()

static int intFlashCheckErrors ( )
static

Definition at line 89 of file flash_int.cpp.

89 {
90 uint32_t sr = FLASH_SR;
91
92#ifdef FLASH_SR_OPERR
93 if (sr & FLASH_SR_OPERR)
94 return FLASH_RETURN_OPERROR;
95#endif
96 if (sr & FLASH_SR_WRPERR)
97 return FLASH_RETURN_WPERROR;
98#ifdef FLASH_SR_PGAERR
99 if (sr & FLASH_SR_PGAERR)
100 return FLASH_RETURN_ALIGNERROR;
101#endif
102#ifdef FLASH_SR_PGPERR
103 if (sr & FLASH_SR_PGPERR)
104 return FLASH_RETURN_PPARALLERROR;
105#endif
106#ifdef FLASH_SR_ERSERR
107 if (sr & FLASH_SR_ERSERR)
108 return FLASH_RETURN_ESEQERROR;
109#endif
110#ifdef FLASH_SR_PGSERR
111 if (sr & FLASH_SR_PGSERR)
112 return FLASH_RETURN_PSEQERROR;
113#endif
114#ifdef FLASH_SR_RDSERR
115 if (sr & FLASH_SR_RDSERR)
116 return FLASH_RETURN_SECURITYERROR;
117#endif
118#ifdef FLASH_SR_RDPERR
119 if (sr & FLASH_SR_RDPERR)
120 return FLASH_RETURN_SECURITYERROR;
121#endif
122#ifdef FLASH_SR_WRPERR
123 if (sr & FLASH_SR_WRPERR)
124 return FLASH_RETURN_SECURITYERROR;
125#endif
126#ifdef FLASH_SR_CRCRDERR
127 if (sr & FLASH_SR_CRCRDERR)
128 return FLASH_RETURN_CRCERROR;
129#endif
130
132}
return FLASH_RETURN_SUCCESS
Definition flash_int.cpp:80

Referenced by intFlashSectorErase(), and intFlashWriteData().

Here is the caller graph for this function:

◆ intFlashClearErrors()

static void intFlashClearErrors ( )
static

Definition at line 80 of file flash_int.cpp.

80 {
81#ifdef STM32H7XX
82 FLASH_CCR = 0xffffffff;
83#else
84 FLASH_SR = 0x0000ffff;
85#endif
86 __DSB();
87}

Referenced by intFlashSectorErase(), and intFlashWriteData().

Here is the caller graph for this function:

◆ intFlashCompare()

bool intFlashCompare ( flashaddr_t  address,
const char buffer,
size_t  size 
)

Check if the data in buffer are identical to the one in flash memory.

Parameters
addressFirst address in flash memory to be checked.
bufferBuffer containing the data to compare.
sizeSize of buffer in bytes.
Returns
TRUE if the flash memory and the buffer contain identical data.
FALSE if the flash memory and the buffer don't contain identical data.

Definition at line 290 of file flash_int.cpp.

290 {
291 /* For efficiency, compare flashdata_t values as much as possible,
292 * then, fallback to byte per byte comparison. */
293 while (size >= sizeof(flashdata_t)) {
294 if (*(volatile flashdata_t*) address != *(flashdata_t*) buffer)
295 return FALSE;
296 address += sizeof(flashdata_t);
297 buffer += sizeof(flashdata_t);
298 size -= sizeof(flashdata_t);
299 }
300 while (size > 0) {
301 if (*(volatile char*) address != *buffer)
302 return FALSE;
303 ++address;
304 ++buffer;
305 --size;
306 }
307
308 return TRUE;
309}
int size_t size
Definition flash_int.cpp:51
uint32_t flashdata_t
Definition flash_int.cpp:20
uint32_t flashdata_t
Definition flash_int.h:58
static BigBufferHandle buffer

◆ intFlashErase()

int intFlashErase ( flashaddr_t  address,
size_t  size 
)

Erase the sectors containing the span of size bytes starting at address.

Warning
If address doesn't match the beginning of a sector, the data contained between the beginning of the sector and address will be erased too. The same applies for data contained at address + size up to the end of the sector.
Parameters
addressStarting address of the span in flash memory.
sizeSize of the span in bytes.
Returns
FLASH_RETURN_SUCCESS No error erasing the flash memory.
FLASH_RETURN_BAD_FLASH Flash cell error.
FLASH_RETURN_NO_PERMISSION Access denied.

Definition at line 250 of file flash_int.cpp.

250 {
251 flashaddr_t endAddress = address + size - 1;
252 while (address <= endAddress) {
253 flashsector_t sector = intFlashSectorAt(address);
254 int err = intFlashSectorErase(sector);
255 if (err != FLASH_RETURN_SUCCESS)
256 return err;
257 address = intFlashSectorEnd(sector);
258 }
259
261}
uintptr_t flashaddr_t
Address in the flash memory.
Definition flash_int.h:90
uint8_t flashsector_t
Index of a sector.
Definition flash_int.h:93
flashsector_t intFlashSectorAt(flashaddr_t address)
Definition flash_int.cpp:73
static int intFlashSectorErase(flashsector_t sector)
Erase the flash sector.
flashaddr_t intFlashSectorEnd(flashsector_t sector)
Definition flash_int.cpp:69

Referenced by backupRamFlush(), and FlashErase().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ intFlashIsErased()

bool intFlashIsErased ( flashaddr_t  address,
size_t  size 
)

Check if the size bytes of flash memory starting at address are erased.

Note
If the memory is erased, one can write data into it safely.
Parameters
addressFirst address in flash memory to be checked.
sizeSize of the memory space to be checked in bytes.
Returns
TRUE Memory is already erased.
FALSE Memory is not erased.

Definition at line 263 of file flash_int.cpp.

263 {
264#if CORTEX_MODEL == 7
265 // If we have a cache, invalidate the relevant cache lines.
266 // They may still contain old data, leading us to believe that the
267 // flash erase failed.
268 SCB_InvalidateDCache_by_Addr((uint32_t*)address, size);
269#endif
270
271 /* Check for default set bits in the flash memory
272 * For efficiency, compare flashdata_t values as much as possible,
273 * then, fallback to byte per byte comparison. */
274 while (size >= sizeof(flashdata_t)) {
275 if (*(volatile flashdata_t*) address != (flashdata_t) (-1)) // flashdata_t being unsigned, -1 is 0xFF..FF
276 return false;
277 address += sizeof(flashdata_t);
278 size -= sizeof(flashdata_t);
279 }
280 while (size > 0) {
281 if (*(char*) address != 0xFF)
282 return false;
283 ++address;
284 --size;
285 }
286
287 return TRUE;
288}

Referenced by FlashErase(), and FlashVerifyChecksum().

Here is the caller graph for this function:

◆ intFlashRead()

int intFlashRead ( flashaddr_t  source,
char destination,
size_t  size 
)

Copy data from the flash memory to a destination.

Warning
The destination must be at least size bytes long.
Parameters
sourceFirst address of the flash memory to be copied.
destinationBuffer to copy to.
sizeSize of the data to be copied in bytes.
Returns
FLASH_RETURN_SUCCESS if successfully copied.

Definition at line 311 of file flash_int.cpp.

311 {
312#if CORTEX_MODEL == 7
313 // If we have a cache, invalidate the relevant cache lines.
314 // They may still contain old data, leading us to read invalid data.
315 SCB_InvalidateDCache_by_Addr((uint32_t*)source, size);
316#endif
317
318 memcpy(destination, (char*) source, size);
320}

Referenced by backupInit().

Here is the caller graph for this function:

◆ intFlashSectorAt()

flashsector_t intFlashSectorAt ( flashaddr_t  address)

Definition at line 73 of file flash_int.cpp.

73 {
74 flashsector_t sector = 0;
75 while (address >= intFlashSectorEnd(sector))
76 ++sector;
77 return sector;
78}

Referenced by intFlashErase().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ intFlashSectorBegin()

flashaddr_t intFlashSectorBegin ( flashsector_t  sector)

Definition at line 60 of file flash_int.cpp.

60 {
61 flashaddr_t address = FLASH_BASE;
62 while (sector > 0) {
63 --sector;
64 address += flashSectorSize(sector);
65 }
66 return address;
67}
size_t flashSectorSize(flashsector_t sector)
Get the size of sector.
Definition mpu_util.cpp:237

Referenced by intFlashSectorEnd(), and intFlashSectorErase().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ intFlashSectorEnd()

flashaddr_t intFlashSectorEnd ( flashsector_t  sector)

Definition at line 69 of file flash_int.cpp.

69 {
70 return intFlashSectorBegin(sector + 1);
71}
flashaddr_t intFlashSectorBegin(flashsector_t sector)
Definition flash_int.cpp:60

Referenced by intFlashErase(), and intFlashSectorAt().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ intFlashSectorErase()

static int intFlashSectorErase ( flashsector_t  sector)
static

Erase the flash sector.

The sector is checked for errors after erase.

Note
The sector is deleted regardless of its current state.
Parameters
sectorSector which is going to be erased.
Returns
FLASH_RETURN_SUCCESS No error erasing the sector.
FLASH_RETURN_BAD_FLASH Flash cell error.
FLASH_RETURN_NO_PERMISSION Access denied.

Definition at line 180 of file flash_int.cpp.

180 {
181 int ret;
182 uint8_t sectorRegIdx = sector;
183#ifdef STM32F7XX
184 // On dual bank STM32F7, sector index doesn't match register value.
185 // High bit indicates bank, low 4 bits indicate sector within bank.
186 // Since each bank has 12 sectors, increment second-bank sector idx
187 // by 4 so that the first sector of the second bank (12) ends up with
188 // index 16 (0b10000)
189 if (isDualBank() && sectorRegIdx >= 12) {
190 sectorRegIdx -= 12;
191 /* bit 4 defines bank.
192 * Sectors starting from 12 are in bank #2 */
193 sectorRegIdx |= 0x10;
194 }
195#endif
196
197 /* Unlock flash for write access */
198 if (intFlashUnlock() == HAL_FAILED)
199 return FLASH_RETURN_NO_PERMISSION;
200
201 /* Wait for any busy flags. */
202 intFlashWaitWhileBusy();
203
204 /* Clearing error status bits.*/
206
207 /* Setup parallelism before any program/erase */
208 FLASH_CR &= ~FLASH_CR_PSIZE_MASK;
209 FLASH_CR |= FLASH_CR_PSIZE_VALUE;
210
211 /* Start deletion of sector.
212 * SNB(4:1) is defined as:
213 * 00000 sector 0
214 * 00001 sector 1
215 * ...
216 * 01011 sector 11 (the end of 1st bank, 1Mb border)
217 * 10000 sector 12 (start of 2nd bank)
218 * ...
219 * 11011 sector 23 (the end of 2nd bank, 2Mb border)
220 * others not allowed */
221 FLASH_CR &= ~FLASH_CR_SNB_Msk;
222 FLASH_CR |= (sectorRegIdx << FLASH_CR_SNB_Pos) & FLASH_CR_SNB_Msk;
223 /* sector erase */
224 FLASH_CR |= FLASH_CR_SER;
225 /* start erase operation */
226 FLASH_CR |= FLASH_CR_STRT;
227
228 /* Wait until it's finished. */
229 intFlashWaitWhileBusy();
230
231 /* Sector erase flag does not clear automatically. */
232 FLASH_CR &= ~FLASH_CR_SER;
233
234 /* Lock flash again */
235 intFlashLock()
236 ;
237
238 ret = intFlashCheckErrors();
239 if (ret != FLASH_RETURN_SUCCESS)
240 return ret;
241
242 /* Check deleted sector for errors */
243 if (intFlashIsErased(intFlashSectorBegin(sector), flashSectorSize(sector)) == FALSE)
244 return FLASH_RETURN_BAD_FLASH; /* Sector is not empty despite the erase cycle! */
245
246 /* Successfully deleted sector */
248}
bool intFlashIsErased(flashaddr_t address, size_t size)
Check if the size bytes of flash memory starting at address are erased.
Definition flash_int.cpp:89
static bool isDualBank(void)
static int intFlashCheckErrors()
Definition flash_int.cpp:89
static void intFlashClearErrors()
Definition flash_int.cpp:80
static bool intFlashUnlock(void)
Unlock the flash memory for write access.

Referenced by intFlashErase().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ intFlashUnlock()

static bool intFlashUnlock ( void  )
static

Unlock the flash memory for write access.

Returns
HAL_SUCCESS Unlock was successful.
HAL_FAILED Unlock failed.

Definition at line 139 of file flash_int.cpp.

139 {
140 /* Check if unlock is really needed */
141 if (!(FLASH_CR & FLASH_CR_LOCK))
142 return HAL_SUCCESS;
143
144 /* Write magic unlock sequence */
145 FLASH_KEYR = 0x45670123;
146 FLASH_KEYR = 0xCDEF89AB;
147
148 /* Check if unlock was successful */
149 if (FLASH_CR & FLASH_CR_LOCK)
150 return HAL_FAILED;
151 return HAL_SUCCESS;
152}

Referenced by intFlashSectorErase(), and intFlashWrite().

Here is the caller graph for this function:

◆ intFlashWrite()

int intFlashWrite ( flashaddr_t  address,
const char buffer,
size_t  size 
)

Copy data from a buffer to the flash memory.

Warning
The flash memory area receiving the data must be erased.
The buffer must be at least size bytes long.
Parameters
addressFirst address in the flash memory where to copy the data to.
bufferBuffer containing the data to copy.
sizeSize of the data to be copied in bytes.
Returns
FLASH_RETURN_SUCCESS No error.
FLASH_RETURN_NO_PERMISSION Access denied.

Definition at line 323 of file flash_int.cpp.

323 {
324 /* Unlock flash for write access */
325 if (intFlashUnlock() == HAL_FAILED)
326 return FLASH_RETURN_NO_PERMISSION;
327
328 /* Wait for any busy flags */
329 intFlashWaitWhileBusy();
330
331 /* Setup parallelism before program */
332 FLASH_CR &= ~FLASH_CR_PSIZE_MASK;
333 FLASH_CR |= FLASH_CR_PSIZE_VALUE;
334
335 // Round up to the next number of full 32 byte words
336 size_t flashWordCount = (size - 1) / 32 + 1;
337
338 // Read units of flashdata_t from the buffer, writing to flash
339 const flashdata_t* pRead = (const flashdata_t*)buffer;
340 flashdata_t* pWrite = (flashdata_t*)address;
341
342 for (size_t word = 0; word < flashWordCount; word++) {
343 /* Enter flash programming mode */
344 FLASH_CR |= FLASH_CR_PG;
345
346 // Flush pipelines
347 __ISB();
348 __DSB();
349
350 static_assert(sizeof(*pWrite) == 4, "Driver supports only 32bit PSIZE");
351
352 // Write 32 bytes/256bits
353 for (size_t i = 0; i < 8; i++) {
354 *pWrite++ = *pRead++;
355 }
356
357 // Flush pipelines
358 __ISB();
359 __DSB();
360
361 /* Wait for completion */
362 intFlashWaitWhileBusy();
363
364 /* Exit flash programming mode */
365 FLASH_CR &= ~FLASH_CR_PG;
366
367 // Flush pipelines
368 __ISB();
369 __DSB();
370 }
371
372 /* Lock flash again */
373 intFlashLock();
374
376}

Referenced by backupInit(), backupRamFlush(), and FlashWrite().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ intFlashWriteData()

static int intFlashWriteData ( flashaddr_t  address,
const flashdata_t  data 
)
static

Definition at line 379 of file flash_int.cpp.

379 {
380 /* Clearing error status bits.*/
382
383 /* Enter flash programming mode */
384 FLASH->CR |= FLASH_CR_PG;
385
386 /* Write the data */
387 *(flashdata_t*) address = data;
388
389 // Cortex-M7 (STM32F7/H7) can execute out order - need to force a full flush
390 // so that we actually wait for the operation to complete!
391#if CORTEX_MODEL == 7
392 __DSB();
393#endif
394
395 /* Wait for completion */
396 intFlashWaitWhileBusy();
397
398 /* Exit flash programming mode */
399 FLASH->CR &= ~FLASH_CR_PG;
400
401 return intFlashCheckErrors();
402}

Referenced by intFlashWrite().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ isDualBank()

static bool isDualBank ( void  )
static

Definition at line 160 of file flash_int.cpp.

160 {
161#ifdef FLASH_OPTCR_nDBANK
162 // cleared bit indicates dual bank
163 return (FLASH->OPTCR & FLASH_OPTCR_nDBANK) == 0;
164#else
165 return 0;
166#endif
167}

Referenced by intFlashSectorErase().

Here is the caller graph for this function:

Go to the source code of this file.