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.
 
static void intFlashSetPVD ()
 
static bool intFlashGetPVDStatus ()
 
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 319 of file flash_int.cpp.

319 {
320 /* For efficiency, compare flashdata_t values as much as possible,
321 * then, fallback to byte per byte comparison. */
322 while (size >= sizeof(flashdata_t)) {
323 if (*(volatile flashdata_t*) address != *(flashdata_t*) buffer)
324 return FALSE;
325 address += sizeof(flashdata_t);
326 buffer += sizeof(flashdata_t);
327 size -= sizeof(flashdata_t);
328 }
329 while (size > 0) {
330 if (*(volatile char*) address != *buffer)
331 return FALSE;
332 ++address;
333 ++buffer;
334 --size;
335 }
336
337 return TRUE;
338}
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:64
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 279 of file flash_int.cpp.

279 {
280 flashaddr_t endAddress = address + size - 1;
281 while (address <= endAddress) {
282 flashsector_t sector = intFlashSectorAt(address);
283 int err = intFlashSectorErase(sector);
284 if (err != FLASH_RETURN_SUCCESS)
285 return err;
286 address = intFlashSectorEnd(sector);
287 }
288
290}
uintptr_t flashaddr_t
Address in the flash memory.
Definition flash_int.h:111
uint8_t flashsector_t
Index of a sector.
Definition flash_int.h:114
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:

◆ intFlashGetPVDStatus()

static bool intFlashGetPVDStatus ( )
static

Definition at line 270 of file flash_int.cpp.

270 {
271 /* Return true if Vdd is higher then selected threshold */
272#if defined(STM32F4XX)
273 return !(PWR->CSR & PWR_CSR_PVDO);
274#else
275 return !(PWR->CSR1 & PWR_CSR1_PVDO);
276#endif
277}

Referenced by intFlashWrite().

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 292 of file flash_int.cpp.

292 {
293#if CORTEX_MODEL == 7
294 // If we have a cache, invalidate the relevant cache lines.
295 // They may still contain old data, leading us to believe that the
296 // flash erase failed.
297 SCB_InvalidateDCache_by_Addr((uint32_t*)address, size);
298#endif
299
300 /* Check for default set bits in the flash memory
301 * For efficiency, compare flashdata_t values as much as possible,
302 * then, fallback to byte per byte comparison. */
303 while (size >= sizeof(flashdata_t)) {
304 if (*(volatile flashdata_t*) address != (flashdata_t) (-1)) // flashdata_t being unsigned, -1 is 0xFF..FF
305 return false;
306 address += sizeof(flashdata_t);
307 size -= sizeof(flashdata_t);
308 }
309 while (size > 0) {
310 if (*(char*) address != 0xFF)
311 return false;
312 ++address;
313 --size;
314 }
315
316 return TRUE;
317}

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 340 of file flash_int.cpp.

340 {
341#if CORTEX_MODEL == 7
342 // If we have a cache, invalidate the relevant cache lines.
343 // They may still contain old data, leading us to read invalid data.
344 SCB_InvalidateDCache_by_Addr((uint32_t*)source, size);
345#endif
346
347 memcpy(destination, (char*) source, size);
349}

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:242

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:

◆ intFlashSetPVD()

static void intFlashSetPVD ( )
static

Definition at line 251 of file flash_int.cpp.

251 {
252#if defined(STM32F4XX)
253 /* Set threshold */
254 PWR->CR = (PWR->CR & ~PWR_CR_PLS_Msk) | PWR_CR_PLS_VALUE;
255 /* Enable PVD */
256 PWR->CR |= PWR_CR_PVDE;
257#elif defined(STM32F7XX)
258 /* Set threshold */
259 PWR->CR1 = (PWR->CR1 & ~PWR_CR1_PLS_Msk) | PWR_CR1_PLS_VALUE;
260 /* Enable PVD */
261 PWR->CR1 |= PWR_CR1_PVDE;
262#elif defined(STM32H7XX)
263 /* Set threshold */
264 PWR->CR1 = (PWR->CR1 & ~PWR_CR1_PLS_Msk) | PWR_CR1_PLS_VALUE;
265 /* Enable PVD */
266 PWR->CR1 |= PWR_CR1_PVDEN;
267#endif
268}

Referenced by intFlashWrite().

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 352 of file flash_int.cpp.

352 {
354 if (!intFlashGetPVDStatus()) {
355 return FLASH_RETURN_LOWVOLTAGEERROR;
356 }
357
358 /* Unlock flash for write access */
359 if (intFlashUnlock() == HAL_FAILED)
360 return FLASH_RETURN_NO_PERMISSION;
361
362 /* Wait for any busy flags */
363 intFlashWaitWhileBusy();
364
365 /* Setup parallelism before program */
366 FLASH_CR &= ~FLASH_CR_PSIZE_MASK;
367 FLASH_CR |= FLASH_CR_PSIZE_VALUE;
368
369 // Round up to the next number of full 32 byte words
370 size_t flashWordCount = (size - 1) / 32 + 1;
371
372 // Read units of flashdata_t from the buffer, writing to flash
373 const flashdata_t* pRead = (const flashdata_t*)buffer;
374 flashdata_t* pWrite = (flashdata_t*)address;
375
376 for (size_t word = 0; word < flashWordCount; word++) {
377 if (!intFlashGetPVDStatus()) {
378 intFlashLock();
379 return FLASH_RETURN_LOWVOLTAGEERROR;
380 }
381
382 /* Enter flash programming mode */
383 FLASH_CR |= FLASH_CR_PG;
384
385 // Flush pipelines
386 __ISB();
387 __DSB();
388
389 static_assert(sizeof(*pWrite) == 4, "Driver supports only 32bit PSIZE");
390
391 // Write 32 bytes/256bits
392 for (size_t i = 0; i < 8; i++) {
393 *pWrite++ = *pRead++;
394 }
395
396 // Flush pipelines
397 __ISB();
398 __DSB();
399
400 /* Wait for completion */
401 intFlashWaitWhileBusy();
402
403 /* Exit flash programming mode */
404 FLASH_CR &= ~FLASH_CR_PG;
405
406 // Flush pipelines
407 __ISB();
408 __DSB();
409 }
410
411 /* Lock flash again */
412 intFlashLock();
413
415}
static bool intFlashGetPVDStatus()
static void intFlashSetPVD()

Referenced by backupInit(), backupRamFlush(), FlashBufferFlush(), 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 418 of file flash_int.cpp.

418 {
419 /* Clearing error status bits.*/
421
422 /* Enter flash programming mode */
423 FLASH->CR |= FLASH_CR_PG;
424
425 /* Write the data */
426 *(flashdata_t*) address = data;
427
428 // Cortex-M7 (STM32F7/H7) can execute out order - need to force a full flush
429 // so that we actually wait for the operation to complete!
430#if CORTEX_MODEL == 7
431 __DSB();
432#endif
433
434 /* Wait for completion */
435 intFlashWaitWhileBusy();
436
437 /* Exit flash programming mode */
438 FLASH->CR &= ~FLASH_CR_PG;
439
440 return intFlashCheckErrors();
441}

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.