/**
******************************************************************************
* @file stm8l_discovery_lcd.c
* @author Microcontroller Division
* @version V1.2.0
* @date 09/2010
* @brief This file includes driver for the glass LCD Module mounted on
* STM8L1526 discovery board MB915A.
******************************************************************************
* @copy
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>© COPYRIGHT 2010 STMicroelectronics</center></h2>
*/
/* Includes ------------------------------------------------------------------*/
#include "stm8l_discovery_lcd.h"
#include "discover_board.h"
/* this variable can be used for accelerate the scrolling exit when push user button */
bool KeyPressed = FALSE;
/* =========================================================================
LCD MAPPING
=========================================================================
A
_ ----------
COL |_| |\ |J /|
F| H | K |B
_ | \ | / |
COL |_| --G-- --M--
| /| \ |
E| Q | N |C
_ | / |P \|
DP |_| -----------
D
An LCD character coding is based on the following matrix:
{ E , D , F , COL }
{ M , C , G , H }
{ B , A , B , A }
{ G , F , K , J }
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
*/
/* Constant table for cap characters 'A' --> 'Z' */
const uint16_t CapLetterMap[26]=
{
/* A B C D E F G H I */
0xFE00,0x6711,0x1d00,0x4711,0x9d00,0x9c00,0x3f00,0xfa00,0x0011,
/* J K L M N O P Q R */
0x5300,0x9844,0x1900,0x5a42,0x5a06,0x5f00,0xFC00,0x5F04,0xFC04,
/* S T U V W X Y Z */
0xAF00,0x0411,0x5b00,0x18c0,0x5a84,0x00c6,0x0052,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
};
/* LCD BAR status: We don't write directly in LCD RAM for save the bar setting */
uint8_t t_bar[2]={0x0,0X0};
static void LCD_Conv_Char_Seg(uint8_t* c,bool point,bool column,uint8_t* digit);
/**
* @brief Configures the LCD GLASS relative GPIO port IOs and LCD peripheral.
* @param None
* @retval None
*/
void LCD_GLASS_Init(void)
{
/* Enable LCD/RTC clock */
CLK_PeripheralClockConfig(CLK_Peripheral_RTC, ENABLE);
CLK_PeripheralClockConfig(CLK_Peripheral_LCD, ENABLE);
#ifdef USE_LSE
CLK_RTCClockConfig(CLK_RTCCLKSource_LSE, CLK_RTCCLKDiv_1);
#else
CLK_RTCClockConfig(CLK_RTCCLKSource_LSI, CLK_RTCCLKDiv_1);
#endif
/* Initialize the LCD */
LCD_Init(LCD_Prescaler_1, LCD_Divider_31, LCD_Duty_1_4,
LCD_Bias_1_3, LCD_VoltageSource_Internal);
/* Mask register
For declare the segements used.
in the Discovery we use 0 to 23 segments. */
LCD_PortMaskConfig(LCD_PortMaskRegister_0, 0xFF);
LCD_PortMaskConfig(LCD_PortMaskRegister_1, 0xFF);
LCD_PortMaskConfig(LCD_PortMaskRegister_2, 0xff);
/* To set contrast to mean value */
LCD_ContrastConfig(LCD_Contrast_3V0);
LCD_DeadTimeConfig(LCD_DeadTime_0);
LCD_PulseOnDurationConfig(LCD_PulseOnDuration_1);
/* Enable LCD peripheral */
LCD_Cmd(ENABLE);
}
/**
* @brief LCD contrast setting min-->max-->min by pressing user button
* @param None
* @retval None
*/
void LCD_contrast()
{
LCD_Contrast_TypeDef contrast;
/* To get the actual contrast value in register */
contrast = (LCD_Contrast_TypeDef) (LCD->CR2 & LCD_Contrast_3V3);
while ((GPIOC->IDR & USER_GPIO_PIN) == 0x0)
{
contrast+=2;
if (contrast>LCD_Contrast_3V3)
contrast=LCD_Contrast_2V6;
LCD_ContrastConfig(contrast);
delay_ms(100);
}
}
/**
* @brief Setting bar on LCD, writes bar value in LCD frame buffer
* @param None
* @retval None
*/
void LCD_bar()
{
/* bar0 bar2 */
LCD->RAM[LCD_RAMRegister_11] &= 0x5f;
LCD->RAM[LCD_RAMRegister_11] |= t_bar[0]&0xa0;
/*bar1 bar3 */
LCD->RAM[LCD_RAMRegister_8] &= 0xf5;
LCD->RAM[LCD_RAMRegister_8] |= t_bar[1]&0x0a;
}
/**
* @brief Converts an ascii char to the a LCD digit.
* @param c: a char to display.
* @param point: a point to add in front of char
* This parameter can be: POINT_OFF or POINT_ON
* @param column : flag indicating if a column has to be add in front
* of displayed character.
* This parameter can be: COLUMN_OFF or COLUMN_ON.
* @param digit array with segment
* @retval None
*/
static void LCD_Conv_Char_Seg(uint8_t* c,bool point,bool column, uint8_t* digit)
{
uint16_t ch = 0 ;
uint8_t i,j;
switch (*c)
{
case ' ' :
ch = 0x00;
break;
case '*':
ch = star;
break;
case '?':
ch = C_UMAP;
break;
case 'm' :
ch = C_mMap;
break;
case 'n' :
ch = C_nMap;
break;
case '-' :
ch = C_minus;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
ch = NumberMap[*c-0x30];
break;
default:
/* The character c is one letter in upper case*/
if ( (*c < 0x5b) && (*c > 0x40) )
{
ch = CapLetterMap[*c-'A'];
}
/* The character c is one letter in lower case*/
if ( (*c <0x7b) && ( *c> 0x60) )
{
ch = CapLetterMap[*c-'a'];
}
break;
}
/* Set the digital point can be displayed if the point is on */
if (point)
{
ch |= 0x0008;
}
/* Set the "COL" segment in the character that can be displayed if the column is on */
if (column)
{
ch |= 0x0020;
}
for (i = 12,j=0 ;j<4; i-=4,j++)
{
digit[j] = (ch >> i) & 0x0f; //To isolate the less signifiant dibit
}
}
/**
* @brief This function writes a char in the LCD frame buffer.
* @param ch: the character to dispaly.
* @param point: a point to add in front of char
* This parameter can be: POINT_OFF or POINT_ON
* @param column: flag indicating if a column has to be add in front
* of displayed character.
* This parameter can be: COLUMN_OFF or COLUMN_ON.
* @param position: position in the LCD of the caracter to write [0:7]
* @retval None
* @par Required preconditions: The LCD should be cleared before to start the
* write operation.
*/
void LCD_GLASS_WriteChar(uint8_t* ch, bool point, bool column, uint8_t position)
{
uint8_t digit[4]; /* Digit frame buffer */
/* To convert displayed character in segment in array digit */
LCD_Conv_Char_Seg(ch,point,column,digit);
switch (position)
{
/* Position 1 on LCD (Digit1)*/
case 1:
LCD->RAM[LCD_RAMRegister_0] &= 0x0