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