STM32756G_EVAL BSP User Manual: stm32756g_eval_qspi.c Source File

STM32756G EVAL BSP Drivers

stm32756g_eval_qspi.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32756g_eval_qspi.c
00004   * @author  MCD Application Team
00005   * @version V1.0.0
00006   * @date    22-May-2015
00007   * @brief   This file includes a standard driver for the N25Q512A QSPI
00008   *          memory mounted on STM32756G-EVAL and STM32746G-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 STM32756G-EVAL and STM32746G-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) 2015 STMicroelectronics</center></h2>
00041   *
00042   * Redistribution and use in source and binary forms, with or without modification,
00043   * are permitted provided that the following conditions are met:
00044   *   1. Redistributions of source code must retain the above copyright notice,
00045   *      this list of conditions and the following disclaimer.
00046   *   2. Redistributions in binary form must reproduce the above copyright notice,
00047   *      this list of conditions and the following disclaimer in the documentation
00048   *      and/or other materials provided with the distribution.
00049   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00050   *      may be used to endorse or promote products derived from this software
00051   *      without specific prior written permission.
00052   *
00053   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00054   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00055   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00056   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00057   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00058   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00059   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00060   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00061   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00062   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00063   *
00064   ******************************************************************************
00065   */ 
00066 
00067 /* Includes ------------------------------------------------------------------*/
00068 #include "stm32756g_eval_qspi.h"
00069 
00070 /** @addtogroup BSP
00071   * @{
00072   */
00073 
00074 /** @addtogroup STM32756G_EVAL
00075   * @{
00076   */ 
00077   
00078 /** @defgroup STM32756G_EVAL_QSPI STM32756G-EVAL QSPI
00079   * @{
00080   */ 
00081 
00082 
00083 /* Private variables ---------------------------------------------------------*/
00084 
00085 /** @defgroup STM32756G_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 STM32756G_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 STM32756G_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_2_CYCLE;
00139   QSPIHandle.Init.ClockMode          = QSPI_CLOCK_MODE_0;
00140   QSPIHandle.Init.FlashID            = QSPI_FLASH_ID_1;
00141   QSPIHandle.Init.DualFlash          = QSPI_DUALFLASH_DISABLE;
00142 
00143   if (HAL_QSPI_Init(&QSPIHandle) != HAL_OK)
00144   {
00145     return QSPI_ERROR;
00146   }
00147 
00148   /* QSPI memory reset */
00149   if (QSPI_ResetMemory(&QSPIHandle) != QSPI_OK)
00150   {
00151     return QSPI_NOT_SUPPORTED;
00152   }
00153  
00154   /* 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   /* Reception of the data */
00221   if (HAL_QSPI_Receive(&QSPIHandle, pData, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00222   {
00223     return QSPI_ERROR;
00224   }
00225 
00226   return QSPI_OK;
00227 }
00228 
00229 /**
00230   * @brief  Writes an amount of data to the QSPI memory.
00231   * @param  pData: Pointer to data to be written
00232   * @param  WriteAddr: Write start address
00233   * @param  Size: Size of data to write    
00234   * @retval QSPI memory status
00235   */
00236 uint8_t BSP_QSPI_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size)
00237 {
00238   QSPI_CommandTypeDef s_command;
00239   uint32_t end_addr, current_size, current_addr;
00240 
00241   /* Calculation of the size between the write address and the end of the page */
00242   current_addr = 0;
00243 
00244   while (current_addr <= WriteAddr)
00245   {
00246     current_addr += N25Q512A_PAGE_SIZE;
00247   }
00248   current_size = current_addr - WriteAddr;
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_MemoryMappedMode(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_ENABLE;
00486   s_mem_mapped_cfg.TimeOutPeriod     = 1;
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 STM32756G_EVAL_QSPI_Private_Functions
00501   * @{
00502   */ 
00503 
00504 /**
00505   * @brief QSPI MSP Initialization
00506   *        This function configures the hardware resources used in this example:
00507   *           - Peripheral's clock enable
00508   *           - Peripheral's GPIO Configuration
00509   *           - NVIC configuration for QSPI interrupt
00510   * @retval None
00511   */
00512 __weak void BSP_QSPI_MspInit(QSPI_HandleTypeDef *hqspi, void *Params)
00513 {
00514   GPIO_InitTypeDef gpio_init_structure;
00515 
00516   /*##-1- Enable peripherals and GPIO Clocks #################################*/
00517   /* Enable the QuadSPI memory interface clock */
00518   QSPI_CLK_ENABLE();
00519   /* Reset the QuadSPI memory interface */
00520   QSPI_FORCE_RESET();
00521   QSPI_RELEASE_RESET();
00522   /* Enable GPIO clocks */
00523   QSPI_CS_GPIO_CLK_ENABLE();
00524   QSPI_CLK_GPIO_CLK_ENABLE();
00525   QSPI_D0_GPIO_CLK_ENABLE();
00526   QSPI_D1_GPIO_CLK_ENABLE();
00527   QSPI_D2_GPIO_CLK_ENABLE();
00528   QSPI_D3_GPIO_CLK_ENABLE();
00529 
00530   /*##-2- Configure peripheral GPIO ##########################################*/
00531   /* QSPI CS GPIO pin configuration  */
00532   gpio_init_structure.Pin       = QSPI_CS_PIN;
00533   gpio_init_structure.Mode      = GPIO_MODE_AF_PP;
00534   gpio_init_structure.Pull      = GPIO_PULLUP;
00535   gpio_init_structure.Speed     = GPIO_SPEED_HIGH;
00536   gpio_init_structure.Alternate = GPIO_AF10_QUADSPI;
00537   HAL_GPIO_Init(QSPI_CS_GPIO_PORT, &gpio_init_structure);
00538 
00539   /* QSPI CLK GPIO pin configuration  */
00540   gpio_init_structure.Pin       = QSPI_CLK_PIN;
00541   gpio_init_structure.Pull      = GPIO_NOPULL;
00542   gpio_init_structure.Alternate = GPIO_AF9_QUADSPI;
00543   HAL_GPIO_Init(QSPI_CLK_GPIO_PORT, &gpio_init_structure);
00544 
00545   /* QSPI D0 GPIO pin configuration  */
00546   gpio_init_structure.Pin       = QSPI_D0_PIN;
00547   gpio_init_structure.Alternate = GPIO_AF10_QUADSPI;
00548   HAL_GPIO_Init(QSPI_D0_GPIO_PORT, &gpio_init_structure);
00549 
00550   /* QSPI D1 GPIO pin configuration  */
00551   gpio_init_structure.Pin       = QSPI_D1_PIN;
00552   gpio_init_structure.Alternate = GPIO_AF10_QUADSPI;
00553   HAL_GPIO_Init(QSPI_D1_GPIO_PORT, &gpio_init_structure);
00554 
00555   /* QSPI D2 GPIO pin configuration  */
00556   gpio_init_structure.Pin       = QSPI_D2_PIN;
00557   gpio_init_structure.Alternate = GPIO_AF9_QUADSPI;
00558   HAL_GPIO_Init(QSPI_D2_GPIO_PORT, &gpio_init_structure);
00559 
00560   /* QSPI D3 GPIO pin configuration  */
00561   gpio_init_structure.Pin       = QSPI_D3_PIN;
00562   gpio_init_structure.Alternate = GPIO_AF9_QUADSPI;
00563   HAL_GPIO_Init(QSPI_D3_GPIO_PORT, &gpio_init_structure);
00564 
00565   /*##-3- Configure the NVIC for QSPI #########################################*/
00566   /* NVIC configuration for QSPI interrupt */
00567   HAL_NVIC_SetPriority(QUADSPI_IRQn, 0x0F, 0);
00568   HAL_NVIC_EnableIRQ(QUADSPI_IRQn);
00569 }
00570 
00571 /**
00572   * @brief QSPI MSP De-Initialization
00573   *        This function frees the hardware resources used in this example:
00574   *          - Disable the Peripheral's clock
00575   *          - Revert GPIO and NVIC configuration to their default state
00576   * @retval None
00577   */
00578 __weak void BSP_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi, void *Params)
00579 {
00580   /*##-1- Disable the NVIC for QSPI ###########################################*/
00581   HAL_NVIC_DisableIRQ(QUADSPI_IRQn);
00582 
00583   /*##-2- Disable peripherals and GPIO Clocks ################################*/
00584   /* De-Configure QSPI pins */
00585   HAL_GPIO_DeInit(QSPI_CS_GPIO_PORT, QSPI_CS_PIN);
00586   HAL_GPIO_DeInit(QSPI_CLK_GPIO_PORT, QSPI_CLK_PIN);
00587   HAL_GPIO_DeInit(QSPI_D0_GPIO_PORT, QSPI_D0_PIN);
00588   HAL_GPIO_DeInit(QSPI_D1_GPIO_PORT, QSPI_D1_PIN);
00589   HAL_GPIO_DeInit(QSPI_D2_GPIO_PORT, QSPI_D2_PIN);
00590   HAL_GPIO_DeInit(QSPI_D3_GPIO_PORT, QSPI_D3_PIN);
00591 
00592   /*##-3- Reset peripherals ##################################################*/
00593   /* Reset the QuadSPI memory interface */
00594   QSPI_FORCE_RESET();
00595   QSPI_RELEASE_RESET();
00596 
00597   /* Disable the QuadSPI memory interface clock */
00598   QSPI_CLK_DISABLE();
00599 }
00600 
00601 /**
00602   * @brief  This function reset the QSPI memory.
00603   * @param  hqspi: QSPI handle
00604   * @retval None
00605   */
00606 static uint8_t QSPI_ResetMemory(QSPI_HandleTypeDef *hqspi)
00607 {
00608   QSPI_CommandTypeDef s_command;
00609 
00610   /* Initialize the reset enable command */
00611   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00612   s_command.Instruction       = RESET_ENABLE_CMD;
00613   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00614   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00615   s_command.DataMode          = QSPI_DATA_NONE;
00616   s_command.DummyCycles       = 0;
00617   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00618   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00619   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00620 
00621   /* Send the command */
00622   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00623   {
00624     return QSPI_ERROR;
00625   }
00626 
00627   /* Send the reset memory command */
00628   s_command.Instruction = RESET_MEMORY_CMD;
00629   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00630   {
00631     return QSPI_ERROR;
00632   }
00633 
00634   /* Configure automatic polling mode to wait the memory is ready */  
00635   if (QSPI_AutoPollingMemReady(hqspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
00636   {
00637     return QSPI_ERROR;
00638   }
00639 
00640   return QSPI_OK;
00641 }
00642 
00643 /**
00644   * @brief  This function set the QSPI memory in 4-byte address mode
00645   * @param  hqspi: QSPI handle
00646   * @retval None
00647   */
00648 static uint8_t QSPI_EnterFourBytesAddress(QSPI_HandleTypeDef *hqspi)
00649 {
00650   QSPI_CommandTypeDef s_command;
00651 
00652   /* Initialize the command */
00653   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00654   s_command.Instruction       = ENTER_4_BYTE_ADDR_MODE_CMD;
00655   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00656   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00657   s_command.DataMode          = QSPI_DATA_NONE;
00658   s_command.DummyCycles       = 0;
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   /* Enable write operations */
00664   if (QSPI_WriteEnable(hqspi) != QSPI_OK)
00665   {
00666     return QSPI_ERROR;
00667   }
00668 
00669   /* Send the command */
00670   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00671   {
00672     return QSPI_ERROR;
00673   }
00674 
00675   /* Configure automatic polling mode to wait the memory is ready */  
00676   if (QSPI_AutoPollingMemReady(hqspi, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != QSPI_OK)
00677   {
00678     return QSPI_ERROR;
00679   }
00680 
00681   return QSPI_OK;
00682 }
00683 
00684 /**
00685   * @brief  This function configure the dummy cycles on memory side.
00686   * @param  hqspi: QSPI handle
00687   * @retval None
00688   */
00689 static uint8_t QSPI_DummyCyclesCfg(QSPI_HandleTypeDef *hqspi)
00690 {
00691   QSPI_CommandTypeDef s_command;
00692   uint8_t reg;
00693 
00694   /* Initialize the read volatile configuration register command */
00695   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00696   s_command.Instruction       = READ_VOL_CFG_REG_CMD;
00697   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00698   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00699   s_command.DataMode          = QSPI_DATA_1_LINE;
00700   s_command.DummyCycles       = 0;
00701   s_command.NbData            = 1;
00702   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00703   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00704   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00705 
00706   /* Configure the command */
00707   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00708   {
00709     return QSPI_ERROR;
00710   }
00711 
00712   /* Reception of the data */
00713   if (HAL_QSPI_Receive(hqspi, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00714   {
00715     return QSPI_ERROR;
00716   }
00717 
00718   /* Enable write operations */
00719   if (QSPI_WriteEnable(hqspi) != QSPI_OK)
00720   {
00721     return QSPI_ERROR;
00722   }
00723 
00724   /* Update volatile configuration register (with new dummy cycles) */  
00725   s_command.Instruction = WRITE_VOL_CFG_REG_CMD;
00726   MODIFY_REG(reg, N25Q512A_VCR_NB_DUMMY, (N25Q512A_DUMMY_CYCLES_READ_QUAD << POSITION_VAL(N25Q512A_VCR_NB_DUMMY)));
00727       
00728   /* Configure the write volatile configuration register command */
00729   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00730   {
00731     return QSPI_ERROR;
00732   }
00733 
00734   /* Transmission of the data */
00735   if (HAL_QSPI_Transmit(hqspi, &reg, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00736   {
00737     return QSPI_ERROR;
00738   }
00739   
00740   return QSPI_OK;
00741 }
00742 
00743 /**
00744   * @brief  This function send a Write Enable and wait it is effective.
00745   * @param  hqspi: QSPI handle
00746   * @retval None
00747   */
00748 static uint8_t QSPI_WriteEnable(QSPI_HandleTypeDef *hqspi)
00749 {
00750   QSPI_CommandTypeDef     s_command;
00751   QSPI_AutoPollingTypeDef s_config;
00752 
00753   /* Enable write operations */
00754   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00755   s_command.Instruction       = WRITE_ENABLE_CMD;
00756   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00757   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00758   s_command.DataMode          = QSPI_DATA_NONE;
00759   s_command.DummyCycles       = 0;
00760   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00761   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00762   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00763 
00764   if (HAL_QSPI_Command(hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00765   {
00766     return QSPI_ERROR;
00767   }
00768   
00769   /* Configure automatic polling mode to wait for write enabling */  
00770   s_config.Match           = N25Q512A_SR_WREN;
00771   s_config.Mask            = N25Q512A_SR_WREN;
00772   s_config.MatchMode       = QSPI_MATCH_MODE_AND;
00773   s_config.StatusBytesSize = 1;
00774   s_config.Interval        = 0x10;
00775   s_config.AutomaticStop   = QSPI_AUTOMATIC_STOP_ENABLE;
00776 
00777   s_command.Instruction    = READ_STATUS_REG_CMD;
00778   s_command.DataMode       = QSPI_DATA_1_LINE;
00779 
00780   if (HAL_QSPI_AutoPolling(hqspi, &s_command, &s_config, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
00781   {
00782     return QSPI_ERROR;
00783   }
00784 
00785   return QSPI_OK;
00786 }
00787 
00788 /**
00789   * @brief  This function read the SR of the memory and wait the EOP.
00790   * @param  hqspi: QSPI handle
00791   * @retval None
00792   */
00793 static uint8_t QSPI_AutoPollingMemReady(QSPI_HandleTypeDef *hqspi, uint32_t Timeout)
00794 {
00795   QSPI_CommandTypeDef     s_command;
00796   QSPI_AutoPollingTypeDef s_config;
00797 
00798   /* Configure automatic polling mode to wait for memory ready */  
00799   s_command.InstructionMode   = QSPI_INSTRUCTION_1_LINE;
00800   s_command.Instruction       = READ_STATUS_REG_CMD;
00801   s_command.AddressMode       = QSPI_ADDRESS_NONE;
00802   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
00803   s_command.DataMode          = QSPI_DATA_1_LINE;
00804   s_command.DummyCycles       = 0;
00805   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
00806   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
00807   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
00808 
00809   s_config.Match           = 0;
00810   s_config.Mask            = N25Q512A_SR_WIP;
00811   s_config.MatchMode       = QSPI_MATCH_MODE_AND;
00812   s_config.StatusBytesSize = 1;
00813   s_config.Interval        = 0x10;
00814   s_config.AutomaticStop   = QSPI_AUTOMATIC_STOP_ENABLE;
00815 
00816   if (HAL_QSPI_AutoPolling(hqspi, &s_command, &s_config, Timeout) != HAL_OK)
00817   {
00818     return QSPI_ERROR;
00819   }
00820 
00821   return QSPI_OK;
00822 }
00823 /**
00824   * @}
00825   */  
00826   
00827 /**
00828   * @}
00829   */ 
00830   
00831 /**
00832   * @}
00833   */ 
00834   
00835 /**
00836   * @}
00837   */ 
00838 
00839 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
00840 
Generated on Fri May 22 2015 13:59:20 for STM32756G_EVAL BSP User Manual by   doxygen 1.7.6.1