STM32L476G_EVAL BSP User Manual: stm32l476g_eval_qspi.c Source File

STM32L476G_EVAL BSP

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