This driver is meant for the monochrome LCD display (model no: LS013B4DN04) from Sharp; but it should be easily adaptable to other Sharp displays.
FrameBuffer.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include "SharpLCD.hpp" 00018 00019 SharpLCD::FrameBuffer::FrameBuffer(uint8_t *fb) : buffer(fb) 00020 { 00021 clear(); 00022 00023 /* Make sure the dummy bytes are clear */ 00024 ((uint8_t *)buffer)[SIZEOF_FRAMEBUFFER] = DUMMY8; 00025 ((uint8_t *)buffer)[SIZEOF_FRAMEBUFFER + 1] = DUMMY8; 00026 } 00027 00028 void 00029 SharpLCD::FrameBuffer::clear(void) 00030 { 00031 uint8_t *pfb; 00032 unsigned int row; 00033 unsigned int index; 00034 00035 /* initialize the frame buffer */ 00036 pfb = buffer; 00037 for (row = 0; row < LCD_HEIGHT; row++) { 00038 for (index = 0; index < LCD_FRAMEBUFFER_SIZEOF_SCAN_LINE; index++) { 00039 switch (index) { 00040 case 0: 00041 *pfb++ = M0_FLAG; /* update line command */ 00042 break; 00043 case 1: 00044 *pfb++ = bitReverse8(row + 1); 00045 break; 00046 default: 00047 *pfb++ = 0xFF; /* all white */ 00048 break; 00049 } 00050 } 00051 } 00052 } 00053 00054 void 00055 SharpLCD::FrameBuffer::bitBlit(const uint8_t *bitmap, 00056 unsigned int width, /* width of the bitmap */ 00057 unsigned int height, /* height of the bitmap */ 00058 unsigned int posx, /* x-offset of the top-left 00059 * corner of the bitmap 00060 * w.r.t. the top-left 00061 * corner of the screen */ 00062 unsigned int posy /* y-offset of the top-left 00063 * corner of the bitmap 00064 * w.r.t. the top-left 00065 * corner of the screen */) 00066 { 00067 unsigned int row; 00068 unsigned int col; 00069 unsigned int bitsToBlitInRow; 00070 unsigned int destByteIndex; /* within the current row */ 00071 unsigned int destBitIndexMod8; /* bits to the right of this index in 00072 * 'destByte' need to be blitted next; 00073 * MSB has index 0. */ 00074 unsigned int srcByteIndex; /* byte index within the source bitmap */ 00075 unsigned int srcBitIndexMod8; /* bits to the right of this index in 00076 * source byte (at index srcByteIndex) 00077 * need to be blitted to the dest; MSB 00078 * has index 0. */ 00079 const unsigned int endRow = posy + height; 00080 uint8_t destByte; 00081 uint8_t srcBits; 00082 00083 #if 0 00084 unsigned long current_cycle_count = Get_system_register(AVR32_COUNT); 00085 #endif 00086 00087 // ASSERT(bitmap != NULL, "%s: passed in a NULL bitmap", __FUNCTION__); 00088 // ASSERT(width > 0, "%s: passed in an invalid width", __FUNCTION__); 00089 // ASSERT(height > 0, "%s: passed in an invalid height", __FUNCTION__); 00090 // ASSERT(posx + width <= LCD_WIDTH, 00091 // "%s: bitmap will exceed the screen width", __FUNCTION__); 00092 // ASSERT(posy + height <= LCD_HEIGHT, 00093 // "%s: bitmap will exceed the screen height", __FUNCTION__); 00094 00095 /* 00096 * A couple of helpful macros to maintain a source bitstream. 00097 */ 00098 #define SHIFT_INTO_SRC_BITS_FROM_SINGLE_SRC_BYTE(M) do { \ 00099 uint8_t mask; \ 00100 \ 00101 mask = ((uint8_t)((uint8_t)1 << (M)) - 1); \ 00102 srcBits <<= (M); \ 00103 srcBits |= (bitmap[srcByteIndex] >> (8 - (srcBitIndexMod8 + (M)))) & mask; \ 00104 \ 00105 /* update the indices */ \ 00106 srcBitIndexMod8 += (M); \ 00107 if (srcBitIndexMod8 == 8) { \ 00108 srcBitIndexMod8 = 0; \ 00109 srcByteIndex++; \ 00110 } \ 00111 } while (0) 00112 00113 /* Left-shift N bits into srcBits; fetching them from the source 00114 * bitmap. */ 00115 #define SHIFT_INTO_SRC_BITS(N) do { \ 00116 uint8_t bitsToShift; \ 00117 \ 00118 bitsToShift = (N); \ 00119 \ 00120 if ((srcBitIndexMod8 + (N)) > 8) { \ 00121 bitsToShift = 8 - srcBitIndexMod8; \ 00122 SHIFT_INTO_SRC_BITS_FROM_SINGLE_SRC_BYTE(bitsToShift); \ 00123 bitsToShift = (N) - bitsToShift; \ 00124 } \ 00125 \ 00126 SHIFT_INTO_SRC_BITS_FROM_SINGLE_SRC_BYTE(bitsToShift); \ 00127 } while (0) 00128 00129 srcByteIndex = 0; 00130 srcBitIndexMod8 = 0; 00131 for (row = posy; row < endRow; row++) { 00132 col = posx; 00133 bitsToBlitInRow = width; 00134 destBitIndexMod8 = col & 0x7 /* col % 8 */; 00135 destByteIndex = col >> 3 /* col / 8 */; 00136 srcBits = 0; 00137 00138 /* While there are bits in this row remaining to be blitted to 00139 * the destination, ... */ 00140 while (bitsToBlitInRow) { 00141 if ((destBitIndexMod8 == 0) && (bitsToBlitInRow >= 8)) { 00142 /* We know that destBitIndexMod8 == 0, which means that 00143 * the destination is byte aligned and we can simply 00144 * do the equivalent of a memcpy. */ 00145 while (bitsToBlitInRow >= 8) { 00146 SHIFT_INTO_SRC_BITS(8); 00147 setRowByte(row, destByteIndex, srcBits); 00148 00149 bitsToBlitInRow -= 8; 00150 destByteIndex++; 00151 } 00152 } else { 00153 uint8_t blit; /* number of bits to blit in this iteration */ 00154 uint8_t mask; 00155 uint8_t leftShift; 00156 00157 /* This will be a read-modify-write operation, so we 00158 * need to fetch the destination byte. */ 00159 destByte = getRowByte(row, destByteIndex); 00160 00161 if ((destBitIndexMod8 + bitsToBlitInRow) >= 8) { 00162 blit = 8 - destBitIndexMod8; 00163 leftShift = 0; 00164 } else { 00165 blit = bitsToBlitInRow; 00166 leftShift = (8 - (destBitIndexMod8 + bitsToBlitInRow)); 00167 } 00168 00169 SHIFT_INTO_SRC_BITS(blit); 00170 mask = ((uint8_t)((uint8_t)1 << blit) - 1) << leftShift; 00171 00172 /* update destByte */ 00173 destByte &= ~mask; 00174 destByte |= ((uint8_t)(srcBits << leftShift) & mask); 00175 00176 setRowByte(row, destByteIndex, destByte); 00177 00178 /* update dest indices */ 00179 bitsToBlitInRow -= blit; 00180 destBitIndexMod8 += blit; 00181 if (destBitIndexMod8 == 8) { 00182 destBitIndexMod8 = 0; 00183 destByteIndex++; 00184 } 00185 } 00186 } 00187 00188 /* potentially update srcByteIndex */ 00189 if (srcBitIndexMod8 != 0) { 00190 srcBitIndexMod8 = 0; 00191 srcByteIndex++; 00192 } 00193 } 00194 } 00195 00196 void 00197 SharpLCD::FrameBuffer::printString(const font_face_t *face, 00198 unsigned short baselineX, 00199 unsigned short baselineY, 00200 font_color_t fgColor, 00201 const char *string) 00202 { 00203 unsigned char ch; 00204 while ((ch = *string++) != '\0') { 00205 if ((ch < FONT_LOWEST_SUPPORTED_CHAR_ENCODING) || 00206 (ch > FONT_HIGHEST_SUPPORTED_CHAR_ENCODING)) { 00207 // TRACE_WARNING("printString: attempt to render unsupported char (enc: 0x%x)\n", ch); 00208 continue; 00209 } 00210 00211 const glyph_t *glyph = &face->glyphs[ch - FONT_LOWEST_SUPPORTED_CHAR_ENCODING]; 00212 00213 if ((glyph->width > 0) && (glyph->height > 0)) { 00214 bitBlit(&face->bitmaps[glyph->bitmapIndex], /* bitmap */ 00215 glyph->width, /* width of the bitmap */ 00216 glyph->height, /* height of the bitmap */ 00217 baselineX + glyph->bearingX, /* x-offset for the 00218 * placement of the top-left 00219 * corner of the bitmap. */ 00220 baselineY - glyph->bearingY /* y-offset for the 00221 * placement of the top-left 00222 * corner of the bitmap. */ 00223 ); 00224 } 00225 00226 baselineX += glyph->advance; 00227 } 00228 }
Generated on Tue Jul 12 2022 19:17:11 by 1.7.2