1 /**
2   ******************************************************************************
3   * @file    stm32l4xx_hal_dsi.c
4   * @author  MCD Application Team
5   * @brief   DSI HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the DSI peripheral:
8   *           + Initialization and de-initialization functions
9   *           + IO operation functions
10   *           + Peripheral Control functions
11   *           + Peripheral State and Errors functions
12   ******************************************************************************
13   * @attention
14   *
15   * Copyright (c) 2017 STMicroelectronics.
16   * All rights reserved.
17   *
18   * This software is licensed under terms that can be found in the LICENSE file
19   * in the root directory of this software component.
20   * If no LICENSE file comes with this software, it is provided AS-IS.
21   *
22   ******************************************************************************
23   @verbatim
24   ==============================================================================
25                         ##### How to use this driver #####
26   ==============================================================================
27   [..]
28     The DSI HAL driver can be used as follows:
29 
30     (#) Declare a DSI_HandleTypeDef handle structure, for example: DSI_HandleTypeDef  hdsi;
31 
32     (#) Initialize the DSI low level resources by implementing the HAL_DSI_MspInit() API:
33         (##) Enable the DSI interface clock
34         (##) NVIC configuration if you need to use interrupt process
35             (+++) Configure the DSI interrupt priority
36             (+++) Enable the NVIC DSI IRQ Channel
37 
38     (#) Initialize the DSI Host peripheral, the required PLL parameters, number of lances and
39         TX Escape clock divider by calling the HAL_DSI_Init() API which calls HAL_DSI_MspInit().
40 
41     *** Configuration ***
42     =========================
43     [..]
44     (#) Use HAL_DSI_ConfigAdaptedCommandMode() function to configure the DSI host in adapted
45         command mode.
46 
47     (#) When operating in video mode , use HAL_DSI_ConfigVideoMode() to configure the DSI host.
48 
49     (#) Function HAL_DSI_ConfigCommand() is used to configure the DSI commands behavior in low power mode.
50 
51     (#) To configure the DSI PHY timings parameters, use function HAL_DSI_ConfigPhyTimer().
52 
53     (#) The DSI Host can be started/stopped using respectively functions HAL_DSI_Start() and HAL_DSI_Stop().
54         Functions HAL_DSI_ShortWrite(), HAL_DSI_LongWrite() and HAL_DSI_Read() allows respectively
55         to write DSI short packets, long packets and to read DSI packets.
56 
57     (#) The DSI Host Offers two Low power modes :
58         (++) Low Power Mode on data lanes only: Only DSI data lanes are shut down.
59             It is possible to enter/exit from this mode using respectively functions HAL_DSI_EnterULPMData()
60             and HAL_DSI_ExitULPMData()
61 
62         (++) Low Power Mode on data and clock lanes : All DSI lanes are shut down including data and clock lanes.
63             It is possible to enter/exit from this mode using respectively functions HAL_DSI_EnterULPM()
64             and HAL_DSI_ExitULPM()
65 
66     (#) To control DSI state you can use the following function: HAL_DSI_GetState()
67 
68     *** Error management ***
69     ========================
70     [..]
71     (#) User can select the DSI errors to be reported/monitored using function HAL_DSI_ConfigErrorMonitor()
72         When an error occurs, the callback HAL_DSI_ErrorCallback() is asserted and then user can retrieve
73         the error code by calling function HAL_DSI_GetError()
74 
75     *** DSI HAL driver macros list ***
76     =============================================
77     [..]
78        Below the list of most used macros in DSI HAL driver.
79 
80       (+) __HAL_DSI_ENABLE: Enable the DSI Host.
81       (+) __HAL_DSI_DISABLE: Disable the DSI Host.
82       (+) __HAL_DSI_WRAPPER_ENABLE: Enables the DSI wrapper.
83       (+) __HAL_DSI_WRAPPER_DISABLE: Disable the DSI wrapper.
84       (+) __HAL_DSI_PLL_ENABLE: Enables the DSI PLL.
85       (+) __HAL_DSI_PLL_DISABLE: Disables the DSI PLL.
86       (+) __HAL_DSI_REG_ENABLE: Enables the DSI regulator.
87       (+) __HAL_DSI_REG_DISABLE: Disables the DSI regulator.
88       (+) __HAL_DSI_GET_FLAG: Get the DSI pending flags.
89       (+) __HAL_DSI_CLEAR_FLAG: Clears the DSI pending flags.
90       (+) __HAL_DSI_ENABLE_IT: Enables the specified DSI interrupts.
91       (+) __HAL_DSI_DISABLE_IT: Disables the specified DSI interrupts.
92       (+) __HAL_DSI_GET_IT_SOURCE: Checks whether the specified DSI interrupt source is enabled or not.
93 
94     [..]
95       (@) You can refer to the DSI HAL driver header file for more useful macros
96 
97     *** Callback registration ***
98     =============================================
99     [..]
100     The compilation define  USE_HAL_DSI_REGISTER_CALLBACKS when set to 1
101     allows the user to configure dynamically the driver callbacks.
102     Use Function HAL_DSI_RegisterCallback() to register a callback.
103 
104     [..]
105     Function HAL_DSI_RegisterCallback() allows to register following callbacks:
106       (+) TearingEffectCallback : DSI Tearing Effect Callback.
107       (+) EndOfRefreshCallback  : DSI End Of Refresh Callback.
108       (+) ErrorCallback         : DSI Error Callback
109       (+) MspInitCallback       : DSI MspInit.
110       (+) MspDeInitCallback     : DSI MspDeInit.
111     [..]
112     This function takes as parameters the HAL peripheral handle, the callback ID
113     and a pointer to the user callback function.
114 
115     [..]
116     Use function HAL_DSI_UnRegisterCallback() to reset a callback to the default
117     weak function.
118     HAL_DSI_UnRegisterCallback takes as parameters the HAL peripheral handle,
119     and the callback ID.
120     [..]
121     This function allows to reset following callbacks:
122       (+) TearingEffectCallback : DSI Tearing Effect Callback.
123       (+) EndOfRefreshCallback  : DSI End Of Refresh Callback.
124       (+) ErrorCallback         : DSI Error Callback
125       (+) MspInitCallback       : DSI MspInit.
126       (+) MspDeInitCallback     : DSI MspDeInit.
127 
128     [..]
129     By default, after the HAL_DSI_Init and when the state is HAL_DSI_STATE_RESET
130     all callbacks are set to the corresponding weak functions:
131     examples HAL_DSI_TearingEffectCallback(), HAL_DSI_EndOfRefreshCallback().
132     Exception done for MspInit and MspDeInit functions that are respectively
133     reset to the legacy weak (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 "stm32l4xx_hal.h"
158 
159 /** @addtogroup STM32L4xx_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   /* Verify the initial status of the DSI Host */
1839 
1840   /* Verify that the clock lane and the digital section of the D-PHY are enabled */
1841   if ((hdsi->Instance->PCTLR & (DSI_PCTLR_CKE | DSI_PCTLR_DEN)) != (DSI_PCTLR_CKE | DSI_PCTLR_DEN))
1842   {
1843     /* Process Unlocked */
1844     __HAL_UNLOCK(hdsi);
1845     return HAL_ERROR;
1846   }
1847 
1848   /* Verify that the D-PHY PLL and the reference bias are enabled */
1849   if ((hdsi->Instance->WRPCR & DSI_WRPCR_PLLEN) != DSI_WRPCR_PLLEN)
1850   {
1851     /* Process Unlocked */
1852     __HAL_UNLOCK(hdsi);
1853     return HAL_ERROR;
1854   }
1855 
1856   /* Verify that there are no ULPS exit or request on data lanes */
1857   if ((hdsi->Instance->PUCR & (DSI_PUCR_UEDL | DSI_PUCR_URDL)) != 0U)
1858   {
1859     /* Process Unlocked */
1860     __HAL_UNLOCK(hdsi);
1861     return HAL_ERROR;
1862   }
1863 
1864   /* Verify that there are no Transmission trigger */
1865   if ((hdsi->Instance->PTTCR & DSI_PTTCR_TX_TRIG) != 0U)
1866   {
1867     /* Process Unlocked */
1868     __HAL_UNLOCK(hdsi);
1869     return HAL_ERROR;
1870   }
1871 
1872   /* Requires min of 400us delay before reading the PLLLS flag */
1873   /* 1ms delay is inserted that is the minimum HAL delay granularity */
1874   HAL_Delay(1);
1875 
1876   /* Verify that D-PHY PLL is locked */
1877   tickstart = HAL_GetTick();
1878 
1879   while ((__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U))
1880   {
1881     /* Check for the Timeout */
1882     if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
1883     {
1884       /* Process Unlocked */
1885       __HAL_UNLOCK(hdsi);
1886 
1887       return HAL_TIMEOUT;
1888     }
1889   }
1890 
1891   /* Verify that all active lanes are in Stop state */
1892   if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
1893   {
1894     if ((hdsi->Instance->PSR & DSI_PSR_UAN0) != DSI_PSR_UAN0)
1895     {
1896       /* Process Unlocked */
1897       __HAL_UNLOCK(hdsi);
1898       return HAL_ERROR;
1899     }
1900   }
1901   else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
1902   {
1903     if ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1)) != (DSI_PSR_UAN0 | DSI_PSR_UAN1))
1904     {
1905       /* Process Unlocked */
1906       __HAL_UNLOCK(hdsi);
1907       return HAL_ERROR;
1908     }
1909   }
1910   else
1911   {
1912     /* Process unlocked */
1913     __HAL_UNLOCK(hdsi);
1914     return HAL_ERROR;
1915   }
1916 
1917   /* ULPS Request on Data Lanes */
1918   hdsi->Instance->PUCR |= DSI_PUCR_URDL;
1919 
1920   /* Get tick */
1921   tickstart = HAL_GetTick();
1922 
1923   /* Wait until the D-PHY active lanes enter into ULPM */
1924   if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
1925   {
1926     while ((hdsi->Instance->PSR & DSI_PSR_UAN0) != 0U)
1927     {
1928       /* Check for the Timeout */
1929       if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
1930       {
1931         /* Process Unlocked */
1932         __HAL_UNLOCK(hdsi);
1933 
1934         return HAL_TIMEOUT;
1935       }
1936     }
1937   }
1938   else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
1939   {
1940     while ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1)) != 0U)
1941     {
1942       /* Check for the Timeout */
1943       if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
1944       {
1945         /* Process Unlocked */
1946         __HAL_UNLOCK(hdsi);
1947 
1948         return HAL_TIMEOUT;
1949       }
1950     }
1951   }
1952   else
1953   {
1954     /* Process unlocked */
1955     __HAL_UNLOCK(hdsi);
1956 
1957     return HAL_ERROR;
1958   }
1959 
1960   /* Process unlocked */
1961   __HAL_UNLOCK(hdsi);
1962 
1963   return HAL_OK;
1964 }
1965 
1966 /**
1967   * @brief  Exit the ULPM (Ultra Low Power Mode) with the D-PHY PLL running
1968   *         (only data lanes are in ULPM)
1969   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
1970   *               the configuration information for the DSI.
1971   * @retval HAL status
1972   */
HAL_DSI_ExitULPMData(DSI_HandleTypeDef * hdsi)1973 HAL_StatusTypeDef HAL_DSI_ExitULPMData(DSI_HandleTypeDef *hdsi)
1974 {
1975   uint32_t tickstart;
1976 
1977   /* Process locked */
1978   __HAL_LOCK(hdsi);
1979 
1980   /* Verify that all active lanes are in ULPM */
1981   if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
1982   {
1983     if ((hdsi->Instance->PSR &  DSI_PSR_UAN0) != 0U)
1984     {
1985       /* Process Unlocked */
1986       __HAL_UNLOCK(hdsi);
1987 
1988       return HAL_ERROR;
1989     }
1990   }
1991   else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
1992   {
1993     if ((hdsi->Instance->PSR & (DSI_PSR_UAN0  | DSI_PSR_UAN1)) != 0U)
1994     {
1995       /* Process Unlocked */
1996       __HAL_UNLOCK(hdsi);
1997 
1998       return HAL_ERROR;
1999     }
2000   }
2001   else
2002   {
2003     /* Process unlocked */
2004     __HAL_UNLOCK(hdsi);
2005 
2006     return HAL_ERROR;
2007   }
2008 
2009   /* Turn on the DSI PLL */
2010   __HAL_DSI_PLL_ENABLE(hdsi);
2011 
2012   /* Requires min of 400us delay before reading the PLLLS flag */
2013   /* 1ms delay is inserted that is the minimum HAL delay granularity */
2014   HAL_Delay(1);
2015 
2016   /* Get tick */
2017   tickstart = HAL_GetTick();
2018 
2019   /* Wait for the lock of the PLL */
2020   while (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U)
2021   {
2022     /* Check for the Timeout */
2023     if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2024     {
2025       /* Process Unlocked */
2026       __HAL_UNLOCK(hdsi);
2027 
2028       return HAL_TIMEOUT;
2029     }
2030   }
2031 
2032   /* Exit ULPS on Data Lanes */
2033   hdsi->Instance->PUCR |= DSI_PUCR_UEDL;
2034 
2035   /* Get tick */
2036   tickstart = HAL_GetTick();
2037 
2038   /* Wait until all active lanes exit ULPM */
2039   if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2040   {
2041     while ((hdsi->Instance->PSR & DSI_PSR_UAN0) != DSI_PSR_UAN0)
2042     {
2043       /* Check for the Timeout */
2044       if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2045       {
2046         /* Process Unlocked */
2047         __HAL_UNLOCK(hdsi);
2048 
2049         return HAL_TIMEOUT;
2050       }
2051     }
2052   }
2053   else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2054   {
2055     while ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1)) != (DSI_PSR_UAN0 | DSI_PSR_UAN1))
2056     {
2057       /* Check for the Timeout */
2058       if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2059       {
2060         /* Process Unlocked */
2061         __HAL_UNLOCK(hdsi);
2062 
2063         return HAL_TIMEOUT;
2064       }
2065     }
2066   }
2067   else
2068   {
2069     /* Process unlocked */
2070     __HAL_UNLOCK(hdsi);
2071 
2072     return HAL_ERROR;
2073   }
2074 
2075   /* wait for 1 ms*/
2076   HAL_Delay(1U);
2077 
2078   /* De-assert the ULPM requests and the ULPM exit bits */
2079   hdsi->Instance->PUCR = 0U;
2080 
2081   /* Verify that D-PHY PLL is enabled */
2082   if ((hdsi->Instance->WRPCR & DSI_WRPCR_PLLEN) != DSI_WRPCR_PLLEN)
2083   {
2084     /* Process Unlocked */
2085     __HAL_UNLOCK(hdsi);
2086     return HAL_ERROR;
2087   }
2088 
2089   /* Verify that all active lanes are in Stop state */
2090   if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2091   {
2092     if ((hdsi->Instance->PSR & DSI_PSR_UAN0) != DSI_PSR_UAN0)
2093     {
2094       /* Process Unlocked */
2095       __HAL_UNLOCK(hdsi);
2096       return HAL_ERROR;
2097     }
2098   }
2099   else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2100   {
2101     if ((hdsi->Instance->PSR & (DSI_PSR_UAN0  |  DSI_PSR_UAN1)) != (DSI_PSR_UAN0 | DSI_PSR_UAN1))
2102     {
2103       /* Process Unlocked */
2104       __HAL_UNLOCK(hdsi);
2105       return HAL_ERROR;
2106     }
2107   }
2108   else
2109   {
2110     /* Process unlocked */
2111     __HAL_UNLOCK(hdsi);
2112     return HAL_ERROR;
2113   }
2114 
2115   /* Verify that D-PHY PLL is locked */
2116   /* Requires min of 400us delay before reading the PLLLS flag */
2117   /* 1ms delay is inserted that is the minimum HAL delay granularity */
2118   HAL_Delay(1);
2119 
2120   /* Get tick */
2121   tickstart = HAL_GetTick();
2122 
2123   /* Wait for the lock of the PLL */
2124   while (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U)
2125   {
2126     /* Check for the Timeout */
2127     if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2128     {
2129       /* Process Unlocked */
2130       __HAL_UNLOCK(hdsi);
2131 
2132       return HAL_TIMEOUT;
2133     }
2134   }
2135 
2136   /* Process unlocked */
2137   __HAL_UNLOCK(hdsi);
2138 
2139   return HAL_OK;
2140 }
2141 
2142 /**
2143   * @brief  Enter the ULPM (Ultra Low Power Mode) with the D-PHY PLL turned off
2144   *         (both data and clock lanes are in ULPM)
2145   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2146   *               the configuration information for the DSI.
2147   * @retval HAL status
2148   */
HAL_DSI_EnterULPM(DSI_HandleTypeDef * hdsi)2149 HAL_StatusTypeDef HAL_DSI_EnterULPM(DSI_HandleTypeDef *hdsi)
2150 {
2151   uint32_t tickstart;
2152 
2153   /* Process locked */
2154   __HAL_LOCK(hdsi);
2155 
2156   /* Verify the initial status of the DSI Host */
2157 
2158   /* Verify that the clock lane and the digital section of the D-PHY are enabled */
2159   if ((hdsi->Instance->PCTLR & (DSI_PCTLR_CKE | DSI_PCTLR_DEN)) != (DSI_PCTLR_CKE | DSI_PCTLR_DEN))
2160   {
2161     /* Process Unlocked */
2162     __HAL_UNLOCK(hdsi);
2163     return HAL_ERROR;
2164   }
2165 
2166   /* Verify that the D-PHY PLL and the reference bias are enabled */
2167   if ((hdsi->Instance->WRPCR & DSI_WRPCR_PLLEN) != DSI_WRPCR_PLLEN)
2168   {
2169     /* Process Unlocked */
2170     __HAL_UNLOCK(hdsi);
2171     return HAL_ERROR;
2172   }
2173 
2174   /* Verify that there are no ULPS exit or request on both data and clock lanes */
2175   if ((hdsi->Instance->PUCR & (DSI_PUCR_UEDL | DSI_PUCR_URDL | DSI_PUCR_UECL | DSI_PUCR_URCL)) != 0U)
2176   {
2177     /* Process Unlocked */
2178     __HAL_UNLOCK(hdsi);
2179     return HAL_ERROR;
2180   }
2181 
2182   /* Verify that there are no Transmission trigger */
2183   if ((hdsi->Instance->PTTCR & DSI_PTTCR_TX_TRIG) != 0U)
2184   {
2185     /* Process Unlocked */
2186     __HAL_UNLOCK(hdsi);
2187     return HAL_ERROR;
2188   }
2189 
2190   /* Requires min of 400us delay before reading the PLLLS flag */
2191   /* 1ms delay is inserted that is the minimum HAL delay granularity */
2192   HAL_Delay(1);
2193 
2194   /* Verify that D-PHY PLL is locked */
2195   tickstart = HAL_GetTick();
2196 
2197   while ((__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U))
2198   {
2199     /* Check for the Timeout */
2200     if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2201     {
2202       /* Process Unlocked */
2203       __HAL_UNLOCK(hdsi);
2204 
2205       return HAL_TIMEOUT;
2206     }
2207   }
2208 
2209   /* Verify that all active lanes are in Stop state */
2210   if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2211   {
2212     if ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_PSS0)) != (DSI_PSR_UAN0 | DSI_PSR_PSS0))
2213     {
2214       /* Process Unlocked */
2215       __HAL_UNLOCK(hdsi);
2216       return HAL_ERROR;
2217     }
2218   }
2219   else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2220   {
2221     if ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_PSS0 | DSI_PSR_PSS1 | \
2222                                 DSI_PSR_UAN1)) != (DSI_PSR_UAN0 | DSI_PSR_PSS0 | DSI_PSR_PSS1 | DSI_PSR_UAN1))
2223     {
2224       /* Process Unlocked */
2225       __HAL_UNLOCK(hdsi);
2226       return HAL_ERROR;
2227     }
2228   }
2229   else
2230   {
2231     /* Process unlocked */
2232     __HAL_UNLOCK(hdsi);
2233     return HAL_ERROR;
2234   }
2235 
2236   /* Clock lane configuration: no more HS request */
2237   hdsi->Instance->CLCR &= ~DSI_CLCR_DPCC;
2238 
2239   /* Use system PLL as byte lane clock source before stopping DSIPHY clock source */
2240   __HAL_RCC_DSI_CONFIG(RCC_DSICLKSOURCE_PLLSAI2);
2241 
2242   /* ULPS Request on Clock and Data Lanes */
2243   hdsi->Instance->PUCR |= (DSI_PUCR_URCL | DSI_PUCR_URDL);
2244 
2245   /* Get tick */
2246   tickstart = HAL_GetTick();
2247 
2248   /* Wait until all active lanes enter ULPM */
2249   if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2250   {
2251     while ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UANC)) != 0U)
2252     {
2253       /* Check for the Timeout */
2254       if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2255       {
2256         /* Process Unlocked */
2257         __HAL_UNLOCK(hdsi);
2258 
2259         return HAL_TIMEOUT;
2260       }
2261     }
2262   }
2263   else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2264   {
2265     while ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1 | DSI_PSR_UANC)) != 0U)
2266     {
2267       /* Check for the Timeout */
2268       if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2269       {
2270         /* Process Unlocked */
2271         __HAL_UNLOCK(hdsi);
2272 
2273         return HAL_TIMEOUT;
2274       }
2275     }
2276   }
2277   else
2278   {
2279     /* Process unlocked */
2280     __HAL_UNLOCK(hdsi);
2281 
2282     return HAL_ERROR;
2283   }
2284 
2285   /* Turn off the DSI PLL */
2286   __HAL_DSI_PLL_DISABLE(hdsi);
2287 
2288   /* Process unlocked */
2289   __HAL_UNLOCK(hdsi);
2290 
2291   return HAL_OK;
2292 }
2293 
2294 /**
2295   * @brief  Exit the ULPM (Ultra Low Power Mode) with the D-PHY PLL turned off
2296   *         (both data and clock lanes are in ULPM)
2297   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2298   *               the configuration information for the DSI.
2299   * @retval HAL status
2300   */
HAL_DSI_ExitULPM(DSI_HandleTypeDef * hdsi)2301 HAL_StatusTypeDef HAL_DSI_ExitULPM(DSI_HandleTypeDef *hdsi)
2302 {
2303   uint32_t tickstart;
2304 
2305   /* Process locked */
2306   __HAL_LOCK(hdsi);
2307 
2308   /* Verify that all active lanes are in ULPM */
2309   if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2310   {
2311     if ((hdsi->Instance->PSR & (DSI_PSR_RUE0 | DSI_PSR_UAN0 | DSI_PSR_PSS0 | \
2312                                 DSI_PSR_UANC | DSI_PSR_PSSC | DSI_PSR_PD)) != 0U)
2313     {
2314       /* Process Unlocked */
2315       __HAL_UNLOCK(hdsi);
2316 
2317       return HAL_ERROR;
2318     }
2319   }
2320   else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2321   {
2322     if ((hdsi->Instance->PSR & (DSI_PSR_RUE0 | DSI_PSR_UAN0 | DSI_PSR_PSS0 | DSI_PSR_UAN1 | \
2323                                 DSI_PSR_PSS1 | DSI_PSR_UANC | DSI_PSR_PSSC | DSI_PSR_PD)) != 0U)
2324     {
2325       /* Process Unlocked */
2326       __HAL_UNLOCK(hdsi);
2327 
2328       return HAL_ERROR;
2329     }
2330   }
2331   else
2332   {
2333     /* Process unlocked */
2334     __HAL_UNLOCK(hdsi);
2335 
2336     return HAL_ERROR;
2337   }
2338 
2339   /* Turn on the DSI PLL */
2340   __HAL_DSI_PLL_ENABLE(hdsi);
2341 
2342   /* Requires min of 400us delay before reading the PLLLS flag */
2343   /* 1ms delay is inserted that is the minimum HAL delay granularity */
2344   HAL_Delay(1);
2345 
2346   /* Get tick */
2347   tickstart = HAL_GetTick();
2348 
2349   /* Wait for the lock of the PLL */
2350   while (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U)
2351   {
2352     /* Check for the Timeout */
2353     if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2354     {
2355       /* Process Unlocked */
2356       __HAL_UNLOCK(hdsi);
2357 
2358       return HAL_TIMEOUT;
2359     }
2360   }
2361 
2362   /* Exit ULPS on Clock and Data Lanes */
2363   hdsi->Instance->PUCR |= (DSI_PUCR_UECL | DSI_PUCR_UEDL);
2364 
2365   /* Get tick */
2366   tickstart = HAL_GetTick();
2367 
2368   /* Wait until all active lanes exit ULPM */
2369   if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2370   {
2371     while ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UANC)) != (DSI_PSR_UAN0 | DSI_PSR_UANC))
2372     {
2373       /* Check for the Timeout */
2374       if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2375       {
2376         /* Process Unlocked */
2377         __HAL_UNLOCK(hdsi);
2378 
2379         return HAL_TIMEOUT;
2380       }
2381     }
2382   }
2383   else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2384   {
2385     while ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_UAN1 | DSI_PSR_UANC)) != (DSI_PSR_UAN0 | DSI_PSR_UAN1 |
2386                                                                                     DSI_PSR_UANC))
2387     {
2388       /* Check for the Timeout */
2389       if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2390       {
2391         /* Process Unlocked */
2392         __HAL_UNLOCK(hdsi);
2393 
2394         return HAL_TIMEOUT;
2395       }
2396     }
2397   }
2398   else
2399   {
2400     /* Process unlocked */
2401     __HAL_UNLOCK(hdsi);
2402 
2403     return HAL_ERROR;
2404   }
2405 
2406   /* wait for 1 ms */
2407   HAL_Delay(1U);
2408 
2409   /* De-assert the ULPM requests and the ULPM exit bits */
2410   hdsi->Instance->PUCR = 0U;
2411 
2412   /* Switch the lane byte clock source in the RCC from system PLL to D-PHY */
2413   __HAL_RCC_DSI_CONFIG(RCC_DSICLKSOURCE_DSIPHY);
2414 
2415   /* Restore clock lane configuration to HS */
2416   hdsi->Instance->CLCR |= DSI_CLCR_DPCC;
2417 
2418   /* Verify that D-PHY PLL is enabled */
2419   if ((hdsi->Instance->WRPCR & DSI_WRPCR_PLLEN) != DSI_WRPCR_PLLEN)
2420   {
2421     /* Process Unlocked */
2422     __HAL_UNLOCK(hdsi);
2423     return HAL_ERROR;
2424   }
2425 
2426   /* Verify that all active lanes are in Stop state */
2427   if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_ONE_DATA_LANE)
2428   {
2429     if ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_PSS0)) != (DSI_PSR_UAN0 | DSI_PSR_PSS0))
2430     {
2431       /* Process Unlocked */
2432       __HAL_UNLOCK(hdsi);
2433       return HAL_ERROR;
2434     }
2435   }
2436   else if ((hdsi->Instance->PCONFR & DSI_PCONFR_NL) == DSI_TWO_DATA_LANES)
2437   {
2438     if ((hdsi->Instance->PSR & (DSI_PSR_UAN0 | DSI_PSR_PSS0 | DSI_PSR_PSS1 | \
2439                                 DSI_PSR_UAN1)) != (DSI_PSR_UAN0 | DSI_PSR_PSS0 | DSI_PSR_PSS1 | DSI_PSR_UAN1))
2440     {
2441       /* Process Unlocked */
2442       __HAL_UNLOCK(hdsi);
2443       return HAL_ERROR;
2444     }
2445   }
2446   else
2447   {
2448     /* Process unlocked */
2449     __HAL_UNLOCK(hdsi);
2450     return HAL_ERROR;
2451   }
2452 
2453   /* Verify that D-PHY PLL is locked */
2454   /* Requires min of 400us delay before reading the PLLLS flag */
2455   /* 1ms delay is inserted that is the minimum HAL delay granularity */
2456   HAL_Delay(1);
2457 
2458   /* Get tick */
2459   tickstart = HAL_GetTick();
2460 
2461   /* Wait for the lock of the PLL */
2462   while (__HAL_DSI_GET_FLAG(hdsi, DSI_FLAG_PLLLS) == 0U)
2463   {
2464     /* Check for the Timeout */
2465     if ((HAL_GetTick() - tickstart) > DSI_TIMEOUT_VALUE)
2466     {
2467       /* Process Unlocked */
2468       __HAL_UNLOCK(hdsi);
2469 
2470       return HAL_TIMEOUT;
2471     }
2472   }
2473 
2474   /* Process unlocked */
2475   __HAL_UNLOCK(hdsi);
2476 
2477   return HAL_OK;
2478 }
2479 
2480 /**
2481   * @brief  Start test pattern generation
2482   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2483   *               the configuration information for the DSI.
2484   * @param  Mode  Pattern generator mode
2485   *          This parameter can be one of the following values:
2486   *           0 : Color bars (horizontal or vertical)
2487   *           1 : BER pattern (vertical only)
2488   * @param  Orientation  Pattern generator orientation
2489   *          This parameter can be one of the following values:
2490   *           0 : Vertical color bars
2491   *           1 : Horizontal color bars
2492   * @retval HAL status
2493   */
HAL_DSI_PatternGeneratorStart(DSI_HandleTypeDef * hdsi,uint32_t Mode,uint32_t Orientation)2494 HAL_StatusTypeDef HAL_DSI_PatternGeneratorStart(DSI_HandleTypeDef *hdsi, uint32_t Mode, uint32_t Orientation)
2495 {
2496   /* Process locked */
2497   __HAL_LOCK(hdsi);
2498 
2499   /* Configure pattern generator mode and orientation */
2500   hdsi->Instance->VMCR &= ~(DSI_VMCR_PGM | DSI_VMCR_PGO);
2501   hdsi->Instance->VMCR |= ((Mode << 20U) | (Orientation << 24U));
2502 
2503   /* Enable pattern generator by setting PGE bit */
2504   hdsi->Instance->VMCR |= DSI_VMCR_PGE;
2505 
2506   /* Process unlocked */
2507   __HAL_UNLOCK(hdsi);
2508 
2509   return HAL_OK;
2510 }
2511 
2512 /**
2513   * @brief  Stop test pattern generation
2514   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2515   *               the configuration information for the DSI.
2516   * @retval HAL status
2517   */
HAL_DSI_PatternGeneratorStop(DSI_HandleTypeDef * hdsi)2518 HAL_StatusTypeDef HAL_DSI_PatternGeneratorStop(DSI_HandleTypeDef *hdsi)
2519 {
2520   /* Process locked */
2521   __HAL_LOCK(hdsi);
2522 
2523   /* Disable pattern generator by clearing PGE bit */
2524   hdsi->Instance->VMCR &= ~DSI_VMCR_PGE;
2525 
2526   /* Process unlocked */
2527   __HAL_UNLOCK(hdsi);
2528 
2529   return HAL_OK;
2530 }
2531 
2532 /**
2533   * @brief  Set Slew-Rate And Delay Tuning
2534   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2535   *               the configuration information for the DSI.
2536   * @param  CommDelay  Communication delay to be adjusted.
2537   *                    This parameter can be any value of @arg DSI_Communication_Delay
2538   * @param  Lane  select between clock or data lanes.
2539   *               This parameter can be any value of @arg DSI_Lane_Group
2540   * @param  Value  Custom value of the slew-rate or delay
2541   * @retval HAL status
2542   */
HAL_DSI_SetSlewRateAndDelayTuning(DSI_HandleTypeDef * hdsi,uint32_t CommDelay,uint32_t Lane,uint32_t Value)2543 HAL_StatusTypeDef HAL_DSI_SetSlewRateAndDelayTuning(DSI_HandleTypeDef *hdsi, uint32_t CommDelay, uint32_t Lane,
2544                                                     uint32_t Value)
2545 {
2546   /* Process locked */
2547   __HAL_LOCK(hdsi);
2548 
2549   /* Check function parameters */
2550   assert_param(IS_DSI_COMMUNICATION_DELAY(CommDelay));
2551   assert_param(IS_DSI_LANE_GROUP(Lane));
2552 
2553   switch (CommDelay)
2554   {
2555     case DSI_SLEW_RATE_HSTX:
2556       if (Lane == DSI_CLOCK_LANE)
2557       {
2558         /* High-Speed Transmission Slew Rate Control on Clock Lane */
2559         hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_HSTXSRCCL;
2560         hdsi->Instance->WPCR[1U] |= Value << 16U;
2561       }
2562       else if (Lane == DSI_DATA_LANES)
2563       {
2564         /* High-Speed Transmission Slew Rate Control on Data Lanes */
2565         hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_HSTXSRCDL;
2566         hdsi->Instance->WPCR[1U] |= Value << 18U;
2567       }
2568       else
2569       {
2570         /* Process unlocked */
2571         __HAL_UNLOCK(hdsi);
2572 
2573         return HAL_ERROR;
2574       }
2575       break;
2576     case DSI_SLEW_RATE_LPTX:
2577       if (Lane == DSI_CLOCK_LANE)
2578       {
2579         /* Low-Power transmission Slew Rate Compensation on Clock Lane */
2580         hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_LPSRCCL;
2581         hdsi->Instance->WPCR[1U] |= Value << 6U;
2582       }
2583       else if (Lane == DSI_DATA_LANES)
2584       {
2585         /* Low-Power transmission Slew Rate Compensation on Data Lanes */
2586         hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_LPSRCDL;
2587         hdsi->Instance->WPCR[1U] |= Value << 8U;
2588       }
2589       else
2590       {
2591         /* Process unlocked */
2592         __HAL_UNLOCK(hdsi);
2593 
2594         return HAL_ERROR;
2595       }
2596       break;
2597     case DSI_HS_DELAY:
2598       if (Lane == DSI_CLOCK_LANE)
2599       {
2600         /* High-Speed Transmission Delay on Clock Lane */
2601         hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_HSTXDCL;
2602         hdsi->Instance->WPCR[1U] |= Value;
2603       }
2604       else if (Lane == DSI_DATA_LANES)
2605       {
2606         /* High-Speed Transmission Delay on Data Lanes */
2607         hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_HSTXDDL;
2608         hdsi->Instance->WPCR[1U] |= Value << 2U;
2609       }
2610       else
2611       {
2612         /* Process unlocked */
2613         __HAL_UNLOCK(hdsi);
2614 
2615         return HAL_ERROR;
2616       }
2617       break;
2618     default:
2619       break;
2620   }
2621 
2622   /* Process unlocked */
2623   __HAL_UNLOCK(hdsi);
2624 
2625   return HAL_OK;
2626 }
2627 
2628 /**
2629   * @brief  Low-Power Reception Filter Tuning
2630   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2631   *               the configuration information for the DSI.
2632   * @param  Frequency  cutoff frequency of low-pass filter at the input of LPRX
2633   * @retval HAL status
2634   */
HAL_DSI_SetLowPowerRXFilter(DSI_HandleTypeDef * hdsi,uint32_t Frequency)2635 HAL_StatusTypeDef HAL_DSI_SetLowPowerRXFilter(DSI_HandleTypeDef *hdsi, uint32_t Frequency)
2636 {
2637   /* Process locked */
2638   __HAL_LOCK(hdsi);
2639 
2640   /* Low-Power RX low-pass Filtering Tuning */
2641   hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_LPRXFT;
2642   hdsi->Instance->WPCR[1U] |= Frequency << 25U;
2643 
2644   /* Process unlocked */
2645   __HAL_UNLOCK(hdsi);
2646 
2647   return HAL_OK;
2648 }
2649 
2650 /**
2651   * @brief  Activate an additional current path on all lanes to meet the SDDTx parameter
2652   *         defined in the MIPI D-PHY specification
2653   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2654   *               the configuration information for the DSI.
2655   * @param  State  ENABLE or DISABLE
2656   * @retval HAL status
2657   */
HAL_DSI_SetSDD(DSI_HandleTypeDef * hdsi,FunctionalState State)2658 HAL_StatusTypeDef HAL_DSI_SetSDD(DSI_HandleTypeDef *hdsi, FunctionalState State)
2659 {
2660   /* Process locked */
2661   __HAL_LOCK(hdsi);
2662 
2663   /* Check function parameters */
2664   assert_param(IS_FUNCTIONAL_STATE(State));
2665 
2666   /* Activate/Disactivate additional current path on all lanes */
2667   hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_SDDC;
2668   hdsi->Instance->WPCR[1U] |= ((uint32_t)State << 12U);
2669 
2670   /* Process unlocked */
2671   __HAL_UNLOCK(hdsi);
2672 
2673   return HAL_OK;
2674 }
2675 
2676 /**
2677   * @brief  Custom lane pins configuration
2678   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2679   *               the configuration information for the DSI.
2680   * @param  CustomLane  Function to be applied on selected lane.
2681   *                     This parameter can be any value of @arg DSI_CustomLane
2682   * @param  Lane  select between clock or data lane 0 or data lane 1.
2683   *               This parameter can be any value of @arg DSI_Lane_Select
2684   * @param  State  ENABLE or DISABLE
2685   * @retval HAL status
2686   */
HAL_DSI_SetLanePinsConfiguration(DSI_HandleTypeDef * hdsi,uint32_t CustomLane,uint32_t Lane,FunctionalState State)2687 HAL_StatusTypeDef HAL_DSI_SetLanePinsConfiguration(DSI_HandleTypeDef *hdsi, uint32_t CustomLane, uint32_t Lane,
2688                                                    FunctionalState State)
2689 {
2690   /* Process locked */
2691   __HAL_LOCK(hdsi);
2692 
2693   /* Check function parameters */
2694   assert_param(IS_DSI_CUSTOM_LANE(CustomLane));
2695   assert_param(IS_DSI_LANE(Lane));
2696   assert_param(IS_FUNCTIONAL_STATE(State));
2697 
2698   switch (CustomLane)
2699   {
2700     case DSI_SWAP_LANE_PINS:
2701       if (Lane == DSI_CLK_LANE)
2702       {
2703         /* Swap pins on clock lane */
2704         hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_SWCL;
2705         hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 6U);
2706       }
2707       else if (Lane == DSI_DATA_LANE0)
2708       {
2709         /* Swap pins on data lane 0 */
2710         hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_SWDL0;
2711         hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 7U);
2712       }
2713       else if (Lane == DSI_DATA_LANE1)
2714       {
2715         /* Swap pins on data lane 1 */
2716         hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_SWDL1;
2717         hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 8U);
2718       }
2719       else
2720       {
2721         /* Process unlocked */
2722         __HAL_UNLOCK(hdsi);
2723 
2724         return HAL_ERROR;
2725       }
2726       break;
2727     case DSI_INVERT_HS_SIGNAL:
2728       if (Lane == DSI_CLK_LANE)
2729       {
2730         /* Invert HS signal on clock lane */
2731         hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_HSICL;
2732         hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 9U);
2733       }
2734       else if (Lane == DSI_DATA_LANE0)
2735       {
2736         /* Invert HS signal on data lane 0 */
2737         hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_HSIDL0;
2738         hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 10U);
2739       }
2740       else if (Lane == DSI_DATA_LANE1)
2741       {
2742         /* Invert HS signal on data lane 1 */
2743         hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_HSIDL1;
2744         hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 11U);
2745       }
2746       else
2747       {
2748         /* Process unlocked */
2749         __HAL_UNLOCK(hdsi);
2750 
2751         return HAL_ERROR;
2752       }
2753       break;
2754     default:
2755       break;
2756   }
2757 
2758   /* Process unlocked */
2759   __HAL_UNLOCK(hdsi);
2760 
2761   return HAL_OK;
2762 }
2763 
2764 /**
2765   * @brief  Set custom timing for the PHY
2766   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2767   *               the configuration information for the DSI.
2768   * @param  Timing  PHY timing to be adjusted.
2769   *                 This parameter can be any value of @arg DSI_PHY_Timing
2770   * @param  State  ENABLE or DISABLE
2771   * @param  Value  Custom value of the timing
2772   * @retval HAL status
2773   */
HAL_DSI_SetPHYTimings(DSI_HandleTypeDef * hdsi,uint32_t Timing,FunctionalState State,uint32_t Value)2774 HAL_StatusTypeDef HAL_DSI_SetPHYTimings(DSI_HandleTypeDef *hdsi, uint32_t Timing, FunctionalState State, uint32_t Value)
2775 {
2776   /* Process locked */
2777   __HAL_LOCK(hdsi);
2778 
2779   /* Check function parameters */
2780   assert_param(IS_DSI_PHY_TIMING(Timing));
2781   assert_param(IS_FUNCTIONAL_STATE(State));
2782 
2783   switch (Timing)
2784   {
2785     case DSI_TCLK_POST:
2786       /* Enable/Disable custom timing setting */
2787       hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_TCLKPOSTEN;
2788       hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 27U);
2789 
2790       if (State != DISABLE)
2791       {
2792         /* Set custom value */
2793         hdsi->Instance->WPCR[4U] &= ~DSI_WPCR4_TCLKPOST;
2794         hdsi->Instance->WPCR[4U] |= Value & DSI_WPCR4_TCLKPOST;
2795       }
2796 
2797       break;
2798     case DSI_TLPX_CLK:
2799       /* Enable/Disable custom timing setting */
2800       hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_TLPXCEN;
2801       hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 26U);
2802 
2803       if (State != DISABLE)
2804       {
2805         /* Set custom value */
2806         hdsi->Instance->WPCR[3U] &= ~DSI_WPCR3_TLPXC;
2807         hdsi->Instance->WPCR[3U] |= (Value << 24U) & DSI_WPCR3_TLPXC;
2808       }
2809 
2810       break;
2811     case DSI_THS_EXIT:
2812       /* Enable/Disable custom timing setting */
2813       hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_THSEXITEN;
2814       hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 25U);
2815 
2816       if (State != DISABLE)
2817       {
2818         /* Set custom value */
2819         hdsi->Instance->WPCR[3U] &= ~DSI_WPCR3_THSEXIT;
2820         hdsi->Instance->WPCR[3U] |= (Value << 16U) & DSI_WPCR3_THSEXIT;
2821       }
2822 
2823       break;
2824     case DSI_TLPX_DATA:
2825       /* Enable/Disable custom timing setting */
2826       hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_TLPXDEN;
2827       hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 24U);
2828 
2829       if (State != DISABLE)
2830       {
2831         /* Set custom value */
2832         hdsi->Instance->WPCR[3U] &= ~DSI_WPCR3_TLPXD;
2833         hdsi->Instance->WPCR[3U] |= (Value << 8U) & DSI_WPCR3_TLPXD;
2834       }
2835 
2836       break;
2837     case DSI_THS_ZERO:
2838       /* Enable/Disable custom timing setting */
2839       hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_THSZEROEN;
2840       hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 23U);
2841 
2842       if (State != DISABLE)
2843       {
2844         /* Set custom value */
2845         hdsi->Instance->WPCR[3U] &= ~DSI_WPCR3_THSZERO;
2846         hdsi->Instance->WPCR[3U] |= Value & DSI_WPCR3_THSZERO;
2847       }
2848 
2849       break;
2850     case DSI_THS_TRAIL:
2851       /* Enable/Disable custom timing setting */
2852       hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_THSTRAILEN;
2853       hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 22U);
2854 
2855       if (State != DISABLE)
2856       {
2857         /* Set custom value */
2858         hdsi->Instance->WPCR[2U] &= ~DSI_WPCR2_THSTRAIL;
2859         hdsi->Instance->WPCR[2U] |= (Value << 24U) & DSI_WPCR2_THSTRAIL;
2860       }
2861 
2862       break;
2863     case DSI_THS_PREPARE:
2864       /* Enable/Disable custom timing setting */
2865       hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_THSPREPEN;
2866       hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 21U);
2867 
2868       if (State != DISABLE)
2869       {
2870         /* Set custom value */
2871         hdsi->Instance->WPCR[2U] &= ~DSI_WPCR2_THSPREP;
2872         hdsi->Instance->WPCR[2U] |= (Value << 16U) & DSI_WPCR2_THSPREP;
2873       }
2874 
2875       break;
2876     case DSI_TCLK_ZERO:
2877       /* Enable/Disable custom timing setting */
2878       hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_TCLKZEROEN;
2879       hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 20U);
2880 
2881       if (State != DISABLE)
2882       {
2883         /* Set custom value */
2884         hdsi->Instance->WPCR[2U] &= ~DSI_WPCR2_TCLKZERO;
2885         hdsi->Instance->WPCR[2U] |= (Value << 8U) & DSI_WPCR2_TCLKZERO;
2886       }
2887 
2888       break;
2889     case DSI_TCLK_PREPARE:
2890       /* Enable/Disable custom timing setting */
2891       hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_TCLKPREPEN;
2892       hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 19U);
2893 
2894       if (State != DISABLE)
2895       {
2896         /* Set custom value */
2897         hdsi->Instance->WPCR[2U] &= ~DSI_WPCR2_TCLKPREP;
2898         hdsi->Instance->WPCR[2U] |= Value & DSI_WPCR2_TCLKPREP;
2899       }
2900 
2901       break;
2902     default:
2903       break;
2904   }
2905 
2906   /* Process unlocked */
2907   __HAL_UNLOCK(hdsi);
2908 
2909   return HAL_OK;
2910 }
2911 
2912 /**
2913   * @brief  Force the Clock/Data Lane in TX Stop Mode
2914   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2915   *               the configuration information for the DSI.
2916   * @param  Lane  select between clock or data lanes.
2917   *               This parameter can be any value of @arg DSI_Lane_Group
2918   * @param  State  ENABLE or DISABLE
2919   * @retval HAL status
2920   */
HAL_DSI_ForceTXStopMode(DSI_HandleTypeDef * hdsi,uint32_t Lane,FunctionalState State)2921 HAL_StatusTypeDef HAL_DSI_ForceTXStopMode(DSI_HandleTypeDef *hdsi, uint32_t Lane, FunctionalState State)
2922 {
2923   /* Process locked */
2924   __HAL_LOCK(hdsi);
2925 
2926   /* Check function parameters */
2927   assert_param(IS_DSI_LANE_GROUP(Lane));
2928   assert_param(IS_FUNCTIONAL_STATE(State));
2929 
2930   if (Lane == DSI_CLOCK_LANE)
2931   {
2932     /* Force/Unforce the Clock Lane in TX Stop Mode */
2933     hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_FTXSMCL;
2934     hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 12U);
2935   }
2936   else if (Lane == DSI_DATA_LANES)
2937   {
2938     /* Force/Unforce the Data Lanes in TX Stop Mode */
2939     hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_FTXSMDL;
2940     hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 13U);
2941   }
2942   else
2943   {
2944     /* Process unlocked */
2945     __HAL_UNLOCK(hdsi);
2946 
2947     return HAL_ERROR;
2948   }
2949 
2950   /* Process unlocked */
2951   __HAL_UNLOCK(hdsi);
2952 
2953   return HAL_OK;
2954 }
2955 
2956 /**
2957   * @brief  Force LP Receiver in Low-Power Mode
2958   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2959   *               the configuration information for the DSI.
2960   * @param  State  ENABLE or DISABLE
2961   * @retval HAL status
2962   */
HAL_DSI_ForceRXLowPower(DSI_HandleTypeDef * hdsi,FunctionalState State)2963 HAL_StatusTypeDef HAL_DSI_ForceRXLowPower(DSI_HandleTypeDef *hdsi, FunctionalState State)
2964 {
2965   /* Process locked */
2966   __HAL_LOCK(hdsi);
2967 
2968   /* Check function parameters */
2969   assert_param(IS_FUNCTIONAL_STATE(State));
2970 
2971   /* Force/Unforce LP Receiver in Low-Power Mode */
2972   hdsi->Instance->WPCR[1U] &= ~DSI_WPCR1_FLPRXLPM;
2973   hdsi->Instance->WPCR[1U] |= ((uint32_t)State << 22U);
2974 
2975   /* Process unlocked */
2976   __HAL_UNLOCK(hdsi);
2977 
2978   return HAL_OK;
2979 }
2980 
2981 /**
2982   * @brief  Force Data Lanes in RX Mode after a BTA
2983   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
2984   *               the configuration information for the DSI.
2985   * @param  State  ENABLE or DISABLE
2986   * @retval HAL status
2987   */
HAL_DSI_ForceDataLanesInRX(DSI_HandleTypeDef * hdsi,FunctionalState State)2988 HAL_StatusTypeDef HAL_DSI_ForceDataLanesInRX(DSI_HandleTypeDef *hdsi, FunctionalState State)
2989 {
2990   /* Process locked */
2991   __HAL_LOCK(hdsi);
2992 
2993   /* Check function parameters */
2994   assert_param(IS_FUNCTIONAL_STATE(State));
2995 
2996   /* Force Data Lanes in RX Mode */
2997   hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_TDDL;
2998   hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 16U);
2999 
3000   /* Process unlocked */
3001   __HAL_UNLOCK(hdsi);
3002 
3003   return HAL_OK;
3004 }
3005 
3006 /**
3007   * @brief  Enable a pull-down on the lanes to prevent from floating states when unused
3008   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
3009   *               the configuration information for the DSI.
3010   * @param  State  ENABLE or DISABLE
3011   * @retval HAL status
3012   */
HAL_DSI_SetPullDown(DSI_HandleTypeDef * hdsi,FunctionalState State)3013 HAL_StatusTypeDef HAL_DSI_SetPullDown(DSI_HandleTypeDef *hdsi, FunctionalState State)
3014 {
3015   /* Process locked */
3016   __HAL_LOCK(hdsi);
3017 
3018   /* Check function parameters */
3019   assert_param(IS_FUNCTIONAL_STATE(State));
3020 
3021   /* Enable/Disable pull-down on lanes */
3022   hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_PDEN;
3023   hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 18U);
3024 
3025   /* Process unlocked */
3026   __HAL_UNLOCK(hdsi);
3027 
3028   return HAL_OK;
3029 }
3030 
3031 /**
3032   * @brief  Switch off the contention detection on data lanes
3033   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
3034   *               the configuration information for the DSI.
3035   * @param  State  ENABLE or DISABLE
3036   * @retval HAL status
3037   */
HAL_DSI_SetContentionDetectionOff(DSI_HandleTypeDef * hdsi,FunctionalState State)3038 HAL_StatusTypeDef HAL_DSI_SetContentionDetectionOff(DSI_HandleTypeDef *hdsi, FunctionalState State)
3039 {
3040   /* Process locked */
3041   __HAL_LOCK(hdsi);
3042 
3043   /* Check function parameters */
3044   assert_param(IS_FUNCTIONAL_STATE(State));
3045 
3046   /* Contention Detection on Data Lanes OFF */
3047   hdsi->Instance->WPCR[0U] &= ~DSI_WPCR0_CDOFFDL;
3048   hdsi->Instance->WPCR[0U] |= ((uint32_t)State << 14U);
3049 
3050   /* Process unlocked */
3051   __HAL_UNLOCK(hdsi);
3052 
3053   return HAL_OK;
3054 }
3055 
3056 /**
3057   * @}
3058   */
3059 
3060 /** @defgroup DSI_Group4 Peripheral State and Errors functions
3061   *  @brief    Peripheral State and Errors functions
3062   *
3063 @verbatim
3064  ===============================================================================
3065                   ##### Peripheral State and Errors functions #####
3066  ===============================================================================
3067     [..]
3068     This subsection provides functions allowing to
3069       (+) Check the DSI state.
3070       (+) Get error code.
3071 
3072 @endverbatim
3073   * @{
3074   */
3075 
3076 /**
3077   * @brief  Return the DSI state
3078   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
3079   *               the configuration information for the DSI.
3080   * @retval HAL state
3081   */
HAL_DSI_GetState(DSI_HandleTypeDef * hdsi)3082 HAL_DSI_StateTypeDef HAL_DSI_GetState(DSI_HandleTypeDef *hdsi)
3083 {
3084   return hdsi->State;
3085 }
3086 
3087 /**
3088   * @brief  Return the DSI error code
3089   * @param  hdsi  pointer to a DSI_HandleTypeDef structure that contains
3090   *               the configuration information for the DSI.
3091   * @retval DSI Error Code
3092   */
HAL_DSI_GetError(DSI_HandleTypeDef * hdsi)3093 uint32_t HAL_DSI_GetError(DSI_HandleTypeDef *hdsi)
3094 {
3095   /* Get the error code */
3096   return hdsi->ErrorCode;
3097 }
3098 
3099 /**
3100   * @}
3101   */
3102 
3103 /**
3104   * @}
3105   */
3106 
3107 /**
3108   * @}
3109   */
3110 
3111 #endif /* DSI */
3112 
3113 #endif /* HAL_DSI_MODULE_ENABLED */
3114 
3115 /**
3116   * @}
3117   */
3118