STM32446E_EVAL BSP User Manual: stm32446e_eval_qspi.c Source File

STM32446E EVAL BSP Drivers

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