1 /*
2  * Copyright (c) 2013-2022 Arm Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "Driver_Flash.h"
18 #include "low_level_flash.h"
19 #include <string.h>
20 #include "cmsis.h"
21 #include "flash_layout.h"
22 #include "stm32hal.h"
23 #include <stdio.h>
24 #include "board.h"
25 
26 #ifndef ARG_UNUSED
27 #define ARG_UNUSED(arg)  ((void)arg)
28 #endif /* ARG_UNUSED */
29 
30 /* config for flash driver */
31 /*
32 #define DEBUG_FLASH_ACCESS
33 #define CHECK_ERASE
34 */
35 
36 /* Driver version */
37 #define ARM_FLASH_DRV_VERSION   ARM_DRIVER_VERSION_MAJOR_MINOR(1, 0)
38 
39 static const ARM_DRIVER_VERSION DriverVersion =
40 {
41   ARM_FLASH_API_VERSION,  /* Defined in the CMSIS Flash Driver header file */
42   ARM_FLASH_DRV_VERSION
43 };
44 
45 /**
46   * \brief Flash driver capability macro definitions \ref ARM_FLASH_CAPABILITIES
47   */
48 /* Flash Ready event generation capability values */
49 #define EVENT_READY_NOT_AVAILABLE   (0u)
50 #define EVENT_READY_AVAILABLE       (1u)
51 /* Data access size values */
52 #define DATA_WIDTH_8BIT             (0u)
53 #define DATA_WIDTH_16BIT            (1u)
54 #define DATA_WIDTH_32BIT            (2u)
55 /* Chip erase capability values */
56 #define CHIP_ERASE_NOT_SUPPORTED    (0u)
57 #define CHIP_ERASE_SUPPORTED        (1u)
58 
59 /* Driver Capabilities */
60 static const ARM_FLASH_CAPABILITIES DriverCapabilities =
61 {
62   EVENT_READY_NOT_AVAILABLE,
63   DATA_WIDTH_32BIT,
64   CHIP_ERASE_SUPPORTED
65 };
66 
67 static const uint32_t data_width_byte[] = {
68     sizeof(uint8_t),
69     sizeof(uint16_t),
70     sizeof(uint32_t),
71 };
72 
73 /**
74   * \brief Flash status macro definitions \ref ARM_FLASH_STATUS
75   */
76 /* Busy status values of the Flash driver  */
77 #define DRIVER_STATUS_IDLE      (0u)
78 #define DRIVER_STATUS_BUSY      (1u)
79 /* Error status values of the Flash driver */
80 #define DRIVER_STATUS_NO_ERROR  (0u)
81 #define DRIVER_STATUS_ERROR     (1u)
82 
83 /**
84   * \brief Arm Flash device structure.
85   */
86 struct arm_flash_dev_t
87 {
88   struct low_level_device *dev;
89   ARM_FLASH_INFO *data;       /*!< FLASH memory device data */
90 };
91 /**
92   * @}
93   */
94 /** @defgroup FLASH_Private_Variables Private Variables
95   * @{
96   */
97 static __IO uint32_t DoubleECC_Error_Counter = 0U;
98 /**
99   * \brief      Check if the Flash memory boundaries are not violated.
100   * \param[in]  flash_dev  Flash device structure \ref arm_flash_dev_t
101   * \param[in]  offset     Highest Flash memory address which would be accessed.
102   * \return     Returns true if Flash memory boundaries are not violated, false
103   *             otherwise.
104   */
105 
is_range_valid(struct arm_flash_dev_t * flash_dev,uint32_t offset)106 static bool is_range_valid(struct arm_flash_dev_t *flash_dev,
107                            uint32_t offset)
108 {
109   uint32_t flash_limit = 0;
110 
111   /* Calculating the highest address of the Flash memory address range */
112   flash_limit = FLASH_TOTAL_SIZE - 1;
113 
114   return (offset > flash_limit) ? (false) : (true) ;
115 }
116 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
117 /**
118   * \brief        Check if the range is secure .
119   * \param[in]    flash_dev  Flash device structure \ref arm_flash_dev_t
120   * \param[in]    param      Any number that can be checked against the
121   *                          program_unit, e.g. Flash memory address or
122   *                          data length in bytes.
123   * \return       Returns true if param is aligned to program_unit, false
124   *               otherwise.
125   */
is_range_secure(struct arm_flash_dev_t * flash_dev,uint32_t start,uint32_t len)126 static bool is_range_secure(struct arm_flash_dev_t *flash_dev,
127                             uint32_t start, uint32_t len)
128 {
129   /*  allow write access in area provided by device info */
130   struct flash_vect *vect = &flash_dev->dev->secure;
131   uint32_t nb;
132   /* NULL descriptor , means range is only secure */
133   if (!vect->range)
134   {
135     return true;
136   }
137   for (nb = 0; nb < vect->nb; nb++)
138     if ((start >= vect->range[nb].base) && ((start + len - 1) <= vect->range[nb].limit))
139     {
140       return true;
141     }
142   return false;
143 }
144 #endif /*  defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)  */
145 /**
146   * \brief        Check if the parameter is an erasebale page.
147   * \param[in]    flash_dev  Flash device structure \ref arm_flash_dev_t
148   * \param[in]    param      Any number that can be checked against the
149   *                          program_unit, e.g. Flash memory address or
150   *                          data length in bytes.
151   * \return       Returns true if param is a sector eraseable, false
152   *               otherwise.
153   */
is_erase_allow(struct arm_flash_dev_t * flash_dev,uint32_t param)154 static bool is_erase_allow(struct arm_flash_dev_t *flash_dev,
155                            uint32_t param)
156 {
157   /*  allow erase in range provided by device info */
158   struct flash_vect *vect = &flash_dev->dev->erase;
159   uint32_t nb;
160   for (nb = 0; nb < vect->nb; nb++)
161     if ((param >= vect->range[nb].base) && (param <= vect->range[nb].limit))
162     {
163       return true;
164     }
165   return false;
166 }
167 /**
168   * \brief        Check if the parameter is writeable area.
169   * \param[in]    flash_dev  Flash device structure \ref arm_flash_dev_t
170   * \param[in]    param      Any number that can be checked against the
171   *                          program_unit, e.g. Flash memory address or
172   *                          data length in bytes.
173   * \return       Returns true if param is aligned to program_unit, false
174   *               otherwise.
175   */
is_write_allow(struct arm_flash_dev_t * flash_dev,uint32_t start,uint32_t len)176 static bool is_write_allow(struct arm_flash_dev_t *flash_dev,
177                            uint32_t start, uint32_t len)
178 {
179   /*  allow write access in area provided by device info */
180   struct flash_vect *vect = &flash_dev->dev->write;
181   uint32_t nb;
182   for (nb = 0; nb < vect->nb; nb++)
183     if ((start >= vect->range[nb].base) && ((start + len - 1) <= vect->range[nb].limit))
184     {
185       return true;
186     }
187   return false;
188 }
189 
190 /**
191   * \brief        Check if the parameter is aligned to program_unit.
192   * \param[in]    flash_dev  Flash device structure \ref arm_flash_dev_t
193   * \param[in]    param      Any number that can be checked against the
194   *                          program_unit, e.g. Flash memory address or
195   *                          data length in bytes.
196   * \return       Returns true if param is aligned to program_unit, false
197   *               otherwise.
198   */
199 
is_write_aligned(struct arm_flash_dev_t * flash_dev,uint32_t param)200 static bool is_write_aligned(struct arm_flash_dev_t *flash_dev,
201                              uint32_t param)
202 {
203   return ((param % flash_dev->data->program_unit) != 0) ? (false) : (true);
204 }
205 /**
206   * \brief        Check if the parameter is aligned to page_unit.
207   * \param[in]    flash_dev  Flash device structure \ref arm_flash_dev_t
208   * \param[in]    param      Any number that can be checked against the
209   *                          program_unit, e.g. Flash memory address or
210   *                          data length in bytes.
211   * \return       Returns true if param is aligned to sector_unit, false
212   *               otherwise.
213   */
is_erase_aligned(struct arm_flash_dev_t * flash_dev,uint32_t param)214 static bool is_erase_aligned(struct arm_flash_dev_t *flash_dev,
215                              uint32_t param)
216 {
217   /*  2 pages */
218   return ((param % (flash_dev->data->sector_size)) != 0) ? (false) : (true);
219 }
220 
221 /**
222   * \brief        compute bank number.
223   * \param[in]    flash_dev  Flash device structure \ref arm_flash_dev_t
224   * \param[in]    param      &n address in flash
225   * \return       Returns true if param is aligned to sector_unit, false
226   *               otherwise.
227   */
bank_number(struct arm_flash_dev_t * flash_dev,uint32_t param)228 static uint32_t bank_number(struct arm_flash_dev_t *flash_dev,
229                             uint32_t param)
230 {
231   return ((param >= (FLASH_TOTAL_SIZE / 2)) ? 2 : 1);
232 }
233 
234 /**
235   * \brief        compute page number.
236   * \param[in]    flash_dev  Flash device structure \ref arm_flash_dev_t
237   * \param[in]    param      &n address in flash
238   * \return       Returns true if param is aligned to sector_unit, false
239   *               otherwise.
240   */
page_number(struct arm_flash_dev_t * flash_dev,uint32_t param)241 static uint32_t page_number(struct arm_flash_dev_t *flash_dev,
242                             uint32_t param)
243 {
244   uint32_t page = param / flash_dev->data->page_size ;
245   page = ((page > (flash_dev->data->sector_count))) ? page - ((flash_dev->data->sector_count)) : page;
246 #ifdef DEBUG_FLASH_ACCESS
247   printf("page = %x \r\n", page);
248 #endif /* DEBUG_FLASH_ACCESS */
249   return page;
250 }
251 
252 static ARM_FLASH_INFO ARM_FLASH0_DEV_DATA =
253 {
254   .sector_info    = NULL,     /* Uniform sector layout */
255   .sector_count   = FLASH_TOTAL_SIZE / FLASH0_SECTOR_SIZE,
256   .sector_size    = FLASH0_SECTOR_SIZE,
257   .page_size      = FLASH0_PAGE_SIZE,
258   .program_unit   = FLASH0_PROG_UNIT,       /* Minimum write size in bytes */
259   .erased_value   = FLASH0_ERASED_VAL,
260 };
261 
262 static struct arm_flash_dev_t ARM_FLASH0_DEV =
263 {
264   .dev = &(FLASH0_DEV),
265   .data   = &(ARM_FLASH0_DEV_DATA)
266 };
267 
memcpy_flash(void * dest,const void * src,size_t n)268 __attribute__((naked)) static void memcpy_flash(void *dest, const void *src, size_t n)
269 {
270     __ASM volatile(
271 #if !defined(__ICCARM__)
272     ".syntax unified     \n"
273 #endif /* !defined(__ICCARM__) */
274     "cmp   r2, #4        \n"
275     "blt  testbyte       \n"
276     "loopwords:          \n"
277     "ldr   r3, [r1, #0]  \n"
278     "str   r3, [r0, #0]  \n"
279     "add   r0, r0, #4    \n"
280     "add   r1, r1, #4    \n"
281     "sub   r2, r2, #4    \n"
282     "cmp   r2, #4        \n"
283     "bge   loopwords     \n"
284     "testbyte:           \n"
285     "cmp   r2, #0        \n"
286     "beq   finish        \n"
287     "loopbytes:          \n"
288     "ldrb  r3, [r1, #0]  \n"
289     "strb  r3, [r0, #0]  \n"
290     "add   r0, r0, #1    \n"
291     "add   r1, r1, #1    \n"
292     "sub   r2, r2, #1    \n"
293     "cmp   r2, #1        \n"
294     "bge   loopbytes     \n"
295     "finish:             \n"
296     "bx    lr            \n");
297 };
298 
299 
300 /* Flash Status */
301 static ARM_FLASH_STATUS ARM_FLASH0_STATUS = {0, 0, 0};
302 
303 
Flash_GetVersion(void)304 static ARM_DRIVER_VERSION Flash_GetVersion(void)
305 {
306   return DriverVersion;
307 }
308 
Flash_GetCapabilities(void)309 static ARM_FLASH_CAPABILITIES Flash_GetCapabilities(void)
310 {
311   return DriverCapabilities;
312 }
313 
Flash_Initialize(ARM_Flash_SignalEvent_t cb_event)314 static int32_t Flash_Initialize(ARM_Flash_SignalEvent_t cb_event)
315 {
316 #ifdef DEBUG_FLASH_ACCESS
317   FLASH_OperationTypeDef flash_operation;
318 #endif
319   ARG_UNUSED(cb_event);
320 
321 #ifdef DEBUG_FLASH_ACCESS
322   HAL_FLASHEx_GetOperation(&flash_operation);
323   printf("Flash operation: Op=0x%x, Area=0x%x, Address=0x%x",
324                flash_operation.OperationType,
325                flash_operation.FlashArea,
326                flash_operation.Address);
327 #endif
328   FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
329   return ARM_DRIVER_OK;
330 }
331 
Flash_Uninitialize(void)332 static int32_t Flash_Uninitialize(void)
333 {
334   return ARM_DRIVER_OK;
335 }
336 
Flash_PowerControl(ARM_POWER_STATE state)337 static int32_t Flash_PowerControl(ARM_POWER_STATE state)
338 {
339   switch (state)
340   {
341     case ARM_POWER_FULL:
342       /* Nothing to be done */
343       return ARM_DRIVER_OK;
344     case ARM_POWER_OFF:
345     case ARM_POWER_LOW:
346       return ARM_DRIVER_ERROR_UNSUPPORTED;
347     default:
348       return ARM_DRIVER_ERROR_PARAMETER;
349   }
350 }
351 
Flash_ReadData(uint32_t addr,void * data,uint32_t cnt)352 static int32_t Flash_ReadData(uint32_t addr, void *data, uint32_t cnt)
353 {
354   int32_t ret = ARM_DRIVER_ERROR_SPECIFIC;
355   bool is_valid = true;
356 
357   /* Conversion between data items and bytes */
358   cnt *= data_width_byte[DriverCapabilities.data_width];
359   ARM_FLASH0_STATUS.error = DRIVER_STATUS_NO_ERROR;
360 
361   /* Check Flash memory boundaries */
362   is_valid = is_range_valid(&ARM_FLASH0_DEV, addr + cnt - 1);
363   if (is_valid != true)
364   {
365     if (ARM_FLASH0_DEV.dev->read_error)
366     {
367       ARM_FLASH0_STATUS.error = DRIVER_STATUS_ERROR;
368       return ARM_DRIVER_ERROR_PARAMETER;
369     }
370     memset(data, 0xff, cnt);
371     return ARM_DRIVER_OK;
372   }
373   /*  ECC to implement with NMI */
374   /*  do a memcpy */
375 #ifdef DEBUG_FLASH_ACCESS
376   printf("read %lx n=%x \r\n", (addr + FLASH_BASE), cnt);
377 #endif /*  DEBUG_FLASH_ACCESS */
378   DoubleECC_Error_Counter = 0U;
379 
380 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
381   /* area secure and non secure are done with a non secure access */
382   if (is_range_secure(&ARM_FLASH0_DEV, addr, cnt))
383   {
384     memcpy_flash(data, (void *)((uint32_t)addr + FLASH_BASE), cnt);
385   }
386   else
387   {
388     memcpy_flash(data, (void *)((uint32_t)addr + FLASH_BASE_NS), cnt);
389   }
390 #else
391   memcpy_flash(data, (void *)((uint32_t)addr + FLASH_BASE_NS), cnt);
392 #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
393   if (DoubleECC_Error_Counter == 0U)
394   {
395     ret = ARM_DRIVER_OK;
396   }
397   else
398   {
399     /* Return OK with data = 0, when double ECC error */
400 #ifdef DEBUG_FLASH_ACCESS
401     printf("Double ECC error detected: FLASH_ECCR=0x%x", FLASH->ECCR);
402 #endif
403     memset(data, 0x00, cnt);
404     ret = ARM_DRIVER_OK;
405   }
406   DoubleECC_Error_Counter = 0U;
407   if (ret == ARM_DRIVER_OK) {
408     cnt /= data_width_byte[DriverCapabilities.data_width];
409     return cnt;
410   } else {
411     return ret;
412   }
413 }
414 
Flash_ProgramData(uint32_t addr,const void * data,uint32_t cnt)415 static int32_t Flash_ProgramData(uint32_t addr,
416                                  const void *data, uint32_t cnt)
417 {
418   uint32_t loop = 0;
419   uint32_t flash_base = (uint32_t)FLASH_BASE;
420 #if FLASH0_PROG_UNIT == 0x8
421   uint32_t write_type = FLASH_TYPEPROGRAM_DOUBLEWORD;
422 #elif FLASH0_PROG_UNIT == 0x10
423   uint32_t write_type = FLASH_TYPEPROGRAM_QUADWORD;
424 #else
425 #error "flash configuration must be defined here"
426 #endif /* FLASH0_PROG_UNIT */
427   HAL_StatusTypeDef err;
428 #if defined(CHECK_WRITE) || defined(DEBUG_FLASH_ACCESS)
429   void *dest;
430 #endif
431   /* Conversion between data items and bytes */
432   cnt *= data_width_byte[DriverCapabilities.data_width];
433   ARM_FLASH0_STATUS.error = DRIVER_STATUS_NO_ERROR;
434 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
435   if (is_range_secure(&ARM_FLASH0_DEV, addr, cnt))
436   {
437     flash_base = (uint32_t)FLASH_BASE_S;
438 #if FLASH0_PROG_UNIT == 0x8
439     write_type = FLASH_TYPEPROGRAM_DOUBLEWORD;
440 #elif FLASH0_PROG_UNIT == 0x10
441     write_type = FLASH_TYPEPROGRAM_QUADWORD;
442 #else
443 #error "flash configuration must be defined here"
444 #endif /* FLASH0_PROG_UNIT */
445   }
446   else
447   {
448     flash_base = (uint32_t)FLASH_BASE_NS;
449 #if FLASH0_PROG_UNIT == 0x8
450     write_type = FLASH_TYPEPROGRAM_DOUBLEWORD_NS;
451 #elif FLASH0_PROG_UNIT == 0x10
452     write_type = FLASH_TYPEPROGRAM_QUADWORD_NS;
453 #else
454 #error "flash configuration must be defined here"
455 #endif
456   }
457 #endif
458 #if defined(CHECK_WRITE) || defined(DEBUG_FLASH_ACCESS)
459   dest = (void *)(flash_base + addr);
460 #endif
461 #ifdef DEBUG_FLASH_ACCESS
462   printf("write %x n=%x \r\n", (uint32_t) dest, cnt);
463 #endif /* DEBUG_FLASH_ACCESS */
464   /* Check Flash memory boundaries and alignment with minimum write size
465     * (program_unit), data size also needs to be a multiple of program_unit.
466   */
467   if ((!is_range_valid(&ARM_FLASH0_DEV, addr + cnt - 1)) ||
468       (!is_write_aligned(&ARM_FLASH0_DEV, addr))     ||
469       (!is_write_aligned(&ARM_FLASH0_DEV, cnt))      ||
470       (!is_write_allow(&ARM_FLASH0_DEV, addr, cnt))
471      )
472   {
473     ARM_FLASH0_STATUS.error = DRIVER_STATUS_ERROR;
474     return ARM_DRIVER_ERROR_PARAMETER;
475   }
476 
477   HAL_FLASH_Unlock();
478   ARM_FLASH0_STATUS.busy = DRIVER_STATUS_BUSY;
479   do
480   {
481 #if FLASH0_PROG_UNIT == 0x8
482     /* dword api*/
483     uint64_t dword;
484     memcpy(&dword, (void *)((uint32_t)data + loop), sizeof(dword));
485     if (dword != -1)
486         err = HAL_FLASH_Program(write_type, (flash_base + addr), dword);
487     else
488         err = HAL_OK;
489 #elif FLASH0_PROG_UNIT == 0x10
490     /* quadword api*/
491     uint64_t dword[2];
492     memcpy(dword, (void *)((uint32_t)data + loop), sizeof(dword));
493     if ((dword[0] != -1) || (dword[1] != -1))
494         err = HAL_FLASH_Program(write_type, (flash_base + addr), (uint32_t)&dword[0]);
495     else
496         err = HAL_OK;
497 #else
498 #error "flash configuration must be defined here"
499 #endif
500     loop += sizeof(dword);
501     addr += sizeof(dword);
502   } while ((loop != cnt) && (err == HAL_OK));
503 
504   ARM_FLASH0_STATUS.busy = DRIVER_STATUS_IDLE;
505   HAL_FLASH_Lock();
506   /* compare data written */
507 #ifdef CHECK_WRITE
508   if ((err == HAL_OK) && memcmp(dest, data, cnt))
509   {
510     err = HAL_ERROR;
511 #ifdef DEBUG_FLASH_ACCESS
512     printf("write %x n=%x (cmp failed)\r\n", (uint32_t)(dest), cnt);
513 #endif /* DEBUG_FLASH_ACCESS */
514   }
515 #endif /* CHECK_WRITE */
516 #ifdef DEBUG_FLASH_ACCESS
517   if (err != HAL_OK)
518   {
519     printf("failed write %x n=%x \r\n", (uint32_t)(dest), cnt);
520   }
521 #endif /* DEBUG_FLASH_ACCESS */
522   cnt /= data_width_byte[DriverCapabilities.data_width];
523   return (err == HAL_OK) ? cnt : ARM_DRIVER_ERROR;
524 }
525 
Flash_EraseSector(uint32_t addr)526 static int32_t Flash_EraseSector(uint32_t addr)
527 {
528   FLASH_EraseInitTypeDef EraseInit;
529   HAL_StatusTypeDef err;
530   uint32_t pageError;
531 #ifdef CHECK_ERASE
532   uint32_t i;
533   uint32_t *pt;
534 #endif /* CHECK_ERASE */
535 #ifdef DEBUG_FLASH_ACCESS
536   printf("erase %x\r\n", addr);
537 #endif /* DEBUG_FLASH_ACCESS */
538   if (!(is_range_valid(&ARM_FLASH0_DEV, addr)) ||
539       !(is_erase_aligned(&ARM_FLASH0_DEV, addr)) ||
540       !(is_erase_allow(&ARM_FLASH0_DEV, addr)))
541   {
542     ARM_FLASH0_STATUS.error = DRIVER_STATUS_ERROR;
543 #ifdef DEBUG_FLASH_ACCESS
544 #if defined(__ARMCC_VERSION)
545     printf("failed erase %x\r\n", addr);
546 #else
547     printf("failed erase %lx\r\n", addr);
548 #endif /* __ARMCC_VERSION */
549 #endif /* DEBUG_FLASH_ACCESS */
550     return ARM_DRIVER_ERROR_PARAMETER;
551   }
552 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
553   if (is_range_secure(&ARM_FLASH0_DEV, addr, 4))
554   {
555     EraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
556   }
557   else
558     EraseInit.TypeErase = FLASH_TYPEERASE_PAGES_NS;
559 #else
560   EraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
561 #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
562   /*  fix me assume dual bank, reading DBANK in OPTR in Flash init is better */
563   /*  flash size in  DB256K in OPTR */
564   EraseInit.Banks = bank_number(&ARM_FLASH0_DEV, addr);
565 
566   EraseInit.NbPages = FLASH0_SECTOR_SIZE / FLASH_PAGE_SIZE;
567 
568   EraseInit.Page = page_number(&ARM_FLASH0_DEV, addr);
569 
570   ARM_FLASH0_STATUS.error = DRIVER_STATUS_NO_ERROR;
571   HAL_FLASH_Unlock();
572   ARM_FLASH0_STATUS.busy = DRIVER_STATUS_BUSY;
573   err = HAL_FLASHEx_Erase(&EraseInit, &pageError);
574   ARM_FLASH0_STATUS.busy = DRIVER_STATUS_IDLE;
575   HAL_FLASH_Lock();
576 #ifdef DEBUG_FLASH_ACCESS
577   if (err != HAL_OK)
578   {
579     printf("erase failed \r\n");
580   }
581 #endif /* DEBUG_FLASH_ACCESS */
582 #ifdef CHECK_ERASE
583 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
584   if (is_range_secure(&ARM_FLASH0_DEV, addr, 4))
585   {
586     pt = (uint32_t *)((uint32_t)FLASH_BASE_S + addr);
587   }
588   else
589   {
590     pt = (uint32_t *)((uint32_t)FLASH_BASE_NS + addr);
591   }
592 #else
593   pt = (uint32_t *)((uint32_t)FLASH_BASE + addr);
594 #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)  */
595   for (i = 0; i > 0x400; i++)
596   {
597     if (pt[i] != 0xffffffff)
598     {
599 #ifdef DEBUG_FLASH_ACCESS
600       printf("erase failed off %x %x %x\r\n", addr, &pt[i], pt[i]);
601 #endif /* DEBUG_FLASH_ACCESS */
602       err = HAL_ERROR;
603       break;
604     }
605   }
606 #endif /* CHECK_ERASE */
607   return (err == HAL_OK) ? ARM_DRIVER_OK : ARM_DRIVER_ERROR;
608 }
609 
Flash_EraseChip(void)610 static int32_t Flash_EraseChip(void)
611 {
612   return ARM_DRIVER_ERROR_UNSUPPORTED;
613 }
614 
Flash_GetStatus(void)615 static ARM_FLASH_STATUS Flash_GetStatus(void)
616 {
617   return ARM_FLASH0_STATUS;
618 }
619 
Flash_GetInfo(void)620 static ARM_FLASH_INFO *Flash_GetInfo(void)
621 {
622   return ARM_FLASH0_DEV.data;
623 }
624 
625 ARM_DRIVER_FLASH TFM_Driver_FLASH0 =
626 {
627   /* Get Version */
628   Flash_GetVersion,
629   /* Get Capability */
630   Flash_GetCapabilities,
631   /* Initialize */
632   Flash_Initialize,
633   /* UnInitialize */
634   Flash_Uninitialize,
635   /* power control */
636   Flash_PowerControl,
637   /* Read data */
638   Flash_ReadData,
639   /* Program data */
640   Flash_ProgramData,
641   /* Erase Sector */
642   Flash_EraseSector,
643   /* Erase chip */
644   Flash_EraseChip,
645   /* Get Status */
646   Flash_GetStatus,
647   /* Get Info */
648   Flash_GetInfo
649 };
650 /**
651   * @brief  Get Link Register value (LR)
652   * @param  None.
653   * @retval LR Register value
654   */
__get_LR(void)655 __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_LR(void)
656 {
657   register uint32_t result;
658 
659 #if defined ( __ICCARM__ ) || ( __GNUC__ )
660   __ASM volatile("MOV %0, LR" : "=r"(result));
661 #elif defined ( __CC_ARM )
662   __ASM volatile("MOV result, __return_address()");
663 #endif /* ( __ICCARM__ ) || ( __GNUC__ )  */
664 
665   return result;
666 }
667 
668 /*
669    As this handler code relies on stack pointer position to manipulate the PC return value, it is important
670    not to use extra registers (on top of scratch registers), because it would change the stack pointer
671    position. Then compiler optimizations are customized to ensure that.
672 */
673 
674 /*  to rework the define has changed with  ARMCLANG .... */
675 #if defined(__ARMCC_VERSION)
676 /*#pragma O0 */
677 #elif defined ( __GNUC__ )
678 /**/
679 #endif /*__ARMCC_VERSION */
680 
NMI_Handler(void)681 void NMI_Handler(void)
682 {
683   uint32_t *p_sp;
684   uint32_t lr;
685   uint16_t opcode_msb;
686   if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_ECCD))
687   {
688     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ECCD);
689     /* Memorize error to ignore the read value */
690     DoubleECC_Error_Counter++;
691 
692     lr = __get_LR();
693 
694     /* Check EXC_RETURN value in LR to know which SP was used prior entering exception */
695     if (((lr) & (0xFU)) == 0xDU)
696     {
697       /* interrupted code was using Process Stack Pointer */
698       p_sp = (uint32_t *)__get_PSP();
699     }
700     else
701     {
702       /* interrupted code was using Main Stack Pointer */
703       p_sp = (uint32_t *)__get_MSP();
704     }
705 
706     /* Test caller mode T bit from CPSR in stack */
707     if ((*(p_sp + 7U) & (1U << xPSR_T_Pos)) != 0U)
708     {
709       /* Thumb  mode.
710          Test PC in stack.
711          If bits [15:11] of the halfword being decoded take any of the following values,
712          the halfword is the first halfword of a 32-bit instruction: 0b11101, 0b11110, 0b11111.
713          Otherwise, the halfword is a 16-bit instruction.
714       */
715       opcode_msb = (*(uint16_t *)(*(p_sp + 6) & 0xFFFFFFFEU) & 0xF800U);
716       if ((opcode_msb == 0xE800U) || (opcode_msb == 0xF000U) || (opcode_msb == 0xF800U))
717       {
718         /* execute next instruction PC +4  */
719         *(p_sp + 6U) += 4U;
720       }
721       else
722       {
723         /* execute next instruction PC +2  */
724         *(p_sp + 6U) += 2U;
725       }
726     }
727     else
728     {
729       /* ARM mode execute next instruction PC +4 */
730       *(p_sp + 6U) += 4U;
731     }
732   }
733   else
734   {
735     /* This exception occurs for another reason than flash double ECC errors */
736     while (1U);
737   }
738 }
739 
740