[*** Just copy the following into a text editor and save as a60-lcd.c then build by typing make a60-lcd from a terminal: ***] #include #include #include #include #include #include #include int fd; int data = 0x7f; /* * Linux tester for Siemens A60 LCD (A65, M55, C60, MC60, S55, etc) * * Connect signals to parallel port via ~10K resistors thus: - * * Parallel Port A60-LCD * 2 D0 <--10K-> 1 CS * 3 D1 <--10K-> 2 Reset * 4 D2 <--10K-> 3 RS * 5 D3 <--10K-> 4 SCL * 6 D4 <--10K-> 5 SDA * 7 D5 <-620R-> 6 +2.9V *and* 8 A1 * 8 D6 <-620R-> 10 A2 * 25 GND <------> 7 GND *and* 9 K * * LCD pad 1 is nearest the edge of the frame, pad 10 is nearest the * middle of the assembly. * * By coincidence, Vf of the backlight LEDs is approx 2.9V, thus * one can be used as a simple shunt regulator for the LCD supply. * * Remember, the series resistor limits the current in the shunt. * The series resistors in the signal lines limit the current in * the LCD's clamp diodes. Adjust values as necessary to suit the * specific parallel port. * * Make sure you have your distro's ppdev package installed. */ void Send (X) { int mask; /* clock a byte out serially to the LCD */ for (mask = 0x80; mask; mask >>= 1) //for (mask = 0x01; mask & 0x100; mask <<= 1) { if (mask & X) data |= 0x10; else data &= ~0x10; data &= ~0x08; ioctl (fd, PPWDATA, &data); //ioctl (fd, PPWDATA, &data); data |= 0x08; ioctl (fd, PPWDATA, &data); //ioctl (fd, PPWDATA, &data); } } void Initialise (void) { int i, flag; int Sequence [] = { 0xf4, 0x90, 0xb3, 0xa0, 0xd0, -1, 0xf0, 0xe2, 0xd4, 0x70, 0x66, 0xb2, 0xba, 0xa1, 0xa3, 0xab, 0x94, 0x95, 0x95, 0x95, -1, 0xf5, 0x90, -1, 0xf1, 0x00, 0x10, 0x22, 0x30, 0x45, 0x50, 0x68, 0x70, 0x8a, 0x90, 0xac, 0xb0, 0xce, 0xd0, -1, 0xf2, 0x0f, 0x10, 0x20, 0x30, 0x43, 0x50, 0x66, 0x70, 0x89, 0x90, 0xab, 0xb0, 0xcd, 0xd0, -1, 0xf3, 0x0e, 0x10, 0x2f, 0x30, 0x40, 0x50, 0x64, 0x70, 0x87, 0x90, 0xaa, 0xb0, 0xcb, 0xd0, -1, 0xf4, 0x0d, 0x10, 0x2e, 0x30, 0x4f, 0x50, -1, 0xf5, 0x91, -1, 0xf1, 0x01, 0x11, 0x22, 0x31, 0x43, 0x51, 0x64, 0x71, 0x86, 0x91, 0xa8, 0xb1, 0xcb, 0xd1, -1, 0xf2, 0x0f, 0x11, 0x21, 0x31, 0x42, 0x51, 0x63, 0x71, 0x85, 0x91, 0xa6, 0xb1, 0xc8, 0xd1, -1, 0xf3, 0x0b, 0x11, 0x2f, 0x31, 0x41, 0x51, 0x62, 0x71, 0x83, 0x91, 0xa4, 0xb1, 0xc6, 0xd1, -1, 0xf4, 0x08, 0x11, 0x2b, 0x31, 0x4f, 0x51, -1, 0x80, 0x94, -1, 0xf5, 0xa2, -1, 0xf4, 0x60, -1, 0xf0, 0x40, 0x50, 0xc0, -1, 0xf4, 0x70, -1, -1, 0xf0, 0x81, -1, 0xf4, 0xb3, 0xa0, -1, 0xf0, 0x00 | 0x6, 0x10, 0x20, 0x30, -1, 0xf5, 0x00 | 0xf, 0x10 | 0xc, 0x20 | 0xf, 0x30 | 0x4, -1, -1, -1 }; /* power off */ data = 0; ioctl (fd, PPWDATA, &data); usleep (500000); /* power on, reset */ data = 0x7d; ioctl (fd, PPWDATA, &data); usleep (10000); /* reset off */ data |= 0x02; ioctl (fd, PPWDATA, &data); usleep (10000); /* send commands */ i = 0; data &= ~0x01; data |= 0x04; ioctl (fd, PPWDATA, &data); flag = 1; do { Send (Sequence [i++]); if (Sequence [i] == -1) { data |= 0x01; ioctl (fd, PPWDATA, &data); usleep (1); data &= ~0x01; ioctl (fd, PPWDATA, &data); i++; } if (Sequence [i] == -1) { usleep (20000); i++; } } while (Sequence [i] != -1); /* select data register */ data &= ~0x04; ioctl (fd, PPWDATA, &data); /* good to go! */ } void PowerOff (void) { data = 0; ioctl (fd, PPWDATA, &data); } void SetWindow (int x, int y, int sx, int sy) { /* bounds checking */ sx += x; if (x < 0) x = 0; if (x > 100) x = 100; if (sx <= x) sx = x + 1; if (sx > 101) sx = 101; sy += y; if (y < 0) y = 0; if (y > 79) y = 79; if (sy <= y) sy = y + 1; if (sy > 80) sy = 80; /* send command */ x = 2 * (3 + x); sx = 2 * (3 + sx) + 1; data |= 0x04; data &= ~0x01; ioctl (fd, PPWDATA, &data); Send (0xf0); Send (0x00 | (x & 0x0f)); Send (0x10 | (x >> 4)); Send (0x20 | (y & 0x0f)); Send (0x30 | (y >> 4)); Send (0xf5); Send (0x00 | (sx & 0x0f)); Send (0x10 | (sx >> 4)); Send (0x20 | (sy & 0x0f)); Send (0x30 | (sy >> 4)); data &= ~0x04; data |= 0x01; ioctl (fd, PPWDATA, &data); } int main (int argc, char *argv[]) { int i, j, k, demo; /* open the parallel port driver */ fd = open ("/dev/parport0", O_RDWR); if (fd == -1) { perror ("open"); exit (1); } if (ioctl (fd, PPCLAIM)) { perror ("PPCLAIM"); close (fd); exit (1); } /* mode = IEEE1284_MODE_COMPAT; if (ioctl (fd, PPNEGOT, &mode)) { perror ("PPNEGOT"); close (fd); exit (1); } */ if (argc > 1 && argv[1][0] == '0') { PowerOff (); close (fd); exit (0); } if (argc < 2 || argv[1][0] != 's') { Initialise (); } demo = (argc > 1 && argv[1][0] == 'd'); k = 0; do { for (i = 0; i < 80; i++) { SetWindow (0, i, 101, 1); data &= ~0x01; ioctl (fd, PPWDATA, &data); for (j = 0; j < 101; j++) { if (demo) { int x, c; x = ((i + k) ^ (j - k)) & 0xFF; c = ((x >> 4) % 7) + 1; x &= 0x0F; Send ((c & 0x01)? x: 0); Send (((c & 0x02)? x << 4: 0) | ((c & 0x04)? x: 0)); } else { int r, g, b; r = getchar (); g = getchar (); b = getchar (); Send ((r >> 4) & 0x0F); Send (((b >> 4) & 0x0F) | (g & 0xF0)); } } data |= 0x01; ioctl (fd, PPWDATA, &data); } k++; usleep (100000); } while (demo); close (fd); return 0; }