lcd.c


1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <avr/signal.h>
4
#include <avr/pgmspace.h>
5
6
#include "lcd.h"
7
#include "display.h"
8
#include "delay.h"
9
10
void lcd_write(unsigned char data, unsigned char mode);
11
void lcd_enable(void);
12
unsigned char lcd_read(unsigned char mode);
13
unsigned char lcd_waitbusy(void);
14
15
void lcd_init(void)
16
{
17
  LCD_LIGHT_INIT;                            /* set output for contrast and backlight */
18
  LCD_DATA_OUT_INIT;                          /* set output for databytes */
19
  LCD_E_INIT;                              /* set output for enable */
20
  LCD_RS_INIT;                            /* set output for select */
21
  LCD_RW_INIT;                            /* set output for write/read-toggle */
22
  LCD_RS_CLR;                              /* disable lcd */
23
  
24
  cli();
25
  OCR1B = DISPLAY_PWM_TOP;                      /* set display contrast */
26
  OCR1C = DISPLAY_PWM_TOP;                      /* set display backlight */
27
28
  /* init display */
29
  TCNT1 = 0;                              /* set counter to zero */
30
  TCCR1A |= 1<<COM1B1 | 1<<COM1C1 | 1<<WGM11;            /* fast pwm 9-bit, set at top, clear on match */
31
  TCCR1B |= 1<<WGM12 | 1<<CS11;                    /* 8 prescaling: 16 MHz -> 3906 Hz */
32
33
  sei();
34
  delay_ms(16);                            /* power up lcd */
35
  LCD_DATA |= 0x30;
36
  lcd_enable();                            /* activate lcd */
37
  delay_ms(5);
38
  lcd_enable();                            /* activate lcd */
39
  delay_us(100);
40
  lcd_enable();  
41
  delay_us(100);
42
  lcd_write(LCD_CMD_SET_4BIT, 0);
43
  delay_us(100);
44
  lcd_write(LCD_CMD_CLEAR, 0);
45
  return;
46
}
47
48
void lcd_set(uint8_t option, uint16_t value)
49
{
50
  value = DISPLAY_PWM_TOP - value;                  /* invert contrast and backlight */
51
  switch (option) {
52
    case DISPLAY_CONFIG_CONTRAST:
53
    OCR1B = value;
54
    break;
55
  
56
    case DISPLAY_CONFIG_BACKLIGHT:
57
    OCR1C = value;
58
    break;
59
  }
60
  return;
61
}
62
63
void lcd_putc(unsigned char c)
64
{
65
  unsigned char       addr;
66
67
  addr = lcd_waitbusy();
68
  if (c == '\r') {
69
    if (addr < LCD_ADDR_LINE2) addr = 0;
70
    else addr = LCD_ADDR_LINE2;
71
    lcd_write(LCD_CMD_CURSOR_SET + addr, 0);
72
  } else if (c == '\n') {
73
    if (addr < LCD_ADDR_LINE2) addr = addr - LCD_ADDR_LINE1 + LCD_ADDR_LINE2;
74
    else addr = addr - LCD_ADDR_LINE2 + LCD_ADDR_LINE1;
75
    lcd_write(LCD_CMD_CURSOR_SET + addr, 0);
76
  } else lcd_write(c, 1);
77
  return;
78
}
79
80
void lcd_write(unsigned char data, unsigned char mode)
81
{
82
  if (mode) LCD_RS_SET;                        /* set to data mode */
83
  else LCD_RS_CLR;                          /* set to instruction mode */
84
  LCD_RW_CLR;                              /* set to write */
85
  LCD_DATA &= 0x0F;                          /* clear output: 0000xxxx */
86
  LCD_DATA |= (data & 0xF0);                      /* first high nibble */
87
  lcd_enable();
88
  LCD_DATA &= 0x0F;                          /* clear output: 0000xxxx */
89
  LCD_DATA |= ((data<<4) & 0xF0);                  /* second low nibble */
90
  lcd_enable();
91
  return;
92
}
93
94
void lcd_enable(void)
95
{
96
  LCD_E_SET;
97
  asm("nop");
98
  asm("nop");
99
  asm("nop");
100
  LCD_E_CLR;
101
  return;
102
}
103
104
unsigned char lcd_read(unsigned char mode)
105
{
106
  unsigned char       data;
107
108
  LCD_DATA_IN_INIT;
109
  if (mode) LCD_RS_SET;                        /* set to data mode */
110
  else LCD_RS_CLR;                          /* set to instruction mode */
111
  LCD_RW_SET;                              /* set to write */
112
  LCD_E_SET;
113
  asm("nop");
114
  asm("nop");
115
  asm("nop");
116
  data = LCD_DATA_IN & 0xF0;
117
  LCD_E_CLR;
118
  asm("nop");
119
  asm("nop");
120
  asm("nop");
121
  LCD_E_SET;
122
  asm("nop");
123
  asm("nop");
124
  asm("nop");
125
  data |= (LCD_DATA_IN & 0xF0)>>4;
126
  LCD_E_CLR;
127
  LCD_DATA_OUT_INIT;
128
  return(data);
129
}
130
131
unsigned char lcd_waitbusy(void)
132
{
133
  unsigned char       data;
134
135
  while ((data = lcd_read(0)) & 0x80);
136
  return(data);
137
}