1 /** 2 ****************************************************************************** 3 * @file stm32h7xx_ll_delayblock.c 4 * @author MCD Application Team 5 * @brief DelayBlock Low Layer HAL module driver. 6 * 7 * This file provides firmware functions to manage the following 8 * functionalities of the Delay Block peripheral: 9 * + input clock frequency range 25MHz to 208MHz 10 * + up to 12 oversampling phases 11 * 12 ****************************************************************************** 13 * @attention 14 * 15 * Copyright (c) 2017 STMicroelectronics. 16 * All rights reserved. 17 * 18 * This software is licensed under terms that can be found in the LICENSE file 19 * in the root directory of this software component. 20 * If no LICENSE file comes with this software, it is provided AS-IS. 21 * 22 ****************************************************************************** 23 @verbatim 24 ============================================================================== 25 ##### DelayBlock peripheral features ##### 26 ============================================================================== 27 [..] The Delay block is used to generate an Output clock which is de-phased from the Input 28 clock. The phase of the Output clock is programmed by FW. The Output clock is then used 29 to clock the receive data in i.e. a SDMMC or QSPI interface. 30 The delay is Voltage and Temperature dependent, which may require FW to do re-tuning 31 and recenter the Output clock phase to the receive data. 32 33 [..] The Delay Block features include the following: 34 (+) Input clock frequency range 25MHz to 208MHz. 35 (+) Up to 12 oversampling phases. 36 37 ##### How to use this driver ##### 38 ============================================================================== 39 [..] 40 This driver is a considered as a driver of service for external devices drivers 41 that interfaces with the DELAY peripheral. 42 The DelayBlock_Enable() function, enables the DelayBlock instance, configure the delay line length 43 and configure the Output clock phase. 44 The DelayBlock_Disable() function, disables the DelayBlock instance by setting DEN flag to 0. 45 46 47 @endverbatim 48 */ 49 50 /* Includes ------------------------------------------------------------------*/ 51 #include "stm32h7xx_hal.h" 52 53 /** @addtogroup STM32H7xx_HAL_Driver 54 * @{ 55 */ 56 57 /** @defgroup DELAYBLOCK_LL DELAYBLOCK_LL 58 * @brief Low layer module for Delay Block 59 * @{ 60 */ 61 62 #if defined(HAL_SD_MODULE_ENABLED) || defined(HAL_QSPI_MODULE_ENABLED) 63 64 /* Private typedef -----------------------------------------------------------*/ 65 /* Private define ------------------------------------------------------------*/ 66 /** @defgroup DelayBlock_LL_Private_Defines Delay Block Low Layer Private Defines 67 * @{ 68 */ 69 #define DLYB_TIMEOUT 0xFFU 70 /** 71 * @} 72 */ 73 /* Private macro -------------------------------------------------------------*/ 74 /* Private variables ---------------------------------------------------------*/ 75 /* Private function prototypes -----------------------------------------------*/ 76 /* Exported functions --------------------------------------------------------*/ 77 78 /** @defgroup DelayBlock_LL_Exported_Functions Delay Block Low Layer Exported Functions 79 * @{ 80 */ 81 82 /** @defgroup HAL_DELAY_LL_Group1 Initialization de-initialization functions 83 * @brief Initialization and Configuration functions 84 * 85 @verbatim 86 =============================================================================== 87 ##### Initialization and de-initialization functions ##### 88 =============================================================================== 89 [..] This section provides functions allowing to: 90 91 @endverbatim 92 * @{ 93 */ 94 95 96 /** 97 * @brief Enable the Delay Block instance. 98 * @param DLYBx: Pointer to DLYB instance. 99 * @retval HAL status 100 */ DelayBlock_Enable(DLYB_TypeDef * DLYBx)101HAL_StatusTypeDef DelayBlock_Enable(DLYB_TypeDef *DLYBx) 102 { 103 uint32_t unit = 0U; 104 uint32_t sel = 0U; 105 uint32_t sel_current; 106 uint32_t unit_current; 107 uint32_t tuning; 108 uint32_t lng_mask; 109 uint32_t tickstart; 110 111 DLYBx->CR = DLYB_CR_DEN | DLYB_CR_SEN; 112 113 for (sel_current = 0U; sel_current < DLYB_MAX_SELECT; sel_current++) 114 { 115 /* lng_mask is the mask bit for the LNG field to check the output of the UNITx*/ 116 lng_mask = DLYB_CFGR_LNG_0 << sel_current; 117 tuning = 0U; 118 for (unit_current = 0U; unit_current < DLYB_MAX_UNIT; unit_current++) 119 { 120 /* Set the Delay of the UNIT(s)*/ 121 DLYBx->CFGR = DLYB_MAX_SELECT | (unit_current << DLYB_CFGR_UNIT_Pos); 122 123 /* Waiting for a LNG valid value */ 124 tickstart = HAL_GetTick(); 125 while ((DLYBx->CFGR & DLYB_CFGR_LNGF) == 0U) 126 { 127 if((HAL_GetTick() - tickstart) >= DLYB_TIMEOUT) 128 { 129 return HAL_TIMEOUT; 130 } 131 } 132 if (tuning == 0U) 133 { 134 if ((DLYBx->CFGR & lng_mask) != 0U) 135 { 136 /* 1/2 period HIGH is detected */ 137 tuning = 1U; 138 } 139 } 140 else 141 { 142 /* 1/2 period LOW detected after the HIGH 1/2 period => FULL PERIOD passed*/ 143 if((DLYBx->CFGR & lng_mask ) == 0U) 144 { 145 /* Save the first result */ 146 if( unit == 0U ) 147 { 148 unit = unit_current; 149 sel = sel_current + 1U; 150 } 151 break; 152 } 153 } 154 } 155 } 156 157 /* Apply the Tuning settings */ 158 DLYBx->CR = 0U; 159 DLYBx->CR = DLYB_CR_DEN | DLYB_CR_SEN; 160 DLYBx->CFGR = sel | (unit << DLYB_CFGR_UNIT_Pos); 161 DLYBx->CR = DLYB_CR_DEN; 162 163 return HAL_OK; 164 } 165 166 /** 167 * @brief Disable the Delay Block instance. 168 * @param DLYBx: Pointer to DLYB instance. 169 * @retval HAL status 170 */ DelayBlock_Disable(DLYB_TypeDef * DLYBx)171HAL_StatusTypeDef DelayBlock_Disable(DLYB_TypeDef *DLYBx) 172 { 173 /* Disable DLYB */ 174 DLYBx->CR = 0U; 175 return HAL_OK; 176 } 177 178 /** 179 * @brief Configure the Delay Block instance. 180 * @param DLYBx: Pointer to DLYB instance. 181 * @param PhaseSel: Phase selection [0..11]. 182 * @param Units: Delay units[0..127]. 183 * @retval HAL status 184 */ DelayBlock_Configure(DLYB_TypeDef * DLYBx,uint32_t PhaseSel,uint32_t Units)185HAL_StatusTypeDef DelayBlock_Configure(DLYB_TypeDef *DLYBx,uint32_t PhaseSel, uint32_t Units ) 186 { 187 /* Apply the delay settings */ 188 189 DLYBx->CR = 0U; 190 DLYBx->CR = DLYB_CR_DEN | DLYB_CR_SEN; 191 DLYBx->CFGR = PhaseSel | (Units << DLYB_CFGR_UNIT_Pos); 192 DLYBx->CR = DLYB_CR_DEN; 193 194 return HAL_OK; 195 } 196 197 198 /** 199 * @} 200 */ 201 202 /** 203 * @} 204 */ 205 206 #endif /* (HAL_SD_MODULE_ENABLED) & (HAL_QSPI_MODULE_ENABLED)*/ 207 /** 208 * @} 209 */ 210 211 /** 212 * @} 213 */ 214 215