pert_interf.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  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. fprintf(stderr,"Error writing to pert: %s\n",c);
  74. tcdrain(pert_fd);
  75. sleep_us(char_delay);
  76. }
  77. /*
  78. * putcode
  79. * This function writes a code byte to the device
  80. */
  81. void putcode(unsigned char code) {
  82. wrtch((char)0xfe);
  83. wrtch(code);
  84. sleep_us(char_delay);
  85. }
  86. /*
  87. * wrt
  88. * This function writes a character string to the device (0 terminated)
  89. * it writes the data to whereever the cursor is pointing
  90. */
  91. void wrt(char *p) {
  92. while(*p) {
  93. wrtch(*p);
  94. p++;
  95. }
  96. }
  97. /*
  98. * wrtln
  99. * This function writes a character string to a specific row
  100. */
  101. void wrtln(int row, char *p) {
  102. putcode(rowoffset[row]);
  103. wrt(p);
  104. }
  105. /* display_init - initialize the Pertelian */
  106. void display_init(char *device_name) {
  107. struct termios term;
  108. pert_fd = open(device_name, O_WRONLY | O_NONBLOCK);
  109. if (pert_fd < 0) {
  110. fprintf(stderr, "Cannot open device %s for writing !\n", device_name);
  111. exit(EXIT_FAILURE);
  112. }
  113. /* Get the tty config */
  114. if (tcgetattr(pert_fd,&term) < 0) {
  115. fprintf(stderr,"Unable to get terminal attributes\n");
  116. exit(EXIT_FAILURE);
  117. }
  118. /* set the terminal attributes */
  119. term.c_cflag = CRTSCTS | CS8 | CLOCAL | CREAD;
  120. term.c_iflag = ICRNL | IGNPAR;
  121. term.c_oflag = 0;
  122. term.c_lflag = 0;
  123. term.c_cc[VMIN] = 1;
  124. term.c_cc[CTIME] = 0;
  125. cfsetispeed(&term,B38400);
  126. cfsetospeed(&term,B38400);
  127. /* Flush any trash on the line */
  128. tcflush(pert_fd,TCIFLUSH);
  129. /* Sent the new attributes to the port */
  130. if (tcsetattr(pert_fd,TCSANOW,&term) < 0) {
  131. fprintf(stderr,"Unable to set terminal attributes\n");
  132. exit(EXIT_FAILURE);
  133. }
  134. /* We are connected - now set up the Pertelian */
  135. putcode(0x38); /* initialise display (8 bit interface, shift to right */
  136. putcode(0x06); /* cursor move direction to the right, no automatic shift */
  137. putcode(0x10); /* move cursor on data write */
  138. putcode(0x0c); /* cursor off */
  139. putcode(0x01); /* clear display */
  140. }
  141. void display_close() {
  142. close(pert_fd);
  143. }
  144. void backlight(int on) {
  145. if (on)
  146. putcode(0x03); /* backlight on (3 = on, 2 = off) */
  147. else
  148. putcode(0x02);
  149. }