![]() | LCD Library 1.2.1 LCD Library - LCD control class hierarchy library. Drop in replacement for the LiquidCrystal Library. |
00001 // ---------------------------------------------------------------------------00002 // Originally Created by Francisco Malpartida on 2011/08/20.00003 // Copyright 2011 - Under creative commons license 3.0:00004 // Attribution-ShareAlike CC BY-SA00005 //00006 // This software is furnished "as is", without technical support, and with no 00007 // warranty, express or implied, as to its usefulness for any purpose.00008 //00009 // 2012/01/21 - Marc MERLIN00010 // This library, LiquidCrystal_SR_LCD3, was forked off LiquidCrystal_SR which00011 // used a different wiring than the Pebble and Pebblev2 (just released by00012 // freetronics in the arduino miniconf as part of linux.conf.au 2012) and00013 // therefore this code organizes the output data differently.00014 //00015 // Upstream source for this module is00016 // https://github.com/marcmerlin/NewLiquidCrystal00017 //00018 // Thread Safe: No00019 // Extendable: Yes00020 //00021 // @file LiquidCrystal_SR_LCD3.h00022 //00023 // Connects an LCD using 3 pins from the Arduino, via an 8-bit 00024 // ShiftRegister (SR from now on).00025 // The original port source for this module is https://github.com/marcmerlin/NewLiquidCrystal00026 // The 'FastIO' merge has madethis code 4 times faster.00027 // 00028 // @brief 00029 // This is a port of the ShiftRegLCD library from raron and ported to the00030 // LCD library.00031 //00032 // The functionality provided by this class and its base class is identical00033 // to the original functionality of the Arduino LiquidCrystal library and can00034 // be used as such.00035 //00036 // Pinout for this code is used by derivatives of the original LCD3Wire page:00037 // http://www.arduino.cc/playground/Code/LCD3wires00038 //00039 // This includes the LCA (linux.conf.au) Arduino Miniconf Pebble: 00040 // http://shieldlist.org/luke-weston/pebble00041 // https://github.com/lukeweston/Pebble00042 //00043 // It also includes the Pebble v2:00044 // http://www.arduinominiconf.org/index.php/Pebble_V2.0_Instructions00045 // http://www.freetronics.com/pages/pebble-v200046 // https://github.com/lukeweston/pebble20/blob/master/README.md00047 // https://github.com/lukeweston/pebble20/blob/master/pebble-sch.pdf00048 //00049 // Shiftregister connection description:00050 // MC14094 input: Arduino digital pin 2=Clock, pin 3=Data, pin 4=Strobe00051 // MC14094 output: Q8=DB4, Q7=DB5, Q6=DB6, Q5=DB7, Q4=E, Q3=RW, Q2=RS, Q1=None00052 //00053 // +--------------------------------------------+00054 // | Arduino (ATMega 168 or 328) |00055 // | D02 D03 D04 |00056 // +----+-------------+-------------+-----------+00057 // |4 |5 |600058 // |1 |2 |300059 // +----+-------------+-------------+-----------+00060 // | Strobe Data Clock |00061 // | MC14094 8-bit shift/latch register |00062 // | Q8 Q7 Q6 Q5 Q4 Q3 Q2 Q1 |00063 // +----+----+----+----+----+----+----+----+----+00064 // |11 |12 |13 |14 |7 |6 |5 |400065 // |11 |12 |13 |14 |6 |5 |400066 // +----+----+----+----+----+----+----+---------+00067 // | DB4 DB5 DB6 DB7 E RW RS |00068 // | LCD KS0066 |00069 // +--------------------------------------------+00070 //00071 // 3 Pins required from the Arduino for Data, Clock, and Enable/Strobe.00072 //00073 // This code was inspired from LiquidCrystal_SR from00074 // http://code.google.com/p/arduinoshiftreglcd/00075 // but was written for implementing LiquidCrystal support for the Pebble00076 // and Pebblev2 (see below).00077 // The Pebbles's LCD and shift register wiring were inspired from this00078 // original page:00079 // http://www.arduino.cc/playground/Code/LCD3wires00080 // 00081 // Pebbles and the LCD3Wires design are compatible hardware-wise, but00082 // the LCD3Wire code does not work with arduino 1.0 anymore and is generally00083 // quite limited in functionality compared to this framework that provides the00084 // entire LiquidDisplay functionality.00085 // Why not just use the LiquidCrystal_SR pinout?00086 // - LCD3Wire was first and therefore have hardware that was designed with 00087 // incompatible (IMO better if you don't mind 3 wires) pinout.00088 // - The pinout used here is same saner (the 4 bits for the LCD are all in one 00089 // nibble of the shift register, not spread across 2 like in the00090 // LiquidCrystal_SR pinout)00091 //00092 // Note however that LiquidCrystal_SR while a bit more complex wiring and code00093 // wise, supports non latching shift registers and it a few percent faster than00094 // this code since it can address the LCD enable pin without having to send 00095 // a pulse through the shift register like the LCD3Wires setup requires.00096 // 00097 // This code makes sure to properly follow the specifications when talking00098 // to the LCD while using minimal delays (it's faster than the LCD3wire and aiko00099 // pebble code).00100 //00101 // @author Marc MERLIN - marc_soft<at>merlins.org.00102 // ---------------------------------------------------------------------------00103 #include <stdio.h>00104 #include <string.h>00105 #include <inttypes.h>00106 00107 #if (ARDUINO < 100)00108 #include <WProgram.h>00109 #else00110 #include <Arduino.h>00111 #endif00112 #include "FastIO.h"00113 #include "LiquidCrystal_SR_LCD3.h"00114 00115 00116 // STATIC helper functions00117 // ---------------------------------------------------------------------------00118 00119 00120 // CONSTRUCTORS00121 // ---------------------------------------------------------------------------00122 // Assuming 1 line 8 pixel high font00123LiquidCrystal_SR_LCD3::LiquidCrystal_SR_LCD3 ( uint8_t srdata, uint8_t srclock, 00124 uint8_t strobe ) 00125 { 00126 init ( srdata, srclock, strobe, 1, 0 ); 00127 } 00128 00129 00130 // PRIVATE METHODS00131 // ---------------------------------------------------------------------------00132 00133 //00134 // init00135 void LiquidCrystal_SR_LCD3::init( uint8_t srdata, uint8_t srclock, uint8_t strobe, 00136 uint8_t lines, uint8_t font ) 00137 { 00138 // Initialise private variables00139 // translate all pins to bits and registers00140 // pinMode to OUTPUT, Output LOW00141 00142 _srdata_bit = fio_pinToBit(srdata); 00143 _srdata_register = fio_pinToOutputRegister(srdata); 00144 _srclock_bit = fio_pinToBit(srclock); 00145 _srclock_register = fio_pinToOutputRegister(srclock); 00146 _strobe_bit = fio_pinToBit(strobe); 00147 _strobe_register = fio_pinToOutputRegister(strobe); 00148 00149 // Little trick to force a pulse of the LCD enable bit and make sure it is00150 // low before we start further writes since this is assumed.00151 00152 write4bits(0); 00153 00154 _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x10DOTS; 00155 } 00156 00157 // PUBLIC METHODS00158 // ---------------------------------------------------------------------------00159 00160 00161 /************ low level data pushing commands **********/00162 00163 // Code below was borrowed from LCD3Wire from00164 // http://www.arduino.cc/playground/Code/LCD3wires00165 00166 // bitmasks for control bits on shift register00167#define SR_EN_BIT B00010000 // LCD Data enable bit.00168#define SR_RW_BIT B00100000 // RW can be pinned low since we only send00169#define SR_RS_BIT B01000000 // LOW: command. HIGH: character.00170 00171voidLiquidCrystal_SR_LCD3::send(uint8_t value, uint8_t mode) 00172 { 00173 uint8_t nibble; 00174 00175 mode = mode ? SR_RS_BIT : 0; // RS bit; LOW: command. HIGH: character.00176 00177 nibble = value >> 4; // Get high nibble.00178 write4bits(nibble | mode); 00179 00180 //delay(1); // This was in the LCD3 code but does not seem needed -- merlin00181 00182 nibble = value & 15; // Get low nibble00183 write4bits(nibble | mode); 00184 } 00185 00186 void LiquidCrystal_SR_LCD3::write4bits(uint8_t nibble) 00187 { 00188 nibble &= ~SR_RW_BIT; // set RW LOW (we do this always since we only write).00189 00190 // Send a High transition to display the data that was pushed00191 nibble |= SR_EN_BIT; // LCD Data Enable HIGH00192 _pushOut(nibble); 00193 nibble &= ~SR_EN_BIT; // LCD Data Enable LOW00194 _pushOut(nibble); 00195 } 00196 00197 // push byte to shift register and on to LCD00198 void LiquidCrystal_SR_LCD3::_pushOut(uint8_t nibble) 00199 { 00200 // Make data available for pushing to the LCD.00201 fio_shiftOut(_srdata_register, _srdata_bit, _srclock_register, _srclock_bit, nibble, LSBFIRST); 00202 00203 // Make new data active.00204 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) 00205 { 00206 fio_digitalWrite_HIGH(_strobe_register, _strobe_bit); 00207 waitUsec( 1 ); // strobe pulse must be >450ns (old code had 10ms)00208 fio_digitalWrite_SWITCHTO(_strobe_register, _strobe_bit,LOW); 00209 } 00210 waitUsec( 40 ); // commands need > 37us to settle00211 }