00001 /* 00002 graphic LCD backpack code 00003 00004 set up for the big LCD, 160x128 00005 00006 10/16/08, everything works. Pixel, line, circle, set x, set y, print_char, clear_screen. All good. 00007 00008 11/14/08, block erase, box, converted to ATMega168 00009 00010 11/19/08 added reverse mode 00011 00012 11/20/08 added backlight modulation 00013 00014 11/21/08 Added changable baud rate, also added EEPROM settings for 00015 baudrate, reverse mode, spash screen on/off, and backlight 00016 */ 00017 00018 00019 #include <avr/io.h> 00020 #include "rprintf.h" 00021 #include <math.h> 00022 #include <avr/interrupt.h> 00023 00024 #define FOSC 16000000// Clock Speed 00025 //#define BAUD 115200 00026 //#define MYUBRR FOSC/16/(BAUD/2)-1 00027 00028 #define WR 0 //PC0 00029 #define RD 1 //PC1 00030 #define CE 2 //PC2 00031 #define CD 3 //PC3 00032 #define HALT 4 //PC4 00033 #define RST 5 //PC5 00034 00035 #define BL_EN 2 //PB2 00036 00037 #define X_ENDPOINT 159 00038 #define Y_ENDPOINT 127 00039 00040 #define BPS 0 00041 #define BACKLIGHT 1 00042 #define SPLASH 2 00043 #define REV 3 00044 00045 00046 //Define functions 00047 //====================== 00048 void EEPROM_write(unsigned int uiAddress, unsigned char ucData); 00049 unsigned char EEPROM_read(unsigned int uiAddress); 00050 00051 void ioinit(void); //Initializes IO 00052 void delay_ms(uint16_t x); //General purpose delay 00053 void delay_us(uint8_t x); 00054 void USART_Init( unsigned int ubrr); 00055 void set_baud(char b); 00056 void put_char(char byte); 00057 int rnd(float number); 00058 00059 void set_data(char data);//sets the data port 00060 char read(char D_S);//reads data (D_S = 1) or status (D_S = anything else) 00061 void write(char D_C, char byte);//writes data or command 00062 void display_init(void);//initializes the display 00063 void set_backlight(unsigned char dutycycle); 00064 00065 00066 void clear_screen(void); 00067 00068 void print_char(char S_R, char txt); 00069 void del_char(char endpoint); 00070 void pixel(char S_R, char x, char y); 00071 void line(char S_R, char x1, char y1, char x2, char y2); 00072 void circle(char S_R, int x, int y, int r); 00073 void demo(void); 00074 00075 void erase_block(char x1, char y1, char x2, char y2); 00076 void box(char x1, char y1, char x2, char y2); 00077 00078 //====================== 00079 char x_offset = 0; 00080 char y_offset = 127; 00081 char reverse = 0; 00082 char baud_rate = 6;//115200 by default 00083 00084 unsigned char RX_array[416]; 00085 volatile unsigned short RX_in = 0; 00086 unsigned short RX_read = 0; 00087 unsigned char BL_dutycycle = 100; 00088 unsigned char splash_screen = 1; 00089 00090 static char logo[30] = {0x01,0xC0,0x03,0x80,0x03,0x80,0x01,0xD0, 00091 0x01,0xF8,0x0C,0xF8,0x18,0xF8,0x1F,0xF8, 00092 0x1F,0xF8,0x1F,0xF0,0x1F,0xE0,0x1F,0xC0, 00093 0x1C,0x00,0x18,0x00,0x10,0x00}; 00094 00095 //Jacked from Sinister 7 code 00096 static char text_array[475] = {0x00,0x00,0x00,0x00,0x00,/*space*/ 00097 0x00,0xF6,0xF6,0x00,0x00,/*!*/ 00098 0x00,0xE0,0x00,0xE0,0x00,/*"*/ 00099 0x28,0xFE,0x28,0xFE,0x28,/*#*/ 00100 0x00,0x64,0xD6,0x54,0x08,/*$*/ 00101 0xC2,0xCC,0x10,0x26,0xC6,/*%*/ 00102 0x4C,0xB2,0x92,0x6C,0x0A,/*&*/ 00103 0x00,0x00,0xE0,0x00,0x00,/*'*/ 00104 0x00,0x38,0x44,0x82,0x00,/*(*/ 00105 0x00,0x82,0x44,0x38,0x00,/*)*/ 00106 0x88,0x50,0xF8,0x50,0x88,/***/ 00107 0x08,0x08,0x3E,0x08,0x08,/*+*/ 00108 0x00,0x00,0x05,0x06,0x00,/*,*/ 00109 0x08,0x08,0x08,0x08,0x08,/*-*/ 00110 0x00,0x00,0x06,0x06,0x00,/*.*/ 00111 0x02,0x0C,0x10,0x60,0x80,/*/*/ 00112 0x7C,0x8A,0x92,0xA2,0x7C,/*0*/ 00113 0x00,0x42,0xFE,0x02,0x00,/*1*/ 00114 0x42,0x86,0x8A,0x92,0x62,/*2*/ 00115 0x44,0x82,0x92,0x92,0x6C,/*3*/ 00116 0x10,0x30,0x50,0xFE,0x10,/*4*/ 00117 0xE4,0xA2,0xA2,0xA2,0x9C,/*5*/ 00118 0x3C,0x52,0x92,0x92,0x0C,/*6*/ 00119 0x80,0x86,0x98,0xE0,0x80,/*7*/ 00120 0x6C,0x92,0x92,0x92,0x6C,/*8*/ 00121 0x60,0x92,0x92,0x94,0x78,/*9*/ 00122 0x00,0x00,0x36,0x36,0x00,/*:*/ 00123 0x00,0x00,0x35,0x36,0x00,/*;*/ 00124 0x10,0x28,0x44,0x82,0x00,/*<*/ 00125 0x28,0x28,0x28,0x28,0x28,/*=*/ 00126 0x00,0x82,0x44,0x28,0x10,/*>*/ 00127 0x40,0x80,0x8A,0x90,0x60,/*?*/ 00128 0x7C,0x82,0xBA,0xBA,0x62,/*@*/ 00129 0x3E,0x48,0x88,0x48,0x3E,/*A*/ 00130 0xFE,0x92,0x92,0x92,0x6C,/*B*/ 00131 0x7C,0x82,0x82,0x82,0x44,/*C*/ 00132 0xFE,0x82,0x82,0x82,0x7C,/*D*/ 00133 0xFE,0x92,0x92,0x92,0x82,/*E*/ 00134 0xFE,0x90,0x90,0x90,0x80,/*F*/ 00135 0x7C,0x82,0x82,0x8A,0x4E,/*G*/ 00136 0xFE,0x10,0x10,0x10,0xFE,/*H*/ 00137 0x82,0x82,0xFE,0x82,0x82,/*I*/ 00138 0x84,0x82,0xFC,0x80,0x80,/*J*/ 00139 0xFE,0x10,0x28,0x44,0x82,/*K*/ 00140 0xFE,0x02,0x02,0x02,0x02,/*L*/ 00141 0xFE,0x40,0x20,0x40,0xFE,/*M*/ 00142 0xFE,0x60,0x10,0x0C,0xFE,/*N*/ 00143 0x7C,0x82,0x82,0x82,0x7C,/*O*/ 00144 0xFE,0x90,0x90,0x90,0x60,/*P*/ 00145 0x7C,0x82,0x82,0x86,0x7E,/*Q*/ 00146 0xFE,0x90,0x98,0x94,0x62,/*R*/ 00147 0x64,0x92,0x92,0x92,0x4C,/*S*/ 00148 0x80,0x80,0xFE,0x80,0x80,/*T*/ 00149 0xFC,0x02,0x02,0x02,0xFC,/*U*/ 00150 0xF8,0x04,0x02,0x04,0xF8,/*V*/ 00151 0xFC,0x02,0x0C,0x02,0xFC,/*W*/ 00152 0xC6,0x28,0x10,0x28,0xC6,/*X*/ 00153 0xC0,0x20,0x1E,0x20,0xC0,/*Y*/ 00154 0x86,0x8A,0x92,0xA2,0xC2,/*Z*/ 00155 0x00,0x00,0xFE,0x82,0x00,/*[*/ 00156 0x80,0x60,0x10,0x0C,0x02,/*this should be / */ 00157 0x80,0x60,0x10,0x0C,0x02,/*]*/ 00158 0x20,0x40,0x80,0x40,0x20,/*^*/ 00159 0x01,0x01,0x01,0x01,0x01,/*_*/ 00160 0x80,0x40,0x20,0x00,0x00,/*`*/ 00161 0x04,0x2A,0x2A,0x2A,0x1E,/*a*/ 00162 0xFE,0x12,0x22,0x22,0x1C,/*b*/ 00163 0x1C,0x22,0x22,0x22,0x14,/*c*/ 00164 0x1C,0x22,0x22,0x12,0xFE,/*d*/ 00165 0x1C,0x2A,0x2A,0x2A,0x18,/*e*/ 00166 0x10,0x7E,0x90,0x80,0x40,/*f*/ 00167 0x18,0x25,0x25,0x25,0x1E,/*g*/ 00168 0xFE,0x10,0x10,0x10,0x0E,/*h*/ 00169 0x00,0x12,0x5E,0x02,0x00,/*i*/ 00170 0x02,0x01,0x01,0x11,0x5E,/*j*/ 00171 0xFE,0x08,0x08,0x14,0x22,/*k*/ 00172 0x00,0x82,0xFE,0x02,0x00,/*l*/ 00173 0x3E,0x20,0x1C,0x20,0x1E,/*m*/ 00174 0x3E,0x20,0x20,0x20,0x1E,/*n*/ 00175 0x1C,0x22,0x22,0x22,0x1C,/*o*/ 00176 0x3F,0x24,0x24,0x24,0x18,/*p*/ 00177 0x18,0x24,0x24,0x3F,0x01,/*q*/ 00178 0x3E,0x10,0x20,0x20,0x10,/*r*/ 00179 0x12,0x2A,0x2A,0x2A,0x04,/*s*/ 00180 0x00,0x10,0x3C,0x12,0x04,/*t*/ 00181 0x3C,0x02,0x02,0x02,0x3E,/*u*/ 00182 0x30,0x0C,0x02,0x0C,0x30,/*v*/ 00183 0x38,0x06,0x18,0x06,0x38,/*w*/ 00184 0x22,0x14,0x08,0x14,0x22,/*x*/ 00185 0x38,0x05,0x05,0x05,0x3E,/*y*/ 00186 0x22,0x26,0x2A,0x32,0x22,/*z*/ 00187 0x00,0x10,0x6C,0x82,0x82,/*{*/ 00188 //0x00,0x00,0xFF,0x00,0x00,/*|*/ 00189 0x04,0x02,0xFF,0x02,0x04,/*|, arrow*/ 00190 0x82,0x82,0x6C,0x10,0x00,/*}*/ 00191 0x08,0x10,0x18,0x08,0x10};/*~*/ 00192 00193 00194 00195 ISR (SIG_USART_RECV)//USART Receive Interrupt 00196 { 00197 cli();//Disable Interrupts 00198 RX_array[RX_in] = UDR0; 00199 00200 RX_in++; 00201 00202 if (RX_in >= 416) RX_in = 0; 00203 00204 sei();//Enable Interrupts 00205 00206 } 00207 00208 ISR (TIMER0_COMPA_vect) 00209 { 00210 unsigned char y; 00211 00212 //cli();//Disable Interrupts 00213 00214 TCCR0B = 0; 00215 TIMSK0 = 0;//disable timer ints 00216 00217 TIFR0 = 0x02;//clear the interrupt 00218 TCNT0 = 0; 00219 00220 //PORTB |= (1<<BL_EN);//off 00221 00222 00223 y = PINB; 00224 if (y & (1<<BL_EN))//on 00225 { 00226 PORTB &= (~(1<<BL_EN)); 00227 OCR0A = BL_dutycycle; 00228 } 00229 00230 else//off 00231 { 00232 PORTB |= (1<<BL_EN); 00233 OCR0A = 100 - BL_dutycycle; 00234 } 00235 00236 //PORTB |= (1<<BL_EN); 00237 00238 TIMSK0 = 0x02;//enable OCR0A 00239 TCCR0B = 0x02; 00240 //sei();//Enable Interrupts 00241 } 00242 00243 00244 00245 00246 int main (void) 00247 { 00248 char x, y, temp, q; 00249 00250 ioinit(); //Setup IO pins and defaults 00251 //USART_Init( MYUBRR); 00252 set_baud(6);//115200 00253 rprintf_devopen(put_char); // init rrprintf 00254 00255 //check for existing preset values============================================================== 00256 temp = EEPROM_read((unsigned int)BPS); 00257 00258 if ((temp < 1) | (temp > 6))//BPS will only be 1-6 00259 { 00260 cli();//Disable Interrupts 00261 00262 EEPROM_write((unsigned int) BPS, 6); 00263 EEPROM_write((unsigned int) BACKLIGHT, 100); 00264 EEPROM_write((unsigned int) SPLASH, 1); 00265 EEPROM_write((unsigned int) REV, 0); 00266 00267 sei();//Enable Interrupts 00268 00269 BL_dutycycle = 100; 00270 baud_rate = 6; 00271 splash_screen = 1; 00272 reverse = 0; 00273 } 00274 00275 else 00276 { 00277 baud_rate = temp; 00278 BL_dutycycle = EEPROM_read((unsigned int)BACKLIGHT); 00279 splash_screen = EEPROM_read((unsigned int)SPLASH); 00280 reverse = EEPROM_read((unsigned int)REV); 00281 } 00282 00283 //reset the display 00284 delay_ms(1); 00285 PORTC |= (1<<RST); 00286 00287 //initialize the display 00288 display_init(); 00289 00290 set_backlight(BL_dutycycle); 00291 00292 clear_screen(); 00293 00294 //Backlight on 00295 PORTB &= (~(1<<BL_EN)); 00296 00297 //Logo========================================================== 00298 if (splash_screen == 1) 00299 { 00300 y = 72; 00301 00302 for (q = 0; q < 30; q++) 00303 { 00304 temp = logo[q]; 00305 for (x = 72; x < 80; x++) 00306 { 00307 if (temp & 0x80) pixel(1,x,y); 00308 00309 temp <<= 1; 00310 } 00311 00312 q++; 00313 00314 temp = logo[q]; 00315 for (x = 80; x < 88; x++) 00316 { 00317 if (temp & 0x80) pixel(1,x,y); 00318 00319 temp <<= 1; 00320 } 00321 y--; 00322 00323 } 00324 } 00325 00326 RX_in = 0; 00327 00328 delay_ms(1000); 00329 clear_screen(); 00330 00331 if (RX_in > 0)//revert to 115200 00332 { 00333 print_char(1,'1'); 00334 print_char(1,'1'); 00335 print_char(1,'5'); 00336 print_char(1,'2'); 00337 print_char(1,'0'); 00338 print_char(1,'0'); 00339 00340 baud_rate = 6; 00341 set_baud(6);//115200 00342 00343 cli(); 00344 00345 EEPROM_write((unsigned int) BPS, 6); 00346 00347 sei();//Enable Interrupts 00348 } 00349 00350 else (set_baud(baud_rate)); 00351 00352 delay_ms(1000); 00353 clear_screen(); 00354 00355 //main loop=================================================== 00356 while(1) 00357 { 00358 if(RX_in != RX_read) 00359 { 00360 x = RX_array[RX_read]; 00361 RX_read++; 00362 if(RX_read >= 416) RX_read = 0; 00363 00364 //Backspace=================================================== 00365 if(x == 8) del_char(0); 00366 00367 //Special commands 00368 else if (x == 124) 00369 { 00370 //make sure the next byte is there 00371 while(RX_in == RX_read); 00372 00373 //0, clear screen====================================================== 00374 if(RX_array[RX_read] == 0)//^@ 00375 { 00376 clear_screen(); 00377 RX_read++; 00378 if(RX_read >= 416) RX_read = 0; 00379 } 00380 00381 //demo mode 00382 else if(RX_array[RX_read] == 4)//^d 00383 { 00384 RX_in = 0, RX_read = 0; 00385 demo(); 00386 clear_screen(); 00387 RX_in = 0; 00388 } 00389 00390 //reverse mode 00391 else if(RX_array[RX_read] == 18)//^r 00392 { 00393 reverse ^= 1; 00394 clear_screen(); 00395 RX_read++; 00396 if(RX_read >= 416) RX_read = 0; 00397 00398 cli(); 00399 EEPROM_write((unsigned int) REV, reverse); 00400 sei(); 00401 } 00402 00403 //toggle spasl screen 00404 else if(RX_array[RX_read] == 19)//^s 00405 { 00406 splash_screen ^= 1; 00407 //clear_screen(); 00408 RX_read++; 00409 if(RX_read >= 416) RX_read = 0; 00410 00411 cli(); 00412 EEPROM_write((unsigned int) SPLASH, splash_screen); 00413 sei(); 00414 } 00415 00416 else 00417 { 00418 //set backlight (0 to 100)========================================================= 00419 if(RX_array[RX_read] == 2)//^b 00420 { 00421 RX_read++; 00422 if(RX_read >= 416) RX_read = 0; 00423 while(RX_in == RX_read);//wait for byte 00424 BL_dutycycle = RX_array[RX_read]; 00425 00426 RX_read++; 00427 if(RX_read >= 416) RX_read = 0; 00428 00429 set_backlight(BL_dutycycle); 00430 00431 cli(); 00432 EEPROM_write((unsigned int) BACKLIGHT, BL_dutycycle); 00433 sei(); 00434 00435 /* 00436 if(BL_dutycycle >= 100) 00437 { 00438 TCCR0B = 0; 00439 TIMSK0 = 0;//disable timer ints 00440 00441 //Backlight on 00442 PORTB &= (~(1<<BL_EN)); 00443 } 00444 else if (BL_dutycycle == 0) 00445 { 00446 TCCR0B = 0; 00447 TIMSK0 = 0;//disable timer ints 00448 00449 //Backlight off 00450 PORTB |= (1<<BL_EN); 00451 } 00452 00453 else 00454 { 00455 TCCR0B = 0; 00456 TIMSK0 = 0;//disable timer ints 00457 00458 OCR0A = 100 - BL_dutycycle; 00459 00460 TIMSK0 = 0x02;//enable match on A 00461 TCCR0B = 0x02; 00462 00463 SREG |= 0x80; 00464 00465 } 00466 */ 00467 00468 } 00469 00470 00471 //change baud rate========================================================= 00472 if(RX_array[RX_read] == 7)//^g 00473 { 00474 RX_read++; 00475 if(RX_read >= 416) RX_read = 0; 00476 while(RX_in == RX_read);//wait for byte 00477 //if (RX_array[RX_read] == '1') USART_Init( 1000000/2400-1);//4800 00478 //else if (RX_array[RX_read] == '2') USART_Init( 1000000/4800-1);//9600 00479 //else if (RX_array[RX_read] == '3') USART_Init( 1000000/9600-1);//19200 00480 //else if (RX_array[RX_read] == '4') USART_Init( 1000000/19200-1);//38400 00481 //else if (RX_array[RX_read] == '5') USART_Init( 1000000/28800-1);//57600 00482 //else if (RX_array[RX_read] == '6') USART_Init( 1000000/57600-1);//115200 00483 00484 if ((RX_array[RX_read] > '0') * (RX_array[RX_read] < '7')) baud_rate = (RX_array[RX_read]) - 48; 00485 00486 set_baud(baud_rate); 00487 00488 cli(); 00489 EEPROM_write((unsigned int) BPS, baud_rate); 00490 sei(); 00491 00492 RX_read++; 00493 if(RX_read >= 416) RX_read = 0; 00494 00495 } 00496 00497 00498 //set x or y========================================================= 00499 if((RX_array[RX_read] == 24) | (RX_array[RX_read] == 25))//^x or ^y 00500 { 00501 RX_read++; 00502 if(RX_read >= 416) RX_read = 0; 00503 while(RX_in == RX_read);//wait for byte 00504 if (RX_array[RX_read-1] == 24) x_offset = RX_array[RX_read]; 00505 else if (RX_array[RX_read-1] == 25) y_offset = RX_array[RX_read]; 00506 00507 RX_read++; 00508 if(RX_read >= 416) RX_read = 0; 00509 00510 if (x_offset > 159) x_offset = 159; 00511 if (y_offset > 127) y_offset = 127; 00512 00513 } 00514 00515 //set pixel========================================================= 00516 if (RX_array[RX_read] == 16)//^p 00517 { 00518 //need 3 bytes 00519 for (y = 0; y < 3; y++) 00520 { 00521 RX_read++; 00522 if(RX_read >= 416) RX_read = 0; 00523 while(RX_in == RX_read);//wait for byte 00524 } 00525 00526 pixel(RX_array[RX_read], RX_array[RX_read-2], RX_array[RX_read-1]); 00527 00528 RX_read++; 00529 if(RX_read >= 416) RX_read = 0; 00530 00531 } 00532 00533 00534 //<ctrl>c, circle====================================================== 00535 if(RX_array[RX_read] == 3)//^c 00536 { 00537 //need 4 bytes 00538 for (y = 0; y < 4; y++) 00539 { 00540 RX_read++; 00541 if(RX_read >= 416) RX_read = 0; 00542 while(RX_in == RX_read);//wait for byte 00543 } 00544 00545 circle(RX_array[RX_read], RX_array[RX_read-3], RX_array[RX_read-2], RX_array[RX_read-1]); 00546 00547 RX_read++; 00548 if(RX_read >= 416) RX_read = 0; 00549 } 00550 00551 00552 //<ctrl>e, erase block====================================================== 00553 if(RX_array[RX_read] == 5)//^e 00554 { 00555 //need 4 bytes 00556 for (y = 0; y < 4; y++) 00557 { 00558 RX_read++; 00559 if(RX_read >= 416) RX_read = 0; 00560 while(RX_in == RX_read);//wait for byte 00561 } 00562 00563 erase_block(RX_array[RX_read-3], RX_array[RX_read-2], RX_array[RX_read-1], RX_array[RX_read]); 00564 00565 RX_read++; 00566 if(RX_read >= 416) RX_read = 0; 00567 } 00568 00569 00570 //box====================================================== 00571 if(RX_array[RX_read] == 15)//^o 00572 { 00573 //need 4 bytes 00574 for (y = 0; y < 4; y++) 00575 { 00576 RX_read++; 00577 if(RX_read >= 416) RX_read = 0; 00578 while(RX_in == RX_read);//wait for byte 00579 } 00580 00581 box(RX_array[RX_read-3], RX_array[RX_read-2], RX_array[RX_read-1], RX_array[RX_read]); 00582 00583 RX_read++; 00584 if(RX_read >= 416) RX_read = 0; 00585 } 00586 00587 00588 //line======================================================== 00589 else if (RX_array[RX_read] == 12)//^l 00590 { 00591 //need 5 bytes 00592 for (y = 0; y < 5; y++) 00593 { 00594 RX_read++; 00595 if(RX_read >= 416) RX_read = 0; 00596 while(RX_in == RX_read);//wait for byte 00597 } 00598 00599 line(RX_array[RX_read], RX_array[RX_read-4], RX_array[RX_read-3], RX_array[RX_read-2], RX_array[RX_read+-1]); 00600 RX_read++; 00601 if(RX_read >= 416) RX_read = 0; 00602 } 00603 00604 00605 } 00606 00607 } 00608 00609 //print character to the screen=============================================== 00610 else 00611 { 00612 del_char(1); 00613 print_char(1, x); 00614 } 00615 } 00616 00617 } 00618 00619 00620 00621 } 00622 00623 void ioinit (void) 00624 { 00625 00626 //1 = output, 0 = input 00627 00628 /* 00629 WR //PC0 00630 RD //PC1 00631 CE //PC2 00632 C_D //PC3 00633 HALT //PC4 00634 RST //PC5 00635 */ 00636 00637 PORTB |= (1<<BL_EN);//Backlight off 00638 DDRB |= (1<<BL_EN);//set PB2 as output 00639 00640 PORTC = ((1<<WR) | (1<<RD) | (1<<CE) | (1<<CD) | (1<<HALT)); 00641 PORTC &= (~(1<<RST));//set the reset line low at power up 00642 DDRC = ((1<<WR) | (1<<RD) | (1<<CE) | (1<<CD) | (1<<HALT) | (1<<RST)); 00643 00644 //Init timer 2 00645 TCCR2B = (1<<CS21); //Set Prescaler to 8. CS21=1 00646 00647 //Set up Timer 0 00648 TCCR0A = 0x02;//CTC mode 00649 //TCCR0B = 0x02; 00650 TIMSK0 = 0x02;//enable OCR0A 00651 //OCR0B = 255 - BL_dutycycle; 00652 00653 //OCR0A = 255 - (100 - BL_dutycycle); 00654 OCR0A = BL_dutycycle; 00655 00656 //SREG |= 0x80; 00657 } 00658 00659 //General short delays 00660 void delay_ms(uint16_t x) 00661 { 00662 for (; x > 0 ; x--) 00663 { 00664 delay_us(250); 00665 delay_us(250); 00666 delay_us(250); 00667 delay_us(250); 00668 } 00669 00670 } 00671 00672 //General short delays 00673 void delay_us(uint8_t x) 00674 { 00675 char temp; 00676 00677 if (x == 0) temp = 1; 00678 else temp = x; 00679 00680 TIFR2 |= 0x01;//Clear any interrupt flags on Timer2 00681 00682 TCNT2 = 256 - temp; //256 - 125 = 131 : Preload timer 2 for x clicks. Should be 1us per click 00683 00684 while(!(TIFR2 & 0x01)); 00685 00686 if (x == 0) return;//this is for display timing 00687 00688 //The prescaler doesn't allow for a setting of 16, just 8 or 32. So, we do this twice. 00689 TIFR2 |= 0x01; 00690 00691 TCNT2 = 256 - temp; //256 - 125 = 131 : Preload timer 2 for x clicks. Should be 1us per click 00692 00693 while(!(TIFR2 & 0x01)); 00694 00695 } 00696 00697 void USART_Init( unsigned int ubrr) 00698 { 00699 // Set baud rate 00700 UBRR0H = (unsigned char)(ubrr>>8); 00701 UBRR0L = (unsigned char)ubrr; 00702 00703 // Enable receiver and transmitter 00704 UCSR0A = (1<<U2X0); 00705 UCSR0B = (1<<RXCIE0)|(1<<RXEN0)|(1<<TXEN0); //Enable Interrupts on receive character 00706 00707 UCSR0C = (1<<UCSZ00)|(1<<UCSZ01); 00708 sei(); 00709 } 00710 00711 void put_char(char byte) 00712 { 00713 /* Wait for empty transmit buffer */ 00714 while ( !( UCSR0A & (1<<UDRE0)) ); 00715 /* Put data into buffer, sends the data */ 00716 UDR0 = byte; 00717 } 00718 00719 00720 //set data port 00721 void set_data(char data) 00722 { 00723 //PORTB 00724 //DB0 = PB0 00725 //DB1 = PB1 00726 00727 PORTB &= 0xFC; 00728 00729 //PORTD 00730 //DB2 = PD2 00731 //DB3 = PD3 00732 //DB4 = PD4 00733 //DB5 = PD5 00734 //DB6 = PD6 00735 //DB7 = PD7 00736 00737 PORTD &= 0x03; 00738 00739 PORTB |= (data & 0x03); 00740 PORTD |= (data & 0xFC); 00741 00742 } 00743 00744 00745 //Reads data or status 00746 //for data D_S = 1, for status D_S = 0 00747 //returns the value of the data bus 00748 char read(char D_S) 00749 { 00750 char data1 = 0, data2 = 0; 00751 00752 DDRB &= 0xFC;//PB0 and PB1 inputs 00753 DDRD &= 0x02;//everything but PD1 as input 00754 00755 PORTC &= ~((1 << RD) | (1 << CE));//CD high for status 00756 if (D_S == 1) PORTC &= ~(1 << CD);//CD down for data 00757 00758 delay_us(0); 00759 00760 data1 = PINB; 00761 data1 &= 0x03; 00762 00763 data2 = PIND; 00764 data2 &= 0xFC; 00765 00766 data1 |= data2; 00767 00768 PORTC |= ((1 << CD) | (1 << RD) | (1 << CE));//all up 00769 00770 delay_us(0); 00771 00772 return data1; 00773 00774 } 00775 00776 00777 //Writes data (D_C = 1) or command (D_C = anything else) 00778 void write(char D_C, char byte) 00779 { 00780 DDRB |= 0x03; //PB0 and PB1 are outs 00781 DDRD |= 0xFC; //PD2-PD7 are also outs. Ports B and D are the data bus 00782 00783 set_data(byte); 00784 00785 if (D_C == 1) PORTC &= ~((1 << WR) | (1 << CE) | (1 << CD));//down 00786 else PORTC &= ~((1 << WR) | (1 << CE));//down 00787 00788 delay_us(0); 00789 PORTC |= ((1 << CD) | (1 << WR) | (1 << CE));//all up 00790 delay_us(0); 00791 DDRB &= 0xFC;//PB0 and PB1 inputs 00792 DDRD &= 0x02;//everything but PD1 as input 00793 00794 delay_us(0); 00795 00796 } 00797 00798 00799 00800 void display_init(void) 00801 { 00802 //set graphics home address to 0 00803 while(!(read(0) & 3));//read status 00804 write(1, 0); 00805 while(!(read(0) & 3));//read status 00806 write(1, 0); 00807 while(!(read(0) & 3));//read status 00808 write(0, 0x42); 00809 00810 //set graphics area 00811 while(!(read(0) & 3));//read status 00812 write(1, 20);//20 bytes, 160/8 00813 while(!(read(0) & 3));//read status 00814 write(1, 0); 00815 while(!(read(0) & 3));//read status 00816 write(0, 0x43); 00817 00818 //set mode 00819 while(!(read(0) & 3));//read status 00820 write(0, 0x80);//Or, with internal character generator 00821 00822 //set display mode 00823 while(!(read(0) & 3));//read status 00824 write(0, 0x98);//Graphics on 00825 00826 } 00827 00828 00829 00830 00831 00832 void clear_screen(void) 00833 { 00834 int x; 00835 00836 //set address pointer to 0, start of graphics 00837 while(!(read(0) & 3));//read status 00838 write(1, 0); 00839 while(!(read(0) & 3));//read status 00840 write(1, 0); 00841 while(!(read(0) & 3));//read status 00842 write(0, 0x24); 00843 00844 for(x = 0; x < 0xA00; x++) 00845 { 00846 while(!(read(0) & 3));//read status 00847 if (reverse == 1) write(1,0xFF); 00848 else if (reverse == 0) write(1, 0); 00849 while(!(read(0) & 3));//read status 00850 write(0, 0xC0); 00851 } 00852 00853 x_offset = 0; 00854 y_offset = 127; 00855 } 00856 00857 00858 //sets (S_R = 1) or resets (S_R = 0) at x, y 00859 void pixel(char S_R, char x, char y) 00860 { 00861 short address = 0; 00862 char byte = 0; 00863 00864 if (reverse == 1) S_R ^= 1; 00865 00866 //don't try to print something outside of our range 00867 if (x > 159) return; 00868 if (y > 127) return; 00869 00870 address = ((127-y) * 20) + (x / 8); 00871 00872 //set address pointer 00873 while(!(read(0) & 3));//read status 00874 byte = (char)(address & 0xFF); 00875 00876 write(1, byte);//20 bytes, 160/8 00877 00878 while(!(read(0) & 3));//read status 00879 byte = (char)((address & 0xFF00) >> 8); 00880 00881 write(1, byte); 00882 00883 while(!(read(0) & 3));//read status 00884 write(0, 0x24); 00885 00886 byte = ~(x % 8); 00887 00888 byte |= 0xF8; 00889 if (S_R == 0) byte &= 0xF7; 00890 00891 //if (reverse == 1) byte = ~(byte); 00892 00893 //set-reset bit 00894 while(!(read(0) & 3));//read status 00895 write(0, byte); 00896 00897 } 00898 00899 00900 //draws (S_R = 1) or erases (S_R = 0) a line from x1, y1 to x2, y2 00901 void line(char S_R, char x1, char y1, char x2, char y2) 00902 { 00903 float m, q; 00904 int x_dif, y_dif; 00905 int a, b, c; 00906 00907 if ((x1 > X_ENDPOINT) | (x2 > X_ENDPOINT)) return; 00908 if ((y1 > Y_ENDPOINT) | (y2 > Y_ENDPOINT)) return; 00909 00910 x_dif = x2 - x1; 00911 y_dif = y2 - y1; 00912 if (y_dif < 0) y_dif *= (-1); 00913 00914 00915 m = (float)(y2 - y1) / (float)(x2 - x1); 00916 00917 b = y1-(m*x1); 00918 00919 if(x_dif >= y_dif) 00920 { 00921 for (a = x1; a <= x2; a++) 00922 { 00923 pixel(S_R, (char)a, (char)((m*a)+b)); 00924 00925 } 00926 } 00927 00928 else 00929 { 00930 if (y2 > y1) 00931 { 00932 for (a = y1; a <= y2; a++) 00933 { 00934 if (x_dif == 0) c = x1; 00935 else 00936 { 00937 q = (((float)(a-b))/m); 00938 c = rnd(q); 00939 } 00940 00941 pixel(S_R, (char)c, (char)a); 00942 00943 } 00944 } 00945 00946 else if (y1 > y2) 00947 { 00948 for (a = y1; a >= y2; a--) 00949 { 00950 if (x_dif == 0) c = x1; 00951 else 00952 { 00953 q = (((float)(a-b))/m); 00954 c = rnd(q); 00955 } 00956 00957 pixel(S_R, (char)c, (char)a); 00958 00959 } 00960 } 00961 } 00962 00963 } 00964 00965 00966 //draws (S_R = 1) or erases (S_R = 0) a circle ar x, y with radius r 00967 void circle(char S_R, int x, int y, int r) 00968 { 00969 int x1 = 0, x2 = 0; 00970 int x_line = 0, y_line = 0; 00971 int temp_y; 00972 int temp_x; 00973 00974 x1 = x - r; 00975 x2 = x + r; 00976 00977 for (temp_x = x1; temp_x <= x2; temp_x++) 00978 { 00979 temp_y = ((sqrt((r*r) - ((temp_x - x)*(temp_x - x)))) - y); 00980 00981 temp_y *= (-1); 00982 00983 if (temp_x > x1) 00984 { 00985 line(S_R, (char)x_line, (char)y_line, (char)temp_x, (char)temp_y); 00986 line(S_R, (char)x_line, (char)(2*y - y_line), (char)temp_x, (char)(2*y - temp_y)); 00987 } 00988 00989 else 00990 { 00991 pixel(S_R, (char)temp_x, (char)temp_y); 00992 pixel(S_R, (char)temp_x, (char)(y + y - temp_y)); 00993 } 00994 00995 x_line = temp_x; 00996 y_line = temp_y; 00997 00998 } 00999 01000 01001 } 01002 01003 //rounds a floar to the nearest int 01004 int rnd(float number) 01005 { 01006 int a; 01007 float b; 01008 01009 a = number / 1; 01010 b = number - a; 01011 01012 if (b >= 0.5) a++; 01013 01014 return a; 01015 01016 } 01017 01018 //prints (S_R = 1) or erases (S_R = 0) a character to the screen 01019 //at x_offset, y_offset. Automatically augments offsets for next write 01020 void print_char(char S_R, char txt) 01021 { 01022 short text_array_offset = (txt - 32)*5, j; 01023 char x, k; 01024 01025 01026 for (j = text_array_offset; j < text_array_offset+5; j++) 01027 { 01028 k = text_array[j]; 01029 01030 for (x = 0; x < 8; x++) 01031 { 01032 if(k & 0x80) pixel(S_R, x_offset, y_offset - x); 01033 k <<= 1; 01034 } 01035 01036 x_offset++; 01037 01038 } 01039 01040 x_offset++; 01041 01042 if ((x_offset + 6) > 160) 01043 { 01044 x_offset = 0; 01045 if (y_offset <= 7) 01046 { 01047 y_offset = 127; 01048 //clear_screen(); 01049 } 01050 else y_offset -= 8; 01051 01052 } 01053 01054 } 01055 01056 01057 //demonstration code 01058 void demo(void) 01059 { 01060 char x, y, temp; 01061 int q = 0; 01062 01063 while(1) 01064 { 01065 x_offset = 0; 01066 y_offset = 127; 01067 01068 for (y = 0; y < 5; y++) 01069 { 01070 for (x = 32; x < 123; x++) 01071 { 01072 del_char(1); 01073 print_char(1, x); 01074 if (RX_in > 0) return; 01075 } 01076 } 01077 01078 clear_screen(); 01079 01080 for (y = 0; y < 5; y++) 01081 { 01082 for (x = 32; x < 123; x++) 01083 { 01084 //x_offset += 4; 01085 y_offset -= 6; 01086 if (y_offset <= 8) y_offset = 127; 01087 del_char(1); 01088 print_char(1, x); 01089 if (RX_in > 0) return; 01090 } 01091 } 01092 01093 clear_screen(); 01094 01095 //draw circles================================ 01096 for (x = 5; x < 120; x += 5) 01097 { 01098 circle(1,80,64,x); 01099 if (RX_in > 0) return; 01100 } 01101 01102 01103 //draw lines=================================== 01104 y = Y_ENDPOINT; 01105 01106 for (x = 0; x < X_ENDPOINT; x += 20) 01107 { 01108 line(1,0,y,x,0); 01109 y -= 16; 01110 } 01111 01112 y = 0; 01113 01114 for (x = 0; x < X_ENDPOINT; x += 20) 01115 { 01116 line(1,x,0,X_ENDPOINT,y); 01117 y += 16; 01118 } 01119 01120 y = Y_ENDPOINT; 01121 01122 for (x = 0; x < X_ENDPOINT; x += 20) 01123 { 01124 line(1,x,Y_ENDPOINT,X_ENDPOINT,y); 01125 y -= 16; 01126 } 01127 01128 y = 0; 01129 01130 for (x = 0; x < X_ENDPOINT; x += 20) 01131 { 01132 line(1,0,y,x,Y_ENDPOINT); 01133 y += 16; 01134 } 01135 01136 01137 //erase circles================================ 01138 for (x = 5; x < 120; x += 5) 01139 { 01140 circle(0,80,64,x); 01141 if (RX_in > 0) return; 01142 } 01143 01144 //erase lines=================================== 01145 y = Y_ENDPOINT; 01146 01147 for (x = 0; x < X_ENDPOINT; x += 20) 01148 { 01149 line(0,0,y,x,0); 01150 y -= 16; 01151 } 01152 01153 y = 0; 01154 01155 for (x = 0; x < X_ENDPOINT; x += 20) 01156 { 01157 line(0,x,0,X_ENDPOINT,y); 01158 y += 16; 01159 } 01160 01161 y = Y_ENDPOINT; 01162 01163 for (x = 0; x < X_ENDPOINT; x += 20) 01164 { 01165 line(0,x,Y_ENDPOINT,X_ENDPOINT,y); 01166 y -= 16; 01167 } 01168 01169 y = 0; 01170 01171 for (x = 0; x < X_ENDPOINT; x += 20) 01172 { 01173 line(0,0,y,x,Y_ENDPOINT); 01174 y += 16; 01175 } 01176 01177 if (RX_in > 0) return; 01178 01179 //Boxes================================================================= 01180 y = 111; 01181 for (x = 0; x <= 140; x += 10) 01182 { 01183 erase_block(x, y, x+16, y+16); 01184 box(x, y, x+16, y+16); 01185 y -= 7; 01186 } 01187 01188 01189 //x = 110; 01190 y = 28; 01191 //Logo================================================================= 01192 q = 0; 01193 while(q < 30) 01194 { 01195 temp = logo[q]; 01196 for (x = 140; x < 148; x++) 01197 { 01198 if (temp & 0x80) pixel(1,x,y); 01199 01200 temp <<= 1; 01201 } 01202 q++; 01203 temp = logo[q]; 01204 for (x = 148; x < 156; x++) 01205 { 01206 if (temp & 0x80) pixel(1,x,y); 01207 01208 temp <<= 1; 01209 } 01210 y--; 01211 q++; 01212 } 01213 01214 delay_ms(1000); 01215 reverse ^= 1; 01216 clear_screen(); 01217 01218 } 01219 01220 01221 } 01222 01223 //Deletes a full character space. Endpoint == 0 for a backwards delete, 01224 //Endpoint != 0 to erase spot for a new character write 01225 void del_char(char endpoint) 01226 { 01227 char a, y; 01228 01229 if (endpoint == 0)//Backwards delete 01230 { 01231 if (x_offset <= 5) 01232 { 01233 x_offset += 120; 01234 y_offset += 8; 01235 01236 if (y_offset > 63) y_offset -= 64; 01237 } 01238 01239 else x_offset -= 6; 01240 } 01241 01242 for (a = x_offset; a < x_offset + 6; a++) 01243 { 01244 for (y = y_offset - 7; y <= y_offset; y++) 01245 { 01246 pixel(0, a, y); 01247 01248 } 01249 } 01250 01251 } 01252 01253 01254 //erases a block of the screen. Block is decribed 01255 //by a diagonal line from x, y1 to x2, y2 01256 void erase_block(char x1, char y1, char x2, char y2) 01257 { 01258 static char temp_x = 0, temp_y = 0; 01259 01260 for (temp_y = y2; temp_y >= y1; temp_y--) 01261 { 01262 for (temp_x = x1; temp_x <= x2; temp_x++) 01263 { 01264 pixel(0, temp_x, temp_y); 01265 01266 } 01267 } 01268 01269 01270 01271 } 01272 01273 //draws a box. The box is decribed 01274 //by a diagonal line from x, y1 to x2, y2 01275 void box(char x1, char y1, char x2, char y2) 01276 { 01277 line(1, x1, y1, x1, y2); 01278 line(1, x1, y1, x2, y1); 01279 line(1, x2, y1, x2, y2); 01280 line(1, x1, y2, x2, y2); 01281 01282 } 01283 01284 void EEPROM_write(unsigned int uiAddress, unsigned char ucData) 01285 { 01286 /* Wait for completion of previous write */ 01287 while(EECR & (1<<EEPE)) 01288 ; 01289 /* Set up address and Data Registers */ 01290 EEAR = uiAddress; 01291 EEDR = ucData; 01292 /* Write logical one to EEMPE */ 01293 EECR |= (1<<EEMPE); 01294 /* Start eeprom write by setting EEPE */ 01295 EECR |= (1<<EEPE); 01296 } 01297 01298 unsigned char EEPROM_read(unsigned int uiAddress) 01299 { 01300 /* Wait for completion of previous write */ 01301 while(EECR & (1<<EEPE)) 01302 ; 01303 /* Set up address register */ 01304 EEAR = uiAddress; 01305 /* Start eeprom read by writing EERE */ 01306 EECR |= (1<<EERE); 01307 /* Return data from Data Register */ 01308 return EEDR; 01309 } 01310 01311 01312 void set_baud(char b) 01313 { 01314 if (b == 1) USART_Init( 1000000/2400-1);//4800 01315 else if (b == 2) USART_Init( 1000000/4800-1);//9600 01316 else if (b == 3) USART_Init( 1000000/9600-1);//19200 01317 else if (b == 4) USART_Init( 1000000/19200-1);//38400 01318 else if (b == 5) USART_Init( 1000000/28800-1);//57600 01319 else if (b == 6) USART_Init( 1000000/57600-1);//115200 01320 01321 } 01322 01323 01324 void set_backlight(unsigned char dutycycle) 01325 { 01326 //Set up Timer 0 01327 TCCR0A = 0x02;//CTC mode 01328 //TCCR0B = 0x02; 01329 //TIMSK0 = 0x02;//enable OCR0A 01330 //OCR0B = 255 - BL_dutycycle; 01331 01332 //OCR0A = 255 - (100 - BL_dutycycle); 01333 //OCR0A = dutycycle; 01334 01335 //SREG |= 0x80; 01336 01337 if(BL_dutycycle >= 100) 01338 { 01339 TCCR0B = 0; 01340 TIMSK0 = 0;//disable timer ints 01341 01342 //Backlight on 01343 PORTB &= (~(1<<BL_EN)); 01344 } 01345 else if (BL_dutycycle == 0) 01346 { 01347 TCCR0B = 0; 01348 TIMSK0 = 0;//disable timer ints 01349 01350 //Backlight off 01351 PORTB |= (1<<BL_EN); 01352 } 01353 01354 else 01355 { 01356 TCCR0B = 0; 01357 TIMSK0 = 0;//disable timer ints 01358 01359 OCR0A = 100 - BL_dutycycle; 01360 01361 TIMSK0 = 0x02;//enable match on A 01362 TCCR0B = 0x02; 01363 01364 SREG |= 0x80; 01365 01366 } 01367 01368 } 01369 01370 01371 01372 01373 01374