text: // ---------------------------------------------------------------------------
  // Created/Adapted by Bill Perry 2012-03-16
  // Copyright 2012 - Under creative commons license 3.0:
  //        Attribution-ShareAlike CC BY-SA
  //
  // This software is furnished "as is", without technical support, and with no 
  // warranty, express or implied, as to its usefulness for any purpose.
  //
  // Thread Safe: No
  // Extendable: Yes
  //
  // @file LiquidCrystal_SR2W.cpp
  // Connects a hd44780 LCD using 2 pins from the Arduino, via an 8-bit 
  // ShiftRegister (SR2W from now on).
  // 
  // @brief 
  // This is a port of the ShiftRegLCD library from raron and ported to the
  // LCD library.
  //
  //
  // See the corresponding SR2W header file for full details.
  //
  // History
  // 2012.03.29  bperrybap - Fixed incorrect use of 5x10 for default font 
  //                         (now matches original LQ library)
  //                         Fixed typo in SR2W mask define names
  //                         changed default backlight state to on
  // 2012.03.16  bperrybap - created/modified from SR sources to create SR2W
  // @author B. Perry - bperrybap@opensource.billsworld.billandterrie.com
  // ---------------------------------------------------------------------------
  
  #include "LiquidCrystal_SR2W.h"
  
  // CONSTRUCTORS
  // ---------------------------------------------------------------------------
  // Assuming 1 line 8 pixel high font
  LiquidCrystal_SR2W::LiquidCrystal_SR2W (uint8_t srdata, uint8_t srclock, t_backlighPol blpol)
  {
  	init ( srdata, srclock, blpol, 1, 0 );
  }
  
  
  // PRIVATE METHODS
  // ---------------------------------------------------------------------------
  
  //
  // init
  void LiquidCrystal_SR2W::init(uint8_t srdata, uint8_t srclock, t_backlighPol blpol, uint8_t lines, uint8_t font)
  {
  	_srDataRegister = fio_pinToOutputRegister(srdata);
  	_srDataMask = fio_pinToBit(srdata);
  	_srClockRegister = fio_pinToOutputRegister(srclock);
  	_srClockMask = fio_pinToBit(srclock);
     
  	_blPolarity = blpol;
     
  	_displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
     
  	backlight(); // set default backlight state to on
  }
  
  //
  // loadSR
  void LiquidCrystal_SR2W::loadSR(uint8_t val)
  {
  	// Clear to keep Enable LOW while clocking in new bits
  	fio_shiftOut(_srDataRegister, _srDataMask, _srClockRegister, _srClockMask);
     
     
  	// clock out SR data byte
  	fio_shiftOut(_srDataRegister, _srDataMask, _srClockRegister, _srClockMask, val, MSBFIRST);
     
   	
  	// strobe LCD enable which can now be toggled by the data line
  	ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
  	{
  		fio_digitalWrite_HIGH(_srDataRegister, _srDataMask);
  		waitUsec (1);         // enable pulse must be >450ns               
  		fio_digitalWrite_SWITCHTO(_srDataRegister, _srDataMask, LOW);
  	} // end critical section
  }
  
  // PUBLIC METHODS
  // ---------------------------------------------------------------------------
  
  
  /************ low level data pushing commands **********/
  //
  // send
  void LiquidCrystal_SR2W::send(uint8_t value, uint8_t mode)
  {
  	uint8_t myMode = ( mode == DATAt ) ? SR2W_RS_MASK : 0; 
     
  	myMode = myMode | SR2W_EN_MASK | _blMask;
  
  	if ( mode != FOUR_BITS )
  	{
  		loadSR(myMode | ((value >> 1) & SR2W_DATA_MASK)); // upper nibble
  	}
  
  	loadSR(myMode | ((value << 3) & SR2W_DATA_MASK)); // lower nibble
     
  	/*
  	 * Don't call waitUsec()
  	 * do our own delay optmization since this code is so fast it needs some added delay
  	 * even on slower AVRs.
  	 */
  #if (F_CPU <= 16000000)
  	delayMicroseconds ( 10 );      // commands & data writes need > 37us to complete
  #else
  	delayMicroseconds ( 37 );      // commands & data writes need > 37us to complete
  #endif
  }
  
  //
  // setBacklight
  void LiquidCrystal_SR2W::setBacklight ( uint8_t value ) 
  { 
  	// Check for polarity to configure mask accordingly
  	// ----------------------------------------------------------
  	if  ( ((_blPolarity == POSITIVE) && (value > 0)) || 
          ((_blPolarity == NEGATIVE ) && ( value == 0 )) )
  	{
  		_blMask = SR2W_BL_MASK;
  	}
  	else 
  	{
  		_blMask = 0;
  	}
     
  	// send dummy data of blMask to set BL pin
  	// Note: loadSR() will strobe the data line trying to pulse EN
  	// but E will not strobe because the EN output bit is not set.
  	loadSR(_blMask); 
  }
  