-
Notifications
You must be signed in to change notification settings - Fork 90
/
LiquidCrystal_SR2W.cpp
147 lines (125 loc) · 4.6 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
136
137
138
139
140
141
142
143
144
145
146
147
// ---------------------------------------------------------------------------
// Created/Adapted by Bill Perry 2012-03-16
// Copyright (C) - 2018
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License v3.0
// along with this program.
// If not, see <https://www.gnu.org/licenses/gpl-3.0.en.html>.
//
// ---------------------------------------------------------------------------
//
// 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 - [email protected]
// ---------------------------------------------------------------------------
#include "LiquidCrystal_SR2W.h"
// CONSTRUCTORS
// ---------------------------------------------------------------------------
// Assuming 1 line 8 pixel high font
LiquidCrystal_SR2W::LiquidCrystal_SR2W (uint8_t srdata, uint8_t srclock, t_backlightPol blpol)
{
init ( srdata, srclock, blpol, 1, 0 );
}
// PRIVATE METHODS
// ---------------------------------------------------------------------------
//
// init
void LiquidCrystal_SR2W::init(uint8_t srdata, uint8_t srclock, t_backlightPol 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 == LCD_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);
}