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

Dependents:   N3310LCD_Demo FRDM_N3110LCD

Revision:
3:9808f63fd2fe
Parent:
1:51961974fe55
Child:
4:90dce6032a37
--- a/N3310LCD.cpp	Fri Mar 15 08:01:22 2013 +0000
+++ b/N3310LCD.cpp	Sun Mar 24 15:15:08 2013 +0000
@@ -27,6 +27,12 @@
 #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
 
 N3310LCD::N3310LCD (PinName mosi, PinName miso, PinName sck,
                     PinName ce, PinName dat_cmd, PinName lcd_rst, PinName bl_on) :
@@ -39,7 +45,7 @@
 {
     // use default SPI format
     lcdPort.format(8,0);
-    lcdPort.frequency(1000000);
+    lcdPort.frequency(2000000);
 
     // lcd reset
     wait_ms(1);
@@ -47,22 +53,45 @@
     wait_ms(1);
     rstWire = 1;
 
-    write(0x21, CMD);
-    write(0xc8, CMD);
-    write(0x06, CMD);
-    write(0x13, CMD);
-    write(0x20, CMD);
+    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();
-    write(0x0c, CMD);
+    setFont( FONT_5x7 );
+//    setFont( FONT_6x8 );
+
+}
+
+void N3310LCD::setFont(BYTE font )
+{
+
+    switch( font ) {
+        case FONT_6x8:
+            fontWidth = 6;
+            fontHeight = 8;
+            fontStart = font6_8;
+            break;
+        default:
+            fontWidth = 5;
+            fontHeight = 7;
+            fontStart = font5_7;
+            break;
+    }
+
 }
 
 void N3310LCD::cls()
 {
-    write(0x0c, CMD);
-    write(0x80, CMD);
-
-    for (int i = 0; i < 504; i++) {
-        write(0, DATA);
+    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;
+        }
     }
 }
 
@@ -72,15 +101,23 @@
     blWire = state;
 }
 
-void N3310LCD::write(BYTE data, eRequestType req_type)
+void N3310LCD::writeCommand(BYTE data)
 {
     // bring CS low for write
     ceWire = 0;
+    dcWire = 0;
 
-    if (CMD == req_type)
-        dcWire = 0;
-    else // DATA
-        dcWire = 1;
+    lcdPort.write(data);
+
+    // write finished
+    ceWire = 1;
+}
+
+void N3310LCD::writeData(BYTE data)
+{
+    // bring CS low for write
+    ceWire = 0;
+    dcWire = 1;
 
     lcdPort.write(data);
 
@@ -90,8 +127,10 @@
 
 void N3310LCD::locate(BYTE xPos, BYTE yPos)
 {
-    write(0x40 | yPos, CMD);      // column
-    write(0x80 | xPos, CMD);      // row
+    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)
@@ -106,7 +145,7 @@
     for (BYTE n = 0; n < row; n++) {
         locate(xPos, yPos);
         for(BYTE i = 0; i < bmpXSize; i++) {
-            write(bitmap[i + (n * bmpXSize)], DATA);
+            writeData(bitmap[i + (n * bmpXSize)]);
         }
         yPos++;
     }
@@ -128,15 +167,11 @@
     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 );
+            writeData( 0x00 );
         }
         y++;
     }
@@ -165,40 +200,90 @@
 
 void N3310LCD::writeChar(BYTE ch, eDisplayMode mode)
 {
-    BYTE sendByte;
+//   BYTE sendByte;
 
-    unsigned char* pFont = (unsigned char*)font6_8;
-    ch -= 32;
+ //   unsigned char* pFont = (unsigned char*)font6_8;
+//    ch -= 32;
+    /*
+        for (BYTE line = 0; line < 6; line++) {
+            sendByte = *(pFont + ch*6 + line);
+            writeData((mode == NORMAL)? sendByte: (sendByte ^ 0xff));
+        }
+    */
 
-    for (BYTE line = 0; line < 6; line++) {
-        sendByte = *(pFont + ch*6 + line);
-        write((mode == NORMAL)? sendByte: (sendByte ^ 0xff) , DATA);
+    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-32)*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;
+        }
+    }
+
+
 }
 
 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)
+
+    if(ch == '.') {
         ch = 10;
-    else if ('+' == ch)
+        colsUsed=5;
+    } else if (ch == '+')
         ch = 11;
-    else if ('-' == ch)
+    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 i = 0; i < 3; i++) {
+            locate(xPos, yPos + i);
 
-        for(BYTE j = 0; j < 16; j++) {
+            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);
-            write((mode == NORMAL)? sendByte : (sendByte^0xff), DATA);
+//       ch_dat =  pFont[ch*48 + i*16 +j];  // 16 cols in data for char even if we use fewer.
+            //ch_dat =  pgm_read_byte(pFont+ch*48 + i*12 +j);    // 12 cols in data for char even if we use fewer.
+            lcd_buffer[cursor_row][cursor_col + j] = (mode == NORMAL)? sendByte : (sendByte^0xff);
+
+            writeData( (mode == NORMAL)? sendByte : (sendByte^0xff));
         }
     }
+
+
+
 }
 
 /*
@@ -230,7 +315,7 @@
     lcd_buffer[row][x] = value;
 
     locate (x,row);
-    write(value, DATA);
+    writeData(value);
 }