Subversion Repositories LedShow

Rev

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

Rev Author Line No. Line
2 mjames 1
/**
2
  ******************************************************************************
3
  * @file    stm32f1xx_hal_nor.c
4
  * @author  MCD Application Team
5
  * @brief   NOR HAL module driver.
6
  *          This file provides a generic firmware to drive NOR memories mounted
7
  *          as external device.
8
  *        
9
  @verbatim
10
  ==============================================================================
11
                     ##### How to use this driver #####
12
  ==============================================================================      
13
    [..]
14
      This driver is a generic layered driver which contains a set of APIs used to
15
      control NOR flash memories. It uses the FSMC layer functions to interface
16
      with NOR devices. This driver is used as follows:
17
 
18
      (+) NOR flash memory configuration sequence using the function HAL_NOR_Init()
19
          with control and timing parameters for both normal and extended mode.
20
 
21
      (+) Read NOR flash memory manufacturer code and device IDs using the function
22
          HAL_NOR_Read_ID(). The read information is stored in the NOR_ID_TypeDef
23
          structure declared by the function caller.
24
 
25
      (+) Access NOR flash memory by read/write data unit operations using the functions
26
          HAL_NOR_Read(), HAL_NOR_Program().
27
 
28
      (+) Perform NOR flash erase block/chip operations using the functions
29
          HAL_NOR_Erase_Block() and HAL_NOR_Erase_Chip().
30
 
31
      (+) Read the NOR flash CFI (common flash interface) IDs using the function
32
          HAL_NOR_Read_CFI(). The read information is stored in the NOR_CFI_TypeDef
33
          structure declared by the function caller.
34
 
35
      (+) You can also control the NOR device by calling the control APIs HAL_NOR_WriteOperation_Enable()/
36
          HAL_NOR_WriteOperation_Disable() to respectively enable/disable the NOR write operation  
37
 
38
      (+) You can monitor the NOR device HAL state by calling the function
39
          HAL_NOR_GetState()
40
    [..]
41
     (@) This driver is a set of generic APIs which handle standard NOR flash operations.
42
         If a NOR flash device contains different operations and/or implementations,
43
         it should be implemented separately.
44
 
45
     *** NOR HAL driver macros list ***
46
     =============================================
47
     [..]
48
       Below the list of most used macros in NOR HAL driver.
49
 
50
      (+) NOR_WRITE : NOR memory write data to specified address
51
 
52
  @endverbatim
53
  ******************************************************************************
54
  * @attention
55
  *
56
  * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
57
  *
58
  * Redistribution and use in source and binary forms, with or without modification,
59
  * are permitted provided that the following conditions are met:
60
  *   1. Redistributions of source code must retain the above copyright notice,
61
  *      this list of conditions and the following disclaimer.
62
  *   2. Redistributions in binary form must reproduce the above copyright notice,
63
  *      this list of conditions and the following disclaimer in the documentation
64
  *      and/or other materials provided with the distribution.
65
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
66
  *      may be used to endorse or promote products derived from this software
67
  *      without specific prior written permission.
68
  *
69
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
70
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
71
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
72
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
73
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
74
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
75
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
76
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
77
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
78
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
79
  *
80
  ******************************************************************************
81
  */
82
 
83
/* Includes ------------------------------------------------------------------*/
84
#include "stm32f1xx_hal.h"
85
 
86
/** @addtogroup STM32F1xx_HAL_Driver
87
  * @{
88
  */
89
 
90
#ifdef HAL_NOR_MODULE_ENABLED
91
#if defined (STM32F101xE) || defined(STM32F103xE) || defined(STM32F101xG) || defined(STM32F103xG) || defined(STM32F100xE)
92
 
93
/** @defgroup NOR NOR
94
  * @brief NOR driver modules
95
  * @{
96
  */
97
/* Private typedef -----------------------------------------------------------*/
98
/* Private define ------------------------------------------------------------*/
99
/** @defgroup NOR_Private_Constants NOR Private Constants
100
  * @{
101
  */
102
 
103
/* Constants to define address to set to write a command */
104
#define NOR_CMD_ADDRESS_FIRST                 (uint16_t)0x0555
105
#define NOR_CMD_ADDRESS_FIRST_CFI             (uint16_t)0x0055
106
#define NOR_CMD_ADDRESS_SECOND                (uint16_t)0x02AA
107
#define NOR_CMD_ADDRESS_THIRD                 (uint16_t)0x0555
108
#define NOR_CMD_ADDRESS_FOURTH                (uint16_t)0x0555
109
#define NOR_CMD_ADDRESS_FIFTH                 (uint16_t)0x02AA
110
#define NOR_CMD_ADDRESS_SIXTH                 (uint16_t)0x0555
111
 
112
/* Constants to define data to program a command */
113
#define NOR_CMD_DATA_READ_RESET               (uint16_t)0x00F0
114
#define NOR_CMD_DATA_FIRST                    (uint16_t)0x00AA
115
#define NOR_CMD_DATA_SECOND                   (uint16_t)0x0055
116
#define NOR_CMD_DATA_AUTO_SELECT              (uint16_t)0x0090
117
#define NOR_CMD_DATA_PROGRAM                  (uint16_t)0x00A0
118
#define NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD   (uint16_t)0x0080
119
#define NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH  (uint16_t)0x00AA
120
#define NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH   (uint16_t)0x0055
121
#define NOR_CMD_DATA_CHIP_ERASE               (uint16_t)0x0010
122
#define NOR_CMD_DATA_CFI                      (uint16_t)0x0098
123
 
124
#define NOR_CMD_DATA_BUFFER_AND_PROG          (uint8_t)0x25
125
#define NOR_CMD_DATA_BUFFER_AND_PROG_CONFIRM  (uint8_t)0x29
126
#define NOR_CMD_DATA_BLOCK_ERASE              (uint8_t)0x30
127
 
128
/* Mask on NOR STATUS REGISTER */
129
#define NOR_MASK_STATUS_DQ5                   (uint16_t)0x0020
130
#define NOR_MASK_STATUS_DQ6                   (uint16_t)0x0040
131
 
132
/**
133
  * @}
134
  */
135
 
136
/* Private macro -------------------------------------------------------------*/
137
/** @defgroup NOR_Private_Macros NOR Private Macros
138
  * @{
139
  */
140
 
141
/**
142
  * @}
143
  */
144
 
145
/* Private variables ---------------------------------------------------------*/
146
 
147
/** @defgroup NOR_Private_Variables NOR Private Variables
148
  * @{
149
  */
150
 
151
static uint32_t uwNORMemoryDataWidth  = NOR_MEMORY_8B;
152
 
153
/**
154
  * @}
155
  */
156
 
157
/* Private function prototypes -----------------------------------------------*/
158
/* Private functions ---------------------------------------------------------*/
159
 
160
/** @defgroup NOR_Exported_Functions NOR Exported Functions
161
  * @{
162
  */
163
 
164
/** @defgroup NOR_Exported_Functions_Group1 Initialization and de-initialization functions
165
  * @brief    Initialization and Configuration functions
166
  *
167
  @verbatim    
168
  ==============================================================================
169
           ##### NOR Initialization and de_initialization functions #####
170
  ==============================================================================
171
  [..]  
172
    This section provides functions allowing to initialize/de-initialize
173
    the NOR memory
174
 
175
@endverbatim
176
  * @{
177
  */
178
 
179
/**
180
  * @brief  Perform the NOR memory Initialization sequence
181
  * @param  hnor: pointer to a NOR_HandleTypeDef structure that contains
182
  *                the configuration information for NOR module.
183
  * @param  Timing: pointer to NOR control timing structure
184
  * @param  ExtTiming: pointer to NOR extended mode timing structure    
185
  * @retval HAL status
186
  */
187
HAL_StatusTypeDef HAL_NOR_Init(NOR_HandleTypeDef *hnor, FSMC_NORSRAM_TimingTypeDef *Timing, FSMC_NORSRAM_TimingTypeDef *ExtTiming)
188
{
189
  /* Check the NOR handle parameter */
190
  if(hnor == NULL)
191
  {
192
     return HAL_ERROR;
193
  }
194
 
195
  if(hnor->State == HAL_NOR_STATE_RESET)
196
  {
197
    /* Allocate lock resource and initialize it */
198
    hnor->Lock = HAL_UNLOCKED;
199
 
200
    /* Initialize the low level hardware (MSP) */
201
    HAL_NOR_MspInit(hnor);
202
  }
203
 
204
  /* Initialize NOR control Interface */
205
  FSMC_NORSRAM_Init(hnor->Instance, &(hnor->Init));
206
 
207
  /* Initialize NOR timing Interface */
208
  FSMC_NORSRAM_Timing_Init(hnor->Instance, Timing, hnor->Init.NSBank);
209
 
210
  /* Initialize NOR extended mode timing Interface */
211
  FSMC_NORSRAM_Extended_Timing_Init(hnor->Extended, ExtTiming, hnor->Init.NSBank, hnor->Init.ExtendedMode);
212
 
213
  /* Enable the NORSRAM device */
214
  __FSMC_NORSRAM_ENABLE(hnor->Instance, hnor->Init.NSBank);  
215
 
216
  /* Initialize NOR Memory Data Width*/
217
  if (hnor->Init.MemoryDataWidth == FSMC_NORSRAM_MEM_BUS_WIDTH_8)
218
  {
219
    uwNORMemoryDataWidth = NOR_MEMORY_8B;
220
  }
221
  else
222
  {
223
    uwNORMemoryDataWidth = NOR_MEMORY_16B;
224
  }
225
 
226
  /* Check the NOR controller state */
227
  hnor->State = HAL_NOR_STATE_READY;
228
 
229
  return HAL_OK;
230
}
231
 
232
/**
233
  * @brief  Perform NOR memory De-Initialization sequence
234
  * @param  hnor: pointer to a NOR_HandleTypeDef structure that contains
235
  *                the configuration information for NOR module.
236
  * @retval HAL status
237
  */
238
HAL_StatusTypeDef HAL_NOR_DeInit(NOR_HandleTypeDef *hnor)  
239
{
240
  /* De-Initialize the low level hardware (MSP) */
241
  HAL_NOR_MspDeInit(hnor);
242
 
243
  /* Configure the NOR registers with their reset values */
244
  FSMC_NORSRAM_DeInit(hnor->Instance, hnor->Extended, hnor->Init.NSBank);
245
 
246
  /* Update the NOR controller state */
247
  hnor->State = HAL_NOR_STATE_RESET;
248
 
249
  /* Release Lock */
250
  __HAL_UNLOCK(hnor);
251
 
252
  return HAL_OK;
253
}
254
 
255
/**
256
  * @brief  NOR MSP Init
257
  * @param  hnor: pointer to a NOR_HandleTypeDef structure that contains
258
  *                the configuration information for NOR module.
259
  * @retval None
260
  */
261
__weak void HAL_NOR_MspInit(NOR_HandleTypeDef *hnor)
262
{
263
  /* Prevent unused argument(s) compilation warning */
264
  UNUSED(hnor);
265
  /* NOTE : This function Should not be modified, when the callback is needed,
266
            the HAL_NOR_MspInit could be implemented in the user file
267
   */
268
}
269
 
270
/**
271
  * @brief  NOR MSP DeInit
272
  * @param  hnor: pointer to a NOR_HandleTypeDef structure that contains
273
  *                the configuration information for NOR module.
274
  * @retval None
275
  */
276
__weak void HAL_NOR_MspDeInit(NOR_HandleTypeDef *hnor)
277
{
278
  /* Prevent unused argument(s) compilation warning */
279
  UNUSED(hnor);
280
  /* NOTE : This function Should not be modified, when the callback is needed,
281
            the HAL_NOR_MspDeInit could be implemented in the user file
282
   */
283
}
284
 
285
/**
286
  * @brief  NOR MSP Wait fro Ready/Busy signal
287
  * @param  hnor: pointer to a NOR_HandleTypeDef structure that contains
288
  *                the configuration information for NOR module.
289
  * @param  Timeout: Maximum timeout value
290
  * @retval None
291
  */
292
__weak void HAL_NOR_MspWait(NOR_HandleTypeDef *hnor, uint32_t Timeout)
293
{
294
  /* Prevent unused argument(s) compilation warning */
295
  UNUSED(hnor);
296
  UNUSED(Timeout);
297
  /* NOTE : This function Should not be modified, when the callback is needed,
298
            the HAL_NOR_MspWait could be implemented in the user file
299
   */
300
}
301
 
302
/**
303
  * @}
304
  */
305
 
306
/** @defgroup NOR_Exported_Functions_Group2 Input and Output functions
307
  * @brief    Input Output and memory control functions
308
  *
309
  @verbatim    
310
  ==============================================================================
311
                ##### NOR Input and Output functions #####
312
  ==============================================================================
313
  [..]  
314
    This section provides functions allowing to use and control the NOR memory
315
 
316
@endverbatim
317
  * @{
318
  */
319
 
320
/**
321
  * @brief  Read NOR flash IDs
322
  * @param  hnor: pointer to a NOR_HandleTypeDef structure that contains
323
  *                the configuration information for NOR module.
324
  * @param  pNOR_ID : pointer to NOR ID structure
325
  * @retval HAL status
326
  */
327
HAL_StatusTypeDef HAL_NOR_Read_ID(NOR_HandleTypeDef *hnor, NOR_IDTypeDef *pNOR_ID)
328
{
329
  uint32_t deviceaddress = 0U;
330
 
331
  /* Process Locked */
332
  __HAL_LOCK(hnor);
333
 
334
  /* Check the NOR controller state */
335
  if(hnor->State == HAL_NOR_STATE_BUSY)
336
  {
337
     return HAL_BUSY;
338
  }
339
 
340
  /* Select the NOR device address */
341
  if (hnor->Init.NSBank == FSMC_NORSRAM_BANK1)
342
  {
343
    deviceaddress = NOR_MEMORY_ADRESS1;
344
  }
345
  else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK2)
346
  {
347
    deviceaddress = NOR_MEMORY_ADRESS2;
348
  }
349
  else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK3)
350
  {
351
    deviceaddress = NOR_MEMORY_ADRESS3;
352
  }
353
  else /* FSMC_NORSRAM_BANK4 */
354
  {
355
    deviceaddress = NOR_MEMORY_ADRESS4;
356
  }  
357
 
358
  /* Update the NOR controller state */
359
  hnor->State = HAL_NOR_STATE_BUSY;
360
 
361
  /* Send read ID command */
362
  NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
363
  NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
364
  NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_AUTO_SELECT);
365
 
366
  /* Read the NOR IDs */
367
  pNOR_ID->Manufacturer_Code = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, MC_ADDRESS);
368
  pNOR_ID->Device_Code1      = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, DEVICE_CODE1_ADDR);
369
  pNOR_ID->Device_Code2      = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, DEVICE_CODE2_ADDR);
370
  pNOR_ID->Device_Code3      = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, DEVICE_CODE3_ADDR);
371
 
372
  /* Check the NOR controller state */
373
  hnor->State = HAL_NOR_STATE_READY;
374
 
375
  /* Process unlocked */
376
  __HAL_UNLOCK(hnor);  
377
 
378
  return HAL_OK;
379
}
380
 
381
/**
382
  * @brief  Returns the NOR memory to Read mode.
383
  * @param  hnor: pointer to a NOR_HandleTypeDef structure that contains
384
  *                the configuration information for NOR module.
385
  * @retval HAL status
386
  */
387
HAL_StatusTypeDef HAL_NOR_ReturnToReadMode(NOR_HandleTypeDef *hnor)
388
{
389
  uint32_t deviceaddress = 0U;  
390
 
391
  /* Process Locked */
392
  __HAL_LOCK(hnor);
393
 
394
  /* Check the NOR controller state */
395
  if(hnor->State == HAL_NOR_STATE_BUSY)
396
  {
397
     return HAL_BUSY;
398
  }
399
 
400
  /* Select the NOR device address */
401
  if (hnor->Init.NSBank == FSMC_NORSRAM_BANK1)
402
  {
403
    deviceaddress = NOR_MEMORY_ADRESS1;
404
  }
405
  else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK2)
406
  {
407
    deviceaddress = NOR_MEMORY_ADRESS2;
408
  }
409
  else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK3)
410
  {
411
    deviceaddress = NOR_MEMORY_ADRESS3;
412
  }
413
  else /* FSMC_NORSRAM_BANK4 */
414
  {
415
    deviceaddress = NOR_MEMORY_ADRESS4;
416
  }  
417
 
418
  NOR_WRITE(deviceaddress, NOR_CMD_DATA_READ_RESET);
419
 
420
  /* Check the NOR controller state */
421
  hnor->State = HAL_NOR_STATE_READY;
422
 
423
  /* Process unlocked */
424
  __HAL_UNLOCK(hnor);  
425
 
426
  return HAL_OK;
427
}
428
 
429
/**
430
  * @brief  Read data from NOR memory
431
  * @param  hnor: pointer to a NOR_HandleTypeDef structure that contains
432
  *                the configuration information for NOR module.
433
  * @param  pAddress: pointer to Device address
434
  * @param  pData : pointer to read data  
435
  * @retval HAL status
436
  */
437
HAL_StatusTypeDef HAL_NOR_Read(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData)
438
{
439
  uint32_t deviceaddress = 0U;
440
 
441
  /* Process Locked */
442
  __HAL_LOCK(hnor);
443
 
444
  /* Check the NOR controller state */
445
  if(hnor->State == HAL_NOR_STATE_BUSY)
446
  {
447
     return HAL_BUSY;
448
  }
449
 
450
  /* Select the NOR device address */
451
  if (hnor->Init.NSBank == FSMC_NORSRAM_BANK1)
452
  {
453
    deviceaddress = NOR_MEMORY_ADRESS1;
454
  }
455
  else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK2)
456
  {
457
    deviceaddress = NOR_MEMORY_ADRESS2;
458
  }
459
  else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK3)
460
  {
461
    deviceaddress = NOR_MEMORY_ADRESS3;
462
  }
463
  else /* FSMC_NORSRAM_BANK4 */
464
  {
465
    deviceaddress = NOR_MEMORY_ADRESS4;
466
  }
467
 
468
  /* Update the NOR controller state */
469
  hnor->State = HAL_NOR_STATE_BUSY;
470
 
471
  /* Send read data command */
472
  NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
473
  NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);  
474
  NOR_WRITE((uint32_t)pAddress, NOR_CMD_DATA_READ_RESET);
475
 
476
  /* Read the data */
477
  *pData = *(__IO uint32_t *)(uint32_t)pAddress;
478
 
479
  /* Check the NOR controller state */
480
  hnor->State = HAL_NOR_STATE_READY;
481
 
482
  /* Process unlocked */
483
  __HAL_UNLOCK(hnor);
484
 
485
  return HAL_OK;  
486
}
487
 
488
/**
489
  * @brief  Program data to NOR memory
490
  * @param  hnor: pointer to a NOR_HandleTypeDef structure that contains
491
  *                the configuration information for NOR module.
492
  * @param  pAddress: Device address
493
  * @param  pData : pointer to the data to write  
494
  * @retval HAL status
495
  */
496
HAL_StatusTypeDef HAL_NOR_Program(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData)
497
{
498
  uint32_t deviceaddress = 0U;
499
 
500
  /* Process Locked */
501
  __HAL_LOCK(hnor);
502
 
503
  /* Check the NOR controller state */
504
  if(hnor->State == HAL_NOR_STATE_BUSY)
505
  {
506
     return HAL_BUSY;
507
  }
508
 
509
  /* Select the NOR device address */
510
  if (hnor->Init.NSBank == FSMC_NORSRAM_BANK1)
511
  {
512
    deviceaddress = NOR_MEMORY_ADRESS1;
513
  }
514
  else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK2)
515
  {
516
    deviceaddress = NOR_MEMORY_ADRESS2;
517
  }
518
  else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK3)
519
  {
520
    deviceaddress = NOR_MEMORY_ADRESS3;
521
  }
522
  else /* FSMC_NORSRAM_BANK4 */
523
  {
524
    deviceaddress = NOR_MEMORY_ADRESS4;
525
  }
526
 
527
  /* Update the NOR controller state */
528
  hnor->State = HAL_NOR_STATE_BUSY;
529
 
530
  /* Send program data command */
531
  NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
532
  NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
533
  NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_PROGRAM);
534
 
535
  /* Write the data */
536
  NOR_WRITE(pAddress, *pData);
537
 
538
  /* Check the NOR controller state */
539
  hnor->State = HAL_NOR_STATE_READY;
540
 
541
  /* Process unlocked */
542
  __HAL_UNLOCK(hnor);
543
 
544
  return HAL_OK;  
545
}
546
 
547
/**
548
  * @brief  Reads a block of data from the FSMC NOR memory.
549
  * @param  hnor: pointer to a NOR_HandleTypeDef structure that contains
550
  *                the configuration information for NOR module.
551
  * @param  uwAddress: NOR memory internal address to read from.
552
  * @param  pData: pointer to the buffer that receives the data read from the
553
  *         NOR memory.
554
  * @param  uwBufferSize : number of Half word to read.
555
  * @retval HAL status
556
  */
557
HAL_StatusTypeDef HAL_NOR_ReadBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData, uint32_t uwBufferSize)
558
{
559
  uint32_t deviceaddress = 0U;
560
 
561
  /* Process Locked */
562
  __HAL_LOCK(hnor);
563
 
564
  /* Check the NOR controller state */
565
  if(hnor->State == HAL_NOR_STATE_BUSY)
566
  {
567
     return HAL_BUSY;
568
  }
569
 
570
  /* Select the NOR device address */
571
  if (hnor->Init.NSBank == FSMC_NORSRAM_BANK1)
572
  {
573
    deviceaddress = NOR_MEMORY_ADRESS1;
574
  }
575
  else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK2)
576
  {
577
    deviceaddress = NOR_MEMORY_ADRESS2;
578
  }
579
  else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK3)
580
  {
581
    deviceaddress = NOR_MEMORY_ADRESS3;
582
  }
583
  else /* FSMC_NORSRAM_BANK4 */
584
  {
585
    deviceaddress = NOR_MEMORY_ADRESS4;
586
  }  
587
 
588
  /* Update the NOR controller state */
589
  hnor->State = HAL_NOR_STATE_BUSY;
590
 
591
  /* Send read data command */
592
  NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
593
  NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);  
594
  NOR_WRITE(uwAddress, NOR_CMD_DATA_READ_RESET);
595
 
596
  /* Read buffer */
597
  while( uwBufferSize > 0U)
598
  {
599
    *pData++ = *(__IO uint16_t *)uwAddress;
600
    uwAddress += 2U;
601
    uwBufferSize--;
602
  }
603
 
604
  /* Check the NOR controller state */
605
  hnor->State = HAL_NOR_STATE_READY;
606
 
607
  /* Process unlocked */
608
  __HAL_UNLOCK(hnor);
609
 
610
  return HAL_OK;  
611
}
612
 
613
/**
614
  * @brief  Writes a half-word buffer to the FSMC NOR memory. This function
615
  *         must be used only with S29GL128P NOR memory.
616
  * @param  hnor: pointer to a NOR_HandleTypeDef structure that contains
617
  *                the configuration information for NOR module.
618
  * @param  uwAddress: NOR memory internal address from which the data
619
  * @note   Some NOR memory need Address aligned to xx bytes (can be aligned to
620
  *          64 bytes boundary for example).
621
  * @param  pData: pointer to source data buffer.
622
  * @param  uwBufferSize: number of Half words to write.
623
  * @note   The maximum buffer size allowed is NOR memory dependent
624
  *         (can be 64 Bytes max for example).
625
  * @retval HAL status
626
  */
627
HAL_StatusTypeDef HAL_NOR_ProgramBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData, uint32_t uwBufferSize)
628
{
629
  uint16_t * p_currentaddress = (uint16_t *)NULL;
630
  uint16_t * p_endaddress = (uint16_t *)NULL;
631
  uint32_t lastloadedaddress = 0U, deviceaddress = 0U;
632
 
633
  /* Process Locked */
634
  __HAL_LOCK(hnor);
635
 
636
  /* Check the NOR controller state */
637
  if(hnor->State == HAL_NOR_STATE_BUSY)
638
  {
639
     return HAL_BUSY;
640
  }
641
 
642
  /* Select the NOR device address */
643
  if (hnor->Init.NSBank == FSMC_NORSRAM_BANK1)
644
  {
645
    deviceaddress = NOR_MEMORY_ADRESS1;
646
  }
647
  else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK2)
648
  {
649
    deviceaddress = NOR_MEMORY_ADRESS2;
650
  }
651
  else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK3)
652
  {
653
    deviceaddress = NOR_MEMORY_ADRESS3;
654
  }
655
  else /* FSMC_NORSRAM_BANK4 */
656
  {
657
    deviceaddress = NOR_MEMORY_ADRESS4;
658
  }  
659
 
660
  /* Update the NOR controller state */
661
  hnor->State = HAL_NOR_STATE_BUSY;
662
 
663
  /* Initialize variables */
664
  p_currentaddress  = (uint16_t*)((uint32_t)(uwAddress));
665
  p_endaddress      = p_currentaddress + (uwBufferSize-1U);
666
  lastloadedaddress = (uint32_t)(uwAddress);
667
 
668
  /* Issue unlock command sequence */
669
  NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
670
  NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
671
 
672
  /* Write Buffer Load Command */
673
  NOR_WRITE((uint32_t)(p_currentaddress), NOR_CMD_DATA_BUFFER_AND_PROG);
674
  NOR_WRITE((uint32_t)(p_currentaddress), (uwBufferSize-1U));
675
 
676
  /* Load Data into NOR Buffer */
677
  while(p_currentaddress <= p_endaddress)
678
  {
679
    /* Store last loaded address & data value (for polling) */
680
    lastloadedaddress = (uint32_t)p_currentaddress;
681
 
682
    NOR_WRITE(p_currentaddress, *pData++);
683
 
684
    p_currentaddress++;
685
  }
686
 
687
  NOR_WRITE((uint32_t)(lastloadedaddress), NOR_CMD_DATA_BUFFER_AND_PROG_CONFIRM);
688
 
689
  /* Check the NOR controller state */
690
  hnor->State = HAL_NOR_STATE_READY;
691
 
692
  /* Process unlocked */
693
  __HAL_UNLOCK(hnor);
694
 
695
  return HAL_OK;
696
 
697
}
698
 
699
/**
700
  * @brief  Erase the specified block of the NOR memory
701
  * @param  hnor: pointer to a NOR_HandleTypeDef structure that contains
702
  *                the configuration information for NOR module.
703
  * @param  BlockAddress : Block to erase address
704
  * @param  Address: Device address
705
  * @retval HAL status
706
  */
707
HAL_StatusTypeDef HAL_NOR_Erase_Block(NOR_HandleTypeDef *hnor, uint32_t BlockAddress, uint32_t Address)
708
{
709
  uint32_t deviceaddress = 0U;
710
 
711
  /* Process Locked */
712
  __HAL_LOCK(hnor);
713
 
714
  /* Check the NOR controller state */
715
  if(hnor->State == HAL_NOR_STATE_BUSY)
716
  {
717
     return HAL_BUSY;
718
  }
719
 
720
  /* Select the NOR device address */
721
  if (hnor->Init.NSBank == FSMC_NORSRAM_BANK1)
722
  {
723
    deviceaddress = NOR_MEMORY_ADRESS1;
724
  }
725
  else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK2)
726
  {
727
    deviceaddress = NOR_MEMORY_ADRESS2;
728
  }
729
  else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK3)
730
  {
731
    deviceaddress = NOR_MEMORY_ADRESS3;
732
  }
733
  else /* FSMC_NORSRAM_BANK4 */
734
  {
735
    deviceaddress = NOR_MEMORY_ADRESS4;
736
  }
737
 
738
  /* Update the NOR controller state */
739
  hnor->State = HAL_NOR_STATE_BUSY;
740
 
741
  /* Send block erase command sequence */
742
  NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
743
  NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
744
  NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD);
745
  NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FOURTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH);
746
  NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIFTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH);
747
  NOR_WRITE((uint32_t)(BlockAddress + Address), NOR_CMD_DATA_BLOCK_ERASE);
748
 
749
  /* Check the NOR memory status and update the controller state */
750
  hnor->State = HAL_NOR_STATE_READY;
751
 
752
  /* Process unlocked */
753
  __HAL_UNLOCK(hnor);
754
 
755
  return HAL_OK;
756
 
757
}
758
 
759
/**
760
  * @brief  Erase the entire NOR chip.
761
  * @param  hnor: pointer to a NOR_HandleTypeDef structure that contains
762
  *                the configuration information for NOR module.
763
  * @param  Address : Device address  
764
  * @retval HAL status
765
  */
766
HAL_StatusTypeDef HAL_NOR_Erase_Chip(NOR_HandleTypeDef *hnor, uint32_t Address)
767
{
768
  /* Prevent unused argument(s) compilation warning */
769
  UNUSED(Address);
770
 
771
  uint32_t deviceaddress = 0U;
772
 
773
  /* Process Locked */
774
  __HAL_LOCK(hnor);
775
 
776
  /* Check the NOR controller state */
777
  if(hnor->State == HAL_NOR_STATE_BUSY)
778
  {
779
     return HAL_BUSY;
780
  }
781
 
782
  /* Select the NOR device address */
783
  if (hnor->Init.NSBank == FSMC_NORSRAM_BANK1)
784
  {
785
    deviceaddress = NOR_MEMORY_ADRESS1;
786
  }
787
  else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK2)
788
  {
789
    deviceaddress = NOR_MEMORY_ADRESS2;
790
  }
791
  else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK3)
792
  {
793
    deviceaddress = NOR_MEMORY_ADRESS3;
794
  }
795
  else /* FSMC_NORSRAM_BANK4 */
796
  {
797
    deviceaddress = NOR_MEMORY_ADRESS4;
798
  }
799
 
800
  /* Update the NOR controller state */
801
  hnor->State = HAL_NOR_STATE_BUSY;  
802
 
803
  /* Send NOR chip erase command sequence */
804
  NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
805
  NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
806
  NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD);
807
  NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FOURTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH);
808
  NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIFTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH);  
809
  NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SIXTH), NOR_CMD_DATA_CHIP_ERASE);
810
 
811
  /* Check the NOR memory status and update the controller state */
812
  hnor->State = HAL_NOR_STATE_READY;
813
 
814
  /* Process unlocked */
815
  __HAL_UNLOCK(hnor);
816
 
817
  return HAL_OK;  
818
}
819
 
820
/**
821
  * @brief  Read NOR flash CFI IDs
822
  * @param  hnor: pointer to a NOR_HandleTypeDef structure that contains
823
  *                the configuration information for NOR module.
824
  * @param  pNOR_CFI : pointer to NOR CFI IDs structure  
825
  * @retval HAL status
826
  */
827
HAL_StatusTypeDef HAL_NOR_Read_CFI(NOR_HandleTypeDef *hnor, NOR_CFITypeDef *pNOR_CFI)
828
{
829
  uint32_t deviceaddress = 0U;
830
 
831
  /* Process Locked */
832
  __HAL_LOCK(hnor);
833
 
834
  /* Check the NOR controller state */
835
  if(hnor->State == HAL_NOR_STATE_BUSY)
836
  {
837
     return HAL_BUSY;
838
  }
839
 
840
  /* Select the NOR device address */
841
  if (hnor->Init.NSBank == FSMC_NORSRAM_BANK1)
842
  {
843
    deviceaddress = NOR_MEMORY_ADRESS1;
844
  }
845
  else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK2)
846
  {
847
    deviceaddress = NOR_MEMORY_ADRESS2;
848
  }
849
  else if (hnor->Init.NSBank == FSMC_NORSRAM_BANK3)
850
  {
851
    deviceaddress = NOR_MEMORY_ADRESS3;
852
  }
853
  else /* FSMC_NORSRAM_BANK4 */
854
  {
855
    deviceaddress = NOR_MEMORY_ADRESS4;
856
  }  
857
 
858
  /* Update the NOR controller state */
859
  hnor->State = HAL_NOR_STATE_BUSY;
860
 
861
  /* Send read CFI query command */
862
  NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_CFI), NOR_CMD_DATA_CFI);
863
 
864
  /* read the NOR CFI information */
865
  pNOR_CFI->CFI_1 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI1_ADDRESS);
866
  pNOR_CFI->CFI_2 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI2_ADDRESS);
867
  pNOR_CFI->CFI_3 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI3_ADDRESS);
868
  pNOR_CFI->CFI_4 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI4_ADDRESS);
869
 
870
  /* Check the NOR controller state */
871
  hnor->State = HAL_NOR_STATE_READY;
872
 
873
  /* Process unlocked */
874
  __HAL_UNLOCK(hnor);
875
 
876
  return HAL_OK;
877
}
878
 
879
/**
880
  * @}
881
  */
882
 
883
/** @defgroup NOR_Exported_Functions_Group3 Control functions
884
 *  @brief   management functions
885
 *
886
@verbatim  
887
  ==============================================================================
888
                        ##### NOR Control functions #####
889
  ==============================================================================
890
  [..]
891
    This subsection provides a set of functions allowing to control dynamically
892
    the NOR interface.
893
 
894
@endverbatim
895
  * @{
896
  */
897
 
898
/**
899
  * @brief  Enables dynamically NOR write operation.
900
  * @param  hnor: pointer to a NOR_HandleTypeDef structure that contains
901
  *                the configuration information for NOR module.
902
  * @retval HAL status
903
  */
904
HAL_StatusTypeDef HAL_NOR_WriteOperation_Enable(NOR_HandleTypeDef *hnor)
905
{
906
  /* Process Locked */
907
  __HAL_LOCK(hnor);
908
 
909
  /* Enable write operation */
910
  FSMC_NORSRAM_WriteOperation_Enable(hnor->Instance, hnor->Init.NSBank);
911
 
912
  /* Update the NOR controller state */
913
  hnor->State = HAL_NOR_STATE_READY;
914
 
915
  /* Process unlocked */
916
  __HAL_UNLOCK(hnor);
917
 
918
  return HAL_OK;  
919
}
920
 
921
/**
922
  * @brief  Disables dynamically NOR write operation.
923
  * @param  hnor: pointer to a NOR_HandleTypeDef structure that contains
924
  *                the configuration information for NOR module.
925
  * @retval HAL status
926
  */
927
HAL_StatusTypeDef HAL_NOR_WriteOperation_Disable(NOR_HandleTypeDef *hnor)
928
{
929
  /* Process Locked */
930
  __HAL_LOCK(hnor);
931
 
932
  /* Update the SRAM controller state */
933
  hnor->State = HAL_NOR_STATE_BUSY;
934
 
935
  /* Disable write operation */
936
  FSMC_NORSRAM_WriteOperation_Disable(hnor->Instance, hnor->Init.NSBank);
937
 
938
  /* Update the NOR controller state */
939
  hnor->State = HAL_NOR_STATE_PROTECTED;
940
 
941
  /* Process unlocked */
942
  __HAL_UNLOCK(hnor);
943
 
944
  return HAL_OK;  
945
}
946
 
947
/**
948
  * @}
949
  */  
950
 
951
/** @defgroup NOR_Exported_Functions_Group4 State functions
952
 *  @brief   Peripheral State functions
953
 *
954
@verbatim  
955
  ==============================================================================
956
                      ##### NOR State functions #####
957
  ==============================================================================  
958
  [..]
959
    This subsection permits to get in run-time the status of the NOR controller
960
    and the data flow.
961
 
962
@endverbatim
963
  * @{
964
  */
965
 
966
/**
967
  * @brief  return the NOR controller state
968
  * @param  hnor: pointer to a NOR_HandleTypeDef structure that contains
969
  *                the configuration information for NOR module.
970
  * @retval NOR controller state
971
  */
972
HAL_NOR_StateTypeDef HAL_NOR_GetState(NOR_HandleTypeDef *hnor)
973
{
974
  return hnor->State;
975
}
976
 
977
/**
978
  * @brief  Returns the NOR operation status.
979
  * @param  hnor: pointer to a NOR_HandleTypeDef structure that contains
980
  *                the configuration information for NOR module.  
981
  * @param  Address: Device address
982
  * @param  Timeout: NOR progamming Timeout
983
  * @retval NOR_Status: The returned value can be: HAL_NOR_STATUS_SUCCESS, HAL_NOR_STATUS_ERROR
984
  *         or HAL_NOR_STATUS_TIMEOUT
985
  */
986
HAL_NOR_StatusTypeDef HAL_NOR_GetStatus(NOR_HandleTypeDef *hnor, uint32_t Address, uint32_t Timeout)
987
{
988
  HAL_NOR_StatusTypeDef status = HAL_NOR_STATUS_ONGOING;
989
  uint16_t tmp_sr1 = 0, tmp_sr2 = 0;
990
  uint32_t tickstart = 0U;
991
 
992
  /* Poll on NOR memory Ready/Busy signal ------------------------------------*/
993
  HAL_NOR_MspWait(hnor, Timeout);
994
 
995
  /* Get tick */
996
  tickstart = HAL_GetTick();
997
  while((status != HAL_NOR_STATUS_SUCCESS) && (status != HAL_NOR_STATUS_TIMEOUT))
998
  {
999
    /* Check for the Timeout */
1000
    if(Timeout != HAL_MAX_DELAY)
1001
    {
1002
      if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
1003
      {
1004
        status = HAL_NOR_STATUS_TIMEOUT;
1005
      }  
1006
    }
1007
 
1008
    /* Read NOR status register (DQ6 and DQ5) */
1009
    tmp_sr1 = *(__IO uint16_t *)Address;
1010
    tmp_sr2 = *(__IO uint16_t *)Address;
1011
 
1012
    /* If DQ6 did not toggle between the two reads then return NOR_Success */
1013
    if((tmp_sr1 & NOR_MASK_STATUS_DQ6) == (tmp_sr2 & NOR_MASK_STATUS_DQ6))
1014
    {
1015
      return HAL_NOR_STATUS_SUCCESS;
1016
    }
1017
 
1018
    if((tmp_sr1 & NOR_MASK_STATUS_DQ5) != NOR_MASK_STATUS_DQ5)
1019
    {
1020
      status = HAL_NOR_STATUS_ONGOING;
1021
    }
1022
 
1023
    tmp_sr1 = *(__IO uint16_t *)Address;
1024
    tmp_sr2 = *(__IO uint16_t *)Address;
1025
 
1026
    /* If DQ6 did not toggle between the two reads then return NOR_Success */
1027
    if((tmp_sr1 & NOR_MASK_STATUS_DQ6) == (tmp_sr2 & NOR_MASK_STATUS_DQ6))
1028
    {
1029
      return HAL_NOR_STATUS_SUCCESS;
1030
    }
1031
    else if((tmp_sr1 & NOR_MASK_STATUS_DQ5) == NOR_MASK_STATUS_DQ5)
1032
    {
1033
      return HAL_NOR_STATUS_ERROR;
1034
    }
1035
  }
1036
 
1037
  /* Return the operation status */
1038
  return status;
1039
}
1040
 
1041
/**
1042
  * @}
1043
  */
1044
 
1045
/**
1046
  * @}
1047
  */
1048
/**
1049
  * @}
1050
  */
1051
#endif /* STM32F101xE || STM32F103xE || STM32F101xG || STM32F103xG || STM32F100xE */
1052
#endif /* HAL_NOR_MODULE_ENABLED */
1053
 
1054
/**
1055
  * @}
1056
  */
1057
 
1058
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/