SSD1331 Oled driver library for 96x64 colour Oled display. Demo included in .h file
Dependents: Oled-SSD1331 PJ12_device
ssd1331.cpp
- Committer:
- star297
- Date:
- 2016-05-29
- Revision:
- 5:4385fd242db0
- Parent:
- 4:062b4708eb35
File content as of revision 5:4385fd242db0:
#include "mbed.h" #include "ssd1331.h" #define countof(x) ( sizeof(x) / sizeof(x[0]) ) static const char font6x8[0x60][6] = { { 0x00,0x00,0x00,0x00,0x00,0x00 } , /*SPC */ { 0x00,0x00,0x5F,0x00,0x00,0x00 } , /* ! */ { 0x04,0x03,0x04,0x03,0x00,0x00 } , /* " */ { 0x28,0x7E,0x14,0x3F,0x0A,0x00 } , /* # */ { 0x24,0x2A,0x7F,0x2A,0x12,0x00 } , /* $ */ { 0x23,0x13,0x08,0x64,0x62,0x00 } , /* % */ { 0x30,0x4E,0x59,0x26,0x50,0x00 } , /* & */ { 0x00,0x00,0x02,0x01,0x00,0x00 } , /* ' */ { 0x00,0x00,0x1C,0x22,0x41,0x00 } , /* ( */ { 0x41,0x22,0x1C,0x00,0x00,0x00 } , /* ) */ { 0x22,0x14,0x08,0x14,0x22,0x00 } , /* * */ { 0x08,0x08,0x3E,0x08,0x08,0x00 } , /* + */ { 0x50,0x30,0x00,0x00,0x00,0x00 } , /* , */ { 0x08,0x08,0x08,0x08,0x08,0x00 } , /* - */ { 0x60,0x60,0x00,0x00,0x00,0x00 } , /* . */ { 0x20,0x10,0x08,0x04,0x02,0x00 } , /* / */ { 0x3E,0x51,0x49,0x45,0x3E,0x00 } , /* 0 */ { 0x00,0x42,0x7F,0x40,0x00,0x00 } , /* 1 */ { 0x62,0x51,0x49,0x49,0x46,0x00 } , /* 2 */ { 0x22,0x41,0x49,0x49,0x36,0x00 } , /* 3 */ { 0x18,0x14,0x12,0x7F,0x10,0x00 } , /* 4 */ { 0x2F,0x45,0x45,0x45,0x39,0x00 } , /* 5 */ { 0x3E,0x49,0x49,0x49,0x32,0x00 } , /* 6 */ { 0x01,0x61,0x19,0x05,0x03,0x00 } , /* 7 */ { 0x36,0x49,0x49,0x49,0x36,0x00 } , /* 8 */ { 0x26,0x49,0x49,0x49,0x3E,0x00 } , /* 9 */ { 0x00,0x36,0x36,0x00,0x00,0x00 } , /* : */ { 0x00,0x56,0x36,0x00,0x00,0x00 } , /* ; */ { 0x00,0x08,0x14,0x22,0x41,0x00 } , /* < */ { 0x14,0x14,0x14,0x14,0x14,0x00 } , /* = */ { 0x41,0x22,0x14,0x08,0x00,0x00 } , /* > */ { 0x02,0x01,0x59,0x09,0x06,0x00 } , /* ? */ { 0x3E,0x41,0x5D,0x55,0x2E,0x00 } , /* @ */ { 0x60,0x1C,0x13,0x1C,0x60,0x00 } , /* A */ { 0x7F,0x49,0x49,0x49,0x36,0x00 } , /* B */ { 0x3E,0x41,0x41,0x41,0x22,0x00 } , /* C */ { 0x7F,0x41,0x41,0x22,0x1C,0x00 } , /* D */ { 0x7F,0x49,0x49,0x49,0x41,0x00 } , /* E */ { 0x7F,0x09,0x09,0x09,0x01,0x00 } , /* F */ { 0x1C,0x22,0x41,0x49,0x3A,0x00 } , /* G */ { 0x7F,0x08,0x08,0x08,0x7F,0x00 } , /* H */ { 0x00,0x41,0x7F,0x41,0x00,0x00 } , /* I */ { 0x20,0x40,0x40,0x40,0x3F,0x00 } , /* J */ { 0x7F,0x08,0x14,0x22,0x41,0x00 } , /* K */ { 0x7F,0x40,0x40,0x40,0x00,0x00 } , /* L */ { 0x7F,0x04,0x18,0x04,0x7F,0x00 } , /* M */ { 0x7F,0x04,0x08,0x10,0x7F,0x00 } , /* N */ { 0x3E,0x41,0x41,0x41,0x3E,0x00 } , /* O */ { 0x7F,0x09,0x09,0x09,0x06,0x00 } , /* P */ { 0x3E,0x41,0x51,0x21,0x5E,0x00 } , /* Q */ { 0x7F,0x09,0x19,0x29,0x46,0x00 } , /* R */ { 0x26,0x49,0x49,0x49,0x32,0x00 } , /* S */ { 0x01,0x01,0x7F,0x01,0x01,0x00 } , /* T */ { 0x3F,0x40,0x40,0x40,0x3F,0x00 } , /* U */ { 0x03,0x1C,0x60,0x1C,0x03,0x00 } , /* V */ { 0x0F,0x70,0x0F,0x70,0x0F,0x00 } , /* W */ { 0x41,0x36,0x08,0x36,0x41,0x00 } , /* X */ { 0x01,0x06,0x78,0x02,0x01,0x00 } , /* Y */ { 0x61,0x51,0x49,0x45,0x43,0x00 } , /* Z */ { 0x00,0x00,0x7F,0x41,0x41,0x00 } , /* [ */ { 0x15,0x16,0x7C,0x16,0x11,0x00 } , /* \ */ { 0x41,0x41,0x7F,0x00,0x00,0x00 } , /* ] */ { 0x00,0x02,0x01,0x02,0x00,0x00 } , /* ^ */ { 0x40,0x40,0x40,0x40,0x40,0x00 } , /* _ */ { 0x00,0x01,0x02,0x00,0x00,0x00 } , /* ` */ { 0x00,0x20,0x54,0x54,0x78,0x00 } , /* a */ { 0x00,0x7F,0x44,0x44,0x38,0x00 } , /* b */ { 0x00,0x38,0x44,0x44,0x28,0x00 } , /* c */ { 0x00,0x38,0x44,0x44,0x7F,0x00 } , /* d */ { 0x00,0x38,0x54,0x54,0x18,0x00 } , /* e */ { 0x00,0x04,0x3E,0x05,0x01,0x00 } , /* f */ { 0x00,0x08,0x54,0x54,0x3C,0x00 } , /* g */ { 0x00,0x7F,0x04,0x04,0x78,0x00 } , /* h */ { 0x00,0x00,0x7D,0x00,0x00,0x00 } , /* i */ { 0x00,0x40,0x40,0x3D,0x00,0x00 } , /* j */ { 0x00,0x7F,0x10,0x28,0x44,0x00 } , /* k */ { 0x00,0x01,0x7F,0x00,0x00,0x00 } , /* l */ { 0x7C,0x04,0x7C,0x04,0x78,0x00 } , /* m */ { 0x00,0x7C,0x04,0x04,0x78,0x00 } , /* n */ { 0x00,0x38,0x44,0x44,0x38,0x00 } , /* o */ { 0x00,0x7C,0x14,0x14,0x08,0x00 } , /* p */ { 0x00,0x08,0x14,0x14,0x7C,0x00 } , /* q */ { 0x00,0x7C,0x08,0x04,0x04,0x00 } , /* r */ { 0x00,0x48,0x54,0x54,0x24,0x00 } , /* s */ { 0x00,0x04,0x3E,0x44,0x40,0x00 } , /* t */ { 0x00,0x3C,0x40,0x40,0x7C,0x00 } , /* u */ { 0x00,0x7C,0x20,0x10,0x0C,0x00 } , /* v */ { 0x1C,0x60,0x1C,0x60,0x1C,0x00 } , /* w */ { 0x00,0x6C,0x10,0x10,0x6C,0x00 } , /* x */ { 0x00,0x4C,0x50,0x30,0x1C,0x00 } , /* y */ { 0x00,0x44,0x64,0x54,0x4C,0x00 } , /* z */ { 0x00,0x08,0x36,0x41,0x41,0x00 } , /* { */ { 0x00,0x00,0x7F,0x00,0x00,0x00 } , /* | */ { 0x41,0x41,0x36,0x08,0x00,0x00 } , /* } */ { 0x08,0x04,0x08,0x10,0x08,0x00 } , /* ~ */ { 0x00,0x00,0x00,0x00,0x00,0x00 } /*null*/ }; ssd1331::ssd1331(PinName cs_pin, PinName rst_pin, PinName a0_pin, PinName mosi_pin, PinName miso_pin, PinName sclk_pin) : CS(cs_pin), RES(rst_pin), DC(a0_pin), spi(mosi_pin, miso_pin, sclk_pin) { Init(); } void ssd1331::Init(void) { spi.format(8,3); spi.frequency(24000000); // 12Mhz max for KL25z // reset wait_ms(200); RES = 0; //Reset active wait_ms(200); RES = 1; // initialize sequence RegWrite(0xAE); //OLED display OFF RegWrite(0x75); /* Set Row Address */ RegWrite(0x00); /* Start = 0 */ RegWrite(0x3F); /* End = 63 */ RegWrite(0x15); /* Set Column Address */ RegWrite(0x00); /* Start = 0 */ RegWrite(0x5F); /* End = 95 */ RegWrite(0xA0); //Set remap & data format 0111 0000 RegWrite(0x72); // RGB colour RegWrite(0xA1); //set display start row RAM RegWrite(0x00); RegWrite(0xA2); //set dispaly offset RegWrite(0x00); RegWrite(0xA4); //Set Display Mode RegWrite(0xA8); //Set Multiplex Ratio RegWrite(0x3F); RegWrite(0xAD); //Set Master Configuration RegWrite(0x8F); //(External VCC Supply Selected) RegWrite(0xB0); //Set Power Saving Mode RegWrite(0x1A); RegWrite(0xB1); //Set Phase 1 & 2 Period Adjustment RegWrite(0x74); RegWrite(0xB3); //Set Display Clock Divide Ratio / Oscillator Frequency RegWrite(0xD0); RegWrite(0x8A); //Set Second Pre-charge Speed of Color A RegWrite(0x81); RegWrite(0x8B); //Set Second Pre-charge Speed of Color B RegWrite(0x82); RegWrite(0x8C); //Set Second Pre-charge Speed of Color C RegWrite(0x83); RegWrite(0xBB); //Set Pre-charge Level RegWrite(0x3E); RegWrite(0xBE); //Set VCOMH RegWrite(0x3E); RegWrite(0x87); //Set Master Current Control RegWrite(0x0F); RegWrite(0x81); //Set Contrast Control for Color gAh RegWrite(0x80); RegWrite(0x82); //Set Contrast Control for Color gBh RegWrite(0x80); RegWrite(0x83); //Set Contrast Control for Color gCh RegWrite(0x80); RegWrite(0xAF); //display ON chr_size = NORMAL; cls(); } void ssd1331::on() { RegWrite(display_on); } void ssd1331::off() { RegWrite(display_off); } void ssd1331::cls() { unsigned char cmd[6]= {GAC_CLEAR_WINDOW,0,0,width,height}; RegWriteM(cmd,5); wait_us(500); Maxwindow(); background(0); } void ssd1331::set_font(unsigned char* f) { font = f; if (font==NULL) { externalfont=0; // set display.font } else { externalfont=1; } } void ssd1331::PutChar(uint8_t column,uint8_t row, int value) { if(externalfont) { // external font uint8_t hor,vert,offset,bpl,j,i,b; const unsigned char* sign; unsigned char z,w; // 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(value == '\n') { char_x = 0; char_y = char_y + vert; } if ((value < 31) || (value > 127)) return; // test char range if (char_x + hor > 95) { char_x = 0; char_y = char_y + vert; if (char_y >= 63 - 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(BGround_Color); } else { putp(Char_Color); } } } if ((w + 2) < hor) { // x offset to next char char_x += w + 2; } else char_x += hor; } else { // internal font if(value == '\n') { char_x = 0; char_y = char_y + Y_height; } if ((value < 31) || (value > 127)) return; // test char range if (char_x + X_width > width) { char_x = 0; char_y = char_y + Y_height; if (char_y >= height - Y_height) { char_y = 0; } } int i,j,w,lpx,lpy,k,l,xw; unsigned char Temp=0; j = 0; i = 0; w = X_width; FontSizeConvert(&lpx, &lpy); xw = X_width; for(i=0; i<xw; i++) { for ( l=0; l<lpx; l++) { Temp = font6x8[value-32][i]; for(j=Y_height-1; j>=0; j--) { for (k=0; k<lpy; k++) { pixel(char_x+(i*lpx)+l, char_y+(((j+1)*lpy)-1)-k, ((Temp & 0x80)==0x80) ? Char_Color : BGround_Color); } Temp = Temp << 1; } } } FontSizeConvert(&lpx, &lpy); char_x += (w*lpx); } } void ssd1331::dim() { unsigned char cmd[5]= {GAC_DIM_WINDOW,0,0,width,height}; RegWriteM(cmd,5); } void ssd1331::contrast(char value) { int v = value*20; if(v>180) { v=180; } unsigned char cmd[7]; cmd[0] = contrastA; cmd[1] = v; cmd[2] = contrastB; cmd[3] = v; cmd[4] = contrastC; cmd[5] = v; RegWriteM(cmd, 6); } uint16_t ssd1331::toRGB(uint16_t R,uint16_t G,uint16_t B) { uint16_t c; c = R >> 3; c <<= 6; c |= G >> 2; c <<= 5; c |= B >> 3; return c; } void ssd1331::rect(uint8_t x1,uint8_t y1,uint8_t x2,uint8_t y2,uint16_t colorline) { if ( x1 > width ) x1 = width; if ( y1 > height ) y1 = height; if ( x2 > width ) x2 = width; if ( y2 > height ) y2 = height; unsigned char cmd[11]= { 0 }; cmd[0] = GAC_FILL_ENABLE_DISABLE; cmd[1] = 0; // fill 1, empty 0 RegWriteM(cmd, 2); cmd[0] = GAC_DRAW_RECTANGLE; cmd[1] = (unsigned char)x1; cmd[2] = (unsigned char)y1; cmd[3] = (unsigned char)x2; cmd[4] = (unsigned char)y2; cmd[5] = (unsigned char)((colorline>> 11) << 1); // Outline Blue cmd[6] = (unsigned char)((colorline>> 5 ) & 0x3F); // Outline Green cmd[7] = (unsigned char)((colorline<< 1 ) & 0x3F); // Outline Red cmd[8] = (0); cmd[9] = (0); cmd[10]= (0); RegWriteM(cmd, 11); wait_us(500); } void ssd1331::fillrect(uint8_t x1,uint8_t y1,uint8_t x2,uint8_t y2,uint16_t colorline,uint16_t colorfill) { if ( x1 > width ) x1 = width; if ( y1 > height ) y1 = height; if ( x2 > width ) x2 = width; if ( y2 > height ) y2 = height; unsigned char cmd[11]= { 0 }; cmd[0] = GAC_FILL_ENABLE_DISABLE; cmd[1] = 1; // fill 1, empty 0 RegWriteM(cmd, 2); cmd[0] = GAC_DRAW_RECTANGLE; cmd[1] = (unsigned char)x1; cmd[2] = (unsigned char)y1; cmd[3] = (unsigned char)x2; cmd[4] = (unsigned char)y2; cmd[5] = (unsigned char)((colorline>> 11) << 1); // Outline Blue cmd[6] = (unsigned char)((colorline>> 5 ) & 0x3F); // Outline Green cmd[7] = (unsigned char)((colorline<< 1 ) & 0x3F); // Outline Red cmd[8] = (unsigned char)((colorfill>> 11) << 1); // fill Blue cmd[9] = (unsigned char)((colorfill>> 5 ) & 0x3F); // fill Green cmd[10]= (unsigned char)((colorfill<< 1 ) & 0x3F); // fill Red RegWriteM(cmd, 11); wait_us(500); } void ssd1331::line(uint8_t x1,uint8_t y1,uint8_t x2,uint8_t y2,uint16_t color) { if ( x1 > width ) x1 = width; if ( y1 > height ) y1 = height; if ( x2 > width ) x2 = width; if ( y2 > height ) y2 = height; unsigned char cmd[11]= { 0 }; cmd[0] = GAC_FILL_ENABLE_DISABLE; cmd[1] = 0; // fill 0, empty 0 RegWriteM(cmd, 2); cmd[0] = GAC_DRAW_LINE; cmd[1] = (unsigned char)x1; cmd[2] = (unsigned char)y1; cmd[3] = (unsigned char)x2; cmd[4] = (unsigned char)y2; cmd[5] = (unsigned char)(((color>>11)&0x1F)<<1); // Blue cmd[6] = (unsigned char)((color>>5)&0x3F); // Green cmd[7] = (unsigned char)((color&0x1F)<<1); // Red RegWriteM(cmd, 8); wait_us(500); } void ssd1331::circle (uint8_t radius, uint8_t x, uint8_t y , uint16_t col, uint16_t fill) { if ( x > width ) x = width; if ( y > height ) y = height; int16_t cx, cy, d; d = 3 - 2 * radius; cy = radius; pixel(x, radius+y, col); pixel(x, -radius+y, col); pixel(radius+x, y, col); pixel(-radius+x, y, col); if(fill) { line(x,radius+y,x,-radius+y,col); line( radius+x,y,-radius+x,y,col); } for (cx = 0; cx <= cy; cx++) { if(d>=0) { d+=10+4*cx-4*cy; cy--; } else { d+=6+4*cx; } pixel(cy+x, cx+y, col); pixel(cx+x, cy+y, col); pixel(-cx+x, cy+y, col); pixel(-cy+x, cx+y, col); pixel(-cy+x, -cx+y, col); pixel(-cx+x, -cy+y, col); pixel(cx+x, -cy+y, col); pixel(cy+x, -cx+y, col); if(fill) { line(cy+x, cx+y, cy+x, -cx+y, col); line(cx+x, cy+y, cx+x, -cy + y, col); line(-cx+x, cy+y, -cx+x, cy+y, col); line(-cy+x, cx+y, -cy+x, cx+y, col); line(-cy+x, -cx+y, -cy+x, cx+y, col); line(-cx+x, -cy+y, -cx+x, cy+y, col); line(cx+x, -cy+y, cx+x, cy+y, col); line(cy+x, -cx+y, cy+x, cx+y, col); } } } void ssd1331::ScrollSet(int8_t horizontal, int8_t startline, int8_t linecount, int8_t vertical , int8_t frame_interval) { unsigned char cmd[7]; if((startline>height+1)||((startline+linecount)>height+1)) return ; if ( frame_interval > 3 ) frame_interval = 3; cmd[0] = SCROLL_SETUP; // cmd[1] = horizontal; cmd[2] = startline; cmd[3] = linecount; cmd[4] = vertical; cmd[5] = frame_interval; RegWriteM(cmd,6); } void ssd1331::Bitmap(const uint8_t *bitmap, uint8_t x, uint8_t y, uint8_t w, uint8_t h, unsigned char color) { window(x, y, w, h); int16_t i, j, byteWidth = (w + 7) / 8; for(j=0; j<h; j++) { for(i=0; i<w; i++ ) { if(bitmap[ j * byteWidth + i / 8] & (128 >> (i & 7))) { pixel(x+i, y+j, color); } } } Maxwindow(); } void ssd1331::Bitmap16(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *bitmap) { int8_t i,j; int8_t padd; unsigned short *bitmap_ptr = (unsigned short *)bitmap; window(x, y, w, h); // the lines are padded to multiple of 4 bytes in a bitmap padd = -1; do { padd ++; } while (2*(w + padd)%4 != 0); window(x, y, w, h); bitmap_ptr += ((h - 1)* (w + padd)); for (j = 0; j < h; j++) { //Lines for (i = 0; i < w; i++) { // one line DataWrite_to(*bitmap_ptr); bitmap_ptr++; } bitmap_ptr -= 2*w; bitmap_ptr -= padd; } Maxwindow(); } int ssd1331::Bitmap16RAM(uint8_t x, uint8_t y, unsigned char *Name_BMP) { #define OffsetPixelWidth 18 #define OffsetPixelHeigh 22 #define OffsetFileSize 34 #define OffsetPixData 10 #define OffsetBPP 28 char filename[50]; unsigned char BMP_Header[54]; unsigned short BPP_t; unsigned int PixelWidth,PixelHeigh,start_data; char * buffer; size_t result; int fileSize,padd,i,j; i=0; while (*Name_BMP!='\0') { filename[i++]=*Name_BMP++; } filename[i] = 0; FILE *Image = fopen((const char *)&filename[0], "rb"); // open the bmp file if (!Image) { return(0); // error file not found ! } fread(&BMP_Header[0],1,54,Image); // get the BMP Header if (BMP_Header[0] != 0x42 || BMP_Header[1] != 0x4D) { // check magic byte fclose(Image); return(-1); // error not BMP file } BPP_t = BMP_Header[OffsetBPP] + (BMP_Header[OffsetBPP + 1] << 8); if (BPP_t != 0x0010) { fclose(Image); return(-2); // error not 16 bit BMP } PixelHeigh = BMP_Header[OffsetPixelHeigh] + (BMP_Header[OffsetPixelHeigh + 1] << 8) + (BMP_Header[OffsetPixelHeigh + 2] << 16) + (BMP_Header[OffsetPixelHeigh + 3] << 24); PixelWidth = BMP_Header[OffsetPixelWidth] + (BMP_Header[OffsetPixelWidth + 1] << 8) + (BMP_Header[OffsetPixelWidth + 2] << 16) + (BMP_Header[OffsetPixelWidth + 3] << 24); if (PixelHeigh > height+1 + y || PixelWidth > width+1 + x) { fclose(Image); return(-3); // to big } start_data = BMP_Header[OffsetPixData] + (BMP_Header[OffsetPixData + 1] << 8) + (BMP_Header[OffsetPixData + 2] << 16) + (BMP_Header[OffsetPixData + 3] << 24); // obtain file size: fseek (Image , 0 , SEEK_END); fileSize = ftell (Image)-start_data; rewind (Image); // allocate memory to contain the whole file: buffer = (char*) malloc (sizeof(char)*fileSize/2); if (buffer == NULL) {return (fileSize/2);} // copy the file into the buffer: fseek (Image, start_data , SEEK_SET ); // set SD file data start position result = fread (buffer,1,fileSize,Image); fclose (Image); if (result != fileSize) {return (-5);} unsigned short *bitmap_ptr = (unsigned short *)buffer; // the lines are padded to multiple of 4 bytes in a bitmap padd = -1; do { padd ++; } while (2*(PixelWidth + padd)%4 != 0); bitmap_ptr += ((PixelHeigh - 1)* (PixelWidth + padd)); window(x, y, PixelWidth, PixelHeigh); for (j = 0; j < PixelHeigh; j++) { //Lines for (i = 0; i < PixelWidth; i++) { // one line DataWrite_to(*bitmap_ptr); bitmap_ptr++; } bitmap_ptr -= 2*PixelWidth ; bitmap_ptr -= padd; } // terminate free (buffer); Maxwindow(); return (fileSize); } int ssd1331::Bitmap16FS(uint8_t x, uint8_t y, unsigned char *Name_BMP) { #define OffsetPixelWidth 18 #define OffsetPixelHeigh 22 #define OffsetFileSize 34 #define OffsetPixData 10 #define OffsetBPP 28 char filename[50]; unsigned char BMP_Header[54]; unsigned short BPP_t; unsigned int PixelWidth,PixelHeigh,start_data; unsigned int i,off; int padd,j; unsigned short *line; i=0; while (*Name_BMP!='\0') { filename[i++]=*Name_BMP++; } filename[i] = 0; FILE *Image = fopen((const char *)&filename[0], "rb"); // open the bmp file if (!Image) { return(0); // error file not found ! } fread(&BMP_Header[0],1,54,Image); // get the BMP Header if (BMP_Header[0] != 0x42 || BMP_Header[1] != 0x4D) { // check magic byte fclose(Image); return(-1); // error no BMP file } BPP_t = BMP_Header[OffsetBPP] + (BMP_Header[OffsetBPP + 1] << 8); if (BPP_t != 0x0010) { fclose(Image); return(-2); // error no 16 bit BMP } PixelHeigh = BMP_Header[OffsetPixelHeigh] + (BMP_Header[OffsetPixelHeigh + 1] << 8) + (BMP_Header[OffsetPixelHeigh + 2] << 16) + (BMP_Header[OffsetPixelHeigh + 3] << 24); PixelWidth = BMP_Header[OffsetPixelWidth] + (BMP_Header[OffsetPixelWidth + 1] << 8) + (BMP_Header[OffsetPixelWidth + 2] << 16) + (BMP_Header[OffsetPixelWidth + 3] << 24); if (PixelHeigh > height+1 + y || PixelWidth > width+1 + x) { fclose(Image); return(-3); // to big } start_data = BMP_Header[OffsetPixData] + (BMP_Header[OffsetPixData + 1] << 8) + (BMP_Header[OffsetPixData + 2] << 16) + (BMP_Header[OffsetPixData + 3] << 24); line = (unsigned short *) malloc (PixelWidth); // we need a buffer for a line if (line == NULL) { return(-4); // error no memory } // the lines are padded to multiple of 4 bytes padd = -1; do { padd ++; } while ((PixelWidth * 2 + padd)%4 != 0); window(x, y,PixelWidth,PixelHeigh); for (j = PixelHeigh - 1; j >= 0; j--) { //Lines bottom up off = j * (PixelWidth * 2 + padd) + start_data; // start of line fseek(Image, off ,SEEK_SET); fread(line,1,PixelWidth * 2,Image); // read a line - slow ! for (i = 0; i < PixelWidth; i++) { // copy pixel data to TFT DataWrite_to(line[i]); } } free (line); fclose(Image); Maxwindow(); return(PixelWidth); } void ssd1331::Copy(uint8_t src_x1,uint8_t src_y1,uint8_t src_x2,uint8_t src_y2,uint8_t dst_x,uint8_t dst_y) { unsigned char cmd[8]= { 0 }; if ((src_x1>width)||(src_y1>height)||(src_x2>width)||(src_y2>height)) return; if ((dst_x>width)||(dst_y>height))return; cmd[0] = GAC_COPY_AREA; // cmd[1] = (unsigned char)src_x1; cmd[2] = (unsigned char)src_y1; cmd[3] = (unsigned char)src_x2; cmd[4] = (unsigned char)src_y2; cmd[5] = (unsigned char)dst_x; cmd[6] = (unsigned char)dst_y; RegWriteM(cmd,7); } void ssd1331::Fill_Screen(uint16_t color) { BGround_Color = color; fillrect(0,0,width,height,color,color); } void ssd1331::locate(uint8_t column, uint8_t row) { char_x = column; char_y = row; } void ssd1331::foreground(uint16_t color) { Char_Color = color; } void ssd1331::background(uint16_t color) { BGround_Color = color; } void ssd1331::SetFontSize(uint8_t Csize) { chr_size = Csize; } void ssd1331::putp(int colour) { pixel(_x, _y, colour); _x++; if(_x > _x2) { _x = _x1; _y++; if(_y > _y2) { _y = _y1; } } } int ssd1331::_putc( int c ) { PutChar( char_x , char_y ,c); return c; } void ssd1331::pixel(uint8_t x,uint8_t y,uint16_t Color) { unsigned char cmd[7]= {Set_Column_Address,0x00,0x00,Set_Row_Address,0x00,0x00}; if ((x>width)||(y>height)) return ; cmd[1] = (unsigned char)x; cmd[2] = (unsigned char)x; cmd[4] = (unsigned char)y; cmd[5] = (unsigned char)y; RegWriteM(cmd, 6); DataWrite_to(Color); } void ssd1331::Maxwindow() { unsigned char cmd[7]= {Set_Column_Address,0x00,0x5F,Set_Row_Address,0x00,0x3F}; RegWriteM(cmd, 6); } void ssd1331::window(uint8_t x, uint8_t y, uint8_t w, uint8_t h) { _x = x; _y = y; // window settings _x1 = x; // start y _x2 = x + w - 1; // end x _y1 = y; // start y _y2 = y + h - 1; // end y unsigned char cmd[7]= {Set_Column_Address,0x00,0x00,Set_Row_Address,0x00,0x00}; RegWriteM(cmd, 6); unsigned char cmd2[7]= {Set_Column_Address,_x1,_x2,Set_Row_Address,_y1,_y2}; RegWriteM(cmd2, 6); } void ssd1331::Scrollstart() { RegWrite(SCROLL_START); } void ssd1331::Scrollstop() { RegWrite(SCROLL_STOP); } int ssd1331::_getc() { return -1; } uint8_t ssd1331::row() { return char_y; } uint8_t ssd1331::column() { return char_x; } void ssd1331::FontSizeConvert(int *lpx,int *lpy) { switch( chr_size ) { case WIDE: *lpx=2; *lpy=1; break; case HIGH: *lpx=1; *lpy=2; break; case WH : *lpx=2; *lpy=2; break; case WHx36 : *lpx=6; *lpy=6; break; case NORMAL: default: *lpx=1; *lpy=1; break; } } void ssd1331::RegWrite(unsigned char Command) { DC = 0; // Command CS = 0; // CS enable spi.write(Command); CS = 1; // CS dissable } void ssd1331::RegWriteM(unsigned char *Command, uint8_t count) { int i; DC = 0; // Command CS = 0; // CS enable for( i=0; i<count; i++) { spi.write(*Command++); } CS = 1; // CS dissable } void ssd1331::DataWrite(unsigned char c) { DC = 1; // DATA CS = 0; // CS enable spi.write(c); CS = 1; // CS dissable } void ssd1331::DataWrite_to(uint16_t Dat) { DC = 1; // DATA CS = 0; // CS enable spi.write((unsigned char)((Dat >> 8))); spi.write((unsigned char)(Dat)); CS = 1; // CS dissable }