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

STM32F723E-Discovery BSP Drivers

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