STM32F469I-Discovery BSP User Manual: stm32469i_discovery_qspi.c Source File

STM32F469I-Discovery BSP Drivers

stm32469i_discovery_qspi.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32469i_discovery_qspi.c
00004   * @author  MCD Application Team
00005   * @version V1.0.2
00006   * @date    13-January-2016
00007   * @brief   This file includes a standard driver for the N25Q128A QSPI
00008   *          memory mounted on STM32469I-Discovery board.
00009   @verbatim
00010   ==============================================================================
00011                      ##### How to use this driver #####
00012   ==============================================================================
00013   [..]
00014    (#) This driver is used to drive the N25Q128A QSPI external
00015        memory mounted on STM32469I-Discovery board.
00016 
00017    (#) This driver need a specific component driver N25Q128A 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_discovery_qspi.h"
00069 
00070 /** @addtogroup BSP
00071   * @{
00072   */
00073 
00074 /** @addtogroup STM32469I_Discovery
00075   * @{
00076   */
00077 
00078 /** @defgroup STM32469I_Discovery_QSPI STM32469I Discovery QSPI
00079   * @{
00080   */
00081 
00082 
00083 /* Private variables ---------------------------------------------------------*/
00084 
00085 
00086 /** @defgroup STM32469I_Discovery_QSPI_Private_Variables STM32469I Discovery QSPI Private Variables
00087   * @{
00088   */
00089 QSPI_HandleTypeDef QSPIHandle;
00090 
00091 /**
00092   * @}
00093   */
00094 
00095 
00096 
00097 /* Private functions ---------------------------------------------------------*/
00098 
00099 /** @defgroup STM32469I_Discovery_QSPI_Private_Functions STM32469I Discovery QSPI Private Functions
00100   * @{
00101   */
00102 static uint8_t QSPI_ResetMemory          (QSPI_HandleTypeDef *hqspi);
00103 static uint8_t QSPI_DummyCyclesCfg       (QSPI_HandleTypeDef *hqspi);
00104 static uint8_t QSPI_WriteEnable          (QSPI_HandleTypeDef *hqspi);
00105 static uint8_t QSPI_AutoPollingMemReady  (QSPI_HandleTypeDef *hqspi, uint32_t Timeout);
00106 
00107 
00108 /**
00109   * @}
00110   */
00111 
00112 /** @defgroup STM32469I_Discovery_QSPI_Exported_Functions STM32469I Discovery QSPI Exported Functions
00113   * @{
00114   */
00115 
00116 /**
00117   * @brief  Initializes the QSPI interface.
00118   * @retval QSPI memory status
00119   */
00120 uint8_t BSP_QSPI_Init(void)
00121 {
00122   QSPIHandle.Instance = QUADSPI;
00123 
00124   /* Call the DeInit function to reset the driver */
00125   if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK)
00126   {
00127     return QSPI_ERROR;
00128   }
00129 
00130   /* System level initialization */
00131   BSP_QSPI_MspInit(&QSPIHandle, NULL);
00132 
00133   /* QSPI initialization */
00134   QSPIHandle.Init.ClockPrescaler     = 1; /* QSPI Freq= 180 MHz / (1+1) = 90 MHz */
00135   QSPIHandle.Init.FifoThreshold      = 1;
00136   QSPIHandle.Init.SampleShifting     = QSPI_SAMPLE_SHIFTING_HALFCYCLE;
00137   QSPIHandle.Init.FlashSize          = POSITION_VAL(N25Q128A_FLASH_SIZE) - 1;
00138   QSPIHandle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_2_CYCLE;
00139   QSPIHandle.Init.ClockMode          = QSPI_CLOCK_MODE_0;
00140   QSPIHandle.Init.FlashID            = QSPI_FLASH_ID_1;
00141   QSPIHandle.Init.DualFlash          = QSPI_DUALFLASH_DISABLE;
00142 
00143   if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK)
00144   {
00145     return QSPI_ERROR;
00146   }
00147 
00148   /* QSPI memory reset */
00149   if (QSPI_ResetMemory(&QSPIHandle) != QSPI_OK)
00150   {
00151     return QSPI_NOT_SUPPORTED;
00152   }
00153 
00154 
00155   /* Configuration of the dummy cucles on QSPI memory side */
00156   if (QSPI_DummyCyclesCfg(&QSPIHandle) != QSPI_OK)
00157   {
00158     return QSPI_NOT_SUPPORTED;
00159   }
00160 
00161   return QSPI_OK;
00162 }
00163 
00164 /**
00165   * @brief  De-Initializes the QSPI interface.
00166   * @retval QSPI memory status
00167   */
00168 uint8_t BSP_QSPI_DeInit(void)
00169 {
00170   QSPIHandle.Instance = QUADSPI;
00171 
00172   /* Call the DeInit function to reset the driver */
00173   if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK)
00174   {
00175     return QSPI_ERROR;
00176   }
00177 
00178   /* System level De-initialization */
00179   BSP_QSPI_MspDeInit(&QSPIHandle, NULL);
00180 
00181   return QSPI_OK;
00182 }
00183 
00184 /**
00185   * @brief  Reads an amount of data from the QSPI memory.
00186   * @param  pData: Pointer to data to be read
00187   * @param  ReadAddr: Read start address
00188   * @param  Size: Size of data to read
00189   * @retval QSPI memory status
00190   */
00191 uint8_t BSP_QSPI_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size)
00192 {
00193   QSPI_CommandTypeDef s_command;
00194 
00195   /* Initialize the read command */
00196   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00197   s_command.Instruction       = QUAD_INOUT_FAST_READ_CMD;
00198   s_command.AddressMode       = QSPI_ADDRESS_4_LINES;
00199   s_command.AddressSize       = QSPI_ADDRESS_24_BITS;
00200   s_command.Address           = ReadAddr;
00201   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00202   s_command.DataMode          = QSPI_DATA_4_LINES;
00203   s_command.DummyCycles       = N25Q128A_DUMMY_CYCLES_READ_QUAD;
00204   s_command.NbData            = Size;
00205   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00206   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00207   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00208 
00209   /* Configure the command */
00210   if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00211   {
00212     return QSPI_ERROR;
00213   }
00214 
00215   /* Reception of the data */
00216   if (HAL_QSPI_Receive(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00217   {
00218     return QSPI_ERROR;
00219   }
00220 
00221   return QSPI_OK;
00222 }
00223 
00224 /**
00225   * @brief  Writes an amount of data to the QSPI memory.
00226   * @param  pData: Pointer to data to be written
00227   * @param  WriteAddr: Write start address
00228   * @param  Size: Size of data to write
00229   * @retval QSPI memory status
00230   */
00231 uint8_t BSP_QSPI_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size)
00232 {
00233   QSPI_CommandTypeDef s_command;
00234   uint32_t end_addr, current_size, current_addr;
00235 
00236   /* Calculation of the size between the write address and the end of the page */
00237   current_addr = 0;
00238 
00239   while (current_addr <= WriteAddr)
00240   {
00241     current_addr += N25Q128A_PAGE_SIZE;
00242   }
00243   current_size = current_addr - WriteAddr;
00244 
00245   /* Check if the size of the data is less than the remaining place in the page */
00246   if (current_size > Size)
00247   {
00248     current_size = Size;
00249   }
00250 
00251   /* Initialize the address variables */
00252   current_addr = WriteAddr;
00253   end_addr = WriteAddr + Size;
00254 
00255   /* Initialize the program command */
00256   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00257   s_command.Instruction       = EXT_QUAD_IN_FAST_PROG_CMD;
00258   s_command.AddressMode       = QSPI_ADDRESS_4_LINES;
00259   s_command.AddressSize       = QSPI_ADDRESS_24_BITS;
00260   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00261   s_command.DataMode          = QSPI_DATA_4_LINES;
00262   s_command.DummyCycles       = 0;
00263   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00264   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00265   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00266 
00267   /* Perform the write page by page */
00268   do
00269   {
00270     s_command.Address = current_addr;
00271     s_command.NbData  = current_size;
00272 
00273     /* Enable write operations */
00274     if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
00275     {
00276       return QSPI_ERROR;
00277     }
00278 
00279     /* Configure the command */
00280     if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00281     {
00282       return QSPI_ERROR;
00283     }
00284 
00285     /* Transmission of the data */
00286     if (HAL_QSPI_Transmit(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00287     {
00288       return QSPI_ERROR;
00289     }
00290 
00291     /* Configure automatic polling mode to wait for end of program */
00292     if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
00293     {
00294       return QSPI_ERROR;
00295     }
00296 
00297     /* Update the address and size variables for next page programming */
00298     current_addr += current_size;
00299     pData += current_size;
00300     current_size = ((current_addr + N25Q128A_PAGE_SIZE) > end_addr) ? (end_addr - current_addr) : N25Q128A_PAGE_SIZE;
00301   } while (current_addr < end_addr);
00302 
00303   return QSPI_OK;
00304 }
00305 
00306 /**
00307   * @brief  Erases the specified block of the QSPI memory.
00308   * @param  BlockAddress: Block address to erase
00309   * @retval QSPI memory status
00310   */
00311 uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress)
00312 {
00313   QSPI_CommandTypeDef s_command;
00314 
00315   /* Initialize the erase command */
00316   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00317   s_command.Instruction       = SUBSECTOR_ERASE_CMD;
00318   s_command.AddressMode       = QSPI_ADDRESS_1_LINE;
00319   s_command.AddressSize       = QSPI_ADDRESS_24_BITS;
00320   s_command.Address           = BlockAddress;
00321   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00322   s_command.DataMode          = QSPI_DATA_NONE;
00323   s_command.DummyCycles       = 0;
00324   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00325   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00326   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00327 
00328   /* Enable write operations */
00329   if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
00330   {
00331     return QSPI_ERROR;
00332   }
00333 
00334   /* Send the command */
00335   if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00336   {
00337     return QSPI_ERROR;
00338   }
00339   
00340   /* Configure automatic polling mode to wait for end of erase */  
00341   if (QSPI_AutoPollingMemReady(&QSPIHandle, N25Q128A_SUBSECTOR_ERASE_MAX_TIME) != QSPI_OK)
00342   {
00343     return QSPI_ERROR;
00344   }
00345 
00346   return QSPI_OK;
00347 }
00348 
00349 /**
00350   * @brief  Erases the entire QSPI memory.
00351   * @retval QSPI memory status
00352   */
00353 uint8_t BSP_QSPI_Erase_Chip(void)
00354 {
00355   QSPI_CommandTypeDef s_command;
00356 
00357   /* Initialize the erase command */
00358   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00359   s_command.Instruction       = BULK_ERASE_CMD;
00360   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00361   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00362   s_command.DataMode          = QSPI_DATA_NONE;
00363   s_command.DummyCycles       = 0;
00364   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00365   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00366   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00367 
00368   /* Enable write operations */
00369   if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
00370   {
00371     return QSPI_ERROR;
00372   }
00373 
00374   /* Send the command */
00375   if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00376   {
00377     return QSPI_ERROR;
00378   }
00379   
00380   /* Configure automatic polling mode to wait for end of erase */  
00381   if (QSPI_AutoPollingMemReady(&QSPIHandle, N25Q128A_BULK_ERASE_MAX_TIME) != QSPI_OK)
00382   {
00383     return QSPI_ERROR;
00384   }
00385 
00386   return QSPI_OK;
00387 }
00388 
00389 /**
00390   * @brief  Reads current status of the QSPI memory.
00391   * @retval QSPI memory status
00392   */
00393 uint8_t BSP_QSPI_GetStatus(void)
00394 {
00395   QSPI_CommandTypeDef s_command;
00396   uint8_t reg;
00397 
00398   /* Initialize the read flag status register command */
00399   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00400   s_command.Instruction       = READ_FLAG_STATUS_REG_CMD;
00401   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00402   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00403   s_command.DataMode          = QSPI_DATA_1_LINE;
00404   s_command.DummyCycles       = 0;
00405   s_command.NbData            = 1;
00406   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00407   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00408   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00409 
00410   /* Configure the command */
00411   if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00412   {
00413     return QSPI_ERROR;
00414   }
00415 
00416   /* Reception of the data */
00417   if (HAL_QSPI_Receive(&QSPIHandle, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00418   {
00419     return QSPI_ERROR;
00420   }
00421   
00422   /* Check the value of the register */
00423   if ((reg & (N25Q128A_FSR_PRERR | N25Q128A_FSR_VPPERR | N25Q128A_FSR_PGERR | N25Q128A_FSR_ERERR)) != 0)
00424   {
00425     return QSPI_ERROR;
00426   }
00427   else if ((reg & (N25Q128A_FSR_PGSUS | N25Q128A_FSR_ERSUS)) != 0)
00428   {
00429     return QSPI_SUSPENDED;
00430   }
00431   else if ((reg & N25Q128A_FSR_READY) != 0)
00432   {
00433     return QSPI_OK;
00434   }
00435   else
00436   {
00437     return QSPI_BUSY;
00438   }
00439 }
00440 
00441 /**
00442   * @brief  Reads the configuration of the memory and fills QspiInfo struct
00443   * @param  pInfo pointer to Info structure
00444   * @retval QSPI memory status
00445   */
00446 uint8_t BSP_QSPI_GetInfo(QSPI_InfoTypeDef* pInfo)
00447 {
00448   /* Configure the structure with the memory configuration */
00449   pInfo->FlashSize          = N25Q128A_FLASH_SIZE;
00450   pInfo->EraseSectorSize    = N25Q128A_SUBSECTOR_SIZE;
00451   pInfo->EraseSectorsNumber = (N25Q128A_FLASH_SIZE/N25Q128A_SUBSECTOR_SIZE);
00452   pInfo->ProgPageSize       = N25Q128A_PAGE_SIZE;
00453   pInfo->ProgPagesNumber    = (N25Q128A_FLASH_SIZE/N25Q128A_PAGE_SIZE);
00454 
00455   return QSPI_OK;
00456 }
00457 
00458 /**
00459   * @brief  Configure the QSPI in memory-mapped mode 
00460   * @retval QSPI memory status
00461   */
00462 uint8_t BSP_QSPI_MemoryMappedMode(void)
00463 {
00464   QSPI_CommandTypeDef      s_command;
00465   QSPI_MemoryMappedTypeDef s_mem_mapped_cfg;
00466 
00467   /* Configure the command for the read instruction */
00468   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00469   s_command.Instruction       = QUAD_INOUT_FAST_READ_CMD;
00470   s_command.AddressMode       = QSPI_ADDRESS_4_LINES;
00471   s_command.AddressSize       = QSPI_ADDRESS_24_BITS;
00472   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00473   s_command.DataMode          = QSPI_DATA_4_LINES;
00474   s_command.DummyCycles       = N25Q128A_DUMMY_CYCLES_READ_QUAD;
00475   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00476   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00477   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00478   
00479   /* Configure the memory mapped mode */
00480   s_mem_mapped_cfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_ENABLE;
00481   s_mem_mapped_cfg.TimeOutPeriod     = 100;
00482   
00483   if (HAL_QSPI_MemoryMapped(&QSPIHandle, &s_command, &s_mem_mapped_cfg) != HAL_OK)
00484   {
00485     return QSPI_ERROR;
00486   }
00487 
00488   return QSPI_OK;
00489 }
00490 
00491 /**
00492   * @}
00493   */
00494 
00495 /** @defgroup STM32469I_Discovery_QSPI_Private_Functions STM32469I Discovery QSPI Private Functions
00496   * @{
00497   */
00498 
00499 /**
00500   * @brief QSPI MSP Initialization
00501   *        This function configures the hardware resources used in this example:
00502   *           - Peripheral's clock enable
00503   *           - Peripheral's GPIO Configuration
00504   *           - NVIC configuration for QSPI interrupt
00505   */
00506 __weak void BSP_QSPI_MspInit(QSPI_HandleTypeDef *hqspi, void *Params)
00507 {
00508   GPIO_InitTypeDef gpio_init_structure;
00509 
00510   /*##-1- Enable peripherals and GPIO Clocks #################################*/
00511   /* Enable the QuadSPI memory interface clock */
00512   QSPI_CLK_ENABLE();
00513   /* Reset the QuadSPI memory interface */
00514   QSPI_FORCE_RESET();
00515   QSPI_RELEASE_RESET();
00516   /* Enable GPIO clocks */
00517   QSPI_CS_GPIO_CLK_ENABLE();
00518   QSPI_DX_CLK_GPIO_CLK_ENABLE();
00519 
00520   /*##-2- Configure peripheral GPIO ##########################################*/
00521   /* QSPI CS GPIO pin configuration  */
00522   gpio_init_structure.Pin       = QSPI_CS_PIN;
00523   gpio_init_structure.Mode      = GPIO_MODE_AF_PP;
00524   gpio_init_structure.Pull      = GPIO_PULLUP;
00525   gpio_init_structure.Speed     = GPIO_SPEED_HIGH;
00526   gpio_init_structure.Alternate = GPIO_AF10_QSPI;
00527   HAL_GPIO_Init(QSPI_CS_GPIO_PORT, &gpio_init_structure);
00528 
00529   /* QSPI CLK GPIO pin configuration  */
00530   gpio_init_structure.Pin       = QSPI_CLK_PIN;
00531   gpio_init_structure.Pull      = GPIO_NOPULL;
00532   gpio_init_structure.Alternate = GPIO_AF9_QSPI;
00533   HAL_GPIO_Init(QSPI_CLK_GPIO_PORT, &gpio_init_structure);
00534 
00535   /* QSPI D0 and D1 GPIO pin configuration  */
00536   gpio_init_structure.Pin       = (QSPI_D0_PIN | QSPI_D1_PIN);
00537   gpio_init_structure.Alternate = GPIO_AF10_QSPI;
00538   HAL_GPIO_Init(QSPI_DX_GPIO_PORT, &gpio_init_structure);
00539 
00540   /* QSPI D2 and D3 GPIO pin configuration  */
00541   gpio_init_structure.Pin       = (QSPI_D2_PIN | QSPI_D3_PIN) ;
00542   gpio_init_structure.Alternate = GPIO_AF9_QSPI;
00543   HAL_GPIO_Init(QSPI_DX_GPIO_PORT, &gpio_init_structure);
00544 
00545   /*##-3- Configure the NVIC for QSPI #########################################*/
00546   /* NVIC configuration for QSPI interrupt */
00547   HAL_NVIC_SetPriority(QUADSPI_IRQn, 0x0F, 0);
00548   HAL_NVIC_EnableIRQ(QUADSPI_IRQn);
00549 
00550 }
00551 
00552 /**
00553   * @brief QSPI MSP De-Initialization
00554   *        This function frees the hardware resources used in this example:
00555   *          - Disable the Peripheral's clock
00556   *          - Revert GPIO and NVIC configuration to their default state
00557   */
00558 __weak void BSP_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi, void *Params)
00559 {
00560   /*##-1- Disable the NVIC for QSPI ###########################################*/
00561   HAL_NVIC_DisableIRQ(QUADSPI_IRQn);
00562 
00563   /*##-2- Disable peripherals and GPIO Clocks ################################*/
00564   /* De-Configure QSPI pins */
00565   HAL_GPIO_DeInit(QSPI_CS_GPIO_PORT, QSPI_CS_PIN);
00566   HAL_GPIO_DeInit(QSPI_CLK_GPIO_PORT, QSPI_CLK_PIN);
00567   HAL_GPIO_DeInit(QSPI_DX_GPIO_PORT, QSPI_D0_PIN);
00568   HAL_GPIO_DeInit(QSPI_DX_GPIO_PORT, QSPI_D1_PIN);
00569   HAL_GPIO_DeInit(QSPI_DX_GPIO_PORT, QSPI_D2_PIN);
00570   HAL_GPIO_DeInit(QSPI_DX_GPIO_PORT, QSPI_D3_PIN);
00571 
00572   /*##-3- Reset peripherals ##################################################*/
00573   /* Reset the QuadSPI memory interface */
00574   QSPI_FORCE_RESET();
00575   QSPI_RELEASE_RESET();
00576 
00577   /* Disable the QuadSPI memory interface clock */
00578   QSPI_CLK_DISABLE();
00579 }
00580 
00581 /**
00582   * @brief  This function reset the QSPI memory.
00583   * @param  hqspi: QSPI handle
00584   */
00585 static uint8_t QSPI_ResetMemory(QSPI_HandleTypeDef *hqspi)
00586 {
00587   QSPI_CommandTypeDef s_command;
00588 
00589   /* Initialize the reset enable command */
00590   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00591   s_command.Instruction       = RESET_ENABLE_CMD;
00592   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00593   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00594   s_command.DataMode          = QSPI_DATA_NONE;
00595   s_command.DummyCycles       = 0;
00596   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00597   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00598   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00599 
00600   /* Send the command */
00601   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00602   {
00603     return QSPI_ERROR;
00604   }
00605 
00606   /* Send the reset memory command */
00607   s_command.Instruction = RESET_MEMORY_CMD;
00608   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00609   {
00610     return QSPI_ERROR;
00611   }
00612 
00613   /* Configure automatic polling mode to wait the memory is ready */  
00614   if (QSPI_AutoPollingMemReady(hqspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
00615   {
00616     return QSPI_ERROR;
00617   }
00618 
00619   return QSPI_OK;
00620 }
00621 
00622 /**
00623   * @brief  This function configure the dummy cycles on memory side.
00624   * @param  hqspi: QSPI handle
00625   */
00626 static uint8_t QSPI_DummyCyclesCfg(QSPI_HandleTypeDef *hqspi)
00627 {
00628   QSPI_CommandTypeDef s_command;
00629   uint8_t reg;
00630 
00631   /* Initialize the read volatile configuration register command */
00632   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00633   s_command.Instruction       = READ_VOL_CFG_REG_CMD;
00634   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00635   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00636   s_command.DataMode          = QSPI_DATA_1_LINE;
00637   s_command.DummyCycles       = 0;
00638   s_command.NbData            = 1;
00639   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00640   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00641   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00642 
00643   /* Configure the command */
00644   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00645   {
00646     return QSPI_ERROR;
00647   }
00648 
00649   /* Reception of the data */
00650   if (HAL_QSPI_Receive(hqspi, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00651   {
00652     return QSPI_ERROR;
00653   }
00654 
00655   /* Enable write operations */
00656   if (QSPI_WriteEnable(hqspi) != QSPI_OK)
00657   {
00658     return QSPI_ERROR;
00659   }
00660 
00661   /* Update volatile configuration register (with new dummy cycles) */  
00662   s_command.Instruction = WRITE_VOL_CFG_REG_CMD;
00663   MODIFY_REG(reg, N25Q128A_VCR_NB_DUMMY, (N25Q128A_DUMMY_CYCLES_READ_QUAD << POSITION_VAL(N25Q128A_VCR_NB_DUMMY)));
00664       
00665   /* Configure the write volatile configuration register command */
00666   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00667   {
00668     return QSPI_ERROR;
00669   }
00670 
00671   /* Transmission of the data */
00672   if (HAL_QSPI_Transmit(hqspi, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00673   {
00674     return QSPI_ERROR;
00675   }
00676   
00677   return QSPI_OK;
00678 }
00679 
00680 /**
00681   * @brief  This function send a Write Enable and wait it is effective.
00682   * @param  hqspi: QSPI handle
00683   */
00684 static uint8_t QSPI_WriteEnable(QSPI_HandleTypeDef *hqspi)
00685 {
00686   QSPI_CommandTypeDef     s_command;
00687   QSPI_AutoPollingTypeDef s_config;
00688 
00689   /* Enable write operations */
00690   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00691   s_command.Instruction       = WRITE_ENABLE_CMD;
00692   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00693   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00694   s_command.DataMode          = QSPI_DATA_NONE;
00695   s_command.DummyCycles       = 0;
00696   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00697   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00698   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00699 
00700   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00701   {
00702     return QSPI_ERROR;
00703   }
00704   
00705   /* Configure automatic polling mode to wait for write enabling */  
00706   s_config.Match           = N25Q128A_SR_WREN;
00707   s_config.Mask            = N25Q128A_SR_WREN;
00708   s_config.MatchMode       = QSPI_MATCH_MODE_AND;
00709   s_config.StatusBytesSize = 1;
00710   s_config.Interval        = 0x10;
00711   s_config.AutomaticStop   = QSPI_AUTOMATIC_STOP_ENABLE;
00712 
00713   s_command.Instruction    = READ_STATUS_REG_CMD;
00714   s_command.DataMode       = QSPI_DATA_1_LINE;
00715 
00716   if (HAL_QSPI_AutoPolling(hqspi, &s_command, &s_config, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00717   {
00718     return QSPI_ERROR;
00719   }
00720 
00721   return QSPI_OK;
00722 }
00723 
00724 /**
00725   * @brief  This function read the SR of the memory and wait the EOP.
00726   * @param  hqspi: QSPI handle
00727   * @param  Timeout: timeout value before returning an error
00728   */
00729 static uint8_t QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi, uint32_t Timeout)
00730 {
00731   QSPI_CommandTypeDef     s_command;
00732   QSPI_AutoPollingTypeDef s_config;
00733 
00734   /* Configure automatic polling mode to wait for memory ready */  
00735   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00736   s_command.Instruction       = READ_STATUS_REG_CMD;
00737   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00738   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00739   s_command.DataMode          = QSPI_DATA_1_LINE;
00740   s_command.DummyCycles       = 0;
00741   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00742   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00743   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00744 
00745   s_config.Match           = 0;
00746   s_config.Mask            = N25Q128A_SR_WIP;
00747   s_config.MatchMode       = QSPI_MATCH_MODE_AND;
00748   s_config.StatusBytesSize = 1;
00749   s_config.Interval        = 0x10;
00750   s_config.AutomaticStop   = QSPI_AUTOMATIC_STOP_ENABLE;
00751 
00752   if (HAL_QSPI_AutoPolling(hqspi, &s_command, &s_config, Timeout) != HAL_OK)
00753   {
00754     return QSPI_ERROR;
00755   }
00756 
00757   return QSPI_OK;
00758 }
00759 /**
00760   * @}
00761   */
00762 
00763 /**
00764   * @}
00765   */
00766 
00767 /**
00768   * @}
00769   */
00770 
00771 /**
00772   * @}
00773   */
00774 
00775 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
00776 
Generated on Wed Jan 13 2016 10:58:45 for STM32F469I-Discovery BSP User Manual by   doxygen 1.7.6.1