5
« on: July 31, 2015, 10:13:55 AM »
/* LCD commands */
#define CHARLCD_CMD_CLEAR 0x01
#define CHARLCD_CMD_HOME 0x02
#define CHARLCD_CMD_ENTRY 0x04
#define CHARLCD_CMD_DISPLAY 0x08
#define CHARLCD_CMD_FS 0x20 /* function set */
#define CHARLCD_CMD_ADDR_DD 0x80
#define CHARLCD_CMD_ADDR_CG 0x40
/* Bit fields */
#define CHARLCD_CMD_FS_D8 (1<<4) /* 8bit display */
#define CHARLCD_CMD_FS_2L (1<<3) /* two lines */
#define CHARLCD_CMD_FS_5x8 (0<<2) /* 5x8 font */
#define LCD_DISPLAY_ON (1<<2)
#define LCD_DISPLAY_OFF (0<<2)
#define LCD_CURSOR_ON (1<<1)
#define LCD_CURSOR_OFF (0<<1)
#define LCD_FONT_ENG_JAP (0x00)
#define LCD_FONT_WEST_EUROPE1 (0x01)
#define LCD_FONT_ENG_RUSSIAN (0x02)
#define LCD_FONT_WEST_EUROPE2 (0x03)
#define CHARLCD_STAT_BUSY 0x80
/* Maximum execution time is for the CLEAR DISPLAY command. */
#define MAX_EXECUTION_TIME_MS 2
void WriteLCD(qint8 controls, qint8 data)
{
LCD_device_->WriteI2Cint((quint16)(data * 256 + controls));
/*
* No need to introduce delay here: the maximum setup time between
* any commands is 250nS, and the previous command takes around 300uS
* to execute.
*/
}
void WriteCommand(qint8 command)
{
WaitReady();
WriteLCD(0x00, command); /* RS=0, R/W=0, E=0 */
WriteLCD(ENABLE_LCD, command); /* E=1 */
WriteLCD(0x00, command); /* E=0 */
}
void WriteData(qint8 data)
{
WaitReady();
WriteLCD(DATA_SELECT, data); /* RS=1, R/W=0 */
WriteLCD(DATA_SELECT | ENABLE_LCD, data); /* RS=1, R/W=0, E=1 */
WriteLCD(DATA_SELECT, data); /* E=0 */
}
qint8 ReadLCDStatus()
{
uint8_t returned_value[2];
returned_value[0] = 0;
returned_value[1] = 0;
WriteLCD(READ_nWRITE, LCD_DATA_BUS_INPUT); /* RS=0, R/W=1, E=0 */
WriteLCD(ENABLE_LCD | READ_nWRITE, LCD_DATA_BUS_INPUT);
LCD_device_->ReadI2C(returned_value, sizeof(returned_value));
WriteLCD(READ_nWRITE, LCD_DATA_BUS_INPUT); /* RS=0, R/W=1, E=0 */
return returned_value[1];
}
void lcd_init(void)
{
uint8_t v;
/* Initial state: RS=0, R/W=0, E=0, data bus is input */
WriteLCD(0x00, LCD_DATA_BUS_INPUT);
/*
* Make sure to configure 8-bit interface first.
* Send the command 3 times, to take into account the fact that the LCD
* could be in 4 bit mode, and not in sync.
*/
v = CHARLCD_CMD_FS | /* Function set */
CHARLCD_CMD_FS_D8; /* 8-bit interface */
WriteCommand(v);
WriteCommand(v);
WriteCommand(v);
v = CHARLCD_CMD_FS | /* Function set */
CHARLCD_CMD_FS_D8 | /* 8-bit interface */
CHARLCD_CMD_FS_2L | /* 2 lines mode */
CHARLCD_CMD_FS_5x8 | /* 5x8 font */
LCD_FONT_WEST_EUROPE1;
WriteCommand(v);
/* From this point on, the BUSY flag and address counters can be read. */
busy_flag_valid = true;
/* Turn display OFF. */
WriteCommand(CHARLCD_CMD_DISPLAY | LCD_DISPLAY_OFF);
/* Clear display */
WriteCommand(CHARLCD_CMD_CLEAR);
/* Entry mode set */
WriteCommand(CHARLCD_CMD_ENTRY | LCD_MODE_INCREMENT);
/* Return home. */
WriteCommand(CHARLCD_CMD_HOME);
/* Turn display ON. */
WriteCommand(CHARLCD_CMD_DISPLAY | LCD_DISPLAY_ON);
}