00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00038 #include <stdio.h>
00039
00040 #include <aversive/pgmspace.h>
00041 #include <aversive.h>
00042 #include <aversive/wait.h>
00043
00044 #include <lcd.h>
00045 #include <lcd_protocol.h>
00046
00047
00048
00049 #define e_delay() _delay_loop_1(1) // ok ca ?
00050
00051
00052
00053
00054
00055
00056
00057
00058 static inline void port_set_out(void)
00059 {
00060 uint8_t flags;
00061
00062 IRQ_LOCK(flags);
00063 DDR(LCD_PORT) |= LCD_DATA_MASK;
00064 IRQ_UNLOCK(flags);
00065 }
00066
00067
00068 static inline void port_set_in(void)
00069 {
00070 uint8_t flags;
00071
00072 IRQ_LOCK(flags);
00073 DDR(LCD_PORT) &= ~(LCD_DATA_MASK);
00074 IRQ_UNLOCK(flags);
00075 }
00076
00077
00078
00079 static inline void e_toggle(void)
00080 {
00081 sbi(LCD_E_PORT, LCD_E_BIT);
00082 e_delay();
00083 cbi(LCD_E_PORT, LCD_E_BIT);
00084 }
00085
00086
00087
00088
00089
00090 static inline void lcd_write(uint8_t data,uint8_t rs)
00091 {
00092 register uint8_t port_save;
00093 uint8_t flags;
00094
00095
00096 port_set_out();
00097
00098
00099 cbi(LCD_RW_PORT, LCD_RW_BIT);
00100
00101 if (rs)
00102 sbi(LCD_RS_PORT, LCD_RS_BIT);
00103 else
00104 cbi(LCD_RS_PORT, LCD_RS_BIT);
00105
00106
00107
00108 IRQ_LOCK(flags);
00109
00110 port_save= LCD_DATA_PORT & ~(LCD_DATA_MASK);
00111
00112
00113 LCD_DATA_PORT = ( ( ((data>>4) << LCD_FIRST_DATA_BIT) & LCD_DATA_MASK )
00114 | port_save );
00115
00116 e_toggle();
00117
00118
00119 LCD_DATA_PORT = ( ((data<<LCD_FIRST_DATA_BIT) & LCD_DATA_MASK)
00120 | port_save );
00121
00122
00123 IRQ_UNLOCK(flags);
00124
00125 e_toggle();
00126 }
00127
00128
00129
00130 static uint8_t lcd_read(uint8_t rs)
00131 {
00132 register uint8_t dataH, dataL;
00133
00134
00135 if (rs) sbi(LCD_RS_PORT, LCD_RS_BIT);
00136 else cbi(LCD_RS_PORT, LCD_RS_BIT);
00137 sbi(LCD_RW_PORT, LCD_RW_BIT);
00138
00139
00140 port_set_in();
00141
00142 sbi(LCD_E_PORT, LCD_E_BIT);
00143 e_delay();
00144
00145
00146 dataH = PIN(LCD_PORT) >> LCD_FIRST_DATA_BIT ;
00147
00148 cbi(LCD_E_PORT, LCD_E_BIT);
00149 e_delay();
00150
00151
00152 sbi(LCD_E_PORT, LCD_E_BIT);
00153 e_delay();
00154
00155 dataL = PIN(LCD_PORT) >> LCD_FIRST_DATA_BIT ;
00156
00157 cbi(LCD_E_PORT, LCD_E_BIT);
00158
00159 return ( (dataH<<4) | (dataL&0x0F) );
00160 }
00161
00162
00163
00164 void initial_8_bit_write(uint8_t value)
00165 {
00166 register uint8_t port_save;
00167 uint8_t flags;
00168
00169
00170 cbi(LCD_RW_PORT, LCD_RW_BIT);
00171
00172 cbi(LCD_RS_PORT, LCD_RS_BIT);
00173
00174
00175 IRQ_LOCK(flags);
00176
00177
00178 port_save = LCD_DATA_PORT & ~(LCD_DATA_MASK);
00179
00180
00181 LCD_DATA_PORT = ( ((value <<LCD_FIRST_DATA_BIT) & LCD_DATA_MASK)
00182 | port_save );
00183
00184 IRQ_UNLOCK(flags);
00185
00186 e_toggle();
00187 wait_ms(1);
00188 }
00189
00190
00191
00192
00193
00194
00195 static inline unsigned char lcd_waitbusy(void)
00196
00197 {
00198 register unsigned char c;
00199
00200 while ( (c=lcd_read(0)) & (1<<LCD_BUSY)) ;
00201
00202 return (c);
00203 }
00204
00205
00206
00207 void lcd_command(uint8_t cmd)
00208
00209 {
00210 lcd_waitbusy();
00211 lcd_write(cmd,0);
00212 }
00213
00214
00215
00216 static inline void lcd_newline(uint8_t pos)
00217
00218 {
00219 register uint8_t addressCounter;
00220
00221
00222 #if LCD_LINES==1
00223 addressCounter = 0;
00224 #endif
00225 #if LCD_LINES==2
00226 if ( pos < (LCD_START_LINE2) )
00227 addressCounter = LCD_START_LINE2;
00228 else
00229 addressCounter = LCD_START_LINE1;
00230 #endif
00231 #if LCD_LINES==4
00232 if ( pos < LCD_START_LINE3 )
00233 addressCounter = LCD_START_LINE2;
00234 else if ( (pos >= LCD_START_LINE2) && (pos < LCD_START_LINE4) )
00235 addressCounter = LCD_START_LINE3;
00236 else if ( (pos >= LCD_START_LINE3) && (pos < LCD_START_LINE2) )
00237 addressCounter = LCD_START_LINE4;
00238 else
00239 addressCounter = LCD_START_LINE1;
00240 #endif
00241
00242
00243 lcd_command((1<<LCD_DDRAM)+addressCounter);
00244
00245 }
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 void lcd_gotoxy(uint8_t x, uint8_t y)
00261
00262 {
00263 #if (LCD_LINES==1)
00264 lcd_command((1<<LCD_DDRAM)+LCD_START_LINE1+x);
00265 #endif
00266 #if (LCD_LINES==2)
00267 if ( y==0 )
00268 lcd_command((1<<LCD_DDRAM)+LCD_START_LINE1+x);
00269 else
00270 lcd_command((1<<LCD_DDRAM)+LCD_START_LINE2+x);
00271 #endif
00272 #if LCD_LINES==4
00273 if ( y==0 )
00274 lcd_command((1<<LCD_DDRAM)+LCD_START_LINE1+x);
00275 else if ( y==1)
00276 lcd_command((1<<LCD_DDRAM)+LCD_START_LINE2+x);
00277 else if ( y==2)
00278 lcd_command((1<<LCD_DDRAM)+LCD_START_LINE3+x);
00279 else
00280 lcd_command((1<<LCD_DDRAM)+LCD_START_LINE4+x);
00281 #endif
00282
00283 }
00284
00285
00286
00287
00288 void lcd_clrscr(void)
00289
00290 {
00291 lcd_command(1<<LCD_CLR);
00292 }
00293
00294
00295
00296 void lcd_home(void)
00297
00298 {
00299 lcd_command(1<<LCD_HOME);
00300 }
00301
00302
00303
00304 void lcd_putc(char c)
00305
00306 {
00307 register unsigned char pos;
00308
00309 pos = lcd_waitbusy();
00310
00311 #if LCD_DOUBLE_ADDRESSING == 1
00312 if(pos==8)
00313 {
00314 lcd_gotoxy(0,1);
00315 lcd_waitbusy();
00316 }
00317 #endif
00318
00319 if (c=='\n')
00320 lcd_newline(pos);
00321 else if (c== '\f')
00322 lcd_clrscr();
00323 else
00324 lcd_write(c, 1);
00325 }
00326
00327
00328 int lcd_dev_putc(char c, FILE* f)
00329 {
00330 lcd_putc(c);
00331 return c;
00332 }
00333
00334 void lcd_init(uint8_t dispAttr)
00335
00336
00337 {
00338
00339
00340
00341 port_set_out();
00342
00343 sbi(DDR(LCD_RW_PORT), LCD_RW_BIT);
00344 sbi(DDR(LCD_RS_PORT), LCD_RS_BIT);
00345 sbi(DDR(LCD_E_PORT), LCD_E_BIT);
00346
00347
00348 wait_ms(16);
00349
00350
00351
00352 initial_8_bit_write(LCD_FUNCTION_8BIT_1LINE>>4);
00353 initial_8_bit_write(LCD_FUNCTION_8BIT_1LINE>>4);
00354 initial_8_bit_write(LCD_FUNCTION_8BIT_1LINE>>4);
00355 initial_8_bit_write(LCD_FUNCTION_4BIT_1LINE>>4);
00356
00357
00358
00359 lcd_command(LCD_FUNCTION_DEFAULT);
00360 lcd_command(LCD_DISP_OFF);
00361 lcd_clrscr();
00362 lcd_command(LCD_MODE_DEFAULT);
00363 lcd_command(dispAttr);
00364
00365
00366
00367
00368 }