![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
TO CHECKOUT
Diff: lcd.c
- Revision:
- 0:785c2b62c4d1
diff -r 000000000000 -r 785c2b62c4d1 lcd.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lcd.c Sat Nov 29 17:48:10 2014 +0000 @@ -0,0 +1,762 @@ +#include <stdarg.h> +#include "lcd.h" + +void lcd_init(lcd_t * lcd, spi_t * spi, PinName CS, PinName CD) { + //Prepare pins + gpio_init_out(&(lcd->CS), CS ); + gpio_init_out(&(lcd->CD), CD); + + gpio_write(&(lcd->CS), 1); + gpio_write(&(lcd->CD), 1); + // + + lcd->mode = PORTRAIT; + //lcd->mode = LANDSCAPE; + lcd->spi = spi; + + wait_ms(500); + lcd_writeCommand(lcd, 0x01); + wait_ms(200); + + + lcd_writeCommand(lcd, 0xCF); + lcd_writeData(lcd, 0x00); + lcd_writeData(lcd, 0x8B); + lcd_writeData(lcd, 0x30); + + lcd_writeCommand(lcd, 0xED); + lcd_writeData(lcd, 0x67); + lcd_writeData(lcd, 0x03); + lcd_writeData(lcd, 0x12); + lcd_writeData(lcd, 0x81); + + lcd_writeCommand(lcd, 0xE8); + lcd_writeData(lcd, 0x85); + lcd_writeData(lcd, 0x10); + lcd_writeData(lcd, 0x7A); + + lcd_writeCommand(lcd, 0xCB); + lcd_writeData(lcd, 0x39); + lcd_writeData(lcd, 0x2C); + lcd_writeData(lcd, 0x00); + lcd_writeData(lcd, 0x34); + lcd_writeData(lcd, 0x02); + + lcd_writeCommand(lcd, 0xF7); + lcd_writeData(lcd, 0x20); + + lcd_writeCommand(lcd, 0xEA); + lcd_writeData(lcd, 0x00); + lcd_writeData(lcd, 0x00); + + lcd_writeCommand(lcd, 0xC0); /* Power control */ + lcd_writeData(lcd, 0x1B); /* VRH[5:0] */ + + lcd_writeCommand(lcd, 0xC1); /* Power control */ + lcd_writeData(lcd, 0x10); /* SAP[2:0];BT[3:0] */ + + lcd_writeCommand(lcd, 0xC5); /* VCM control */ + lcd_writeData(lcd, 0x3F); + lcd_writeData(lcd, 0x3C); + + lcd_writeCommand(lcd, 0xC7); /* VCM control2 */ + lcd_writeData(lcd, 0xB7); + + lcd_writeCommand(lcd, 0x36); /* Memory Access Control */ + lcd_writeData(lcd, 0x08); + + lcd_writeCommand(lcd, 0x3A); + lcd_writeData(lcd, 0x55); + + lcd_writeCommand(lcd, 0xB1); + lcd_writeData(lcd, 0x00); + lcd_writeData(lcd, 0x1B); + + lcd_writeCommand(lcd, 0xB6); /* Display Function Control */ + lcd_writeData(lcd, 0x0A); + lcd_writeData(lcd, 0xA2); + + lcd_writeCommand(lcd, 0xF2); /* 3Gamma Function Disable */ + lcd_writeData(lcd, 0x00); + + lcd_writeCommand(lcd, 0x26); /* Gamma curve selected */ + lcd_writeData(lcd, 0x01); + + lcd_writeCommand(lcd, 0xE0); /* Set Gamma */ + lcd_writeData(lcd, 0x0F); + lcd_writeData(lcd, 0x2A); + lcd_writeData(lcd, 0x28); + lcd_writeData(lcd, 0x08); + lcd_writeData(lcd, 0x0E); + lcd_writeData(lcd, 0x08); + lcd_writeData(lcd, 0x54); + lcd_writeData(lcd, 0xA9); + lcd_writeData(lcd, 0x43); + lcd_writeData(lcd, 0x0A); + lcd_writeData(lcd, 0x0F); + lcd_writeData(lcd, 0x00); + lcd_writeData(lcd, 0x00); + lcd_writeData(lcd, 0x00); + lcd_writeData(lcd, 0x00); + + lcd_writeCommand(lcd, 0xE1); /* Set Gamma */ + lcd_writeData(lcd, 0x00); + lcd_writeData(lcd, 0x15); + lcd_writeData(lcd, 0x17); + lcd_writeData(lcd, 0x07); + lcd_writeData(lcd, 0x11); + lcd_writeData(lcd, 0x06); + lcd_writeData(lcd, 0x2B); + lcd_writeData(lcd, 0x56); + lcd_writeData(lcd, 0x3C); + lcd_writeData(lcd, 0x05); + lcd_writeData(lcd, 0x10); + lcd_writeData(lcd, 0x0F); + lcd_writeData(lcd, 0x3F); + lcd_writeData(lcd, 0x3F); + lcd_writeData(lcd, 0x0F); + + lcd_writeCommand(lcd, 0x11); /* Exit Sleep */ + wait_ms(120); + lcd_writeCommand(lcd, 0x29); + lcd_fillScreen(lcd); +} + +void lcd_cs(lcd_t * lcd, int value) { + while(spi_busy(lcd->spi)); + gpio_write(&(lcd->CS), value); +} + +void lcd_cd(lcd_t * lcd, int value) { + while(spi_busy(lcd->spi)); + gpio_write(&(lcd->CD), value); +} + +void lcd_setMode(lcd_t * lcd, lcd_mode mode) { + lcd->mode = mode; +} + +void lcd_writeCommand(lcd_t * lcd, int value) { + lcd_cd(lcd, 0); + lcd_cs(lcd, 0); + + spi_master_write(lcd->spi, value); + + lcd_cs(lcd, 1); +} + +void lcd_writeData(lcd_t * lcd, int value) { + lcd_cd(lcd, 1); + lcd_cs(lcd, 0); + + spi_master_write(lcd->spi, value); + + lcd_cs(lcd, 1); +} + +void lcd_writeData16(lcd_t * lcd, int value) { + int data1 = value >> 8; + int data2 = value & 0xff; + lcd_cd(lcd, 1); + lcd_cs(lcd, 0); + + spi_master_write(lcd->spi, data1); + spi_master_write(lcd->spi, data2); + + lcd_cs(lcd, 1); +} + +void lcd_setColumn(lcd_t * lcd, int start, int end) { + lcd_writeCommand(lcd, 0x2A); /* column command address */ + lcd_writeData16(lcd, start); + lcd_writeData16(lcd, end); +} + +void lcd_setPage(lcd_t * lcd, int start, int end) { + lcd_writeCommand(lcd, 0x2B); /* column command address */ + lcd_writeData16(lcd, start); + lcd_writeData16(lcd, end); +} + +void lcd_setXY(lcd_t * lcd, int x, int y) { + lcd_setColumn(lcd, x, x); + lcd_setPage(lcd, y, y); + lcd_writeCommand(lcd, 0x2c); +} + +void lcd_setPixel(lcd_t * lcd, int x, int y, int color) { + lcd_setXY(lcd, x, y); + lcd_writeData16(lcd, color); +} + +void lcd_setLandscape(lcd_t * lcd) { + lcd->mode = LANDSCAPE; +} + +void lcd_setPortrait(lcd_t * lcd) { + lcd->mode = PORTRAIT; +} + +void lcd_fillScreen(lcd_t * lcd) { + lcd_setColumn(lcd, 0, 239); + lcd_setPage(lcd, 0, 319); + lcd_writeCommand(lcd, 0x2c); /* start to write to display ram */ + + lcd_cd(lcd, 1); + lcd_cs(lcd, 0); + for(int i = 0; i < 76800; i++) + { + spi_master_write(lcd->spi, 0xFF); + spi_master_write(lcd->spi, 0xFF); + } + while(spi_busy(lcd->spi)); + lcd_cs(lcd, 1); +} + +void lcd_drawLine(lcd_t * lcd, int x0, int y0, int x1, int y1, int color) { + if (x0 == x1) { + lcd_drawVerticalLine(lcd, x0, y0, y1-y0, color); + }else if (y0 == y1) { + lcd_drawHorizontalLine(lcd, x0, y0, x1-x0, color); + }else { + if(lcd->mode == LANDSCAPE) { + y0 = y0^x0; + x0 = y0^x0; + y0 = y0^x0; + + y1 = y1^x1; + x1 = y1^x1; + y1 = y1^x1; + + x0 = 239-(x0); + x1 = 239-(x1); + } + int x = x1-x0; + int y = y1-y0; + int dx = abs(x), sx = x0 < x1 ? 1 : -1; + int dy = -abs(y), sy = y0 < y1 ? 1 : -1; + int err = dx + dy, e2; /* error value e_xy */ + + lcd_setPixel(lcd, x0, y0, color); + + do + { + e2 = 2*err; + + if (e2 >= dy) { /* e_xy+e_x > 0 */ + err += dy; x0 += sx; + } + + if (e2 <= dx) { /* e_xy+e_y < 0 */ + err += dx; y0 += sy; + } + + lcd_setPixel(lcd, x0, y0, color); + } while (x0 != x1 || y0 != y1); + } +} + +void lcd_drawVerticalLine(lcd_t * lcd, int x, int y, int length, int color) { + if(lcd->mode == LANDSCAPE) { + y = y^x; + x = y^x; + y = y^x; + x = 239-(x); + } + + lcd_setColumn(lcd, x, x); + lcd_setPage(lcd, y, y + length); + + lcd_writeCommand(lcd, 0x2c); + for(int i=0; i<length; i++) + lcd_writeData16(lcd, color); +} + +void lcd_drawHorizontalLine(lcd_t * lcd, int x, int y, int length, int color) { + if(lcd->mode == LANDSCAPE) { + y = y^x; + x = y^x; + y = y^x; + x = 239-x; + lcd_setColumn(lcd, x - length, x); + }else { + lcd_setColumn(lcd, x, x + length); + } + + lcd_setPage(lcd, y, y); + + lcd_writeCommand(lcd, 0x2c); + for(int i=0; i<length; i++) + lcd_writeData16(lcd, color); +} + +void lcd_drawRectangle(lcd_t * lcd , int x0, int y0, int x1, int y1, int color) { + if(x0>x1) { + x0=x0^x1; + x1=x0^x1; + x0=x0^x1; + } + + if(y0>y1) { + y0=y0^y1; + y1=y0^y1; + y0=y0^y1; + } + + lcd_drawVerticalLine(lcd, x0, y0, y1-y0, color); + lcd_drawVerticalLine(lcd, x0, y1, y1-y0, color); + lcd_drawHorizontalLine(lcd, x0, y0, x1-x0, color); + lcd_drawHorizontalLine(lcd, x1, y0, x1-x0, color); +} + +void lcd_fillRectangle(lcd_t * lcd, int x0, int y0, int length, int width, int color) { + int XY=0; + + int x1 = x0+length; + int y1 = y0+width; + + if(x0 > x1) + { + x0 = x0^x1; + x1 = x0^x1; + x0 = x0^x1; + } + + if(y0 > y1) + { + y0 = y0^y1; + y1 = y0^y1; + y0 = y0^y1; + } + + if(lcd->mode == LANDSCAPE) { + y0 = y0^x0; + x0 = y0^x0; + y0 = y0^x0; + + y1 = y1^x1; + x1 = y1^x1; + y1 = y1^x1; + + x0 = x0^x1; + x1 = x0^x1; + x0 = x0^x1; + x0 = 239-x0; + x1 = 239-x1; + } + + //XL = constrain(XL, MIN_X, MAX_X); + //x1 = constrain(x1, MIN_X, MAX_X); + //y0 = constrain(y0, MIN_Y, MAX_Y); + //y1 = constrain(y1, MIN_Y, MAX_Y); + + XY = (x1-x0+1); + XY = XY*(y1-y0+1); + + lcd_setColumn(lcd, x0, x1); + lcd_setPage(lcd, y0, y1); + lcd_writeCommand(lcd, 0x2c); /* start to write to display ram */ + + for(int i = 0; i < XY; i++) + { + lcd_writeData16(lcd, color); + } +} + +void lcd_fillSprite(lcd_t * lcd, int x0, int y0, int length, int width, short int *pColor) { + int XY=0; + + int x1 = x0+length; + int y1 = y0+width; + short int color; + if(x0 > x1) + { + x0 = x0^x1; + x1 = x0^x1; + x0 = x0^x1; + } + + if(y0 > y1) + { + y0 = y0^y1; + y1 = y0^y1; + y0 = y0^y1; + } + + if(lcd->mode == LANDSCAPE) { + y0 = y0^x0; + x0 = y0^x0; + y0 = y0^x0; + + y1 = y1^x1; + x1 = y1^x1; + y1 = y1^x1; + + x0 = x0^x1; + x1 = x0^x1; + x0 = x0^x1; + x0 = 239-x0; + x1 = 239-x1; + } + + //XL = constrain(XL, MIN_X, MAX_X); + //x1 = constrain(x1, MIN_X, MAX_X); + //y0 = constrain(y0, MIN_Y, MAX_Y); + //y1 = constrain(y1, MIN_Y, MAX_Y); + + XY = (x1-x0+1); + XY = XY*(y1-y0+1); + + lcd_setColumn(lcd, x0, x1); + lcd_setPage(lcd, y0, y1); + lcd_writeCommand(lcd, 0x2c); /* start to write to display ram */ + +#if 1 /* speed up */ + lcd_cd(lcd, 1); + lcd_cs(lcd, 0); + for(int i = 0; i < XY; i++) + { + color = *pColor++; + spi_master_write(lcd->spi, (color >> 8)); + spi_master_write(lcd->spi, (color & 0xff)); + } + lcd_cs(lcd, 1); +#else + for(int i = 0; i < XY; i++) + { + lcd_writeData16(lcd, *color++); + } +#endif +} + + +void lcd_drawTraingle(lcd_t * lcd, int x0, int y0, int x1, int y1, int x2, int y2, int color) +{ + lcd_drawLine(lcd, x0, y0, x1, y1, color); + lcd_drawLine(lcd, x0, y0, x2, y2, color); + lcd_drawLine(lcd, x1, y1, x2, y2, color); +} + +void lcd_fillTraingle(lcd_t * lcd, int x0, int y0, int x1, int y1, int x2, int y2, int color) +{ + if(lcd->mode == LANDSCAPE) { + y0 = y0^x0; + x0 = y0^x0; + y0 = y0^x0; + + y1 = y1^x1; + x1 = y1^x1; + y1 = y1^x1; + + y2 = y2^x2; + x2 = y2^x2; + y2 = y2^x2; + + x0 = 239-x0; + x1 = 239-x1; + x2 = 239-x2; + } + + if(y0 > y1) { + y0 = y0^y1; + y1 = y0^y1; + y0 = y0^y1; + + x0 = x0^x1; + x1 = x0^x1; + x0 = x0^x1; + } + + if(y1 > y2) { + y2 = y2^y1; + y1 = y2^y1; + y2 = y2^y1; + + x2 = x2^x1; + x1 = x2^x1; + x2 = x2^x1; + } + + if(y0 > y1) { + y0 = y0^y1; + y1 = y0^y1; + y0 = y0^y1; + + x0 = x0^x1; + x1 = x0^x1; + x0 = x0^x1; + } + + if(x1 > x2) { + x1 = x1^x2; + x2 = x1^x2; + x1 = x1^x2; + + y1 = y1^y2; + y2 = y1^y2; + y1 = y1^y2; + } + + int xl = x0; + int yl = y0; + int xle = x1; + int yle = y1; + int dxl = abs(x1-x0), sxl = x0 < x1 ? 1 : -1; + int dyl = -abs(y1-y0), syl = y0 < y1 ? 1 : -1; + int errl = dxl + dyl, e2l; + + int xr = x0; + int yr = y0; + int xre = x2; + int yre = y2; + int dxr = abs(x2-x0), sxr = x0 < x2 ? 1 : -1; + int dyr = -abs(y2-y0), syr = y0 < y2 ? 1 : -1; + int errr = dxr + dyr, e2r; + + int xlp = xl; + int xrp = xr; + + do { + if(yl <= yr && (xl != xle || yl != yle)) { + e2l = 2*errl; + if (e2l >= dyl && xl != xle) { + errl += dyl; xl += sxl; + } + + if (e2l <= dxl && yl != yle) { + errl += dxl; yl += syl; + + if(yl == yr) { + //lcd_drawHorizontalLine(lcd, xlp, yl-1, xrp-xlp+1, color); + + lcd_setColumn(lcd, xlp, xrp); + lcd_setPage(lcd, yl-1, yl-1); + lcd_writeCommand(lcd, 0x2c); + for(int i=0; i < xrp-xlp; i++) + lcd_writeData16(lcd, color); + + xlp = xl; + xrp = xr; + } + }else { + if(sxl < 0) { + xlp = xl; + } + } + }else if (yle < yre) { + dxl = abs(xl-x2); + sxl = xl < x2 ? 1 : -1; + dyl = -abs(yl-y2); + syl = 1; + xle = x2; + yle = y2; + errl = dxl + dyl; + } + + if(yr <= yl && (xr != xre || yr != yre)) { + e2r = 2*errr; + if (e2r >= dyr && xr != xre) { + errr += dyr; xr += sxr; + } + + if (e2r <= dxr && yr != yre) { + errr += dxr; yr += syr; + + if(yl==yr) { + //lcd_drawHorizontalLine(lcd, xlp, yl-1, xrp-xlp+1, color); + + lcd_setColumn(lcd, xlp, xrp); + lcd_setPage(lcd, yl-1, yl-1); + lcd_writeCommand(lcd, 0x2c); + for(int i=0; i < xrp-xlp; i++) + lcd_writeData16(lcd, color); + + xlp = xl; + xrp = xr; + } + }else { + if(sxr > 0) { + xrp = xr; + } + } + + }else if (yre < yle) { + dxr = abs(xr-x1); + dyr = -abs(yr-y1); + sxr = xr < x1 ? 1 : -1; + syr = 1; + xre = x1; + yre = y1; + errr = dxr + dyr; + } + }while ((xl < xle || yl < yle || xr < xre || yr < yre)); + + lcd_setColumn(lcd, xlp, xrp); + lcd_setPage(lcd, yl, yl); + lcd_writeCommand(lcd, 0x2c); + for(int i=0; i < xrp-xlp; i++) + lcd_writeData16(lcd, color); +} + +void lcd_drawCircle(lcd_t * lcd, int x, int y, int radius, int color) +{ + if(lcd->mode==LANDSCAPE) { + y=x^y; + x=x^y; + y=x^y; + x=239-x; + } + + int dx = -radius, dy = 0, err = 2-2*radius, e2; + do { + lcd_setPixel(lcd, x-dx, y+dy, color); + lcd_setPixel(lcd, x+dx, y+dy, color); + lcd_setPixel(lcd, x+dx, y-dy, color); + lcd_setPixel(lcd, x-dx, y-dy, color); + e2 = err; + if (e2 <= dy) { + err += ++dy*2+1; + if (-dx == dy && e2 <= dx) e2 = 0; + } + if (e2 > dx) err += ++dx*2+1; + } while (dx <= 0); +} + +void lcd_drawChar(lcd_t * lcd, char c, int x, int y, uint16_t size, uint16_t color) +{ + if(!(c >= 32) && (c <= 127)) { + c = '?'-32; + } + + for (int i =0; i < FONT_X; i++ ) { + uint8_t temp = simpleFont[c-32][i]; + for(uint8_t f = 0; f < 8; f++) { + if((temp>>f)&0x01) { + lcd_fillRectangle(lcd, x+i*size, y+f*size, size, size, color); + } +#if 1 /* Hintergrund ebenfalls setzen */ + else{ + lcd_fillRectangle(lcd, x+i*size, y+f*size, size, size, WHITE); + } +#endif + } + } +} + +void lcd_drawString(lcd_t * lcd, char * ca, int x, int y, uint16_t size, uint16_t color) +{ + while(*ca) { + lcd_drawChar(lcd, *ca, x, y, size, color); + *ca++; + + if(x < MAX_X) { + x += FONT_SPACE*size; /* Move cursor right */ + } + } +} + +uint8_t lcd_drawNumber(lcd_t * lcd, long long_num, int x, int y, uint16_t size, uint16_t color) +{ + uint8_t char_buffer[10] = ""; + uint8_t i = 0; + uint8_t f = 0; + + if(long_num < 0) { + f = 1; + lcd_drawChar(lcd, '-', x, y, size, color); + long_num = -long_num; + + if(x < MAX_X) { + x += FONT_SPACE*size; /* Move cursor right */ + } + }else if(long_num == 0) { + f = 1; + lcd_drawChar(lcd, '0', x, y, size, color); + return f; //<-- Bullshit --> + + //if(x < MAX_X) { + // x += FONT_SPACE*size; /* Move cursor right */ + //} + } + + while (long_num > 0) { + char_buffer[i++] = long_num % 10; + long_num /= 10; + } + + f = f+i; + + for(; i > 0; i--) { + lcd_drawChar(lcd, '0' + char_buffer[i - 1], x, y, size, color); + + if(x < MAX_X) { + x += FONT_SPACE*size; /* Move cursor right */ + } + } + + return f; +} + +uint8_t lcd_drawFloat(lcd_t * lcd, float floatNumber, uint8_t decimal, int x, int y, uint16_t size, uint16_t color) +{ + uint16_t temp = 0; + float decy = 0.0; + float rounding = 0.5; + uint8_t f = 0; + + if(floatNumber < 0.0) + { + lcd_drawChar(lcd, '-', x, y, size, color); + floatNumber = -floatNumber; + if(x < MAX_X) + { + x += FONT_SPACE * size; /* Move cursor right */ + } + f = 1; + } + + for(uint8_t i = 0; i < decimal; ++i) + { + rounding /= 10.0; + } + floatNumber += rounding; + + temp = (uint16_t)floatNumber; + uint8_t howlong = lcd_drawNumber(lcd, temp, x, y, size, color); + f += howlong; + + if((x+8*size*howlong) < MAX_X) + { + x += FONT_SPACE * size * howlong; /* Move cursor right */ + } + + if(decimal > 0) + { + lcd_drawChar(lcd, '.', x, y, size, color); + if(x < MAX_X) + { + x += FONT_SPACE * size; /* Move cursor right */ + } + f += 1; + } + + decy = floatNumber - temp; + /* decimal part, 4 */ + for(uint8_t i = 0; i < decimal; i++) + { + decy *= 10; /* for the next decimal */ + temp = decy; /* get the decimal */ + lcd_drawNumber(lcd, temp, x, y, size, color); + floatNumber = -floatNumber; + + if(x < MAX_X) + { + x += FONT_SPACE * size; /* Move cursor right */ + } + + decy -= temp; + } + + f += decimal; + return f; +}