Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
stm32l4xx_hal_nor.c
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l4xx_hal_nor.c 00004 * @author MCD Application Team 00005 * @version V1.5.1 00006 * @date 31-May-2016 00007 * @brief NOR HAL module driver. 00008 * This file provides a generic firmware to drive NOR memories mounted 00009 * as external device. 00010 * 00011 @verbatim 00012 ============================================================================== 00013 ##### How to use this driver ##### 00014 ============================================================================== 00015 [..] 00016 This driver is a generic layered driver which contains a set of APIs used to 00017 control NOR flash memories. It uses the FMC layer functions to interface 00018 with NOR devices. This driver is used as follows: 00019 00020 (+) NOR flash memory configuration sequence using the function HAL_NOR_Init() 00021 with control and timing parameters for both normal and extended mode. 00022 00023 (+) Read NOR flash memory manufacturer code and device IDs using the function 00024 HAL_NOR_Read_ID(). The read information is stored in the NOR_ID_TypeDef 00025 structure declared by the function caller. 00026 00027 (+) Access NOR flash memory by read/write data unit operations using the functions 00028 HAL_NOR_Read(), HAL_NOR_Program(). 00029 00030 (+) Perform NOR flash erase block/chip operations using the functions 00031 HAL_NOR_Erase_Block() and HAL_NOR_Erase_Chip(). 00032 00033 (+) Read the NOR flash CFI (common flash interface) IDs using the function 00034 HAL_NOR_Read_CFI(). The read information is stored in the NOR_CFI_TypeDef 00035 structure declared by the function caller. 00036 00037 (+) You can also control the NOR device by calling the control APIs HAL_NOR_WriteOperation_Enable()/ 00038 HAL_NOR_WriteOperation_Disable() to respectively enable/disable the NOR write operation 00039 00040 (+) You can monitor the NOR device HAL state by calling the function 00041 HAL_NOR_GetState() 00042 [..] 00043 (@) This driver is a set of generic APIs which handle standard NOR flash operations. 00044 If a NOR flash device contains different operations and/or implementations, 00045 it should be implemented separately. 00046 00047 *** NOR HAL driver macros list *** 00048 ============================================= 00049 [..] 00050 Below the list of most used macros in NOR HAL driver. 00051 00052 (+) NOR_WRITE : NOR memory write data to specified address 00053 00054 @endverbatim 00055 ****************************************************************************** 00056 * @attention 00057 * 00058 * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2> 00059 * 00060 * Redistribution and use in source and binary forms, with or without modification, 00061 * are permitted provided that the following conditions are met: 00062 * 1. Redistributions of source code must retain the above copyright notice, 00063 * this list of conditions and the following disclaimer. 00064 * 2. Redistributions in binary form must reproduce the above copyright notice, 00065 * this list of conditions and the following disclaimer in the documentation 00066 * and/or other materials provided with the distribution. 00067 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00068 * may be used to endorse or promote products derived from this software 00069 * without specific prior written permission. 00070 * 00071 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00072 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00073 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00074 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00075 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00076 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00077 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00078 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00079 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00080 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00081 * 00082 ****************************************************************************** 00083 */ 00084 00085 /* Includes ------------------------------------------------------------------*/ 00086 #include "stm32l4xx_hal.h" 00087 00088 #if defined(STM32L471xx) || defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx) 00089 00090 /** @addtogroup STM32L4xx_HAL_Driver 00091 * @{ 00092 */ 00093 00094 #ifdef HAL_NOR_MODULE_ENABLED 00095 00096 /** @defgroup NOR NOR 00097 * @brief NOR HAL module driver 00098 * @{ 00099 */ 00100 /* Private typedef -----------------------------------------------------------*/ 00101 /* Private define ------------------------------------------------------------*/ 00102 /** @defgroup NOR_Private_Constants NOR Private Constants 00103 * @{ 00104 */ 00105 00106 /* Constants to define address to set to write a command */ 00107 #define NOR_CMD_ADDRESS_FIRST (uint16_t)0x0555 00108 #define NOR_CMD_ADDRESS_FIRST_CFI (uint16_t)0x0055 00109 #define NOR_CMD_ADDRESS_SECOND (uint16_t)0x02AA 00110 #define NOR_CMD_ADDRESS_THIRD (uint16_t)0x0555 00111 #define NOR_CMD_ADDRESS_FOURTH (uint16_t)0x0555 00112 #define NOR_CMD_ADDRESS_FIFTH (uint16_t)0x02AA 00113 #define NOR_CMD_ADDRESS_SIXTH (uint16_t)0x0555 00114 00115 /* Constants to define data to program a command */ 00116 #define NOR_CMD_DATA_READ_RESET (uint16_t)0x00F0 00117 #define NOR_CMD_DATA_FIRST (uint16_t)0x00AA 00118 #define NOR_CMD_DATA_SECOND (uint16_t)0x0055 00119 #define NOR_CMD_DATA_AUTO_SELECT (uint16_t)0x0090 00120 #define NOR_CMD_DATA_PROGRAM (uint16_t)0x00A0 00121 #define NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD (uint16_t)0x0080 00122 #define NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH (uint16_t)0x00AA 00123 #define NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH (uint16_t)0x0055 00124 #define NOR_CMD_DATA_CHIP_ERASE (uint16_t)0x0010 00125 #define NOR_CMD_DATA_CFI (uint16_t)0x0098 00126 00127 #define NOR_CMD_DATA_BUFFER_AND_PROG (uint8_t)0x25 00128 #define NOR_CMD_DATA_BUFFER_AND_PROG_CONFIRM (uint8_t)0x29 00129 #define NOR_CMD_DATA_BLOCK_ERASE (uint8_t)0x30 00130 00131 /* Mask on NOR STATUS REGISTER */ 00132 #define NOR_MASK_STATUS_DQ5 (uint16_t)0x0020 00133 #define NOR_MASK_STATUS_DQ6 (uint16_t)0x0040 00134 00135 /** 00136 * @} 00137 */ 00138 00139 /* Private macro -------------------------------------------------------------*/ 00140 /** @defgroup NOR_Private_Macros NOR Private Macros 00141 * @{ 00142 */ 00143 00144 /** 00145 * @} 00146 */ 00147 00148 /* Private variables ---------------------------------------------------------*/ 00149 00150 /** @defgroup NOR_Private_Variables NOR Private Variables 00151 * @{ 00152 */ 00153 00154 static uint32_t uwNORMemoryDataWidth = NOR_MEMORY_8B; 00155 00156 /** 00157 * @} 00158 */ 00159 00160 /* Exported functions ---------------------------------------------------------*/ 00161 00162 /** @defgroup NOR_Exported_Functions NOR Exported Functions 00163 * @{ 00164 */ 00165 00166 /** @defgroup NOR_Exported_Functions_Group1 Initialization and de-initialization functions 00167 * @brief Initialization and Configuration functions 00168 * 00169 @verbatim 00170 ============================================================================== 00171 ##### NOR Initialization and de-initialization functions ##### 00172 ============================================================================== 00173 [..] 00174 This section provides functions allowing to initialize/de-initialize 00175 the NOR memory 00176 00177 @endverbatim 00178 * @{ 00179 */ 00180 00181 /** 00182 * @brief Perform the NOR memory Initialization sequence. 00183 * @param hnor: pointer to a NOR_HandleTypeDef structure that contains 00184 * the configuration information for NOR module. 00185 * @param Timing: pointer to NOR control timing structure 00186 * @param ExtTiming: pointer to NOR extended mode timing structure 00187 * @retval HAL status 00188 */ 00189 HAL_StatusTypeDef HAL_NOR_Init(NOR_HandleTypeDef *hnor, FMC_NORSRAM_TimingTypeDef *Timing, FMC_NORSRAM_TimingTypeDef *ExtTiming) 00190 { 00191 /* Check the NOR handle parameter */ 00192 if(hnor == NULL) 00193 { 00194 return HAL_ERROR; 00195 } 00196 00197 if(hnor->State == HAL_NOR_STATE_RESET) 00198 { 00199 /* Allocate lock resource and initialize it */ 00200 hnor->Lock = HAL_UNLOCKED; 00201 00202 /* Initialize the low level hardware (MSP) */ 00203 HAL_NOR_MspInit(hnor); 00204 } 00205 00206 /* Initialize NOR control Interface */ 00207 FMC_NORSRAM_Init(hnor->Instance, &(hnor->Init)); 00208 00209 /* Initialize NOR timing Interface */ 00210 FMC_NORSRAM_Timing_Init(hnor->Instance, Timing, hnor->Init.NSBank); 00211 00212 /* Initialize NOR extended mode timing Interface */ 00213 FMC_NORSRAM_Extended_Timing_Init(hnor->Extended, ExtTiming, hnor->Init.NSBank, hnor->Init.ExtendedMode); 00214 00215 /* Enable the NORSRAM device */ 00216 __FMC_NORSRAM_ENABLE(hnor->Instance, hnor->Init.NSBank); 00217 00218 /* Initialize NOR Memory Data Width*/ 00219 if (hnor->Init.MemoryDataWidth == FMC_NORSRAM_MEM_BUS_WIDTH_8) 00220 { 00221 uwNORMemoryDataWidth = NOR_MEMORY_8B; 00222 } 00223 else 00224 { 00225 uwNORMemoryDataWidth = NOR_MEMORY_16B; 00226 } 00227 00228 /* Check the NOR controller state */ 00229 hnor->State = HAL_NOR_STATE_READY; 00230 00231 return HAL_OK; 00232 } 00233 00234 /** 00235 * @brief Perform NOR memory De-Initialization sequence. 00236 * @param hnor: pointer to a NOR_HandleTypeDef structure that contains 00237 * the configuration information for NOR module. 00238 * @retval HAL status 00239 */ 00240 HAL_StatusTypeDef HAL_NOR_DeInit(NOR_HandleTypeDef *hnor) 00241 { 00242 /* De-Initialize the low level hardware (MSP) */ 00243 HAL_NOR_MspDeInit(hnor); 00244 00245 /* Configure the NOR registers with their reset values */ 00246 FMC_NORSRAM_DeInit(hnor->Instance, hnor->Extended, hnor->Init.NSBank); 00247 00248 /* Update the NOR controller state */ 00249 hnor->State = HAL_NOR_STATE_RESET; 00250 00251 /* Release Lock */ 00252 __HAL_UNLOCK(hnor); 00253 00254 return HAL_OK; 00255 } 00256 00257 /** 00258 * @brief Initialize the NOR MSP. 00259 * @param hnor: pointer to a NOR_HandleTypeDef structure that contains 00260 * the configuration information for NOR module. 00261 * @retval None 00262 */ 00263 __weak void HAL_NOR_MspInit(NOR_HandleTypeDef *hnor) 00264 { 00265 /* Prevent unused argument(s) compilation warning */ 00266 UNUSED(hnor); 00267 00268 /* NOTE : This function should not be modified, when the callback is needed, 00269 the HAL_NOR_MspInit could be implemented in the user file 00270 */ 00271 } 00272 00273 /** 00274 * @brief DeInitialize the NOR MSP. 00275 * @param hnor: pointer to a NOR_HandleTypeDef structure that contains 00276 * the configuration information for NOR module. 00277 * @retval None 00278 */ 00279 __weak void HAL_NOR_MspDeInit(NOR_HandleTypeDef *hnor) 00280 { 00281 /* Prevent unused argument(s) compilation warning */ 00282 UNUSED(hnor); 00283 00284 /* NOTE : This function should not be modified, when the callback is needed, 00285 the HAL_NOR_MspDeInit could be implemented in the user file 00286 */ 00287 } 00288 00289 /** 00290 * @brief NOR MSP Wait for Ready/Busy signal. 00291 * @param hnor: pointer to a NOR_HandleTypeDef structure that contains 00292 * the configuration information for NOR module. 00293 * @param Timeout: Maximum timeout value 00294 * @retval None 00295 */ 00296 __weak void HAL_NOR_MspWait(NOR_HandleTypeDef *hnor, uint32_t Timeout) 00297 { 00298 /* Prevent unused argument(s) compilation warning */ 00299 UNUSED(hnor); 00300 UNUSED(Timeout); 00301 00302 /* NOTE : This function should not be modified, when the callback is needed, 00303 the HAL_NOR_MspWait could be implemented in the user file 00304 */ 00305 } 00306 00307 /** 00308 * @} 00309 */ 00310 00311 /** @defgroup NOR_Exported_Functions_Group2 Input and Output functions 00312 * @brief Input Output and memory control functions 00313 * 00314 @verbatim 00315 ============================================================================== 00316 ##### NOR Input and Output functions ##### 00317 ============================================================================== 00318 [..] 00319 This section provides functions allowing to use and control the NOR memory 00320 00321 @endverbatim 00322 * @{ 00323 */ 00324 00325 /** 00326 * @brief Read NOR flash IDs. 00327 * @param hnor: pointer to a NOR_HandleTypeDef structure that contains 00328 * the configuration information for NOR module. 00329 * @param pNOR_ID : pointer to NOR ID structure 00330 * @retval HAL status 00331 */ 00332 HAL_StatusTypeDef HAL_NOR_Read_ID(NOR_HandleTypeDef *hnor, NOR_IDTypeDef *pNOR_ID) 00333 { 00334 uint32_t deviceaddress = 0; 00335 00336 /* Process Locked */ 00337 __HAL_LOCK(hnor); 00338 00339 /* Check the NOR controller state */ 00340 if(hnor->State == HAL_NOR_STATE_BUSY) 00341 { 00342 return HAL_BUSY; 00343 } 00344 00345 /* Select the NOR device address */ 00346 if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) 00347 { 00348 deviceaddress = NOR_MEMORY_ADRESS1; 00349 } 00350 else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) 00351 { 00352 deviceaddress = NOR_MEMORY_ADRESS2; 00353 } 00354 else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) 00355 { 00356 deviceaddress = NOR_MEMORY_ADRESS3; 00357 } 00358 else /* FMC_NORSRAM_BANK4 */ 00359 { 00360 deviceaddress = NOR_MEMORY_ADRESS4; 00361 } 00362 00363 /* Update the NOR controller state */ 00364 hnor->State = HAL_NOR_STATE_BUSY; 00365 00366 /* Send read ID command */ 00367 NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST); 00368 NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND); 00369 NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_AUTO_SELECT); 00370 00371 /* Read the NOR IDs */ 00372 pNOR_ID->Manufacturer_Code = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, MC_ADDRESS); 00373 pNOR_ID->Device_Code1 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, DEVICE_CODE1_ADDR); 00374 pNOR_ID->Device_Code2 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, DEVICE_CODE2_ADDR); 00375 pNOR_ID->Device_Code3 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, DEVICE_CODE3_ADDR); 00376 00377 /* Check the NOR controller state */ 00378 hnor->State = HAL_NOR_STATE_READY; 00379 00380 /* Process unlocked */ 00381 __HAL_UNLOCK(hnor); 00382 00383 return HAL_OK; 00384 } 00385 00386 /** 00387 * @brief Return the NOR memory to Read mode. 00388 * @param hnor: pointer to a NOR_HandleTypeDef structure that contains 00389 * the configuration information for NOR module. 00390 * @retval HAL status 00391 */ 00392 HAL_StatusTypeDef HAL_NOR_ReturnToReadMode(NOR_HandleTypeDef *hnor) 00393 { 00394 uint32_t deviceaddress = 0; 00395 00396 /* Process Locked */ 00397 __HAL_LOCK(hnor); 00398 00399 /* Check the NOR controller state */ 00400 if(hnor->State == HAL_NOR_STATE_BUSY) 00401 { 00402 return HAL_BUSY; 00403 } 00404 00405 /* Select the NOR device address */ 00406 if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) 00407 { 00408 deviceaddress = NOR_MEMORY_ADRESS1; 00409 } 00410 else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) 00411 { 00412 deviceaddress = NOR_MEMORY_ADRESS2; 00413 } 00414 else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) 00415 { 00416 deviceaddress = NOR_MEMORY_ADRESS3; 00417 } 00418 else /* FMC_NORSRAM_BANK4 */ 00419 { 00420 deviceaddress = NOR_MEMORY_ADRESS4; 00421 } 00422 00423 NOR_WRITE(deviceaddress, NOR_CMD_DATA_READ_RESET); 00424 00425 /* Check the NOR controller state */ 00426 hnor->State = HAL_NOR_STATE_READY; 00427 00428 /* Process unlocked */ 00429 __HAL_UNLOCK(hnor); 00430 00431 return HAL_OK; 00432 } 00433 00434 /** 00435 * @brief Read data from NOR memory. 00436 * @param hnor: pointer to a NOR_HandleTypeDef structure that contains 00437 * the configuration information for NOR module. 00438 * @param pAddress: pointer to Device address 00439 * @param pData : pointer to read data 00440 * @retval HAL status 00441 */ 00442 HAL_StatusTypeDef HAL_NOR_Read(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData) 00443 { 00444 uint32_t deviceaddress = 0; 00445 00446 /* Process Locked */ 00447 __HAL_LOCK(hnor); 00448 00449 /* Check the NOR controller state */ 00450 if(hnor->State == HAL_NOR_STATE_BUSY) 00451 { 00452 return HAL_BUSY; 00453 } 00454 00455 /* Select the NOR device address */ 00456 if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) 00457 { 00458 deviceaddress = NOR_MEMORY_ADRESS1; 00459 } 00460 else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) 00461 { 00462 deviceaddress = NOR_MEMORY_ADRESS2; 00463 } 00464 else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) 00465 { 00466 deviceaddress = NOR_MEMORY_ADRESS3; 00467 } 00468 else /* FMC_NORSRAM_BANK4 */ 00469 { 00470 deviceaddress = NOR_MEMORY_ADRESS4; 00471 } 00472 00473 /* Update the NOR controller state */ 00474 hnor->State = HAL_NOR_STATE_BUSY; 00475 00476 /* Send read data command */ 00477 NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST); 00478 NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND); 00479 NOR_WRITE((uint32_t)pAddress, NOR_CMD_DATA_READ_RESET); 00480 00481 /* Read the data */ 00482 *pData = *(__IO uint32_t *)(uint32_t)pAddress; 00483 00484 /* Check the NOR controller state */ 00485 hnor->State = HAL_NOR_STATE_READY; 00486 00487 /* Process unlocked */ 00488 __HAL_UNLOCK(hnor); 00489 00490 return HAL_OK; 00491 } 00492 00493 /** 00494 * @brief Program data to NOR memory. 00495 * @param hnor: pointer to a NOR_HandleTypeDef structure that contains 00496 * the configuration information for NOR module. 00497 * @param pAddress: Device address 00498 * @param pData : pointer to the data to write 00499 * @retval HAL status 00500 */ 00501 HAL_StatusTypeDef HAL_NOR_Program(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData) 00502 { 00503 uint32_t deviceaddress = 0; 00504 00505 /* Process Locked */ 00506 __HAL_LOCK(hnor); 00507 00508 /* Check the NOR controller state */ 00509 if(hnor->State == HAL_NOR_STATE_BUSY) 00510 { 00511 return HAL_BUSY; 00512 } 00513 00514 /* Select the NOR device address */ 00515 if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) 00516 { 00517 deviceaddress = NOR_MEMORY_ADRESS1; 00518 } 00519 else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) 00520 { 00521 deviceaddress = NOR_MEMORY_ADRESS2; 00522 } 00523 else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) 00524 { 00525 deviceaddress = NOR_MEMORY_ADRESS3; 00526 } 00527 else /* FMC_NORSRAM_BANK4 */ 00528 { 00529 deviceaddress = NOR_MEMORY_ADRESS4; 00530 } 00531 00532 /* Update the NOR controller state */ 00533 hnor->State = HAL_NOR_STATE_BUSY; 00534 00535 /* Send program data command */ 00536 NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST); 00537 NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND); 00538 NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_PROGRAM); 00539 00540 /* Write the data */ 00541 NOR_WRITE(pAddress, *pData); 00542 00543 /* Check the NOR controller state */ 00544 hnor->State = HAL_NOR_STATE_READY; 00545 00546 /* Process unlocked */ 00547 __HAL_UNLOCK(hnor); 00548 00549 return HAL_OK; 00550 } 00551 00552 /** 00553 * @brief Read a block of data from the FMC NOR memory. 00554 * @param hnor: pointer to a NOR_HandleTypeDef structure that contains 00555 * the configuration information for NOR module. 00556 * @param uwAddress: NOR memory internal address to read from. 00557 * @param pData: pointer to the buffer that receives the data read from the 00558 * NOR memory. 00559 * @param uwBufferSize : number of Half word to read. 00560 * @retval HAL status 00561 */ 00562 HAL_StatusTypeDef HAL_NOR_ReadBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData, uint32_t uwBufferSize) 00563 { 00564 uint32_t deviceaddress = 0; 00565 00566 /* Process Locked */ 00567 __HAL_LOCK(hnor); 00568 00569 /* Check the NOR controller state */ 00570 if(hnor->State == HAL_NOR_STATE_BUSY) 00571 { 00572 return HAL_BUSY; 00573 } 00574 00575 /* Select the NOR device address */ 00576 if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) 00577 { 00578 deviceaddress = NOR_MEMORY_ADRESS1; 00579 } 00580 else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) 00581 { 00582 deviceaddress = NOR_MEMORY_ADRESS2; 00583 } 00584 else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) 00585 { 00586 deviceaddress = NOR_MEMORY_ADRESS3; 00587 } 00588 else /* FMC_NORSRAM_BANK4 */ 00589 { 00590 deviceaddress = NOR_MEMORY_ADRESS4; 00591 } 00592 00593 /* Update the NOR controller state */ 00594 hnor->State = HAL_NOR_STATE_BUSY; 00595 00596 /* Send read data command */ 00597 NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST); 00598 NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND); 00599 NOR_WRITE(uwAddress, NOR_CMD_DATA_READ_RESET); 00600 00601 /* Read buffer */ 00602 while( uwBufferSize > 0) 00603 { 00604 *pData++ = *(__IO uint16_t *)uwAddress; 00605 uwAddress += 2; 00606 uwBufferSize--; 00607 } 00608 00609 /* Check the NOR controller state */ 00610 hnor->State = HAL_NOR_STATE_READY; 00611 00612 /* Process unlocked */ 00613 __HAL_UNLOCK(hnor); 00614 00615 return HAL_OK; 00616 } 00617 00618 /** 00619 * @brief Write a half-word buffer to the FMC NOR memory. This function 00620 * must be used only with S29GL128P NOR memory. 00621 * @param hnor: pointer to a NOR_HandleTypeDef structure that contains 00622 * the configuration information for NOR module. 00623 * @param uwAddress: NOR memory internal address from which the data 00624 * @note Some NOR memory need Address aligned to xx bytes (can be aligned to 00625 * 64 bytes boundary for example). 00626 * @param pData: pointer to source data buffer. 00627 * @param uwBufferSize: number of Half words to write. 00628 * @note The maximum buffer size allowed is NOR memory dependent 00629 * (can be 64 Bytes max for example). 00630 * @retval HAL status 00631 */ 00632 HAL_StatusTypeDef HAL_NOR_ProgramBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData, uint32_t uwBufferSize) 00633 { 00634 uint16_t * p_currentaddress = (uint16_t *)NULL; 00635 uint16_t * p_endaddress = (uint16_t *)NULL; 00636 uint32_t lastloadedaddress = 0, deviceaddress = 0; 00637 00638 /* Process Locked */ 00639 __HAL_LOCK(hnor); 00640 00641 /* Check the NOR controller state */ 00642 if(hnor->State == HAL_NOR_STATE_BUSY) 00643 { 00644 return HAL_BUSY; 00645 } 00646 00647 /* Select the NOR device address */ 00648 if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) 00649 { 00650 deviceaddress = NOR_MEMORY_ADRESS1; 00651 } 00652 else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) 00653 { 00654 deviceaddress = NOR_MEMORY_ADRESS2; 00655 } 00656 else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) 00657 { 00658 deviceaddress = NOR_MEMORY_ADRESS3; 00659 } 00660 else /* FMC_NORSRAM_BANK4 */ 00661 { 00662 deviceaddress = NOR_MEMORY_ADRESS4; 00663 } 00664 00665 /* Update the NOR controller state */ 00666 hnor->State = HAL_NOR_STATE_BUSY; 00667 00668 /* Initialize variables */ 00669 p_currentaddress = (uint16_t*)((uint32_t)(uwAddress)); 00670 p_endaddress = p_currentaddress + (uwBufferSize-1); 00671 lastloadedaddress = (uint32_t)(uwAddress); 00672 00673 /* Issue unlock command sequence */ 00674 NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST); 00675 NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND); 00676 00677 /* Write Buffer Load Command */ 00678 NOR_WRITE((uint32_t)(p_currentaddress), NOR_CMD_DATA_BUFFER_AND_PROG); 00679 NOR_WRITE((uint32_t)(p_currentaddress), (uwBufferSize-1)); 00680 00681 /* Load Data into NOR Buffer */ 00682 while(p_currentaddress <= p_endaddress) 00683 { 00684 /* Store last loaded address & data value (for polling) */ 00685 lastloadedaddress = (uint32_t)p_currentaddress; 00686 00687 NOR_WRITE(p_currentaddress, *pData++); 00688 00689 p_currentaddress++; 00690 } 00691 00692 NOR_WRITE((uint32_t)(lastloadedaddress), NOR_CMD_DATA_BUFFER_AND_PROG_CONFIRM); 00693 00694 /* Check the NOR controller state */ 00695 hnor->State = HAL_NOR_STATE_READY; 00696 00697 /* Process unlocked */ 00698 __HAL_UNLOCK(hnor); 00699 00700 return HAL_OK; 00701 00702 } 00703 00704 /** 00705 * @brief Erase the specified block of the NOR memory. 00706 * @param hnor: pointer to a NOR_HandleTypeDef structure that contains 00707 * the configuration information for NOR module. 00708 * @param BlockAddress : Block to erase address 00709 * @param Address: Device address 00710 * @retval HAL status 00711 */ 00712 HAL_StatusTypeDef HAL_NOR_Erase_Block(NOR_HandleTypeDef *hnor, uint32_t BlockAddress, uint32_t Address) 00713 { 00714 uint32_t deviceaddress = 0; 00715 00716 /* Process Locked */ 00717 __HAL_LOCK(hnor); 00718 00719 /* Check the NOR controller state */ 00720 if(hnor->State == HAL_NOR_STATE_BUSY) 00721 { 00722 return HAL_BUSY; 00723 } 00724 00725 /* Select the NOR device address */ 00726 if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) 00727 { 00728 deviceaddress = NOR_MEMORY_ADRESS1; 00729 } 00730 else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) 00731 { 00732 deviceaddress = NOR_MEMORY_ADRESS2; 00733 } 00734 else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) 00735 { 00736 deviceaddress = NOR_MEMORY_ADRESS3; 00737 } 00738 else /* FMC_NORSRAM_BANK4 */ 00739 { 00740 deviceaddress = NOR_MEMORY_ADRESS4; 00741 } 00742 00743 /* Update the NOR controller state */ 00744 hnor->State = HAL_NOR_STATE_BUSY; 00745 00746 /* Send block erase command sequence */ 00747 NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST); 00748 NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND); 00749 NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD); 00750 NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FOURTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH); 00751 NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIFTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH); 00752 NOR_WRITE((uint32_t)(BlockAddress + Address), NOR_CMD_DATA_BLOCK_ERASE); 00753 00754 /* Check the NOR memory status and update the controller state */ 00755 hnor->State = HAL_NOR_STATE_READY; 00756 00757 /* Process unlocked */ 00758 __HAL_UNLOCK(hnor); 00759 00760 return HAL_OK; 00761 00762 } 00763 00764 /** 00765 * @brief Erase the entire NOR chip. 00766 * @param hnor: pointer to a NOR_HandleTypeDef structure that contains 00767 * the configuration information for NOR module. 00768 * @param Address : Device address 00769 * @retval HAL status 00770 */ 00771 HAL_StatusTypeDef HAL_NOR_Erase_Chip(NOR_HandleTypeDef *hnor, uint32_t Address) 00772 { 00773 uint32_t deviceaddress = 0; 00774 00775 /* Prevent unused argument(s) compilation warning */ 00776 UNUSED(Address); 00777 00778 /* Process Locked */ 00779 __HAL_LOCK(hnor); 00780 00781 /* Check the NOR controller state */ 00782 if(hnor->State == HAL_NOR_STATE_BUSY) 00783 { 00784 return HAL_BUSY; 00785 } 00786 00787 /* Select the NOR device address */ 00788 if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) 00789 { 00790 deviceaddress = NOR_MEMORY_ADRESS1; 00791 } 00792 else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) 00793 { 00794 deviceaddress = NOR_MEMORY_ADRESS2; 00795 } 00796 else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) 00797 { 00798 deviceaddress = NOR_MEMORY_ADRESS3; 00799 } 00800 else /* FMC_NORSRAM_BANK4 */ 00801 { 00802 deviceaddress = NOR_MEMORY_ADRESS4; 00803 } 00804 00805 /* Update the NOR controller state */ 00806 hnor->State = HAL_NOR_STATE_BUSY; 00807 00808 /* Send NOR chip erase command sequence */ 00809 NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST); 00810 NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND); 00811 NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD); 00812 NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FOURTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH); 00813 NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIFTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH); 00814 NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SIXTH), NOR_CMD_DATA_CHIP_ERASE); 00815 00816 /* Check the NOR memory status and update the controller state */ 00817 hnor->State = HAL_NOR_STATE_READY; 00818 00819 /* Process unlocked */ 00820 __HAL_UNLOCK(hnor); 00821 00822 return HAL_OK; 00823 } 00824 00825 /** 00826 * @brief Read NOR flash CFI IDs. 00827 * @param hnor: pointer to a NOR_HandleTypeDef structure that contains 00828 * the configuration information for NOR module. 00829 * @param pNOR_CFI : pointer to NOR CFI IDs structure 00830 * @retval HAL status 00831 */ 00832 HAL_StatusTypeDef HAL_NOR_Read_CFI(NOR_HandleTypeDef *hnor, NOR_CFITypeDef *pNOR_CFI) 00833 { 00834 uint32_t deviceaddress = 0; 00835 00836 /* Process Locked */ 00837 __HAL_LOCK(hnor); 00838 00839 /* Check the NOR controller state */ 00840 if(hnor->State == HAL_NOR_STATE_BUSY) 00841 { 00842 return HAL_BUSY; 00843 } 00844 00845 /* Select the NOR device address */ 00846 if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) 00847 { 00848 deviceaddress = NOR_MEMORY_ADRESS1; 00849 } 00850 else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) 00851 { 00852 deviceaddress = NOR_MEMORY_ADRESS2; 00853 } 00854 else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) 00855 { 00856 deviceaddress = NOR_MEMORY_ADRESS3; 00857 } 00858 else /* FMC_NORSRAM_BANK4 */ 00859 { 00860 deviceaddress = NOR_MEMORY_ADRESS4; 00861 } 00862 00863 /* Update the NOR controller state */ 00864 hnor->State = HAL_NOR_STATE_BUSY; 00865 00866 /* Send read CFI query command */ 00867 NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_CFI), NOR_CMD_DATA_CFI); 00868 00869 /* read the NOR CFI information */ 00870 pNOR_CFI->CFI_1 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI1_ADDRESS); 00871 pNOR_CFI->CFI_2 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI2_ADDRESS); 00872 pNOR_CFI->CFI_3 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI3_ADDRESS); 00873 pNOR_CFI->CFI_4 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI4_ADDRESS); 00874 00875 /* Check the NOR controller state */ 00876 hnor->State = HAL_NOR_STATE_READY; 00877 00878 /* Process unlocked */ 00879 __HAL_UNLOCK(hnor); 00880 00881 return HAL_OK; 00882 } 00883 00884 /** 00885 * @} 00886 */ 00887 00888 /** @defgroup NOR_Exported_Functions_Group3 Peripheral Control functions 00889 * @brief management functions 00890 * 00891 @verbatim 00892 ============================================================================== 00893 ##### NOR Control functions ##### 00894 ============================================================================== 00895 [..] 00896 This subsection provides a set of functions allowing to control dynamically 00897 the NOR interface. 00898 00899 @endverbatim 00900 * @{ 00901 */ 00902 00903 /** 00904 * @brief Enable dynamically NOR write operation. 00905 * @param hnor: pointer to a NOR_HandleTypeDef structure that contains 00906 * the configuration information for NOR module. 00907 * @retval HAL status 00908 */ 00909 HAL_StatusTypeDef HAL_NOR_WriteOperation_Enable(NOR_HandleTypeDef *hnor) 00910 { 00911 /* Process Locked */ 00912 __HAL_LOCK(hnor); 00913 00914 /* Enable write operation */ 00915 FMC_NORSRAM_WriteOperation_Enable(hnor->Instance, hnor->Init.NSBank); 00916 00917 /* Update the NOR controller state */ 00918 hnor->State = HAL_NOR_STATE_READY; 00919 00920 /* Process unlocked */ 00921 __HAL_UNLOCK(hnor); 00922 00923 return HAL_OK; 00924 } 00925 00926 /** 00927 * @brief Disable dynamically NOR write operation. 00928 * @param hnor: pointer to a NOR_HandleTypeDef structure that contains 00929 * the configuration information for NOR module. 00930 * @retval HAL status 00931 */ 00932 HAL_StatusTypeDef HAL_NOR_WriteOperation_Disable(NOR_HandleTypeDef *hnor) 00933 { 00934 /* Process Locked */ 00935 __HAL_LOCK(hnor); 00936 00937 /* Update the SRAM controller state */ 00938 hnor->State = HAL_NOR_STATE_BUSY; 00939 00940 /* Disable write operation */ 00941 FMC_NORSRAM_WriteOperation_Disable(hnor->Instance, hnor->Init.NSBank); 00942 00943 /* Update the NOR controller state */ 00944 hnor->State = HAL_NOR_STATE_PROTECTED; 00945 00946 /* Process unlocked */ 00947 __HAL_UNLOCK(hnor); 00948 00949 return HAL_OK; 00950 } 00951 00952 /** 00953 * @} 00954 */ 00955 00956 /** @defgroup NOR_Exported_Functions_Group4 Peripheral State functions 00957 * @brief Peripheral State functions 00958 * 00959 @verbatim 00960 ============================================================================== 00961 ##### NOR State functions ##### 00962 ============================================================================== 00963 [..] 00964 This subsection permits to get in run-time the status of the NOR controller 00965 and the data flow. 00966 00967 @endverbatim 00968 * @{ 00969 */ 00970 00971 /** 00972 * @brief Return the NOR controller handle state. 00973 * @param hnor: pointer to a NOR_HandleTypeDef structure that contains 00974 * the configuration information for NOR module. 00975 * @retval NOR controller state 00976 */ 00977 HAL_NOR_StateTypeDef HAL_NOR_GetState(NOR_HandleTypeDef *hnor) 00978 { 00979 /* Return NOR handle state */ 00980 return hnor->State; 00981 } 00982 00983 /** 00984 * @brief Return the NOR operation status. 00985 * @param hnor: pointer to a NOR_HandleTypeDef structure that contains 00986 * the configuration information for NOR module. 00987 * @param Address: Device address 00988 * @param Timeout: NOR programming Timeout 00989 * @retval NOR_Status: The returned value can be: HAL_NOR_STATUS_SUCCESS, HAL_NOR_STATUS_ERROR 00990 * or HAL_NOR_STATUS_TIMEOUT 00991 */ 00992 HAL_NOR_StatusTypeDef HAL_NOR_GetStatus(NOR_HandleTypeDef *hnor, uint32_t Address, uint32_t Timeout) 00993 { 00994 HAL_NOR_StatusTypeDef status = HAL_NOR_STATUS_ONGOING; 00995 uint16_t tmp_sr1 = 0, tmp_sr2 = 0; 00996 uint32_t tickstart = 0; 00997 00998 /* Poll on NOR memory Ready/Busy signal ------------------------------------*/ 00999 HAL_NOR_MspWait(hnor, Timeout); 01000 01001 /* Get tick */ 01002 tickstart = HAL_GetTick(); 01003 while((status != HAL_NOR_STATUS_SUCCESS) && (status != HAL_NOR_STATUS_TIMEOUT)) 01004 { 01005 /* Check for the Timeout */ 01006 if(Timeout != HAL_MAX_DELAY) 01007 { 01008 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) 01009 { 01010 status = HAL_NOR_STATUS_TIMEOUT; 01011 } 01012 } 01013 01014 /* Read NOR status register (DQ6 and DQ5) */ 01015 tmp_sr1 = *(__IO uint16_t *)Address; 01016 tmp_sr2 = *(__IO uint16_t *)Address; 01017 01018 /* If DQ6 did not toggle between the two reads then return NOR_Success */ 01019 if((tmp_sr1 & NOR_MASK_STATUS_DQ6) == (tmp_sr2 & NOR_MASK_STATUS_DQ6)) 01020 { 01021 return HAL_NOR_STATUS_SUCCESS; 01022 } 01023 01024 if((tmp_sr1 & NOR_MASK_STATUS_DQ5) != NOR_MASK_STATUS_DQ5) 01025 { 01026 status = HAL_NOR_STATUS_ONGOING; 01027 } 01028 01029 tmp_sr1 = *(__IO uint16_t *)Address; 01030 tmp_sr2 = *(__IO uint16_t *)Address; 01031 01032 /* If DQ6 did not toggle between the two reads then return NOR_Success */ 01033 if((tmp_sr1 & NOR_MASK_STATUS_DQ6) == (tmp_sr2 & NOR_MASK_STATUS_DQ6)) 01034 { 01035 return HAL_NOR_STATUS_SUCCESS; 01036 } 01037 else if((tmp_sr1 & NOR_MASK_STATUS_DQ5) == NOR_MASK_STATUS_DQ5) 01038 { 01039 return HAL_NOR_STATUS_ERROR; 01040 } 01041 } 01042 01043 /* Return the operation status */ 01044 return status; 01045 } 01046 01047 /** 01048 * @} 01049 */ 01050 01051 /** 01052 * @} 01053 */ 01054 /** 01055 * @} 01056 */ 01057 #endif /* HAL_NOR_MODULE_ENABLED */ 01058 01059 /** 01060 * @} 01061 */ 01062 01063 #endif /* STM32L471xx || STM32L475xx || STM32L476xx || STM32L485xx || STM32L486xx */ 01064 01065 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Tue Jul 12 2022 10:59:58 by
