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. |