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