| /** |
| ****************************************************************************** |
| * @file stm32g4xx_hal_nor.c |
| * @author MCD Application Team |
| * @brief NOR HAL module driver. |
| * This file provides a generic firmware to drive NOR memories mounted |
| * as external device. |
| * |
| @verbatim |
| ============================================================================== |
| ##### How to use this driver ##### |
| ============================================================================== |
| [..] |
| This driver is a generic layered driver which contains a set of APIs used to |
| control NOR flash memories. It uses the FMC layer functions to interface |
| with NOR devices. This driver is used as follows: |
| |
| (+) NOR flash memory configuration sequence using the function HAL_NOR_Init() |
| with control and timing parameters for both normal and extended mode. |
| |
| (+) Read NOR flash memory manufacturer code and device IDs using the function |
| HAL_NOR_Read_ID(). The read information is stored in the NOR_ID_TypeDef |
| structure declared by the function caller. |
| |
| (+) Access NOR flash memory by read/write data unit operations using the functions |
| HAL_NOR_Read(), HAL_NOR_Program(). |
| |
| (+) Perform NOR flash erase block/chip operations using the functions |
| HAL_NOR_Erase_Block() and HAL_NOR_Erase_Chip(). |
| |
| (+) Read the NOR flash CFI (common flash interface) IDs using the function |
| HAL_NOR_Read_CFI(). The read information is stored in the NOR_CFI_TypeDef |
| structure declared by the function caller. |
| |
| (+) You can also control the NOR device by calling the control APIs HAL_NOR_WriteOperation_Enable()/ |
| HAL_NOR_WriteOperation_Disable() to respectively enable/disable the NOR write operation |
| |
| (+) You can monitor the NOR device HAL state by calling the function |
| HAL_NOR_GetState() |
| [..] |
| (@) This driver is a set of generic APIs which handle standard NOR flash operations. |
| If a NOR flash device contains different operations and/or implementations, |
| it should be implemented separately. |
| |
| *** NOR HAL driver macros list *** |
| ============================================= |
| [..] |
| Below the list of most used macros in NOR HAL driver. |
| |
| (+) NOR_WRITE : NOR memory write data to specified address |
| |
| *** Callback registration *** |
| ============================================= |
| [..] |
| The compilation define USE_HAL_NOR_REGISTER_CALLBACKS when set to 1 |
| allows the user to configure dynamically the driver callbacks. |
| |
| Use Functions @ref HAL_NOR_RegisterCallback() to register a user callback, |
| it allows to register following callbacks: |
| (+) MspInitCallback : NOR MspInit. |
| (+) MspDeInitCallback : NOR MspDeInit. |
| This function takes as parameters the HAL peripheral handle, the Callback ID |
| and a pointer to the user callback function. |
| |
| Use function @ref HAL_NOR_UnRegisterCallback() to reset a callback to the default |
| weak (surcharged) function. It allows to reset following callbacks: |
| (+) MspInitCallback : NOR MspInit. |
| (+) MspDeInitCallback : NOR MspDeInit. |
| This function) takes as parameters the HAL peripheral handle and the Callback ID. |
| |
| By default, after the @ref HAL_NOR_Init and if the state is HAL_NOR_STATE_RESET |
| all callbacks are reset to the corresponding legacy weak (surcharged) functions. |
| Exception done for MspInit and MspDeInit callbacks that are respectively |
| reset to the legacy weak (surcharged) functions in the @ref HAL_NOR_Init |
| and @ref HAL_NOR_DeInit only when these callbacks are null (not registered beforehand). |
| If not, MspInit or MspDeInit are not null, the @ref HAL_NOR_Init and @ref HAL_NOR_DeInit |
| keep and use the user MspInit/MspDeInit callbacks (registered beforehand) |
| |
| Callbacks can be registered/unregistered in READY state only. |
| Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered |
| in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used |
| during the Init/DeInit. |
| In that case first register the MspInit/MspDeInit user callbacks |
| using @ref HAL_NOR_RegisterCallback before calling @ref HAL_NOR_DeInit |
| or @ref HAL_NOR_Init function. |
| |
| When The compilation define USE_HAL_NOR_REGISTER_CALLBACKS is set to 0 or |
| not defined, the callback registering feature is not available |
| and weak (surcharged) callbacks are used. |
| |
| @endverbatim |
| ****************************************************************************** |
| * @attention |
| * |
| * <h2><center>© Copyright (c) 2019 STMicroelectronics. |
| * All rights reserved.</center></h2> |
| * |
| * This software component is licensed by ST under BSD 3-Clause license, |
| * the "License"; You may not use this file except in compliance with the |
| * License. You may obtain a copy of the License at: |
| * opensource.org/licenses/BSD-3-Clause |
| * |
| ****************************************************************************** |
| */ |
| |
| /* Includes ------------------------------------------------------------------*/ |
| #include "stm32g4xx_hal.h" |
| |
| #if defined(FMC_BANK1) |
| |
| /** @addtogroup STM32G4xx_HAL_Driver |
| * @{ |
| */ |
| |
| #ifdef HAL_NOR_MODULE_ENABLED |
| |
| /** @defgroup NOR NOR |
| * @brief NOR driver modules |
| * @{ |
| */ |
| |
| /* Private typedef -----------------------------------------------------------*/ |
| /* Private define ------------------------------------------------------------*/ |
| |
| /** @defgroup NOR_Private_Defines NOR Private Defines |
| * @{ |
| */ |
| |
| /* Constants to define address to set to write a command */ |
| #define NOR_CMD_ADDRESS_FIRST (uint16_t)0x0555 |
| #define NOR_CMD_ADDRESS_FIRST_CFI (uint16_t)0x0055 |
| #define NOR_CMD_ADDRESS_SECOND (uint16_t)0x02AA |
| #define NOR_CMD_ADDRESS_THIRD (uint16_t)0x0555 |
| #define NOR_CMD_ADDRESS_FOURTH (uint16_t)0x0555 |
| #define NOR_CMD_ADDRESS_FIFTH (uint16_t)0x02AA |
| #define NOR_CMD_ADDRESS_SIXTH (uint16_t)0x0555 |
| |
| /* Constants to define data to program a command */ |
| #define NOR_CMD_DATA_READ_RESET (uint16_t)0x00F0 |
| #define NOR_CMD_DATA_FIRST (uint16_t)0x00AA |
| #define NOR_CMD_DATA_SECOND (uint16_t)0x0055 |
| #define NOR_CMD_DATA_AUTO_SELECT (uint16_t)0x0090 |
| #define NOR_CMD_DATA_PROGRAM (uint16_t)0x00A0 |
| #define NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD (uint16_t)0x0080 |
| #define NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH (uint16_t)0x00AA |
| #define NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH (uint16_t)0x0055 |
| #define NOR_CMD_DATA_CHIP_ERASE (uint16_t)0x0010 |
| #define NOR_CMD_DATA_CFI (uint16_t)0x0098 |
| |
| #define NOR_CMD_DATA_BUFFER_AND_PROG (uint8_t)0x25 |
| #define NOR_CMD_DATA_BUFFER_AND_PROG_CONFIRM (uint8_t)0x29 |
| #define NOR_CMD_DATA_BLOCK_ERASE (uint8_t)0x30 |
| |
| /* Mask on NOR STATUS REGISTER */ |
| #define NOR_MASK_STATUS_DQ5 (uint16_t)0x0020 |
| #define NOR_MASK_STATUS_DQ6 (uint16_t)0x0040 |
| |
| /** |
| * @} |
| */ |
| |
| /* Private macro -------------------------------------------------------------*/ |
| /* Private variables ---------------------------------------------------------*/ |
| /** @defgroup NOR_Private_Variables NOR Private Variables |
| * @{ |
| */ |
| |
| static uint32_t uwNORMemoryDataWidth = NOR_MEMORY_8B; |
| |
| /** |
| * @} |
| */ |
| |
| /* Private functions ---------------------------------------------------------*/ |
| /* Exported functions --------------------------------------------------------*/ |
| /** @defgroup NOR_Exported_Functions NOR Exported Functions |
| * @{ |
| */ |
| |
| /** @defgroup NOR_Exported_Functions_Group1 Initialization and de-initialization functions |
| * @brief Initialization and Configuration functions |
| * |
| @verbatim |
| ============================================================================== |
| ##### NOR Initialization and de_initialization functions ##### |
| ============================================================================== |
| [..] |
| This section provides functions allowing to initialize/de-initialize |
| the NOR memory |
| |
| @endverbatim |
| * @{ |
| */ |
| |
| /** |
| * @brief Perform the NOR memory Initialization sequence |
| * @param hnor pointer to a NOR_HandleTypeDef structure that contains |
| * the configuration information for NOR module. |
| * @param Timing pointer to NOR control timing structure |
| * @param ExtTiming pointer to NOR extended mode timing structure |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_NOR_Init(NOR_HandleTypeDef *hnor, FMC_NORSRAM_TimingTypeDef *Timing, FMC_NORSRAM_TimingTypeDef *ExtTiming) |
| { |
| /* Check the NOR handle parameter */ |
| if (hnor == NULL) |
| { |
| return HAL_ERROR; |
| } |
| |
| if (hnor->State == HAL_NOR_STATE_RESET) |
| { |
| /* Allocate lock resource and initialize it */ |
| hnor->Lock = HAL_UNLOCKED; |
| |
| #if (USE_HAL_NOR_REGISTER_CALLBACKS == 1) |
| if(hnor->MspInitCallback == NULL) |
| { |
| hnor->MspInitCallback = HAL_NOR_MspInit; |
| } |
| |
| /* Init the low level hardware */ |
| hnor->MspInitCallback(hnor); |
| #else |
| /* Initialize the low level hardware (MSP) */ |
| HAL_NOR_MspInit(hnor); |
| #endif /* (USE_HAL_NOR_REGISTER_CALLBACKS) */ |
| } |
| |
| /* Initialize NOR control Interface */ |
| (void)FMC_NORSRAM_Init(hnor->Instance, &(hnor->Init)); |
| |
| /* Initialize NOR timing Interface */ |
| (void)FMC_NORSRAM_Timing_Init(hnor->Instance, Timing, hnor->Init.NSBank); |
| |
| /* Initialize NOR extended mode timing Interface */ |
| (void)FMC_NORSRAM_Extended_Timing_Init(hnor->Extended, ExtTiming, hnor->Init.NSBank, hnor->Init.ExtendedMode); |
| |
| /* Enable the NORSRAM device */ |
| __FMC_NORSRAM_ENABLE(hnor->Instance, hnor->Init.NSBank); |
| |
| /* Initialize NOR Memory Data Width*/ |
| if (hnor->Init.MemoryDataWidth == FMC_NORSRAM_MEM_BUS_WIDTH_8) |
| { |
| uwNORMemoryDataWidth = NOR_MEMORY_8B; |
| } |
| else |
| { |
| uwNORMemoryDataWidth = NOR_MEMORY_16B; |
| } |
| |
| /* Initialize the NOR controller state */ |
| hnor->State = HAL_NOR_STATE_READY; |
| |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Perform NOR memory De-Initialization sequence |
| * @param hnor pointer to a NOR_HandleTypeDef structure that contains |
| * the configuration information for NOR module. |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_NOR_DeInit(NOR_HandleTypeDef *hnor) |
| { |
| #if (USE_HAL_NOR_REGISTER_CALLBACKS == 1) |
| if(hnor->MspDeInitCallback == NULL) |
| { |
| hnor->MspDeInitCallback = HAL_NOR_MspDeInit; |
| } |
| |
| /* DeInit the low level hardware */ |
| hnor->MspDeInitCallback(hnor); |
| #else |
| /* De-Initialize the low level hardware (MSP) */ |
| HAL_NOR_MspDeInit(hnor); |
| #endif /* (USE_HAL_NOR_REGISTER_CALLBACKS) */ |
| |
| /* Configure the NOR registers with their reset values */ |
| (void)FMC_NORSRAM_DeInit(hnor->Instance, hnor->Extended, hnor->Init.NSBank); |
| |
| /* Reset the NOR controller state */ |
| hnor->State = HAL_NOR_STATE_RESET; |
| |
| /* Release Lock */ |
| __HAL_UNLOCK(hnor); |
| |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief NOR MSP Init |
| * @param hnor pointer to a NOR_HandleTypeDef structure that contains |
| * the configuration information for NOR module. |
| * @retval None |
| */ |
| __weak void HAL_NOR_MspInit(NOR_HandleTypeDef *hnor) |
| { |
| /* Prevent unused argument(s) compilation warning */ |
| UNUSED(hnor); |
| |
| /* NOTE : This function Should not be modified, when the callback is needed, |
| the HAL_NOR_MspInit could be implemented in the user file |
| */ |
| } |
| |
| /** |
| * @brief NOR MSP DeInit |
| * @param hnor pointer to a NOR_HandleTypeDef structure that contains |
| * the configuration information for NOR module. |
| * @retval None |
| */ |
| __weak void HAL_NOR_MspDeInit(NOR_HandleTypeDef *hnor) |
| { |
| /* Prevent unused argument(s) compilation warning */ |
| UNUSED(hnor); |
| |
| /* NOTE : This function Should not be modified, when the callback is needed, |
| the HAL_NOR_MspDeInit could be implemented in the user file |
| */ |
| } |
| |
| /** |
| * @brief NOR MSP Wait for Ready/Busy signal |
| * @param hnor pointer to a NOR_HandleTypeDef structure that contains |
| * the configuration information for NOR module. |
| * @param Timeout Maximum timeout value |
| * @retval None |
| */ |
| __weak void HAL_NOR_MspWait(NOR_HandleTypeDef *hnor, uint32_t Timeout) |
| { |
| /* Prevent unused argument(s) compilation warning */ |
| UNUSED(hnor); |
| UNUSED(Timeout); |
| |
| /* NOTE : This function Should not be modified, when the callback is needed, |
| the HAL_NOR_MspWait could be implemented in the user file |
| */ |
| } |
| |
| /** |
| * @} |
| */ |
| |
| /** @defgroup NOR_Exported_Functions_Group2 Input and Output functions |
| * @brief Input Output and memory control functions |
| * |
| @verbatim |
| ============================================================================== |
| ##### NOR Input and Output functions ##### |
| ============================================================================== |
| [..] |
| This section provides functions allowing to use and control the NOR memory |
| |
| @endverbatim |
| * @{ |
| */ |
| |
| /** |
| * @brief Read NOR flash IDs |
| * @param hnor pointer to a NOR_HandleTypeDef structure that contains |
| * the configuration information for NOR module. |
| * @param pNOR_ID pointer to NOR ID structure |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_NOR_Read_ID(NOR_HandleTypeDef *hnor, NOR_IDTypeDef *pNOR_ID) |
| { |
| uint32_t deviceaddress; |
| HAL_NOR_StateTypeDef state; |
| |
| /* Check the NOR controller state */ |
| state = hnor->State; |
| if (state == HAL_NOR_STATE_BUSY) |
| { |
| return HAL_BUSY; |
| } |
| else if ((state == HAL_NOR_STATE_READY) || (state == HAL_NOR_STATE_PROTECTED)) |
| { |
| /* Process Locked */ |
| __HAL_LOCK(hnor); |
| |
| /* Update the NOR controller state */ |
| hnor->State = HAL_NOR_STATE_BUSY; |
| |
| /* Select the NOR device address */ |
| if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) |
| { |
| deviceaddress = NOR_MEMORY_ADRESS1; |
| } |
| else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) |
| { |
| deviceaddress = NOR_MEMORY_ADRESS2; |
| } |
| else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) |
| { |
| deviceaddress = NOR_MEMORY_ADRESS3; |
| } |
| else /* FMC_NORSRAM_BANK4 */ |
| { |
| deviceaddress = NOR_MEMORY_ADRESS4; |
| } |
| |
| /* Send read ID command */ |
| NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST); |
| NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND); |
| NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_AUTO_SELECT); |
| |
| /* Read the NOR IDs */ |
| pNOR_ID->Manufacturer_Code = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, MC_ADDRESS); |
| pNOR_ID->Device_Code1 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, DEVICE_CODE1_ADDR); |
| pNOR_ID->Device_Code2 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, DEVICE_CODE2_ADDR); |
| pNOR_ID->Device_Code3 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, DEVICE_CODE3_ADDR); |
| |
| /* Check the NOR controller state */ |
| hnor->State = state; |
| |
| /* Process unlocked */ |
| __HAL_UNLOCK(hnor); |
| } |
| else |
| { |
| return HAL_ERROR; |
| } |
| |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Returns the NOR memory to Read mode. |
| * @param hnor pointer to a NOR_HandleTypeDef structure that contains |
| * the configuration information for NOR module. |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_NOR_ReturnToReadMode(NOR_HandleTypeDef *hnor) |
| { |
| uint32_t deviceaddress; |
| HAL_NOR_StateTypeDef state; |
| |
| /* Check the NOR controller state */ |
| state = hnor->State; |
| if (state == HAL_NOR_STATE_BUSY) |
| { |
| return HAL_BUSY; |
| } |
| else if ((state == HAL_NOR_STATE_READY) || (state == HAL_NOR_STATE_PROTECTED)) |
| { |
| /* Process Locked */ |
| __HAL_LOCK(hnor); |
| |
| /* Update the NOR controller state */ |
| hnor->State = HAL_NOR_STATE_BUSY; |
| |
| /* Select the NOR device address */ |
| if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) |
| { |
| deviceaddress = NOR_MEMORY_ADRESS1; |
| } |
| else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) |
| { |
| deviceaddress = NOR_MEMORY_ADRESS2; |
| } |
| else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) |
| { |
| deviceaddress = NOR_MEMORY_ADRESS3; |
| } |
| else /* FMC_NORSRAM_BANK4 */ |
| { |
| deviceaddress = NOR_MEMORY_ADRESS4; |
| } |
| |
| NOR_WRITE(deviceaddress, NOR_CMD_DATA_READ_RESET); |
| |
| /* Check the NOR controller state */ |
| hnor->State = state; |
| |
| /* Process unlocked */ |
| __HAL_UNLOCK(hnor); |
| } |
| else |
| { |
| return HAL_ERROR; |
| } |
| |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Read data from NOR memory |
| * @param hnor pointer to a NOR_HandleTypeDef structure that contains |
| * the configuration information for NOR module. |
| * @param pAddress pointer to Device address |
| * @param pData pointer to read data |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_NOR_Read(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData) |
| { |
| uint32_t deviceaddress; |
| HAL_NOR_StateTypeDef state; |
| |
| /* Check the NOR controller state */ |
| state = hnor->State; |
| if (state == HAL_NOR_STATE_BUSY) |
| { |
| return HAL_BUSY; |
| } |
| else if ((state == HAL_NOR_STATE_READY) || (state == HAL_NOR_STATE_PROTECTED)) |
| { |
| /* Process Locked */ |
| __HAL_LOCK(hnor); |
| |
| /* Update the NOR controller state */ |
| hnor->State = HAL_NOR_STATE_BUSY; |
| |
| /* Select the NOR device address */ |
| if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) |
| { |
| deviceaddress = NOR_MEMORY_ADRESS1; |
| } |
| else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) |
| { |
| deviceaddress = NOR_MEMORY_ADRESS2; |
| } |
| else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) |
| { |
| deviceaddress = NOR_MEMORY_ADRESS3; |
| } |
| else /* FMC_NORSRAM_BANK4 */ |
| { |
| deviceaddress = NOR_MEMORY_ADRESS4; |
| } |
| |
| /* Send read data command */ |
| NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST); |
| NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND); |
| NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_READ_RESET); |
| |
| /* Read the data */ |
| *pData = (uint16_t)(*(__IO uint32_t *)pAddress); |
| |
| /* Check the NOR controller state */ |
| hnor->State = state; |
| |
| /* Process unlocked */ |
| __HAL_UNLOCK(hnor); |
| } |
| else |
| { |
| return HAL_ERROR; |
| } |
| |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Program data to NOR memory |
| * @param hnor pointer to a NOR_HandleTypeDef structure that contains |
| * the configuration information for NOR module. |
| * @param pAddress Device address |
| * @param pData pointer to the data to write |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_NOR_Program(NOR_HandleTypeDef *hnor, uint32_t *pAddress, uint16_t *pData) |
| { |
| uint32_t deviceaddress; |
| |
| /* Check the NOR controller state */ |
| if (hnor->State == HAL_NOR_STATE_BUSY) |
| { |
| return HAL_BUSY; |
| } |
| else if (hnor->State == HAL_NOR_STATE_READY) |
| { |
| /* Process Locked */ |
| __HAL_LOCK(hnor); |
| |
| /* Update the NOR controller state */ |
| hnor->State = HAL_NOR_STATE_BUSY; |
| |
| /* Select the NOR device address */ |
| if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) |
| { |
| deviceaddress = NOR_MEMORY_ADRESS1; |
| } |
| else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) |
| { |
| deviceaddress = NOR_MEMORY_ADRESS2; |
| } |
| else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) |
| { |
| deviceaddress = NOR_MEMORY_ADRESS3; |
| } |
| else /* FMC_NORSRAM_BANK4 */ |
| { |
| deviceaddress = NOR_MEMORY_ADRESS4; |
| } |
| |
| /* Send program data command */ |
| NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST); |
| NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND); |
| NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_PROGRAM); |
| |
| /* Write the data */ |
| NOR_WRITE(pAddress, *pData); |
| |
| /* Check the NOR controller state */ |
| hnor->State = HAL_NOR_STATE_READY; |
| |
| /* Process unlocked */ |
| __HAL_UNLOCK(hnor); |
| } |
| else |
| { |
| return HAL_ERROR; |
| } |
| |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Reads a half-word buffer from the NOR memory. |
| * @param hnor pointer to the NOR handle |
| * @param uwAddress NOR memory internal address to read from. |
| * @param pData pointer to the buffer that receives the data read from the |
| * NOR memory. |
| * @param uwBufferSize number of Half word to read. |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_NOR_ReadBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData, uint32_t uwBufferSize) |
| { |
| uint32_t deviceaddress, size = uwBufferSize, address = uwAddress; |
| uint16_t *data = pData; |
| HAL_NOR_StateTypeDef state; |
| |
| /* Check the NOR controller state */ |
| state = hnor->State; |
| if (state == HAL_NOR_STATE_BUSY) |
| { |
| return HAL_BUSY; |
| } |
| else if ((state == HAL_NOR_STATE_READY) || (state == HAL_NOR_STATE_PROTECTED)) |
| { |
| /* Process Locked */ |
| __HAL_LOCK(hnor); |
| |
| /* Update the NOR controller state */ |
| hnor->State = HAL_NOR_STATE_BUSY; |
| |
| /* Select the NOR device address */ |
| if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) |
| { |
| deviceaddress = NOR_MEMORY_ADRESS1; |
| } |
| else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) |
| { |
| deviceaddress = NOR_MEMORY_ADRESS2; |
| } |
| else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) |
| { |
| deviceaddress = NOR_MEMORY_ADRESS3; |
| } |
| else /* FMC_NORSRAM_BANK4 */ |
| { |
| deviceaddress = NOR_MEMORY_ADRESS4; |
| } |
| |
| /* Send read data command */ |
| NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST); |
| NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND); |
| NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_READ_RESET); |
| |
| /* Read buffer */ |
| while (size > 0U) |
| { |
| *data = *(__IO uint16_t *)address; |
| data++; |
| address += 2U; |
| size--; |
| } |
| |
| /* Check the NOR controller state */ |
| hnor->State = state; |
| |
| /* Process unlocked */ |
| __HAL_UNLOCK(hnor); |
| } |
| else |
| { |
| return HAL_ERROR; |
| } |
| |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Writes a half-word buffer to the NOR memory. This function must be used |
| only with S29GL128P NOR memory. |
| * @param hnor pointer to the NOR handle |
| * @param uwAddress NOR memory internal start write address |
| * @param pData pointer to source data buffer. |
| * @param uwBufferSize Size of the buffer to write |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_NOR_ProgramBuffer(NOR_HandleTypeDef *hnor, uint32_t uwAddress, uint16_t *pData, uint32_t uwBufferSize) |
| { |
| uint16_t *p_currentaddress; |
| const uint16_t *p_endaddress; |
| uint16_t *data = pData; |
| uint32_t lastloadedaddress, deviceaddress; |
| |
| /* Check the NOR controller state */ |
| if (hnor->State == HAL_NOR_STATE_BUSY) |
| { |
| return HAL_BUSY; |
| } |
| else if (hnor->State == HAL_NOR_STATE_READY) |
| { |
| /* Process Locked */ |
| __HAL_LOCK(hnor); |
| |
| /* Update the NOR controller state */ |
| hnor->State = HAL_NOR_STATE_BUSY; |
| |
| /* Select the NOR device address */ |
| if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) |
| { |
| deviceaddress = NOR_MEMORY_ADRESS1; |
| } |
| else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) |
| { |
| deviceaddress = NOR_MEMORY_ADRESS2; |
| } |
| else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) |
| { |
| deviceaddress = NOR_MEMORY_ADRESS3; |
| } |
| else /* FMC_NORSRAM_BANK4 */ |
| { |
| deviceaddress = NOR_MEMORY_ADRESS4; |
| } |
| |
| /* Initialize variables */ |
| p_currentaddress = (uint16_t *)(uwAddress); |
| p_endaddress = (const uint16_t *)(uwAddress + (uwBufferSize - 1U)); |
| lastloadedaddress = uwAddress; |
| |
| /* Issue unlock command sequence */ |
| NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST); |
| NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND); |
| |
| /* Write Buffer Load Command */ |
| NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, uwAddress), NOR_CMD_DATA_BUFFER_AND_PROG); |
| NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, uwAddress), (uint16_t)(uwBufferSize - 1U)); |
| |
| /* Load Data into NOR Buffer */ |
| while (p_currentaddress <= p_endaddress) |
| { |
| /* Store last loaded address & data value (for polling) */ |
| lastloadedaddress = (uint32_t)p_currentaddress; |
| |
| NOR_WRITE(p_currentaddress, *data); |
| |
| data++; |
| p_currentaddress ++; |
| } |
| |
| NOR_WRITE((uint32_t)(lastloadedaddress), NOR_CMD_DATA_BUFFER_AND_PROG_CONFIRM); |
| |
| /* Check the NOR controller state */ |
| hnor->State = HAL_NOR_STATE_READY; |
| |
| /* Process unlocked */ |
| __HAL_UNLOCK(hnor); |
| } |
| else |
| { |
| return HAL_ERROR; |
| } |
| |
| return HAL_OK; |
| |
| } |
| |
| /** |
| * @brief Erase the specified block of the NOR memory |
| * @param hnor pointer to a NOR_HandleTypeDef structure that contains |
| * the configuration information for NOR module. |
| * @param BlockAddress Block to erase address |
| * @param Address Device address |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_NOR_Erase_Block(NOR_HandleTypeDef *hnor, uint32_t BlockAddress, uint32_t Address) |
| { |
| uint32_t deviceaddress; |
| |
| /* Check the NOR controller state */ |
| if (hnor->State == HAL_NOR_STATE_BUSY) |
| { |
| return HAL_BUSY; |
| } |
| else if (hnor->State == HAL_NOR_STATE_READY) |
| { |
| /* Process Locked */ |
| __HAL_LOCK(hnor); |
| |
| /* Update the NOR controller state */ |
| hnor->State = HAL_NOR_STATE_BUSY; |
| |
| /* Select the NOR device address */ |
| if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) |
| { |
| deviceaddress = NOR_MEMORY_ADRESS1; |
| } |
| else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) |
| { |
| deviceaddress = NOR_MEMORY_ADRESS2; |
| } |
| else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) |
| { |
| deviceaddress = NOR_MEMORY_ADRESS3; |
| } |
| else /* FMC_NORSRAM_BANK4 */ |
| { |
| deviceaddress = NOR_MEMORY_ADRESS4; |
| } |
| |
| /* Send block erase command sequence */ |
| NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST); |
| NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND); |
| NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD); |
| NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FOURTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH); |
| NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIFTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH); |
| NOR_WRITE((uint32_t)(BlockAddress + Address), NOR_CMD_DATA_BLOCK_ERASE); |
| |
| /* Check the NOR memory status and update the controller state */ |
| hnor->State = HAL_NOR_STATE_READY; |
| |
| /* Process unlocked */ |
| __HAL_UNLOCK(hnor); |
| } |
| else |
| { |
| return HAL_ERROR; |
| } |
| |
| return HAL_OK; |
| |
| } |
| |
| /** |
| * @brief Erase the entire NOR chip. |
| * @param hnor pointer to a NOR_HandleTypeDef structure that contains |
| * the configuration information for NOR module. |
| * @param Address Device address |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_NOR_Erase_Chip(NOR_HandleTypeDef *hnor, uint32_t Address) |
| { |
| uint32_t deviceaddress; |
| UNUSED(Address); |
| |
| /* Check the NOR controller state */ |
| if (hnor->State == HAL_NOR_STATE_BUSY) |
| { |
| return HAL_BUSY; |
| } |
| else if (hnor->State == HAL_NOR_STATE_READY) |
| { |
| /* Process Locked */ |
| __HAL_LOCK(hnor); |
| |
| /* Update the NOR controller state */ |
| hnor->State = HAL_NOR_STATE_BUSY; |
| |
| /* Select the NOR device address */ |
| if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) |
| { |
| deviceaddress = NOR_MEMORY_ADRESS1; |
| } |
| else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) |
| { |
| deviceaddress = NOR_MEMORY_ADRESS2; |
| } |
| else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) |
| { |
| deviceaddress = NOR_MEMORY_ADRESS3; |
| } |
| else /* FMC_NORSRAM_BANK4 */ |
| { |
| deviceaddress = NOR_MEMORY_ADRESS4; |
| } |
| |
| /* Send NOR chip erase command sequence */ |
| NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST); |
| NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND); |
| NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD), NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD); |
| NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FOURTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH); |
| NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIFTH), NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH); |
| NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SIXTH), NOR_CMD_DATA_CHIP_ERASE); |
| |
| /* Check the NOR memory status and update the controller state */ |
| hnor->State = HAL_NOR_STATE_READY; |
| |
| /* Process unlocked */ |
| __HAL_UNLOCK(hnor); |
| } |
| else |
| { |
| return HAL_ERROR; |
| } |
| |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Read NOR flash CFI IDs |
| * @param hnor pointer to a NOR_HandleTypeDef structure that contains |
| * the configuration information for NOR module. |
| * @param pNOR_CFI pointer to NOR CFI IDs structure |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_NOR_Read_CFI(NOR_HandleTypeDef *hnor, NOR_CFITypeDef *pNOR_CFI) |
| { |
| uint32_t deviceaddress; |
| HAL_NOR_StateTypeDef state; |
| |
| /* Check the NOR controller state */ |
| state = hnor->State; |
| if (state == HAL_NOR_STATE_BUSY) |
| { |
| return HAL_BUSY; |
| } |
| else if ((state == HAL_NOR_STATE_READY) || (state == HAL_NOR_STATE_PROTECTED)) |
| { |
| /* Process Locked */ |
| __HAL_LOCK(hnor); |
| |
| /* Update the NOR controller state */ |
| hnor->State = HAL_NOR_STATE_BUSY; |
| |
| /* Select the NOR device address */ |
| if (hnor->Init.NSBank == FMC_NORSRAM_BANK1) |
| { |
| deviceaddress = NOR_MEMORY_ADRESS1; |
| } |
| else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2) |
| { |
| deviceaddress = NOR_MEMORY_ADRESS2; |
| } |
| else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3) |
| { |
| deviceaddress = NOR_MEMORY_ADRESS3; |
| } |
| else /* FMC_NORSRAM_BANK4 */ |
| { |
| deviceaddress = NOR_MEMORY_ADRESS4; |
| } |
| |
| /* Send read CFI query command */ |
| NOR_WRITE(NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST_CFI), NOR_CMD_DATA_CFI); |
| |
| /* read the NOR CFI information */ |
| pNOR_CFI->CFI_1 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI1_ADDRESS); |
| pNOR_CFI->CFI_2 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI2_ADDRESS); |
| pNOR_CFI->CFI_3 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI3_ADDRESS); |
| pNOR_CFI->CFI_4 = *(__IO uint16_t *) NOR_ADDR_SHIFT(deviceaddress, uwNORMemoryDataWidth, CFI4_ADDRESS); |
| |
| /* Check the NOR controller state */ |
| hnor->State = state; |
| |
| /* Process unlocked */ |
| __HAL_UNLOCK(hnor); |
| } |
| else |
| { |
| return HAL_ERROR; |
| } |
| |
| return HAL_OK; |
| } |
| |
| #if (USE_HAL_NOR_REGISTER_CALLBACKS == 1) |
| /** |
| * @brief Register a User NOR Callback |
| * To be used instead of the weak (surcharged) predefined callback |
| * @param hnor : NOR handle |
| * @param CallbackId : ID of the callback to be registered |
| * This parameter can be one of the following values: |
| * @arg @ref HAL_NOR_MSP_INIT_CB_ID NOR MspInit callback ID |
| * @arg @ref HAL_NOR_MSP_DEINIT_CB_ID NOR MspDeInit callback ID |
| * @param pCallback : pointer to the Callback function |
| * @retval status |
| */ |
| HAL_StatusTypeDef HAL_NOR_RegisterCallback (NOR_HandleTypeDef *hnor, HAL_NOR_CallbackIDTypeDef CallbackId, pNOR_CallbackTypeDef pCallback) |
| { |
| HAL_StatusTypeDef status = HAL_OK; |
| HAL_NOR_StateTypeDef state; |
| |
| if(pCallback == NULL) |
| { |
| return HAL_ERROR; |
| } |
| |
| /* Process locked */ |
| __HAL_LOCK(hnor); |
| |
| state = hnor->State; |
| if((state == HAL_NOR_STATE_READY) || (state == HAL_NOR_STATE_RESET) || (state == HAL_NOR_STATE_PROTECTED)) |
| { |
| switch (CallbackId) |
| { |
| case HAL_NOR_MSP_INIT_CB_ID : |
| hnor->MspInitCallback = pCallback; |
| break; |
| case HAL_NOR_MSP_DEINIT_CB_ID : |
| hnor->MspDeInitCallback = pCallback; |
| break; |
| default : |
| /* update return status */ |
| status = HAL_ERROR; |
| break; |
| } |
| } |
| else |
| { |
| /* update return status */ |
| status = HAL_ERROR; |
| } |
| |
| /* Release Lock */ |
| __HAL_UNLOCK(hnor); |
| return status; |
| } |
| |
| /** |
| * @brief Unregister a User NOR Callback |
| * NOR Callback is redirected to the weak (surcharged) predefined callback |
| * @param hnor : NOR handle |
| * @param CallbackId : ID of the callback to be unregistered |
| * This parameter can be one of the following values: |
| * @arg @ref HAL_NOR_MSP_INIT_CB_ID NOR MspInit callback ID |
| * @arg @ref HAL_NOR_MSP_DEINIT_CB_ID NOR MspDeInit callback ID |
| * @retval status |
| */ |
| HAL_StatusTypeDef HAL_NOR_UnRegisterCallback (NOR_HandleTypeDef *hnor, HAL_NOR_CallbackIDTypeDef CallbackId) |
| { |
| HAL_StatusTypeDef status = HAL_OK; |
| HAL_NOR_StateTypeDef state; |
| |
| /* Process locked */ |
| __HAL_LOCK(hnor); |
| |
| state = hnor->State; |
| if((state == HAL_NOR_STATE_READY) || (state == HAL_NOR_STATE_RESET) || (state == HAL_NOR_STATE_PROTECTED)) |
| { |
| switch (CallbackId) |
| { |
| case HAL_NOR_MSP_INIT_CB_ID : |
| hnor->MspInitCallback = HAL_NOR_MspInit; |
| break; |
| case HAL_NOR_MSP_DEINIT_CB_ID : |
| hnor->MspDeInitCallback = HAL_NOR_MspDeInit; |
| break; |
| default : |
| /* update return status */ |
| status = HAL_ERROR; |
| break; |
| } |
| } |
| else |
| { |
| /* update return status */ |
| status = HAL_ERROR; |
| } |
| |
| /* Release Lock */ |
| __HAL_UNLOCK(hnor); |
| return status; |
| } |
| #endif /* (USE_HAL_NOR_REGISTER_CALLBACKS) */ |
| |
| /** |
| * @} |
| */ |
| |
| /** @defgroup NOR_Exported_Functions_Group3 NOR Control functions |
| * @brief management functions |
| * |
| @verbatim |
| ============================================================================== |
| ##### NOR Control functions ##### |
| ============================================================================== |
| [..] |
| This subsection provides a set of functions allowing to control dynamically |
| the NOR interface. |
| |
| @endverbatim |
| * @{ |
| */ |
| |
| /** |
| * @brief Enables dynamically NOR write operation. |
| * @param hnor pointer to a NOR_HandleTypeDef structure that contains |
| * the configuration information for NOR module. |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_NOR_WriteOperation_Enable(NOR_HandleTypeDef *hnor) |
| { |
| /* Check the NOR controller state */ |
| if(hnor->State == HAL_NOR_STATE_PROTECTED) |
| { |
| /* Process Locked */ |
| __HAL_LOCK(hnor); |
| |
| /* Update the NOR controller state */ |
| hnor->State = HAL_NOR_STATE_BUSY; |
| |
| /* Enable write operation */ |
| (void)FMC_NORSRAM_WriteOperation_Enable(hnor->Instance, hnor->Init.NSBank); |
| |
| /* Update the NOR controller state */ |
| hnor->State = HAL_NOR_STATE_READY; |
| |
| /* Process unlocked */ |
| __HAL_UNLOCK(hnor); |
| } |
| else |
| { |
| return HAL_ERROR; |
| } |
| |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Disables dynamically NOR write operation. |
| * @param hnor pointer to a NOR_HandleTypeDef structure that contains |
| * the configuration information for NOR module. |
| * @retval HAL status |
| */ |
| HAL_StatusTypeDef HAL_NOR_WriteOperation_Disable(NOR_HandleTypeDef *hnor) |
| { |
| /* Check the NOR controller state */ |
| if(hnor->State == HAL_NOR_STATE_READY) |
| { |
| /* Process Locked */ |
| __HAL_LOCK(hnor); |
| |
| /* Update the NOR controller state */ |
| hnor->State = HAL_NOR_STATE_BUSY; |
| |
| /* Disable write operation */ |
| (void)FMC_NORSRAM_WriteOperation_Disable(hnor->Instance, hnor->Init.NSBank); |
| |
| /* Update the NOR controller state */ |
| hnor->State = HAL_NOR_STATE_PROTECTED; |
| |
| /* Process unlocked */ |
| __HAL_UNLOCK(hnor); |
| } |
| else |
| { |
| return HAL_ERROR; |
| } |
| |
| return HAL_OK; |
| } |
| |
| /** |
| * @} |
| */ |
| |
| /** @defgroup NOR_Exported_Functions_Group4 NOR State functions |
| * @brief Peripheral State functions |
| * |
| @verbatim |
| ============================================================================== |
| ##### NOR State functions ##### |
| ============================================================================== |
| [..] |
| This subsection permits to get in run-time the status of the NOR controller |
| and the data flow. |
| |
| @endverbatim |
| * @{ |
| */ |
| |
| /** |
| * @brief return the NOR controller state |
| * @param hnor pointer to a NOR_HandleTypeDef structure that contains |
| * the configuration information for NOR module. |
| * @retval NOR controller state |
| */ |
| HAL_NOR_StateTypeDef HAL_NOR_GetState(NOR_HandleTypeDef *hnor) |
| { |
| return hnor->State; |
| } |
| |
| /** |
| * @brief Returns the NOR operation status. |
| * @param hnor pointer to a NOR_HandleTypeDef structure that contains |
| * the configuration information for NOR module. |
| * @param Address Device address |
| * @param Timeout NOR programming Timeout |
| * @retval NOR_Status The returned value can be: HAL_NOR_STATUS_SUCCESS, HAL_NOR_STATUS_ERROR |
| * or HAL_NOR_STATUS_TIMEOUT |
| */ |
| HAL_NOR_StatusTypeDef HAL_NOR_GetStatus(NOR_HandleTypeDef *hnor, uint32_t Address, uint32_t Timeout) |
| { |
| HAL_NOR_StatusTypeDef status = HAL_NOR_STATUS_ONGOING; |
| uint16_t tmpSR1, tmpSR2; |
| uint32_t tickstart; |
| |
| /* Poll on NOR memory Ready/Busy signal ------------------------------------*/ |
| HAL_NOR_MspWait(hnor, Timeout); |
| |
| /* Get the NOR memory operation status -------------------------------------*/ |
| |
| /* Get tick */ |
| tickstart = HAL_GetTick(); |
| while ((status != HAL_NOR_STATUS_SUCCESS) && (status != HAL_NOR_STATUS_TIMEOUT)) |
| { |
| /* Check for the Timeout */ |
| if (Timeout != HAL_MAX_DELAY) |
| { |
| if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) |
| { |
| status = HAL_NOR_STATUS_TIMEOUT; |
| } |
| } |
| |
| /* Read NOR status register (DQ6 and DQ5) */ |
| tmpSR1 = *(__IO uint16_t *)Address; |
| tmpSR2 = *(__IO uint16_t *)Address; |
| |
| /* If DQ6 did not toggle between the two reads then return HAL_NOR_STATUS_SUCCESS */ |
| if ((tmpSR1 & NOR_MASK_STATUS_DQ6) == (tmpSR2 & NOR_MASK_STATUS_DQ6)) |
| { |
| return HAL_NOR_STATUS_SUCCESS ; |
| } |
| |
| if ((tmpSR1 & NOR_MASK_STATUS_DQ5) == NOR_MASK_STATUS_DQ5) |
| { |
| status = HAL_NOR_STATUS_ONGOING; |
| } |
| |
| tmpSR1 = *(__IO uint16_t *)Address; |
| tmpSR2 = *(__IO uint16_t *)Address; |
| |
| /* If DQ6 did not toggle between the two reads then return HAL_NOR_STATUS_SUCCESS */ |
| if ((tmpSR1 & NOR_MASK_STATUS_DQ6) == (tmpSR2 & NOR_MASK_STATUS_DQ6)) |
| { |
| return HAL_NOR_STATUS_SUCCESS; |
| } |
| if ((tmpSR1 & NOR_MASK_STATUS_DQ5) == NOR_MASK_STATUS_DQ5) |
| { |
| return HAL_NOR_STATUS_ERROR; |
| } |
| } |
| |
| /* Return the operation status */ |
| return status; |
| } |
| |
| /** |
| * @} |
| */ |
| |
| /** |
| * @} |
| */ |
| |
| /** |
| * @} |
| */ |
| |
| #endif /* HAL_NOR_MODULE_ENABLED */ |
| |
| /** |
| * @} |
| */ |
| |
| #endif /* FMC_BANK1 */ |
| |
| /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |