Subversion Repositories AFRtranscoder

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 1
/**
2
  ******************************************************************************
3
  * @file    stm32f1xx_hal_flash.c
4
  * @author  MCD Application Team
5
  * @brief   FLASH HAL module driver.
6
  *          This file provides firmware functions to manage the following
7
  *          functionalities of the internal FLASH memory:
8
  *           + Program operations functions
9
  *           + Memory Control functions
10
  *           + Peripheral State functions
11
  *        
12
  @verbatim
13
  ==============================================================================
14
                        ##### FLASH peripheral features #####
15
  ==============================================================================
16
  [..] The Flash memory interface manages CPU AHB I-Code and D-Code accesses
17
       to the Flash memory. It implements the erase and program Flash memory operations
18
       and the read and write protection mechanisms.
19
 
20
  [..] The Flash memory interface accelerates code execution with a system of instruction
21
      prefetch.
22
 
23
  [..] The FLASH main features are:
24
      (+) Flash memory read operations
25
      (+) Flash memory program/erase operations
26
      (+) Read / write protections
27
      (+) Prefetch on I-Code
28
      (+) Option Bytes programming
29
 
30
 
31
                     ##### How to use this driver #####
32
  ==============================================================================
33
  [..]                            
34
      This driver provides functions and macros to configure and program the FLASH
35
      memory of all STM32F1xx devices.
36
 
37
      (#) FLASH Memory I/O Programming functions: this group includes all needed
38
          functions to erase and program the main memory:
39
        (++) Lock and Unlock the FLASH interface
40
        (++) Erase function: Erase page, erase all pages
41
        (++) Program functions: half word, word and doubleword
42
      (#) FLASH Option Bytes Programming functions: this group includes all needed
43
          functions to manage the Option Bytes:
44
        (++) Lock and Unlock the Option Bytes
45
        (++) Set/Reset the write protection
46
        (++) Set the Read protection Level
47
        (++) Program the user Option Bytes
48
        (++) Launch the Option Bytes loader
49
        (++) Erase Option Bytes
50
        (++) Program the data Option Bytes
51
        (++) Get the Write protection.
52
        (++) Get the user option bytes.
53
 
54
      (#) Interrupts and flags management functions : this group
55
          includes all needed functions to:
56
        (++) Handle FLASH interrupts
57
        (++) Wait for last FLASH operation according to its status
58
        (++) Get error flag status
59
 
60
  [..] In addition to these function, this driver includes a set of macros allowing
61
       to handle the following operations:
62
 
63
      (+) Set/Get the latency
64
      (+) Enable/Disable the prefetch buffer
65
      (+) Enable/Disable the half cycle access
66
      (+) Enable/Disable the FLASH interrupts
67
      (+) Monitor the FLASH flags status
68
 
69
  @endverbatim
70
  ******************************************************************************
71
  * @attention
72
  *
73
  * Copyright (c) 2016 STMicroelectronics.
74
  * All rights reserved.
75
  *
76
  * This software is licensed under terms that can be found in the LICENSE file in
77
  * the root directory of this software component.
78
  * If no LICENSE file comes with this software, it is provided AS-IS.
79
  ******************************************************************************
80
  */
81
 
82
/* Includes ------------------------------------------------------------------*/
83
#include "stm32f1xx_hal.h"
84
 
85
/** @addtogroup STM32F1xx_HAL_Driver
86
  * @{
87
  */
88
 
89
#ifdef HAL_FLASH_MODULE_ENABLED
90
 
91
/** @defgroup FLASH FLASH
92
  * @brief FLASH HAL module driver
93
  * @{
94
  */
95
 
96
/* Private typedef -----------------------------------------------------------*/
97
/* Private define ------------------------------------------------------------*/
98
/** @defgroup FLASH_Private_Constants FLASH Private Constants
99
  * @{
100
  */
101
/**
102
  * @}
103
  */
104
 
105
/* Private macro ---------------------------- ---------------------------------*/
106
/** @defgroup FLASH_Private_Macros FLASH Private Macros
107
  * @{
108
  */
109
 
110
/**
111
  * @}
112
  */
113
 
114
/* Private variables ---------------------------------------------------------*/
115
/** @defgroup FLASH_Private_Variables FLASH Private Variables
116
  * @{
117
  */
118
/* Variables used for Erase pages under interruption*/
119
FLASH_ProcessTypeDef pFlash;
120
/**
121
  * @}
122
  */
123
 
124
/* Private function prototypes -----------------------------------------------*/
125
/** @defgroup FLASH_Private_Functions FLASH Private Functions
126
  * @{
127
  */
128
static  void   FLASH_Program_HalfWord(uint32_t Address, uint16_t Data);
129
static  void   FLASH_SetErrorCode(void);
130
extern void    FLASH_PageErase(uint32_t PageAddress);
131
/**
132
  * @}
133
  */
134
 
135
/* Exported functions ---------------------------------------------------------*/
136
/** @defgroup FLASH_Exported_Functions FLASH Exported Functions
137
  * @{
138
  */
139
 
140
/** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions
141
  *  @brief   Programming operation functions
142
  *
143
@verbatim  
144
@endverbatim
145
  * @{
146
  */
147
 
148
/**
149
  * @brief  Program halfword, word or double word at a specified address
150
  * @note   The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
151
  *         The function HAL_FLASH_Lock() should be called after to lock the FLASH interface
152
  *
153
  * @note   If an erase and a program operations are requested simultaneously,    
154
  *         the erase operation is performed before the program one.
155
  *  
156
  * @note   FLASH should be previously erased before new programmation (only exception to this
157
  *         is when 0x0000 is programmed)
158
  *
159
  * @param  TypeProgram:  Indicate the way to program at a specified address.
160
  *                       This parameter can be a value of @ref FLASH_Type_Program
161
  * @param  Address:      Specifies the address to be programmed.
162
  * @param  Data:         Specifies the data to be programmed
163
  *
164
  * @retval HAL_StatusTypeDef HAL Status
165
  */
166
HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
167
{
168
  HAL_StatusTypeDef status = HAL_ERROR;
169
  uint8_t index = 0;
170
  uint8_t nbiterations = 0;
171
 
172
  /* Process Locked */
173
  __HAL_LOCK(&pFlash);
174
 
175
  /* Check the parameters */
176
  assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
177
  assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
178
 
179
#if defined(FLASH_BANK2_END)
180
  if(Address <= FLASH_BANK1_END)
181
  {
182
#endif /* FLASH_BANK2_END */
183
    /* Wait for last operation to be completed */
184
    status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
185
#if defined(FLASH_BANK2_END)
186
  }
187
  else
188
  {
189
    /* Wait for last operation to be completed */
190
    status = FLASH_WaitForLastOperationBank2(FLASH_TIMEOUT_VALUE);
191
  }
192
#endif /* FLASH_BANK2_END */
193
 
194
  if(status == HAL_OK)
195
  {
196
    if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD)
197
    {
198
      /* Program halfword (16-bit) at a specified address. */
199
      nbiterations = 1U;
200
    }
201
    else if(TypeProgram == FLASH_TYPEPROGRAM_WORD)
202
    {
203
      /* Program word (32-bit = 2*16-bit) at a specified address. */
204
      nbiterations = 2U;
205
    }
206
    else
207
    {
208
      /* Program double word (64-bit = 4*16-bit) at a specified address. */
209
      nbiterations = 4U;
210
    }
211
 
212
    for (index = 0U; index < nbiterations; index++)
213
    {
214
      FLASH_Program_HalfWord((Address + (2U*index)), (uint16_t)(Data >> (16U*index)));
215
 
216
#if defined(FLASH_BANK2_END)
217
      if(Address <= FLASH_BANK1_END)
218
      {
219
#endif /* FLASH_BANK2_END */
220
        /* Wait for last operation to be completed */
221
        status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
222
 
223
        /* If the program operation is completed, disable the PG Bit */
224
        CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
225
#if defined(FLASH_BANK2_END)
226
      }
227
      else
228
      {
229
        /* Wait for last operation to be completed */
230
        status = FLASH_WaitForLastOperationBank2(FLASH_TIMEOUT_VALUE);
231
 
232
        /* If the program operation is completed, disable the PG Bit */
233
        CLEAR_BIT(FLASH->CR2, FLASH_CR2_PG);
234
      }
235
#endif /* FLASH_BANK2_END */
236
      /* In case of error, stop programation procedure */
237
      if (status != HAL_OK)
238
      {
239
        break;
240
      }
241
    }
242
  }
243
 
244
  /* Process Unlocked */
245
  __HAL_UNLOCK(&pFlash);
246
 
247
  return status;
248
}
249
 
250
/**
251
  * @brief  Program halfword, word or double word at a specified address  with interrupt enabled.
252
  * @note   The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
253
  *         The function HAL_FLASH_Lock() should be called after to lock the FLASH interface
254
  *
255
  * @note   If an erase and a program operations are requested simultaneously,    
256
  *         the erase operation is performed before the program one.
257
  *
258
  * @param  TypeProgram: Indicate the way to program at a specified address.
259
  *                      This parameter can be a value of @ref FLASH_Type_Program
260
  * @param  Address:     Specifies the address to be programmed.
261
  * @param  Data:        Specifies the data to be programmed
262
  *
263
  * @retval HAL_StatusTypeDef HAL Status
264
  */
265
HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
266
{
267
  HAL_StatusTypeDef status = HAL_OK;
268
 
269
  /* Process Locked */
270
  __HAL_LOCK(&pFlash);
271
 
272
  /* Check the parameters */
273
  assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
274
  assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
275
 
276
#if defined(FLASH_BANK2_END)
277
  /* If procedure already ongoing, reject the next one */
278
  if (pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
279
  {
280
    return HAL_ERROR;
281
  }
282
 
283
  if(Address <= FLASH_BANK1_END)
284
  {
285
    /* Enable End of FLASH Operation and Error source interrupts */
286
    __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP_BANK1 | FLASH_IT_ERR_BANK1);
287
 
288
  }else
289
  {
290
    /* Enable End of FLASH Operation and Error source interrupts */
291
    __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2);
292
  }
293
#else
294
  /* Enable End of FLASH Operation and Error source interrupts */
295
  __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR);
296
#endif /* FLASH_BANK2_END */
297
 
298
  pFlash.Address = Address;
299
  pFlash.Data = Data;
300
 
301
  if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD)
302
  {
303
    pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMHALFWORD;
304
    /* Program halfword (16-bit) at a specified address. */
305
    pFlash.DataRemaining = 1U;
306
  }
307
  else if(TypeProgram == FLASH_TYPEPROGRAM_WORD)
308
  {
309
    pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMWORD;
310
    /* Program word (32-bit : 2*16-bit) at a specified address. */
311
    pFlash.DataRemaining = 2U;
312
  }
313
  else
314
  {
315
    pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMDOUBLEWORD;
316
    /* Program double word (64-bit : 4*16-bit) at a specified address. */
317
    pFlash.DataRemaining = 4U;
318
  }
319
 
320
  /* Program halfword (16-bit) at a specified address. */
321
  FLASH_Program_HalfWord(Address, (uint16_t)Data);
322
 
323
  return status;
324
}
325
 
326
/**
327
  * @brief This function handles FLASH interrupt request.
328
  * @retval None
329
  */
330
void HAL_FLASH_IRQHandler(void)
331
{
332
  uint32_t addresstmp = 0U;
333
 
334
  /* Check FLASH operation error flags */
335
#if defined(FLASH_BANK2_END)
336
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK1) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK1) || \
337
    (__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK2) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK2)))
338
#else
339
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) ||__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR))
340
#endif /* FLASH_BANK2_END */
341
  {
342
    /* Return the faulty address */
343
    addresstmp = pFlash.Address;
344
    /* Reset address */
345
    pFlash.Address = 0xFFFFFFFFU;
346
 
347
    /* Save the Error code */
348
    FLASH_SetErrorCode();
349
 
350
    /* FLASH error interrupt user callback */
351
    HAL_FLASH_OperationErrorCallback(addresstmp);
352
 
353
    /* Stop the procedure ongoing */
354
    pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
355
  }
356
 
357
  /* Check FLASH End of Operation flag  */
358
#if defined(FLASH_BANK2_END)
359
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP_BANK1))
360
  {
361
    /* Clear FLASH End of Operation pending bit */
362
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK1);
363
#else
364
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
365
  {
366
    /* Clear FLASH End of Operation pending bit */
367
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
368
#endif /* FLASH_BANK2_END */
369
 
370
    /* Process can continue only if no error detected */
371
    if(pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
372
    {
373
      if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE)
374
      {
375
        /* Nb of pages to erased can be decreased */
376
        pFlash.DataRemaining--;
377
 
378
        /* Check if there are still pages to erase */
379
        if(pFlash.DataRemaining != 0U)
380
        {
381
          addresstmp = pFlash.Address;
382
          /*Indicate user which sector has been erased */
383
          HAL_FLASH_EndOfOperationCallback(addresstmp);
384
 
385
          /*Increment sector number*/
386
          addresstmp = pFlash.Address + FLASH_PAGE_SIZE;
387
          pFlash.Address = addresstmp;
388
 
389
          /* If the erase operation is completed, disable the PER Bit */
390
          CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
391
 
392
          FLASH_PageErase(addresstmp);
393
        }
394
        else
395
        {
396
          /* No more pages to Erase, user callback can be called. */
397
          /* Reset Sector and stop Erase pages procedure */
398
          pFlash.Address = addresstmp = 0xFFFFFFFFU;
399
          pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
400
          /* FLASH EOP interrupt user callback */
401
          HAL_FLASH_EndOfOperationCallback(addresstmp);
402
        }
403
      }
404
      else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE)
405
      {
406
        /* Operation is completed, disable the MER Bit */
407
        CLEAR_BIT(FLASH->CR, FLASH_CR_MER);
408
 
409
#if defined(FLASH_BANK2_END)
410
        /* Stop Mass Erase procedure if no pending mass erase on other bank */
411
        if (HAL_IS_BIT_CLR(FLASH->CR2, FLASH_CR2_MER))
412
        {
413
#endif /* FLASH_BANK2_END */
414
          /* MassErase ended. Return the selected bank */
415
          /* FLASH EOP interrupt user callback */
416
          HAL_FLASH_EndOfOperationCallback(0U);
417
 
418
          /* Stop Mass Erase procedure*/
419
          pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
420
        }
421
#if defined(FLASH_BANK2_END)
422
      }
423
#endif /* FLASH_BANK2_END */
424
      else
425
      {
426
        /* Nb of 16-bit data to program can be decreased */
427
        pFlash.DataRemaining--;
428
 
429
        /* Check if there are still 16-bit data to program */
430
        if(pFlash.DataRemaining != 0U)
431
        {
432
          /* Increment address to 16-bit */
433
          pFlash.Address += 2U;
434
          addresstmp = pFlash.Address;
435
 
436
          /* Shift to have next 16-bit data */
437
          pFlash.Data = (pFlash.Data >> 16U);
438
 
439
          /* Operation is completed, disable the PG Bit */
440
          CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
441
 
442
          /*Program halfword (16-bit) at a specified address.*/
443
          FLASH_Program_HalfWord(addresstmp, (uint16_t)pFlash.Data);
444
        }
445
        else
446
        {
447
          /* Program ended. Return the selected address */
448
          /* FLASH EOP interrupt user callback */
449
          if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMHALFWORD)
450
          {
451
            HAL_FLASH_EndOfOperationCallback(pFlash.Address);
452
          }
453
          else if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMWORD)
454
          {
455
            HAL_FLASH_EndOfOperationCallback(pFlash.Address - 2U);
456
          }
457
          else
458
          {
459
            HAL_FLASH_EndOfOperationCallback(pFlash.Address - 6U);
460
          }
461
 
462
          /* Reset Address and stop Program procedure */
463
          pFlash.Address = 0xFFFFFFFFU;
464
          pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
465
        }
466
      }
467
    }
468
  }
469
 
470
#if defined(FLASH_BANK2_END)
471
  /* Check FLASH End of Operation flag  */
472
  if(__HAL_FLASH_GET_FLAG( FLASH_FLAG_EOP_BANK2))
473
  {
474
    /* Clear FLASH End of Operation pending bit */
475
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK2);
476
 
477
    /* Process can continue only if no error detected */
478
    if(pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
479
    {
480
      if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE)
481
      {
482
        /* Nb of pages to erased can be decreased */
483
        pFlash.DataRemaining--;
484
 
485
        /* Check if there are still pages to erase*/
486
        if(pFlash.DataRemaining != 0U)
487
        {
488
          /* Indicate user which page address has been erased*/
489
          HAL_FLASH_EndOfOperationCallback(pFlash.Address);
490
 
491
          /* Increment page address to next page */
492
          pFlash.Address += FLASH_PAGE_SIZE;
493
          addresstmp = pFlash.Address;
494
 
495
          /* Operation is completed, disable the PER Bit */
496
          CLEAR_BIT(FLASH->CR2, FLASH_CR2_PER);
497
 
498
          FLASH_PageErase(addresstmp);
499
        }
500
        else
501
        {
502
          /*No more pages to Erase*/
503
 
504
          /*Reset Address and stop Erase pages procedure*/
505
          pFlash.Address = 0xFFFFFFFFU;
506
          pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
507
 
508
          /* FLASH EOP interrupt user callback */
509
          HAL_FLASH_EndOfOperationCallback(pFlash.Address);
510
        }
511
      }
512
      else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE)
513
      {
514
        /* Operation is completed, disable the MER Bit */
515
        CLEAR_BIT(FLASH->CR2, FLASH_CR2_MER);
516
 
517
        if (HAL_IS_BIT_CLR(FLASH->CR, FLASH_CR_MER))
518
        {
519
          /* MassErase ended. Return the selected bank*/
520
          /* FLASH EOP interrupt user callback */
521
          HAL_FLASH_EndOfOperationCallback(0U);
522
 
523
          pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
524
        }
525
      }
526
      else
527
      {
528
        /* Nb of 16-bit data to program can be decreased */
529
        pFlash.DataRemaining--;
530
 
531
        /* Check if there are still 16-bit data to program */
532
        if(pFlash.DataRemaining != 0U)
533
        {
534
          /* Increment address to 16-bit */
535
          pFlash.Address += 2U;
536
          addresstmp = pFlash.Address;
537
 
538
          /* Shift to have next 16-bit data */
539
          pFlash.Data = (pFlash.Data >> 16U);
540
 
541
          /* Operation is completed, disable the PG Bit */
542
          CLEAR_BIT(FLASH->CR2, FLASH_CR2_PG);
543
 
544
          /*Program halfword (16-bit) at a specified address.*/
545
          FLASH_Program_HalfWord(addresstmp, (uint16_t)pFlash.Data);
546
        }
547
        else
548
        {
549
          /*Program ended. Return the selected address*/
550
          /* FLASH EOP interrupt user callback */
551
          if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMHALFWORD)
552
          {
553
            HAL_FLASH_EndOfOperationCallback(pFlash.Address);
554
          }
555
          else if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMWORD)
556
          {
557
            HAL_FLASH_EndOfOperationCallback(pFlash.Address-2U);
558
          }
559
          else
560
          {
561
            HAL_FLASH_EndOfOperationCallback(pFlash.Address-6U);
562
          }
563
 
564
          /* Reset Address and stop Program procedure*/
565
          pFlash.Address = 0xFFFFFFFFU;
566
          pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
567
        }
568
      }
569
    }
570
  }
571
#endif 
572
 
573
  if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE)
574
  {
575
#if defined(FLASH_BANK2_END)
576
    /* Operation is completed, disable the PG, PER and MER Bits for both bank */
577
    CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_PER | FLASH_CR_MER));
578
    CLEAR_BIT(FLASH->CR2, (FLASH_CR2_PG | FLASH_CR2_PER | FLASH_CR2_MER));  
579
 
580
    /* Disable End of FLASH Operation and Error source interrupts for both banks */
581
    __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP_BANK1 | FLASH_IT_ERR_BANK1 | FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2);
582
#else
583
    /* Operation is completed, disable the PG, PER and MER Bits */
584
    CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_PER | FLASH_CR_MER));
585
 
586
    /* Disable End of FLASH Operation and Error source interrupts */
587
    __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR);
588
#endif /* FLASH_BANK2_END */
589
 
590
    /* Process Unlocked */
591
    __HAL_UNLOCK(&pFlash);
592
  }
593
}
594
 
595
/**
596
  * @brief  FLASH end of operation interrupt callback
597
  * @param  ReturnValue: The value saved in this parameter depends on the ongoing procedure
598
  *                 - Mass Erase: No return value expected
599
  *                 - Pages Erase: Address of the page which has been erased
600
  *                    (if 0xFFFFFFFF, it means that all the selected pages have been erased)
601
  *                 - Program: Address which was selected for data program
602
  * @retval none
603
  */
604
__weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
605
{
606
  /* Prevent unused argument(s) compilation warning */
607
  UNUSED(ReturnValue);
608
 
609
  /* NOTE : This function Should not be modified, when the callback is needed,
610
            the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
611
   */
612
}
613
 
614
/**
615
  * @brief  FLASH operation error interrupt callback
616
  * @param  ReturnValue: The value saved in this parameter depends on the ongoing procedure
617
  *                 - Mass Erase: No return value expected
618
  *                 - Pages Erase: Address of the page which returned an error
619
  *                 - Program: Address which was selected for data program
620
  * @retval none
621
  */
622
__weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
623
{
624
  /* Prevent unused argument(s) compilation warning */
625
  UNUSED(ReturnValue);
626
 
627
  /* NOTE : This function Should not be modified, when the callback is needed,
628
            the HAL_FLASH_OperationErrorCallback could be implemented in the user file
629
   */
630
}
631
 
632
/**
633
  * @}
634
  */
635
 
636
/** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions
637
 *  @brief   management functions
638
 *
639
@verbatim  
640
 ===============================================================================
641
                      ##### Peripheral Control functions #####
642
 ===============================================================================  
643
    [..]
644
    This subsection provides a set of functions allowing to control the FLASH
645
    memory operations.
646
 
647
@endverbatim
648
  * @{
649
  */
650
 
651
/**
652
  * @brief  Unlock the FLASH control register access
653
  * @retval HAL Status
654
  */
655
HAL_StatusTypeDef HAL_FLASH_Unlock(void)
656
{
657
  HAL_StatusTypeDef status = HAL_OK;
658
 
659
  if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != RESET)
660
  {
661
    /* Authorize the FLASH Registers access */
662
    WRITE_REG(FLASH->KEYR, FLASH_KEY1);
663
    WRITE_REG(FLASH->KEYR, FLASH_KEY2);
664
 
665
    /* Verify Flash is unlocked */
666
    if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != RESET)
667
    {
668
      status = HAL_ERROR;
669
    }
670
  }
671
#if defined(FLASH_BANK2_END)
672
  if(READ_BIT(FLASH->CR2, FLASH_CR2_LOCK) != RESET)
673
  {
674
    /* Authorize the FLASH BANK2 Registers access */
675
    WRITE_REG(FLASH->KEYR2, FLASH_KEY1);
676
    WRITE_REG(FLASH->KEYR2, FLASH_KEY2);
677
 
678
    /* Verify Flash BANK2 is unlocked */
679
    if(READ_BIT(FLASH->CR2, FLASH_CR2_LOCK) != RESET)
680
    {
681
      status = HAL_ERROR;
682
    }
683
  }
684
#endif /* FLASH_BANK2_END */
685
 
686
  return status;
687
}
688
 
689
/**
690
  * @brief  Locks the FLASH control register access
691
  * @retval HAL Status
692
  */
693
HAL_StatusTypeDef HAL_FLASH_Lock(void)
694
{
695
  /* Set the LOCK Bit to lock the FLASH Registers access */
696
  SET_BIT(FLASH->CR, FLASH_CR_LOCK);
697
 
698
#if defined(FLASH_BANK2_END)
699
  /* Set the LOCK Bit to lock the FLASH BANK2 Registers access */
700
  SET_BIT(FLASH->CR2, FLASH_CR2_LOCK);
701
 
702
#endif /* FLASH_BANK2_END */
703
  return HAL_OK;  
704
}
705
 
706
/**
707
  * @brief  Unlock the FLASH Option Control Registers access.
708
  * @retval HAL Status
709
  */
710
HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
711
{
712
  if (HAL_IS_BIT_CLR(FLASH->CR, FLASH_CR_OPTWRE))
713
  {
714
    /* Authorizes the Option Byte register programming */
715
    WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY1);
716
    WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY2);
717
  }
718
  else
719
  {
720
    return HAL_ERROR;
721
  }  
722
 
723
  return HAL_OK;  
724
}
725
 
726
/**
727
  * @brief  Lock the FLASH Option Control Registers access.
728
  * @retval HAL Status
729
  */
730
HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
731
{
732
  /* Clear the OPTWRE Bit to lock the FLASH Option Byte Registers access */
733
  CLEAR_BIT(FLASH->CR, FLASH_CR_OPTWRE);
734
 
735
  return HAL_OK;  
736
}
737
 
738
/**
739
  * @brief  Launch the option byte loading.
740
  * @note   This function will reset automatically the MCU.
741
  * @retval None
742
  */
743
void HAL_FLASH_OB_Launch(void)
744
{
745
  /* Initiates a system reset request to launch the option byte loading */
746
  HAL_NVIC_SystemReset();
747
}
748
 
749
/**
750
  * @}
751
  */  
752
 
753
/** @defgroup FLASH_Exported_Functions_Group3 Peripheral errors functions
754
 *  @brief    Peripheral errors functions
755
 *
756
@verbatim  
757
 ===============================================================================
758
                      ##### Peripheral Errors functions #####
759
 ===============================================================================  
760
    [..]
761
    This subsection permit to get in run-time errors of  the FLASH peripheral.
762
 
763
@endverbatim
764
  * @{
765
  */
766
 
767
/**
768
  * @brief  Get the specific FLASH error flag.
769
  * @retval FLASH_ErrorCode The returned value can be:
770
  *            @ref FLASH_Error_Codes
771
  */
772
uint32_t HAL_FLASH_GetError(void)
773
{
774
   return pFlash.ErrorCode;
775
}
776
 
777
/**
778
  * @}
779
  */
780
 
781
/**
782
  * @}
783
  */
784
 
785
/** @addtogroup FLASH_Private_Functions
786
 * @{
787
 */
788
 
789
/**
790
  * @brief  Program a half-word (16-bit) at a specified address.
791
  * @param  Address specify the address to be programmed.
792
  * @param  Data    specify the data to be programmed.
793
  * @retval None
794
  */
795
static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data)
796
{
797
  /* Clean the error context */
798
  pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
799
 
800
#if defined(FLASH_BANK2_END)
801
  if(Address <= FLASH_BANK1_END)
802
  {
803
#endif /* FLASH_BANK2_END */
804
    /* Proceed to program the new data */
805
    SET_BIT(FLASH->CR, FLASH_CR_PG);
806
#if defined(FLASH_BANK2_END)
807
  }
808
  else
809
  {
810
    /* Proceed to program the new data */
811
    SET_BIT(FLASH->CR2, FLASH_CR2_PG);
812
  }
813
#endif /* FLASH_BANK2_END */
814
 
815
  /* Write data in the address */
816
  *(__IO uint16_t*)Address = Data;
817
}
818
 
819
/**
820
  * @brief  Wait for a FLASH operation to complete.
821
  * @param  Timeout  maximum flash operation timeout
822
  * @retval HAL Status
823
  */
824
HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
825
{
826
  /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
827
     Even if the FLASH operation fails, the BUSY flag will be reset and an error
828
     flag will be set */
829
 
830
  uint32_t tickstart = HAL_GetTick();
831
 
832
  while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY))
833
  {
834
    if (Timeout != HAL_MAX_DELAY)
835
    {
836
      if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout))
837
      {
838
        return HAL_TIMEOUT;
839
      }
840
    }
841
  }
842
 
843
  /* Check FLASH End of Operation flag  */
844
  if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
845
  {
846
    /* Clear FLASH End of Operation pending bit */
847
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
848
  }
849
 
850
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)  ||
851
     __HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR) ||
852
     __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR))
853
  {
854
    /*Save the error code*/
855
    FLASH_SetErrorCode();
856
    return HAL_ERROR;
857
  }
858
 
859
  /* There is no error flag set */
860
  return HAL_OK;
861
}
862
 
863
#if defined(FLASH_BANK2_END)
864
/**
865
  * @brief  Wait for a FLASH BANK2 operation to complete.
866
  * @param  Timeout maximum flash operation timeout
867
  * @retval HAL_StatusTypeDef HAL Status
868
  */
869
HAL_StatusTypeDef FLASH_WaitForLastOperationBank2(uint32_t Timeout)
870
{
871
  /* Wait for the FLASH BANK2 operation to complete by polling on BUSY flag to be reset.
872
     Even if the FLASH BANK2 operation fails, the BUSY flag will be reset and an error
873
     flag will be set */
874
 
875
  uint32_t tickstart = HAL_GetTick();
876
 
877
  while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY_BANK2))
878
  {
879
    if (Timeout != HAL_MAX_DELAY)
880
    {
881
      if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout))
882
      {
883
        return HAL_TIMEOUT;
884
      }
885
    }
886
  }
887
 
888
  /* Check FLASH End of Operation flag  */
889
  if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP_BANK2))
890
  {
891
    /* Clear FLASH End of Operation pending bit */
892
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK2);
893
  }
894
 
895
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK2) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK2))
896
  {
897
    /*Save the error code*/
898
    FLASH_SetErrorCode();
899
    return HAL_ERROR;
900
  }
901
 
902
  /* If there is an error flag set */
903
  return HAL_OK;
904
 
905
}
906
#endif /* FLASH_BANK2_END */
907
 
908
/**
909
  * @brief  Set the specific FLASH error flag.
910
  * @retval None
911
  */
912
static void FLASH_SetErrorCode(void)
913
{
914
  uint32_t flags = 0U;
915
 
916
#if defined(FLASH_BANK2_END)
917
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK2))
918
#else
919
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR))
920
#endif /* FLASH_BANK2_END */
921
  {
922
    pFlash.ErrorCode |= HAL_FLASH_ERROR_WRP;
923
#if defined(FLASH_BANK2_END)
924
    flags |= FLASH_FLAG_WRPERR | FLASH_FLAG_WRPERR_BANK2;
925
#else
926
    flags |= FLASH_FLAG_WRPERR;
927
#endif /* FLASH_BANK2_END */
928
  }
929
#if defined(FLASH_BANK2_END)
930
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK2))
931
#else
932
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR))
933
#endif /* FLASH_BANK2_END */
934
  {
935
    pFlash.ErrorCode |= HAL_FLASH_ERROR_PROG;
936
#if defined(FLASH_BANK2_END)
937
    flags |= FLASH_FLAG_PGERR | FLASH_FLAG_PGERR_BANK2;
938
#else
939
    flags |= FLASH_FLAG_PGERR;
940
#endif /* FLASH_BANK2_END */
941
  }
942
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR))
943
  {
944
    pFlash.ErrorCode |= HAL_FLASH_ERROR_OPTV;
945
  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
946
  }
947
 
948
  /* Clear FLASH error pending bits */
949
  __HAL_FLASH_CLEAR_FLAG(flags);
950
}  
951
/**
952
  * @}
953
  */
954
 
955
/**
956
  * @}
957
  */
958
 
959
#endif /* HAL_FLASH_MODULE_ENABLED */
960
 
961
/**
962
  * @}
963
  */
964