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-10
- Revision:
- 0:7efa6655d94b
- Child:
- 1:51961974fe55
File content as of revision 0:7efa6655d94b:
/* * 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]; 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(1000000); // lcd reset wait_ms(1); rstWire = 0; wait_ms(1); rstWire = 1; write(0x21, CMD); write(0xc8, CMD); write(0x06, CMD); write(0x13, CMD); write(0x20, CMD); cls(); write(0x0c, CMD); } void N3310LCD::cls() { write(0x0c, CMD); write(0x80, CMD); for (int i = 0; i < 504; i++) { write(0, DATA); } } void N3310LCD::backlight(eBacklight state) { // switch off/on back light blWire = state; } void N3310LCD::write(BYTE data, eRequestType req_type) { // bring CS low for write ceWire = 0; if (CMD == req_type) dcWire = 0; else // DATA dcWire = 1; lcdPort.write(data); // write finished ceWire = 1; } void N3310LCD::locate(BYTE xPos, BYTE yPos) { write(0x40 | yPos, CMD); // column write(0x80 | xPos, CMD); // row } 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++) { write(bitmap[i + (n * bmpXSize)], DATA); } 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; // if (size_y % 8==0) // row=size_y/8; // else // row=size_y/8+1; for (n=0;n<row;n++) { locate(x,y); for(i=0; i<size_x; i++) { write( 0x00, DATA ); } 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) { BYTE sendByte; unsigned char* pFont = (unsigned char*)font6_8; ch -= 32; for (BYTE line = 0; line < 6; line++) { sendByte = *(pFont + ch*6 + line); write((mode == NORMAL)? sendByte: (sendByte ^ 0xff) , DATA); } } void N3310LCD::writeCharBig(BYTE xPos, BYTE yPos, BYTE ch, eDisplayMode mode) { BYTE sendByte; unsigned char* pFont = (unsigned char *) big_number; if('.' == ch) ch = 10; else if ('+' == ch) ch = 11; else if ('-' == ch) ch = 12; 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); write((mode == NORMAL)? sendByte : (sendByte^0xff), DATA); } } } /* * 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); write(value, DATA); } /* * 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); } }