|
|
|
#include "smartxxlcd.h"
|
|
#include "conio.h"
|
|
#include "utils/SystemInfo.h"
|
|
#include "memutil.h"
|
|
#include "Application.h" // for g_application.IsInScreenSaver()
|
|
#include "utils/LED.h"
|
|
#include "settings/Settings.h"
|
|
#include "utils/log.h"
|
|
|
|
#include <conio.h>
|
|
|
|
/*
|
|
HD44780 or equivalent
|
|
Character located 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
|
DDRAM address 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13
|
|
DDRAM address 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53
|
|
DDRAM address 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27
|
|
DDRAM address 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67
|
|
*/
|
|
|
|
#define SCROLL_SPEED_IN_MSEC 250
|
|
#define DISP_O 0xF700 // Display Port
|
|
#define DISP_O_LIGHT 0xF701 // Display Port brightness control
|
|
#define DISP_O_CONTRAST 0xF703 // Display Port contrast control
|
|
#define DISP_CTR_TIME 2 // Controll Timing for Display routine
|
|
|
|
#define DISPCON_RS 0x02 // some Display definitions
|
|
#define DISPCON_E 0x04
|
|
|
|
#define INI 0x01
|
|
#define CMD 0x00
|
|
#define DAT 0x02
|
|
|
|
#define DISP_CLEAR 0x01 // cmd: clear display command
|
|
#define DISP_HOME 0x02 // cmd: return cursor to home
|
|
#define DISP_ENTRY_MODE_SET 0x04 // cmd: enable cursor moving direction and enable the shift of entire display
|
|
#define DISP_S_FLAG 0x01
|
|
#define DISP_ID_FLAG 0x02
|
|
|
|
#define DISP_CONTROL 0x08 //cmd: display ON/OFF
|
|
#define DISP_D_FLAG 0x04 // display on
|
|
#define DISP_C_FLAG 0x02 // cursor on
|
|
#define DISP_B_FLAG 0x01 // blinking on
|
|
|
|
#define DISP_EXT_CONTROL 0x08 //RE_FLAG = 1
|
|
#define DISP_FW_FLAG 0x04 //RE_FLAG = 1
|
|
#define DISP_BW_FLAG 0x02 //RE_FLAG = 1
|
|
#define DISP_NW_FLAG 0x01 //RE_FLAG = 1
|
|
|
|
#define DISP_SHIFT 0x10 //cmd: set cursor moving and display shift control bit, and the direction without changing of ddram data
|
|
#define DISP_SC_FLAG 0x08
|
|
#define DISP_RL_FLAG 0x04
|
|
|
|
#define DISP_FUNCTION_SET 0x20 // cmd: set interface data length
|
|
#define DISP_DL_FLAG 0x10 // set interface data length: 8bit/4bit
|
|
#define DISP_N_FLAG 0x08 // number of display lines:2-line / 1-line
|
|
#define DISP_F_FLAG 0x04 // display font type 5x11 dots or 5x8 dots
|
|
#define DISP_RE_FLAG 0x04
|
|
|
|
#define DISP_CGRAM_SET 0x40 // cmd: set CGRAM address in address counter
|
|
#define DISP_SEGRAM_SET 0x40 //RE_FLAG = 1
|
|
|
|
#define DISP_DDRAM_SET 0x80 // cmd: set DDRAM address in address counter
|
|
|
|
char AnimIndex=0;
|
|
|
|
//*************************************************************************************************************
|
|
CSmartXXLCD::CSmartXXLCD()
|
|
{
|
|
m_iActualpos=0;
|
|
m_iRows = 4;
|
|
m_iColumns = 20; // display rows each line
|
|
m_iBackLight=32;
|
|
|
|
if (g_guiSettings.GetInt("lcd.type") == LCD_TYPE_LCD_KS0073)
|
|
{
|
|
// Special case: it's the KS0073
|
|
m_iRow1adr = 0x00;
|
|
m_iRow2adr = 0x20;
|
|
m_iRow3adr = 0x40;
|
|
m_iRow4adr = 0x60;
|
|
}
|
|
else
|
|
{
|
|
// We assume that it's a HD44780 compatible
|
|
m_iRow1adr = 0x00;
|
|
m_iRow2adr = 0x40;
|
|
m_iRow3adr = 0x14;
|
|
m_iRow4adr = 0x54;
|
|
}
|
|
}
|
|
|
|
//*************************************************************************************************************
|
|
CSmartXXLCD::~CSmartXXLCD()
|
|
{
|
|
}
|
|
|
|
//*************************************************************************************************************
|
|
void CSmartXXLCD::Initialize()
|
|
{
|
|
StopThread();
|
|
if (g_guiSettings.GetInt("lcd.type") == LCD_TYPE_NONE)
|
|
{
|
|
CLog::Log(LOGINFO, "lcd not used");
|
|
return;
|
|
}
|
|
ILCD::Initialize();
|
|
Create();
|
|
|
|
}
|
|
void CSmartXXLCD::SetBackLight(int iLight)
|
|
{
|
|
m_iBackLight=iLight;
|
|
}
|
|
|
|
void CSmartXXLCD::SetContrast(int iContrast)
|
|
{
|
|
m_iContrast=iContrast;
|
|
}
|
|
|
|
//*************************************************************************************************************
|
|
void CSmartXXLCD::Stop()
|
|
{
|
|
if (g_guiSettings.GetInt("lcd.type") == LCD_TYPE_NONE) return;
|
|
StopThread();
|
|
}
|
|
|
|
//*************************************************************************************************************
|
|
void CSmartXXLCD::SetLine(int iLine, const CStdString& strLine)
|
|
{
|
|
if (g_guiSettings.GetInt("lcd.type") == LCD_TYPE_NONE) return;
|
|
if (iLine < 0 || iLine >= (int)m_iRows) return;
|
|
|
|
CStdString strLineLong=strLine;
|
|
//strLineLong.Trim();
|
|
StringToLCDCharSet(strLineLong);
|
|
|
|
while (strLineLong.size() < m_iColumns) strLineLong+=" ";
|
|
if (strLineLong != m_strLine[iLine])
|
|
{
|
|
// CLog::Log(LOGINFO, "set line:%i [%s]", iLine,strLineLong.c_str());
|
|
m_bUpdate[iLine]=true;
|
|
m_strLine[iLine]=strLineLong;
|
|
m_event.Set();
|
|
}
|
|
}
|
|
|
|
|
|
//************************************************************************************************************************
|
|
// wait_us: delay routine
|
|
// Input: (wait in ~us)
|
|
//************************************************************************************************************************
|
|
void CSmartXXLCD::wait_us(unsigned int value)
|
|
{
|
|
// 1 us = 1000msec
|
|
int iValue=value/30;
|
|
if (iValue>10) iValue=10;
|
|
if (iValue) Sleep(iValue);
|
|
}
|
|
|
|
|
|
//************************************************************************************************************************
|
|
// DisplayOut: writes command or datas to display
|
|
// Input: (Value to write, token as CMD = Command / DAT = DATAs / INI for switching to 4 bit mode)
|
|
//************************************************************************************************************************
|
|
void CSmartXXLCD::DisplayOut(unsigned char data, unsigned char command)
|
|
{
|
|
unsigned char odathigh;
|
|
unsigned char odatlow;
|
|
static DWORD dwTick=0;
|
|
|
|
if ((GetTickCount()-dwTick) < 3)
|
|
{
|
|
Sleep(1);
|
|
}
|
|
dwTick=GetTickCount();
|
|
|
|
// Data bit's mapping for higher nibble outbut
|
|
odathigh = (data >> 2) & 0x28; // outD7 => PortD5 => DisplayD7 //outD5 => PortD3 => DisplayD5
|
|
odathigh |= (data >> 0) & 0x50; // outD6 => PortD6 => DisplayD6 //outD4 => PortD4 => DisplayD4
|
|
|
|
// Data bit's mapping for lower nibble outbut
|
|
odatlow = (data << 2) & 0x28; // outD3 => PortD5 => DisplayD7 //outD1 => PortD3 => DisplayD5
|
|
odatlow |= (data << 4) & 0x50; // outD2 => PortD6 => DisplayD6 //outD0 => PortD4 => DisplayD4
|
|
|
|
//outbut higher nibble
|
|
_outp(DISP_O, (command & DISPCON_RS) | odathigh); // set the RS if needed
|
|
_outp(DISP_O,((command & DISPCON_RS) | DISPCON_E | odathigh)); // set E
|
|
_outp(DISP_O,((command & DISPCON_RS) | odathigh)); // reset E
|
|
|
|
|
|
if ((command & INI) == 0)
|
|
{
|
|
// if it's not the init command, do second nibble
|
|
//wait_us(DISP_CTR_TIME * 21);
|
|
//outbut lower nibble
|
|
_outp(DISP_O,((command & DISPCON_RS) | odatlow)); // set E
|
|
_outp(DISP_O,((command & DISPCON_RS) | DISPCON_E | odatlow)); // set Data
|
|
_outp(DISP_O,((command & DISPCON_RS) | odatlow)); // reset E
|
|
if ((data & 0xFC) == 0)
|
|
{
|
|
// if command was a Clear Display
|
|
// or Cursor Home, wait at least 1.5 ms more
|
|
m_iActualpos = 0;
|
|
Sleep(2);
|
|
}
|
|
if ((command & DISPCON_RS) == 0x02) m_iActualpos++;
|
|
}
|
|
else
|
|
{
|
|
m_iActualpos = 0;
|
|
|
|
//wait_us(2500); // wait 2.5 msec
|
|
}
|
|
usleep(50);
|
|
}
|
|
|
|
//************************************************************************************************************************
|
|
//DisplayBuildCustomChars: load customized characters to character ram of display, resets cursor to pos 0
|
|
//************************************************************************************************************************
|
|
void CSmartXXLCD::DisplayBuildCustomChars()
|
|
{
|
|
int I;
|
|
|
|
static char Bar0[] ={0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10};
|
|
static char Bar1[] ={0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18};
|
|
static char Bar2[] ={0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c};
|
|
static char Bar3[] ={0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}; //4pixel
|
|
|
|
// Animated Rew
|
|
static char REW[8][8]=
|
|
{
|
|
{0x00, 0x05, 0x0a, 0x14, 0x0a, 0x05, 0x00, 0x00},
|
|
{0x00, 0x0a, 0x14, 0x08, 0x14, 0x0a, 0x00, 0x00},
|
|
{0x00, 0x14, 0x08, 0x10, 0x08, 0x14, 0x00, 0x00},
|
|
{0x00, 0x08, 0x10, 0x00, 0x10, 0x08, 0x00, 0x00},
|
|
{0x00, 0x10, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00},
|
|
{0x00, 0x00, 0x01, 0x02, 0x01, 0x00, 0x00, 0x00},
|
|
{0x00, 0x01, 0x02, 0x05, 0x02, 0x01, 0x00, 0x00},
|
|
{0x00, 0x02, 0x05, 0x0a, 0x05, 0x02, 0x00, 0x00}
|
|
|
|
};
|
|
|
|
// Animated FF
|
|
static char FF[8][8]=
|
|
{
|
|
{0x00, 0x14, 0x0a, 0x05, 0x0a, 0x14, 0x00, 0x00},
|
|
{0x00, 0x0a, 0x05, 0x02, 0x05, 0x0a, 0x00, 0x00},
|
|
{0x00, 0x05, 0x02, 0x01, 0x02, 0x05, 0x00, 0x00},
|
|
{0x00, 0x02, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00},
|
|
{0x00, 0x01, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00},
|
|
{0x00, 0x00, 0x10, 0x08, 0x10, 0x00, 0x00, 0x00},
|
|
{0x00, 0x10, 0x08, 0x14, 0x08, 0x10, 0x00, 0x00},
|
|
{0x00, 0x08, 0x14, 0x0a, 0x14, 0x08, 0x00, 0x00}
|
|
};
|
|
static char Play[] ={0x00, 0x04, 0x06, 0x07, 0x07, 0x06, 0x04, 0x00};
|
|
static char Stop[] ={0x00, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x00};
|
|
static char Pause[]={0x00, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00};
|
|
|
|
DisplayOut(DISP_CGRAM_SET, CMD);
|
|
|
|
// TODO: it's probably better to move the default charset in ILCD also:
|
|
// that will take out the screensaver mode check here and keeps everything central,
|
|
// but ILCD then has to deal with animation
|
|
if ( g_application.IsInScreenSaver() ) //IsInScreenSaver()
|
|
{
|
|
for(I=0;I<64;I++) DisplayOut( GetLCDCharsetCharacter( I ), DAT ); // all numberblocks chars
|
|
}
|
|
else
|
|
{
|
|
for(I=0;I<8;I++) DisplayOut(Bar0[I], DAT); // Bar0
|
|
for(I=0;I<8;I++) DisplayOut(Bar1[I], DAT); // Bar1
|
|
for(I=0;I<8;I++) DisplayOut(Bar2[I], DAT); // Bar2
|
|
for(I=0;I<8;I++) DisplayOut(REW[AnimIndex][I], DAT); // REW
|
|
for(I=0;I<8;I++) DisplayOut(FF[AnimIndex][I], DAT); // FF
|
|
for(I=0;I<8;I++) DisplayOut(Play[I], DAT); // Play
|
|
//for(I=0;I<8;I++) DisplayOut(Stop[I], DAT); // Stop - dont need as its a built in char
|
|
for(I=0;I<8;I++) DisplayOut(Bar3[I], DAT);
|
|
for(I=0;I<8;I++) DisplayOut(Pause[I], DAT); // Pause
|
|
}
|
|
DisplayOut(DISP_DDRAM_SET, CMD);
|
|
AnimIndex=(AnimIndex+1) & 0x7;
|
|
}
|
|
|
|
|
|
//************************************************************************************************************************
|
|
// DisplaySetPos: sets cursor position
|
|
// Input: (row position, line number from 0 to 3)
|
|
//************************************************************************************************************************
|
|
void CSmartXXLCD::DisplaySetPos(unsigned char pos, unsigned char line)
|
|
{
|
|
|
|
unsigned int cursorpointer;
|
|
|
|
cursorpointer = pos % m_iColumns;
|
|
|
|
if (line == 0) {
|
|
cursorpointer += m_iRow1adr;
|
|
}
|
|
if (line == 1) {
|
|
cursorpointer += m_iRow2adr;
|
|
}
|
|
if (line == 2) {
|
|
cursorpointer += m_iRow3adr;
|
|
}
|
|
if (line == 3) {
|
|
cursorpointer += m_iRow4adr;
|
|
}
|
|
DisplayOut(DISP_DDRAM_SET | cursorpointer, CMD);
|
|
m_iActualpos = cursorpointer;
|
|
}
|
|
|
|
//************************************************************************************************************************
|
|
// DisplayWriteFixText: write a fixed text to actual cursor position
|
|
// Input: ("fixed text like")
|
|
//************************************************************************************************************************
|
|
void CSmartXXLCD::DisplayWriteFixtext(const char *textstring)
|
|
{
|
|
unsigned char c;
|
|
while (c = *textstring++) {
|
|
DisplayOut(c,DAT);
|
|
}
|
|
}
|
|
|
|
|
|
//************************************************************************************************************************
|
|
// DisplayWriteString: write a string to acutal cursor position
|
|
// Input: (pointer to a 0x00 terminated string)
|
|
//************************************************************************************************************************
|
|
|
|
void CSmartXXLCD::DisplayWriteString(char *pointer)
|
|
{
|
|
/* display a normal 0x00 terminated string on the LCD display */
|
|
unsigned char c;
|
|
do {
|
|
c = *pointer;
|
|
if (c == 0x00)
|
|
break;
|
|
|
|
DisplayOut(c, DAT);
|
|
*pointer++;
|
|
} while(1);
|
|
|
|
}
|
|
|
|
|
|
//************************************************************************************************************************
|
|
// DisplayClearChars: clears a number of chars in a line and resets cursor position to it's startposition
|
|
// Input: (Startposition of clear in row, row number, number of chars to clear)
|
|
//************************************************************************************************************************
|
|
void CSmartXXLCD::DisplayClearChars(unsigned char startpos , unsigned char line, unsigned char lenght)
|
|
{
|
|
int i;
|
|
|
|
DisplaySetPos(startpos,line);
|
|
for (i=0;i<lenght; i++){
|
|
DisplayOut(0x20,DAT);
|
|
}
|
|
DisplaySetPos(startpos,line);
|
|
|
|
}
|
|
|
|
|
|
//************************************************************************************************************************
|
|
// DisplayProgressBar: shows a grafic bar staring at actual cursor position
|
|
// Input: (percent of bar to display, lenght of whole bar in chars when 100 %)
|
|
//************************************************************************************************************************
|
|
void CSmartXXLCD::DisplayProgressBar(unsigned char percent, unsigned char charcnt)
|
|
{
|
|
|
|
unsigned int barcnt100;
|
|
|
|
barcnt100 = charcnt * 5 * percent / 100;
|
|
|
|
int i;
|
|
for (i=1; i<=charcnt; i++) {
|
|
if (i<=(int)(barcnt100 / 5)){
|
|
DisplayOut(4,DAT);
|
|
}
|
|
else
|
|
{
|
|
if ( (i == (barcnt100 /5)+1) && (barcnt100 % 5 != 0) ){
|
|
DisplayOut((barcnt100 % 5)-1,DAT);
|
|
}
|
|
else{
|
|
DisplayOut(0x20,DAT);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//************************************************************************************************************************
|
|
//Set brightness level
|
|
//************************************************************************************************************************
|
|
void CSmartXXLCD::DisplaySetBacklight(unsigned char level)
|
|
{
|
|
if (g_guiSettings.GetInt("lcd.type")==LCD_TYPE_VFD)
|
|
{
|
|
//VFD:(value 0 to 3 = 100%, 75%, 50%, 25%)
|
|
if (level<0) level=0;
|
|
if (level>99) level=99;
|
|
level = (99-level);
|
|
level/=25;
|
|
DisplayOut(DISP_FUNCTION_SET | DISP_N_FLAG | level,CMD);
|
|
}
|
|
else //if (g_guiSettings.GetInt("lcd.type")==LCD_TYPE_LCD_HD44780)
|
|
{
|
|
if (g_sysinfo.SmartXXModCHIP().Equals("SmartXX V3"))
|
|
{
|
|
float fBackLight=((float)level)/100.0f;
|
|
fBackLight*=127.0f;
|
|
int iNewLevel=(int)fBackLight;
|
|
if (iNewLevel==63) iNewLevel=64;
|
|
_outp(DISP_O_LIGHT, iNewLevel&127);
|
|
}
|
|
else if (g_sysinfo.SmartXXModCHIP().Equals("SmartXX OPX"))
|
|
{
|
|
float fBackLight=((float)level)/100.0f;
|
|
fBackLight*=127.0f;
|
|
int iNewLevel=(int)fBackLight;
|
|
if (iNewLevel==63) iNewLevel=64;
|
|
|
|
// SmartXX OPX port for RGB-Red is the same port for display brightness control
|
|
// The brightness control has a higher priority, stopping possible running rgb controls
|
|
if ( g_iledSmartxxrgb.IsRunning() )
|
|
g_iledSmartxxrgb.Stop();
|
|
|
|
// Set new value
|
|
_outp(DISP_O_LIGHT, iNewLevel&127);
|
|
}
|
|
else
|
|
{
|
|
float fBackLight=((float)level)/100.0f;
|
|
fBackLight*=63.0f;
|
|
int iNewLevel=(int)fBackLight;
|
|
if (iNewLevel==31) iNewLevel=32;
|
|
_outp(DISP_O_LIGHT, iNewLevel&63);
|
|
}
|
|
}
|
|
}
|
|
//************************************************************************************************************************
|
|
//Set Contrast level
|
|
//************************************************************************************************************************
|
|
void CSmartXXLCD::DisplaySetContrast(unsigned char level)
|
|
{
|
|
// can't set contrast with a VFD
|
|
if (g_guiSettings.GetInt("lcd.type")==LCD_TYPE_VFD)
|
|
return;
|
|
|
|
if (g_sysinfo.SmartXXModCHIP().Equals("SmartXX V3"))
|
|
{
|
|
float fContrast=((float)level/100)*127.0f;
|
|
int iNewLevel=(int)fContrast;
|
|
if (iNewLevel==41) iNewLevel=42;
|
|
// 42 = x0101010 e.g half on
|
|
|
|
/*
|
|
7 Bit Pulse Wide Modulation (PWM) output controll register:
|
|
bit 7 not used
|
|
bit 6 - bit 0: Pulse Wide Modulation (PWM) Value
|
|
Value Range: 0 - 127
|
|
mask top bit (7)
|
|
*/
|
|
_outp(DISP_O_CONTRAST, iNewLevel&127|128);
|
|
}
|
|
else if ( g_sysinfo.SmartXXModCHIP().Equals("SmartXX OPX"))
|
|
{
|
|
|
|
// this is untested by me and has no defcets open for it.
|
|
// so i guess it working, but it looks wrong
|
|
// smartxx software docs suggest it should be as for V3
|
|
|
|
level = (99-level);
|
|
float fContrast=((float)level/100)*42.0f;
|
|
int iNewLevel=(int)fContrast;
|
|
if (iNewLevel>=41) iNewLevel=42;
|
|
_outp(DISP_O_CONTRAST, iNewLevel&127|128);
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
/*
|
|
Assumes its a SmartXX V2
|
|
bit 7 not used
|
|
bit 6: not used
|
|
bit 5 - bit 0: Pulse Wide Modulation (PWM) Value
|
|
Value Range: 0 - 63
|
|
where 0 means output is always 'high' (open collector)
|
|
and '63' means output is always 'low' (GND - full contrast)
|
|
Values in between '0' and '63' defines the ratio between 'low' to 'high' time (pulse width)
|
|
*/
|
|
float fContrast=(((float)level)/100.0f)*63.0f;
|
|
int iNewLevel=(int)fContrast;
|
|
if (iNewLevel>=31) iNewLevel=32;
|
|
_outp(DISP_O_CONTRAST, iNewLevel&63);
|
|
}
|
|
}
|
|
|
|
//************************************************************************************************************************
|
|
void CSmartXXLCD::DisplayInit()
|
|
{
|
|
_outp(DISP_O,0);
|
|
DisplayOut(DISP_FUNCTION_SET | DISP_DL_FLAG, INI); // 8-Bit Datalenght if display is already initialized to 4 bit
|
|
Sleep(5);
|
|
DisplayOut(DISP_FUNCTION_SET | DISP_DL_FLAG, INI); // 8-Bit Datalenght if display is already initialized to 4 bit
|
|
Sleep(5);
|
|
DisplayOut(DISP_FUNCTION_SET | DISP_DL_FLAG, INI); // 8-Bit Datalenght if display is already initialized to 4 bit
|
|
Sleep(5);
|
|
DisplayOut(DISP_FUNCTION_SET,INI); // 4-Bit Datalenght
|
|
Sleep(5);
|
|
DisplayOut(DISP_FUNCTION_SET | DISP_N_FLAG | DISP_RE_FLAG ,CMD); // 4-Bit Datalenght, 2 Lines, Font 5x7, and set RE Flag
|
|
Sleep(5);
|
|
DisplayOut(DISP_SEGRAM_SET, CMD); // set SEGRAM to 0x00 (RE = 1)
|
|
Sleep(5);
|
|
DisplayOut(DISP_EXT_CONTROL | DISP_NW_FLAG ,CMD); // set Display to 2 lines (RE = 1)
|
|
Sleep(5);
|
|
DisplayOut(DISP_FUNCTION_SET | DISP_N_FLAG ,CMD); // 4-Bit Datalenght, 2 Lines, Font 5x7, clear RE Flag
|
|
Sleep(5);
|
|
DisplayOut(DISP_CONTROL | DISP_D_FLAG ,CMD); // Display on
|
|
Sleep(5);
|
|
DisplayOut(DISP_CLEAR,CMD); // Display clear
|
|
Sleep(5);
|
|
DisplayOut(DISP_ENTRY_MODE_SET | DISP_ID_FLAG,CMD); // Cursor autoincrement
|
|
Sleep(5);
|
|
|
|
DisplayBuildCustomChars();
|
|
DisplaySetPos(0,0);
|
|
}
|
|
|
|
//************************************************************************************************************************
|
|
void CSmartXXLCD::Process()
|
|
{
|
|
int iOldLight=-1;
|
|
int iOldContrast=-1;
|
|
|
|
|
|
m_iColumns = g_advancedSettings.m_lcdColumns;
|
|
m_iRows = g_advancedSettings.m_lcdRows;
|
|
m_iRow1adr = g_advancedSettings.m_lcdAddress1;
|
|
m_iRow2adr = g_advancedSettings.m_lcdAddress2;
|
|
m_iRow3adr = g_advancedSettings.m_lcdAddress3;
|
|
m_iRow4adr = g_advancedSettings.m_lcdAddress4;
|
|
m_iBackLight= g_guiSettings.GetInt("lcd.backlight");
|
|
m_iContrast = g_guiSettings.GetInt("lcd.contrast");
|
|
if (m_iRows >= MAX_ROWS) m_iRows=MAX_ROWS-1;
|
|
|
|
DisplayInit();
|
|
while (!m_bStop)
|
|
{
|
|
Sleep(SCROLL_SPEED_IN_MSEC);
|
|
if (m_iBackLight != iOldLight)
|
|
{
|
|
// backlight setting changed
|
|
iOldLight=m_iBackLight;
|
|
DisplaySetBacklight(m_iBackLight);
|
|
}
|
|
if (m_iContrast != iOldContrast)
|
|
{
|
|
// contrast setting changed
|
|
iOldContrast=m_iContrast;
|
|
DisplaySetContrast(m_iContrast);
|
|
}
|
|
DisplayBuildCustomChars();
|
|
for (int iLine=0; iLine < (int)m_iRows; ++iLine)
|
|
{
|
|
if (m_bUpdate[iLine])
|
|
{
|
|
CStdString strTmp=m_strLine[iLine];
|
|
if (strTmp.size() > m_iColumns)
|
|
{
|
|
strTmp=m_strLine[iLine].Left(m_iColumns);
|
|
}
|
|
m_iPos[iLine]=0;
|
|
DisplaySetPos(0,iLine);
|
|
DisplayWriteFixtext(strTmp.c_str());
|
|
m_bUpdate[iLine]=false;
|
|
m_dwSleep[iLine]=GetTickCount();
|
|
}
|
|
else if ( (GetTickCount()-m_dwSleep[iLine]) > 1000)
|
|
{
|
|
int iSize=m_strLine[iLine].size();
|
|
if (iSize > (int)m_iColumns)
|
|
{
|
|
//scroll line
|
|
CStdString strRow=m_strLine[iLine]+" - ";
|
|
int iSize=strRow.size();
|
|
m_iPos[iLine]++;
|
|
if (m_iPos[iLine]>=iSize) m_iPos[iLine]=0;
|
|
int iPos=m_iPos[iLine];
|
|
CStdString strLine="";
|
|
for (int iCol=0; iCol < (int)m_iColumns;++iCol)
|
|
{
|
|
strLine +=strRow.GetAt(iPos);
|
|
iPos++;
|
|
if (iPos >= iSize) iPos=0;
|
|
}
|
|
DisplaySetPos(0,iLine);
|
|
DisplayWriteFixtext(strLine.c_str());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
for (int i=0; i < (int)m_iRows; i++)
|
|
{
|
|
DisplayClearChars(0,i,m_iColumns);
|
|
}
|
|
DisplayOut(DISP_CONTROL ,CMD); // Display off
|
|
}
|