Project

General

Profile

Statistics
| Revision:

root / trunk / code / lib / src / libdragonfly / lcd.c @ 7

History | View | Annotate | Download (12.4 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
#define LCD_RS    PB4 // Command/Data
18
#define LCD_RSTB  PE2 // reset line
19
#define LCD_CS    PB0
20

    
21
//////lcd defines
22
#define RST _BV(4)  // pd4 (GPIO)
23
#define SCE _BV(0)  // pb0 (~SS)
24
#define D_C _BV(5)  // pd5 (GPIO?)
25
#define SDI _BV(2)  // pb2 (MOSI)
26
#define SCK _BV(1) // pb1 (SCK)
27

    
28
#define LCDPORT PORTB
29
#define LCDDDR DDRB
30

    
31
#define LCDRESETPORT PORTD
32
#define LCDRESETDDR DDRD
33

    
34
// Internal Function Prototypes
35
// inialize OLED and SPI
36
void OLED_init(void);
37

    
38
// reset Controller
39
void Reset_SSD1339(void);
40

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

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

    
48
// these functions set / clear pins for OLED control lines.  they accecpt a 0 or 1 
49
void DC(char stat);
50
void RES(char stat);
51
void CS(char stat);
52

    
53
void lcd_putbyte(unsigned char b);
54

    
55
void crazycircle (void) {
56
/*  int i;
57
  // draw 100 random circles
58
  for(i = 0;i < 100;i++){
59
      write_c(0x86);    // draw circle command
60
      write_d(rand() % 130);
61
      write_d(rand() % 130);
62
      write_d(rand() % 64);
63
      write_d(rand());
64
      write_d(rand());
65
      write_d(rand());
66
      write_d(rand());
67

68
      delay_ms(10);
69
  }
70
*/
71
}
72

    
73
void OLEDtest (void) {
74
  //int   i = 0;
75

    
76
  // Initialize
77
  //Initialize();
78
  OLED_init();
79

    
80
  delay_ms(120);
81

    
82
  write_c(0x8e);    // clear window command
83
  write_d(0);
84
  write_d(0);
85
  write_d(130);
86
  write_d(130);
87

    
88
  delay_ms(100);
89
  
90
  write_c(0x92);    // fill enable command
91
  write_d(0x01); 
92
  
93
  delay_ms(10);
94

    
95
  crazycircle();
96
/*
97
  // write directly to ram,  this fills up bottom 1/3 of display with color pattern
98
  write_c(0x5c);
99
  for (i = 0; i < 2000; i++){
100
  write_c(0x5c);  
101
   write_d(i);
102
   write_d(i);
103
   write_d(i);
104
  }
105
  */
106
} 
107

    
108
/**********************************************************
109
                      Initialize
110
**********************************************************/
111

    
112
void OLED_init(void)
113
{
114
  // Setup SPI here
115
  SPCR = 0x5D; //  enable SPI, master, SPI mode 3
116
  DDRB |= 0x06; // enable MOSI and SCK as outputs
117

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

    
154
void Reset_SSD1339(void)
155
{
156
  RES(0);
157
  delay_ms(100);
158
  RES(1);
159
}
160
void write_c(unsigned char out_command)
161
{
162
  DC(0);CS(0);
163
  //delay_ms(1);
164
  
165
  LCD_out(out_command);
166
 // delay_ms(1);
167
  
168
  DC(1);
169
  // potentially add NOP
170
  CS(1);
171

    
172
}
173

    
174
void write_d(unsigned char out_data)
175
{
176
  DC(1);CS(0);
177
 // delay_ms(1);
178
 
179
  LCD_out(out_data);
180
 // delay_ms(1);
181
  DC(1);
182
  //potentially add NOP
183
  CS(1);
184
}
185

    
186
// these functions set / clear pins for LCD control lines.  they accecpt a 0 or 1 
187
void DC(char stat)
188
{
189
        DDRB |= _BV(LCD_RS);                                // RS is P0.30, set to output
190
        if (stat)        
191
                PORTB |= _BV(LCD_RS);
192
        else
193
                PORTB &= ~(_BV(LCD_RS));
194
}
195

    
196
void RES(char stat)
197
{
198
        DDRE |= _BV(LCD_RSTB);                                // RSTB is P0.7, set to output
199
        if (stat)        
200
                PORTE |= _BV(LCD_RSTB);
201
        else
202
                PORTE &= ~(_BV(LCD_RSTB));
203
}
204

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

    
214
// send to the LCD
215
void LCD_out(unsigned char cmd)
216
{
217
        SPDR = cmd;
218
    // could also do this via interrupts
219
        loop_until_bit_is_set(SPSR, SPIF);
220
}
221

    
222

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

    
327

    
328
/**
329
 * @defgroup lcd LCD
330
 * @brief Functions for the LCD
331
 * Functions for writing to the LCD.
332
 * All functions may be found in lcd.h.
333
 *
334
 * @{
335
 **/
336

    
337
/**
338
 * Initializes the LCD. Must be called before any other
339
 * LCD functions.
340
 **/
341
void lcd_init(void)
342
{
343
        LCDDDR |= (SCE | SDI | SCK);
344
        LCDRESETDDR |= (RST|D_C);
345

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

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

    
370
/**
371
 * Clears the LCD screen. lcd_init must be called first.
372
 * 
373
 * @see lcd_init
374
 **/
375
void lcd_clear_screen( void ) {
376
        int i;
377
        for (i = 0; i < 504; i++)
378
                        lcd_putbyte(0x0);
379
        
380
        lcd_gotoxy(0,0);
381
}
382

    
383
/**
384
 * Prints a character on the LCD screen. lcd_init
385
 * must be called before this function may be used.
386
 *
387
 * @param c the character to print
388
 *
389
 * @see lcd_init
390
 **/
391
void lcd_putc(char c)
392
{
393
        int i;
394
        
395
        for (i = 0; i < 5; i++)
396
                lcd_putbyte(FontLookup[c-32][i]);
397
        lcd_putbyte(0);
398
}
399

    
400
/*
401
print an entire string to the lcd
402
*/
403
void lcd_puts(char *s)
404
{
405
        char *t = s;
406
        while (*t != 0)
407
        {
408
                lcd_putc(*t);
409
                t++;
410
        }
411
}
412

    
413
/*
414
go to coordinate x, y
415
y: vertically - 1 char
416
x: horizontally - 1 pixel
417

418
multiply x by 6 if want to move 1 entire character
419

420
origin (0,0) is at top left corner of lcd screen
421
*/
422
/**
423
 * Move the current cursor position to the one specified.
424
 * lcd_init must be called before this function may be used.
425
 * 
426
 * @param x The x coordinate of the new position
427
 * @param y The y coordinate of the new position
428
 *
429
 * @see lcd_init
430
 **/
431
void lcd_gotoxy(int x, int y)
432
{
433
  LCDRESETPORT &= ~(D_C);
434
  lcd_putbyte(0x40 | (y & 0x07));
435
  lcd_putbyte(0x80 | (x & 0x7f));
436
  LCDRESETPORT |= D_C;
437
}
438

    
439
/*
440
prints an int to the lcd
441

442
code adapted from Chris Efstathiou's code (hendrix@otenet.gr)
443
*/
444
/**
445
 * Print an integer to the LCD screen.
446
 * lcd_init must be called before this function may be used.
447
 * 
448
 * @param value the integer to print
449
 *
450
 * @see lcd_init
451
 **/
452
void lcd_puti(int value ) {
453
        unsigned char lcd_data[6]={'0','0','0','0','0','0' }, position=sizeof(lcd_data), radix=10; 
454

    
455
        /* convert int to ascii  */ 
456
        if(value<0) { lcd_putc('-'); value=-value; }    
457
        do { position--; *(lcd_data+position)=(value%radix)+'0'; value/=radix;  } while(value); 
458

    
459
    
460
        /* start displaying the number */
461
        for(;position<=(sizeof(lcd_data)-1);position++)
462
          {
463
            
464
            lcd_putc(lcd_data[position]);
465
          }
466

    
467
        return;
468
}
469

    
470
/** @} **/ //end defgroup
471

    
472
void lcd_putbyte(unsigned char b)
473
{
474
        SPDR = b;
475
        while (!(SPSR & 0x80)); /* Wait until SPI transaction is complete */
476
}
477