diff options
Diffstat (limited to 'bsps/arm/stm32h7/boards/stm/stm32h757i-eval')
9 files changed, 2682 insertions, 0 deletions
diff --git a/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h7-bspstarthooks.c b/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h7-bspstarthooks.c new file mode 100644 index 0000000000..a5d495f521 --- /dev/null +++ b/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h7-bspstarthooks.c @@ -0,0 +1,95 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/* + * Copyright (C) 2020 embedded brains GmbH & Co. KG + * + * 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. + * + * 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 OWNER 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. + */ + +#include <bsp.h> +#include <bsp/bootcard.h> +#include <bsp/linker-symbols.h> +#include <bsp/start.h> +#include <stm32h7/hal.h> +#include <stm32h7/memory.h> +#include <stm32h7/mpu-config.h> +#include <rtems/score/armv7m.h> + +#include <string.h> + +#include <stm32h747i_eval_qspi.h> +static BSP_QSPI_Init_t QSPinit; + +void stm32h7_init_qspi(void) +{ +#if defined(STM32H7_MEMORY_QUADSPI_SIZE) && STM32H7_MEMORY_QUADSPI_SIZE > 0 + /* let's initialize Quad SPI memory here for memory mapped mode */ + /* due to usage of static QSPinit variable please call this function + after bsp_start_clear_bss call since otherwise you would hit uninitialized + variable memory while accessing it and in addition the call to bsp_start_clear_bss + would wipe the variable content later after its initialization here. */ + BSP_QSPI_Init(0, &QSPinit); + BSP_QSPI_EnableMemoryMappedMode(0); +#endif +} + +void bsp_start_hook_0(void) +{ + if ((RCC->AHB3ENR & RCC_AHB3ENR_FMCEN) == 0) { + /* + * Only perform the low-level initialization if necessary. An initialized + * FMC indicates that a boot loader already performed the low-level + * initialization. + */ + SystemInit(); + stm32h7_init_power(); + stm32h7_init_oscillator(); + stm32h7_init_clocks(); + stm32h7_init_peripheral_clocks(); + HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSI, RCC_MCODIV_1); + HAL_Init(); + SystemInit_ExtMemCtl(); + } + +#if __CORTEX_M == 0x07U + if ((SCB->CCR & SCB_CCR_IC_Msk) == 0) { + SCB_EnableICache(); + } + + if ((SCB->CCR & SCB_CCR_DC_Msk) == 0) { + SCB_EnableDCache(); + } + + _ARMV7M_MPU_Setup(ARMV7M_MPU_CTRL_DEFAULT, stm32h7_config_mpu_region, stm32h7_config_mpu_region_count); +#endif +} + +void bsp_start_hook_1(void) +{ + bsp_start_copy_sections_compact(); +#if __CORTEX_M == 0x07U + SCB_CleanDCache(); + SCB_InvalidateICache(); +#endif + bsp_start_clear_bss(); + stm32h7_init_qspi(); +} diff --git a/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h7-config-clk.c b/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h7-config-clk.c new file mode 100644 index 0000000000..c4ea947c3c --- /dev/null +++ b/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h7-config-clk.c @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/* + * Copyright (C) 2022 Karel Gardas <karel@functional.vision> + * + * 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. + * + * 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 OWNER 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stm32h7/hal.h> + +const RCC_ClkInitTypeDef stm32h7_config_clocks = { + .ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK + | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 + | RCC_CLOCKTYPE_D3PCLK1 | RCC_CLOCKTYPE_D1PCLK1, + .SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK, + .SYSCLKDivider = RCC_SYSCLK_DIV1, + .AHBCLKDivider = RCC_HCLK_DIV2, + .APB3CLKDivider = RCC_APB3_DIV2, + .APB1CLKDivider = RCC_APB1_DIV2, + .APB2CLKDivider = RCC_APB2_DIV2, + .APB4CLKDivider = RCC_APB4_DIV2 +}; diff --git a/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h7-config-osc.c b/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h7-config-osc.c new file mode 100644 index 0000000000..8f23508cbb --- /dev/null +++ b/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h7-config-osc.c @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/* + * Copyright (C) 2022 Karel Gardas <karel@functional.vision> + * + * 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. + * + * 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 OWNER 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stm32h7/hal.h> + +const RCC_OscInitTypeDef stm32h7_config_oscillator = { + .OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSE + | RCC_OSCILLATORTYPE_HSI48, + .HSEState = RCC_HSE_ON, + .LSEState = RCC_LSE_OFF, + .HSIState = RCC_HSI_DIV1, + .HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT, + .HSI48State = RCC_HSI48_ON, + .CSIState = RCC_CSI_OFF, + .PLL.PLLState = RCC_PLL_ON, + .PLL.PLLSource = RCC_PLLSOURCE_HSE, + .PLL.PLLM = 2, + .PLL.PLLN = 64, + .PLL.PLLFRACN = 0, + .PLL.PLLP = 2, + .PLL.PLLR = 2, + .PLL.PLLQ = 6, + .PLL.PLLVCOSEL = RCC_PLL1VCOWIDE, + .PLL.PLLRGE = RCC_PLL1VCIRANGE_3 +}; diff --git a/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h7-config-per.c b/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h7-config-per.c new file mode 100644 index 0000000000..a72b0b2ef5 --- /dev/null +++ b/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h7-config-per.c @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/* + * Copyright (C) 2022 Karel Gardas <karel@functional.vision> + * + * 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. + * + * 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 OWNER 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stm32h7/hal.h> + +const RCC_PeriphCLKInitTypeDef stm32h7_config_peripheral_clocks = { + /* for stm32h757-eval BSP we provide only minimalistic peripheral + configuration just to make available U(S)ART working */ + .PeriphClockSelection = RCC_PERIPHCLK_USART1, + .Usart16ClockSelection = RCC_USART16CLKSOURCE_D2PCLK2 +}; diff --git a/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h747i_eval_conf.h b/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h747i_eval_conf.h new file mode 100644 index 0000000000..673125eec3 --- /dev/null +++ b/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h747i_eval_conf.h @@ -0,0 +1,130 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/** + ****************************************************************************** + * @file stm32h747i_eval_config.h + * @author MCD Application Team + * @brief STM32H747I_EVAL board configuration file. + ****************************************************************************** + * @attention + * + * Copyright (c) 2019 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-EVAL/stm32h747i_eval_conf_template.h + * + * The file root directory is: + * https://github.com/STMicroelectronics/STM32CubeH7/tree/master/Drivers/BSP/STM32H747I-EVAL + * + * 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_EVAL_CONFIG_H +#define STM32H747I_EVAL_CONFIG_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7xx_hal.h" + + /* COM define */ +#define USE_COM_LOG 0U + + /* IO class usage define */ +#define USE_BSP_IO_CLASS 1U + + /* JOY usage define */ +#define USE_BSP_JOY_FEATURE 1U + + /* POT usage define */ +#define USE_BSP_POT_FEATURE 1U + + /* LCD controllers defines */ +#define USE_LCD_CTRL_OTM8009A 1U +#define USE_LCD_CTRL_ADV7533 1U +#define LCD_LAYER_0_ADDRESS 0xD0000000U +#define LCD_LAYER_1_ADDRESS 0xD0200000U + + /* SD high performance usage define */ +#define USE_SD_HIGH_PERFORMANCE 0U + + /*DMA2D to fill RGB rectangle usage define*/ +#define USE_DMA2D_TO_FILL_RGB_RECT 0U + + /* Audio codecs defines */ +#define USE_AUDIO_CODEC_WM8994 1U +#define USE_AUDIO_CODEC_ADV7533 1U + + /* Default Audio IN internal buffer size */ +#define DEFAULT_AUDIO_IN_BUFFER_SIZE 256U + +/* TS supported features defines */ +#define USE_TS_GESTURE 1U +#define USE_TS_MULTI_TOUCH 1U + +/* Default TS touch number */ +#define TS_TOUCH_NBR 2U + +/* Default EEPROM max trials */ +#define EEPROM_MAX_TRIALS 3000U + +/* IRQ priorities */ +#define BSP_SRAM_IT_PRIORITY 15U +#define BSP_SDRAM_IT_PRIORITY 15U +#define BSP_IOEXPANDER_IT_PRIORITY 15U +#define BSP_BUTTON_USER_IT_PRIORITY 15U +#define BSP_BUTTON_WAKEUP_IT_PRIORITY 15U +#define BSP_BUTTON_TAMPER_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 + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H747I_EVAL_CONFIG_H */ + diff --git a/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h747i_eval_errno.h b/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h747i_eval_errno.h new file mode 100644 index 0000000000..8b928c98a1 --- /dev/null +++ b/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h747i_eval_errno.h @@ -0,0 +1,105 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/** +****************************************************************************** +* @file stm32h747i_eval_errno.h +* @author MCD Application Team +* @brief Error Code. +* +****************************************************************************** +* @attention +* +* Copyright (c) 2019 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-EVAL/stm32h747i_eval_errno.h + * + * The file root directory is: + * https://github.com/STMicroelectronics/STM32CubeH7/tree/master/Drivers/BSP/STM32H747I-EVAL + * + * 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_EVAL_ERRNO_H +#define STM32H747I_EVAL_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_EVAL_ERRNO_H */ diff --git a/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h747i_eval_qspi.c b/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h747i_eval_qspi.c new file mode 100644 index 0000000000..6614200509 --- /dev/null +++ b/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h747i_eval_qspi.c @@ -0,0 +1,1088 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/** + ****************************************************************************** + * @file stm32h747i_eval_qspi.c + * @author MCD Application Team + * @brief This file includes a standard driver for the MT25TL01G QSPI + * memory mounted on STM32H747I-EVAL board. + ****************************************************************************** + @verbatim + How To use this driver: + ----------------------- + - This driver is used to drive the MT25TL01G QSPI external + memory mounted on STM32H747I-EVAL evaluation 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_EVAL board, there's one instance. Then, this + parameter should be 0. + + @endverbatim + ****************************************************************************** + * @attention + * + * Copyright (c) 2019 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-EVAL/stm32h747i_eval_qspi.c + * + * The file root directory is: + * https://github.com/STMicroelectronics/STM32CubeH7/tree/master/Drivers/BSP/STM32H747I-EVAL + * + * 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_eval_qspi.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32H747I_EVAL + * @{ + */ + +/** @defgroup STM32H747I_EVAL_QSPI QSPI + * @{ + */ + +/** @defgroup STM32H747I_EVAL_QSPI_Exported_Variables Exported Variables + * @{ + */ +QSPI_HandleTypeDef hqspi; +BSP_QSPI_Ctx_t QSPI_Ctx[QSPI_INSTANCES_NUMBER]; +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup STM32H747I_EVAL_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_EVAL_QSPI_Exported_Functions Exported Functions + * @{ + */ + +/** + * @brief Initializes the QSPI interface. + * @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 100Mhz + 3: For DTR mode to reach max 50Mhz + */ + 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 = HCLK /(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_EVAL_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; + + /* Prevent unused argument(s) compilation warning */ + UNUSED(hQspi); + + /*##-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); + + gpio_init_structure.Pin = QSPI_BK2_CS_PIN; + gpio_init_structure.Mode = GPIO_MODE_AF_PP; + gpio_init_structure.Pull = GPIO_PULLUP; + gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + gpio_init_structure.Alternate = GPIO_AF9_QUADSPI; + HAL_GPIO_Init(QSPI_BK2_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_AF10_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/stm32h757i-eval/stm32h747i_eval_qspi.h b/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h747i_eval_qspi.h new file mode 100644 index 0000000000..52293dba89 --- /dev/null +++ b/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/stm32h747i_eval_qspi.h @@ -0,0 +1,284 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/** + ****************************************************************************** + * @file stm32h747i_eval_qspi.h + * @author MCD Application Team + * @brief This file contains the common defines and functions prototypes for + * the stm32h747i_eval_qspi.c driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2019 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-EVAL/stm32h747i_eval_qspi.h + * + * The file root directory is: + * https://github.com/STMicroelectronics/STM32CubeH7/tree/master/Drivers/BSP/STM32H747I-EVAL + * + * 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_EVAL_QSPI_H +#define STM32H747I_EVAL_QSPI_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h747i_eval_conf.h" +#include "stm32h747i_eval_errno.h" +#include "../Components/mt25tl01g/mt25tl01g.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32H747I_EVAL + * @{ + */ + +/** @addtogroup STM32H747I_EVAL_QSPI + * @{ + */ +/* Exported types ------------------------------------------------------------*/ +/** @defgroup STM32H747I_EVAL_QSPI_Exported_Types QSPI 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_EVAL_QSPI_Exported_Constants QSPI 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_GPIOF_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_GPIOC_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_8 +#define QSPI_BK1_D0_GPIO_PORT GPIOF +#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_11 +#define QSPI_BK2_CS_GPIO_PORT GPIOC +#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_EVAL_QSPI_Exported_Variables + * @{ + */ +extern QSPI_HandleTypeDef hqspi; +extern BSP_QSPI_Ctx_t QSPI_Ctx[]; +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup STM32H747I_EVAL_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_EVAL_QSPI_H */ +/** + * @} + */ + +/** + * @} + */ diff --git a/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/system_stm32h7xx.c b/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/system_stm32h7xx.c new file mode 100644 index 0000000000..59e66e133e --- /dev/null +++ b/bsps/arm/stm32h7/boards/stm/stm32h757i-eval/system_stm32h7xx.c @@ -0,0 +1,843 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/** + ****************************************************************************** + * @file system_stm32h7xx.c + * @author MCD Application Team + * @brief CMSIS Cortex-Mx Device Peripheral Access Layer System Source File. + * + * This file provides two functions and one global variable to be called from + * user application: + * - SystemInit(): This function is called at startup just after reset and + * before branch to main program. This call is made inside + * the "startup_stm32h7xx.s" file. + * + * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used + * by the user application to setup the SysTick + * timer or configure other parameters. + * + * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must + * be called whenever the core clock is changed + * during program execution. + * + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2019 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 from its Projects + * subdirectory. There is Templates subdirectory per every supported + * BSP there. The Templates contains the file. In our case the file is + * here: + * https://github.com/STMicroelectronics/STM32CubeH7/blob/master/Projects/STM32H747I-EVAL/Templates/BootCM4_CM7/Common/Src/system_stm32h7xx.c + * + * When we go up in the directory tree starting from the file, we find + * out that the "root directory" in the sense of license claim above is Templates + * directory here: + * https://github.com/STMicroelectronics/STM32CubeH7/tree/master/Projects/STM32H747I-EVAL/Templates + * + * 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. + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32h7xx_system + * @{ + */ + +/** @addtogroup STM32H7xx_System_Private_Includes + * @{ + */ + +#include "stm32h7xx.h" +#include <math.h> +#ifdef __rtems__ +#include <bsp/linker-symbols.h> +#include <bspopts.h> + +#define HSE_VALUE STM32H7_HSE_FREQUENCY + +#endif /* __rtems__ */ +#if !defined (HSE_VALUE) +#define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (CSI_VALUE) + #define CSI_VALUE ((uint32_t)4000000) /*!< Value of the Internal oscillator in Hz*/ +#endif /* CSI_VALUE */ + +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)64000000) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @} + */ + +/** @addtogroup STM32H7xx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32H7xx_System_Private_Defines + * @{ + */ + +/************************* Miscellaneous Configuration ************************/ +/*!< Uncomment the following line if you need to use external SRAM or SDRAM mounted + on EVAL board as data memory */ +#define DATA_IN_ExtSRAM +#define DATA_IN_ExtSDRAM + +/*!< Uncomment the following line if you need to relocate your vector Table in + Internal SRAM. */ +/* #define VECT_TAB_SRAM */ +#define VECT_TAB_OFFSET 0x00000000UL /*!< Vector Table base offset field. + This value must be a multiple of 0x200. */ +/******************************************************************************/ + +/** + * @} + */ + +/** @addtogroup STM32H7xx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32H7xx_System_Private_Variables + * @{ + */ + /* This variable is updated in three ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 2) by calling HAL API function HAL_RCC_GetHCLKFreq() + 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency + Note: If you use this function to configure the system clock; then there + is no need to call the 2 first functions listed above, since SystemCoreClock + variable is updated automatically. + */ +#ifndef __rtems__ + uint32_t SystemCoreClock = 64000000; + uint32_t SystemD2Clock = 64000000; +#else /* __rtems__ */ + RTEMS_SECTION(".rtemsstack") uint32_t SystemCoreClock; + RTEMS_SECTION(".rtemsstack") uint32_t SystemD2Clock; +#endif /* __rtems__ */ + const uint8_t D1CorePrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9}; + +/** + * @} + */ + +/** @addtogroup STM32H7xx_System_Private_FunctionPrototypes + * @{ + */ +#ifndef __rtems__ +#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM) + static void SystemInit_ExtMemCtl(void); +#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */ +#endif /* __rtems__ */ + +/** + * @} + */ + +/** @addtogroup STM32H7xx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system + * Initialize the FPU setting, vector table location and External memory + * configuration. + * @param None + * @retval None + */ +void SystemInit (void) +{ + /* FPU settings ------------------------------------------------------------*/ + #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + SCB->CPACR |= ((3UL << (10*2))|(3UL << (11*2))); /* set CP10 and CP11 Full Access */ + #endif + + /*SEVONPEND enabled so that an interrupt coming from the CPU(n) interrupt signal is + detectable by the CPU after a WFI/WFE instruction.*/ + SCB->SCR |= SCB_SCR_SEVONPEND_Msk; + +#ifdef CORE_CM7 + /* Reset the RCC clock configuration to the default reset state ------------*/ + /* Set HSION bit */ + RCC->CR |= RCC_CR_HSION; + + /* Reset CFGR register */ + RCC->CFGR = 0x00000000; + + /* Reset HSEON, CSSON , CSION,RC48ON, CSIKERON PLL1ON, PLL2ON and PLL3ON bits */ + RCC->CR &= 0xEAF6ED7FU; + + /* Reset D1CFGR register */ + RCC->D1CFGR = 0x00000000; + + /* Reset D2CFGR register */ + RCC->D2CFGR = 0x00000000; + + /* Reset D3CFGR register */ + RCC->D3CFGR = 0x00000000; + + /* Reset PLLCKSELR register */ + RCC->PLLCKSELR = 0x00000000; + + /* Reset PLLCFGR register */ + RCC->PLLCFGR = 0x00000000; + /* Reset PLL1DIVR register */ + RCC->PLL1DIVR = 0x00000000; + /* Reset PLL1FRACR register */ + RCC->PLL1FRACR = 0x00000000; + + /* Reset PLL2DIVR register */ + RCC->PLL2DIVR = 0x00000000; + + /* Reset PLL2FRACR register */ + + RCC->PLL2FRACR = 0x00000000; + /* Reset PLL3DIVR register */ + RCC->PLL3DIVR = 0x00000000; + + /* Reset PLL3FRACR register */ + RCC->PLL3FRACR = 0x00000000; + + /* Reset HSEBYP bit */ + RCC->CR &= 0xFFFBFFFFU; + + /* Disable all interrupts */ + RCC->CIER = 0x00000000; + + /* Enable CortexM7 HSEM EXTI line (line 78)*/ + EXTI_D2->EMR3 |= 0x4000UL; + + /* Change the switch matrix read issuing capability to 1 for the AXI SRAM target (Target 7) */ + if((DBGMCU->IDCODE & 0xFFFF0000U) < 0x20000000U) + { + /* if stm32h7 revY*/ + /* Change the switch matrix read issuing capability to 1 for the AXI SRAM target (Target 7) */ + *((__IO uint32_t*)0x51008108) = 0x00000001U; + } + + +/* + * Disable the FMC bank1 (enabled after reset). + * This, prevents CPU speculation access on this bank which blocks the use of FMC during + * 24us. During this time the others FMC master (such as LTDC) cannot use it! + */ + FMC_Bank1_R->BTCR[0] = 0x000030D2; + +#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM) + SystemInit_ExtMemCtl(); +#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */ + +#endif /* CORE_CM7*/ + +#ifndef __rtems__ +#ifdef CORE_CM4 + + /* Configure the Vector Table location add offset address ------------------*/ +#ifdef VECT_TAB_SRAM + SCB->VTOR = D2_AXISRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ +#else + SCB->VTOR = FLASH_BANK2_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ +#endif + +#else +#ifdef CORE_CM7 + + /* Configure the Vector Table location add offset address ------------------*/ +#ifdef VECT_TAB_SRAM + SCB->VTOR = D1_AXISRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ +#else + SCB->VTOR = FLASH_BANK1_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ +#endif + +#else +#error Please #define CORE_CM4 or CORE_CM7 +#endif +#endif + +#else /* __rtems__ */ + SCB->VTOR = (uint32_t) bsp_start_vector_table_begin; +#endif /* __rtems__ */ + +} + +/** + * @brief Update SystemCoreClock variable according to Clock Register Values. + * The SystemCoreClock variable contains the core clock , it can + * be used by the user application to setup the SysTick timer or configure + * other parameters. + * + * @note Each time the core clock changes, this function must be called + * to update SystemCoreClock variable value. Otherwise, any configuration + * based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is CSI, SystemCoreClock will contain the CSI_VALUE(*) + * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**) + * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***) + * - If SYSCLK source is PLL, SystemCoreClock will contain the CSI_VALUE(*), + * HSI_VALUE(**) or HSE_VALUE(***) multiplied/divided by the PLL factors. + * + * (*) CSI_VALUE is a constant defined in stm32h7xx_hal.h file (default value + * 4 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * (**) HSI_VALUE is a constant defined in stm32h7xx_hal.h file (default value + * 64 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (***)HSE_VALUE is a constant defined in stm32h7xx_hal.h file (default value + * 25 MHz), user has to ensure that HSE_VALUE is same as the real + * frequency of the crystal used. Otherwise, this function may + * have wrong result. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * @param None + * @retval None + */ +void SystemCoreClockUpdate (void) +{ + uint32_t pllp, pllsource, pllm, pllfracen, hsivalue, tmp; + uint32_t common_system_clock; + float_t fracn1, pllvco; + + /* Get SYSCLK source -------------------------------------------------------*/ + + switch (RCC->CFGR & RCC_CFGR_SWS) + { + case RCC_CFGR_SWS_HSI: /* HSI used as system clock source */ + common_system_clock = (uint32_t) (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3)); + break; + + case RCC_CFGR_SWS_CSI: /* CSI used as system clock source */ + common_system_clock = CSI_VALUE; + break; + + case RCC_CFGR_SWS_HSE: /* HSE used as system clock source */ + common_system_clock = HSE_VALUE; + break; + + case RCC_CFGR_SWS_PLL1: /* PLL1 used as system clock source */ + + /* PLL_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLLM) * PLLN + SYSCLK = PLL_VCO / PLLR + */ + pllsource = (RCC->PLLCKSELR & RCC_PLLCKSELR_PLLSRC); + pllm = ((RCC->PLLCKSELR & RCC_PLLCKSELR_DIVM1)>> 4) ; + pllfracen = ((RCC->PLLCFGR & RCC_PLLCFGR_PLL1FRACEN)>>RCC_PLLCFGR_PLL1FRACEN_Pos); + fracn1 = (float_t)(uint32_t)(pllfracen* ((RCC->PLL1FRACR & RCC_PLL1FRACR_FRACN1)>> 3)); + + if (pllm != 0U) + { + switch (pllsource) + { + case RCC_PLLCKSELR_PLLSRC_HSI: /* HSI used as PLL clock source */ + + hsivalue = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)>> 3)) ; + pllvco = ( (float_t)hsivalue / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 ); + + break; + + case RCC_PLLCKSELR_PLLSRC_CSI: /* CSI used as PLL clock source */ + pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 ); + break; + + case RCC_PLLCKSELR_PLLSRC_HSE: /* HSE used as PLL clock source */ + pllvco = ((float_t)HSE_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 ); + break; + + default: + pllvco = ((float_t)CSI_VALUE / (float_t)pllm) * ((float_t)(uint32_t)(RCC->PLL1DIVR & RCC_PLL1DIVR_N1) + (fracn1/(float_t)0x2000) +(float_t)1 ); + break; + } + pllp = (((RCC->PLL1DIVR & RCC_PLL1DIVR_P1) >>9) + 1U ) ; + common_system_clock = (uint32_t)(float_t)(pllvco/(float_t)pllp); + } + else + { + common_system_clock = 0U; + } + break; + + default: + common_system_clock = CSI_VALUE; + break; + } + + /* Compute SystemClock frequency --------------------------------------------------*/ + tmp = D1CorePrescTable[(RCC->D1CFGR & RCC_D1CFGR_D1CPRE)>> RCC_D1CFGR_D1CPRE_Pos]; + + /* common_system_clock frequency : CM7 CPU frequency */ + common_system_clock >>= tmp; + + /* SystemD2Clock frequency : CM4 CPU, AXI and AHBs Clock frequency */ + SystemD2Clock = (common_system_clock >> ((D1CorePrescTable[(RCC->D1CFGR & RCC_D1CFGR_HPRE)>> RCC_D1CFGR_HPRE_Pos]) & 0x1FU)); + +#if defined(DUAL_CORE) && defined(CORE_CM4) + SystemCoreClock = SystemD2Clock; +#else + SystemCoreClock = common_system_clock; +#endif /* DUAL_CORE && CORE_CM4 */ +} +#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM) +/** + * @brief Setup the external memory controller. + * Called in startup_stm32h7xx.s before jump to main. + * This function configures the external memories (SRAM/SDRAM) + * This SRAM/SDRAM will be used as program data memory (including heap and stack). + * @param None + * @retval None + */ +void SystemInit_ExtMemCtl(void) +{ + __IO uint32_t tmp = 0; + +#if defined (DATA_IN_ExtSDRAM) && defined (DATA_IN_ExtSRAM) + register uint32_t tmpreg = 0, timeout = 0xFFFF; + register __IO uint32_t index; + + /* Enable GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface + clock */ + RCC->AHB4ENR |= 0x000001F8; + + /* Delay after an RCC peripheral clock enabling */ + tmp = READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_GPIOEEN); + + /* Connect PDx pins to FMC Alternate function */ + GPIOD->AFR[0] = 0x00CC00CC; + GPIOD->AFR[1] = 0xCCCCCCCC; + /* Configure PDx pins in Alternate function mode */ + GPIOD->MODER = 0xAAAAFAFA; + /* Configure PDx pins speed to 100 MHz */ + GPIOD->OSPEEDR = 0xFFFF0F0F; + /* Configure PDx pins Output type to push-pull */ + GPIOD->OTYPER = 0x00000000; + /* Configure PDx pins in Pull-up */ + GPIOD->PUPDR = 0x55550505; + + /* Connect PEx pins to FMC Alternate function */ + GPIOE->AFR[0] = 0xC00CC0CC; + GPIOE->AFR[1] = 0xCCCCCCCC; + /* Configure PEx pins in Alternate function mode */ + GPIOE->MODER = 0xAAAABEBA; + /* Configure PEx pins speed to 100 MHz */ + GPIOE->OSPEEDR = 0xFFFFC3CF; + /* Configure PEx pins Output type to push-pull */ + GPIOE->OTYPER = 0x00000000; + /* Configure PEx pins in Pull-up */ + GPIOE->PUPDR = 0x55554145; + + /* Connect PFx pins to FMC Alternate function */ + GPIOF->AFR[0] = 0x00CCCCCC; + GPIOF->AFR[1] = 0xCCCCC000; + /* Configure PFx pins in Alternate function mode */ + GPIOF->MODER = 0xAABFFAAA; + /* Configure PFx pins speed to 100 MHz */ + GPIOF->OSPEEDR = 0xFFC00FFF; + /* Configure PFx pins Output type to push-pull */ + GPIOF->OTYPER = 0x00000000; + /* Configure PFx pins in Pull-up */ + GPIOF->PUPDR = 0x55400555; + + /* Connect PGx pins to FMC Alternate function */ + GPIOG->AFR[0] = 0x00CCCCCC; + GPIOG->AFR[1] = 0xC0000C0C; + /* Configure PGx pins in Alternate function mode */ + GPIOG->MODER = 0xBFEEFAAA; + /* Configure PGx pins speed to 100 MHz */ + GPIOG->OSPEEDR = 0xC0330FFF; + /* Configure PGx pins Output type to push-pull */ + GPIOG->OTYPER = 0x00000000; + /* Configure PGx pins in Pull-up */ + GPIOG->PUPDR = 0x40110555; + + /* Connect PHx pins to FMC Alternate function */ + GPIOH->AFR[0] = 0xCCC00000; + GPIOH->AFR[1] = 0xCCCCCCCC; + /* Configure PHx pins in Alternate function mode */ + GPIOH->MODER = 0xAAAAABFF; + /* Configure PHx pins speed to 100 MHz */ + GPIOH->OSPEEDR = 0xFFFFFC00; + /* Configure PHx pins Output type to push-pull */ + GPIOH->OTYPER = 0x00000000; + /* Configure PHx pins in Pull-up */ + GPIOH->PUPDR = 0x55555400; + + /* Connect PIx pins to FMC Alternate function */ + GPIOI->AFR[0] = 0xCCCCCCCC; + GPIOI->AFR[1] = 0x00000CC0; + /* Configure PIx pins in Alternate function mode */ + GPIOI->MODER = 0xFFEBAAAA; + /* Configure PIx pins speed to 100 MHz */ + GPIOI->OSPEEDR = 0x003CFFFF; + /* Configure PIx pins Output type to push-pull */ + GPIOI->OTYPER = 0x00000000; + /* Configure PIx pins in Pull-up */ + GPIOI->PUPDR = 0x00145555; + + /* Enable the FMC/FSMC interface clock */ + (RCC->AHB3ENR |= (RCC_AHB3ENR_FMCEN)); + + /* Configure and enable Bank1_SRAM2 */ + FMC_Bank1_R->BTCR[4] = 0x00001091; + FMC_Bank1_R->BTCR[5] = 0x00110212; + FMC_Bank1E_R->BWTR[4] = 0x0FFFFFFF; + + /*SDRAM Timing and access interface configuration*/ + /*LoadToActiveDelay = 2 + ExitSelfRefreshDelay = 6 + SelfRefreshTime = 4 + RowCycleDelay = 6 + WriteRecoveryTime = 2 + RPDelay = 2 + RCDDelay = 2 + SDBank = FMC_SDRAM_BANK2 + ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_9 + RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12 + MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_32 + InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4 + CASLatency = FMC_SDRAM_CAS_LATENCY_2 + WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE + SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2 + ReadBurst = FMC_SDRAM_RBURST_ENABLE + ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0*/ + + FMC_Bank5_6_R->SDCR[0] = 0x00001800; + FMC_Bank5_6_R->SDCR[1] = 0x00000165; + FMC_Bank5_6_R->SDTR[0] = 0x00105000; + FMC_Bank5_6_R->SDTR[1] = 0x01010351; + + /* SDRAM initialization sequence */ + /* Clock enable command */ + FMC_Bank5_6_R->SDCMR = 0x00000009; + tmpreg = FMC_Bank5_6_R->SDSR & 0x00000020; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6_R->SDSR & 0x00000020; + } + + /* Delay */ + for (index = 0; index<1000; index++); + + /* PALL command */ + FMC_Bank5_6_R->SDCMR = 0x0000000A; + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6_R->SDSR & 0x00000020; + } + + FMC_Bank5_6_R->SDCMR = 0x000000EB; + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6_R->SDSR & 0x00000020; + } + + FMC_Bank5_6_R->SDCMR = 0x0004400C; + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6_R->SDSR & 0x00000020; + } + /* Set refresh count */ + tmpreg = FMC_Bank5_6_R->SDRTR; + FMC_Bank5_6_R->SDRTR = (tmpreg | (0x00000603<<1)); + + /* Disable write protection */ + tmpreg = FMC_Bank5_6_R->SDCR[1]; + FMC_Bank5_6_R->SDCR[1] = (tmpreg & 0xFFFFFDFF); + + /*FMC controller Enable*/ + FMC_Bank1_R->BTCR[0] |= 0x80000000; + +#elif defined (DATA_IN_ExtSDRAM) + register uint32_t tmpreg = 0, timeout = 0xFFFF; + register __IO uint32_t index; + + /* Enable GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface + clock */ + RCC->AHB4ENR |= 0x000001F8; + + /* Connect PDx pins to FMC Alternate function */ + GPIOD->AFR[0] = 0x000000CC; + GPIOD->AFR[1] = 0xCC000CCC; + /* Configure PDx pins in Alternate function mode */ + GPIOD->MODER = 0xAFEAFFFA; + /* Configure PDx pins speed to 100 MHz */ + GPIOD->OSPEEDR = 0xF03F000F; + /* Configure PDx pins Output type to push-pull */ + GPIOD->OTYPER = 0x00000000; + /* Configure PDx pins in Pull-up */ + GPIOD->PUPDR = 0x50150005; + + /* Connect PEx pins to FMC Alternate function */ + GPIOE->AFR[0] = 0xC00000CC; + GPIOE->AFR[1] = 0xCCCCCCCC; + /* Configure PEx pins in Alternate function mode */ + GPIOE->MODER = 0xAAAABFFA; + /* Configure PEx pins speed to 100 MHz */ + GPIOE->OSPEEDR = 0xFFFFC00F; + /* Configure PEx pins Output type to push-pull */ + GPIOE->OTYPER = 0x00000000; + /* Configure PEx pins in Pull-up */ + GPIOE->PUPDR = 0x55554005; + + /* Connect PFx pins to FMC Alternate function */ + GPIOF->AFR[0] = 0x00CCCCCC; + GPIOF->AFR[1] = 0xCCCCC000; + /* Configure PFx pins in Alternate function mode */ + GPIOF->MODER = 0xAABFFAAA; + /* Configure PFx pins speed to 100 MHz */ + GPIOF->OSPEEDR = 0xFFC00FFF; + /* Configure PFx pins Output type to push-pull */ + GPIOF->OTYPER = 0x00000000; + /* Configure PFx pins in Pull-up */ + GPIOF->PUPDR = 0x55400555; + + /* Connect PGx pins to FMC Alternate function */ + GPIOG->AFR[0] = 0x00CCCCCC; + GPIOG->AFR[1] = 0xC000000C; + /* Configure PGx pins in Alternate function mode */ + GPIOG->MODER = 0xBFFEFAAA; + /* Configure PGx pins speed to 100 MHz */ + GPIOG->OSPEEDR = 0xC0030FFF; + /* Configure PGx pins Output type to push-pull */ + GPIOG->OTYPER = 0x00000000; + /* Configure PGx pins in Pull-up */ + GPIOG->PUPDR = 0x40010555; + + /* Connect PHx pins to FMC Alternate function */ + GPIOH->AFR[0] = 0xCCC00000; + GPIOH->AFR[1] = 0xCCCCCCCC; + /* Configure PHx pins in Alternate function mode */ + GPIOH->MODER = 0xAAAAABFF; + /* Configure PHx pins speed to 100 MHz */ + GPIOH->OSPEEDR = 0xFFFFFC00; + /* Configure PHx pins Output type to push-pull */ + GPIOH->OTYPER = 0x00000000; + /* Configure PHx pins in Pull-up */ + GPIOH->PUPDR = 0x55555400; + + /* Connect PIx pins to FMC Alternate function */ + GPIOI->AFR[0] = 0xCCCCCCCC; + GPIOI->AFR[1] = 0x00000CC0; + /* Configure PIx pins in Alternate function mode */ + GPIOI->MODER = 0xFFEBAAAA; + /* Configure PIx pins speed to 100 MHz */ + GPIOI->OSPEEDR = 0x003CFFFF; + /* Configure PIx pins Output type to push-pull */ + GPIOI->OTYPER = 0x00000000; + /* Configure PIx pins in Pull-up */ + GPIOI->PUPDR = 0x00145555; + +/*-- FMC Configuration ------------------------------------------------------*/ + /* Enable the FMC interface clock */ + (RCC->AHB3ENR |= (RCC_AHB3ENR_FMCEN)); + /*SDRAM Timing and access interface configuration*/ + /*LoadToActiveDelay = 2 + ExitSelfRefreshDelay = 6 + SelfRefreshTime = 4 + RowCycleDelay = 6 + WriteRecoveryTime = 2 + RPDelay = 2 + RCDDelay = 2 + SDBank = FMC_SDRAM_BANK2 + ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_9 + RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12 + MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_32 + InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4 + CASLatency = FMC_SDRAM_CAS_LATENCY_2 + WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE + SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2 + ReadBurst = FMC_SDRAM_RBURST_ENABLE + ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0*/ + + FMC_Bank5_6_R->SDCR[0] = 0x00001800; + FMC_Bank5_6_R->SDCR[1] = 0x00000165; + FMC_Bank5_6_R->SDTR[0] = 0x00105000; + FMC_Bank5_6_R->SDTR[1] = 0x01010351; + + /* SDRAM initialization sequence */ + /* Clock enable command */ + FMC_Bank5_6_R->SDCMR = 0x00000009; + tmpreg = FMC_Bank5_6_R->SDSR & 0x00000020; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6_R->SDSR & 0x00000020; + } + + /* Delay */ + for (index = 0; index<1000; index++); + + /* PALL command */ + FMC_Bank5_6_R->SDCMR = 0x0000000A; + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6_R->SDSR & 0x00000020; + } + + FMC_Bank5_6_R->SDCMR = 0x000000EB; + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6_R->SDSR & 0x00000020; + } + + FMC_Bank5_6_R->SDCMR = 0x0004400C; + timeout = 0xFFFF; + while((tmpreg != 0) && (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6_R->SDSR & 0x00000020; + } + /* Set refresh count */ + tmpreg = FMC_Bank5_6_R->SDRTR; + FMC_Bank5_6_R->SDRTR = (tmpreg | (0x00000603<<1)); + + /* Disable write protection */ + tmpreg = FMC_Bank5_6_R->SDCR[1]; + FMC_Bank5_6_R->SDCR[1] = (tmpreg & 0xFFFFFDFF); + + /*FMC controller Enable*/ + FMC_Bank1_R->BTCR[0] |= 0x80000000; + +#elif defined(DATA_IN_ExtSRAM) +/*-- GPIOs Configuration -----------------------------------------------------*/ + /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */ + RCC->AHB4ENR |= 0x00000078; + + /* Connect PDx pins to FMC Alternate function */ + GPIOD->AFR[0] = 0x00CC00CC; + GPIOD->AFR[1] = 0xCCCCCCCC; + /* Configure PDx pins in Alternate function mode */ + GPIOD->MODER = 0xAAAAFABA; + /* Configure PDx pins speed to 100 MHz */ + GPIOD->OSPEEDR = 0xFFFF0F0F; + /* Configure PDx pins Output type to push-pull */ + GPIOD->OTYPER = 0x00000000; + /* Configure PDx pins in Pull-up */ + GPIOD->PUPDR = 0x55550505; + + /* Connect PEx pins to FMC Alternate function */ + GPIOE->AFR[0] = 0xC00CC0CC; + GPIOE->AFR[1] = 0xCCCCCCCC; + /* Configure PEx pins in Alternate function mode */ + GPIOE->MODER = 0xAAAABEBA; + /* Configure PEx pins speed to 100 MHz */ + GPIOE->OSPEEDR = 0xFFFFC3CF; + /* Configure PEx pins Output type to push-pull */ + GPIOE->OTYPER = 0x00000000; + /* Configure PEx pins in Pull-up */ + GPIOE->PUPDR = 0x55554145; + + /* Connect PFx pins to FMC Alternate function */ + GPIOF->AFR[0] = 0x00CCCCCC; + GPIOF->AFR[1] = 0xCCCC0000; + /* Configure PFx pins in Alternate function mode */ + GPIOF->MODER = 0xAAFFFAAA; + /* Configure PFx pins speed to 100 MHz */ + GPIOF->OSPEEDR = 0xFF000FFF; + /* Configure PFx pins Output type to push-pull */ + GPIOF->OTYPER = 0x00000000; + /* Configure PFx pins in Pull-up */ + GPIOF->PUPDR = 0x55000555; + + /* Connect PGx pins to FMC Alternate function */ + GPIOG->AFR[0] = 0x00CCCCCC; + GPIOG->AFR[1] = 0x00000C00; + /* Configure PGx pins in Alternate function mode */ + GPIOG->MODER = 0xFFEFFAAA; + /* Configure PGx pins speed to 100 MHz */ + GPIOG->OSPEEDR = 0x00300FFF; + /* Configure PGx pins Output type to push-pull */ + GPIOG->OTYPER = 0x00000000; + /* Configure PGx pins in Pull-up */ + GPIOG->PUPDR = 0x00100555; + +/*-- FMC/FSMC Configuration --------------------------------------------------*/ + /* Enable the FMC/FSMC interface clock */ + (RCC->AHB3ENR |= (RCC_AHB3ENR_FMCEN)); + + /* Configure and enable Bank1_SRAM2 */ + FMC_Bank1_R->BTCR[4] = 0x00001091; + FMC_Bank1_R->BTCR[5] = 0x00110212; + FMC_Bank1E_R->BWTR[4] = 0x0FFFFFFF; + + /*FMC controller Enable*/ + FMC_Bank1_R->BTCR[0] |= 0x80000000; + +#endif /* DATA_IN_ExtSRAM */ + + (void)(tmp); +} +#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */ + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ |