#include "main.h" #include "display.h" #include "analog.h" #include "compass.h" #include #include #include short xdata write_cursor_x = 0; // current X pos of the write cursor short xdata write_cursor_y = 0; // current Y pos of the write cursor short xdata read_cursor_x = 5; // current X pos of the read cursor short xdata read_cursor_y = 0; // current Y pos of the read cursor BYTE xdata screen [18][8]; // array version of the screen to be displayed BYTE xdata select_screen [18][8]; // array version of the 'clickable' areas on the screen //Writes one command word to the display void wrtCommand(BYTE command) { P1 |= 0x02; //Make sure DISPLAY_RES# High P1 &= 0xFE; //Set DISPLAY_D/C to zero P1 &= 0xFB; //Set NSS_DISPLAY line to 0 Write_Read_Spi_Byte(command); //Put command word on the SPI bus P1 |= 0x04; //Set NSS_DISPLAY line to 1 } //Turn the display on void dispOn(void) { wrtCommand(0xAF); } //Changes the display's active page (row) and column. void setRWaddr(BYTE page, BYTE col) { // the screen is numbered 7 - 0, with 7 at the top // it's easier to think of 0 at the top, so reverse things page = 7 - page; wrtCommand(page + 0xB0); wrtCommand(col & 0xf); wrtCommand((col & 0xF0)/16 + 0x10); } // Writes one column of pixels to the display. //The column is 8 pixels tall and 1 pixel wide. //The active column auto-increments by one every time a column is written. void wrtData(BYTE pixels) { P1 |= 0x02; //Make sure DISPLAY_RES# High P1 |= 0x01; //Set DISPLAY_D/C to one P1 &= 0xFB; //Set NSS_DISPLAY line to 0 Write_Read_Spi_Byte(pixels); //Put data word on the SPI bus P1 &= 0xFE; //Set DISPLAY_D/C to zero Write_Read_Spi_Byte(0xE3); //Put NOP command on the SPI bus P1 |= 0x04; //Set NSS_DISPLAY line to 1 } //Writes one ascii character to the display, then auto-increments the active pixel column by 7. void display_putchar(BYTE ascii_character) { int i; for(i=0; i<7; i++) { wrtData(ascii_font[ascii_character - 0x20][i]); } } // Inverts the pixels and writes one ascii character to the display, // then auto-increments the active pixel column by 7 void invert_display_putchar(BYTE ascii_character) { int i; for(i=0; i<7; i++) { wrtData( (ascii_font[ascii_character - 0x20][i]) ^ 0xFF ); } } //Writes one hexadecimal digit to the display, then auto-increments the active pixel column by 7. void display_puthex(BYTE hex_digit) { int i; BYTE ascii_character; //Convert hexadecimal digit to ASCII first if(hex_digit <= 0x09) ascii_character = 0x30 + hex_digit; else if(hex_digit <= 0x0F) ascii_character = 0x37 + hex_digit; else ascii_character = 0x20; //Now write the character to the display for(i=0; i<7; i++) { wrtData(ascii_font[ascii_character - 0x20][i]); } } // put a space in every slot of the screen array, and reset the cursor to the beginning void resetscreen(void) { int x, y; // fill screen with spaces for(y=0; y<8; y++) { for(x=0; x<18; x++) { screen[x][y] = ' '; } } // reset write cursor write_cursor_x = 0; write_cursor_y = 0; } // reset the select_screen array void resetselectscreen(void) { int x, y; // fill the select_screen with CURRENT_SCREEN (non-clickable) links for(y=0; y<8; y++) { for(x=0; x<18; x++) { select_screen[x][y] = CURRENT_SCREEN; } } } // Send the screen array to the display for visual output // reset the cursor when finished void displayscreen(void) { int x; int y; for(y=0; y<8; y++) { setRWaddr(y,0); for(x=0; x<18; x++) { // offset for the screen not displaying correctly at the edge if (x == 0) { wrtData(0); wrtData(0); } // invert the character at read_cursor_x, read_cursor_y if ( (read_cursor_x == x) && (read_cursor_y == y) ) { invert_display_putchar(screen[x][y]); } else { display_putchar(screen[x][y]); } } } // reset the cursor screen resetscreen(); } //Clears the display to all dark pixels void clrDisplay(void) { // reset the cursor screen resetscreen(); // reset the select_screen resetselectscreen(); // display the blank screen displayscreen(); } void InitializeSPI_Display_SD() { //Initialize SPI Registers SPI0CN = 0x0E; // disable SPIEN before changing SPI0CFG SPI0CFG = 0x70; // data sampled on rising edge, clk active LOW, master mode SPI0CN = 0x0F; // 4-wire mode, SPI enabled, flags cleared SPI0CKR = 2; // 2 or higher works for the display NSSMD0 = 1; // NSSSMD0 sets port pin P0.3 (aka NSS_SD_FLASH) P1 |= 0x0C; //Set NSS_Display and NSS_Compass High P4 |= 0x40; //Set NSS_DSP High } void InitializeDisplay(void) { // hardware reset of the screen, only done once at startup P1 &= 0xFD; //Set display RES# Low delay(10); P1 |= 0x02; //Set display RES# High delay(10); wrtCommand(0x40); //Send Display Initialize Commands wrtCommand(0x81); wrtCommand(0x5c); //wrtCommand(0xA0); wrtCommand(0xA6); wrtCommand(0xA8); wrtCommand(0x3F); wrtCommand(0xAD); wrtCommand(0x8A); wrtCommand(0xD3); wrtCommand(0x00); wrtCommand(0xD5); wrtCommand(0xA0); wrtCommand(0xA4); wrtCommand(0xD8); wrtCommand(0x00); wrtCommand(0xDA); wrtCommand(0x12); wrtCommand(0xDB); wrtCommand(0x0B); wrtCommand(0xD9); wrtCommand(0x22); wrtCommand(0x2E); //wrtCommand(0xC0); wrtCommand(0xA1); wrtCommand(0xC8); dispOn(); clrDisplay(); } // very similar to InitializeDisplay(), but without the dispOn() and clrDisplay() void RefreshDisplay(void) { wrtCommand(0x40); //Send Display Initialize Commands wrtCommand(0x81); wrtCommand(0x5c); //wrtCommand(0xA0); wrtCommand(0xA6); wrtCommand(0xA8); wrtCommand(0x3F); wrtCommand(0xAD); wrtCommand(0x8A); wrtCommand(0xD3); wrtCommand(0x00); wrtCommand(0xD5); wrtCommand(0xA0); wrtCommand(0xA4); wrtCommand(0xD8); wrtCommand(0x00); wrtCommand(0xDA); wrtCommand(0x12); wrtCommand(0xDB); wrtCommand(0x0B); wrtCommand(0xD9); wrtCommand(0x22); wrtCommand(0x2E); //wrtCommand(0xC0); wrtCommand(0xA1); wrtCommand(0xC8); } // Write the string "text" to the screen array, starting at the current cursor location // Truncate any additional characters that won't fit on the current line void write(char *text) { int x; // loop control variable int stringlength; // number of characters in the string "text" int looplength; // number of characters to move from "text" to "screen" stringlength = strlen(text); // get the length of "text" // determine the number of characters from the string that will get // moved onto the screen if ( (17 - write_cursor_x) >= stringlength) { looplength = stringlength; } else { looplength = 17 - write_cursor_x; } // move the characters over for (x=0; x < looplength; x++) { screen[write_cursor_x++][write_cursor_y] = text[x]; } } // Write the screen type "screen" to the select_screen array, starting at ("startx", "y" // and ending at ("endx", "y"). Other characters before "startx" or after "endx" will // be filled with CURRENT_SCREEN. "startx" and "endx" are 0 based. // Truncate any additional characters that won't fit on the current line void ss_write(short startx, short endx, short y, unsigned char screen) { int x; // loop control variable // check if endx is on the screen, if not, put it on the screen if (endx > 17) { endx = 17; } // fill in the appropriate slots with the given screen for (x = startx; x <= endx; x++) { select_screen[x][y] = screen; } } // Write the string "text to the screen array, starting at the current cursor location // described by ("x", "y"). Truncate any additional characters that won't fit on the // current line. "x" must be in the range 0-17, "y" must be in the range 0-7. void writepos(char *text, unsigned char x, unsigned char y) { int i; // loop control variable int stringlength; // number of characters in the string "text" int looplength; // number of characters to move from "text" to "screen" stringlength = strlen(text); // get the length of "text" // determine the number of characters from the string that will get // moved onto the screen if ( (17 - x) >= stringlength) { looplength = stringlength; } else { looplength = 17 - x; } // move the characters over for (i=0; i < looplength; i++) { screen[x++][y] = text[i]; } // set write_cursor_x and write_cursor_y equal to the new curosr position write_cursor_x = x; write_cursor_y = y; } // Write the string "text" to the screen array, starting at the current cursor location // Truncate any additional characters that won't fit on the current line // Finally, advance the cursor to the beginning of the next line. If the cursor // is already on the last line, it will remain at it's current location. void writeln(char *text) { int x; // loop control variable int stringlength; // number of characters in the string "text" int looplength; // number of characters to move from "text" to "screen" stringlength = strlen(text); // get the length of "text" // determine the number of characters from the string that will get // moved onto the screen if ( (17 - write_cursor_x) >= stringlength) { looplength = stringlength; } else { looplength = 17 - write_cursor_x; } // move the characters over for (x=0; x < looplength; x++) { screen[write_cursor_x++][write_cursor_y] = text[x]; } // now advance the cursor to the beginning of the next line // leave the cursor where it's at if we're on the last line if (write_cursor_y < 7) { write_cursor_y++; write_cursor_x = 0; } } // Write the string "text to the screen array, starting at the current cursor location // described by ("x", "y"). Truncate any additional characters that won't fit on the // current line. "x" must be in the range 0-17, "y" must be in the range 0-7. // Finally, advance the cursor to the beginning of the next line. If the cursor // is already on the last line, it will remain at it's current location. void writelnpos(char *text, unsigned char x, unsigned char y) { int i; // loop control variable int stringlength; // number of characters in the string "text" int looplength; // number of characters to move from "text" to "screen" stringlength = strlen(text); // get the length of "text" // determine the number of characters from the string that will get // moved onto the screen if ( (17 - x) >= stringlength) { looplength = stringlength; } else { looplength = 17 - x; } // move the characters over for (i=0; i < looplength; i++) { screen[x++][y] = text[i]; } // set write_cursor_x and write_cursor_y equal to the new curosr position write_cursor_x = x; write_cursor_y = y; // now advance the cursor to the beginning of the next line // leave the cursor where it's at if we're on the last line if (write_cursor_y < 7) { write_cursor_y++; write_cursor_x = 0; } } // move the read cursor 1 unit in the given direction void moveCursor(unsigned char direction) { switch (direction) { case CURSOR_UP: if (read_cursor_y > 0) { read_cursor_y--; Redraw = 1; } break; case CURSOR_DOWN: if (read_cursor_y < 7) { read_cursor_y++; Redraw = 1; } break; case CURSOR_LEFT: if (read_cursor_x > 0) { read_cursor_x--; Redraw = 1; } break; case CURSOR_RIGHT: if (read_cursor_x < 18) { read_cursor_x++; Redraw = 1; } break; } // if any settings changed, we'll need a redraw if (Redraw == 1) { draw(CurrentScreen); } } // handle the user pressing the 'Enter' button void enterPress(void) { draw(select_screen[read_cursor_x][read_cursor_y]); } // Create the splash screen void writeSplashScreen(void) { writeln(" GPD "); writeln(" "); writeln("H/W: 1.2.3 "); writeln("S/W: 4.5.6 "); writeln(" "); writeln("INITIALIZING... "); writeln(" "); writeln(" "); } // Create the contact list screen void writeContactListScreen(char *total) { writeln(strcat(strcat(" CONTACTS (", total), ") ")); writeln(" "); writeln(" "); writeln(" "); writeln(" "); writeln(" "); writeln(" "); writeln(" "); } // Create the configuration screen void writeConfigurationScreen(void) { writeln(" CONFIGURATION "); writeln(" "); writeln(" "); writeln(" "); writeln(" "); writeln(" "); writeln(" "); writeln(" "); } // Create the system status screen void writeStatusScreen(void) { char temp[10]; // used for converting numbers to strings writeln(" STATUS "); ss_write(6, 10, write_cursor_y - 1, NAVIGATION_SCREEN); // convert battery life to a string and display sprintf(temp, "%d", GetBatteryVoltage()); write("BATTERY: "); writeln(temp); // convert time to a string and display write("TIME: "); writeln("N/A"); // convert temp to a string and display sprintf(temp, "%d C", GetTemperature()); write("TEMP: "); writeln(temp); // display audible alert voluem/level write("ALERT: "); writeln("N/A"); // display any errors write("ERR: "); writeln("N/A "); // display flash card usage write("FLASH CARD: "); writeln("N/A "); // finish the screen with whitespace writeln(" "); } // Create the navigation screen void writeNavigationScreen(void) { char xdata temp[10]; // used for converting numbers to strings writeln(" NAVIGATION "); writeln("NORTH POS "); writeln("EAST POS "); // convert temp to a string and display if (Tilt == 0) { sprintf(temp, "%d", Heading); write("HEADING: "); writeln(temp); } else { writeln("HEADING: TILT!"); } writeln(" "); writeln(" "); writeln(" "); writeln(" "); } // Create the detailed contact information screen void writeContactScreen(void) { char xdata tempstr[18]; // temporary string int xdata tempint; tempint = Contact[0].bearing; // form up and print the title bar sprintf(tempstr, " CONTACT %c ", Contact[0].id); writeln(tempstr); printf("tempstr = %s, Contact[0].id = %c\r\n", tempstr, Contact[0].id); // form up and print the name writeln("NAM: "); // form up and print the bearing sprintf(tempstr, "BRG: %d ", tempint); writeln(tempstr); printf(tempstr); writeln(" "); writeln(" "); writeln(" "); writeln(" "); writeln(" "); writeln(" "); } // Create the navigation screen void writeContactMapScreen(void) { writeln(" CONTACT MAP "); writeln(" %% %%"); writeln(" % %"); writeln(" "); writeln(" + "); writeln(" "); writeln(" % %"); writeln(" %% %%"); } // draw the requested screen void draw(unsigned char screen) { // int j = 0x20; // make sure our display looks happy RefreshDisplay(); // if instructed to draw the CURRENT_SCREEN set screen = CurrentScreen if (screen == CURRENT_SCREEN) { screen = CurrentScreen; } else { // save which screen we're drawing CurrentScreen = screen; } switch (screen) { case SPLASH_SCREEN: writeSplashScreen(); break; case STATUS_SCREEN: writeStatusScreen(); break; case NAVIGATION_SCREEN: writeNavigationScreen(); break; case CONTACT_SCREEN: writeContactScreen(); break; } // now display the screen that we just created displayscreen(); // now that we've draw a screen, the Redraw flag can be reset Redraw = 0; }