?lang_form? ?lang_select? ?lang_submit? ?lang_endform?
{HEADER END}
{BLAME START}

library

?curdirlinks? -

Blame information for rev 6

Line No. Rev Author Line
1 6 kaklik /*! \file ks0108.c \brief Graphic LCD driver for HD61202/KS0108 displays. */
2 //*****************************************************************************
3 //
4 // File Name : 'ks0108.c'
5 // Title : Graphic LCD driver for HD61202/KS0108 displays
6 // Author : Pascal Stang - Copyright (C) 2001-2003
7 // Date : 10/19/2002
8 // Revised : 5/5/2003
9 // Version : 0.5
10 // Target MCU : Atmel AVR
11 // Editor Tabs : 4
12 //
13 // NOTE: This code is currently below version 1.0, and therefore is considered
14 // to be lacking in some functionality or documentation, or may not be fully
15 // tested. Nonetheless, you can expect most functions to work.
16 //
17 // This code is distributed under the GNU Public License
18 // which can be found at http://www.gnu.org/licenses/gpl.txt
19 //
20 //*****************************************************************************
21  
22 #ifndef WIN32
23 // AVR specific includes
24 #include <avr/io.h>
25 #include <avr/interrupt.h>
26 #endif
27  
28 #include "global.h"
29 #include "ks0108.h"
30  
31 // global variables
32 GrLcdStateType GrLcdState;
33  
34 /*************************************************************/
35 /********************** LOCAL FUNCTIONS **********************/
36 /*************************************************************/
37  
38 void glcdInitHW(void)
39 {
40 // initialize I/O ports
41 // if I/O interface is in use
42 #ifdef GLCD_PORT_INTERFACE
43  
44 //TODO: make setup of chip select lines contingent on how
45 // many controllers are actually in the display
46  
47 // initialize LCD control lines levels
48 cbi(GLCD_CTRL_PORT, GLCD_CTRL_RS);
49 cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
50 cbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
51 cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS0);
52 cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS1);
53 cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS2);
54 cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS3);
55 cbi(GLCD_CTRL_PORT, GLCD_CTRL_RESET);
56 // initialize LCD control port to output
57 sbi(GLCD_CTRL_DDR, GLCD_CTRL_RS);
58 sbi(GLCD_CTRL_DDR, GLCD_CTRL_RW);
59 sbi(GLCD_CTRL_DDR, GLCD_CTRL_E);
60 sbi(GLCD_CTRL_DDR, GLCD_CTRL_CS0);
61 sbi(GLCD_CTRL_DDR, GLCD_CTRL_CS1);
62 sbi(GLCD_CTRL_DDR, GLCD_CTRL_CS2);
63 sbi(GLCD_CTRL_DDR, GLCD_CTRL_CS3);
64 sbi(GLCD_CTRL_DDR, GLCD_CTRL_RESET);
65 // initialize LCD data
66 outb(GLCD_DATA_PORT, 0x00);
67 // initialize LCD data port to output
68 outb(GLCD_DATA_DDR, 0xFF);
69 #endif
70 }
71  
72 void glcdControllerSelect(u08 controller)
73 {
74 #ifdef GLCD_PORT_INTERFACE
75 //TODO: make control of chip select lines contingent on how
76 // many controllers are actually in the display
77  
78 // unselect all controllers
79 cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS0);
80 cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS1);
81 cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS2);
82 cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS3);
83  
84 // select requested controller
85 switch(controller)
86 {
87 case 0: sbi(GLCD_CTRL_PORT, GLCD_CTRL_CS0); break;
88 case 1: sbi(GLCD_CTRL_PORT, GLCD_CTRL_CS1); break;
89 case 2: sbi(GLCD_CTRL_PORT, GLCD_CTRL_CS2); break;
90 case 3: sbi(GLCD_CTRL_PORT, GLCD_CTRL_CS3); break;
91 default: break;
92 }
93 #endif
94 }
95  
96 void glcdBusyWait(u08 controller)
97 {
98 #ifdef GLCD_PORT_INTERFACE
99 cli();
100 // wait until LCD busy bit goes to zero
101 // select the controller chip
102 glcdControllerSelect(controller);
103 // do a read from control register
104 outb(GLCD_DATA_PORT, 0xFF);
105 cbi(GLCD_CTRL_PORT, GLCD_CTRL_RS);
106 outb(GLCD_DATA_DDR, 0x00);
107 sbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
108 sbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
109 asm volatile ("nop"); asm volatile ("nop");
110 while(inb(GLCD_DATA_PIN) & GLCD_STATUS_BUSY)
111 {
112 cbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
113 asm volatile ("nop"); asm volatile ("nop");
114 asm volatile ("nop"); asm volatile ("nop");
115 sbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
116 asm volatile ("nop"); asm volatile ("nop");
117 asm volatile ("nop"); asm volatile ("nop");
118 }
119 cbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
120 cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
121 outb(GLCD_DATA_DDR, 0xFF);
122 sei();
123 #else
124 // sbi(MCUCR, SRW); // enable RAM waitstate
125 // wait until LCD busy bit goes to zero
126 while(*(volatile unsigned char *)
127 (GLCD_CONTROLLER0_CTRL_ADDR + GLCD_CONTROLLER_ADDR_OFFSET*controller) & GLCD_STATUS_BUSY);
128 // cbi(MCUCR, SRW); // disable RAM waitstate
129 #endif
130 }
131  
132 void glcdControlWrite(u08 controller, u08 data)
133 {
134 #ifdef GLCD_PORT_INTERFACE
135 cli();
136 glcdBusyWait(controller); // wait until LCD not busy
137 cbi(GLCD_CTRL_PORT, GLCD_CTRL_RS);
138 cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
139 sbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
140 outb(GLCD_DATA_DDR, 0xFF);
141 outb(GLCD_DATA_PORT, data);
142 asm volatile ("nop"); asm volatile ("nop");
143 asm volatile ("nop"); asm volatile ("nop");
144 asm volatile ("nop"); asm volatile ("nop");
145 asm volatile ("nop"); asm volatile ("nop");
146 cbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
147 sei();
148 #else
149 //sbi(MCUCR, SRW); // enable RAM waitstate
150 glcdBusyWait(controller); // wait until LCD not busy
151 *(volatile unsigned char *) (GLCD_CONTROLLER0_CTRL_ADDR + GLCD_CONTROLLER_ADDR_OFFSET*controller) = data;
152 //cbi(MCUCR, SRW); // disable RAM waitstate
153 #endif
154 }
155  
156 u08 glcdControlRead(u08 controller)
157 {
158 register u08 data;
159 #ifdef GLCD_PORT_INTERFACE
160 cli();
161 glcdBusyWait(controller); // wait until LCD not busy
162 cbi(GLCD_CTRL_PORT, GLCD_CTRL_RS);
163 outb(GLCD_DATA_DDR, 0x00);
164 sbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
165 sbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
166 asm volatile ("nop"); asm volatile ("nop");
167 asm volatile ("nop"); asm volatile ("nop");
168 asm volatile ("nop"); asm volatile ("nop");
169 asm volatile ("nop"); asm volatile ("nop");
170 data = inb(GLCD_DATA_PIN);
171 cbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
172 cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
173 outb(GLCD_DATA_DDR, 0xFF);
174 sei();
175 #else
176 //sbi(MCUCR, SRW); // enable RAM waitstate
177 glcdBusyWait(controller); // wait until LCD not busy
178 data = *(volatile unsigned char *) (GLCD_CONTROLLER0_CTRL_ADDR + GLCD_CONTROLLER_ADDR_OFFSET*controller);
179 //cbi(MCUCR, SRW); // disable RAM waitstate
180 #endif
181 return data;
182 }
183  
184 void glcdDataWrite(u08 data)
185 {
186 register u08 controller = (GrLcdState.lcdXAddr/GLCD_CONTROLLER_XPIXELS);
187 #ifdef GLCD_PORT_INTERFACE
188 cli();
189 glcdBusyWait(controller); // wait until LCD not busy
190 sbi(GLCD_CTRL_PORT, GLCD_CTRL_RS);
191 cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
192 sbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
193 outb(GLCD_DATA_DDR, 0xFF);
194 outb(GLCD_DATA_PORT, data);
195 asm volatile ("nop"); asm volatile ("nop");
196 asm volatile ("nop"); asm volatile ("nop");
197 asm volatile ("nop"); asm volatile ("nop");
198 asm volatile ("nop"); asm volatile ("nop");
199 cbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
200 sei();
201 #else
202 //sbi(MCUCR, SRW); // enable RAM waitstate
203 glcdBusyWait(controller); // wait until LCD not busy
204 *(volatile unsigned char *) (GLCD_CONTROLLER0_CTRL_ADDR + GLCD_CONTROLLER_ADDR_OFFSET*controller) = data;
205 //cbi(MCUCR, SRW); // disable RAM waitstate
206 #endif
207 // increment our local address counter
208 GrLcdState.ctrlr[controller].xAddr++;
209 GrLcdState.lcdXAddr++;
210 if(GrLcdState.lcdXAddr >= GLCD_XPIXELS)
211 {
212 GrLcdState.lcdYAddr++;
213 glcdSetYAddress(GrLcdState.lcdYAddr);
214 glcdSetXAddress(0);
215 }
216 }
217  
218 u08 glcdDataRead(void)
219 {
220 register u08 data;
221 register u08 controller = (GrLcdState.lcdXAddr/GLCD_CONTROLLER_XPIXELS);
222 #ifdef GLCD_PORT_INTERFACE
223 cli();
224 glcdBusyWait(controller); // wait until LCD not busy
225 sbi(GLCD_CTRL_PORT, GLCD_CTRL_RS);
226 outb(GLCD_DATA_DDR, 0x00);
227 sbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
228 sbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
229 asm volatile ("nop"); asm volatile ("nop");
230 asm volatile ("nop"); asm volatile ("nop");
231 asm volatile ("nop"); asm volatile ("nop");
232 asm volatile ("nop"); asm volatile ("nop");
233 data = inb(GLCD_DATA_PIN);
234 cbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
235 cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
236 sei();
237 #else
238 //sbi(MCUCR, SRW); // enable RAM waitstate
239 glcdBusyWait(controller); // wait until LCD not busy
240 data = *(volatile unsigned char *) (GLCD_CONTROLLER0_CTRL_ADDR + GLCD_CONTROLLER_ADDR_OFFSET*controller);
241 //cbi(MCUCR, SRW); // disable RAM waitstate
242 #endif
243 // increment our local address counter
244 GrLcdState.ctrlr[controller].xAddr++;
245 GrLcdState.lcdXAddr++;
246 if(GrLcdState.lcdXAddr >= GLCD_XPIXELS)
247 {
248 GrLcdState.lcdYAddr++;
249 glcdSetYAddress(GrLcdState.lcdYAddr);
250 glcdSetXAddress(0);
251 }
252 return data;
253 }
254  
255 void glcdReset(u08 resetState)
256 {
257 // reset lcd if argument is true
258 // run lcd if argument is false
259 #ifdef GLCD_PORT_INTERFACE
260 if(resetState)
261 cbi(GLCD_CTRL_PORT, GLCD_CTRL_RESET);
262 else
263 sbi(GLCD_CTRL_PORT, GLCD_CTRL_RESET);
264 #endif
265 }
266  
267 void glcdSetXAddress(u08 xAddr)
268 {
269 u08 i;
270 // record address change locally
271 GrLcdState.lcdXAddr = xAddr;
272  
273 // clear y (col) address on all controllers
274 for(i=0; i<GLCD_NUM_CONTROLLERS; i++)
275 {
276 glcdControlWrite(i, GLCD_SET_Y_ADDR | 0x00);
277 GrLcdState.ctrlr[i].xAddr = 0;
278 }
279  
280 // set y (col) address on destination controller
281 glcdControlWrite((GrLcdState.lcdXAddr/GLCD_CONTROLLER_XPIXELS),
282 GLCD_SET_Y_ADDR | (GrLcdState.lcdXAddr & 0x3F));
283 }
284  
285 void glcdSetYAddress(u08 yAddr)
286 {
287 u08 i;
288 // record address change locally
289 GrLcdState.lcdYAddr = yAddr;
290 // set page address for all controllers
291 for(i=0; i<GLCD_NUM_CONTROLLERS; i++)
292 {
293 glcdControlWrite(i, GLCD_SET_PAGE | yAddr);
294 }
295 }
296  
297 /*************************************************************/
298 /********************* PUBLIC FUNCTIONS **********************/
299 /*************************************************************/
300  
301 void glcdInit()
302 {
303 u08 i;
304 // initialize hardware
305 glcdInitHW();
306 // bring lcd out of reset
307 glcdReset(FALSE);
308 // Turn on LCD
309 for(i=0; i<GLCD_NUM_CONTROLLERS; i++)
310 {
311 glcdControlWrite(i, GLCD_ON_CTRL | GLCD_ON_DISPLAY);
312 }
313 // clear lcd
314 glcdClearScreen();
315 // initialize positions
316 glcdHome();
317 }
318  
319 void glcdHome(void)
320 {
321 u08 i;
322 // initialize addresses/positions
323 glcdStartLine(0);
324 glcdSetAddress(0,0);
325 // initialize local data structures
326 for(i=0; i<GLCD_NUM_CONTROLLERS; i++)
327 {
328 GrLcdState.ctrlr[i].xAddr = 0;
329 GrLcdState.ctrlr[i].yAddr = 0;
330 }
331 }
332  
333 void glcdClearScreen(void)
334 {
335 u08 pageAddr;
336 u08 xAddr;
337  
338 // clear LCD
339 // loop through all pages
340 for(pageAddr=0; pageAddr<(GLCD_YPIXELS>>3); pageAddr++)
341 {
342 // set page address
343 glcdSetAddress(0, pageAddr);
344 // clear all lines of this page of display memory
345 for(xAddr=0; xAddr<GLCD_XPIXELS; xAddr++)
346 {
347 glcdDataWrite(0x00);
348 }
349 }
350 }
351  
352 void glcdStartLine(u08 start)
353 {
354 glcdControlWrite(0, GLCD_START_LINE | start);
355 glcdControlWrite(1, GLCD_START_LINE | start);
356 }
357  
358 void glcdSetAddress(u08 x, u08 yLine)
359 {
360 // set addresses
361 glcdSetYAddress(yLine);
362 glcdSetXAddress(x);
363 }
364  
365 void glcdGotoChar(u08 line, u08 col)
366 {
367 glcdSetAddress(col*6, line);
368 }
369  
370 void glcdDelay(u16 p) // 1-8us ...2-13us ...5-31us
371 { // 10-60us ...50-290us
372 unsigned int i; // 100-580us ...500-2,9ms
373 unsigned char j; // 1000-5,8ms ...5000-29ms
374 // 10000-56ms ...30000-170ms
375 // 50000-295ms...60000-345ms
376 // for (i = 0; i < p; i++) for (j = 0; j < 10; j++) asm volatile ("nop");
377 for (i = 0; i < p; i++) for (j = 0; j < 10; j++);
378 }
379  
380  
381 // Higher level functionality has been moved to the API-layer glcd.c/glcd.h
{BLAME END}
{FOOTER START}

Powered by WebSVN v2.8.3