pert_interf.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*
  2. * Code from:
  3. * A small demo program to show how to drive the Pertelian X2040 USB LCD
  4. * display from Linux.
  5. *
  6. * Note that this comes without any warranty.
  7. * This worked fine for me, and I am unaware of any problem, but if this
  8. * program causes a problem to you or your hardware you are on your own and
  9. * I will not be liable for damages in any way.
  10. * If this is not acceptable to you, you are not allowed to use this program.
  11. *
  12. * Otherwise you are free to use this program as you see fit provided that
  13. * - you do not pretent having written this yourself
  14. * - changes you make are clearly identified as such
  15. *
  16. * Information on how to program the device mainly came from
  17. * http://pertelian.com/index.php?option=com_content&task=view&id=27&Itemid=33
  18. * and some small local experiments
  19. *
  20. * Frans Meulenbroeks
  21. */
  22. #include <stdio.h>
  23. #include <time.h>
  24. #include <string.h>
  25. #include <stdlib.h>
  26. #include <fcntl.h>
  27. #include <termios.h>
  28. #include <unistd.h>
  29. #include "sleep_us.h"
  30. /* Ron Lauzon - 7/16/2006
  31. * Changed DELAY to mean milliseconds and removed the delay()
  32. * function. I replaced it with a sleep_us for DELAY microseconds.
  33. * A 1 ms pause seems sufficient. No pause will generate garbled
  34. * output on the display */
  35. /* Ron Lauzon - 3/14/2007
  36. * Changed the device interface to use file handles instead of FILE.
  37. * This allows me to set serial port attributes (like speed).
  38. * It also allowed me to remove the delay completely.
  39. */
  40. /* DELAY is constant used to generate some delay.
  41. * You might want to tweak it for your hardware.
  42. * If the value is too small some or all of the data is going to be garbled
  43. * or the initialisation will fail.
  44. * If the value is too large you'll have to wait quite a while....
  45. */
  46. /*#define DELAY 1 */
  47. int pert_fd; /* file descriptor to the Pertelian */
  48. unsigned int char_delay;
  49. const static unsigned char rowoffset[4] =
  50. { 0x80, 0x80+0x40, 0x80 + 0x14, 0x80 + 0x40 + 0x14 };
  51. /* offsets to address the various rows.
  52. * the addressing structure is a little bit odd. actually row 3 is a
  53. * continuation of row 1 and row4 of row2
  54. */
  55. /*
  56. * delay
  57. * This function introduces some delay. After writing a character to
  58. * the display one needs to wait a short while. This is achieved by the
  59. * code below. Actually there are two different delays for the device
  60. * but this code does not make the distinction.
  61. */
  62. /*void delay(int n) {
  63. volatile int i;
  64. for (i = 0; i < n; i++) {
  65. }
  66. } */
  67. /*
  68. * wrtch
  69. * This function writes a character byte to the device
  70. */
  71. void wrtch(unsigned char c) {
  72. if (write(pert_fd,&c,1) != 1)
  73. // %s makes a warning
  74. //fprintf(stderr,"Error writing to pert: %s\n",c);
  75. fprintf(stderr,"Error writing to pert: %d\n",c);
  76. tcdrain(pert_fd);
  77. sleep_us(char_delay);
  78. }
  79. /*
  80. * putcode
  81. * This function writes a code byte to the device
  82. */
  83. void putcode(unsigned char code) {
  84. wrtch((char)0xfe);
  85. wrtch(code);
  86. sleep_us(char_delay);
  87. }
  88. /*
  89. * wrt
  90. * This function writes a character string to the device (0 terminated)
  91. * it writes the data to whereever the cursor is pointing
  92. */
  93. void wrt(char *p) {
  94. while(*p) {
  95. wrtch(*p);
  96. p++;
  97. }
  98. }
  99. /*
  100. * wrtln
  101. * This function writes a character string to a specific row
  102. */
  103. void wrtln(int row, char *p) {
  104. putcode(rowoffset[row]);
  105. wrt(p);
  106. }
  107. /* display_init - initialize the Pertelian */
  108. void display_init(char *device_name) {
  109. struct termios term;
  110. pert_fd = open(device_name, O_WRONLY | O_NONBLOCK);
  111. if (pert_fd < 0) {
  112. fprintf(stderr, "Cannot open device %s for writing !\n", device_name);
  113. exit(EXIT_FAILURE);
  114. }
  115. /* Get the tty config */
  116. if (tcgetattr(pert_fd,&term) < 0) {
  117. fprintf(stderr,"Unable to get terminal attributes\n");
  118. exit(EXIT_FAILURE);
  119. }
  120. /* set the terminal attributes */
  121. term.c_cflag = CRTSCTS | CS8 | CLOCAL | CREAD;
  122. term.c_iflag = ICRNL | IGNPAR;
  123. term.c_oflag = 0;
  124. term.c_lflag = 0;
  125. term.c_cc[VMIN] = 1;
  126. term.c_cc[CTIME] = 0;
  127. cfsetispeed(&term,B38400);
  128. cfsetospeed(&term,B38400);
  129. /* Flush any trash on the line */
  130. tcflush(pert_fd,TCIFLUSH);
  131. /* Sent the new attributes to the port */
  132. if (tcsetattr(pert_fd,TCSANOW,&term) < 0) {
  133. fprintf(stderr,"Unable to set terminal attributes\n");
  134. exit(EXIT_FAILURE);
  135. }
  136. /* We are connected - now set up the Pertelian */
  137. putcode(0x38); /* initialise display (8 bit interface, shift to right */
  138. putcode(0x06); /* cursor move direction to the right, no automatic shift */
  139. putcode(0x10); /* move cursor on data write */
  140. putcode(0x0c); /* cursor off */
  141. putcode(0x01); /* clear display */
  142. }
  143. void display_close() {
  144. close(pert_fd);
  145. }
  146. void backlight(int on) {
  147. if (on)
  148. putcode(0x03); /* backlight on (3 = on, 2 = off) */
  149. else
  150. putcode(0x02);
  151. }