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  lcdPins = 0;
54 }
55 
56 void Max_LCD::init() {
57  _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
58 
59  // MAX3421E::gpioWr(0x55);
60 
61  begin(16, 1);
62 }
63 
64 void Max_LCD::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) {
65  if (lines > 1) {
66  _displayfunction |= LCD_2LINE;
67  }
68  _numlines = lines;
69  _currline = 0;
70 
71  // for some 1 line displays you can select a 10 pixel high font
72  if ((dotsize != 0) && (lines == 1)) {
73  _displayfunction |= LCD_5x10DOTS;
74  }
75 
76  // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
77  // according to datasheet, we need at least 40ms after power rises above 2.7V
78  // before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50
79  delayMicroseconds(50000);
80  lcdPins = 0x30;
81  SET_E;
82  SENDlcdPins();
83  CLR_E;
84  SENDlcdPins();
85  delayMicroseconds(10000); // wait min 4.1ms
86  //second try
87  SET_E;
88  SENDlcdPins();
89  CLR_E;
90  SENDlcdPins();
91  delayMicroseconds(10000); // wait min 4.1ms
92  // third go!
93  SET_E;
94  SENDlcdPins();
95  CLR_E;
96  SENDlcdPins();
97  delayMicroseconds(10000);
98  // finally, set to 4-bit interface
99  lcdPins = 0x20;
100  //SET_RS;
101  SET_E;
102  SENDlcdPins();
103  //CLR_RS;
104  CLR_E;
105  SENDlcdPins();
106  delayMicroseconds(10000);
107  // finally, set # lines, font size, etc.
108  command(LCD_FUNCTIONSET | _displayfunction);
109 
110  // turn the display on with no cursor or blinking default
111  _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
112  display();
113 
114  // clear it off
115  clear();
116 
117  // Initialize to default text direction (for romance languages)
118  _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
119  // set the entry mode
120  command(LCD_ENTRYMODESET | _displaymode);
121 }
122 
123 /********** high level commands, for the user! */
125  command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero
126  delayMicroseconds(2000); // this command takes a long time!
127 }
128 
130  command(LCD_RETURNHOME); // set cursor position to zero
131  delayMicroseconds(2000); // this command takes a long time!
132 }
133 
134 void Max_LCD::setCursor(uint8_t col, uint8_t row) {
135  int row_offsets[] = {0x00, 0x40, 0x14, 0x54};
136  if (row > _numlines) {
137  row = _numlines - 1; // we count rows starting w/0
138  }
139 
140  command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
141 }
142 
143 // Turn the display on/off (quickly)
144 
146  _displaycontrol &= ~LCD_DISPLAYON;
147  command(LCD_DISPLAYCONTROL | _displaycontrol);
148 }
149 
151  _displaycontrol |= LCD_DISPLAYON;
152  command(LCD_DISPLAYCONTROL | _displaycontrol);
153 }
154 
155 // Turns the underline cursor on/off
156 
158  _displaycontrol &= ~LCD_CURSORON;
159  command(LCD_DISPLAYCONTROL | _displaycontrol);
160 }
161 
163  _displaycontrol |= LCD_CURSORON;
164  command(LCD_DISPLAYCONTROL | _displaycontrol);
165 }
166 
167 
168 // Turn on and off the blinking cursor
169 
171  _displaycontrol &= ~LCD_BLINKON;
172  command(LCD_DISPLAYCONTROL | _displaycontrol);
173 }
174 
176  _displaycontrol |= LCD_BLINKON;
177  command(LCD_DISPLAYCONTROL | _displaycontrol);
178 }
179 
180 // These commands scroll the display without changing the RAM
181 
184 }
185 
188 }
189 
190 // This is for text that flows Left to Right
191 
193  _displaymode |= LCD_ENTRYLEFT;
194  command(LCD_ENTRYMODESET | _displaymode);
195 }
196 
197 // This is for text that flows Right to Left
198 
200  _displaymode &= ~LCD_ENTRYLEFT;
201  command(LCD_ENTRYMODESET | _displaymode);
202 }
203 
204 // This will 'right justify' text from the cursor
205 
207  _displaymode |= LCD_ENTRYSHIFTINCREMENT;
208  command(LCD_ENTRYMODESET | _displaymode);
209 }
210 
211 // This will 'left justify' text from the cursor
212 
214  _displaymode &= ~LCD_ENTRYSHIFTINCREMENT;
215  command(LCD_ENTRYMODESET | _displaymode);
216 }
217 
218 // Allows us to fill the first 8 CGRAM locations
219 // with custom characters
220 
221 void Max_LCD::createChar(uint8_t location, uint8_t charmap[]) {
222  location &= 0x7; // we only have 8 locations 0-7
223  command(LCD_SETCGRAMADDR | (location << 3));
224  for (int i = 0; i < 8; i++) {
225  write(charmap[i]);
226  }
227 }
228 
229 /*********** mid level commands, for sending data/cmds */
230 
231 inline void Max_LCD::command(uint8_t value) {
232  LCD_sendcmd(value);
233  delayMicroseconds(100);
234 }
235 
236 inline void Max_LCD::write(uint8_t value) {
237  LCD_sendchar(value);
238 }
239 
240 void Max_LCD::sendbyte(uint8_t val) {
241  lcdPins &= 0x0f; //prepare place for the upper nibble
242  lcdPins |= (val & 0xf0); //copy upper nibble to LCD variable
243  SET_E; //send
244  SENDlcdPins();
245  delayMicroseconds(2);
246  CLR_E;
247  delayMicroseconds(2);
248  SENDlcdPins();
249  lcdPins &= 0x0f; //prepare place for the lower nibble
250  lcdPins |= (val << 4) & 0xf0; //copy lower nibble to LCD variable
251  SET_E; //send
252  SENDlcdPins();
253  CLR_E;
254  SENDlcdPins();
255  delayMicroseconds(100);
256 }