You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

max_LCD.cpp 6.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. /* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
  2. This software may be distributed and modified under the terms of the GNU
  3. General Public License version 2 (GPL2) as published by the Free Software
  4. Foundation and appearing in the file GPL2.TXT included in the packaging of
  5. this file. Please note that GPL2 Section 2[b] requires that all works based
  6. on this software must also be made publicly available under the terms of
  7. the GPL2 ("Copyleft").
  8. Contact information
  9. -------------------
  10. Circuits At Home, LTD
  11. Web : http://www.circuitsathome.com
  12. e-mail : [email protected]
  13. */
  14. #include "max_LCD.h"
  15. #include <string.h>
  16. // pin definition and set/clear
  17. #define RS 0x04 // RS pin
  18. #define E 0x08 // E pin
  19. #define SET_RS lcdPins |= RS
  20. #define CLR_RS lcdPins &= ~RS
  21. #define SET_E lcdPins |= E
  22. #define CLR_E lcdPins &= ~E
  23. #define SENDlcdPins() pUsb->gpioWr( lcdPins )
  24. #define LCD_sendcmd(a) { CLR_RS; \
  25. sendbyte(a); \
  26. }
  27. #define LCD_sendchar(a) { SET_RS; \
  28. sendbyte(a); \
  29. }
  30. static byte lcdPins; //copy of LCD pins
  31. Max_LCD::Max_LCD(USB *pusb) : pUsb(pusb) {
  32. lcdPins = 0;
  33. }
  34. void Max_LCD::init() {
  35. _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
  36. // MAX3421E::gpioWr(0x55);
  37. begin(16, 1);
  38. }
  39. void Max_LCD::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) {
  40. if(lines > 1) {
  41. _displayfunction |= LCD_2LINE;
  42. }
  43. _numlines = lines;
  44. _currline = 0;
  45. // for some 1 line displays you can select a 10 pixel high font
  46. if((dotsize != 0) && (lines == 1)) {
  47. _displayfunction |= LCD_5x10DOTS;
  48. }
  49. // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
  50. // according to datasheet, we need at least 40ms after power rises above 2.7V
  51. // before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50
  52. delayMicroseconds(50000);
  53. lcdPins = 0x30;
  54. SET_E;
  55. SENDlcdPins();
  56. CLR_E;
  57. SENDlcdPins();
  58. delayMicroseconds(10000); // wait min 4.1ms
  59. //second try
  60. SET_E;
  61. SENDlcdPins();
  62. CLR_E;
  63. SENDlcdPins();
  64. delayMicroseconds(10000); // wait min 4.1ms
  65. // third go!
  66. SET_E;
  67. SENDlcdPins();
  68. CLR_E;
  69. SENDlcdPins();
  70. delayMicroseconds(10000);
  71. // finally, set to 4-bit interface
  72. lcdPins = 0x20;
  73. //SET_RS;
  74. SET_E;
  75. SENDlcdPins();
  76. //CLR_RS;
  77. CLR_E;
  78. SENDlcdPins();
  79. delayMicroseconds(10000);
  80. // finally, set # lines, font size, etc.
  81. command(LCD_FUNCTIONSET | _displayfunction);
  82. // turn the display on with no cursor or blinking default
  83. _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
  84. display();
  85. // clear it off
  86. clear();
  87. // Initialize to default text direction (for romance languages)
  88. _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
  89. // set the entry mode
  90. command(LCD_ENTRYMODESET | _displaymode);
  91. }
  92. /********** high level commands, for the user! */
  93. void Max_LCD::clear() {
  94. command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero
  95. delayMicroseconds(2000); // this command takes a long time!
  96. }
  97. void Max_LCD::home() {
  98. command(LCD_RETURNHOME); // set cursor position to zero
  99. delayMicroseconds(2000); // this command takes a long time!
  100. }
  101. void Max_LCD::setCursor(uint8_t col, uint8_t row) {
  102. int row_offsets[] = {0x00, 0x40, 0x14, 0x54};
  103. if(row > _numlines) {
  104. row = _numlines - 1; // we count rows starting w/0
  105. }
  106. command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
  107. }
  108. // Turn the display on/off (quickly)
  109. void Max_LCD::noDisplay() {
  110. _displaycontrol &= ~LCD_DISPLAYON;
  111. command(LCD_DISPLAYCONTROL | _displaycontrol);
  112. }
  113. void Max_LCD::display() {
  114. _displaycontrol |= LCD_DISPLAYON;
  115. command(LCD_DISPLAYCONTROL | _displaycontrol);
  116. }
  117. // Turns the underline cursor on/off
  118. void Max_LCD::noCursor() {
  119. _displaycontrol &= ~LCD_CURSORON;
  120. command(LCD_DISPLAYCONTROL | _displaycontrol);
  121. }
  122. void Max_LCD::cursor() {
  123. _displaycontrol |= LCD_CURSORON;
  124. command(LCD_DISPLAYCONTROL | _displaycontrol);
  125. }
  126. // Turn on and off the blinking cursor
  127. void Max_LCD::noBlink() {
  128. _displaycontrol &= ~LCD_BLINKON;
  129. command(LCD_DISPLAYCONTROL | _displaycontrol);
  130. }
  131. void Max_LCD::blink() {
  132. _displaycontrol |= LCD_BLINKON;
  133. command(LCD_DISPLAYCONTROL | _displaycontrol);
  134. }
  135. // These commands scroll the display without changing the RAM
  136. void Max_LCD::scrollDisplayLeft(void) {
  137. command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);
  138. }
  139. void Max_LCD::scrollDisplayRight(void) {
  140. command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);
  141. }
  142. // This is for text that flows Left to Right
  143. void Max_LCD::leftToRight(void) {
  144. _displaymode |= LCD_ENTRYLEFT;
  145. command(LCD_ENTRYMODESET | _displaymode);
  146. }
  147. // This is for text that flows Right to Left
  148. void Max_LCD::rightToLeft(void) {
  149. _displaymode &= ~LCD_ENTRYLEFT;
  150. command(LCD_ENTRYMODESET | _displaymode);
  151. }
  152. // This will 'right justify' text from the cursor
  153. void Max_LCD::autoscroll(void) {
  154. _displaymode |= LCD_ENTRYSHIFTINCREMENT;
  155. command(LCD_ENTRYMODESET | _displaymode);
  156. }
  157. // This will 'left justify' text from the cursor
  158. void Max_LCD::noAutoscroll(void) {
  159. _displaymode &= ~LCD_ENTRYSHIFTINCREMENT;
  160. command(LCD_ENTRYMODESET | _displaymode);
  161. }
  162. // Allows us to fill the first 8 CGRAM locations
  163. // with custom characters
  164. void Max_LCD::createChar(uint8_t location, uint8_t charmap[]) {
  165. location &= 0x7; // we only have 8 locations 0-7
  166. command(LCD_SETCGRAMADDR | (location << 3));
  167. for(int i = 0; i < 8; i++) {
  168. write(charmap[i]);
  169. }
  170. }
  171. /*********** mid level commands, for sending data/cmds */
  172. inline void Max_LCD::command(uint8_t value) {
  173. LCD_sendcmd(value);
  174. delayMicroseconds(100);
  175. }
  176. #if defined(ARDUINO) && ARDUINO >=100
  177. inline size_t Max_LCD::write(uint8_t value) {
  178. LCD_sendchar(value);
  179. return 1; // Assume success
  180. }
  181. #else
  182. inline void Max_LCD::write(uint8_t value) {
  183. LCD_sendchar(value);
  184. }
  185. #endif
  186. void Max_LCD::sendbyte(uint8_t val) {
  187. lcdPins &= 0x0f; //prepare place for the upper nibble
  188. lcdPins |= (val & 0xf0); //copy upper nibble to LCD variable
  189. SET_E; //send
  190. SENDlcdPins();
  191. delayMicroseconds(2);
  192. CLR_E;
  193. delayMicroseconds(2);
  194. SENDlcdPins();
  195. lcdPins &= 0x0f; //prepare place for the lower nibble
  196. lcdPins |= (val << 4) & 0xf0; //copy lower nibble to LCD variable
  197. SET_E; //send
  198. SENDlcdPins();
  199. CLR_E;
  200. SENDlcdPins();
  201. delayMicroseconds(100);
  202. }