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