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