lcd.c

Go to the documentation of this file.
00001 
00039 #include <includes.h>
00040 
00041 // *******************************************************************************
00042 // LCD Instructions
00043 // *******************************************************************************
00044 #define LCD_CLEAR 0x01   
00045 #define LCD_HOME 0x02    
00046 #define LCD_ENTRY_MODE 0x06   
00047 #define LCD_FUNCTION_SET 0x38  
00048 #define LCD_DISPLAY_ON 0x0C  
00049 #define LCD_DISPLAY_OFF 0x08   
00050 #define LCD_CURSOR_SHIFT_R 0x14  
00051 #define LCD_CURSOR_SHIFT_L 0x10  
00052 #define LCD_DISPLAY_SHIFT_R 0x1C  
00053 #define LCD_DISPLAY_SHIFT_L 0x18  
00054 #define LCD_BOTTOM_LINE 0xA0 
00055 #define LCD_TOP_LINE 0x80 
00057 #define LCD_LENGTH (100) 
00058 #define QUAD_NUM (4) 
00059 LCD_CHAR lcd_ring[QUAD_NUM][LCD_LENGTH]; 
00060 unsigned int lcd_head[QUAD_NUM] = {0,0,0,0}; 
00061 unsigned int lcd_tail[QUAD_NUM] = {0,0,0,0};
00062 unsigned int lcd_period;
00063 unsigned int lcd_quad = 0; 
00065 VOID_VOID_F lcd_overflowfunc = voidvoid; 
00067 //Annoying state stuff...
00068 int lcd_wait = 0; //time to execute the next function
00069 LCD_CHAR lcd_target_char;
00070 LCD_STATE lcd_state = LCD_IDLE;
00071 
00076 void lcd_write_instruction(unsigned char instruction)
00077 {
00078   int i;
00079   // ****** WRITE INSTRUCTION ******
00080   FIO0CLR = (1<<15); // RS = 0 instruction
00081   FIO0CLR = (1<<10); // R/~W = 0 write
00082   FIO0SET = (1<<11); // EN = 1   
00083 //  FIO0PIN0 = instruction;
00084   for (i = 0; i < 8; i++){
00085     lcd_write_bit(i, instruction & (1<<i));
00086   }
00087   FIO0CLR = (1<<11); // EN = 0, falling edge
00088   
00089   if (instruction == LCD_HOME || instruction == LCD_CLEAR){
00090     lcd_wait = 2000;
00091   } else {
00092     lcd_wait = 50; //in ms; time to wait before executing the next function
00093     //lcd_wait = lcd_period;
00094   }
00095 }
00096 
00102 void lcd_write_bit(unsigned int db, unsigned int bit)
00103 {
00104   if (bit == 0){
00105     FIO0CLR = (1<<db);
00106   } else {
00107     FIO0SET = (1<<db);
00108   }
00109 }
00110 
00115 void lcd_write_data(unsigned char data)
00116 {
00117   int i;
00118   // ****** WRITE BYTE ******
00119   FIO0SET = (1<<15); // RS = 1 data
00120   FIO0CLR = (1<<10); // R/~W = 0 write
00121   FIO0SET = (1<<11); // EN = 1
00122 //  FIO0PIN0 = data;
00123   for (i = 0; i < 8; i++){
00124     lcd_write_bit(i, data & (1<<i));
00125   }
00126   FIO0CLR = (1<<11); // EN = 0, falling edge
00127   lcd_wait = lcd_period;
00128 }
00129 
00136 void lcd_print(char* string, unsigned int length, unsigned int start_pos)
00137 {
00138   int i;
00139   for (i = 0; i < length; i++){
00140     lcd_print_char(string[i], start_pos + i);
00141   }
00142 }
00143 
00149 void lcd_print_char(char ch, unsigned int pos)
00150 {    
00151   LCD_CHAR next_char;
00152   next_char.data = (unsigned char)ch;
00153   next_char.pos = pos % 16; //only acceptable positions are 0-15
00154   next_char.quad_num = pos/4;
00155   lcd_push(&next_char);
00156 }
00157 
00164 int lcd_push(LCD_CHAR* c)
00165 {
00166   if ((lcd_head[(*c).quad_num] % LCD_LENGTH) != (lcd_tail[(*c).quad_num] % LCD_LENGTH) //ring not full
00167     || lcd_head[(*c).quad_num] == lcd_tail[(*c).quad_num]){ //or empty
00168     lcd_ring[(*c).quad_num][lcd_head[(*c).quad_num] % LCD_LENGTH] = *c;
00169     
00170     
00171     lcd_head[(*c).quad_num]++;
00172     return 1;
00173   } else { //buffer full, ignore new data
00174     error_occurred(ERROR_LCD_STR_OF);
00175     return 0;
00176   }
00177 }
00178 
00186 int lcd_pop(LCD_CHAR* c)
00187 {
00188   //int i;
00189   //for(i = 0; i < 4; i++){ //check all buffers
00190     if (lcd_tail[0] != lcd_head[0]){ //buffer not empty
00191       *c = lcd_ring[0][lcd_tail[0] % LCD_LENGTH];
00192       lcd_tail[0]++;
00193       return 1;
00194     } 
00195   //}
00196     if (lcd_tail[1] != lcd_head[1]){ //buffer not empty
00197       *c = lcd_ring[1][lcd_tail[1] % LCD_LENGTH];
00198       lcd_tail[1]++;
00199       return 1;
00200     }
00201     if (lcd_tail[2] != lcd_head[2]){ //buffer not empty
00202       *c = lcd_ring[2][lcd_tail[2] % LCD_LENGTH];
00203       lcd_tail[2]++;
00204       return 1;
00205     }
00206     if (lcd_tail[3] != lcd_head[3]){ //buffer not empty
00207       *c = lcd_ring[3][lcd_tail[3] % LCD_LENGTH];
00208       lcd_tail[3]++;
00209       return 1;
00210     }
00211   return 0; //empty
00212 }
00213 
00219 void lcd_us_delay(long unsigned int delay_time_us)
00220 {
00221   long unsigned int ii;
00222   for (ii = 0; ii < (delay_time_us*2)/5; ii++){}
00223 }
00224 
00232 void lcd_set_quad1(char c1, char c2, char c3, char c4)
00233 {
00234   int i = 0;
00235   lcd_print_char(c1, i++);
00236   lcd_print_char(c2, i++);  
00237   lcd_print_char(c3, i++);
00238   lcd_print_char(c4, i++);
00239 }
00240 
00248 void lcd_set_quad2(char c1, char c2, char c3, char c4)
00249 {
00250   int i = 4;
00251   lcd_print_char(c1, i++);
00252   lcd_print_char(c2, i++);  
00253   lcd_print_char(c3, i++);
00254   lcd_print_char(c4, i++);
00255 }
00256 
00264 void lcd_set_quad3(char c1, char c2, char c3, char c4)
00265 {
00266   int i = 8;
00267   lcd_print_char(c1, i++);
00268   lcd_print_char(c2, i++);  
00269   lcd_print_char(c3, i++);
00270   lcd_print_char(c4, i++);
00271 }
00272 
00280 void lcd_set_quad4(char c1, char c2, char c3, char c4)
00281 {
00282   int i = 12;
00283   lcd_print_char(c1, i++);
00284   lcd_print_char(c2, i++);  
00285   lcd_print_char(c3, i++);
00286   lcd_print_char(c4, i++);
00287 }
00288 
00297 void lcd_isr(void) __irq
00298 {
00299   //executed every lcd_period ms, so decrement msec wait counter by that much
00300   lcd_wait -= lcd_period;
00301   
00302   // ****** EXECUTE IF ALLOWED ******
00303   if (lcd_wait <= 0){
00304     // ****** ACT ACCORDING TO STATE ******
00305     switch (lcd_state){
00306       case LCD_MOVE: 
00307         lcd_write_instruction(0x80 | ((lcd_target_char.pos/8)*0x40)+(lcd_target_char.pos%8));
00308         lcd_state = LCD_DISPLAY;
00309         break;
00310       case LCD_DISPLAY: 
00311         lcd_write_data(lcd_target_char.data);
00312         
00313         
00314         if (lcd_pop(&lcd_target_char)){
00315 //          lcd_target_char = lcd_pop();
00316           lcd_state = LCD_MOVE;
00317         } else {
00318           lcd_state = LCD_IDLE;
00319         }
00320           break;
00321         case LCD_IDLE: 
00322         if (lcd_pop(&lcd_target_char)){
00323 //          lcd_target_char = lcd_pop();
00324           lcd_state = LCD_MOVE;
00325         }
00326         break;
00327     }
00328   }
00329 
00330   lcd_overflowfunc();
00331   
00332   T1IR = 0xFFFFFFFF;  // Clear ALL Timer1 interrupt flags.
00333   VICVectAddr = 0;
00334 }
00335 
00341 void lcd_init(VOID_VOID_F overflowfunc)
00342 {
00343   lcd_period = 60000000 / ((T1MR0 + 1) * 1000); //in ms 
00344   lcd_overflowfunc = overflowfunc;
00345   lcd_write_instruction(LCD_FUNCTION_SET);
00346   lcd_us_delay(200);     
00347   lcd_write_instruction(LCD_DISPLAY_ON);
00348   lcd_us_delay(200);
00349   lcd_write_instruction(LCD_ENTRY_MODE);
00350   lcd_us_delay(200);
00351   lcd_write_instruction(LCD_CLEAR);
00352   lcd_us_delay(3000);  
00353   lcd_write_instruction(LCD_HOME);
00354   lcd_us_delay(3000);
00355 }
Generated on Tue Jun 29 16:36:14 2010 by  doxygen 1.6.3