STM32F723E-Discovery BSP User Manual: stm32f723e_discovery_qspi.c Source File

STM32F723E-Discovery BSP

stm32f723e_discovery_qspi.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f723e_discovery_qspi.c
00004   * @author  MCD Application Team
00005   * @brief   This file includes a standard driver for the MX25L512 QSPI
00006   *          memory mounted on STM32F723E-Discovery board.
00007   @verbatim
00008   ==============================================================================
00009                      ##### How to use this driver #####
00010   ==============================================================================  
00011   [..] 
00012    (#) This driver is used to drive the MX25L512 QSPI external
00013        memory mounted on STM32F723E-Discovery board.
00014        
00015    (#) This driver need a specific component driver (MX25L51245G) 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.
00021   
00022    (#) QSPI memory operations
00023        (++) QSPI memory can be accessed with read/write operations once it is
00024             initialized.
00025             Read/write operation can be performed with AHB access using the functions
00026             BSP_QSPI_Read()/BSP_QSPI_Write(). 
00027        (++) The function BSP_QSPI_GetInfo() returns the configuration of the QSPI memory. 
00028             (see the QSPI memory data sheet)
00029        (++) Perform erase block operation using the function BSP_QSPI_Erase_Block() and by
00030             specifying the block address. You can perform an erase operation of the whole 
00031             chip by calling the function BSP_QSPI_Erase_Chip(). 
00032        (++) The function BSP_QSPI_GetStatus() returns the current status of the QSPI memory. 
00033             (see the QSPI memory data sheet)
00034   @endverbatim
00035   ******************************************************************************
00036   * @attention
00037   *
00038   * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
00039   *
00040   * Redistribution and use in source and binary forms, with or without modification,
00041   * are permitted provided that the following conditions are met:
00042   *   1. Redistributions of source code must retain the above copyright notice,
00043   *      this list of conditions and the following disclaimer.
00044   *   2. Redistributions in binary form must reproduce the above copyright notice,
00045   *      this list of conditions and the following disclaimer in the documentation
00046   *      and/or other materials provided with the distribution.
00047   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00048   *      may be used to endorse or promote products derived from this software
00049   *      without specific prior written permission.
00050   *
00051   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00052   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00053   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00054   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00055   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00056   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00057   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00058   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00059   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00060   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00061   *
00062   ******************************************************************************
00063   */ 
00064 
00065 /* Dependencies
00066 - stm32f7xx_hal_qspi.c
00067 - stm32f7xx_hal_gpio.c
00068 - stm32f7xx_hal_cortex.c
00069 - stm32f7xx_hal_rcc_ex.h
00070 - mx25l512.h
00071 EndDependencies */
00072 
00073 /* Includes ------------------------------------------------------------------*/
00074 #include "stm32f723e_discovery_qspi.h"
00075 
00076 /** @addtogroup BSP
00077   * @{
00078   */
00079 
00080 /** @addtogroup STM32F723E_DISCOVERY
00081   * @{
00082   */ 
00083   
00084 /** @defgroup STM32F723E_DISCOVERY_QSPI STM32F723E-DISCOVERY QSPI
00085   * @{
00086   */ 
00087 
00088 
00089 /* Private variables ---------------------------------------------------------*/
00090 
00091 /** @defgroup STM32F723E_DISCOVERY_QSPI_Private_Variables STM32F723E_DISCOVERY QSPI Private Variables
00092   * @{
00093   */       
00094 QSPI_HandleTypeDef QSPIHandle;
00095 
00096 /**
00097   * @}
00098   */ 
00099 
00100 
00101 
00102 /* Private functions ---------------------------------------------------------*/
00103     
00104 /** @defgroup STM32F723E_DISCOVERY_QSPI_Private_Functions STM32F723E_DISCOVERY QSPI Private Functions
00105   * @{
00106   */ 
00107 static uint8_t QSPI_ResetMemory(QSPI_HandleTypeDef *hqspi);
00108 static uint8_t QSPI_EnterFourBytesAddress(QSPI_HandleTypeDef *hqspi);
00109 static uint8_t QSPI_DummyCyclesCfg(QSPI_HandleTypeDef *hqspi);
00110 static uint8_t QSPI_EnterMemory_QPI(QSPI_HandleTypeDef *hqspi);
00111 static uint8_t QSPI_ExitMemory_QPI(QSPI_HandleTypeDef *hqspi);
00112 static uint8_t QSPI_OutDrvStrengthCfg(QSPI_HandleTypeDef *hqspi);
00113 static uint8_t QSPI_WriteEnable(QSPI_HandleTypeDef *hqspi);
00114 static uint8_t QSPI_AutoPollingMemReady  (QSPI_HandleTypeDef *hqspi, uint32_t Timeout);
00115 
00116 /**
00117   * @}
00118   */
00119     
00120 /** @defgroup STM32F723E_DISCOVERY_QSPI_Exported_Functions STM32F723E_DISCOVERY QSPI Exported Functions
00121   * @{
00122   */ 
00123 
00124 /**
00125   * @brief  Initializes the QSPI interface.
00126   * @retval QSPI memory status
00127   */
00128 uint8_t BSP_QSPI_Init(void)
00129 { 
00130   QSPIHandle.Instance = QUADSPI;
00131   
00132   /* Call the DeInit function to reset the driver */
00133   if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK)
00134   {
00135     return QSPI_ERROR;
00136   }
00137   
00138   /* System level initialization */
00139   BSP_QSPI_MspInit(&QSPIHandle, NULL);
00140   
00141   /* QSPI initialization */
00142   /* QSPI freq = SYSCLK /(1 + ClockPrescaler) = 216 MHz/(1+1) = 108 Mhz */
00143   QSPIHandle.Init.ClockPrescaler     = 1;   /* QSPI freq = 216 MHz/(1+1) = 108 Mhz */
00144   QSPIHandle.Init.FifoThreshold      = 16;
00145   QSPIHandle.Init.SampleShifting     = QSPI_SAMPLE_SHIFTING_HALFCYCLE; 
00146   QSPIHandle.Init.FlashSize          = POSITION_VAL(MX25L512_FLASH_SIZE) - 1;
00147   QSPIHandle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_4_CYCLE; /* Min 30ns for nonRead */
00148   QSPIHandle.Init.ClockMode          = QSPI_CLOCK_MODE_0;
00149   QSPIHandle.Init.FlashID            = QSPI_FLASH_ID_1;
00150   QSPIHandle.Init.DualFlash          = QSPI_DUALFLASH_DISABLE;
00151   
00152   if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK)
00153   {
00154     return QSPI_ERROR;
00155   }
00156   
00157   /* QSPI memory reset */
00158   if (QSPI_ResetMemory(&QSPIHandle) != QSPI_OK)
00159   {
00160     return QSPI_NOT_SUPPORTED;
00161   }
00162   
00163   /* Put QSPI memory in QPI mode */
00164   if( QSPI_EnterMemory_QPI( &QSPIHandle )!=QSPI_OK )
00165   {
00166     return QSPI_NOT_SUPPORTED;
00167   }
00168   
00169   /* Set the QSPI memory in 4-bytes address mode */
00170   if (QSPI_EnterFourBytesAddress(&QSPIHandle) != QSPI_OK)
00171   {
00172     return QSPI_NOT_SUPPORTED;
00173   }
00174   
00175   /* Configuration of the dummy cycles on QSPI memory side */
00176   if (QSPI_DummyCyclesCfg(&QSPIHandle) != QSPI_OK)
00177   {
00178     return QSPI_NOT_SUPPORTED;
00179   }
00180   
00181   /* Configuration of the Output driver strength on memory side */
00182   if( QSPI_OutDrvStrengthCfg( &QSPIHandle ) != QSPI_OK )
00183   {
00184     return QSPI_NOT_SUPPORTED;
00185   }
00186   
00187   return QSPI_OK;
00188 }
00189 
00190 /**
00191   * @brief  De-Initializes the QSPI interface.
00192   * @retval QSPI memory status
00193   */
00194 uint8_t BSP_QSPI_DeInit(void)
00195 { 
00196   QSPIHandle.Instance = QUADSPI;
00197 
00198   /* Put QSPI memory in SPI mode */
00199   if( QSPI_ExitMemory_QPI(&QSPIHandle )!=QSPI_OK )
00200   {
00201     return QSPI_NOT_SUPPORTED;
00202   }
00203   
00204   /* Call the DeInit function to reset the driver */
00205   if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK)
00206   {
00207     return QSPI_ERROR;
00208   }
00209         
00210   /* System level De-initialization */
00211   BSP_QSPI_MspDeInit(&QSPIHandle, NULL);
00212   
00213   return QSPI_OK;
00214 }
00215 
00216 /**
00217   * @brief  Reads an amount of data from the QSPI memory.
00218   * @param  pData: Pointer to data to be read
00219   * @param  ReadAddr: Read start address
00220   * @param  Size: Size of data to read    
00221   * @retval QSPI memory status
00222   */
00223 uint8_t BSP_QSPI_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size)
00224 {
00225   QSPI_CommandTypeDef s_command;
00226 
00227   /* Initialize the read command */
00228   s_command.InstructionMode   = QSPI_INSTRUCTION_4_LINES;
00229   s_command.Instruction       = QSPI_READ_4_BYTE_ADDR_CMD;
00230   s_command.AddressMode       = QSPI_ADDRESS_4_LINES;
00231   s_command.AddressSize       = QSPI_ADDRESS_32_BITS;
00232   s_command.Address           = ReadAddr;
00233   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00234   s_command.DataMode          = QSPI_DATA_4_LINES;
00235   s_command.DummyCycles       = MX25L512_DUMMY_CYCLES_READ_QUAD_IO;
00236   s_command.NbData            = Size;
00237   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00238   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00239   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00240   
00241   /* Configure the command */
00242   if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00243   {
00244     return QSPI_ERROR;
00245   }
00246 
00247   /* Set S# timing for Read command */
00248   MODIFY_REG(QSPIHandle.Instance->DCR, QUADSPI_DCR_CSHT, QSPI_CS_HIGH_TIME_1_CYCLE);
00249 
00250   /* Reception of the data */
00251   if (HAL_QSPI_Receive(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00252   {
00253     return QSPI_ERROR;
00254   }
00255 
00256   /* Restore S# timing for nonRead commands */
00257   MODIFY_REG(QSPIHandle.Instance->DCR, QUADSPI_DCR_CSHT, QSPI_CS_HIGH_TIME_4_CYCLE);
00258 
00259   return QSPI_OK;
00260 }
00261 
00262 /**
00263   * @brief  Writes an amount of data to the QSPI memory.
00264   * @param  pData: Pointer to data to be written
00265   * @param  WriteAddr: Write start address
00266   * @param  Size: Size of data to write    
00267   * @retval QSPI memory status
00268   */
00269 uint8_t BSP_QSPI_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size)
00270 {
00271   QSPI_CommandTypeDef s_command;
00272   uint32_t end_addr, current_size, current_addr;
00273 
00274   /* Calculation of the size between the write address and the end of the page */
00275   current_size = MX25L512_PAGE_SIZE - (WriteAddr % MX25L512_PAGE_SIZE);
00276 
00277   /* Check if the size of the data is less than the remaining place in the page */
00278   if (current_size > Size)
00279   {
00280     current_size = Size;
00281   }
00282 
00283   /* Initialize the address variables */
00284   current_addr = WriteAddr;
00285   end_addr = WriteAddr + Size;
00286 
00287   /* Initialize the program command */
00288   s_command.InstructionMode   = QSPI_INSTRUCTION_4_LINES;
00289   s_command.Instruction       = QSPI_PAGE_PROG_4_BYTE_ADDR_CMD;
00290   s_command.AddressMode       = QSPI_ADDRESS_4_LINES;
00291   s_command.AddressSize       = QSPI_ADDRESS_32_BITS;
00292   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00293   s_command.DataMode          = QSPI_DATA_4_LINES;
00294   s_command.DummyCycles       = 0;
00295   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00296   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00297   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00298   
00299   /* Perform the write page by page */
00300   do
00301   {
00302     s_command.Address = current_addr;
00303     s_command.NbData  = current_size;
00304 
00305     /* Enable write operations */
00306     if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
00307     {
00308       return QSPI_ERROR;
00309     }
00310     
00311     /* Configure the command */
00312     if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00313     {
00314       return QSPI_ERROR;
00315     }
00316     
00317     /* Transmission of the data */
00318     if (HAL_QSPI_Transmit(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00319     {
00320       return QSPI_ERROR;
00321     }
00322     
00323     /* Configure automatic polling mode to wait for end of program */  
00324     if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
00325     {
00326       return QSPI_ERROR;
00327     }
00328     
00329     /* Update the address and size variables for next page programming */
00330     current_addr += current_size;
00331     pData += current_size;
00332     current_size = ((current_addr + MX25L512_PAGE_SIZE) > end_addr) ? (end_addr - current_addr) : MX25L512_PAGE_SIZE;
00333   } while (current_addr < end_addr);
00334   
00335   return QSPI_OK;
00336 }
00337 
00338 /**
00339   * @brief  Erases the specified block of the QSPI memory. 
00340   * @param  BlockAddress: Block address to erase  
00341   * @retval QSPI memory status
00342   */
00343 uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress)
00344 {
00345   QSPI_CommandTypeDef s_command;
00346 
00347   /* Initialize the erase command */
00348   s_command.InstructionMode   = QSPI_INSTRUCTION_4_LINES;
00349   s_command.Instruction       = SUBSECTOR_ERASE_4_BYTE_ADDR_CMD;
00350   s_command.AddressMode       = QSPI_ADDRESS_4_LINES;
00351   s_command.AddressSize       = QSPI_ADDRESS_32_BITS;
00352   s_command.Address           = BlockAddress;
00353   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00354   s_command.DataMode          = QSPI_DATA_NONE;
00355   s_command.DummyCycles       = 0;
00356   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00357   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00358   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00359 
00360   /* Enable write operations */
00361   if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
00362   {
00363     return QSPI_ERROR;
00364   }
00365 
00366   /* Send the command */
00367   if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00368   {
00369     return QSPI_ERROR;
00370   }
00371   
00372   /* Configure automatic polling mode to wait for end of erase */  
00373   if (QSPI_AutoPollingMemReady(&QSPIHandle, MX25L512_SUBSECTOR_ERASE_MAX_TIME) != QSPI_OK)
00374   {
00375     return QSPI_ERROR;
00376   }
00377 
00378   return QSPI_OK;
00379 }
00380 
00381 /**
00382   * @brief  Erases the entire QSPI memory.
00383   * @retval QSPI memory status
00384   */
00385 uint8_t BSP_QSPI_Erase_Chip(void)
00386 {
00387   QSPI_CommandTypeDef s_command;
00388 
00389   /* Initialize the erase command */
00390   s_command.InstructionMode   = QSPI_INSTRUCTION_4_LINES;
00391   s_command.Instruction       = BULK_ERASE_CMD;
00392   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00393   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00394   s_command.DataMode          = QSPI_DATA_NONE;
00395   s_command.DummyCycles       = 0;
00396   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00397   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00398   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00399 
00400   /* Enable write operations */
00401   if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
00402   {
00403     return QSPI_ERROR;
00404   }
00405 
00406   /* Send the command */
00407   if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00408   {
00409     return QSPI_ERROR;
00410   }
00411   
00412   /* Configure automatic polling mode to wait for end of erase */  
00413   if (QSPI_AutoPollingMemReady(&QSPIHandle, MX25L512_BULK_ERASE_MAX_TIME) != QSPI_OK)
00414   {
00415     return QSPI_ERROR;
00416   }
00417 
00418   return QSPI_OK;
00419 }
00420 
00421 /**
00422   * @brief  Reads current status of the QSPI memory.
00423   * @retval QSPI memory status
00424   */
00425 uint8_t BSP_QSPI_GetStatus(void)
00426 {
00427   QSPI_CommandTypeDef s_command;
00428   uint8_t reg;
00429   
00430   /* Initialize the read flag status register command */
00431   s_command.InstructionMode   = QSPI_INSTRUCTION_4_LINES;
00432   s_command.Instruction       = READ_STATUS_REG_CMD;
00433   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00434   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00435   s_command.DataMode          = QSPI_DATA_4_LINES;
00436   s_command.DummyCycles       = 0;
00437   s_command.NbData            = 1;
00438   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00439   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00440   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00441   
00442   /* Configure the command */
00443   if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00444   {
00445     return QSPI_ERROR;
00446   }
00447   
00448   /* Reception of the data */
00449   if (HAL_QSPI_Receive(&QSPIHandle, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00450   {
00451     return QSPI_ERROR;
00452   }
00453   
00454   /* Check the value of the register*/ 
00455   if ((reg & MX25L512_SR_WIP) == 0)
00456   {
00457     return QSPI_OK;
00458   }
00459   else
00460   {
00461     return QSPI_BUSY;
00462   }
00463 }
00464 
00465 /**
00466   * @brief  Return the configuration of the QSPI memory.
00467   * @param  pInfo: pointer on the configuration structure  
00468   * @retval QSPI memory status
00469   */
00470 uint8_t BSP_QSPI_GetInfo(QSPI_Info* pInfo)
00471 {
00472   /* Configure the structure with the memory configuration */
00473   pInfo->FlashSize          = MX25L512_FLASH_SIZE;
00474   pInfo->EraseSectorSize    = MX25L512_SUBSECTOR_SIZE;
00475   pInfo->EraseSectorsNumber = (MX25L512_FLASH_SIZE/MX25L512_SUBSECTOR_SIZE);
00476   pInfo->ProgPageSize       = MX25L512_PAGE_SIZE;
00477   pInfo->ProgPagesNumber    = (MX25L512_FLASH_SIZE/MX25L512_PAGE_SIZE);
00478   
00479   return QSPI_OK;
00480 }
00481 
00482 /**
00483   * @brief  Configure the QSPI in memory-mapped mode
00484   * @retval QSPI memory status
00485   */
00486 uint8_t BSP_QSPI_EnableMemoryMappedMode(void)
00487 {
00488   QSPI_CommandTypeDef      s_command;
00489   QSPI_MemoryMappedTypeDef s_mem_mapped_cfg;
00490 
00491   /* Configure the command for the read instruction */
00492   s_command.InstructionMode   = QSPI_INSTRUCTION_4_LINES;
00493   s_command.Instruction       = QSPI_READ_4_BYTE_ADDR_CMD;
00494   s_command.AddressMode       = QSPI_ADDRESS_4_LINES;
00495   s_command.AddressSize       = QSPI_ADDRESS_32_BITS;
00496   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00497   s_command.DataMode          = QSPI_DATA_4_LINES;
00498   s_command.DummyCycles       = MX25L512_DUMMY_CYCLES_READ_QUAD_IO;
00499   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00500   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00501   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00502   
00503   /* Configure the memory mapped mode */
00504   s_mem_mapped_cfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE;
00505   s_mem_mapped_cfg.TimeOutPeriod     = 0;
00506   
00507   if (HAL_QSPI_MemoryMapped(&QSPIHandle, &s_command, &s_mem_mapped_cfg) != HAL_OK)
00508   {
00509     return QSPI_ERROR;
00510   }
00511 
00512   return QSPI_OK;
00513 }
00514 
00515 /**
00516   * @}
00517   */
00518 
00519 /** @addtogroup STM32F723E_DISCOVERY_QSPI_Private_Functions
00520   * @{
00521   */ 
00522 
00523 /**
00524   * @brief QSPI MSP Initialization
00525   *        This function configures the hardware resources used in this example:
00526   *           - Peripheral's clock enable
00527   *           - Peripheral's GPIO Configuration
00528   *           - NVIC configuration for QSPI interrupt
00529   * @retval None
00530   */
00531 __weak void BSP_QSPI_MspInit(QSPI_HandleTypeDef *hqspi, void *Params)
00532 {
00533   GPIO_InitTypeDef gpio_init_structure;
00534 
00535   /*##-1- Enable peripherals and GPIO Clocks #################################*/
00536   /* Enable the QuadSPI memory interface clock */
00537   QSPI_CLK_ENABLE();
00538   /* Reset the QuadSPI memory interface */
00539   QSPI_FORCE_RESET();
00540   QSPI_RELEASE_RESET();
00541   /* Enable GPIO clocks */
00542   QSPI_CS_GPIO_CLK_ENABLE();
00543   QSPI_CLK_GPIO_CLK_ENABLE();
00544   QSPI_D0_GPIO_CLK_ENABLE();
00545   QSPI_D1_GPIO_CLK_ENABLE();
00546   QSPI_D2_GPIO_CLK_ENABLE();
00547   QSPI_D3_GPIO_CLK_ENABLE();
00548 
00549   /*##-2- Configure peripheral GPIO ##########################################*/
00550   /* QSPI CS GPIO pin configuration  */
00551   gpio_init_structure.Pin       = QSPI_CS_PIN;
00552   gpio_init_structure.Alternate = QSPI_CS_PIN_AF;
00553   gpio_init_structure.Mode      = GPIO_MODE_AF_PP;
00554   gpio_init_structure.Pull      = GPIO_PULLUP;
00555   gpio_init_structure.Speed     = GPIO_SPEED_FREQ_HIGH;
00556   HAL_GPIO_Init(QSPI_CS_GPIO_PORT, &gpio_init_structure);
00557   /* QSPI CLK GPIO pin configuration  */
00558   gpio_init_structure.Pin       = QSPI_CLK_PIN;
00559   gpio_init_structure.Alternate = QSPI_CLK_PIN_AF;
00560   gpio_init_structure.Pull      = GPIO_NOPULL;
00561   HAL_GPIO_Init(QSPI_CLK_GPIO_PORT, &gpio_init_structure);
00562   /* QSPI D0 GPIO pin configuration  */
00563   gpio_init_structure.Pin       = QSPI_D0_PIN;
00564   gpio_init_structure.Alternate = QSPI_D0_PIN_AF;
00565   HAL_GPIO_Init(QSPI_D0_GPIO_PORT, &gpio_init_structure);
00566   /* QSPI D1 GPIO pin configuration  */
00567   gpio_init_structure.Pin       = QSPI_D1_PIN;
00568   gpio_init_structure.Alternate = QSPI_D1_PIN_AF;
00569   HAL_GPIO_Init(QSPI_D1_GPIO_PORT, &gpio_init_structure);
00570   /* QSPI D2 GPIO pin configuration  */
00571   gpio_init_structure.Pin       = QSPI_D2_PIN;
00572   gpio_init_structure.Alternate = QSPI_D2_PIN_AF;
00573   HAL_GPIO_Init(QSPI_D2_GPIO_PORT, &gpio_init_structure);
00574   /* QSPI D3 GPIO pin configuration  */
00575   gpio_init_structure.Pin       = QSPI_D3_PIN;
00576   gpio_init_structure.Alternate = QSPI_D3_PIN_AF;
00577   HAL_GPIO_Init(QSPI_D3_GPIO_PORT, &gpio_init_structure);
00578 
00579   /*##-3- Configure the NVIC for QSPI #########################################*/
00580   /* NVIC configuration for QSPI interrupt */
00581   HAL_NVIC_SetPriority(QUADSPI_IRQn, 0x0F, 0);
00582   HAL_NVIC_EnableIRQ(QUADSPI_IRQn);
00583 }
00584 
00585 /**
00586   * @brief QSPI MSP De-Initialization
00587   *        This function frees the hardware resources used in this example:
00588   *          - Disable the Peripheral's clock
00589   *          - Revert GPIO and NVIC configuration to their default state
00590   * @retval None
00591   */
00592 __weak void BSP_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi, void *Params)
00593 {
00594   /*##-1- Disable the NVIC for QSPI ###########################################*/
00595   HAL_NVIC_DisableIRQ(QUADSPI_IRQn);
00596 
00597   /*##-2- Disable peripherals and GPIO Clocks ################################*/
00598   /* De-Configure QSPI pins */
00599   HAL_GPIO_DeInit(QSPI_CS_GPIO_PORT, QSPI_CS_PIN);
00600   HAL_GPIO_DeInit(QSPI_CLK_GPIO_PORT, QSPI_CLK_PIN);
00601   HAL_GPIO_DeInit(QSPI_D0_GPIO_PORT, QSPI_D0_PIN);
00602   HAL_GPIO_DeInit(QSPI_D1_GPIO_PORT, QSPI_D1_PIN);
00603   HAL_GPIO_DeInit(QSPI_D2_GPIO_PORT, QSPI_D2_PIN);
00604   HAL_GPIO_DeInit(QSPI_D3_GPIO_PORT, QSPI_D3_PIN);
00605 
00606   /*##-3- Reset peripherals ##################################################*/
00607   /* Reset the QuadSPI memory interface */
00608   QSPI_FORCE_RESET();
00609   QSPI_RELEASE_RESET();
00610 
00611   /* Disable the QuadSPI memory interface clock */
00612   QSPI_CLK_DISABLE();
00613 }
00614 
00615 /**
00616   * @brief  This function reset the QSPI memory.
00617   * @param  hqspi: QSPI handle
00618   * @retval None
00619   */
00620 static uint8_t QSPI_ResetMemory(QSPI_HandleTypeDef *hqspi)
00621 {
00622   QSPI_CommandTypeDef      s_command;
00623   QSPI_AutoPollingTypeDef  s_config;
00624   uint8_t                  reg;
00625 
00626   /* Send command RESET command in QPI mode (QUAD I/Os) */
00627   /* Initialize the reset enable command */
00628   s_command.InstructionMode   = QSPI_INSTRUCTION_4_LINES;
00629   s_command.Instruction       = RESET_ENABLE_CMD;
00630   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00631   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00632   s_command.DataMode          = QSPI_DATA_NONE;
00633   s_command.DummyCycles       = 0;
00634   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00635   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00636   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00637   /* Send the command */
00638   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00639   {
00640     return QSPI_ERROR;
00641   }
00642   /* Send the reset memory command */
00643   s_command.Instruction = RESET_MEMORY_CMD;
00644   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00645   {
00646     return QSPI_ERROR;
00647   }  
00648 
00649   /* Send command RESET command in SPI mode */
00650   /* Initialize the reset enable command */
00651   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00652   s_command.Instruction       = RESET_ENABLE_CMD;
00653   /* Send the command */
00654   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00655   {
00656     return QSPI_ERROR;
00657   }
00658   /* Send the reset memory command */
00659   s_command.Instruction = RESET_MEMORY_CMD;
00660   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00661   {
00662     return QSPI_ERROR;
00663   }
00664 
00665   /* After reset CMD, 1000ms requested if QSPI memory SWReset occured during full chip erase operation */
00666   HAL_Delay( 1000 );
00667 
00668   /* Configure automatic polling mode to wait the WIP bit=0 */
00669   s_config.Match           = 0;
00670   s_config.Mask            = MX25L512_SR_WIP;
00671   s_config.MatchMode       = QSPI_MATCH_MODE_AND;
00672   s_config.StatusBytesSize = 1;
00673   s_config.Interval        = 0x10;
00674   s_config.AutomaticStop   = QSPI_AUTOMATIC_STOP_ENABLE;
00675 
00676   s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
00677   s_command.Instruction     = READ_STATUS_REG_CMD;
00678   s_command.DataMode        = QSPI_DATA_1_LINE;
00679 
00680   if (HAL_QSPI_AutoPolling(hqspi, &s_command, &s_config, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00681   {
00682     return QSPI_ERROR;
00683   }
00684 
00685   /* Initialize the reading of status register */
00686   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00687   s_command.Instruction       = READ_STATUS_REG_CMD;
00688   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00689   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00690   s_command.DataMode          = QSPI_DATA_1_LINE;
00691   s_command.DummyCycles       = 0;
00692   s_command.NbData            = 1;
00693   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00694   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00695   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00696 
00697   /* Configure the command */
00698   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00699   {
00700     return QSPI_ERROR;
00701   }
00702 
00703   /* Reception of the data */
00704   if (HAL_QSPI_Receive(hqspi, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00705   {
00706     return QSPI_ERROR;
00707   }
00708 
00709   /* Enable write operations, command in 1 bit */
00710   /* Enable write operations */
00711   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00712   s_command.Instruction       = WRITE_ENABLE_CMD;
00713   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00714   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00715   s_command.DataMode          = QSPI_DATA_NONE;
00716   s_command.DummyCycles       = 0;
00717   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00718   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00719   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00720 
00721   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00722   {
00723     return QSPI_ERROR;
00724   }
00725   
00726   /* Configure automatic polling mode to wait for write enabling */  
00727   s_config.Match           = MX25L512_SR_WREN;
00728   s_config.Mask            = MX25L512_SR_WREN;
00729   s_config.MatchMode       = QSPI_MATCH_MODE_AND;
00730   s_config.StatusBytesSize = 1;
00731   s_config.Interval        = 0x10;
00732   s_config.AutomaticStop   = QSPI_AUTOMATIC_STOP_ENABLE;
00733 
00734   s_command.Instruction    = READ_STATUS_REG_CMD;
00735   s_command.DataMode       = QSPI_DATA_1_LINE;
00736 
00737   if (HAL_QSPI_AutoPolling(hqspi, &s_command, &s_config, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00738   {
00739     return QSPI_ERROR;
00740   }
00741 
00742   /* Update the configuration register with new dummy cycles */
00743   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00744   s_command.Instruction       = WRITE_STATUS_CFG_REG_CMD;
00745   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00746   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00747   s_command.DataMode          = QSPI_DATA_1_LINE;
00748   s_command.DummyCycles       = 0;
00749   s_command.NbData            = 1;
00750   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00751   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00752   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00753 
00754   /* Enable the Quad IO on the QSPI memory (Non-volatile bit) */
00755   reg |= MX25L512_SR_QUADEN;
00756 
00757   /* Configure the command */
00758   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00759   {
00760     return QSPI_ERROR;
00761   }
00762   
00763   /* Transmission of the data */
00764   if (HAL_QSPI_Transmit(hqspi, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00765   {
00766     return QSPI_ERROR;
00767   }
00768   
00769   /* 40ms  Write Status/Configuration Register Cycle Time */
00770   HAL_Delay( 40 );  
00771 
00772   return QSPI_OK;
00773 }
00774 
00775 /**
00776   * @brief  This function set the QSPI memory in 4-byte address mode
00777   * @param  hqspi: QSPI handle
00778   * @retval None
00779   */
00780 static uint8_t QSPI_EnterFourBytesAddress(QSPI_HandleTypeDef *hqspi)
00781 {
00782   QSPI_CommandTypeDef s_command;
00783 
00784   /* Initialize the command */
00785   s_command.InstructionMode   = QSPI_INSTRUCTION_4_LINES;
00786   s_command.Instruction       = ENTER_4_BYTE_ADDR_MODE_CMD;
00787   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00788   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00789   s_command.DataMode          = QSPI_DATA_NONE;
00790   s_command.DummyCycles       = 0;
00791   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00792   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00793   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00794 
00795   /* Enable write operations */
00796   if (QSPI_WriteEnable(hqspi) != QSPI_OK)
00797   {
00798     return QSPI_ERROR;
00799   }
00800 
00801   /* Send the command */
00802   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00803   {
00804     return QSPI_ERROR;
00805   }
00806 
00807   /* Configure automatic polling mode to wait the memory is ready */  
00808   if (QSPI_AutoPollingMemReady(hqspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
00809   {
00810     return QSPI_ERROR;
00811   }
00812 
00813   return QSPI_OK;
00814 }
00815 
00816 /**
00817   * @brief  This function configure the dummy cycles on memory side.
00818   * @param  hqspi: QSPI handle
00819   * @retval None
00820   */
00821 static uint8_t QSPI_DummyCyclesCfg(QSPI_HandleTypeDef *hqspi)
00822 {
00823   QSPI_CommandTypeDef s_command;
00824   uint8_t reg[2];
00825   
00826   /* Initialize the reading of status register */
00827   s_command.InstructionMode   = QSPI_INSTRUCTION_4_LINES;
00828   s_command.Instruction       = READ_STATUS_REG_CMD;
00829   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00830   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00831   s_command.DataMode          = QSPI_DATA_4_LINES;
00832   s_command.DummyCycles       = 0;
00833   s_command.NbData            = 1;
00834   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00835   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00836   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00837   
00838   /* Configure the command */
00839   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00840   {
00841     return QSPI_ERROR;
00842   }
00843   
00844   /* Reception of the data */
00845   if (HAL_QSPI_Receive(hqspi, &(reg[0]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00846   {
00847     return QSPI_ERROR;
00848   }
00849   
00850   /* Initialize the reading of configuration register */
00851   s_command.InstructionMode   = QSPI_INSTRUCTION_4_LINES;
00852   s_command.Instruction       = READ_CFG_REG_CMD;
00853   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00854   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00855   s_command.DataMode          = QSPI_DATA_4_LINES;
00856   s_command.DummyCycles       = 0;
00857   s_command.NbData            = 1;
00858   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00859   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00860   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00861   
00862   /* Configure the command */
00863   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00864   {
00865     return QSPI_ERROR;
00866   }
00867   
00868   /* Reception of the data */
00869   if (HAL_QSPI_Receive(hqspi, &(reg[1]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00870   {
00871     return QSPI_ERROR;
00872   }
00873   
00874   /* Enable write operations */
00875   if (QSPI_WriteEnable(hqspi) != QSPI_OK)
00876   {
00877     return QSPI_ERROR;
00878   }
00879   
00880   /* Update the configuration register with new dummy cycles */
00881   s_command.InstructionMode   = QSPI_INSTRUCTION_4_LINES;
00882   s_command.Instruction       = WRITE_STATUS_CFG_REG_CMD;
00883   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00884   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00885   s_command.DataMode          = QSPI_DATA_4_LINES;
00886   s_command.DummyCycles       = 0;
00887   s_command.NbData            = 2;
00888   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00889   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00890   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00891   
00892   /* MX25L512_DUMMY_CYCLES_READ_QUAD = 3 for 10 cycles in QPI mode */
00893   MODIFY_REG( reg[1], MX25L512_CR_NB_DUMMY, (MX25L512_DUMMY_CYCLES_READ_QUAD << POSITION_VAL(MX25L512_CR_NB_DUMMY)));
00894   
00895   /* Configure the write volatile configuration register command */
00896   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00897   {
00898     return QSPI_ERROR;
00899   }
00900   
00901   /* Transmission of the data */
00902   if (HAL_QSPI_Transmit(hqspi, &(reg[0]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00903   {
00904     return QSPI_ERROR;
00905   }
00906   
00907   /* 40ms  Write Status/Configuration Register Cycle Time */
00908   HAL_Delay( 40 );  
00909   
00910   return QSPI_OK;
00911 }
00912 
00913 /**
00914   * @brief  This function put QSPI memory in QPI mode (quad I/O).
00915   * @param  hqspi: QSPI handle
00916   * @retval None
00917   */
00918 static uint8_t QSPI_EnterMemory_QPI( QSPI_HandleTypeDef *hqspi )
00919 {
00920   QSPI_CommandTypeDef      s_command;
00921   QSPI_AutoPollingTypeDef  s_config;
00922 
00923   /* Initialize the QPI enable command */
00924   /* QSPI memory is supported to be in SPI mode, so CMD on 1 LINE */
00925   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;  
00926   s_command.Instruction       = ENTER_QUAD_CMD;
00927   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00928   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00929   s_command.DataMode          = QSPI_DATA_NONE;
00930   s_command.DummyCycles       = 0;
00931   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00932   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00933   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00934 
00935   /* Send the command */
00936   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00937   {
00938     return QSPI_ERROR;
00939   }
00940 
00941   /* Configure automatic polling mode to wait the QUADEN bit=1 and WIP bit=0 */
00942   s_config.Match           = MX25L512_SR_QUADEN;
00943   s_config.Mask            = MX25L512_SR_QUADEN|MX25L512_SR_WIP;
00944   s_config.MatchMode       = QSPI_MATCH_MODE_AND;
00945   s_config.StatusBytesSize = 1;
00946   s_config.Interval        = 0x10;
00947   s_config.AutomaticStop   = QSPI_AUTOMATIC_STOP_ENABLE;
00948 
00949   s_command.InstructionMode   = QSPI_INSTRUCTION_4_LINES;
00950   s_command.Instruction       = READ_STATUS_REG_CMD;
00951   s_command.DataMode          = QSPI_DATA_4_LINES;
00952 
00953   if (HAL_QSPI_AutoPolling(hqspi, &s_command, &s_config, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00954   {
00955     return QSPI_ERROR;
00956   }
00957 
00958   return QSPI_OK;
00959 }
00960 
00961 /**
00962   * @brief  This function put QSPI memory in SPI mode.
00963   * @param  hqspi: QSPI handle
00964   * @retval None
00965   */
00966 static uint8_t QSPI_ExitMemory_QPI( QSPI_HandleTypeDef *hqspi)
00967 {
00968   QSPI_CommandTypeDef      s_command;
00969 
00970   /* Initialize the QPI enable command */
00971   /* QSPI memory is supported to be in QPI mode, so CMD on 4 LINES */
00972   s_command.InstructionMode   = QSPI_INSTRUCTION_4_LINES;  
00973   s_command.Instruction       = EXIT_QUAD_CMD;
00974   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00975   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00976   s_command.DataMode          = QSPI_DATA_NONE;
00977   s_command.DummyCycles       = 0;
00978   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00979   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00980   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00981 
00982   /* Send the command */
00983   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00984   {
00985     return QSPI_ERROR;
00986   }
00987 
00988   return QSPI_OK;
00989 }
00990 
00991 /**
00992   * @brief  This function configure the Output driver strength on memory side.
00993   * @param  hqspi: QSPI handle
00994   * @retval None
00995   */
00996 static uint8_t QSPI_OutDrvStrengthCfg( QSPI_HandleTypeDef *hqspi )
00997 {
00998   QSPI_CommandTypeDef s_command;
00999   uint8_t reg[2];
01000 
01001   /* Initialize the reading of status register */
01002   s_command.InstructionMode   = QSPI_INSTRUCTION_4_LINES;
01003   s_command.Instruction       = READ_STATUS_REG_CMD;
01004   s_command.AddressMode       = QSPI_ADDRESS_NONE;
01005   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
01006   s_command.DataMode          = QSPI_DATA_4_LINES;
01007   s_command.DummyCycles       = 0;
01008   s_command.NbData            = 1;
01009   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
01010   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
01011   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
01012 
01013   /* Configure the command */
01014   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
01015   {
01016     return QSPI_ERROR;
01017   }
01018 
01019   /* Reception of the data */
01020   if (HAL_QSPI_Receive(hqspi, &(reg[0]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
01021   {
01022     return QSPI_ERROR;
01023   }
01024 
01025   /* Initialize the reading of configuration register */
01026   s_command.InstructionMode   = QSPI_INSTRUCTION_4_LINES;
01027   s_command.Instruction       = READ_CFG_REG_CMD;
01028   s_command.AddressMode       = QSPI_ADDRESS_NONE;
01029   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
01030   s_command.DataMode          = QSPI_DATA_4_LINES;
01031   s_command.DummyCycles       = 0;
01032   s_command.NbData            = 1;
01033   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
01034   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
01035   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
01036 
01037   /* Configure the command */
01038   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
01039   {
01040     return QSPI_ERROR;
01041   }
01042 
01043   /* Reception of the data */
01044   if (HAL_QSPI_Receive(hqspi, &(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   /* Update the configuration register with new output driver strength */
01056   s_command.InstructionMode   = QSPI_INSTRUCTION_4_LINES;
01057   s_command.Instruction       = WRITE_STATUS_CFG_REG_CMD;
01058   s_command.AddressMode       = QSPI_ADDRESS_NONE;
01059   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
01060   s_command.DataMode          = QSPI_DATA_4_LINES;
01061   s_command.DummyCycles       = 0;
01062   s_command.NbData            = 2;
01063   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
01064   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
01065   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
01066 
01067   /* Set Output Strength of the QSPI memory 15 ohms */
01068   MODIFY_REG( reg[1], MX25L512_CR_ODS, (MX25L512_CR_ODS_15 << POSITION_VAL(MX25L512_CR_ODS)));
01069 
01070   /* Configure the write volatile configuration register command */
01071   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
01072   {
01073     return QSPI_ERROR;
01074   }
01075 
01076   /* Transmission of the data */
01077   if (HAL_QSPI_Transmit(hqspi, &(reg[0]), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
01078   {
01079     return QSPI_ERROR;
01080   }
01081 
01082   return QSPI_OK;
01083 }
01084 
01085 /**
01086   * @brief  This function send a Write Enable and wait it is effective.
01087   * @param  hqspi: QSPI handle
01088   * @retval None
01089   */
01090 static uint8_t QSPI_WriteEnable(QSPI_HandleTypeDef *hqspi)
01091 {
01092   QSPI_CommandTypeDef     s_command;
01093   QSPI_AutoPollingTypeDef s_config;
01094   
01095   /* Enable write operations */
01096   s_command.InstructionMode   = QSPI_INSTRUCTION_4_LINES;
01097   s_command.Instruction       = WRITE_ENABLE_CMD;
01098   s_command.AddressMode       = QSPI_ADDRESS_NONE;
01099   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
01100   s_command.DataMode          = QSPI_DATA_NONE;
01101   s_command.DummyCycles       = 0;
01102   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
01103   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
01104   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
01105   
01106   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
01107   {
01108     return QSPI_ERROR;
01109   }
01110   
01111   /* Configure automatic polling mode to wait for write enabling */  
01112   s_config.Match           = MX25L512_SR_WREN;
01113   s_config.Mask            = MX25L512_SR_WREN;
01114   s_config.MatchMode       = QSPI_MATCH_MODE_AND;
01115   s_config.StatusBytesSize = 1;
01116   s_config.Interval        = 0x10;
01117   s_config.AutomaticStop   = QSPI_AUTOMATIC_STOP_ENABLE;
01118   
01119   s_command.Instruction    = READ_STATUS_REG_CMD;
01120   s_command.DataMode       = QSPI_DATA_4_LINES;
01121   
01122   if (HAL_QSPI_AutoPolling(hqspi, &s_command, &s_config, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
01123   {
01124     return QSPI_ERROR;
01125   }
01126   
01127   return QSPI_OK;
01128 }
01129 
01130 /**
01131   * @brief  This function read the SR of the memory and wait the EOP.
01132   * @param  hqspi: QSPI handle
01133   * @param  Timeout
01134   * @retval None
01135   */
01136 static uint8_t QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi, uint32_t Timeout)
01137 {
01138   QSPI_CommandTypeDef     s_command;
01139   QSPI_AutoPollingTypeDef s_config;
01140 
01141   /* Configure automatic polling mode to wait for memory ready */  
01142   s_command.InstructionMode   = QSPI_INSTRUCTION_4_LINES;
01143   s_command.Instruction       = READ_STATUS_REG_CMD;
01144   s_command.AddressMode       = QSPI_ADDRESS_NONE;
01145   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
01146   s_command.DataMode          = QSPI_DATA_4_LINES;
01147   s_command.DummyCycles       = 0;
01148   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
01149   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
01150   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
01151 
01152   s_config.Match           = 0;
01153   s_config.Mask            = MX25L512_SR_WIP;
01154   s_config.MatchMode       = QSPI_MATCH_MODE_AND;
01155   s_config.StatusBytesSize = 1;
01156   s_config.Interval        = 0x10;
01157   s_config.AutomaticStop   = QSPI_AUTOMATIC_STOP_ENABLE;
01158 
01159   if (HAL_QSPI_AutoPolling(hqspi, &s_command, &s_config, Timeout) != HAL_OK)
01160   {
01161     return QSPI_ERROR;
01162   }
01163 
01164   return QSPI_OK;
01165 }
01166 /**
01167   * @}
01168   */  
01169   
01170 /**
01171   * @}
01172   */ 
01173   
01174 /**
01175   * @}
01176   */ 
01177   
01178 /**
01179   * @}
01180   */ 
01181 
01182 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Tue May 30 2017 13:59:12 for STM32F723E-Discovery BSP User Manual by   doxygen 1.7.6.1