From: Luis C. <lfc...@lf...> - 2004-10-08 23:04:10
|
Luis.F.Correia wrote: >Hi List, especially Luis, > >I just checked in a new version of drv_HD44780.c. I did some code >cleanups, and separated the parport specific stuff from the display >specific stuff, and already wrote a framework for other 'busses'. There >is support for a keyword 'bus' in the display section of lcd4linux.conf, >which can be 'parport (default) or 'i2c'. There are already skeleton >functions for I2C access. > >So Luis can start filling these skeletion functions! > >But take care, I'm currently working on the HD44780 driver, too! So >update regularly! > >The reason on my side is that I got a Nexcom 19" blade server donated by >OpenSystems, which has a 16x2 display, and four keys. > >Yes, keys! I'm working on keypad support for lcd4linux. > >stay tuned! > > > Ok, here it goes my first try to support I2C: This is a huge mess, because i'm working on a CVS version of some weeks ago. Since the functions were empty, I think i'm not stepping on anyone's toes. This reads the following config variables: Port '/dev/i2c-0' Device '70' and my config file looks like this: Display HD44780-I2C { Driver 'HD44780' Model 'WRAP1C-PCF8574' Port '/dev/i2c-0' Device '70' Bus 'i2c' Bits '4' Size '20x4' asc255bug 0 Icons 1 Wire { RW 'DB5' RS 'DB4' ENABLE 'DB6' GPO 'GND' } } ------------------------------------- includes at the top of the file: #include <linux/i2c.h> #include <linux/i2c-dev.h> global variable: /* handle for I2C device*/ static int i2c_device; Functions: /****************************************/ /*** i2c dependant functions ***/ /****************************************/ static void drv_HD_I2C_nibble (const unsigned char controller, const unsigned char nibble) { /* clear ENABLE */ /* put data on DB1..DB4 */ /* nibble already contains RS bit! */ i2c_smbus_write_byte_data(i2c_device, 0, nibble); /* Address set-up time */ ndelay(T_AS); /* rise ENABLE */ i2c_smbus_write_byte_data(i2c_device, 0, nibble | SIGNAL_ENABLE); /* Enable pulse width */ ndelay(T_PW); /* lower ENABLE */ i2c_smbus_write_byte_data(i2c_device, 0, nibble); /* Address hold time */ ndelay(T_H); } static void drv_HD_I2C_byte (const unsigned char controller, const unsigned char data) { /* send data with RS disabled */ /* send high nibble of the data */ drv_HD_I2C_nibble (controller, ((data>>4)&0x0f)|SIGNAL_RS); /* Make sure we honour T_CYCLE */ ndelay(T_CYCLE-T_AS-T_PW); /* send low nibble of the data */ drv_HD_I2C_nibble(controller, (data&0x0f)|SIGNAL_RS); } static void drv_HD_I2C_command (const unsigned char controller, const unsigned char cmd, const int delay) { /* send data with RS disabled */ drv_HD_I2C_byte (controller, cmd); /* wait for command completion */ udelay(delay); } static void drv_HD_I2C_data (const unsigned char controller, const char *string, const int len, const int delay) { int l = len; /* sanity check */ if (len<=0) return; while (l--) { /* send data with RS enabled */ drv_HD_I2C_byte (controller, *(string++)); /* wait for command completion */ udelay(delay); } } static int drv_HD_I2C_load (const char *section) { int dev; char *bus,*device; bus =cfg_get(section, "Port", NULL); device =cfg_get(section, "Device", NULL); dev =0x70; info("%s: initializing I2C bus %s",Name,bus); if ((i2c_device = open(bus,O_RDWR)) < 0) { error("%s: I2C bus %s open failed !\n",Name,bus); return -1; } info("%s: initializing I2C slave device 0x%x",Name,dev); if (ioctl(i2c_device,I2C_SLAVE, (dev>>1) ) < 0) { error("%s: error initializing device 0x%x\n",Name,dev); close(i2c_device); return -1; } info("%s: detecting I2C device 0x%x on bus %s ",Name,dev,bus); if (i2c_smbus_write_quick(i2c_device,I2C_SMBUS_WRITE) < 0) { error("%s: i2c slave-device 0x%x not found!\n",Name,dev); close(i2c_device); return -1; } 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); /* initialize *both* displays */ 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 */ info("%s: I2C initialization done", Name); return 0; } static void drv_HD_I2C_stop (void) { /* clear all signals */ // drv_generic_i2c_data (0); /* close port */ // drv_generic_i2c_close(); close(i2c_device); } ------------------------------------- Michael, please feel free to redirect that SCUD missile you have to my email address :) Cheers! Luis Correia |