]> git.friedersdorff.com Git - max/tmk_keyboard.git/blob - tmk_core/protocol/usb_hid/USB_Host_Shield_2.0/max_LCD.cpp
lufa: usb-usb: Use LUFA startup instead of cusotom
[max/tmk_keyboard.git] / tmk_core / protocol / usb_hid / USB_Host_Shield_2.0 / max_LCD.cpp
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 <string.h>
19
20 // pin definition and set/clear
21
22 #define RS  0x04    // RS pin
23 #define E   0x08    // E pin
24
25 #define SET_RS  lcdPins |= RS
26 #define CLR_RS  lcdPins &= ~RS
27 #define SET_E   lcdPins |= E
28 #define CLR_E   lcdPins &= ~E
29
30 #define SENDlcdPins()   pUsb->gpioWr( lcdPins )
31
32 #define LCD_sendcmd(a)  {   CLR_RS;             \
33                             sendbyte(a);    \
34                         }
35
36 #define LCD_sendchar(a) {   SET_RS;             \
37                             sendbyte(a);    \
38                         }
39
40 static byte lcdPins; //copy of LCD pins
41
42 Max_LCD::Max_LCD(USB *pusb) : pUsb(pusb) {
43         lcdPins = 0;
44 }
45
46 void Max_LCD::init() {
47         _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
48
49         //   MAX3421E::gpioWr(0x55);
50
51         begin(16, 1);
52 }
53
54 void Max_LCD::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) {
55         if(lines > 1) {
56                 _displayfunction |= LCD_2LINE;
57         }
58         _numlines = lines;
59         _currline = 0;
60
61         // for some 1 line displays you can select a 10 pixel high font
62         if((dotsize != 0) && (lines == 1)) {
63                 _displayfunction |= LCD_5x10DOTS;
64         }
65
66         // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
67         // according to datasheet, we need at least 40ms after power rises above 2.7V
68         // before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50
69         delayMicroseconds(50000);
70         lcdPins = 0x30;
71         SET_E;
72         SENDlcdPins();
73         CLR_E;
74         SENDlcdPins();
75         delayMicroseconds(10000); // wait min 4.1ms
76         //second try
77         SET_E;
78         SENDlcdPins();
79         CLR_E;
80         SENDlcdPins();
81         delayMicroseconds(10000); // wait min 4.1ms
82         // third go!
83         SET_E;
84         SENDlcdPins();
85         CLR_E;
86         SENDlcdPins();
87         delayMicroseconds(10000);
88         // finally, set to 4-bit interface
89         lcdPins = 0x20;
90         //SET_RS;
91         SET_E;
92         SENDlcdPins();
93         //CLR_RS;
94         CLR_E;
95         SENDlcdPins();
96         delayMicroseconds(10000);
97         // finally, set # lines, font size, etc.
98         command(LCD_FUNCTIONSET | _displayfunction);
99
100         // turn the display on with no cursor or blinking default
101         _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
102         display();
103
104         // clear it off
105         clear();
106
107         // Initialize to default text direction (for romance languages)
108         _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
109         // set the entry mode
110         command(LCD_ENTRYMODESET | _displaymode);
111 }
112
113 /********** high level commands, for the user! */
114 void Max_LCD::clear() {
115         command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero
116         delayMicroseconds(2000); // this command takes a long time!
117 }
118
119 void Max_LCD::home() {
120         command(LCD_RETURNHOME); // set cursor position to zero
121         delayMicroseconds(2000); // this command takes a long time!
122 }
123
124 void Max_LCD::setCursor(uint8_t col, uint8_t row) {
125         int row_offsets[] = {0x00, 0x40, 0x14, 0x54};
126         if(row > _numlines) {
127                 row = _numlines - 1; // we count rows starting w/0
128         }
129
130         command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
131 }
132
133 // Turn the display on/off (quickly)
134
135 void Max_LCD::noDisplay() {
136         _displaycontrol &= ~LCD_DISPLAYON;
137         command(LCD_DISPLAYCONTROL | _displaycontrol);
138 }
139
140 void Max_LCD::display() {
141         _displaycontrol |= LCD_DISPLAYON;
142         command(LCD_DISPLAYCONTROL | _displaycontrol);
143 }
144
145 // Turns the underline cursor on/off
146
147 void Max_LCD::noCursor() {
148         _displaycontrol &= ~LCD_CURSORON;
149         command(LCD_DISPLAYCONTROL | _displaycontrol);
150 }
151
152 void Max_LCD::cursor() {
153         _displaycontrol |= LCD_CURSORON;
154         command(LCD_DISPLAYCONTROL | _displaycontrol);
155 }
156
157
158 // Turn on and off the blinking cursor
159
160 void Max_LCD::noBlink() {
161         _displaycontrol &= ~LCD_BLINKON;
162         command(LCD_DISPLAYCONTROL | _displaycontrol);
163 }
164
165 void Max_LCD::blink() {
166         _displaycontrol |= LCD_BLINKON;
167         command(LCD_DISPLAYCONTROL | _displaycontrol);
168 }
169
170 // These commands scroll the display without changing the RAM
171
172 void Max_LCD::scrollDisplayLeft(void) {
173         command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);
174 }
175
176 void Max_LCD::scrollDisplayRight(void) {
177         command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);
178 }
179
180 // This is for text that flows Left to Right
181
182 void Max_LCD::leftToRight(void) {
183         _displaymode |= LCD_ENTRYLEFT;
184         command(LCD_ENTRYMODESET | _displaymode);
185 }
186
187 // This is for text that flows Right to Left
188
189 void Max_LCD::rightToLeft(void) {
190         _displaymode &= ~LCD_ENTRYLEFT;
191         command(LCD_ENTRYMODESET | _displaymode);
192 }
193
194 // This will 'right justify' text from the cursor
195
196 void Max_LCD::autoscroll(void) {
197         _displaymode |= LCD_ENTRYSHIFTINCREMENT;
198         command(LCD_ENTRYMODESET | _displaymode);
199 }
200
201 // This will 'left justify' text from the cursor
202
203 void Max_LCD::noAutoscroll(void) {
204         _displaymode &= ~LCD_ENTRYSHIFTINCREMENT;
205         command(LCD_ENTRYMODESET | _displaymode);
206 }
207
208 // Allows us to fill the first 8 CGRAM locations
209 // with custom characters
210
211 void Max_LCD::createChar(uint8_t location, uint8_t charmap[]) {
212         location &= 0x7; // we only have 8 locations 0-7
213         command(LCD_SETCGRAMADDR | (location << 3));
214         for(int i = 0; i < 8; i++) {
215                 write(charmap[i]);
216         }
217 }
218
219 /*********** mid level commands, for sending data/cmds */
220
221 inline void Max_LCD::command(uint8_t value) {
222         LCD_sendcmd(value);
223         delayMicroseconds(100);
224 }
225
226 #if defined(ARDUINO) && ARDUINO >=100
227
228 inline size_t Max_LCD::write(uint8_t value) {
229         LCD_sendchar(value);
230         return 1; // Assume success
231 }
232 #else
233
234 inline void Max_LCD::write(uint8_t value) {
235         LCD_sendchar(value);
236 }
237 #endif
238
239 void Max_LCD::sendbyte(uint8_t val) {
240         lcdPins &= 0x0f; //prepare place for the upper nibble
241         lcdPins |= (val & 0xf0); //copy upper nibble to LCD variable
242         SET_E; //send
243         SENDlcdPins();
244         delayMicroseconds(2);
245         CLR_E;
246         delayMicroseconds(2);
247         SENDlcdPins();
248         lcdPins &= 0x0f; //prepare place for the lower nibble
249         lcdPins |= (val << 4) & 0xf0; //copy lower nibble to LCD variable
250         SET_E; //send
251         SENDlcdPins();
252         CLR_E;
253         SENDlcdPins();
254         delayMicroseconds(100);
255 }