Subversion Repositories EngineBay2

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 1
/**
2
  ******************************************************************************
3
  * @file    stm32l1xx_hal_flash_ex.c
4
  * @author  MCD Application Team
5
  * @brief   Extended FLASH HAL module driver.
28 mjames 6
  *
7
  *          This file provides firmware functions to manage the following
2 mjames 8
  *          functionalities of the internal FLASH memory:
9
  *            + FLASH Interface configuration
10
  *            + FLASH Memory Erasing
11
  *            + DATA EEPROM Programming/Erasing
12
  *            + Option Bytes Programming
13
  *            + Interrupts management
28 mjames 14
  *
2 mjames 15
  @verbatim
16
  ==============================================================================
17
               ##### Flash peripheral Extended features  #####
18
  ==============================================================================
28 mjames 19
 
2 mjames 20
  [..] Comparing to other products, the FLASH interface for STM32L1xx
28 mjames 21
       devices contains the following additional features
2 mjames 22
       (+) Erase functions
23
       (+) DATA_EEPROM memory management
28 mjames 24
       (+) BOOT option bit configuration
2 mjames 25
       (+) PCROP protection for all sectors
28 mjames 26
 
2 mjames 27
                      ##### How to use this driver #####
28
  ==============================================================================
28 mjames 29
  [..] This driver provides functions to configure and program the FLASH memory
2 mjames 30
       of all STM32L1xx. It includes:
31
       (+) Full DATA_EEPROM erase and program management
32
       (+) Boot activation
33
       (+) PCROP protection configuration and control for all pages
28 mjames 34
 
2 mjames 35
  @endverbatim
36
  ******************************************************************************
37
  * @attention
38
  *
28 mjames 39
  * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
40
  * All rights reserved.</center></h2>
2 mjames 41
  *
28 mjames 42
  * This software component is licensed by ST under BSD 3-Clause license,
43
  * the "License"; You may not use this file except in compliance with the
44
  * License. You may obtain a copy of the License at:
45
  *                        opensource.org/licenses/BSD-3-Clause
2 mjames 46
  *
28 mjames 47
  ******************************************************************************
48
  */
2 mjames 49
 
50
/* Includes ------------------------------------------------------------------*/
51
#include "stm32l1xx_hal.h"
52
 
53
/** @addtogroup STM32L1xx_HAL_Driver
54
  * @{
55
  */
56
#ifdef HAL_FLASH_MODULE_ENABLED
57
 
58
/** @addtogroup FLASH
59
  * @{
60
  */
61
/** @addtogroup FLASH_Private_Variables
62
 * @{
63
 */
64
/* Variables used for Erase pages under interruption*/
65
extern FLASH_ProcessTypeDef pFlash;
66
/**
67
  * @}
68
  */
69
 
70
/**
71
  * @}
72
  */
28 mjames 73
 
2 mjames 74
/** @defgroup FLASHEx FLASHEx
75
  * @brief FLASH HAL Extension module driver
76
  * @{
77
  */
78
 
79
/* Private typedef -----------------------------------------------------------*/
80
/* Private define ------------------------------------------------------------*/
81
/** @defgroup FLASHEx_Private_Constants FLASHEx Private Constants
82
 * @{
83
 */
84
/**
85
  * @}
86
  */
87
 
88
/* Private macro -------------------------------------------------------------*/
89
/** @defgroup FLASHEx_Private_Macros FLASHEx Private Macros
90
  * @{
91
  */
92
/**
93
  * @}
28 mjames 94
  */
2 mjames 95
 
96
/* Private variables ---------------------------------------------------------*/
97
/* Private function prototypes -----------------------------------------------*/
98
/** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions
99
 * @{
100
 */
101
void                      FLASH_PageErase(uint32_t PageAddress);
102
static HAL_StatusTypeDef  FLASH_OB_WRPConfig(FLASH_OBProgramInitTypeDef *pOBInit, FunctionalState NewState);
103
static void               FLASH_OB_WRPConfigWRP1OrPCROP1(uint32_t WRP1OrPCROP1, FunctionalState NewState);
104
#if defined(STM32L100xC) || defined(STM32L151xC) || defined(STM32L152xC) || defined(STM32L162xC)    \
105
 || defined(STM32L151xCA) || defined(STM32L151xD) || defined(STM32L151xDX) || defined(STM32L152xCA) \
106
 || defined(STM32L152xD) || defined(STM32L152xDX) || defined(STM32L162xCA) || defined(STM32L162xD)  \
107
 || defined(STM32L162xDX) || defined(STM32L151xE) || defined(STM32L152xE) || defined(STM32L162xE)
108
static void               FLASH_OB_WRPConfigWRP2OrPCROP2(uint32_t WRP2OrPCROP2, FunctionalState NewState);
109
#endif /* STM32L100xC || STM32L151xC || STM32L152xC || (...) || STM32L151xE || STM32L152xE || STM32L162xE */
110
#if defined(STM32L151xD) || defined(STM32L151xDX) || defined(STM32L152xD) || defined(STM32L152xDX) \
111
 || defined(STM32L162xD) || defined(STM32L162xDX) || defined(STM32L151xE) || defined(STM32L152xE)   \
112
 || defined(STM32L162xE)
113
static void               FLASH_OB_WRPConfigWRP3(uint32_t WRP3, FunctionalState NewState);
114
#endif /* STM32L151xD || STM32L152xD || STM32L162xD || STM32L151xE || STM32L152xE || STM32L162xE */
115
#if defined(STM32L151xE) || defined(STM32L152xE) || defined(STM32L162xE) || defined(STM32L151xDX) \
116
 || defined(STM32L152xDX) || defined(STM32L162xDX)
117
static void               FLASH_OB_WRPConfigWRP4(uint32_t WRP4, FunctionalState NewState);
118
#endif /* STM32L151xE || STM32L152xE || STM32L151xDX || ... */
119
#if defined(FLASH_OBR_SPRMOD)
120
static HAL_StatusTypeDef  FLASH_OB_PCROPConfig(FLASH_AdvOBProgramInitTypeDef *pAdvOBInit, FunctionalState NewState);
121
#endif /* FLASH_OBR_SPRMOD */
122
#if defined(FLASH_OBR_nRST_BFB2)
123
static HAL_StatusTypeDef  FLASH_OB_BootConfig(uint8_t OB_BOOT);
124
#endif /* FLASH_OBR_nRST_BFB2 */
125
static HAL_StatusTypeDef  FLASH_OB_RDPConfig(uint8_t OB_RDP);
126
static HAL_StatusTypeDef  FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY);
127
static HAL_StatusTypeDef  FLASH_OB_BORConfig(uint8_t OB_BOR);
128
static uint8_t            FLASH_OB_GetRDP(void);
129
static uint8_t            FLASH_OB_GetUser(void);
130
static uint8_t            FLASH_OB_GetBOR(void);
131
static HAL_StatusTypeDef  FLASH_DATAEEPROM_FastProgramByte(uint32_t Address, uint8_t Data);
132
static HAL_StatusTypeDef  FLASH_DATAEEPROM_FastProgramHalfWord(uint32_t Address, uint16_t Data);
133
static HAL_StatusTypeDef  FLASH_DATAEEPROM_FastProgramWord(uint32_t Address, uint32_t Data);
134
static HAL_StatusTypeDef  FLASH_DATAEEPROM_ProgramWord(uint32_t Address, uint32_t Data);
135
static HAL_StatusTypeDef  FLASH_DATAEEPROM_ProgramHalfWord(uint32_t Address, uint16_t Data);
136
static HAL_StatusTypeDef  FLASH_DATAEEPROM_ProgramByte(uint32_t Address, uint8_t Data);
137
/**
138
  * @}
139
  */
140
 
141
/* Exported functions ---------------------------------------------------------*/
142
/** @defgroup FLASHEx_Exported_Functions FLASHEx Exported Functions
143
  * @{
144
  */
145
 
146
/** @defgroup FLASHEx_Exported_Functions_Group1 FLASHEx Memory Erasing functions
147
 *  @brief   FLASH Memory Erasing functions
148
 *
28 mjames 149
@verbatim
2 mjames 150
  ==============================================================================
28 mjames 151
                ##### FLASH Erasing Programming functions #####
2 mjames 152
  ==============================================================================
153
 
154
    [..] The FLASH Memory Erasing functions, includes the following functions:
155
    (+) @ref HAL_FLASHEx_Erase: return only when erase has been done
28 mjames 156
    (+) @ref HAL_FLASHEx_Erase_IT: end of erase is done when @ref HAL_FLASH_EndOfOperationCallback
2 mjames 157
        is called with parameter 0xFFFFFFFF
158
 
159
    [..] Any operation of erase should follow these steps:
28 mjames 160
    (#) Call the @ref HAL_FLASH_Unlock() function to enable the flash control register and
2 mjames 161
        program memory access.
162
    (#) Call the desired function to erase page.
28 mjames 163
    (#) Call the @ref HAL_FLASH_Lock() to disable the flash program memory access
2 mjames 164
       (recommended to protect the FLASH memory against possible unwanted operation).
165
 
166
@endverbatim
167
  * @{
168
  */
28 mjames 169
 
2 mjames 170
/**
28 mjames 171
  * @brief  Erase the specified FLASH memory Pages
2 mjames 172
  * @note   To correctly run this function, the @ref HAL_FLASH_Unlock() function
173
  *         must be called before.
28 mjames 174
  *         Call the @ref HAL_FLASH_Lock() to disable the flash memory access
2 mjames 175
  *         (recommended to protect the FLASH memory against possible unwanted operation)
176
  * @note   For STM32L151xDX/STM32L152xDX/STM32L162xDX, as memory is not continuous between
177
  *         2 banks, user should perform pages erase by bank only.
178
  * @param[in]  pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
179
  *         contains the configuration information for the erasing.
28 mjames 180
  *
2 mjames 181
  * @param[out]  PageError pointer to variable  that
182
  *         contains the configuration information on faulty page in case of error
183
  *         (0xFFFFFFFF means that all the pages have been correctly erased)
28 mjames 184
  *
2 mjames 185
  * @retval HAL_StatusTypeDef HAL Status
186
  */
187
HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError)
188
{
189
  HAL_StatusTypeDef status = HAL_ERROR;
28 mjames 190
  uint32_t address = 0U;
191
 
2 mjames 192
  /* Process Locked */
193
  __HAL_LOCK(&pFlash);
194
 
195
  /* Wait for last operation to be completed */
196
  status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
197
 
198
  if (status == HAL_OK)
199
  {
200
    /*Initialization of PageError variable*/
201
    *PageError = 0xFFFFFFFFU;
202
 
203
    /* Check the parameters */
204
    assert_param(IS_NBPAGES(pEraseInit->NbPages));
205
    assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
206
    assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress));
28 mjames 207
    assert_param(IS_FLASH_PROGRAM_ADDRESS((pEraseInit->PageAddress & ~(FLASH_PAGE_SIZE - 1U)) + pEraseInit->NbPages * FLASH_PAGE_SIZE - 1U));
2 mjames 208
 
209
#if defined(STM32L151xDX) || defined(STM32L152xDX) || defined(STM32L162xDX)
210
    /* Check on which bank belongs the 1st address to erase */
211
    if (pEraseInit->PageAddress < FLASH_BANK2_BASE)
212
    {
213
      /* BANK1 */
214
      /* Check that last page to erase still belongs to BANK1 */
28 mjames 215
      if (((pEraseInit->PageAddress & ~(FLASH_PAGE_SIZE - 1U)) + pEraseInit->NbPages * FLASH_PAGE_SIZE - 1U) > FLASH_BANK1_END)
2 mjames 216
      {
217
        /*  Last page does not belong to BANK1, erase procedure cannot be performed because memory is not
218
            continuous */
219
        /* Process Unlocked */
220
        __HAL_UNLOCK(&pFlash);
221
        return HAL_ERROR;
222
      }
223
    }
224
    else
225
    {
226
      /* BANK2 */
227
      /* Check that last page to erase still belongs to BANK2 */
28 mjames 228
      if (((pEraseInit->PageAddress & ~(FLASH_PAGE_SIZE - 1U)) + pEraseInit->NbPages * FLASH_PAGE_SIZE - 1U) > FLASH_BANK2_END)
2 mjames 229
      {
230
        /*  Last page does not belong to BANK2, erase procedure cannot be performed because memory is not
231
            continuous */
232
        /* Process Unlocked */
233
        __HAL_UNLOCK(&pFlash);
234
        return HAL_ERROR;
235
      }
236
    }
237
#endif /* STM32L151xDX || STM32L152xDX || STM32L162xDX */
238
 
239
    /* Erase page by page to be done*/
28 mjames 240
    for(address = pEraseInit->PageAddress;
2 mjames 241
        address < ((pEraseInit->NbPages * FLASH_PAGE_SIZE) + pEraseInit->PageAddress);
242
        address += FLASH_PAGE_SIZE)
243
    {
244
      FLASH_PageErase(address);
245
 
246
      /* Wait for last operation to be completed */
247
      status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
248
 
249
      /* If the erase operation is completed, disable the ERASE Bit */
250
      CLEAR_BIT(FLASH->PECR, FLASH_PECR_PROG);
251
      CLEAR_BIT(FLASH->PECR, FLASH_PECR_ERASE);
252
 
28 mjames 253
      if (status != HAL_OK)
2 mjames 254
      {
255
        /* In case of error, stop erase procedure and return the faulty address */
256
        *PageError = address;
257
        break;
258
      }
259
    }
260
  }
261
 
262
  /* Process Unlocked */
263
  __HAL_UNLOCK(&pFlash);
264
 
265
  return status;
266
}
267
 
268
/**
269
  * @brief  Perform a page erase of the specified FLASH memory pages  with interrupt enabled
270
  * @note   To correctly run this function, the @ref HAL_FLASH_Unlock() function
271
  *         must be called before.
28 mjames 272
  *         Call the @ref HAL_FLASH_Lock() to disable the flash memory access
2 mjames 273
  *         (recommended to protect the FLASH memory against possible unwanted operation)
274
  *          End of erase is done when @ref HAL_FLASH_EndOfOperationCallback is called with parameter
275
  *          0xFFFFFFFF
276
  * @note   For STM32L151xDX/STM32L152xDX/STM32L162xDX, as memory is not continuous between
277
  *         2 banks, user should perform pages erase by bank only.
278
  * @param  pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
279
  *         contains the configuration information for the erasing.
28 mjames 280
  *
2 mjames 281
  * @retval HAL_StatusTypeDef HAL Status
282
  */
283
HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)
284
{
28 mjames 285
  HAL_StatusTypeDef status = HAL_ERROR;
2 mjames 286
 
287
  /* If procedure already ongoing, reject the next one */
288
  if (pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
289
  {
290
    return HAL_ERROR;
291
  }
292
 
293
  /* Check the parameters */
294
  assert_param(IS_NBPAGES(pEraseInit->NbPages));
295
  assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
296
  assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress));
28 mjames 297
  assert_param(IS_FLASH_PROGRAM_ADDRESS((pEraseInit->PageAddress & ~(FLASH_PAGE_SIZE - 1U)) + pEraseInit->NbPages * FLASH_PAGE_SIZE - 1U));
2 mjames 298
 
299
  /* Process Locked */
300
  __HAL_LOCK(&pFlash);
301
 
302
#if defined(STM32L151xDX) || defined(STM32L152xDX) || defined(STM32L162xDX)
303
    /* Check on which bank belongs the 1st address to erase */
304
    if (pEraseInit->PageAddress < FLASH_BANK2_BASE)
305
    {
306
      /* BANK1 */
307
      /* Check that last page to erase still belongs to BANK1 */
28 mjames 308
      if (((pEraseInit->PageAddress & ~(FLASH_PAGE_SIZE - 1U)) + pEraseInit->NbPages * FLASH_PAGE_SIZE - 1U) > FLASH_BANK1_END)
2 mjames 309
      {
310
        /*  Last page does not belong to BANK1, erase procedure cannot be performed because memory is not
311
            continuous */
312
        /* Process Unlocked */
313
        __HAL_UNLOCK(&pFlash);
314
        return HAL_ERROR;
315
      }
316
    }
317
    else
318
    {
319
      /* BANK2 */
320
      /* Check that last page to erase still belongs to BANK2 */
28 mjames 321
      if (((pEraseInit->PageAddress & ~(FLASH_PAGE_SIZE - 1U)) + pEraseInit->NbPages * FLASH_PAGE_SIZE - 1U) > FLASH_BANK2_END)
2 mjames 322
      {
323
        /*  Last page does not belong to BANK2, erase procedure cannot be performed because memory is not
324
            continuous */
325
        /* Process Unlocked */
326
        __HAL_UNLOCK(&pFlash);
327
        return HAL_ERROR;
328
      }
329
    }
330
#endif /* STM32L151xDX || STM32L152xDX || STM32L162xDX */
331
 
28 mjames 332
  /* Wait for last operation to be completed */
333
  status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
2 mjames 334
 
28 mjames 335
  if (status == HAL_OK)
336
  {
337
    /* Enable End of FLASH Operation and Error source interrupts */
338
    __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR);
2 mjames 339
 
28 mjames 340
    pFlash.ProcedureOnGoing = FLASH_PROC_PAGEERASE;
341
    pFlash.NbPagesToErase = pEraseInit->NbPages;
342
    pFlash.Page = pEraseInit->PageAddress;
343
 
344
    /*Erase 1st page and wait for IT*/
345
    FLASH_PageErase(pEraseInit->PageAddress);
346
  }
347
  else
348
  {
349
    /* Process Unlocked */
350
    __HAL_UNLOCK(&pFlash);
351
  }
352
 
2 mjames 353
  return status;
354
}
355
 
356
/**
357
  * @}
358
  */
359
 
360
/** @defgroup FLASHEx_Exported_Functions_Group2 Option Bytes Programming functions
361
 *  @brief   Option Bytes Programming functions
362
 *
28 mjames 363
@verbatim
2 mjames 364
  ==============================================================================
28 mjames 365
                ##### Option Bytes Programming functions #####
366
  ==============================================================================
2 mjames 367
 
368
    [..] Any operation of erase or program should follow these steps:
28 mjames 369
    (#) Call the @ref HAL_FLASH_OB_Unlock() function to enable the Flash option control
2 mjames 370
        register access.
371
    (#) Call following function to program the desired option bytes.
372
        (++) @ref HAL_FLASHEx_OBProgram:
373
         - To Enable/Disable the desired sector write protection.
374
         - To set the desired read Protection Level.
375
         - To configure the user option Bytes: IWDG, STOP and the Standby.
376
         - To Set the BOR level.
377
    (#) Once all needed option bytes to be programmed are correctly written, call the
378
        @ref HAL_FLASH_OB_Launch(void) function to launch the Option Bytes programming process.
379
    (#) Call the @ref HAL_FLASH_OB_Lock() to disable the Flash option control register access (recommended
380
        to protect the option Bytes against possible unwanted operations).
381
 
382
    [..] Proprietary code Read Out Protection (PcROP):
383
    (#) The PcROP sector is selected by using the same option bytes as the Write
384
        protection (nWRPi bits). As a result, these 2 options are exclusive each other.
28 mjames 385
    (#) In order to activate the PcROP (change the function of the nWRPi option bits),
2 mjames 386
        the SPRMOD option bit must be activated.
387
    (#) The active value of nWRPi bits is inverted when PCROP mode is active, this
388
        means: if SPRMOD = 1 and nWRPi = 1 (default value), then the user sector "i"
389
        is read/write protected.
390
    (#) To activate PCROP mode for Flash sector(s), you need to call the following function:
391
        (++) @ref HAL_FLASHEx_AdvOBProgram in selecting sectors to be read/write protected
392
        (++) @ref HAL_FLASHEx_OB_SelectPCROP to enable the read/write protection
393
    (#) PcROP is available only in STM32L151xBA, STM32L152xBA, STM32L151xC, STM32L152xC & STM32L162xC devices.
394
 
395
@endverbatim
396
  * @{
397
  */
398
 
399
/**
400
  * @brief  Program option bytes
401
  * @param  pOBInit pointer to an FLASH_OBInitStruct structure that
402
  *         contains the configuration information for the programming.
28 mjames 403
  *
2 mjames 404
  * @retval HAL_StatusTypeDef HAL Status
405
  */
406
HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
407
{
408
  HAL_StatusTypeDef status = HAL_ERROR;
28 mjames 409
 
2 mjames 410
  /* Process Locked */
411
  __HAL_LOCK(&pFlash);
412
 
413
  /* Check the parameters */
414
  assert_param(IS_OPTIONBYTE(pOBInit->OptionType));
415
 
416
  /*Write protection configuration*/
417
  if((pOBInit->OptionType & OPTIONBYTE_WRP) == OPTIONBYTE_WRP)
418
  {
419
    assert_param(IS_WRPSTATE(pOBInit->WRPState));
420
    if (pOBInit->WRPState == OB_WRPSTATE_ENABLE)
421
    {
422
      /* Enable of Write protection on the selected Sector*/
423
      status = FLASH_OB_WRPConfig(pOBInit, ENABLE);
424
    }
425
    else
426
    {
427
      /* Disable of Write protection on the selected Sector*/
428
      status = FLASH_OB_WRPConfig(pOBInit, DISABLE);
429
    }
430
    if (status != HAL_OK)
431
    {
432
      /* Process Unlocked */
433
      __HAL_UNLOCK(&pFlash);
434
      return status;
435
    }
436
  }
28 mjames 437
 
2 mjames 438
  /* Read protection configuration*/
439
  if((pOBInit->OptionType & OPTIONBYTE_RDP) == OPTIONBYTE_RDP)
440
  {
441
    status = FLASH_OB_RDPConfig(pOBInit->RDPLevel);
442
    if (status != HAL_OK)
443
    {
444
      /* Process Unlocked */
445
      __HAL_UNLOCK(&pFlash);
446
      return status;
447
    }
448
  }
28 mjames 449
 
2 mjames 450
  /* USER  configuration*/
451
  if((pOBInit->OptionType & OPTIONBYTE_USER) == OPTIONBYTE_USER)
452
  {
28 mjames 453
    status = FLASH_OB_UserConfig(pOBInit->USERConfig & OB_IWDG_SW,
2 mjames 454
                                 pOBInit->USERConfig & OB_STOP_NORST,
455
                                 pOBInit->USERConfig & OB_STDBY_NORST);
456
    if (status != HAL_OK)
457
    {
458
      /* Process Unlocked */
459
      __HAL_UNLOCK(&pFlash);
460
      return status;
461
    }
462
  }
463
 
464
  /* BOR Level  configuration*/
465
  if((pOBInit->OptionType & OPTIONBYTE_BOR) == OPTIONBYTE_BOR)
466
  {
467
    status = FLASH_OB_BORConfig(pOBInit->BORLevel);
468
    if (status != HAL_OK)
469
    {
470
      /* Process Unlocked */
471
      __HAL_UNLOCK(&pFlash);
472
      return status;
473
    }
474
  }
475
  /* Process Unlocked */
476
  __HAL_UNLOCK(&pFlash);
477
 
478
  return status;
479
}
480
 
481
/**
482
  * @brief   Get the Option byte configuration
483
  * @param  pOBInit pointer to an FLASH_OBInitStruct structure that
484
  *         contains the configuration information for the programming.
28 mjames 485
  *
2 mjames 486
  * @retval None
487
  */
488
void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
489
{
490
  pOBInit->OptionType = OPTIONBYTE_WRP | OPTIONBYTE_RDP | OPTIONBYTE_USER | OPTIONBYTE_BOR;
491
 
492
  /*Get WRP1*/
493
  pOBInit->WRPSector0To31 = (uint32_t)(FLASH->WRPR1);
494
 
495
#if defined(STM32L100xC) || defined(STM32L151xC) || defined(STM32L152xC) || defined(STM32L162xC)    \
496
 || defined(STM32L151xCA) || defined(STM32L151xD) || defined(STM32L151xDX) || defined(STM32L152xCA) \
497
 || defined(STM32L152xD) || defined(STM32L152xDX) || defined(STM32L162xCA) || defined(STM32L162xD)  \
498
 || defined(STM32L162xDX) || defined(STM32L151xE) || defined(STM32L152xE) || defined(STM32L162xE)
28 mjames 499
 
2 mjames 500
  /*Get WRP2*/
501
  pOBInit->WRPSector32To63 = (uint32_t)(FLASH->WRPR2);
502
 
503
#endif /* STM32L100xC || STM32L151xC || STM32L152xC || (...) || STM32L151xE || STM32L152xE || STM32L162xE */
28 mjames 504
 
2 mjames 505
#if defined(STM32L151xD) || defined(STM32L151xDX) || defined(STM32L152xD) || defined(STM32L152xDX) \
506
 || defined(STM32L162xD) || defined(STM32L162xDX) || defined(STM32L151xE) || defined(STM32L152xE)  \
507
 || defined(STM32L162xE)
28 mjames 508
 
2 mjames 509
  /*Get WRP3*/
510
  pOBInit->WRPSector64To95 = (uint32_t)(FLASH->WRPR3);
511
 
512
#endif /* STM32L151xD || STM32L152xD || STM32L162xD || STM32L151xE || STM32L152xE || STM32L162xE */
28 mjames 513
 
2 mjames 514
#if defined(STM32L151xE) || defined(STM32L152xE) || defined(STM32L162xE) || defined(STM32L151xDX) \
515
 || defined(STM32L152xDX) || defined(STM32L162xDX)
516
 
517
  /*Get WRP4*/
518
  pOBInit->WRPSector96To127 = (uint32_t)(FLASH->WRPR4);
519
 
520
#endif /* STM32L151xE || STM32L152xE || STM32L162xE || STM32L151xDX || ... */
521
 
522
  /*Get RDP Level*/
523
  pOBInit->RDPLevel   = FLASH_OB_GetRDP();
524
 
525
  /*Get USER*/
526
  pOBInit->USERConfig = FLASH_OB_GetUser();
527
 
528
  /*Get BOR Level*/
529
  pOBInit->BORLevel   = FLASH_OB_GetBOR();
530
}
531
 
532
#if defined(FLASH_OBR_SPRMOD) || defined(FLASH_OBR_nRST_BFB2)
28 mjames 533
 
2 mjames 534
/**
535
  * @brief  Program option bytes
536
  * @note   This function can be used only for Cat2 & Cat3 devices for PCROP and Cat4 & Cat5 for BFB2.
537
  * @param  pAdvOBInit pointer to an FLASH_AdvOBProgramInitTypeDef structure that
538
  *         contains the configuration information for the programming.
28 mjames 539
  *
2 mjames 540
  * @retval HAL_StatusTypeDef HAL Status
541
  */
542
HAL_StatusTypeDef HAL_FLASHEx_AdvOBProgram (FLASH_AdvOBProgramInitTypeDef *pAdvOBInit)
543
{
544
  HAL_StatusTypeDef status = HAL_ERROR;
28 mjames 545
 
2 mjames 546
  /* Check the parameters */
547
  assert_param(IS_OBEX(pAdvOBInit->OptionType));
548
 
549
#if defined(FLASH_OBR_SPRMOD)
28 mjames 550
 
2 mjames 551
  /* Program PCROP option byte*/
552
  if ((pAdvOBInit->OptionType & OPTIONBYTE_PCROP) == OPTIONBYTE_PCROP)
553
  {
554
    /* Check the parameters */
555
    assert_param(IS_PCROPSTATE(pAdvOBInit->PCROPState));
556
    if (pAdvOBInit->PCROPState == OB_PCROP_STATE_ENABLE)
557
    {
558
      /*Enable of Write protection on the selected Sector*/
559
      status = FLASH_OB_PCROPConfig(pAdvOBInit, ENABLE);
560
      if (status != HAL_OK)
561
      {
562
        return status;
563
      }
564
    }
565
    else
566
    {
28 mjames 567
      /* Disable of Write protection on the selected Sector*/
2 mjames 568
      status = FLASH_OB_PCROPConfig(pAdvOBInit, DISABLE);
569
      if (status != HAL_OK)
570
      {
571
        return status;
572
      }
573
    }
574
  }
28 mjames 575
 
2 mjames 576
#endif /* FLASH_OBR_SPRMOD */
577
 
578
#if defined(FLASH_OBR_nRST_BFB2)
28 mjames 579
 
2 mjames 580
  /* Program BOOT config option byte */
581
  if ((pAdvOBInit->OptionType & OPTIONBYTE_BOOTCONFIG) == OPTIONBYTE_BOOTCONFIG)
582
  {
583
    status = FLASH_OB_BootConfig(pAdvOBInit->BootConfig);
584
  }
28 mjames 585
 
2 mjames 586
#endif /* FLASH_OBR_nRST_BFB2 */
587
 
588
  return status;
589
}
590
 
591
/**
592
  * @brief  Get the OBEX byte configuration
593
  * @note   This function can be used only for Cat2  & Cat3 devices for PCROP and Cat4 & Cat5 for BFB2.
594
  * @param  pAdvOBInit pointer to an FLASH_AdvOBProgramInitTypeDef structure that
595
  *         contains the configuration information for the programming.
28 mjames 596
  *
2 mjames 597
  * @retval None
598
  */
599
void HAL_FLASHEx_AdvOBGetConfig(FLASH_AdvOBProgramInitTypeDef *pAdvOBInit)
600
{
28 mjames 601
  pAdvOBInit->OptionType = 0U;
602
 
2 mjames 603
#if defined(FLASH_OBR_SPRMOD)
28 mjames 604
 
2 mjames 605
  pAdvOBInit->OptionType |= OPTIONBYTE_PCROP;
606
 
607
  /*Get PCROP state */
608
  pAdvOBInit->PCROPState = (FLASH->OBR & FLASH_OBR_SPRMOD) >> POSITION_VAL(FLASH_OBR_SPRMOD);
28 mjames 609
 
2 mjames 610
  /*Get PCROP protected sector from 0 to 31 */
611
  pAdvOBInit->PCROPSector0To31 = FLASH->WRPR1;
28 mjames 612
 
2 mjames 613
#if defined(STM32L100xC) || defined(STM32L151xC) || defined(STM32L152xC) || defined(STM32L162xC)
614
 
615
  /*Get PCROP protected sector from 32 to 63 */
616
  pAdvOBInit->PCROPSector32To63 = FLASH->WRPR2;
617
 
618
#endif /* STM32L100xC || STM32L151xC || STM32L152xC || STM32L162xC */
619
#endif /* FLASH_OBR_SPRMOD */
620
 
621
#if defined(FLASH_OBR_nRST_BFB2)
28 mjames 622
 
2 mjames 623
  pAdvOBInit->OptionType |= OPTIONBYTE_BOOTCONFIG;
624
 
625
  /* Get Boot config OB */
28 mjames 626
  pAdvOBInit->BootConfig = (FLASH->OBR & FLASH_OBR_nRST_BFB2) >> 16U;
2 mjames 627
 
628
#endif /* FLASH_OBR_nRST_BFB2 */
629
}
630
 
631
#endif /* FLASH_OBR_SPRMOD || FLASH_OBR_nRST_BFB2 */
632
 
633
#if defined(FLASH_OBR_SPRMOD)
634
 
635
/**
636
  * @brief  Select the Protection Mode (SPRMOD).
637
  * @note   This function can be used only for STM32L151xBA, STM32L152xBA, STM32L151xC, STM32L152xC & STM32L162xC devices
28 mjames 638
  * @note   Once SPRMOD bit is active, unprotection of a protected sector is not possible
2 mjames 639
  * @note   Read a protected sector will set RDERR Flag and write a protected sector will set WRPERR Flag
640
  * @retval HAL status
641
  */
642
HAL_StatusTypeDef HAL_FLASHEx_OB_SelectPCROP(void)
643
{
644
  HAL_StatusTypeDef status = HAL_OK;
28 mjames 645
  uint16_t tmp1 = 0U;
646
  uint32_t tmp2 = 0U;
647
  uint8_t optiontmp = 0U;
648
  uint16_t optiontmp2 = 0U;
649
 
2 mjames 650
  status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
28 mjames 651
 
2 mjames 652
  /* Mask RDP Byte */
28 mjames 653
  optiontmp =  (uint8_t)(*(__IO uint8_t *)(OB_BASE));
654
 
2 mjames 655
  /* Update Option Byte */
28 mjames 656
  optiontmp2 = (uint16_t)(OB_PCROP_SELECTED | optiontmp);
657
 
2 mjames 658
  /* calculate the option byte to write */
659
  tmp1 = (uint16_t)(~(optiontmp2 ));
28 mjames 660
  tmp2 = (uint32_t)(((uint32_t)((uint32_t)(tmp1) << 16U)) | ((uint32_t)optiontmp2));
661
 
2 mjames 662
  if(status == HAL_OK)
28 mjames 663
  {
2 mjames 664
    /* Clean the error context */
665
    pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
666
 
667
    /* program PCRop */
668
    OB->RDP = tmp2;
28 mjames 669
 
2 mjames 670
    /* Wait for last operation to be completed */
671
    status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
672
  }
28 mjames 673
 
2 mjames 674
  /* Return the Read protection operation Status */
28 mjames 675
  return status;
2 mjames 676
}
677
 
678
/**
679
  * @brief  Deselect the Protection Mode (SPRMOD).
680
  * @note   This function can be used only for STM32L151xBA, STM32L152xBA, STM32L151xC, STM32L152xC & STM32L162xC devices
28 mjames 681
  * @note   Once SPRMOD bit is active, unprotection of a protected sector is not possible
2 mjames 682
  * @note   Read a protected sector will set RDERR Flag and write a protected sector will set WRPERR Flag
683
  * @retval HAL status
684
  */
685
HAL_StatusTypeDef HAL_FLASHEx_OB_DeSelectPCROP(void)
686
{
687
  HAL_StatusTypeDef status = HAL_OK;
28 mjames 688
  uint16_t tmp1 = 0U;
689
  uint32_t tmp2 = 0U;
690
  uint8_t optiontmp = 0U;
691
  uint16_t optiontmp2 = 0U;
692
 
2 mjames 693
  status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
28 mjames 694
 
2 mjames 695
  /* Mask RDP Byte */
28 mjames 696
  optiontmp =  (uint8_t)(*(__IO uint8_t *)(OB_BASE));
697
 
2 mjames 698
  /* Update Option Byte */
28 mjames 699
  optiontmp2 = (uint16_t)(OB_PCROP_DESELECTED | optiontmp);
700
 
2 mjames 701
  /* calculate the option byte to write */
702
  tmp1 = (uint16_t)(~(optiontmp2 ));
28 mjames 703
  tmp2 = (uint32_t)(((uint32_t)((uint32_t)(tmp1) << 16U)) | ((uint32_t)optiontmp2));
704
 
2 mjames 705
  if(status == HAL_OK)
28 mjames 706
  {
2 mjames 707
    /* Clean the error context */
708
    pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
709
 
710
    /* program PCRop */
711
    OB->RDP = tmp2;
28 mjames 712
 
2 mjames 713
    /* Wait for last operation to be completed */
714
    status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
715
  }
28 mjames 716
 
2 mjames 717
  /* Return the Read protection operation Status */
28 mjames 718
  return status;
2 mjames 719
}
720
 
721
#endif /* FLASH_OBR_SPRMOD */
722
 
723
/**
724
  * @}
725
  */
726
 
727
/** @defgroup FLASHEx_Exported_Functions_Group3 DATA EEPROM Programming functions
728
 *  @brief   DATA EEPROM Programming functions
729
 *
28 mjames 730
@verbatim
2 mjames 731
 ===============================================================================
28 mjames 732
                     ##### DATA EEPROM Programming functions #####
733
 ===============================================================================
734
 
2 mjames 735
    [..] Any operation of erase or program should follow these steps:
736
    (#) Call the @ref HAL_FLASHEx_DATAEEPROM_Unlock() function to enable the data EEPROM access
737
        and Flash program erase control register access.
738
    (#) Call the desired function to erase or program data.
739
    (#) Call the @ref HAL_FLASHEx_DATAEEPROM_Lock() to disable the data EEPROM access
740
        and Flash program erase control register access(recommended
741
        to protect the DATA_EEPROM against possible unwanted operation).
742
 
743
@endverbatim
744
  * @{
745
  */
746
 
747
/**
748
  * @brief  Unlocks the data memory and FLASH_PECR register access.
749
  * @retval HAL_StatusTypeDef HAL Status
750
  */
751
HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Unlock(void)
752
{
753
  if((FLASH->PECR & FLASH_PECR_PELOCK) != RESET)
28 mjames 754
  {
2 mjames 755
    /* Unlocking the Data memory and FLASH_PECR register access*/
756
    FLASH->PEKEYR = FLASH_PEKEY1;
757
    FLASH->PEKEYR = FLASH_PEKEY2;
758
  }
759
  else
760
  {
761
    return HAL_ERROR;
762
  }
28 mjames 763
  return HAL_OK;
2 mjames 764
}
765
 
766
/**
767
  * @brief  Locks the Data memory and FLASH_PECR register access.
768
  * @retval HAL_StatusTypeDef HAL Status
769
  */
770
HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Lock(void)
771
{
772
  /* Set the PELOCK Bit to lock the data memory and FLASH_PECR register access */
773
  SET_BIT(FLASH->PECR, FLASH_PECR_PELOCK);
28 mjames 774
 
2 mjames 775
  return HAL_OK;
776
}
777
 
778
/**
779
  * @brief  Erase a word in data memory.
780
  * @param  Address specifies the address to be erased.
781
  * @param  TypeErase  Indicate the way to erase at a specified address.
782
  *         This parameter can be a value of @ref FLASH_Type_Program
783
  * @note   To correctly run this function, the @ref HAL_FLASHEx_DATAEEPROM_Unlock() function
784
  *         must be called before.
785
  *         Call the @ref HAL_FLASHEx_DATAEEPROM_Lock() to the data EEPROM access
28 mjames 786
  *         and Flash program erase control register access(recommended to protect
2 mjames 787
  *         the DATA_EEPROM against possible unwanted operation).
788
  * @retval HAL_StatusTypeDef HAL Status
789
  */
790
HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Erase(uint32_t TypeErase, uint32_t Address)
791
{
792
  HAL_StatusTypeDef status = HAL_OK;
28 mjames 793
 
2 mjames 794
  /* Check the parameters */
28 mjames 795
  assert_param(IS_TYPEERASEDATA(TypeErase));
2 mjames 796
  assert_param(IS_FLASH_DATA_ADDRESS(Address));
28 mjames 797
 
2 mjames 798
  /* Wait for last operation to be completed */
799
  status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
28 mjames 800
 
2 mjames 801
  if(status == HAL_OK)
802
  {
803
    /* Clean the error context */
804
    pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
805
 
806
    if(TypeErase == FLASH_TYPEERASEDATA_WORD)
807
    {
808
      /* Write 00000000h to valid address in the data memory */
28 mjames 809
      *(__IO uint32_t *) Address = 0x00000000U;
2 mjames 810
    }
811
 
812
    if(TypeErase == FLASH_TYPEERASEDATA_HALFWORD)
813
    {
814
      /* Write 0000h to valid address in the data memory */
815
      *(__IO uint16_t *) Address = (uint16_t)0x0000;
816
    }
817
 
818
    if(TypeErase == FLASH_TYPEERASEDATA_BYTE)
819
    {
820
      /* Write 00h to valid address in the data memory */
821
      *(__IO uint8_t *) Address = (uint8_t)0x00;
822
    }
823
 
824
    status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
825
  }
28 mjames 826
 
2 mjames 827
  /* Return the erase status */
828
  return status;
28 mjames 829
}
2 mjames 830
 
831
/**
832
  * @brief  Program word at a specified address
833
  * @note   To correctly run this function, the @ref HAL_FLASHEx_DATAEEPROM_Unlock() function
834
  *         must be called before.
835
  *         Call the @ref HAL_FLASHEx_DATAEEPROM_Unlock() to he data EEPROM access
28 mjames 836
  *         and Flash program erase control register access(recommended to protect
2 mjames 837
  *         the DATA_EEPROM against possible unwanted operation).
28 mjames 838
  * @note   The function @ref HAL_FLASHEx_DATAEEPROM_EnableFixedTimeProgram() can be called before
2 mjames 839
  *         this function to configure the Fixed Time Programming.
840
  * @param  TypeProgram  Indicate the way to program at a specified address.
841
  *         This parameter can be a value of @ref FLASHEx_Type_Program_Data
28 mjames 842
  * @param  Address  specifie the address to be programmed.
843
  * @param  Data     specifie the data to be programmed
844
  *
2 mjames 845
  * @retval HAL_StatusTypeDef HAL Status
846
  */
847
 
848
HAL_StatusTypeDef   HAL_FLASHEx_DATAEEPROM_Program(uint32_t TypeProgram, uint32_t Address, uint32_t Data)
849
{
850
  HAL_StatusTypeDef status = HAL_ERROR;
28 mjames 851
 
2 mjames 852
  /* Process Locked */
853
  __HAL_LOCK(&pFlash);
854
 
855
  /* Check the parameters */
856
  assert_param(IS_TYPEPROGRAMDATA(TypeProgram));
857
 
858
  /* Wait for last operation to be completed */
859
  status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
28 mjames 860
 
2 mjames 861
  if(status == HAL_OK)
862
  {
863
    /* Clean the error context */
864
    pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
865
 
28 mjames 866
    if(TypeProgram == FLASH_TYPEPROGRAMDATA_WORD)
2 mjames 867
    {
28 mjames 868
      /* Program word (32-bit) at a specified address.*/
869
      status = FLASH_DATAEEPROM_ProgramWord(Address, (uint32_t) Data);
870
    }
871
    else if(TypeProgram == FLASH_TYPEPROGRAMDATA_HALFWORD)
872
    {
873
      /* Program halfword (16-bit) at a specified address.*/
874
      status = FLASH_DATAEEPROM_ProgramHalfWord(Address, (uint16_t) Data);
875
    }
876
    else if(TypeProgram == FLASH_TYPEPROGRAMDATA_BYTE)
877
    {
878
      /* Program byte (8-bit) at a specified address.*/
879
      status = FLASH_DATAEEPROM_ProgramByte(Address, (uint8_t) Data);
880
    }
881
    else if(TypeProgram == FLASH_TYPEPROGRAMDATA_FASTBYTE)
882
    {
2 mjames 883
      /*Program word (8-bit) at a specified address.*/
884
      status = FLASH_DATAEEPROM_FastProgramByte(Address, (uint8_t) Data);
885
    }
28 mjames 886
    else if(TypeProgram == FLASH_TYPEPROGRAMDATA_FASTHALFWORD)
2 mjames 887
    {
888
      /* Program halfword (16-bit) at a specified address.*/
889
      status = FLASH_DATAEEPROM_FastProgramHalfWord(Address, (uint16_t) Data);
28 mjames 890
    }
891
    else if(TypeProgram == FLASH_TYPEPROGRAMDATA_FASTWORD)
2 mjames 892
    {
893
      /* Program word (32-bit) at a specified address.*/
894
      status = FLASH_DATAEEPROM_FastProgramWord(Address, (uint32_t) Data);
895
    }
28 mjames 896
    else
2 mjames 897
    {
28 mjames 898
      status = HAL_ERROR;
2 mjames 899
    }
28 mjames 900
 
2 mjames 901
  }
28 mjames 902
 
2 mjames 903
  /* Process Unlocked */
904
  __HAL_UNLOCK(&pFlash);
905
 
906
  return status;
907
}
908
 
909
/**
910
  * @brief  Enable DATA EEPROM fixed Time programming (2*Tprog).
911
  * @retval None
912
  */
913
void HAL_FLASHEx_DATAEEPROM_EnableFixedTimeProgram(void)
914
{
915
  SET_BIT(FLASH->PECR, FLASH_PECR_FTDW);
916
}
917
 
918
/**
919
  * @brief  Disables DATA EEPROM fixed Time programming (2*Tprog).
920
  * @retval None
921
  */
922
void HAL_FLASHEx_DATAEEPROM_DisableFixedTimeProgram(void)
923
{
924
  CLEAR_BIT(FLASH->PECR, FLASH_PECR_FTDW);
925
}
926
 
927
/**
928
  * @}
929
  */
930
 
931
/**
932
  * @}
933
  */
934
 
935
/** @addtogroup FLASHEx_Private_Functions
936
 * @{
937
 */
938
 
939
/*
940
==============================================================================
941
              OPTIONS BYTES
942
==============================================================================
943
*/
944
/**
945
  * @brief  Enables or disables the read out protection.
946
  * @note   To correctly run this function, the @ref HAL_FLASH_OB_Unlock() function
947
  *         must be called before.
28 mjames 948
  * @param  OB_RDP specifies the read protection level.
2 mjames 949
  *   This parameter can be:
950
  *     @arg @ref OB_RDP_LEVEL_0 No protection
951
  *     @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
952
  *     @arg @ref OB_RDP_LEVEL_2 Chip protection
28 mjames 953
  *
2 mjames 954
  *  !!!Warning!!! When enabling OB_RDP_LEVEL_2 it's no more possible to go back to level 1 or 0
28 mjames 955
  *
2 mjames 956
  * @retval HAL status
957
  */
958
static HAL_StatusTypeDef FLASH_OB_RDPConfig(uint8_t OB_RDP)
959
{
960
  HAL_StatusTypeDef status = HAL_OK;
28 mjames 961
  uint32_t tmp1 = 0U, tmp2 = 0U, tmp3 = 0U;
962
 
2 mjames 963
  /* Check the parameters */
964
  assert_param(IS_OB_RDP(OB_RDP));
28 mjames 965
 
2 mjames 966
  tmp1 = (uint32_t)(OB->RDP & FLASH_OBR_RDPRT);
28 mjames 967
 
2 mjames 968
  /* According to errata sheet, DocID022054 Rev 5, par2.1.5
969
  Before setting Level0 in the RDP register, check that the current level is not equal to Level0.
970
  If the current level is not equal to Level0, Level0 can be activated.
971
  If the current level is Level0 then the RDP register must not be written again with Level0. */
28 mjames 972
 
2 mjames 973
  if ((tmp1 == OB_RDP_LEVEL_0) && (OB_RDP == OB_RDP_LEVEL_0))
974
  {
975
    /*current level is Level0 then the RDP register must not be written again with Level0. */
976
    status = HAL_ERROR;
977
  }
28 mjames 978
  else
2 mjames 979
  {
980
#if defined(FLASH_OBR_SPRMOD)
981
    /* Mask SPRMOD bit */
982
    tmp3 = (uint32_t)(OB->RDP & FLASH_OBR_SPRMOD);
983
#endif
984
 
985
    /* calculate the option byte to write */
986
    tmp1 = (~((uint32_t)(OB_RDP | tmp3)));
28 mjames 987
    tmp2 = (uint32_t)(((uint32_t)((uint32_t)(tmp1) << 16U)) | ((uint32_t)(OB_RDP | tmp3)));
2 mjames 988
 
989
    /* Wait for last operation to be completed */
990
    status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
991
 
992
    if(status == HAL_OK)
993
    {
994
      /* Clean the error context */
995
      pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
996
 
997
      /* program read protection level */
998
      OB->RDP = tmp2;
999
 
1000
      /* Wait for last operation to be completed */
1001
      status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1002
    }
1003
  }
1004
 
1005
  /* Return the Read protection operation Status */
1006
  return status;
1007
}
1008
 
1009
/**
1010
  * @brief  Programs the FLASH brownout reset threshold level Option Byte.
1011
  * @param  OB_BOR Selects the brownout reset threshold level.
1012
  *   This parameter can be one of the following values:
28 mjames 1013
  *     @arg @ref OB_BOR_OFF BOR is disabled at power down, the reset is asserted when the VDD
2 mjames 1014
  *                      power supply reaches the PDR(Power Down Reset) threshold (1.5V)
1015
  *     @arg @ref OB_BOR_LEVEL1 BOR Reset threshold levels for 1.7V - 1.8V VDD power supply
1016
  *     @arg @ref OB_BOR_LEVEL2 BOR Reset threshold levels for 1.9V - 2.0V VDD power supply
1017
  *     @arg @ref OB_BOR_LEVEL3 BOR Reset threshold levels for 2.3V - 2.4V VDD power supply
1018
  *     @arg @ref OB_BOR_LEVEL4 BOR Reset threshold levels for 2.55V - 2.65V VDD power supply
1019
  *     @arg @ref OB_BOR_LEVEL5 BOR Reset threshold levels for 2.8V - 2.9V VDD power supply
1020
  * @retval HAL status
1021
  */
1022
static HAL_StatusTypeDef FLASH_OB_BORConfig(uint8_t OB_BOR)
1023
{
1024
  HAL_StatusTypeDef status = HAL_OK;
28 mjames 1025
  uint32_t tmp = 0U, tmp1 = 0U;
2 mjames 1026
 
1027
  /* Check the parameters */
1028
  assert_param(IS_OB_BOR_LEVEL(OB_BOR));
1029
 
1030
  /* Get the User Option byte register */
28 mjames 1031
  tmp1 = OB->USER & ((~FLASH_OBR_BOR_LEV) >> 16U);
2 mjames 1032
 
28 mjames 1033
  /* Calculate the option byte to write - [0xFFU | nUSER | 0x00U | USER]*/
1034
  tmp = (uint32_t)~((OB_BOR | tmp1)) << 16U;
2 mjames 1035
  tmp |= (OB_BOR | tmp1);
28 mjames 1036
 
2 mjames 1037
  /* Wait for last operation to be completed */
1038
  status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
28 mjames 1039
 
2 mjames 1040
  if(status == HAL_OK)
28 mjames 1041
  {
2 mjames 1042
    /* Clean the error context */
1043
    pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
1044
 
28 mjames 1045
    /* Write the BOR Option Byte */
2 mjames 1046
    OB->USER = tmp;
1047
 
1048
    /* Wait for last operation to be completed */
1049
    status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1050
  }
28 mjames 1051
 
1052
  /* Return the Option Byte BOR Programming Status */
2 mjames 1053
  return status;
1054
}
1055
 
1056
/**
1057
  * @brief  Returns the FLASH User Option Bytes values.
1058
  * @retval The FLASH User Option Bytes.
1059
  */
1060
static uint8_t FLASH_OB_GetUser(void)
1061
{
1062
  /* Return the User Option Byte */
28 mjames 1063
  return (uint8_t)((FLASH->OBR & (FLASH_OBR_IWDG_SW | FLASH_OBR_nRST_STOP | FLASH_OBR_nRST_STDBY)) >> 16U);
2 mjames 1064
}
1065
 
1066
/**
1067
  * @brief  Returns the FLASH Read Protection level.
1068
  * @retval FLASH RDP level
1069
  *         This parameter can be one of the following values:
1070
  *            @arg @ref OB_RDP_LEVEL_0 No protection
1071
  *            @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
1072
  *            @arg @ref OB_RDP_LEVEL_2 Full chip protection
1073
  */
1074
static uint8_t FLASH_OB_GetRDP(void)
1075
{
28 mjames 1076
  uint8_t rdp_level = (uint8_t)(FLASH->OBR & FLASH_OBR_RDPRT);
1077
 
1078
  if ((rdp_level != OB_RDP_LEVEL_0) && (rdp_level != OB_RDP_LEVEL_2))
1079
  {
1080
    return (OB_RDP_LEVEL_1);
1081
  }
1082
  else
1083
  {
1084
    return (rdp_level);
1085
  }
2 mjames 1086
}
1087
 
1088
/**
1089
  * @brief  Returns the FLASH BOR level.
1090
  * @retval The BOR level Option Bytes.
1091
  */
1092
static uint8_t FLASH_OB_GetBOR(void)
1093
{
1094
  /* Return the BOR level */
28 mjames 1095
  return (uint8_t)((FLASH->OBR & (uint32_t)FLASH_OBR_BOR_LEV) >> 16U);
2 mjames 1096
}
1097
 
1098
/**
1099
  * @brief  Write protects the desired pages of the first 64KB of the Flash.
1100
  * @param  pOBInit pointer to an FLASH_OBInitStruct structure that
1101
  *         contains WRP parameters.
1102
  * @param  NewState new state of the specified FLASH Pages Wtite protection.
1103
  *   This parameter can be: ENABLE or DISABLE.
1104
  * @retval HAL_StatusTypeDef
1105
  */
1106
static HAL_StatusTypeDef FLASH_OB_WRPConfig(FLASH_OBProgramInitTypeDef *pOBInit, FunctionalState NewState)
1107
{
1108
  HAL_StatusTypeDef status = HAL_OK;
28 mjames 1109
 
2 mjames 1110
  /* Wait for last operation to be completed */
1111
  status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
28 mjames 1112
 
2 mjames 1113
  if(status == HAL_OK)
1114
  {
1115
    /* Clean the error context */
1116
    pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
1117
 
1118
    /* WRP for sector between 0 to 31 */
28 mjames 1119
    if (pOBInit->WRPSector0To31 != 0U)
2 mjames 1120
    {
1121
      FLASH_OB_WRPConfigWRP1OrPCROP1(pOBInit->WRPSector0To31, NewState);
1122
    }
28 mjames 1123
 
2 mjames 1124
#if defined(STM32L100xC) || defined(STM32L151xC) || defined(STM32L152xC) || defined(STM32L162xC)    \
1125
 || defined(STM32L151xCA) || defined(STM32L151xD) || defined(STM32L151xDX) || defined(STM32L152xCA) \
1126
 || defined(STM32L152xD) || defined(STM32L152xDX) || defined(STM32L162xCA) || defined(STM32L162xD)  \
1127
 || defined(STM32L162xDX) || defined(STM32L151xE) || defined(STM32L152xE) || defined(STM32L162xE)
28 mjames 1128
 
2 mjames 1129
    /* Pages for Cat3, Cat4 & Cat5 devices*/
1130
    /* WRP for sector between 32 to 63 */
28 mjames 1131
    if (pOBInit->WRPSector32To63 != 0U)
2 mjames 1132
    {
1133
      FLASH_OB_WRPConfigWRP2OrPCROP2(pOBInit->WRPSector32To63, NewState);
1134
    }
28 mjames 1135
 
2 mjames 1136
#endif /* STM32L100xC || STM32L151xC || STM32L152xC || (...) || STM32L151xE || STM32L152xE || STM32L162xE */
1137
 
1138
#if defined(STM32L151xD) || defined(STM32L151xDX) || defined(STM32L152xD) || defined(STM32L152xDX) \
1139
 || defined(STM32L162xD) || defined(STM32L162xDX) || defined(STM32L151xE) || defined(STM32L152xE)  \
1140
 || defined(STM32L162xE)
28 mjames 1141
 
2 mjames 1142
    /* Pages for devices with FLASH >= 256KB*/
1143
    /* WRP for sector between 64 to 95 */
28 mjames 1144
    if (pOBInit->WRPSector64To95 != 0U)
2 mjames 1145
    {
1146
      FLASH_OB_WRPConfigWRP3(pOBInit->WRPSector64To95, NewState);
1147
    }
28 mjames 1148
 
2 mjames 1149
#endif /* STM32L151xD || STM32L152xD || STM32L162xD || STM32L151xE || STM32L152xE || STM32L162xE */
1150
 
1151
#if defined(STM32L151xE) || defined(STM32L152xE) || defined(STM32L162xE) || defined(STM32L151xDX) \
1152
 || defined(STM32L152xDX) || defined(STM32L162xDX)
1153
 
1154
    /* Pages for Cat5 devices*/
1155
    /* WRP for sector between 96 to 127 */
28 mjames 1156
    if (pOBInit->WRPSector96To127 != 0U)
2 mjames 1157
    {
1158
      FLASH_OB_WRPConfigWRP4(pOBInit->WRPSector96To127, NewState);
1159
    }
28 mjames 1160
 
2 mjames 1161
#endif /* STM32L151xE || STM32L152xE || STM32L162xE || STM32L151xDX || ... */
1162
 
1163
    /* Wait for last operation to be completed */
1164
    status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1165
  }
1166
 
1167
  /* Return the write protection operation Status */
28 mjames 1168
  return status;
2 mjames 1169
}
1170
 
1171
#if defined(STM32L151xBA) || defined(STM32L152xBA) || defined(STM32L151xC) || defined(STM32L152xC) \
1172
 || defined(STM32L162xC)
1173
/**
28 mjames 1174
  * @brief  Enables the read/write protection (PCROP) of the desired
2 mjames 1175
  *         sectors.
1176
  * @note   This function can be used only for Cat2 & Cat3 devices
1177
  * @param  pAdvOBInit pointer to an FLASH_AdvOBProgramInitTypeDef structure that
1178
  *         contains PCROP parameters.
1179
  * @param  NewState new state of the specified FLASH Pages read/Write protection.
1180
  *   This parameter can be: ENABLE or DISABLE.
1181
  * @retval HAL status
1182
  */
1183
static HAL_StatusTypeDef FLASH_OB_PCROPConfig(FLASH_AdvOBProgramInitTypeDef *pAdvOBInit, FunctionalState NewState)
1184
{
1185
  HAL_StatusTypeDef status = HAL_OK;
1186
  FunctionalState pcropstate = DISABLE;
28 mjames 1187
 
2 mjames 1188
  /* Wait for last operation to be completed */
1189
  status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
28 mjames 1190
 
2 mjames 1191
  /* Invert state to use same function of WRP */
1192
  if (NewState == DISABLE)
1193
  {
1194
    pcropstate = ENABLE;
1195
  }
28 mjames 1196
 
2 mjames 1197
  if(status == HAL_OK)
1198
  {
1199
    /* Clean the error context */
1200
    pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
1201
 
1202
    /* Pages for Cat2 devices*/
1203
    /* PCROP for sector between 0 to 31 */
28 mjames 1204
    if (pAdvOBInit->PCROPSector0To31 != 0U)
2 mjames 1205
    {
1206
      FLASH_OB_WRPConfigWRP1OrPCROP1(pAdvOBInit->PCROPSector0To31, pcropstate);
1207
    }
28 mjames 1208
 
2 mjames 1209
#if defined(STM32L100xC) || defined(STM32L151xC) || defined(STM32L152xC) || defined(STM32L162xC)
1210
 
1211
    /* Pages for Cat3 devices*/
1212
    /* WRP for sector between 32 to 63 */
28 mjames 1213
    if (pAdvOBInit->PCROPSector32To63 != 0U)
2 mjames 1214
    {
1215
      FLASH_OB_WRPConfigWRP2OrPCROP2(pAdvOBInit->PCROPSector32To63, pcropstate);
1216
    }
28 mjames 1217
 
2 mjames 1218
#endif /* STM32L100xC || STM32L151xC || STM32L152xC || STM32L162xC  */
28 mjames 1219
 
2 mjames 1220
    /* Wait for last operation to be completed */
1221
    status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1222
  }
1223
 
1224
  /* Return the write protection operation Status */
28 mjames 1225
  return status;
2 mjames 1226
}
1227
#endif /* STM32L151xBA || STM32L152xBA || STM32L151xC || STM32L152xC || STM32L162xC */
1228
 
1229
/**
1230
  * @brief  Write protects the desired pages of the first 128KB of the Flash.
1231
  * @param  WRP1OrPCROP1 specifies the address of the pages to be write protected.
1232
  *   This parameter can be a combination of @ref FLASHEx_Option_Bytes_Write_Protection1
1233
  * @param  NewState new state of the specified FLASH Pages Write protection.
1234
  *   This parameter can be: ENABLE or DISABLE.
1235
  * @retval None
1236
  */
1237
static void FLASH_OB_WRPConfigWRP1OrPCROP1(uint32_t WRP1OrPCROP1, FunctionalState NewState)
1238
{
28 mjames 1239
  uint32_t wrp01data = 0U, wrp23data = 0U;
1240
 
1241
  uint32_t tmp1 = 0U, tmp2 = 0U;
1242
 
2 mjames 1243
  /* Check the parameters */
1244
  assert_param(IS_OB_WRP(WRP1OrPCROP1));
1245
  assert_param(IS_FUNCTIONAL_STATE(NewState));
1246
 
1247
  if (NewState != DISABLE)
1248
  {
1249
    wrp01data = (uint16_t)(((WRP1OrPCROP1 & WRP_MASK_LOW) | OB->WRP01));
28 mjames 1250
    wrp23data = (uint16_t)((((WRP1OrPCROP1 & WRP_MASK_HIGH)>>16U | OB->WRP23)));
1251
    tmp1 = (uint32_t)(~(wrp01data) << 16U)|(wrp01data);
2 mjames 1252
    OB->WRP01 = tmp1;
1253
 
28 mjames 1254
    tmp2 = (uint32_t)(~(wrp23data) << 16U)|(wrp23data);
1255
    OB->WRP23 = tmp2;
2 mjames 1256
  }
1257
  else
1258
  {
1259
    wrp01data = (uint16_t)(~WRP1OrPCROP1 & (WRP_MASK_LOW & OB->WRP01));
28 mjames 1260
    wrp23data = (uint16_t)((((~WRP1OrPCROP1 & WRP_MASK_HIGH)>>16U & OB->WRP23)));
2 mjames 1261
 
28 mjames 1262
    tmp1 = (uint32_t)((~wrp01data) << 16U)|(wrp01data);
2 mjames 1263
    OB->WRP01 = tmp1;
28 mjames 1264
 
1265
    tmp2 = (uint32_t)((~wrp23data) << 16U)|(wrp23data);
2 mjames 1266
    OB->WRP23 = tmp2;
1267
  }
1268
}
1269
 
1270
#if defined(STM32L100xC) || defined(STM32L151xC) || defined(STM32L152xC) || defined(STM32L162xC)    \
1271
 || defined(STM32L151xCA) || defined(STM32L151xD) || defined(STM32L151xDX) || defined(STM32L152xCA) \
1272
 || defined(STM32L152xD) || defined(STM32L152xDX) || defined(STM32L162xCA) || defined(STM32L162xD)  \
1273
 || defined(STM32L162xDX) || defined(STM32L151xE) || defined(STM32L152xE) || defined(STM32L162xE)
1274
/**
1275
  * @brief  Enable Write protects the desired pages of the second 128KB of the Flash.
1276
  * @note   This function can be used only for Cat3, Cat4  & Cat5 devices.
1277
  * @param  WRP2OrPCROP2 specifies the address of the pages to be write protected.
1278
  *   This parameter can be a combination of @ref FLASHEx_Option_Bytes_Write_Protection2
1279
  * @param  NewState new state of the specified FLASH Pages Wtite protection.
1280
  *   This parameter can be: ENABLE or DISABLE.
1281
  * @retval None
1282
  */
1283
static void FLASH_OB_WRPConfigWRP2OrPCROP2(uint32_t WRP2OrPCROP2, FunctionalState NewState)
1284
{
28 mjames 1285
  uint32_t wrp45data = 0U, wrp67data = 0U;
1286
 
1287
  uint32_t tmp1 = 0U, tmp2 = 0U;
1288
 
2 mjames 1289
  /* Check the parameters */
1290
  assert_param(IS_OB_WRP(WRP2OrPCROP2));
1291
  assert_param(IS_FUNCTIONAL_STATE(NewState));
1292
 
1293
  if (NewState != DISABLE)
1294
  {
1295
    wrp45data = (uint16_t)(((WRP2OrPCROP2 & WRP_MASK_LOW) | OB->WRP45));
28 mjames 1296
    wrp67data = (uint16_t)((((WRP2OrPCROP2 & WRP_MASK_HIGH)>>16U | OB->WRP67)));
1297
    tmp1 = (uint32_t)(~(wrp45data) << 16U)|(wrp45data);
2 mjames 1298
    OB->WRP45 = tmp1;
28 mjames 1299
 
1300
    tmp2 = (uint32_t)(~(wrp67data) << 16U)|(wrp67data);
2 mjames 1301
    OB->WRP67 = tmp2;
1302
  }
1303
  else
1304
  {
1305
    wrp45data = (uint16_t)(~WRP2OrPCROP2 & (WRP_MASK_LOW & OB->WRP45));
28 mjames 1306
    wrp67data = (uint16_t)((((~WRP2OrPCROP2 & WRP_MASK_HIGH)>>16U & OB->WRP67)));
1307
 
1308
    tmp1 = (uint32_t)((~wrp45data) << 16U)|(wrp45data);
2 mjames 1309
    OB->WRP45 = tmp1;
28 mjames 1310
 
1311
    tmp2 = (uint32_t)((~wrp67data) << 16U)|(wrp67data);
2 mjames 1312
    OB->WRP67 = tmp2;
1313
  }
1314
}
1315
#endif /* STM32L100xC || STM32L151xC || STM32L152xC || (...) || STM32L151xE || STM32L152xE || STM32L162xE */
1316
 
1317
#if defined(STM32L151xD) || defined(STM32L151xDX) || defined(STM32L152xD) || defined(STM32L152xDX) \
1318
 || defined(STM32L162xD) || defined(STM32L162xDX) || defined(STM32L151xE) || defined(STM32L152xE)  \
1319
 || defined(STM32L162xE)
1320
/**
1321
  * @brief  Enable Write protects the desired pages of the third 128KB of the Flash.
1322
  * @note   This function can be used only for STM32L151xD, STM32L152xD, STM32L162xD  & Cat5 devices.
1323
  * @param  WRP3 specifies the address of the pages to be write protected.
1324
  *   This parameter can be a combination of @ref FLASHEx_Option_Bytes_Write_Protection3
1325
  * @param  NewState new state of the specified FLASH Pages Wtite protection.
1326
  *   This parameter can be: ENABLE or DISABLE.
1327
  * @retval None
1328
  */
1329
static void FLASH_OB_WRPConfigWRP3(uint32_t WRP3, FunctionalState NewState)
1330
{
28 mjames 1331
  uint32_t wrp89data = 0U, wrp1011data = 0U;
1332
 
1333
  uint32_t tmp1 = 0U, tmp2 = 0U;
1334
 
2 mjames 1335
  /* Check the parameters */
1336
  assert_param(IS_OB_WRP(WRP3));
1337
  assert_param(IS_FUNCTIONAL_STATE(NewState));
1338
 
1339
  if (NewState != DISABLE)
1340
  {
1341
    wrp89data = (uint16_t)(((WRP3 & WRP_MASK_LOW) | OB->WRP89));
28 mjames 1342
    wrp1011data = (uint16_t)((((WRP3 & WRP_MASK_HIGH)>>16U | OB->WRP1011)));
1343
    tmp1 = (uint32_t)(~(wrp89data) << 16U)|(wrp89data);
2 mjames 1344
    OB->WRP89 = tmp1;
1345
 
28 mjames 1346
    tmp2 = (uint32_t)(~(wrp1011data) << 16U)|(wrp1011data);
1347
    OB->WRP1011 = tmp2;
2 mjames 1348
  }
1349
  else
1350
  {
1351
    wrp89data = (uint16_t)(~WRP3 & (WRP_MASK_LOW & OB->WRP89));
28 mjames 1352
    wrp1011data = (uint16_t)((((~WRP3 & WRP_MASK_HIGH)>>16U & OB->WRP1011)));
2 mjames 1353
 
28 mjames 1354
    tmp1 = (uint32_t)((~wrp89data) << 16U)|(wrp89data);
2 mjames 1355
    OB->WRP89 = tmp1;
1356
 
28 mjames 1357
    tmp2 = (uint32_t)((~wrp1011data) << 16U)|(wrp1011data);
2 mjames 1358
    OB->WRP1011 = tmp2;
1359
  }
1360
}
1361
#endif /* STM32L151xD || STM32L152xD || STM32L162xD || STM32L151xE || STM32L152xE || STM32L162xE */
1362
 
1363
#if defined(STM32L151xE) || defined(STM32L152xE) || defined(STM32L162xE) || defined(STM32L151xDX) \
1364
 || defined(STM32L152xDX) || defined(STM32L162xDX)
1365
/**
1366
  * @brief  Enable Write protects the desired pages of the Fourth 128KB of the Flash.
1367
  * @note   This function can be used only for Cat5 & STM32L1xxDX devices.
1368
  * @param  WRP4 specifies the address of the pages to be write protected.
1369
  *   This parameter can be a combination of @ref FLASHEx_Option_Bytes_Write_Protection4
1370
  * @param  NewState new state of the specified FLASH Pages Wtite protection.
1371
  *   This parameter can be: ENABLE or DISABLE.
1372
  * @retval None
1373
  */
1374
static void FLASH_OB_WRPConfigWRP4(uint32_t WRP4, FunctionalState NewState)
1375
{
28 mjames 1376
  uint32_t wrp1213data = 0U, wrp1415data = 0U;
1377
 
1378
  uint32_t tmp1 = 0U, tmp2 = 0U;
1379
 
2 mjames 1380
  /* Check the parameters */
1381
  assert_param(IS_OB_WRP(WRP4));
1382
  assert_param(IS_FUNCTIONAL_STATE(NewState));
1383
 
1384
  if (NewState != DISABLE)
1385
  {
1386
    wrp1213data = (uint16_t)(((WRP4 & WRP_MASK_LOW) | OB->WRP1213));
28 mjames 1387
    wrp1415data = (uint16_t)((((WRP4 & WRP_MASK_HIGH)>>16U | OB->WRP1415)));
1388
    tmp1 = (uint32_t)(~(wrp1213data) << 16U)|(wrp1213data);
2 mjames 1389
    OB->WRP1213 = tmp1;
1390
 
28 mjames 1391
    tmp2 = (uint32_t)(~(wrp1415data) << 16U)|(wrp1415data);
1392
    OB->WRP1415 = tmp2;
2 mjames 1393
  }
1394
  else
1395
  {
1396
    wrp1213data = (uint16_t)(~WRP4 & (WRP_MASK_LOW & OB->WRP1213));
28 mjames 1397
    wrp1415data = (uint16_t)((((~WRP4 & WRP_MASK_HIGH)>>16U & OB->WRP1415)));
2 mjames 1398
 
28 mjames 1399
    tmp1 = (uint32_t)((~wrp1213data) << 16U)|(wrp1213data);
2 mjames 1400
    OB->WRP1213 = tmp1;
1401
 
28 mjames 1402
    tmp2 = (uint32_t)((~wrp1415data) << 16U)|(wrp1415data);
2 mjames 1403
    OB->WRP1415 = tmp2;
1404
  }
1405
}
1406
#endif /* STM32L151xE || STM32L152xE || STM32L162xE || STM32L151xDX || ... */
1407
 
1408
/**
1409
  * @brief  Programs the FLASH User Option Byte: IWDG_SW / RST_STOP / RST_STDBY.
1410
  * @param  OB_IWDG Selects the WDG mode.
1411
  *   This parameter can be one of the following values:
1412
  *     @arg @ref OB_IWDG_SW Software WDG selected
1413
  *     @arg @ref OB_IWDG_HW Hardware WDG selected
1414
  * @param  OB_STOP Reset event when entering STOP mode.
1415
  *   This parameter can be one of the following values:
1416
  *     @arg @ref OB_STOP_NORST No reset generated when entering in STOP
1417
  *     @arg @ref OB_STOP_RST Reset generated when entering in STOP
1418
  * @param  OB_STDBY Reset event when entering Standby mode.
1419
  *   This parameter can be one of the following values:
1420
  *     @arg @ref OB_STDBY_NORST No reset generated when entering in STANDBY
1421
  *     @arg @ref OB_STDBY_RST Reset generated when entering in STANDBY
1422
  * @retval HAL status
1423
  */
1424
static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY)
1425
{
28 mjames 1426
  HAL_StatusTypeDef status = HAL_OK;
1427
  uint32_t tmp = 0U, tmp1 = 0U;
2 mjames 1428
 
1429
  /* Check the parameters */
1430
  assert_param(IS_OB_IWDG_SOURCE(OB_IWDG));
1431
  assert_param(IS_OB_STOP_SOURCE(OB_STOP));
1432
  assert_param(IS_OB_STDBY_SOURCE(OB_STDBY));
1433
 
1434
  /* Get the User Option byte register */
28 mjames 1435
  tmp1 = OB->USER & ((~(FLASH_OBR_IWDG_SW | FLASH_OBR_nRST_STOP | FLASH_OBR_nRST_STDBY)) >> 16U);
2 mjames 1436
 
28 mjames 1437
  /* Calculate the user option byte to write */
1438
  tmp = (uint32_t)(((uint32_t)~((uint32_t)((uint32_t)(OB_IWDG) | (uint32_t)(OB_STOP) | (uint32_t)(OB_STDBY) | tmp1))) << 16U);
2 mjames 1439
  tmp |= ((uint32_t)(OB_IWDG) | ((uint32_t)OB_STOP) | (uint32_t)(OB_STDBY) | tmp1);
28 mjames 1440
 
2 mjames 1441
  /* Wait for last operation to be completed */
1442
  status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
28 mjames 1443
 
2 mjames 1444
  if(status == HAL_OK)
28 mjames 1445
  {
2 mjames 1446
    /* Clean the error context */
1447
    pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
1448
 
1449
    /* Write the User Option Byte */
1450
    OB->USER = tmp;
28 mjames 1451
 
2 mjames 1452
    /* Wait for last operation to be completed */
1453
    status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1454
  }
1455
 
1456
  /* Return the Option Byte program Status */
1457
  return status;
1458
}
1459
 
1460
#if defined(FLASH_OBR_nRST_BFB2)
1461
/**
1462
  * @brief  Configures to boot from Bank1 or Bank2.
1463
  * @param  OB_BOOT select the FLASH Bank to boot from.
1464
  *   This parameter can be one of the following values:
1465
  *     @arg @ref OB_BOOT_BANK2 At startup, if boot pins are set in boot from user Flash
1466
  *        position and this parameter is selected the device will boot from Bank2 or Bank1,
1467
  *        depending on the activation of the bank. The active banks are checked in
1468
  *        the following order: Bank2, followed by Bank1.
1469
  *        The active bank is recognized by the value programmed at the base address
1470
  *        of the respective bank (corresponding to the initial stack pointer value
1471
  *        in the interrupt vector table).
1472
  *     @arg @ref OB_BOOT_BANK1 At startup, if boot pins are set in boot from user Flash
1473
  *        position and this parameter is selected the device will boot from Bank1(Default).
28 mjames 1474
  *        For more information, please refer to AN2606 from www.st.com.
2 mjames 1475
  * @retval HAL status
1476
  */
1477
static HAL_StatusTypeDef FLASH_OB_BootConfig(uint8_t OB_BOOT)
1478
{
28 mjames 1479
  HAL_StatusTypeDef status = HAL_OK;
1480
  uint32_t tmp = 0U, tmp1 = 0U;
2 mjames 1481
 
1482
  /* Check the parameters */
1483
  assert_param(IS_OB_BOOT_BANK(OB_BOOT));
1484
 
1485
  /* Get the User Option byte register  and BOR Level*/
28 mjames 1486
  tmp1 = OB->USER & ((~FLASH_OBR_nRST_BFB2) >> 16U);
2 mjames 1487
 
1488
  /* Calculate the option byte to write */
28 mjames 1489
  tmp = (uint32_t)~(OB_BOOT | tmp1) << 16U;
2 mjames 1490
  tmp |= (OB_BOOT | tmp1);
1491
 
1492
  /* Wait for last operation to be completed */
1493
  status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1494
 
1495
  if(status == HAL_OK)
28 mjames 1496
  {
2 mjames 1497
    /* Clean the error context */
1498
    pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
1499
 
1500
    /* Write the BOOT Option Byte */
1501
    OB->USER = tmp;
28 mjames 1502
 
2 mjames 1503
    /* Wait for last operation to be completed */
1504
    status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1505
  }
1506
 
1507
  /* Return the Option Byte program Status */
1508
  return status;
1509
}
1510
 
1511
#endif /* FLASH_OBR_nRST_BFB2 */
1512
 
1513
/*
1514
==============================================================================
1515
              DATA
1516
==============================================================================
1517
*/
1518
 
1519
/**
1520
  * @brief  Write a Byte at a specified address in data memory.
1521
  * @param  Address specifies the address to be written.
1522
  * @param  Data specifies the data to be written.
1523
  * @note   This function assumes that the is data word is already erased.
1524
  * @retval HAL status
1525
  */
1526
static HAL_StatusTypeDef FLASH_DATAEEPROM_FastProgramByte(uint32_t Address, uint8_t Data)
1527
{
1528
  HAL_StatusTypeDef status = HAL_OK;
1529
#if defined(STM32L100xB) || defined(STM32L151xB) || defined(STM32L152xB)
28 mjames 1530
  uint32_t tmp = 0U, tmpaddr = 0U;
2 mjames 1531
#endif /* STM32L100xB || STM32L151xB || STM32L152xB  */
28 mjames 1532
 
2 mjames 1533
  /* Check the parameters */
28 mjames 1534
  assert_param(IS_FLASH_DATA_ADDRESS(Address));
2 mjames 1535
 
1536
  /* Wait for last operation to be completed */
1537
  status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
28 mjames 1538
 
2 mjames 1539
  if(status == HAL_OK)
1540
  {
1541
    /* Clear the FTDW bit */
1542
    CLEAR_BIT(FLASH->PECR, FLASH_PECR_FTDW);
1543
 
1544
#if defined(STM32L100xB) || defined(STM32L151xB) || defined(STM32L152xB)
1545
    /* Possible only on Cat1 devices */
28 mjames 1546
    if(Data != (uint8_t)0x00U)
2 mjames 1547
    {
1548
      /* If the previous operation is completed, proceed to write the new Data */
1549
      *(__IO uint8_t *)Address = Data;
28 mjames 1550
 
2 mjames 1551
      /* Wait for last operation to be completed */
1552
      status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1553
    }
1554
    else
1555
    {
28 mjames 1556
      tmpaddr = Address & 0xFFFFFFFCU;
2 mjames 1557
      tmp = * (__IO uint32_t *) tmpaddr;
28 mjames 1558
      tmpaddr = 0xFFU << ((uint32_t) (0x8U * (Address & 0x3U)));
2 mjames 1559
      tmp &= ~tmpaddr;
28 mjames 1560
      status = HAL_FLASHEx_DATAEEPROM_Erase(FLASH_TYPEERASEDATA_WORD, Address & 0xFFFFFFFCU);
2 mjames 1561
      /* Process Unlocked */
1562
      __HAL_UNLOCK(&pFlash);
28 mjames 1563
      status = HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_FASTWORD, (Address & 0xFFFFFFFCU), tmp);
2 mjames 1564
      /* Process Locked */
1565
      __HAL_LOCK(&pFlash);
1566
    }
28 mjames 1567
#else /*!Cat1*/
2 mjames 1568
    /* If the previous operation is completed, proceed to write the new Data */
1569
    *(__IO uint8_t *)Address = Data;
28 mjames 1570
 
2 mjames 1571
    /* Wait for last operation to be completed */
1572
    status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1573
#endif /* STM32L100xB || STM32L151xB || STM32L152xB  */
1574
  }
1575
  /* Return the Write Status */
1576
  return status;
1577
}
1578
 
1579
/**
1580
  * @brief  Writes a half word at a specified address in data memory.
1581
  * @param  Address specifies the address to be written.
1582
  * @param  Data specifies the data to be written.
1583
  * @note   This function assumes that the is data word is already erased.
1584
  * @retval HAL status
1585
  */
1586
static HAL_StatusTypeDef FLASH_DATAEEPROM_FastProgramHalfWord(uint32_t Address, uint16_t Data)
1587
{
1588
  HAL_StatusTypeDef status = HAL_OK;
1589
#if defined(STM32L100xB) || defined(STM32L151xB) || defined(STM32L152xB)
28 mjames 1590
  uint32_t tmp = 0U, tmpaddr = 0U;
2 mjames 1591
#endif /* STM32L100xB || STM32L151xB || STM32L152xB  */
28 mjames 1592
 
2 mjames 1593
  /* Check the parameters */
1594
  assert_param(IS_FLASH_DATA_ADDRESS(Address));
1595
 
1596
  /* Wait for last operation to be completed */
1597
  status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
28 mjames 1598
 
2 mjames 1599
  if(status == HAL_OK)
1600
  {
1601
    /* Clear the FTDW bit */
1602
    CLEAR_BIT(FLASH->PECR, FLASH_PECR_FTDW);
1603
 
1604
#if defined(STM32L100xB) || defined(STM32L151xB) || defined(STM32L152xB)
1605
    /* Possible only on Cat1 devices */
28 mjames 1606
    if(Data != (uint16_t)0x0000U)
2 mjames 1607
    {
1608
      /* If the previous operation is completed, proceed to write the new data */
1609
      *(__IO uint16_t *)Address = Data;
28 mjames 1610
 
2 mjames 1611
      /* Wait for last operation to be completed */
1612
      status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1613
    }
1614
    else
1615
    {
1616
      /* Process Unlocked */
1617
      __HAL_UNLOCK(&pFlash);
28 mjames 1618
      if((Address & 0x3U) != 0x3U)
2 mjames 1619
      {
28 mjames 1620
        tmpaddr = Address & 0xFFFFFFFCU;
2 mjames 1621
        tmp = * (__IO uint32_t *) tmpaddr;
28 mjames 1622
        tmpaddr = 0xFFFFU << ((uint32_t) (0x8U * (Address & 0x3U)));
1623
        tmp &= ~tmpaddr;
1624
        status = HAL_FLASHEx_DATAEEPROM_Erase(FLASH_TYPEERASEDATA_WORD, Address & 0xFFFFFFFCU);
1625
        status = HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_FASTWORD, (Address & 0xFFFFFFFCU), tmp);
2 mjames 1626
      }
1627
      else
1628
      {
28 mjames 1629
        HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_FASTBYTE, Address, 0x00U);
1630
        HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_FASTBYTE, Address + 1U, 0x00U);
2 mjames 1631
      }
1632
      /* Process Locked */
1633
      __HAL_LOCK(&pFlash);
1634
    }
1635
#else /* !Cat1 */
1636
    /* If the previous operation is completed, proceed to write the new data */
1637
    *(__IO uint16_t *)Address = Data;
28 mjames 1638
 
2 mjames 1639
    /* Wait for last operation to be completed */
1640
    status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1641
#endif /* STM32L100xB || STM32L151xB || STM32L152xB  */
1642
  }
1643
  /* Return the Write Status */
1644
  return status;
1645
}
1646
 
1647
/**
1648
  * @brief  Programs a word at a specified address in data memory.
1649
  * @param  Address specifies the address to be written.
1650
  * @param  Data specifies the data to be written.
1651
  * @note   This function assumes that the is data word is already erased.
1652
  * @retval HAL status
1653
  */
1654
static HAL_StatusTypeDef FLASH_DATAEEPROM_FastProgramWord(uint32_t Address, uint32_t Data)
1655
{
1656
  HAL_StatusTypeDef status = HAL_OK;
1657
 
1658
  /* Check the parameters */
1659
  assert_param(IS_FLASH_DATA_ADDRESS(Address));
28 mjames 1660
 
2 mjames 1661
  /* Wait for last operation to be completed */
1662
  status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
28 mjames 1663
 
2 mjames 1664
  if(status == HAL_OK)
1665
  {
1666
    /* Clear the FTDW bit */
1667
    CLEAR_BIT(FLASH->PECR, FLASH_PECR_FTDW);
28 mjames 1668
 
1669
    /* If the previous operation is completed, proceed to program the new data */
2 mjames 1670
    *(__IO uint32_t *)Address = Data;
28 mjames 1671
 
2 mjames 1672
    /* Wait for last operation to be completed */
28 mjames 1673
    status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
2 mjames 1674
  }
1675
  /* Return the Write Status */
1676
  return status;
1677
}
1678
 
1679
/**
1680
  * @brief  Write a Byte at a specified address in data memory without erase.
1681
  * @param  Address specifies the address to be written.
1682
  * @param  Data specifies the data to be written.
1683
  * @retval HAL status
1684
  */
1685
static HAL_StatusTypeDef FLASH_DATAEEPROM_ProgramByte(uint32_t Address, uint8_t Data)
1686
{
1687
  HAL_StatusTypeDef status = HAL_OK;
1688
#if defined(STM32L100xB) || defined(STM32L151xB) || defined(STM32L152xB)
28 mjames 1689
  uint32_t tmp = 0U, tmpaddr = 0U;
2 mjames 1690
#endif /* STM32L100xB || STM32L151xB || STM32L152xB  */
28 mjames 1691
 
2 mjames 1692
  /* Check the parameters */
28 mjames 1693
  assert_param(IS_FLASH_DATA_ADDRESS(Address));
2 mjames 1694
 
1695
  /* Wait for last operation to be completed */
1696
  status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
28 mjames 1697
 
2 mjames 1698
  if(status == HAL_OK)
1699
  {
1700
#if defined(STM32L100xB) || defined(STM32L151xB) || defined(STM32L152xB)
28 mjames 1701
    if(Data != (uint8_t) 0x00U)
1702
    {
2 mjames 1703
      *(__IO uint8_t *)Address = Data;
28 mjames 1704
 
2 mjames 1705
      /* Wait for last operation to be completed */
1706
      status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1707
 
1708
    }
1709
    else
1710
    {
28 mjames 1711
      tmpaddr = Address & 0xFFFFFFFCU;
2 mjames 1712
      tmp = * (__IO uint32_t *) tmpaddr;
28 mjames 1713
      tmpaddr = 0xFFU << ((uint32_t) (0x8U * (Address & 0x3U)));
1714
      tmp &= ~tmpaddr;
1715
      status = HAL_FLASHEx_DATAEEPROM_Erase(FLASH_TYPEERASEDATA_WORD, Address & 0xFFFFFFFCU);
2 mjames 1716
      /* Process Unlocked */
1717
      __HAL_UNLOCK(&pFlash);
28 mjames 1718
      status = HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_FASTWORD, (Address & 0xFFFFFFFCU), tmp);
2 mjames 1719
      /* Process Locked */
1720
      __HAL_LOCK(&pFlash);
1721
    }
1722
#else /* Not Cat1*/
1723
    *(__IO uint8_t *)Address = Data;
28 mjames 1724
 
2 mjames 1725
    /* Wait for last operation to be completed */
1726
    status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1727
#endif /* STM32L100xB || STM32L151xB || STM32L152xB  */
1728
  }
1729
  /* Return the Write Status */
1730
  return status;
1731
}
1732
 
1733
/**
1734
  * @brief  Writes a half word at a specified address in data memory without erase.
1735
  * @param  Address specifies the address to be written.
1736
  * @param  Data specifies the data to be written.
1737
  * @retval HAL status
1738
  */
1739
static HAL_StatusTypeDef FLASH_DATAEEPROM_ProgramHalfWord(uint32_t Address, uint16_t Data)
1740
{
1741
  HAL_StatusTypeDef status = HAL_OK;
1742
#if defined(STM32L100xB) || defined(STM32L151xB) || defined(STM32L152xB)
28 mjames 1743
  uint32_t tmp = 0U, tmpaddr = 0U;
2 mjames 1744
#endif /* STM32L100xB || STM32L151xB || STM32L152xB  */
28 mjames 1745
 
2 mjames 1746
  /* Check the parameters */
1747
  assert_param(IS_FLASH_DATA_ADDRESS(Address));
1748
 
1749
  /* Wait for last operation to be completed */
1750
  status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
28 mjames 1751
 
2 mjames 1752
  if(status == HAL_OK)
1753
  {
1754
#if defined(STM32L100xB) || defined(STM32L151xB) || defined(STM32L152xB)
28 mjames 1755
    if(Data != (uint16_t)0x0000U)
2 mjames 1756
    {
1757
      *(__IO uint16_t *)Address = Data;
28 mjames 1758
 
2 mjames 1759
      /* Wait for last operation to be completed */
1760
      status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1761
    }
1762
    else
1763
    {
1764
      /* Process Unlocked */
1765
      __HAL_UNLOCK(&pFlash);
28 mjames 1766
      if((Address & 0x3U) != 0x3U)
2 mjames 1767
      {
28 mjames 1768
        tmpaddr = Address & 0xFFFFFFFCU;
2 mjames 1769
        tmp = * (__IO uint32_t *) tmpaddr;
28 mjames 1770
        tmpaddr = 0xFFFFU << ((uint32_t) (0x8U * (Address & 0x3U)));
1771
        tmp &= ~tmpaddr;
1772
        status = HAL_FLASHEx_DATAEEPROM_Erase(FLASH_TYPEERASEDATA_WORD, Address & 0xFFFFFFFCU);
1773
        status = HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_FASTWORD, (Address & 0xFFFFFFFCU), tmp);
2 mjames 1774
      }
1775
      else
1776
      {
28 mjames 1777
        HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_FASTBYTE, Address, 0x00U);
1778
        HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_FASTBYTE, Address + 1U, 0x00U);
2 mjames 1779
      }
1780
      /* Process Locked */
1781
      __HAL_LOCK(&pFlash);
1782
    }
1783
#else /* Not Cat1*/
1784
    *(__IO uint16_t *)Address = Data;
28 mjames 1785
 
2 mjames 1786
    /* Wait for last operation to be completed */
1787
    status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1788
#endif /* STM32L100xB || STM32L151xB || STM32L152xB  */
1789
  }
1790
  /* Return the Write Status */
1791
  return status;
1792
}
1793
 
1794
/**
1795
  * @brief  Programs a word at a specified address in data memory without erase.
1796
  * @param  Address specifies the address to be written.
1797
  * @param  Data specifies the data to be written.
1798
  * @retval HAL status
1799
  */
1800
static HAL_StatusTypeDef FLASH_DATAEEPROM_ProgramWord(uint32_t Address, uint32_t Data)
1801
{
1802
  HAL_StatusTypeDef status = HAL_OK;
28 mjames 1803
 
2 mjames 1804
  /* Check the parameters */
1805
  assert_param(IS_FLASH_DATA_ADDRESS(Address));
28 mjames 1806
 
2 mjames 1807
  /* Wait for last operation to be completed */
1808
  status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
28 mjames 1809
 
2 mjames 1810
  if(status == HAL_OK)
1811
  {
1812
    *(__IO uint32_t *)Address = Data;
1813
 
1814
    /* Wait for last operation to be completed */
1815
    status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1816
  }
1817
  /* Return the Write Status */
1818
  return status;
1819
}
1820
 
1821
/**
1822
  * @}
1823
  */
1824
 
1825
/**
1826
  * @}
1827
  */
1828
 
1829
/** @addtogroup FLASH
1830
  * @{
1831
  */
1832
 
1833
 
1834
/** @addtogroup FLASH_Private_Functions
1835
 * @{
1836
 */
1837
 
1838
/**
1839
  * @brief  Erases a specified page in program memory.
1840
  * @param  PageAddress The page address in program memory to be erased.
28 mjames 1841
  * @note   A Page is erased in the Program memory only if the address to load
2 mjames 1842
  *         is the start address of a page (multiple of @ref FLASH_PAGE_SIZE bytes).
1843
  * @retval None
1844
  */
1845
void FLASH_PageErase(uint32_t PageAddress)
1846
{
1847
  /* Clean the error context */
1848
  pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
1849
 
1850
  /* Set the ERASE bit */
1851
  SET_BIT(FLASH->PECR, FLASH_PECR_ERASE);
1852
 
1853
  /* Set PROG bit */
1854
  SET_BIT(FLASH->PECR, FLASH_PECR_PROG);
1855
 
1856
  /* Write 00000000h to the first word of the program page to erase */
1857
  *(__IO uint32_t *)(uint32_t)(PageAddress & ~(FLASH_PAGE_SIZE - 1)) = 0x00000000;
1858
}
28 mjames 1859
 
2 mjames 1860
/**
1861
  * @}
1862
  */
1863
 
1864
/**
1865
  * @}
1866
  */
1867
 
1868
#endif /* HAL_FLASH_MODULE_ENABLED */
1869
/**
1870
  * @}
1871
  */
1872
 
1873
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/