mirror of
https://github.com/netfun2000/lcd4linux.git
synced 2026-02-27 09:44:34 +08:00
drv_HD44780: add 8bit i2c mode for HD44780 by Michael Grzeschik <m.grzeschik@pengutronix.de>
git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@1202 3ae390bd-cb1e-0410-b409-cd5a39f66f1f
This commit is contained in:
+57
-25
@@ -706,10 +706,10 @@ static void drv_HD_PP_stop(void)
|
||||
|
||||
*/
|
||||
|
||||
static void drv_HD_I2C_nibble(unsigned char controller, unsigned char nibble)
|
||||
static void drv_HD_I2C(unsigned char controller, unsigned char byte, int rs, int rw)
|
||||
{
|
||||
unsigned char enable;
|
||||
unsigned char command; /* this is actually the first data byte on the PCF8574 */
|
||||
unsigned char command = 0; /* this is actually the first data byte on the PCF8574 */
|
||||
unsigned char data_block[2];
|
||||
/* enable signal: 'controller' is a bitmask */
|
||||
/* bit n .. send to controller #n */
|
||||
@@ -738,28 +738,51 @@ static void drv_HD_I2C_nibble(unsigned char controller, unsigned char nibble)
|
||||
The main advantage we see is that we do 2 less IOCTL's from our driver.
|
||||
*/
|
||||
|
||||
command = nibble;
|
||||
data_block[0] = nibble | enable;
|
||||
data_block[1] = nibble;
|
||||
if (Bits == 4) {
|
||||
if (rw)
|
||||
byte |= SIGNAL_RW;
|
||||
if (rs)
|
||||
byte |= SIGNAL_RS;
|
||||
command = byte;
|
||||
data_block[0] = byte | enable;
|
||||
data_block[1] = byte;
|
||||
|
||||
drv_generic_i2c_command(command, data_block, 2);
|
||||
} else if (Bits == 8) {
|
||||
if (rw)
|
||||
command |= SIGNAL_RW;
|
||||
if (rs)
|
||||
command |= SIGNAL_RS;
|
||||
|
||||
data_block[0] = byte;
|
||||
data_block[1] = enable;
|
||||
}
|
||||
|
||||
drv_generic_i2c_command(command, data_block, 2, Bits);
|
||||
}
|
||||
|
||||
|
||||
static void drv_HD_I2C_byte(const unsigned char controller, const unsigned char data)
|
||||
{
|
||||
/* send data with RS enabled */
|
||||
drv_HD_I2C_nibble(controller, ((data >> 4) & 0x0f) | SIGNAL_RS);
|
||||
drv_HD_I2C_nibble(controller, (data & 0x0f) | SIGNAL_RS);
|
||||
if (Bits == 4) {
|
||||
drv_HD_I2C(controller, ((data >> 4) & 0x0f), 1, 0);
|
||||
drv_HD_I2C(controller, (data & 0x0f), 1, 0);
|
||||
} else if (Bits == 8) {
|
||||
drv_HD_I2C(controller, data, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void drv_HD_I2C_command(const unsigned char controller, const unsigned char cmd, __attribute__ ((unused))
|
||||
const unsigned long delay)
|
||||
{
|
||||
/* send data with RS disabled */
|
||||
drv_HD_I2C_nibble(controller, ((cmd >> 4) & 0x0f));
|
||||
drv_HD_I2C_nibble(controller, ((cmd) & 0x0f));
|
||||
/* send command data with RS disabled */
|
||||
if (Bits == 4) {
|
||||
drv_HD_I2C(controller, ((cmd >> 4) & 0x0f), 0, 0);
|
||||
drv_HD_I2C(controller, ((cmd) & 0x0f), 0, 0);
|
||||
} else if (Bits == 8) {
|
||||
drv_HD_I2C(controller, cmd, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void drv_HD_I2C_data(const unsigned char controller, const char *string, const int len, __attribute__ ((unused))
|
||||
@@ -781,13 +804,14 @@ static int drv_HD_I2C_load(const char *section)
|
||||
{
|
||||
if (cfg_number(section, "Bits", 8, 4, 8, &Bits) < 0)
|
||||
return -1;
|
||||
if (Bits != 4) {
|
||||
error("%s: bad %s.Bits '%d' from %s, should be '4'", Name, section, Bits, cfg_source());
|
||||
return -1;
|
||||
}
|
||||
|
||||
info("%s: using %d bit mode", Name, Bits);
|
||||
|
||||
if (Bits != 4 && Bits != 8) {
|
||||
error("%s: bad %s.Bits '%d' from %s, should be '4' or '8'", Name, section, Bits, cfg_source());
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (drv_generic_i2c_open(section, Name) != 0) {
|
||||
error("%s: could not initialize i2c attached device!", Name);
|
||||
return -1;
|
||||
@@ -804,16 +828,24 @@ static int drv_HD_I2C_load(const char *section)
|
||||
if ((SIGNAL_GPO = drv_generic_i2c_wire("GPO", "GND")) == 0xff)
|
||||
return -1;
|
||||
|
||||
/* initialize display */
|
||||
drv_HD_I2C_nibble(allControllers, 0x03);
|
||||
udelay(T_INIT1); /* 4 Bit mode, wait 4.1 ms */
|
||||
drv_HD_I2C_nibble(allControllers, 0x03);
|
||||
udelay(T_INIT2); /* 4 Bit mode, wait 100 us */
|
||||
drv_HD_I2C_nibble(allControllers, 0x03);
|
||||
udelay(T_INIT1); /* 4 Bit mode, wait 4.1 ms */
|
||||
drv_HD_I2C_nibble(allControllers, 0x02);
|
||||
udelay(T_INIT2); /* 4 Bit mode, wait 100 us */
|
||||
drv_HD_I2C_command(allControllers, 0x28, T_EXEC); /* 4 Bit mode, 1/16 duty cycle, 5x8 font */
|
||||
if (Bits == 4) {
|
||||
/* initialize display */
|
||||
drv_HD_I2C(allControllers, 0x02, 0, 0);
|
||||
udelay(T_INIT1); /* 4 Bit mode, wait 4.1 ms */
|
||||
drv_HD_I2C(allControllers, 0x03, 0, 0);
|
||||
udelay(T_INIT2); /* 4 Bit mode, wait 100 us */
|
||||
drv_HD_I2C(allControllers, 0x03, 0, 0);
|
||||
udelay(T_INIT1); /* 4 Bit mode, wait 4.1 ms */
|
||||
drv_HD_I2C(allControllers, 0x02, 0, 0);
|
||||
udelay(T_INIT2); /* 4 Bit mode, wait 100 us */
|
||||
drv_HD_I2C_command(allControllers, 0x28, T_EXEC); /* 4 Bit mode, 1/16 duty cycle, 5x8 font */
|
||||
} else if (Bits == 8) {
|
||||
drv_HD_I2C(allControllers, 0x30, 0, 0); /* 8 Bit mode, wait 4.1 ms */
|
||||
udelay(T_INIT1); /* 8 Bit mode, wait 4.1 ms */
|
||||
drv_HD_I2C(allControllers, 0x30, 0, 0); /* 8 Bit mode, wait 100 us */
|
||||
udelay(T_INIT2); /* 8 Bit mode, wait 4.1 ms */
|
||||
drv_HD_I2C_command(allControllers, 0x38, T_EXEC); /* 8 Bit mode, 1/16 duty cycle, 5x8 font */
|
||||
}
|
||||
|
||||
info("%s: I2C initialization done", Name);
|
||||
|
||||
|
||||
+54
-15
@@ -62,7 +62,8 @@
|
||||
static char *Driver = "";
|
||||
static char *Section = "";
|
||||
static int i2c_device;
|
||||
|
||||
static int ctrldev;
|
||||
static int datadev;
|
||||
|
||||
static void my_i2c_smbus_write_byte_data(const int device, const unsigned char val)
|
||||
{
|
||||
@@ -91,33 +92,49 @@ static void my_i2c_smbus_read_byte_data(const int device, const unsigned char da
|
||||
}
|
||||
#endif
|
||||
|
||||
int drv_generic_i2c_pre_write(int dev)
|
||||
{
|
||||
|
||||
info("%s: selecting slave device 0x%x", Driver, dev);
|
||||
if (ioctl(i2c_device, I2C_SLAVE, dev) < 0) {
|
||||
error("%s: error selecting slave device 0x%x\n", Driver, dev);
|
||||
return -EPIPE;
|
||||
}
|
||||
|
||||
info("%s: initializing I2C slave device 0x%x for output", Driver, dev);
|
||||
if (i2c_smbus_write_byte_data(i2c_device, 3, 0) < 0) {
|
||||
error("%s: error initializing device 0x%x\n", Driver, dev);
|
||||
close(i2c_device);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int drv_generic_i2c_open(const char *section, const char *driver)
|
||||
{
|
||||
int dev;
|
||||
char *bus, *device;
|
||||
udelay_init();
|
||||
Section = (char *) section;
|
||||
Driver = (char *) driver;
|
||||
bus = cfg_get(Section, "Port", NULL);
|
||||
device = cfg_get(Section, "Device", NULL);
|
||||
dev = atoi(device);
|
||||
ctrldev = atoi(device);
|
||||
device = cfg_get(Section, "DDevice", NULL);
|
||||
datadev = atoi(device);
|
||||
|
||||
info("%s: initializing I2C bus %s", Driver, bus);
|
||||
if ((i2c_device = open(bus, O_WRONLY)) < 0) {
|
||||
error("%s: I2C bus %s open failed !\n", Driver, bus);
|
||||
goto exit_error;
|
||||
}
|
||||
info("%s: selecting slave device 0x%x", Driver, dev);
|
||||
if (ioctl(i2c_device, I2C_SLAVE, dev) < 0) {
|
||||
error("%s: error selecting slave device 0x%x\n", Driver, dev);
|
||||
goto exit_error;
|
||||
|
||||
if (datadev) {
|
||||
if (drv_generic_i2c_pre_write(datadev) < 0)
|
||||
goto exit_error;
|
||||
}
|
||||
|
||||
info("%s: initializing I2C slave device 0x%x", Driver, dev);
|
||||
if (i2c_smbus_write_quick(i2c_device, I2C_SMBUS_WRITE) < 0) {
|
||||
error("%s: error initializing device 0x%x\n", Driver, dev);
|
||||
close(i2c_device);
|
||||
}
|
||||
if (drv_generic_i2c_pre_write(ctrldev) < 0)
|
||||
goto exit_error;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -172,8 +189,30 @@ void drv_generic_i2c_data(const unsigned char data)
|
||||
my_i2c_smbus_write_byte_data(i2c_device, data);
|
||||
}
|
||||
|
||||
|
||||
void drv_generic_i2c_command(const unsigned char command, /*const */ unsigned char *data, const unsigned char length)
|
||||
static void i2c_out(int dev, unsigned char val)
|
||||
{
|
||||
i2c_smbus_write_block_data(i2c_device, command, length, data);
|
||||
info("%s: initializing I2C slave device 0x%x", Driver, dev);
|
||||
if (ioctl(i2c_device, I2C_SLAVE, dev) < 0) {
|
||||
error("%s: error selecting slave device 0x%x\n", Driver, dev);
|
||||
return;
|
||||
}
|
||||
|
||||
i2c_smbus_write_byte_data(i2c_device, 1, val);
|
||||
}
|
||||
|
||||
void drv_generic_i2c_command(const unsigned char command, /*const */ unsigned char *data, const unsigned char length,
|
||||
int bits)
|
||||
{
|
||||
if (bits == 4) {
|
||||
i2c_smbus_write_block_data(i2c_device, command, length, data);
|
||||
} else if (bits == 8 && datadev) {
|
||||
/* set data on pins */
|
||||
info("cmd: %08x, data0: %08x, data1: %08x\n", command, data[0], data[1]);
|
||||
i2c_out(datadev, data[0]);
|
||||
/* set enable pin including optional rs and rw */
|
||||
i2c_out(ctrldev, command | data[1]);
|
||||
/* unset enable pin including optional rs and rw */
|
||||
i2c_out(ctrldev, command);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-1
@@ -57,6 +57,7 @@ int drv_generic_i2c_close(void);
|
||||
unsigned char drv_generic_i2c_wire(const char *name, const char *deflt);
|
||||
void drv_generic_i2c_byte(const unsigned char data);
|
||||
void drv_generic_i2c_data(const unsigned char data);
|
||||
void drv_generic_i2c_command(const unsigned char command, /*const */ unsigned char *data, const unsigned char length);
|
||||
void drv_generic_i2c_command(const unsigned char command, /*const */ unsigned char *data, const unsigned char length,
|
||||
int bits);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user