just another tini example
[fw/sdcc] / device / examples / rtc390 / lcd.c
1 /*-------------------------------------------------------------------------
2   lcd.c - lcd routines for the DS80C390 (tested on TINI)
3   
4    Written By - Johan Knol, johan.knol@iduna.nl
5     
6    This program is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published by the
8    Free Software Foundation; either version 2, or (at your option) any
9    later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19    
20    In other words, you are welcome to use, share and improve this program.
21    You are forbidden to forbid anyone else to use, share and improve
22    what you give them.   Help stamp out software-hoarding!  
23 -------------------------------------------------------------------------*/
24
25 #include <stdio.h>
26 #include <stdarg.h>
27 #include "lcd.h"
28
29 #define LCD_ROWS 4
30 #define LCD_COLLUMNS 20
31
32 xdata at 0x380002 static unsigned char lcdIwr;
33 xdata at 0x38000a static unsigned char lcdDwr;
34
35 #ifdef LCD_RW
36
37 xdata at 0x380003 static unsigned char lcdIrd;
38 xdata at 0x38000b static unsigned char lcdDrd;
39
40 #define LcdWait { while (lcdIrd&0x80) ; }
41
42 #else ifdef LCD_RW
43
44 // wait for 100us
45 #define LcdWait { ClockMicroSecondsDelay(100) ; }
46
47 #endif ifdef LCD_RW
48
49 // set the dd ram addresses for the rows
50 // this one is for a 20x4 LCD
51 xdata static unsigned char lcdLinesStart[LCD_ROWS]={0, 0x40, 0x14, 0x54};
52
53 void LcdInit() {
54   
55   ClockMilliSecondsDelay(16); // >15 ms
56   
57   lcdIwr=0x38 ;
58   ClockMilliSecondsDelay(5); // >4.1 ms
59   
60   lcdIwr=0x38;
61   ClockMicroSecondsDelay(101); // >100 us
62   
63   lcdIwr=0x38;
64   ClockMicroSecondsDelay(101); // >100 us
65   
66   lcdIwr=0x38; // interface 8 bit
67   ClockMicroSecondsDelay(41); // >40 us
68   
69   lcdIwr=0x0c; // display on
70   ClockMicroSecondsDelay(41); // >40 us
71
72   LcdClear();
73 }
74
75 void LcdOn() {
76   lcdIwr=0x0c; // display on
77   LcdWait;
78 }
79
80 void LcdOff() {
81   lcdIwr=0x08; // display off
82   LcdWait;
83 }
84
85 void LcdCursorOn() {
86   // TODO
87 }
88
89 void LcdCursorOff() {
90   // TODO
91 }
92
93 void LcdScrollOn() {
94   // TODO
95 }
96
97 void LcdScrollOff() {
98   // TODO
99 }
100
101 void LcdCharDefine() {
102   // TODO
103 }
104
105 void LcdClear() {
106   lcdIwr=0x01; // display clear
107   ClockMilliSecondsDelay(6); // > 5ms
108 }
109
110 void LcdHome() {
111   lcdIwr=0x80; // set dd ram address 0
112   LcdWait;
113 }
114
115 void LcdGoto(unsigned int collumnRow) { // msb=collumn, lsb=row
116   lcdIwr=0x80 + \
117     lcdLinesStart[collumnRow&0xff] + (collumnRow>>8);
118   LcdWait;
119 }
120
121 void LcdPutChar(char c) {
122   lcdDwr=c;
123   LcdWait;
124 }
125
126 void LcdPutString (char *string) {
127   char c;
128   while (c=*string++) {
129     LcdPutChar (c);
130   }
131 }
132
133 void LcdLPutString (unsigned int collumnRow, char *string) {
134   LcdGoto(collumnRow);
135   LcdPutString(string);
136 }
137
138 // let's hope that no one ever printf's more than the display width,
139 // however they will :), so to be sure
140 static char lcdPrintfBuffer[LCD_COLLUMNS*4];
141
142 void LcdPrintf (xdata const char *format, ...) reentrant {
143   va_list arg;
144
145   va_start (arg, format);
146   vsprintf (lcdPrintfBuffer, format, arg);
147   puts (lcdPrintfBuffer);
148   LcdPutString(lcdPrintfBuffer);
149
150   va_end (arg);
151 }
152
153 void LcdLPrintf (unsigned int collumnRow, xdata const char *format, ...) reentrant {
154   va_list arg;
155
156   LcdGoto(collumnRow);
157
158   // we can not just call LcdPrintf since we have no idea what is on the stack,
159   // so we have to do it all over again
160   va_start (arg, format);
161   vsprintf (lcdPrintfBuffer, format, arg);
162
163   LcdPutString(lcdPrintfBuffer);
164
165   va_end (arg);
166 }