123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- /*
- * Code from:
- * A small demo program to show how to drive the Pertelian X2040 USB LCD
- * display from Linux.
- *
- * Note that this comes without any warranty.
- * This worked fine for me, and I am unaware of any problem, but if this
- * program causes a problem to you or your hardware you are on your own and
- * I will not be liable for damages in any way.
- * If this is not acceptable to you, you are not allowed to use this program.
- *
- * Otherwise you are free to use this program as you see fit provided that
- * - you do not pretent having written this yourself
- * - changes you make are clearly identified as such
- *
- * Information on how to program the device mainly came from
- * http://pertelian.com/index.php?option=com_content&task=view&id=27&Itemid=33
- * and some small local experiments
- *
- * Frans Meulenbroeks
- */
- #include <stdio.h>
- #include <time.h>
- #include <string.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #include <termios.h>
- #include <unistd.h>
- #include "sleep_us.h"
- /* Ron Lauzon - 7/16/2006
- * Changed DELAY to mean milliseconds and removed the delay()
- * function. I replaced it with a sleep_us for DELAY microseconds.
- * A 1 ms pause seems sufficient. No pause will generate garbled
- * output on the display */
- /* Ron Lauzon - 3/14/2007
- * Changed the device interface to use file handles instead of FILE.
- * This allows me to set serial port attributes (like speed).
- * It also allowed me to remove the delay completely.
- */
- /* DELAY is constant used to generate some delay.
- * You might want to tweak it for your hardware.
- * If the value is too small some or all of the data is going to be garbled
- * or the initialisation will fail.
- * If the value is too large you'll have to wait quite a while....
- */
- /*#define DELAY 1 */
- int pert_fd; /* file descriptor to the Pertelian */
- unsigned int char_delay;
- const static unsigned char rowoffset[4] =
- { 0x80, 0x80+0x40, 0x80 + 0x14, 0x80 + 0x40 + 0x14 };
- /* offsets to address the various rows.
- * the addressing structure is a little bit odd. actually row 3 is a
- * continuation of row 1 and row4 of row2
- */
- /*
- * delay
- * This function introduces some delay. After writing a character to
- * the display one needs to wait a short while. This is achieved by the
- * code below. Actually there are two different delays for the device
- * but this code does not make the distinction.
- */
- /*void delay(int n) {
- volatile int i;
- for (i = 0; i < n; i++) {
- }
- } */
- /*
- * wrtch
- * This function writes a character byte to the device
- */
- void wrtch(unsigned char c) {
- if (write(pert_fd,&c,1) != 1)
- // %s makes a warning
- //fprintf(stderr,"Error writing to pert: %s\n",c);
- fprintf(stderr,"Error writing to pert: %d\n",c);
- tcdrain(pert_fd);
- sleep_us(char_delay);
- }
- /*
- * putcode
- * This function writes a code byte to the device
- */
- void putcode(unsigned char code) {
- wrtch((char)0xfe);
- wrtch(code);
- sleep_us(char_delay);
- }
- /*
- * wrt
- * This function writes a character string to the device (0 terminated)
- * it writes the data to whereever the cursor is pointing
- */
- void wrt(char *p) {
- while(*p) {
- wrtch(*p);
- p++;
- }
- }
- /*
- * wrtln
- * This function writes a character string to a specific row
- */
- void wrtln(int row, char *p) {
- putcode(rowoffset[row]);
- wrt(p);
- }
- /* display_init - initialize the Pertelian */
- void display_init(char *device_name) {
- struct termios term;
- pert_fd = open(device_name, O_WRONLY | O_NONBLOCK);
- if (pert_fd < 0) {
- fprintf(stderr, "Cannot open device %s for writing !\n", device_name);
- exit(EXIT_FAILURE);
- }
- /* Get the tty config */
- if (tcgetattr(pert_fd,&term) < 0) {
- fprintf(stderr,"Unable to get terminal attributes\n");
- exit(EXIT_FAILURE);
- }
- /* set the terminal attributes */
- term.c_cflag = CRTSCTS | CS8 | CLOCAL | CREAD;
- term.c_iflag = ICRNL | IGNPAR;
- term.c_oflag = 0;
- term.c_lflag = 0;
- term.c_cc[VMIN] = 1;
- term.c_cc[CTIME] = 0;
- cfsetispeed(&term,B38400);
- cfsetospeed(&term,B38400);
- /* Flush any trash on the line */
- tcflush(pert_fd,TCIFLUSH);
- /* Sent the new attributes to the port */
- if (tcsetattr(pert_fd,TCSANOW,&term) < 0) {
- fprintf(stderr,"Unable to set terminal attributes\n");
- exit(EXIT_FAILURE);
- }
- /* We are connected - now set up the Pertelian */
- putcode(0x38); /* initialise display (8 bit interface, shift to right */
- putcode(0x06); /* cursor move direction to the right, no automatic shift */
- putcode(0x10); /* move cursor on data write */
- putcode(0x0c); /* cursor off */
- putcode(0x01); /* clear display */
- }
- void display_close() {
- close(pert_fd);
- }
- void backlight(int on) {
- if (on)
- putcode(0x03); /* backlight on (3 = on, 2 = off) */
- else
- putcode(0x02);
- }
|