STM32F413H-Discovery BSP User Manual: stm32f413h_discovery_qspi.c Source File

STM32F413H-Discovery BSP Drivers

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