Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:06

0001 /* SPDX-License-Identifier: BSD-3-Clause */
0002 /**
0003   ******************************************************************************
0004   * @file    stm32h747i_eval_qspi.c
0005   * @author  MCD Application Team
0006   * @brief   This file includes a standard driver for the MT25TL01G QSPI
0007   *          memory mounted on STM32H747I-EVAL board.
0008   ******************************************************************************
0009   @verbatim
0010   How To use this driver:
0011   -----------------------
0012    - This driver is used to drive the MT25TL01G QSPI external
0013        memory mounted on STM32H747I-EVAL evaluation board.
0014 
0015    - This driver need a specific component driver (MT25TL01G) to be included with.
0016 
0017   Driver description:
0018   -------------------
0019    - Initialization steps:
0020        + Initialize the QPSI external memory using the BSP_QSPI_Init() function. This
0021             function includes the MSP layer hardware resources initialization and the
0022             QSPI interface with the external memory.
0023          STR and DTR transfer rates are supported.
0024          SPI, SPI 2-IO, SPI-4IO and QPI modes are supported
0025 
0026    - QSPI memory operations
0027        + QSPI memory can be accessed with read/write operations once it is
0028             initialized.
0029             Read/write operation can be performed with AHB access using the functions
0030             BSP_QSPI_Read()/BSP_QSPI_Write().
0031        + The function BSP_QSPI_GetInfo() returns the configuration of the QSPI memory.
0032             (see the QSPI memory data sheet)
0033        + Perform erase block operation using the function BSP_QSPI_EraseBlock() and by
0034             specifying the block address. You can perform an erase operation of the whole
0035             chip by calling the function BSP_QSPI_EraseChip().
0036        + The function BSP_QSPI_GetStatus() returns the current status of the QSPI memory.
0037             (see the QSPI memory data sheet)
0038        + The function BSP_QSPI_EnableMemoryMappedMode enables the QSPI memory mapped mode
0039        + The function BSP_QSPI_DisableMemoryMappedMode disables the QSPI memory mapped mode
0040        + The function BSP_QSPI_ConfigFlash() allow to configure the QSPI mode and transfer rate
0041 
0042   Note:
0043   --------
0044     Regarding the "Instance" parameter, needed for all functions, it is used to select
0045     an QSPI instance. On the STM32H747I_EVAL board, there's one instance. Then, this
0046     parameter should be 0.
0047 
0048   @endverbatim
0049   ******************************************************************************
0050   * @attention
0051   *
0052   * Copyright (c) 2019 STMicroelectronics.
0053   * All rights reserved.
0054   *
0055   * This software is licensed under terms that can be found in the LICENSE file
0056   * in the root directory of this software component.
0057   * If no LICENSE file comes with this software, it is provided AS-IS.
0058   *
0059   ******************************************************************************
0060   */
0061 /*
0062  * RTEMS committer clarification comment on license above:
0063  *
0064  * This file comes from STM32CubeH7 project and is located here:
0065  * https://github.com/STMicroelectronics/STM32CubeH7/blob/master/Drivers/BSP/STM32H747I-EVAL/stm32h747i_eval_qspi.c
0066  *
0067  * The file root directory is:
0068  * https://github.com/STMicroelectronics/STM32CubeH7/tree/master/Drivers/BSP/STM32H747I-EVAL
0069  *
0070  * This directory contains LICENSE.md file with a following license text:
0071  *
0072  * Copyright 2019 STMicroelectronics.
0073  * All rights reserved.
0074  *
0075  * Redistribution and use in source and binary forms, with or without modification,
0076  * are permitted provided that the following conditions are met:
0077  *
0078  * 1. Redistributions of source code must retain the above copyright notice, this
0079  * list of conditions and the following disclaimer.
0080  *
0081  * 2. Redistributions in binary form must reproduce the above copyright notice,
0082  * this list of conditions and the following disclaimer in the documentation and/or
0083  * other materials provided with the distribution.
0084  *
0085  * 3. Neither the name of the copyright holder nor the names of its contributors
0086  * may be used to endorse or promote products derived from this software without
0087  * specific prior written permission.
0088  *
0089  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
0090  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
0091  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0092  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
0093  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
0094  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
0095  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
0096  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0097  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
0098  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0099  */
0100 
0101 /* Includes ------------------------------------------------------------------*/
0102 #include "stm32h747i_eval_qspi.h"
0103 
0104 /** @addtogroup BSP
0105   * @{
0106   */
0107 
0108 /** @addtogroup STM32H747I_EVAL
0109   * @{
0110   */
0111 
0112 /** @defgroup STM32H747I_EVAL_QSPI QSPI
0113   * @{
0114   */
0115 
0116 /** @defgroup STM32H747I_EVAL_QSPI_Exported_Variables Exported Variables
0117   * @{
0118   */
0119 QSPI_HandleTypeDef hqspi;
0120 BSP_QSPI_Ctx_t     QSPI_Ctx[QSPI_INSTANCES_NUMBER];
0121 /**
0122   * @}
0123   */
0124 
0125 /* Private functions ---------------------------------------------------------*/
0126 
0127 /** @defgroup STM32H747I_EVAL_QSPI_Private_Functions Private Functions
0128   * @{
0129   */
0130 static void QSPI_MspInit(QSPI_HandleTypeDef *hQspi);
0131 static void QSPI_MspDeInit(QSPI_HandleTypeDef *hSspi);
0132 static int32_t QSPI_ResetMemory(uint32_t Instance);
0133 static int32_t QSPI_DummyCyclesCfg(uint32_t Instance);
0134 
0135 /**
0136   * @}
0137   */
0138 
0139 /** @defgroup STM32H747I_EVAL_QSPI_Exported_Functions Exported Functions
0140   * @{
0141   */
0142 
0143 /**
0144   * @brief  Initializes the QSPI interface.
0145   * @param  Instance   QSPI Instance
0146   * @param  Init       QSPI Init structure
0147   * @retval BSP status
0148   */
0149 int32_t BSP_QSPI_Init(uint32_t Instance, BSP_QSPI_Init_t *Init)
0150 {
0151   int32_t ret = BSP_ERROR_NONE;
0152   BSP_QSPI_Info_t pInfo;
0153   MX_QSPI_Init_t qspi_init;
0154   /* Table to handle clock prescalers:
0155   1: For STR mode to reach max 100Mhz
0156   3: For DTR mode to reach max 50Mhz
0157   */
0158   static const uint32_t PrescalerTab[2] = {1, 3};
0159 
0160   /* Check if the instance is supported */
0161   if(Instance >= QSPI_INSTANCES_NUMBER)
0162   {
0163     ret = BSP_ERROR_WRONG_PARAM;
0164   }
0165   else
0166   {
0167     /* Check if instance is already initialized */
0168     if(QSPI_Ctx[Instance].IsInitialized == QSPI_ACCESS_NONE)
0169     {
0170 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
0171       /* Register the QSPI MSP Callbacks */
0172       if(QSPI_Ctx[Instance].IsMspCallbacksValid == 0UL)
0173       {
0174         if(BSP_QSPI_RegisterDefaultMspCallbacks(Instance) != BSP_ERROR_NONE)
0175         {
0176           ret = BSP_ERROR_PERIPH_FAILURE;
0177         }
0178       }
0179 #else
0180       /* Msp QSPI initialization */
0181       QSPI_MspInit(&hqspi);
0182 #endif /* USE_HAL_QSPI_REGISTER_CALLBACKS */
0183 
0184       if(ret == BSP_ERROR_NONE)
0185       {
0186         /* STM32 QSPI interface initialization */
0187         (void)MT25TL01G_GetFlashInfo(&pInfo);
0188         qspi_init.ClockPrescaler = PrescalerTab[Init->TransferRate];
0189         qspi_init.DualFlashMode  = QSPI_DUALFLASH_ENABLE;
0190         qspi_init.FlashSize      = (uint32_t)POSITION_VAL((uint32_t)pInfo.FlashSize) - 1U;
0191         qspi_init.SampleShifting = (Init->TransferRate == BSP_QSPI_STR_TRANSFER) ? QSPI_SAMPLE_SHIFTING_HALFCYCLE : QSPI_SAMPLE_SHIFTING_NONE;
0192 
0193         if(MX_QSPI_Init(&hqspi, &qspi_init) != HAL_OK)
0194         {
0195           ret = BSP_ERROR_PERIPH_FAILURE;
0196         }/* QSPI memory reset */
0197         else if(QSPI_ResetMemory(Instance) != BSP_ERROR_NONE)
0198         {
0199           ret = BSP_ERROR_COMPONENT_FAILURE;
0200         }/* Force Flash enter 4 Byte address mode */
0201         else if(MT25TL01G_AutoPollingMemReady(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != MT25TL01G_OK)
0202         {
0203           ret = BSP_ERROR_COMPONENT_FAILURE;
0204         }
0205         else if(MT25TL01G_Enter4BytesAddressMode(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != MT25TL01G_OK)
0206         {
0207           ret = BSP_ERROR_COMPONENT_FAILURE;
0208         }/* Configuration of the dummy cycles on QSPI memory side */
0209         else if(QSPI_DummyCyclesCfg(Instance) != BSP_ERROR_NONE)
0210         {
0211           ret = BSP_ERROR_COMPONENT_FAILURE;
0212         }
0213         else
0214         {
0215           /* Configure Flash to desired mode */
0216           if(BSP_QSPI_ConfigFlash(Instance, Init->InterfaceMode, Init->TransferRate) != BSP_ERROR_NONE)
0217           {
0218             ret = BSP_ERROR_COMPONENT_FAILURE;
0219           }
0220         }
0221       }
0222     }
0223   }
0224 
0225   /* Return BSP status */
0226   return ret;
0227 }
0228 
0229 /**
0230   * @brief  De-Initializes the QSPI interface.
0231   * @param  Instance   QSPI Instance
0232   * @retval BSP status
0233   */
0234 int32_t BSP_QSPI_DeInit(uint32_t Instance)
0235 {
0236   int32_t ret = BSP_ERROR_NONE;
0237 
0238   /* Check if the instance is supported */
0239   if(Instance >= QSPI_INSTANCES_NUMBER)
0240   {
0241     ret = BSP_ERROR_WRONG_PARAM;
0242   }
0243   else
0244   {
0245     if(QSPI_Ctx[Instance].IsInitialized == QSPI_ACCESS_MMP)
0246     {
0247       if(BSP_QSPI_DisableMemoryMappedMode(Instance) != BSP_ERROR_NONE)
0248       {
0249         ret = BSP_ERROR_COMPONENT_FAILURE;
0250       }
0251     }
0252 
0253     if(ret == BSP_ERROR_NONE)
0254     {
0255       /* Set default QSPI_Ctx values */
0256       QSPI_Ctx[Instance].IsInitialized = QSPI_ACCESS_NONE;
0257       QSPI_Ctx[Instance].InterfaceMode = BSP_QSPI_SPI_MODE;
0258       QSPI_Ctx[Instance].TransferRate  = BSP_QSPI_STR_TRANSFER;
0259       QSPI_Ctx[Instance].DualFlashMode = QSPI_DUALFLASH_ENABLE;
0260 
0261 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 0)
0262       QSPI_MspDeInit(&hqspi);
0263 #endif /* (USE_HAL_QSPI_REGISTER_CALLBACKS == 0) */
0264 
0265       /* Call the DeInit function to reset the driver */
0266       if (HAL_QSPI_DeInit(&hqspi) != HAL_OK)
0267       {
0268         ret = BSP_ERROR_PERIPH_FAILURE;
0269       }
0270     }
0271   }
0272 
0273   /* Return BSP status */
0274   return ret;
0275 }
0276 
0277 /**
0278   * @brief  Initializes the QSPI interface.
0279   * @param  hQspi       QSPI handle
0280   * @param  Config      QSPI configuration structure
0281   * @retval BSP status
0282   */
0283 __weak HAL_StatusTypeDef MX_QSPI_Init(QSPI_HandleTypeDef *hQspi, MX_QSPI_Init_t *Config)
0284 {
0285   /* QSPI initialization */
0286   /* QSPI freq = HCLK /(1 + ClockPrescaler) Mhz */
0287   hQspi->Instance                = QUADSPI;
0288   hQspi->Init.ClockPrescaler     = Config->ClockPrescaler;
0289   hQspi->Init.FifoThreshold      = 1;
0290   hQspi->Init.SampleShifting     = Config->SampleShifting;
0291   hQspi->Init.FlashSize          = Config->FlashSize;
0292   hQspi->Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_4_CYCLE; /* Min 50ns for nonRead */
0293   hQspi->Init.ClockMode          = QSPI_CLOCK_MODE_0;
0294   hQspi->Init.FlashID            = QSPI_FLASH_ID_1;
0295   hQspi->Init.DualFlash          = Config->DualFlashMode;
0296 
0297   return HAL_QSPI_Init(hQspi);
0298 }
0299 
0300 #if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1)
0301 /**
0302   * @brief Default BSP QSPI Msp Callbacks
0303   * @param Instance      QSPI Instance
0304   * @retval BSP status
0305   */
0306 int32_t BSP_QSPI_RegisterDefaultMspCallbacks (uint32_t Instance)
0307 {
0308   int32_t ret = BSP_ERROR_NONE;
0309 
0310   /* Check if the instance is supported */
0311   if(Instance >= QSPI_INSTANCES_NUMBER)
0312   {
0313     ret = BSP_ERROR_WRONG_PARAM;
0314   }
0315   else
0316   {
0317     /* Register MspInit/MspDeInit Callbacks */
0318     if(HAL_QSPI_RegisterCallback(&hqspi, HAL_QSPI_MSPINIT_CB_ID, QSPI_MspInit) != HAL_OK)
0319     {
0320       ret = BSP_ERROR_PERIPH_FAILURE;
0321     }
0322     else if(HAL_QSPI_RegisterCallback(&hqspi, HAL_QSPI_MSPDEINIT_CB_ID, QSPI_MspDeInit) != HAL_OK)
0323     {
0324       ret = BSP_ERROR_PERIPH_FAILURE;
0325     }
0326     else
0327     {
0328       QSPI_Ctx[Instance].IsMspCallbacksValid = 1U;
0329     }
0330   }
0331 
0332   /* Return BSP status */
0333   return ret;
0334 }
0335 
0336 /**
0337   * @brief BSP QSPI Msp Callback registering
0338   * @param Instance     QSPI Instance
0339   * @param CallBacks    pointer to MspInit/MspDeInit callbacks functions
0340   * @retval BSP status
0341   */
0342 int32_t BSP_QSPI_RegisterMspCallbacks (uint32_t Instance, BSP_QSPI_Cb_t *CallBacks)
0343 {
0344   int32_t ret = BSP_ERROR_NONE;
0345 
0346   /* Check if the instance is supported */
0347   if(Instance >= QSPI_INSTANCES_NUMBER)
0348   {
0349     ret = BSP_ERROR_WRONG_PARAM;
0350   }
0351   else
0352   {
0353     /* Register MspInit/MspDeInit Callbacks */
0354     if(HAL_QSPI_RegisterCallback(&hqspi, HAL_QSPI_MSPINIT_CB_ID, CallBacks->pMspInitCb) != HAL_OK)
0355     {
0356       ret = BSP_ERROR_PERIPH_FAILURE;
0357     }
0358     else if(HAL_QSPI_RegisterCallback(&hqspi, HAL_QSPI_MSPDEINIT_CB_ID, CallBacks->pMspDeInitCb) != HAL_OK)
0359     {
0360       ret = BSP_ERROR_PERIPH_FAILURE;
0361     }
0362     else
0363     {
0364       QSPI_Ctx[Instance].IsMspCallbacksValid = 1U;
0365     }
0366   }
0367 
0368   /* Return BSP status */
0369   return ret;
0370 }
0371 #endif /* (USE_HAL_QSPI_REGISTER_CALLBACKS == 1) */
0372 
0373 /**
0374   * @brief  Reads an amount of data from the QSPI memory.
0375   * @param  Instance  QSPI instance
0376   * @param  pData     Pointer to data to be read
0377   * @param  ReadAddr  Read start address
0378   * @param  Size      Size of data to read
0379   * @retval BSP status
0380   */
0381 int32_t BSP_QSPI_Read(uint32_t Instance, uint8_t *pData, uint32_t ReadAddr, uint32_t Size)
0382 {
0383   int32_t ret = BSP_ERROR_NONE;
0384 
0385   /* Check if the instance is supported */
0386   if(Instance >= QSPI_INSTANCES_NUMBER)
0387   {
0388     ret = BSP_ERROR_WRONG_PARAM;
0389   }
0390   else
0391   {
0392     if(QSPI_Ctx[Instance].TransferRate == BSP_QSPI_STR_TRANSFER)
0393     {
0394       if(MT25TL01G_ReadSTR(&hqspi, QSPI_Ctx[Instance].InterfaceMode, pData, ReadAddr, Size) != MT25TL01G_OK)
0395       {
0396         ret = BSP_ERROR_COMPONENT_FAILURE;
0397       }
0398     }
0399     else
0400     {
0401       if(MT25TL01G_ReadDTR(&hqspi, QSPI_Ctx[Instance].InterfaceMode, pData, ReadAddr, Size) != MT25TL01G_OK)
0402       {
0403         ret = BSP_ERROR_COMPONENT_FAILURE;
0404       }
0405     }
0406   }
0407 
0408   /* Return BSP status */
0409   return ret;
0410 }
0411 
0412 /**
0413   * @brief  Writes an amount of data to the QSPI memory.
0414   * @param  Instance   QSPI instance
0415   * @param  pData      Pointer to data to be written
0416   * @param  WriteAddr  Write start address
0417   * @param  Size       Size of data to write
0418   * @retval BSP status
0419   */
0420 int32_t BSP_QSPI_Write(uint32_t Instance, uint8_t *pData, uint32_t WriteAddr, uint32_t Size)
0421 {
0422   int32_t ret = BSP_ERROR_NONE;
0423   uint32_t end_addr, current_size, current_addr;
0424   uint8_t *write_data;
0425 
0426   /* Check if the instance is supported */
0427   if(Instance >= QSPI_INSTANCES_NUMBER)
0428   {
0429     ret = BSP_ERROR_WRONG_PARAM;
0430   }
0431   else
0432   {
0433     /* Calculation of the size between the write address and the end of the page */
0434     current_size = MT25TL01G_PAGE_SIZE - (WriteAddr % MT25TL01G_PAGE_SIZE);
0435 
0436     /* Check if the size of the data is less than the remaining place in the page */
0437     if (current_size > Size)
0438     {
0439       current_size = Size;
0440     }
0441 
0442     /* Initialize the address variables */
0443     current_addr = WriteAddr;
0444     end_addr = WriteAddr + Size;
0445     write_data = pData;
0446 
0447     /* Perform the write page by page */
0448     do
0449     {
0450       /* Check if Flash busy ? */
0451       if(MT25TL01G_AutoPollingMemReady(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != MT25TL01G_OK)
0452       {
0453         ret = BSP_ERROR_COMPONENT_FAILURE;
0454       }/* Enable write operations */
0455       else if(MT25TL01G_WriteEnable(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != MT25TL01G_OK)
0456       {
0457         ret = BSP_ERROR_COMPONENT_FAILURE;
0458       }/* Issue page program command */
0459       else if(MT25TL01G_PageProgram(&hqspi, QSPI_Ctx[Instance].InterfaceMode, write_data, current_addr, current_size) != MT25TL01G_OK)
0460       {
0461         ret = BSP_ERROR_COMPONENT_FAILURE;
0462       }/* Configure automatic polling mode to wait for end of program */
0463       else if (MT25TL01G_AutoPollingMemReady(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != MT25TL01G_OK)
0464       {
0465         ret = BSP_ERROR_COMPONENT_FAILURE;
0466       }
0467       else
0468       {
0469         /* Update the address and size variables for next page programming */
0470         current_addr += current_size;
0471         write_data += current_size;
0472         current_size = ((current_addr + MT25TL01G_PAGE_SIZE) > end_addr) ? (end_addr - current_addr) : MT25TL01G_PAGE_SIZE;
0473       }
0474     } while ((current_addr < end_addr) && (ret == BSP_ERROR_NONE));
0475   }
0476 
0477   /* Return BSP status */
0478   return ret;
0479 }
0480 
0481 /**
0482   * @brief  Erases the specified block of the QSPI memory.
0483   *         MT25TL01G support 4K, 32K, 64K size block erase commands for each Die.
0484   *           i.e 8K, 64K, 128K at BSP level (see BSP_QSPI_Erase_t type definition)
0485   * @param  Instance     QSPI instance
0486   * @param  BlockAddress Block address to erase
0487   * @param  BlockSize    Erase Block size
0488   * @retval BSP status
0489   */
0490 int32_t BSP_QSPI_EraseBlock(uint32_t Instance, uint32_t BlockAddress, BSP_QSPI_Erase_t BlockSize)
0491 {
0492   int32_t ret = BSP_ERROR_NONE;
0493 
0494   /* Check if the instance is supported */
0495   if(Instance >= QSPI_INSTANCES_NUMBER)
0496   {
0497     ret = BSP_ERROR_WRONG_PARAM;
0498   }
0499   else
0500   {
0501     /* Check Flash busy ? */
0502     if(MT25TL01G_AutoPollingMemReady(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != MT25TL01G_OK)
0503     {
0504       ret = BSP_ERROR_COMPONENT_FAILURE;
0505     }/* Enable write operations */
0506     else if(MT25TL01G_WriteEnable(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != MT25TL01G_OK)
0507     {
0508       ret = BSP_ERROR_COMPONENT_FAILURE;
0509     }
0510     else
0511     {
0512       /* Issue Block Erase command */
0513       if(MT25TL01G_BlockErase(&hqspi, QSPI_Ctx[Instance].InterfaceMode, BlockAddress, (MT25TL01G_Erase_t)BlockSize) != MT25TL01G_OK)
0514       {
0515         ret = BSP_ERROR_COMPONENT_FAILURE;
0516       }
0517     }
0518   }
0519 
0520   /* Return BSP status */
0521   return ret;
0522 }
0523 
0524 /**
0525   * @brief  Erases the entire QSPI memory.
0526   * @param  Instance  QSPI instance
0527   * @retval BSP status
0528   */
0529 int32_t BSP_QSPI_EraseChip(uint32_t Instance)
0530 {
0531   int32_t ret = BSP_ERROR_NONE;
0532 
0533   /* Check if the instance is supported */
0534   if(Instance >= QSPI_INSTANCES_NUMBER)
0535   {
0536     ret = BSP_ERROR_WRONG_PARAM;
0537   }
0538   else
0539   {
0540     /* Check Flash busy ? */
0541     if(MT25TL01G_AutoPollingMemReady(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != MT25TL01G_OK)
0542     {
0543       ret = BSP_ERROR_COMPONENT_FAILURE;
0544     }/* Enable write operations */
0545     else if (MT25TL01G_WriteEnable(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != MT25TL01G_OK)
0546     {
0547       ret = BSP_ERROR_COMPONENT_FAILURE;
0548     }
0549     else
0550     {
0551       /* Issue Chip erase command */
0552       if(MT25TL01G_ChipErase(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != MT25TL01G_OK)
0553       {
0554         ret = BSP_ERROR_COMPONENT_FAILURE;
0555       }
0556     }
0557   }
0558 
0559   /* Return BSP status */
0560   return ret;
0561 }
0562 
0563 /**
0564   * @brief  Reads current status of the QSPI memory.
0565   *         If WIP != 0 then return busy.
0566   * @param  Instance  QSPI instance
0567   * @retval QSPI memory status: whether busy or not
0568   */
0569 int32_t BSP_QSPI_GetStatus(uint32_t Instance)
0570 {
0571   int32_t ret = BSP_ERROR_NONE;
0572   uint8_t reg;
0573 
0574   /* Check if the instance is supported */
0575   if(Instance >= QSPI_INSTANCES_NUMBER)
0576   {
0577     ret = BSP_ERROR_WRONG_PARAM;
0578   }
0579   else
0580   {
0581     if(MT25TL01G_ReadStatusRegister(&hqspi, QSPI_Ctx[Instance].InterfaceMode, &reg) != MT25TL01G_OK)
0582     {
0583       ret = BSP_ERROR_COMPONENT_FAILURE;
0584     }
0585     else
0586     {
0587       /* Check the value of the register */
0588       if ((reg & MT25TL01G_SR_WIP) != 0U)
0589       {
0590         ret = BSP_ERROR_BUSY;
0591       }
0592     }
0593   }
0594 
0595   /* Return BSP status */
0596   return ret;
0597 }
0598 
0599 /**
0600   * @brief  Return the configuration of the QSPI memory.
0601   * @param  Instance  QSPI instance
0602   * @param  pInfo     pointer on the configuration structure
0603   * @retval BSP status
0604   */
0605 int32_t BSP_QSPI_GetInfo(uint32_t Instance, BSP_QSPI_Info_t *pInfo)
0606 {
0607   int32_t ret = BSP_ERROR_NONE;
0608 
0609   /* Check if the instance is supported */
0610   if(Instance >= QSPI_INSTANCES_NUMBER)
0611   {
0612     ret = BSP_ERROR_WRONG_PARAM;
0613   }
0614   else
0615   {
0616     (void)MT25TL01G_GetFlashInfo(pInfo);
0617   }
0618 
0619   /* Return BSP status */
0620   return ret;
0621 }
0622 
0623 /**
0624   * @brief  Configure the QSPI in memory-mapped mode
0625   *         Only 1 Instance can running MMP mode. And it will lock system at this mode.
0626   * @param  Instance  QSPI instance
0627   * @retval BSP status
0628   */
0629 int32_t BSP_QSPI_EnableMemoryMappedMode(uint32_t Instance)
0630 {
0631   int32_t ret = BSP_ERROR_NONE;
0632 
0633   /* Check if the instance is supported */
0634   if(Instance >= QSPI_INSTANCES_NUMBER)
0635   {
0636     ret = BSP_ERROR_WRONG_PARAM;
0637   }
0638   else
0639   {
0640     if(QSPI_Ctx[Instance].TransferRate == BSP_QSPI_STR_TRANSFER)
0641     {
0642       if(MT25TL01G_EnableMemoryMappedModeSTR(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != MT25TL01G_OK)
0643       {
0644         ret = BSP_ERROR_COMPONENT_FAILURE;
0645       }
0646       else /* Update QSPI context if all operations are well done */
0647       {
0648         QSPI_Ctx[Instance].IsInitialized = QSPI_ACCESS_MMP;
0649       }
0650     }
0651     else
0652     {
0653       if(MT25TL01G_EnableMemoryMappedModeDTR(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != MT25TL01G_OK)
0654       {
0655         ret = BSP_ERROR_COMPONENT_FAILURE;
0656       }
0657       else /* Update QSPI context if all operations are well done */
0658       {
0659         QSPI_Ctx[Instance].IsInitialized = QSPI_ACCESS_MMP;
0660       }
0661     }
0662   }
0663 
0664   /* Return BSP status */
0665   return ret;
0666 }
0667 
0668 /**
0669   * @brief  Exit form memory-mapped mode
0670   *         Only 1 Instance can running MMP mode. And it will lock system at this mode.
0671   * @param  Instance  QSPI instance
0672   * @retval BSP status
0673   */
0674 int32_t BSP_QSPI_DisableMemoryMappedMode(uint32_t Instance)
0675 {
0676   uint8_t Dummy;
0677   int32_t ret = BSP_ERROR_NONE;
0678 
0679   /* Check if the instance is supported */
0680   if(Instance >= QSPI_INSTANCES_NUMBER)
0681   {
0682     ret = BSP_ERROR_WRONG_PARAM;
0683   }
0684   else
0685   {
0686     if(QSPI_Ctx[Instance].IsInitialized != QSPI_ACCESS_MMP)
0687     {
0688       ret = BSP_ERROR_QSPI_MMP_UNLOCK_FAILURE;
0689     }/* Abort MMP back to indirect mode */
0690     else if(HAL_QSPI_Abort(&hqspi) != HAL_OK)
0691     {
0692       ret = BSP_ERROR_PERIPH_FAILURE;
0693     }
0694     else
0695     {
0696       /* Force QSPI interface Sampling Shift to half cycle */
0697       hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE;
0698 
0699       if(HAL_QSPI_Init(&hqspi)!= HAL_OK)
0700       {
0701         ret = BSP_ERROR_PERIPH_FAILURE;
0702       }
0703       /* Dummy read for exit from Performance Enhance mode */
0704       else if(MT25TL01G_ReadSTR(&hqspi, QSPI_Ctx[Instance].InterfaceMode, &Dummy, 0, 1) != MT25TL01G_OK)
0705       {
0706         ret = BSP_ERROR_COMPONENT_FAILURE;
0707       }
0708       else /* Update QSPI context if all operations are well done */
0709       {
0710         QSPI_Ctx[Instance].IsInitialized = QSPI_ACCESS_INDIRECT;
0711       }
0712     }
0713   }
0714   /* Return BSP status */
0715   return ret;
0716 }
0717 
0718 /**
0719   * @brief  Get flash ID, 3 Byte
0720   *         Manufacturer ID, Memory type, Memory density
0721   * @param  Instance  QSPI instance
0722   * @param  Id QSPI Identifier
0723   * @retval BSP status
0724   */
0725 int32_t BSP_QSPI_ReadID(uint32_t Instance, uint8_t *Id)
0726 {
0727   int32_t ret = BSP_ERROR_NONE;
0728 
0729   /* Check if the instance is supported */
0730   if(Instance >= QSPI_INSTANCES_NUMBER)
0731   {
0732     ret = BSP_ERROR_WRONG_PARAM;
0733   }
0734   else
0735   {
0736     if(MT25TL01G_ReadID(&hqspi, QSPI_Ctx[Instance].InterfaceMode, Id) != MT25TL01G_OK)
0737     {
0738       ret = BSP_ERROR_COMPONENT_FAILURE;
0739     }
0740   }
0741 
0742   /* Return BSP status */
0743   return ret;
0744 }
0745 
0746 /**
0747   * @brief  Set Flash to desired Interface mode. And this instance becomes current instance.
0748   *         If current instance running at MMP mode then this function isn't work.
0749   *         Indirect -> Indirect
0750   * @param  Instance  QSPI instance
0751   * @param  Mode      QSPI mode
0752   * @param  Rate      QSPI transfer rate
0753   * @retval BSP status
0754   */
0755 int32_t BSP_QSPI_ConfigFlash(uint32_t Instance, BSP_QSPI_Interface_t Mode, BSP_QSPI_Transfer_t Rate)
0756 {
0757   int32_t ret = BSP_ERROR_NONE;
0758 
0759   /* Check if the instance is supported */
0760   if(Instance >= QSPI_INSTANCES_NUMBER)
0761   {
0762     ret = BSP_ERROR_WRONG_PARAM;
0763   }
0764   else
0765   {
0766     /* Check if MMP mode locked ************************************************/
0767     if(QSPI_Ctx[Instance].IsInitialized == QSPI_ACCESS_MMP)
0768     {
0769       ret = BSP_ERROR_QSPI_MMP_LOCK_FAILURE;
0770     }
0771     else
0772     {
0773       /* Setup MCU transfer rate setting ***************************************************/
0774       hqspi.Init.SampleShifting = (Rate == BSP_QSPI_STR_TRANSFER) ? QSPI_SAMPLE_SHIFTING_HALFCYCLE : QSPI_SAMPLE_SHIFTING_NONE;
0775 
0776       if(HAL_QSPI_Init(&hqspi)!= HAL_OK)
0777       {
0778         ret = BSP_ERROR_PERIPH_FAILURE;
0779       }
0780       else
0781       {
0782         /* Setup Flash interface ***************************************************/
0783         switch(QSPI_Ctx[Instance].InterfaceMode)
0784         {
0785         case MT25TL01G_QPI_MODE :               /* 4-4-4 commands */
0786           if(Mode != MT25TL01G_QPI_MODE)
0787           {
0788             if(MT25TL01G_ExitQPIMode(&hqspi) != MT25TL01G_OK)
0789             {
0790               ret = BSP_ERROR_COMPONENT_FAILURE;
0791             }
0792           }
0793           break;
0794 
0795         case BSP_QSPI_SPI_MODE :               /* 1-1-1 commands, Power on H/W default setting */
0796         case BSP_QSPI_SPI_2IO_MODE :           /* 1-2-2 read commands */
0797         case BSP_QSPI_SPI_4IO_MODE :           /* 1-4-4 read commands */
0798         default :
0799           if(Mode == MT25TL01G_QPI_MODE)
0800           {
0801             if(MT25TL01G_EnterQPIMode(&hqspi) != MT25TL01G_OK)
0802             {
0803               ret = BSP_ERROR_COMPONENT_FAILURE;
0804             }
0805           }
0806           break;
0807         }
0808 
0809         /* Update QSPI context if all operations are well done */
0810         if(ret == BSP_ERROR_NONE)
0811         {
0812           /* Update current status parameter *****************************************/
0813           QSPI_Ctx[Instance].IsInitialized = QSPI_ACCESS_INDIRECT;
0814           QSPI_Ctx[Instance].InterfaceMode = Mode;
0815           QSPI_Ctx[Instance].TransferRate  = Rate;
0816         }
0817       }
0818     }
0819   }
0820 
0821   /* Return BSP status */
0822   return ret;
0823 }
0824 
0825 /**
0826   * @}
0827   */
0828 
0829 /** @defgroup STM32H747I_EVAL_QSPI_Private_Functions Private Functions
0830   * @{
0831   */
0832 
0833 /**
0834   * @brief QSPI MSP Initialization
0835   * @param hQspi : QSPI handle
0836   *        This function configures the hardware resources used in this example:
0837   *           - Peripheral's clock enable
0838   *           - Peripheral's GPIO Configuration
0839   *           - NVIC configuration for QSPI interrupt
0840   * @retval None
0841   */
0842 static void QSPI_MspInit(QSPI_HandleTypeDef *hQspi)
0843 {
0844   GPIO_InitTypeDef gpio_init_structure;
0845 
0846   /* Prevent unused argument(s) compilation warning */
0847   UNUSED(hQspi);
0848 
0849   /*##-1- Enable peripherals and GPIO Clocks #################################*/
0850   /* Enable the QuadSPI memory interface clock */
0851   QSPI_CLK_ENABLE();
0852   /* Reset the QuadSPI memory interface */
0853   QSPI_FORCE_RESET();
0854   QSPI_RELEASE_RESET();
0855   /* Enable GPIO clocks */
0856   QSPI_CLK_GPIO_CLK_ENABLE();
0857   QSPI_BK1_CS_GPIO_CLK_ENABLE();
0858   QSPI_BK1_D0_GPIO_CLK_ENABLE();
0859   QSPI_BK1_D1_GPIO_CLK_ENABLE();
0860   QSPI_BK1_D2_GPIO_CLK_ENABLE();
0861   QSPI_BK1_D3_GPIO_CLK_ENABLE();
0862 
0863   QSPI_BK2_CS_GPIO_CLK_ENABLE();
0864   QSPI_BK2_D0_GPIO_CLK_ENABLE();
0865   QSPI_BK2_D1_GPIO_CLK_ENABLE();
0866   QSPI_BK2_D2_GPIO_CLK_ENABLE();
0867   QSPI_BK2_D3_GPIO_CLK_ENABLE();
0868 
0869   /*##-2- Configure peripheral GPIO ##########################################*/
0870   /* QSPI CLK GPIO pin configuration  */
0871   gpio_init_structure.Pin       = QSPI_CLK_PIN;
0872   gpio_init_structure.Mode      = GPIO_MODE_AF_PP;
0873   gpio_init_structure.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
0874   gpio_init_structure.Pull      = GPIO_NOPULL;
0875   gpio_init_structure.Alternate = GPIO_AF9_QUADSPI;
0876   HAL_GPIO_Init(QSPI_CLK_GPIO_PORT, &gpio_init_structure);
0877 
0878   /* QSPI CS GPIO pin configuration  */
0879   gpio_init_structure.Pin       = QSPI_BK1_CS_PIN;
0880   gpio_init_structure.Pull      = GPIO_PULLUP;
0881   gpio_init_structure.Alternate = GPIO_AF10_QUADSPI;
0882   HAL_GPIO_Init(QSPI_BK1_CS_GPIO_PORT, &gpio_init_structure);
0883 
0884   gpio_init_structure.Pin       = QSPI_BK2_CS_PIN;
0885   gpio_init_structure.Mode      = GPIO_MODE_AF_PP;
0886   gpio_init_structure.Pull      = GPIO_PULLUP;
0887   gpio_init_structure.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
0888   gpio_init_structure.Alternate = GPIO_AF9_QUADSPI;
0889   HAL_GPIO_Init(QSPI_BK2_CS_GPIO_PORT, &gpio_init_structure);
0890 
0891   /* QSPI D0 GPIO pin configuration  */
0892   gpio_init_structure.Pin       = QSPI_BK1_D0_PIN;
0893   gpio_init_structure.Pull      = GPIO_NOPULL;
0894   gpio_init_structure.Alternate = GPIO_AF10_QUADSPI;
0895   HAL_GPIO_Init(QSPI_BK1_D0_GPIO_PORT, &gpio_init_structure);
0896 
0897   gpio_init_structure.Pin       = QSPI_BK2_D0_PIN;
0898   gpio_init_structure.Alternate = GPIO_AF9_QUADSPI;
0899   HAL_GPIO_Init(QSPI_BK2_D0_GPIO_PORT, &gpio_init_structure);
0900 
0901   /* QSPI D1 GPIO pin configuration  */
0902   gpio_init_structure.Pin       = QSPI_BK1_D1_PIN;
0903   gpio_init_structure.Alternate = GPIO_AF10_QUADSPI;
0904   HAL_GPIO_Init(QSPI_BK1_D1_GPIO_PORT, &gpio_init_structure);
0905 
0906   gpio_init_structure.Pin       = QSPI_BK2_D1_PIN;
0907   gpio_init_structure.Alternate = GPIO_AF9_QUADSPI;
0908   HAL_GPIO_Init(QSPI_BK2_D1_GPIO_PORT, &gpio_init_structure);
0909 
0910   /* QSPI D2 GPIO pin configuration  */
0911   gpio_init_structure.Pin       = QSPI_BK1_D2_PIN;
0912   gpio_init_structure.Alternate = GPIO_AF9_QUADSPI;
0913   HAL_GPIO_Init(QSPI_BK1_D2_GPIO_PORT, &gpio_init_structure);
0914 
0915   gpio_init_structure.Pin       = QSPI_BK2_D2_PIN;
0916   HAL_GPIO_Init(QSPI_BK2_D2_GPIO_PORT, &gpio_init_structure);
0917 
0918   /* QSPI D3 GPIO pin configuration  */
0919   gpio_init_structure.Pin       = QSPI_BK1_D3_PIN;
0920   HAL_GPIO_Init(QSPI_BK1_D3_GPIO_PORT, &gpio_init_structure);
0921 
0922   gpio_init_structure.Pin       = QSPI_BK2_D3_PIN;
0923   HAL_GPIO_Init(QSPI_BK2_D3_GPIO_PORT, &gpio_init_structure);
0924 
0925   /*##-3- Configure the NVIC for QSPI #########################################*/
0926   /* NVIC configuration for QSPI interrupt */
0927   HAL_NVIC_SetPriority(QUADSPI_IRQn, 0x0F, 0);
0928   HAL_NVIC_EnableIRQ(QUADSPI_IRQn);
0929 }
0930 
0931 /**
0932   * @brief QSPI MSP De-Initialization
0933   * @param hQspi  QSPI handle
0934   *        This function frees the hardware resources used in this example:
0935   *          - Disable the Peripheral's clock
0936   *          - Revert GPIO and NVIC configuration to their default state
0937   * @retval None
0938   */
0939 static void QSPI_MspDeInit(QSPI_HandleTypeDef *hQspi)
0940 {
0941   /* Prevent unused argument(s) compilation warning */
0942   UNUSED(hQspi);
0943 
0944   /*##-2- Disable peripherals and GPIO Clocks ################################*/
0945   /* De-Configure QSPI pins */
0946   HAL_GPIO_DeInit(QSPI_CLK_GPIO_PORT, QSPI_CLK_PIN);
0947   HAL_GPIO_DeInit(QSPI_BK1_CS_GPIO_PORT, QSPI_BK1_CS_PIN);
0948   HAL_GPIO_DeInit(QSPI_BK1_D0_GPIO_PORT, QSPI_BK1_D0_PIN);
0949   HAL_GPIO_DeInit(QSPI_BK1_D1_GPIO_PORT, QSPI_BK1_D1_PIN);
0950   HAL_GPIO_DeInit(QSPI_BK1_D2_GPIO_PORT, QSPI_BK1_D2_PIN);
0951   HAL_GPIO_DeInit(QSPI_BK1_D3_GPIO_PORT, QSPI_BK1_D3_PIN);
0952 
0953   HAL_GPIO_DeInit(QSPI_BK2_CS_GPIO_PORT, QSPI_BK2_CS_PIN);
0954   HAL_GPIO_DeInit(QSPI_BK2_D0_GPIO_PORT, QSPI_BK2_D0_PIN);
0955   HAL_GPIO_DeInit(QSPI_BK2_D1_GPIO_PORT, QSPI_BK2_D1_PIN);
0956   HAL_GPIO_DeInit(QSPI_BK2_D2_GPIO_PORT, QSPI_BK2_D2_PIN);
0957   HAL_GPIO_DeInit(QSPI_BK2_D3_GPIO_PORT, QSPI_BK2_D3_PIN);
0958 
0959   /*##-3- Reset peripherals ##################################################*/
0960   /* Reset the QuadSPI memory interface */
0961   QSPI_FORCE_RESET();
0962   QSPI_RELEASE_RESET();
0963 
0964   /* Disable the QuadSPI memory interface clock */
0965   QSPI_CLK_DISABLE();
0966 }
0967 
0968 /**
0969   * @brief  This function reset the QSPI Flash memory.
0970   *         Fore QPI+SPI reset to avoid system come from unknown status.
0971   *         Flash accept 1-1-1, 1-1-2, 1-2-2 commands after reset.
0972   * @param  Instance  QSPI instance
0973   * @retval BSP status
0974   */
0975 static int32_t QSPI_ResetMemory(uint32_t Instance)
0976 {
0977   int32_t ret = BSP_ERROR_NONE;
0978 
0979   /* Send RESET ENABLE command in QPI mode (QUAD I/Os, 4-4-4) */
0980   if(MT25TL01G_ResetEnable(&hqspi, MT25TL01G_QPI_MODE) != MT25TL01G_OK)
0981   {
0982     ret =BSP_ERROR_COMPONENT_FAILURE;
0983   }/* Send RESET memory command in QPI mode (QUAD I/Os, 4-4-4) */
0984   else if(MT25TL01G_ResetMemory(&hqspi, MT25TL01G_QPI_MODE) != MT25TL01G_OK)
0985   {
0986     ret = BSP_ERROR_COMPONENT_FAILURE;
0987   }/* Wait Flash ready */
0988   else if(MT25TL01G_AutoPollingMemReady(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != MT25TL01G_OK)
0989   {
0990     ret = BSP_ERROR_COMPONENT_FAILURE;
0991   }/* Send RESET ENABLE command in SPI mode (1-1-1) */
0992   else if(MT25TL01G_ResetEnable(&hqspi, BSP_QSPI_SPI_MODE) != MT25TL01G_OK)
0993   {
0994     ret = BSP_ERROR_COMPONENT_FAILURE;
0995   }/* Send RESET memory command in SPI mode (1-1-1) */
0996   else if(MT25TL01G_ResetMemory(&hqspi, BSP_QSPI_SPI_MODE) != MT25TL01G_OK)
0997   {
0998     ret = BSP_ERROR_COMPONENT_FAILURE;
0999   }
1000   else
1001   {
1002     QSPI_Ctx[Instance].IsInitialized = QSPI_ACCESS_INDIRECT;  /* After reset S/W setting to indirect access   */
1003     QSPI_Ctx[Instance].InterfaceMode = BSP_QSPI_SPI_MODE;     /* After reset H/W back to SPI mode by default  */
1004     QSPI_Ctx[Instance].TransferRate  = BSP_QSPI_STR_TRANSFER; /* After reset S/W setting to STR mode          */
1005 
1006   }
1007 
1008   /* Return BSP status */
1009   return ret;
1010 }
1011 
1012 /**
1013   * @brief  This function configure the dummy cycles on memory side.
1014   *         Dummy cycle bit locate in Configuration Register[7:6]
1015   * @param  Instance  QSPI instance
1016   * @retval BSP status
1017   */
1018 static int32_t QSPI_DummyCyclesCfg(uint32_t Instance)
1019 {
1020     int32_t ret= BSP_ERROR_NONE;
1021     QSPI_CommandTypeDef s_command;
1022   uint16_t reg=0;
1023 
1024   /* Initialize the read volatile configuration register command */
1025   s_command.InstructionMode   = QSPI_INSTRUCTION_4_LINES;
1026   s_command.Instruction       = MT25TL01G_READ_VOL_CFG_REG_CMD;
1027   s_command.AddressMode       = QSPI_ADDRESS_NONE;
1028   s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
1029   s_command.DataMode          = QSPI_DATA_4_LINES;
1030   s_command.DummyCycles       = 0;
1031   s_command.NbData            = 2;
1032   s_command.DdrMode           = QSPI_DDR_MODE_DISABLE;
1033   s_command.DdrHoldHalfCycle  = QSPI_DDR_HHC_ANALOG_DELAY;
1034   s_command.SIOOMode          = QSPI_SIOO_INST_EVERY_CMD;
1035 
1036   /* Configure the command */
1037   if (HAL_QSPI_Command(&hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
1038   {
1039     return BSP_ERROR_COMPONENT_FAILURE;
1040   }
1041 
1042   /* Reception of the data */
1043   if (HAL_QSPI_Receive(&hqspi, (uint8_t *)(&reg), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
1044   {
1045     return BSP_ERROR_COMPONENT_FAILURE;
1046   }
1047 
1048   /* Enable write operations */
1049   if (MT25TL01G_WriteEnable(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != MT25TL01G_OK)
1050   {
1051     return BSP_ERROR_COMPONENT_FAILURE;
1052   }
1053 
1054   /* Update volatile configuration register (with new dummy cycles) */
1055   s_command.Instruction = MT25TL01G_WRITE_VOL_CFG_REG_CMD;
1056   MODIFY_REG(reg, 0xF0F0, ((MT25TL01G_DUMMY_CYCLES_READ_QUAD << 4) |
1057                                (MT25TL01G_DUMMY_CYCLES_READ_QUAD << 12)));
1058 
1059   /* Configure the write volatile configuration register command */
1060   if (HAL_QSPI_Command(&hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
1061   {
1062     return BSP_ERROR_COMPONENT_FAILURE;
1063   }
1064 
1065   /* Transmission of the data */
1066   if (HAL_QSPI_Transmit(&hqspi, (uint8_t *)(&reg), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
1067   {
1068     return BSP_ERROR_COMPONENT_FAILURE;
1069   }
1070 
1071   /* Return BSP status */
1072   return ret;
1073 }
1074 /**
1075   * @}
1076   */
1077 
1078 /**
1079   * @}
1080   */
1081 
1082 /**
1083   * @}
1084   */
1085 
1086 /**
1087   * @}
1088   */