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