Library for Nuelectronics Nokia 3310/5110 LCD Display and joystick.
Fork of N3310LCD by
Library for Nuelectronics Nokia 3310/5110 LCD Display and joystick.
N3310LCD.cpp
- Committer:
- SomeRandomBloke
- Date:
- 2013-03-27
- Revision:
- 5:1fd7af32e521
- Parent:
- 4:90dce6032a37
- Child:
- 6:46bcc4e584c4
File content as of revision 5:1fd7af32e521:
/* * N3310LCD. A program to interface mbed with the nuelectronics * Nokia 3310 LCD shield from www.nuelectronics.com. Ported from * the nuelectronics Arduino code. * * Copyright (C) <2009> Petras Saduikis <petras@petras.co.uk> * * Converted to a mbed library by Andrew D. Lindsay * * This file is part of N3310LCD. * * N3310LCD 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 3 of the License, or * (at your option) any later version. * * N3310LCD 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 N3310LCD. If not, see <http://www.gnu.org/licenses/>. */ #include "N3310LCD.h" #include "N3310Fonts.h" static unsigned char lcd_buffer[LCDROWMAX][LCDCOLMAX]; // current cursor postition static unsigned char cursor_row = 0; /* 0-5 */ static unsigned char cursor_col = 0; /* 0-83 */ unsigned char *fontStart; // Start of font data int8_t fontWidth; // Font width int8_t fontHeight; // Font height int16_t fontStartChar; // Start, usually 32 int16_t fontEndChar; // End character, usually 127 or 128 N3310LCD::N3310LCD (PinName mosi, PinName miso, PinName sck, PinName ce, PinName dat_cmd, PinName lcd_rst, PinName bl_on) : lcdPort(mosi, miso, sck), ceWire(ce), dcWire(dat_cmd), rstWire(lcd_rst), blWire(bl_on) { } void N3310LCD::init() { // use default SPI format lcdPort.format(8,0); lcdPort.frequency(8000000); // Lets try 8MHz // lcd reset wait_ms(1); rstWire = 0; wait_ms(1); rstWire = 1; writeCommand(0x21); // LCD Extended Commands writeCommand(0xC0); // Set LCD Vop (Contrast) writeCommand(0x06); // Set temp coefficient writeCommand(0x13); // LCD bias mode1:48 writeCommand(0x20); // LCD Standard Commands, Horizontal addressing mode writeCommand(0x0c); // LCD in normal mode cls(); setFont( FONT_5x7 ); // setFont( FONT_6x8 ); } void N3310LCD::setFont(BYTE font ) { switch( font ) { case FONT_6x8: fontWidth = 6; fontHeight = 8; fontStartChar = 32; fontEndChar = 128; fontStart = font6_8; break; /* case FONT_ALPHA_17x17: fontWidth = 17; fontHeight = 17; fontStartChar = 65; fontEndChar = 91; fontStart = Liberation_Sans17x17_Alpha; break; */ default: fontWidth = 5; fontHeight = 7; fontStartChar = 32; fontEndChar = 128; fontStart = font5_7; break; } } void N3310LCD::cls() { writeCommand(0x40); // column writeCommand(0x80); // row for(int i=0; i< LCDROWMAX; i++) { for(int j=0; j< LCDCOLMAX; j++) { writeData( 0x00 ); lcd_buffer[i][j] = 0x00; } } } void N3310LCD::backlight(eBacklight state) { // switch off/on back light blWire = state; } void N3310LCD::writeCommand(BYTE data) { // bring CS low for write ceWire = 0; dcWire = 0; lcdPort.write(data); // write finished ceWire = 1; } void N3310LCD::writeData(BYTE data) { // bring CS low for write ceWire = 0; dcWire = 1; lcdPort.write(data); // write finished ceWire = 1; } void N3310LCD::locate(BYTE xPos, BYTE yPos) { writeCommand(0x40 | yPos); // column writeCommand(0x80 | xPos); // row cursor_row = yPos; cursor_col = xPos; } void N3310LCD::drawBitmap(BYTE xPos, BYTE yPos, BYTE* bitmap, BYTE bmpXSize, BYTE bmpYSize) { BYTE row; if (0 == bmpYSize % 8) row = bmpYSize/8; else row = bmpYSize/8 + 1; for (BYTE n = 0; n < row; n++) { locate(xPos, yPos); for(BYTE i = 0; i < bmpXSize; i++) { writeData(bitmap[i + (n * bmpXSize)]); } yPos++; } } /* * Name : clearBitmap * Description : Clear an area of the screen, usually to blank out a * previously drawn image or part of image. * Argument(s) : x, y - Position on screen, x 0-83, y 1-6 * size_x,size_y - Size of the image in pixels, * size_y is multiple of 8 * Return value : none */ void N3310LCD::clearBitmap( unsigned char x,unsigned char y, unsigned char size_x,unsigned char size_y) { unsigned int i,n; unsigned char row; row = (size_y % 8 == 0 ) ? size_y / 8 : size_y / 8 + 1; for (n=0; n<row; n++) { locate(x,y); for(i=0; i<size_x; i++) { writeData( 0x00 ); } y++; } } void N3310LCD::writeString(BYTE xPos, BYTE yPos, char* string, eDisplayMode mode) { locate(xPos, yPos); while (*string) { writeChar(*string++, mode); } } void N3310LCD::writeStringBig(BYTE xPos, BYTE yPos, char* string, eDisplayMode mode) { while (*string) { writeCharBig(xPos, yPos, *string , mode); if('.' == *string++) xPos += 5; else xPos += 12; } } void N3310LCD::writeChar(BYTE ch, eDisplayMode mode) { ch -= fontStartChar; if (cursor_col > LCDCOLMAX - (fontWidth+1)) cursor_col = LCDCOLMAX - (fontWidth+1); // ensure space is available for the character if (cursor_row > LCDROWMAX - 1) cursor_row = LCDROWMAX - 1; // ensure space is available for the character lcd_buffer[cursor_row][cursor_col] = 0x00; for(int8_t j=0; j< fontHeight; j++) { lcd_buffer[cursor_row][cursor_col + j] = fontStart[(ch)*fontWidth + j]; } lcd_buffer[cursor_row][cursor_col + fontWidth] = 0x00; for(int8_t j=0; j< (fontWidth+1); j++) { if( mode == NORMAL ) writeData(lcd_buffer[cursor_row][cursor_col++]); else writeData(lcd_buffer[cursor_row][cursor_col++] ^ 0xff); if (cursor_col >= LCDCOLMAX) { cursor_col=0; cursor_row++; if (cursor_row >= LCDROWMAX) cursor_row=0; } } } int N3310LCD::_putc(int c) { writeChar(c, NORMAL); return c; } int N3310LCD::_getc() { return -1; } void N3310LCD::writeCharBig(BYTE xPos, BYTE yPos, BYTE ch, eDisplayMode mode) { BYTE sendByte; int8_t colsUsed = 12; unsigned char* pFont = (unsigned char *) big_number; if(ch == '.') { ch = 10; colsUsed=5; } else if (ch == '+') ch = 11; else if (ch == '-') ch = 12; else if (ch == ':') ch = 13; else if (ch == '/') ch = 14; else ch = ch & 0x0f; /* for(BYTE i = 0; i < 3; i++) { locate(xPos, yPos + i); for(BYTE j = 0; j < 16; j++) { sendByte = *(pFont + ch*48 + i*16 + j); writeData((mode == NORMAL)? sendByte : (sendByte^0xff)); } } */ if (xPos > LCDCOLMAX - colsUsed) xPos = LCDCOLMAX - colsUsed ; // ensure space is available for the character if (yPos > LCDROWMAX - 3) yPos = LCDROWMAX - 3 ; // ensure space is available for the character for(int8_t i=0; i<3; i++) { locate( xPos, yPos + i); for(int8_t j=0; j<colsUsed; j++) { sendByte = *(pFont + ch*48 + i*16 + j); lcd_buffer[cursor_row][cursor_col + j] = (mode == NORMAL)? sendByte : (sendByte^0xff); writeData( lcd_buffer[cursor_row][cursor_col + j] ); } } } /* * Name : setPixel * Description : Set a single pixel either on or off, update display buffer. * Argument(s) : x,y - position, x = 0-83, y = 0-6 * c - colour, either PIXEL_ON, PIXEL_OFF or PIXEL_XOR * Return value : none */ void N3310LCD::setPixel( unsigned char x, unsigned char y, unsigned char c ) { unsigned char value; unsigned char row; // if( x < 0 || x >= LCDCOLMAX || y < 0 || y >= LCDPIXELROWMAX ) return; if( x >= LCDCOLMAX || y >= LCDPIXELROWMAX ) return; row = y / 8; value = lcd_buffer[row][x]; if( c == PIXEL_ON ) { value |= (1 << (y % 8)); } else if( c == PIXEL_XOR ) { value ^= (1 << (y % 8)); } else { value &= ~(1 << (y % 8)); } lcd_buffer[row][x] = value; locate (x,row); writeData(value); } /* * Name : drawLine * Description : Draws a line between two points on the display. * Argument(s) : x1, y1 - Absolute pixel coordinates for line origin. * x2, y2 - Absolute pixel coordinates for line end. * c - either PIXEL_ON, PIXEL_OFF or PIXEL_XOR * Return value : none */ void N3310LCD::drawLine(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2, unsigned char c) { int dx, dy, stepx, stepy, fraction; /* Calculate differential form */ /* dy y2 - y1 */ /* -- = ------- */ /* dx x2 - x1 */ /* Take differences */ dy = y2 - y1; dx = x2 - x1; /* dy is negative */ if ( dy < 0 ) { dy = -dy; stepy = -1; } else { stepy = 1; } /* dx is negative */ if ( dx < 0 ) { dx = -dx; stepx = -1; } else { stepx = 1; } dx <<= 1; dy <<= 1; /* Draw initial position */ setPixel( x1, y1, c ); /* Draw next positions until end */ if ( dx > dy ) { /* Take fraction */ fraction = dy - ( dx >> 1); while ( x1 != x2 ) { if ( fraction >= 0 ) { y1 += stepy; fraction -= dx; } x1 += stepx; fraction += dy; /* Draw calculated point */ setPixel( x1, y1, c ); } } else { /* Take fraction */ fraction = dx - ( dy >> 1); while ( y1 != y2 ) { if ( fraction >= 0 ) { x1 += stepx; fraction -= dy; } y1 += stepy; fraction += dx; /* Draw calculated point */ setPixel( x1, y1, c ); } } } /* * Name : drawRectangle * Description : Draw a rectangle given to top left and bottom right points * Argument(s) : x1, y1 - Absolute pixel coordinates for top left corner * x2, y2 - Absolute pixel coordinates for bottom right corner * c - either PIXEL_ON, PIXEL_OFF or PIXEL_XOR * Return value : none */ void N3310LCD::drawRectangle(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2, unsigned char c) { drawLine( x1, y1, x2, y1, c ); drawLine( x1, y1, x1, y2, c ); drawLine( x1, y2, x2, y2, c ); drawLine( x2, y1, x2, y2, c ); } /* * Name : drawFilledRectangle * Description : Draw a filled rectangle given to top left and bottom right points * just simply draws horizontal lines where the rectangle would be * Argument(s) : x1, y1 - Absolute pixel coordinates for top left corner * x2, y2 - Absolute pixel coordinates for bottom right corner * c - either PIXEL_ON, PIXEL_OFF or PIXEL_XOR * Return value : none */ void N3310LCD::drawFilledRectangle(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2, unsigned char c) { for(int i=y1; i <= y2; i++ ) { drawLine( x1, i, x2, i, c ); } } /* * Name : drawCircle * Description : Draw a circle using Bresenham's algorithm. * Some small circles will look like squares!! * Argument(s) : xc, yc - Centre of circle * r - Radius * c - either PIXEL_ON, PIXEL_OFF or PIXEL_XOR * Return value : None */ void N3310LCD::drawCircle(unsigned char xc, unsigned char yc, unsigned char r, unsigned char c) { int x=0; int y=r; int p=3-(2*r); setPixel( (uint8_t)(xc+x),(uint8_t)(yc-y), c); for(x=0; x<=y; x++) { if (p<0) { y=y; p=(p+(4*x)+6); } else { y=y-1; p=p+((4*(x-y)+10)); } setPixel((uint8_t)(xc+x),(uint8_t)(yc-y), c); setPixel((uint8_t)(xc-x),(uint8_t)(yc-y), c); setPixel((uint8_t)(xc+x),(uint8_t)(yc+y), c); setPixel((uint8_t)(xc-x),(uint8_t)(yc+y), c); setPixel((uint8_t)(xc+y),(uint8_t)(yc-x), c); setPixel((uint8_t)(xc-y),(uint8_t)(yc-x), c); setPixel((uint8_t)(xc+y),(uint8_t)(yc+x), c); setPixel((uint8_t)(xc-y),(uint8_t)(yc+x), c); } }