1// --------------------------------------------------------------------------- 2// Created by Francisco Malpartida on 20/08/11. 3// Copyright 2011 - Under creative commons license 3.0: 4// Attribution-ShareAlike CC BY-SA 5// 6// This software is furnished "as is", without technical support, and with no 7// warranty, express or implied, as to its usefulness for any purpose. 8// 9// Thread Safe: No 10// Extendable: Yes 11// 12// @file LiquidCrystal_SR.h 13// Connects an LCD using 2 or 3 pins from the Arduino, via an 8-bit 14// ShiftRegister (SR from now on). 15// 16// @brief 17// This is a port of the ShiftRegLCD library from raron and ported to the 18// LCD library. 19// 20// The functionality provided by this class and its base class is identical 21// to the original functionality of the Arduino LiquidCrystal library and can 22// be used as such. 23// 24// Modified to work serially with the shiftOut() function, an 8-bit 25// unlatched, no-tristate, unidirectional SIPO (Serial-In-Parallel-Out) 26// shift register (IE a very simple SR), and an LCD in 4-bit mode. 27// Any such shift register should do (pref. 74LS family IC's for 2-wire). 28// I used 74LS164, for the reason that's what I had at hand. 29// 30// Connection description: 31// 32// SR output: 33// Bit #0 - N/C - not connected, used to hold a zero 34// Bit #1 - N/C 35// Bit #2 - connects to RS (Register Select) on the LCD 36// Bits #3-6 - connects to LCD data inputs D4 - D7. 37// Bit #7 - enables the LCD enable-puls (via the diode-resistor AND "gate") 38// 39// 2 or 3 Pins required from the Arduino for Data, Clock and (optional) Enable 40// If not using Enable, the Data pin is used for the enable signal by defining 41// the same pin for Enable as for Data. Data and Clock outputs/pins goes to 42// the shiftregister. 43// LCD RW-pin hardwired to LOW (only writing to LCD). 44// Busy Flag (BF, data bit D7) is not read. 45// 46// Original project homepage: http://code.google.com/p/arduinoshiftreglcd/ 47// 48// 49// History 50// 2012.03.29 bperrybap - Added delays for faster fio shiftout (it got too fast) 51// AVR needed delay. cmd/write delays are based on CPU speed so it works on pic32. 52// Added code to support indicating two wire mode by using enable=data pin 53// (documentation indicated this as working) 54// Fixed incorrect use of 5x10 for default font - now matches original LQ library. 55// can now eliminate enable pin in constructor for two wire mode. 56// 2012.01.16 Florian Fida - faster digitalWrite/shiftOut 57// 2011.10.29 fmalpartida - adaption of the library to the LCD class hierarchy. 58// 2011.07.02 Fixed a minor flaw in setCursor function. No functional change, 59// just a bit more memory efficient. 60// Thanks to CapnBry (from google code and github) who noticed it. 61// URL to his version of shiftregLCD: 62// https://github.com/CapnBry/HeaterMeter/commit/c6beba1b46b092ab0b33bcbd0a30a201fd1f28c1 63// 2009.07.30 raron - minor corrections to the comments. 64// Fixed timing to datasheet safe. Fixed keyword highlights. 65// 2009.07.28 Mircho / raron - a new modification to the schematics, and a 66// more streamlined interface 67// 2009.07.27 Thanks to an excellent suggestion from mircho at the Arduino 68// playgrond forum, the number of wires now required is only two! 69// 2009.07.25 raron - Fixed comments. I really messed up the comments before 70// posting this, so I had to fix it. 71// Renamed a function, but no improvements or functional changes. 72// 2009.07.23 Incorporated some proper initialization routines 73// inspired (lets say copy-paste-tweaked) from LiquidCrystal 74// library improvements from LadyAda. 75// 2009.05.23 raron - first version, but based mostly (as in almost verbatim) 76// on the "official" LiquidCrystal library. 77// 78// 79// @author F. Malpartida - fmalpartida@gmail.com 80// --------------------------------------------------------------------------- 81#include <stdio.h> 82#include <string.h> 83#include <inttypes.h> 84 85#if (ARDUINO < 100) 86#include <WProgram.h> 87#else 88#include <Arduino.h> 89#endif 90#include"Visuino_LiquidCrystal_SR.h" 91 92#include"Visuino_FastIO.h" 93 94 95// CONSTRUCTORS 96// --------------------------------------------------------------------------- 97// Assuming 1 line 8 pixel high font 98LiquidCrystal_SR::LiquidCrystal_SR(uint8_t srdata,uint8_t srclock, 99uint8_t enable ) 100{ 101init( srdata, srclock, enable,1,0); 102} 103 104 105// PRIVATE METHODS 106// --------------------------------------------------------------------------- 107 108// 109// init 110voidLiquidCrystal_SR::init(uint8_t srdata,uint8_t srclock,uint8_t enable, 111uint8_t lines,uint8_t font) 112{ 113// Initialise private variables 114 _two_wire =0; 115 116 _srDataRegister =fio_pinToOutputRegister(srdata); 117 _srDataBit =fio_pinToBit(srdata); 118 _srClockRegister =fio_pinToOutputRegister(srclock); 119 _srClockBit =fio_pinToBit(srclock); 120 121if((enable == TWO_WIRE) || (enable == srdata)) 122{ 123 _two_wire =1; 124 _srEnableRegister = _srDataRegister; 125 _srEnableBit = _srDataBit; 126} 127else 128{ 129 _srEnableRegister =fio_pinToOutputRegister(enable); 130 _srEnableBit =fio_pinToBit(enable); 131} 132 133// Configure control pins as outputs 134// ------------------------------------------------------------------------ 135 136 _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS; 137} 138 139// 140// shiftIt 141voidLiquidCrystal_SR::shiftIt(uint8_t val) 142{ 143if(_two_wire) 144{ 145// Clear to get Enable LOW 146fio_shiftOut(_srDataRegister, _srDataBit, _srClockRegister, _srClockBit); 147} 148fio_shiftOut(_srDataRegister, _srDataBit, _srClockRegister, _srClockBit, val, MSBFIRST); 149 150// LCD ENABLE PULSE 151// 152// While this library is written with a shift register without an output 153// latch in mind, it can work in 3-wire mode with a shiftregister with a 154// latch. The shiftregister latch pin (STR, RCL or similar) is then 155// connected to the LCD enable pin. The LCD is (very likely) slower 156// to read the Enable pulse, and then reads the new contents of the SR. 157ATOMIC_BLOCK(ATOMIC_RESTORESTATE) 158{ 159fio_digitalWrite_HIGH(_srEnableRegister, _srEnableBit); 160waitUsec(1);// enable pulse must be >450ns 161fio_digitalWrite_SWITCHTO(_srEnableRegister, _srEnableBit, LOW); 162}// end critical section 163} 164 165// PUBLIC METHODS 166// --------------------------------------------------------------------------- 167 168 169/************ low level data pushing commands **********/ 170// 171// send 172voidLiquidCrystal_SR::send(uint8_t value,uint8_t mode) 173{ 174// Divide byte in two nibbles include the RS signal 175// and format it for shiftregister output wiring to the LCD 176// We are only interested in my COMMAND or DATA for myMode 177uint8_t myMode = ( mode == DATA ) ? SR_RS_BIT :0;// RS bit; LOW: command. HIGH: character. 178 179if( mode != FOUR_BITS ) 180{ 181shiftIt(myMode | SR_EN_BIT | ((value >>1) &0x78));// upper nibble 182} 183 184shiftIt(myMode | SR_EN_BIT | ((value <<3) &0x78));// lower nibble 185/* 186 * Add some delay since this code is so fast it needs some added delay 187 * even on AVRs because the shiftout is shorter than the LCD command execution time. 188 */ 189#if (F_CPU <= 16000000) 190if(_two_wire) 191delayMicroseconds(10); 192else 193delayMicroseconds(17);// 3 wire mode is faster so it must delay longer 194#else 195delayMicroseconds(37);// commands & data writes need > 37us to complete 196#endif 197 198} 199 200// 201// setBacklightPin 202voidLiquidCrystal_SR::setBacklightPin(uint8_t pin, t_backlighPol pol ) 203{ } 204 205// 206// setBacklight 207voidLiquidCrystal_SR::setBacklight(uint8_t mode ) 208{ } 209