📄 lcdgraphics.c
字号:
/** @file lcdgraphics.c @brief LCD MP3 Functions @author Nick Lott @date September 2004 This file represents a convergence of a number of code snippets found on the web, some of the Yampp system by Jesper Hansen and the work done by Sylvain.Bissonnette@microsyl.com. The goal of this code is to run the graphical LCD for the Butterfly MP3 project. http://butterflymp3.sourceforge.net/ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.**///#define LCDG_C#include <avr/io.h>#include <avr/pgmspace.h>#include <avr/interrupt.h>#include "main.h"#include "types.h"#include "lcdgraphics.h"#include "BCD.h"#include "avrfat16.h" // Included for long filename / ID3 stuff. #ifdef NOKIA #include "pcd8544.h" #include "fontset0.h" #include "font_ttuf1.h" #include "font_ttuf2.h"#endif#ifdef ALPHA #include "LCD_driver.h" #include "LCD_functions.h"// volatile char gLCD_Update_Required;// char LCD_Data[LCD_REGISTER_COUNT];// char gTextBuffer[TEXTBUFFER_SIZE];// volatile char gScrollMode;// char gFlashTimer;// char gColon;// volatile signed char gScroll; uint8 ALPHA_textBufferPos;extern uint8 gDisplayTimeOut; // from main.c to set # of seconds to show info#endif#include "uart.h"// Butterfly MP3 title graphic//static unsigned char __attribute__ ((progmem))static const char __attribute__ ((progmem)) bfMP3Title[] = { 0x41,0x51,0x47, // 'B' 0x7F, 0x41,0x5F,0x41, // 'U' 0x7F, 0x7D,0x41,0x7D, // 'T' 0x7F, 0x7D,0x41,0x7D, // 'T' 0x7F, 0x41,0x55,0x5D, // 'E' 0x7F, 0x41,0x75,0x4B, // 'R' 0x7F, 0x41,0x75,0x7D, // 'F' 0x7F, 0x41,0x5F,0x5F, // 'L' 0x7F, 0x71,0x47,0x71, // 'Y' 0x7F, 0x7F,0x7F,0x7F, // ' ' 0x7F, 0x41,0x79,0x41, // 'M' 0x7F, 0x41,0x75,0x71, // 'P' 0x7F, 0x5D,0x55,0x41, // '3' };/*** Initialize hardware **/void LCD_Initialize(void){ #ifdef NOKIA lcdInit(); #endif #ifdef ALPHA LCD_Init(); #endif}/** * clear LCD**/void LCD_Blank(void){ #ifdef NOKIA uint8 i; lcdClr(); lcdXY(0,0); lcdModeData; for (i=0;i<16; i++) lcdByte(0x7F); for (i=0; i<sizeof(bfMP3Title); i++) { lcdByte(pgm_read_byte(bfMP3Title+i)); } for (i=0;i<17; i++) lcdByte(0x7F); #endif #ifdef ALPHA LCD_Clear(); #endif}/** * Put LCD into powersave mode**/void LCD_Sleep(void){ #ifdef NOKIA lcdClr(); lcdSuspend; lcdReset; #endif #ifdef ALPHA LCD_Clear(); //CBI(LCDCRA, 7); // disable LCD //Enable LCD start of frame interrupt LCDCRA &= ~( (1<<LCDEN)); #endif}/*** Wake LCD from powersave mode**/void LCD_Wake(void){ extern uint8 gLCD_Refresh; #ifdef NOKIA lcdResume; lcdInit(); LCD_Blank(); // Make sure backgound image only is set #endif #ifdef ALPHA LCD_Init(); //SBI(LCDCRA, 7); // enable LCD LCDCRA |= (1<<LCDEN) ; #endif gLCD_Refresh=TRUE;}/** Print a single 4bit digit @param Data 8bit int to print, upper nibble is ignored **/void LCD_PrintfU4(uint8 Data){ /* Send 4-bit hex value */ uint8 Character[2]; Character[0] = Data&0x0f; if (Character[0]>9) { Character[0]+='A'-10; } else { Character[0]+='0'; } #ifdef NOKIA // load a pointer to the font uint8* font = (uint8*)fontSet0;// uint8* font2 = (uint8*)fontSet1;// uint8* font2 = (uint8*)fontSet1; // uint8 fontSize = pgm_read_byte(font+0); // chars in this font// uint8 fontX = pgm_read_byte(font+1); // font width// uint8 fontY = pgm_read_byte(font+2); // font hieght Character[1]=0x00; lcdWrite(font,Character,0,1); #endif #ifdef ALPHA gTextBuffer[ALPHA_textBufferPos++] = Character[0]; gTextBuffer[ALPHA_textBufferPos] =0; #endif }/** Print two 4bit Digits @param Data 8bit int to print**/void LCD_PrintfU8(uint8 Data){ /* Send 8-bit hex value */ LCD_PrintfU4(Data>>4); LCD_PrintfU4(Data);}/** Print Play time on display @param data[] 16bit integer array containting play time information. TODO: - better play time indicator - decimal time - song position.**/uint8 LCD_Time(uint16 data){#ifdef NOKIA uint8* font = (uint8*)fontSet1; uint8 cBuff[6]; lcdModeData; //fbXY[0] = 43; // x //fbXY[1] = 2;// y //LCD_PrintfU8(data >> 8); //LCD_PrintfU8(data & 0xFF); fbXY[0] = 65; // x fbXY[1] = 3;// y cBuff[0] = (data/600); data -= 600 * cBuff[0]; cBuff[1] = (data/60); data -= 60 * cBuff[1]; cBuff[2] = 58; //':' cBuff[3] = (data/10); data -= 10 * cBuff[3]; cBuff[4] = (data); cBuff[5] = '\0'; cBuff[0] += 0x30; cBuff[1] += 0x30; cBuff[3] += 0x30; cBuff[4] += 0x30; lcdWrite(font, cBuff ,0, 0xFF);#endif return 0;}/** Print long filename on display @param name[] null terminated string containing filename**/uint8 LCD_FileName(uint8 resetScroll){ #ifdef NOKIA static uint8 byte = 0; static uint8 textIndex = LFN_TITLE_INDEX; static uint8 *textLen = &FAT16_LFNTitleLen; uint8 i; uint8* font = (uint8*)fontSet1; if (resetScroll) { byte = 0; textIndex = LFN_TITLE_INDEX; textLen = &FAT16_LFNTitleLen; } fbXY[0] = 0; // x fbXY[1] = 2; // y // Blank out the whole line (artist could be shorter than track and // vice-versa) lcdClrLine(2); lcdModeData; if (byte < SONG_TITLE_PAUSE) lcdWrite(font, FAT16_longfilename+textIndex, 0, SONG_TITLE_WIDTH); else { lcdWrite(font, FAT16_longfilename+textIndex+byte-SONG_TITLE_PAUSE, 0, SONG_TITLE_WIDTH); } byte++; if (*textLen >= SONG_TITLE_WIDTH) // We are scrolling { if (byte > *textLen-SONG_TITLE_WIDTH+SONG_TITLE_PAUSE) goto toggleText; } else // We are not scrolling { if (byte > SONG_TITLE_PAUSE) goto toggleText; } return 0;// Only efficient way of doing (without yet another function call with a lot// of parameters was a gototoggleText:{ byte = 0; // Toggle between displaying artist and title if ((FAT16_longfilename[LFN_TYPE_INDEX] == LFN_TYPE_FILENAME) || (textIndex == LFN_ARTIST_INDEX)) { textIndex = LFN_TITLE_INDEX; textLen = &FAT16_LFNTitleLen; } else if ((FAT16_longfilename[LFN_TYPE_INDEX] & LFN_TYPE_ID3_ARTIST) == LFN_TYPE_ID3_ARTIST) { textIndex = LFN_ARTIST_INDEX; textLen = &FAT16_LFNArtistLen; } return 0;} #endif // NOKIA #ifdef ALPHA uint8 i; //extern char gScroll; //extern char gScrollMode; extern char gLCD_Start_Scroll_Timer; gDisplayTimeOut = 0; gShowFilename = TRUE; for (i=0;FAT16_longfilename[i]&&i<=LFN_BUFFER_LENGTH;i++); // find name length if ((i>6)){ // scroll if larger than display gLCD_Start_Scroll_Timer=3; gScroll=0; LCD_UpdateRequired(TRUE,TRUE); } else{ gScroll = 0; LCD_UpdateRequired(TRUE,FALSE); } #endif return 0;}/** Display the "playing" symbol **/void LCD_Play(void){ #ifdef NOKIA lcdXY(0,3); lcdModeData; lcdByte(0x1F); lcdByte(0x1F); lcdByte(0x0E); lcdByte(0x0E); lcdByte(0x04); lcdByte(0x04); #endif #ifdef ALPHA //gShowFilename =FALSE; LCD_puts_f(PSTR("PLAY\0"), 1); gDisplayTimeOut = STAT_DISPLAY_TIME+1; //LCD_UpdateRequired(TRUE,TRUE); #endif}/** Display the "stopped" symbol**/void LCD_Stop(void){ #ifdef NOKIA lcdXY(0,3); lcdModeData; lcdByte(0x1F); lcdByte(0x1F); lcdByte(0x1F); lcdByte(0x1F); lcdByte(0x1F); #endif #ifdef ALPHA LCD_puts_f(PSTR("STOP\0"), 1); gDisplayTimeOut = STAT_DISPLAY_TIME+1; #endif}/** Display the "Paused" symbol**/void LCD_Pause(void){ #ifdef NOKIA lcdXY(0,3); lcdModeData; lcdByte(0x1F); lcdByte(0x1F); lcdByte(0); lcdByte(0x1F); lcdByte(0x1F); #endif #ifdef ALPHA LCD_puts_f(PSTR("PAUSE\0"), 1); gDisplayTimeOut = STAT_DISPLAY_TIME+1; #endif}/** Show the volume @param uint8 containing the volumt lower nibble is used.**/void LCD_Vol(uint8 volume, uint8 boostOn){ #ifdef NOKIA uint8 i; uint8 level; lcdXY(0,5); lcdModeData; // draw speaker icon lcdByte(60); lcdByte(60); lcdByte(126); lcdByte(255); lcdByte(0); lcdByte(0); // draw volume graphic for (i=0; i<10; i++) { if (volume >= i) { if (i<8) { level = 0xFF << (7-i); if (boostOn) level |= 0x01 << (5-i); } else level = 0xFF; lcdByte(level); lcdByte(level); lcdByte(level); lcdByte(0x00); } else { lcdByte(0x00); lcdByte(0x00); lcdByte(0x00); lcdByte(0x00); } } // draw volume level //fbXY[0] = 10; // x //fbXY[1] = 4;// y //LCD_PrintfU4(volume); #endif #ifdef ALPHA gTextBuffer[0]='V'; gTextBuffer[1]='O'; gTextBuffer[2]='L'; gTextBuffer[3]=' '; ALPHA_textBufferPos =4; LCD_PrintfU4(volume); gDisplayTimeOut = STAT_DISPLAY_TIME+1; LCD_puts(gTextBuffer,1); #endif}/** Print the startup message to the LCD screen @return uint8 status code (always zero)**/uint8 LCD_Tester(void){ #ifdef NOKIA // load a pointer to the font uint8* font = (uint8*)fontSet1; //uint8* font2 = (uint8*)fontSet2; // uint8 fontSize = pgm_read_byte(font+0); // chars in this font// uint8 fontX = pgm_read_byte(font+1); // font width// uint8 fontY = pgm_read_byte(font+2); // font hieght lcdModeData;// fbXY[0] = 0; // x fbXY[1] = 1;// y lcdWrite(font,VERSIONINFO2,1, 0xFF);// lcdWrite(font,PSTR(__TIME__),1, 0xFF);// fbXY[0] = 0; // x// fbXY[1] = 2;// y// lcdWrite(font,(uint8*) PSTR(__DATE__),1, 0xFF); fbXY[0] = 0; // x fbXY[1] = 3;// y lcdWrite(font,(uint8*) VERSIONINFO1, 1, 0xFF); fbXY[0] = 0; // x fbXY[1] = 5;// y lcdWrite(font,(uint8*) PSTR("NO MMC\0"), 1, 0xFF); #endif #ifdef ALPHA uint8 i; gShowFilename = TRUE; for (i = 0; pgm_read_byte(&VERSIONINFO1[i]) && i < 25; i++){ FAT16_longfilename[i] = pgm_read_byte(&VERSIONINFO1[i]); } FAT16_longfilename[i] = 0; LCD_UpdateRequired(TRUE,TRUE); #endif return 0;} /** Print Sanning message while searching MMC**/void LCD_Scanning(void){#ifdef NOKIA // load a pointer to the font uint8* font = (uint8*)fontSet1; lcdModeData; fbXY[0] = 0; // x fbXY[1] = 5;// y lcdWrite(font, (uint8*) PSTR("SCANNING\0"),1, 0xFF);#endif#ifdef ALPHA LCD_puts_f( PSTR("SCANNING...\0"),1); gDisplayTimeOut = 0;#endif }/** Print Battery Status on LCD **/void LCD_Battery(uint8 percentage){#ifdef NOKIA // TODO : draw a nice battery symbol with a graph // load a pointer to the font uint8* font = (uint8*)fontSet0; uint8 i; lcdXY(71,5); lcdModeData; //fbXY[0] = 10; // x //fbXY[1] = 5;// y //LCD_PrintfU8(percentage); //lcdCh(font,04);// '%' // Draw battery graphic lcdByte(0x7E); //lcdByte(0x42); for (i=0; i<100; i+=10) { if (percentage > i) { lcdByte(0x5A); } else { lcdByte(0x42); } } lcdByte(0x42); lcdByte(0x3C);#endif#ifdef ALPHA // TODO: make use of the flat battery LCD segment if (percentage <100){ ALPHA_textBufferPos =0; LCD_PrintfU8(CHAR2BCD2(percentage)); }else{ gTextBuffer[0]='1'; gTextBuffer[1]='0'; gTextBuffer[2]='0'; ALPHA_textBufferPos =3; } gTextBuffer[ALPHA_textBufferPos]=' '; gTextBuffer[ALPHA_textBufferPos+1]='*';//'%' gTextBuffer[ALPHA_textBufferPos+2]='/'; gTextBuffer[ALPHA_textBufferPos+3]=':'; gTextBuffer[ALPHA_textBufferPos+4]=' '; gTextBuffer[ALPHA_textBufferPos+5]='B'; gTextBuffer[ALPHA_textBufferPos+6]='T'; gTextBuffer[ALPHA_textBufferPos+7]='R'; gTextBuffer[ALPHA_textBufferPos+8]='Y'; gTextBuffer[ALPHA_textBufferPos+9]=0x00; LCD_puts(gTextBuffer,1); gDisplayTimeOut = STAT_DISPLAY_TIME+1;#endif }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -