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