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