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