Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

kernel/lcd.c

Go to the documentation of this file.
00001 
00006 /*
00007  *  The contents of this file are subject to the Mozilla Public License
00008  *  Version 1.0 (the "License"); you may not use this file except in
00009  *  compliance with the License. You may obtain a copy of the License at
00010  *  http://www.mozilla.org/MPL/
00011  *
00012  *  Software distributed under the License is distributed on an "AS IS"
00013  *  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
00014  *  License for the specific language governing rights and limitations
00015  *  under the License.
00016  *
00017  *  The Original Code is legOS code, released October 17, 1999.
00018  *
00019  *  The Initial Developer of the Original Code is Markus L. Noga.
00020  *  Portions created by Markus L. Noga are Copyright (C) 1999
00021  *  Markus L. Noga. All Rights Reserved.
00022  *
00023  *  Contributor(s): Markus L. Noga <markus@noga.de>
00024  */
00025 
00026 #include <config.h>
00027 #include <dlcd.h>
00028 #include <conio.h>
00029 #include <string.h>
00030 #include <sys/h8.h>
00031 #include <sys/lcd.h>
00032 #include <rom/registers.h>
00033 #include <lnp/sys/irq.h>
00034 
00036 //
00037 // Variables
00038 //
00040 
00041 #ifdef CONF_LCD_REFRESH
00042 unsigned char lcd_refresh_counter;    
00043 unsigned char lcd_byte_counter;       
00044 unsigned char lcd_refresh_period = 2; 
00045 #endif
00046 
00048 
00072 static unsigned char lcd_shadow[LCD_DATA_OFFSET + LCD_DATA_SIZE];
00073 
00075 //
00076 // Functions
00077 //
00079 
00081 
00085 void lcd_number(int i,lcd_number_style n,lcd_comma_style c  );
00086 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00087 __asm__("\n\
00088 .text\n\
00089 .align 1\n\
00090 .globl _lcd_number\n\
00091 _lcd_number:\n\
00092         push r6         ; save r6\n\
00093     \n\
00094         push r2         ; comma_style  -> stack\n\
00095         push r0         ; number       -> stack\n\
00096     \n\
00097         mov.w r1,r6     ; number_style -> r6\n\
00098     \n\
00099         jsr @lcd_number ; call ROM\n\
00100     \n\
00101         adds #0x02,sp   ; clear stack\n\
00102         adds #0x02,sp\n\
00103         \n\
00104         pop r6          ; restore r6\n\
00105         rts\n\
00106         \n\
00107        ");
00108 #endif // DOXYGEN_SHOULD_SKIP_THIS
00109 
00111 #define set(b)  __asm__ __volatile__("bset %0,@0xbb:8" : : "i"(b));
00112 
00113 #define clr(b)  __asm__ __volatile__("bclr %0,@0xbb:8" : : "i"(b));
00114 
00116 
00121 #define slowdown()
00122 
00124 static __inline__ void i2c_start(void)
00125 {
00126     set(SDA);
00127     set(SCL);
00128     slowdown();
00129     clr(SDA);
00130     slowdown();
00131     clr(SCL);
00132     slowdown();
00133 }
00134 
00136 static __inline__ void i2c_stop(void)
00137 {
00138     clr(SDA);
00139     set(SCL);
00140     slowdown();
00141     set(SDA);
00142     slowdown();
00143     clr(SCL);
00144     slowdown();
00145     set(SCL);           // relax output driver (saves 0.5 mA)
00146 }
00147 
00149 
00153 static __inline__ void i2c_read_ack(void)
00154 {
00155     rom_port6_ddr &= ~(1 << SDA);
00156     PORT6_DDR      = rom_port6_ddr;
00157     slowdown();
00158     set(SCL);
00159     slowdown();
00160     clr(SCL);
00161     rom_port6_ddr |= (1 << SDA);
00162     PORT6_DDR      = rom_port6_ddr;
00163     slowdown();
00164 }
00165 
00167 
00169 static __inline__ void i2c_write(unsigned char val)
00170 {
00171     unsigned char bit;
00172 
00173     for (bit = (1 << 7); bit; bit >>= 1) {
00174         if (bit & val) {
00175             set(SDA);
00176         } else {
00177             clr(SDA);
00178         }
00179         slowdown();
00180         set(SCL);
00181         slowdown();
00182         clr(SCL);
00183         slowdown();
00184     }
00185 }
00186 
00188 
00195 static void lcd_write_data(unsigned char *data, unsigned char len)
00196 {
00197     unsigned char i;
00198 
00199     i2c_start();
00200     for (i = 0; i < len; i++) {
00201         i2c_write(*data++);
00202         i2c_read_ack();
00203     }
00204     i2c_stop();
00205 }
00206 
00207 
00208 #ifdef CONF_LCD_REFRESH
00209 
00211 
00222 #ifdef CONF_RCX_COMPILER
00223 void lcd_refresh_next_byte(void)
00224 #else
00225 HANDLER_WRAPPER("lcd_refresh_next_byte", "lcd_refresh_next_byte_core");
00227 
00229 void lcd_refresh_next_byte_core(void)
00230 #endif
00231 {
00232     unsigned char byte;
00233 
00234     byte = lcd_byte_counter++;
00235     if (lcd_byte_counter >= LCD_DATA_SIZE)
00236         lcd_byte_counter = 0;
00237 
00238     if (lcd_shadow[byte + LCD_DATA_OFFSET] == display_memory[byte])
00239         return;
00240 
00241     lcd_shadow[byte + LCD_DATA_OFFSET] = display_memory[byte];
00242     lcd_shadow[LCD_SHORT_CMD + 1] = byte << 1;
00243     lcd_shadow[LCD_SHORT_CMD + 2] = display_memory[byte];
00244     lcd_write_data(&lcd_shadow[LCD_SHORT_CMD], 3);
00245 }
00246 
00247 #endif // CONF_LCD_REFRESH
00248 
00250 
00254 void lcd_refresh(void)
00255 {
00256     unsigned char i;
00257 
00258     for (i = 0; i < LCD_DATA_SIZE; i++)
00259         lcd_shadow[i + LCD_DATA_OFFSET] = display_memory[i];
00260     lcd_write_data(&lcd_shadow[LCD_LONG_CMD], 11);
00261 }
00262 
00264 
00266 void lcd_power_on(void)
00267 {
00268     lcd_shadow[LCD_SHORT_CMD + 1] = LCD_MODE_SET | LCD_ENABLE;
00269     lcd_write_data(&lcd_shadow[LCD_SHORT_CMD], 2);
00270 }
00271 
00273 
00279 void lcd_power_off(void)
00280 {
00281     lcd_refresh();
00282 
00283     lcd_shadow[LCD_SHORT_CMD + 1] = LCD_MODE_SET | LCD_DISABLE;
00284     lcd_write_data(&lcd_shadow[LCD_SHORT_CMD], 2);
00285 
00286     clr(SCL);
00287     clr(SDA);
00288 }
00289 
00291 
00295 void lcd_init(void)
00296 {
00297     rom_port6_ddr |= (1 << SCL);
00298     PORT6_DDR      = rom_port6_ddr;
00299     clr(SCL);
00300     rom_port6_ddr |= (1 << SDA);
00301     PORT6_DDR      = rom_port6_ddr;
00302     clr(SDA);
00303 
00304     memset(lcd_shadow, 0, sizeof(lcd_shadow));
00305     lcd_shadow[LCD_SHORT_CMD] = LCD_DEV_ID | I2C_WRITE;
00306     lcd_shadow[LCD_LONG_CMD]  = LCD_DEV_ID | I2C_WRITE;
00307 
00308     lcd_power_on();
00309 
00310 #ifdef CONF_LCD_REFRESH
00311     lcd_refresh_counter = 0;
00312     lcd_byte_counter = 0;
00313 #endif
00314 }

brickOS is released under the Mozilla Public License.
Original code copyright 1998-2002 by the authors.

Generated on Mon Feb 16 21:02:10 2004 for brickOS Kernel Developer by doxygen 1.3.5