Christopher H
/
DI_LAB2
TO CHECKOUT
lcd.c
- Committer:
- chrish
- Date:
- 2014-12-02
- Revision:
- 1:6a77fc8e1389
- Parent:
- 0:785c2b62c4d1
File content as of revision 1:6a77fc8e1389:
#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; }