Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
BufferedDisplay.cpp
00001 /***************************************************************************//** 00002 * @file BufferedDisplay.cpp 00003 * @brief Buffered version of GraphicsDisplay 00004 ******************************************************************************* 00005 * @section License 00006 * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b> 00007 ******************************************************************************* 00008 * 00009 * Permission is granted to anyone to use this software for any purpose, 00010 * including commercial applications, and to alter it and redistribute it 00011 * freely, subject to the following restrictions: 00012 * 00013 * 1. The origin of this software must not be misrepresented; you must not 00014 * claim that you wrote the original software. 00015 * 2. Altered source versions must be plainly marked as such, and must not be 00016 * misrepresented as being the original software. 00017 * 3. This notice may not be removed or altered from any source distribution. 00018 * 00019 * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no 00020 * obligation to support this Software. Silicon Labs is providing the 00021 * Software "AS IS", with no express or implied warranties of any kind, 00022 * including, but not limited to, any implied warranties of merchantability 00023 * or fitness for any particular purpose or warranties against infringement 00024 * of any proprietary rights of a third party. 00025 * 00026 * Silicon Labs will not be liable for any consequential, incidental, or 00027 * special damages, or any other relief, or for any claim by any third party, 00028 * arising from your use of this Software. 00029 * 00030 ******************************************************************************/ 00031 00032 #include "../screen/BufferedDisplay.h" 00033 00034 #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)) 00035 00036 namespace silabs { 00037 00038 BufferedDisplay::BufferedDisplay(const char *name) : GraphicsDisplay(name) { 00039 memset((uint8_t*)_pixelBuffer, White, sizeof(_pixelBuffer)); // init full frame buffer 00040 memset((uint8_t*)_dirtyRows, 0xFF, sizeof(_dirtyRows)); // init dirty status 00041 } 00042 00043 /** 00044 * Override of GraphicsDisplay's pixel() 00045 */ 00046 00047 void BufferedDisplay::pixel(int x, int y, int colour) { 00048 /* Apply constraint to x and y */ 00049 if(x < 0 || y < 0) return; 00050 if(x >= DISPLAY_WIDTH || y >= DISPLAY_HEIGHT) return; 00051 00052 /***************************************************************************************************************** 00053 * The display expects LSB input, while the SPI is configured for 8bit MSB transfers. Therefore, we should 00054 * construct the framebuffer accordingly, so that an MSB transmission will put pixel 0 first on the wire. 00055 * 00056 * So the actual pixel layout in framebuffer (for 128x128) is as follows: 00057 * { //Framebuffer 00058 * { //Line 0 00059 * {p0, p1, p2, p3, p4, p5, p6, p7}, //Line 0 byte 0 (byte 0) 00060 * {p8, p9,p10,p11,p12,p13,p14,p15}, //Line 0 byte 1 (byte 1) 00061 * ... 00062 * {p120,p121,p122,p123,p124,p125,p126,p127} //Line 0 byte 15 (byte 15) 00063 * }, 00064 * { //Line 1 00065 * {p128,p129,p130,p131,p132,p133,p134,p135}, //Line 1 byte 0 (byte 16) 00066 * ... 00067 * }, 00068 * ... 00069 * { //Line 127 00070 * {...}, //Line 127 byte 0 (byte 2032) 00071 * ... 00072 * {...} //Line 127 byte 15 (byte 2047) = 128*128 bits 00073 * } 00074 * } 00075 * 00076 * This means that to calculate the actual bit position in the framebuffer byte, we need to swap the bit 00077 * 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. 00078 *****************************************************************************************************************/ 00079 uint8_t swapx = 7 - ((unsigned int)x & 0x07); 00080 x = ((unsigned int)x & 0xFFFFFFF8) | swapx; 00081 00082 /* Since we are dealing with 1-bit pixels, we can avoid having to do bitshift and comparison operations twice. 00083 * 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. 00084 */ 00085 bool change = ((_pixelBuffer[((y * DISPLAY_WIDTH) + x) / DISPLAY_BUFFER_TYPE_SIZE] & (1 << (x & DISPLAY_BUFFER_TYPE_MASK))) != ((colour & 0x01) << (x & DISPLAY_BUFFER_TYPE_MASK))); 00086 if(change) { 00087 /* Pixel's value and requested value are different, so since it's binary, we can simply do an XOR */ 00088 _pixelBuffer[((y * DISPLAY_WIDTH) + x) / DISPLAY_BUFFER_TYPE_SIZE] ^= (1 << (x & DISPLAY_BUFFER_TYPE_MASK)); 00089 00090 /* notify dirty status of this line */ 00091 _dirtyRows[y / DISPLAY_BUFFER_TYPE_SIZE] |= (1 << (y & DISPLAY_BUFFER_TYPE_MASK)); 00092 } 00093 } 00094 00095 int BufferedDisplay::width() { 00096 return DISPLAY_WIDTH; 00097 } 00098 int BufferedDisplay::height() { 00099 return DISPLAY_HEIGHT; 00100 } 00101 00102 /** 00103 * Function to move bitmap into frame buffer 00104 * arguments: 00105 * * bitmap: pointer to uint8 array containing horizontal pixel data 00106 * * bmpWidth: width of the bitmap in pixels (must be multiple of 8) 00107 * * bmpHeight: height of the bitmap in pixels 00108 * * startX: starting position to apply bitmap in horizontal direction (0 = leftmost) (must be multiple of 8) 00109 * * startY: starting position to apply bitmap in vertical direction (0 = topmost) 00110 */ 00111 void BufferedDisplay::showBMP(const uint8_t* bitmap, const uint32_t bmpWidth, const uint32_t bmpHeight, const uint32_t startX, const uint32_t startY) { 00112 uint32_t bmpLine = 0, y = startY, bytesPerLine = ((bmpWidth >= (DISPLAY_WIDTH - startX)) ? (DISPLAY_WIDTH - startX) : bmpWidth) / 8; 00113 00114 /* Apply constraints */ 00115 if((bmpWidth & 0x07) != 0) return; 00116 if((startX & 0x07) != 0) return; 00117 if(startX >= DISPLAY_WIDTH) return; 00118 00119 //Superflouous due to for-loop check 00120 //if((startY >= DISPLAY_HEIGHT) return; 00121 00122 /* Copy over bytes to the framebuffer, do not write outside framebuffer boundary */ 00123 for(; y < DISPLAY_HEIGHT; y++) { 00124 /* Check that we are not writing more than the BMP height */ 00125 if(bmpLine >= bmpHeight) break; 00126 00127 /* Copy over one line (bmpLine) from the BMP file to the corresponding line (y) in the pixel buffer */ 00128 memcpy( (void*) &(((uint8_t*)_pixelBuffer)[((y * DISPLAY_WIDTH) + startX) / 8]), 00129 (const void*) &(bitmap[bmpLine * (bmpWidth / 8)]), 00130 bytesPerLine); 00131 00132 /* Set dirty status for the line we just overwrote */ 00133 _dirtyRows[y / DISPLAY_BUFFER_TYPE_SIZE] |= (1 << (y % DISPLAY_BUFFER_TYPE_SIZE)); 00134 bmpLine++; 00135 } 00136 00137 return; 00138 } 00139 }
Generated on Fri Jul 15 2022 01:41:58 by
1.7.2