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