📄 display.c
字号:
#include <common.h>#include <asm/inca-ip.h>#ifdef CONFIG_DISPLAYextern void udelay (unsigned long usec);/*Table which maps ascii to display ascii*/unsigned char auc_ascii_to_display[] = { 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x08,0x20,0x0a,/*0x0a-New line*/ 0x20,0x20,0x0d,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,/*0x0d-Carriage return*/ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,/* Lst one space*/ 0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,/*0x21 to ox3f remains same*/ 0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36, 0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0xa0,0x41,/*0xa0 - @ for display */ 0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,/*ox41-0x5a remains same*/ 0x4d,0x4e,0x4f,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57, 0x58,0x59,0x5a,0xfa,0xfb,0xfc,0x1d,0xc4,0x20,0x61,0x62,/*0x61-0x7a same a to z*/ 0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d, 0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78, 0x79,0x7a,0xfd,0xfe,0xff,0xce,0x20};/**************************************************************************************************//********************************* GENERAL DISPLAY FUNCTIONS **************************************//* DISPLAY INITIALIZATION *//**************************/int display_init(void){ int i; unsigned char init_codes[] = { 0x3C, 0x06, 0x09, 0x02, 0x10, 0X38, 0x0F, 0x06, 0x01 }; /* Set GPIO ports */ /* Port 2.15 is used for the LCD */ *INCA_IP_Ports_P2_ALTSEL |= (1 << 15); /* P2.15 set to GPIO */ *INCA_IP_Ports_P2_DIR |= (1 << 15); /* P2.15 direction output */ pwm_init(); pwm_set(PWM1, 100); /* Set the contrast */ pwm_set(PWM2, 255); /* Set the brightness */ for(i = 0; i < sizeof(init_codes); i++) { display_wait(); display_write(COMMAND, init_codes[i]); } return 0;}/* DISPLAY CLEAR *//*****************/int display_clear(void){ display_wait(); display_write(COMMAND, 0X01); return 0;}/* DISPLAY CLEANUP *//*******************/int display_cleanup(void){ int i; unsigned char cleanup_codes[] = { 0x3C, 0x01, 0x03 }; for(i = 0; i < sizeof(cleanup_codes); i++) { display_wait(); display_write(COMMAND, cleanup_codes[i]); } pwm_set(PWM1, 0); pwm_set(PWM2, 0); pwm_close(); ssc_close(); return 0;}/* DISPLAY WAIT *//****************//* * display_wait: Waits for the display's busy flag to change to low. * If the flag is high, then an operation internal to the display * is being processed. */int display_wait(void){ unsigned char uc_value = 0xFF; while(1) { display_read(COMMAND, &uc_value); /* Busy flag is read into bit 7, address counter bits 0~6 */ if(uc_value & 0x80) /* Busy flag is set */ udelay(50); else /* Busy flag is low */ return 0; } return 0;}/**************************************************************************************************//********************************* DISPLAY CURSOR FUNCTIONS ***************************************//* DISPLAY SCROLL DOWN *//***********************//* * display_scroll: this function will scroll up the display to make room * for a new line. It saves the last three lines (2 to 4) to a buffer * then clears the display. Next the save three lines are retrieved and * written starting at home. */int display_scroll(){ int i; unsigned char offset = 0; char buff[60]; /* Go to the beginning of the second line */ display_write(COMMAND, 0X80 | 0x20); for(i=0; i<60; i++) { display_wait(); display_write(COMMAND, 0x80 | (0x20 + offset)); display_read(DATA, buff+i); if(offset == 0x13 || offset == 0x33 ) offset += 0xD; else offset++; } display_clear(); for(i=0; i<60; i++) { display_wait(); display_write(DATA, maplcdchar(buff[i])); } return 0;}/* SHOW or HIDE DISPLAY CURSOR *//*******************************/int display_cursor_show(int option){ if(option == CURSOR_ON) { display_wait(); display_write(COMMAND, 0x0F); } else if(option == CURSOR_OFF) { display_wait(); display_write(COMMAND, 0x0C); } else return 1; return 0;}/* GOTO DISPLAY POSITION *//*************************/int display_goto(int option){ unsigned char uc_value; display_wait(); display_read(COMMAND, &uc_value); switch (option) { case DISPLAY_LEFT: { display_wait(); display_write(COMMAND, 0x10); break; } case DISPLAY_RIGHT: { display_wait(); display_write(COMMAND, 0x14); break; } case DISPLAY_HOME: { display_wait(); display_write(COMMAND, 0x02); break; } case DISPLAY_NEXTLINE: { /* If it's the 4 line then scroll */ if(uc_value >= 0x60 && uc_value <= 0x73) display_scroll(); else { display_wait(); display_write(COMMAND, 0x80 | (0x20 * ((uc_value&0x7F)/0x20) + 0x20)); } break; } case DISPLAY_ROWHOME: { display_wait(); display_write(COMMAND, 0x80 | (0x20 * ((uc_value&0x7F)/0x20))); break; } default: return 1; } /* switch */ return 0;}/**************************************************************************************************//********************************* DISPLAY OUTPUT/INPUT FUNCTIONS *********************************//* READ ONE BYTE (COMMAND or DATA) FROM LCD *//********************************************/int display_read(int cmd_data, unsigned char *uc_value){ DISPLAY_CHIPSELECT_0; if(cmd_data == COMMAND) /* Read busy flag */ { ssc_write(0x3F); ssc_write(0x00); } else if(cmd_data == DATA) /* Read data */ { ssc_write(0x7F); ssc_write(0x00); } else return 1; udelay(350); ssc_read(uc_value); if(cmd_data == DATA) *uc_value = mapfromlcd(*uc_value); DISPLAY_CHIPSELECT_1; return 0;}/* WRITE ONE BYTE (COMMAND or DATA) TO LCD *//*******************************************/int display_write(int cmd_data, unsigned char uc_value){ DISPLAY_CHIPSELECT_0; if(cmd_data == COMMAND) ssc_write(0x1F); else if(cmd_data == DATA) ssc_write(0x5F); else return 1; ssc_write(uc_value & 0xF); ssc_write((uc_value >> 4) & 0xF); udelay(50); DISPLAY_CHIPSELECT_1; return 0;}/* PRINT STRING TO DISPLAY *//***************************/int display_print(char *data){ int i=0; unsigned char uc_value; while(1) { if(data[i] == '\0') /* End of string! */ return 0; display_wait(); display_read(COMMAND, &uc_value); /* Check whether to scroll after writing to the last position */ if(uc_value == 0x73) { if(data[i] == '\n') display_goto(DISPLAY_NEXTLINE); else if(data[i] == '\r') display_goto(DISPLAY_ROWHOME); else if(data[i] == '\b') display_goto(DISPLAY_LEFT); /* data[i] is a character */ else { display_write(DATA, maplcdchar(data[i])); display_goto(DISPLAY_LEFT); i++; /* The next character is considered */ switch (data[i]) { case '\b': { display_goto(DISPLAY_LEFT); break; /* already went back 1 left */ } case '\n': { display_scroll(); break; } case '\0': return 0; case '\r': { display_goto(DISPLAY_ROWHOME); break; } default: /* The next character is data */ { display_scroll(); display_wait(); display_write(DATA, maplcdchar(data[i])); break; } } } } /* uc_value == 0x73 */ else { if(data[i] == '\n') display_goto(DISPLAY_NEXTLINE); else if(data[i] == '\r') display_goto(DISPLAY_ROWHOME); else if(data[i] == '\b') display_goto(DISPLAY_LEFT); else { if(uc_value == 0x13 || uc_value == 0x33 || uc_value == 0x53) { display_wait(); display_write(DATA, maplcdchar(data[i])); switch(data[i+1]) { case '\n': break; case '\r': { display_goto(DISPLAY_LEFT); display_goto(DISPLAY_ROWHOME); break; } case '\b': { display_goto(DISPLAY_LEFT); break; } case '\0': return 0; default: display_wait(); display_write(DATA, maplcdchar(data[i+1])); break; } i++; } else { display_wait(); display_write(DATA, maplcdchar(data[i])); } } } i++; } /* while(1) */ return 0; }int display_printf(char *data, int i_value){ int from_buffer=0; /* When from_buff is 1, write data from buffer[] */ int d_ctr=0; int b_ctr=0; char buffer[15]; char *ptr; /* Points to the location of the data to be written next */ unsigned char uc_value; ptr = data; /* We start writing from data */ while(1) { if(from_buffer) ptr = buffer + b_ctr; else ptr = data + d_ctr; if(from_buffer == 0 && *ptr == '%' && *(ptr+1) == 'd') { sprintf(buffer, "%d", i_value); from_buffer = 1; b_ctr = 0; ptr = buffer; d_ctr += 2; } if(*ptr == '\0') /* End of string! */ { if(from_buffer) /* Return ptr to the next byte in data to be written */ { from_buffer = 0; ptr = data + d_ctr; /* * The rest of the code assumes that ptr is not points to a \0 * so a check if the next byte in data is a \0 or not! */ if(*ptr == '\0') return 0; } else return 0; } display_wait(); display_read(COMMAND, &uc_value); /* Check whether to scroll after writing to the last position */ if(uc_value == 0x73) { /* For \n, \r and \b, ptr can only be pointing to data */ if(*ptr == '\n') { display_goto(DISPLAY_NEXTLINE); d_ctr++; } else if(*ptr == '\r') { display_goto(DISPLAY_ROWHOME); d_ctr++; } else if(*ptr == '\b') { display_goto(DISPLAY_LEFT); d_ctr++; } else /* ptr is pointing to a character */ { display_write(DATA, maplcdchar(*ptr)); display_goto(DISPLAY_LEFT); if(from_buffer) b_ctr++; else d_ctr++; /* At this point, the next character has to be considered */ /* If from buffer, the next byte is either a char byte from the buffer * itself or a \0. It can't be a byte from data. */ ptr++; switch (*ptr) { case '\b': display_goto(DISPLAY_LEFT); d_ctr++; break; /* already went back 1 left */ case '\n': display_scroll(); d_ctr++; break; case '\0': if(from_buffer) { from_buffer = 0; ptr = data + d_ctr; if(*ptr == '\0') return 0; else display_scroll(); } else return 0; break; case '\r': display_goto(DISPLAY_ROWHOME); d_ctr++; break; default: /* The next character is data */ display_scroll(); if(from_buffer == 0 && *ptr == '%' && *(ptr+1) == 'd') { sprintf(buffer, "%d", i_value); from_buffer = 1; b_ctr = 0; d_ctr += 2; } else { display_wait(); display_write(DATA, maplcdchar(*ptr)); if(from_buffer) b_ctr++; else d_ctr++; } break; } /* switch */ } /* else is a data */ } /* if 0x73 */ else { if(*ptr == '\n') { display_goto(DISPLAY_NEXTLINE); d_ctr++; } else if(*ptr == '\r') { display_goto(DISPLAY_ROWHOME); d_ctr++; } else if(*ptr == '\b') { display_goto(DISPLAY_LEFT); d_ctr++; } else { if(from_buffer == 0 && (uc_value == 0x13 || uc_value == 0x33 || uc_value == 0x53)) { display_wait(); display_write(DATA, maplcdchar(*ptr)); d_ctr++; ptr++; switch(*ptr) { case '\n': d_ctr++; break; case '\r': display_goto(DISPLAY_LEFT); display_goto(DISPLAY_ROWHOME); d_ctr++; break; case '\b': display_goto(DISPLAY_LEFT); d_ctr++; break; default: ptr--; break; } } else { display_wait(); display_write(DATA, maplcdchar(*ptr)); if(from_buffer) { b_ctr++; } else { d_ctr++; } } } } } /* while */ return 0;}/* Clears the current line and goes to row-home */int display_clear_line(void){ int i; display_goto(DISPLAY_ROWHOME); for(i=0; i<20; i++) { display_wait(); display_write(DATA, 0x20); } display_goto(DISPLAY_LEFT); display_goto(DISPLAY_ROWHOME); return 0;}/**************************************************************************************************//********************************* OTHER FUNCTIONS ************************************************/unsigned char maplcdchar(unsigned char uc_char){ if(uc_char > 127) { return 0x20;/*Blank space ascii for display*/ } return auc_ascii_to_display[uc_char];}unsigned char mapfromlcd(unsigned char uc_char){ switch(uc_char) { case 0xa0: /* The char @ */ return 0x40; case 0xfa: /* The char [ */ return 0x5B; case 0xfb: /* The char \ */ return 0x5c; case 0xfc: /* The char ] */ return 0x5d; case 0x1d: return 0x5e; case 0xfd: /* The char { */ return 0x7b; case 0xfe: /* The char | */ return 0x7c; case 0xff: /* The char } */ return 0x7d; case 0xce: /* The char ~ */ return 0x7e; default: if((uc_char > 0x20 && uc_char < 0x40) || (uc_char > 0x40 && uc_char < 0x5b) || (uc_char > 0x60 && uc_char < 0x7b)) return uc_char; else return 0x20; }}int pwm_init(void){ /* enable PWM */ *INCA_IP_PMU_PM_GEN |= INCA_IP_PMU_PM_GEN_EN9; *INCA_IP_TSF_TSF_CONF |= INCA_IP_TSF_TSF_CONF_PWMEN; *INCA_IP_Ports_P2_ALTSEL &= ~0x1800; /* P2.11 and P2.12 set to default */ *INCA_IP_Ports_P2_DIR |= (0x01800); /* P2.11 and P2.12 direction out */ return 0;}int pwm_close(void){ *INCA_IP_PMU_PM_GEN &= ~INCA_IP_PMU_PM_GEN_EN9; return 0;}/*************************************************************************** * set_pwm: sets the brightness and contrast of the display via the PWM * * id = PWM1 (0) sets the contrast * * id = PWM2 (1) sets the brightness * ***************************************************************************/int pwm_set(int id, unsigned int uc_duty_cycle_val){ unsigned char value; u32 temp; value = uc_duty_cycle_val; temp = (volatile u32)(*INCA_IP_TSF_PWM12 & ~(0xFFFF << 16*id)); *INCA_IP_TSF_PWM12 = temp | (value << 16*id); return 0;}#endif /* CONFIG_DISPLAY */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -