STM32769I_EVAL BSP User Manual: stm32f769i_eval_qspi.c Source File

STM32769I EVAL BSP Drivers

stm32f769i_eval_qspi.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f769i_eval_qspi.c
00004   * @author  MCD Application Team
00005   * @version V2.0.0
00006   * @date    30-December-2016
00007   * @brief   This file includes a standard driver for the N25Q512A QSPI
00008   *          memory mounted on STM32F769I-EVAL board.
00009   @verbatim
00010   ==============================================================================
00011                      ##### How to use this driver #####
00012   ==============================================================================  
00013   [..] 
00014    (#) This driver is used to drive the N25Q512A QSPI external
00015        memory mounted on STM32F769I-EVAL evaluation board.
00016        
00017    (#) This driver need a specific component driver (N25Q512A) to be included with.
00018 
00019    (#) Initialization steps:
00020        (++) Initialize the QPSI external memory using the BSP_QSPI_Init() function. This 
00021             function includes the MSP layer hardware resources initialization and the
00022             QSPI interface with the external memory.
00023   
00024    (#) QSPI memory operations
00025        (++) QSPI memory can be accessed with read/write operations once it is
00026             initialized.
00027             Read/write operation can be performed with AHB access using the functions
00028             BSP_QSPI_Read()/BSP_QSPI_Write(). 
00029        (++) The function BSP_QSPI_GetInfo() returns the configuration of the QSPI memory. 
00030             (see the QSPI memory data sheet)
00031        (++) Perform erase block operation using the function BSP_QSPI_Erase_Block() and by
00032             specifying the block address. You can perform an erase operation of the whole 
00033             chip by calling the function BSP_QSPI_Erase_Chip(). 
00034        (++) The function BSP_QSPI_GetStatus() returns the current status of the QSPI memory. 
00035             (see the QSPI memory data sheet)
00036   @endverbatim
00037   ******************************************************************************
00038   * @attention
00039   *
00040   * <h2><center>&copy; COPYRIGHT(c) 2016 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 "stm32f769i_eval_qspi.h"
00069 
00070 /** @addtogroup BSP
00071   * @{
00072   */
00073 
00074 /** @addtogroup STM32F769I_EVAL
00075   * @{
00076   */ 
00077   
00078 /** @defgroup STM32F769I_EVAL_QSPI STM32F769I_EVAL QSPI
00079   * @{
00080   */ 
00081 
00082 
00083 /* Private variables ---------------------------------------------------------*/
00084 
00085 /** @defgroup STM32F769I_EVAL_QSPI_Private_Variables Private Variables
00086   * @{
00087   */       
00088 QSPI_HandleTypeDef QSPIHandle;
00089 
00090 /**
00091   * @}
00092   */ 
00093 
00094 
00095 
00096 /* Private functions ---------------------------------------------------------*/
00097     
00098 /** @defgroup STM32F769I_EVAL_QSPI_Private_Functions Private Functions
00099   * @{
00100   */ 
00101 static uint8_t QSPI_ResetMemory          (QSPI_HandleTypeDef *hqspi);
00102 static uint8_t QSPI_EnterFourBytesAddress(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 /** @defgroup STM32F769I_EVAL_QSPI_Exported_Functions Exported Functions
00112   * @{
00113   */ 
00114 
00115 /**
00116   * @brief  Initializes the QSPI interface.
00117   * @retval QSPI memory status
00118   */
00119 uint8_t BSP_QSPI_Init(void)
00120 { 
00121   QSPIHandle.Instance = QUADSPI;
00122 
00123   /* Call the DeInit function to reset the driver */
00124   if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK)
00125   {
00126     return QSPI_ERROR;
00127   }
00128         
00129   /* System level initialization */
00130   BSP_QSPI_MspInit(&QSPIHandle, NULL);
00131   
00132   /* QSPI initialization */
00133   /* QSPI freq = SYSCLK /(1 + ClockPrescaler) = 216 MHz/(1+1) = 108 Mhz */
00134   QSPIHandle.Init.ClockPrescaler     = 1; 
00135   QSPIHandle.Init.FifoThreshold      = 4;
00136   QSPIHandle.Init.SampleShifting     = QSPI_SAMPLE_SHIFTING_HALFCYCLE;
00137   QSPIHandle.Init.FlashSize          = POSITION_VAL(N25Q512A_FLASH_SIZE) - 1;
00138   QSPIHandle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_6_CYCLE; /* Min 50ns for nonRead */
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   /* Set the QSPI memory in 4-bytes address mode */
00155   if (QSPI_EnterFourBytesAddress(&QSPIHandle) != QSPI_OK)
00156   {
00157     return QSPI_NOT_SUPPORTED;
00158   }
00159  
00160   /* Configuration of the dummy cycles on QSPI memory side */
00161   if (QSPI_DummyCyclesCfg(&QSPIHandle) != QSPI_OK)
00162   {
00163     return QSPI_NOT_SUPPORTED;
00164   }
00165   
00166   return QSPI_OK;
00167 }
00168 
00169 /**
00170   * @brief  De-Initializes the QSPI interface.
00171   * @retval QSPI memory status
00172   */
00173 uint8_t BSP_QSPI_DeInit(void)
00174 { 
00175   QSPIHandle.Instance = QUADSPI;
00176 
00177   /* Call the DeInit function to reset the driver */
00178   if (HAL_QSPI_DeInit(&QSPIHandle) != HAL_OK)
00179   {
00180     return QSPI_ERROR;
00181   }
00182         
00183   /* System level De-initialization */
00184   BSP_QSPI_MspDeInit(&QSPIHandle, NULL);
00185   
00186   return QSPI_OK;
00187 }
00188 
00189 /**
00190   * @brief  Reads an amount of data from the QSPI memory.
00191   * @param  pData: Pointer to data to be read
00192   * @param  ReadAddr: Read start address
00193   * @param  Size: Size of data to read    
00194   * @retval QSPI memory status
00195   */
00196 uint8_t BSP_QSPI_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size)
00197 {
00198   QSPI_CommandTypeDef s_command;
00199 
00200   /* Initialize the read command */
00201   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00202   s_command.Instruction       = QUAD_OUT_FAST_READ_CMD;
00203   s_command.AddressMode       = QSPI_ADDRESS_1_LINE;
00204   s_command.AddressSize       = QSPI_ADDRESS_32_BITS;
00205   s_command.Address           = ReadAddr;
00206   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00207   s_command.DataMode          = QSPI_DATA_4_LINES;
00208   s_command.DummyCycles       = N25Q512A_DUMMY_CYCLES_READ_QUAD;
00209   s_command.NbData            = Size;
00210   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00211   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00212   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00213   
00214   /* Configure the command */
00215   if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00216   {
00217     return QSPI_ERROR;
00218   }
00219   
00220   /* Set S# timing for Read command */
00221   MODIFY_REG(QSPIHandle.Instance->DCR, QUADSPI_DCR_CSHT, QSPI_CS_HIGH_TIME_3_CYCLE);
00222   
00223   /* Reception of the data */
00224   if (HAL_QSPI_Receive(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00225   {
00226     return QSPI_ERROR;
00227   }
00228   
00229   /* Restore S# timing for nonRead commands */
00230   MODIFY_REG(QSPIHandle.Instance->DCR, QUADSPI_DCR_CSHT, QSPI_CS_HIGH_TIME_6_CYCLE);
00231 
00232   return QSPI_OK;
00233 }
00234 
00235 /**
00236   * @brief  Writes an amount of data to the QSPI memory.
00237   * @param  pData: Pointer to data to be written
00238   * @param  WriteAddr: Write start address
00239   * @param  Size: Size of data to write    
00240   * @retval QSPI memory status
00241   */
00242 uint8_t BSP_QSPI_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size)
00243 {
00244   QSPI_CommandTypeDef s_command;
00245   uint32_t end_addr, current_size, current_addr;
00246 
00247   /* Calculation of the size between the write address and the end of the page */
00248   current_size = N25Q512A_PAGE_SIZE - (WriteAddr % N25Q512A_PAGE_SIZE);
00249 
00250   /* Check if the size of the data is less than the remaining place in the page */
00251   if (current_size > Size)
00252   {
00253     current_size = Size;
00254   }
00255 
00256   /* Initialize the address variables */
00257   current_addr = WriteAddr;
00258   end_addr = WriteAddr + Size;
00259 
00260   /* Initialize the program command */
00261   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00262   s_command.Instruction       = QUAD_IN_FAST_PROG_CMD;
00263   s_command.AddressMode       = QSPI_ADDRESS_1_LINE;
00264   s_command.AddressSize       = QSPI_ADDRESS_32_BITS;
00265   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00266   s_command.DataMode          = QSPI_DATA_4_LINES;
00267   s_command.DummyCycles       = 0;
00268   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00269   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00270   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00271   
00272   /* Perform the write page by page */
00273   do
00274   {
00275     s_command.Address = current_addr;
00276     s_command.NbData  = current_size;
00277 
00278     /* Enable write operations */
00279     if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
00280     {
00281       return QSPI_ERROR;
00282     }
00283     
00284     /* Configure the command */
00285     if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00286     {
00287       return QSPI_ERROR;
00288     }
00289     
00290     /* Transmission of the data */
00291     if (HAL_QSPI_Transmit(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00292     {
00293       return QSPI_ERROR;
00294     }
00295     
00296     /* Configure automatic polling mode to wait for end of program */  
00297     if (QSPI_AutoPollingMemReady(&QSPIHandle, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
00298     {
00299       return QSPI_ERROR;
00300     }
00301     
00302     /* Update the address and size variables for next page programming */
00303     current_addr += current_size;
00304     pData += current_size;
00305     current_size = ((current_addr + N25Q512A_PAGE_SIZE) > end_addr) ? (end_addr - current_addr) : N25Q512A_PAGE_SIZE;
00306   } while (current_addr < end_addr);
00307   
00308   return QSPI_OK;
00309 }
00310 
00311 /**
00312   * @brief  Erases the specified block of the QSPI memory. 
00313   * @param  BlockAddress: Block address to erase  
00314   * @retval QSPI memory status
00315   */
00316 uint8_t BSP_QSPI_Erase_Block(uint32_t BlockAddress)
00317 {
00318   QSPI_CommandTypeDef s_command;
00319 
00320   /* Initialize the erase command */
00321   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00322   s_command.Instruction       = SUBSECTOR_ERASE_CMD;
00323   s_command.AddressMode       = QSPI_ADDRESS_1_LINE;
00324   s_command.AddressSize       = QSPI_ADDRESS_32_BITS;
00325   s_command.Address           = BlockAddress;
00326   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00327   s_command.DataMode          = QSPI_DATA_NONE;
00328   s_command.DummyCycles       = 0;
00329   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00330   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00331   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00332 
00333   /* Enable write operations */
00334   if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
00335   {
00336     return QSPI_ERROR;
00337   }
00338 
00339   /* Send the command */
00340   if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00341   {
00342     return QSPI_ERROR;
00343   }
00344   
00345   /* Configure automatic polling mode to wait for end of erase */  
00346   if (QSPI_AutoPollingMemReady(&QSPIHandle, N25Q512A_SUBSECTOR_ERASE_MAX_TIME) != QSPI_OK)
00347   {
00348     return QSPI_ERROR;
00349   }
00350 
00351   return QSPI_OK;
00352 }
00353 
00354 /**
00355   * @brief  Erases the entire QSPI memory.
00356   * @retval QSPI memory status
00357   */
00358 uint8_t BSP_QSPI_Erase_Chip(void)
00359 {
00360   QSPI_CommandTypeDef s_command;
00361 
00362   /* Initialize the erase command */
00363   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00364   s_command.Instruction       = BULK_ERASE_CMD;
00365   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00366   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00367   s_command.DataMode          = QSPI_DATA_NONE;
00368   s_command.DummyCycles       = 0;
00369   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00370   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00371   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00372 
00373   /* Enable write operations */
00374   if (QSPI_WriteEnable(&QSPIHandle) != QSPI_OK)
00375   {
00376     return QSPI_ERROR;
00377   }
00378 
00379   /* Send the command */
00380   if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00381   {
00382     return QSPI_ERROR;
00383   }
00384   
00385   /* Configure automatic polling mode to wait for end of erase */  
00386   if (QSPI_AutoPollingMemReady(&QSPIHandle, N25Q512A_BULK_ERASE_MAX_TIME) != QSPI_OK)
00387   {
00388     return QSPI_ERROR;
00389   }
00390 
00391   return QSPI_OK;
00392 }
00393 
00394 /**
00395   * @brief  Reads current status of the QSPI memory.
00396   * @retval QSPI memory status
00397   */
00398 uint8_t BSP_QSPI_GetStatus(void)
00399 {
00400   QSPI_CommandTypeDef s_command;
00401   uint8_t reg;
00402 
00403   /* Initialize the read flag status register command */
00404   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00405   s_command.Instruction       = READ_FLAG_STATUS_REG_CMD;
00406   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00407   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00408   s_command.DataMode          = QSPI_DATA_1_LINE;
00409   s_command.DummyCycles       = 0;
00410   s_command.NbData            = 1;
00411   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00412   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00413   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00414 
00415   /* Configure the command */
00416   if (HAL_QSPI_Command(&QSPIHandle, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00417   {
00418     return QSPI_ERROR;
00419   }
00420 
00421   /* Reception of the data */
00422   if (HAL_QSPI_Receive(&QSPIHandle, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00423   {
00424     return QSPI_ERROR;
00425   }
00426   
00427   /* Check the value of the register */
00428   if ((reg & (N25Q512A_FSR_PRERR | N25Q512A_FSR_VPPERR | N25Q512A_FSR_PGERR | N25Q512A_FSR_ERERR)) != 0)
00429   {
00430     return QSPI_ERROR;
00431   }
00432   else if ((reg & (N25Q512A_FSR_PGSUS | N25Q512A_FSR_ERSUS)) != 0)
00433   {
00434     return QSPI_SUSPENDED;
00435   }
00436   else if ((reg & N25Q512A_FSR_READY) != 0)
00437   {
00438     return QSPI_OK;
00439   }
00440   else
00441   {
00442     return QSPI_BUSY;
00443   }
00444 }
00445 
00446 /**
00447   * @brief  Return the configuration of the QSPI memory.
00448   * @param  pInfo: pointer on the configuration structure  
00449   * @retval QSPI memory status
00450   */
00451 uint8_t BSP_QSPI_GetInfo(QSPI_Info* pInfo)
00452 {
00453   /* Configure the structure with the memory configuration */
00454   pInfo->FlashSize          = N25Q512A_FLASH_SIZE;
00455   pInfo->EraseSectorSize    = N25Q512A_SUBSECTOR_SIZE;
00456   pInfo->EraseSectorsNumber = (N25Q512A_FLASH_SIZE/N25Q512A_SUBSECTOR_SIZE);
00457   pInfo->ProgPageSize       = N25Q512A_PAGE_SIZE;
00458   pInfo->ProgPagesNumber    = (N25Q512A_FLASH_SIZE/N25Q512A_PAGE_SIZE);
00459   
00460   return QSPI_OK;
00461 }
00462 
00463 /**
00464   * @brief  Configure the QSPI in memory-mapped mode
00465   * @retval QSPI memory status
00466   */
00467 uint8_t BSP_QSPI_EnableMemoryMappedMode(void)
00468 {
00469   QSPI_CommandTypeDef      s_command;
00470   QSPI_MemoryMappedTypeDef s_mem_mapped_cfg;
00471 
00472   /* Configure the command for the read instruction */
00473   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00474   s_command.Instruction       = QUAD_OUT_FAST_READ_CMD;
00475   s_command.AddressMode       = QSPI_ADDRESS_1_LINE;
00476   s_command.AddressSize       = QSPI_ADDRESS_32_BITS;
00477   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00478   s_command.DataMode          = QSPI_DATA_4_LINES;
00479   s_command.DummyCycles       = N25Q512A_DUMMY_CYCLES_READ_QUAD;
00480   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00481   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00482   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00483   
00484   /* Configure the memory mapped mode */
00485   s_mem_mapped_cfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE;
00486   s_mem_mapped_cfg.TimeOutPeriod     = 0;
00487   
00488   if (HAL_QSPI_MemoryMapped(&QSPIHandle, &s_command, &s_mem_mapped_cfg) != HAL_OK)
00489   {
00490     return QSPI_ERROR;
00491   }
00492 
00493   return QSPI_OK;
00494 }
00495 
00496 /**
00497   * @}
00498   */
00499 
00500 /** @addtogroup STM32F769I_EVAL_QSPI_Private_Functions
00501   * @{
00502   */ 
00503 
00504 /**
00505   * @brief QSPI MSP Initialization
00506   * @param hqspi: QSPI handle
00507   * @param Params    
00508   *        This function configures the hardware resources used in this example:
00509   *           - Peripheral's clock enable
00510   *           - Peripheral's GPIO Configuration
00511   *           - NVIC configuration for QSPI interrupt
00512   * @retval None
00513   */
00514 __weak void BSP_QSPI_MspInit(QSPI_HandleTypeDef *hqspi, void *Params)
00515 {
00516   GPIO_InitTypeDef gpio_init_structure;
00517 
00518   /*##-1- Enable peripherals and GPIO Clocks #################################*/
00519   /* Enable the QuadSPI memory interface clock */
00520   QSPI_CLK_ENABLE();
00521   /* Reset the QuadSPI memory interface */
00522   QSPI_FORCE_RESET();
00523   QSPI_RELEASE_RESET();
00524   /* Enable GPIO clocks */
00525   QSPI_CS_GPIO_CLK_ENABLE();
00526   QSPI_CLK_GPIO_CLK_ENABLE();
00527   QSPI_D0_GPIO_CLK_ENABLE();
00528   QSPI_D1_GPIO_CLK_ENABLE();
00529   QSPI_D2_GPIO_CLK_ENABLE();
00530   QSPI_D3_GPIO_CLK_ENABLE();
00531 
00532   /*##-2- Configure peripheral GPIO ##########################################*/
00533   /* QSPI CS GPIO pin configuration  */
00534   gpio_init_structure.Pin       = QSPI_CS_PIN;
00535   gpio_init_structure.Mode      = GPIO_MODE_AF_PP;
00536   gpio_init_structure.Pull      = GPIO_PULLUP;
00537   gpio_init_structure.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
00538   gpio_init_structure.Alternate = GPIO_AF10_QUADSPI;
00539   HAL_GPIO_Init(QSPI_CS_GPIO_PORT, &gpio_init_structure);
00540 
00541   /* QSPI CLK GPIO pin configuration  */
00542   gpio_init_structure.Pin       = QSPI_CLK_PIN;
00543   gpio_init_structure.Pull      = GPIO_NOPULL;
00544   gpio_init_structure.Alternate = GPIO_AF9_QUADSPI;
00545   HAL_GPIO_Init(QSPI_CLK_GPIO_PORT, &gpio_init_structure);
00546 
00547   /* QSPI D0 GPIO pin configuration  */
00548   gpio_init_structure.Pin       = QSPI_D0_PIN;
00549   gpio_init_structure.Alternate = GPIO_AF10_QUADSPI;
00550   HAL_GPIO_Init(QSPI_D0_GPIO_PORT, &gpio_init_structure);
00551 
00552   /* QSPI D1 GPIO pin configuration  */
00553   gpio_init_structure.Pin       = QSPI_D1_PIN;
00554   gpio_init_structure.Alternate = GPIO_AF10_QUADSPI;
00555   HAL_GPIO_Init(QSPI_D1_GPIO_PORT, &gpio_init_structure);
00556 
00557   /* QSPI D2 GPIO pin configuration  */
00558   gpio_init_structure.Pin       = QSPI_D2_PIN;
00559   gpio_init_structure.Alternate = GPIO_AF9_QUADSPI;
00560   HAL_GPIO_Init(QSPI_D2_GPIO_PORT, &gpio_init_structure);
00561 
00562   /* QSPI D3 GPIO pin configuration  */
00563   gpio_init_structure.Pin       = QSPI_D3_PIN;
00564   gpio_init_structure.Alternate = GPIO_AF9_QUADSPI;
00565   HAL_GPIO_Init(QSPI_D3_GPIO_PORT, &gpio_init_structure);
00566 
00567   /*##-3- Configure the NVIC for QSPI #########################################*/
00568   /* NVIC configuration for QSPI interrupt */
00569   HAL_NVIC_SetPriority(QUADSPI_IRQn, 0x0F, 0);
00570   HAL_NVIC_EnableIRQ(QUADSPI_IRQn);
00571 }
00572 
00573 /**
00574   * @brief QSPI MSP De-Initialization
00575   * @param hqspi: QSPI handle
00576   * @param Params    
00577   *        This function frees the hardware resources used in this example:
00578   *          - Disable the Peripheral's clock
00579   *          - Revert GPIO and NVIC configuration to their default state
00580   * @retval None
00581   */
00582 __weak void BSP_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi, void *Params)
00583 {
00584   /*##-1- Disable the NVIC for QSPI ###########################################*/
00585   HAL_NVIC_DisableIRQ(QUADSPI_IRQn);
00586 
00587   /*##-2- Disable peripherals and GPIO Clocks ################################*/
00588   /* De-Configure QSPI pins */
00589   HAL_GPIO_DeInit(QSPI_CS_GPIO_PORT, QSPI_CS_PIN);
00590   HAL_GPIO_DeInit(QSPI_CLK_GPIO_PORT, QSPI_CLK_PIN);
00591   HAL_GPIO_DeInit(QSPI_D0_GPIO_PORT, QSPI_D0_PIN);
00592   HAL_GPIO_DeInit(QSPI_D1_GPIO_PORT, QSPI_D1_PIN);
00593   HAL_GPIO_DeInit(QSPI_D2_GPIO_PORT, QSPI_D2_PIN);
00594   HAL_GPIO_DeInit(QSPI_D3_GPIO_PORT, QSPI_D3_PIN);
00595 
00596   /*##-3- Reset peripherals ##################################################*/
00597   /* Reset the QuadSPI memory interface */
00598   QSPI_FORCE_RESET();
00599   QSPI_RELEASE_RESET();
00600 
00601   /* Disable the QuadSPI memory interface clock */
00602   QSPI_CLK_DISABLE();
00603 }
00604 
00605 /**
00606   * @brief  This function reset the QSPI memory.
00607   * @param  hqspi: QSPI handle
00608   * @retval None
00609   */
00610 static uint8_t QSPI_ResetMemory(QSPI_HandleTypeDef *hqspi)
00611 {
00612   QSPI_CommandTypeDef s_command;
00613 
00614   /* Initialize the reset enable command */
00615   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00616   s_command.Instruction       = RESET_ENABLE_CMD;
00617   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00618   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00619   s_command.DataMode          = QSPI_DATA_NONE;
00620   s_command.DummyCycles       = 0;
00621   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00622   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00623   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00624 
00625   /* Send the command */
00626   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00627   {
00628     return QSPI_ERROR;
00629   }
00630 
00631   /* Send the reset memory command */
00632   s_command.Instruction = RESET_MEMORY_CMD;
00633   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00634   {
00635     return QSPI_ERROR;
00636   }
00637 
00638   /* Configure automatic polling mode to wait the memory is ready */  
00639   if (QSPI_AutoPollingMemReady(hqspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
00640   {
00641     return QSPI_ERROR;
00642   }
00643 
00644   return QSPI_OK;
00645 }
00646 
00647 /**
00648   * @brief  This function set the QSPI memory in 4-byte address mode
00649   * @param  hqspi: QSPI handle
00650   * @retval None
00651   */
00652 static uint8_t QSPI_EnterFourBytesAddress(QSPI_HandleTypeDef *hqspi)
00653 {
00654   QSPI_CommandTypeDef s_command;
00655 
00656   /* Initialize the command */
00657   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00658   s_command.Instruction       = ENTER_4_BYTE_ADDR_MODE_CMD;
00659   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00660   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00661   s_command.DataMode          = QSPI_DATA_NONE;
00662   s_command.DummyCycles       = 0;
00663   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00664   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00665   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00666 
00667   /* Enable write operations */
00668   if (QSPI_WriteEnable(hqspi) != QSPI_OK)
00669   {
00670     return QSPI_ERROR;
00671   }
00672 
00673   /* Send the command */
00674   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00675   {
00676     return QSPI_ERROR;
00677   }
00678 
00679   /* Configure automatic polling mode to wait the memory is ready */  
00680   if (QSPI_AutoPollingMemReady(hqspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
00681   {
00682     return QSPI_ERROR;
00683   }
00684 
00685   return QSPI_OK;
00686 }
00687 
00688 /**
00689   * @brief  This function configure the dummy cycles on memory side.
00690   * @param  hqspi: QSPI handle
00691   * @retval None
00692   */
00693 static uint8_t QSPI_DummyCyclesCfg(QSPI_HandleTypeDef *hqspi)
00694 {
00695   QSPI_CommandTypeDef s_command;
00696   uint8_t reg;
00697 
00698   /* Initialize the read volatile configuration register command */
00699   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00700   s_command.Instruction       = READ_VOL_CFG_REG_CMD;
00701   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00702   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00703   s_command.DataMode          = QSPI_DATA_1_LINE;
00704   s_command.DummyCycles       = 0;
00705   s_command.NbData            = 1;
00706   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00707   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00708   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00709 
00710   /* Configure the command */
00711   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00712   {
00713     return QSPI_ERROR;
00714   }
00715 
00716   /* Reception of the data */
00717   if (HAL_QSPI_Receive(hqspi, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00718   {
00719     return QSPI_ERROR;
00720   }
00721 
00722   /* Enable write operations */
00723   if (QSPI_WriteEnable(hqspi) != QSPI_OK)
00724   {
00725     return QSPI_ERROR;
00726   }
00727 
00728   /* Update volatile configuration register (with new dummy cycles) */  
00729   s_command.Instruction = WRITE_VOL_CFG_REG_CMD;
00730   MODIFY_REG(reg, N25Q512A_VCR_NB_DUMMY, (N25Q512A_DUMMY_CYCLES_READ_QUAD << POSITION_VAL(N25Q512A_VCR_NB_DUMMY)));
00731       
00732   /* Configure the write volatile configuration register command */
00733   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00734   {
00735     return QSPI_ERROR;
00736   }
00737 
00738   /* Transmission of the data */
00739   if (HAL_QSPI_Transmit(hqspi, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00740   {
00741     return QSPI_ERROR;
00742   }
00743   
00744   return QSPI_OK;
00745 }
00746 
00747 /**
00748   * @brief  This function send a Write Enable and wait it is effective.
00749   * @param  hqspi: QSPI handle
00750   * @retval None
00751   */
00752 static uint8_t QSPI_WriteEnable(QSPI_HandleTypeDef *hqspi)
00753 {
00754   QSPI_CommandTypeDef     s_command;
00755   QSPI_AutoPollingTypeDef s_config;
00756 
00757   /* Enable write operations */
00758   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00759   s_command.Instruction       = WRITE_ENABLE_CMD;
00760   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00761   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00762   s_command.DataMode          = QSPI_DATA_NONE;
00763   s_command.DummyCycles       = 0;
00764   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00765   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00766   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00767 
00768   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00769   {
00770     return QSPI_ERROR;
00771   }
00772   
00773   /* Configure automatic polling mode to wait for write enabling */  
00774   s_config.Match           = N25Q512A_SR_WREN;
00775   s_config.Mask            = N25Q512A_SR_WREN;
00776   s_config.MatchMode       = QSPI_MATCH_MODE_AND;
00777   s_config.StatusBytesSize = 1;
00778   s_config.Interval        = 0x10;
00779   s_config.AutomaticStop   = QSPI_AUTOMATIC_STOP_ENABLE;
00780 
00781   s_command.Instruction    = READ_STATUS_REG_CMD;
00782   s_command.DataMode       = QSPI_DATA_1_LINE;
00783 
00784   if (HAL_QSPI_AutoPolling(hqspi, &s_command, &s_config, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00785   {
00786     return QSPI_ERROR;
00787   }
00788 
00789   return QSPI_OK;
00790 }
00791 
00792 /**
00793   * @brief  This function read the SR of the memory and wait the EOP.
00794   * @param  hqspi: QSPI handle
00795   * @param  Timeout  
00796   * @retval None
00797   */
00798 static uint8_t QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi, uint32_t Timeout)
00799 {
00800   QSPI_CommandTypeDef     s_command;
00801   QSPI_AutoPollingTypeDef s_config;
00802 
00803   /* Configure automatic polling mode to wait for memory ready */  
00804   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00805   s_command.Instruction       = READ_STATUS_REG_CMD;
00806   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00807   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00808   s_command.DataMode          = QSPI_DATA_1_LINE;
00809   s_command.DummyCycles       = 0;
00810   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00811   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00812   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00813 
00814   s_config.Match           = 0;
00815   s_config.Mask            = N25Q512A_SR_WIP;
00816   s_config.MatchMode       = QSPI_MATCH_MODE_AND;
00817   s_config.StatusBytesSize = 1;
00818   s_config.Interval        = 0x10;
00819   s_config.AutomaticStop   = QSPI_AUTOMATIC_STOP_ENABLE;
00820 
00821   if (HAL_QSPI_AutoPolling(hqspi, &s_command, &s_config, Timeout) != HAL_OK)
00822   {
00823     return QSPI_ERROR;
00824   }
00825 
00826   return QSPI_OK;
00827 }
00828 /**
00829   * @}
00830   */  
00831   
00832 /**
00833   * @}
00834   */ 
00835   
00836 /**
00837   * @}
00838   */ 
00839   
00840 /**
00841   * @}
00842   */ 
00843 
00844 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
00845 
Generated on Fri Dec 30 2016 20:55:35 for STM32769I_EVAL BSP User Manual by   doxygen 1.7.6.1