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

73 {
74 uint32_t sr = FLASH_SR;
75
76#ifdef FLASH_SR_OPERR
77 if (sr & FLASH_SR_OPERR)
78 return FLASH_RETURN_OPERROR;
79#endif
80 if (sr & FLASH_SR_WRPERR)
81 return FLASH_RETURN_WPERROR;
82#ifdef FLASH_SR_PGAERR
83 if (sr & FLASH_SR_PGAERR)
84 return FLASH_RETURN_ALIGNERROR;
85#endif
86#ifdef FLASH_SR_PGPERR
87 if (sr & FLASH_SR_PGPERR)
88 return FLASH_RETURN_PPARALLERROR;
89#endif
90#ifdef FLASH_SR_ERSERR
91 if (sr & FLASH_SR_ERSERR)
92 return FLASH_RETURN_ESEQERROR;
93#endif
94#ifdef FLASH_SR_PGSERR
95 if (sr & FLASH_SR_PGSERR)
96 return FLASH_RETURN_PSEQERROR;
97#endif
98
100}
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 65 of file flash_int.cpp.

65 {
66#ifdef STM32H7XX
67 FLASH->CCR2 = 0xffffffff;
68#else
69 FLASH_SR = 0x0000ffff;
70#endif
71}

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

258 {
259 /* For efficiency, compare flashdata_t values as much as possible,
260 * then, fallback to byte per byte comparison. */
261 while (size >= sizeof(flashdata_t)) {
262 if (*(volatile flashdata_t*) address != *(flashdata_t*) buffer)
263 return FALSE;
264 address += sizeof(flashdata_t);
265 buffer += sizeof(flashdata_t);
266 size -= sizeof(flashdata_t);
267 }
268 while (size > 0) {
269 if (*(volatile char*) address != *buffer)
270 return FALSE;
271 ++address;
272 ++buffer;
273 --size;
274 }
275
276 return TRUE;
277}
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:54
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 218 of file flash_int.cpp.

218 {
219 flashaddr_t endAddress = address + size - 1;
220 while (address <= endAddress) {
221 flashsector_t sector = intFlashSectorAt(address);
222 int err = intFlashSectorErase(sector);
223 if (err != FLASH_RETURN_SUCCESS)
224 return err;
225 address = intFlashSectorEnd(sector);
226 }
227
229}
uintptr_t flashaddr_t
Address in the flash memory.
Definition flash_int.h:86
uint8_t flashsector_t
Index of a sector.
Definition flash_int.h:89
flashsector_t intFlashSectorAt(flashaddr_t address)
Definition flash_int.cpp:58
static int intFlashSectorErase(flashsector_t sector)
Erase the flash sector.
flashaddr_t intFlashSectorEnd(flashsector_t sector)
Definition flash_int.cpp:54

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

231 {
232#if CORTEX_MODEL == 7
233 // If we have a cache, invalidate the relevant cache lines.
234 // They may still contain old data, leading us to believe that the
235 // flash erase failed.
236 SCB_InvalidateDCache_by_Addr((uint32_t*)address, size);
237#endif
238
239 /* Check for default set bits in the flash memory
240 * For efficiency, compare flashdata_t values as much as possible,
241 * then, fallback to byte per byte comparison. */
242 while (size >= sizeof(flashdata_t)) {
243 if (*(volatile flashdata_t*) address != (flashdata_t) (-1)) // flashdata_t being unsigned, -1 is 0xFF..FF
244 return false;
245 address += sizeof(flashdata_t);
246 size -= sizeof(flashdata_t);
247 }
248 while (size > 0) {
249 if (*(char*) address != 0xFF)
250 return false;
251 ++address;
252 --size;
253 }
254
255 return TRUE;
256}

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

279 {
280#if CORTEX_MODEL == 7
281 // If we have a cache, invalidate the relevant cache lines.
282 // They may still contain old data, leading us to read invalid data.
283 SCB_InvalidateDCache_by_Addr((uint32_t*)source, size);
284#endif
285
286 memcpy(destination, (char*) source, size);
288}

Referenced by backupInit().

Here is the caller graph for this function:

◆ intFlashSectorAt()

flashsector_t intFlashSectorAt ( flashaddr_t  address)

Definition at line 58 of file flash_int.cpp.

58 {
59 flashsector_t sector = 0;
60 while (address >= intFlashSectorEnd(sector))
61 ++sector;
62 return sector;
63}

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

45 {
46 flashaddr_t address = FLASH_BASE;
47 while (sector > 0) {
48 --sector;
49 address += flashSectorSize(sector);
50 }
51 return address;
52}
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 54 of file flash_int.cpp.

54 {
55 return intFlashSectorBegin(sector + 1);
56}
flashaddr_t intFlashSectorBegin(flashsector_t sector)
Definition flash_int.cpp:45

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

148 {
149 int ret;
150 uint8_t sectorRegIdx = sector;
151#ifdef STM32F7XX
152 // On dual bank STM32F7, sector index doesn't match register value.
153 // High bit indicates bank, low 4 bits indicate sector within bank.
154 // Since each bank has 12 sectors, increment second-bank sector idx
155 // by 4 so that the first sector of the second bank (12) ends up with
156 // index 16 (0b10000)
157 if (isDualBank() && sectorRegIdx >= 12) {
158 sectorRegIdx -= 12;
159 /* bit 4 defines bank.
160 * Sectors starting from 12 are in bank #2 */
161 sectorRegIdx |= 0x10;
162 }
163#endif
164
165 /* Unlock flash for write access */
166 if (intFlashUnlock() == HAL_FAILED)
167 return FLASH_RETURN_NO_PERMISSION;
168
169 /* Wait for any busy flags. */
170 intFlashWaitWhileBusy();
171
172 /* Clearing error status bits.*/
174
175 /* Setup parallelism before any program/erase */
176 FLASH_CR &= ~FLASH_CR_PSIZE_MASK;
177 FLASH_CR |= FLASH_CR_PSIZE_VALUE;
178
179 /* Start deletion of sector.
180 * SNB(4:1) is defined as:
181 * 00000 sector 0
182 * 00001 sector 1
183 * ...
184 * 01011 sector 11 (the end of 1st bank, 1Mb border)
185 * 10000 sector 12 (start of 2nd bank)
186 * ...
187 * 11011 sector 23 (the end of 2nd bank, 2Mb border)
188 * others not allowed */
189 FLASH_CR &= ~FLASH_CR_SNB_Msk;
190 FLASH_CR |= (sectorRegIdx << FLASH_CR_SNB_Pos) & FLASH_CR_SNB_Msk;
191 /* sector erase */
192 FLASH_CR |= FLASH_CR_SER;
193 /* start erase operation */
194 FLASH_CR |= FLASH_CR_STRT;
195
196 /* Wait until it's finished. */
197 intFlashWaitWhileBusy();
198
199 /* Sector erase flag does not clear automatically. */
200 FLASH_CR &= ~FLASH_CR_SER;
201
202 /* Lock flash again */
203 intFlashLock()
204 ;
205
206 ret = intFlashCheckErrors();
207 if (ret != FLASH_RETURN_SUCCESS)
208 return ret;
209
210 /* Check deleted sector for errors */
211 if (intFlashIsErased(intFlashSectorBegin(sector), flashSectorSize(sector)) == FALSE)
212 return FLASH_RETURN_BAD_FLASH; /* Sector is not empty despite the erase cycle! */
213
214 /* Successfully deleted sector */
216}
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:73
static void intFlashClearErrors()
Definition flash_int.cpp:65
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 107 of file flash_int.cpp.

107 {
108 /* Check if unlock is really needed */
109 if (!(FLASH_CR & FLASH_CR_LOCK))
110 return HAL_SUCCESS;
111
112 /* Write magic unlock sequence */
113 FLASH_KEYR = 0x45670123;
114 FLASH_KEYR = 0xCDEF89AB;
115
116 /* Check if unlock was successful */
117 if (FLASH_CR & FLASH_CR_LOCK)
118 return HAL_FAILED;
119 return HAL_SUCCESS;
120}

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

291 {
292 /* Unlock flash for write access */
293 if (intFlashUnlock() == HAL_FAILED)
294 return FLASH_RETURN_NO_PERMISSION;
295
296 /* Wait for any busy flags */
297 intFlashWaitWhileBusy();
298
299 /* Setup parallelism before program */
300 FLASH_CR &= ~FLASH_CR_PSIZE_MASK;
301 FLASH_CR |= FLASH_CR_PSIZE_VALUE;
302
303 // Round up to the next number of full 32 byte words
304 size_t flashWordCount = (size - 1) / 32 + 1;
305
306 // Read units of flashdata_t from the buffer, writing to flash
307 const flashdata_t* pRead = (const flashdata_t*)buffer;
308 flashdata_t* pWrite = (flashdata_t*)address;
309
310 for (size_t word = 0; word < flashWordCount; word++) {
311 /* Enter flash programming mode */
312 FLASH_CR |= FLASH_CR_PG;
313
314 // Flush pipelines
315 __ISB();
316 __DSB();
317
318 // Write 32 bytes
319 for (size_t i = 0; i < 8; i++) {
320 *pWrite++ = *pRead++;
321 }
322
323 // Flush pipelines
324 __ISB();
325 __DSB();
326
327 /* Wait for completion */
328 intFlashWaitWhileBusy();
329
330 /* Exit flash programming mode */
331 FLASH_CR &= ~FLASH_CR_PG;
332
333 // Flush pipelines
334 __ISB();
335 __DSB();
336 }
337
338 /* Lock flash again */
339 intFlashLock();
340
342}

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

345 {
346 /* Clearing error status bits.*/
348
349 /* Enter flash programming mode */
350 FLASH->CR |= FLASH_CR_PG;
351
352 /* Write the data */
353 *(flashdata_t*) address = data;
354
355 // Cortex-M7 (STM32F7/H7) can execute out order - need to force a full flush
356 // so that we actually wait for the operation to complete!
357#if CORTEX_MODEL == 7
358 __DSB();
359#endif
360
361 /* Wait for completion */
362 intFlashWaitWhileBusy();
363
364 /* Exit flash programming mode */
365 FLASH->CR &= ~FLASH_CR_PG;
366
367 return intFlashCheckErrors();
368}

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

128 {
129#ifdef FLASH_OPTCR_nDBANK
130 // cleared bit indicates dual bank
131 return (FLASH->OPTCR & FLASH_OPTCR_nDBANK) == 0;
132#else
133 return 0;
134#endif
135}

Referenced by intFlashSectorErase().

Here is the caller graph for this function:

Go to the source code of this file.