-
Notifications
You must be signed in to change notification settings - Fork 1
/
LiquidCrystal_SR2W.cpp
135 lines (113 loc) · 4.06 KB
/
LiquidCrystal_SR2W.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// ---------------------------------------------------------------------------
// 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 == DATA ) ? 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);
}