This driver is meant for the monochrome LCD display (model no: LS013B4DN04) from Sharp; but it should be easily adaptable to other Sharp displays.

Dependents:   sharpLCD-demo

Committer:
rgrover1
Date:
Thu Aug 07 14:27:12 2014 +0000
Revision:
3:761d0f489b61
Parent:
2:270ee57c0367
minor improvement to the constructor for SharpLCD

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rgrover1 0:62d7cfac67ca 1 /* mbed Microcontroller Library
rgrover1 0:62d7cfac67ca 2 * Copyright (c) 2006-2013 ARM Limited
rgrover1 0:62d7cfac67ca 3 *
rgrover1 0:62d7cfac67ca 4 * Licensed under the Apache License, Version 2.0 (the "License");
rgrover1 0:62d7cfac67ca 5 * you may not use this file except in compliance with the License.
rgrover1 0:62d7cfac67ca 6 * You may obtain a copy of the License at
rgrover1 0:62d7cfac67ca 7 *
rgrover1 0:62d7cfac67ca 8 * http://www.apache.org/licenses/LICENSE-2.0
rgrover1 0:62d7cfac67ca 9 *
rgrover1 0:62d7cfac67ca 10 * Unless required by applicable law or agreed to in writing, software
rgrover1 0:62d7cfac67ca 11 * distributed under the License is distributed on an "AS IS" BASIS,
rgrover1 0:62d7cfac67ca 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rgrover1 0:62d7cfac67ca 13 * See the License for the specific language governing permissions and
rgrover1 0:62d7cfac67ca 14 * limitations under the License.
rgrover1 0:62d7cfac67ca 15 */
rgrover1 0:62d7cfac67ca 16
rgrover1 0:62d7cfac67ca 17 #include "SharpLCD.hpp"
rgrover1 0:62d7cfac67ca 18
rgrover1 0:62d7cfac67ca 19 SharpLCD::FrameBuffer::FrameBuffer(uint8_t *fb) : buffer(fb)
rgrover1 0:62d7cfac67ca 20 {
rgrover1 2:270ee57c0367 21 clear();
rgrover1 2:270ee57c0367 22
rgrover1 2:270ee57c0367 23 /* Make sure the dummy bytes are clear */
rgrover1 2:270ee57c0367 24 ((uint8_t *)buffer)[SIZEOF_FRAMEBUFFER] = DUMMY8;
rgrover1 2:270ee57c0367 25 ((uint8_t *)buffer)[SIZEOF_FRAMEBUFFER + 1] = DUMMY8;
rgrover1 2:270ee57c0367 26 }
rgrover1 2:270ee57c0367 27
rgrover1 2:270ee57c0367 28 void
rgrover1 2:270ee57c0367 29 SharpLCD::FrameBuffer::clear(void)
rgrover1 2:270ee57c0367 30 {
rgrover1 0:62d7cfac67ca 31 uint8_t *pfb;
rgrover1 0:62d7cfac67ca 32 unsigned int row;
rgrover1 0:62d7cfac67ca 33 unsigned int index;
rgrover1 0:62d7cfac67ca 34
rgrover1 0:62d7cfac67ca 35 /* initialize the frame buffer */
rgrover1 0:62d7cfac67ca 36 pfb = buffer;
rgrover1 0:62d7cfac67ca 37 for (row = 0; row < LCD_HEIGHT; row++) {
rgrover1 0:62d7cfac67ca 38 for (index = 0; index < LCD_FRAMEBUFFER_SIZEOF_SCAN_LINE; index++) {
rgrover1 0:62d7cfac67ca 39 switch (index) {
rgrover1 0:62d7cfac67ca 40 case 0:
rgrover1 0:62d7cfac67ca 41 *pfb++ = M0_FLAG; /* update line command */
rgrover1 0:62d7cfac67ca 42 break;
rgrover1 0:62d7cfac67ca 43 case 1:
rgrover1 0:62d7cfac67ca 44 *pfb++ = bitReverse8(row + 1);
rgrover1 0:62d7cfac67ca 45 break;
rgrover1 0:62d7cfac67ca 46 default:
rgrover1 0:62d7cfac67ca 47 *pfb++ = 0xFF; /* all white */
rgrover1 0:62d7cfac67ca 48 break;
rgrover1 0:62d7cfac67ca 49 }
rgrover1 0:62d7cfac67ca 50 }
rgrover1 0:62d7cfac67ca 51 }
rgrover1 0:62d7cfac67ca 52 }
rgrover1 0:62d7cfac67ca 53
rgrover1 0:62d7cfac67ca 54 void
rgrover1 0:62d7cfac67ca 55 SharpLCD::FrameBuffer::bitBlit(const uint8_t *bitmap,
rgrover1 0:62d7cfac67ca 56 unsigned int width, /* width of the bitmap */
rgrover1 0:62d7cfac67ca 57 unsigned int height, /* height of the bitmap */
rgrover1 0:62d7cfac67ca 58 unsigned int posx, /* x-offset of the top-left
rgrover1 0:62d7cfac67ca 59 * corner of the bitmap
rgrover1 0:62d7cfac67ca 60 * w.r.t. the top-left
rgrover1 0:62d7cfac67ca 61 * corner of the screen */
rgrover1 0:62d7cfac67ca 62 unsigned int posy /* y-offset of the top-left
rgrover1 0:62d7cfac67ca 63 * corner of the bitmap
rgrover1 0:62d7cfac67ca 64 * w.r.t. the top-left
rgrover1 0:62d7cfac67ca 65 * corner of the screen */)
rgrover1 0:62d7cfac67ca 66 {
rgrover1 0:62d7cfac67ca 67 unsigned int row;
rgrover1 0:62d7cfac67ca 68 unsigned int col;
rgrover1 0:62d7cfac67ca 69 unsigned int bitsToBlitInRow;
rgrover1 0:62d7cfac67ca 70 unsigned int destByteIndex; /* within the current row */
rgrover1 0:62d7cfac67ca 71 unsigned int destBitIndexMod8; /* bits to the right of this index in
rgrover1 0:62d7cfac67ca 72 * 'destByte' need to be blitted next;
rgrover1 0:62d7cfac67ca 73 * MSB has index 0. */
rgrover1 0:62d7cfac67ca 74 unsigned int srcByteIndex; /* byte index within the source bitmap */
rgrover1 0:62d7cfac67ca 75 unsigned int srcBitIndexMod8; /* bits to the right of this index in
rgrover1 0:62d7cfac67ca 76 * source byte (at index srcByteIndex)
rgrover1 0:62d7cfac67ca 77 * need to be blitted to the dest; MSB
rgrover1 0:62d7cfac67ca 78 * has index 0. */
rgrover1 0:62d7cfac67ca 79 const unsigned int endRow = posy + height;
rgrover1 0:62d7cfac67ca 80 uint8_t destByte;
rgrover1 0:62d7cfac67ca 81 uint8_t srcBits;
rgrover1 0:62d7cfac67ca 82
rgrover1 0:62d7cfac67ca 83 #if 0
rgrover1 0:62d7cfac67ca 84 unsigned long current_cycle_count = Get_system_register(AVR32_COUNT);
rgrover1 0:62d7cfac67ca 85 #endif
rgrover1 0:62d7cfac67ca 86
rgrover1 0:62d7cfac67ca 87 // ASSERT(bitmap != NULL, "%s: passed in a NULL bitmap", __FUNCTION__);
rgrover1 0:62d7cfac67ca 88 // ASSERT(width > 0, "%s: passed in an invalid width", __FUNCTION__);
rgrover1 0:62d7cfac67ca 89 // ASSERT(height > 0, "%s: passed in an invalid height", __FUNCTION__);
rgrover1 0:62d7cfac67ca 90 // ASSERT(posx + width <= LCD_WIDTH,
rgrover1 0:62d7cfac67ca 91 // "%s: bitmap will exceed the screen width", __FUNCTION__);
rgrover1 0:62d7cfac67ca 92 // ASSERT(posy + height <= LCD_HEIGHT,
rgrover1 0:62d7cfac67ca 93 // "%s: bitmap will exceed the screen height", __FUNCTION__);
rgrover1 0:62d7cfac67ca 94
rgrover1 0:62d7cfac67ca 95 /*
rgrover1 0:62d7cfac67ca 96 * A couple of helpful macros to maintain a source bitstream.
rgrover1 0:62d7cfac67ca 97 */
rgrover1 0:62d7cfac67ca 98 #define SHIFT_INTO_SRC_BITS_FROM_SINGLE_SRC_BYTE(M) do { \
rgrover1 0:62d7cfac67ca 99 uint8_t mask; \
rgrover1 0:62d7cfac67ca 100 \
rgrover1 0:62d7cfac67ca 101 mask = ((uint8_t)((uint8_t)1 << (M)) - 1); \
rgrover1 0:62d7cfac67ca 102 srcBits <<= (M); \
rgrover1 0:62d7cfac67ca 103 srcBits |= (bitmap[srcByteIndex] >> (8 - (srcBitIndexMod8 + (M)))) & mask; \
rgrover1 0:62d7cfac67ca 104 \
rgrover1 0:62d7cfac67ca 105 /* update the indices */ \
rgrover1 0:62d7cfac67ca 106 srcBitIndexMod8 += (M); \
rgrover1 0:62d7cfac67ca 107 if (srcBitIndexMod8 == 8) { \
rgrover1 0:62d7cfac67ca 108 srcBitIndexMod8 = 0; \
rgrover1 0:62d7cfac67ca 109 srcByteIndex++; \
rgrover1 0:62d7cfac67ca 110 } \
rgrover1 0:62d7cfac67ca 111 } while (0)
rgrover1 0:62d7cfac67ca 112
rgrover1 0:62d7cfac67ca 113 /* Left-shift N bits into srcBits; fetching them from the source
rgrover1 0:62d7cfac67ca 114 * bitmap. */
rgrover1 0:62d7cfac67ca 115 #define SHIFT_INTO_SRC_BITS(N) do { \
rgrover1 0:62d7cfac67ca 116 uint8_t bitsToShift; \
rgrover1 0:62d7cfac67ca 117 \
rgrover1 0:62d7cfac67ca 118 bitsToShift = (N); \
rgrover1 0:62d7cfac67ca 119 \
rgrover1 0:62d7cfac67ca 120 if ((srcBitIndexMod8 + (N)) > 8) { \
rgrover1 0:62d7cfac67ca 121 bitsToShift = 8 - srcBitIndexMod8; \
rgrover1 0:62d7cfac67ca 122 SHIFT_INTO_SRC_BITS_FROM_SINGLE_SRC_BYTE(bitsToShift); \
rgrover1 0:62d7cfac67ca 123 bitsToShift = (N) - bitsToShift; \
rgrover1 0:62d7cfac67ca 124 } \
rgrover1 0:62d7cfac67ca 125 \
rgrover1 0:62d7cfac67ca 126 SHIFT_INTO_SRC_BITS_FROM_SINGLE_SRC_BYTE(bitsToShift); \
rgrover1 0:62d7cfac67ca 127 } while (0)
rgrover1 0:62d7cfac67ca 128
rgrover1 0:62d7cfac67ca 129 srcByteIndex = 0;
rgrover1 0:62d7cfac67ca 130 srcBitIndexMod8 = 0;
rgrover1 0:62d7cfac67ca 131 for (row = posy; row < endRow; row++) {
rgrover1 0:62d7cfac67ca 132 col = posx;
rgrover1 0:62d7cfac67ca 133 bitsToBlitInRow = width;
rgrover1 0:62d7cfac67ca 134 destBitIndexMod8 = col & 0x7 /* col % 8 */;
rgrover1 0:62d7cfac67ca 135 destByteIndex = col >> 3 /* col / 8 */;
rgrover1 0:62d7cfac67ca 136 srcBits = 0;
rgrover1 0:62d7cfac67ca 137
rgrover1 0:62d7cfac67ca 138 /* While there are bits in this row remaining to be blitted to
rgrover1 0:62d7cfac67ca 139 * the destination, ... */
rgrover1 0:62d7cfac67ca 140 while (bitsToBlitInRow) {
rgrover1 0:62d7cfac67ca 141 if ((destBitIndexMod8 == 0) && (bitsToBlitInRow >= 8)) {
rgrover1 0:62d7cfac67ca 142 /* We know that destBitIndexMod8 == 0, which means that
rgrover1 0:62d7cfac67ca 143 * the destination is byte aligned and we can simply
rgrover1 0:62d7cfac67ca 144 * do the equivalent of a memcpy. */
rgrover1 0:62d7cfac67ca 145 while (bitsToBlitInRow >= 8) {
rgrover1 0:62d7cfac67ca 146 SHIFT_INTO_SRC_BITS(8);
rgrover1 0:62d7cfac67ca 147 setRowByte(row, destByteIndex, srcBits);
rgrover1 0:62d7cfac67ca 148
rgrover1 0:62d7cfac67ca 149 bitsToBlitInRow -= 8;
rgrover1 0:62d7cfac67ca 150 destByteIndex++;
rgrover1 0:62d7cfac67ca 151 }
rgrover1 0:62d7cfac67ca 152 } else {
rgrover1 0:62d7cfac67ca 153 uint8_t blit; /* number of bits to blit in this iteration */
rgrover1 0:62d7cfac67ca 154 uint8_t mask;
rgrover1 0:62d7cfac67ca 155 uint8_t leftShift;
rgrover1 0:62d7cfac67ca 156
rgrover1 0:62d7cfac67ca 157 /* This will be a read-modify-write operation, so we
rgrover1 0:62d7cfac67ca 158 * need to fetch the destination byte. */
rgrover1 0:62d7cfac67ca 159 destByte = getRowByte(row, destByteIndex);
rgrover1 0:62d7cfac67ca 160
rgrover1 0:62d7cfac67ca 161 if ((destBitIndexMod8 + bitsToBlitInRow) >= 8) {
rgrover1 0:62d7cfac67ca 162 blit = 8 - destBitIndexMod8;
rgrover1 0:62d7cfac67ca 163 leftShift = 0;
rgrover1 0:62d7cfac67ca 164 } else {
rgrover1 0:62d7cfac67ca 165 blit = bitsToBlitInRow;
rgrover1 0:62d7cfac67ca 166 leftShift = (8 - (destBitIndexMod8 + bitsToBlitInRow));
rgrover1 0:62d7cfac67ca 167 }
rgrover1 0:62d7cfac67ca 168
rgrover1 0:62d7cfac67ca 169 SHIFT_INTO_SRC_BITS(blit);
rgrover1 0:62d7cfac67ca 170 mask = ((uint8_t)((uint8_t)1 << blit) - 1) << leftShift;
rgrover1 0:62d7cfac67ca 171
rgrover1 0:62d7cfac67ca 172 /* update destByte */
rgrover1 0:62d7cfac67ca 173 destByte &= ~mask;
rgrover1 0:62d7cfac67ca 174 destByte |= ((uint8_t)(srcBits << leftShift) & mask);
rgrover1 0:62d7cfac67ca 175
rgrover1 0:62d7cfac67ca 176 setRowByte(row, destByteIndex, destByte);
rgrover1 0:62d7cfac67ca 177
rgrover1 0:62d7cfac67ca 178 /* update dest indices */
rgrover1 0:62d7cfac67ca 179 bitsToBlitInRow -= blit;
rgrover1 0:62d7cfac67ca 180 destBitIndexMod8 += blit;
rgrover1 0:62d7cfac67ca 181 if (destBitIndexMod8 == 8) {
rgrover1 0:62d7cfac67ca 182 destBitIndexMod8 = 0;
rgrover1 0:62d7cfac67ca 183 destByteIndex++;
rgrover1 0:62d7cfac67ca 184 }
rgrover1 0:62d7cfac67ca 185 }
rgrover1 0:62d7cfac67ca 186 }
rgrover1 0:62d7cfac67ca 187
rgrover1 0:62d7cfac67ca 188 /* potentially update srcByteIndex */
rgrover1 0:62d7cfac67ca 189 if (srcBitIndexMod8 != 0) {
rgrover1 0:62d7cfac67ca 190 srcBitIndexMod8 = 0;
rgrover1 0:62d7cfac67ca 191 srcByteIndex++;
rgrover1 0:62d7cfac67ca 192 }
rgrover1 0:62d7cfac67ca 193 }
rgrover1 0:62d7cfac67ca 194 }
rgrover1 0:62d7cfac67ca 195
rgrover1 0:62d7cfac67ca 196 void
rgrover1 0:62d7cfac67ca 197 SharpLCD::FrameBuffer::printString(const font_face_t *face,
rgrover1 0:62d7cfac67ca 198 unsigned short baselineX,
rgrover1 0:62d7cfac67ca 199 unsigned short baselineY,
rgrover1 0:62d7cfac67ca 200 font_color_t fgColor,
rgrover1 0:62d7cfac67ca 201 const char *string)
rgrover1 0:62d7cfac67ca 202 {
rgrover1 0:62d7cfac67ca 203 unsigned char ch;
rgrover1 0:62d7cfac67ca 204 while ((ch = *string++) != '\0') {
rgrover1 0:62d7cfac67ca 205 if ((ch < FONT_LOWEST_SUPPORTED_CHAR_ENCODING) ||
rgrover1 0:62d7cfac67ca 206 (ch > FONT_HIGHEST_SUPPORTED_CHAR_ENCODING)) {
rgrover1 0:62d7cfac67ca 207 // TRACE_WARNING("printString: attempt to render unsupported char (enc: 0x%x)\n", ch);
rgrover1 0:62d7cfac67ca 208 continue;
rgrover1 0:62d7cfac67ca 209 }
rgrover1 0:62d7cfac67ca 210
rgrover1 0:62d7cfac67ca 211 const glyph_t *glyph = &face->glyphs[ch - FONT_LOWEST_SUPPORTED_CHAR_ENCODING];
rgrover1 0:62d7cfac67ca 212
rgrover1 0:62d7cfac67ca 213 if ((glyph->width > 0) && (glyph->height > 0)) {
rgrover1 0:62d7cfac67ca 214 bitBlit(&face->bitmaps[glyph->bitmapIndex], /* bitmap */
rgrover1 0:62d7cfac67ca 215 glyph->width, /* width of the bitmap */
rgrover1 0:62d7cfac67ca 216 glyph->height, /* height of the bitmap */
rgrover1 0:62d7cfac67ca 217 baselineX + glyph->bearingX, /* x-offset for the
rgrover1 0:62d7cfac67ca 218 * placement of the top-left
rgrover1 0:62d7cfac67ca 219 * corner of the bitmap. */
rgrover1 0:62d7cfac67ca 220 baselineY - glyph->bearingY /* y-offset for the
rgrover1 0:62d7cfac67ca 221 * placement of the top-left
rgrover1 0:62d7cfac67ca 222 * corner of the bitmap. */
rgrover1 0:62d7cfac67ca 223 );
rgrover1 0:62d7cfac67ca 224 }
rgrover1 0:62d7cfac67ca 225
rgrover1 0:62d7cfac67ca 226 baselineX += glyph->advance;
rgrover1 0:62d7cfac67ca 227 }
rgrover1 0:62d7cfac67ca 228 }