STM32746G-Discovery board drivers V1.0.0

Dependents:   DISCO-F746NG_LCDTS_CC3000_NTP DISCO-F746NG_ROPE_WIFI F746_SpectralAnalysis_NoPhoto ecte433 ... more

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   * @brief   This file includes a standard driver for the N25Q128A QSPI
00006   *          memory mounted on STM32746G-Discovery board.
00007   @verbatim
00008   ==============================================================================
00009                      ##### How to use this driver #####
00010   ==============================================================================  
00011   [..] 
00012    (#) This driver is used to drive the N25Q128A QSPI external
00013        memory mounted on STM32746G-Discovery board.
00014        
00015    (#) This driver need a specific component driver (N25Q128A) to be included with.
00016 
00017    (#) Initialization steps:
00018        (++) Initialize the QPSI external memory using the BSP_QSPI_Init() function. This 
00019             function includes the MSP layer hardware resources initialization and the
00020             QSPI interface with the external memory.
00021   
00022    (#) QSPI memory operations
00023        (++) QSPI memory can be accessed with read/write operations once it is
00024             initialized.
00025             Read/write operation can be performed with AHB access using the functions
00026             BSP_QSPI_Read()/BSP_QSPI_Write(). 
00027        (++) The function BSP_QSPI_GetInfo() returns the configuration of the QSPI memory. 
00028             (see the QSPI memory data sheet)
00029        (++) Perform erase block operation using the function BSP_QSPI_Erase_Block() and by
00030             specifying the block address. You can perform an erase operation of the whole 
00031             chip by calling the function BSP_QSPI_Erase_Chip(). 
00032        (++) The function BSP_QSPI_GetStatus() returns the current status of the QSPI memory. 
00033             (see the QSPI memory data sheet)
00034   @endverbatim
00035   ******************************************************************************
00036   * @attention
00037   *
00038   * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
00039   *
00040   * Redistribution and use in source and binary forms, with or without modification,
00041   * are permitted provided that the following conditions are met:
00042   *   1. Redistributions of source code must retain the above copyright notice,
00043   *      this list of conditions and the following disclaimer.
00044   *   2. Redistributions in binary form must reproduce the above copyright notice,
00045   *      this list of conditions and the following disclaimer in the documentation
00046   *      and/or other materials provided with the distribution.
00047   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00048   *      may be used to endorse or promote products derived from this software
00049   *      without specific prior written permission.
00050   *
00051   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00052   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00053   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00054   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00055   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00056   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00057   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00058   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00059   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00060   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00061   *
00062   ******************************************************************************
00063   */ 
00064 
00065 /* Dependencies
00066 - stm32f7xx_hal_qspi.c
00067 - stm32f7xx_hal_gpio.c
00068 - stm32f7xx_hal_cortex.c
00069 - stm32f7xx_hal_rcc_ex.h
00070 - n25q128a.h
00071 EndDependencies */
00072 
00073 /* Includes ------------------------------------------------------------------*/
00074 #include "stm32746g_discovery_qspi.h"
00075 
00076 /** @addtogroup BSP
00077   * @{
00078   */
00079 
00080 /** @addtogroup STM32746G_DISCOVERY
00081   * @{
00082   */ 
00083   
00084 /** @defgroup STM32746G_DISCOVERY_QSPI STM32746G-Discovery QSPI
00085   * @{
00086   */ 
00087 
00088 
00089 /* Private variables ---------------------------------------------------------*/
00090 
00091 /** @defgroup STM32746G_DISCOVERY_QSPI_Private_Variables STM32746G_DISCOVERY QSPI Private Variables
00092   * @{
00093   */       
00094 QSPI_HandleTypeDef QSPIHandle;
00095 
00096 /**
00097   * @}
00098   */ 
00099 
00100 
00101 
00102 /* Private functions ---------------------------------------------------------*/
00103     
00104 /** @defgroup STM32746G_DISCOVERY_QSPI_Private_Functions STM32746G_DISCOVERY QSPI Private Functions
00105   * @{
00106   */ 
00107 static uint8_t QSPI_ResetMemory          (QSPI_HandleTypeDef *hqspi);
00108 static uint8_t QSPI_DummyCyclesCfg       (QSPI_HandleTypeDef *hqspi);
00109 static uint8_t QSPI_WriteEnable          (QSPI_HandleTypeDef *hqspi);
00110 static uint8_t QSPI_AutoPollingMemReady  (QSPI_HandleTypeDef *hqspi, uint32_t Timeout);
00111 
00112 /**
00113   * @}
00114   */
00115     
00116 /** @defgroup STM32746G_DISCOVERY_QSPI_Exported_Functions STM32746G_DISCOVERY QSPI Exported Functions
00117   * @{
00118   */ 
00119 
00120 /**
00121   * @brief  Initializes the QSPI interface.
00122   * @retval QSPI memory status
00123   */
00124 uint8_t BSP_QSPI_Init(void)
00125 { 
00126   QSPIHandle.Instance = QUADSPI;
00127 
00128   /* Call the DeInit function to reset the driver */
00129   if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK)
00130   {
00131     return QSPI_ERROR;
00132   }
00133         
00134   /* System level initialization */
00135   BSP_QSPI_MspInit(&QSPIHandle, NULL);
00136   
00137   /* QSPI initialization */
00138   QSPIHandle.Init.ClockPrescaler     = 1; /* QSPI freq = 216 MHz/(1+1) = 108 Mhz */
00139   QSPIHandle.Init.FifoThreshold      = 4;
00140   QSPIHandle.Init.SampleShifting     = QSPI_SAMPLE_SHIFTING_HALFCYCLE;
00141   QSPIHandle.Init.FlashSize          = POSITION_VAL(N25Q128A_FLASH_SIZE) - 1;
00142   QSPIHandle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_6_CYCLE; /* Min 50ns for nonRead */
00143   QSPIHandle.Init.ClockMode          = QSPI_CLOCK_MODE_0;
00144   QSPIHandle.Init.FlashID            = QSPI_FLASH_ID_1;
00145   QSPIHandle.Init.DualFlash          = QSPI_DUALFLASH_DISABLE;
00146 
00147   if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK)
00148   {
00149     return QSPI_ERROR;
00150   }
00151 
00152   /* QSPI memory reset */
00153   if (QSPI_ResetMemory(&QSPIHandle) != QSPI_OK)
00154   {
00155     return QSPI_NOT_SUPPORTED;
00156   }
00157  
00158   /* Configuration of the dummy cycles on QSPI memory side */
00159   if (QSPI_DummyCyclesCfg(&QSPIHandle) != QSPI_OK)
00160   {
00161     return QSPI_NOT_SUPPORTED;
00162   }
00163   
00164   return QSPI_OK;
00165 }
00166 
00167 /**
00168   * @brief  De-Initializes the QSPI interface.
00169   * @retval QSPI memory status
00170   */
00171 uint8_t BSP_QSPI_DeInit(void)
00172 { 
00173   QSPIHandle.Instance = QUADSPI;
00174 
00175   /* Call the DeInit function to reset the driver */
00176   if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK)
00177   {
00178     return QSPI_ERROR;
00179   }
00180         
00181   /* System level De-initialization */
00182   BSP_QSPI_MspDeInit(&QSPIHandle, NULL);
00183   
00184   return QSPI_OK;
00185 }
00186 
00187 /**
00188   * @brief  Reads an amount of data from the QSPI memory.
00189   * @param  pData: Pointer to data to be read
00190   * @param  ReadAddr: Read start address
00191   * @param  Size: Size of data to read    
00192   * @retval QSPI memory status
00193   */
00194 uint8_t BSP_QSPI_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size)
00195 {
00196   QSPI_CommandTypeDef s_command;
00197 
00198   /* Initialize the read command */
00199   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00200   s_command.Instruction       = QUAD_INOUT_FAST_READ_CMD;
00201   s_command.AddressMode       = QSPI_ADDRESS_4_LINES;
00202   s_command.AddressSize       = QSPI_ADDRESS_24_BITS;
00203   s_command.Address           = ReadAddr;
00204   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00205   s_command.DataMode          = QSPI_DATA_4_LINES;
00206   s_command.DummyCycles       = N25Q128A_DUMMY_CYCLES_READ_QUAD;
00207   s_command.NbData            = Size;
00208   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00209   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00210   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00211   
00212   /* Configure the command */
00213   if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00214   {
00215     return QSPI_ERROR;
00216   }
00217   
00218   /* Set S# timing for Read command */
00219   MODIFY_REG(QSPIHandle.Instance->DCR, QUADSPI_DCR_CSHT, QSPI_CS_HIGH_TIME_3_CYCLE);
00220   
00221   /* Reception of the data */
00222   if (HAL_QSPI_Receive(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00223   {
00224     return QSPI_ERROR;
00225   }
00226   
00227   /* Restore S# timing for nonRead commands */
00228   MODIFY_REG(QSPIHandle.Instance->DCR, QUADSPI_DCR_CSHT, QSPI_CS_HIGH_TIME_6_CYCLE);
00229 
00230   return QSPI_OK;
00231 }
00232 
00233 /**
00234   * @brief  Writes an amount of data to the QSPI memory.
00235   * @param  pData: Pointer to data to be written
00236   * @param  WriteAddr: Write start address
00237   * @param  Size: Size of data to write    
00238   * @retval QSPI memory status
00239   */
00240 uint8_t BSP_QSPI_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size)
00241 {
00242   QSPI_CommandTypeDef s_command;
00243   uint32_t end_addr, current_size, current_addr;
00244 
00245   /* Calculation of the size between the write address and the end of the page */
00246   current_size = N25Q128A_PAGE_SIZE - (WriteAddr % N25Q128A_PAGE_SIZE);
00247 
00248   /* Check if the size of the data is less than the remaining place in the page */
00249   if (current_size > Size)
00250   {
00251     current_size = Size;
00252   }
00253 
00254   /* Initialize the adress variables */
00255   current_addr = WriteAddr;
00256   end_addr = WriteAddr + Size;
00257 
00258   /* Initialize the program command */
00259   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00260   s_command.Instruction       = EXT_QUAD_IN_FAST_PROG_CMD;
00261   s_command.AddressMode       = QSPI_ADDRESS_4_LINES;
00262   s_command.AddressSize       = QSPI_ADDRESS_24_BITS;
00263   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00264   s_command.DataMode          = QSPI_DATA_4_LINES;
00265   s_command.DummyCycles       = 0;
00266   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00267   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00268   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00269   
00270   /* Perform the write page by page */
00271   do
00272   {
00273     s_command.Address = current_addr;
00274     s_command.NbData  = current_size;
00275 
00276     /* Enable write operations */
00277     if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
00278     {
00279       return QSPI_ERROR;
00280     }
00281     
00282     /* Configure the command */
00283     if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00284     {
00285       return QSPI_ERROR;
00286     }
00287     
00288     /* Transmission of the data */
00289     if (HAL_QSPI_Transmit(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00290     {
00291       return QSPI_ERROR;
00292     }
00293     
00294     /* Configure automatic polling mode to wait for end of program */  
00295     if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
00296     {
00297       return QSPI_ERROR;
00298     }
00299     
00300     /* Update the address and size variables for next page programming */
00301     current_addr += current_size;
00302     pData += current_size;
00303     current_size = ((current_addr + N25Q128A_PAGE_SIZE) > end_addr) ? (end_addr - current_addr) : N25Q128A_PAGE_SIZE;
00304   } while (current_addr < end_addr);
00305   
00306   return QSPI_OK;
00307 }
00308 
00309 /**
00310   * @brief  Erases the specified block of the QSPI memory. 
00311   * @param  BlockAddress: Block address to erase  
00312   * @retval QSPI memory status
00313   */
00314 uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress)
00315 {
00316   QSPI_CommandTypeDef s_command;
00317 
00318   /* Initialize the erase command */
00319   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00320   s_command.Instruction       = SUBSECTOR_ERASE_CMD;
00321   s_command.AddressMode       = QSPI_ADDRESS_1_LINE;
00322   s_command.AddressSize       = QSPI_ADDRESS_24_BITS;
00323   s_command.Address           = BlockAddress;
00324   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00325   s_command.DataMode          = QSPI_DATA_NONE;
00326   s_command.DummyCycles       = 0;
00327   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00328   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00329   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00330 
00331   /* Enable write operations */
00332   if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
00333   {
00334     return QSPI_ERROR;
00335   }
00336 
00337   /* Send the command */
00338   if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00339   {
00340     return QSPI_ERROR;
00341   }
00342   
00343   /* Configure automatic polling mode to wait for end of erase */  
00344   if (QSPI_AutoPollingMemReady(&QSPIHandle, N25Q128A_SUBSECTOR_ERASE_MAX_TIME) != QSPI_OK)
00345   {
00346     return QSPI_ERROR;
00347   }
00348 
00349   return QSPI_OK;
00350 }
00351 
00352 /**
00353   * @brief  Erases the entire QSPI memory.
00354   * @retval QSPI memory status
00355   */
00356 uint8_t BSP_QSPI_Erase_Chip(void)
00357 {
00358   QSPI_CommandTypeDef s_command;
00359 
00360   /* Initialize the erase command */
00361   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00362   s_command.Instruction       = BULK_ERASE_CMD;
00363   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00364   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00365   s_command.DataMode          = QSPI_DATA_NONE;
00366   s_command.DummyCycles       = 0;
00367   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00368   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00369   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00370 
00371   /* Enable write operations */
00372   if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
00373   {
00374     return QSPI_ERROR;
00375   }
00376 
00377   /* Send the command */
00378   if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00379   {
00380     return QSPI_ERROR;
00381   }
00382   
00383   /* Configure automatic polling mode to wait for end of erase */  
00384   if (QSPI_AutoPollingMemReady(&QSPIHandle, N25Q128A_BULK_ERASE_MAX_TIME) != QSPI_OK)
00385   {
00386     return QSPI_ERROR;
00387   }
00388 
00389   return QSPI_OK;
00390 }
00391 
00392 /**
00393   * @brief  Reads current status of the QSPI memory.
00394   * @retval QSPI memory status
00395   */
00396 uint8_t BSP_QSPI_GetStatus(void)
00397 {
00398   QSPI_CommandTypeDef s_command;
00399   uint8_t reg;
00400 
00401   /* Initialize the read flag status register command */
00402   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00403   s_command.Instruction       = READ_FLAG_STATUS_REG_CMD;
00404   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00405   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00406   s_command.DataMode          = QSPI_DATA_1_LINE;
00407   s_command.DummyCycles       = 0;
00408   s_command.NbData            = 1;
00409   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00410   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00411   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00412 
00413   /* Configure the command */
00414   if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00415   {
00416     return QSPI_ERROR;
00417   }
00418 
00419   /* Reception of the data */
00420   if (HAL_QSPI_Receive(&QSPIHandle, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00421   {
00422     return QSPI_ERROR;
00423   }
00424   
00425   /* Check the value of the register */
00426   if ((reg & (N25Q128A_FSR_PRERR | N25Q128A_FSR_VPPERR | N25Q128A_FSR_PGERR | N25Q128A_FSR_ERERR)) != 0)
00427   {
00428     return QSPI_ERROR;
00429   }
00430   else if ((reg & (N25Q128A_FSR_PGSUS | N25Q128A_FSR_ERSUS)) != 0)
00431   {
00432     return QSPI_SUSPENDED;
00433   }
00434   else if ((reg & N25Q128A_FSR_READY) != 0)
00435   {
00436     return QSPI_OK;
00437   }
00438   else
00439   {
00440     return QSPI_BUSY;
00441   }
00442 }
00443 
00444 /**
00445   * @brief  Return the configuration of the QSPI memory.
00446   * @param  pInfo: pointer on the configuration structure  
00447   * @retval QSPI memory status
00448   */
00449 uint8_t BSP_QSPI_GetInfo(QSPI_Info* pInfo)
00450 {
00451   /* Configure the structure with the memory configuration */
00452   pInfo->FlashSize          = N25Q128A_FLASH_SIZE;
00453   pInfo->EraseSectorSize    = N25Q128A_SUBSECTOR_SIZE;
00454   pInfo->EraseSectorsNumber = (N25Q128A_FLASH_SIZE/N25Q128A_SUBSECTOR_SIZE);
00455   pInfo->ProgPageSize       = N25Q128A_PAGE_SIZE;
00456   pInfo->ProgPagesNumber    = (N25Q128A_FLASH_SIZE/N25Q128A_PAGE_SIZE);
00457   
00458   return QSPI_OK;
00459 }
00460 
00461 /**
00462   * @brief  Configure the QSPI in memory-mapped mode
00463   * @retval QSPI memory status
00464   */
00465 uint8_t BSP_QSPI_EnableMemoryMappedMode(void)
00466 {
00467   QSPI_CommandTypeDef      s_command;
00468   QSPI_MemoryMappedTypeDef s_mem_mapped_cfg;
00469 
00470   /* Configure the command for the read instruction */
00471   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00472   s_command.Instruction       = QUAD_INOUT_FAST_READ_CMD;
00473   s_command.AddressMode       = QSPI_ADDRESS_4_LINES;
00474   s_command.AddressSize       = QSPI_ADDRESS_24_BITS;
00475   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00476   s_command.DataMode          = QSPI_DATA_4_LINES;
00477   s_command.DummyCycles       = N25Q128A_DUMMY_CYCLES_READ_QUAD;
00478   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00479   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00480   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00481   
00482   /* Configure the memory mapped mode */
00483   s_mem_mapped_cfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE;
00484   s_mem_mapped_cfg.TimeOutPeriod     = 0;
00485   
00486   if (HAL_QSPI_MemoryMapped(&QSPIHandle, &s_command, &s_mem_mapped_cfg) != HAL_OK)
00487   {
00488     return QSPI_ERROR;
00489   }
00490 
00491   return QSPI_OK;
00492 }
00493 
00494 /**
00495   * @}
00496   */
00497 
00498 /** @addtogroup STM32746G_DISCOVERY_QSPI_Private_Functions
00499   * @{
00500   */ 
00501 
00502 /**
00503   * @brief QSPI MSP Initialization
00504   *        This function configures the hardware resources used in this example:
00505   *           - Peripheral's clock enable
00506   *           - Peripheral's GPIO Configuration
00507   *           - NVIC configuration for QSPI interrupt
00508   * @retval None
00509   */
00510 __weak void BSP_QSPI_MspInit(QSPI_HandleTypeDef *hqspi, void *Params)
00511 {
00512   GPIO_InitTypeDef gpio_init_structure;
00513 
00514   /*##-1- Enable peripherals and GPIO Clocks #################################*/
00515   /* Enable the QuadSPI memory interface clock */
00516   QSPI_CLK_ENABLE();
00517   /* Reset the QuadSPI memory interface */
00518   QSPI_FORCE_RESET();
00519   QSPI_RELEASE_RESET();
00520   /* Enable GPIO clocks */
00521   QSPI_CS_GPIO_CLK_ENABLE();
00522   QSPI_CLK_GPIO_CLK_ENABLE();
00523   QSPI_D0_GPIO_CLK_ENABLE();
00524   QSPI_D1_GPIO_CLK_ENABLE();
00525   QSPI_D2_GPIO_CLK_ENABLE();
00526   QSPI_D3_GPIO_CLK_ENABLE();
00527 
00528   /*##-2- Configure peripheral GPIO ##########################################*/
00529   /* QSPI CS GPIO pin configuration  */
00530   gpio_init_structure.Pin       = QSPI_CS_PIN;
00531   gpio_init_structure.Mode      = GPIO_MODE_AF_PP;
00532   gpio_init_structure.Pull      = GPIO_PULLUP;
00533   gpio_init_structure.Speed     = GPIO_SPEED_HIGH;
00534   gpio_init_structure.Alternate = GPIO_AF10_QUADSPI;
00535   HAL_GPIO_Init(QSPI_CS_GPIO_PORT, &gpio_init_structure);
00536 
00537   /* QSPI CLK GPIO pin configuration  */
00538   gpio_init_structure.Pin       = QSPI_CLK_PIN;
00539   gpio_init_structure.Pull      = GPIO_NOPULL;
00540   gpio_init_structure.Alternate = GPIO_AF9_QUADSPI;
00541   HAL_GPIO_Init(QSPI_CLK_GPIO_PORT, &gpio_init_structure);
00542 
00543   /* QSPI D0 GPIO pin configuration  */
00544   gpio_init_structure.Pin       = QSPI_D0_PIN;
00545   gpio_init_structure.Alternate = GPIO_AF9_QUADSPI;
00546   HAL_GPIO_Init(QSPI_D0_GPIO_PORT, &gpio_init_structure);
00547 
00548   /* QSPI D1 GPIO pin configuration  */
00549   gpio_init_structure.Pin       = QSPI_D1_PIN;
00550   gpio_init_structure.Alternate = GPIO_AF9_QUADSPI;
00551   HAL_GPIO_Init(QSPI_D1_GPIO_PORT, &gpio_init_structure);
00552 
00553   /* QSPI D2 GPIO pin configuration  */
00554   gpio_init_structure.Pin       = QSPI_D2_PIN;
00555   gpio_init_structure.Alternate = GPIO_AF9_QUADSPI;
00556   HAL_GPIO_Init(QSPI_D2_GPIO_PORT, &gpio_init_structure);
00557 
00558   /* QSPI D3 GPIO pin configuration  */
00559   gpio_init_structure.Pin       = QSPI_D3_PIN;
00560   gpio_init_structure.Alternate = GPIO_AF9_QUADSPI;
00561   HAL_GPIO_Init(QSPI_D3_GPIO_PORT, &gpio_init_structure);
00562 
00563   /*##-3- Configure the NVIC for QSPI #########################################*/
00564   /* NVIC configuration for QSPI interrupt */
00565   HAL_NVIC_SetPriority(QUADSPI_IRQn, 0x0F, 0);
00566   HAL_NVIC_EnableIRQ(QUADSPI_IRQn);
00567 }
00568 
00569 /**
00570   * @brief QSPI MSP De-Initialization
00571   *        This function frees the hardware resources used in this example:
00572   *          - Disable the Peripheral's clock
00573   *          - Revert GPIO and NVIC configuration to their default state
00574   * @retval None
00575   */
00576 __weak void BSP_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi, void *Params)
00577 {
00578   /*##-1- Disable the NVIC for QSPI ###########################################*/
00579   HAL_NVIC_DisableIRQ(QUADSPI_IRQn);
00580 
00581   /*##-2- Disable peripherals and GPIO Clocks ################################*/
00582   /* De-Configure QSPI pins */
00583   HAL_GPIO_DeInit(QSPI_CS_GPIO_PORT, QSPI_CS_PIN);
00584   HAL_GPIO_DeInit(QSPI_CLK_GPIO_PORT, QSPI_CLK_PIN);
00585   HAL_GPIO_DeInit(QSPI_D0_GPIO_PORT, QSPI_D0_PIN);
00586   HAL_GPIO_DeInit(QSPI_D1_GPIO_PORT, QSPI_D1_PIN);
00587   HAL_GPIO_DeInit(QSPI_D2_GPIO_PORT, QSPI_D2_PIN);
00588   HAL_GPIO_DeInit(QSPI_D3_GPIO_PORT, QSPI_D3_PIN);
00589 
00590   /*##-3- Reset peripherals ##################################################*/
00591   /* Reset the QuadSPI memory interface */
00592   QSPI_FORCE_RESET();
00593   QSPI_RELEASE_RESET();
00594 
00595   /* Disable the QuadSPI memory interface clock */
00596   QSPI_CLK_DISABLE();
00597 }
00598 
00599 /**
00600   * @brief  This function reset the QSPI memory.
00601   * @param  hqspi: QSPI handle
00602   * @retval None
00603   */
00604 static uint8_t QSPI_ResetMemory(QSPI_HandleTypeDef *hqspi)
00605 {
00606   QSPI_CommandTypeDef s_command;
00607 
00608   /* Initialize the reset enable command */
00609   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00610   s_command.Instruction       = RESET_ENABLE_CMD;
00611   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00612   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00613   s_command.DataMode          = QSPI_DATA_NONE;
00614   s_command.DummyCycles       = 0;
00615   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00616   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00617   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00618 
00619   /* Send the command */
00620   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00621   {
00622     return QSPI_ERROR;
00623   }
00624 
00625   /* Send the reset memory command */
00626   s_command.Instruction = RESET_MEMORY_CMD;
00627   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00628   {
00629     return QSPI_ERROR;
00630   }
00631 
00632   /* Configure automatic polling mode to wait the memory is ready */  
00633   if (QSPI_AutoPollingMemReady(hqspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
00634   {
00635     return QSPI_ERROR;
00636   }
00637 
00638   return QSPI_OK;
00639 }
00640 
00641 /**
00642   * @brief  This function configure the dummy cycles on memory side.
00643   * @param  hqspi: QSPI handle
00644   * @retval None
00645   */
00646 static uint8_t QSPI_DummyCyclesCfg(QSPI_HandleTypeDef *hqspi)
00647 {
00648   QSPI_CommandTypeDef s_command;
00649   uint8_t reg;
00650 
00651   /* Initialize the read volatile configuration register command */
00652   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00653   s_command.Instruction       = READ_VOL_CFG_REG_CMD;
00654   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00655   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00656   s_command.DataMode          = QSPI_DATA_1_LINE;
00657   s_command.DummyCycles       = 0;
00658   s_command.NbData            = 1;
00659   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00660   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00661   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00662 
00663   /* Configure the command */
00664   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00665   {
00666     return QSPI_ERROR;
00667   }
00668 
00669   /* Reception of the data */
00670   if (HAL_QSPI_Receive(hqspi, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00671   {
00672     return QSPI_ERROR;
00673   }
00674 
00675   /* Enable write operations */
00676   if (QSPI_WriteEnable(hqspi) != QSPI_OK)
00677   {
00678     return QSPI_ERROR;
00679   }
00680 
00681   /* Update volatile configuration register (with new dummy cycles) */  
00682   s_command.Instruction = WRITE_VOL_CFG_REG_CMD;
00683   MODIFY_REG(reg, N25Q128A_VCR_NB_DUMMY, (N25Q128A_DUMMY_CYCLES_READ_QUAD << POSITION_VAL(N25Q128A_VCR_NB_DUMMY)));
00684       
00685   /* Configure the write volatile configuration register command */
00686   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00687   {
00688     return QSPI_ERROR;
00689   }
00690 
00691   /* Transmission of the data */
00692   if (HAL_QSPI_Transmit(hqspi, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00693   {
00694     return QSPI_ERROR;
00695   }
00696   
00697   return QSPI_OK;
00698 }
00699 
00700 /**
00701   * @brief  This function send a Write Enable and wait it is effective.
00702   * @param  hqspi: QSPI handle
00703   * @retval None
00704   */
00705 static uint8_t QSPI_WriteEnable(QSPI_HandleTypeDef *hqspi)
00706 {
00707   QSPI_CommandTypeDef     s_command;
00708   QSPI_AutoPollingTypeDef s_config;
00709 
00710   /* Enable write operations */
00711   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00712   s_command.Instruction       = WRITE_ENABLE_CMD;
00713   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00714   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00715   s_command.DataMode          = QSPI_DATA_NONE;
00716   s_command.DummyCycles       = 0;
00717   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00718   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00719   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00720 
00721   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00722   {
00723     return QSPI_ERROR;
00724   }
00725   
00726   /* Configure automatic polling mode to wait for write enabling */  
00727   s_config.Match           = N25Q128A_SR_WREN;
00728   s_config.Mask            = N25Q128A_SR_WREN;
00729   s_config.MatchMode       = QSPI_MATCH_MODE_AND;
00730   s_config.StatusBytesSize = 1;
00731   s_config.Interval        = 0x10;
00732   s_config.AutomaticStop   = QSPI_AUTOMATIC_STOP_ENABLE;
00733 
00734   s_command.Instruction    = READ_STATUS_REG_CMD;
00735   s_command.DataMode       = QSPI_DATA_1_LINE;
00736 
00737   if (HAL_QSPI_AutoPolling(hqspi, &s_command, &s_config, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00738   {
00739     return QSPI_ERROR;
00740   }
00741 
00742   return QSPI_OK;
00743 }
00744 
00745 /**
00746   * @brief  This function read the SR of the memory and wait the EOP.
00747   * @param  hqspi: QSPI handle
00748   * @param  Timeout
00749   * @retval None
00750   */
00751 static uint8_t QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi, uint32_t Timeout)
00752 {
00753   QSPI_CommandTypeDef     s_command;
00754   QSPI_AutoPollingTypeDef s_config;
00755 
00756   /* Configure automatic polling mode to wait for memory ready */  
00757   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00758   s_command.Instruction       = READ_STATUS_REG_CMD;
00759   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00760   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00761   s_command.DataMode          = QSPI_DATA_1_LINE;
00762   s_command.DummyCycles       = 0;
00763   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00764   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00765   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00766 
00767   s_config.Match           = 0;
00768   s_config.Mask            = N25Q128A_SR_WIP;
00769   s_config.MatchMode       = QSPI_MATCH_MODE_AND;
00770   s_config.StatusBytesSize = 1;
00771   s_config.Interval        = 0x10;
00772   s_config.AutomaticStop   = QSPI_AUTOMATIC_STOP_ENABLE;
00773 
00774   if (HAL_QSPI_AutoPolling(hqspi, &s_command, &s_config, Timeout) != HAL_OK)
00775   {
00776     return QSPI_ERROR;
00777   }
00778 
00779   return QSPI_OK;
00780 }
00781 /**
00782   * @}
00783   */  
00784   
00785 /**
00786   * @}
00787   */ 
00788   
00789 /**
00790   * @}
00791   */ 
00792   
00793 /**
00794   * @}
00795   */ 
00796 
00797 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
00798