1 /**
2 ******************************************************************************
3 * @file stm32u0xx_hal_lcd.c
4 * @author MCD Application Team
5 * @brief LCD Controller HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the LCD Controller (LCD) peripheral:
8 * + Initialization/de-initialization methods
9 * + I/O operation methods
10 * + Peripheral State methods
11 *
12 ******************************************************************************
13 * @attention
14 *
15 * Copyright (c) 2023 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 [..] The LCD HAL driver can be used as follows:
28
29 (#) Declare a LCD_HandleTypeDef handle structure.
30
31 -@- The frequency generator allows you to achieve various LCD frame rates
32 starting from an LCD input clock frequency (LCDCLK) which can vary
33 from 32 kHz up to 1 MHz.
34
35 (#) Initialize the LCD low level resources by implementing the HAL_LCD_MspInit() API:
36
37 (++) Enable the LCDCLK (same as RTCCLK): to configure the RTCCLK/LCDCLK, proceed as follows:
38 (+++) Use RCC function HAL_RCCEx_PeriphCLKConfig in indicating RCC_PERIPHCLK_LCD and
39 selected clock source (HSE, LSI or LSE)
40
41 (++) LCD pins configuration:
42 (+++) Enable the clock for the LCD GPIOs.
43 (+++) Configure these LCD pins as alternate function no-pull.
44 (++) Enable the LCD interface clock.
45
46
47 (#) Program the Prescaler, Divider, Blink mode, Blink Frequency Duty, Bias,
48 Voltage Source, Dead Time, Pulse On Duration, Contrast, High drive and Multiplexer
49 Segment in the Init structure of the LCD handle.
50
51 (#) Initialize the LCD registers by calling the HAL_LCD_Init() API.
52
53 -@- The HAL_LCD_Init() API configures also the low level Hardware GPIO, CLOCK, ...etc)
54 by calling the customized HAL_LCD_MspInit() API.
55 -@- After calling the HAL_LCD_Init() the LCD RAM memory is cleared
56
57 (#) Optionally you can update the LCD configuration using these macros:
58 (++) LCD High Drive using the __HAL_LCD_HIGHDRIVER_ENABLE() and __HAL_LCD_HIGHDRIVER_DISABLE() macros
59 (++) Voltage output buffer using __HAL_LCD_VOLTAGE_BUFFER_ENABLE() and __HAL_LCD_VOLTAGE_BUFFER_DISABLE() macros
60 (++) LCD Pulse ON Duration using the __HAL_LCD_PULSEONDURATION_CONFIG() macro
61 (++) LCD Dead Time using the __HAL_LCD_DEADTIME_CONFIG() macro
62 (++) The LCD Blink mode and frequency using the __HAL_LCD_BLINK_CONFIG() macro
63 (++) The LCD Contrast using the __HAL_LCD_CONTRAST_CONFIG() macro
64
65 (#) Write to the LCD RAM memory using the HAL_LCD_Write() API, this API can be called
66 more time to update the different LCD RAM registers before calling
67 HAL_LCD_UpdateDisplayRequest() API.
68
69 (#) The HAL_LCD_Clear() API can be used to clear the LCD RAM memory.
70
71 (#) When LCD RAM memory is updated enable the update display request using
72 the HAL_LCD_UpdateDisplayRequest() API.
73
74 [..] LCD and low power modes:
75 (#) The LCD remain active during Sleep, Low Power run, Low Power Sleep and
76 STOP modes.
77
78 @endverbatim
79 ******************************************************************************
80 */
81
82 /* Includes ------------------------------------------------------------------*/
83 #include "stm32u0xx_hal.h"
84
85
86 /** @addtogroup STM32U0xx_HAL_Driver
87 * @{
88 */
89
90 #ifdef HAL_LCD_MODULE_ENABLED
91
92 #if defined (LCD)
93
94 /** @defgroup LCD LCD
95 * @brief LCD HAL module driver
96 * @{
97 */
98
99 /* Private typedef -----------------------------------------------------------*/
100 /* Private define ------------------------------------------------------------*/
101 /** @defgroup LCD_Private_Defines LCD Private Defines
102 * @{
103 */
104
105 #define LCD_TIMEOUT_VALUE 1000U
106
107 /**
108 * @}
109 */
110
111 /* Private macro -------------------------------------------------------------*/
112 /* Private variables ---------------------------------------------------------*/
113 /* Private function prototypes -----------------------------------------------*/
114 /* Exported functions --------------------------------------------------------*/
115
116 /** @defgroup LCD_Exported_Functions LCD Exported Functions
117 * @{
118 */
119
120 /** @defgroup LCD_Exported_Functions_Group1 Initialization/de-initialization methods
121 * @brief Initialization and Configuration functions
122 *
123 @verbatim
124 ===============================================================================
125 ##### Initialization and Configuration functions #####
126 ===============================================================================
127 [..]
128
129 @endverbatim
130 * @{
131 */
132
133 /**
134 * @brief Initialize the LCD peripheral according to the specified parameters
135 * in the LCD_InitStruct and initialize the associated handle.
136 * @note This function can be used only when the LCD is disabled.
137 * @param hlcd LCD handle
138 * @retval None
139 */
HAL_LCD_Init(LCD_HandleTypeDef * hlcd)140 HAL_StatusTypeDef HAL_LCD_Init(LCD_HandleTypeDef *hlcd)
141 {
142 uint32_t tickstart;
143 uint32_t counter;
144 HAL_StatusTypeDef status;
145
146 /* Check the LCD handle allocation */
147 if (hlcd == NULL)
148 {
149 return HAL_ERROR;
150 }
151
152 /* Check function parameters */
153 assert_param(IS_LCD_ALL_INSTANCE(hlcd->Instance));
154 assert_param(IS_LCD_PRESCALER(hlcd->Init.Prescaler));
155 assert_param(IS_LCD_DIVIDER(hlcd->Init.Divider));
156 assert_param(IS_LCD_DUTY(hlcd->Init.Duty));
157 assert_param(IS_LCD_BIAS(hlcd->Init.Bias));
158 assert_param(IS_LCD_VOLTAGE_SOURCE(hlcd->Init.VoltageSource));
159 assert_param(IS_LCD_PULSE_ON_DURATION(hlcd->Init.PulseOnDuration));
160 assert_param(IS_LCD_HIGH_DRIVE(hlcd->Init.HighDrive));
161 assert_param(IS_LCD_DEAD_TIME(hlcd->Init.DeadTime));
162 assert_param(IS_LCD_CONTRAST(hlcd->Init.Contrast));
163 assert_param(IS_LCD_BLINK_FREQUENCY(hlcd->Init.BlinkFrequency));
164 assert_param(IS_LCD_BLINK_MODE(hlcd->Init.BlinkMode));
165 assert_param(IS_LCD_MUX_SEGMENT(hlcd->Init.MuxSegment));
166
167 if (hlcd->State == HAL_LCD_STATE_RESET)
168 {
169 /* Allocate lock resource and initialize it */
170 hlcd->Lock = HAL_UNLOCKED;
171
172 /* Initialize the low level hardware (MSP) */
173 HAL_LCD_MspInit(hlcd);
174 }
175
176 hlcd->State = HAL_LCD_STATE_BUSY;
177
178 /* Disable the peripheral */
179 __HAL_LCD_DISABLE(hlcd);
180
181 /* Clear the LCD_RAM registers and enable the display request by setting the UDR bit
182 in the LCD_SR register */
183 for (counter = LCD_RAM_REGISTER0; counter <= LCD_RAM_REGISTER7; counter++)
184 {
185 hlcd->Instance->RAM[counter] = 0;
186 }
187 /* Enable the display request */
188 /* hlcd->Instance->SR |= LCD_SR_UDR */
189 /* Configure the LCD Prescaler, Divider, Blink mode and Blink Frequency:
190 Set PS[3:0] bits according to hlcd->Init.Prescaler value
191 Set DIV[3:0] bits according to hlcd->Init.Divider value
192 Set BLINK[1:0] bits according to hlcd->Init.BlinkMode value
193 Set BLINKF[2:0] bits according to hlcd->Init.BlinkFrequency value
194 Set DEAD[2:0] bits according to hlcd->Init.DeadTime value
195 Set PON[2:0] bits according to hlcd->Init.PulseOnDuration value
196 Set CC[2:0] bits according to hlcd->Init.Contrast value
197 Set HD bit according to hlcd->Init.HighDrive value */
198 MODIFY_REG(hlcd->Instance->FCR, \
199 (LCD_FCR_PS | LCD_FCR_DIV | LCD_FCR_BLINK | LCD_FCR_BLINKF | \
200 LCD_FCR_DEAD | LCD_FCR_PON | LCD_FCR_CC | LCD_FCR_HD), \
201 (hlcd->Init.Prescaler | hlcd->Init.Divider | hlcd->Init.BlinkMode | hlcd->Init.BlinkFrequency | \
202 hlcd->Init.DeadTime | hlcd->Init.PulseOnDuration | hlcd->Init.Contrast | hlcd->Init.HighDrive));
203
204 /* Wait until LCD Frame Control Register Synchronization flag (FCRSF) is set in the LCD_SR register
205 This bit is set by hardware each time the LCD_FCR register is updated in the LCDCLK
206 domain. It is cleared by hardware when writing to the LCD_FCR register.*/
207 status = LCD_WaitForSynchro(hlcd);
208 if (status != HAL_OK)
209 {
210 return status;
211 }
212
213 /* Configure the LCD Duty, Bias, Voltage Source, Dead Time, Pulse On Duration and Contrast:
214 Set DUTY[2:0] bits according to hlcd->Init.Duty value
215 Set BIAS[1:0] bits according to hlcd->Init.Bias value
216 Set VSEL bit according to hlcd->Init.VoltageSource value
217 Set MUX_SEG bit according to hlcd->Init.MuxSegment value */
218 MODIFY_REG(hlcd->Instance->CR, \
219 (LCD_CR_DUTY | LCD_CR_BIAS | LCD_CR_VSEL | LCD_CR_MUX_SEG), \
220 (hlcd->Init.Duty | hlcd->Init.Bias | hlcd->Init.VoltageSource | hlcd->Init.MuxSegment));
221
222 /* Enable the peripheral */
223 __HAL_LCD_ENABLE(hlcd);
224
225 /* Get timeout */
226 tickstart = HAL_GetTick();
227
228 /* Wait Until the LCD is enabled */
229 while (__HAL_LCD_GET_FLAG(hlcd, LCD_FLAG_ENS) == RESET)
230 {
231 if ((HAL_GetTick() - tickstart) > LCD_TIMEOUT_VALUE)
232 {
233 hlcd->ErrorCode = HAL_LCD_ERROR_ENS;
234 return HAL_TIMEOUT;
235 }
236 }
237
238 /* Get timeout */
239 tickstart = HAL_GetTick();
240
241 /*!< Wait Until the LCD Booster is ready */
242 while (__HAL_LCD_GET_FLAG(hlcd, LCD_FLAG_RDY) == RESET)
243 {
244 if ((HAL_GetTick() - tickstart) > LCD_TIMEOUT_VALUE)
245 {
246 hlcd->ErrorCode = HAL_LCD_ERROR_RDY;
247 return HAL_TIMEOUT;
248 }
249 }
250
251 /* Initialize the LCD state */
252 hlcd->ErrorCode = HAL_LCD_ERROR_NONE;
253 hlcd->State = HAL_LCD_STATE_READY;
254
255 return status;
256 }
257
258 /**
259 * @brief DeInitialize the LCD peripheral.
260 * @param hlcd LCD handle
261 * @retval HAL status
262 */
HAL_LCD_DeInit(LCD_HandleTypeDef * hlcd)263 HAL_StatusTypeDef HAL_LCD_DeInit(LCD_HandleTypeDef *hlcd)
264 {
265 /* Check the LCD handle allocation */
266 if (hlcd == NULL)
267 {
268 return HAL_ERROR;
269 }
270
271 /* Check the parameters */
272 assert_param(IS_LCD_ALL_INSTANCE(hlcd->Instance));
273
274 hlcd->State = HAL_LCD_STATE_BUSY;
275
276 /* DeInit the low level hardware */
277 HAL_LCD_MspDeInit(hlcd);
278
279 hlcd->ErrorCode = HAL_LCD_ERROR_NONE;
280 hlcd->State = HAL_LCD_STATE_RESET;
281
282 /* Release Lock */
283 __HAL_UNLOCK(hlcd);
284
285 return HAL_OK;
286 }
287
288 /**
289 * @brief DeInitialize the LCD MSP.
290 * @param hlcd LCD handle
291 * @retval None
292 */
HAL_LCD_MspDeInit(LCD_HandleTypeDef * hlcd)293 __weak void HAL_LCD_MspDeInit(LCD_HandleTypeDef *hlcd)
294 {
295 /* Prevent unused argument(s) compilation warning */
296 UNUSED(hlcd);
297
298 /* NOTE: This function should not be modified, when the callback is needed,
299 the HAL_LCD_MspDeInit it to be implemented in the user file
300 */
301 }
302
303 /**
304 * @brief Initialize the LCD MSP.
305 * @param hlcd LCD handle
306 * @retval None
307 */
HAL_LCD_MspInit(LCD_HandleTypeDef * hlcd)308 __weak void HAL_LCD_MspInit(LCD_HandleTypeDef *hlcd)
309 {
310 /* Prevent unused argument(s) compilation warning */
311 UNUSED(hlcd);
312
313 /* NOTE: This function should not be modified, when the callback is needed,
314 the HAL_LCD_MspInit is to be implemented in the user file
315 */
316 }
317
318 /**
319 * @}
320 */
321
322 /** @defgroup LCD_Exported_Functions_Group2 IO operation methods
323 * @brief LCD RAM functions
324 *
325 @verbatim
326 ===============================================================================
327 ##### IO operation functions #####
328 ===============================================================================
329 [..] Using its double buffer memory the LCD controller ensures the coherency of the
330 displayed information without having to use interrupts to control LCD_RAM
331 modification.
332
333 [..] The application software can access the first buffer level (LCD_RAM) through
334 the APB interface. Once it has modified the LCD_RAM using the HAL_LCD_Write() API,
335 it sets the UDR flag in the LCD_SR register using the HAL_LCD_UpdateDisplayRequest() API.
336
337 [..] This UDR flag (update display request) requests the updated information to be
338 moved into the second buffer level (LCD_DISPLAY).
339
340 [..] This operation is done synchronously with the frame (at the beginning of the
341 next frame), until the update is completed, the LCD_RAM is write protected and
342 the UDR flag stays high.
343
344 [..] Once the update is completed another flag (UDD - Update Display Done) is set and
345 generates an interrupt if the UDDIE bit in the LCD_FCR register is set.
346 The time it takes to update LCD_DISPLAY is, in the worst case, one odd and one
347 even frame.
348
349 [..] The update will not occur (UDR = 1 and UDD = 0) until the display is
350 enabled (LCDEN = 1).
351
352 @endverbatim
353 * @{
354 */
355
356 /**
357 * @brief Write a word in the specific LCD RAM.
358 * @param hlcd LCD handle
359 * @param RAMRegisterIndex specifies the LCD RAM Register.
360 * This parameter can be one of the following values:
361 * @arg LCD_RAM_REGISTER0: LCD RAM Register 0
362 * @arg LCD_RAM_REGISTER1: LCD RAM Register 1
363 * @arg LCD_RAM_REGISTER2: LCD RAM Register 2
364 * @arg LCD_RAM_REGISTER3: LCD RAM Register 3
365 * @arg LCD_RAM_REGISTER4: LCD RAM Register 4
366 * @arg LCD_RAM_REGISTER5: LCD RAM Register 5
367 * @arg LCD_RAM_REGISTER6: LCD RAM Register 6
368 * @arg LCD_RAM_REGISTER7: LCD RAM Register 7
369 * @arg LCD_RAM_REGISTER8: LCD RAM Register 8
370 * @arg LCD_RAM_REGISTER9: LCD RAM Register 9
371 * @arg LCD_RAM_REGISTER10: LCD RAM Register 10
372 * @arg LCD_RAM_REGISTER11: LCD RAM Register 11
373 * @arg LCD_RAM_REGISTER12: LCD RAM Register 12
374 * @arg LCD_RAM_REGISTER13: LCD RAM Register 13
375 * @arg LCD_RAM_REGISTER14: LCD RAM Register 14
376 * @arg LCD_RAM_REGISTER15: LCD RAM Register 15
377 * @param RAMRegisterMask specifies the LCD RAM Register Data Mask.
378 * @param Data specifies LCD Data Value to be written.
379 * @retval None
380 */
HAL_LCD_Write(LCD_HandleTypeDef * hlcd,uint32_t RAMRegisterIndex,uint32_t RAMRegisterMask,uint32_t Data)381 HAL_StatusTypeDef HAL_LCD_Write(LCD_HandleTypeDef *hlcd, uint32_t RAMRegisterIndex, uint32_t RAMRegisterMask,
382 uint32_t Data)
383 {
384 uint32_t tickstart;
385 HAL_LCD_StateTypeDef state = hlcd->State;
386
387 if ((state == HAL_LCD_STATE_READY) || (state == HAL_LCD_STATE_BUSY))
388 {
389 /* Check the parameters */
390 assert_param(IS_LCD_RAM_REGISTER(RAMRegisterIndex));
391
392 if (hlcd->State == HAL_LCD_STATE_READY)
393 {
394 /* Process Locked */
395 __HAL_LOCK(hlcd);
396 hlcd->State = HAL_LCD_STATE_BUSY;
397
398 /* Get timeout */
399 tickstart = HAL_GetTick();
400
401 /*!< Wait Until the LCD is ready */
402 while (__HAL_LCD_GET_FLAG(hlcd, LCD_FLAG_UDR) != RESET)
403 {
404 if ((HAL_GetTick() - tickstart) > LCD_TIMEOUT_VALUE)
405 {
406 hlcd->ErrorCode = HAL_LCD_ERROR_UDR;
407
408 /* Process Unlocked */
409 __HAL_UNLOCK(hlcd);
410
411 return HAL_TIMEOUT;
412 }
413 }
414 }
415
416 /* Copy the new Data bytes to LCD RAM register */
417 MODIFY_REG(hlcd->Instance->RAM[RAMRegisterIndex], ~(RAMRegisterMask), Data);
418
419 return HAL_OK;
420 }
421 else
422 {
423 return HAL_ERROR;
424 }
425 }
426
427 /**
428 * @brief Clear the LCD RAM registers.
429 * @param hlcd LCD handle
430 * @retval None
431 */
HAL_LCD_Clear(LCD_HandleTypeDef * hlcd)432 HAL_StatusTypeDef HAL_LCD_Clear(LCD_HandleTypeDef *hlcd)
433 {
434 uint32_t tickstart;
435 uint32_t counter;
436 HAL_StatusTypeDef status = HAL_ERROR;
437 HAL_LCD_StateTypeDef state = hlcd->State;
438
439 if ((state == HAL_LCD_STATE_READY) || (state == HAL_LCD_STATE_BUSY))
440 {
441 /* Process Locked */
442 __HAL_LOCK(hlcd);
443
444 hlcd->State = HAL_LCD_STATE_BUSY;
445
446 /* Get timeout */
447 tickstart = HAL_GetTick();
448
449 /*!< Wait Until the LCD is ready */
450 while (__HAL_LCD_GET_FLAG(hlcd, LCD_FLAG_UDR) != RESET)
451 {
452 if ((HAL_GetTick() - tickstart) > LCD_TIMEOUT_VALUE)
453 {
454 hlcd->ErrorCode = HAL_LCD_ERROR_UDR;
455
456 /* Process Unlocked */
457 __HAL_UNLOCK(hlcd);
458
459 return HAL_TIMEOUT;
460 }
461 }
462 /* Clear the LCD_RAM registers */
463 for (counter = LCD_RAM_REGISTER0; counter <= LCD_RAM_REGISTER15; counter++)
464 {
465 hlcd->Instance->RAM[counter] = 0;
466 }
467
468 /* Update the LCD display */
469 status = HAL_LCD_UpdateDisplayRequest(hlcd);
470 }
471 return status;
472 }
473
474 /**
475 * @brief Enable the Update Display Request.
476 * @param hlcd LCD handle
477 * @note Each time software modifies the LCD_RAM it must set the UDR bit to
478 * transfer the updated data to the second level buffer.
479 * The UDR bit stays set until the end of the update and during this
480 * time the LCD_RAM is write protected.
481 * @note When the display is disabled, the update is performed for all
482 * LCD_DISPLAY locations.
483 * When the display is enabled, the update is performed only for locations
484 * for which commons are active (depending on DUTY). For example if
485 * DUTY = 1/2, only the LCD_DISPLAY of COM0 and COM1 will be updated.
486 * @retval None
487 */
HAL_LCD_UpdateDisplayRequest(LCD_HandleTypeDef * hlcd)488 HAL_StatusTypeDef HAL_LCD_UpdateDisplayRequest(LCD_HandleTypeDef *hlcd)
489 {
490 uint32_t tickstart;
491
492 /* Clear the Update Display Done flag before starting the update display request */
493 __HAL_LCD_CLEAR_FLAG(hlcd, LCD_FLAG_UDD);
494
495 /* Enable the display request */
496 hlcd->Instance->SR |= LCD_SR_UDR;
497
498 /* Get timeout */
499 tickstart = HAL_GetTick();
500
501 /*!< Wait Until the LCD display is done */
502 while (__HAL_LCD_GET_FLAG(hlcd, LCD_FLAG_UDD) == RESET)
503 {
504 if ((HAL_GetTick() - tickstart) > LCD_TIMEOUT_VALUE)
505 {
506 hlcd->ErrorCode = HAL_LCD_ERROR_UDD;
507
508 /* Process Unlocked */
509 __HAL_UNLOCK(hlcd);
510
511 return HAL_TIMEOUT;
512 }
513 }
514
515 hlcd->State = HAL_LCD_STATE_READY;
516
517 /* Process Unlocked */
518 __HAL_UNLOCK(hlcd);
519
520 return HAL_OK;
521 }
522
523 /**
524 * @}
525 */
526
527 /** @defgroup LCD_Exported_Functions_Group3 Peripheral State methods
528 * @brief LCD State functions
529 *
530 @verbatim
531 ===============================================================================
532 ##### Peripheral State functions #####
533 ===============================================================================
534 [..]
535 This subsection provides a set of functions allowing to control the LCD:
536 (+) HAL_LCD_GetState() API can be helpful to check in run-time the state of the LCD peripheral State.
537 (+) HAL_LCD_GetError() API to return the LCD error code.
538 @endverbatim
539 * @{
540 */
541
542 /**
543 * @brief Return the LCD handle state.
544 * @param hlcd LCD handle
545 * @retval HAL state
546 */
HAL_LCD_GetState(LCD_HandleTypeDef * hlcd)547 HAL_LCD_StateTypeDef HAL_LCD_GetState(LCD_HandleTypeDef *hlcd)
548 {
549 /* Return LCD handle state */
550 return hlcd->State;
551 }
552
553 /**
554 * @brief Return the LCD error code.
555 * @param hlcd LCD handle
556 * @retval LCD Error Code
557 */
HAL_LCD_GetError(LCD_HandleTypeDef * hlcd)558 uint32_t HAL_LCD_GetError(LCD_HandleTypeDef *hlcd)
559 {
560 return hlcd->ErrorCode;
561 }
562
563 /**
564 * @}
565 */
566
567 /**
568 * @}
569 */
570
571 /** @defgroup LCD_Private_Functions LCD Private Functions
572 * @{
573 */
574
575 /**
576 * @brief Wait until the LCD FCR register is synchronized in the LCDCLK domain.
577 * This function must be called after any write operation to LCD_FCR register.
578 * @retval None
579 */
LCD_WaitForSynchro(LCD_HandleTypeDef * hlcd)580 HAL_StatusTypeDef LCD_WaitForSynchro(LCD_HandleTypeDef *hlcd)
581 {
582 uint32_t tickstart;
583
584 /* Get timeout */
585 tickstart = HAL_GetTick();
586
587 /* Loop until FCRSF flag is set */
588 while (__HAL_LCD_GET_FLAG(hlcd, LCD_FLAG_FCRSF) == RESET)
589 {
590 if ((HAL_GetTick() - tickstart) > LCD_TIMEOUT_VALUE)
591 {
592 hlcd->ErrorCode = HAL_LCD_ERROR_FCRSF;
593 return HAL_TIMEOUT;
594 }
595 }
596
597 return HAL_OK;
598 }
599
600 /**
601 * @}
602 */
603
604 /**
605 * @}
606 */
607
608 #endif /* LCD */
609
610 #endif /* HAL_LCD_MODULE_ENABLED */
611
612 /**
613 * @}
614 */
615