Library for Nuelectronics Nokia 3310/5110 LCD Display and joystick.

Dependents:   N3310LCD_Demo FRDM_N3110LCD

Revision:
0:7efa6655d94b
Child:
1:51961974fe55
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/N3310LCD.cpp	Sun Mar 10 18:15:25 2013 +0000
@@ -0,0 +1,389 @@
+/*
+* 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);
+    }
+}