1 /**
2   ******************************************************************************
3   * @file    stm32u5xx_hal_dsi.c
4   * @author  MCD Application Team
5   * @brief   DSI HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the DSI peripheral:
8   *           + Initialization and de-initialization functions
9   *           + IO operation functions
10   *           + Peripheral Control functions
11   *           + Peripheral State and Errors functions
12   ******************************************************************************
13   * @attention
14   *
15   * Copyright (c) 2021 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                         ##### How to use this driver #####
26   ==============================================================================
27   [..]
28     The DSI HAL driver can be used as follows:
29 
30     (#) Declare a DSI_HandleTypeDef handle structure, for example: DSI_HandleTypeDef  hdsi;
31 
32     (#) Initialize the DSI low level resources by implementing the HAL_DSI_MspInit() API:
33         (##) Enable the DSI interface clock
34         (##) NVIC configuration if you need to use interrupt process
35             (+++) Configure the DSI interrupt priority
36             (+++) Enable the NVIC DSI IRQ Channel
37 
38     (#) Initialize the DSI Host peripheral, the required PLL parameters, number of lances and
39         TX Escape clock divider by calling the HAL_DSI_Init() API which calls HAL_DSI_MspInit().
40 
41     *** Configuration ***
42     =========================
43     [..]
44     (#) Use HAL_DSI_ConfigAdaptedCommandMode() function to configure the DSI host in adapted
45         command mode.
46 
47     (#) When operating in video mode , use HAL_DSI_ConfigVideoMode() to configure the DSI host.
48 
49     (#) Function HAL_DSI_ConfigCommand() is used to configure the DSI commands behavior in low power mode.
50 
51     (#) To configure the DSI PHY timings parameters, use function HAL_DSI_ConfigPhyTimer().
52 
53     (#) The DSI Host can be started/stopped using respectively functions HAL_DSI_Start() and HAL_DSI_Stop().
54         Functions HAL_DSI_ShortWrite(), HAL_DSI_LongWrite() and HAL_DSI_Read() allows respectively
55         to write DSI short packets, long packets and to read DSI packets.
56 
57     (#) The DSI Host Offers two Low power modes :
58         (++) Low Power Mode on data lanes only: Only DSI data lanes are shut down.
59             It is possible to enter/exit from this mode using respectively functions HAL_DSI_EnterULPMData()
60             and HAL_DSI_ExitULPMData()
61 
62         (++) Low Power Mode on data and clock lanes : All DSI lanes are shut down including data and clock lanes.
63             It is possible to enter/exit from this mode using respectively functions HAL_DSI_EnterULPM()
64             and HAL_DSI_ExitULPM()
65 
66     (#) To control DSI state you can use the following function: HAL_DSI_GetState()
67 
68     *** Error management ***
69     ========================
70     [..]
71     (#) User can select the DSI errors to be reported/monitored using function HAL_DSI_ConfigErrorMonitor()
72         When an error occurs, the callback HAL_DSI_ErrorCallback() is asserted and then user can retrieve
73         the error code by calling function HAL_DSI_GetError()
74 
75     *** DSI HAL driver macros list ***
76     =============================================
77     [..]
78        Below the list of most used macros in DSI HAL driver.
79 
80       (+) __HAL_DSI_ENABLE: Enable the DSI Host.
81       (+) __HAL_DSI_DISABLE: Disable the DSI Host.
82       (+) __HAL_DSI_WRAPPER_ENABLE: Enables the DSI wrapper.
83       (+) __HAL_DSI_WRAPPER_DISABLE: Disable the DSI wrapper.
84       (+) __HAL_DSI_PLL_ENABLE: Enables the DSI PLL.
85       (+) __HAL_DSI_PLL_DISABLE: Disables the DSI PLL.
86       (+) __HAL_DSI_REG_ENABLE: Enables the DSI regulator.
87       (+) __HAL_DSI_REG_DISABLE: Disables the DSI regulator.
88       (+) __HAL_DSI_GET_FLAG: Get the DSI pending flags.
89       (+) __HAL_DSI_CLEAR_FLAG: Clears the DSI pending flags.
90       (+) __HAL_DSI_ENABLE_IT: Enables the specified DSI interrupts.
91       (+) __HAL_DSI_DISABLE_IT: Disables the specified DSI interrupts.
92       (+) __HAL_DSI_GET_IT_SOURCE: Checks whether the specified DSI interrupt source is enabled or not.
93 
94     [..]
95       (@) You can refer to the DSI HAL driver header file for more useful macros
96 
97     *** Callback registration ***
98     =============================================
99     [..]
100     The compilation define  USE_HAL_DSI_REGISTER_CALLBACKS when set to 1
101     allows the user to configure dynamically the driver callbacks.
102     Use Function HAL_DSI_RegisterCallback() to register a callback.
103 
104     [..]
105     Function HAL_DSI_RegisterCallback() allows to register following callbacks:
106       (+) TearingEffectCallback : DSI Tearing Effect Callback.
107       (+) EndOfRefreshCallback  : DSI End Of Refresh Callback.
108       (+) ErrorCallback         : DSI Error Callback
109       (+) MspInitCallback       : DSI MspInit.
110       (+) MspDeInitCallback     : DSI MspDeInit.
111     [..]
112     This function takes as parameters the HAL peripheral handle, the callback ID
113     and a pointer to the user callback function.
114 
115     [..]
116     Use function HAL_DSI_UnRegisterCallback() to reset a callback to the default
117     weak function.
118     HAL_DSI_UnRegisterCallback takes as parameters the HAL peripheral handle,
119     and the callback ID.
120     [..]
121     This function allows to reset following callbacks:
122       (+) TearingEffectCallback : DSI Tearing Effect Callback.
123       (+) EndOfRefreshCallback  : DSI End Of Refresh Callback.
124       (+) ErrorCallback         : DSI Error Callback
125       (+) MspInitCallback       : DSI MspInit.
126       (+) MspDeInitCallback     : DSI MspDeInit.
127 
128     [..]
129     By default, after the HAL_DSI_Init and when the state is HAL_DSI_STATE_RESET
130     all callbacks are set to the corresponding weak functions:
131     examples HAL_DSI_TearingEffectCallback(), HAL_DSI_EndOfRefreshCallback().
132     Exception done for MspInit and MspDeInit functions that are respectively
133     reset to the legacy weak (surcharged) functions in the HAL_DSI_Init()
134     and HAL_DSI_DeInit() only when these callbacks are null (not registered beforehand).
135     If not, MspInit or MspDeInit are not null, the HAL_DSI_Init() and HAL_DSI_DeInit()
136     keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
137 
138     [..]
139     Callbacks can be registered/unregistered in HAL_DSI_STATE_READY state only.
140     Exception done MspInit/MspDeInit that can be registered/unregistered
141     in HAL_DSI_STATE_READY or HAL_DSI_STATE_RESET state,
142     thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
143     In that case first register the MspInit/MspDeInit user callbacks
144     using HAL_DSI_RegisterCallback() before calling HAL_DSI_DeInit()
145     or HAL_DSI_Init() function.
146 
147     [..]
148     When The compilation define USE_HAL_DSI_REGISTER_CALLBACKS is set to 0 or
149     not defined, the callback registration feature is not available and all callbacks
150     are set to the corresponding weak functions.
151 
152   @endverbatim
153   ******************************************************************************
154   */
155 
156 /* Includes ------------------------------------------------------------------*/
157 #include "stm32u5xx_hal.h"
158 
159 /** @addtogroup STM32U5xx_HAL_Driver
160   * @{
161   */
162 
163 #ifdef HAL_DSI_MODULE_ENABLED
164 
165 #if defined(DSI)
166 
167 /** @addtogroup DSI
168   * @{
169   */
170 
171 /* Private types -------------------------------------------------------------*/
172 /* Private defines -----------------------------------------------------------*/
173 /** @addtogroup DSI_Private_Constants
174   * @{
175   */
176 #define DSI_TIMEOUT_VALUE ((uint32_t)100U)  /* 100ms */
177 
178 #define DSI_ERROR_ACK_MASK (DSI_ISR0_AE0 | DSI_ISR0_AE1 | DSI_ISR0_AE2 | DSI_ISR0_AE3 | \
179                             DSI_ISR0_AE4 | DSI_ISR0_AE5 | DSI_ISR0_AE6 | DSI_ISR0_AE7 | \
180                             DSI_ISR0_AE8 | DSI_ISR0_AE9 | DSI_ISR0_AE10 | DSI_ISR0_AE11 | \
181                             DSI_ISR0_AE12 | DSI_ISR0_AE13 | DSI_ISR0_AE14 | DSI_ISR0_AE15)
182 #define DSI_ERROR_PHY_MASK (DSI_ISR0_PE0 | DSI_ISR0_PE1 | DSI_ISR0_PE2 | DSI_ISR0_PE3 | DSI_ISR0_PE4)
183 #define DSI_ERROR_TX_MASK  DSI_ISR1_TOHSTX
184 #define DSI_ERROR_RX_MASK  DSI_ISR1_TOLPRX
185 #define DSI_ERROR_ECC_MASK (DSI_ISR1_ECCSE | DSI_ISR1_ECCME)
186 #define DSI_ERROR_CRC_MASK DSI_ISR1_CRCE
187 #define DSI_ERROR_PSE_MASK DSI_ISR1_PSE
188 #define DSI_ERROR_EOT_MASK DSI_ISR1_EOTPE
189 #define DSI_ERROR_OVF_MASK DSI_ISR1_LPWRE
190 #define DSI_ERROR_GEN_MASK (DSI_ISR1_GCWRE | DSI_ISR1_GPWRE | DSI_ISR1_GPTXE | DSI_ISR1_GPRDE | DSI_ISR1_GPRXE)
191 #define DSI_ERROR_PBU_MASK DSI_ISR1_PBUE
192 /**
193   * @}
194   */
195 
196 /* Private variables ---------------------------------------------------------*/
197 /* Private constants ---------------------------------------------------------*/
198 /* Private macros ------------------------------------------------------------*/
199 /* Private function prototypes -----------------------------------------------*/
200 static void DSI_ConfigPacketHeader(DSI_TypeDef *DSIx, uint32_t ChannelID, uint32_t DataType, uint32_t Data0,
201                                    uint32_t Data1);
202 
203 static HAL_StatusTypeDef DSI_ShortWrite(DSI_HandleTypeDef *hdsi,
204                                         uint32_t ChannelID,
205                                         uint32_t Mode,
206                                         uint32_t Param1,
207                                         uint32_t Param2);
208 static void DSI_ConfigBandControl(DSI_HandleTypeDef *hdsi);
209 static void DSI_SetWrapperPLLTuning(DSI_HandleTypeDef *hdsi, DSI_PLLInitTypeDef *PLLInit);
210 /* Private functions ---------------------------------------------------------*/
211 /** @defgroup DSI_Private_Functions DSI Private Functions
212   * @{
213   */
214 /**
215   * @brief  Generic DSI packet header configuration
216   * @param  DSIx  Pointer to DSI register base
217   * @param  ChannelID Virtual channel ID of the header packet
218   * @param  DataType  Packet data type of the header packet
219   *                   This parameter can be any value of :
220   *                      @arg DSI_SHORT_WRITE_PKT_Data_Type
221   *                      @arg DSI_LONG_WRITE_PKT_Data_Type
222   *                      @arg DSI_SHORT_READ_PKT_Data_Type
223   *                      @arg DSI_MAX_RETURN_PKT_SIZE
224   * @param  Data0  Word count LSB
225   * @param  Data1  Word count MSB
226   * @retval None
227   */
DSI_ConfigPacketHeader(DSI_TypeDef * DSIx,uint32_t ChannelID,uint32_t DataType,uint32_t Data0,uint32_t Data1)228 static void DSI_ConfigPacketHeader(DSI_TypeDef *DSIx,
229                                    uint32_t ChannelID,
230                                    uint32_t DataType,
231                                    uint32_t Data0,
232                                    uint32_t Data1)
233 {
234   /* Update the DSI packet header with new information */
235   DSIx->GHCR = (DataType | (ChannelID << 6U) | (Data0 << 8U) | (Data1 << 16U));
236 }
237 
238 /**
239   * @brief  write short DCS or short Generic command
240   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
241   *               the configuration information for the DSI.
242   * @param  ChannelID  Virtual channel ID.
243   * @param  Mode  DSI short packet data type.
244   *               This parameter can be any value of @arg DSI_SHORT_WRITE_PKT_Data_Type.
245   * @param  Param1  DSC command or first generic parameter.
246   *                 This parameter can be any value of @arg DSI_DCS_Command or a
247   *                 generic command code.
248   * @param  Param2  DSC parameter or second generic parameter.
249   * @retval HAL status
250   */
DSI_ShortWrite(DSI_HandleTypeDef * hdsi,uint32_t ChannelID,uint32_t Mode,uint32_t Param1,uint32_t Param2)251 static HAL_StatusTypeDef DSI_ShortWrite(DSI_HandleTypeDef *hdsi,
252                                         uint32_t ChannelID,
253                                         uint32_t Mode,
254                                         uint32_t Param1,
255                                         uint32_t Param2)
256 {
257   uint32_t tickstart;
258 
259   /* Get tick */
260   tickstart = HAL_GetTick();
261 
262   /* Wait for Command FIFO Empty */
263   while ((hdsi->Instance->GPSR & DSI_GPSR_CMDFE) == 0U)
264   {
265     /* Check for the Timeout */
266     if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
267     {
268       return HAL_TIMEOUT;
269     }
270   }
271 
272   /* Configure the packet to send a short DCS command with 0 or 1 parameter */
273   /* Update the DSI packet header with new information */
274   hdsi->Instance->GHCR = (Mode | (ChannelID << 6U) | (Param1 << 8U) | (Param2 << 16U));
275 
276   return HAL_OK;
277 }
278 
279 /**
280   * @brief  Configure Band Control Frequency and LPX Offset
281   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
282   *               the configuration information for the DSI.
283   * @retval None
284   */
DSI_ConfigBandControl(DSI_HandleTypeDef * hdsi)285 static void DSI_ConfigBandControl(DSI_HandleTypeDef *hdsi)
286 {
287 
288   /* Set Band Control Frequency for clock lane */
289   hdsi->Instance->DPCBCR &= ~DSI_DPCBCR;
290   hdsi->Instance->DPCBCR |= (hdsi->Init.PHYFrequencyRange << DSI_DPCBCR_Pos);
291 
292   /* Set the slew rate for clock lane */
293   hdsi->Instance->DPCSRCR = DSI_DPHY_SLEW_HS_TX_SPEED;
294 
295   /* Set Band Control Frequency for Data Lane0 */
296   hdsi->Instance->DPDL0BCR &= ~DSI_DPDL0BCR;
297   hdsi->Instance->DPDL0BCR = (hdsi->Init.PHYFrequencyRange << DSI_DPDL0BCR_Pos);
298 
299   /* Set the slew rate for data Lane0 */
300   hdsi->Instance->DPDL0SRCR = DSI_DPHY_SLEW_HS_TX_SPEED;
301 
302   /* Set Band Control Frequency for Data Lane1 */
303   hdsi->Instance->DPDL1BCR &= ~DSI_DPDL1BCR;
304   hdsi->Instance->DPDL1BCR = (hdsi->Init.PHYFrequencyRange << DSI_DPDL1BCR_Pos);
305 
306   /* Set Slew rate for data Lane1 */
307   hdsi->Instance->DPDL1SRCR = DSI_DPHY_SLEW_HS_TX_SPEED;
308 
309   /* Set HS prepare offset for data lanes */
310   hdsi->Instance->DPDL0HSOCR &= ~DSI_DPDL0HSOCR;
311   hdsi->Instance->DPDL1HSOCR &= ~DSI_DPDL1HSOCR;
312 
313   if ((hdsi->Init.PHYFrequencyRange == DSI_DPHY_FRANGE_100MHZ_120MHZ) || \
314       (hdsi->Init.PHYFrequencyRange == DSI_DPHY_FRANGE_120MHZ_160MHZ) || \
315       (hdsi->Init.PHYFrequencyRange == DSI_DPHY_FRANGE_240MHZ_320MHZ))
316   {
317     hdsi->Instance->DPDL0HSOCR = (DSI_HS_PREPARE_OFFSET0 << DSI_DPDL0HSOCR_Pos);
318     hdsi->Instance->DPDL1HSOCR = (DSI_HS_PREPARE_OFFSET0 << DSI_DPDL1HSOCR_Pos);
319   }
320   else if ((hdsi->Init.PHYFrequencyRange == DSI_DPHY_FRANGE_80MHZ_100MHZ)  || \
321            (hdsi->Init.PHYFrequencyRange == DSI_DPHY_FRANGE_160MHZ_200MHZ) || \
322            (hdsi->Init.PHYFrequencyRange == DSI_DPHY_FRANGE_200MHZ_240MHZ) || \
323            (hdsi->Init.PHYFrequencyRange == DSI_DPHY_FRANGE_320MHZ_390MHZ))
324   {
325     hdsi->Instance->DPDL0HSOCR = (DSI_HS_PREPARE_OFFSET1 << DSI_DPDL0HSOCR_Pos);
326     hdsi->Instance->DPDL1HSOCR = (DSI_HS_PREPARE_OFFSET1 << DSI_DPDL1HSOCR_Pos);
327   }
328   else if ((hdsi->Init.PHYFrequencyRange == DSI_DPHY_FRANGE_390MHZ_450MHZ) || \
329            (hdsi->Init.PHYFrequencyRange == DSI_DPHY_FRANGE_450MHZ_510MHZ))
330   {
331     hdsi->Instance->DPDL0HSOCR = (DSI_HS_PREPARE_OFFSET2 << DSI_DPDL0HSOCR_Pos);
332     hdsi->Instance->DPDL1HSOCR = (DSI_HS_PREPARE_OFFSET2 << DSI_DPDL1HSOCR_Pos);
333   }
334   else
335   {
336     /* Nothing to do */
337   }
338 
339   /* Set LPXO value for data lanes */
340   hdsi->Instance->DPDL0LPXOCR &= ~DSI_DPDL0LPXOCR;
341   hdsi->Instance->DPDL1LPXOCR &= ~DSI_DPDL1LPXOCR;
342 
343   hdsi->Instance->DPDL0LPXOCR = hdsi->Init.PHYLowPowerOffset;
344   hdsi->Instance->DPDL1LPXOCR = hdsi->Init.PHYLowPowerOffset;
345 
346 }
347 
348 /**
349   * @brief  Set Wrapper PLL Tuning and Charge Pump
350   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
351   *               the configuration information for the DSI.
352   * @param  PLLInit  pointer to a DSI_PLLInitTypeDef structure that contains
353   *                  the PLL Clock structure definition for the DSI.
354   * @retval HAL status
355   */
DSI_SetWrapperPLLTuning(DSI_HandleTypeDef * hdsi,DSI_PLLInitTypeDef * PLLInit)356 static void DSI_SetWrapperPLLTuning(DSI_HandleTypeDef *hdsi, DSI_PLLInitTypeDef *PLLInit)
357 {
358   /* Set the VCO Frequency */
359   hdsi->Instance->WRPCR &= ~(DSI_WRPCR_BC);
360   hdsi->Instance->WRPCR |= (PLLInit->PLLVCORange << DSI_WRPCR_BC_Pos);
361 
362   hdsi->Instance->WPTR &= ~(DSI_WPTR_LPF | DSI_WPTR_CP);
363 
364   /* Set PLL Tuning */
365   hdsi->Instance->WPTR |= (PLLInit->PLLTuning << DSI_WPTR_LPF_Pos);
366 
367   /* Set PLL_Charge Value */
368   hdsi->Instance->WPTR |= (PLLInit->PLLChargePump << DSI_WPTR_CP_Pos);
369 
370 }
371 /**
372   * @}
373   */
374 
375 /* Exported functions --------------------------------------------------------*/
376 /** @addtogroup DSI_Exported_Functions
377   * @{
378   */
379 
380 /** @defgroup DSI_Group1 Initialization and Configuration functions
381   *  @brief   Initialization and Configuration functions
382   *
383 @verbatim
384  ===============================================================================
385                 ##### Initialization and Configuration functions #####
386  ===============================================================================
387     [..]  This section provides functions allowing to:
388       (+) Initialize and configure the DSI
389       (+) De-initialize the DSI
390 
391 @endverbatim
392   * @{
393   */
394 
395 /**
396   * @brief  Initializes the DSI according to the specified
397   *         parameters in the DSI_InitTypeDef and create the associated handle.
398   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
399   *               the configuration information for the DSI.
400   * @param  PLLInit  pointer to a DSI_PLLInitTypeDef structure that contains
401   *                  the PLL Clock structure definition for the DSI.
402   * @retval HAL status
403   */
HAL_DSI_Init(DSI_HandleTypeDef * hdsi,DSI_PLLInitTypeDef * PLLInit)404 HAL_StatusTypeDef HAL_DSI_Init(DSI_HandleTypeDef *hdsi, DSI_PLLInitTypeDef *PLLInit)
405 {
406   uint32_t tickstart;
407 
408   /* Check the DSI handle allocation */
409   if (hdsi == NULL)
410   {
411     return HAL_ERROR;
412   }
413 
414   /* Check function parameters */
415   assert_param(IS_DSI_PLL_NDIV(PLLInit->PLLNDIV));
416   assert_param(IS_DSI_PLL_IDF(PLLInit->PLLIDF));
417   assert_param(IS_DSI_PLL_ODF(PLLInit->PLLODF));
418   assert_param(IS_DSI_AUTO_CLKLANE_CONTROL(hdsi->Init.AutomaticClockLaneControl));
419   assert_param(IS_DSI_NUMBER_OF_LANES(hdsi->Init.NumberOfLanes));
420   assert_param(IS_DSI_DPHY_BAND_CTL_FRANGE(hdsi->Init.PHYFrequencyRange));
421   assert_param(IS_DSI_DPHY_LOW_POWER_OFFSET(hdsi->Init.PHYLowPowerOffset));
422   assert_param(IS_DSI_DPHY_VCO_FREQUENCY_RANGE(PLLInit->PLLVCORange));
423   assert_param(IS_DSI_PLL_TUNING(PLLInit->PLLTuning));
424   assert_param(IS_DSI_PLL_CHARGEPUMP(PLLInit->PLLChargePump));
425 
426 #if (USE_HAL_DSI_REGISTER_CALLBACKS == 1)
427   if (hdsi->State == HAL_DSI_STATE_RESET)
428   {
429     /* Reset the DSI callback to the legacy weak callbacks */
430     hdsi->TearingEffectCallback = HAL_DSI_TearingEffectCallback; /* Legacy weak TearingEffectCallback */
431     hdsi->EndOfRefreshCallback  = HAL_DSI_EndOfRefreshCallback;  /* Legacy weak EndOfRefreshCallback  */
432     hdsi->ErrorCallback         = HAL_DSI_ErrorCallback;         /* Legacy weak ErrorCallback         */
433 
434     if (hdsi->MspInitCallback == NULL)
435     {
436       hdsi->MspInitCallback = HAL_DSI_MspInit;
437     }
438     /* Initialize the low level hardware */
439     hdsi->MspInitCallback(hdsi);
440   }
441 #else
442   if (hdsi->State == HAL_DSI_STATE_RESET)
443   {
444     /* Initialize the low level hardware */
445     HAL_DSI_MspInit(hdsi);
446   }
447 #endif /* USE_HAL_DSI_REGISTER_CALLBACKS */
448 
449   /* Change DSI peripheral state */
450   hdsi->State = HAL_DSI_STATE_BUSY;
451 
452   /**************** Turn on the Reference Bias and enable the DSI PLL ****************/
453   /* bias power up */
454   hdsi->Instance->BCFGR |= DSI_BCFGR_PWRUP;
455 
456   /* Requires min of 2ms delay, 2ms delay is inserted */
457   HAL_Delay(2);
458 
459 
460   /* Set the PLL division factors */
461   hdsi->Instance->WRPCR &= ~(DSI_WRPCR_PLL_NDIV | DSI_WRPCR_PLL_IDF | DSI_WRPCR_PLL_ODF);
462   hdsi->Instance->WRPCR |= (((PLLInit->PLLNDIV) << DSI_WRPCR_PLL_NDIV_Pos) | \
463                             ((PLLInit->PLLIDF) << DSI_WRPCR_PLL_IDF_Pos) | \
464                             ((PLLInit->PLLODF) << DSI_WRPCR_PLL_ODF_Pos));
465 
466   /************************ Set D-PHY Band Control registers ******************************/
467   /* Set Band Control Frequency and LPX Offset */
468   DSI_ConfigBandControl(hdsi);
469 
470   /* Set PLL Tuning */
471   DSI_SetWrapperPLLTuning(hdsi, PLLInit);
472 
473   /* Enable the DSI PLL */
474   __HAL_DSI_PLL_ENABLE(hdsi);
475 
476   /* Requires min of 400us delay before reading the PLLLS flag */
477   /* 1ms delay is inserted that is the minimum HAL delay granularity */
478   HAL_Delay(1);
479 
480   /* Get tick */
481   tickstart = HAL_GetTick();
482 
483   /* Wait for the lock of the PLL */
484   while (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U)
485   {
486     /* Check for the Timeout */
487     if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
488     {
489       return HAL_TIMEOUT;
490     }
491   }
492 
493   /*************************** Set the PHY parameters ***************************/
494 
495   /* D-PHY clock and digital enable*/
496   hdsi->Instance->PCTLR |= (DSI_PCTLR_CKE | DSI_PCTLR_DEN);
497 
498   /* Clock lane configuration */
499   hdsi->Instance->CLCR &= ~(DSI_CLCR_DPCC | DSI_CLCR_ACR);
500   hdsi->Instance->CLCR |= (DSI_CLCR_DPCC | hdsi->Init.AutomaticClockLaneControl);
501 
502   /* Configure the number of active data lanes */
503   hdsi->Instance->PCONFR &= ~DSI_PCONFR_NL;
504   hdsi->Instance->PCONFR |= hdsi->Init.NumberOfLanes;
505 
506   /************************ Set the DSI clock parameters ************************/
507 
508   /* Set the TX escape clock division factor */
509   hdsi->Instance->CCR &= ~DSI_CCR_TXECKDIV;
510   hdsi->Instance->CCR |= hdsi->Init.TXEscapeCkdiv;
511 
512 
513   /****************************** Error management *****************************/
514 
515   /* Disable all error interrupts and reset the Error Mask */
516   hdsi->Instance->IER[0U] = 0U;
517   hdsi->Instance->IER[1U] = 0U;
518   hdsi->ErrorMsk = 0U;
519 
520   /* Initialize the error code */
521   hdsi->ErrorCode = HAL_DSI_ERROR_NONE;
522 
523   /* Initialize the DSI state*/
524   hdsi->State = HAL_DSI_STATE_READY;
525 
526   return HAL_OK;
527 }
528 
529 /**
530   * @brief  De-initializes the DSI peripheral registers to their default reset
531   *         values.
532   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
533   *               the configuration information for the DSI.
534   * @retval HAL status
535   */
HAL_DSI_DeInit(DSI_HandleTypeDef * hdsi)536 HAL_StatusTypeDef HAL_DSI_DeInit(DSI_HandleTypeDef *hdsi)
537 {
538   /* Check the DSI handle allocation */
539   if (hdsi == NULL)
540   {
541     return HAL_ERROR;
542   }
543 
544   /* Change DSI peripheral state */
545   hdsi->State = HAL_DSI_STATE_BUSY;
546 
547   /* Disable the DSI wrapper */
548   __HAL_DSI_WRAPPER_DISABLE(hdsi);
549 
550   /* Disable the DSI host */
551   __HAL_DSI_DISABLE(hdsi);
552 
553   /* D-PHY clock and digital disable */
554   hdsi->Instance->PCTLR &= ~(DSI_PCTLR_CKE | DSI_PCTLR_DEN);
555 
556   /* Turn off the DSI PLL */
557   __HAL_DSI_PLL_DISABLE(hdsi);
558 
559   /* Disable the reference bias */
560   hdsi->Instance->BCFGR &= ~DSI_BCFGR_PWRUP;
561 
562 #if (USE_HAL_DSI_REGISTER_CALLBACKS == 1)
563   if (hdsi->MspDeInitCallback == NULL)
564   {
565     hdsi->MspDeInitCallback = HAL_DSI_MspDeInit;
566   }
567   /* DeInit the low level hardware */
568   hdsi->MspDeInitCallback(hdsi);
569 #else
570   /* DeInit the low level hardware */
571   HAL_DSI_MspDeInit(hdsi);
572 #endif /* USE_HAL_DSI_REGISTER_CALLBACKS */
573 
574   /* Initialize the error code */
575   hdsi->ErrorCode = HAL_DSI_ERROR_NONE;
576 
577   /* Initialize the DSI state*/
578   hdsi->State = HAL_DSI_STATE_RESET;
579 
580   /* Release Lock */
581   __HAL_UNLOCK(hdsi);
582 
583   return HAL_OK;
584 }
585 
586 /**
587   * @brief  Enable the error monitor flags
588   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
589   *               the configuration information for the DSI.
590   * @param  ActiveErrors  indicates which error interrupts will be enabled.
591   *                      This parameter can be any combination of @arg DSI_Error_Data_Type.
592   * @retval HAL status
593   */
HAL_DSI_ConfigErrorMonitor(DSI_HandleTypeDef * hdsi,uint32_t ActiveErrors)594 HAL_StatusTypeDef HAL_DSI_ConfigErrorMonitor(DSI_HandleTypeDef *hdsi, uint32_t ActiveErrors)
595 {
596   /* Process locked */
597   __HAL_LOCK(hdsi);
598 
599   hdsi->Instance->IER[0U] = 0U;
600   hdsi->Instance->IER[1U] = 0U;
601 
602   /* Store active errors to the handle */
603   hdsi->ErrorMsk = ActiveErrors;
604 
605   if ((ActiveErrors & HAL_DSI_ERROR_ACK) != 0U)
606   {
607     /* Enable the interrupt generation on selected errors */
608     hdsi->Instance->IER[0U] |= DSI_ERROR_ACK_MASK;
609   }
610 
611   if ((ActiveErrors & HAL_DSI_ERROR_PHY) != 0U)
612   {
613     /* Enable the interrupt generation on selected errors */
614     hdsi->Instance->IER[0U] |= DSI_ERROR_PHY_MASK;
615   }
616 
617   if ((ActiveErrors & HAL_DSI_ERROR_TX) != 0U)
618   {
619     /* Enable the interrupt generation on selected errors */
620     hdsi->Instance->IER[1U] |= DSI_ERROR_TX_MASK;
621   }
622 
623   if ((ActiveErrors & HAL_DSI_ERROR_RX) != 0U)
624   {
625     /* Enable the interrupt generation on selected errors */
626     hdsi->Instance->IER[1U] |= DSI_ERROR_RX_MASK;
627   }
628 
629   if ((ActiveErrors & HAL_DSI_ERROR_ECC) != 0U)
630   {
631     /* Enable the interrupt generation on selected errors */
632     hdsi->Instance->IER[1U] |= DSI_ERROR_ECC_MASK;
633   }
634 
635   if ((ActiveErrors & HAL_DSI_ERROR_CRC) != 0U)
636   {
637     /* Enable the interrupt generation on selected errors */
638     hdsi->Instance->IER[1U] |= DSI_ERROR_CRC_MASK;
639   }
640 
641   if ((ActiveErrors & HAL_DSI_ERROR_PSE) != 0U)
642   {
643     /* Enable the interrupt generation on selected errors */
644     hdsi->Instance->IER[1U] |= DSI_ERROR_PSE_MASK;
645   }
646 
647   if ((ActiveErrors & HAL_DSI_ERROR_EOT) != 0U)
648   {
649     /* Enable the interrupt generation on selected errors */
650     hdsi->Instance->IER[1U] |= DSI_ERROR_EOT_MASK;
651   }
652 
653   if ((ActiveErrors & HAL_DSI_ERROR_OVF) != 0U)
654   {
655     /* Enable the interrupt generation on selected errors */
656     hdsi->Instance->IER[1U] |= DSI_ERROR_OVF_MASK;
657   }
658 
659   if ((ActiveErrors & HAL_DSI_ERROR_GEN) != 0U)
660   {
661     /* Enable the interrupt generation on selected errors */
662     hdsi->Instance->IER[1U] |= DSI_ERROR_GEN_MASK;
663   }
664 
665   if ((ActiveErrors & HAL_DSI_ERROR_PBU) != 0U)
666   {
667     /* Enable the interrupt generation on selected errors */
668     hdsi->Instance->IER[1U] |= DSI_ERROR_PBU_MASK;
669   }
670   /* Process Unlocked */
671   __HAL_UNLOCK(hdsi);
672 
673   return HAL_OK;
674 }
675 
676 /**
677   * @brief  Initializes the DSI MSP.
678   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
679   *               the configuration information for the DSI.
680   * @retval None
681   */
HAL_DSI_MspInit(DSI_HandleTypeDef * hdsi)682 __weak void HAL_DSI_MspInit(DSI_HandleTypeDef *hdsi)
683 {
684   /* Prevent unused argument(s) compilation warning */
685   UNUSED(hdsi);
686   /* NOTE : This function Should not be modified, when the callback is needed,
687             the HAL_DSI_MspInit could be implemented in the user file
688    */
689 }
690 
691 /**
692   * @brief  De-initializes the DSI MSP.
693   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
694   *               the configuration information for the DSI.
695   * @retval None
696   */
HAL_DSI_MspDeInit(DSI_HandleTypeDef * hdsi)697 __weak void HAL_DSI_MspDeInit(DSI_HandleTypeDef *hdsi)
698 {
699   /* Prevent unused argument(s) compilation warning */
700   UNUSED(hdsi);
701   /* NOTE : This function Should not be modified, when the callback is needed,
702             the HAL_DSI_MspDeInit could be implemented in the user file
703    */
704 }
705 
706 #if (USE_HAL_DSI_REGISTER_CALLBACKS == 1)
707 /**
708   * @brief  Register a User DSI Callback
709   *         To be used instead of the weak predefined callback
710   * @param hdsi dsi handle
711   * @param CallbackID ID of the callback to be registered
712   *        This parameter can be one of the following values:
713   *          @arg HAL_DSI_TEARING_EFFECT_CB_ID Tearing Effect Callback ID
714   *          @arg HAL_DSI_ENDOF_REFRESH_CB_ID End Of Refresh Callback ID
715   *          @arg HAL_DSI_ERROR_CB_ID Error Callback ID
716   *          @arg HAL_DSI_MSPINIT_CB_ID MspInit callback ID
717   *          @arg HAL_DSI_MSPDEINIT_CB_ID MspDeInit callback ID
718   * @param pCallback pointer to the Callback function
719   * @retval status
720   */
HAL_DSI_RegisterCallback(DSI_HandleTypeDef * hdsi,HAL_DSI_CallbackIDTypeDef CallbackID,pDSI_CallbackTypeDef pCallback)721 HAL_StatusTypeDef HAL_DSI_RegisterCallback(DSI_HandleTypeDef *hdsi, HAL_DSI_CallbackIDTypeDef CallbackID,
722                                            pDSI_CallbackTypeDef pCallback)
723 {
724   HAL_StatusTypeDef status = HAL_OK;
725 
726   if (pCallback == NULL)
727   {
728     /* Update the error code */
729     hdsi->ErrorCode |= HAL_DSI_ERROR_INVALID_CALLBACK;
730 
731     return HAL_ERROR;
732   }
733   /* Process locked */
734   __HAL_LOCK(hdsi);
735 
736   if (hdsi->State == HAL_DSI_STATE_READY)
737   {
738     switch (CallbackID)
739     {
740       case HAL_DSI_TEARING_EFFECT_CB_ID :
741         hdsi->TearingEffectCallback = pCallback;
742         break;
743 
744       case HAL_DSI_ENDOF_REFRESH_CB_ID :
745         hdsi->EndOfRefreshCallback = pCallback;
746         break;
747 
748       case HAL_DSI_ERROR_CB_ID :
749         hdsi->ErrorCallback = pCallback;
750         break;
751 
752       case HAL_DSI_MSPINIT_CB_ID :
753         hdsi->MspInitCallback = pCallback;
754         break;
755 
756       case HAL_DSI_MSPDEINIT_CB_ID :
757         hdsi->MspDeInitCallback = pCallback;
758         break;
759 
760       default :
761         /* Update the error code */
762         hdsi->ErrorCode |= HAL_DSI_ERROR_INVALID_CALLBACK;
763         /* Return error status */
764         status =  HAL_ERROR;
765         break;
766     }
767   }
768   else if (hdsi->State == HAL_DSI_STATE_RESET)
769   {
770     switch (CallbackID)
771     {
772       case HAL_DSI_MSPINIT_CB_ID :
773         hdsi->MspInitCallback = pCallback;
774         break;
775 
776       case HAL_DSI_MSPDEINIT_CB_ID :
777         hdsi->MspDeInitCallback = pCallback;
778         break;
779 
780       default :
781         /* Update the error code */
782         hdsi->ErrorCode |= HAL_DSI_ERROR_INVALID_CALLBACK;
783         /* Return error status */
784         status =  HAL_ERROR;
785         break;
786     }
787   }
788   else
789   {
790     /* Update the error code */
791     hdsi->ErrorCode |= HAL_DSI_ERROR_INVALID_CALLBACK;
792     /* Return error status */
793     status =  HAL_ERROR;
794   }
795 
796   /* Release Lock */
797   __HAL_UNLOCK(hdsi);
798 
799   return status;
800 }
801 
802 /**
803   * @brief  Unregister a DSI Callback
804   *         DSI callback is redirected to the weak predefined callback
805   * @param hdsi dsi handle
806   * @param CallbackID ID of the callback to be unregistered
807   *        This parameter can be one of the following values:
808   *          @arg HAL_DSI_TEARING_EFFECT_CB_ID Tearing Effect Callback ID
809   *          @arg HAL_DSI_ENDOF_REFRESH_CB_ID End Of Refresh Callback ID
810   *          @arg HAL_DSI_ERROR_CB_ID Error Callback ID
811   *          @arg HAL_DSI_MSPINIT_CB_ID MspInit callback ID
812   *          @arg HAL_DSI_MSPDEINIT_CB_ID MspDeInit callback ID
813   * @retval status
814   */
HAL_DSI_UnRegisterCallback(DSI_HandleTypeDef * hdsi,HAL_DSI_CallbackIDTypeDef CallbackID)815 HAL_StatusTypeDef HAL_DSI_UnRegisterCallback(DSI_HandleTypeDef *hdsi, HAL_DSI_CallbackIDTypeDef CallbackID)
816 {
817   HAL_StatusTypeDef status = HAL_OK;
818 
819   /* Process locked */
820   __HAL_LOCK(hdsi);
821 
822   if (hdsi->State == HAL_DSI_STATE_READY)
823   {
824     switch (CallbackID)
825     {
826       case HAL_DSI_TEARING_EFFECT_CB_ID :
827         hdsi->TearingEffectCallback = HAL_DSI_TearingEffectCallback; /* Legacy weak TearingEffectCallback */
828         break;
829 
830       case HAL_DSI_ENDOF_REFRESH_CB_ID :
831         hdsi->EndOfRefreshCallback = HAL_DSI_EndOfRefreshCallback;   /* Legacy weak EndOfRefreshCallback  */
832         break;
833 
834       case HAL_DSI_ERROR_CB_ID :
835         hdsi->ErrorCallback        = HAL_DSI_ErrorCallback;          /* Legacy weak ErrorCallback        */
836         break;
837 
838       case HAL_DSI_MSPINIT_CB_ID :
839         hdsi->MspInitCallback = HAL_DSI_MspInit;                     /* Legacy weak MspInit Callback     */
840         break;
841 
842       case HAL_DSI_MSPDEINIT_CB_ID :
843         hdsi->MspDeInitCallback = HAL_DSI_MspDeInit;                 /* Legacy weak MspDeInit Callback   */
844         break;
845 
846       default :
847         /* Update the error code */
848         hdsi->ErrorCode |= HAL_DSI_ERROR_INVALID_CALLBACK;
849         /* Return error status */
850         status =  HAL_ERROR;
851         break;
852     }
853   }
854   else if (hdsi->State == HAL_DSI_STATE_RESET)
855   {
856     switch (CallbackID)
857     {
858       case HAL_DSI_MSPINIT_CB_ID :
859         hdsi->MspInitCallback = HAL_DSI_MspInit;                  /* Legacy weak MspInit Callback   */
860         break;
861 
862       case HAL_DSI_MSPDEINIT_CB_ID :
863         hdsi->MspDeInitCallback = HAL_DSI_MspDeInit;              /* Legacy weak MspDeInit Callback */
864         break;
865 
866       default :
867         /* Update the error code */
868         hdsi->ErrorCode |= HAL_DSI_ERROR_INVALID_CALLBACK;
869         /* Return error status */
870         status =  HAL_ERROR;
871         break;
872     }
873   }
874   else
875   {
876     /* Update the error code */
877     hdsi->ErrorCode |= HAL_DSI_ERROR_INVALID_CALLBACK;
878     /* Return error status */
879     status =  HAL_ERROR;
880   }
881 
882   /* Release Lock */
883   __HAL_UNLOCK(hdsi);
884 
885   return status;
886 }
887 #endif /* USE_HAL_DSI_REGISTER_CALLBACKS */
888 
889 /**
890   * @}
891   */
892 
893 /** @defgroup DSI_Group2 IO operation functions
894   *  @brief    IO operation functions
895   *
896 @verbatim
897  ===============================================================================
898                       #####  IO operation functions  #####
899  ===============================================================================
900     [..]  This section provides function allowing to:
901       (+) Handle DSI interrupt request
902 
903 @endverbatim
904   * @{
905   */
906 /**
907   * @brief  Handles DSI interrupt request.
908   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
909   *               the configuration information for the DSI.
910   * @retval HAL status
911   */
HAL_DSI_IRQHandler(DSI_HandleTypeDef * hdsi)912 void HAL_DSI_IRQHandler(DSI_HandleTypeDef *hdsi)
913 {
914   uint32_t ErrorStatus0;
915   uint32_t ErrorStatus1;
916 
917   /* Tearing Effect Interrupt management ***************************************/
918   if (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_TE) != 0U)
919   {
920     if (__HAL_DSI_GET_IT_SOURCE(hdsi, DSI_IT_TE) != 0U)
921     {
922       /* Clear the Tearing Effect Interrupt Flag */
923       __HAL_DSI_CLEAR_FLAG(hdsi, DSI_FLAG_TE);
924 
925       /* Tearing Effect Callback */
926 #if (USE_HAL_DSI_REGISTER_CALLBACKS == 1)
927       /*Call registered Tearing Effect callback */
928       hdsi->TearingEffectCallback(hdsi);
929 #else
930       /*Call legacy Tearing Effect callback*/
931       HAL_DSI_TearingEffectCallback(hdsi);
932 #endif /* USE_HAL_DSI_REGISTER_CALLBACKS */
933     }
934   }
935 
936   /* End of Refresh Interrupt management ***************************************/
937   if (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_ER) != 0U)
938   {
939     if (__HAL_DSI_GET_IT_SOURCE(hdsi, DSI_IT_ER) != 0U)
940     {
941       /* Clear the End of Refresh Interrupt Flag */
942       __HAL_DSI_CLEAR_FLAG(hdsi, DSI_FLAG_ER);
943 
944       /* End of Refresh Callback */
945 #if (USE_HAL_DSI_REGISTER_CALLBACKS == 1)
946       /*Call registered End of refresh callback */
947       hdsi->EndOfRefreshCallback(hdsi);
948 #else
949       /*Call Legacy End of refresh callback */
950       HAL_DSI_EndOfRefreshCallback(hdsi);
951 #endif /* USE_HAL_DSI_REGISTER_CALLBACKS */
952     }
953   }
954 
955   /* Error Interrupts management ***********************************************/
956   if (hdsi->ErrorMsk != 0U)
957   {
958     ErrorStatus0 = hdsi->Instance->ISR[0U];
959     ErrorStatus0 &= hdsi->Instance->IER[0U];
960     ErrorStatus1 = hdsi->Instance->ISR[1U];
961     ErrorStatus1 &= hdsi->Instance->IER[1U];
962 
963     if ((ErrorStatus0 & DSI_ERROR_ACK_MASK) != 0U)
964     {
965       hdsi->ErrorCode |= HAL_DSI_ERROR_ACK;
966     }
967 
968     if ((ErrorStatus0 & DSI_ERROR_PHY_MASK) != 0U)
969     {
970       hdsi->ErrorCode |= HAL_DSI_ERROR_PHY;
971     }
972 
973     if ((ErrorStatus1 & DSI_ERROR_TX_MASK) != 0U)
974     {
975       hdsi->ErrorCode |= HAL_DSI_ERROR_TX;
976     }
977 
978     if ((ErrorStatus1 & DSI_ERROR_RX_MASK) != 0U)
979     {
980       hdsi->ErrorCode |= HAL_DSI_ERROR_RX;
981     }
982 
983     if ((ErrorStatus1 & DSI_ERROR_ECC_MASK) != 0U)
984     {
985       hdsi->ErrorCode |= HAL_DSI_ERROR_ECC;
986     }
987 
988     if ((ErrorStatus1 & DSI_ERROR_CRC_MASK) != 0U)
989     {
990       hdsi->ErrorCode |= HAL_DSI_ERROR_CRC;
991     }
992 
993     if ((ErrorStatus1 & DSI_ERROR_PSE_MASK) != 0U)
994     {
995       hdsi->ErrorCode |= HAL_DSI_ERROR_PSE;
996     }
997 
998     if ((ErrorStatus1 & DSI_ERROR_EOT_MASK) != 0U)
999     {
1000       hdsi->ErrorCode |= HAL_DSI_ERROR_EOT;
1001     }
1002 
1003     if ((ErrorStatus1 & DSI_ERROR_OVF_MASK) != 0U)
1004     {
1005       hdsi->ErrorCode |= HAL_DSI_ERROR_OVF;
1006     }
1007 
1008     if ((ErrorStatus1 & DSI_ERROR_GEN_MASK) != 0U)
1009     {
1010       hdsi->ErrorCode |= HAL_DSI_ERROR_GEN;
1011     }
1012 
1013     if ((ErrorStatus1 & DSI_ERROR_PBU_MASK) != 0U)
1014     {
1015       hdsi->ErrorCode |= HAL_DSI_ERROR_PBU;
1016     }
1017     /* Check only selected errors */
1018     if (hdsi->ErrorCode != HAL_DSI_ERROR_NONE)
1019     {
1020       /* DSI error interrupt callback */
1021 #if (USE_HAL_DSI_REGISTER_CALLBACKS == 1)
1022       /*Call registered Error callback */
1023       hdsi->ErrorCallback(hdsi);
1024 #else
1025       /*Call Legacy Error callback */
1026       HAL_DSI_ErrorCallback(hdsi);
1027 #endif /* USE_HAL_DSI_REGISTER_CALLBACKS */
1028     }
1029   }
1030 }
1031 
1032 /**
1033   * @brief  Tearing Effect DSI callback.
1034   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1035   *               the configuration information for the DSI.
1036   * @retval None
1037   */
HAL_DSI_TearingEffectCallback(DSI_HandleTypeDef * hdsi)1038 __weak void HAL_DSI_TearingEffectCallback(DSI_HandleTypeDef *hdsi)
1039 {
1040   /* Prevent unused argument(s) compilation warning */
1041   UNUSED(hdsi);
1042   /* NOTE : This function Should not be modified, when the callback is needed,
1043             the HAL_DSI_TearingEffectCallback could be implemented in the user file
1044    */
1045 }
1046 
1047 /**
1048   * @brief  End of Refresh DSI callback.
1049   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1050   *               the configuration information for the DSI.
1051   * @retval None
1052   */
HAL_DSI_EndOfRefreshCallback(DSI_HandleTypeDef * hdsi)1053 __weak void HAL_DSI_EndOfRefreshCallback(DSI_HandleTypeDef *hdsi)
1054 {
1055   /* Prevent unused argument(s) compilation warning */
1056   UNUSED(hdsi);
1057   /* NOTE : This function Should not be modified, when the callback is needed,
1058             the HAL_DSI_EndOfRefreshCallback could be implemented in the user file
1059    */
1060 }
1061 
1062 /**
1063   * @brief  Operation Error DSI callback.
1064   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1065   *               the configuration information for the DSI.
1066   * @retval None
1067   */
HAL_DSI_ErrorCallback(DSI_HandleTypeDef * hdsi)1068 __weak void HAL_DSI_ErrorCallback(DSI_HandleTypeDef *hdsi)
1069 {
1070   /* Prevent unused argument(s) compilation warning */
1071   UNUSED(hdsi);
1072   /* NOTE : This function Should not be modified, when the callback is needed,
1073             the HAL_DSI_ErrorCallback could be implemented in the user file
1074    */
1075 }
1076 
1077 /**
1078   * @}
1079   */
1080 
1081 /** @defgroup DSI_Group3 Peripheral Control functions
1082   *  @brief    Peripheral Control functions
1083   *
1084 @verbatim
1085  ===============================================================================
1086                     ##### Peripheral Control functions #####
1087  ===============================================================================
1088     [..]  This section provides functions allowing to:
1089       (+) Configure the Generic interface read-back Virtual Channel ID
1090       (+) Select video mode and configure the corresponding parameters
1091       (+) Configure command transmission mode: High-speed or Low-power
1092       (+) Configure the flow control
1093       (+) Configure the DSI PHY timer
1094       (+) Configure the DSI HOST timeout
1095       (+) Configure the DSI HOST timeout
1096       (+) Start/Stop the DSI module
1097       (+) Refresh the display in command mode
1098       (+) Controls the display color mode in Video mode
1099       (+) Control the display shutdown in Video mode
1100       (+) write short DCS or short Generic command
1101       (+) write long DCS or long Generic command
1102       (+) Read command (DCS or generic)
1103       (+) Enter/Exit the Ultra Low Power Mode on data only (D-PHY PLL running)
1104       (+) Enter/Exit the Ultra Low Power Mode on data only and clock (D-PHY PLL turned off)
1105       (+) Start/Stop test pattern generation
1106       (+) Slew-Rate And Delay Tuning
1107       (+) Low-Power Reception Filter Tuning
1108       (+) Activate an additional current path on all lanes to meet the SDDTx parameter
1109       (+) Custom lane pins configuration
1110       (+) Set custom timing for the PHY
1111       (+) Force the Clock/Data Lane in TX Stop Mode
1112       (+) Force LP Receiver in Low-Power Mode
1113       (+) Force Data Lanes in RX Mode after a BTA
1114       (+) Enable a pull-down on the lanes to prevent from floating states when unused
1115       (+) Switch off the contention detection on data lanes
1116 
1117 @endverbatim
1118   * @{
1119   */
1120 
1121 /**
1122   * @brief  Configure the Generic interface read-back Virtual Channel ID.
1123   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1124   *               the configuration information for the DSI.
1125   * @param  VirtualChannelIdRx  Virtual channel ID
1126   * @retval HAL status
1127   */
HAL_DSI_SetGenericVCIDRX(DSI_HandleTypeDef * hdsi,uint32_t VirtualChannelIdRx)1128 HAL_StatusTypeDef HAL_DSI_SetGenericVCIDRX(DSI_HandleTypeDef *hdsi, uint32_t VirtualChannelIdRx)
1129 {
1130   /* Process locked */
1131   __HAL_LOCK(hdsi);
1132 
1133   /* Update the GVCID register */
1134   hdsi->Instance->GVCIDR &= ~DSI_GVCIDR_VCIDRX;
1135   hdsi->Instance->GVCIDR |= VirtualChannelIdRx << DSI_GVCIDR_VCIDRX_Pos;
1136 
1137   /* Process unlocked */
1138   __HAL_UNLOCK(hdsi);
1139 
1140   return HAL_OK;
1141 }
1142 
1143 /**
1144   * @brief  Configure the Virtual channel ID for transmission.
1145   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1146   *               the configuration information for the DSI.
1147   * @param  VirtualChannelIdTx  Virtual channel ID
1148   * @retval HAL status
1149   */
HAL_DSI_SetGenericVCIDTX(DSI_HandleTypeDef * hdsi,uint32_t VirtualChannelIdTx)1150 HAL_StatusTypeDef HAL_DSI_SetGenericVCIDTX(DSI_HandleTypeDef *hdsi, uint32_t VirtualChannelIdTx)
1151 {
1152   /* Process locked */
1153   __HAL_LOCK(hdsi);
1154 
1155   /* Update the GVCID register */
1156   hdsi->Instance->GVCIDR &= ~DSI_GVCIDR_VCIDTX;
1157   hdsi->Instance->GVCIDR |= VirtualChannelIdTx << DSI_GVCIDR_VCIDTX_Pos;
1158 
1159   /* Process unlocked */
1160   __HAL_UNLOCK(hdsi);
1161 
1162   return HAL_OK;
1163 }
1164 /**
1165   * @brief  Configure the Generic interface read-back Virtual Channel ID.
1166   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1167   *               the configuration information for the DSI.
1168   * @param  VirtualChannelID  Virtual channel ID
1169   * @retval HAL status
1170   */
HAL_DSI_SetGenericVCID(DSI_HandleTypeDef * hdsi,uint32_t VirtualChannelID)1171 HAL_StatusTypeDef HAL_DSI_SetGenericVCID(DSI_HandleTypeDef *hdsi, uint32_t VirtualChannelID)
1172 {
1173   /* Process locked */
1174   __HAL_LOCK(hdsi);
1175 
1176   /* Update the GVCIDR register with the Tx and Rx Virtual channel ID */
1177   hdsi->Instance->GVCIDR &= ~(DSI_GVCIDR_VCIDRX | DSI_GVCIDR_VCIDTX);
1178   hdsi->Instance->GVCIDR |= ((VirtualChannelID << DSI_GVCIDR_VCIDRX_Pos) | \
1179                              (VirtualChannelID << DSI_GVCIDR_VCIDTX_Pos));
1180 
1181   /* Process unlocked */
1182   __HAL_UNLOCK(hdsi);
1183 
1184   return HAL_OK;
1185 }
1186 
1187 /**
1188   * @brief  Select video mode and configure the corresponding parameters
1189   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1190   *               the configuration information for the DSI.
1191   * @param  VidCfg pointer to a DSI_VidCfgTypeDef structure that contains
1192   *                the DSI video mode configuration parameters
1193   * @retval HAL status
1194   */
HAL_DSI_ConfigVideoMode(DSI_HandleTypeDef * hdsi,DSI_VidCfgTypeDef * VidCfg)1195 HAL_StatusTypeDef HAL_DSI_ConfigVideoMode(DSI_HandleTypeDef *hdsi, DSI_VidCfgTypeDef *VidCfg)
1196 {
1197   /* Process locked */
1198   __HAL_LOCK(hdsi);
1199 
1200   /* Check the parameters */
1201   assert_param(IS_DSI_COLOR_CODING(VidCfg->ColorCoding));
1202   assert_param(IS_DSI_VIDEO_MODE_TYPE(VidCfg->Mode));
1203   assert_param(IS_DSI_LP_COMMAND(VidCfg->LPCommandEnable));
1204   assert_param(IS_DSI_LP_HFP(VidCfg->LPHorizontalFrontPorchEnable));
1205   assert_param(IS_DSI_LP_HBP(VidCfg->LPHorizontalBackPorchEnable));
1206   assert_param(IS_DSI_LP_VACTIVE(VidCfg->LPVerticalActiveEnable));
1207   assert_param(IS_DSI_LP_VFP(VidCfg->LPVerticalFrontPorchEnable));
1208   assert_param(IS_DSI_LP_VBP(VidCfg->LPVerticalBackPorchEnable));
1209   assert_param(IS_DSI_LP_VSYNC(VidCfg->LPVerticalSyncActiveEnable));
1210   assert_param(IS_DSI_FBTAA(VidCfg->FrameBTAAcknowledgeEnable));
1211   assert_param(IS_DSI_DE_POLARITY(VidCfg->DEPolarity));
1212   assert_param(IS_DSI_VSYNC_POLARITY(VidCfg->VSPolarity));
1213   assert_param(IS_DSI_HSYNC_POLARITY(VidCfg->HSPolarity));
1214   /* Check the LooselyPacked variant only in 18-bit mode */
1215   if (VidCfg->ColorCoding == DSI_RGB666)
1216   {
1217     assert_param(IS_DSI_LOOSELY_PACKED(VidCfg->LooselyPacked));
1218   }
1219 
1220   /* Select video mode by resetting CMDM and DSIM bits */
1221   hdsi->Instance->MCR &= ~DSI_MCR_CMDM;
1222   hdsi->Instance->WCFGR &= ~DSI_WCFGR_DSIM;
1223 
1224   /* Configure the video mode transmission type */
1225   hdsi->Instance->VMCR &= ~DSI_VMCR_VMT;
1226   hdsi->Instance->VMCR |= VidCfg->Mode;
1227 
1228   /* Configure the video packet size */
1229   hdsi->Instance->VPCR &= ~DSI_VPCR_VPSIZE;
1230   hdsi->Instance->VPCR |= VidCfg->PacketSize;
1231 
1232   /* Set the chunks number to be transmitted through the DSI link */
1233   hdsi->Instance->VCCR &= ~DSI_VCCR_NUMC;
1234   hdsi->Instance->VCCR |= VidCfg->NumberOfChunks;
1235 
1236   /* Set the size of the null packet */
1237   hdsi->Instance->VNPCR &= ~DSI_VNPCR_NPSIZE;
1238   hdsi->Instance->VNPCR |= VidCfg->NullPacketSize;
1239 
1240   /* Select the virtual channel for the LTDC interface traffic */
1241   hdsi->Instance->LVCIDR &= ~DSI_LVCIDR_VCID;
1242   hdsi->Instance->LVCIDR |= VidCfg->VirtualChannelID;
1243 
1244   /* Configure the polarity of control signals */
1245   hdsi->Instance->LPCR &= ~(DSI_LPCR_DEP | DSI_LPCR_VSP | DSI_LPCR_HSP);
1246   hdsi->Instance->LPCR |= (VidCfg->DEPolarity | VidCfg->VSPolarity | VidCfg->HSPolarity);
1247 
1248   /* Select the color coding for the host */
1249   hdsi->Instance->LCOLCR &= ~DSI_LCOLCR_COLC;
1250   hdsi->Instance->LCOLCR |= VidCfg->ColorCoding;
1251 
1252   /* Select the color coding for the wrapper */
1253   hdsi->Instance->WCFGR &= ~DSI_WCFGR_COLMUX;
1254   hdsi->Instance->WCFGR |= ((VidCfg->ColorCoding) << 1U);
1255 
1256   /* Enable/disable the loosely packed variant to 18-bit configuration */
1257   if (VidCfg->ColorCoding == DSI_RGB666)
1258   {
1259     hdsi->Instance->LCOLCR &= ~DSI_LCOLCR_LPE;
1260     hdsi->Instance->LCOLCR |= VidCfg->LooselyPacked;
1261   }
1262 
1263   /* Set the Horizontal Synchronization Active (HSA) in lane byte clock cycles */
1264   hdsi->Instance->VHSACR &= ~DSI_VHSACR_HSA;
1265   hdsi->Instance->VHSACR |= VidCfg->HorizontalSyncActive;
1266 
1267   /* Set the Horizontal Back Porch (HBP) in lane byte clock cycles */
1268   hdsi->Instance->VHBPCR &= ~DSI_VHBPCR_HBP;
1269   hdsi->Instance->VHBPCR |= VidCfg->HorizontalBackPorch;
1270 
1271   /* Set the total line time (HLINE=HSA+HBP+HACT+HFP) in lane byte clock cycles */
1272   hdsi->Instance->VLCR &= ~DSI_VLCR_HLINE;
1273   hdsi->Instance->VLCR |= VidCfg->HorizontalLine;
1274 
1275   /* Set the Vertical Synchronization Active (VSA) */
1276   hdsi->Instance->VVSACR &= ~DSI_VVSACR_VSA;
1277   hdsi->Instance->VVSACR |= VidCfg->VerticalSyncActive;
1278 
1279   /* Set the Vertical Back Porch (VBP)*/
1280   hdsi->Instance->VVBPCR &= ~DSI_VVBPCR_VBP;
1281   hdsi->Instance->VVBPCR |= VidCfg->VerticalBackPorch;
1282 
1283   /* Set the Vertical Front Porch (VFP)*/
1284   hdsi->Instance->VVFPCR &= ~DSI_VVFPCR_VFP;
1285   hdsi->Instance->VVFPCR |= VidCfg->VerticalFrontPorch;
1286 
1287   /* Set the Vertical Active period*/
1288   hdsi->Instance->VVACR &= ~DSI_VVACR_VA;
1289   hdsi->Instance->VVACR |= VidCfg->VerticalActive;
1290 
1291   /* Configure the command transmission mode */
1292   hdsi->Instance->VMCR &= ~DSI_VMCR_LPCE;
1293   hdsi->Instance->VMCR |= VidCfg->LPCommandEnable;
1294 
1295   /* Low power largest packet size */
1296   hdsi->Instance->LPMCR &= ~DSI_LPMCR_LPSIZE;
1297   hdsi->Instance->LPMCR |= ((VidCfg->LPLargestPacketSize) << 16U);
1298 
1299   /* Low power VACT largest packet size */
1300   hdsi->Instance->LPMCR &= ~DSI_LPMCR_VLPSIZE;
1301   hdsi->Instance->LPMCR |= VidCfg->LPVACTLargestPacketSize;
1302 
1303   /* Enable LP transition in HFP period */
1304   hdsi->Instance->VMCR &= ~DSI_VMCR_LPHFPE;
1305   hdsi->Instance->VMCR |= VidCfg->LPHorizontalFrontPorchEnable;
1306 
1307   /* Enable LP transition in HBP period */
1308   hdsi->Instance->VMCR &= ~DSI_VMCR_LPHBPE;
1309   hdsi->Instance->VMCR |= VidCfg->LPHorizontalBackPorchEnable;
1310 
1311   /* Enable LP transition in VACT period */
1312   hdsi->Instance->VMCR &= ~DSI_VMCR_LPVAE;
1313   hdsi->Instance->VMCR |= VidCfg->LPVerticalActiveEnable;
1314 
1315   /* Enable LP transition in VFP period */
1316   hdsi->Instance->VMCR &= ~DSI_VMCR_LPVFPE;
1317   hdsi->Instance->VMCR |= VidCfg->LPVerticalFrontPorchEnable;
1318 
1319   /* Enable LP transition in VBP period */
1320   hdsi->Instance->VMCR &= ~DSI_VMCR_LPVBPE;
1321   hdsi->Instance->VMCR |= VidCfg->LPVerticalBackPorchEnable;
1322 
1323   /* Enable LP transition in vertical sync period */
1324   hdsi->Instance->VMCR &= ~DSI_VMCR_LPVSAE;
1325   hdsi->Instance->VMCR |= VidCfg->LPVerticalSyncActiveEnable;
1326 
1327   /* Enable the request for an acknowledge response at the end of a frame */
1328   hdsi->Instance->VMCR &= ~DSI_VMCR_FBTAAE;
1329   hdsi->Instance->VMCR |= VidCfg->FrameBTAAcknowledgeEnable;
1330 
1331   /* Process unlocked */
1332   __HAL_UNLOCK(hdsi);
1333 
1334   return HAL_OK;
1335 }
1336 
1337 /**
1338   * @brief  Select adapted command mode and configure the corresponding parameters
1339   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1340   *               the configuration information for the DSI.
1341   * @param  CmdCfg  pointer to a DSI_CmdCfgTypeDef structure that contains
1342   *                 the DSI command mode configuration parameters
1343   * @retval HAL status
1344   */
HAL_DSI_ConfigAdaptedCommandMode(DSI_HandleTypeDef * hdsi,DSI_CmdCfgTypeDef * CmdCfg)1345 HAL_StatusTypeDef HAL_DSI_ConfigAdaptedCommandMode(DSI_HandleTypeDef *hdsi, DSI_CmdCfgTypeDef *CmdCfg)
1346 {
1347   /* Process locked */
1348   __HAL_LOCK(hdsi);
1349 
1350   /* Check the parameters */
1351   assert_param(IS_DSI_COLOR_CODING(CmdCfg->ColorCoding));
1352   assert_param(IS_DSI_TE_SOURCE(CmdCfg->TearingEffectSource));
1353   assert_param(IS_DSI_TE_POLARITY(CmdCfg->TearingEffectPolarity));
1354   assert_param(IS_DSI_AUTOMATIC_REFRESH(CmdCfg->AutomaticRefresh));
1355   assert_param(IS_DSI_VS_POLARITY(CmdCfg->VSyncPol));
1356   assert_param(IS_DSI_TE_ACK_REQUEST(CmdCfg->TEAcknowledgeRequest));
1357   assert_param(IS_DSI_DE_POLARITY(CmdCfg->DEPolarity));
1358   assert_param(IS_DSI_VSYNC_POLARITY(CmdCfg->VSPolarity));
1359   assert_param(IS_DSI_HSYNC_POLARITY(CmdCfg->HSPolarity));
1360 
1361   /* Select command mode by setting CMDM and DSIM bits */
1362   hdsi->Instance->MCR |= DSI_MCR_CMDM;
1363   hdsi->Instance->WCFGR &= ~DSI_WCFGR_DSIM;
1364   hdsi->Instance->WCFGR |= DSI_WCFGR_DSIM;
1365 
1366   /* Select the virtual channel for the LTDC interface traffic */
1367   hdsi->Instance->LVCIDR &= ~DSI_LVCIDR_VCID;
1368   hdsi->Instance->LVCIDR |= CmdCfg->VirtualChannelID;
1369 
1370   /* Configure the polarity of control signals */
1371   hdsi->Instance->LPCR &= ~(DSI_LPCR_DEP | DSI_LPCR_VSP | DSI_LPCR_HSP);
1372   hdsi->Instance->LPCR |= (CmdCfg->DEPolarity | CmdCfg->VSPolarity | CmdCfg->HSPolarity);
1373 
1374   /* Select the color coding for the host */
1375   hdsi->Instance->LCOLCR &= ~DSI_LCOLCR_COLC;
1376   hdsi->Instance->LCOLCR |= CmdCfg->ColorCoding;
1377 
1378   /* Select the color coding for the wrapper */
1379   hdsi->Instance->WCFGR &= ~DSI_WCFGR_COLMUX;
1380   hdsi->Instance->WCFGR |= ((CmdCfg->ColorCoding) << 1U);
1381 
1382   /* Configure the maximum allowed size for write memory command */
1383   hdsi->Instance->LCCR &= ~DSI_LCCR_CMDSIZE;
1384   hdsi->Instance->LCCR |= CmdCfg->CommandSize;
1385 
1386   /* Configure the tearing effect source and polarity and select the refresh mode */
1387   hdsi->Instance->WCFGR &= ~(DSI_WCFGR_TESRC | DSI_WCFGR_TEPOL | DSI_WCFGR_AR | DSI_WCFGR_VSPOL);
1388   hdsi->Instance->WCFGR |= (CmdCfg->TearingEffectSource | CmdCfg->TearingEffectPolarity | CmdCfg->AutomaticRefresh |
1389                             CmdCfg->VSyncPol);
1390 
1391   /* Configure the tearing effect acknowledge request */
1392   hdsi->Instance->CMCR &= ~DSI_CMCR_TEARE;
1393   hdsi->Instance->CMCR |= CmdCfg->TEAcknowledgeRequest;
1394 
1395   /* Enable the Tearing Effect interrupt */
1396   __HAL_DSI_ENABLE_IT(hdsi, DSI_IT_TE);
1397 
1398   /* Enable the End of Refresh interrupt */
1399   __HAL_DSI_ENABLE_IT(hdsi, DSI_IT_ER);
1400 
1401   /* Process unlocked */
1402   __HAL_UNLOCK(hdsi);
1403 
1404   return HAL_OK;
1405 }
1406 
1407 /**
1408   * @brief  Configure command transmission mode: High-speed or Low-power
1409   *         and enable/disable acknowledge request after packet transmission
1410   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1411   *               the configuration information for the DSI.
1412   * @param  LPCmd  pointer to a DSI_LPCmdTypeDef structure that contains
1413   *                the DSI command transmission mode configuration parameters
1414   * @retval HAL status
1415   */
HAL_DSI_ConfigCommand(DSI_HandleTypeDef * hdsi,DSI_LPCmdTypeDef * LPCmd)1416 HAL_StatusTypeDef HAL_DSI_ConfigCommand(DSI_HandleTypeDef *hdsi, DSI_LPCmdTypeDef *LPCmd)
1417 {
1418   /* Process locked */
1419   __HAL_LOCK(hdsi);
1420 
1421   assert_param(IS_DSI_LP_GSW0P(LPCmd->LPGenShortWriteNoP));
1422   assert_param(IS_DSI_LP_GSW1P(LPCmd->LPGenShortWriteOneP));
1423   assert_param(IS_DSI_LP_GSW2P(LPCmd->LPGenShortWriteTwoP));
1424   assert_param(IS_DSI_LP_GSR0P(LPCmd->LPGenShortReadNoP));
1425   assert_param(IS_DSI_LP_GSR1P(LPCmd->LPGenShortReadOneP));
1426   assert_param(IS_DSI_LP_GSR2P(LPCmd->LPGenShortReadTwoP));
1427   assert_param(IS_DSI_LP_GLW(LPCmd->LPGenLongWrite));
1428   assert_param(IS_DSI_LP_DSW0P(LPCmd->LPDcsShortWriteNoP));
1429   assert_param(IS_DSI_LP_DSW1P(LPCmd->LPDcsShortWriteOneP));
1430   assert_param(IS_DSI_LP_DSR0P(LPCmd->LPDcsShortReadNoP));
1431   assert_param(IS_DSI_LP_DLW(LPCmd->LPDcsLongWrite));
1432   assert_param(IS_DSI_LP_MRDP(LPCmd->LPMaxReadPacket));
1433   assert_param(IS_DSI_ACK_REQUEST(LPCmd->AcknowledgeRequest));
1434 
1435   /* Select High-speed or Low-power for command transmission */
1436   hdsi->Instance->CMCR &= ~(DSI_CMCR_GSW0TX | \
1437                             DSI_CMCR_GSW1TX | \
1438                             DSI_CMCR_GSW2TX | \
1439                             DSI_CMCR_GSR0TX | \
1440                             DSI_CMCR_GSR1TX | \
1441                             DSI_CMCR_GSR2TX | \
1442                             DSI_CMCR_GLWTX  | \
1443                             DSI_CMCR_DSW0TX | \
1444                             DSI_CMCR_DSW1TX | \
1445                             DSI_CMCR_DSR0TX | \
1446                             DSI_CMCR_DLWTX  | \
1447                             DSI_CMCR_MRDPS);
1448   hdsi->Instance->CMCR |= (LPCmd->LPGenShortWriteNoP  | \
1449                            LPCmd->LPGenShortWriteOneP | \
1450                            LPCmd->LPGenShortWriteTwoP | \
1451                            LPCmd->LPGenShortReadNoP   | \
1452                            LPCmd->LPGenShortReadOneP  | \
1453                            LPCmd->LPGenShortReadTwoP  | \
1454                            LPCmd->LPGenLongWrite      | \
1455                            LPCmd->LPDcsShortWriteNoP  | \
1456                            LPCmd->LPDcsShortWriteOneP | \
1457                            LPCmd->LPDcsShortReadNoP   | \
1458                            LPCmd->LPDcsLongWrite      | \
1459                            LPCmd->LPMaxReadPacket);
1460 
1461   /* Configure the acknowledge request after each packet transmission */
1462   hdsi->Instance->CMCR &= ~DSI_CMCR_ARE;
1463   hdsi->Instance->CMCR |= LPCmd->AcknowledgeRequest;
1464 
1465   /* Process unlocked */
1466   __HAL_UNLOCK(hdsi);
1467 
1468   return HAL_OK;
1469 }
1470 
1471 /**
1472   * @brief  Configure the flow control parameters
1473   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1474   *               the configuration information for the DSI.
1475   * @param  FlowControl  flow control feature(s) to be enabled.
1476   *                      This parameter can be any combination of @arg DSI_FlowControl.
1477   * @retval HAL status
1478   */
HAL_DSI_ConfigFlowControl(DSI_HandleTypeDef * hdsi,uint32_t FlowControl)1479 HAL_StatusTypeDef HAL_DSI_ConfigFlowControl(DSI_HandleTypeDef *hdsi, uint32_t FlowControl)
1480 {
1481   /* Process locked */
1482   __HAL_LOCK(hdsi);
1483 
1484   /* Check the parameters */
1485   assert_param(IS_DSI_FLOW_CONTROL(FlowControl));
1486 
1487   /* Set the DSI Host Protocol Configuration Register */
1488   hdsi->Instance->PCR &= ~DSI_FLOW_CONTROL_ALL;
1489   hdsi->Instance->PCR |= FlowControl;
1490 
1491   /* Process unlocked */
1492   __HAL_UNLOCK(hdsi);
1493 
1494   return HAL_OK;
1495 }
1496 
1497 /**
1498   * @brief  Configure the DSI PHY timer parameters
1499   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1500   *               the configuration information for the DSI.
1501   * @param  PhyTimers  DSI_PHY_TimerTypeDef structure that contains
1502   *                    the DSI PHY timing parameters
1503   * @retval HAL status
1504   */
HAL_DSI_ConfigPhyTimer(DSI_HandleTypeDef * hdsi,DSI_PHY_TimerTypeDef * PhyTimers)1505 HAL_StatusTypeDef HAL_DSI_ConfigPhyTimer(DSI_HandleTypeDef *hdsi, DSI_PHY_TimerTypeDef *PhyTimers)
1506 {
1507   uint32_t maxTime;
1508   /* Process locked */
1509   __HAL_LOCK(hdsi);
1510 
1511   /* Insert LPX Offset into the timings */
1512   PhyTimers->ClockLaneHS2LPTime = PhyTimers->ClockLaneHS2LPTime + hdsi->Init.PHYLowPowerOffset;
1513   PhyTimers->ClockLaneLP2HSTime = PhyTimers->ClockLaneLP2HSTime + (3U * hdsi->Init.PHYLowPowerOffset);
1514   PhyTimers->DataLaneLP2HSTime  = PhyTimers->DataLaneLP2HSTime + (2U * hdsi->Init.PHYLowPowerOffset);
1515 
1516   maxTime = (PhyTimers->ClockLaneLP2HSTime > PhyTimers->ClockLaneHS2LPTime) ? PhyTimers->ClockLaneLP2HSTime :
1517             PhyTimers->ClockLaneHS2LPTime;
1518 
1519   /* Clock lane timer configuration */
1520 
1521   /* In Automatic Clock Lane control mode, the DSI Host can turn off the clock lane between two
1522      High-Speed transmission.
1523      To do so, the DSI Host calculates the time required for the clock lane to change from HighSpeed
1524      to Low-Power and from Low-Power to High-Speed.
1525      This timings are configured by the HS2LP_TIME and LP2HS_TIME in the DSI Host Clock Lane Timer Configuration
1526      Register (DSI_CLTCR).
1527      But the DSI Host is not calculating LP2HS_TIME + HS2LP_TIME but 2 x HS2LP_TIME.
1528 
1529      Workaround : Configure HS2LP_TIME and LP2HS_TIME with the same value being the max of HS2LP_TIME or LP2HS_TIME.
1530     */
1531   hdsi->Instance->CLTCR &= ~(DSI_CLTCR_LP2HS_TIME | DSI_CLTCR_HS2LP_TIME);
1532   hdsi->Instance->CLTCR |= (maxTime | ((maxTime) << 16U));
1533 
1534   /* Data lane timer configuration */
1535   hdsi->Instance->DLTCR &= ~(DSI_DLTCR_LP2HS_TIME | DSI_DLTCR_HS2LP_TIME);
1536   hdsi->Instance->DLTCR |= (PhyTimers->DataLaneLP2HSTime | ((PhyTimers->DataLaneHS2LPTime) << 16U));
1537   hdsi->Instance->DLTRCR &= ~DSI_DLTRCR_MRD_TIME;
1538   hdsi->Instance->DLTRCR |= PhyTimers->DataLaneMaxReadTime;
1539 
1540   /* Configure the wait period to request HS transmission after a stop state */
1541   hdsi->Instance->PCONFR &= ~DSI_PCONFR_SW_TIME;
1542   hdsi->Instance->PCONFR |= ((PhyTimers->StopWaitTime) << 8U);
1543 
1544   /* Process unlocked */
1545   __HAL_UNLOCK(hdsi);
1546 
1547   return HAL_OK;
1548 }
1549 
1550 /**
1551   * @brief  Configure the DSI HOST timeout parameters
1552   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1553   *               the configuration information for the DSI.
1554   * @param  HostTimeouts  DSI_HOST_TimeoutTypeDef structure that contains
1555   *                       the DSI host timeout parameters
1556   * @retval HAL status
1557   */
HAL_DSI_ConfigHostTimeouts(DSI_HandleTypeDef * hdsi,DSI_HOST_TimeoutTypeDef * HostTimeouts)1558 HAL_StatusTypeDef HAL_DSI_ConfigHostTimeouts(DSI_HandleTypeDef *hdsi, DSI_HOST_TimeoutTypeDef *HostTimeouts)
1559 {
1560   /* Process locked */
1561   __HAL_LOCK(hdsi);
1562 
1563   /* Set the timeout clock division factor */
1564   hdsi->Instance->CCR &= ~DSI_CCR_TOCKDIV;
1565   hdsi->Instance->CCR |= ((HostTimeouts->TimeoutCkdiv) << 8U);
1566 
1567   /* High-speed transmission timeout */
1568   hdsi->Instance->TCCR[0U] &= ~DSI_TCCR0_HSTX_TOCNT;
1569   hdsi->Instance->TCCR[0U] |= ((HostTimeouts->HighSpeedTransmissionTimeout) << 16U);
1570 
1571   /* Low-power reception timeout */
1572   hdsi->Instance->TCCR[0U] &= ~DSI_TCCR0_LPRX_TOCNT;
1573   hdsi->Instance->TCCR[0U] |= HostTimeouts->LowPowerReceptionTimeout;
1574 
1575   /* High-speed read timeout */
1576   hdsi->Instance->TCCR[1U] &= ~DSI_TCCR1_HSRD_TOCNT;
1577   hdsi->Instance->TCCR[1U] |= HostTimeouts->HighSpeedReadTimeout;
1578 
1579   /* Low-power read timeout */
1580   hdsi->Instance->TCCR[2U] &= ~DSI_TCCR2_LPRD_TOCNT;
1581   hdsi->Instance->TCCR[2U] |= HostTimeouts->LowPowerReadTimeout;
1582 
1583   /* High-speed write timeout */
1584   hdsi->Instance->TCCR[3U] &= ~DSI_TCCR3_HSWR_TOCNT;
1585   hdsi->Instance->TCCR[3U] |= HostTimeouts->HighSpeedWriteTimeout;
1586 
1587   /* High-speed write presp mode */
1588   hdsi->Instance->TCCR[3U] &= ~DSI_TCCR3_PM;
1589   hdsi->Instance->TCCR[3U] |= HostTimeouts->HighSpeedWritePrespMode;
1590 
1591   /* Low-speed write timeout */
1592   hdsi->Instance->TCCR[4U] &= ~DSI_TCCR4_LPWR_TOCNT;
1593   hdsi->Instance->TCCR[4U] |= HostTimeouts->LowPowerWriteTimeout;
1594 
1595   /* BTA timeout */
1596   hdsi->Instance->TCCR[5U] &= ~DSI_TCCR5_BTA_TOCNT;
1597   hdsi->Instance->TCCR[5U] |= HostTimeouts->BTATimeout;
1598 
1599   /* Process unlocked */
1600   __HAL_UNLOCK(hdsi);
1601 
1602   return HAL_OK;
1603 }
1604 
1605 /**
1606   * @brief  Start the DSI module
1607   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1608   *               the configuration information for the DSI.
1609   * @retval HAL status
1610   */
HAL_DSI_Start(DSI_HandleTypeDef * hdsi)1611 HAL_StatusTypeDef HAL_DSI_Start(DSI_HandleTypeDef *hdsi)
1612 {
1613   /* Process locked */
1614   __HAL_LOCK(hdsi);
1615 
1616   /* Enable the DSI host */
1617   __HAL_DSI_ENABLE(hdsi);
1618 
1619   /* Enable the DSI wrapper */
1620   __HAL_DSI_WRAPPER_ENABLE(hdsi);
1621 
1622   /* Process unlocked */
1623   __HAL_UNLOCK(hdsi);
1624 
1625   return HAL_OK;
1626 }
1627 
1628 /**
1629   * @brief  Stop the DSI module
1630   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1631   *               the configuration information for the DSI.
1632   * @retval HAL status
1633   */
HAL_DSI_Stop(DSI_HandleTypeDef * hdsi)1634 HAL_StatusTypeDef HAL_DSI_Stop(DSI_HandleTypeDef *hdsi)
1635 {
1636   /* Process locked */
1637   __HAL_LOCK(hdsi);
1638 
1639   /* Disable the DSI host */
1640   __HAL_DSI_DISABLE(hdsi);
1641 
1642   /* Disable the DSI wrapper */
1643   __HAL_DSI_WRAPPER_DISABLE(hdsi);
1644 
1645   /* Process unlocked */
1646   __HAL_UNLOCK(hdsi);
1647 
1648   return HAL_OK;
1649 }
1650 
1651 /**
1652   * @brief  Refresh the display in command mode
1653   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1654   *               the configuration information for the DSI.
1655   * @retval HAL status
1656   */
HAL_DSI_Refresh(DSI_HandleTypeDef * hdsi)1657 HAL_StatusTypeDef HAL_DSI_Refresh(DSI_HandleTypeDef *hdsi)
1658 {
1659   /* Process locked */
1660   __HAL_LOCK(hdsi);
1661 
1662   /* Update the display */
1663   hdsi->Instance->WCR |= DSI_WCR_LTDCEN;
1664 
1665   /* Process unlocked */
1666   __HAL_UNLOCK(hdsi);
1667 
1668   return HAL_OK;
1669 }
1670 
1671 /**
1672   * @brief  Controls the display color mode in Video mode
1673   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1674   *               the configuration information for the DSI.
1675   * @param  ColorMode  Color mode (full or 8-colors).
1676   *                    This parameter can be any value of @arg DSI_Color_Mode
1677   * @retval HAL status
1678   */
HAL_DSI_ColorMode(DSI_HandleTypeDef * hdsi,uint32_t ColorMode)1679 HAL_StatusTypeDef HAL_DSI_ColorMode(DSI_HandleTypeDef *hdsi, uint32_t ColorMode)
1680 {
1681   /* Process locked */
1682   __HAL_LOCK(hdsi);
1683 
1684   /* Check the parameters */
1685   assert_param(IS_DSI_COLOR_MODE(ColorMode));
1686 
1687   /* Update the display color mode */
1688   hdsi->Instance->WCR &= ~DSI_WCR_COLM;
1689   hdsi->Instance->WCR |= ColorMode;
1690 
1691   /* Process unlocked */
1692   __HAL_UNLOCK(hdsi);
1693 
1694   return HAL_OK;
1695 }
1696 
1697 /**
1698   * @brief  Control the display shutdown in Video mode
1699   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1700   *               the configuration information for the DSI.
1701   * @param  Shutdown  Shut-down (Display-ON or Display-OFF).
1702   *                   This parameter can be any value of @arg DSI_ShutDown
1703   * @retval HAL status
1704   */
HAL_DSI_Shutdown(DSI_HandleTypeDef * hdsi,uint32_t Shutdown)1705 HAL_StatusTypeDef HAL_DSI_Shutdown(DSI_HandleTypeDef *hdsi, uint32_t Shutdown)
1706 {
1707   /* Process locked */
1708   __HAL_LOCK(hdsi);
1709 
1710   /* Check the parameters */
1711   assert_param(IS_DSI_SHUT_DOWN(Shutdown));
1712 
1713   /* Update the display Shutdown */
1714   hdsi->Instance->WCR &= ~DSI_WCR_SHTDN;
1715   hdsi->Instance->WCR |= Shutdown;
1716 
1717   /* Process unlocked */
1718   __HAL_UNLOCK(hdsi);
1719 
1720   return HAL_OK;
1721 }
1722 
1723 /**
1724   * @brief  write short DCS or short Generic command
1725   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1726   *               the configuration information for the DSI.
1727   * @param  ChannelID  Virtual channel ID.
1728   * @param  Mode  DSI short packet data type.
1729   *               This parameter can be any value of @arg DSI_SHORT_WRITE_PKT_Data_Type.
1730   * @param  Param1  DSC command or first generic parameter.
1731   *                 This parameter can be any value of @arg DSI_DCS_Command or a
1732   *                 generic command code.
1733   * @param  Param2  DSC parameter or second generic parameter.
1734   * @retval HAL status
1735   */
HAL_DSI_ShortWrite(DSI_HandleTypeDef * hdsi,uint32_t ChannelID,uint32_t Mode,uint32_t Param1,uint32_t Param2)1736 HAL_StatusTypeDef HAL_DSI_ShortWrite(DSI_HandleTypeDef *hdsi,
1737                                      uint32_t ChannelID,
1738                                      uint32_t Mode,
1739                                      uint32_t Param1,
1740                                      uint32_t Param2)
1741 {
1742   HAL_StatusTypeDef status;
1743   /* Check the parameters */
1744   assert_param(IS_DSI_SHORT_WRITE_PACKET_TYPE(Mode));
1745 
1746   /* Process locked */
1747   __HAL_LOCK(hdsi);
1748 
1749   status = DSI_ShortWrite(hdsi, ChannelID, Mode, Param1, Param2);
1750 
1751   /* Process unlocked */
1752   __HAL_UNLOCK(hdsi);
1753 
1754   return status;
1755 }
1756 
1757 /**
1758   * @brief  write long DCS or long Generic command
1759   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1760   *               the configuration information for the DSI.
1761   * @param  ChannelID  Virtual channel ID.
1762   * @param  Mode  DSI long packet data type.
1763   *               This parameter can be any value of @arg DSI_LONG_WRITE_PKT_Data_Type.
1764   * @param  NbParams  Number of parameters.
1765   * @param  Param1  DSC command or first generic parameter.
1766   *                 This parameter can be any value of @arg DSI_DCS_Command or a
1767   *                 generic command code
1768   * @param  ParametersTable  Pointer to parameter values table.
1769   * @retval HAL status
1770   */
HAL_DSI_LongWrite(DSI_HandleTypeDef * hdsi,uint32_t ChannelID,uint32_t Mode,uint32_t NbParams,uint32_t Param1,uint8_t * ParametersTable)1771 HAL_StatusTypeDef HAL_DSI_LongWrite(DSI_HandleTypeDef *hdsi,
1772                                     uint32_t ChannelID,
1773                                     uint32_t Mode,
1774                                     uint32_t NbParams,
1775                                     uint32_t Param1,
1776                                     uint8_t *ParametersTable)
1777 {
1778   uint32_t uicounter;
1779   uint32_t nbBytes;
1780   uint32_t count;
1781   uint32_t tickstart;
1782   uint32_t fifoword;
1783   uint8_t *pparams = ParametersTable;
1784 
1785   /* Process locked */
1786   __HAL_LOCK(hdsi);
1787 
1788   /* Check the parameters */
1789   assert_param(IS_DSI_LONG_WRITE_PACKET_TYPE(Mode));
1790 
1791   /* Get tick */
1792   tickstart = HAL_GetTick();
1793 
1794   /* Wait for Command FIFO Empty */
1795   while ((hdsi->Instance->GPSR & DSI_GPSR_CMDFE) == 0U)
1796   {
1797     /* Check for the Timeout */
1798     if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
1799     {
1800       /* Process Unlocked */
1801       __HAL_UNLOCK(hdsi);
1802 
1803       return HAL_TIMEOUT;
1804     }
1805   }
1806 
1807   /* Set the DCS code on payload byte 1, and the other parameters on the write FIFO command*/
1808   fifoword = Param1;
1809   nbBytes = (NbParams < 3U) ? NbParams : 3U;
1810 
1811   for (count = 0U; count < nbBytes; count++)
1812   {
1813     fifoword |= (((uint32_t)(*(pparams + count))) << (8U + (8U * count)));
1814   }
1815   hdsi->Instance->GPDR = fifoword;
1816 
1817   uicounter = NbParams - nbBytes;
1818   pparams += nbBytes;
1819   /* Set the Next parameters on the write FIFO command*/
1820   while (uicounter != 0U)
1821   {
1822     nbBytes = (uicounter < 4U) ? uicounter : 4U;
1823     fifoword = 0U;
1824     for (count = 0U; count < nbBytes; count++)
1825     {
1826       fifoword |= (((uint32_t)(*(pparams + count))) << (8U * count));
1827     }
1828     hdsi->Instance->GPDR = fifoword;
1829 
1830     uicounter -= nbBytes;
1831     pparams += nbBytes;
1832   }
1833 
1834   /* Configure the packet to send a long DCS command */
1835   DSI_ConfigPacketHeader(hdsi->Instance,
1836                          ChannelID,
1837                          Mode,
1838                          ((NbParams + 1U) & 0x00FFU),
1839                          (((NbParams + 1U) & 0xFF00U) >> 8U));
1840 
1841   /* Process unlocked */
1842   __HAL_UNLOCK(hdsi);
1843 
1844   return HAL_OK;
1845 }
1846 
1847 /**
1848   * @brief  Read command (DCS or generic)
1849   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1850   *               the configuration information for the DSI.
1851   * @param  ChannelNbr  Virtual channel ID
1852   * @param  Array pointer to a buffer to store the payload of a read back operation.
1853   * @param  Size  Data size to be read (in byte).
1854   * @param  Mode  DSI read packet data type.
1855   *               This parameter can be any value of @arg DSI_SHORT_READ_PKT_Data_Type.
1856   * @param  DCSCmd  DCS get/read command.
1857   * @param  ParametersTable  Pointer to parameter values table.
1858   * @retval HAL status
1859   */
HAL_DSI_Read(DSI_HandleTypeDef * hdsi,uint32_t ChannelNbr,uint8_t * Array,uint32_t Size,uint32_t Mode,uint32_t DCSCmd,uint8_t * ParametersTable)1860 HAL_StatusTypeDef HAL_DSI_Read(DSI_HandleTypeDef *hdsi,
1861                                uint32_t ChannelNbr,
1862                                uint8_t *Array,
1863                                uint32_t Size,
1864                                uint32_t Mode,
1865                                uint32_t DCSCmd,
1866                                uint8_t *ParametersTable)
1867 {
1868   uint32_t tickstart;
1869   uint8_t *pdata = Array;
1870   uint32_t datasize = Size;
1871   uint32_t fifoword;
1872   uint32_t nbbytes;
1873   uint32_t count;
1874 
1875   /* Process locked */
1876   __HAL_LOCK(hdsi);
1877 
1878   /* Check the parameters */
1879   assert_param(IS_DSI_READ_PACKET_TYPE(Mode));
1880 
1881   if (datasize > 2U)
1882   {
1883     /* set max return packet size */
1884     if (DSI_ShortWrite(hdsi, ChannelNbr, DSI_MAX_RETURN_PKT_SIZE, ((datasize) & 0xFFU),
1885                        (((datasize) >> 8U) & 0xFFU)) != HAL_OK)
1886     {
1887       /* Process Unlocked */
1888       __HAL_UNLOCK(hdsi);
1889 
1890       return HAL_ERROR;
1891     }
1892   }
1893 
1894   /* Configure the packet to read command */
1895   if (Mode == DSI_DCS_SHORT_PKT_READ)
1896   {
1897     DSI_ConfigPacketHeader(hdsi->Instance, ChannelNbr, Mode, DCSCmd, 0U);
1898   }
1899   else if (Mode == DSI_GEN_SHORT_PKT_READ_P0)
1900   {
1901     DSI_ConfigPacketHeader(hdsi->Instance, ChannelNbr, Mode, 0U, 0U);
1902   }
1903   else if (Mode == DSI_GEN_SHORT_PKT_READ_P1)
1904   {
1905     DSI_ConfigPacketHeader(hdsi->Instance, ChannelNbr, Mode, ParametersTable[0U], 0U);
1906   }
1907   else if (Mode == DSI_GEN_SHORT_PKT_READ_P2)
1908   {
1909     DSI_ConfigPacketHeader(hdsi->Instance, ChannelNbr, Mode, ParametersTable[0U], ParametersTable[1U]);
1910   }
1911   else
1912   {
1913     /* Process Unlocked */
1914     __HAL_UNLOCK(hdsi);
1915 
1916     return HAL_ERROR;
1917   }
1918 
1919   /* Get tick */
1920   tickstart = HAL_GetTick();
1921 
1922   /* If DSI fifo is not empty, read requested bytes */
1923   while (((int32_t)(datasize)) > 0)
1924   {
1925     if ((hdsi->Instance->GPSR & DSI_GPSR_PRDFE) == 0U)
1926     {
1927       fifoword = hdsi->Instance->GPDR;
1928       nbbytes = (datasize < 4U) ? datasize : 4U;
1929 
1930       for (count = 0U; count < nbbytes; count++)
1931       {
1932         *pdata = (uint8_t)(fifoword >> (8U * count));
1933         pdata++;
1934         datasize--;
1935       }
1936     }
1937 
1938     /* Check for the Timeout */
1939     if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
1940     {
1941       /* Process Unlocked */
1942       __HAL_UNLOCK(hdsi);
1943 
1944       return HAL_TIMEOUT;
1945     }
1946 
1947     /* Software workaround to avoid HAL_TIMEOUT when a DSI read command is   */
1948     /* issued to the panel and the read data is not captured by the DSI Host */
1949     /* which returns Packet Size Error.                                      */
1950     /* Need to ensure that the Read command has finished before checking PSE */
1951     if ((hdsi->Instance->GPSR & DSI_GPSR_RCB) == 0U)
1952     {
1953       if ((hdsi->Instance->ISR[1U] & DSI_ISR1_PSE) == DSI_ISR1_PSE)
1954       {
1955         /* Process Unlocked */
1956         __HAL_UNLOCK(hdsi);
1957 
1958         return HAL_ERROR;
1959       }
1960     }
1961   }
1962 
1963   /* Process unlocked */
1964   __HAL_UNLOCK(hdsi);
1965 
1966   return HAL_OK;
1967 }
1968 
1969 /**
1970   * @brief  Enter the ULPM (Ultra Low Power Mode) with the D-PHY PLL running
1971   *         (only data lanes are in ULPM)
1972   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1973   *               the configuration information for the DSI.
1974   * @retval HAL status
1975   */
HAL_DSI_EnterULPMData(DSI_HandleTypeDef * hdsi)1976 HAL_StatusTypeDef HAL_DSI_EnterULPMData(DSI_HandleTypeDef *hdsi)
1977 {
1978   uint32_t tickstart;
1979 
1980   /* Process locked */
1981   __HAL_LOCK(hdsi);
1982 
1983   /* Verify the initial status of the DSI Host */
1984 
1985   /* Verify that the clock lane and the digital section of the D-PHY are enabled */
1986   if ((hdsi->Instance->PCTLR & (DSI_PCTLR_CKE | DSI_PCTLR_DEN)) != (DSI_PCTLR_CKE | DSI_PCTLR_DEN))
1987   {
1988     /* Process Unlocked */
1989     __HAL_UNLOCK(hdsi);
1990     return HAL_ERROR;
1991   }
1992 
1993   /* Verify that the D-PHY PLL and the reference bias are enabled */
1994   if ((hdsi->Instance->WRPCR & DSI_WRPCR_PLLEN) != DSI_WRPCR_PLLEN)
1995   {
1996     /* Process Unlocked */
1997     __HAL_UNLOCK(hdsi);
1998     return HAL_ERROR;
1999   }
2000   else if ((hdsi->Instance->BCFGR  & DSI_BCFGR_PWRUP) != DSI_BCFGR_PWRUP)
2001   {
2002     /* Process Unlocked */
2003     __HAL_UNLOCK(hdsi);
2004     return HAL_ERROR;
2005   }
2006   else
2007   {
2008     /* Nothing to do */
2009   }
2010 
2011   /* Verify that there are no ULPS exit or request on data lanes */
2012   if ((hdsi->Instance->PUCR & (DSI_PUCR_UEDL | DSI_PUCR_URDL)) != 0U)
2013   {
2014     /* Process Unlocked */
2015     __HAL_UNLOCK(hdsi);
2016     return HAL_ERROR;
2017   }
2018 
2019   /* Verify that there are no Transmission trigger */
2020   if ((hdsi->Instance->PTTCR & DSI_PTTCR_TX_TRIG) != 0U)
2021   {
2022     /* Process Unlocked */
2023     __HAL_UNLOCK(hdsi);
2024     return HAL_ERROR;
2025   }
2026 
2027   /* Requires min of 400us delay before reading the PLLLS flag */
2028   /* 1ms delay is inserted that is the minimum HAL delay granularity */
2029   HAL_Delay(1);
2030 
2031   /* Verify that D-PHY PLL is locked */
2032   tickstart = HAL_GetTick();
2033 
2034   while ((__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U))
2035   {
2036     /* Check for the Timeout */
2037     if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2038     {
2039       /* Process Unlocked */
2040       __HAL_UNLOCK(hdsi);
2041 
2042       return HAL_TIMEOUT;
2043     }
2044   }
2045 
2046   /* Verify that all active lanes are in Stop state */
2047   if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2048   {
2049     if ((hdsi->Instance->PSR & DSI_PSR_UAN0) != DSI_PSR_UAN0)
2050     {
2051       /* Process Unlocked */
2052       __HAL_UNLOCK(hdsi);
2053       return HAL_ERROR;
2054     }
2055   }
2056   else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2057   {
2058     if ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1)) != (DSI_PSR_UAN0 | DSI_PSR_UAN1))
2059     {
2060       /* Process Unlocked */
2061       __HAL_UNLOCK(hdsi);
2062       return HAL_ERROR;
2063     }
2064   }
2065   else
2066   {
2067     /* Process unlocked */
2068     __HAL_UNLOCK(hdsi);
2069     return HAL_ERROR;
2070   }
2071 
2072   /* ULPS Request on Data Lanes */
2073   hdsi->Instance->PUCR |= DSI_PUCR_URDL;
2074 
2075   /* Get tick */
2076   tickstart = HAL_GetTick();
2077 
2078   /* Wait until the D-PHY active lanes enter into ULPM */
2079   if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2080   {
2081     while ((hdsi->Instance->PSR & DSI_PSR_UAN0) != 0U)
2082     {
2083       /* Check for the Timeout */
2084       if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2085       {
2086         /* Process Unlocked */
2087         __HAL_UNLOCK(hdsi);
2088 
2089         return HAL_TIMEOUT;
2090       }
2091     }
2092   }
2093   else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2094   {
2095     while ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1)) != 0U)
2096     {
2097       /* Check for the Timeout */
2098       if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2099       {
2100         /* Process Unlocked */
2101         __HAL_UNLOCK(hdsi);
2102 
2103         return HAL_TIMEOUT;
2104       }
2105     }
2106   }
2107   else
2108   {
2109     /* Process unlocked */
2110     __HAL_UNLOCK(hdsi);
2111 
2112     return HAL_ERROR;
2113   }
2114 
2115   /* Process unlocked */
2116   __HAL_UNLOCK(hdsi);
2117 
2118   return HAL_OK;
2119 }
2120 
2121 /**
2122   * @brief  Exit the ULPM (Ultra Low Power Mode) with the D-PHY PLL running
2123   *         (only data lanes are in ULPM)
2124   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2125   *               the configuration information for the DSI.
2126   * @retval HAL status
2127   */
HAL_DSI_ExitULPMData(DSI_HandleTypeDef * hdsi)2128 HAL_StatusTypeDef HAL_DSI_ExitULPMData(DSI_HandleTypeDef *hdsi)
2129 {
2130   uint32_t tickstart;
2131 
2132   /* Process locked */
2133   __HAL_LOCK(hdsi);
2134 
2135   /* Verify that all active lanes are in ULPM */
2136   if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2137   {
2138     if ((hdsi->Instance->PSR &  DSI_PSR_UAN0) != 0U)
2139     {
2140       /* Process Unlocked */
2141       __HAL_UNLOCK(hdsi);
2142 
2143       return HAL_ERROR;
2144     }
2145   }
2146   else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2147   {
2148     if ((hdsi->Instance->PSR & (DSI_PSR_UAN0  | DSI_PSR_UAN1)) != 0U)
2149     {
2150       /* Process Unlocked */
2151       __HAL_UNLOCK(hdsi);
2152 
2153       return HAL_ERROR;
2154     }
2155   }
2156   else
2157   {
2158     /* Process unlocked */
2159     __HAL_UNLOCK(hdsi);
2160 
2161     return HAL_ERROR;
2162   }
2163 
2164   /* Turn on the DSI PLL */
2165   __HAL_DSI_PLL_ENABLE(hdsi);
2166 
2167   /* Requires min of 400us delay before reading the PLLLS flag */
2168   /* 1ms delay is inserted that is the minimum HAL delay granularity */
2169   HAL_Delay(1);
2170 
2171   /* Get tick */
2172   tickstart = HAL_GetTick();
2173 
2174   /* Wait for the lock of the PLL */
2175   while (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U)
2176   {
2177     /* Check for the Timeout */
2178     if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2179     {
2180       /* Process Unlocked */
2181       __HAL_UNLOCK(hdsi);
2182 
2183       return HAL_TIMEOUT;
2184     }
2185   }
2186 
2187   /* Exit ULPS on Data Lanes */
2188   hdsi->Instance->PUCR |= DSI_PUCR_UEDL;
2189 
2190   /* Get tick */
2191   tickstart = HAL_GetTick();
2192 
2193   /* Wait until all active lanes exit ULPM */
2194   if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2195   {
2196     while ((hdsi->Instance->PSR & DSI_PSR_UAN0) != DSI_PSR_UAN0)
2197     {
2198       /* Check for the Timeout */
2199       if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2200       {
2201         /* Process Unlocked */
2202         __HAL_UNLOCK(hdsi);
2203 
2204         return HAL_TIMEOUT;
2205       }
2206     }
2207   }
2208   else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2209   {
2210     while ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1)) != (DSI_PSR_UAN0 | DSI_PSR_UAN1))
2211     {
2212       /* Check for the Timeout */
2213       if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2214       {
2215         /* Process Unlocked */
2216         __HAL_UNLOCK(hdsi);
2217 
2218         return HAL_TIMEOUT;
2219       }
2220     }
2221   }
2222   else
2223   {
2224     /* Process unlocked */
2225     __HAL_UNLOCK(hdsi);
2226 
2227     return HAL_ERROR;
2228   }
2229 
2230   /* wait for 1 ms*/
2231   HAL_Delay(1U);
2232 
2233   /* De-assert the ULPM requests and the ULPM exit bits */
2234   hdsi->Instance->PUCR = 0U;
2235 
2236   /* Verify that D-PHY PLL is enabled */
2237   if ((hdsi->Instance->WRPCR & DSI_WRPCR_PLLEN) != DSI_WRPCR_PLLEN)
2238   {
2239     /* Process Unlocked */
2240     __HAL_UNLOCK(hdsi);
2241     return HAL_ERROR;
2242   }
2243 
2244   /* Verify that all active lanes are in Stop state */
2245   if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2246   {
2247     if ((hdsi->Instance->PSR & DSI_PSR_UAN0) != DSI_PSR_UAN0)
2248     {
2249       /* Process Unlocked */
2250       __HAL_UNLOCK(hdsi);
2251       return HAL_ERROR;
2252     }
2253   }
2254   else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2255   {
2256     if ((hdsi->Instance->PSR & (DSI_PSR_UAN0  |  DSI_PSR_UAN1)) != (DSI_PSR_UAN0 | DSI_PSR_UAN1))
2257     {
2258       /* Process Unlocked */
2259       __HAL_UNLOCK(hdsi);
2260       return HAL_ERROR;
2261     }
2262   }
2263   else
2264   {
2265     /* Process unlocked */
2266     __HAL_UNLOCK(hdsi);
2267     return HAL_ERROR;
2268   }
2269 
2270   /* Verify that D-PHY PLL is locked */
2271   /* Requires min of 400us delay before reading the PLLLS flag */
2272   /* 1ms delay is inserted that is the minimum HAL delay granularity */
2273   HAL_Delay(1);
2274 
2275   /* Get tick */
2276   tickstart = HAL_GetTick();
2277 
2278   /* Wait for the lock of the PLL */
2279   while (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U)
2280   {
2281     /* Check for the Timeout */
2282     if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2283     {
2284       /* Process Unlocked */
2285       __HAL_UNLOCK(hdsi);
2286 
2287       return HAL_TIMEOUT;
2288     }
2289   }
2290 
2291   /* Process unlocked */
2292   __HAL_UNLOCK(hdsi);
2293 
2294   return HAL_OK;
2295 }
2296 
2297 /**
2298   * @brief  Enter the ULPM (Ultra Low Power Mode) with the D-PHY PLL turned off
2299   *         (both data and clock lanes are in ULPM)
2300   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2301   *               the configuration information for the DSI.
2302   * @retval HAL status
2303   */
HAL_DSI_EnterULPM(DSI_HandleTypeDef * hdsi)2304 HAL_StatusTypeDef HAL_DSI_EnterULPM(DSI_HandleTypeDef *hdsi)
2305 {
2306   uint32_t tickstart;
2307 
2308   /* Process locked */
2309   __HAL_LOCK(hdsi);
2310 
2311   /* Verify the initial status of the DSI Host */
2312 
2313   /* Verify that the clock lane and the digital section of the D-PHY are enabled */
2314   if ((hdsi->Instance->PCTLR & (DSI_PCTLR_CKE | DSI_PCTLR_DEN)) != (DSI_PCTLR_CKE | DSI_PCTLR_DEN))
2315   {
2316     /* Process Unlocked */
2317     __HAL_UNLOCK(hdsi);
2318     return HAL_ERROR;
2319   }
2320 
2321   /* Verify that the D-PHY PLL and the reference bias are enabled */
2322   if ((hdsi->Instance->WRPCR & DSI_WRPCR_PLLEN) != DSI_WRPCR_PLLEN)
2323   {
2324     /* Process Unlocked */
2325     __HAL_UNLOCK(hdsi);
2326     return HAL_ERROR;
2327   }
2328   else if ((hdsi->Instance->BCFGR  & DSI_BCFGR_PWRUP) != DSI_BCFGR_PWRUP)
2329   {
2330     /* Process Unlocked */
2331     __HAL_UNLOCK(hdsi);
2332     return HAL_ERROR;
2333   }
2334   else
2335   {
2336     /* Nothing to do */
2337   }
2338 
2339   /* Verify that there are no ULPS exit or request on both data and clock lanes */
2340   if ((hdsi->Instance->PUCR & (DSI_PUCR_UEDL | DSI_PUCR_URDL | DSI_PUCR_UECL | DSI_PUCR_URCL)) != 0U)
2341   {
2342     /* Process Unlocked */
2343     __HAL_UNLOCK(hdsi);
2344     return HAL_ERROR;
2345   }
2346 
2347   /* Verify that there are no Transmission trigger */
2348   if ((hdsi->Instance->PTTCR & DSI_PTTCR_TX_TRIG) != 0U)
2349   {
2350     /* Process Unlocked */
2351     __HAL_UNLOCK(hdsi);
2352     return HAL_ERROR;
2353   }
2354 
2355   /* Requires min of 400us delay before reading the PLLLS flag */
2356   /* 1ms delay is inserted that is the minimum HAL delay granularity */
2357   HAL_Delay(1);
2358 
2359   /* Verify that D-PHY PLL is locked */
2360   tickstart = HAL_GetTick();
2361 
2362   while ((__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U))
2363   {
2364     /* Check for the Timeout */
2365     if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2366     {
2367       /* Process Unlocked */
2368       __HAL_UNLOCK(hdsi);
2369 
2370       return HAL_TIMEOUT;
2371     }
2372   }
2373 
2374   /* Verify that all active lanes are in Stop state */
2375   if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2376   {
2377     if ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_PSS0)) != (DSI_PSR_UAN0 | DSI_PSR_PSS0))
2378     {
2379       /* Process Unlocked */
2380       __HAL_UNLOCK(hdsi);
2381       return HAL_ERROR;
2382     }
2383   }
2384   else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2385   {
2386     if ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_PSS0 | DSI_PSR_PSS1 | \
2387                                 DSI_PSR_UAN1)) != (DSI_PSR_UAN0 | DSI_PSR_PSS0 | DSI_PSR_PSS1 | DSI_PSR_UAN1))
2388     {
2389       /* Process Unlocked */
2390       __HAL_UNLOCK(hdsi);
2391       return HAL_ERROR;
2392     }
2393   }
2394   else
2395   {
2396     /* Process unlocked */
2397     __HAL_UNLOCK(hdsi);
2398     return HAL_ERROR;
2399   }
2400 
2401   /* Clock lane configuration: no more HS request */
2402   hdsi->Instance->CLCR &= ~DSI_CLCR_DPCC;
2403 
2404   /* Use system PLL as byte lane clock source before stopping DSIPHY clock source */
2405   __HAL_RCC_DSI_CONFIG(RCC_DSICLKSOURCE_PLL3);
2406 
2407   /* ULPS Request on Clock and Data Lanes */
2408   hdsi->Instance->PUCR |= (DSI_PUCR_URCL | DSI_PUCR_URDL);
2409 
2410   /* Get tick */
2411   tickstart = HAL_GetTick();
2412 
2413   /* Wait until all active lanes enter ULPM */
2414   if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2415   {
2416     while ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UANC)) != 0U)
2417     {
2418       /* Check for the Timeout */
2419       if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2420       {
2421         /* Process Unlocked */
2422         __HAL_UNLOCK(hdsi);
2423 
2424         return HAL_TIMEOUT;
2425       }
2426     }
2427   }
2428   else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2429   {
2430     while ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1 | DSI_PSR_UANC)) != 0U)
2431     {
2432       /* Check for the Timeout */
2433       if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2434       {
2435         /* Process Unlocked */
2436         __HAL_UNLOCK(hdsi);
2437 
2438         return HAL_TIMEOUT;
2439       }
2440     }
2441   }
2442   else
2443   {
2444     /* Process unlocked */
2445     __HAL_UNLOCK(hdsi);
2446 
2447     return HAL_ERROR;
2448   }
2449 
2450   /* Turn off the DSI PLL */
2451   __HAL_DSI_PLL_DISABLE(hdsi);
2452 
2453   /* Process unlocked */
2454   __HAL_UNLOCK(hdsi);
2455 
2456   return HAL_OK;
2457 }
2458 
2459 /**
2460   * @brief  Exit the ULPM (Ultra Low Power Mode) with the D-PHY PLL turned off
2461   *         (both data and clock lanes are in ULPM)
2462   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2463   *               the configuration information for the DSI.
2464   * @retval HAL status
2465   */
HAL_DSI_ExitULPM(DSI_HandleTypeDef * hdsi)2466 HAL_StatusTypeDef HAL_DSI_ExitULPM(DSI_HandleTypeDef *hdsi)
2467 {
2468   uint32_t tickstart;
2469 
2470   /* Process locked */
2471   __HAL_LOCK(hdsi);
2472 
2473   /* Verify that all active lanes are in ULPM */
2474   if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2475   {
2476     if ((hdsi->Instance->PSR & (DSI_PSR_RUE0 | DSI_PSR_UAN0 | DSI_PSR_PSS0 | \
2477                                 DSI_PSR_UANC | DSI_PSR_PSSC | DSI_PSR_PD)) != 0U)
2478     {
2479       /* Process Unlocked */
2480       __HAL_UNLOCK(hdsi);
2481 
2482       return HAL_ERROR;
2483     }
2484   }
2485   else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2486   {
2487     if ((hdsi->Instance->PSR & (DSI_PSR_RUE0 | DSI_PSR_UAN0 | DSI_PSR_PSS0 | DSI_PSR_UAN1 | \
2488                                 DSI_PSR_PSS1 | DSI_PSR_UANC | DSI_PSR_PSSC | DSI_PSR_PD)) != 0U)
2489     {
2490       /* Process Unlocked */
2491       __HAL_UNLOCK(hdsi);
2492 
2493       return HAL_ERROR;
2494     }
2495   }
2496   else
2497   {
2498     /* Process unlocked */
2499     __HAL_UNLOCK(hdsi);
2500 
2501     return HAL_ERROR;
2502   }
2503 
2504   /* Turn on the DSI PLL */
2505   __HAL_DSI_PLL_ENABLE(hdsi);
2506 
2507   /* Requires min of 400us delay before reading the PLLLS flag */
2508   /* 1ms delay is inserted that is the minimum HAL delay granularity */
2509   HAL_Delay(1);
2510 
2511   /* Get tick */
2512   tickstart = HAL_GetTick();
2513 
2514   /* Wait for the lock of the PLL */
2515   while (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U)
2516   {
2517     /* Check for the Timeout */
2518     if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2519     {
2520       /* Process Unlocked */
2521       __HAL_UNLOCK(hdsi);
2522 
2523       return HAL_TIMEOUT;
2524     }
2525   }
2526 
2527   /* Exit ULPS on Clock and Data Lanes */
2528   hdsi->Instance->PUCR |= (DSI_PUCR_UECL | DSI_PUCR_UEDL);
2529 
2530   /* Get tick */
2531   tickstart = HAL_GetTick();
2532 
2533   /* Wait until all active lanes exit ULPM */
2534   if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2535   {
2536     while ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UANC)) != (DSI_PSR_UAN0 | DSI_PSR_UANC))
2537     {
2538       /* Check for the Timeout */
2539       if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2540       {
2541         /* Process Unlocked */
2542         __HAL_UNLOCK(hdsi);
2543 
2544         return HAL_TIMEOUT;
2545       }
2546     }
2547   }
2548   else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2549   {
2550     while ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1 | DSI_PSR_UANC)) != (DSI_PSR_UAN0 | DSI_PSR_UAN1 |
2551                                                                                     DSI_PSR_UANC))
2552     {
2553       /* Check for the Timeout */
2554       if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2555       {
2556         /* Process Unlocked */
2557         __HAL_UNLOCK(hdsi);
2558 
2559         return HAL_TIMEOUT;
2560       }
2561     }
2562   }
2563   else
2564   {
2565     /* Process unlocked */
2566     __HAL_UNLOCK(hdsi);
2567 
2568     return HAL_ERROR;
2569   }
2570 
2571   /* wait for 1 ms */
2572   HAL_Delay(1U);
2573 
2574   /* De-assert the ULPM requests and the ULPM exit bits */
2575   hdsi->Instance->PUCR = 0U;
2576 
2577   /* Switch the lane byte clock source in the RCC from system PLL to D-PHY */
2578   __HAL_RCC_DSI_CONFIG(RCC_DSICLKSOURCE_DSIPHY);
2579 
2580   /* Restore clock lane configuration to HS */
2581   hdsi->Instance->CLCR |= DSI_CLCR_DPCC;
2582 
2583   /* Verify that D-PHY PLL is enabled */
2584   if ((hdsi->Instance->WRPCR & DSI_WRPCR_PLLEN) != DSI_WRPCR_PLLEN)
2585   {
2586     /* Process Unlocked */
2587     __HAL_UNLOCK(hdsi);
2588     return HAL_ERROR;
2589   }
2590 
2591   /* Verify that all active lanes are in Stop state */
2592   if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2593   {
2594     if ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_PSS0)) != (DSI_PSR_UAN0 | DSI_PSR_PSS0))
2595     {
2596       /* Process Unlocked */
2597       __HAL_UNLOCK(hdsi);
2598       return HAL_ERROR;
2599     }
2600   }
2601   else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2602   {
2603     if ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_PSS0 | DSI_PSR_PSS1 | \
2604                                 DSI_PSR_UAN1)) != (DSI_PSR_UAN0 | DSI_PSR_PSS0 | DSI_PSR_PSS1 | DSI_PSR_UAN1))
2605     {
2606       /* Process Unlocked */
2607       __HAL_UNLOCK(hdsi);
2608       return HAL_ERROR;
2609     }
2610   }
2611   else
2612   {
2613     /* Process unlocked */
2614     __HAL_UNLOCK(hdsi);
2615     return HAL_ERROR;
2616   }
2617 
2618   /* Verify that D-PHY PLL is locked */
2619   /* Requires min of 400us delay before reading the PLLLS flag */
2620   /* 1ms delay is inserted that is the minimum HAL delay granularity */
2621   HAL_Delay(1);
2622 
2623   /* Get tick */
2624   tickstart = HAL_GetTick();
2625 
2626   /* Wait for the lock of the PLL */
2627   while (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U)
2628   {
2629     /* Check for the Timeout */
2630     if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2631     {
2632       /* Process Unlocked */
2633       __HAL_UNLOCK(hdsi);
2634 
2635       return HAL_TIMEOUT;
2636     }
2637   }
2638 
2639   /* Process unlocked */
2640   __HAL_UNLOCK(hdsi);
2641 
2642   return HAL_OK;
2643 }
2644 
2645 /**
2646   * @brief  Start test pattern generation
2647   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2648   *               the configuration information for the DSI.
2649   * @param  Mode  Pattern generator mode
2650   *          This parameter can be one of the following values:
2651   *           0 : Color bars (horizontal or vertical)
2652   *           1 : BER pattern (vertical only)
2653   * @param  Orientation  Pattern generator orientation
2654   *          This parameter can be one of the following values:
2655   *           0 : Vertical color bars
2656   *           1 : Horizontal color bars
2657   * @retval HAL status
2658   */
HAL_DSI_PatternGeneratorStart(DSI_HandleTypeDef * hdsi,uint32_t Mode,uint32_t Orientation)2659 HAL_StatusTypeDef HAL_DSI_PatternGeneratorStart(DSI_HandleTypeDef *hdsi, uint32_t Mode, uint32_t Orientation)
2660 {
2661   /* Process locked */
2662   __HAL_LOCK(hdsi);
2663 
2664   /* Configure pattern generator mode and orientation */
2665   hdsi->Instance->VMCR &= ~(DSI_VMCR_PGM | DSI_VMCR_PGO);
2666   hdsi->Instance->VMCR |= ((Mode << 20U) | (Orientation << 24U));
2667 
2668   /* Enable pattern generator by setting PGE bit */
2669   hdsi->Instance->VMCR |= DSI_VMCR_PGE;
2670 
2671   /* Process unlocked */
2672   __HAL_UNLOCK(hdsi);
2673 
2674   return HAL_OK;
2675 }
2676 
2677 /**
2678   * @brief  Stop test pattern generation
2679   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2680   *               the configuration information for the DSI.
2681   * @retval HAL status
2682   */
HAL_DSI_PatternGeneratorStop(DSI_HandleTypeDef * hdsi)2683 HAL_StatusTypeDef HAL_DSI_PatternGeneratorStop(DSI_HandleTypeDef *hdsi)
2684 {
2685   /* Process locked */
2686   __HAL_LOCK(hdsi);
2687 
2688   /* Disable pattern generator by clearing PGE bit */
2689   hdsi->Instance->VMCR &= ~DSI_VMCR_PGE;
2690 
2691   /* Process unlocked */
2692   __HAL_UNLOCK(hdsi);
2693 
2694   return HAL_OK;
2695 }
2696 
2697 
2698 /**
2699   * @brief  Custom lane pins configuration
2700   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2701   *               the configuration information for the DSI.
2702   * @param  CustomLane  Function to be applied on selected lane.
2703   *                     This parameter can be any value of @arg DSI_CustomLane
2704   * @param  Lane  select between clock or data lane 0 or data lane 1.
2705   *               This parameter can be any value of @arg DSI_Lane_Select
2706   * @param  State  ENABLE or DISABLE
2707   * @retval HAL status
2708   */
HAL_DSI_SetLanePinsConfiguration(DSI_HandleTypeDef * hdsi,uint32_t CustomLane,uint32_t Lane,FunctionalState State)2709 HAL_StatusTypeDef HAL_DSI_SetLanePinsConfiguration(DSI_HandleTypeDef *hdsi, uint32_t CustomLane, uint32_t Lane,
2710                                                    FunctionalState State)
2711 {
2712   /* Process locked */
2713   __HAL_LOCK(hdsi);
2714 
2715   /* Check function parameters */
2716   assert_param(IS_DSI_LANE(Lane));
2717   assert_param(IS_FUNCTIONAL_STATE(State));
2718 
2719   switch (CustomLane)
2720   {
2721     case DSI_SWAP_LANE_PINS:
2722       if (Lane == DSI_CLK_LANE)
2723       {
2724         /* Swap pins on clock lane */
2725         hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_SWCL;
2726         hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 6U);
2727       }
2728       else if (Lane == DSI_DATA_LANE0)
2729       {
2730         /* Swap pins on data lane 0 */
2731         hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_SWDL0;
2732         hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 7U);
2733       }
2734       else if (Lane == DSI_DATA_LANE1)
2735       {
2736         /* Swap pins on data lane 1 */
2737         hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_SWDL1;
2738         hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 8U);
2739       }
2740       else
2741       {
2742         /* Process unlocked */
2743         __HAL_UNLOCK(hdsi);
2744 
2745         return HAL_ERROR;
2746       }
2747       break;
2748     default:
2749       break;
2750   }
2751 
2752   /* Process unlocked */
2753   __HAL_UNLOCK(hdsi);
2754 
2755   return HAL_OK;
2756 }
2757 
2758 
2759 /**
2760   * @brief  Force the Clock/Data Lane in TX Stop Mode
2761   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2762   *               the configuration information for the DSI.
2763   * @param  Lane  select between clock or data lanes.
2764   *               This parameter can be any value of @arg DSI_Lane_Group
2765   * @param  State  ENABLE or DISABLE
2766   * @retval HAL status
2767   */
HAL_DSI_ForceTXStopMode(DSI_HandleTypeDef * hdsi,uint32_t Lane,FunctionalState State)2768 HAL_StatusTypeDef HAL_DSI_ForceTXStopMode(DSI_HandleTypeDef *hdsi, uint32_t Lane, FunctionalState State)
2769 {
2770   /* Process locked */
2771   __HAL_LOCK(hdsi);
2772 
2773   /* Check function parameters */
2774   assert_param(IS_FUNCTIONAL_STATE(State));
2775 
2776   if (Lane == DSI_CLOCK_LANE)
2777   {
2778     /* Force/Unforce the Clock Lane in TX Stop Mode */
2779     hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_FTXSMCL;
2780     hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 12U);
2781   }
2782   else if (Lane == DSI_DATA_LANES)
2783   {
2784     /* Force/Unforce the Data Lanes in TX Stop Mode */
2785     hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_FTXSMDL;
2786     hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 13U);
2787   }
2788   else
2789   {
2790     /* Process unlocked */
2791     __HAL_UNLOCK(hdsi);
2792 
2793     return HAL_ERROR;
2794   }
2795 
2796   /* Process unlocked */
2797   __HAL_UNLOCK(hdsi);
2798 
2799   return HAL_OK;
2800 }
2801 
2802 
2803 /**
2804   * @}
2805   */
2806 
2807 /** @defgroup DSI_Group4 Peripheral State and Errors functions
2808   *  @brief    Peripheral State and Errors functions
2809   *
2810 @verbatim
2811  ===============================================================================
2812                   ##### Peripheral State and Errors functions #####
2813  ===============================================================================
2814     [..]
2815     This subsection provides functions allowing to
2816       (+) Check the DSI state.
2817       (+) Get error code.
2818 
2819 @endverbatim
2820   * @{
2821   */
2822 
2823 /**
2824   * @brief  Return the DSI state
2825   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2826   *               the configuration information for the DSI.
2827   * @retval HAL state
2828   */
HAL_DSI_GetState(DSI_HandleTypeDef * hdsi)2829 HAL_DSI_StateTypeDef HAL_DSI_GetState(DSI_HandleTypeDef *hdsi)
2830 {
2831   return hdsi->State;
2832 }
2833 
2834 /**
2835   * @brief  Return the DSI error code
2836   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2837   *               the configuration information for the DSI.
2838   * @retval DSI Error Code
2839   */
HAL_DSI_GetError(DSI_HandleTypeDef * hdsi)2840 uint32_t HAL_DSI_GetError(DSI_HandleTypeDef *hdsi)
2841 {
2842   /* Get the error code */
2843   return hdsi->ErrorCode;
2844 }
2845 
2846 /**
2847   * @}
2848   */
2849 
2850 /**
2851   * @}
2852   */
2853 
2854 /**
2855   * @}
2856   */
2857 
2858 #endif /* DSI */
2859 
2860 #endif /* HAL_DSI_MODULE_ENABLED */
2861 
2862 /**
2863   * @}
2864   */
2865