STM32746G-Discovery board drivers V1.0.0

Dependents:   F746_SD_GraphicEqualizer_ren0620

Fork of BSP_DISCO_F746NG by ST

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32746g_discovery_qspi.c Source File

stm32746g_discovery_qspi.c

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