Skip to content

Commit d38b3dc

Browse files
author
michael
committed
drv_HD44780: add 8bit i2c mode for HD44780 by Michael Grzeschik <[email protected]>
git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@1202 3ae390bd-cb1e-0410-b409-cd5a39f66f1f
1 parent 00c0fae commit d38b3dc

File tree

3 files changed

+112
-40
lines changed

3 files changed

+112
-40
lines changed

Diff for: drv_HD44780.c

+57-25
Original file line numberDiff line numberDiff line change
@@ -706,10 +706,10 @@ static void drv_HD_PP_stop(void)
706706
707707
*/
708708

709-
static void drv_HD_I2C_nibble(unsigned char controller, unsigned char nibble)
709+
static void drv_HD_I2C(unsigned char controller, unsigned char byte, int rs, int rw)
710710
{
711711
unsigned char enable;
712-
unsigned char command; /* this is actually the first data byte on the PCF8574 */
712+
unsigned char command = 0; /* this is actually the first data byte on the PCF8574 */
713713
unsigned char data_block[2];
714714
/* enable signal: 'controller' is a bitmask */
715715
/* bit n .. send to controller #n */
@@ -738,28 +738,51 @@ static void drv_HD_I2C_nibble(unsigned char controller, unsigned char nibble)
738738
The main advantage we see is that we do 2 less IOCTL's from our driver.
739739
*/
740740

741-
command = nibble;
742-
data_block[0] = nibble | enable;
743-
data_block[1] = nibble;
741+
if (Bits == 4) {
742+
if (rw)
743+
byte |= SIGNAL_RW;
744+
if (rs)
745+
byte |= SIGNAL_RS;
746+
command = byte;
747+
data_block[0] = byte | enable;
748+
data_block[1] = byte;
749+
750+
} else if (Bits == 8) {
751+
if (rw)
752+
command |= SIGNAL_RW;
753+
if (rs)
754+
command |= SIGNAL_RS;
755+
756+
data_block[0] = byte;
757+
data_block[1] = enable;
758+
}
744759

745-
drv_generic_i2c_command(command, data_block, 2);
760+
drv_generic_i2c_command(command, data_block, 2, Bits);
746761
}
747762

748763

749764
static void drv_HD_I2C_byte(const unsigned char controller, const unsigned char data)
750765
{
751766
/* send data with RS enabled */
752-
drv_HD_I2C_nibble(controller, ((data >> 4) & 0x0f) | SIGNAL_RS);
753-
drv_HD_I2C_nibble(controller, (data & 0x0f) | SIGNAL_RS);
767+
if (Bits == 4) {
768+
drv_HD_I2C(controller, ((data >> 4) & 0x0f), 1, 0);
769+
drv_HD_I2C(controller, (data & 0x0f), 1, 0);
770+
} else if (Bits == 8) {
771+
drv_HD_I2C(controller, data, 1, 0);
772+
}
754773
}
755774

756775

757776
static void drv_HD_I2C_command(const unsigned char controller, const unsigned char cmd, __attribute__ ((unused))
758777
const unsigned long delay)
759778
{
760-
/* send data with RS disabled */
761-
drv_HD_I2C_nibble(controller, ((cmd >> 4) & 0x0f));
762-
drv_HD_I2C_nibble(controller, ((cmd) & 0x0f));
779+
/* send command data with RS disabled */
780+
if (Bits == 4) {
781+
drv_HD_I2C(controller, ((cmd >> 4) & 0x0f), 0, 0);
782+
drv_HD_I2C(controller, ((cmd) & 0x0f), 0, 0);
783+
} else if (Bits == 8) {
784+
drv_HD_I2C(controller, cmd, 0, 0);
785+
}
763786
}
764787

765788
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)
781804
{
782805
if (cfg_number(section, "Bits", 8, 4, 8, &Bits) < 0)
783806
return -1;
784-
if (Bits != 4) {
785-
error("%s: bad %s.Bits '%d' from %s, should be '4'", Name, section, Bits, cfg_source());
786-
return -1;
787-
}
788807

789808
info("%s: using %d bit mode", Name, Bits);
790809

810+
if (Bits != 4 && Bits != 8) {
811+
error("%s: bad %s.Bits '%d' from %s, should be '4' or '8'", Name, section, Bits, cfg_source());
812+
return -1;
813+
}
814+
791815
if (drv_generic_i2c_open(section, Name) != 0) {
792816
error("%s: could not initialize i2c attached device!", Name);
793817
return -1;
@@ -804,16 +828,24 @@ static int drv_HD_I2C_load(const char *section)
804828
if ((SIGNAL_GPO = drv_generic_i2c_wire("GPO", "GND")) == 0xff)
805829
return -1;
806830

807-
/* initialize display */
808-
drv_HD_I2C_nibble(allControllers, 0x03);
809-
udelay(T_INIT1); /* 4 Bit mode, wait 4.1 ms */
810-
drv_HD_I2C_nibble(allControllers, 0x03);
811-
udelay(T_INIT2); /* 4 Bit mode, wait 100 us */
812-
drv_HD_I2C_nibble(allControllers, 0x03);
813-
udelay(T_INIT1); /* 4 Bit mode, wait 4.1 ms */
814-
drv_HD_I2C_nibble(allControllers, 0x02);
815-
udelay(T_INIT2); /* 4 Bit mode, wait 100 us */
816-
drv_HD_I2C_command(allControllers, 0x28, T_EXEC); /* 4 Bit mode, 1/16 duty cycle, 5x8 font */
831+
if (Bits == 4) {
832+
/* initialize display */
833+
drv_HD_I2C(allControllers, 0x02, 0, 0);
834+
udelay(T_INIT1); /* 4 Bit mode, wait 4.1 ms */
835+
drv_HD_I2C(allControllers, 0x03, 0, 0);
836+
udelay(T_INIT2); /* 4 Bit mode, wait 100 us */
837+
drv_HD_I2C(allControllers, 0x03, 0, 0);
838+
udelay(T_INIT1); /* 4 Bit mode, wait 4.1 ms */
839+
drv_HD_I2C(allControllers, 0x02, 0, 0);
840+
udelay(T_INIT2); /* 4 Bit mode, wait 100 us */
841+
drv_HD_I2C_command(allControllers, 0x28, T_EXEC); /* 4 Bit mode, 1/16 duty cycle, 5x8 font */
842+
} else if (Bits == 8) {
843+
drv_HD_I2C(allControllers, 0x30, 0, 0); /* 8 Bit mode, wait 4.1 ms */
844+
udelay(T_INIT1); /* 8 Bit mode, wait 4.1 ms */
845+
drv_HD_I2C(allControllers, 0x30, 0, 0); /* 8 Bit mode, wait 100 us */
846+
udelay(T_INIT2); /* 8 Bit mode, wait 4.1 ms */
847+
drv_HD_I2C_command(allControllers, 0x38, T_EXEC); /* 8 Bit mode, 1/16 duty cycle, 5x8 font */
848+
}
817849

818850
info("%s: I2C initialization done", Name);
819851

Diff for: drv_generic_i2c.c

+53-14
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@
6262
static char *Driver = "";
6363
static char *Section = "";
6464
static int i2c_device;
65-
65+
static int ctrldev;
66+
static int datadev;
6667

6768
static void my_i2c_smbus_write_byte_data(const int device, const unsigned char val)
6869
{
@@ -91,34 +92,50 @@ static void my_i2c_smbus_read_byte_data(const int device, const unsigned char da
9192
}
9293
#endif
9394

95+
int drv_generic_i2c_pre_write(int dev)
96+
{
97+
98+
info("%s: selecting slave device 0x%x", Driver, dev);
99+
if (ioctl(i2c_device, I2C_SLAVE, dev) < 0) {
100+
error("%s: error selecting slave device 0x%x\n", Driver, dev);
101+
return -EPIPE;
102+
}
103+
104+
info("%s: initializing I2C slave device 0x%x for output", Driver, dev);
105+
if (i2c_smbus_write_byte_data(i2c_device, 3, 0) < 0) {
106+
error("%s: error initializing device 0x%x\n", Driver, dev);
107+
close(i2c_device);
108+
}
109+
110+
return 0;
111+
}
94112

95113
int drv_generic_i2c_open(const char *section, const char *driver)
96114
{
97-
int dev;
98115
char *bus, *device;
99116
udelay_init();
100117
Section = (char *) section;
101118
Driver = (char *) driver;
102119
bus = cfg_get(Section, "Port", NULL);
103120
device = cfg_get(Section, "Device", NULL);
104-
dev = atoi(device);
121+
ctrldev = atoi(device);
122+
device = cfg_get(Section, "DDevice", NULL);
123+
datadev = atoi(device);
124+
105125
info("%s: initializing I2C bus %s", Driver, bus);
106126
if ((i2c_device = open(bus, O_WRONLY)) < 0) {
107127
error("%s: I2C bus %s open failed !\n", Driver, bus);
108128
goto exit_error;
109129
}
110-
info("%s: selecting slave device 0x%x", Driver, dev);
111-
if (ioctl(i2c_device, I2C_SLAVE, dev) < 0) {
112-
error("%s: error selecting slave device 0x%x\n", Driver, dev);
113-
goto exit_error;
114-
}
115130

116-
info("%s: initializing I2C slave device 0x%x", Driver, dev);
117-
if (i2c_smbus_write_quick(i2c_device, I2C_SMBUS_WRITE) < 0) {
118-
error("%s: error initializing device 0x%x\n", Driver, dev);
119-
close(i2c_device);
131+
if (datadev) {
132+
if (drv_generic_i2c_pre_write(datadev) < 0)
133+
goto exit_error;
120134
}
121135

136+
if (drv_generic_i2c_pre_write(ctrldev) < 0)
137+
goto exit_error;
138+
122139
return 0;
123140

124141
exit_error:
@@ -172,8 +189,30 @@ void drv_generic_i2c_data(const unsigned char data)
172189
my_i2c_smbus_write_byte_data(i2c_device, data);
173190
}
174191

192+
static void i2c_out(int dev, unsigned char val)
193+
{
194+
info("%s: initializing I2C slave device 0x%x", Driver, dev);
195+
if (ioctl(i2c_device, I2C_SLAVE, dev) < 0) {
196+
error("%s: error selecting slave device 0x%x\n", Driver, dev);
197+
return;
198+
}
175199

176-
void drv_generic_i2c_command(const unsigned char command, /*const */ unsigned char *data, const unsigned char length)
200+
i2c_smbus_write_byte_data(i2c_device, 1, val);
201+
}
202+
203+
void drv_generic_i2c_command(const unsigned char command, /*const */ unsigned char *data, const unsigned char length,
204+
int bits)
177205
{
178-
i2c_smbus_write_block_data(i2c_device, command, length, data);
206+
if (bits == 4) {
207+
i2c_smbus_write_block_data(i2c_device, command, length, data);
208+
} else if (bits == 8 && datadev) {
209+
/* set data on pins */
210+
info("cmd: %08x, data0: %08x, data1: %08x\n", command, data[0], data[1]);
211+
i2c_out(datadev, data[0]);
212+
/* set enable pin including optional rs and rw */
213+
i2c_out(ctrldev, command | data[1]);
214+
/* unset enable pin including optional rs and rw */
215+
i2c_out(ctrldev, command);
216+
}
217+
179218
}

Diff for: drv_generic_i2c.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ int drv_generic_i2c_close(void);
5757
unsigned char drv_generic_i2c_wire(const char *name, const char *deflt);
5858
void drv_generic_i2c_byte(const unsigned char data);
5959
void drv_generic_i2c_data(const unsigned char data);
60-
void drv_generic_i2c_command(const unsigned char command, /*const */ unsigned char *data, const unsigned char length);
60+
void drv_generic_i2c_command(const unsigned char command, /*const */ unsigned char *data, const unsigned char length,
61+
int bits);
6162

6263
#endif

0 commit comments

Comments
 (0)