Max_LCD.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2009-2011 Oleg Mazurov, Circuits At Home, http://www.circuitsathome.com
00003  * MAX3421E USB host controller support
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the authors nor the names of its contributors
00014  *    may be used to endorse or promote products derived from this software
00015  *    without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00027  * SUCH DAMAGE.
00028  */
00029 
00030 //this code is heavily borrowed from official Arduino source v.0017
00031 // link to original http://code.google.com/p/arduino/source/browse/trunk/hardware/libraries/LiquidCrystal/LiquidCrystal.cpp
00032 #include "Max_LCD.h"
00033 #include "Max3421e.h"
00034 
00035 #include <stdio.h>
00036 #include <string.h>
00037 #include <inttypes.h>
00038 #include "WProgram.h"
00039 
00040 // When the display powers up, it is configured as follows:
00041 //
00042 // 1. Display clear
00043 // 2. Function set:
00044 //    DL = 1; 8-bit interface data
00045 //    N = 0; 1-line display
00046 //    F = 0; 5x8 dot character font
00047 // 3. Display on/off control:
00048 //    D = 0; Display off
00049 //    C = 0; Cursor off
00050 //    B = 0; Blinking off
00051 // 4. Entry mode set:
00052 //    I/D = 1; Increment by 1
00053 //    S = 0; No shift
00054 //
00055 // Note, however, that resetting the Arduino doesn't reset the LCD, so we
00056 // can't assume that it's in that state when a sketch starts
00057 
00058 // pin definition and set/clear
00059 
00060 #define RS  0x04    // RS pin
00061 #define E   0x08    // E pin
00062 
00063 #define SET_RS  lcdPins |= RS
00064 #define CLR_RS  lcdPins &= ~RS
00065 #define SET_E   lcdPins |= E
00066 #define CLR_E   lcdPins &= ~E
00067 
00068 #define SENDlcdPins()   MAX3421E::gpioWr( lcdPins )
00069     
00070 #define LCD_sendcmd(a)  {   CLR_RS;             \
00071                             sendbyte(a);    \
00072                         }
00073  
00074 #define LCD_sendchar(a) {   SET_RS;             \
00075                             sendbyte(a);    \
00076                         }
00077                             
00078 static byte lcdPins;    //copy of LCD pins
00079 
00080 Max_LCD::Max_LCD()
00081 {
00082     lcdPins = 0;
00083 }
00084 
00085 
00086 void Max_LCD::init()
00087 {
00088     _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
00089  
00090  //   MAX3421E::gpioWr(0x55);
00091  
00092   begin(16, 1);  
00093 }
00094 
00095 void Max_LCD::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) {
00096   if (lines > 1) {
00097     _displayfunction |= LCD_2LINE;
00098   }
00099   _numlines = lines;
00100   _currline = 0;
00101 
00102   // for some 1 line displays you can select a 10 pixel high font
00103   if ((dotsize != 0) && (lines == 1)) {
00104     _displayfunction |= LCD_5x10DOTS;
00105   }
00106 
00107   // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
00108   // according to datasheet, we need at least 40ms after power rises above 2.7V
00109   // before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50
00110   delayMicroseconds(50000);
00111   lcdPins = 0x30;
00112   SET_E;
00113   SENDlcdPins();
00114   CLR_E;
00115   SENDlcdPins();
00116   delayMicroseconds(10000); // wait min 4.1ms
00117   //second try
00118   SET_E;
00119   SENDlcdPins();
00120   CLR_E;
00121   SENDlcdPins();
00122   delayMicroseconds(10000); // wait min 4.1ms
00123   // third go!
00124   SET_E;
00125   SENDlcdPins();
00126   CLR_E;
00127   SENDlcdPins();
00128   delayMicroseconds(10000);
00129   // finally, set to 4-bit interface
00130     lcdPins = 0x20;
00131     //SET_RS;
00132     SET_E;
00133     SENDlcdPins();
00134     //CLR_RS;
00135     CLR_E;
00136     SENDlcdPins();
00137     delayMicroseconds(10000);
00138   // finally, set # lines, font size, etc.
00139   command(LCD_FUNCTIONSET | _displayfunction);  
00140 
00141   // turn the display on with no cursor or blinking default
00142   _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;  
00143   display();
00144 
00145   // clear it off
00146   clear();
00147 
00148   // Initialize to default text direction (for romance languages)
00149   _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
00150   // set the entry mode
00151   command(LCD_ENTRYMODESET | _displaymode);
00152 }
00153 
00154 /********** high level commands, for the user! */
00155 void Max_LCD::clear()
00156 {
00157   command(LCD_CLEARDISPLAY);  // clear display, set cursor position to zero
00158   delayMicroseconds(2000);  // this command takes a long time!
00159 }
00160 
00161 void Max_LCD::home()
00162 {
00163   command(LCD_RETURNHOME);  // set cursor position to zero
00164   delayMicroseconds(2000);  // this command takes a long time!
00165 }
00166 
00167 void Max_LCD::setCursor(uint8_t col, uint8_t row)
00168 {
00169   int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
00170   if ( row > _numlines ) {
00171     row = _numlines-1;    // we count rows starting w/0
00172   }
00173  
00174   command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
00175 }
00176 
00177 // Turn the display on/off (quickly)
00178 void Max_LCD::noDisplay() {
00179   _displaycontrol &= ~LCD_DISPLAYON;
00180   command(LCD_DISPLAYCONTROL | _displaycontrol);
00181 }
00182 void Max_LCD::display() {
00183   _displaycontrol |= LCD_DISPLAYON;
00184   command(LCD_DISPLAYCONTROL | _displaycontrol);
00185 }
00186 
00187 // Turns the underline cursor on/off
00188 void Max_LCD::noCursor() {
00189   _displaycontrol &= ~LCD_CURSORON;
00190   command(LCD_DISPLAYCONTROL | _displaycontrol);
00191 }
00192 void Max_LCD::cursor() {
00193   _displaycontrol |= LCD_CURSORON;
00194   command(LCD_DISPLAYCONTROL | _displaycontrol);
00195 }
00196 
00197 
00198 // Turn on and off the blinking cursor
00199 void Max_LCD::noBlink() {
00200   _displaycontrol &= ~LCD_BLINKON;
00201   command(LCD_DISPLAYCONTROL | _displaycontrol);
00202 }
00203 void Max_LCD::blink() {
00204   _displaycontrol |= LCD_BLINKON;
00205   command(LCD_DISPLAYCONTROL | _displaycontrol);
00206 }
00207 
00208 // These commands scroll the display without changing the RAM
00209 void Max_LCD::scrollDisplayLeft(void) {
00210   command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);
00211 }
00212 void Max_LCD::scrollDisplayRight(void) {
00213   command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);
00214 }
00215 
00216 // This is for text that flows Left to Right
00217 void Max_LCD::leftToRight(void) {
00218   _displaymode |= LCD_ENTRYLEFT;
00219   command(LCD_ENTRYMODESET | _displaymode);
00220 }
00221 
00222 // This is for text that flows Right to Left
00223 void Max_LCD::rightToLeft(void) {
00224   _displaymode &= ~LCD_ENTRYLEFT;
00225   command(LCD_ENTRYMODESET | _displaymode);
00226 }
00227 
00228 // This will 'right justify' text from the cursor
00229 void Max_LCD::autoscroll(void) {
00230   _displaymode |= LCD_ENTRYSHIFTINCREMENT;
00231   command(LCD_ENTRYMODESET | _displaymode);
00232 }
00233 
00234 // This will 'left justify' text from the cursor
00235 void Max_LCD::noAutoscroll(void) {
00236   _displaymode &= ~LCD_ENTRYSHIFTINCREMENT;
00237   command(LCD_ENTRYMODESET | _displaymode);
00238 }
00239 
00240 // Allows us to fill the first 8 CGRAM locations
00241 // with custom characters
00242 void Max_LCD::createChar(uint8_t location, uint8_t charmap[]) {
00243   location &= 0x7; // we only have 8 locations 0-7
00244   command(LCD_SETCGRAMADDR | (location << 3));
00245   for (int i=0; i<8; i++) {
00246     write(charmap[i]);
00247   }
00248 }
00249 
00250 /*********** mid level commands, for sending data/cmds */
00251 
00252 inline void Max_LCD::command(uint8_t value) {
00253   LCD_sendcmd(value);
00254   delayMicroseconds(100);
00255 }
00256 
00257 inline void Max_LCD::write(uint8_t value) {
00258   LCD_sendchar(value);
00259 }
00260 
00261 void Max_LCD::sendbyte( uint8_t val )
00262 {
00263     lcdPins &= 0x0f;                //prepare place for the upper nibble
00264     lcdPins |= ( val & 0xf0 );      //copy upper nibble to LCD variable
00265     SET_E;                          //send
00266     SENDlcdPins();
00267     delayMicroseconds(2);  
00268     CLR_E;
00269     delayMicroseconds(2);
00270     SENDlcdPins();
00271     lcdPins &= 0x0f;                    //prepare place for the lower nibble
00272     lcdPins |= ( val << 4 ) & 0xf0;    //copy lower nibble to LCD variable
00273     SET_E;                              //send
00274     SENDlcdPins();  
00275     CLR_E;
00276     SENDlcdPins();
00277     delayMicroseconds(100);
00278 }


rosserial_adk_demo
Author(s): Adam Stambler
autogenerated on Mon Dec 2 2013 12:02:02