#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/i2c-dev.h>
#define PULSE_PERIOD 500
#define CMD_PERIOD 4100
#define BACKLIGHT 8
#define DATA 1
static int iBackLight = BACKLIGHT;
static int file_i2c = -1;
static void WriteCommand(unsigned char ucCMD)
{
unsigned char uc;
uc = (ucCMD & 0xf0) | iBackLight; write(file_i2c, &uc, 1);
usleep(PULSE_PERIOD); uc |= 4; write(file_i2c, &uc, 1);
usleep(PULSE_PERIOD);
uc &= ~4; write(file_i2c, &uc, 1);
usleep(CMD_PERIOD);
uc = iBackLight | (ucCMD << 4); write(file_i2c, &uc, 1);
usleep(PULSE_PERIOD);
uc |= 4; write(file_i2c, &uc, 1);
usleep(PULSE_PERIOD);
uc &= ~4; write(file_i2c, &uc, 1);
usleep(CMD_PERIOD);
}
int lcd1602Control(int bBacklight, int bCursor, int bBlink)
{
unsigned char ucCMD = 0xc;
if (file_i2c < 0)
return 1;
iBackLight = (bBacklight) ? BACKLIGHT : 0;
if (bCursor)
ucCMD |= 2;
if (bBlink)
ucCMD |= 1;
WriteCommand(ucCMD);
return 0;
}
int lcd1602WriteString(char *text)
{
unsigned char ucTemp[2];
int i = 0;
if (file_i2c < 0 || text == NULL)
return 1;
while (i<16 && *text)
{
ucTemp[0] = iBackLight | DATA | (*text & 0xf0);
write(file_i2c, ucTemp, 1);
usleep(PULSE_PERIOD);
ucTemp[0] |= 4; write(file_i2c, ucTemp, 1);
usleep(PULSE_PERIOD);
ucTemp[0] &= ~4;
write(file_i2c, ucTemp, 1);
usleep(PULSE_PERIOD);
ucTemp[0] = iBackLight | DATA | (*text << 4);
write(file_i2c, ucTemp, 1);
ucTemp[0] |= 4; write(file_i2c, ucTemp, 1);
usleep(PULSE_PERIOD);
ucTemp[0] &= ~4;
write(file_i2c, ucTemp, 1);
usleep(CMD_PERIOD);
text++;
i++;
}
return 0;
}
int lcd1602Clear(void)
{
if (file_i2c < 0)
return 1;
WriteCommand(0x01); return 0;
}
int lcd1602Init(int iChannel, int iAddr)
{
char szFile[32];
int rc;
sprintf(szFile, "/dev/i2c-%d", iChannel);
file_i2c = open(szFile, O_RDWR);
if (file_i2c < 0)
{
fprintf(stderr, "Error opening i2c device; not running as sudo?\n");
return 1;
}
rc = ioctl(file_i2c, I2C_SLAVE, iAddr);
if (rc < 0)
{
close(file_i2c);
fprintf(stderr, "Error setting I2C device address\n");
return 1;
}
iBackLight = BACKLIGHT; WriteCommand(0x02); WriteCommand(0x28); WriteCommand(0x0c); WriteCommand(0x06); WriteCommand(0x80); lcd1602Clear();
return 0;
}
int lcd1602SetCursor(int x, int y)
{
unsigned char cCmd;
if (file_i2c < 0 || x < 0 || x > 15 || y < 0 || y > 1)
return 1;
cCmd = (y==0) ? 0x80 : 0xc0;
cCmd |= x;
WriteCommand(cCmd);
return 0;
}
void lcd1602Shutdown(void)
{
iBackLight = 0; WriteCommand(0x08); close(file_i2c);
file_i2c = -1;
}