Farnell-Element14 Bologna IOT Team / BSP_B-L475E-IOT01

Dependencies:   VL53L0X

Fork of BSP_B-L475E-IOT01 by ST

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32l475e_iot01_qspi.c Source File

stm32l475e_iot01_qspi.c

Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32l475e_iot01_qspi.c
00004   * @author  MCD Application Team
00005   * @brief   This file includes a standard driver for the MX25R6435F QSPI 
00006   *          memory mounted on STM32L475E IOT01 board.
00007   @verbatim
00008   ==============================================================================
00009                      ##### How to use this driver #####
00010   ==============================================================================  
00011   [..] 
00012    (#) This driver is used to drive the MX25R6435F QSPI external 
00013        memory mounted on STM32L475E IOT01 board.
00014        
00015    (#) This driver need a specific component driver (MX25R6435F) to be included with.
00016 
00017    (#) Initialization steps:
00018        (++) Initialize the QPSI external memory using the BSP_QSPI_Init() function. This 
00019             function includes the MSP layer hardware resources initialization and the
00020             QSPI interface with the external memory. The BSP_QSPI_DeInit() can be used 
00021             to deactivate the QSPI interface.
00022   
00023    (#) QSPI memory operations
00024        (++) QSPI memory can be accessed with read/write operations once it is
00025             initialized.
00026             Read/write operation can be performed with AHB access using the functions
00027             BSP_QSPI_Read()/BSP_QSPI_Write().
00028        (++) The function to the QSPI memory in memory-mapped mode is possible after 
00029             the call of the function BSP_QSPI_EnableMemoryMappedMode().
00030        (++) The function BSP_QSPI_GetInfo() returns the configuration of the QSPI memory. 
00031             (see the QSPI memory data sheet)
00032        (++) Perform erase block operation using the function BSP_QSPI_Erase_Block() and by
00033             specifying the block address. You can perform an erase operation of the whole 
00034             chip by calling the function BSP_QSPI_Erase_Chip(). 
00035        (++) The function BSP_QSPI_GetStatus() returns the current status of the QSPI memory. 
00036             (see the QSPI memory data sheet)
00037        (++) Perform erase sector operation using the function BSP_QSPI_Erase_Sector()
00038             which is not blocking. So the function BSP_QSPI_GetStatus() should be used
00039             to check if the memory is busy, and the functions BSP_QSPI_SuspendErase()/
00040             BSP_QSPI_ResumeErase() can be used to perform other operations during the 
00041             sector erase.
00042        (++) Deep power down of the QSPI memory is managed with the call of the functions
00043             BSP_QSPI_EnterDeepPowerDown()/BSP_QSPI_LeaveDeepPowerDown()
00044   @endverbatim
00045   ******************************************************************************
00046   * @attention
00047   *
00048   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
00049   *
00050   * Redistribution and use in source and binary forms, with or without modification,
00051   * are permitted provided that the following conditions are met:
00052   *   1. Redistributions of source code must retain the above copyright notice,
00053   *      this list of conditions and the following disclaimer.
00054   *   2. Redistributions in binary form must reproduce the above copyright notice,
00055   *      this list of conditions and the following disclaimer in the documentation
00056   *      and/or other materials provided with the distribution.
00057   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00058   *      may be used to endorse or promote products derived from this software
00059   *      without specific prior written permission.
00060   *
00061   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00062   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00063   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00064   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00065   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00066   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00067   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00068   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00069   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00070   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00071   *
00072   ******************************************************************************
00073   */
00074 
00075 /* Includes ------------------------------------------------------------------*/
00076 #include "stm32l475e_iot01_qspi.h"
00077 
00078 /** @addtogroup BSP
00079   * @{
00080   */
00081 
00082 /** @addtogroup STM32L475E_IOT01
00083   * @{
00084   */
00085 
00086 /** @defgroup STM32L475E_IOT01_QSPI QSPI
00087   * @{
00088   */
00089 
00090 /* Private constants --------------------------------------------------------*/ 
00091 /** @defgroup STM32L475E_IOT01_QSPI_Private_Constants QSPI Private Constants
00092   * @{
00093   */
00094 #define QSPI_QUAD_DISABLE       0x0
00095 #define QSPI_QUAD_ENABLE        0x1
00096 
00097 #define QSPI_HIGH_PERF_DISABLE  0x0
00098 #define QSPI_HIGH_PERF_ENABLE   0x1
00099 /**
00100   * @}
00101   */
00102 /* Private variables ---------------------------------------------------------*/
00103 
00104 /** @defgroup STM32L475E_IOT01_QSPI_Private_Variables QSPI Private Variables
00105   * @{
00106   */
00107 QSPI_HandleTypeDef QSPIHandle;
00108 
00109 /**
00110   * @}
00111   */
00112 
00113 
00114 /* Private functions ---------------------------------------------------------*/
00115 
00116 /** @defgroup STM32L475E_IOT01_QSPI_Private_Functions QSPI Private Functions
00117   * @{
00118   */
00119 static uint8_t QSPI_ResetMemory        (QSPI_HandleTypeDef *hqspi);
00120 static uint8_t QSPI_WriteEnable        (QSPI_HandleTypeDef *hqspi);
00121 static uint8_t QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi, uint32_t Timeout);
00122 static uint8_t QSPI_QuadMode           (QSPI_HandleTypeDef *hqspi, uint8_t Operation);
00123 static uint8_t QSPI_HighPerfMode       (QSPI_HandleTypeDef *hqspi, uint8_t Operation);
00124 
00125 /**
00126   * @}
00127   */
00128 
00129 /* Exported functions ---------------------------------------------------------*/
00130 
00131 /** @addtogroup STM32L475E_IOT01_QSPI_Exported_Functions
00132   * @{
00133   */
00134 
00135 /**
00136   * @brief  Initializes the QSPI interface.
00137   * @retval QSPI memory status
00138   */
00139 uint8_t BSP_QSPI_Init(void)
00140 { 
00141   QSPIHandle.Instance = QUADSPI;
00142 
00143   /* Call the DeInit function to reset the driver */
00144   if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK)
00145   {
00146     return QSPI_ERROR;
00147   }
00148         
00149   /* System level initialization */
00150   BSP_QSPI_MspInit();
00151   
00152   /* QSPI initialization */
00153   QSPIHandle.Init.ClockPrescaler     = 2; /* QSPI clock = 80MHz / (ClockPrescaler+1) = 26.67MHz */
00154   QSPIHandle.Init.FifoThreshold      = 4;
00155   QSPIHandle.Init.SampleShifting     = QSPI_SAMPLE_SHIFTING_NONE;
00156   QSPIHandle.Init.FlashSize          = POSITION_VAL(MX25R6435F_FLASH_SIZE) - 1;
00157   QSPIHandle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_1_CYCLE;
00158   QSPIHandle.Init.ClockMode          = QSPI_CLOCK_MODE_0;
00159 
00160   if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK)
00161   {
00162     return QSPI_ERROR;
00163   }
00164 
00165   /* QSPI memory reset */
00166   if (QSPI_ResetMemory(&QSPIHandle) != QSPI_OK)
00167   {
00168     return QSPI_NOT_SUPPORTED;
00169   }
00170  
00171   /* QSPI quad enable */
00172   if (QSPI_QuadMode(&QSPIHandle, QSPI_QUAD_ENABLE) != QSPI_OK)
00173   {
00174     return QSPI_ERROR;
00175   }
00176  
00177   /* High performance mode enable */
00178   if (QSPI_HighPerfMode(&QSPIHandle, QSPI_HIGH_PERF_ENABLE) != QSPI_OK)
00179   {
00180     return QSPI_ERROR;
00181   }
00182   
00183   /* Re-configure the clock for the high performance mode */
00184   QSPIHandle.Init.ClockPrescaler = 1; /* QSPI clock = 80MHz / (ClockPrescaler+1) = 40MHz */
00185 
00186   if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK)
00187   {
00188     return QSPI_ERROR;
00189   }
00190 
00191   return QSPI_OK;
00192 }
00193 
00194 /**
00195   * @brief  De-Initializes the QSPI interface.
00196   * @retval QSPI memory status
00197   */
00198 uint8_t BSP_QSPI_DeInit(void)
00199 { 
00200   QSPIHandle.Instance = QUADSPI;
00201   
00202   /* Call the DeInit function to reset the driver */
00203   if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK)
00204   {
00205     return QSPI_ERROR;
00206   }
00207   
00208   /* System level De-initialization */
00209   BSP_QSPI_MspDeInit();
00210   
00211   return QSPI_OK;
00212 }
00213 
00214 /**
00215   * @brief  Reads an amount of data from the QSPI memory.
00216   * @param  pData    : Pointer to data to be read
00217   * @param  ReadAddr : Read start address
00218   * @param  Size     : Size of data to read    
00219   * @retval QSPI memory status
00220   */
00221 uint8_t BSP_QSPI_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size)
00222 {
00223   QSPI_CommandTypeDef sCommand;
00224 
00225   /* Initialize the read command */
00226   sCommand.InstructionMode    = QSPI_INSTRUCTION_1_LINE;
00227   sCommand.Instruction        = QUAD_INOUT_READ_CMD;
00228   sCommand.AddressMode        = QSPI_ADDRESS_4_LINES;
00229   sCommand.AddressSize        = QSPI_ADDRESS_24_BITS;
00230   sCommand.Address            = ReadAddr;
00231   sCommand.AlternateByteMode  = QSPI_ALTERNATE_BYTES_4_LINES;
00232   sCommand.AlternateBytesSize = QSPI_ALTERNATE_BYTES_8_BITS;
00233   sCommand.AlternateBytes     = MX25R6435F_ALT_BYTES_NO_PE_MODE;
00234   sCommand.DataMode           = QSPI_DATA_4_LINES;
00235   sCommand.DummyCycles        = MX25R6435F_DUMMY_CYCLES_READ_QUAD;
00236   sCommand.NbData             = Size;
00237   sCommand.DdrMode            = QSPI_DDR_MODE_DISABLE;
00238   sCommand.DdrHoldHalfCycle   = QSPI_DDR_HHC_ANALOG_DELAY;
00239   sCommand.SIOOMode           = QSPI_SIOO_INST_EVERY_CMD;
00240   
00241   /* Configure the command */
00242   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00243   {
00244     return QSPI_ERROR;
00245   }
00246   
00247   /* Reception of the data */
00248   if (HAL_QSPI_Receive(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00249   {
00250     return QSPI_ERROR;
00251   }
00252 
00253   return QSPI_OK;
00254 }
00255 
00256 /**
00257   * @brief  Writes an amount of data to the QSPI memory.
00258   * @param  pData     : Pointer to data to be written
00259   * @param  WriteAddr : Write start address
00260   * @param  Size      : Size of data to write    
00261   * @retval QSPI memory status
00262   */
00263 uint8_t BSP_QSPI_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size)
00264 {
00265   QSPI_CommandTypeDef sCommand;
00266   uint32_t end_addr, current_size, current_addr;
00267 
00268   /* Calculation of the size between the write address and the end of the page */
00269   current_size = MX25R6435F_PAGE_SIZE - (WriteAddr % MX25R6435F_PAGE_SIZE);
00270 
00271   /* Check if the size of the data is less than the remaining place in the page */
00272   if (current_size > Size)
00273   {
00274     current_size = Size;
00275   }
00276 
00277   /* Initialize the adress variables */
00278   current_addr = WriteAddr;
00279   end_addr = WriteAddr + Size;
00280 
00281   /* Initialize the program command */
00282   sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00283   sCommand.Instruction       = QUAD_PAGE_PROG_CMD;
00284   sCommand.AddressMode       = QSPI_ADDRESS_4_LINES;
00285   sCommand.AddressSize       = QSPI_ADDRESS_24_BITS;
00286   sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00287   sCommand.DataMode          = QSPI_DATA_4_LINES;
00288   sCommand.DummyCycles       = 0;
00289   sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
00290   sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00291   sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00292   
00293   /* Perform the write page by page */
00294   do
00295   {
00296     sCommand.Address = current_addr;
00297     sCommand.NbData  = current_size;
00298 
00299     /* Enable write operations */
00300     if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
00301     {
00302       return QSPI_ERROR;
00303     }
00304     
00305     /* Configure the command */
00306     if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00307     {
00308       return QSPI_ERROR;
00309     }
00310     
00311     /* Transmission of the data */
00312     if (HAL_QSPI_Transmit(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00313     {
00314       return QSPI_ERROR;
00315     }
00316     
00317     /* Configure automatic polling mode to wait for end of program */  
00318     if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
00319     {
00320       return QSPI_ERROR;
00321     }
00322     
00323     /* Update the address and size variables for next page programming */
00324     current_addr += current_size;
00325     pData += current_size;
00326     current_size = ((current_addr + MX25R6435F_PAGE_SIZE) > end_addr) ? (end_addr - current_addr) : MX25R6435F_PAGE_SIZE;
00327   } while (current_addr < end_addr);
00328   
00329   return QSPI_OK;
00330 }
00331 
00332 /**
00333   * @brief  Erases the specified block of the QSPI memory. 
00334   * @param  BlockAddress : Block address to erase  
00335   * @retval QSPI memory status
00336   */
00337 uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress)
00338 {
00339   QSPI_CommandTypeDef sCommand;
00340 
00341   /* Initialize the erase command */
00342   sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00343   sCommand.Instruction       = BLOCK_ERASE_CMD;
00344   sCommand.AddressMode       = QSPI_ADDRESS_1_LINE;
00345   sCommand.AddressSize       = QSPI_ADDRESS_24_BITS;
00346   sCommand.Address           = BlockAddress;
00347   sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00348   sCommand.DataMode          = QSPI_DATA_NONE;
00349   sCommand.DummyCycles       = 0;
00350   sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
00351   sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00352   sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00353 
00354   /* Enable write operations */
00355   if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
00356   {
00357     return QSPI_ERROR;
00358   }
00359 
00360   /* Send the command */
00361   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00362   {
00363     return QSPI_ERROR;
00364   }
00365   
00366   /* Configure automatic polling mode to wait for end of erase */  
00367   if (QSPI_AutoPollingMemReady(&QSPIHandle, MX25R6435F_BLOCK_ERASE_MAX_TIME) != QSPI_OK)
00368   {
00369     return QSPI_ERROR;
00370   }
00371 
00372   return QSPI_OK;
00373 }
00374 
00375 /**
00376   * @brief  Erases the specified sector of the QSPI memory. 
00377   * @param  Sector : Sector address to erase (0 to 255) 
00378   * @retval QSPI memory status
00379   * @note This function is non blocking meaning that sector erase
00380   *       operation is started but not completed when the function 
00381   *       returns. Application has to call BSP_QSPI_GetStatus()
00382   *       to know when the device is available again (i.e. erase operation
00383   *       completed).
00384   */
00385 uint8_t BSP_QSPI_Erase_Sector(uint32_t Sector)
00386 {
00387   QSPI_CommandTypeDef sCommand;
00388   
00389   if (Sector >= (uint32_t)(MX25R6435F_FLASH_SIZE/MX25R6435F_SECTOR_SIZE))
00390   {
00391     return QSPI_ERROR;
00392   }
00393   
00394   /* Initialize the erase command */
00395   sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00396   sCommand.Instruction       = SECTOR_ERASE_CMD;
00397   sCommand.AddressMode       = QSPI_ADDRESS_1_LINE;
00398   sCommand.AddressSize       = QSPI_ADDRESS_24_BITS;
00399   sCommand.Address           = (Sector * MX25R6435F_SECTOR_SIZE);
00400   sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00401   sCommand.DataMode          = QSPI_DATA_NONE;
00402   sCommand.DummyCycles       = 0;
00403   sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
00404   sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00405   sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00406   
00407   /* Enable write operations */
00408   if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
00409   {
00410     return QSPI_ERROR;
00411   }
00412   
00413   /* Send the command */
00414   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00415   {
00416     return QSPI_ERROR;
00417   }
00418   
00419   return QSPI_OK;
00420 }
00421 
00422 /**
00423   * @brief  Erases the entire QSPI memory.
00424   * @retval QSPI memory status
00425   */
00426 uint8_t BSP_QSPI_Erase_Chip(void)
00427 {
00428   QSPI_CommandTypeDef sCommand;
00429 
00430   /* Initialize the erase command */
00431   sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00432   sCommand.Instruction       = CHIP_ERASE_CMD;
00433   sCommand.AddressMode       = QSPI_ADDRESS_NONE;
00434   sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00435   sCommand.DataMode          = QSPI_DATA_NONE;
00436   sCommand.DummyCycles       = 0;
00437   sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
00438   sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00439   sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00440 
00441   /* Enable write operations */
00442   if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
00443   {
00444     return QSPI_ERROR;
00445   }
00446 
00447   /* Send the command */
00448   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00449   {
00450     return QSPI_ERROR;
00451   }
00452   
00453   /* Configure automatic polling mode to wait for end of erase */  
00454   if (QSPI_AutoPollingMemReady(&QSPIHandle, MX25R6435F_CHIP_ERASE_MAX_TIME) != QSPI_OK)
00455   {
00456     return QSPI_ERROR;
00457   }
00458 
00459   return QSPI_OK;
00460 }
00461 
00462 /**
00463   * @brief  Reads current status of the QSPI memory.
00464   * @retval QSPI memory status
00465   */
00466 uint8_t BSP_QSPI_GetStatus(void)
00467 {
00468   QSPI_CommandTypeDef sCommand;
00469   uint8_t reg;
00470 
00471   /* Initialize the read security register command */
00472   sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00473   sCommand.Instruction       = READ_SEC_REG_CMD;
00474   sCommand.AddressMode       = QSPI_ADDRESS_NONE;
00475   sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00476   sCommand.DataMode          = QSPI_DATA_1_LINE;
00477   sCommand.DummyCycles       = 0;
00478   sCommand.NbData            = 1;
00479   sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
00480   sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00481   sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00482 
00483   /* Configure the command */
00484   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00485   {
00486     return QSPI_ERROR;
00487   }
00488 
00489   /* Reception of the data */
00490   if (HAL_QSPI_Receive(&QSPIHandle, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00491   {
00492     return QSPI_ERROR;
00493   }
00494   
00495   /* Check the value of the register */
00496   if ((reg & (MX25R6435F_SECR_P_FAIL | MX25R6435F_SECR_E_FAIL)) != 0)
00497   {
00498     return QSPI_ERROR;
00499   }
00500   else if ((reg & (MX25R6435F_SECR_PSB | MX25R6435F_SECR_ESB)) != 0)
00501   {
00502     return QSPI_SUSPENDED;
00503   }
00504 
00505   /* Initialize the read status register command */
00506   sCommand.Instruction       = READ_STATUS_REG_CMD;
00507 
00508   /* Configure the command */
00509   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00510   {
00511     return QSPI_ERROR;
00512   }
00513 
00514   /* Reception of the data */
00515   if (HAL_QSPI_Receive(&QSPIHandle, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00516   {
00517     return QSPI_ERROR;
00518   }
00519 
00520   /* Check the value of the register */
00521   if ((reg & MX25R6435F_SR_WIP) != 0)
00522   {
00523     return QSPI_BUSY;
00524   }
00525   else
00526   {
00527     return QSPI_OK;
00528   }
00529 }
00530 
00531 /**
00532   * @brief  Return the configuration of the QSPI memory.
00533   * @param  pInfo : pointer on the configuration structure  
00534   * @retval QSPI memory status
00535   */
00536 uint8_t BSP_QSPI_GetInfo(QSPI_Info* pInfo)
00537 {
00538   /* Configure the structure with the memory configuration */
00539   pInfo->FlashSize          = MX25R6435F_FLASH_SIZE;
00540   pInfo->EraseSectorSize    = MX25R6435F_SECTOR_SIZE;
00541   pInfo->EraseSectorsNumber = (MX25R6435F_FLASH_SIZE/MX25R6435F_SECTOR_SIZE);
00542   pInfo->ProgPageSize       = MX25R6435F_PAGE_SIZE;
00543   pInfo->ProgPagesNumber    = (MX25R6435F_FLASH_SIZE/MX25R6435F_PAGE_SIZE);
00544   
00545   return QSPI_OK;
00546 }
00547 
00548 /**
00549   * @brief  Configure the QSPI in memory-mapped mode
00550   * @retval QSPI memory status
00551   */
00552 uint8_t BSP_QSPI_EnableMemoryMappedMode(void)
00553 {
00554   QSPI_CommandTypeDef      sCommand;
00555   QSPI_MemoryMappedTypeDef sMemMappedCfg;
00556 
00557   /* Configure the command for the read instruction */
00558   sCommand.InstructionMode    = QSPI_INSTRUCTION_1_LINE;
00559   sCommand.Instruction        = QUAD_INOUT_READ_CMD;
00560   sCommand.AddressMode        = QSPI_ADDRESS_4_LINES;
00561   sCommand.AddressSize        = QSPI_ADDRESS_24_BITS;
00562   sCommand.AlternateByteMode  = QSPI_ALTERNATE_BYTES_4_LINES;
00563   sCommand.AlternateBytesSize = QSPI_ALTERNATE_BYTES_8_BITS;
00564   sCommand.AlternateBytes     = MX25R6435F_ALT_BYTES_NO_PE_MODE;
00565   sCommand.DataMode           = QSPI_DATA_4_LINES;
00566   sCommand.DummyCycles        = MX25R6435F_DUMMY_CYCLES_READ_QUAD;
00567   sCommand.DdrMode            = QSPI_DDR_MODE_DISABLE;
00568   sCommand.DdrHoldHalfCycle   = QSPI_DDR_HHC_ANALOG_DELAY;
00569   sCommand.SIOOMode           = QSPI_SIOO_INST_EVERY_CMD;
00570   
00571   /* Configure the memory mapped mode */
00572   sMemMappedCfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE;
00573   
00574   if (HAL_QSPI_MemoryMapped(&QSPIHandle, &sCommand, &sMemMappedCfg) != HAL_OK)
00575   {
00576     return QSPI_ERROR;
00577   }
00578 
00579   return QSPI_OK;
00580 }
00581 
00582 /**
00583   * @brief  This function suspends an ongoing erase command.
00584   * @retval QSPI memory status
00585   */
00586 uint8_t BSP_QSPI_SuspendErase(void)
00587 {
00588   QSPI_CommandTypeDef sCommand;
00589   
00590   /* Check whether the device is busy (erase operation is 
00591   in progress).
00592   */
00593   if (BSP_QSPI_GetStatus() == QSPI_BUSY)
00594   {
00595     /* Initialize the erase command */
00596     sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00597     sCommand.Instruction       = PROG_ERASE_SUSPEND_CMD;
00598     sCommand.AddressMode       = QSPI_ADDRESS_NONE;
00599     sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00600     sCommand.DataMode          = QSPI_DATA_NONE;
00601     sCommand.DummyCycles       = 0;
00602     sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
00603     sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00604     sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00605     
00606     /* Send the command */
00607     if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00608     {
00609       return QSPI_ERROR;
00610     }
00611     
00612     if (BSP_QSPI_GetStatus() == QSPI_SUSPENDED)
00613     {
00614       return QSPI_OK;
00615     }
00616     
00617     return QSPI_ERROR;
00618   }
00619   
00620   return QSPI_OK;
00621 }
00622 
00623 /**
00624   * @brief  This function resumes a paused erase command.
00625   * @retval QSPI memory status
00626   */
00627 uint8_t BSP_QSPI_ResumeErase(void)
00628 {
00629   QSPI_CommandTypeDef sCommand;
00630   
00631   /* Check whether the device is in suspended state */
00632   if (BSP_QSPI_GetStatus() == QSPI_SUSPENDED)
00633   {
00634     /* Initialize the erase command */
00635     sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00636     sCommand.Instruction       = PROG_ERASE_RESUME_CMD;
00637     sCommand.AddressMode       = QSPI_ADDRESS_NONE;
00638     sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00639     sCommand.DataMode          = QSPI_DATA_NONE;
00640     sCommand.DummyCycles       = 0;
00641     sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
00642     sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00643     sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00644     
00645     /* Send the command */
00646     if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00647     {
00648       return QSPI_ERROR;
00649     }
00650     
00651     /*
00652     When this command is executed, the status register write in progress bit is set to 1, and
00653     the flag status register program erase controller bit is set to 0. This command is ignored
00654     if the device is not in a suspended state.
00655     */
00656     
00657     if (BSP_QSPI_GetStatus() == QSPI_BUSY)
00658     {
00659       return QSPI_OK;
00660     }
00661     
00662     return QSPI_ERROR;
00663   }
00664 
00665   return QSPI_OK;
00666 }
00667 
00668 /**
00669   * @brief  This function enter the QSPI memory in deep power down mode.
00670   * @retval QSPI memory status
00671   */
00672 uint8_t BSP_QSPI_EnterDeepPowerDown(void)
00673 {
00674   QSPI_CommandTypeDef sCommand;
00675   
00676   /* Initialize the deep power down command */
00677   sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00678   sCommand.Instruction       = DEEP_POWER_DOWN_CMD;
00679   sCommand.AddressMode       = QSPI_ADDRESS_NONE;
00680   sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00681   sCommand.DataMode          = QSPI_DATA_NONE;
00682   sCommand.DummyCycles       = 0;
00683   sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
00684   sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00685   sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00686     
00687   /* Send the command */
00688   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00689   {
00690     return QSPI_ERROR;
00691   }
00692   
00693   /* ---          Memory takes 10us max to enter deep power down          --- */
00694   /* --- At least 30us should be respected before leaving deep power down --- */
00695   
00696   return QSPI_OK;
00697 }
00698 
00699 /**
00700   * @brief  This function leave the QSPI memory from deep power down mode.
00701   * @retval QSPI memory status
00702   */
00703 uint8_t BSP_QSPI_LeaveDeepPowerDown(void)
00704 {
00705   QSPI_CommandTypeDef sCommand;
00706   
00707   /* Initialize the erase command */
00708   sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00709   sCommand.Instruction       = NO_OPERATION_CMD;
00710   sCommand.AddressMode       = QSPI_ADDRESS_NONE;
00711   sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00712   sCommand.DataMode          = QSPI_DATA_NONE;
00713   sCommand.DummyCycles       = 0;
00714   sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
00715   sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00716   sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00717     
00718   /* Send the command */
00719   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00720   {
00721     return QSPI_ERROR;
00722   }
00723   
00724   /* --- A NOP command is sent to the memory, as the nCS should be low for at least 20 ns --- */
00725   /* ---                  Memory takes 35us min to leave deep power down                  --- */
00726   
00727   return QSPI_OK;
00728 }
00729 
00730 /**
00731   * @brief  Initializes the QSPI MSP.
00732   * @retval None
00733   */
00734 __weak void BSP_QSPI_MspInit(void)
00735 {
00736   GPIO_InitTypeDef GPIO_InitStruct;
00737 
00738   /* Enable the QuadSPI memory interface clock */
00739   __HAL_RCC_QSPI_CLK_ENABLE();
00740 
00741   /* Reset the QuadSPI memory interface */
00742   __HAL_RCC_QSPI_FORCE_RESET();
00743   __HAL_RCC_QSPI_RELEASE_RESET();
00744 
00745   /* Enable GPIO clocks */
00746   __HAL_RCC_GPIOE_CLK_ENABLE();
00747 
00748   /* QSPI CLK, CS, D0, D1, D2 and D3 GPIO pins configuration  */
00749   GPIO_InitStruct.Pin       = GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 |\
00750                               GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
00751   GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
00752   GPIO_InitStruct.Pull      = GPIO_NOPULL;
00753   GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
00754   GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI;
00755   HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
00756 }
00757 
00758 /**
00759   * @brief  De-Initializes the QSPI MSP.
00760   * @retval None
00761   */
00762 __weak void BSP_QSPI_MspDeInit(void)
00763 {
00764   GPIO_InitTypeDef GPIO_InitStruct;
00765 
00766   /* QSPI CLK, CS, D0-D3 GPIO pins de-configuration  */
00767   __HAL_RCC_GPIOE_CLK_ENABLE();
00768   GPIO_InitStruct.Pin       = GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 |\
00769                               GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
00770 
00771   HAL_GPIO_DeInit(GPIOE, GPIO_InitStruct.Pin);
00772     
00773   /* Reset the QuadSPI memory interface */
00774   __HAL_RCC_QSPI_FORCE_RESET();
00775   __HAL_RCC_QSPI_RELEASE_RESET();
00776 
00777   /* Disable the QuadSPI memory interface clock */
00778   __HAL_RCC_QSPI_CLK_DISABLE();
00779 }
00780 
00781 /**
00782   * @}
00783   */
00784 
00785 /** @addtogroup STM32L475E_IOT01_QSPI_Private_Functions 
00786   * @{
00787   */
00788 
00789 /**
00790   * @brief  This function reset the QSPI memory.
00791   * @param  hqspi : QSPI handle
00792   * @retval None
00793   */
00794 static uint8_t QSPI_ResetMemory(QSPI_HandleTypeDef *hqspi)
00795 {
00796   QSPI_CommandTypeDef sCommand;
00797 
00798   /* Initialize the reset enable command */
00799   sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00800   sCommand.Instruction       = RESET_ENABLE_CMD;
00801   sCommand.AddressMode       = QSPI_ADDRESS_NONE;
00802   sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00803   sCommand.DataMode          = QSPI_DATA_NONE;
00804   sCommand.DummyCycles       = 0;
00805   sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
00806   sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00807   sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00808 
00809   /* Send the command */
00810   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00811   {
00812     return QSPI_ERROR;
00813   }
00814 
00815   /* Send the reset memory command */
00816   sCommand.Instruction = RESET_MEMORY_CMD;
00817   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00818   {
00819     return QSPI_ERROR;
00820   }
00821 
00822   /* Configure automatic polling mode to wait the memory is ready */  
00823   if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
00824   {
00825     return QSPI_ERROR;
00826   }
00827 
00828   return QSPI_OK;
00829 }
00830 
00831 /**
00832   * @brief  This function send a Write Enable and wait it is effective.
00833   * @param  hqspi : QSPI handle
00834   * @retval None
00835   */
00836 static uint8_t QSPI_WriteEnable(QSPI_HandleTypeDef *hqspi)
00837 {
00838   QSPI_CommandTypeDef     sCommand;
00839   QSPI_AutoPollingTypeDef sConfig;
00840 
00841   /* Enable write operations */
00842   sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00843   sCommand.Instruction       = WRITE_ENABLE_CMD;
00844   sCommand.AddressMode       = QSPI_ADDRESS_NONE;
00845   sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00846   sCommand.DataMode          = QSPI_DATA_NONE;
00847   sCommand.DummyCycles       = 0;
00848   sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
00849   sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00850   sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00851 
00852   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00853   {
00854     return QSPI_ERROR;
00855   }
00856   
00857   /* Configure automatic polling mode to wait for write enabling */  
00858   sConfig.Match           = MX25R6435F_SR_WEL;
00859   sConfig.Mask            = MX25R6435F_SR_WEL;
00860   sConfig.MatchMode       = QSPI_MATCH_MODE_AND;
00861   sConfig.StatusBytesSize = 1;
00862   sConfig.Interval        = 0x10;
00863   sConfig.AutomaticStop   = QSPI_AUTOMATIC_STOP_ENABLE;
00864 
00865   sCommand.Instruction    = READ_STATUS_REG_CMD;
00866   sCommand.DataMode       = QSPI_DATA_1_LINE;
00867 
00868   if (HAL_QSPI_AutoPolling(&QSPIHandle, &sCommand, &sConfig, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00869   {
00870     return QSPI_ERROR;
00871   }
00872 
00873   return QSPI_OK;
00874 }
00875 
00876 /**
00877   * @brief  This function read the SR of the memory and wait the EOP.
00878   * @param  hqspi   : QSPI handle
00879   * @param  Timeout : Timeout for auto-polling
00880   * @retval None
00881   */
00882 static uint8_t QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi, uint32_t Timeout)
00883 {
00884   QSPI_CommandTypeDef     sCommand;
00885   QSPI_AutoPollingTypeDef sConfig;
00886 
00887   /* Configure automatic polling mode to wait for memory ready */  
00888   sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00889   sCommand.Instruction       = READ_STATUS_REG_CMD;
00890   sCommand.AddressMode       = QSPI_ADDRESS_NONE;
00891   sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00892   sCommand.DataMode          = QSPI_DATA_1_LINE;
00893   sCommand.DummyCycles       = 0;
00894   sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
00895   sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00896   sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00897 
00898   sConfig.Match           = 0;
00899   sConfig.Mask            = MX25R6435F_SR_WIP;
00900   sConfig.MatchMode       = QSPI_MATCH_MODE_AND;
00901   sConfig.StatusBytesSize = 1;
00902   sConfig.Interval        = 0x10;
00903   sConfig.AutomaticStop   = QSPI_AUTOMATIC_STOP_ENABLE;
00904 
00905   if (HAL_QSPI_AutoPolling(&QSPIHandle, &sCommand, &sConfig, Timeout) != HAL_OK)
00906   {
00907     return QSPI_ERROR;
00908   }
00909 
00910   return QSPI_OK;
00911 }
00912 
00913 /**
00914   * @brief  This function enables/disables the Quad mode of the memory.
00915   * @param  hqspi     : QSPI handle
00916   * @param  Operation : QSPI_QUAD_ENABLE or QSPI_QUAD_DISABLE mode  
00917   * @retval None
00918   */
00919 static uint8_t QSPI_QuadMode(QSPI_HandleTypeDef *hqspi, uint8_t Operation)
00920 {
00921   QSPI_CommandTypeDef sCommand;
00922   uint8_t reg;
00923 
00924   /* Read status register */
00925   sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00926   sCommand.Instruction       = READ_STATUS_REG_CMD;
00927   sCommand.AddressMode       = QSPI_ADDRESS_NONE;
00928   sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00929   sCommand.DataMode          = QSPI_DATA_1_LINE;
00930   sCommand.DummyCycles       = 0;
00931   sCommand.NbData            = 1;
00932   sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
00933   sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00934   sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00935 
00936   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00937   {
00938     return QSPI_ERROR;
00939   }
00940 
00941   if (HAL_QSPI_Receive(&QSPIHandle, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00942   {
00943     return QSPI_ERROR;
00944   }
00945 
00946   /* Enable write operations */
00947   if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
00948   {
00949     return QSPI_ERROR;
00950   }
00951   
00952   /* Activate/deactivate the Quad mode */
00953   if (Operation == QSPI_QUAD_ENABLE)
00954   {
00955     SET_BIT(reg, MX25R6435F_SR_QE);
00956   }
00957   else
00958   {
00959     CLEAR_BIT(reg, MX25R6435F_SR_QE);
00960   }
00961 
00962   sCommand.Instruction = WRITE_STATUS_CFG_REG_CMD;
00963 
00964   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00965   {
00966     return QSPI_ERROR;
00967   }
00968 
00969   if (HAL_QSPI_Transmit(&QSPIHandle, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00970   {
00971     return QSPI_ERROR;
00972   }
00973 
00974   /* Wait that memory is ready */  
00975   if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
00976   {
00977     return QSPI_ERROR;
00978   }
00979   
00980   /* Check the configuration has been correctly done */
00981   sCommand.Instruction = READ_STATUS_REG_CMD;
00982 
00983   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00984   {
00985     return QSPI_ERROR;
00986   }
00987 
00988   if (HAL_QSPI_Receive(&QSPIHandle, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00989   {
00990     return QSPI_ERROR;
00991   }
00992   
00993   if ((((reg & MX25R6435F_SR_QE) == 0) && (Operation == QSPI_QUAD_ENABLE)) ||
00994       (((reg & MX25R6435F_SR_QE) != 0) && (Operation == QSPI_QUAD_DISABLE)))
00995   {
00996     return QSPI_ERROR;
00997   }
00998 
00999   return QSPI_OK;
01000 }
01001 
01002 /**
01003   * @brief  This function enables/disables the high performance mode of the memory.
01004   * @param  hqspi     : QSPI handle
01005   * @param  Operation : QSPI_HIGH_PERF_ENABLE or QSPI_HIGH_PERF_DISABLE high performance mode    
01006   * @retval None
01007   */
01008 static uint8_t QSPI_HighPerfMode(QSPI_HandleTypeDef *hqspi, uint8_t Operation)
01009 {
01010   QSPI_CommandTypeDef sCommand;
01011   uint8_t reg[3];
01012 
01013   /* Read status register */
01014   sCommand.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
01015   sCommand.Instruction       = READ_STATUS_REG_CMD;
01016   sCommand.AddressMode       = QSPI_ADDRESS_NONE;
01017   sCommand.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
01018   sCommand.DataMode          = QSPI_DATA_1_LINE;
01019   sCommand.DummyCycles       = 0;
01020   sCommand.NbData            = 1;
01021   sCommand.DdrMode           = QSPI_DDR_MODE_DISABLE;
01022   sCommand.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
01023   sCommand.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
01024 
01025   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
01026   {
01027     return QSPI_ERROR;
01028   }
01029 
01030   if (HAL_QSPI_Receive(&QSPIHandle, &(reg[0]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
01031   {
01032     return QSPI_ERROR;
01033   }
01034 
01035   /* Read configuration registers */
01036   sCommand.Instruction = READ_CFG_REG_CMD;
01037   sCommand.NbData      = 2;
01038 
01039   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
01040   {
01041     return QSPI_ERROR;
01042   }
01043 
01044   if (HAL_QSPI_Receive(&QSPIHandle, &(reg[1]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
01045   {
01046     return QSPI_ERROR;
01047   }
01048 
01049   /* Enable write operations */
01050   if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
01051   {
01052     return QSPI_ERROR;
01053   }
01054   
01055   /* Activate/deactivate the Quad mode */
01056   if (Operation == QSPI_HIGH_PERF_ENABLE)
01057   {
01058     SET_BIT(reg[2], MX25R6435F_CR2_LH_SWITCH);
01059   }
01060   else
01061   {
01062     CLEAR_BIT(reg[2], MX25R6435F_CR2_LH_SWITCH);
01063   }
01064 
01065   sCommand.Instruction = WRITE_STATUS_CFG_REG_CMD;
01066   sCommand.NbData      = 3;
01067 
01068   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
01069   {
01070     return QSPI_ERROR;
01071   }
01072 
01073   if (HAL_QSPI_Transmit(&QSPIHandle, &(reg[0]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
01074   {
01075     return QSPI_ERROR;
01076   }
01077 
01078   /* Wait that memory is ready */  
01079   if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
01080   {
01081     return QSPI_ERROR;
01082   }
01083   
01084   /* Check the configuration has been correctly done */
01085   sCommand.Instruction = READ_CFG_REG_CMD;
01086   sCommand.NbData      = 2;
01087 
01088   if (HAL_QSPI_Command(&QSPIHandle, &sCommand, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
01089   {
01090     return QSPI_ERROR;
01091   }
01092 
01093   if (HAL_QSPI_Receive(&QSPIHandle, &(reg[0]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
01094   {
01095     return QSPI_ERROR;
01096   }
01097   
01098   if ((((reg[1] & MX25R6435F_CR2_LH_SWITCH) == 0) && (Operation == QSPI_HIGH_PERF_ENABLE)) ||
01099       (((reg[1] & MX25R6435F_CR2_LH_SWITCH) != 0) && (Operation == QSPI_HIGH_PERF_DISABLE)))
01100   {
01101     return QSPI_ERROR;
01102   }
01103 
01104   return QSPI_OK;
01105 }
01106 
01107 /**
01108   * @}
01109   */
01110 
01111 /**
01112   * @}
01113   */
01114 
01115 /**
01116   * @}
01117   */
01118 
01119 /**
01120   * @}
01121   */
01122 
01123 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
01124