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
Revision 0:0a76610c48a1, committed 2015-08-23
- 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
--- /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