This is the code used on my video series "Hybrid Supercapacitor Car Battery" for my own hardware monitoring system. THe videos can be found on madelectronengineering.com

Dependencies:   BurstSPI Fonts INA219 mbed LPC1114_WakeInterruptIn

Fork of SharpMemoryLCD by Paul Staron

Files at this revision

API Documentation at this revision

Comitter:
star297
Date:
Sun Aug 23 16:21:57 2015 +0000
Child:
1:1bd2b42b305d
Commit message:
Added Font and Image files

Changed in this revision

Fonts.lib Show annotated file Show diff for this revision Revisions of this file
Images.lib Show annotated file Show diff for this revision Revisions of this file
SharpLCD.cpp Show annotated file Show diff for this revision Revisions of this file
SharpLCD.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Fonts.lib	Sun Aug 23 16:21:57 2015 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/star297/code/Fonts/#eefff1149b13
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Images.lib	Sun Aug 23 16:21:57 2015 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/star297/code/Images/#cd5f51ea83f1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SharpLCD.cpp	Sun Aug 23 16:21:57 2015 +0000
@@ -0,0 +1,598 @@
+
+#include "mbed.h"
+#include "SharpLCD.h"
+
+const unsigned char FONT8x8[97][8] = {
+{0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00}, // columns, rows, num_bytes_per_char
+{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // space 0x20
+{0x30,0x78,0x78,0x30,0x30,0x00,0x30,0x00}, // !
+{0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00}, // "
+{0x6C,0x6C,0xFE,0x6C,0xFE,0x6C,0x6C,0x00}, // #
+{0x18,0x3E,0x60,0x3C,0x06,0x7C,0x18,0x00}, // $
+{0x00,0x63,0x66,0x0C,0x18,0x33,0x63,0x00}, // %
+{0x1C,0x36,0x1C,0x3B,0x6E,0x66,0x3B,0x00}, // &
+{0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00}, // '
+{0x0C,0x18,0x30,0x30,0x30,0x18,0x0C,0x00}, // (
+{0x30,0x18,0x0C,0x0C,0x0C,0x18,0x30,0x00}, // )
+{0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00}, // *
+{0x00,0x30,0x30,0xFC,0x30,0x30,0x00,0x00}, // +
+{0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30}, // ,
+{0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00}, // -
+{0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00}, // .
+{0x03,0x06,0x0C,0x18,0x30,0x60,0x40,0x00}, // / (forward slash)
+{0x3E,0x63,0x63,0x6B,0x63,0x63,0x3E,0x00}, // 0 0x30
+{0x18,0x38,0x58,0x18,0x18,0x18,0x7E,0x00}, // 1
+{0x3C,0x66,0x06,0x1C,0x30,0x66,0x7E,0x00}, // 2
+{0x3C,0x66,0x06,0x1C,0x06,0x66,0x3C,0x00}, // 3
+{0x0E,0x1E,0x36,0x66,0x7F,0x06,0x0F,0x00}, // 4
+{0x7E,0x60,0x7C,0x06,0x06,0x66,0x3C,0x00}, // 5
+{0x1C,0x30,0x60,0x7C,0x66,0x66,0x3C,0x00}, // 6
+{0x7E,0x66,0x06,0x0C,0x18,0x18,0x18,0x00}, // 7
+{0x3C,0x66,0x66,0x3C,0x66,0x66,0x3C,0x00}, // 8
+{0x3C,0x66,0x66,0x3E,0x06,0x0C,0x38,0x00}, // 9
+{0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x00}, // :
+{0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x30}, // ;
+{0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00}, // <
+{0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00}, // =
+{0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00}, // >
+{0x3C,0x66,0x06,0x0C,0x18,0x00,0x18,0x00}, // ?
+{0x3E,0x63,0x6F,0x69,0x6F,0x60,0x3E,0x00}, // @ 0x40
+{0x18,0x3C,0x66,0x66,0x7E,0x66,0x66,0x00}, // A
+{0x7E,0x33,0x33,0x3E,0x33,0x33,0x7E,0x00}, // B
+{0x1E,0x33,0x60,0x60,0x60,0x33,0x1E,0x00}, // C
+{0x7C,0x36,0x33,0x33,0x33,0x36,0x7C,0x00}, // D
+{0x7F,0x31,0x34,0x3C,0x34,0x31,0x7F,0x00}, // E
+{0x7F,0x31,0x34,0x3C,0x34,0x30,0x78,0x00}, // F
+{0x1E,0x33,0x60,0x60,0x67,0x33,0x1F,0x00}, // G
+{0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00}, // H
+{0x3C,0x18,0x18,0x18,0x18,0x18,0x3C,0x00}, // I
+{0x0F,0x06,0x06,0x06,0x66,0x66,0x3C,0x00}, // J
+{0x73,0x33,0x36,0x3C,0x36,0x33,0x73,0x00}, // K
+{0x78,0x30,0x30,0x30,0x31,0x33,0x7F,0x00}, // L
+{0x63,0x77,0x7F,0x7F,0x6B,0x63,0x63,0x00}, // M
+{0x63,0x73,0x7B,0x6F,0x67,0x63,0x63,0x00}, // N
+{0x3E,0x63,0x63,0x63,0x63,0x63,0x3E,0x00}, // O
+{0x7E,0x33,0x33,0x3E,0x30,0x30,0x78,0x00}, // P 0x50
+{0x3C,0x66,0x66,0x66,0x6E,0x3C,0x0E,0x00}, // Q
+{0x7E,0x33,0x33,0x3E,0x36,0x33,0x73,0x00}, // R
+{0x3C,0x66,0x30,0x18,0x0C,0x66,0x3C,0x00}, // S
+{0x7E,0x5A,0x18,0x18,0x18,0x18,0x3C,0x00}, // T
+{0x66,0x66,0x66,0x66,0x66,0x66,0x7E,0x00}, // U
+{0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00}, // V
+{0x63,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00}, // W
+{0x63,0x63,0x36,0x1C,0x1C,0x36,0x63,0x00}, // X
+{0x66,0x66,0x66,0x3C,0x18,0x18,0x3C,0x00}, // Y
+{0x7F,0x63,0x46,0x0C,0x19,0x33,0x7F,0x00}, // Z
+{0x3C,0x30,0x30,0x30,0x30,0x30,0x3C,0x00}, // [
+{0x60,0x30,0x18,0x0C,0x06,0x03,0x01,0x00}, // \ (back slash)
+{0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00}, // ]
+{0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00}, // ^
+{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF}, // _
+{0x18,0x18,0x0C,0x00,0x00,0x00,0x00,0x00}, // ` 0x60
+{0x00,0x00,0x3C,0x06,0x3E,0x66,0x3B,0x00}, // a
+{0x70,0x30,0x3E,0x33,0x33,0x33,0x6E,0x00}, // b
+{0x00,0x00,0x3C,0x66,0x60,0x66,0x3C,0x00}, // c
+{0x0E,0x06,0x3E,0x66,0x66,0x66,0x3B,0x00}, // d
+{0x00,0x00,0x3C,0x66,0x7E,0x60,0x3C,0x00}, // e
+{0x1C,0x36,0x30,0x78,0x30,0x30,0x78,0x00}, // f
+{0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x7C}, // g
+{0x70,0x30,0x36,0x3B,0x33,0x33,0x73,0x00}, // h
+{0x18,0x00,0x38,0x18,0x18,0x18,0x3C,0x00}, // i
+{0x06,0x00,0x06,0x06,0x06,0x66,0x66,0x3C}, // j
+{0x70,0x30,0x33,0x36,0x3C,0x36,0x73,0x00}, // k
+{0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00}, // l
+{0x00,0x00,0x66,0x7F,0x7F,0x6B,0x63,0x00}, // m
+{0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x00}, // n
+{0x00,0x00,0x3C,0x66,0x66,0x66,0x3C,0x00}, // o
+{0x00,0x00,0x6E,0x33,0x33,0x3E,0x30,0x78}, // p
+{0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x0F}, // q
+{0x00,0x00,0x6E,0x3B,0x33,0x30,0x78,0x00}, // r
+{0x00,0x00,0x3E,0x60,0x3C,0x06,0x7C,0x00}, // s
+{0x08,0x18,0x3E,0x18,0x18,0x1A,0x0C,0x00}, // t
+{0x00,0x00,0x66,0x66,0x66,0x66,0x3B,0x00}, // u
+{0x00,0x00,0x66,0x66,0x66,0x3C,0x18,0x00}, // v
+{0x00,0x00,0x63,0x6B,0x7F,0x7F,0x36,0x00}, // w
+{0x00,0x00,0x63,0x36,0x1C,0x36,0x63,0x00}, // x
+{0x00,0x00,0x66,0x66,0x66,0x3E,0x06,0x7C}, // y
+{0x00,0x00,0x7E,0x4C,0x18,0x32,0x7E,0x00}, // z
+{0x0E,0x18,0x18,0x70,0x18,0x18,0x0E,0x00}, // {
+{0x0C,0x0C,0x0C,0x00,0x0C,0x0C,0x0C,0x00}, // |
+{0x70,0x18,0x18,0x0E,0x18,0x18,0x70,0x00}, // }
+{0x3B,0x6E,0x00,0x00,0x00,0x00,0x00,0x00}, // ~
+{0x1C,0x36,0x36,0x1C,0x00,0x00,0x00,0x00}}; // DEL
+
+// SharpLCD commands
+#define SharpLCD_CMD_UPDATE     (0x01)
+#define SharpLCD_CMD_ALL_CLEAR  (0x04)
+
+// Macro to switch endianness on char value
+#define SWAP8(a) ((((a) & 0x80) >> 7) | (((a) & 0x40) >> 5) | (((a) & 0x20) >> 3) | (((a) & 0x10) >> 1) | (((a) & 0x08) << 1) | (((a) & 0x04) << 3) | (((a) & 0x02) << 5) | (((a) & 0x01) << 7))
+
+SharpLCD::SharpLCD(PinName mosi, PinName miso, PinName sclk, PinName chipSelect, PinName enable, PinName extcom)
+         :  spi(mosi, miso, sclk), chipSelect(chipSelect), Enable(enable), ExtCom(extcom)
+{
+	//Initialize
+	spi.frequency(3500000);// Nominal speed is 1MHz, tested working at 3MHz
+	lcdPolarity = 0;	
+	rowCount = 0;
+	memset((uint8_t*)pixelBuffer, White, sizeof(pixelBuffer));	// init full pixel buffer to White
+	memset((void*)RowState, 0, sizeof(RowState));	// init row status
+    // current pixel location
+	_x = 0;
+	_y = 0;
+	// window settings
+	_x1 = 0;
+	_x2 = 0;
+	_y1 = 0;
+	_y2 = 0;
+	 _row = 0;
+    _column = 0;
+}
+// Call this function at 55 ~ 65 Hz to keep the display up-to-date.
+void SharpLCD::toggle() {
+	ExtCom=!ExtCom;
+}
+
+void SharpLCD::enableDisplay(void) {
+    Enable = 1;
+}
+
+void SharpLCD::disableDisplay(void) {
+    Enable = 0;
+}
+
+void SharpLCD::clearImmediate() {
+	// Clear out the pixel buffer
+	memset((void*)pixelBuffer, foreground, sizeof(pixelBuffer));
+	memset((void*)RowState, 0, sizeof(RowState));
+	chipSelect = 1;
+	// send clear command to display
+	cmd[0] = (uint8_t)(SWAP8(SharpLCD_CMD_ALL_CLEAR | lcdPolarity));
+	cmd[1] = 0;	
+	spi.fastWrite(cmd[0]);
+	spi.fastWrite(cmd[1]);
+	spi.clearRX();	
+	chipSelect = 0;
+}
+
+void SharpLCD::update() {
+	//Initialize the command vector
+	cmd[0] = (uint8_t)SWAP8(SharpLCD_CMD_UPDATE);
+	cmd[1] = SWAP8(1);
+	chipSelect=1;
+	rowCount = 0;
+	display_write();
+}
+
+void SharpLCD::display_write() {	
+	while(rowCount < DISPLAY_HEIGHT) {		
+		// Determine the next line to send
+		if((RowState[rowCount / DISPLAY_BUFFER_TYPE_SIZE] & (1 << (rowCount % DISPLAY_BUFFER_TYPE_SIZE))) != 0) {
+			// Row has pixel changes, send this row to the display
+			cmd[1] = (uint8_t)SWAP8(rowCount+1);
+			
+			memcpy(&(cmd[2]), (const void*)&(pixelBuffer[rowCount*(DISPLAY_WIDTH/DISPLAY_BUFFER_TYPE_SIZE)]), DISPLAY_WIDTH / DISPLAY_BUFFER_TYPE_SIZE * sizeof(DISPLAY_BUFFER_TYPE));
+						
+			int len=sizeof(cmd);			
+			for(int i=0; i<len; i++) {		
+				spi.fastWrite(cmd[i]);		
+				}
+			// update pixel change status of this line as sent
+			RowState[rowCount / DISPLAY_BUFFER_TYPE_SIZE] &= ~(1 << (rowCount % DISPLAY_BUFFER_TYPE_SIZE));				
+		}				
+		rowCount++;
+	}
+	// send end of transfer bytes 
+	spi.fastWrite(cmd[0]);
+	spi.fastWrite(0xFF);
+	// clear SPI RX buffer
+	spi.clearRX();					
+	chipSelect = 0;		
+}
+
+void SharpLCD::pixel(int x, int y, int colour) {
+    uint8_t swapx = 7 - ((unsigned int)x & 0x07);
+	    x = ((unsigned int)x & 0xFFFFFFF8) | swapx;
+	    // determine if row has pixel changes
+	    bool change = ((pixelBuffer[((y * DISPLAY_WIDTH) + x) / DISPLAY_BUFFER_TYPE_SIZE] & (1 << (x % DISPLAY_BUFFER_TYPE_SIZE))) != ((colour & 0x01) << (x % DISPLAY_BUFFER_TYPE_SIZE)));
+		if(change) {
+            // xor operation
+            pixelBuffer[((y * DISPLAY_WIDTH) + x) / DISPLAY_BUFFER_TYPE_SIZE] ^= (1 << (x % DISPLAY_BUFFER_TYPE_SIZE));
+            // update pixel change status of this line
+            RowState[y / DISPLAY_BUFFER_TYPE_SIZE] |= (1 << (y % DISPLAY_BUFFER_TYPE_SIZE));
+		}
+	}
+    
+int SharpLCD::_putc(int value) {
+    if(value == '\n') {
+        _column = 0;
+        _row++;
+        if(_row >= rows()) {
+            _row = 0;
+        }
+    } else {
+        character(_column, _row, value);
+        _column++;
+        if(_column >= columns()) {
+            _column = 0;
+            _row++;
+            if(_row >= rows()) {
+                _row = 0;
+            }
+        }
+    }
+    return value;
+}
+
+void SharpLCD::set_font(const unsigned char * f) {
+    font = f;
+    if (font==NULL){externalfont=0;}	// set display.font
+    	else{externalfont=1;}
+}
+
+void SharpLCD::locate(int column, int row) {
+    _column = column;
+    _row = row;
+    char_x = column;
+    char_y = row;
+}
+
+int SharpLCD::_getc() {
+    return -1;
+}
+
+void SharpLCD::printf(const char* format, ...) {
+	char buffer[MAX_PRINTF_CHARS + 1] = { 0 };
+	uint32_t iterator = 0;
+	va_list args;
+	va_start(args, format);
+	vsprintf(buffer, format, args);
+	va_end(args);
+
+	while((buffer[iterator] != 0) && (iterator < MAX_PRINTF_CHARS)) {
+		_putc(buffer[iterator++]);
+	}
+}
+   
+void SharpLCD::character(int column, int row, int value) {    
+    if(externalfont){ // send external font
+    	unsigned int hor,vert,offset,bpl,j,i,b;
+    	const unsigned char* sign;
+    	unsigned char z,w;
+    	if ((value < 31) || (value > 127)) return;   // test char range
+    	// read font parameter from start of array
+    	offset = font[0];                    // bytes / char
+    	hor = font[1];                       // get hor size of font
+    	vert = font[2];                      // get vert size of font
+    	bpl = font[3];                       // bytes per line
+    	if (char_x + hor > width()) {
+        	char_x = 0;
+        	char_y = char_y + vert;
+       		if (char_y >= height() - font[2]) {
+            	char_y = 0;
+        	}
+    	}     
+    	window(char_x, char_y,hor,vert); 
+    	sign = &font[((value -32) * offset) + 4]; 
+    	w = sign[0];                         
+    	for (j=0; j<vert; j++) {  
+        	for (i=0; i<hor; i++) {  
+            	z =  sign[bpl * i + ((j & 0xF8) >> 3)+1];
+            	b = 1 << (j & 0x07);
+            	if (( z & b ) == 0x00) {               
+                	putp(foreground);              
+            	} 
+            	else {                     
+               		putp(background);                                
+            	}
+        	}
+    	}
+    	if ((w + 2) < hor) {                   // x offset to next char
+        	char_x += w + 2;
+    		}
+    		else char_x += hor;
+	}	
+	// send default font using blitbit function 			
+	else{
+		blitbit(column * 8, row * 8, 8, 8, (char*)&(FONT8x8[value - 0x1F][0]));
+		}
+}
+
+void SharpLCD::window(int x, int y, int w, int h) {
+    // current pixel location
+    _x = x;
+    _y = y;
+    // window settings
+    _x1 = x;
+    _x2 = x + w - 1;
+    _y1 = y;
+    _y2 = y + h - 1;
+}
+    
+void SharpLCD::putp(int colour) {
+    pixel(_x, _y, colour);
+    _x++;
+    if(_x > _x2) {
+        _x = _x1;
+        _y++;
+        if(_y > _y2) {
+            _y = _y1;
+        }
+    }
+}
+
+void SharpLCD::rect(int x0, int y0, int x1, int y1, int color) {
+    if (x1 > x0) hline(x0,x1,y0,color);
+    else  hline(x1,x0,y0,color);
+    if (y1 > y0) vline(x0,y0,y1,color);
+    else vline(x0,y1,y0,color);
+    if (x1 > x0) hline(x0,x1,y1,color);
+    else  hline(x1,x0,y1,color);
+    if (y1 > y0) vline(x1,y0,y1,color);
+    else vline(x1,y1,y0,color);
+    return;
+}
+
+void SharpLCD::fillrect(int x0, int y0, int w, int h, int colour) {
+    unsigned long int index=0;
+    if (w < 0) {
+        x0 = x0 + w;
+        w = -w;
+    }
+    if (h < 0) {
+        y0 = y0 + h;
+        h = -h;
+    }
+    window(x0,y0,w,h);
+    int num = h*w;
+    for( index = 0; index<num; index++ ) {
+       putp(colour); 
+    }
+    return;
+}
+
+void SharpLCD::circle(int x, int y, int r,int colour){
+	int ce = -r;
+	int cx = r;
+	int cy = 0;
+	while(cx >= cy){
+		pixel(x+cx,y+cy,colour);
+		pixel(x-cx,y-cy,colour);
+		pixel(x-cx,y+cy,colour);
+		pixel(x+cx,y-cy,colour);
+		pixel(x+cy,y+cx,colour);
+		pixel(x-cy,y+cx,colour);
+		pixel(x-cy,y-cx,colour);
+		pixel(x+cy,y-cx,colour);
+		ce += 2*cy++ + 1;
+		if(ce >= 0){
+			ce -= 2*cx---1;	
+		}		
+	}
+}
+
+void SharpLCD::ellipse(int xc, int yc, int a, int b, unsigned int colour)
+{
+    int x = 0, y = b;
+    long a2 = (long)a*a, b2 = (long)b*b;
+    long crit1 = -(a2/4 + a%2 + b2);
+    long crit2 = -(b2/4 + b%2 + a2);
+    long crit3 = -(b2/4 + b%2);
+    long t = -a2*y;
+    long dxt = 2*b2*x, dyt = -2*a2*y;
+    long d2xt = 2*b2, d2yt = 2*a2;
+    while (y>=0 && x<=a) {
+        pixel(xc+x, yc+y, colour);
+        if (x!=0 || y!=0)
+            pixel(xc-x, yc-y, colour);
+        if (x!=0 && y!=0) {
+            pixel(xc+x, yc-y, colour);
+            pixel(xc-x, yc+y, colour);
+        }
+        if (t + b2*x <= crit1 ||            
+                t + a2*y <= crit3)          
+            incx();
+        else if (t - a2*y > crit2)          
+            incy();
+        else {
+            incx();
+            incy();
+        }
+    }
+}
+
+void SharpLCD::fillellipse(int xc, int yc, int a, int b, unsigned int colour)
+{
+   	int x = 0, y = b;
+    int rx = x, ry = y;
+    unsigned int width = 1;
+    unsigned int height = 1;
+    long a2 = (long)a*a, b2 = (long)b*b;
+    long crit1 = -(a2/4 + a%2 + b2);
+    long crit2 = -(b2/4 + b%2 + a2);
+    long crit3 = -(b2/4 + b%2);
+    long t = -a2*y;                         
+    long dxt = 2*b2*x, dyt = -2*a2*y;
+    long d2xt = 2*b2, d2yt = 2*a2;
+    if (b == 0) {
+        fillrect(xc-a, yc, 2*a+1, 1, colour);
+        return;
+    }
+    while (y>=0 && x<=a) {
+        if (t + b2*x <= crit1 ||            
+                t + a2*y <= crit3) {        
+            if (height == 1)
+                ;                           
+            else if (ry*2+1 > (height-1)*2) {
+                fillrect(xc-rx, yc-ry, width, height-1, colour);
+                fillrect(xc-rx, yc+ry+1, width, 1-height, colour);
+                ry -= height-1;
+                height = 1;
+            } else {
+                fillrect(xc-rx, yc-ry, width, ry*2+1, colour);
+                ry -= ry;
+                height = 1;
+            }
+            incx();
+            rx++;
+            width += 2;
+        } else if (t - a2*y > crit2) {      
+            incy();
+            height++;
+        } else {
+            if (ry*2+1 > height*2) {
+                fillrect(xc-rx, yc-ry, width, height, colour);
+                fillrect(xc-rx, yc+ry+1, width, -height, colour);
+            } else {
+                fillrect(xc-rx, yc-ry, width, ry*2+1, colour);
+            }
+            incx();
+            incy();
+            rx++;
+            width += 2;
+            ry -= height;
+            height = 1;
+        }
+    }
+    if (ry > height) {
+        fillrect(xc-rx, yc-ry, width, height, colour);
+        fillrect(xc-rx, yc+ry+1, width, -height, colour);
+    } else {
+        fillrect(xc-rx, yc-ry, width, ry*2+1, colour);
+    }
+}
+
+void SharpLCD::line(int x0, int y0, int x1, int y1, int colour) {
+    int   dx = 0, dy = 0;
+    int   dx_sym = 0, dy_sym = 0;
+    int   dx_x2 = 0, dy_x2 = 0;
+    int   di = 0;
+    dx = x1-x0;
+    dy = y1-y0;
+
+    if (dx == 0) {        
+        if (y1 > y0) vline(x0,y0,y1,colour);
+        else vline(x0,y1,y0,colour);
+        return;
+    }
+    if (dx > 0) {
+        dx_sym = 1;
+    } else {
+        dx_sym = -1;
+    }
+    if (dy == 0) {        
+        if (x1 > x0) hline(x0,x1,y0,colour);
+        else  hline(x1,x0,y0,colour);
+        return;
+    }
+    if (dy > 0) {
+        dy_sym = 1;
+    } else {
+        dy_sym = -1;
+    }
+    dx = dx_sym*dx;
+    dy = dy_sym*dy;
+    dx_x2 = dx*2;
+    dy_x2 = dy*2;
+    if (dx >= dy) {
+        di = dy_x2 - dx;
+        while (x0 != x1) {
+
+            pixel(x0, y0, colour);
+            x0 += dx_sym;
+            if (di<0) {
+                di += dy_x2;
+            } else {
+                di += dy_x2 - dx_x2;
+                y0 += dy_sym;
+            }
+        }
+        pixel(x0, y0, colour);
+    } else {
+        di = dx_x2 - dy;
+        while (y0 != y1) {
+            pixel(x0, y0, colour);
+            y0 += dy_sym;
+            if (di < 0) {
+                di += dx_x2;
+            } else {
+                di += dx_x2 - dy_x2;
+                x0 += dx_sym;
+            }
+        }
+        pixel(x0, y0, colour);
+    }
+    return;
+}
+
+void SharpLCD::hline(int x0, int x1, int y, int colour) {
+    int w;
+    w = x1 - x0 + 1;
+    window(x0,y,w,1);
+    for (int x=0; x<w; x++) {
+        putp(colour);
+    }
+    return;
+}
+
+void SharpLCD::vline(int x, int y0, int y1, int colour) {
+    int h;
+    h = y1 - y0 + 1;
+    window(x,y0,1,h);
+    for (int y=0; y<h; y++) {
+        putp(colour);
+    }
+    return;
+}
+    
+void SharpLCD::blit(int x, int y, int w, int h, const int *colour) { 
+    window(x, y, w, h);
+    for(int i=0; i<w*h; i++) {
+        putp(colour[i]);
+    }
+}
+    
+void SharpLCD::blitbit(int x, int y, int w, int h, const char* colour) {
+    window(x, y, w, h);
+    for(int i = 0; i < w*h; i++) {
+        char byte = colour[i >> 3];
+        int offset = i & 0x7;
+        int c = ((byte << (offset)) & 0x80) ? background : foreground;
+        putp(c);
+    }
+}
+    
+int SharpLCD::columns() { 
+    return width() / 8; 
+}
+
+int SharpLCD::rows() { 
+    return height() / 8; 
+}
+
+int SharpLCD::width() {
+	return DISPLAY_WIDTH;
+}
+
+int SharpLCD::height() {
+	return DISPLAY_HEIGHT;
+}
+
+void SharpLCD::showBMP(const uint8_t* bitmap, const uint32_t bmpWidth, const uint32_t bmpHeight, const uint32_t startX, const uint32_t startY) {
+	uint32_t bitmapLine = 0, y = startY, bytesPerLine = ((bmpWidth >= (DISPLAY_WIDTH - startX)) ? (DISPLAY_WIDTH - startX) : bmpWidth) / 8;
+
+	// Apply constraints
+	if((bmpWidth & 0x07) != 0) return;
+	if(startX >= DISPLAY_WIDTH) return;
+	
+	// Copy over bytes to pixel buffer
+	for(; y < startY + bmpHeight; y++) {
+		memcpy( (void*) &(((uint8_t*)pixelBuffer)[((y * DISPLAY_WIDTH) + startX) / 8]),
+				(const void*) &(bitmap[bitmapLine * (bmpWidth / 8)]),
+				bytesPerLine);
+		RowState[y / DISPLAY_BUFFER_TYPE_SIZE] |= (1 << (y % DISPLAY_BUFFER_TYPE_SIZE));
+		bitmapLine++;
+	}
+	return;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SharpLCD.h	Sun Aug 23 16:21:57 2015 +0000
@@ -0,0 +1,305 @@
+
+#ifndef MBED_SharpLCD_H
+#define MBED_SharpLCD_H
+
+#include "mbed.h"
+#include <stdarg.h>
+#include "BurstSPI.h"
+
+#define incx() x++, dxt += d2xt, t += dxt
+#define incy() y--, dyt += d2yt, t += dyt
+
+/// Set the display geometry depending on the resolution of the display used
+/// common types are 96x96, 128x128, 400x240
+/** MemoryLCD width in pixels */
+#define DISPLAY_WIDTH				(400)
+/** MemoryLCD height in pixels */
+#define DISPLAY_HEIGHT				(240)
+
+/** Maximum length of a printf to the display */
+#define MAX_PRINTF_CHARS			40
+/** Data type for storing buffer the pixel buffer */
+#define	DISPLAY_BUFFER_TYPE			uint8_t
+#define DISPLAY_BUFFER_TYPE_SIZE	(sizeof(DISPLAY_BUFFER_TYPE) * 8)
+#define DISPLAY_BUFFER_ELEMENTS 	((DISPLAY_WIDTH*DISPLAY_HEIGHT)/DISPLAY_BUFFER_TYPE_SIZE)
+
+/** Color definitions */
+#define White			0xFFFF
+#define Black			0x0000
+#define foreground		White
+#define background		Black
+
+/** Sharp Memory LCD.
+ *  Supports 96x96, 128x128, 400x240 displays.
+ *  Uses a Frame Buffer in RAM depending on resolution of display as follows:
+ *  96 Display - 1.7k, 128 Display - 2.6k, 400 Display - 12.4k
+ *
+ * Example:
+ * @code
+#include "mbed.h"
+#include "SharpLCD.h"
+
+//KL25
+SharpLCD display(PTC6, NC, PTC5, PTC3, PTC4, NC); //mosi, miso(not used), sck, cs, enable, extcom
+
+int main()
+{        
+    display.enableDisplay();    
+
+    while(1)
+    {
+       display.clearImmediate();
+        // draw ellipse (To draw circle, set the last two axis the same)
+        for (int j=0; j<60; j++) {
+            display.ellipse(64,64,j,60,Black);
+            display.update();
+            //wait(.01);
+            display.ellipse(64,64,j,50,White); // offset last axis here gives interesting effect!
+            display.locate(5,6); 
+            display.printf("Sharp");
+            display.locate(2,8); 
+            display.printf("Draw Ellipse");
+            display.locate(4,10); 
+            display.printf("MemoryLCD"); 
+            display.update();
+        }
+        // draw rectangle
+        for (int j=0; j<128; j++) {
+            display.rect(0,0,j,j,Black);
+            display.update();
+            //wait(.01);
+            display.rect(0,0,j,j,White); 
+            display.locate(5,6); 
+            display.printf("Sharp");
+            display.locate(1,8); 
+            display.printf("Draw Rectangle");
+            display.locate(4,10); 
+            display.printf("MemoryLCD"); 
+            display.update();
+        }
+         for (int j=60; j>0; j--) {
+            display.circle(64,64,j,Black);
+            display.update();
+            wait(.01);
+            display.circle(64,64,j,White); 
+            display.locate(5,6); 
+            display.printf("Sharp");
+            display.locate(2,8); 
+            display.printf("Draw Circle");
+            display.locate(4,10); 
+            display.printf("MemoryLCD"); 
+            display.update();
+        }   
+   	}            
+}   
+ * @endcode
+ */
+
+
+class SharpLCD {
+public:
+	 
+	SharpLCD(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName enable, PinName extcom);
+	
+    /** 
+    * Sets external font usage, eg. dispaly.set_font(Arial12x12);
+    * This uses pixel positioning.
+    * display.set_font(NULL); returns to internal default font.
+    * void set_font(const unsigned char * f);    
+    */
+    void set_font(const unsigned char * f);    
+    /** 
+    * Sets position of the next character or string print.
+    * External font, set pixel x(column),y(row) position.
+    * internal(default) font, set character column and row position
+    */
+    void locate(int column, int row);
+    /**
+    * printf (from Stream).
+    * Full printf funtionality only available with internal(default) font.
+    * CR and LF have no effect with external fonts.
+    */
+    void printf(const char* format, ...);
+    /**
+    * Enables (power) display.
+    */
+    void enableDisplay(void);
+    /**
+    * Dissables (power) display.
+    */   
+    void disableDisplay(void);
+    /**
+	 * Set a pixel in the pixel buffer.
+     *
+     * @param x      X-Position.
+     * @param y      Y-Position.
+     * @param colour Colour to set pixel to. White or Black.
+	 */     
+    void pixel(int x, int y, int colour);
+    /**
+	 * Draw rectangle one pixel wide (wire frame) in the pixel buffer.
+     *
+     * @param x0      X-Start position.
+     * @param y0      Y-Start position.
+     * @param x1      X-End position.
+     * @param y1      Y-End position.
+     * @param colour Colour to set pixel to. White or Black.
+	 */                
+    void rect(int x0, int y0, int x1, int y1, int colour);
+    /**
+	 * Draw filled rectangle in the pixel buffer.
+     *
+     * @param x0      X-Start position.
+     * @param y0      Y-Start position.
+     * @param w       Width.
+     * @param h       Height.
+     * @param colour Colour to fill rectangle to. White or Black.
+	 */        
+    void fillrect(int x0, int y0, int w, int h, int colour);
+    /**
+	 * Draw Circle one pixel wide in the pixel buffer.
+     *
+     * @param x0      X-Centre position.
+     * @param y0      Y-Centre position.
+     * @param r       Radius.
+     * @param colour Colour to set pixel to. White or Black.
+	 */        
+    void circle(int x, int y, int r, int colour);
+    /**
+	 * Draw Ellipse or Circle one pixel wide in the pixel buffer.
+     * Set v & h to same values to produce a circle.
+      
+     * @param xc      X-Centre position.
+     * @param yc      Y-Centre position.
+     * @param v       Vertical radius.
+     * @param h       Horizontal radius.
+     * @param colour Colour to set pixel to. White or Black.
+	 */        
+    void ellipse(int xc, int yc, int v, int h, unsigned int colour);
+    /**
+	 * Draw Filled Ellipse or Circle in the pixel buffer.
+     * Set v & h to same values to produce a circle.
+      
+     * @param xc      X-Centre position.
+     * @param yc      Y-Centre position.
+     * @param v       Vertical radius.
+     * @param h       Horizontal radius.
+     * @param colour Colour to set pixel to. White or Black.
+	 */        
+    void fillellipse(int xc, int yc, int v, int h, unsigned int colour);
+    /**
+	 * Draw a horizontal line one pixel wide in the pixel buffer.
+     *
+     * @param x0      X-Start position.
+     * @param x1      X-End position.
+     * @param y       Y-position.
+     * @param colour Colour to set pixel to. White or Black.
+	 */     
+    void hline(int x0, int x1, int y, int colour);
+    /**
+	 * Draw a Vertical line one pixel wide in the pixel buffer.
+     *
+     * @param x0      X-Position.
+     * @param y0      Y-Start position.
+     * @param y1      Y-End position.
+     * @param colour Colour to set pixel to. White or Black.
+	 */     
+    void vline(int x0, int y0, int y1, int colour);
+    /**
+	 * Draw a Line in the pixel buffer.
+     *
+     * @param x0      X-Start position.
+     * @param y0      Y-Start position.
+     * @param x1      X-End position.
+     * @param y1      Y-End position.
+     * @param colour Colour to fill rectangle to. White or Black.
+	 */        
+    void line(int x0, int y0, int x1, int y1, int colour);
+    /**
+    * Toggles the EXTCOM connection to the display if used.
+    * Call this function at 55 ~ 65 Hz to keep the display from losing contrast.
+    */
+    void toggle();
+	/**
+	 * Transfers pixel buffer to the display
+	 */	
+	void update();	
+	/**
+	 * Clear the display & set pixel buffer to zero.
+	 */	
+	void clearImmediate();	
+	/**
+     * Move bitmap into pixel buffer
+     * 
+     * @param bitmap      pointer to uint8 array containing horizontal pixel data
+     * @param bmpWidth    width of the bitmap in pixels (must be byte multiple, eg 8,16,32,...)
+     * @param bmpHeight   height of the bitmap in pixels (must be byte multiple, eg 8,16,32,...)
+     * @param startX      starting position to apply bitmap in horizontal direction (0 = leftmost) (pixel resolution)
+     * @param startY      starting position to apply bitmap in vertical direction (0 = topmost) (pixel resolution)
+     */
+   void showBMP(const uint8_t* bitmap, const uint32_t bmpWidth, const uint32_t bmpHeight, const uint32_t startX, const uint32_t startY);
+   /** Output a character at the given position
+     *
+     * @param column column where charater must be written
+     * @param  row where character must be written
+     * @param c the character to be written to the TextDisplay
+     */
+   void character(int column, int row, int c);
+   
+    /** return number if rows on TextDisplay
+     * @result number of rows
+     */
+    int rows();
+    /** return number if columns on TextDisplay
+    * @result number of rows
+    */
+    int columns();   
+
+private:
+	void window(int x, int y, int w, int h);
+    void putp(int colour);
+	void blit(int x, int y, int w, int h, const int *colour);    
+    void blitbit(int x, int y, int w, int h, const char* colour);	
+protected:
+	//SPI        spi; // standard SPI
+	BurstSPI spi; // Faster SPI pixel buffer transfer
+    DigitalOut chipSelect;
+    DigitalOut Enable;
+    DigitalOut ExtCom;
+
+	uint8_t lcdPolarity;
+	volatile uint32_t rowCount;	
+	uint8_t cmd[2 + (DISPLAY_WIDTH / DISPLAY_BUFFER_TYPE_SIZE * sizeof(DISPLAY_BUFFER_TYPE))];
+	volatile DISPLAY_BUFFER_TYPE pixelBuffer[DISPLAY_BUFFER_ELEMENTS]; // one full frame buffer
+	volatile DISPLAY_BUFFER_TYPE RowState[DISPLAY_HEIGHT/DISPLAY_BUFFER_TYPE_SIZE]; // 1 bit per row to indicate row change status
+		
+	// transfers pixel buffer to display
+	void display_write();	 
+	
+	 // pixel location
+    short _x;
+    short _y;
+    
+    // window location
+    short _x1;
+    short _x2;
+    short _y1;
+    short _y2;
+   	
+    int _putc(int value);
+    int _getc();
+    int width();
+    int height(); 
+    
+    // external font functions
+    const unsigned char* font;
+    int externalfont;
+
+    // character location
+    int _column;
+    int _row;
+    unsigned int char_x;
+    unsigned int char_y; 
+
+};
+#endif
\ No newline at end of file