Project

General

Profile

Statistics
| Revision:

root / trunk / code / projects / colonet / utilities / dragonfly_wireless_relay / lcd.c @ 13

History | View | Annotate | Download (11.7 KB)

1
/*
2

3
lcd-ar2.c - implementation for lcd functions
4

5
Author: CMU Robotics Club, Colony Project
6

7
This uses SPI.
8

9
lcd_init MUST be called before anything can be used.
10

11
*/
12

    
13
#include <avr/io.h>
14
#include <lcd.h>
15
#include <time.h>
16

    
17
// data bus for LCD, pins on port 0
18
//#define D0 16
19
//#define D1 17
20
//#define D2 18
21
//#define D3 19
22
//#define D4 20
23
//#define D5 21
24
//#define D6 22
25
//#define D7 23
26

    
27
// OLED data port
28
//#define LCD_DATA 0x00FF0000
29

    
30
// other OLED pins
31
//#define LCD_RW    0x00000080
32
#define LCD_RS    PB4 // Command/Data
33
//#define LCD_RD    0x00008000
34
#define LCD_RSTB  PE2 // reset line
35
#define LCD_CS    PB0
36

    
37
// inialize OLED and SPI
38
void OLED_init(void);
39

    
40
// reset Controller
41
void Reset_SSD1339(void);
42

    
43
// write command or data
44
void write_c(unsigned char out_command);
45
void write_d(unsigned char out_data);
46

    
47
// these write data to the OLED on 8 bit data bus,  depends on MCU
48
void LCD_out(unsigned char cmd);
49

    
50
// these functions set / clear pins for OLED control lines.  they accecpt a 0 or 1 
51
//void RD(char stat);
52
//void RW(char stat);
53
void DC(char stat);
54
void RES(char stat);
55
void CS(char stat);
56

    
57
// a stupid delay
58
//void delay_ms(int count);
59

    
60
// LPC 2138 MCU initialization
61
//void Initialize(void);
62
//void feed(void);
63

    
64
void crazycircle (void) {
65
/*  int i;
66
  // draw 100 random circles
67
  for(i = 0;i < 100;i++){
68
      write_c(0x86);    // draw circle command
69
      write_d(rand() % 130);
70
      write_d(rand() % 130);
71
      write_d(rand() % 64);
72
      write_d(rand());
73
      write_d(rand());
74
      write_d(rand());
75
      write_d(rand());
76

77
      delay_ms(10);
78
  }
79
*/
80
}
81

    
82
void OLEDtest (void) {
83
  //int   i = 0;
84

    
85
  // Initialize
86
  //Initialize();
87
  OLED_init();
88

    
89
  delay_ms(120);
90

    
91
  write_c(0x8e);    // clear window command
92
  write_d(0);
93
  write_d(0);
94
  write_d(130);
95
  write_d(130);
96

    
97
  delay_ms(100);
98
  
99
  write_c(0x92);    // fill enable command
100
  write_d(0x01); 
101
  
102
  delay_ms(10);
103

    
104
  crazycircle();
105
/*
106
  // write directly to ram,  this fills up bottom 1/3 of display with color pattern
107
  write_c(0x5c);
108
  for (i = 0; i < 2000; i++){
109
  write_c(0x5c);  
110
   write_d(i);
111
   write_d(i);
112
   write_d(i);
113
  }
114
  */
115
} 
116

    
117
/**********************************************************
118
                      Initialize
119
**********************************************************/
120

    
121
void OLED_init(void)
122
{
123
  // Setup SPI here
124
  SPCR = 0x5D; //  enable SPI, master, SPI mode 3
125
  DDRB |= 0x06; // enable MOSI and SCK as outputs
126

    
127
  LCD_out(0);
128
  DC(0);
129
  CS(0);
130
  Reset_SSD1339();
131
  write_c(0xa0); // Set Re-map / Color Depth
132
  write_d(0x34);//0xb4); // 262K 8bit R->G->B
133
  write_c(0xa1); // Set display start line
134
  write_d(0x00); // 00h start
135
  //write_c(0xa2); // Set display offset
136
  //write_d(0x80); // 80h start
137
  write_c(0xA6); // Normal display
138
  write_c(0xad); // Set Master Configuration
139
  write_d(0x8e); // DC-DC off & external VcomH voltage & external pre-charge voltage
140
  write_c(0xb0); // Power saving mode
141
  write_d(0x05);
142
  write_c(0xb1); // Set pre & dis_charge
143
  write_d(0x11); // pre=1h dis=1h
144
  write_c(0xb3); // clock & frequency
145
  write_d(0xf0); // clock=Divser+1 frequency=fh
146
  write_c(0xbb); // Set pre-charge voltage of color A B C
147
  write_d(0xff); // color A  was 1c
148
  write_d(0xff); // color B  was 1c
149
  write_d(0xff); // color C  was 1c
150
  write_c(0xbe); // Set VcomH
151
  write_d(0x1f); //
152
  write_c(0xc1); // Set contrast current for A B C
153
  write_d(0xCa); // Color A was AA
154
  write_d(0xD4); // Color B was B4
155
  write_d(0xF8); // Color C was C8
156
  write_c(0xc7); // Set master contrast
157
  write_d(0x0f); // no change
158
  write_c(0xca); // Duty
159
  write_d(0x7f); // 127+1
160
  write_c(0xaf); // Display on
161
}
162

    
163
void Reset_SSD1339(void)
164
{
165
  RES(0);
166
  delay_ms(100);
167
  RES(1);
168
}
169
void write_c(unsigned char out_command)
170
{
171
  DC(0);CS(0);
172
  //delay_ms(1);
173
  
174
  LCD_out(out_command);
175
 // delay_ms(1);
176
  
177
  DC(1);
178
  // potentially add NOP
179
  CS(1);
180

    
181
}
182

    
183
void write_d(unsigned char out_data)
184
{
185
  DC(1);CS(0);
186
 // delay_ms(1);
187
 
188
  LCD_out(out_data);
189
 // delay_ms(1);
190
  DC(1);
191
  //potentially add NOP
192
  CS(1);
193
}
194

    
195
// these functions set / clear pins for LCD control lines.  they accecpt a 0 or 1 
196
void DC(char stat)
197
{
198
        DDRB |= _BV(LCD_RS);                                // RS is P0.30, set to output
199
        if (stat)        
200
                PORTB |= _BV(LCD_RS);
201
        else
202
                PORTB &= ~(_BV(LCD_RS));
203
}
204

    
205
void RES(char stat)
206
{
207
        DDRE |= _BV(LCD_RSTB);                                // RSTB is P0.7, set to output
208
        if (stat)        
209
                PORTE |= _BV(LCD_RSTB);
210
        else
211
                PORTE &= ~(_BV(LCD_RSTB));
212
}
213

    
214
void CS(char stat)
215
{
216
        DDRB |= _BV(LCD_CS);                                // RSTB is P0.7, set to output
217
        if (stat)        
218
                PORTB |= _BV(LCD_CS);
219
        else
220
                PORTB &= ~(_BV(LCD_CS));
221
}
222

    
223
// send to the LCD
224
void LCD_out(unsigned char cmd)
225
{
226
        SPDR = cmd;
227
    // could also do this via interrupts
228
        loop_until_bit_is_set(SPSR, SPIF);
229
}
230

    
231

    
232
//**************************************Old shit below!*****************
233
/*
234
FontLookup - a lookup table for all characters
235
*/
236
static const unsigned char FontLookup [][5] =
237
{
238
    { 0x00, 0x00, 0x00, 0x00, 0x00 },  // sp
239
    { 0x00, 0x00, 0x5f, 0x00, 0x00 },   // !
240
    { 0x00, 0x07, 0x00, 0x07, 0x00 },   // "
241
    { 0x14, 0x7f, 0x14, 0x7f, 0x14 },   // #
242
    { 0x24, 0x2a, 0x7f, 0x2a, 0x12 },   // $
243
    { 0x23, 0x13, 0x08, 0x64, 0x62 },   // %
244
    { 0x36, 0x49, 0x55, 0x22, 0x50 },   // &
245
    { 0x00, 0x05, 0x03, 0x00, 0x00 },   // '
246
    { 0x00, 0x1c, 0x22, 0x41, 0x00 },   // (
247
    { 0x00, 0x41, 0x22, 0x1c, 0x00 },   // )
248
    { 0x14, 0x08, 0x3E, 0x08, 0x14 },   // *
249
    { 0x08, 0x08, 0x3E, 0x08, 0x08 },   // +
250
    { 0x00, 0x00, 0x50, 0x30, 0x00 },   // ,
251
    { 0x10, 0x10, 0x10, 0x10, 0x10 },   // -
252
    { 0x00, 0x60, 0x60, 0x00, 0x00 },   // .
253
    { 0x20, 0x10, 0x08, 0x04, 0x02 },   // /
254
    { 0x3E, 0x51, 0x49, 0x45, 0x3E },   // 0
255
    { 0x00, 0x42, 0x7F, 0x40, 0x00 },   // 1
256
    { 0x42, 0x61, 0x51, 0x49, 0x46 },   // 2
257
    { 0x21, 0x41, 0x45, 0x4B, 0x31 },   // 3
258
    { 0x18, 0x14, 0x12, 0x7F, 0x10 },   // 4
259
    { 0x27, 0x45, 0x45, 0x45, 0x39 },   // 5
260
    { 0x3C, 0x4A, 0x49, 0x49, 0x30 },   // 6
261
    { 0x01, 0x71, 0x09, 0x05, 0x03 },   // 7
262
    { 0x36, 0x49, 0x49, 0x49, 0x36 },   // 8
263
    { 0x06, 0x49, 0x49, 0x29, 0x1E },   // 9
264
    { 0x00, 0x36, 0x36, 0x00, 0x00 },   // :
265
    { 0x00, 0x56, 0x36, 0x00, 0x00 },   // ;
266
    { 0x08, 0x14, 0x22, 0x41, 0x00 },   // <
267
    { 0x14, 0x14, 0x14, 0x14, 0x14 },   // =
268
    { 0x00, 0x41, 0x22, 0x14, 0x08 },   // >
269
    { 0x02, 0x01, 0x51, 0x09, 0x06 },   // ?
270
    { 0x32, 0x49, 0x59, 0x51, 0x3E },   // @
271
    { 0x7E, 0x11, 0x11, 0x11, 0x7E },   // A
272
    { 0x7F, 0x49, 0x49, 0x49, 0x36 },   // B
273
    { 0x3E, 0x41, 0x41, 0x41, 0x22 },   // C
274
    { 0x7F, 0x41, 0x41, 0x22, 0x1C },   // D
275
    { 0x7F, 0x49, 0x49, 0x49, 0x41 },   // E
276
    { 0x7F, 0x09, 0x09, 0x09, 0x01 },   // F
277
    { 0x3E, 0x41, 0x49, 0x49, 0x7A },   // G
278
    { 0x7F, 0x08, 0x08, 0x08, 0x7F },   // H
279
    { 0x00, 0x41, 0x7F, 0x41, 0x00 },   // I
280
    { 0x20, 0x40, 0x41, 0x3F, 0x01 },   // J
281
    { 0x7F, 0x08, 0x14, 0x22, 0x41 },   // K
282
    { 0x7F, 0x40, 0x40, 0x40, 0x40 },   // L
283
    { 0x7F, 0x02, 0x0C, 0x02, 0x7F },   // M
284
    { 0x7F, 0x04, 0x08, 0x10, 0x7F },   // N
285
    { 0x3E, 0x41, 0x41, 0x41, 0x3E },   // O
286
    { 0x7F, 0x09, 0x09, 0x09, 0x06 },   // P
287
    { 0x3E, 0x41, 0x51, 0x21, 0x5E },   // Q
288
    { 0x7F, 0x09, 0x19, 0x29, 0x46 },   // R
289
    { 0x46, 0x49, 0x49, 0x49, 0x31 },   // S
290
    { 0x01, 0x01, 0x7F, 0x01, 0x01 },   // T
291
    { 0x3F, 0x40, 0x40, 0x40, 0x3F },   // U
292
    { 0x1F, 0x20, 0x40, 0x20, 0x1F },   // V
293
    { 0x3F, 0x40, 0x38, 0x40, 0x3F },   // W
294
    { 0x63, 0x14, 0x08, 0x14, 0x63 },   // X
295
    { 0x07, 0x08, 0x70, 0x08, 0x07 },   // Y
296
    { 0x61, 0x51, 0x49, 0x45, 0x43 },   // Z
297
    { 0x00, 0x7F, 0x41, 0x41, 0x00 },   // [
298
    { 0x02, 0x04, 0x08, 0x10, 0x20 },   // backslash
299
    { 0x00, 0x41, 0x41, 0x7F, 0x00 },   // ]
300
    { 0x04, 0x02, 0x01, 0x02, 0x04 },   // ^
301
    { 0x40, 0x40, 0x40, 0x40, 0x40 },   // _
302
    { 0x00, 0x01, 0x02, 0x04, 0x00 },   // '
303
    { 0x20, 0x54, 0x54, 0x54, 0x78 },   // a
304
    { 0x7F, 0x48, 0x44, 0x44, 0x38 },   // b
305
    { 0x38, 0x44, 0x44, 0x44, 0x20 },   // c
306
    { 0x38, 0x44, 0x44, 0x48, 0x7F },   // d
307
    { 0x38, 0x54, 0x54, 0x54, 0x18 },   // e
308
    { 0x08, 0x7E, 0x09, 0x01, 0x02 },   // f
309
    { 0x0C, 0x52, 0x52, 0x52, 0x3E },   // g
310
    { 0x7F, 0x08, 0x04, 0x04, 0x78 },   // h
311
    { 0x00, 0x44, 0x7D, 0x40, 0x00 },   // i
312
    { 0x20, 0x40, 0x44, 0x3D, 0x00 },   // j
313
    { 0x7F, 0x10, 0x28, 0x44, 0x00 },   // k
314
    { 0x00, 0x41, 0x7F, 0x40, 0x00 },   // l
315
    { 0x7C, 0x04, 0x18, 0x04, 0x78 },   // m
316
    { 0x7C, 0x08, 0x04, 0x04, 0x78 },   // n
317
    { 0x38, 0x44, 0x44, 0x44, 0x38 },   // o
318
    { 0x7C, 0x14, 0x14, 0x14, 0x08 },   // p
319
    { 0x08, 0x14, 0x14, 0x18, 0x7C },   // q
320
    { 0x7C, 0x08, 0x04, 0x04, 0x08 },   // r
321
    { 0x48, 0x54, 0x54, 0x54, 0x20 },   // s
322
    { 0x04, 0x3F, 0x44, 0x40, 0x20 },   // t
323
    { 0x3C, 0x40, 0x40, 0x20, 0x7C },   // u
324
    { 0x1C, 0x20, 0x40, 0x20, 0x1C },   // v
325
    { 0x3C, 0x40, 0x30, 0x40, 0x3C },   // w
326
    { 0x44, 0x28, 0x10, 0x28, 0x44 },   // x
327
    { 0x0C, 0x50, 0x50, 0x50, 0x3C },   // y
328
    { 0x44, 0x64, 0x54, 0x4C, 0x44 },    // z
329
    { 0x00, 0x08, 0x36, 0x41, 0x41 },   // {
330
    { 0x00, 0x00, 0x7F, 0x00, 0x00 },   // |
331
    { 0x41, 0x41, 0x36, 0x08, 0x00 },   // }
332
    { 0x02, 0x01, 0x01, 0x02, 0x01 },   // ~
333
    { 0x55, 0x2A, 0x55, 0x2A, 0x55 },   // del
334
};
335

    
336

    
337
/*
338
initializes the LCD
339
*/
340
void lcd_init(void)
341
{
342

    
343

    
344

    
345
        LCDDDR |= (SCE | SDI | SCK);
346
        LCDRESETDDR |= (RST|D_C);
347

    
348
        LCDPORT &= ~( SCE | SDI | SCK);
349
        LCDRESETPORT &=~(D_C);
350
  
351
        SPCR |= 0x50; // no SPI int, SPI en, Master, sample on rising edge, fosc/2
352
        SPSR |= 0x01;       // a continuation of the above
353

    
354
        LCDRESETPORT |= RST;
355
        delay_ms(10);
356
        LCDRESETPORT &= (~RST);
357
        delay_ms(100);
358
        LCDRESETPORT |= RST;
359
        
360
    lcd_putbyte( 0x21 );  // LCD Extended Commands.
361
    lcd_putbyte( 0xC8 );  // Set LCD Vop (Contrast).
362
    lcd_putbyte( 0x06 );  // Set Temp coefficent.
363
    lcd_putbyte( 0x13 );  // LCD bias mode 1:48.
364
    lcd_putbyte( 0x20 );  // LCD Standard Commands, Horizontal addressing mode.
365
    lcd_putbyte( 0x0C );  // LCD in normal mode.
366
        
367
        LCDRESETPORT |= D_C;                //put it in init instead of main
368
        
369
        lcd_clear_screen();
370

    
371
}
372

    
373
/*
374
clear the lcd screen
375
*/
376
void lcd_clear_screen( void ) {
377

    
378

    
379
        int i;
380
        for (i = 0; i < 504; i++)
381
                        lcd_putbyte(0x0);
382
        
383
        lcd_gotoxy(0,0);
384

    
385

    
386
}
387

    
388

    
389
/*
390
print a byte on the lcd screen
391
*/
392
void lcd_putbyte(unsigned char b)
393
{
394

    
395

    
396
        SPDR = b;
397
        while (!(SPSR & 0x80)); /* Wait until SPI transaction is complete */
398

    
399

    
400
}
401

    
402
/*
403
print a character on the lcd
404
*/
405
void lcd_putchar(char c)
406
{
407

    
408

    
409
        int i;
410
        
411
        for (i = 0; i < 5; i++)
412
                lcd_putbyte(FontLookup[c-32][i]);
413
        lcd_putbyte(0);
414

    
415

    
416
}
417

    
418
/*
419
print an entire string to the lcd
420
*/
421
void lcd_putstr(char *s)
422
{
423
        char *t = s;
424
        while (*t != 0)
425
        {
426
                lcd_putchar(*t);
427
                t++;
428
        }
429
}
430

    
431
/*
432
go to coordinate x, y
433
y: vertically - 1 char
434
x: horizontally - 1 pixel
435

436
multiply x by 6 if want to move 1 entire character
437

438
origin (0,0) is at top left corner of lcd screen
439
*/
440
void lcd_gotoxy(int x, int y)
441
{
442

    
443
  LCDRESETPORT &= ~(D_C);
444
  lcd_putbyte(0x40 | (y & 0x07));
445
  lcd_putbyte(0x80 | (x & 0x7f));
446
  LCDRESETPORT |= D_C;
447

    
448
}
449

    
450
/*
451
prints an int to the lcd
452

453
code adapted from Chris Efstathiou's code (hendrix@otenet.gr)
454
*/
455
void lcd_putint(int value ) {
456
        unsigned char lcd_data[6]={'0','0','0','0','0','0' }, position=sizeof(lcd_data), radix=10; 
457

    
458
        /* convert int to ascii  */ 
459
        if(value<0) { lcd_putchar('-'); value=-value; }    
460
        do { position--; *(lcd_data+position)=(value%radix)+'0'; value/=radix;  } while(value); 
461

    
462
    
463
        /* start displaying the number */
464
        for(;position<=(sizeof(lcd_data)-1);position++)
465
          {
466
            
467
            lcd_putchar(lcd_data[position]);
468
          }
469

    
470
        return;
471
}