AudioRecord
Dependencies: STM32L4xx_HAL_Driver CMSIS_DSP_401
Diff: stm32l476g_discovery_glass_lcd.c
- Revision:
- 0:d4e5ad7ad71c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stm32l476g_discovery_glass_lcd.c Mon Nov 23 19:37:13 2015 +0000 @@ -0,0 +1,988 @@ +/** + ****************************************************************************** + * @file stm32l476g_discovery_glass_lcd.c + * @author MCD Application Team + * @version V1.0.1 + * @date 16-September-2015 + * @brief This file provides a set of functions needed to manage the + * LCD Glass driver for the STM32L476G-Discovery board. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l476g_discovery_glass_lcd.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32L476G_DISCOVERY + * @{ + */ + +/** @defgroup STM32L476G_DISCOVERY_GLASS_LCD STM32L476G-DISCOVERY GLASS LCD + * @brief This file includes the LCD Glass driver for LCD Module of + * STM32L476G-DISCOVERY board. + * @{ + */ + +/* Private constants ---------------------------------------------------------*/ + +/** @defgroup STM32L476G_DISCOVERY_GLASS_LCD_Private_Constants Private Constants + * @{ + */ +#define ASCII_CHAR_0 0x30 /* 0 */ +#define ASCII_CHAR_AT_SYMBOL 0x40 /* @ */ +#define ASCII_CHAR_LEFT_OPEN_BRACKET 0x5B /* [ */ +#define ASCII_CHAR_APOSTROPHE 0x60 /* ` */ +#define ASCII_CHAR_LEFT_OPEN_BRACE 0x7B /* ( */ +/** + * @} + */ + +/* Private variables ---------------------------------------------------------*/ + +/** @defgroup STM32L476G_DISCOVERY_GLASS_LCD_Private_Variables Private Variables + * @{ + */ + +/* this variable can be used for accelerate the scrolling exit when push user button */ +__IO uint8_t bLCDGlass_KeyPressed = 0; + +/** + @verbatim +================================================================================ + GLASS LCD MAPPING +================================================================================ +LCD allows to display informations on six 14-segment digits and 4 bars: + + 1 2 3 4 5 6 +----- ----- ----- ----- ----- ----- +|\|/| o |\|/| o |\|/| o |\|/| o |\|/| |\|/| BAR3 +-- -- -- -- -- -- -- -- -- -- -- -- BAR2 +|/|\| o |/|\| o |/|\| o |/|\| o |/|\| |/|\| BAR1 +----- * ----- * ----- * ----- * ----- ----- BAR0 + +LCD segment mapping: +-------------------- + -----A----- _ + |\ | /| COL |_| + F H J K B + | \ | / | _ + --G-- --M-- COL |_| + | / | \ | + E Q P N C + |/ | \| _ + -----D----- DP |_| + + An LCD character coding is based on the following matrix: +COM 0 1 2 3 +SEG(n) { E , D , P , N } +SEG(n+1) { M , C , COL , DP } +SEG(23-n-1) { B , A , K , J } +SEG(23-n) { G , F , Q , H } +with n positive odd number. + + The character 'A' for example is: + ------------------------------- +LSB { 1 , 0 , 0 , 0 } + { 1 , 1 , 0 , 0 } + { 1 , 1 , 0 , 0 } +MSB { 1 , 1 , 0 , 0 } + ------------------- + 'A' = F E 0 0 hexa + + @endverbatim +*/ + +LCD_HandleTypeDef LCDHandle; + +/* Constant table for cap characters 'A' --> 'Z' */ +const uint16_t CapLetterMap[26]= + { + /* A B C D E F G H I */ + 0xFE00, 0x6714, 0x1D00, 0x4714, 0x9D00, 0x9C00, 0x3F00, 0xFA00, 0x0014, + /* J K L M N O P Q R */ + 0x5300, 0x9841, 0x1900, 0x5A48, 0x5A09, 0x5F00, 0xFC00, 0x5F01, 0xFC01, + /* S T U V W X Y Z */ + 0xAF00, 0x0414, 0x5b00, 0x18C0, 0x5A81, 0x00C9, 0x0058, 0x05C0 + }; + +/* Constant table for number '0' --> '9' */ +const uint16_t NumberMap[10]= + { + /* 0 1 2 3 4 5 6 7 8 9 */ + 0x5F00,0x4200,0xF500,0x6700,0xEa00,0xAF00,0xBF00,0x04600,0xFF00,0xEF00 + }; + +uint32_t Digit[4]; /* Digit frame buffer */ + +/* LCD BAR status: To save the bar setting after writing in LCD RAM memory */ +uint8_t LCDBar = BATTERYLEVEL_FULL; + +/** + * @} + */ + +/** @defgroup STM32L476G_DISCOVERY_LCD_Private_Functions Private Functions + * @{ + */ +static void Convert(uint8_t* Char, Point_Typedef Point, DoublePoint_Typedef Colon); +static void WriteChar(uint8_t* ch, Point_Typedef Point, DoublePoint_Typedef Colon, DigitPosition_Typedef Position); +static void LCD_MspInit(LCD_HandleTypeDef *hlcd); +static void LCD_MspDeInit(LCD_HandleTypeDef *hlcd); + +/** + * @} + */ + +/** @addtogroup STM32L476G_DISCOVERY_LCD_Exported_Functions + * @{ + */ + +/** + * @brief Initialize the LCD GLASS relative GPIO port IOs and LCD peripheral. + * @retval None + */ +void BSP_LCD_GLASS_Init(void) +{ + LCDHandle.Instance = LCD; + LCDHandle.Init.Prescaler = LCD_PRESCALER_1; + LCDHandle.Init.Divider = LCD_DIVIDER_31; +#if defined (USE_STM32L476G_DISCO_REVC) || defined (USE_STM32L476G_DISCO_REVB) + LCDHandle.Init.Duty = LCD_DUTY_1_4; +#elif defined (USE_STM32L476G_DISCO_REVA) + LCDHandle.Init.Duty = LCD_DUTY_1_8; +#endif + LCDHandle.Init.Bias = LCD_BIAS_1_3; + LCDHandle.Init.VoltageSource = LCD_VOLTAGESOURCE_INTERNAL; + LCDHandle.Init.Contrast = LCD_CONTRASTLEVEL_5; + LCDHandle.Init.DeadTime = LCD_DEADTIME_0; + LCDHandle.Init.PulseOnDuration = LCD_PULSEONDURATION_4; + LCDHandle.Init.HighDrive = LCD_HIGHDRIVE_DISABLE; + LCDHandle.Init.BlinkMode = LCD_BLINKMODE_OFF; + LCDHandle.Init.BlinkFrequency = LCD_BLINKFREQUENCY_DIV32; + LCDHandle.Init.MuxSegment = LCD_MUXSEGMENT_DISABLE; + + /* Initialize the LCD */ + LCD_MspInit(&LCDHandle); + HAL_LCD_Init(&LCDHandle); + + BSP_LCD_GLASS_Clear(); +} + +/** + * @brief DeInitialize the LCD GLASS relative GPIO port IOs and LCD peripheral. + * @retval None + */ +void BSP_LCD_GLASS_DeInit(void) +{ + /* De-Initialize the LCD */ + LCD_MspDeInit(&LCDHandle); + HAL_LCD_DeInit(&LCDHandle); +} + + +/** + * @brief Configure the LCD Blink mode and Blink frequency. + * @param BlinkMode: specifies the LCD blink mode. + * This parameter can be one of the following values: + * @arg LCD_BLINKMODE_OFF: Blink disabled + * @arg LCD_BLINKMODE_SEG0_COM0: Blink enabled on SEG[0], COM[0] (1 pixel) + * @arg LCD_BLINKMODE_SEG0_ALLCOM: Blink enabled on SEG[0], all COM (up to 8 + * pixels according to the programmed duty) + * @arg LCD_BLINKMODE_ALLSEG_ALLCOM: Blink enabled on all SEG and all COM + * (all pixels) + * @param BlinkFrequency: specifies the LCD blink frequency. + * @arg LCD_BLINKFREQUENCY_DIV8: The Blink frequency = fLcd/8 + * @arg LCD_BLINKFREQUENCY_DIV16: The Blink frequency = fLcd/16 + * @arg LCD_BLINKFREQUENCY_DIV32: The Blink frequency = fLcd/32 + * @arg LCD_BLINKFREQUENCY_DIV64: The Blink frequency = fLcd/64 + * @arg LCD_BLINKFREQUENCY_DIV128: The Blink frequency = fLcd/128 + * @arg LCD_BLINKFREQUENCY_DIV256: The Blink frequency = fLcd/256 + * @arg LCD_BLINKFREQUENCY_DIV512: The Blink frequency = fLcd/512 + * @arg LCD_BLINKFREQUENCY_DIV1024: The Blink frequency = fLcd/1024 + * @retval None + */ +void BSP_LCD_GLASS_BlinkConfig(uint32_t BlinkMode, uint32_t BlinkFrequency) +{ + __HAL_LCD_BLINK_CONFIG(&LCDHandle, BlinkMode, BlinkFrequency); +} + +/** + * @brief Configure the LCD contrast. + * @param Contrast: specifies the LCD contrast value. + * This parameter can be one of the following values: + * @arg LCD_CONTRASTLEVEL_0: Maximum Voltage = 2.60V + * @arg LCD_CONTRASTLEVEL_1: Maximum Voltage = 2.73V + * @arg LCD_CONTRASTLEVEL_2: Maximum Voltage = 2.86V + * @arg LCD_CONTRASTLEVEL_3: Maximum Voltage = 2.99V + * @arg LCD_CONTRASTLEVEL_4: Maximum Voltage = 3.12V + * @arg LCD_CONTRASTLEVEL_5: Maximum Voltage = 3.25V + * @arg LCD_CONTRASTLEVEL_6: Maximum Voltage = 3.38V + * @arg LCD_CONTRASTLEVEL_7: Maximum Voltage = 3.51V + * @retval None + */ +void BSP_LCD_GLASS_Contrast(uint32_t Contrast) +{ + __HAL_LCD_CONTRAST_CONFIG(&LCDHandle, Contrast); +} + +/** + * @brief Display one or several bar in LCD frame buffer. + * @param BarId: specifies the LCD GLASS Bar to display + * This parameter can be one of the following values: + * @arg BAR0: LCD GLASS Bar 0 + * @arg BAR0: LCD GLASS Bar 1 + * @arg BAR0: LCD GLASS Bar 2 + * @arg BAR0: LCD GLASS Bar 3 + * @retval None + */ +void BSP_LCD_GLASS_DisplayBar(uint32_t BarId) +{ + uint32_t position = 0; + + /* Check which bar is selected */ + while ((BarId) >> position) + { + /* Check if current bar is selected */ + switch(BarId & (1 << position)) + { + /* Bar 0 */ + case LCD_BAR_0: + /* Set BAR0 */ + HAL_LCD_Write(&LCDHandle, LCD_BAR0_2_COM, ~(LCD_BAR0_SEG), LCD_BAR0_SEG); + break; + + /* Bar 1 */ + case LCD_BAR_1: + /* Set BAR1 */ + HAL_LCD_Write(&LCDHandle, LCD_BAR1_3_COM, ~(LCD_BAR1_SEG), LCD_BAR1_SEG); + break; + + /* Bar 2 */ + case LCD_BAR_2: + /* Set BAR2 */ + HAL_LCD_Write(&LCDHandle, LCD_BAR0_2_COM, ~(LCD_BAR2_SEG), LCD_BAR2_SEG); + break; + + /* Bar 3 */ + case LCD_BAR_3: + /* Set BAR3 */ + HAL_LCD_Write(&LCDHandle, LCD_BAR1_3_COM, ~(LCD_BAR3_SEG), LCD_BAR3_SEG); + break; + + default: + break; + } + position++; + } + + /* Update the LCD display */ + HAL_LCD_UpdateDisplayRequest(&LCDHandle); +} + +/** + * @brief Clear one or several bar in LCD frame buffer. + * @param BarId: specifies the LCD GLASS Bar to display + * This parameter can be combination of one of the following values: + * @arg LCD_BAR_0: LCD GLASS Bar 0 + * @arg LCD_BAR_1: LCD GLASS Bar 1 + * @arg LCD_BAR_2: LCD GLASS Bar 2 + * @arg LCD_BAR_3: LCD GLASS Bar 3 + * @retval None + */ +void BSP_LCD_GLASS_ClearBar(uint32_t BarId) +{ + uint32_t position = 0; + + /* Check which bar is selected */ + while ((BarId) >> position) + { + /* Check if current bar is selected */ + switch(BarId & (1 << position)) + { + /* Bar 0 */ + case LCD_BAR_0: + /* Set BAR0 */ + HAL_LCD_Write(&LCDHandle, LCD_BAR0_2_COM, ~(LCD_BAR0_SEG) , 0); + break; + + /* Bar 1 */ + case LCD_BAR_1: + /* Set BAR1 */ + HAL_LCD_Write(&LCDHandle, LCD_BAR1_3_COM, ~(LCD_BAR1_SEG), 0); + break; + + /* Bar 2 */ + case LCD_BAR_2: + /* Set BAR2 */ + HAL_LCD_Write(&LCDHandle, LCD_BAR0_2_COM, ~(LCD_BAR2_SEG), 0); + break; + + /* Bar 3 */ + case LCD_BAR_3: + /* Set BAR3 */ + HAL_LCD_Write(&LCDHandle, LCD_BAR1_3_COM, ~(LCD_BAR3_SEG), 0); + break; + + default: + break; + } + position++; + } + + /* Update the LCD display */ + HAL_LCD_UpdateDisplayRequest(&LCDHandle); +} + +/** + * @brief Configure the bar level on LCD by writing bar value in LCD frame buffer. + * @param BarLevel: specifies the LCD GLASS Battery Level. + * This parameter can be one of the following values: + * @arg BATTERYLEVEL_OFF: LCD GLASS Battery Empty + * @arg BATTERYLEVEL_1_4: LCD GLASS Battery 1/4 Full + * @arg BATTERYLEVEL_1_2: LCD GLASS Battery 1/2 Full + * @arg BATTERYLEVEL_3_4: LCD GLASS Battery 3/4 Full + * @arg BATTERYLEVEL_FULL: LCD GLASS Battery Full + * @retval None + */ +void BSP_LCD_GLASS_BarLevelConfig(uint8_t BarLevel) +{ + switch (BarLevel) + { + /* BATTERYLEVEL_OFF */ + case BATTERYLEVEL_OFF: + /* Set BAR0 & BAR2 off */ + HAL_LCD_Write(&LCDHandle, LCD_BAR0_2_COM, ~(LCD_BAR0_SEG | LCD_BAR2_SEG), 0); + /* Set BAR1 & BAR3 off */ + HAL_LCD_Write(&LCDHandle, LCD_BAR1_3_COM, ~(LCD_BAR1_SEG | LCD_BAR3_SEG), 0); + LCDBar = BATTERYLEVEL_OFF; + break; + + /* BARLEVEL 1/4 */ + case BATTERYLEVEL_1_4: + /* Set BAR0 on & BAR2 off */ + HAL_LCD_Write(&LCDHandle, LCD_BAR0_2_COM, ~(LCD_BAR0_SEG | LCD_BAR2_SEG), LCD_BAR0_SEG); + /* Set BAR1 & BAR3 off */ + HAL_LCD_Write(&LCDHandle, LCD_BAR1_3_COM, ~(LCD_BAR1_SEG | LCD_BAR3_SEG), 0); + LCDBar = BATTERYLEVEL_1_4; + break; + + /* BARLEVEL 1/2 */ + case BATTERYLEVEL_1_2: + /* Set BAR0 on & BAR2 off */ + HAL_LCD_Write(&LCDHandle, LCD_BAR0_2_COM, ~(LCD_BAR0_SEG | LCD_BAR2_SEG), LCD_BAR0_SEG); + /* Set BAR1 on & BAR3 off */ + HAL_LCD_Write(&LCDHandle, LCD_BAR1_3_COM, ~(LCD_BAR1_SEG | LCD_BAR3_SEG), LCD_BAR1_SEG); + LCDBar = BATTERYLEVEL_1_2; + break; + + /* Battery Level 3/4 */ + case BATTERYLEVEL_3_4: + /* Set BAR0 & BAR2 on */ + HAL_LCD_Write(&LCDHandle, LCD_BAR0_2_COM, ~(LCD_BAR0_SEG | LCD_BAR2_SEG), (LCD_BAR0_SEG | LCD_BAR2_SEG)); + /* Set BAR1 on & BAR3 off */ + HAL_LCD_Write(&LCDHandle, LCD_BAR1_3_COM, ~(LCD_BAR1_SEG | LCD_BAR3_SEG), LCD_BAR1_SEG); + LCDBar = BATTERYLEVEL_3_4; + break; + + /* BATTERYLEVEL_FULL */ + case BATTERYLEVEL_FULL: + /* Set BAR0 & BAR2 on */ + HAL_LCD_Write(&LCDHandle, LCD_BAR0_2_COM, ~(LCD_BAR0_SEG | LCD_BAR2_SEG), (LCD_BAR0_SEG | LCD_BAR2_SEG)); + /* Set BAR1 on & BAR3 on */ + HAL_LCD_Write(&LCDHandle, LCD_BAR1_3_COM, ~(LCD_BAR1_SEG | LCD_BAR3_SEG), (LCD_BAR1_SEG | LCD_BAR3_SEG)); + LCDBar = BATTERYLEVEL_FULL; + break; + + default: + break; + } + + /* Update the LCD display */ + HAL_LCD_UpdateDisplayRequest(&LCDHandle); +} + +/** + * @brief Write a character in the LCD RAM buffer. + * @param ch: The character to display. + * @param Point: A point to add in front of char. + * This parameter can be one of the following values: + * @arg POINT_OFF: No point to add in front of char. + * @arg POINT_ON: Add a point in front of char. + * @param Colon: Flag indicating if a colon character has to be added in front + * of displayed character. + * This parameter can be one of the following values: + * @arg DOUBLEPOINT_OFF: No colon to add in back of char. + * @arg DOUBLEPOINT_ON: Add an colon in back of char. + * @param Position: Position in the LCD of the character to write. + * This parameter can be any value in range [1:6]. + * @retval None + * @note Required preconditions: The LCD should be cleared before to start the + * write operation. + */ +void BSP_LCD_GLASS_DisplayChar(uint8_t* ch, Point_Typedef Point, DoublePoint_Typedef Colon, DigitPosition_Typedef Position) +{ + WriteChar(ch, Point, Colon, Position); + + /* Update the LCD display */ + HAL_LCD_UpdateDisplayRequest(&LCDHandle); +} + +/** + * @brief Write a character string in the LCD RAM buffer. + * @param ptr: Pointer to string to display on the LCD Glass. + * @retval None + */ +void BSP_LCD_GLASS_DisplayString(uint8_t* ptr) +{ + DigitPosition_Typedef position = LCD_DIGIT_POSITION_1; + + /* Send the string character by character on lCD */ + while ((*ptr != 0) & (position <= LCD_DIGIT_POSITION_6)) + { + /* Write one character on LCD */ + WriteChar(ptr, POINT_OFF, DOUBLEPOINT_OFF, position); + + /* Point on the next character */ + ptr++; + + /* Increment the character counter */ + position++; + } + /* Update the LCD display */ + HAL_LCD_UpdateDisplayRequest(&LCDHandle); +} + +/** + * @brief Write a character string with decimal point in the LCD RAM buffer. + * @param ptr: Pointer to string to display on the LCD Glass. + * @retval None + * @note Required preconditions: Char is ASCCI value "ORed" with decimal point or Colon flag + */ +void BSP_LCD_GLASS_DisplayStrDeci(uint16_t* ptr) +{ + DigitPosition_Typedef index = LCD_DIGIT_POSITION_1; + uint8_t tmpchar = 0; + + /* Send the string character by character on lCD */ + while((*ptr != 0) & (index <= LCD_DIGIT_POSITION_6)) + { + tmpchar = (*ptr) & 0x00FF; + + switch((*ptr) & 0xF000) + { + case DOT: + /* Write one character on LCD with decimal point */ + WriteChar(&tmpchar, POINT_ON, DOUBLEPOINT_OFF, index); + break; + case DOUBLE_DOT: + /* Write one character on LCD with decimal point */ + WriteChar(&tmpchar, POINT_OFF, DOUBLEPOINT_ON, index); + break; + default: + WriteChar(&tmpchar, POINT_OFF, DOUBLEPOINT_OFF, index); + break; + }/* Point on the next character */ + ptr++; + + /* Increment the character counter */ + index++; + } + /* Update the LCD display */ + HAL_LCD_UpdateDisplayRequest(&LCDHandle); +} + +/** + * @brief Clear the whole LCD RAM buffer. + * @retval None + */ +void BSP_LCD_GLASS_Clear(void) +{ + HAL_LCD_Clear(&LCDHandle); +} + +/** + * @brief Display a string in scrolling mode + * @param ptr: Pointer to string to display on the LCD Glass. + * @param nScroll: Specifies how many time the message will be scrolled + * @param ScrollSpeed : Specifies the speed of the scroll, low value gives + * higher speed + * @retval None + * @note Required preconditions: The LCD should be cleared before to start the + * write operation. + */ +void BSP_LCD_GLASS_ScrollSentence(uint8_t* ptr, uint16_t nScroll, uint16_t ScrollSpeed) +{ + uint8_t repetition = 0, nbrchar = 0, sizestr = 0; + uint8_t* ptr1; + uint8_t str[6] = ""; + + /* Reset interrupt variable in case key was press before entering function */ + bLCDGlass_KeyPressed = 0; + + if(ptr == 0) + { + return; + } + + /* To calculate end of string */ + for(ptr1 = ptr, sizestr = 0; *ptr1 != 0; sizestr++, ptr1++); + + ptr1 = ptr; + + BSP_LCD_GLASS_DisplayString(str); + HAL_Delay(ScrollSpeed); + + /* To shift the string for scrolling display*/ + for (repetition = 0; repetition < nScroll; repetition++) + { + for(nbrchar = 0; nbrchar < sizestr; nbrchar++) + { + *(str) =* (ptr1+((nbrchar+1)%sizestr)); + *(str+1) =* (ptr1+((nbrchar+2)%sizestr)); + *(str+2) =* (ptr1+((nbrchar+3)%sizestr)); + *(str+3) =* (ptr1+((nbrchar+4)%sizestr)); + *(str+4) =* (ptr1+((nbrchar+5)%sizestr)); + *(str+5) =* (ptr1+((nbrchar+6)%sizestr)); + BSP_LCD_GLASS_Clear(); + BSP_LCD_GLASS_DisplayString(str); + + /* user button pressed stop the scrolling sentence */ + if(bLCDGlass_KeyPressed) + { + bLCDGlass_KeyPressed = 0; + return; + } + HAL_Delay(ScrollSpeed); + } + } +} + +/** + * @} + */ + +/** @addtogroup STM32L476G_DISCOVERY_LCD_Private_Functions + * @{ + */ + +/** + * @brief Initialize the LCD MSP. + * @param hlcd: LCD handle + * @retval None + */ +static void LCD_MspInit(LCD_HandleTypeDef *hlcd) +{ + GPIO_InitTypeDef gpioinitstruct = {0}; + RCC_OscInitTypeDef oscinitstruct = {0}; + RCC_PeriphCLKInitTypeDef periphclkstruct = {0}; + + /*##-1- Enable PWR peripheral Clock #######################################*/ + __HAL_RCC_PWR_CLK_ENABLE(); + + /*##-2- Configure LSE as RTC clock soucre ###################################*/ + oscinitstruct.OscillatorType = RCC_OSCILLATORTYPE_LSE; + oscinitstruct.PLL.PLLState = RCC_PLL_NONE; + oscinitstruct.LSEState = RCC_LSE_ON; + if(HAL_RCC_OscConfig(&oscinitstruct) != HAL_OK) + { + while(1); + } + + /*##-3- Select LSE as RTC clock source.##########################*/ + /* Backup domain management is done in RCC function */ + periphclkstruct.PeriphClockSelection = RCC_PERIPHCLK_RTC; + periphclkstruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; + HAL_RCCEx_PeriphCLKConfig(&periphclkstruct); + + /*##-4- Enable LCD GPIO Clocks #############################################*/ + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + + + /*##-5- Configure peripheral GPIO ##########################################*/ + /* Configure Output for LCD */ + /* Port A */ + gpioinitstruct.Pin = LCD_GPIO_BANKA_PINS; + gpioinitstruct.Mode = GPIO_MODE_AF_PP; + gpioinitstruct.Pull = GPIO_NOPULL; + gpioinitstruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + gpioinitstruct.Alternate = GPIO_AF11_LCD; + HAL_GPIO_Init(GPIOA, &gpioinitstruct); + + /* Port B */ + gpioinitstruct.Pin = LCD_GPIO_BANKB_PINS; + HAL_GPIO_Init(GPIOB, &gpioinitstruct); + + /* Port C*/ + gpioinitstruct.Pin = LCD_GPIO_BANKC_PINS; + HAL_GPIO_Init(GPIOC, &gpioinitstruct); + + /* Port D */ + gpioinitstruct.Pin = LCD_GPIO_BANKD_PINS; + HAL_GPIO_Init(GPIOD, &gpioinitstruct); + + /* Wait for the external capacitor Cext which is connected to the VLCD pin is charged + (approximately 2ms for Cext=1uF) */ + HAL_Delay(2); + + /*##-6- Enable LCD peripheral Clock ########################################*/ + __HAL_RCC_LCD_CLK_ENABLE(); +} + +/** + * @brief DeInitialize the LCD MSP. + * @param hlcd: LCD handle + * @retval None + */ +static void LCD_MspDeInit(LCD_HandleTypeDef *hlcd) +{ + uint32_t gpiopin = 0; + + /*##-1- Enable LCD GPIO Clocks #############################################*/ + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + + /*##-1- Configure peripheral GPIO ##########################################*/ + /* Configure Output for LCD */ + /* Port A */ + gpiopin = LCD_GPIO_BANKA_PINS; + HAL_GPIO_DeInit(GPIOA, gpiopin); + + /* Port B */ + gpiopin = LCD_GPIO_BANKB_PINS; + HAL_GPIO_DeInit(GPIOB, gpiopin); + + /* Port C*/ + gpiopin = LCD_GPIO_BANKC_PINS; + HAL_GPIO_DeInit(GPIOC, gpiopin); + + /* Port D */ + gpiopin = LCD_GPIO_BANKD_PINS; + HAL_GPIO_DeInit(GPIOD, gpiopin); + + /*##-5- Enable LCD peripheral Clock ########################################*/ + __HAL_RCC_LCD_CLK_DISABLE(); +} + +/** + * @brief Convert an ascii char to the a LCD digit. + * @param Char: a char to display. + * @param Point: a point to add in front of char + * This parameter can be: POINT_OFF or POINT_ON + * @param Colon : flag indicating if a colon character has to be added in front + * of displayed character. + * This parameter can be: DOUBLEPOINT_OFF or DOUBLEPOINT_ON. + * @retval None + */ +static void Convert(uint8_t* Char, Point_Typedef Point, DoublePoint_Typedef Colon) +{ + uint16_t ch = 0 ; + uint8_t loop = 0, index = 0; + + switch (*Char) + { + case ' ' : + ch = 0x00; + break; + + case '*': + ch = C_STAR; + break; + + case '(' : + ch = C_OPENPARMAP; + break; + + case ')' : + ch = C_CLOSEPARMAP; + break; + + case 'd' : + ch = C_DMAP; + break; + + case 'm' : + ch = C_MMAP; + break; + + case 'n' : + ch = C_NMAP; + break; + + case 'u' : + ch = C_UMAP; + break; + + case '-' : + ch = C_MINUS; + break; + + case '+' : + ch = C_PLUS; + break; + + case '/' : + ch = C_SLATCH; + break; + + case '�' : + ch = C_PERCENT_1; + break; + case '%' : + ch = C_PERCENT_2; + break; + case 255 : + ch = C_FULL; + break ; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + ch = NumberMap[*Char - ASCII_CHAR_0]; + break; + + default: + /* The character Char is one letter in upper case*/ + if ( (*Char < ASCII_CHAR_LEFT_OPEN_BRACKET) && (*Char > ASCII_CHAR_AT_SYMBOL) ) + { + ch = CapLetterMap[*Char - 'A']; + } + /* The character Char is one letter in lower case*/ + if ( (*Char < ASCII_CHAR_LEFT_OPEN_BRACE) && ( *Char > ASCII_CHAR_APOSTROPHE) ) + { + ch = CapLetterMap[*Char - 'a']; + } + break; + } + + /* Set the digital point can be displayed if the point is on */ + if (Point == POINT_ON) + { + ch |= 0x0002; + } + + /* Set the "COL" segment in the character that can be displayed if the colon is on */ + if (Colon == DOUBLEPOINT_ON) + { + ch |= 0x0020; + } + + for (loop = 12,index=0 ;index < 4; loop -= 4,index++) + { + Digit[index] = (ch >> loop) & 0x0f; /*To isolate the less significant digit */ + } +} + +/** + * @brief Write a character in the LCD frame buffer. + * @param ch: the character to display. + * @param Point: a point to add in front of char + * This parameter can be: POINT_OFF or POINT_ON + * @param Colon: flag indicating if a colon character has to be added in front + * of displayed character. + * This parameter can be: DOUBLEPOINT_OFF or DOUBLEPOINT_ON. + * @param Position: position in the LCD of the character to write [1:6] + * @retval None + */ +static void WriteChar(uint8_t* ch, Point_Typedef Point, DoublePoint_Typedef Colon, DigitPosition_Typedef Position) +{ + uint32_t data =0x00; + /* To convert displayed character in segment in array digit */ + Convert(ch, (Point_Typedef)Point, (DoublePoint_Typedef)Colon); + + switch (Position) + { + /* Position 1 on LCD (Digit1)*/ + case LCD_DIGIT_POSITION_1: + data = ((Digit[0] & 0x1) << LCD_SEG0_SHIFT) | (((Digit[0] & 0x2) >> 1) << LCD_SEG1_SHIFT) + | (((Digit[0] & 0x4) >> 2) << LCD_SEG22_SHIFT) | (((Digit[0] & 0x8) >> 3) << LCD_SEG23_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT1_COM0, LCD_DIGIT1_COM0_SEG_MASK, data); /* 1G 1B 1M 1E */ + + data = ((Digit[1] & 0x1) << LCD_SEG0_SHIFT) | (((Digit[1] & 0x2) >> 1) << LCD_SEG1_SHIFT) + | (((Digit[1] & 0x4) >> 2) << LCD_SEG22_SHIFT) | (((Digit[1] & 0x8) >> 3) << LCD_SEG23_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT1_COM1, LCD_DIGIT1_COM1_SEG_MASK, data) ; /* 1F 1A 1C 1D */ + + data = ((Digit[2] & 0x1) << LCD_SEG0_SHIFT) | (((Digit[2] & 0x2) >> 1) << LCD_SEG1_SHIFT) + | (((Digit[2] & 0x4) >> 2) << LCD_SEG22_SHIFT) | (((Digit[2] & 0x8) >> 3) << LCD_SEG23_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT1_COM2, LCD_DIGIT1_COM2_SEG_MASK, data) ; /* 1Q 1K 1Col 1P */ + + data = ((Digit[3] & 0x1) << LCD_SEG0_SHIFT) | (((Digit[3] & 0x2) >> 1) << LCD_SEG1_SHIFT) + | (((Digit[3] & 0x4) >> 2) << LCD_SEG22_SHIFT) | (((Digit[3] & 0x8) >> 3) << LCD_SEG23_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT1_COM3, LCD_DIGIT1_COM3_SEG_MASK, data) ; /* 1H 1J 1DP 1N */ + break; + + /* Position 2 on LCD (Digit2)*/ + case LCD_DIGIT_POSITION_2: + data = ((Digit[0] & 0x1) << LCD_SEG2_SHIFT) | (((Digit[0] & 0x2) >> 1) << LCD_SEG3_SHIFT) + | (((Digit[0] & 0x4) >> 2) << LCD_SEG20_SHIFT) | (((Digit[0] & 0x8) >> 3) << LCD_SEG21_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT2_COM0, LCD_DIGIT2_COM0_SEG_MASK, data); /* 1G 1B 1M 1E */ + + data = ((Digit[1] & 0x1) << LCD_SEG2_SHIFT) | (((Digit[1] & 0x2) >> 1) << LCD_SEG3_SHIFT) + | (((Digit[1] & 0x4) >> 2) << LCD_SEG20_SHIFT) | (((Digit[1] & 0x8) >> 3) << LCD_SEG21_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT2_COM1, LCD_DIGIT2_COM1_SEG_MASK, data) ; /* 1F 1A 1C 1D */ + + data = ((Digit[2] & 0x1) << LCD_SEG2_SHIFT) | (((Digit[2] & 0x2) >> 1) << LCD_SEG3_SHIFT) + | (((Digit[2] & 0x4) >> 2) << LCD_SEG20_SHIFT) | (((Digit[2] & 0x8) >> 3) << LCD_SEG21_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT2_COM2, LCD_DIGIT2_COM2_SEG_MASK, data) ; /* 1Q 1K 1Col 1P */ + + data = ((Digit[3] & 0x1) << LCD_SEG2_SHIFT) | (((Digit[3] & 0x2) >> 1) << LCD_SEG3_SHIFT) + | (((Digit[3] & 0x4) >> 2) << LCD_SEG20_SHIFT) | (((Digit[3] & 0x8) >> 3) << LCD_SEG21_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT2_COM3, LCD_DIGIT2_COM3_SEG_MASK, data) ; /* 1H 1J 1DP 1N */ + break; + + /* Position 3 on LCD (Digit3)*/ + case LCD_DIGIT_POSITION_3: + data = ((Digit[0] & 0x1) << LCD_SEG4_SHIFT) | (((Digit[0] & 0x2) >> 1) << LCD_SEG5_SHIFT) + | (((Digit[0] & 0x4) >> 2) << LCD_SEG18_SHIFT) | (((Digit[0] & 0x8) >> 3) << LCD_SEG19_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT3_COM0, LCD_DIGIT3_COM0_SEG_MASK, data); /* 1G 1B 1M 1E */ + + data = ((Digit[1] & 0x1) << LCD_SEG4_SHIFT) | (((Digit[1] & 0x2) >> 1) << LCD_SEG5_SHIFT) + | (((Digit[1] & 0x4) >> 2) << LCD_SEG18_SHIFT) | (((Digit[1] & 0x8) >> 3) << LCD_SEG19_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT3_COM1, LCD_DIGIT3_COM1_SEG_MASK, data) ; /* 1F 1A 1C 1D */ + + data = ((Digit[2] & 0x1) << LCD_SEG4_SHIFT) | (((Digit[2] & 0x2) >> 1) << LCD_SEG5_SHIFT) + | (((Digit[2] & 0x4) >> 2) << LCD_SEG18_SHIFT) | (((Digit[2] & 0x8) >> 3) << LCD_SEG19_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT3_COM2, LCD_DIGIT3_COM2_SEG_MASK, data) ; /* 1Q 1K 1Col 1P */ + + data = ((Digit[3] & 0x1) << LCD_SEG4_SHIFT) | (((Digit[3] & 0x2) >> 1) << LCD_SEG5_SHIFT) + | (((Digit[3] & 0x4) >> 2) << LCD_SEG18_SHIFT) | (((Digit[3] & 0x8) >> 3) << LCD_SEG19_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT3_COM3, LCD_DIGIT3_COM3_SEG_MASK, data) ; /* 1H 1J 1DP 1N */ + break; + + /* Position 4 on LCD (Digit4)*/ + case LCD_DIGIT_POSITION_4: + data = ((Digit[0] & 0x1) << LCD_SEG6_SHIFT) | (((Digit[0] & 0x8) >> 3) << LCD_SEG17_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT4_COM0, LCD_DIGIT4_COM0_SEG_MASK, data); /* 1G 1B 1M 1E */ + + data = (((Digit[0] & 0x2) >> 1) << LCD_SEG7_SHIFT) | (((Digit[0] & 0x4) >> 2) << LCD_SEG16_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT4_COM0_1, LCD_DIGIT4_COM0_1_SEG_MASK, data); /* 1G 1B 1M 1E */ + + data = ((Digit[1] & 0x1) << LCD_SEG6_SHIFT) | (((Digit[1] & 0x8) >> 3) << LCD_SEG17_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT4_COM1, LCD_DIGIT4_COM1_SEG_MASK, data) ; /* 1F 1A 1C 1D */ + + data = (((Digit[1] & 0x2) >> 1) << LCD_SEG7_SHIFT) | (((Digit[1] & 0x4) >> 2) << LCD_SEG16_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT4_COM1_1, LCD_DIGIT4_COM1_1_SEG_MASK, data) ; /* 1F 1A 1C 1D */ + + data = ((Digit[2] & 0x1) << LCD_SEG6_SHIFT) | (((Digit[2] & 0x8) >> 3) << LCD_SEG17_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT4_COM2, LCD_DIGIT4_COM2_SEG_MASK, data) ; /* 1Q 1K 1Col 1P */ + + data = (((Digit[2] & 0x2) >> 1) << LCD_SEG7_SHIFT) | (((Digit[2] & 0x4) >> 2) << LCD_SEG16_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT4_COM2_1, LCD_DIGIT4_COM2_1_SEG_MASK, data) ; /* 1Q 1K 1Col 1P */ + + data = ((Digit[3] & 0x1) << LCD_SEG6_SHIFT) | (((Digit[3] & 0x8) >> 3) << LCD_SEG17_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT4_COM3, LCD_DIGIT4_COM3_SEG_MASK, data) ; /* 1H 1J 1DP 1N */ + + data = (((Digit[3] & 0x2) >> 1) << LCD_SEG7_SHIFT) | (((Digit[3] & 0x4) >> 2) << LCD_SEG16_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT4_COM3_1, LCD_DIGIT4_COM3_1_SEG_MASK, data) ; /* 1H 1J 1DP 1N */ + break; + + /* Position 5 on LCD (Digit5)*/ + case LCD_DIGIT_POSITION_5: + data = (((Digit[0] & 0x2) >> 1) << LCD_SEG9_SHIFT) | (((Digit[0] & 0x4) >> 2) << LCD_SEG14_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT5_COM0, LCD_DIGIT5_COM0_SEG_MASK, data); /* 1G 1B 1M 1E */ + + data = ((Digit[0] & 0x1) << LCD_SEG8_SHIFT) | (((Digit[0] & 0x8) >> 3) << LCD_SEG15_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT5_COM0_1, LCD_DIGIT5_COM0_1_SEG_MASK, data); /* 1G 1B 1M 1E */ + + data = (((Digit[1] & 0x2) >> 1) << LCD_SEG9_SHIFT) | (((Digit[1] & 0x4) >> 2) << LCD_SEG14_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT5_COM1, LCD_DIGIT5_COM1_SEG_MASK, data) ; /* 1F 1A 1C 1D */ + + data = ((Digit[1] & 0x1) << LCD_SEG8_SHIFT) | (((Digit[1] & 0x8) >> 3) << LCD_SEG15_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT5_COM1_1, LCD_DIGIT5_COM1_1_SEG_MASK, data) ; /* 1F 1A 1C 1D */ + + data = (((Digit[2] & 0x2) >> 1) << LCD_SEG9_SHIFT) | (((Digit[2] & 0x4) >> 2) << LCD_SEG14_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT5_COM2, LCD_DIGIT5_COM2_SEG_MASK, data) ; /* 1Q 1K 1Col 1P */ + + data = ((Digit[2] & 0x1) << LCD_SEG8_SHIFT) | (((Digit[2] & 0x8) >> 3) << LCD_SEG15_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT5_COM2_1, LCD_DIGIT5_COM2_1_SEG_MASK, data) ; /* 1Q 1K 1Col 1P */ + + data = (((Digit[3] & 0x2) >> 1) << LCD_SEG9_SHIFT) | (((Digit[3] & 0x4) >> 2) << LCD_SEG14_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT5_COM3, LCD_DIGIT5_COM3_SEG_MASK, data) ; /* 1H 1J 1DP 1N */ + + data = ((Digit[3] & 0x1) << LCD_SEG8_SHIFT) | (((Digit[3] & 0x8) >> 3) << LCD_SEG15_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT5_COM3_1, LCD_DIGIT5_COM3_1_SEG_MASK, data) ; /* 1H 1J 1DP 1N */ + break; + + /* Position 6 on LCD (Digit6)*/ + case LCD_DIGIT_POSITION_6: + data = ((Digit[0] & 0x1) << LCD_SEG10_SHIFT) | (((Digit[0] & 0x2) >> 1) << LCD_SEG11_SHIFT) + | (((Digit[0] & 0x4) >> 2) << LCD_SEG12_SHIFT) | (((Digit[0] & 0x8) >> 3) << LCD_SEG13_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT6_COM0, LCD_DIGIT6_COM0_SEG_MASK, data); /* 1G 1B 1M 1E */ + + data = ((Digit[1] & 0x1) << LCD_SEG10_SHIFT) | (((Digit[1] & 0x2) >> 1) << LCD_SEG11_SHIFT) + | (((Digit[1] & 0x4) >> 2) << LCD_SEG12_SHIFT) | (((Digit[1] & 0x8) >> 3) << LCD_SEG13_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT6_COM1, LCD_DIGIT6_COM1_SEG_MASK, data) ; /* 1F 1A 1C 1D */ + + data = ((Digit[2] & 0x1) << LCD_SEG10_SHIFT) | (((Digit[2] & 0x2) >> 1) << LCD_SEG11_SHIFT) + | (((Digit[2] & 0x4) >> 2) << LCD_SEG12_SHIFT) | (((Digit[2] & 0x8) >> 3) << LCD_SEG13_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT6_COM2, LCD_DIGIT6_COM2_SEG_MASK, data) ; /* 1Q 1K 1Col 1P */ + + data = ((Digit[3] & 0x1) << LCD_SEG10_SHIFT) | (((Digit[3] & 0x2) >> 1) << LCD_SEG11_SHIFT) + | (((Digit[3] & 0x4) >> 2) << LCD_SEG12_SHIFT) | (((Digit[3] & 0x8) >> 3) << LCD_SEG13_SHIFT); + HAL_LCD_Write(&LCDHandle, LCD_DIGIT6_COM3, LCD_DIGIT6_COM3_SEG_MASK, data) ; /* 1H 1J 1DP 1N */ + break; + + default: + break; + } +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +