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 "mbed.h"
rgrover1 1:ffc1d1d55581 18 #include "core_cmInstr.h"
rgrover1 0:62d7cfac67ca 19 #include "font.h"
rgrover1 0:62d7cfac67ca 20
rgrover1 0:62d7cfac67ca 21 #ifndef __SHARP_LCD_HPP__
rgrover1 0:62d7cfac67ca 22 #define __SHARP_LCD_HPP__
rgrover1 0:62d7cfac67ca 23
rgrover1 0:62d7cfac67ca 24 /**
rgrover1 0:62d7cfac67ca 25 * This driver is meant for the monochrome LCD display (model
rgrover1 0:62d7cfac67ca 26 * no: LS013B4DN04) from Sharp.
rgrover1 0:62d7cfac67ca 27 *
rgrover1 0:62d7cfac67ca 28 * The LCD has the following pixel dimensions: width=96pixels,
rgrover1 0:62d7cfac67ca 29 * height=96pixels. This is a monochrome display with an inbuilt
rgrover1 0:62d7cfac67ca 30 * memory of 1 bit per pixel. If a pixel-bit is set to one, the
rgrover1 0:62d7cfac67ca 31 * corresponding pixel will show as black.
rgrover1 0:62d7cfac67ca 32 *
rgrover1 0:62d7cfac67ca 33 * The LCD memory is accessible to the micro-controller only through a
rgrover1 0:62d7cfac67ca 34 * serial interface; and <i>only for write operations</i>. It is
rgrover1 0:62d7cfac67ca 35 * necessary for the application to maintain its own frame-buffer
rgrover1 0:62d7cfac67ca 36 * memory in the micro-controller's SRAM (see fb_alloc())---the
rgrover1 0:62d7cfac67ca 37 * application is not restricted to a single framebuffer; if SRAM size
rgrover1 0:62d7cfac67ca 38 * permits, multiple buffers may be employed. In order to update the
rgrover1 0:62d7cfac67ca 39 * LCD, the application first draws (bitmaps or text) into some
rgrover1 0:62d7cfac67ca 40 * framebuffer memory, and then flushes the framebuffer to the LCD
rgrover1 0:62d7cfac67ca 41 * over the serial interface.
rgrover1 0:62d7cfac67ca 42 *
rgrover1 0:62d7cfac67ca 43 * Here's some sample code to drive the LCD display:
rgrover1 0:62d7cfac67ca 44 *
rgrover1 0:62d7cfac67ca 45 * DigitalOut led1(LED1);
rgrover1 0:62d7cfac67ca 46 * SharpLCD lcd(p9, MBED_SPI0);
rgrover1 0:62d7cfac67ca 47 *
rgrover1 0:62d7cfac67ca 48 * uint8_t framebuffer[SharpLCD::SIZEOF_FRAMEBUFFER_FOR_ALLOC];
rgrover1 0:62d7cfac67ca 49 *
rgrover1 0:62d7cfac67ca 50 * int main(void)
rgrover1 0:62d7cfac67ca 51 * {
rgrover1 0:62d7cfac67ca 52 * SharpLCD::FrameBuffer fb(framebuffer);
rgrover1 0:62d7cfac67ca 53 *
rgrover1 0:62d7cfac67ca 54 * lcd.enableDisplay();
rgrover1 0:62d7cfac67ca 55 * lcd.clear();
rgrover1 0:62d7cfac67ca 56 * fb.printString(lookupFontFace("DejaVu Serif", 8),
rgrover1 0:62d7cfac67ca 57 * 20,
rgrover1 0:62d7cfac67ca 58 * 40,
rgrover1 0:62d7cfac67ca 59 * BLACK,
rgrover1 0:62d7cfac67ca 60 * "Rohit");
rgrover1 0:62d7cfac67ca 61 * lcd.drawFrameBuffer(fb);
rgrover1 0:62d7cfac67ca 62 *
rgrover1 0:62d7cfac67ca 63 * led1 = 1;
rgrover1 0:62d7cfac67ca 64 * while (true) {
rgrover1 0:62d7cfac67ca 65 * wait(0.5);
rgrover1 0:62d7cfac67ca 66 * led1 = !led1;
rgrover1 0:62d7cfac67ca 67 * }
rgrover1 0:62d7cfac67ca 68 * }
rgrover1 0:62d7cfac67ca 69 */
rgrover1 0:62d7cfac67ca 70
rgrover1 0:62d7cfac67ca 71 class SharpLCD {
rgrover1 0:62d7cfac67ca 72 public:
rgrover1 0:62d7cfac67ca 73 class FrameBuffer {
rgrover1 0:62d7cfac67ca 74 public:
rgrover1 0:62d7cfac67ca 75 /**
rgrover1 0:62d7cfac67ca 76 * \brief initialize the hardware dependent component of a given
rgrover1 0:62d7cfac67ca 77 * framebuffer; and set it up to show all-white.
rgrover1 0:62d7cfac67ca 78 *
rgrover1 0:62d7cfac67ca 79 * \note This does not update the LCD automatically; it only
rgrover1 0:62d7cfac67ca 80 * initializes a framebuffer.
rgrover1 0:62d7cfac67ca 81 *
rgrover1 0:62d7cfac67ca 82 * \param[in] fb
rgrover1 0:62d7cfac67ca 83 * A memory buffer to initialize.
rgrover1 0:62d7cfac67ca 84 */
rgrover1 0:62d7cfac67ca 85 FrameBuffer(uint8_t *fb);
rgrover1 0:62d7cfac67ca 86
rgrover1 0:62d7cfac67ca 87 /**
rgrover1 2:270ee57c0367 88 * Clear the framebuffer to prepare for new drawing. The cleared buffer
rgrover1 2:270ee57c0367 89 * still needs to be drawn on the LCD if clearning the LCD is desired.
rgrover1 2:270ee57c0367 90 */
rgrover1 2:270ee57c0367 91 void clear(void);
rgrover1 2:270ee57c0367 92
rgrover1 2:270ee57c0367 93 /**
rgrover1 0:62d7cfac67ca 94 * \brief Copy over a bitmap to a specified location into the framebuffer.
rgrover1 0:62d7cfac67ca 95 *
rgrover1 0:62d7cfac67ca 96 * This is the main work-horse for displaying bitmaps on the LCD. We
rgrover1 0:62d7cfac67ca 97 * only support mono-chrome bitmaps with an encoding of 1 for white
rgrover1 0:62d7cfac67ca 98 * and 0 for black. We have rendering tools to convert a bitmap into
rgrover1 0:62d7cfac67ca 99 * the required encoding.
rgrover1 0:62d7cfac67ca 100
rgrover1 0:62d7cfac67ca 101 * \note The placement of the target bitmap is limited to the LCD's
rgrover1 0:62d7cfac67ca 102 * boundary--otherwise this routine fails.
rgrover1 0:62d7cfac67ca 103 *
rgrover1 0:62d7cfac67ca 104 * In case you are wondering, 'blit' stands for Block Image Transfer.
rgrover1 0:62d7cfac67ca 105 *
rgrover1 0:62d7cfac67ca 106 * Sample code:
rgrover1 0:62d7cfac67ca 107 * <pre>
rgrover1 0:62d7cfac67ca 108 fb_bitBlit(fb,
rgrover1 0:62d7cfac67ca 109 (const uint8_t *)pixel_data,
rgrover1 0:62d7cfac67ca 110 width,
rgrover1 0:62d7cfac67ca 111 height,
rgrover1 0:62d7cfac67ca 112 0, // posx
rgrover1 0:62d7cfac67ca 113 0 // posy
rgrover1 0:62d7cfac67ca 114 );
rgrover1 0:62d7cfac67ca 115 lcd_drawFrameBuffer(fb);
rgrover1 0:62d7cfac67ca 116 </pre>
rgrover1 0:62d7cfac67ca 117 */
rgrover1 0:62d7cfac67ca 118 void bitBlit(const uint8_t *bitmap,
rgrover1 0:62d7cfac67ca 119 unsigned int width, /*!< width of the bitmap */
rgrover1 0:62d7cfac67ca 120 unsigned int height, /*!< height of the bitmap */
rgrover1 0:62d7cfac67ca 121 unsigned int posx, /*!< x-offset for the
rgrover1 0:62d7cfac67ca 122 * placement of the top-left
rgrover1 0:62d7cfac67ca 123 * corner of the bitmap
rgrover1 0:62d7cfac67ca 124 * w.r.t. the top-left
rgrover1 0:62d7cfac67ca 125 * corner of the screen */
rgrover1 0:62d7cfac67ca 126 unsigned int posy /*!< y-offset for the
rgrover1 0:62d7cfac67ca 127 * placement of the top-left
rgrover1 0:62d7cfac67ca 128 * corner of the bitmap
rgrover1 0:62d7cfac67ca 129 * w.r.t. the top-left
rgrover1 0:62d7cfac67ca 130 * corner of the screen */
rgrover1 0:62d7cfac67ca 131 );
rgrover1 0:62d7cfac67ca 132
rgrover1 0:62d7cfac67ca 133 /*
rgrover1 0:62d7cfac67ca 134 * \brief Fetch a byte (8-bit pixel sequence) from a given scan-line
rgrover1 0:62d7cfac67ca 135 * in the framebuffer.
rgrover1 0:62d7cfac67ca 136 *
rgrover1 0:62d7cfac67ca 137 * The scan-line is identified by the row; and pixels are grouped into
rgrover1 0:62d7cfac67ca 138 * 8-bit bytes within a row.
rgrover1 0:62d7cfac67ca 139 *
rgrover1 0:62d7cfac67ca 140 * \note This function is declared inline for a faster implementation.
rgrover1 0:62d7cfac67ca 141 *
rgrover1 0:62d7cfac67ca 142 * \param[in] framebuffer
rgrover1 0:62d7cfac67ca 143 * The framebuffer to fetch the byte from.
rgrover1 0:62d7cfac67ca 144 *
rgrover1 0:62d7cfac67ca 145 * \param[in] row
rgrover1 0:62d7cfac67ca 146 * The row index of the scan line.
rgrover1 0:62d7cfac67ca 147 *
rgrover1 0:62d7cfac67ca 148 * \param[in] byteIndex
rgrover1 0:62d7cfac67ca 149 * The pixel-index expressed as a byte-index.
rgrover1 0:62d7cfac67ca 150 */
rgrover1 0:62d7cfac67ca 151 uint8_t
rgrover1 0:62d7cfac67ca 152 getRowByte(unsigned int row, unsigned int byteIndex) {
rgrover1 0:62d7cfac67ca 153 return buffer[rowColToIndex(row, byteIndex)];
rgrover1 0:62d7cfac67ca 154 }
rgrover1 0:62d7cfac67ca 155
rgrover1 0:62d7cfac67ca 156 /*
rgrover1 0:62d7cfac67ca 157 * \brief Set a byte (8-bit pixel sequence) for a given scan-line in
rgrover1 0:62d7cfac67ca 158 * the framebuffer.
rgrover1 0:62d7cfac67ca 159 *
rgrover1 0:62d7cfac67ca 160 * The scan-line is identified by the row; and pixels are grouped into
rgrover1 0:62d7cfac67ca 161 * 8-bit bytes within a row.
rgrover1 0:62d7cfac67ca 162 *
rgrover1 0:62d7cfac67ca 163 * \note This function is declared inline for a faster implementation.
rgrover1 0:62d7cfac67ca 164 *
rgrover1 0:62d7cfac67ca 165 * \param[in] framebuffer
rgrover1 0:62d7cfac67ca 166 * The framebuffer to set the byte into.
rgrover1 0:62d7cfac67ca 167 *
rgrover1 0:62d7cfac67ca 168 * \param[in] row
rgrover1 0:62d7cfac67ca 169 * The row index of the scan line.
rgrover1 0:62d7cfac67ca 170 *
rgrover1 0:62d7cfac67ca 171 * \param[in] byteIndex
rgrover1 0:62d7cfac67ca 172 * The pixel-index expressed as a byte-index.
rgrover1 0:62d7cfac67ca 173 *
rgrover1 0:62d7cfac67ca 174 * \param[in] pixels
rgrover1 0:62d7cfac67ca 175 * The actual 8 pixels to set.
rgrover1 0:62d7cfac67ca 176 */
rgrover1 0:62d7cfac67ca 177 void
rgrover1 0:62d7cfac67ca 178 setRowByte(unsigned int row, unsigned int byteIndex, uint8_t pixels) {
rgrover1 0:62d7cfac67ca 179 buffer[rowColToIndex(row, byteIndex)] = pixels;
rgrover1 0:62d7cfac67ca 180 }
rgrover1 0:62d7cfac67ca 181
rgrover1 0:62d7cfac67ca 182 /**
rgrover1 0:62d7cfac67ca 183 * \brief The printf function for the frameBuffer.
rgrover1 0:62d7cfac67ca 184 *
rgrover1 0:62d7cfac67ca 185 * This can be used to render strings in a given
rgrover1 0:62d7cfac67ca 186 * font-face. Internally, it uses fb_bitBlit to bilt the glyphs onto a
rgrover1 0:62d7cfac67ca 187 * framebuffer. Currently, since bitBlit doesn't handle the case where
rgrover1 0:62d7cfac67ca 188 * a bitmap exceeds the framebuffer's boundary, you must be very
rgrover1 0:62d7cfac67ca 189 * careful about the placement of the text string. Later, when
rgrover1 0:62d7cfac67ca 190 * fb_bitBlit is able to handle bitmaps which fall outside the LCD's
rgrover1 0:62d7cfac67ca 191 * boundary, the rendered text may be clipped if it doesn't fit the
rgrover1 0:62d7cfac67ca 192 * frame.
rgrover1 0:62d7cfac67ca 193 *
rgrover1 0:62d7cfac67ca 194 * \param[in] face
rgrover1 0:62d7cfac67ca 195 * The font-face to be used for rendering the text.
rgrover1 0:62d7cfac67ca 196 *
rgrover1 0:62d7cfac67ca 197 * \param[in] baselineX
rgrover1 0:62d7cfac67ca 198 * The X-offset from the left corner of the screen of the starting
rgrover1 0:62d7cfac67ca 199 * pen position; this defines the X-coordinate of the baseline.
rgrover1 0:62d7cfac67ca 200 *
rgrover1 0:62d7cfac67ca 201 * \param[in] baselineY
rgrover1 0:62d7cfac67ca 202 * The Y-offset from the top corner of the screen of the starting
rgrover1 0:62d7cfac67ca 203 * pen position; this defines the Y-coordinate of the baseline.
rgrover1 0:62d7cfac67ca 204 *
rgrover1 0:62d7cfac67ca 205 * \param[in] fgColor
rgrover1 0:62d7cfac67ca 206 * The foreground colour.
rgrover1 0:62d7cfac67ca 207 *
rgrover1 0:62d7cfac67ca 208 * \param[in] string
rgrover1 0:62d7cfac67ca 209 * The text to be rendered.
rgrover1 0:62d7cfac67ca 210 *
rgrover1 0:62d7cfac67ca 211 * Sample code:
rgrover1 0:62d7cfac67ca 212 * <pre>
rgrover1 0:62d7cfac67ca 213 * face = lookupFontFace("DejaVu Serif", 9);
rgrover1 0:62d7cfac67ca 214 * if (face == NULL) {
rgrover1 0:62d7cfac67ca 215 * TRACE_FATAL("failed to find face for DejaVu Serif; 10\n");
rgrover1 0:62d7cfac67ca 216 * }
rgrover1 0:62d7cfac67ca 217 * fb_printString(fb,
rgrover1 0:62d7cfac67ca 218 * face,
rgrover1 0:62d7cfac67ca 219 * 90, // baselineX
rgrover1 0:62d7cfac67ca 220 * 140, // baselineY
rgrover1 0:62d7cfac67ca 221 * BLACK, // foregroundColor
rgrover1 0:62d7cfac67ca 222 * "Hello Mr. Obama!");
rgrover1 0:62d7cfac67ca 223 * lcd_drawFrameBuffer(fb);
rgrover1 0:62d7cfac67ca 224 * </pre>
rgrover1 0:62d7cfac67ca 225 */
rgrover1 0:62d7cfac67ca 226 void printString(const font_face_t *face,
rgrover1 0:62d7cfac67ca 227 unsigned short baselineX,
rgrover1 0:62d7cfac67ca 228 unsigned short baselineY,
rgrover1 0:62d7cfac67ca 229 font_color_t fgColor,
rgrover1 0:62d7cfac67ca 230 const char *string);
rgrover1 0:62d7cfac67ca 231
rgrover1 0:62d7cfac67ca 232 const uint8_t *getBuffer(void) const {
rgrover1 0:62d7cfac67ca 233 return (buffer);
rgrover1 0:62d7cfac67ca 234 }
rgrover1 0:62d7cfac67ca 235
rgrover1 0:62d7cfac67ca 236 uint8_t *getBuffer(void) {
rgrover1 0:62d7cfac67ca 237 return (buffer);
rgrover1 0:62d7cfac67ca 238 }
rgrover1 0:62d7cfac67ca 239
rgrover1 0:62d7cfac67ca 240 private:
rgrover1 0:62d7cfac67ca 241 unsigned rowColToIndex(unsigned row, unsigned col) {
rgrover1 0:62d7cfac67ca 242 return (row * LCD_FRAMEBUFFER_SIZEOF_SCAN_LINE) + LCD_FRAMEBUFFER_SIZEOF_SCAN_LINE_METADATA + col;
rgrover1 0:62d7cfac67ca 243 }
rgrover1 0:62d7cfac67ca 244
rgrover1 0:62d7cfac67ca 245 private:
rgrover1 0:62d7cfac67ca 246 uint8_t *const buffer;
rgrover1 0:62d7cfac67ca 247 };
rgrover1 0:62d7cfac67ca 248
rgrover1 0:62d7cfac67ca 249 public:
rgrover1 1:ffc1d1d55581 250 SharpLCD(PinName enable, PinName cs, PinName mosi, PinName miso_unused, PinName sclk, PinName _unused = NC) :
rgrover1 3:761d0f489b61 251 displayEnable(enable, 0), chipSelect(cs, 0), spi(mosi, miso_unused, sclk, _unused) {
rgrover1 0:62d7cfac67ca 252 spi.frequency(1000000);
rgrover1 0:62d7cfac67ca 253 spi.format(8, 0);
rgrover1 0:62d7cfac67ca 254 };
rgrover1 0:62d7cfac67ca 255
rgrover1 0:62d7cfac67ca 256 /**
rgrover1 0:62d7cfac67ca 257 * \brief Turn on the LCD's display.
rgrover1 0:62d7cfac67ca 258 *
rgrover1 0:62d7cfac67ca 259 * \note Updates to the LCD's memory won't show up on the display
rgrover1 0:62d7cfac67ca 260 * until the display is enabled through this function.
rgrover1 0:62d7cfac67ca 261 */
rgrover1 0:62d7cfac67ca 262 void enableDisplay(void);
rgrover1 0:62d7cfac67ca 263
rgrover1 0:62d7cfac67ca 264 /**
rgrover1 0:62d7cfac67ca 265 * \brief Turn off the LCD's display---i.e. make it go blank.
rgrover1 0:62d7cfac67ca 266 *
rgrover1 0:62d7cfac67ca 267 * \note The LCD will retain its memory even when the display is disabled.
rgrover1 0:62d7cfac67ca 268 *
rgrover1 0:62d7cfac67ca 269 * This is different from re-initializing the LCD's display, since it does
rgrover1 0:62d7cfac67ca 270 * not affect the LCD memory. When the display is re-enabled, the LCD
rgrover1 0:62d7cfac67ca 271 * will show the contents of its memory.
rgrover1 0:62d7cfac67ca 272 */
rgrover1 0:62d7cfac67ca 273 void disableDisplay(void);
rgrover1 0:62d7cfac67ca 274
rgrover1 0:62d7cfac67ca 275 /**
rgrover1 0:62d7cfac67ca 276 * \brief Clear the LCD's display
rgrover1 0:62d7cfac67ca 277 *
rgrover1 0:62d7cfac67ca 278 * Write all-white to the LCD's memory. If a frameBuffer is passed in
rgrover1 0:62d7cfac67ca 279 * then it is re-initialized as well; otherwise this function does not
rgrover1 0:62d7cfac67ca 280 * operate on any global frame-buffer and updating any
rgrover1 0:62d7cfac67ca 281 * application-specific frameBuffer is still the application's
rgrover1 0:62d7cfac67ca 282 * responsibility.
rgrover1 0:62d7cfac67ca 283 */
rgrover1 0:62d7cfac67ca 284 void clear(void);
rgrover1 0:62d7cfac67ca 285
rgrover1 0:62d7cfac67ca 286 static uint8_t bitReverse8(uint8_t byte) {
rgrover1 1:ffc1d1d55581 287 #if (__CORTEX_M >= 0x03)
rgrover1 1:ffc1d1d55581 288 return (uint8_t)(__RBIT(byte) >> 24);
rgrover1 1:ffc1d1d55581 289 #else /* #if (__CORTEX_M < 0x03) */
rgrover1 1:ffc1d1d55581 290 uint8_t rev8 = 0;
rgrover1 1:ffc1d1d55581 291
rgrover1 1:ffc1d1d55581 292 for (unsigned i = 0; i < 8; i++) {
rgrover1 1:ffc1d1d55581 293 if (byte & (1 << i)) {
rgrover1 1:ffc1d1d55581 294 rev8 |= 1 << (7 - i);
rgrover1 1:ffc1d1d55581 295 }
rgrover1 1:ffc1d1d55581 296 }
rgrover1 1:ffc1d1d55581 297
rgrover1 1:ffc1d1d55581 298 return rev8;
rgrover1 1:ffc1d1d55581 299 #endif /* #if (__CORTEX_M >= 0x03) */
rgrover1 0:62d7cfac67ca 300 }
rgrover1 0:62d7cfac67ca 301
rgrover1 0:62d7cfac67ca 302 /**
rgrover1 0:62d7cfac67ca 303 * \brief Update LCD using a given framebuffer.
rgrover1 0:62d7cfac67ca 304 *
rgrover1 0:62d7cfac67ca 305 * The entire contents of the framebuffer will be DMA'd to the LCD;
rgrover1 0:62d7cfac67ca 306 * the calling thread will loose the CPU during the transfer, but
rgrover1 0:62d7cfac67ca 307 * other threads may remain active in that duration.
rgrover1 0:62d7cfac67ca 308 *
rgrover1 0:62d7cfac67ca 309 * \param[in] fb
rgrover1 0:62d7cfac67ca 310 * The frame buffer to send to the LCD hardware.
rgrover1 0:62d7cfac67ca 311 */
rgrover1 0:62d7cfac67ca 312 void drawFrameBuffer(const FrameBuffer &fb);
rgrover1 0:62d7cfac67ca 313
rgrover1 0:62d7cfac67ca 314 /**
rgrover1 0:62d7cfac67ca 315 * Toggle the VCOM mode of the LCD; it is recommended to trigger this
rgrover1 0:62d7cfac67ca 316 * periodically. Check the datasheet.
rgrover1 0:62d7cfac67ca 317 */
rgrover1 0:62d7cfac67ca 318 void toggleVCOM(void);
rgrover1 0:62d7cfac67ca 319
rgrover1 0:62d7cfac67ca 320 private:
rgrover1 0:62d7cfac67ca 321 /**
rgrover1 0:62d7cfac67ca 322 * Helper function to write out a buffer onto the LCD's SPI channel.
rgrover1 0:62d7cfac67ca 323 */
rgrover1 0:62d7cfac67ca 324 void writeBuffer(const uint8_t *buffer, unsigned len);
rgrover1 0:62d7cfac67ca 325
rgrover1 0:62d7cfac67ca 326 public:
rgrover1 0:62d7cfac67ca 327 static const unsigned LCD_WIDTH = 96; ///< Constant defining the LCD's geometry.
rgrover1 0:62d7cfac67ca 328 static const unsigned LCD_HEIGHT = 96; ///< Constant defining the LCD's geometry.
rgrover1 0:62d7cfac67ca 329 static const unsigned LCD_END_OF_DUMMY_SIZE = 2;
rgrover1 0:62d7cfac67ca 330 static const unsigned LCD_FRAMEBUFFER_SIZEOF_SCAN_LINE_METADATA =
rgrover1 0:62d7cfac67ca 331 (1 + /* mode byte in SPI update command */
rgrover1 0:62d7cfac67ca 332 1 /* addr byte in SPI update command */);
rgrover1 0:62d7cfac67ca 333 static const unsigned LCD_FRAMEBUFFER_SIZEOF_SCAN_LINE =
rgrover1 0:62d7cfac67ca 334 (LCD_FRAMEBUFFER_SIZEOF_SCAN_LINE_METADATA + (LCD_WIDTH / 8));
rgrover1 0:62d7cfac67ca 335
rgrover1 0:62d7cfac67ca 336 static const unsigned SIZEOF_FRAMEBUFFER = (LCD_HEIGHT * LCD_FRAMEBUFFER_SIZEOF_SCAN_LINE);
rgrover1 0:62d7cfac67ca 337 static const unsigned SIZEOF_FRAMEBUFFER_FOR_ALLOC = SIZEOF_FRAMEBUFFER + LCD_END_OF_DUMMY_SIZE;
rgrover1 0:62d7cfac67ca 338
rgrover1 0:62d7cfac67ca 339 private:
rgrover1 0:62d7cfac67ca 340 /* Constants for the LCD's command protocol */
rgrover1 0:62d7cfac67ca 341 static const uint8_t M0_FLAG = 0x80;
rgrover1 0:62d7cfac67ca 342 static const uint8_t M1_FLAG = 0x40;
rgrover1 0:62d7cfac67ca 343 static const uint8_t M2_FLAG = 0x20;
rgrover1 0:62d7cfac67ca 344 static const uint8_t DUMMY8 = 0x00;
rgrover1 0:62d7cfac67ca 345
rgrover1 0:62d7cfac67ca 346 private:
rgrover1 0:62d7cfac67ca 347 DigitalOut displayEnable;
rgrover1 0:62d7cfac67ca 348 DigitalOut chipSelect;
rgrover1 0:62d7cfac67ca 349 SPI spi;
rgrover1 0:62d7cfac67ca 350 };
rgrover1 0:62d7cfac67ca 351
rgrover1 0:62d7cfac67ca 352 inline void
rgrover1 0:62d7cfac67ca 353 SharpLCD::enableDisplay(void) {
rgrover1 0:62d7cfac67ca 354 displayEnable = 1;
rgrover1 0:62d7cfac67ca 355 }
rgrover1 0:62d7cfac67ca 356
rgrover1 0:62d7cfac67ca 357 inline void
rgrover1 0:62d7cfac67ca 358 SharpLCD::disableDisplay(void) {
rgrover1 0:62d7cfac67ca 359 displayEnable = 0;
rgrover1 0:62d7cfac67ca 360 }
rgrover1 0:62d7cfac67ca 361
rgrover1 0:62d7cfac67ca 362 #endif /* #ifndef __SHARP_LCD_HPP__ */