STM32469I_EVAL BSP User Manual: stm32469i_eval_qspi.c Source File

STM32469I EVAL BSP Drivers

stm32469i_eval_qspi.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32469i_eval_qspi.c
00004   * @author  MCD Application Team
00005   * @version V1.0.2
00006   * @date    12-January-2016
00007   * @brief   This file includes a standard driver for the N25Q256A QSPI 
00008   *          memory mounted on STM32469I-EVAL board.
00009   @verbatim
00010   ==============================================================================
00011                      ##### How to use this driver #####
00012   ==============================================================================  
00013   [..]
00014    (#) This driver is used to drive the S25FL512SAGMFI01 and N25Q512A QSPI external 
00015        memory mounted on STM32469I-EVAL evaluation board.
00016        
00017    (#) This driver need a specific component driver (FL512SAGMFI01 and N25Q512A) 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) 2015 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 "stm32469i_eval_qspi.h"
00069 
00070 /** @addtogroup BSP
00071   * @{
00072   */
00073 
00074 /** @addtogroup STM32469I_EVAL
00075   * @{
00076   */ 
00077   
00078 /** @defgroup STM32469I_EVAL_QSPI STM32469I EVAL QSPI
00079   * @{
00080   */ 
00081 
00082 
00083 /* Private variables ---------------------------------------------------------*/
00084 #define JEDEC_MANUF_ID_MICRON   ((uint8_t) 0x20)
00085 #define JEDEC_MANUF_ID_SPANSION ((uint8_t) 0x01)
00086 /** @defgroup STM32469I_EVAL_QSPI_Private_Variables Private Variables
00087   * @{
00088   */       
00089 QSPI_HandleTypeDef QSPIHandle;
00090 QSPI_InfoTypeDef QspiInfo;
00091 
00092 /**
00093   * @}
00094   */ 
00095 
00096 
00097 
00098 /* Private functions ---------------------------------------------------------*/
00099     
00100 /** @defgroup STM32469I_EVAL_QSPI_Private_Functions STM32469I EVAL QSPI Private Functions
00101   * @{
00102   */ 
00103 static uint8_t QSPI_ResetMemory          (QSPI_HandleTypeDef *hqspi);
00104 static uint8_t QSPI_EnterFourBytesAddress(QSPI_HandleTypeDef *hqspi);
00105 static uint8_t QSPI_DummyCyclesCfg       (QSPI_HandleTypeDef *hqspi);
00106 static uint8_t QSPI_WriteEnable          (QSPI_HandleTypeDef *hqspi);
00107 static uint8_t QSPI_AutoPollingMemReady  (QSPI_HandleTypeDef *hqspi, uint32_t Timeout);
00108 static uint8_t QSPI_ReadID               (QSPI_InfoTypeDef *pqspi_info);
00109 
00110 /**
00111   * @}
00112   */
00113     
00114 /** @defgroup STM32469I_EVAL_QSPI_Exported_Functions STM32469I EVAL 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   /* Init typedef is the same for both S25FL512S and N25Q512A memories, as they have the same FLASH size */
00137   QSPIHandle.Init.ClockPrescaler     = 1; /* QSPI Freq= 180 MHz / (1+1) = 90 MHz */
00138   QSPIHandle.Init.FifoThreshold      = 1;
00139   QSPIHandle.Init.SampleShifting     = QSPI_SAMPLE_SHIFTING_HALFCYCLE;
00140   QSPIHandle.Init.FlashSize          = POSITION_VAL(S25FL512S_FLASH_SIZE) - 1; /* same size on both memory types */
00141   QSPIHandle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_2_CYCLE;
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   /* Detect the memory ID */
00152   if (QSPI_ReadID(&QspiInfo) != QSPI_OK)
00153   {
00154     return QSPI_NOT_SUPPORTED;
00155   }
00156   
00157   /* QSPI memory reset */
00158   if (QSPI_ResetMemory(&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 cucles on QSPI memory side */
00170   if (QSPI_DummyCyclesCfg(&QSPIHandle) != QSPI_OK)
00171   {
00172     return QSPI_NOT_SUPPORTED;
00173   }
00174 
00175   return QSPI_OK;
00176 }
00177 
00178 /**
00179   * @brief  De-Initializes the QSPI interface.
00180   * @retval QSPI memory status
00181   */
00182 uint8_t BSP_QSPI_DeInit(void)
00183 { 
00184   QSPIHandle.Instance = QUADSPI;
00185 
00186   /* Call the DeInit function to reset the driver */
00187   if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK)
00188   {
00189     return QSPI_ERROR;
00190   }
00191         
00192   /* System level De-initialization */
00193   BSP_QSPI_MspDeInit(&QSPIHandle, NULL);
00194   
00195   return QSPI_OK;
00196 }
00197 
00198 /**
00199   * @brief  Reads an amount of data from the QSPI memory.
00200   * @param  pData: Pointer to data to be read
00201   * @param  ReadAddr: Read start address
00202   * @param  Size: Size of data to read    
00203   * @retval QSPI memory status
00204   */
00205 uint8_t BSP_QSPI_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size)
00206 {
00207   QSPI_CommandTypeDef s_command;
00208 
00209   /* Initialize the read command */
00210   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00211   s_command.Instruction       = QUAD_OUT_FAST_READ_CMD; /* same value on both memory types */
00212   s_command.AddressMode       = QSPI_ADDRESS_1_LINE;
00213   s_command.AddressSize       = QSPI_ADDRESS_32_BITS;
00214   s_command.Address           = ReadAddr;
00215   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00216   s_command.DataMode          = QSPI_DATA_4_LINES;
00217   s_command.DummyCycles       = QspiInfo.DummyCyclesRead;
00218   s_command.NbData            = Size;
00219   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00220   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00221   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00222   
00223   /* Configure the command */
00224   if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00225   {
00226     return QSPI_ERROR;
00227   }
00228   
00229   /* Reception of the data */
00230   if (HAL_QSPI_Receive(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00231   {
00232     return QSPI_ERROR;
00233   }
00234 
00235   return QSPI_OK;
00236 }
00237 
00238 /**
00239   * @brief  Writes an amount of data to the QSPI memory.
00240   * @param  pData: Pointer to data to be written
00241   * @param  WriteAddr: Write start address
00242   * @param  Size: Size of data to write    
00243   * @retval QSPI memory status
00244   */
00245 uint8_t BSP_QSPI_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size)
00246 {
00247   QSPI_CommandTypeDef s_command;
00248   uint32_t end_addr, current_size, current_addr;
00249   
00250   /* Calculation of the size between the write address and the end of the page */
00251   current_addr = 0;
00252 
00253   while (current_addr <= WriteAddr)
00254   {
00255     current_addr += QspiInfo.ProgPageSize;
00256   }
00257   current_size = current_addr - WriteAddr;
00258 
00259   /* Check if the size of the data is less than the remaining place in the page */
00260   if (current_size > Size)
00261   {
00262     current_size = Size;
00263   }
00264 
00265   /* Initialize the adress variables */
00266   current_addr = WriteAddr;
00267   end_addr = WriteAddr + Size;
00268 
00269   /* Initialize the program command */
00270   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00271   s_command.Instruction       = QUAD_IN_FAST_PROG_CMD; /* same value on both memory types */
00272   s_command.AddressMode       = QSPI_ADDRESS_1_LINE;
00273   s_command.AddressSize       = QSPI_ADDRESS_32_BITS;
00274   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00275   s_command.DataMode          = QSPI_DATA_4_LINES;
00276   s_command.DummyCycles       = 0;
00277   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00278   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00279   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00280   
00281   /* Perform the write page by page */
00282   do
00283   {
00284     s_command.Address = current_addr;
00285     s_command.NbData  = current_size;
00286 
00287     /* Enable write operations */
00288     if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
00289     {
00290       return QSPI_ERROR;
00291     }
00292     
00293     /* Configure the command */
00294     if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00295     {
00296       return QSPI_ERROR;
00297     }
00298     
00299     /* Transmission of the data */
00300     if (HAL_QSPI_Transmit(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00301     {
00302       return QSPI_ERROR;
00303     }
00304     
00305     /* Configure automatic polling mode to wait for end of program */  
00306     if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
00307     {
00308       return QSPI_ERROR;
00309     }
00310     
00311     /* Update the address and size variables for next page programming */
00312     current_addr += current_size;
00313     pData += current_size;
00314     current_size = ((current_addr + QspiInfo.ProgPageSize) > end_addr) ? (end_addr - current_addr) : QspiInfo.ProgPageSize;
00315   } while (current_addr < end_addr);
00316   
00317   return QSPI_OK;
00318 }
00319 
00320 /**
00321   * @brief  Erases the specified block of the QSPI memory. 
00322   * @param  BlockAddress: Block address to erase  
00323   * @retval QSPI memory status
00324   */
00325 uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress)
00326 {
00327   QSPI_CommandTypeDef s_command;
00328 
00329   /* Initialize the erase command */
00330   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00331   s_command.Instruction       = SECTOR_ERASE_CMD; /* same value on both memory types */
00332   s_command.AddressMode       = QSPI_ADDRESS_1_LINE;
00333   s_command.AddressSize       = QSPI_ADDRESS_32_BITS;
00334   s_command.Address           = BlockAddress;
00335   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00336   s_command.DataMode          = QSPI_DATA_NONE;
00337   s_command.DummyCycles       = 0;
00338   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00339   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00340   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00341 
00342   /* Enable write operations */
00343   if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
00344   {
00345     return QSPI_ERROR;
00346   }
00347 
00348   /* Send the command */
00349   if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00350   {
00351     return QSPI_ERROR;
00352   }
00353   
00354   /* Configure automatic polling mode to wait for end of erase */  
00355   if (QSPI_AutoPollingMemReady(&QSPIHandle, QspiInfo.SectorEraseMaxTime) != QSPI_OK)
00356   {
00357     return QSPI_ERROR;
00358   }
00359 
00360   return QSPI_OK;
00361 }
00362 
00363 /**
00364   * @brief  Erases the entire QSPI memory.
00365   * @retval QSPI memory status
00366   */
00367 uint8_t BSP_QSPI_Erase_Chip(void)
00368 {
00369   QSPI_CommandTypeDef s_command;
00370 
00371   /* Initialize the erase command */
00372   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00373   s_command.Instruction       = BULK_ERASE_CMD; /* same value on both memory types */
00374   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00375   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00376   s_command.DataMode          = QSPI_DATA_NONE;
00377   s_command.DummyCycles       = 0;
00378   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00379   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00380   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00381 
00382   /* Enable write operations */
00383   if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
00384   {
00385     return QSPI_ERROR;
00386   }
00387 
00388   /* Send the command */
00389   if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00390   {
00391     return QSPI_ERROR;
00392   }
00393   
00394   /* Configure automatic polling mode to wait for end of erase */  
00395   if (QSPI_AutoPollingMemReady(&QSPIHandle, QspiInfo.BulkEraseMaxTime) != QSPI_OK)
00396   {
00397     return QSPI_ERROR;
00398   }
00399 
00400   return QSPI_OK;
00401 }
00402 
00403 /**
00404   * @brief  Reads current status of the QSPI memory.
00405   * @retval QSPI memory status
00406   */
00407 uint8_t BSP_QSPI_GetStatus(void)
00408 {
00409   QSPI_CommandTypeDef s_command;
00410   uint8_t reg1, reg2;
00411 
00412   if (QspiInfo.ManufID == QSPI_N25Q512A)
00413   {
00414     /* Initialize the read flag status register command */
00415     s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00416     s_command.Instruction       = READ_FLAG_STATUS_REG_CMD; /* same value on both memory types */
00417     s_command.AddressMode       = QSPI_ADDRESS_NONE;
00418     s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00419     s_command.DataMode          = QSPI_DATA_1_LINE;
00420     s_command.DummyCycles       = 0;
00421     s_command.NbData            = 1;
00422     s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00423     s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00424     s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00425 
00426     /* Configure the command */
00427     if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00428     {
00429       return QSPI_ERROR;
00430     }
00431 
00432     /* Reception of the data */
00433     if (HAL_QSPI_Receive(&QSPIHandle, &reg1, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00434     {
00435       return QSPI_ERROR;
00436     }
00437 
00438     /* Check the value of the register */
00439     if ((reg1 & (N25Q512A_FSR_PRERR | N25Q512A_FSR_VPPERR | N25Q512A_FSR_PGERR | N25Q512A_FSR_ERERR)) != 0)
00440     {
00441       return QSPI_ERROR;
00442     }
00443     else if ((reg1 & (N25Q512A_FSR_PGSUS | N25Q512A_FSR_ERSUS)) != 0)
00444     {
00445       return QSPI_SUSPENDED;
00446     }
00447     else if ((reg1 & N25Q512A_FSR_READY) != 0)
00448     {
00449       return QSPI_OK;
00450     }
00451     else
00452     {
00453       return QSPI_BUSY;
00454     }
00455   }
00456   else
00457   {
00458     /* Initialize the read flag status register1 command */
00459     s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00460     s_command.Instruction       = S25FL512S_READ_STATUS_REG1_CMD;
00461     s_command.AddressMode       = QSPI_ADDRESS_NONE;
00462     s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00463     s_command.DataMode          = QSPI_DATA_1_LINE;
00464     s_command.DummyCycles       = 0;
00465     s_command.NbData            = 1;
00466     s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00467     s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00468     s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00469 
00470     /* Configure the command */
00471     if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00472     {
00473       return QSPI_ERROR;
00474     }
00475 
00476     /* Reception of the data */
00477     if (HAL_QSPI_Receive(&QSPIHandle, &reg1, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00478     {
00479       return QSPI_ERROR;
00480     }
00481 
00482 
00483     /* Initialize the read flag status register2 command */
00484     s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00485     s_command.Instruction       = S25FL512S_READ_STATUS_REG2_CMD;
00486     s_command.AddressMode       = QSPI_ADDRESS_NONE;
00487     s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00488     s_command.DataMode          = QSPI_DATA_1_LINE;
00489     s_command.DummyCycles       = 0;
00490     s_command.NbData            = 1;
00491     s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00492     s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00493     s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00494   
00495     /* Configure the command */
00496     if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00497     {
00498       return QSPI_ERROR;
00499     }
00500   
00501     /* Reception of the data */
00502     if (HAL_QSPI_Receive(&QSPIHandle, &reg2, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00503     {
00504       return QSPI_ERROR;
00505     }
00506 
00507     /* Check the value of the register */
00508     if ((reg1 & (S25FL512S_SR1_ERERR | S25FL512S_SR1_PGERR | S25FL512S_SR1_SRWD )) != 0)
00509     {
00510       return QSPI_ERROR;
00511     }
00512     if ((reg1 & (S25FL512S_SR1_BP0 | S25FL512S_SR1_BP1 | S25FL512S_SR1_BP2)) != 0)
00513     {
00514       return QSPI_PROTECTED;
00515     }
00516 
00517     if ((reg2 & (S25FL512S_SR2_PS | S25FL512S_SR2_ES)) != 0)
00518     {
00519       return QSPI_SUSPENDED;
00520     }
00521     if ((reg1 & (S25FL512S_SR1_WIP | S25FL512S_SR1_WREN)) == 0)
00522     {
00523       return QSPI_OK;
00524     }
00525     else
00526     {
00527       return QSPI_BUSY;
00528     }
00529   }
00530 }
00531 
00532 /**
00533   * @brief  Reads the configuration of the memory and fills QspiInfo struct
00534   * @param  pInfo pointer to Info structure
00535   * @retval QSPI memory status
00536   */
00537 uint8_t BSP_QSPI_GetInfo(QSPI_InfoTypeDef* pInfo)
00538 {
00539 
00540   if (QSPI_ReadID(pInfo) != QSPI_OK)
00541   {
00542     return QSPI_ERROR;
00543   }
00544 
00545   return QSPI_OK;
00546 }
00547 
00548 /**
00549 * @brief Configure the QSPI in memory-mapped mode 
00550 * @retval QSPI memory status
00551 */
00552 uint8_t BSP_QSPI_MemoryMappedMode(void)
00553 {
00554   QSPI_CommandTypeDef s_command;
00555   QSPI_MemoryMappedTypeDef s_mem_mapped_cfg;
00556 
00557   /* Configure the command for the read instruction */
00558   s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
00559   s_command.Instruction = QUAD_OUT_FAST_READ_CMD;
00560   s_command.AddressMode = QSPI_ADDRESS_1_LINE;
00561   s_command.AddressSize = QSPI_ADDRESS_32_BITS;
00562   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00563   s_command.DataMode = QSPI_DATA_4_LINES;
00564   s_command.DummyCycles = QspiInfo.DummyCyclesRead;
00565   s_command.DdrMode = QSPI_DDR_MODE_DISABLE;
00566   s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY;
00567   s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD;
00568 
00569   /* Configure the memory mapped mode */
00570   s_mem_mapped_cfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE;
00571   s_mem_mapped_cfg.TimeOutPeriod = 0; //1;
00572 
00573   if (HAL_QSPI_MemoryMapped(&QSPIHandle, &s_command, &s_mem_mapped_cfg) != HAL_OK)
00574   {
00575     return QSPI_ERROR;
00576   }
00577 
00578   return QSPI_OK;
00579 }
00580 
00581 /**
00582   * @}
00583   */
00584 
00585 /** @addtogroup STM32469I_EVAL_QSPI_Private_Functions 
00586   * @{
00587   */ 
00588 
00589 /**
00590   * @brief QSPI MSP Initialization
00591   *        This function configures the hardware resources used in this example:
00592   *           - Peripheral's clock enable
00593   *           - Peripheral's GPIO Configuration
00594   *           - NVIC configuration for QSPI interrupt
00595   */
00596 __weak void BSP_QSPI_MspInit(QSPI_HandleTypeDef *hqspi, void *Params)
00597 {
00598   GPIO_InitTypeDef gpio_init_structure;
00599 
00600   /*##-1- Enable peripherals and GPIO Clocks #################################*/
00601   /* Enable the QuadSPI memory interface clock */
00602   QSPI_CLK_ENABLE();
00603   /* Reset the QuadSPI memory interface */
00604   QSPI_FORCE_RESET();
00605   QSPI_RELEASE_RESET();
00606   /* Enable GPIO clocks */
00607   QSPI_CS_GPIO_CLK_ENABLE();
00608   QSPI_DX_CLK_GPIO_CLK_ENABLE();
00609 
00610   /*##-2- Configure peripheral GPIO ##########################################*/
00611   /* QSPI CS GPIO pin configuration  */
00612   gpio_init_structure.Pin       = QSPI_CS_PIN;
00613   gpio_init_structure.Mode      = GPIO_MODE_AF_PP;
00614   gpio_init_structure.Pull      = GPIO_PULLUP;
00615   gpio_init_structure.Speed     = GPIO_SPEED_HIGH;
00616   gpio_init_structure.Alternate = GPIO_AF10_QSPI;
00617   HAL_GPIO_Init(QSPI_CS_GPIO_PORT, &gpio_init_structure);
00618 
00619   /* QSPI CLK GPIO pin configuration  */
00620   gpio_init_structure.Pin       = QSPI_CLK_PIN;
00621   gpio_init_structure.Pull      = GPIO_NOPULL;
00622   gpio_init_structure.Alternate = GPIO_AF9_QSPI;
00623   HAL_GPIO_Init(QSPI_CLK_GPIO_PORT, &gpio_init_structure);
00624 
00625   /* QSPI D0 and D1 GPIO pin configuration  */
00626   gpio_init_structure.Pin       = (QSPI_D0_PIN | QSPI_D1_PIN);
00627   gpio_init_structure.Alternate = GPIO_AF10_QSPI;
00628   HAL_GPIO_Init(QSPI_DX_GPIO_PORT, &gpio_init_structure);
00629 
00630   /* QSPI D2 and D3 GPIO pin configuration  */
00631   gpio_init_structure.Pin       = (QSPI_D2_PIN | QSPI_D3_PIN) ;
00632   gpio_init_structure.Alternate = GPIO_AF9_QSPI;
00633   HAL_GPIO_Init(QSPI_DX_GPIO_PORT, &gpio_init_structure);
00634 
00635   /*##-3- Configure the NVIC for QSPI #########################################*/
00636   /* NVIC configuration for QSPI interrupt */
00637   HAL_NVIC_SetPriority(QUADSPI_IRQn, 0x0F, 0);
00638   HAL_NVIC_EnableIRQ(QUADSPI_IRQn);
00639 
00640 }
00641 
00642 /**
00643   * @brief QSPI MSP De-Initialization
00644   *        This function frees the hardware resources used in this example:
00645   *          - Disable the Peripheral's clock
00646   *          - Revert GPIO and NVIC configuration to their default state
00647   */
00648 __weak void BSP_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi, void *Params)
00649 {
00650   /*##-1- Disable the NVIC for QSPI ###########################################*/
00651   HAL_NVIC_DisableIRQ(QUADSPI_IRQn);
00652 
00653   /*##-2- Disable peripherals and GPIO Clocks ################################*/
00654   /* De-Configure QSPI pins */
00655   HAL_GPIO_DeInit(QSPI_CS_GPIO_PORT, QSPI_CS_PIN);
00656   HAL_GPIO_DeInit(QSPI_CLK_GPIO_PORT, QSPI_CLK_PIN);
00657   HAL_GPIO_DeInit(QSPI_DX_GPIO_PORT, QSPI_D0_PIN);
00658   HAL_GPIO_DeInit(QSPI_DX_GPIO_PORT, QSPI_D1_PIN);
00659   HAL_GPIO_DeInit(QSPI_DX_GPIO_PORT, QSPI_D2_PIN);
00660   HAL_GPIO_DeInit(QSPI_DX_GPIO_PORT, QSPI_D3_PIN);
00661 
00662   /*##-3- Reset peripherals ##################################################*/
00663   /* Reset the QuadSPI memory interface */
00664   QSPI_FORCE_RESET();
00665   QSPI_RELEASE_RESET();
00666 
00667   /* Disable the QuadSPI memory interface clock */
00668   QSPI_CLK_DISABLE();
00669 }
00670 
00671 /**
00672   * @brief  This function reset the QSPI memory.
00673   * @param  hqspi: QSPI handle
00674   */
00675 static uint8_t QSPI_ResetMemory(QSPI_HandleTypeDef *hqspi)
00676 {
00677   QSPI_CommandTypeDef s_command;
00678   uint32_t instruction1, instruction2;
00679 
00680   /* Command ID differs between N25Q512A and S25FL512S memories */
00681   if (QspiInfo.ManufID == QSPI_N25Q512A)
00682   {
00683     instruction1 = RESET_ENABLE_CMD;
00684     instruction2 = RESET_MEMORY_CMD;
00685   }
00686   else
00687   {
00688     instruction1 = S25FL512S_MODE_BIT_RESET_CMD;
00689     instruction2 = S25FL512S_SOFTWARE_RESET_CMD;
00690   }
00691 
00692   /* Initialize the Mode Bit Reset command */
00693   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00694   s_command.Instruction       = instruction1;
00695   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00696   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00697   s_command.DataMode          = QSPI_DATA_NONE;
00698   s_command.DummyCycles       = 0;
00699   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00700   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00701   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00702 
00703   /* Send the command */
00704   if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00705   {
00706     return QSPI_ERROR;
00707   }
00708 
00709   /* Send the SW reset command */
00710   s_command.Instruction       = instruction2;
00711   if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00712   {
00713     return QSPI_ERROR;
00714   }
00715 
00716   /* Configure automatic polling mode to wait the memory is ready */  
00717   if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
00718   {
00719     return QSPI_ERROR;
00720   }
00721   return QSPI_OK;
00722 }
00723 
00724 /**
00725   * @brief  This function set the QSPI memory in 4-byte address mode
00726   * @param  hqspi: QSPI handle
00727   */
00728 static uint8_t QSPI_EnterFourBytesAddress(QSPI_HandleTypeDef *hqspi)
00729 {
00730   QSPI_CommandTypeDef s_command;
00731   uint8_t reg1;
00732 
00733   /* Command ID differs between N25Q512A and S25FL512S memories */
00734   if (QspiInfo.ManufID == QSPI_N25Q512A)
00735   {
00736     /* Initialize the command */
00737     s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00738     s_command.Instruction       = ENTER_4_BYTE_ADDR_MODE_CMD;
00739     s_command.AddressMode       = QSPI_ADDRESS_NONE;
00740     s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00741     s_command.DataMode          = QSPI_DATA_NONE;
00742     s_command.DummyCycles       = 0;
00743     s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00744     s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00745     s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00746 
00747     /* Enable write operations */
00748     if (QSPI_WriteEnable(hqspi) != QSPI_OK)
00749     {
00750       return QSPI_ERROR;
00751     }
00752 
00753     /* Send the command */
00754     if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00755     {
00756       return QSPI_ERROR;
00757     }
00758 
00759     /* Configure automatic polling mode to wait the memory is ready */
00760     if (QSPI_AutoPollingMemReady(hqspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
00761     {
00762       return QSPI_ERROR;
00763     }
00764 
00765     return QSPI_OK;
00766   }
00767   else
00768   {
00769     /* Initialize the read bank register command */
00770     s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00771     s_command.Instruction       = S25FL512S_READ_BANK_REG_CMD;
00772     s_command.AddressMode       = QSPI_ADDRESS_NONE;
00773     s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00774     s_command.DataMode          = QSPI_DATA_1_LINE;
00775     s_command.DummyCycles       = 0;
00776     s_command.NbData            = 1;
00777     s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00778     s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00779     s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00780 
00781     /* Configure the command */
00782     if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00783     {
00784       return QSPI_ERROR;
00785     }
00786 
00787     /* Reception of the data */
00788     if (HAL_QSPI_Receive(&QSPIHandle, &reg1, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00789     {
00790       return QSPI_ERROR;
00791     }
00792 
00793     /* Enable write operations */
00794     if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
00795     {
00796       return QSPI_ERROR;
00797     }
00798 
00799     /* Update Bank address register (with 4byte addressing bit) */
00800     s_command.Instruction = S25FL512S_WRITE_BANK_REG_CMD;
00801     MODIFY_REG(reg1, S25FL512S_BA_EXTADD, S25FL512S_BA_EXTADD);
00802 
00803     /* Configure the write volatile configuration register command */
00804     if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00805     {
00806       return QSPI_ERROR;
00807     }
00808 
00809     /* Transmission of the data Status Register 1 */
00810     if (HAL_QSPI_Transmit(&QSPIHandle, &reg1, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00811     {
00812       return QSPI_ERROR;
00813     }
00814     return QSPI_OK;
00815   }
00816 }
00817 
00818 /**
00819   * @brief  This function configure the dummy cycles on memory side.
00820   * @param  hqspi: QSPI handle
00821   */
00822 static uint8_t QSPI_DummyCyclesCfg(QSPI_HandleTypeDef *hqspi)
00823 {
00824   QSPI_CommandTypeDef s_command;
00825   uint8_t reg[2];
00826   /* Command ID differs between N25Q512A and S25FL512S memories */
00827   if (QspiInfo.ManufID == QSPI_N25Q512A)
00828   {
00829     /* Initialize the read volatile configuration register command */
00830     s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00831     s_command.Instruction       = READ_VOL_CFG_REG_CMD;
00832     s_command.AddressMode       = QSPI_ADDRESS_NONE;
00833     s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00834     s_command.DataMode          = QSPI_DATA_1_LINE;
00835     s_command.DummyCycles       = 0;
00836     s_command.NbData            = 1;
00837     s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00838     s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00839     s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00840 
00841     /* Configure the command */
00842     if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00843     {
00844       return QSPI_ERROR;
00845     }
00846 
00847     /* Reception of the data */
00848     if (HAL_QSPI_Receive(hqspi, &reg[0], HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00849     {
00850       return QSPI_ERROR;
00851     }
00852 
00853     /* Enable write operations */
00854     if (QSPI_WriteEnable(hqspi) != QSPI_OK)
00855     {
00856       return QSPI_ERROR;
00857     }
00858 
00859     /* Update volatile configuration register (with new dummy cycles) */
00860     s_command.Instruction = WRITE_VOL_CFG_REG_CMD;
00861     MODIFY_REG(reg[0], N25Q512A_VCR_NB_DUMMY, (N25Q512A_DUMMY_CYCLES_READ_QUAD << POSITION_VAL(N25Q512A_VCR_NB_DUMMY)));
00862 
00863     /* Configure the write volatile configuration register command */
00864     if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00865     {
00866       return QSPI_ERROR;
00867     }
00868 
00869     /* Transmission of the data */
00870     if (HAL_QSPI_Transmit(hqspi, &reg[0], HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00871     {
00872       return QSPI_ERROR;
00873     }
00874   }
00875   else
00876   {
00877     /* Initialize the read configuration register command */
00878     s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00879     s_command.Instruction       = S25FL512S_READ_CONFIGURATION_REG1_CMD;
00880     s_command.AddressMode       = QSPI_ADDRESS_NONE;
00881     s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00882     s_command.DataMode          = QSPI_DATA_1_LINE;
00883     s_command.DummyCycles       = 0;
00884     s_command.NbData            = 1;
00885     s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00886     s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00887     s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00888 
00889     /* Configure the command */
00890     if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00891     {
00892       return QSPI_ERROR;
00893     }
00894 
00895     /* Reception of the data */
00896     if (HAL_QSPI_Receive(&QSPIHandle, &reg[1], HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00897     {
00898       return QSPI_ERROR;
00899     }
00900 
00901     /* Initialize the read status register1 command */
00902     s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00903     s_command.Instruction       = S25FL512S_READ_STATUS_REG1_CMD;
00904     s_command.AddressMode       = QSPI_ADDRESS_NONE;
00905     s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00906     s_command.DataMode          = QSPI_DATA_1_LINE;
00907     s_command.DummyCycles       = 0;
00908     s_command.NbData            = 1;
00909     s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00910     s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00911     s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00912 
00913     /* Configure the command */
00914     if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00915     {
00916       return QSPI_ERROR;
00917     }
00918 
00919     /* Reception of the data */
00920     if (HAL_QSPI_Receive(&QSPIHandle, &reg[0], HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00921     {
00922       return QSPI_ERROR;
00923     }
00924 
00925     /* Enable write operations */
00926     if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
00927     {
00928       return QSPI_ERROR;
00929     }
00930 
00931     /* Update configuration register (with new Latency Code) */
00932     s_command.Instruction       = S25FL512S_WRITE_STATUS_CMD_REG_CMD;
00933     s_command.NbData            = 2;
00934     MODIFY_REG(reg[1], S25FL512S_CR1_LC_MASK, S25FL512S_CR1_LC1);
00935 
00936     /* Configure the write volatile configuration register command */
00937     if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00938     {
00939       return QSPI_ERROR;
00940     }
00941 
00942     /* Transmission of the data Status Register 1 */
00943     if (HAL_QSPI_Transmit(&QSPIHandle, reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00944     {
00945       return QSPI_ERROR;
00946     }
00947   }
00948   return QSPI_OK;
00949 }
00950 
00951 /**
00952   * @brief  This function send a Write Enable and wait it is effective.
00953   * @param  hqspi: QSPI handle
00954   */
00955 static uint8_t QSPI_WriteEnable(QSPI_HandleTypeDef *hqspi)
00956 {
00957   QSPI_CommandTypeDef     s_command;
00958   QSPI_AutoPollingTypeDef sConfig;
00959 
00960   /* Enable write operations */
00961   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00962   s_command.Instruction       = WRITE_ENABLE_CMD; /* equal on both memory types */
00963   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00964   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00965   s_command.DataMode          = QSPI_DATA_NONE;
00966   s_command.DummyCycles       = 0;
00967   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00968   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00969   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00970 
00971   if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00972   {
00973     return QSPI_ERROR;
00974   }
00975   
00976   /* Configure automatic polling mode to wait for write enabling */  
00977   sConfig.Match           = S25FL512S_SR1_WREN;
00978   sConfig.Mask            = S25FL512S_SR1_WREN; /* equal on both memory types */
00979   sConfig.MatchMode       = QSPI_MATCH_MODE_AND;
00980   sConfig.StatusBytesSize = 1;
00981   sConfig.Interval        = 0x10;
00982   sConfig.AutomaticStop   = QSPI_AUTOMATIC_STOP_ENABLE;
00983 
00984   s_command.Instruction    = READ_STATUS_REG_CMD; /* equal on both memory types */
00985   s_command.DataMode       = QSPI_DATA_1_LINE;
00986 
00987   if (HAL_QSPI_AutoPolling(&QSPIHandle, &s_command, &sConfig, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00988   {
00989     return QSPI_ERROR;
00990   }
00991 
00992   return QSPI_OK;
00993 }
00994 
00995 /**
00996   * @brief  This function read the SR of the memory and wait the EOP.
00997   * @param  hqspi: QSPI handle
00998   * @param  Timeout: timeout value before returning an error
00999   */
01000 static uint8_t QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi, uint32_t Timeout)
01001 {
01002   QSPI_CommandTypeDef     s_command;
01003   QSPI_AutoPollingTypeDef sConfig;
01004 
01005   /* Configure automatic polling mode to wait for memory ready */  
01006   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
01007   s_command.Instruction       = READ_STATUS_REG_CMD; /* same value on both memory types */
01008   s_command.AddressMode       = QSPI_ADDRESS_NONE;
01009   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
01010   s_command.DataMode          = QSPI_DATA_1_LINE;
01011   s_command.DummyCycles       = 0;
01012   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
01013   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
01014   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
01015 
01016   sConfig.Match           = 0;
01017   sConfig.Mask            = S25FL512S_SR1_WIP; /* same value on both memory types */
01018   sConfig.MatchMode       = QSPI_MATCH_MODE_AND;
01019   sConfig.StatusBytesSize = 1;
01020   sConfig.Interval        = 0x10;
01021   sConfig.AutomaticStop   = QSPI_AUTOMATIC_STOP_ENABLE;
01022 
01023   if (HAL_QSPI_AutoPolling(&QSPIHandle, &s_command, &sConfig, Timeout) != HAL_OK)
01024   {
01025     return QSPI_ERROR;
01026   }
01027 
01028   return QSPI_OK;
01029 }
01030 
01031 /**
01032   * @brief  This function reads the ID of the QSPI Memory and fills the info struct
01033   * @param  pqspi_info: pointer to the Info Typedef strcture
01034   */
01035 static uint8_t QSPI_ReadID(QSPI_InfoTypeDef *pqspi_info)
01036 {
01037   QSPI_CommandTypeDef     s_command;
01038   uint8_t reg[6];
01039 
01040   /* Configure automatic polling mode to wait for memory ready */
01041   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
01042   s_command.Instruction       = READ_ID_CMD2; /* same value on both memory types */
01043   s_command.AddressMode       = QSPI_ADDRESS_NONE;
01044   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
01045   s_command.DataMode          = QSPI_DATA_1_LINE;
01046   s_command.NbData            = 6;
01047   s_command.DummyCycles       = 0;
01048   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
01049   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
01050   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
01051 
01052   if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
01053   {
01054     return QSPI_ERROR;
01055   }
01056 
01057   /* Reception of the data */
01058   if (HAL_QSPI_Receive(&QSPIHandle, reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
01059   {
01060     return QSPI_ERROR;
01061   }
01062 
01063   /* Check the received ID of the QSPI Memory */
01064   if (reg[0] == JEDEC_MANUF_ID_MICRON)
01065   {
01066     pqspi_info->ManufID = QSPI_N25Q512A;
01067     pqspi_info->FlashSize = (reg[2]<<21) & 0xFFFFFFFF;
01068     pqspi_info->EraseSectorSize = N25Q512A_SECTOR_SIZE;
01069     pqspi_info->EraseSectorsNumber = (N25Q512A_FLASH_SIZE/N25Q512A_SECTOR_SIZE);
01070     pqspi_info->ProgPageSize = N25Q512A_PAGE_SIZE;
01071     pqspi_info->ProgPagesNumber = (N25Q512A_FLASH_SIZE/N25Q512A_PAGE_SIZE);
01072     pqspi_info->DummyCyclesRead = 10;
01073     pqspi_info->SectorEraseMaxTime = N25Q512A_SECTOR_ERASE_MAX_TIME;
01074     pqspi_info->BulkEraseMaxTime = N25Q512A_BULK_ERASE_MAX_TIME;
01075   }
01076   if (reg[0] == JEDEC_MANUF_ID_SPANSION)
01077   {
01078     pqspi_info->ManufID = QSPI_S25FL512S;
01079     pqspi_info->FlashSize = (reg[2]<<21) & 0xFFFFFFFF;
01080     pqspi_info->EraseSectorSize = S25FL512S_SECTOR_SIZE;
01081     pqspi_info->EraseSectorsNumber = (S25FL512S_FLASH_SIZE/S25FL512S_SECTOR_SIZE);
01082     pqspi_info->ProgPageSize = S25FL512S_PAGE_SIZE;
01083     pqspi_info->ProgPagesNumber = (S25FL512S_FLASH_SIZE/S25FL512S_PAGE_SIZE);
01084     pqspi_info->DummyCyclesRead = 8;
01085     pqspi_info->SectorEraseMaxTime = S25FL512S_SECTOR_ERASE_MAX_TIME;
01086     pqspi_info->BulkEraseMaxTime = S25FL512S_BULK_ERASE_MAX_TIME;
01087   }
01088 
01089   return QSPI_OK;
01090 
01091 }
01092 /**
01093   * @}
01094   */  
01095   
01096 /**
01097   * @}
01098   */ 
01099   
01100 /**
01101   * @}
01102   */ 
01103   
01104 /**
01105   * @}
01106   */ 
01107 
01108 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
01109 
Generated on Tue Jan 12 2016 17:51:25 for STM32469I_EVAL BSP User Manual by   doxygen 1.7.6.1