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.
Fork of SharpLCD by
SharpLCD.hpp@2:270ee57c0367, 2014-07-30 (annotated)
- Committer:
- rgrover1
- Date:
- Wed Jul 30 07:53:49 2014 +0000
- Revision:
- 2:270ee57c0367
- Parent:
- 1:ffc1d1d55581
- Child:
- 3:761d0f489b61
Add FrameBuffer::clear()
Who changed what in which revision?
| User | Revision | Line number | New 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 | 1:ffc1d1d55581 | 251 | displayEnable(enable), chipSelect(cs), spi(mosi, miso_unused, sclk, _unused) { |
| rgrover1 | 0:62d7cfac67ca | 252 | displayEnable = 0; |
| rgrover1 | 0:62d7cfac67ca | 253 | chipSelect = 0; |
| rgrover1 | 0:62d7cfac67ca | 254 | spi.frequency(1000000); |
| rgrover1 | 0:62d7cfac67ca | 255 | spi.format(8, 0); |
| rgrover1 | 0:62d7cfac67ca | 256 | }; |
| rgrover1 | 0:62d7cfac67ca | 257 | |
| rgrover1 | 0:62d7cfac67ca | 258 | /** |
| rgrover1 | 0:62d7cfac67ca | 259 | * \brief Turn on the LCD's display. |
| rgrover1 | 0:62d7cfac67ca | 260 | * |
| rgrover1 | 0:62d7cfac67ca | 261 | * \note Updates to the LCD's memory won't show up on the display |
| rgrover1 | 0:62d7cfac67ca | 262 | * until the display is enabled through this function. |
| rgrover1 | 0:62d7cfac67ca | 263 | */ |
| rgrover1 | 0:62d7cfac67ca | 264 | void enableDisplay(void); |
| rgrover1 | 0:62d7cfac67ca | 265 | |
| rgrover1 | 0:62d7cfac67ca | 266 | /** |
| rgrover1 | 0:62d7cfac67ca | 267 | * \brief Turn off the LCD's display---i.e. make it go blank. |
| rgrover1 | 0:62d7cfac67ca | 268 | * |
| rgrover1 | 0:62d7cfac67ca | 269 | * \note The LCD will retain its memory even when the display is disabled. |
| rgrover1 | 0:62d7cfac67ca | 270 | * |
| rgrover1 | 0:62d7cfac67ca | 271 | * This is different from re-initializing the LCD's display, since it does |
| rgrover1 | 0:62d7cfac67ca | 272 | * not affect the LCD memory. When the display is re-enabled, the LCD |
| rgrover1 | 0:62d7cfac67ca | 273 | * will show the contents of its memory. |
| rgrover1 | 0:62d7cfac67ca | 274 | */ |
| rgrover1 | 0:62d7cfac67ca | 275 | void disableDisplay(void); |
| rgrover1 | 0:62d7cfac67ca | 276 | |
| rgrover1 | 0:62d7cfac67ca | 277 | /** |
| rgrover1 | 0:62d7cfac67ca | 278 | * \brief Clear the LCD's display |
| rgrover1 | 0:62d7cfac67ca | 279 | * |
| rgrover1 | 0:62d7cfac67ca | 280 | * Write all-white to the LCD's memory. If a frameBuffer is passed in |
| rgrover1 | 0:62d7cfac67ca | 281 | * then it is re-initialized as well; otherwise this function does not |
| rgrover1 | 0:62d7cfac67ca | 282 | * operate on any global frame-buffer and updating any |
| rgrover1 | 0:62d7cfac67ca | 283 | * application-specific frameBuffer is still the application's |
| rgrover1 | 0:62d7cfac67ca | 284 | * responsibility. |
| rgrover1 | 0:62d7cfac67ca | 285 | */ |
| rgrover1 | 0:62d7cfac67ca | 286 | void clear(void); |
| rgrover1 | 0:62d7cfac67ca | 287 | |
| rgrover1 | 0:62d7cfac67ca | 288 | static uint8_t bitReverse8(uint8_t byte) { |
| rgrover1 | 1:ffc1d1d55581 | 289 | #if (__CORTEX_M >= 0x03) |
| rgrover1 | 1:ffc1d1d55581 | 290 | return (uint8_t)(__RBIT(byte) >> 24); |
| rgrover1 | 1:ffc1d1d55581 | 291 | #else /* #if (__CORTEX_M < 0x03) */ |
| rgrover1 | 1:ffc1d1d55581 | 292 | uint8_t rev8 = 0; |
| rgrover1 | 1:ffc1d1d55581 | 293 | |
| rgrover1 | 1:ffc1d1d55581 | 294 | for (unsigned i = 0; i < 8; i++) { |
| rgrover1 | 1:ffc1d1d55581 | 295 | if (byte & (1 << i)) { |
| rgrover1 | 1:ffc1d1d55581 | 296 | rev8 |= 1 << (7 - i); |
| rgrover1 | 1:ffc1d1d55581 | 297 | } |
| rgrover1 | 1:ffc1d1d55581 | 298 | } |
| rgrover1 | 1:ffc1d1d55581 | 299 | |
| rgrover1 | 1:ffc1d1d55581 | 300 | return rev8; |
| rgrover1 | 1:ffc1d1d55581 | 301 | #endif /* #if (__CORTEX_M >= 0x03) */ |
| rgrover1 | 0:62d7cfac67ca | 302 | } |
| rgrover1 | 0:62d7cfac67ca | 303 | |
| rgrover1 | 0:62d7cfac67ca | 304 | /** |
| rgrover1 | 0:62d7cfac67ca | 305 | * \brief Update LCD using a given framebuffer. |
| rgrover1 | 0:62d7cfac67ca | 306 | * |
| rgrover1 | 0:62d7cfac67ca | 307 | * The entire contents of the framebuffer will be DMA'd to the LCD; |
| rgrover1 | 0:62d7cfac67ca | 308 | * the calling thread will loose the CPU during the transfer, but |
| rgrover1 | 0:62d7cfac67ca | 309 | * other threads may remain active in that duration. |
| rgrover1 | 0:62d7cfac67ca | 310 | * |
| rgrover1 | 0:62d7cfac67ca | 311 | * \param[in] fb |
| rgrover1 | 0:62d7cfac67ca | 312 | * The frame buffer to send to the LCD hardware. |
| rgrover1 | 0:62d7cfac67ca | 313 | */ |
| rgrover1 | 0:62d7cfac67ca | 314 | void drawFrameBuffer(const FrameBuffer &fb); |
| rgrover1 | 0:62d7cfac67ca | 315 | |
| rgrover1 | 0:62d7cfac67ca | 316 | /** |
| rgrover1 | 0:62d7cfac67ca | 317 | * Toggle the VCOM mode of the LCD; it is recommended to trigger this |
| rgrover1 | 0:62d7cfac67ca | 318 | * periodically. Check the datasheet. |
| rgrover1 | 0:62d7cfac67ca | 319 | */ |
| rgrover1 | 0:62d7cfac67ca | 320 | void toggleVCOM(void); |
| rgrover1 | 0:62d7cfac67ca | 321 | |
| rgrover1 | 0:62d7cfac67ca | 322 | private: |
| rgrover1 | 0:62d7cfac67ca | 323 | /** |
| rgrover1 | 0:62d7cfac67ca | 324 | * Helper function to write out a buffer onto the LCD's SPI channel. |
| rgrover1 | 0:62d7cfac67ca | 325 | */ |
| rgrover1 | 0:62d7cfac67ca | 326 | void writeBuffer(const uint8_t *buffer, unsigned len); |
| rgrover1 | 0:62d7cfac67ca | 327 | |
| rgrover1 | 0:62d7cfac67ca | 328 | public: |
| rgrover1 | 0:62d7cfac67ca | 329 | static const unsigned LCD_WIDTH = 96; ///< Constant defining the LCD's geometry. |
| rgrover1 | 0:62d7cfac67ca | 330 | static const unsigned LCD_HEIGHT = 96; ///< Constant defining the LCD's geometry. |
| rgrover1 | 0:62d7cfac67ca | 331 | static const unsigned LCD_END_OF_DUMMY_SIZE = 2; |
| rgrover1 | 0:62d7cfac67ca | 332 | static const unsigned LCD_FRAMEBUFFER_SIZEOF_SCAN_LINE_METADATA = |
| rgrover1 | 0:62d7cfac67ca | 333 | (1 + /* mode byte in SPI update command */ |
| rgrover1 | 0:62d7cfac67ca | 334 | 1 /* addr byte in SPI update command */); |
| rgrover1 | 0:62d7cfac67ca | 335 | static const unsigned LCD_FRAMEBUFFER_SIZEOF_SCAN_LINE = |
| rgrover1 | 0:62d7cfac67ca | 336 | (LCD_FRAMEBUFFER_SIZEOF_SCAN_LINE_METADATA + (LCD_WIDTH / 8)); |
| rgrover1 | 0:62d7cfac67ca | 337 | |
| rgrover1 | 0:62d7cfac67ca | 338 | static const unsigned SIZEOF_FRAMEBUFFER = (LCD_HEIGHT * LCD_FRAMEBUFFER_SIZEOF_SCAN_LINE); |
| rgrover1 | 0:62d7cfac67ca | 339 | static const unsigned SIZEOF_FRAMEBUFFER_FOR_ALLOC = SIZEOF_FRAMEBUFFER + LCD_END_OF_DUMMY_SIZE; |
| rgrover1 | 0:62d7cfac67ca | 340 | |
| rgrover1 | 0:62d7cfac67ca | 341 | private: |
| rgrover1 | 0:62d7cfac67ca | 342 | /* Constants for the LCD's command protocol */ |
| rgrover1 | 0:62d7cfac67ca | 343 | static const uint8_t M0_FLAG = 0x80; |
| rgrover1 | 0:62d7cfac67ca | 344 | static const uint8_t M1_FLAG = 0x40; |
| rgrover1 | 0:62d7cfac67ca | 345 | static const uint8_t M2_FLAG = 0x20; |
| rgrover1 | 0:62d7cfac67ca | 346 | static const uint8_t DUMMY8 = 0x00; |
| rgrover1 | 0:62d7cfac67ca | 347 | |
| rgrover1 | 0:62d7cfac67ca | 348 | private: |
| rgrover1 | 0:62d7cfac67ca | 349 | DigitalOut displayEnable; |
| rgrover1 | 0:62d7cfac67ca | 350 | DigitalOut chipSelect; |
| rgrover1 | 0:62d7cfac67ca | 351 | SPI spi; |
| rgrover1 | 0:62d7cfac67ca | 352 | }; |
| rgrover1 | 0:62d7cfac67ca | 353 | |
| rgrover1 | 0:62d7cfac67ca | 354 | inline void |
| rgrover1 | 0:62d7cfac67ca | 355 | SharpLCD::enableDisplay(void) { |
| rgrover1 | 0:62d7cfac67ca | 356 | displayEnable = 1; |
| rgrover1 | 0:62d7cfac67ca | 357 | } |
| rgrover1 | 0:62d7cfac67ca | 358 | |
| rgrover1 | 0:62d7cfac67ca | 359 | inline void |
| rgrover1 | 0:62d7cfac67ca | 360 | SharpLCD::disableDisplay(void) { |
| rgrover1 | 0:62d7cfac67ca | 361 | displayEnable = 0; |
| rgrover1 | 0:62d7cfac67ca | 362 | } |
| rgrover1 | 0:62d7cfac67ca | 363 | |
| rgrover1 | 0:62d7cfac67ca | 364 | #endif /* #ifndef __SHARP_LCD_HPP__ */ |
