STM32H743I_EVAL BSP User Manual: stm32h743i_eval_qspi.c Source File

STM32H743I_EVAL BSP

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