Library for Nuelectronics Nokia 3310/5110 LCD Display and joystick.
Fork of N3310LCD by
N3310LCD.cpp
00001 /* 00002 * N3310LCD. A program to interface mbed with the nuelectronics 00003 * Nokia 3310 LCD shield from www.nuelectronics.com. Ported from 00004 * the nuelectronics Arduino code. 00005 * 00006 * Copyright (C) <2009> Petras Saduikis <petras@petras.co.uk> 00007 * 00008 * Converted to a mbed library by Andrew D. Lindsay 00009 * 00010 * This file is part of N3310LCD. 00011 * 00012 * N3310LCD is free software: you can redistribute it and/or modify 00013 * it under the terms of the GNU General Public License as published by 00014 * the Free Software Foundation, either version 3 of the License, or 00015 * (at your option) any later version. 00016 * 00017 * N3310LCD is distributed in the hope that it will be useful, 00018 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 * GNU General Public License for more details. 00021 * 00022 * You should have received a copy of the GNU General Public License 00023 * along with N3310LCD. If not, see <http://www.gnu.org/licenses/>. 00024 */ 00025 00026 #include "N3310LCD.h" 00027 #include "N3310Fonts.h" 00028 #include "variables.h" 00029 00030 int contrast = 0xB5; 00031 00032 static unsigned char lcd_buffer[LCDROWMAX][LCDCOLMAX]; 00033 // current cursor postition 00034 static unsigned char cursor_row = 0; /* 0-5 */ 00035 static unsigned char cursor_col = 0; /* 0-83 */ 00036 unsigned char *fontStart; // Start of font data 00037 int8_t fontWidth; // Font width 00038 int8_t fontHeight; // Font height 00039 int16_t fontStartChar; // Start, usually 32 00040 int16_t fontEndChar; // End character, usually 127 or 128 00041 00042 N3310LCD::N3310LCD (PinName mosi, PinName miso, PinName sck, 00043 PinName ce, PinName dat_cmd, PinName lcd_rst, PinName bl_on) : 00044 lcdPort(mosi, miso, sck), 00045 ceWire(ce), dcWire(dat_cmd), rstWire(lcd_rst), blWire(bl_on) { 00046 } 00047 00048 void N3310LCD::init() 00049 { 00050 // use default SPI format 00051 lcdPort.format(8,0); 00052 lcdPort.frequency(8000000); // Lets try 8MHz 00053 00054 // lcd reset 00055 wait_ms(1); 00056 rstWire = 0; 00057 wait_ms(1); 00058 rstWire = 1; 00059 00060 writeCommand(0x21); // LCD Extended Commands 00061 writeCommand(contrast); // Set LCD Vop (Contrast) 00062 writeCommand(0x06); // Set temp coefficient 00063 writeCommand(0x13); // LCD bias mode1:48 00064 writeCommand(0x20); // LCD Standard Commands, Horizontal addressing mode 00065 writeCommand(0x0c); // LCD in normal mode 00066 cls(); 00067 setFont( FONT_5x7 ); 00068 00069 00070 } 00071 00072 void N3310LCD::setFont(BYTE font ) 00073 { 00074 00075 switch( font ) { 00076 case FONT_6x8: 00077 fontWidth = 6; 00078 fontHeight = 8; 00079 fontStartChar = 32; 00080 fontEndChar = 128; 00081 fontStart = font6_8; 00082 break; 00083 00084 default: 00085 fontWidth = 5; 00086 fontHeight = 7; 00087 fontStartChar = 32; 00088 fontEndChar = 128; 00089 fontStart = font5_7; 00090 break; 00091 } 00092 } 00093 00094 void N3310LCD::cls() 00095 { 00096 writeCommand(0x40); // column 00097 writeCommand(0x80); // row 00098 for(int i=0; i< LCDROWMAX; i++) { 00099 for(int j=0; j< LCDCOLMAX; j++) { 00100 writeData( 0x00 ); 00101 lcd_buffer[i][j] = 0x00; 00102 } 00103 } 00104 } 00105 00106 void N3310LCD::backlight(eBacklight state) 00107 { 00108 // switch off/on back light 00109 blWire = state; 00110 } 00111 00112 void N3310LCD::writeCommand(BYTE data) 00113 { 00114 // bring CS low for write 00115 ceWire = 0; 00116 dcWire = 0; 00117 00118 lcdPort.write(data); 00119 00120 // write finished 00121 ceWire = 1; 00122 } 00123 00124 void N3310LCD::writeData(BYTE data) 00125 { 00126 // bring CS low for write 00127 ceWire = 0; 00128 dcWire = 1; 00129 00130 lcdPort.write(data); 00131 00132 // write finished 00133 ceWire = 1; 00134 } 00135 00136 void N3310LCD::locate(BYTE xPos, BYTE yPos) 00137 { 00138 writeCommand(0x40 | yPos); // column 00139 writeCommand(0x80 | xPos); // row 00140 cursor_row = yPos; 00141 cursor_col = xPos; 00142 } 00143 00144 void N3310LCD::drawBitmap(BYTE xPos, BYTE yPos, BYTE* bitmap, BYTE bmpXSize, BYTE bmpYSize) 00145 { 00146 BYTE row; 00147 00148 if (0 == bmpYSize % 8) 00149 row = bmpYSize/8; 00150 else 00151 row = bmpYSize/8 + 1; 00152 00153 for (BYTE n = 0; n < row; n++) { 00154 locate(xPos, yPos); 00155 for(BYTE i = 0; i < bmpXSize; i++) { 00156 writeData(bitmap[i + (n * bmpXSize)]); 00157 } 00158 yPos++; 00159 } 00160 } 00161 00162 /* 00163 * Name : clearBitmap 00164 * Description : Clear an area of the screen, usually to blank out a 00165 * previously drawn image or part of image. 00166 * Argument(s) : x, y - Position on screen, x 0-83, y 1-6 00167 * size_x,size_y - Size of the image in pixels, 00168 * size_y is multiple of 8 00169 * Return value : none 00170 */ 00171 void N3310LCD::clearBitmap( unsigned char x,unsigned char y, 00172 unsigned char size_x,unsigned char size_y) 00173 { 00174 unsigned int i,n; 00175 unsigned char row; 00176 00177 row = (size_y % 8 == 0 ) ? size_y / 8 : size_y / 8 + 1; 00178 00179 for (n=0; n<row; n++) { 00180 locate(x,y); 00181 for(i=0; i<size_x; i++) { 00182 writeData( 0x00 ); 00183 } 00184 y++; 00185 } 00186 } 00187 00188 void N3310LCD::writeString(BYTE xPos, BYTE yPos, char* string, eDisplayMode mode) 00189 { 00190 locate(xPos, yPos); 00191 00192 while (*string) { 00193 writeChar(*string++, mode); 00194 } 00195 } 00196 00197 void N3310LCD::writeStringBig(BYTE xPos, BYTE yPos, char* string, eDisplayMode mode) 00198 { 00199 while (*string) { 00200 writeCharBig(xPos, yPos, *string , mode); 00201 00202 if('.' == *string++) 00203 xPos += 5; 00204 else 00205 xPos += 12; 00206 } 00207 } 00208 00209 void N3310LCD::writeChar(BYTE ch, eDisplayMode mode) 00210 { 00211 ch -= fontStartChar; 00212 00213 if (cursor_col > LCDCOLMAX - (fontWidth+1)) cursor_col = LCDCOLMAX - (fontWidth+1); // ensure space is available for the character 00214 if (cursor_row > LCDROWMAX - 1) cursor_row = LCDROWMAX - 1; // ensure space is available for the character 00215 lcd_buffer[cursor_row][cursor_col] = 0x00; 00216 for(int8_t j=0; j< fontHeight; j++) { 00217 lcd_buffer[cursor_row][cursor_col + j] = fontStart[(ch)*fontWidth + j]; 00218 } 00219 00220 lcd_buffer[cursor_row][cursor_col + fontWidth] = 0x00; 00221 00222 for(int8_t j=0; j< (fontWidth+1); j++) { 00223 if( mode == NORMAL ) 00224 writeData(lcd_buffer[cursor_row][cursor_col++]); 00225 else 00226 writeData(lcd_buffer[cursor_row][cursor_col++] ^ 0xff); 00227 if (cursor_col >= LCDCOLMAX) { 00228 cursor_col=0; 00229 cursor_row++; 00230 if (cursor_row >= LCDROWMAX) cursor_row=0; 00231 } 00232 } 00233 } 00234 00235 int N3310LCD::_putc(int c) { 00236 writeChar(c, NORMAL); 00237 return c; 00238 } 00239 int N3310LCD::_getc() { 00240 return -1; 00241 } 00242 00243 void N3310LCD::writeCharBig(BYTE xPos, BYTE yPos, BYTE ch, eDisplayMode mode) 00244 { 00245 BYTE sendByte; 00246 int8_t colsUsed = 12; 00247 unsigned char* pFont = (unsigned char *) big_number; 00248 00249 00250 if(ch == '.') { 00251 ch = 10; 00252 colsUsed=5; 00253 } else if (ch == '+') 00254 ch = 11; 00255 else if (ch == '-') 00256 ch = 12; 00257 else if (ch == ':') 00258 ch = 13; 00259 else if (ch == '/') 00260 ch = 14; 00261 else 00262 ch = ch & 0x0f; 00263 00264 /* 00265 for(BYTE i = 0; i < 3; i++) { 00266 locate(xPos, yPos + i); 00267 00268 for(BYTE j = 0; j < 16; j++) { 00269 sendByte = *(pFont + ch*48 + i*16 + j); 00270 writeData((mode == NORMAL)? sendByte : (sendByte^0xff)); 00271 } 00272 } 00273 */ 00274 if (xPos > LCDCOLMAX - colsUsed) xPos = LCDCOLMAX - colsUsed ; // ensure space is available for the character 00275 if (yPos > LCDROWMAX - 3) yPos = LCDROWMAX - 3 ; // ensure space is available for the character 00276 00277 for(int8_t i=0; i<3; i++) { 00278 locate( xPos, yPos + i); 00279 00280 for(int8_t j=0; j<colsUsed; j++) { 00281 sendByte = *(pFont + ch*48 + i*16 + j); 00282 lcd_buffer[cursor_row][cursor_col + j] = (mode == NORMAL)? sendByte : (sendByte^0xff); 00283 writeData( lcd_buffer[cursor_row][cursor_col + j] ); 00284 } 00285 } 00286 } 00287 00288 /* 00289 * Name : setPixel 00290 * Description : Set a single pixel either on or off, update display buffer. 00291 * Argument(s) : x,y - position, x = 0-83, y = 0-6 00292 * c - colour, either PIXEL_ON, PIXEL_OFF or PIXEL_XOR 00293 * Return value : none 00294 */ 00295 void N3310LCD::setPixel( unsigned char x, unsigned char y, unsigned char c ) 00296 { 00297 unsigned char value; 00298 unsigned char row; 00299 00300 // if( x < 0 || x >= LCDCOLMAX || y < 0 || y >= LCDPIXELROWMAX ) return; 00301 if( x >= LCDCOLMAX || y >= LCDPIXELROWMAX ) return; 00302 00303 row = y / 8; 00304 00305 value = lcd_buffer[row][x]; 00306 if( c == PIXEL_ON ) { 00307 value |= (1 << (y % 8)); 00308 } else if( c == PIXEL_XOR ) { 00309 value ^= (1 << (y % 8)); 00310 } else { 00311 value &= ~(1 << (y % 8)); 00312 } 00313 00314 lcd_buffer[row][x] = value; 00315 locate (x,row); 00316 writeData(value); 00317 } 00318 00319 00320 /* 00321 * Name : drawLine 00322 * Description : Draws a line between two points on the display. 00323 * Argument(s) : x1, y1 - Absolute pixel coordinates for line origin. 00324 * x2, y2 - Absolute pixel coordinates for line end. 00325 * c - either PIXEL_ON, PIXEL_OFF or PIXEL_XOR 00326 * Return value : none 00327 */ 00328 void N3310LCD::drawLine(unsigned char x1, unsigned char y1, 00329 unsigned char x2, unsigned char y2, unsigned char c) 00330 { 00331 int dx, dy, stepx, stepy, fraction; 00332 00333 /* Calculate differential form */ 00334 /* dy y2 - y1 */ 00335 /* -- = ------- */ 00336 /* dx x2 - x1 */ 00337 00338 /* Take differences */ 00339 dy = y2 - y1; 00340 dx = x2 - x1; 00341 00342 /* dy is negative */ 00343 if ( dy < 0 ) { 00344 dy = -dy; 00345 stepy = -1; 00346 } else { 00347 stepy = 1; 00348 } 00349 00350 /* dx is negative */ 00351 if ( dx < 0 ) { 00352 dx = -dx; 00353 stepx = -1; 00354 } else { 00355 stepx = 1; 00356 } 00357 00358 dx <<= 1; 00359 dy <<= 1; 00360 00361 /* Draw initial position */ 00362 setPixel( x1, y1, c ); 00363 00364 /* Draw next positions until end */ 00365 if ( dx > dy ) { 00366 /* Take fraction */ 00367 fraction = dy - ( dx >> 1); 00368 while ( x1 != x2 ) { 00369 if ( fraction >= 0 ) { 00370 y1 += stepy; 00371 fraction -= dx; 00372 } 00373 x1 += stepx; 00374 fraction += dy; 00375 00376 /* Draw calculated point */ 00377 setPixel( x1, y1, c ); 00378 } 00379 } else { 00380 /* Take fraction */ 00381 fraction = dx - ( dy >> 1); 00382 while ( y1 != y2 ) { 00383 if ( fraction >= 0 ) { 00384 x1 += stepx; 00385 fraction -= dy; 00386 } 00387 y1 += stepy; 00388 fraction += dx; 00389 00390 /* Draw calculated point */ 00391 setPixel( x1, y1, c ); 00392 } 00393 } 00394 } 00395 00396 00397 /* 00398 * Name : drawRectangle 00399 * Description : Draw a rectangle given to top left and bottom right points 00400 * Argument(s) : x1, y1 - Absolute pixel coordinates for top left corner 00401 * x2, y2 - Absolute pixel coordinates for bottom right corner 00402 * c - either PIXEL_ON, PIXEL_OFF or PIXEL_XOR 00403 * Return value : none 00404 */ 00405 void N3310LCD::drawRectangle(unsigned char x1, unsigned char y1, 00406 unsigned char x2, unsigned char y2, unsigned char c) 00407 { 00408 drawLine( x1, y1, x2, y1, c ); 00409 drawLine( x1, y1, x1, y2, c ); 00410 drawLine( x1, y2, x2, y2, c ); 00411 drawLine( x2, y1, x2, y2, c ); 00412 } 00413 00414 00415 /* 00416 * Name : drawFilledRectangle 00417 * Description : Draw a filled rectangle given to top left and bottom right points 00418 * just simply draws horizontal lines where the rectangle would be 00419 * Argument(s) : x1, y1 - Absolute pixel coordinates for top left corner 00420 * x2, y2 - Absolute pixel coordinates for bottom right corner 00421 * c - either PIXEL_ON, PIXEL_OFF or PIXEL_XOR 00422 * Return value : none 00423 */ 00424 void N3310LCD::drawFilledRectangle(unsigned char x1, unsigned char y1, 00425 unsigned char x2, unsigned char y2, unsigned char c) 00426 { 00427 for(int i=y1; i <= y2; i++ ) { 00428 drawLine( x1, i, x2, i, c ); 00429 } 00430 } 00431 00432 00433 /* 00434 * Name : drawCircle 00435 * Description : Draw a circle using Bresenham's algorithm. 00436 * Some small circles will look like squares!! 00437 * Argument(s) : xc, yc - Centre of circle 00438 * r - Radius 00439 * c - either PIXEL_ON, PIXEL_OFF or PIXEL_XOR 00440 * Return value : None 00441 */ 00442 void N3310LCD::drawCircle(unsigned char xc, unsigned char yc, 00443 unsigned char r, unsigned char c) 00444 { 00445 int x=0; 00446 int y=r; 00447 int p=3-(2*r); 00448 00449 setPixel( (uint8_t)(xc+x),(uint8_t)(yc-y), c); 00450 00451 for(x=0; x<=y; x++) { 00452 if (p<0) { 00453 y=y; 00454 p=(p+(4*x)+6); 00455 } else { 00456 y=y-1; 00457 p=p+((4*(x-y)+10)); 00458 } 00459 00460 setPixel((uint8_t)(xc+x),(uint8_t)(yc-y), c); 00461 setPixel((uint8_t)(xc-x),(uint8_t)(yc-y), c); 00462 setPixel((uint8_t)(xc+x),(uint8_t)(yc+y), c); 00463 setPixel((uint8_t)(xc-x),(uint8_t)(yc+y), c); 00464 setPixel((uint8_t)(xc+y),(uint8_t)(yc-x), c); 00465 setPixel((uint8_t)(xc-y),(uint8_t)(yc-x), c); 00466 setPixel((uint8_t)(xc+y),(uint8_t)(yc+x), c); 00467 setPixel((uint8_t)(xc-y),(uint8_t)(yc+x), c); 00468 } 00469 }
Generated on Wed Jul 13 2022 14:26:13 by 1.7.2