00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
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
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);
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 }