Subversion Repositories idreammicro-arduino

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
21 jlesech 1
/***
2
 *
3
 *
4
 * Deuligne library
5
 *
6
 * copyleft 2011 snootlab
7
 * free software, have fun !
8
 *
9
 **/
10
#include "Deuligne.h"
11
#include <Wire.h>
12
 
13
extern "C" {
14
  #include <stdio.h>  //not needed yet
15
  #include <string.h> //needed for strlen()
16
  #include <inttypes.h>
17
#if defined(ARDUINO) &&ARDUINO < 100
18
  #include "WConstants.h"  //all things wiring / arduino
19
#endif
20
}
21
#if defined(ARDUINO) && ARDUINO >= 100
22
#include "Arduino.h"
23
#endif
24
 
25
 
26
//command bytes for LCD
27
#define CMD_CLR 0x01
28
#define CMD_RIGHT 0x1C
29
#define CMD_LEFT 0x18
30
#define CMD_HOME 0x02
31
 
32
//stuff the library user might call---------------------------------
33
 
34
//constructor.  num_lines must be 1 or 2, currently.
35
 
36
byte dataPlusMask = 0x20; // TODO!!!
37
 
38
int   adc_key_val[5] ={
39
  50, 190, 400, 540, 770 };
40
 
41
Deuligne::Deuligne( int devI2CAddress, int num_lines, int lcdwidth, int bufferwidth)  {
42
  myNumLines = num_lines;
43
  myWidth = lcdwidth;
44
  myAddress = devI2CAddress;
45
  myBufferwidth= bufferwidth;
46
  NUM_KEYS = 5;
47
}
48
 
49
void SetMCPReg( byte deviceAddr, byte reg, byte val ) {
50
  Wire.beginTransmission(deviceAddr);
51
  SNOOT_WIREWRITE(reg);
52
  SNOOT_WIREWRITE(val);
53
  Wire.endTransmission();
54
}
55
 
56
void SendToLCD( byte deviceAddr, byte data ) {
57
  data |= dataPlusMask;
58
  SetMCPReg(deviceAddr,0x0A,data);
59
  data ^= 0x10; // E
60
  delayMicroseconds(1);
61
  SetMCPReg(deviceAddr,0x0A,data);
62
  data ^= 0x10; // E
63
  delayMicroseconds(1);
64
  SetMCPReg(deviceAddr,0x0A,data);
65
  delay(1);
66
}
67
 
68
void WriteLCDByte( byte deviceAddr, byte bdata ) {
69
  SendToLCD(deviceAddr,bdata >> 4);
70
  SendToLCD(deviceAddr,bdata & 0x0F);
71
}
72
 
73
void Deuligne::init( void ) {
74
  TWBR = ((CPU_FREQ / TWI_FREQ_MCP23008) - 16) / 2;
75
  dataPlusMask = 0; // initial: 0
76
  SetMCPReg(myAddress,0x05,0x0C); // set CONFREG (0x05) to 0
77
  SetMCPReg(myAddress,0x00,0x00); // set IOREG (0x00) to 0
78
  //
79
  delay(50);
80
  SendToLCD(myAddress,0x03);
81
  delay(5);
82
  SendToLCD(myAddress,0x03);
83
  delayMicroseconds(100);
84
  SendToLCD(myAddress,0x03);
85
  delay(5);
86
  SendToLCD(myAddress,0x02);
87
  WriteLCDByte(myAddress,0x28);
88
  WriteLCDByte(myAddress,0x08);
89
  WriteLCDByte(myAddress,0x0C); // turn on, cursor off, no blinking
90
  delayMicroseconds(60);
91
  WriteLCDByte(myAddress,LCD_CLEARDISPLAY); // clear display
92
  delay(3);  
93
  _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;  
94
  // Initialize to default text direction (for romance languages)
95
  _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
96
  // set the entry mode
97
  command(LCD_ENTRYMODESET | _displaymode);
98
  backLight(1);
99
  display();
100
}
101
 
102
void Deuligne::backLight( bool turnOn ) {
103
  dataPlusMask |= 0x80; // Lights mask
104
  if (!turnOn) dataPlusMask ^= 0x80;
105
  SetMCPReg(myAddress,0x0A,dataPlusMask);  
106
}
107
 
108
 
109
SNOOT_RETURN Deuligne::write( uint8_t value ) {
110
  dataPlusMask |= 0x40; // RS
111
  WriteLCDByte(myAddress,(byte)value);
112
  dataPlusMask ^= 0x40; // RS
113
}
114
/*
115
void Deuligne::printIn( char value[] ) {
116
  for ( char *p = value; *p != 0; p++ )
117
    print(*p);
118
}
119
 
120
*/
121
void Deuligne::clear() {
122
  command(CMD_CLR);
123
}
124
 
125
void Deuligne::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) {
126
 
127
}
128
 
129
void Deuligne::setCursor(uint8_t col, uint8_t row) {
130
  int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
131
  if ( row > myNumLines ) {
132
    row = myNumLines-1;    // we count rows starting w/0
133
  }
134
 
135
  command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
136
}
137
 
138
/*
139
void Deuligne::cursorTo(int line_num, int x) {
140
  command(CMD_HOME);
141
  int targetPos = x + line_num * myBufferwidth;
142
  for ( int i = 0; i < targetPos; i++)
143
    command(0x14);
144
}*/
145
 
146
void Deuligne::command( uint8_t command ) {
147
  // RS - leave low
148
  WriteLCDByte(myAddress,command);
149
  delay(1);
150
}
151
 
152
 
153
/**
154
 *  From LiquidCrystal (official arduino) Library
155
 **/
156
 
157
// Allows us to fill the first 8 CGRAM locations
158
// with custom characters
159
void Deuligne::createChar(uint8_t location, uint8_t charmap[]) {
160
  location &= 0x7; // we only have 8 locations 0-7
161
  command(LCD_SETCGRAMADDR | (location << 3));
162
  for (int i=0; i<8; i++) {
163
    write(charmap[i]);
164
  }
165
}
166
 
167
 
168
 
169
// Turn the display on/off (quickly)
170
void Deuligne::noDisplay() {
171
  _displaycontrol &= ~LCD_DISPLAYON;
172
  command(LCD_DISPLAYCONTROL | _displaycontrol);
173
}
174
void Deuligne::display() {
175
  _displaycontrol |= LCD_DISPLAYON;
176
  command(LCD_DISPLAYCONTROL | _displaycontrol);
177
}
178
 
179
// Turns the underline cursor on/off
180
void Deuligne::noCursor() {
181
  _displaycontrol &= ~LCD_CURSORON;
182
  command(LCD_DISPLAYCONTROL | _displaycontrol);
183
}
184
void Deuligne::cursor() {
185
  _displaycontrol |= LCD_CURSORON;
186
  command(LCD_DISPLAYCONTROL | _displaycontrol);
187
}
188
 
189
// Turn on and off the blinking cursor
190
void Deuligne::noBlink() {
191
  _displaycontrol &= ~LCD_BLINKON;
192
  command(LCD_DISPLAYCONTROL | _displaycontrol);
193
}
194
void Deuligne::blink() {
195
  _displaycontrol |= LCD_BLINKON;
196
  command(LCD_DISPLAYCONTROL | _displaycontrol);
197
}
198
 
199
// These commands scroll the display without changing the RAM
200
void Deuligne::scrollDisplayLeft(void) {
201
  command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);
202
}
203
void Deuligne::scrollDisplayRight(void) {
204
  command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);
205
}
206
 
207
// This is for text that flows Left to Right
208
void Deuligne::leftToRight(void) {
209
  _displaymode |= LCD_ENTRYLEFT;
210
  command(LCD_ENTRYMODESET | _displaymode);
211
}
212
 
213
// This is for text that flows Right to Left
214
void Deuligne::rightToLeft(void) {
215
  _displaymode &= ~LCD_ENTRYLEFT;
216
  command(LCD_ENTRYMODESET | _displaymode);
217
}
218
 
219
// This will 'right justify' text from the cursor
220
void Deuligne::autoscroll(void) {
221
  _displaymode |= LCD_ENTRYSHIFTINCREMENT;
222
  command(LCD_ENTRYMODESET | _displaymode);
223
}
224
 
225
// This will 'left justify' text from the cursor
226
void Deuligne::noAutoscroll(void) {
227
  _displaymode &= ~LCD_ENTRYSHIFTINCREMENT;
228
  command(LCD_ENTRYMODESET | _displaymode);
229
}
230
 
231
void Deuligne::home()
232
{
233
  command(LCD_RETURNHOME);  // set cursor position to zero
234
  delayMicroseconds(2000);  // this command takes a long time!
235
}
236
 
237
 
238
// Get Joystick value
239
// Convert ADC value to key number : 
240
// 0: Right Key
241
// 1: Up Key
242
// 2: Down Key
243
// 3: Left Key
244
// 4: Select Key
245
 
246
int Deuligne::get_key(){
247
  adc_key_in = analogRead(0);    // read the value from the sensor  
248
 
249
  int k;
250
 
251
  //   determine which key is pressed
252
  for (k = 0; k < NUM_KEYS; k++)
253
  {
254
    if (adc_key_in < adc_key_val[k])
255
    {
256
 
257
      return k;
258
    }
259
  }
260
 
261
  if (k >= NUM_KEYS)
262
    k = -1;     // No valid key pressed
263
 
264
  return k;
265
}