Back to home page

LXR

 
 

    


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

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_ll_delayblock.c
0004   * @author  MCD Application Team
0005   * @brief   DelayBlock Low Layer HAL module driver.
0006   *    
0007   *          This file provides firmware functions to manage the following 
0008   *          functionalities of the Delay Block peripheral:
0009   *           + input clock frequency range 25MHz to 208MHz
0010   *           + up to 12 oversampling phases
0011   *
0012   ******************************************************************************
0013   * @attention
0014   *
0015   * Copyright (c) 2017 STMicroelectronics.
0016   * All rights reserved.
0017   *
0018   * This software is licensed under terms that can be found in the LICENSE file
0019   * in the root directory of this software component.
0020   * If no LICENSE file comes with this software, it is provided AS-IS.
0021   *
0022   ******************************************************************************
0023   @verbatim
0024   ==============================================================================
0025                        ##### DelayBlock peripheral features #####
0026   ==============================================================================        
0027     [..] The Delay block is used to generate an Output clock which is de-phased from the Input
0028           clock. The phase of the Output clock is programmed by FW. The Output clock is then used
0029           to clock the receive data in i.e. a SDMMC or QSPI interface.
0030          The delay is Voltage and Temperature dependent, which may require FW to do re-tuning
0031           and recenter the Output clock phase to the receive data.
0032     
0033     [..] The Delay Block features include the following:
0034          (+) Input clock frequency range 25MHz to 208MHz.
0035          (+) Up to 12 oversampling phases.
0036          
0037                            ##### How to use this driver #####
0038   ==============================================================================
0039     [..]
0040       This driver is a considered as a driver of service for external devices drivers
0041       that interfaces with the DELAY peripheral.
0042       The DelayBlock_Enable() function, enables the DelayBlock instance, configure the delay line length
0043       and configure the Output clock phase.
0044       The DelayBlock_Disable() function, disables the DelayBlock instance by setting DEN flag to 0.
0045       
0046   
0047   @endverbatim
0048   */
0049 
0050 /* Includes ------------------------------------------------------------------*/
0051 #include "stm32h7xx_hal.h"
0052 
0053 /** @addtogroup STM32H7xx_HAL_Driver
0054   * @{
0055   */
0056 
0057 /** @defgroup DELAYBLOCK_LL DELAYBLOCK_LL
0058   * @ingroup RTEMSBSPsARMSTM32H7
0059   * @brief Low layer module for Delay Block
0060   * @{
0061   */
0062 
0063 #if defined(HAL_SD_MODULE_ENABLED) || defined(HAL_QSPI_MODULE_ENABLED)
0064 
0065 /* Private typedef -----------------------------------------------------------*/
0066 /* Private define ------------------------------------------------------------*/
0067 /** @defgroup DelayBlock_LL_Private_Defines Delay Block Low Layer Private Defines
0068   * @ingroup RTEMSBSPsARMSTM32H7
0069   * @{
0070   */
0071 #define DLYB_TIMEOUT 0xFFU
0072 /**
0073   * @}
0074   */
0075 /* Private macro -------------------------------------------------------------*/
0076 /* Private variables ---------------------------------------------------------*/
0077 /* Private function prototypes -----------------------------------------------*/
0078 /* Exported functions --------------------------------------------------------*/
0079 
0080 /** @defgroup DelayBlock_LL_Exported_Functions Delay Block Low Layer Exported Functions
0081   * @ingroup RTEMSBSPsARMSTM32H7
0082   * @{
0083   */
0084 
0085 /** @defgroup HAL_DELAY_LL_Group1 Initialization de-initialization functions 
0086   * @ingroup RTEMSBSPsARMSTM32H7
0087  *  @brief    Initialization and Configuration functions 
0088  *
0089 @verbatim    
0090  ===============================================================================
0091               ##### Initialization and de-initialization functions #####
0092  ===============================================================================
0093     [..]  This section provides functions allowing to:
0094  
0095 @endverbatim
0096   * @{
0097   */
0098 
0099 
0100 /**
0101   * @brief  Enable the Delay Block instance.
0102   * @param  DLYBx: Pointer to DLYB instance.
0103   * @retval HAL status
0104   */
0105 HAL_StatusTypeDef DelayBlock_Enable(DLYB_TypeDef *DLYBx)
0106 {
0107   uint32_t unit = 0U;
0108   uint32_t sel = 0U;
0109   uint32_t sel_current;
0110   uint32_t unit_current;
0111   uint32_t tuning;
0112   uint32_t lng_mask;
0113   uint32_t tickstart;
0114 
0115   DLYBx->CR = DLYB_CR_DEN | DLYB_CR_SEN;
0116 
0117   for (sel_current = 0U; sel_current < DLYB_MAX_SELECT; sel_current++)
0118   {
0119     /* lng_mask is the mask bit for the LNG field to check the output of the UNITx*/
0120     lng_mask = DLYB_CFGR_LNG_0 << sel_current;
0121     tuning = 0U;
0122     for (unit_current = 0U; unit_current < DLYB_MAX_UNIT; unit_current++)
0123     {
0124       /* Set the Delay of the UNIT(s)*/
0125       DLYBx->CFGR = DLYB_MAX_SELECT | (unit_current << DLYB_CFGR_UNIT_Pos);
0126 
0127       /* Waiting for a LNG valid value */
0128       tickstart =  HAL_GetTick();
0129       while ((DLYBx->CFGR & DLYB_CFGR_LNGF) == 0U)
0130       {
0131         if((HAL_GetTick() - tickstart) >=  DLYB_TIMEOUT)
0132         {
0133           return HAL_TIMEOUT;
0134         }
0135       }
0136       if (tuning == 0U)
0137       {
0138         if ((DLYBx->CFGR & lng_mask) != 0U)
0139         {
0140           /* 1/2 period HIGH is detected */
0141           tuning = 1U;
0142         }
0143       }
0144       else
0145       {
0146         /* 1/2 period LOW detected after the HIGH 1/2 period => FULL PERIOD passed*/
0147         if((DLYBx->CFGR & lng_mask ) == 0U)
0148         {
0149           /* Save the first result */
0150           if( unit == 0U )
0151           {
0152             unit = unit_current;
0153             sel  = sel_current + 1U;
0154           }
0155           break;
0156         }
0157       }
0158     }
0159   }
0160 
0161   /* Apply the Tuning settings */
0162   DLYBx->CR   = 0U;
0163   DLYBx->CR   = DLYB_CR_DEN | DLYB_CR_SEN;
0164   DLYBx->CFGR = sel | (unit << DLYB_CFGR_UNIT_Pos);
0165   DLYBx->CR   = DLYB_CR_DEN;
0166 
0167   return HAL_OK;
0168 }
0169 
0170 /**
0171   * @brief  Disable the Delay Block instance.
0172   * @param  DLYBx: Pointer to DLYB instance.
0173   * @retval HAL status
0174   */
0175 HAL_StatusTypeDef DelayBlock_Disable(DLYB_TypeDef *DLYBx)
0176 {
0177   /* Disable DLYB */
0178   DLYBx->CR = 0U;
0179   return HAL_OK;
0180 }
0181 
0182 /**
0183   * @brief  Configure the Delay Block instance.
0184   * @param  DLYBx: Pointer to DLYB instance.
0185   * @param  PhaseSel: Phase selection [0..11].
0186   * @param  Units: Delay units[0..127].
0187   * @retval HAL status
0188   */
0189 HAL_StatusTypeDef DelayBlock_Configure(DLYB_TypeDef *DLYBx,uint32_t PhaseSel, uint32_t Units )
0190 {
0191   /* Apply the delay settings */
0192 
0193   DLYBx->CR   = 0U;
0194   DLYBx->CR   = DLYB_CR_DEN | DLYB_CR_SEN;
0195   DLYBx->CFGR = PhaseSel | (Units << DLYB_CFGR_UNIT_Pos);
0196   DLYBx->CR   = DLYB_CR_DEN;
0197 
0198   return HAL_OK;
0199 }
0200 
0201 
0202 /**
0203   * @}
0204   */
0205 
0206 /**
0207   * @}
0208   */
0209 
0210 #endif /* (HAL_SD_MODULE_ENABLED) & (HAL_QSPI_MODULE_ENABLED)*/
0211 /**
0212   * @}
0213   */
0214 
0215 /**
0216   * @}
0217   */
0218