STM32769I_EVAL BSP User Manual: stm32f769i_eval_qspi.c Source File

STM32769I_EVAL BSP

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