Felipe Gomes / BSP_DISCO_F469NI

Dependents:   Aprendendo Final_v3

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32469i_discovery_qspi.c Source File

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.1
00006   * @date    29-September-2015
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 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 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 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   * @param  None  
00461   * @retval QSPI memory status
00462   */
00463 uint8_t BSP_QSPI_MemoryMappedMode(void)
00464 {
00465   QSPI_CommandTypeDef      s_command;
00466   QSPI_MemoryMappedTypeDef s_mem_mapped_cfg;
00467 
00468   /* Configure the command for the read instruction */
00469   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00470   s_command.Instruction       = QUAD_INOUT_FAST_READ_CMD;
00471   s_command.AddressMode       = QSPI_ADDRESS_4_LINES;
00472   s_command.AddressSize       = QSPI_ADDRESS_24_BITS;
00473   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00474   s_command.DataMode          = QSPI_DATA_4_LINES;
00475   s_command.DummyCycles       = N25Q128A_DUMMY_CYCLES_READ_QUAD;
00476   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00477   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00478   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00479   
00480   /* Configure the memory mapped mode */
00481   s_mem_mapped_cfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_ENABLE;
00482   s_mem_mapped_cfg.TimeOutPeriod     = 100;
00483   
00484   if (HAL_QSPI_MemoryMapped(&QSPIHandle, &s_command, &s_mem_mapped_cfg) != HAL_OK)
00485   {
00486     return QSPI_ERROR;
00487   }
00488 
00489   return QSPI_OK;
00490 }
00491 
00492 /**
00493   * @}
00494   */
00495 
00496 /** @addtogroup STM32446E_Discovery_QSPI_Private_Functions
00497   * @{
00498   */
00499 
00500 /**
00501   * @brief QSPI MSP Initialization
00502   *        This function configures the hardware resources used in this example:
00503   *           - Peripheral's clock enable
00504   *           - Peripheral's GPIO Configuration
00505   *           - NVIC configuration for QSPI interrupt
00506   * @retval None
00507   */
00508 __weak void BSP_QSPI_MspInit(QSPI_HandleTypeDef *hqspi, void *Params)
00509 {
00510   GPIO_InitTypeDef gpio_init_structure;
00511 
00512   /*##-1- Enable peripherals and GPIO Clocks #################################*/
00513   /* Enable the QuadSPI memory interface clock */
00514   QSPI_CLK_ENABLE();
00515   /* Reset the QuadSPI memory interface */
00516   QSPI_FORCE_RESET();
00517   QSPI_RELEASE_RESET();
00518   /* Enable GPIO clocks */
00519   QSPI_CS_GPIO_CLK_ENABLE();
00520   QSPI_DX_CLK_GPIO_CLK_ENABLE();
00521 
00522   /*##-2- Configure peripheral GPIO ##########################################*/
00523   /* QSPI CS GPIO pin configuration  */
00524   gpio_init_structure.Pin       = QSPI_CS_PIN;
00525   gpio_init_structure.Mode      = GPIO_MODE_AF_PP;
00526   gpio_init_structure.Pull      = GPIO_PULLUP;
00527   gpio_init_structure.Speed     = GPIO_SPEED_HIGH;
00528   gpio_init_structure.Alternate = GPIO_AF10_QSPI;
00529   HAL_GPIO_Init(QSPI_CS_GPIO_PORT, &gpio_init_structure);
00530 
00531   /* QSPI CLK GPIO pin configuration  */
00532   gpio_init_structure.Pin       = QSPI_CLK_PIN;
00533   gpio_init_structure.Pull      = GPIO_NOPULL;
00534   gpio_init_structure.Alternate = GPIO_AF9_QSPI;
00535   HAL_GPIO_Init(QSPI_CLK_GPIO_PORT, &gpio_init_structure);
00536 
00537   /* QSPI D0 and D1 GPIO pin configuration  */
00538   gpio_init_structure.Pin       = (QSPI_D0_PIN | QSPI_D1_PIN);
00539   gpio_init_structure.Alternate = GPIO_AF10_QSPI;
00540   HAL_GPIO_Init(QSPI_DX_GPIO_PORT, &gpio_init_structure);
00541 
00542   /* QSPI D2 and D3 GPIO pin configuration  */
00543   gpio_init_structure.Pin       = (QSPI_D2_PIN | QSPI_D3_PIN) ;
00544   gpio_init_structure.Alternate = GPIO_AF9_QSPI;
00545   HAL_GPIO_Init(QSPI_DX_GPIO_PORT, &gpio_init_structure);
00546 
00547   /*##-3- Configure the NVIC for QSPI #########################################*/
00548   /* NVIC configuration for QSPI interrupt */
00549   HAL_NVIC_SetPriority(QUADSPI_IRQn, 0x0F, 0);
00550   HAL_NVIC_EnableIRQ(QUADSPI_IRQn);
00551 
00552 }
00553 
00554 /**
00555   * @brief QSPI MSP De-Initialization
00556   *        This function frees the hardware resources used in this example:
00557   *          - Disable the Peripheral's clock
00558   *          - Revert GPIO and NVIC configuration to their default state
00559   * @retval None
00560   */
00561 __weak void BSP_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi, void *Params)
00562 {
00563   /*##-1- Disable the NVIC for QSPI ###########################################*/
00564   HAL_NVIC_DisableIRQ(QUADSPI_IRQn);
00565 
00566   /*##-2- Disable peripherals and GPIO Clocks ################################*/
00567   /* De-Configure QSPI pins */
00568   HAL_GPIO_DeInit(QSPI_CS_GPIO_PORT, QSPI_CS_PIN);
00569   HAL_GPIO_DeInit(QSPI_CLK_GPIO_PORT, QSPI_CLK_PIN);
00570   HAL_GPIO_DeInit(QSPI_DX_GPIO_PORT, QSPI_D0_PIN);
00571   HAL_GPIO_DeInit(QSPI_DX_GPIO_PORT, QSPI_D1_PIN);
00572   HAL_GPIO_DeInit(QSPI_DX_GPIO_PORT, QSPI_D2_PIN);
00573   HAL_GPIO_DeInit(QSPI_DX_GPIO_PORT, QSPI_D3_PIN);
00574 
00575   /*##-3- Reset peripherals ##################################################*/
00576   /* Reset the QuadSPI memory interface */
00577   QSPI_FORCE_RESET();
00578   QSPI_RELEASE_RESET();
00579 
00580   /* Disable the QuadSPI memory interface clock */
00581   QSPI_CLK_DISABLE();
00582 }
00583 
00584 /**
00585   * @brief  This function reset the QSPI memory.
00586   * @param  hqspi: QSPI handle
00587   * @retval None
00588   */
00589 static uint8_t QSPI_ResetMemory(QSPI_HandleTypeDef *hqspi)
00590 {
00591   QSPI_CommandTypeDef s_command;
00592 
00593   /* Initialize the reset enable command */
00594   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00595   s_command.Instruction       = RESET_ENABLE_CMD;
00596   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00597   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00598   s_command.DataMode          = QSPI_DATA_NONE;
00599   s_command.DummyCycles       = 0;
00600   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00601   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00602   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00603 
00604   /* Send the command */
00605   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00606   {
00607     return QSPI_ERROR;
00608   }
00609 
00610   /* Send the reset memory command */
00611   s_command.Instruction = RESET_MEMORY_CMD;
00612   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00613   {
00614     return QSPI_ERROR;
00615   }
00616 
00617   /* Configure automatic polling mode to wait the memory is ready */  
00618   if (QSPI_AutoPollingMemReady(hqspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
00619   {
00620     return QSPI_ERROR;
00621   }
00622 
00623   return QSPI_OK;
00624 }
00625 
00626 /**
00627   * @brief  This function configure the dummy cycles on memory side.
00628   * @param  hqspi: QSPI handle
00629   * @retval None
00630   */
00631 static uint8_t QSPI_DummyCyclesCfg(QSPI_HandleTypeDef *hqspi)
00632 {
00633   QSPI_CommandTypeDef s_command;
00634   uint8_t reg;
00635 
00636   /* Initialize the read volatile configuration register command */
00637   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00638   s_command.Instruction       = READ_VOL_CFG_REG_CMD;
00639   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00640   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00641   s_command.DataMode          = QSPI_DATA_1_LINE;
00642   s_command.DummyCycles       = 0;
00643   s_command.NbData            = 1;
00644   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00645   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00646   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00647 
00648   /* Configure the command */
00649   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00650   {
00651     return QSPI_ERROR;
00652   }
00653 
00654   /* Reception of the data */
00655   if (HAL_QSPI_Receive(hqspi, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00656   {
00657     return QSPI_ERROR;
00658   }
00659 
00660   /* Enable write operations */
00661   if (QSPI_WriteEnable(hqspi) != QSPI_OK)
00662   {
00663     return QSPI_ERROR;
00664   }
00665 
00666   /* Update volatile configuration register (with new dummy cycles) */  
00667   s_command.Instruction = WRITE_VOL_CFG_REG_CMD;
00668   MODIFY_REG(reg, N25Q128A_VCR_NB_DUMMY, (N25Q128A_DUMMY_CYCLES_READ_QUAD << POSITION_VAL(N25Q128A_VCR_NB_DUMMY)));
00669       
00670   /* Configure the write volatile configuration register command */
00671   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00672   {
00673     return QSPI_ERROR;
00674   }
00675 
00676   /* Transmission of the data */
00677   if (HAL_QSPI_Transmit(hqspi, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00678   {
00679     return QSPI_ERROR;
00680   }
00681   
00682   return QSPI_OK;
00683 }
00684 
00685 /**
00686   * @brief  This function send a Write Enable and wait it is effective.
00687   * @param  hqspi: QSPI handle
00688   * @retval None
00689   */
00690 static uint8_t QSPI_WriteEnable(QSPI_HandleTypeDef *hqspi)
00691 {
00692   QSPI_CommandTypeDef     s_command;
00693   QSPI_AutoPollingTypeDef s_config;
00694 
00695   /* Enable write operations */
00696   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00697   s_command.Instruction       = WRITE_ENABLE_CMD;
00698   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00699   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00700   s_command.DataMode          = QSPI_DATA_NONE;
00701   s_command.DummyCycles       = 0;
00702   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00703   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00704   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00705 
00706   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00707   {
00708     return QSPI_ERROR;
00709   }
00710   
00711   /* Configure automatic polling mode to wait for write enabling */  
00712   s_config.Match           = N25Q128A_SR_WREN;
00713   s_config.Mask            = N25Q128A_SR_WREN;
00714   s_config.MatchMode       = QSPI_MATCH_MODE_AND;
00715   s_config.StatusBytesSize = 1;
00716   s_config.Interval        = 0x10;
00717   s_config.AutomaticStop   = QSPI_AUTOMATIC_STOP_ENABLE;
00718 
00719   s_command.Instruction    = READ_STATUS_REG_CMD;
00720   s_command.DataMode       = QSPI_DATA_1_LINE;
00721 
00722   if (HAL_QSPI_AutoPolling(hqspi, &s_command, &s_config, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00723   {
00724     return QSPI_ERROR;
00725   }
00726 
00727   return QSPI_OK;
00728 }
00729 
00730 /**
00731   * @brief  This function read the SR of the memory and wait the EOP.
00732   * @param  hqspi: QSPI handle
00733   * @param  Timeout: timeout value before returning an error
00734   * @retval None
00735   */
00736 static uint8_t QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi, uint32_t Timeout)
00737 {
00738   QSPI_CommandTypeDef     s_command;
00739   QSPI_AutoPollingTypeDef s_config;
00740 
00741   /* Configure automatic polling mode to wait for memory ready */  
00742   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00743   s_command.Instruction       = READ_STATUS_REG_CMD;
00744   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00745   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00746   s_command.DataMode          = QSPI_DATA_1_LINE;
00747   s_command.DummyCycles       = 0;
00748   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00749   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00750   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00751 
00752   s_config.Match           = 0;
00753   s_config.Mask            = N25Q128A_SR_WIP;
00754   s_config.MatchMode       = QSPI_MATCH_MODE_AND;
00755   s_config.StatusBytesSize = 1;
00756   s_config.Interval        = 0x10;
00757   s_config.AutomaticStop   = QSPI_AUTOMATIC_STOP_ENABLE;
00758 
00759   if (HAL_QSPI_AutoPolling(hqspi, &s_command, &s_config, Timeout) != HAL_OK)
00760   {
00761     return QSPI_ERROR;
00762   }
00763 
00764   return QSPI_OK;
00765 }
00766 /**
00767   * @}
00768   */
00769 
00770 /**
00771   * @}
00772   */
00773 
00774 /**
00775   * @}
00776   */
00777 
00778 /**
00779   * @}
00780   */
00781 
00782 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
00783