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