Fork of Silabs MemoryLCD library
Dependents: demoUI whrmDemoUI Host_Software_MAX32664GWEB_HR_EXTENDED Host_Software_MAX32664GWEC_SpO2_HR-_EXTE ... more
C++ library for Sharp Microelectronics 1.28 inch LCD TFT, LS013B7DH03, SPI bus. Forked from Silicon Labs MemoryLCD display driver.
Diff: BufferedDisplay.cpp
- Revision:
- 7:6cf0aa7bc0fc
- Parent:
- 6:fe04073fe90c
- Child:
- 8:39206d1e11f7
--- a/BufferedDisplay.cpp Wed Jul 29 09:03:13 2015 +0000 +++ b/BufferedDisplay.cpp Thu Jul 30 08:51:58 2015 +0000 @@ -45,16 +45,48 @@ */ void BufferedDisplay::pixel(int x, int y, int colour) { + /* Apply constraint to x and y */ + if(x < 0 || y < 0) return; + + /***************************************************************************************************************** + * The display expects LSB input, while the SPI is configured for 8bit MSB transfers. Therefore, we should + * construct the framebuffer accordingly, so that an MSB transmission will put pixel 0 first on the wire. + * + * So the actual pixel layout in framebuffer (for 128x128) is as follows: + * { //Framebuffer + * { //Line 0 + * {p0, p1, p2, p3, p4, p5, p6, p7}, //Line 0 byte 0 (byte 0) + * {p8, p9,p10,p11,p12,p13,p14,p15}, //Line 0 byte 1 (byte 1) + * ... + * {p120,p121,p122,p123,p124,p125,p126,p127} //Line 0 byte 15 (byte 15) + * }, + * { //Line 1 + * {p128,p129,p130,p131,p132,p133,p134,p135}, //Line 1 byte 0 (byte 16) + * ... + * }, + * ... + * { //Line 127 + * {...}, //Line 127 byte 0 (byte 2032) + * ... + * {...} //Line 127 byte 15 (byte 2047) = 128*128 bits + * } + * } + * + * This means that to calculate the actual bit position in the framebuffer byte, we need to swap the bit + * order of the lower three bits. So pixel 7 becomes bit offset 0, 6 -> 1, 5 -> 2, 4->3, 3->4, 2->5, 1->6 and 0->7. + *****************************************************************************************************************/ uint8_t swapx = 7 - ((unsigned int)x & 0x07); x = ((unsigned int)x & 0xFFFFFFF8) | swapx; - // determine change + /* Since we are dealing with 1-bit pixels, we can avoid having to do bitshift and comparison operations twice. + * Basically, do the comparison with the requested state and current state, and if it changed, do an XOR on the framebuffer pixel and set the line to dirty. + */ 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 + /* Do XOR (no bitshifting required) */ _pixelBuffer[((y * DISPLAY_WIDTH) + x) / DISPLAY_BUFFER_TYPE_SIZE] ^= (1 << (x % DISPLAY_BUFFER_TYPE_SIZE)); - // notify dirty status of this line + /* notify dirty status of this line */ _dirtyRows[y / DISPLAY_BUFFER_TYPE_SIZE] |= (1 << (y % DISPLAY_BUFFER_TYPE_SIZE)); } } @@ -86,12 +118,17 @@ //Superflouous due to for-loop check //if((startY >= DISPLAY_HEIGHT) return; - /* Copy over bytes to the framebuffer */ + /* Copy over bytes to the framebuffer, do not write outside framebuffer boundary */ for(; y < DISPLAY_HEIGHT; y++) { + /* Check that we are not writing more than the BMP height */ + if(bitmapLine >= bitmapHeight) break; + + /* Copy over one line (bitmapLine) from the BMP file to the corresponding line (y) in the pixel buffer */ memcpy( (void*) &(((uint8_t*)_pixelBuffer)[((y * DISPLAY_WIDTH) + startX) / 8]), (const void*) &(bitmap[bitmapLine * (bmpWidth / 8)]), bytesPerLine); + /* Set dirty status for the line we just overwrote */ _dirtyRows[y / DISPLAY_BUFFER_TYPE_SIZE] |= (1 << (y % DISPLAY_BUFFER_TYPE_SIZE)); bitmapLine++; }