Sponsored-By: Precidata --- .../stm32h747i_discovery_conf.h | 119 ++ .../stm32h747i_discovery_errno.h | 106 ++ .../stm32h747i_discovery_qspi.c | 1100 +++++++++++++++++ .../stm32h747i_discovery_qspi.h | 286 +++++ 4 files changed, 1611 insertions(+) create mode 100644 bsps/arm/stm32h7/boards/stm/stm32h747i-disco/stm32h747i_discovery_conf.h create mode 100644 bsps/arm/stm32h7/boards/stm/stm32h747i-disco/stm32h747i_discovery_errno.h create mode 100644 bsps/arm/stm32h7/boards/stm/stm32h747i-disco/stm32h747i_discovery_qspi.c create mode 100644 bsps/arm/stm32h7/boards/stm/stm32h747i-disco/stm32h747i_discovery_qspi.h
diff --git a/bsps/arm/stm32h7/boards/stm/stm32h747i-disco/stm32h747i_discovery_conf.h b/bsps/arm/stm32h7/boards/stm/stm32h747i-disco/stm32h747i_discovery_conf.h new file mode 100644 index 0000000000..8cacaddb7e --- /dev/null +++ b/bsps/arm/stm32h7/boards/stm/stm32h747i-disco/stm32h747i_discovery_conf.h @@ -0,0 +1,119 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/** + ****************************************************************************** + * @file stm32h747i_discovery_conf_template.h + * @author MCD Application Team + * @brief STM32H747I_DISCO board configuration file. + ****************************************************************************** + * @attention + * + * Copyright (c) 2018 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* + * RTEMS committer clarification comment on license above: + * + * This file comes from STM32CubeH7 project and is located here: + * https://github.com/STMicroelectronics/STM32CubeH7/blob/master/Drivers/BSP/STM32H747I-DISCO/stm32h747i_discovery_conf_template.h + * + * The file root directory is: + * https://github.com/STMicroelectronics/STM32CubeH7/tree/master/Drivers/BSP/STM32H747I-DISCO + * + * This directory contains LICENSE.md file with a following license text: + * + * Copyright 2019 STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H747I_DISCO_CONF_H +#define STM32H747I_DISCO_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7xx_hal.h" + +/* COM define */ +#define USE_COM_LOG 0U +#define USE_BSP_COM_FEATURE 0U + +/* LCD controllers defines */ +#define USE_LCD_CTRL_OTM8009A 1U +#define USE_LCD_CTRL_ADV7533 1U + +#define LCD_LAYER_0_ADDRESS 0xC0000000U +#define LCD_LAYER_1_ADDRESS 0xC0200000U + +#define USE_DMA2D_TO_FILL_RGB_RECT 0U +/* Camera sensors defines */ +#define USE_CAMERA_SENSOR_OV5640 1U +#define USE_CAMERA_SENSOR_OV9655 1U + +/* SD interface defines */ +#define USE_SD_BUS_WIDE_4B 1U + +/* Audio codecs defines */ +#define USE_AUDIO_CODEC_WM8994 1U + +/* TS supported features defines */ +#define USE_TS_GESTURE 1U +#define USE_TS_MULTI_TOUCH 1U + +/* Default TS touch number */ +#define TS_TOUCH_NBR 2U + +/* IRQ priorities */ +#define BSP_SDRAM_IT_PRIORITY 15U +#define BSP_CAMERA_IT_PRIORITY 15U +#define BSP_BUTTON_WAKEUP_IT_PRIORITY 15U +#define BSP_AUDIO_OUT_IT_PRIORITY 14U +#define BSP_AUDIO_IN_IT_PRIORITY 15U +#define BSP_SD_IT_PRIORITY 14U +#define BSP_SD_RX_IT_PRIORITY 14U +#define BSP_SD_TX_IT_PRIORITY 15U +#define BSP_TS_IT_PRIORITY 15U +#define BSP_JOY1_SEL_IT_PRIORITY 15U +#define BSP_JOY1_DOWN_IT_PRIORITY 15U +#define BSP_JOY1_LEFT_IT_PRIORITY 15U +#define BSP_JOY1_RIGHT_IT_PRIORITY 15U +#define BSP_JOY1_UP_IT_PRIORITY 15U + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H747I_DISCO_CONF_H */ diff --git a/bsps/arm/stm32h7/boards/stm/stm32h747i-disco/stm32h747i_discovery_errno.h b/bsps/arm/stm32h7/boards/stm/stm32h747i-disco/stm32h747i_discovery_errno.h new file mode 100644 index 0000000000..269036d170 --- /dev/null +++ b/bsps/arm/stm32h7/boards/stm/stm32h747i-disco/stm32h747i_discovery_errno.h @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/** + ****************************************************************************** + * @file STM32H747I_discovery_errno.h + * @author MCD Application Team + * @brief Error Code. + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2018 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* + * RTEMS committer clarification comment on license above: + * + * This file comes from STM32CubeH7 project and is located here: + * https://github.com/STMicroelectronics/STM32CubeH7/blob/master/Drivers/BSP/STM32H747I-DISCO/stm32h747i_discovery_errno.h + * + * The file root directory is: + * https://github.com/STMicroelectronics/STM32CubeH7/tree/master/Drivers/BSP/STM32H747I-DISCO + * + * This directory contains LICENSE.md file with a following license text: + * + * Copyright 2019 STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H747I_DISCO_ERRNO_H +#define STM32H747I_DISCO_ERRNO_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Common Error codes */ +#define BSP_ERROR_NONE 0 +#define BSP_ERROR_NO_INIT -1 +#define BSP_ERROR_WRONG_PARAM -2 +#define BSP_ERROR_BUSY -3 +#define BSP_ERROR_PERIPH_FAILURE -4 +#define BSP_ERROR_COMPONENT_FAILURE -5 +#define BSP_ERROR_UNKNOWN_FAILURE -6 +#define BSP_ERROR_UNKNOWN_COMPONENT -7 +#define BSP_ERROR_BUS_FAILURE -8 +#define BSP_ERROR_CLOCK_FAILURE -9 +#define BSP_ERROR_MSP_FAILURE -10 +#define BSP_ERROR_FEATURE_NOT_SUPPORTED -11 + +/* BSP OSPI error codes */ +#define BSP_ERROR_QSPI_ASSIGN_FAILURE -24 +#define BSP_ERROR_QSPI_SETUP_FAILURE -25 +#define BSP_ERROR_QSPI_MMP_LOCK_FAILURE -26 +#define BSP_ERROR_QSPI_MMP_UNLOCK_FAILURE -27 + +/* BSP TS error code */ +#define BSP_ERROR_TS_TOUCH_NOT_DETECTED -30 + +/* BSP BUS error codes */ +#define BSP_ERROR_BUS_TRANSACTION_FAILURE -100 +#define BSP_ERROR_BUS_ARBITRATION_LOSS -101 +#define BSP_ERROR_BUS_ACKNOWLEDGE_FAILURE -102 +#define BSP_ERROR_BUS_PROTOCOL_FAILURE -103 + +#define BSP_ERROR_BUS_MODE_FAULT -104 +#define BSP_ERROR_BUS_FRAME_ERROR -105 +#define BSP_ERROR_BUS_CRC_ERROR -106 +#define BSP_ERROR_BUS_DMA_FAILURE -107 + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H747I_DISCO_ERRNO_H */ diff --git a/bsps/arm/stm32h7/boards/stm/stm32h747i-disco/stm32h747i_discovery_qspi.c b/bsps/arm/stm32h7/boards/stm/stm32h747i-disco/stm32h747i_discovery_qspi.c new file mode 100644 index 0000000000..6c53cb28bb --- /dev/null +++ b/bsps/arm/stm32h7/boards/stm/stm32h747i-disco/stm32h747i_discovery_qspi.c @@ -0,0 +1,1100 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/** + ****************************************************************************** + * @file stm32h747i_discovery_qspi.c + * @author MCD Application Team + * @brief This file includes a standard driver for the MT25TL01G QSPI + * memory mounted on STM32H747I-DISCO board. + @verbatim + How To use this driver: + ----------------------- + - This driver is used to drive the MT25TL01G QSPI external + memory mounted on STM32H747I-DISCO board. + + - This driver need a specific component driver (MT25TL01G) to be included with. + + Driver description: + ------------------- + - Initialization steps: + + Initialize the QPSI external memory using the BSP_QSPI_Init() function. This + function includes the MSP layer hardware resources initialization and the + QSPI interface with the external memory. + STR and DTR transfer rates are supported. + SPI, SPI 2-IO, SPI-4IO and QPI modes are supported + + - QSPI memory operations + + QSPI memory can be accessed with read/write operations once it is + initialized. + Read/write operation can be performed with AHB access using the functions + BSP_QSPI_Read()/BSP_QSPI_Write(). + + The function BSP_QSPI_GetInfo() returns the configuration of the QSPI memory. + (see the QSPI memory data sheet) + + Perform erase block operation using the function BSP_QSPI_EraseBlock() and by + specifying the block address. You can perform an erase operation of the whole + chip by calling the function BSP_QSPI_EraseChip(). + + The function BSP_QSPI_GetStatus() returns the current status of the QSPI memory. + (see the QSPI memory data sheet) + + The function BSP_QSPI_EnableMemoryMappedMode enables the QSPI memory mapped mode + + The function BSP_QSPI_DisableMemoryMappedMode disables the QSPI memory mapped mode + + The function BSP_QSPI_ConfigFlash() allow to configure the QSPI mode and transfer rate + + Note: + -------- + Regarding the "Instance" parameter, needed for all functions, it is used to select + an QSPI instance. On the STM32H747I_DISCO board, there's one instance. Then, this + parameter should be 0. + + @endverbatim + ****************************************************************************** + * @attention + * + * Copyright (c) 2018 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* + * RTEMS committer clarification comment on license above: + * + * This file comes from STM32CubeH7 project and is located here: + * https://github.com/STMicroelectronics/STM32CubeH7/blob/master/Drivers/BSP/STM32H747I-DISCO/stm32h747i_discovery_qspi.c + * + * The file root directory is: + * https://github.com/STMicroelectronics/STM32CubeH7/tree/master/Drivers/BSP/STM32H747I-DISCO + * + * This directory contains LICENSE.md file with a following license text: + * + * Copyright 2019 STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h747i_discovery_qspi.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32H747I_DISCO + * @{ + */ + +/** @defgroup STM32H747I_DISCO_QSPI QSPI + * @{ + */ + +/* Private variables ---------------------------------------------------------*/ + +/** @defgroup STM32H747I_DISCO_QSPI_Exported_Variables Exported Variables + * @{ + */ +QSPI_HandleTypeDef hqspi; +BSP_QSPI_Ctx_t QSPI_Ctx[QSPI_INSTANCES_NUMBER]; +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup STM32H747I_DISCO_QSPI_Private_Functions Private Functions + * @{ + */ +static void QSPI_MspInit(QSPI_HandleTypeDef *hQspi); +static void QSPI_MspDeInit(QSPI_HandleTypeDef *hSspi); +static int32_t QSPI_ResetMemory(uint32_t Instance); +static int32_t QSPI_DummyCyclesCfg(uint32_t Instance); + +/** + * @} + */ + +/** @defgroup STM32H747I_DISCO_QSPI_Exported_Functions Exported Functions + * @{ + */ + +/** + * @brief Initializes the QSPI interface. + * Instance management : + * Instance can running at Indirect or MMP mode. + * Every indirect instance can switch between. + * Once MMP instance active then Instance switch function disabled. + * Only 1 MMP instance can run. + * Instance switch function enabled after MMP instance exit to Indirect mode. + * + * MT25TL01G action : + * QE(Quad Enable, Non-volatile) bit of Status Register + * QE = 0; WP# & RESET# pin active + * Accept 1-1-1, 1-1-2, 1-2-2 commands + * QE = 1; WP# become SIO2 pin, RESET# become SIO3 pin + * Accept 1-1-1, 1-1-2, 1-2-2, 1-1-4, 1-4-4 commands + * Enter QPI mode by issue EQIO(0x35) command from 1-1-1 mode + * Accept 4-4-4 commands + * Exit QPI mode by issue RSTQIO(0xF5) command from 4-4-4 mode + * Accept commands, dependent QE bit status + * Memory Read commands support STR(Single Transfer Rate) & DTR(Double Transfer Rate) mode + * + * Force QE = 1, Enter 4-Byte address mode + * Configure Dummy cycle & ODS(Out Driver Strength) + * STR/DTR effect read commands only + * @param Instance QSPI Instance + * @param Init QSPI Init structure + * @retval BSP status + */ +int32_t BSP_QSPI_Init(uint32_t Instance, BSP_QSPI_Init_t *Init) +{ + int32_t ret = BSP_ERROR_NONE; + BSP_QSPI_Info_t pInfo; + MX_QSPI_Init_t qspi_init; + /* Table to handle clock prescalers: + 1: For STR mode to reach max 108Mhz + 3: For DTR mode to reach max 54Mhz + */ + static const uint32_t PrescalerTab[2] = {1, 3}; + + /* Check if the instance is supported */ + if(Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Check if instance is already initialized */ + if(QSPI_Ctx[Instance].IsInitialized == QSPI_ACCESS_NONE) + { +#if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1) + /* Register the QSPI MSP Callbacks */ + if(QSPI_Ctx[Instance].IsMspCallbacksValid == 0UL) + { + if(BSP_QSPI_RegisterDefaultMspCallbacks(Instance) != BSP_ERROR_NONE) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + } +#else + /* Msp QSPI initialization */ + QSPI_MspInit(&hqspi); +#endif /* USE_HAL_QSPI_REGISTER_CALLBACKS */ + + if(ret == BSP_ERROR_NONE) + { + /* STM32 QSPI interface initialization */ + (void)MT25TL01G_GetFlashInfo(&pInfo); + qspi_init.ClockPrescaler = PrescalerTab[Init->TransferRate]; + qspi_init.DualFlashMode = QSPI_DUALFLASH_ENABLE; + qspi_init.FlashSize = (uint32_t)POSITION_VAL((uint32_t)pInfo.FlashSize) - 1U; + qspi_init.SampleShifting = (Init->TransferRate == BSP_QSPI_STR_TRANSFER) ? QSPI_SAMPLE_SHIFTING_HALFCYCLE : QSPI_SAMPLE_SHIFTING_NONE; + + if(MX_QSPI_Init(&hqspi, &qspi_init) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + }/* QSPI memory reset */ + else if(QSPI_ResetMemory(Instance) != BSP_ERROR_NONE) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + }/* Force Flash enter 4 Byte address mode */ + else if(MT25TL01G_AutoPollingMemReady(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != MT25TL01G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else if(MT25TL01G_Enter4BytesAddressMode(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != MT25TL01G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + }/* Configuration of the dummy cycles on QSPI memory side */ + else if(QSPI_DummyCyclesCfg(Instance) != BSP_ERROR_NONE) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Configure Flash to desired mode */ + if(BSP_QSPI_ConfigFlash(Instance, Init->InterfaceMode, Init->TransferRate) != BSP_ERROR_NONE) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + } + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief De-Initializes the QSPI interface. + * @param Instance QSPI Instance + * @retval BSP status + */ +int32_t BSP_QSPI_DeInit(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if(Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if(QSPI_Ctx[Instance].IsInitialized == QSPI_ACCESS_MMP) + { + if(BSP_QSPI_DisableMemoryMappedMode(Instance) != BSP_ERROR_NONE) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + + if(ret == BSP_ERROR_NONE) + { + /* Set default QSPI_Ctx values */ + QSPI_Ctx[Instance].IsInitialized = QSPI_ACCESS_NONE; + QSPI_Ctx[Instance].InterfaceMode = BSP_QSPI_SPI_MODE; + QSPI_Ctx[Instance].TransferRate = BSP_QSPI_STR_TRANSFER; + QSPI_Ctx[Instance].DualFlashMode = QSPI_DUALFLASH_ENABLE; + +#if (USE_HAL_QSPI_REGISTER_CALLBACKS == 0) + QSPI_MspDeInit(&hqspi); +#endif /* (USE_HAL_QSPI_REGISTER_CALLBACKS == 0) */ + + /* Call the DeInit function to reset the driver */ + if (HAL_QSPI_DeInit(&hqspi) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Initializes the QSPI interface. + * @param hQspi QSPI handle + * @param Config QSPI configuration structure + * @retval BSP status + */ +__weak HAL_StatusTypeDef MX_QSPI_Init(QSPI_HandleTypeDef *hQspi, MX_QSPI_Init_t *Config) +{ + /* QSPI initialization */ + /* QSPI freq = SYSCLK /(1 + ClockPrescaler) Mhz */ + hQspi->Instance = QUADSPI; + hQspi->Init.ClockPrescaler = Config->ClockPrescaler; + hQspi->Init.FifoThreshold = 1; + hQspi->Init.SampleShifting = Config->SampleShifting; + hQspi->Init.FlashSize = Config->FlashSize; + hQspi->Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_4_CYCLE; /* Min 50ns for nonRead */ + hQspi->Init.ClockMode = QSPI_CLOCK_MODE_0; + hQspi->Init.FlashID = QSPI_FLASH_ID_1; + hQspi->Init.DualFlash = Config->DualFlashMode; + + return HAL_QSPI_Init(hQspi); +} + +#if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1) +/** + * @brief Default BSP QSPI Msp Callbacks + * @param Instance QSPI Instance + * @retval BSP status + */ +int32_t BSP_QSPI_RegisterDefaultMspCallbacks (uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if(Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Register MspInit/MspDeInit Callbacks */ + if(HAL_QSPI_RegisterCallback(&hqspi, HAL_QSPI_MSPINIT_CB_ID, QSPI_MspInit) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else if(HAL_QSPI_RegisterCallback(&hqspi, HAL_QSPI_MSPDEINIT_CB_ID, QSPI_MspDeInit) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + QSPI_Ctx[Instance].IsMspCallbacksValid = 1U; + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief BSP QSPI Msp Callback registering + * @param Instance QSPI Instance + * @param CallBacks pointer to MspInit/MspDeInit callbacks functions + * @retval BSP status + */ +int32_t BSP_QSPI_RegisterMspCallbacks (uint32_t Instance, BSP_QSPI_Cb_t *CallBacks) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if(Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Register MspInit/MspDeInit Callbacks */ + if(HAL_QSPI_RegisterCallback(&hqspi, HAL_QSPI_MSPINIT_CB_ID, CallBacks->pMspInitCb) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else if(HAL_QSPI_RegisterCallback(&hqspi, HAL_QSPI_MSPDEINIT_CB_ID, CallBacks->pMspDeInitCb) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + QSPI_Ctx[Instance].IsMspCallbacksValid = 1U; + } + } + + /* Return BSP status */ + return ret; +} +#endif /* (USE_HAL_QSPI_REGISTER_CALLBACKS == 1) */ + +/** + * @brief Reads an amount of data from the QSPI memory. + * @param Instance QSPI instance + * @param pData Pointer to data to be read + * @param ReadAddr Read start address + * @param Size Size of data to read + * @retval BSP status + */ +int32_t BSP_QSPI_Read(uint32_t Instance, uint8_t *pData, uint32_t ReadAddr, uint32_t Size) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if(Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if(QSPI_Ctx[Instance].TransferRate == BSP_QSPI_STR_TRANSFER) + { + if(MT25TL01G_ReadSTR(&hqspi, QSPI_Ctx[Instance].InterfaceMode, pData, ReadAddr, Size) != MT25TL01G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + else + { + if(MT25TL01G_ReadDTR(&hqspi, QSPI_Ctx[Instance].InterfaceMode, pData, ReadAddr, Size) != MT25TL01G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Writes an amount of data to the QSPI memory. + * @param Instance QSPI instance + * @param pData Pointer to data to be written + * @param WriteAddr Write start address + * @param Size Size of data to write + * @retval BSP status + */ +int32_t BSP_QSPI_Write(uint32_t Instance, uint8_t *pData, uint32_t WriteAddr, uint32_t Size) +{ + int32_t ret = BSP_ERROR_NONE; + uint32_t end_addr, current_size, current_addr; + uint8_t *write_data; + + /* Check if the instance is supported */ + if(Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Calculation of the size between the write address and the end of the page */ + current_size = MT25TL01G_PAGE_SIZE - (WriteAddr % MT25TL01G_PAGE_SIZE); + + /* Check if the size of the data is less than the remaining place in the page */ + if (current_size > Size) + { + current_size = Size; + } + + /* Initialize the address variables */ + current_addr = WriteAddr; + end_addr = WriteAddr + Size; + write_data = pData; + + /* Perform the write page by page */ + do + { + /* Check if Flash busy ? */ + if(MT25TL01G_AutoPollingMemReady(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != MT25TL01G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + }/* Enable write operations */ + else if(MT25TL01G_WriteEnable(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != MT25TL01G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + }/* Issue page program command */ + else if(MT25TL01G_PageProgram(&hqspi, QSPI_Ctx[Instance].InterfaceMode, write_data, current_addr, current_size) != MT25TL01G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + }/* Configure automatic polling mode to wait for end of program */ + else if (MT25TL01G_AutoPollingMemReady(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != MT25TL01G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Update the address and size variables for next page programming */ + current_addr += current_size; + write_data += current_size; + current_size = ((current_addr + MT25TL01G_PAGE_SIZE) > end_addr) ? (end_addr - current_addr) : MT25TL01G_PAGE_SIZE; + } + } while ((current_addr < end_addr) && (ret == BSP_ERROR_NONE)); + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Erases the specified block of the QSPI memory. + * MT25TL01G support 4K, 32K, 64K size block erase commands for each Die. + * i.e 8K, 64K, 128K at BSP level (see BSP_QSPI_Erase_t type definition) + * @param Instance QSPI instance + * @param BlockAddress Block address to erase + * @param BlockSize Erase Block size + * @retval BSP status + */ +int32_t BSP_QSPI_EraseBlock(uint32_t Instance, uint32_t BlockAddress, BSP_QSPI_Erase_t BlockSize) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if(Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Check Flash busy ? */ + if(MT25TL01G_AutoPollingMemReady(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != MT25TL01G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + }/* Enable write operations */ + else if(MT25TL01G_WriteEnable(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != MT25TL01G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Issue Block Erase command */ + if(MT25TL01G_BlockErase(&hqspi, QSPI_Ctx[Instance].InterfaceMode, BlockAddress, (MT25TL01G_Erase_t)BlockSize) != MT25TL01G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Erases the entire QSPI memory. + * @param Instance QSPI instance + * @retval BSP status + */ +int32_t BSP_QSPI_EraseChip(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if(Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Check Flash busy ? */ + if(MT25TL01G_AutoPollingMemReady(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != MT25TL01G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + }/* Enable write operations */ + else if (MT25TL01G_WriteEnable(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != MT25TL01G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Issue Chip erase command */ + if(MT25TL01G_ChipErase(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != MT25TL01G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Reads current status of the QSPI memory. + * If WIP != 0 then return busy. + * @param Instance QSPI instance + * @retval QSPI memory status: whether busy or not + */ +int32_t BSP_QSPI_GetStatus(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + uint8_t reg; + + /* Check if the instance is supported */ + if(Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if(MT25TL01G_ReadStatusRegister(&hqspi, QSPI_Ctx[Instance].InterfaceMode, ®) != MT25TL01G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Check the value of the register */ + if ((reg & MT25TL01G_SR_WIP) != 0U) + { + ret = BSP_ERROR_BUSY; + } + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Return the configuration of the QSPI memory. + * @param Instance QSPI instance + * @param pInfo pointer on the configuration structure + * @retval BSP status + */ +int32_t BSP_QSPI_GetInfo(uint32_t Instance, BSP_QSPI_Info_t *pInfo) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if(Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + (void)MT25TL01G_GetFlashInfo(pInfo); + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Configure the QSPI in memory-mapped mode + * Only 1 Instance can running MMP mode. And it will lock system at this mode. + * @param Instance QSPI instance + * @retval BSP status + */ +int32_t BSP_QSPI_EnableMemoryMappedMode(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if(Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if(QSPI_Ctx[Instance].TransferRate == BSP_QSPI_STR_TRANSFER) + { + if(MT25TL01G_EnableMemoryMappedModeSTR(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != MT25TL01G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else /* Update QSPI context if all operations are well done */ + { + QSPI_Ctx[Instance].IsInitialized = QSPI_ACCESS_MMP; + } + } + else + { + if(MT25TL01G_EnableMemoryMappedModeDTR(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != MT25TL01G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else /* Update QSPI context if all operations are well done */ + { + QSPI_Ctx[Instance].IsInitialized = QSPI_ACCESS_MMP; + } + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Exit form memory-mapped mode + * Only 1 Instance can running MMP mode. And it will lock system at this mode. + * @param Instance QSPI instance + * @retval BSP status + */ +int32_t BSP_QSPI_DisableMemoryMappedMode(uint32_t Instance) +{ + uint8_t Dummy; + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if(Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if(QSPI_Ctx[Instance].IsInitialized != QSPI_ACCESS_MMP) + { + ret = BSP_ERROR_QSPI_MMP_UNLOCK_FAILURE; + }/* Abort MMP back to indirect mode */ + else if(HAL_QSPI_Abort(&hqspi) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + /* Force QSPI interface Sampling Shift to half cycle */ + hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE; + + if(HAL_QSPI_Init(&hqspi)!= HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + /* Dummy read for exit from Performance Enhance mode */ + else if(MT25TL01G_ReadSTR(&hqspi, QSPI_Ctx[Instance].InterfaceMode, &Dummy, 0, 1) != MT25TL01G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else /* Update QSPI context if all operations are well done */ + { + QSPI_Ctx[Instance].IsInitialized = QSPI_ACCESS_INDIRECT; + } + } + } + /* Return BSP status */ + return ret; +} + +/** + * @brief Get flash ID, 3 Byte + * Manufacturer ID, Memory type, Memory density + * @param Instance QSPI instance + * @param Id QSPI Identifier + * @retval BSP status + */ +int32_t BSP_QSPI_ReadID(uint32_t Instance, uint8_t *Id) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if(Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if(MT25TL01G_ReadID(&hqspi, QSPI_Ctx[Instance].InterfaceMode, Id) != MT25TL01G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Set Flash to desired Interface mode. And this instance becomes current instance. + * If current instance running at MMP mode then this function isn't work. + * Indirect -> Indirect + * @param Instance QSPI instance + * @param Mode QSPI mode + * @param Rate QSPI transfer rate + * @retval BSP status + */ +int32_t BSP_QSPI_ConfigFlash(uint32_t Instance, BSP_QSPI_Interface_t Mode, BSP_QSPI_Transfer_t Rate) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if(Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Check if MMP mode locked ************************************************/ + if(QSPI_Ctx[Instance].IsInitialized == QSPI_ACCESS_MMP) + { + ret = BSP_ERROR_QSPI_MMP_LOCK_FAILURE; + } + else + { + /* Setup MCU transfer rate setting ***************************************************/ + hqspi.Init.SampleShifting = (Rate == BSP_QSPI_STR_TRANSFER) ? QSPI_SAMPLE_SHIFTING_HALFCYCLE : QSPI_SAMPLE_SHIFTING_NONE; + + if(HAL_QSPI_Init(&hqspi)!= HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + /* Setup Flash interface ***************************************************/ + switch(QSPI_Ctx[Instance].InterfaceMode) + { + case MT25TL01G_QPI_MODE : /* 4-4-4 commands */ + if(Mode != MT25TL01G_QPI_MODE) + { + if(MT25TL01G_ExitQPIMode(&hqspi) != MT25TL01G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + break; + + case BSP_QSPI_SPI_MODE : /* 1-1-1 commands, Power on H/W default setting */ + case BSP_QSPI_SPI_2IO_MODE : /* 1-2-2 read commands */ + case BSP_QSPI_SPI_4IO_MODE : /* 1-4-4 read commands */ + default : + if(Mode == MT25TL01G_QPI_MODE) + { + if(MT25TL01G_EnterQPIMode(&hqspi) != MT25TL01G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + break; + } + + /* Update QSPI context if all operations are well done */ + if(ret == BSP_ERROR_NONE) + { + /* Update current status parameter *****************************************/ + QSPI_Ctx[Instance].IsInitialized = QSPI_ACCESS_INDIRECT; + QSPI_Ctx[Instance].InterfaceMode = Mode; + QSPI_Ctx[Instance].TransferRate = Rate; + } + } + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @} + */ + +/** @defgroup STM32H747I_DISCO_QSPI_Private_Functions Private Functions + * @{ + */ + +/** + * @brief QSPI MSP Initialization + * @param hQspi : QSPI handle + * This function configures the hardware resources used in this example: + * - Peripheral's clock enable + * - Peripheral's GPIO Configuration + * - NVIC configuration for QSPI interrupt + * @retval None + */ +static void QSPI_MspInit(QSPI_HandleTypeDef *hQspi) +{ + GPIO_InitTypeDef gpio_init_structure; + + /*##-1- Enable peripherals and GPIO Clocks #################################*/ + /* Enable the QuadSPI memory interface clock */ + QSPI_CLK_ENABLE(); + /* Reset the QuadSPI memory interface */ + QSPI_FORCE_RESET(); + QSPI_RELEASE_RESET(); + /* Enable GPIO clocks */ + QSPI_CLK_GPIO_CLK_ENABLE(); + QSPI_BK1_CS_GPIO_CLK_ENABLE(); + QSPI_BK1_D0_GPIO_CLK_ENABLE(); + QSPI_BK1_D1_GPIO_CLK_ENABLE(); + QSPI_BK1_D2_GPIO_CLK_ENABLE(); + QSPI_BK1_D3_GPIO_CLK_ENABLE(); + + QSPI_BK2_CS_GPIO_CLK_ENABLE(); + QSPI_BK2_D0_GPIO_CLK_ENABLE(); + QSPI_BK2_D1_GPIO_CLK_ENABLE(); + QSPI_BK2_D2_GPIO_CLK_ENABLE(); + QSPI_BK2_D3_GPIO_CLK_ENABLE(); + + /*##-2- Configure peripheral GPIO ##########################################*/ + /* QSPI CLK GPIO pin configuration */ + gpio_init_structure.Pin = QSPI_CLK_PIN; + gpio_init_structure.Mode = GPIO_MODE_AF_PP; + gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + gpio_init_structure.Pull = GPIO_NOPULL; + gpio_init_structure.Alternate = GPIO_AF9_QUADSPI; + HAL_GPIO_Init(QSPI_CLK_GPIO_PORT, &gpio_init_structure); + + /* QSPI CS GPIO pin configuration */ + gpio_init_structure.Pin = QSPI_BK1_CS_PIN; + gpio_init_structure.Pull = GPIO_PULLUP; + gpio_init_structure.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(QSPI_BK1_CS_GPIO_PORT, &gpio_init_structure); + + /* QSPI D0 GPIO pin configuration */ + gpio_init_structure.Pin = QSPI_BK1_D0_PIN; + gpio_init_structure.Pull = GPIO_NOPULL; + gpio_init_structure.Alternate = GPIO_AF9_QUADSPI; + HAL_GPIO_Init(QSPI_BK1_D0_GPIO_PORT, &gpio_init_structure); + + gpio_init_structure.Pin = QSPI_BK2_D0_PIN; + gpio_init_structure.Alternate = GPIO_AF9_QUADSPI; + HAL_GPIO_Init(QSPI_BK2_D0_GPIO_PORT, &gpio_init_structure); + + /* QSPI D1 GPIO pin configuration */ + gpio_init_structure.Pin = QSPI_BK1_D1_PIN; + gpio_init_structure.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(QSPI_BK1_D1_GPIO_PORT, &gpio_init_structure); + + gpio_init_structure.Pin = QSPI_BK2_D1_PIN; + gpio_init_structure.Alternate = GPIO_AF9_QUADSPI; + HAL_GPIO_Init(QSPI_BK2_D1_GPIO_PORT, &gpio_init_structure); + + /* QSPI D2 GPIO pin configuration */ + gpio_init_structure.Pin = QSPI_BK1_D2_PIN; + gpio_init_structure.Alternate = GPIO_AF9_QUADSPI; + HAL_GPIO_Init(QSPI_BK1_D2_GPIO_PORT, &gpio_init_structure); + + gpio_init_structure.Pin = QSPI_BK2_D2_PIN; + HAL_GPIO_Init(QSPI_BK2_D2_GPIO_PORT, &gpio_init_structure); + + /* QSPI D3 GPIO pin configuration */ + gpio_init_structure.Pin = QSPI_BK1_D3_PIN; + HAL_GPIO_Init(QSPI_BK1_D3_GPIO_PORT, &gpio_init_structure); + + gpio_init_structure.Pin = QSPI_BK2_D3_PIN; + HAL_GPIO_Init(QSPI_BK2_D3_GPIO_PORT, &gpio_init_structure); + + /*##-3- Configure the NVIC for QSPI #########################################*/ + /* NVIC configuration for QSPI interrupt */ + HAL_NVIC_SetPriority(QUADSPI_IRQn, 0x0F, 0); + HAL_NVIC_EnableIRQ(QUADSPI_IRQn); +} + +/** + * @brief QSPI MSP De-Initialization + * @param hQspi QSPI handle + * This function frees the hardware resources used in this example: + * - Disable the Peripheral's clock + * - Revert GPIO and NVIC configuration to their default state + * @retval None + */ +static void QSPI_MspDeInit(QSPI_HandleTypeDef *hQspi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hQspi); + + /*##-2- Disable peripherals and GPIO Clocks ################################*/ + /* De-Configure QSPI pins */ + HAL_GPIO_DeInit(QSPI_CLK_GPIO_PORT, QSPI_CLK_PIN); + HAL_GPIO_DeInit(QSPI_BK1_CS_GPIO_PORT, QSPI_BK1_CS_PIN); + HAL_GPIO_DeInit(QSPI_BK1_D0_GPIO_PORT, QSPI_BK1_D0_PIN); + HAL_GPIO_DeInit(QSPI_BK1_D1_GPIO_PORT, QSPI_BK1_D1_PIN); + HAL_GPIO_DeInit(QSPI_BK1_D2_GPIO_PORT, QSPI_BK1_D2_PIN); + HAL_GPIO_DeInit(QSPI_BK1_D3_GPIO_PORT, QSPI_BK1_D3_PIN); + + HAL_GPIO_DeInit(QSPI_BK2_CS_GPIO_PORT, QSPI_BK2_CS_PIN); + HAL_GPIO_DeInit(QSPI_BK2_D0_GPIO_PORT, QSPI_BK2_D0_PIN); + HAL_GPIO_DeInit(QSPI_BK2_D1_GPIO_PORT, QSPI_BK2_D1_PIN); + HAL_GPIO_DeInit(QSPI_BK2_D2_GPIO_PORT, QSPI_BK2_D2_PIN); + HAL_GPIO_DeInit(QSPI_BK2_D3_GPIO_PORT, QSPI_BK2_D3_PIN); + + /*##-3- Reset peripherals ##################################################*/ + /* Reset the QuadSPI memory interface */ + QSPI_FORCE_RESET(); + QSPI_RELEASE_RESET(); + + /* Disable the QuadSPI memory interface clock */ + QSPI_CLK_DISABLE(); +} + +/** + * @brief This function reset the QSPI Flash memory. + * Fore QPI+SPI reset to avoid system come from unknown status. + * Flash accept 1-1-1, 1-1-2, 1-2-2 commands after reset. + * @param Instance QSPI instance + * @retval BSP status + */ +static int32_t QSPI_ResetMemory(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Send RESET ENABLE command in QPI mode (QUAD I/Os, 4-4-4) */ + if(MT25TL01G_ResetEnable(&hqspi, MT25TL01G_QPI_MODE) != MT25TL01G_OK) + { + ret =BSP_ERROR_COMPONENT_FAILURE; + }/* Send RESET memory command in QPI mode (QUAD I/Os, 4-4-4) */ + else if(MT25TL01G_ResetMemory(&hqspi, MT25TL01G_QPI_MODE) != MT25TL01G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + }/* Wait Flash ready */ + else if(MT25TL01G_AutoPollingMemReady(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != MT25TL01G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + }/* Send RESET ENABLE command in SPI mode (1-1-1) */ + else if(MT25TL01G_ResetEnable(&hqspi, BSP_QSPI_SPI_MODE) != MT25TL01G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + }/* Send RESET memory command in SPI mode (1-1-1) */ + else if(MT25TL01G_ResetMemory(&hqspi, BSP_QSPI_SPI_MODE) != MT25TL01G_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + QSPI_Ctx[Instance].IsInitialized = QSPI_ACCESS_INDIRECT; /* After reset S/W setting to indirect access */ + QSPI_Ctx[Instance].InterfaceMode = BSP_QSPI_SPI_MODE; /* After reset H/W back to SPI mode by default */ + QSPI_Ctx[Instance].TransferRate = BSP_QSPI_STR_TRANSFER; /* After reset S/W setting to STR mode */ + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief This function configure the dummy cycles on memory side. + * Dummy cycle bit locate in Configuration Register[7:6] + * @param Instance QSPI instance + * @retval BSP status + */ +static int32_t QSPI_DummyCyclesCfg(uint32_t Instance) +{ + int32_t ret= BSP_ERROR_NONE; + QSPI_CommandTypeDef s_command; + uint16_t reg=0; + + /* Initialize the read volatile configuration register command */ + s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES; + s_command.Instruction = MT25TL01G_READ_VOL_CFG_REG_CMD; + s_command.AddressMode = QSPI_ADDRESS_NONE; + s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + s_command.DataMode = QSPI_DATA_4_LINES; + s_command.DummyCycles = 0; + s_command.NbData = 2; + s_command.DdrMode = QSPI_DDR_MODE_DISABLE; + s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; + s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; + + /* Configure the command */ + if (HAL_QSPI_Command(&hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return BSP_ERROR_COMPONENT_FAILURE; + } + + /* Reception of the data */ + if (HAL_QSPI_Receive(&hqspi, (uint8_t *)(®), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return BSP_ERROR_COMPONENT_FAILURE; + } + + /* Enable write operations */ + if (MT25TL01G_WriteEnable(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != MT25TL01G_OK) + { + return BSP_ERROR_COMPONENT_FAILURE; + } + + /* Update volatile configuration register (with new dummy cycles) */ + s_command.Instruction = MT25TL01G_WRITE_VOL_CFG_REG_CMD; + MODIFY_REG(reg, 0xF0F0, ((MT25TL01G_DUMMY_CYCLES_READ_QUAD << 4) | + (MT25TL01G_DUMMY_CYCLES_READ_QUAD << 12))); + + /* Configure the write volatile configuration register command */ + if (HAL_QSPI_Command(&hqspi, &s_command, HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return BSP_ERROR_COMPONENT_FAILURE; + } + + /* Transmission of the data */ + if (HAL_QSPI_Transmit(&hqspi, (uint8_t *)(®), HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + return BSP_ERROR_COMPONENT_FAILURE; + } + + /* Return BSP status */ + return ret; +} +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/bsps/arm/stm32h7/boards/stm/stm32h747i-disco/stm32h747i_discovery_qspi.h b/bsps/arm/stm32h7/boards/stm/stm32h747i-disco/stm32h747i_discovery_qspi.h new file mode 100644 index 0000000000..4fff086012 --- /dev/null +++ b/bsps/arm/stm32h7/boards/stm/stm32h747i-disco/stm32h747i_discovery_qspi.h @@ -0,0 +1,286 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/** + ****************************************************************************** + * @file stm32h747i_discovery_qspi.h + * @author MCD Application Team + * @brief This file contains the common defines and functions prototypes for + * the stm32h747i_discovery_qspi.c driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2018 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* + * RTEMS committer clarification comment on license above: + * + * This file comes from STM32CubeH7 project and is located here: + * https://github.com/STMicroelectronics/STM32CubeH7/blob/master/Drivers/BSP/STM32H747I-DISCO/stm32h747i_discovery_qspi.h + * + * The file root directory is: + * https://github.com/STMicroelectronics/STM32CubeH7/tree/master/Drivers/BSP/STM32H747I-DISCO + * + * This directory contains LICENSE.md file with a following license text: + * + * Copyright 2019 STMicroelectronics. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H747I_DISCO_QSPI_H +#define STM32H747I_DISCO_QSPI_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h747i_discovery_conf.h" +#include "stm32h747i_discovery_errno.h" +#include "../Components/mt25tl01g/mt25tl01g.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32H747I_DISCO + * @{ + */ + +/** @addtogroup STM32H747I_DISCO_QSPI + * @{ + */ +/* Exported types ------------------------------------------------------------*/ +/** @defgroup STM32H747I_DISCO_QSPI_Exported_Types Exported Types + * @{ + */ +#define BSP_QSPI_Info_t MT25TL01G_Info_t +#define BSP_QSPI_Interface_t MT25TL01G_Interface_t +#define BSP_QSPI_Transfer_t MT25TL01G_Transfer_t +#define BSP_QSPI_DualFlash_t MT25TL01G_DualFlash_t +#define BSP_QSPI_ODS_t MT25TL01G_ODS_t + +typedef enum +{ + BSP_QSPI_ERASE_8K = MT25TL01G_ERASE_4K , /*!< 8K size Sector erase = 2 x 4K as Dual flash mode is used for this board */ + BSP_QSPI_ERASE_64K = MT25TL01G_ERASE_32K , /*!< 64K size Sector erase = 2 x 32K as Dual flash mode is used for this board */ + BSP_QSPI_ERASE_128K = MT25TL01G_ERASE_64K , /*!< 128K size Sector erase = 2 x 64K as Dual mode is used for this board */ + BSP_QSPI_ERASE_CHIP = MT25TL01G_ERASE_CHIP /*!< Whole chip erase */ + +} BSP_QSPI_Erase_t; + +typedef enum +{ + QSPI_ACCESS_NONE = 0, /*!< Instance not initialized, */ + QSPI_ACCESS_INDIRECT, /*!< Instance use indirect mode access */ + QSPI_ACCESS_MMP /*!< Instance use Memory Mapped Mode read */ +} BSP_QSPI_Access_t; + +typedef struct +{ + BSP_QSPI_Access_t IsInitialized; /*!< Instance access Flash method */ + BSP_QSPI_Interface_t InterfaceMode; /*!< Flash Interface mode of Instance */ + BSP_QSPI_Transfer_t TransferRate; /*!< Flash Transfer mode of Instance */ + uint32_t DualFlashMode; /*!< Flash dual mode */ + uint32_t IsMspCallbacksValid; +} BSP_QSPI_Ctx_t; + +typedef struct +{ + BSP_QSPI_Interface_t InterfaceMode; /*!< Current Flash Interface mode */ + BSP_QSPI_Transfer_t TransferRate; /*!< Current Flash Transfer mode */ + BSP_QSPI_DualFlash_t DualFlashMode; /*!< Dual Flash mode */ +} BSP_QSPI_Init_t; + +typedef struct +{ + uint32_t FlashSize; + uint32_t ClockPrescaler; + uint32_t SampleShifting; + uint32_t DualFlashMode; +}MX_QSPI_Init_t; +#if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1) +typedef struct +{ + void(*pMspInitCb)(pQSPI_CallbackTypeDef); + void(*pMspDeInitCb)(pQSPI_CallbackTypeDef); +}BSP_QSPI_Cb_t; +#endif /* (USE_HAL_QSPI_REGISTER_CALLBACKS == 1) */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup STM32H747I_DISCO_QSPI_Exported_Constants Exported Constants + * @{ + */ +/* QSPI instances number */ +#define QSPI_INSTANCES_NUMBER 1U + +/* Definition for QSPI modes */ +#define BSP_QSPI_SPI_MODE (BSP_QSPI_Interface_t)MT25TL01G_SPI_MODE /* 1 Cmd Line, 1 Address Line and 1 Data Line */ +#define BSP_QSPI_SPI_1I2O_MODE (BSP_QSPI_Interface_t)MT25TL01G_SPI_1I2O_MODE /* 1 Cmd Line, 1 Address Line and 2 Data Lines */ +#define BSP_QSPI_SPI_2IO_MODE (BSP_QSPI_Interface_t)MT25TL01G_SPI_2IO_MODE /* 1 Cmd Line, 2 Address Lines and 2 Data Lines */ +#define BSP_QSPI_SPI_1I4O_MODE (BSP_QSPI_Interface_t)MT25TL01G_SPI_1I4O_MODE /* 1 Cmd Line, 1 Address Line and 4 Data Lines */ +#define BSP_QSPI_SPI_4IO_MODE (BSP_QSPI_Interface_t)MT25TL01G_SPI_4IO_MODE /* 1 Cmd Line, 4 Address Lines and 4 Data Lines */ +#define BSP_QSPI_DPI_MODE (BSP_QSPI_Interface_t)MT25TL01G_DPI_MODE /* 2 Cmd Lines, 2 Address Lines and 2 Data Lines */ +#define BSP_QSPI_QPI_MODE (BSP_QSPI_Interface_t)MT25TL01G_QPI_MODE /* 4 Cmd Lines, 4 Address Lines and 4 Data Lines */ + +/* Definition for QSPI transfer rates */ +#define BSP_QSPI_STR_TRANSFER (BSP_QSPI_Transfer_t)MT25TL01G_STR_TRANSFER /* Single Transfer Rate */ +#define BSP_QSPI_DTR_TRANSFER (BSP_QSPI_Transfer_t)MT25TL01G_DTR_TRANSFER /* Double Transfer Rate */ + +/* Definition for QSPI dual flash mode */ +#define BSP_QSPI_DUALFLASH_DISABLE (BSP_QSPI_DualFlash_t)MT25TL01G_DUALFLASH_DISABLE /* Dual flash mode enabled */ +/* Definition for QSPI Flash ID */ +#define BSP_QSPI_FLASH_ID QSPI_FLASH_ID_1 + +/* QSPI block sizes for dual flash */ +#define BSP_QSPI_BLOCK_8K MT25TL01G_SECTOR_4K +#define BSP_QSPI_BLOCK_64K MT25TL01G_BLOCK_32K +#define BSP_QSPI_BLOCK_128K MT25TL01G_BLOCK_64K + +/* Definition for QSPI clock resources */ +#define QSPI_CLK_ENABLE() __HAL_RCC_QSPI_CLK_ENABLE() +#define QSPI_CLK_DISABLE() __HAL_RCC_QSPI_CLK_DISABLE() +#define QSPI_CLK_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() +#define QSPI_BK1_CS_GPIO_CLK_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE() +#define QSPI_BK1_D0_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE() +#define QSPI_BK1_D1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE() +#define QSPI_BK1_D2_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE() +#define QSPI_BK1_D3_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE() +#define QSPI_BK2_CS_GPIO_CLK_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE() +#define QSPI_BK2_D0_GPIO_CLK_ENABLE() __HAL_RCC_GPIOH_CLK_ENABLE() +#define QSPI_BK2_D1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOH_CLK_ENABLE() +#define QSPI_BK2_D2_GPIO_CLK_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE() +#define QSPI_BK2_D3_GPIO_CLK_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE() + + +#define QSPI_FORCE_RESET() __HAL_RCC_QSPI_FORCE_RESET() +#define QSPI_RELEASE_RESET() __HAL_RCC_QSPI_RELEASE_RESET() + +/* Definition for QSPI Pins */ +#define QSPI_CLK_PIN GPIO_PIN_2 +#define QSPI_CLK_GPIO_PORT GPIOB +/* Bank 1 */ +#define QSPI_BK1_CS_PIN GPIO_PIN_6 +#define QSPI_BK1_CS_GPIO_PORT GPIOG +#define QSPI_BK1_D0_PIN GPIO_PIN_11 +#define QSPI_BK1_D0_GPIO_PORT GPIOD +#define QSPI_BK1_D1_PIN GPIO_PIN_9 +#define QSPI_BK1_D1_GPIO_PORT GPIOF +#define QSPI_BK1_D2_PIN GPIO_PIN_7 +#define QSPI_BK1_D2_GPIO_PORT GPIOF +#define QSPI_BK1_D3_PIN GPIO_PIN_6 +#define QSPI_BK1_D3_GPIO_PORT GPIOF + +/* Bank 2 */ +#define QSPI_BK2_CS_PIN GPIO_PIN_6 +#define QSPI_BK2_CS_GPIO_PORT GPIOG +#define QSPI_BK2_D0_PIN GPIO_PIN_2 +#define QSPI_BK2_D0_GPIO_PORT GPIOH +#define QSPI_BK2_D1_PIN GPIO_PIN_3 +#define QSPI_BK2_D1_GPIO_PORT GPIOH +#define QSPI_BK2_D2_PIN GPIO_PIN_9 +#define QSPI_BK2_D2_GPIO_PORT GPIOG +#define QSPI_BK2_D3_PIN GPIO_PIN_14 +#define QSPI_BK2_D3_GPIO_PORT GPIOG + + +/* MT25TL01G Micron memory */ +/* Size of the flash */ +#define QSPI_FLASH_SIZE 26 /* Address bus width to access whole memory space */ +#define QSPI_PAGE_SIZE 256 + +/* QSPI Base Address */ +#define QSPI_BASE_ADDRESS 0x90000000 + +/** + * @} + */ + +/** @addtogroup STM32H747I_DISCO_QSPI_Exported_Variables + * @{ + */ +extern QSPI_HandleTypeDef hqspi; +extern BSP_QSPI_Ctx_t QSPI_Ctx[]; +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup STM32H747I_DISCO_QSPI_Exported_Functions + * @{ + */ +int32_t BSP_QSPI_Init(uint32_t Instance, BSP_QSPI_Init_t *Init); +int32_t BSP_QSPI_DeInit(uint32_t Instance); +#if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1) +int32_t BSP_QSPI_RegisterMspCallbacks (uint32_t Instance, BSP_QSPI_Cb_t *CallBacks); +int32_t BSP_QSPI_RegisterDefaultMspCallbacks (uint32_t Instance); +#endif /* (USE_HAL_QSPI_REGISTER_CALLBACKS == 1) */ +int32_t BSP_QSPI_Read(uint32_t Instance, uint8_t *pData, uint32_t ReadAddr, uint32_t Size); +int32_t BSP_QSPI_Write(uint32_t Instance, uint8_t *pData, uint32_t WriteAddr, uint32_t Size); +int32_t BSP_QSPI_EraseBlock(uint32_t Instance, uint32_t BlockAddress, BSP_QSPI_Erase_t BlockSize); +int32_t BSP_QSPI_EraseChip(uint32_t Instance); +int32_t BSP_QSPI_GetStatus(uint32_t Instance); +int32_t BSP_QSPI_GetInfo(uint32_t Instance, BSP_QSPI_Info_t *pInfo); +int32_t BSP_QSPI_EnableMemoryMappedMode(uint32_t Instance); +int32_t BSP_QSPI_DisableMemoryMappedMode(uint32_t Instance); +int32_t BSP_QSPI_ReadID(uint32_t Instance, uint8_t *Id); +int32_t BSP_QSPI_ConfigFlash(uint32_t Instance, BSP_QSPI_Interface_t Mode, BSP_QSPI_Transfer_t Rate); + +/* These functions can be modified in case the current settings + need to be changed for specific application needs */ +HAL_StatusTypeDef MX_QSPI_Init(QSPI_HandleTypeDef *hQspi, MX_QSPI_Init_t *Config); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#ifdef __cplusplus +} +#endif + +#endif /*STM32H747I_DISCO_QSPI_H */ -- 2.25.1 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel