WaveShare e-paper module (epd1in54). Monochrome version
Fork of epd1in54 by
epd1in54.cpp@2:01166b6a8b6a, 2018-08-22 (annotated)
- Committer:
- WaleedElmughrabi
- Date:
- Wed Aug 22 18:12:43 2018 +0000
- Revision:
- 2:01166b6a8b6a
- Parent:
- 0:ac97d71fe296
Cosmetic changes
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
imachooon | 0:ac97d71fe296 | 1 | /** |
imachooon | 0:ac97d71fe296 | 2 | * @filename : epd1in54.cpp |
imachooon | 0:ac97d71fe296 | 3 | * @brief : Implements for e-paper library |
imachooon | 0:ac97d71fe296 | 4 | * @author : Yehui from Waveshare |
imachooon | 0:ac97d71fe296 | 5 | * |
imachooon | 0:ac97d71fe296 | 6 | * Copyright (C) Waveshare August 10 2017 |
imachooon | 0:ac97d71fe296 | 7 | * |
imachooon | 0:ac97d71fe296 | 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
imachooon | 0:ac97d71fe296 | 9 | * of this software and associated documnetation files (the "Software"), to deal |
imachooon | 0:ac97d71fe296 | 10 | * in the Software without restriction, including without limitation the rights |
imachooon | 0:ac97d71fe296 | 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
imachooon | 0:ac97d71fe296 | 12 | * copies of the Software, and to permit persons to whom the Software is |
imachooon | 0:ac97d71fe296 | 13 | * furished to do so, subject to the following conditions: |
imachooon | 0:ac97d71fe296 | 14 | * |
imachooon | 0:ac97d71fe296 | 15 | * The above copyright notice and this permission notice shall be included in |
imachooon | 0:ac97d71fe296 | 16 | * all copies or substantial portions of the Software. |
imachooon | 0:ac97d71fe296 | 17 | * |
imachooon | 0:ac97d71fe296 | 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
imachooon | 0:ac97d71fe296 | 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
imachooon | 0:ac97d71fe296 | 20 | * FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
imachooon | 0:ac97d71fe296 | 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
imachooon | 0:ac97d71fe296 | 22 | * LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
imachooon | 0:ac97d71fe296 | 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
imachooon | 0:ac97d71fe296 | 24 | * THE SOFTWARE. |
imachooon | 0:ac97d71fe296 | 25 | */ |
imachooon | 0:ac97d71fe296 | 26 | |
imachooon | 0:ac97d71fe296 | 27 | #include <stdlib.h> |
imachooon | 0:ac97d71fe296 | 28 | #include "epd1in54.h" |
imachooon | 0:ac97d71fe296 | 29 | |
imachooon | 0:ac97d71fe296 | 30 | const unsigned char lut_full_update[] = |
imachooon | 0:ac97d71fe296 | 31 | { |
imachooon | 0:ac97d71fe296 | 32 | 0x02, 0x02, 0x01, 0x11, 0x12, 0x12, 0x22, 0x22, |
imachooon | 0:ac97d71fe296 | 33 | 0x66, 0x69, 0x69, 0x59, 0x58, 0x99, 0x99, 0x88, |
imachooon | 0:ac97d71fe296 | 34 | 0x00, 0x00, 0x00, 0x00, 0xF8, 0xB4, 0x13, 0x51, |
imachooon | 0:ac97d71fe296 | 35 | 0x35, 0x51, 0x51, 0x19, 0x01, 0x00 |
imachooon | 0:ac97d71fe296 | 36 | }; |
imachooon | 0:ac97d71fe296 | 37 | |
imachooon | 0:ac97d71fe296 | 38 | const unsigned char lut_partial_update[] = |
imachooon | 0:ac97d71fe296 | 39 | { |
imachooon | 0:ac97d71fe296 | 40 | 0x10, 0x18, 0x18, 0x08, 0x18, 0x18, 0x08, 0x00, |
imachooon | 0:ac97d71fe296 | 41 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
imachooon | 0:ac97d71fe296 | 42 | 0x00, 0x00, 0x00, 0x00, 0x13, 0x14, 0x44, 0x12, |
imachooon | 0:ac97d71fe296 | 43 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
imachooon | 0:ac97d71fe296 | 44 | }; |
imachooon | 0:ac97d71fe296 | 45 | |
imachooon | 0:ac97d71fe296 | 46 | |
imachooon | 0:ac97d71fe296 | 47 | |
imachooon | 0:ac97d71fe296 | 48 | Epd::~Epd() { |
imachooon | 0:ac97d71fe296 | 49 | }; |
imachooon | 0:ac97d71fe296 | 50 | |
imachooon | 0:ac97d71fe296 | 51 | |
imachooon | 0:ac97d71fe296 | 52 | Epd::Epd(PinName mosi, |
imachooon | 0:ac97d71fe296 | 53 | PinName miso, |
imachooon | 0:ac97d71fe296 | 54 | PinName sclk, |
imachooon | 0:ac97d71fe296 | 55 | PinName cs, |
imachooon | 0:ac97d71fe296 | 56 | PinName dc, |
imachooon | 0:ac97d71fe296 | 57 | PinName rst, |
imachooon | 0:ac97d71fe296 | 58 | PinName busy |
imachooon | 0:ac97d71fe296 | 59 | ):EpdIf(mosi, miso, sclk, cs, dc, rst, busy){ |
imachooon | 0:ac97d71fe296 | 60 | |
imachooon | 0:ac97d71fe296 | 61 | width = EPD_WIDTH; |
imachooon | 0:ac97d71fe296 | 62 | height= EPD_HEIGHT; |
WaleedElmughrabi | 2:01166b6a8b6a | 63 | rotate = ROTATE_270; |
imachooon | 0:ac97d71fe296 | 64 | |
imachooon | 0:ac97d71fe296 | 65 | } |
imachooon | 0:ac97d71fe296 | 66 | |
imachooon | 0:ac97d71fe296 | 67 | int Epd::Init(const unsigned char* lut) { |
imachooon | 0:ac97d71fe296 | 68 | |
imachooon | 0:ac97d71fe296 | 69 | if(IfInit() != 0){ |
imachooon | 0:ac97d71fe296 | 70 | return -1; |
imachooon | 0:ac97d71fe296 | 71 | } |
imachooon | 0:ac97d71fe296 | 72 | |
imachooon | 0:ac97d71fe296 | 73 | /* EPD hardware init start */ |
imachooon | 0:ac97d71fe296 | 74 | Reset(); |
imachooon | 0:ac97d71fe296 | 75 | SendCommand(DRIVER_OUTPUT_CONTROL); |
imachooon | 0:ac97d71fe296 | 76 | SendData((EPD_HEIGHT - 1) & 0xFF); |
imachooon | 0:ac97d71fe296 | 77 | SendData(((EPD_HEIGHT - 1) >> 8) & 0xFF); |
imachooon | 0:ac97d71fe296 | 78 | SendData(0x00); // GD = 0; SM = 0; TB = 0; |
imachooon | 0:ac97d71fe296 | 79 | SendCommand(BOOSTER_SOFT_START_CONTROL); |
imachooon | 0:ac97d71fe296 | 80 | SendData(0xD7); |
imachooon | 0:ac97d71fe296 | 81 | SendData(0xD6); |
imachooon | 0:ac97d71fe296 | 82 | SendData(0x9D); |
imachooon | 0:ac97d71fe296 | 83 | SendCommand(WRITE_VCOM_REGISTER); |
imachooon | 0:ac97d71fe296 | 84 | SendData(0xA8); // VCOM 7C |
imachooon | 0:ac97d71fe296 | 85 | SendCommand(SET_DUMMY_LINE_PERIOD); |
imachooon | 0:ac97d71fe296 | 86 | SendData(0x1A); // 4 dummy lines per gate |
imachooon | 0:ac97d71fe296 | 87 | SendCommand(SET_GATE_TIME); |
imachooon | 0:ac97d71fe296 | 88 | SendData(0x08); // 2us per line |
imachooon | 0:ac97d71fe296 | 89 | SendCommand(DATA_ENTRY_MODE_SETTING); |
imachooon | 0:ac97d71fe296 | 90 | SendData(0x03); // X increment; Y increment |
imachooon | 0:ac97d71fe296 | 91 | SetLut(lut); |
imachooon | 0:ac97d71fe296 | 92 | /* EPD hardware init end */ |
imachooon | 0:ac97d71fe296 | 93 | return 0; |
imachooon | 0:ac97d71fe296 | 94 | } |
imachooon | 0:ac97d71fe296 | 95 | |
imachooon | 0:ac97d71fe296 | 96 | /** |
imachooon | 0:ac97d71fe296 | 97 | * @brief: basic function for sending commands |
imachooon | 0:ac97d71fe296 | 98 | */ |
imachooon | 0:ac97d71fe296 | 99 | void Epd::SendCommand(unsigned char command) { |
imachooon | 0:ac97d71fe296 | 100 | DigitalWrite(m_dc, LOW); |
imachooon | 0:ac97d71fe296 | 101 | SpiTransfer(command); |
imachooon | 0:ac97d71fe296 | 102 | } |
imachooon | 0:ac97d71fe296 | 103 | |
imachooon | 0:ac97d71fe296 | 104 | /** |
imachooon | 0:ac97d71fe296 | 105 | * @brief: basic function for sending data |
imachooon | 0:ac97d71fe296 | 106 | */ |
imachooon | 0:ac97d71fe296 | 107 | void Epd::SendData(unsigned char data) { |
imachooon | 0:ac97d71fe296 | 108 | DigitalWrite(m_dc, HIGH); |
imachooon | 0:ac97d71fe296 | 109 | SpiTransfer(data); |
imachooon | 0:ac97d71fe296 | 110 | } |
imachooon | 0:ac97d71fe296 | 111 | |
imachooon | 0:ac97d71fe296 | 112 | /** |
imachooon | 0:ac97d71fe296 | 113 | * @brief: Wait until the m_busy goes HIGH |
imachooon | 0:ac97d71fe296 | 114 | */ |
imachooon | 0:ac97d71fe296 | 115 | void Epd::WaitUntilIdle(void) { |
imachooon | 0:ac97d71fe296 | 116 | while(DigitalRead(m_busy) == 1) { //0: busy, 1: idle |
imachooon | 0:ac97d71fe296 | 117 | DelayMs(100); |
imachooon | 0:ac97d71fe296 | 118 | } |
imachooon | 0:ac97d71fe296 | 119 | } |
imachooon | 0:ac97d71fe296 | 120 | |
imachooon | 0:ac97d71fe296 | 121 | /** |
imachooon | 0:ac97d71fe296 | 122 | * @brief: module reset. |
imachooon | 0:ac97d71fe296 | 123 | * often used to awaken the module in deep sleep, |
imachooon | 0:ac97d71fe296 | 124 | * see Epd::Sleep(); |
imachooon | 0:ac97d71fe296 | 125 | */ |
imachooon | 0:ac97d71fe296 | 126 | void Epd::Reset(void) { |
imachooon | 0:ac97d71fe296 | 127 | DigitalWrite(m_rst, LOW); //module reset |
imachooon | 0:ac97d71fe296 | 128 | DelayMs(200); |
imachooon | 0:ac97d71fe296 | 129 | DigitalWrite(m_rst, HIGH); |
imachooon | 0:ac97d71fe296 | 130 | DelayMs(200); |
imachooon | 0:ac97d71fe296 | 131 | } |
imachooon | 0:ac97d71fe296 | 132 | |
imachooon | 0:ac97d71fe296 | 133 | |
imachooon | 0:ac97d71fe296 | 134 | /** |
imachooon | 0:ac97d71fe296 | 135 | * @brief: set the look-up table register |
imachooon | 0:ac97d71fe296 | 136 | */ |
imachooon | 0:ac97d71fe296 | 137 | void Epd::SetLut(const unsigned char* lut) { |
imachooon | 0:ac97d71fe296 | 138 | SendCommand(WRITE_LUT_REGISTER); |
imachooon | 0:ac97d71fe296 | 139 | /* the length of look-up table is 30 bytes */ |
imachooon | 0:ac97d71fe296 | 140 | for (int i = 0; i < 30; i++) { |
imachooon | 0:ac97d71fe296 | 141 | SendData(lut[i]); |
imachooon | 0:ac97d71fe296 | 142 | } |
imachooon | 0:ac97d71fe296 | 143 | } |
imachooon | 0:ac97d71fe296 | 144 | |
imachooon | 0:ac97d71fe296 | 145 | |
imachooon | 0:ac97d71fe296 | 146 | /** |
imachooon | 0:ac97d71fe296 | 147 | * @brief: put an image buffer to the frame memory. |
imachooon | 0:ac97d71fe296 | 148 | * this won't update the display. |
imachooon | 0:ac97d71fe296 | 149 | */ |
imachooon | 0:ac97d71fe296 | 150 | void Epd::SetFrameMemory( |
imachooon | 0:ac97d71fe296 | 151 | const unsigned char* image_buffer, |
imachooon | 0:ac97d71fe296 | 152 | int x, |
imachooon | 0:ac97d71fe296 | 153 | int y, |
imachooon | 0:ac97d71fe296 | 154 | int image_width, |
imachooon | 0:ac97d71fe296 | 155 | int image_height |
imachooon | 0:ac97d71fe296 | 156 | ) { |
imachooon | 0:ac97d71fe296 | 157 | int x_end; |
imachooon | 0:ac97d71fe296 | 158 | int y_end; |
imachooon | 0:ac97d71fe296 | 159 | |
imachooon | 0:ac97d71fe296 | 160 | if ( |
imachooon | 0:ac97d71fe296 | 161 | image_buffer == NULL || |
imachooon | 0:ac97d71fe296 | 162 | x < 0 || image_width < 0 || |
imachooon | 0:ac97d71fe296 | 163 | y < 0 || image_height < 0 |
imachooon | 0:ac97d71fe296 | 164 | ) { |
imachooon | 0:ac97d71fe296 | 165 | return; |
imachooon | 0:ac97d71fe296 | 166 | } |
imachooon | 0:ac97d71fe296 | 167 | /* x point must be the multiple of 8 or the last 3 bits will be ignored */ |
imachooon | 0:ac97d71fe296 | 168 | x &= 0xF8; |
imachooon | 0:ac97d71fe296 | 169 | image_width &= 0xF8; |
imachooon | 0:ac97d71fe296 | 170 | if (x + image_width >= this->width) { |
imachooon | 0:ac97d71fe296 | 171 | x_end = this->width - 1; |
imachooon | 0:ac97d71fe296 | 172 | } else { |
imachooon | 0:ac97d71fe296 | 173 | x_end = x + image_width - 1; |
imachooon | 0:ac97d71fe296 | 174 | } |
imachooon | 0:ac97d71fe296 | 175 | if (y + image_height >= this->height) { |
imachooon | 0:ac97d71fe296 | 176 | y_end = this->height - 1; |
imachooon | 0:ac97d71fe296 | 177 | } else { |
imachooon | 0:ac97d71fe296 | 178 | y_end = y + image_height - 1; |
imachooon | 0:ac97d71fe296 | 179 | } |
imachooon | 0:ac97d71fe296 | 180 | SetMemoryArea(x, y, x_end, y_end); |
imachooon | 0:ac97d71fe296 | 181 | SetMemoryPointer(x, y); |
imachooon | 0:ac97d71fe296 | 182 | SendCommand(WRITE_RAM); |
imachooon | 0:ac97d71fe296 | 183 | /* send the image data */ |
imachooon | 0:ac97d71fe296 | 184 | for (int j = 0; j < y_end - y + 1; j++) { |
imachooon | 0:ac97d71fe296 | 185 | for (int i = 0; i < (x_end - x + 1) / 8; i++) { |
imachooon | 0:ac97d71fe296 | 186 | SendData(image_buffer[i + j * (image_width / 8)]); |
imachooon | 0:ac97d71fe296 | 187 | } |
imachooon | 0:ac97d71fe296 | 188 | } |
imachooon | 0:ac97d71fe296 | 189 | } |
imachooon | 0:ac97d71fe296 | 190 | |
imachooon | 0:ac97d71fe296 | 191 | /** |
imachooon | 0:ac97d71fe296 | 192 | * @brief: clear the frame memory with the specified color. |
imachooon | 0:ac97d71fe296 | 193 | * this won't update the display. |
imachooon | 0:ac97d71fe296 | 194 | */ |
imachooon | 0:ac97d71fe296 | 195 | void Epd::ClearFrameMemory(unsigned char color) { |
imachooon | 0:ac97d71fe296 | 196 | SetMemoryArea(0, 0, this->width - 1, this->height - 1); |
imachooon | 0:ac97d71fe296 | 197 | SetMemoryPointer(0, 0); |
imachooon | 0:ac97d71fe296 | 198 | SendCommand(WRITE_RAM); |
imachooon | 0:ac97d71fe296 | 199 | /* send the color data */ |
imachooon | 0:ac97d71fe296 | 200 | for (int i = 0; i < this->width / 8 * this->height; i++) { |
imachooon | 0:ac97d71fe296 | 201 | SendData(color); |
imachooon | 0:ac97d71fe296 | 202 | } |
imachooon | 0:ac97d71fe296 | 203 | } |
imachooon | 0:ac97d71fe296 | 204 | |
imachooon | 0:ac97d71fe296 | 205 | /** |
imachooon | 0:ac97d71fe296 | 206 | * @brief: update the display |
imachooon | 0:ac97d71fe296 | 207 | * there are 2 memory areas embedded in the e-paper display |
imachooon | 0:ac97d71fe296 | 208 | * but once this function is called, |
imachooon | 0:ac97d71fe296 | 209 | * the the next action of SetFrameMemory or ClearFrame will |
imachooon | 0:ac97d71fe296 | 210 | * set the other memory area. |
imachooon | 0:ac97d71fe296 | 211 | */ |
imachooon | 0:ac97d71fe296 | 212 | void Epd::DisplayFrame(void) { |
imachooon | 0:ac97d71fe296 | 213 | SendCommand(DISPLAY_UPDATE_CONTROL_2); |
imachooon | 0:ac97d71fe296 | 214 | SendData(0xC4); |
imachooon | 0:ac97d71fe296 | 215 | SendCommand(MASTER_ACTIVATION); |
imachooon | 0:ac97d71fe296 | 216 | SendCommand(TERMINATE_FRAME_READ_WRITE); |
imachooon | 0:ac97d71fe296 | 217 | WaitUntilIdle(); |
imachooon | 0:ac97d71fe296 | 218 | } |
imachooon | 0:ac97d71fe296 | 219 | |
imachooon | 0:ac97d71fe296 | 220 | /** |
imachooon | 0:ac97d71fe296 | 221 | * @brief: private function to specify the memory area for data R/W |
imachooon | 0:ac97d71fe296 | 222 | */ |
imachooon | 0:ac97d71fe296 | 223 | void Epd::SetMemoryArea(int x_start, int y_start, int x_end, int y_end) { |
imachooon | 0:ac97d71fe296 | 224 | SendCommand(SET_RAM_X_ADDRESS_START_END_POSITION); |
imachooon | 0:ac97d71fe296 | 225 | /* x point must be the multiple of 8 or the last 3 bits will be ignored */ |
imachooon | 0:ac97d71fe296 | 226 | SendData((x_start >> 3) & 0xFF); |
imachooon | 0:ac97d71fe296 | 227 | SendData((x_end >> 3) & 0xFF); |
imachooon | 0:ac97d71fe296 | 228 | SendCommand(SET_RAM_Y_ADDRESS_START_END_POSITION); |
imachooon | 0:ac97d71fe296 | 229 | SendData(y_start & 0xFF); |
imachooon | 0:ac97d71fe296 | 230 | SendData((y_start >> 8) & 0xFF); |
imachooon | 0:ac97d71fe296 | 231 | SendData(y_end & 0xFF); |
imachooon | 0:ac97d71fe296 | 232 | SendData((y_end >> 8) & 0xFF); |
imachooon | 0:ac97d71fe296 | 233 | } |
imachooon | 0:ac97d71fe296 | 234 | |
imachooon | 0:ac97d71fe296 | 235 | /** |
imachooon | 0:ac97d71fe296 | 236 | * @brief: private function to specify the start point for data R/W |
imachooon | 0:ac97d71fe296 | 237 | */ |
imachooon | 0:ac97d71fe296 | 238 | void Epd::SetMemoryPointer(int x, int y) { |
imachooon | 0:ac97d71fe296 | 239 | SendCommand(SET_RAM_X_ADDRESS_COUNTER); |
imachooon | 0:ac97d71fe296 | 240 | /* x point must be the multiple of 8 or the last 3 bits will be ignored */ |
imachooon | 0:ac97d71fe296 | 241 | SendData((x >> 3) & 0xFF); |
imachooon | 0:ac97d71fe296 | 242 | SendCommand(SET_RAM_Y_ADDRESS_COUNTER); |
imachooon | 0:ac97d71fe296 | 243 | SendData(y & 0xFF); |
imachooon | 0:ac97d71fe296 | 244 | SendData((y >> 8) & 0xFF); |
imachooon | 0:ac97d71fe296 | 245 | WaitUntilIdle(); |
imachooon | 0:ac97d71fe296 | 246 | } |
imachooon | 0:ac97d71fe296 | 247 | |
imachooon | 0:ac97d71fe296 | 248 | |
imachooon | 0:ac97d71fe296 | 249 | /** |
imachooon | 0:ac97d71fe296 | 250 | * @brief: After this command is transmitted, the chip would enter the |
imachooon | 0:ac97d71fe296 | 251 | * deep-sleep mode to save power. |
imachooon | 0:ac97d71fe296 | 252 | * The deep sleep mode would return to standby by hardware reset. |
imachooon | 0:ac97d71fe296 | 253 | * You can use Epd::Init() to awaken |
imachooon | 0:ac97d71fe296 | 254 | */ |
imachooon | 0:ac97d71fe296 | 255 | void Epd::Sleep() { |
imachooon | 0:ac97d71fe296 | 256 | SendCommand(DEEP_SLEEP_MODE); |
imachooon | 0:ac97d71fe296 | 257 | WaitUntilIdle(); |
imachooon | 0:ac97d71fe296 | 258 | } |
imachooon | 0:ac97d71fe296 | 259 | |
imachooon | 0:ac97d71fe296 | 260 | |
imachooon | 0:ac97d71fe296 | 261 | void Epd::SetRotate(int rotate){ |
imachooon | 0:ac97d71fe296 | 262 | if (rotate == ROTATE_0){ |
imachooon | 0:ac97d71fe296 | 263 | rotate = ROTATE_0; |
imachooon | 0:ac97d71fe296 | 264 | width = EPD_WIDTH; |
imachooon | 0:ac97d71fe296 | 265 | height = EPD_HEIGHT; |
imachooon | 0:ac97d71fe296 | 266 | } |
imachooon | 0:ac97d71fe296 | 267 | else if (rotate == ROTATE_90){ |
imachooon | 0:ac97d71fe296 | 268 | rotate = ROTATE_90; |
imachooon | 0:ac97d71fe296 | 269 | width = EPD_HEIGHT; |
imachooon | 0:ac97d71fe296 | 270 | height = EPD_WIDTH; |
imachooon | 0:ac97d71fe296 | 271 | } |
imachooon | 0:ac97d71fe296 | 272 | else if (rotate == ROTATE_180){ |
imachooon | 0:ac97d71fe296 | 273 | rotate = ROTATE_180; |
imachooon | 0:ac97d71fe296 | 274 | width = EPD_WIDTH; |
imachooon | 0:ac97d71fe296 | 275 | height = EPD_HEIGHT; |
imachooon | 0:ac97d71fe296 | 276 | } |
imachooon | 0:ac97d71fe296 | 277 | else if (rotate == ROTATE_270){ |
imachooon | 0:ac97d71fe296 | 278 | rotate = ROTATE_270; |
imachooon | 0:ac97d71fe296 | 279 | width = EPD_HEIGHT; |
imachooon | 0:ac97d71fe296 | 280 | height = EPD_WIDTH; |
imachooon | 0:ac97d71fe296 | 281 | } |
imachooon | 0:ac97d71fe296 | 282 | } |
imachooon | 0:ac97d71fe296 | 283 | |
imachooon | 0:ac97d71fe296 | 284 | |
imachooon | 0:ac97d71fe296 | 285 | void Epd::SetPixel(unsigned char* frame_buffer, int x, int y, int colored){ |
imachooon | 0:ac97d71fe296 | 286 | if (x < 0 || x >= width || y < 0 || y >= height){ |
imachooon | 0:ac97d71fe296 | 287 | return; |
imachooon | 0:ac97d71fe296 | 288 | } |
imachooon | 0:ac97d71fe296 | 289 | if (rotate == ROTATE_0){ |
imachooon | 0:ac97d71fe296 | 290 | SetAbsolutePixel(frame_buffer, x, y, colored); |
imachooon | 0:ac97d71fe296 | 291 | } |
imachooon | 0:ac97d71fe296 | 292 | else if (rotate == ROTATE_90){ |
imachooon | 0:ac97d71fe296 | 293 | int point_temp = x; |
imachooon | 0:ac97d71fe296 | 294 | x = EPD_WIDTH - y; |
imachooon | 0:ac97d71fe296 | 295 | y = point_temp; |
imachooon | 0:ac97d71fe296 | 296 | SetAbsolutePixel(frame_buffer, x, y, colored); |
imachooon | 0:ac97d71fe296 | 297 | } |
imachooon | 0:ac97d71fe296 | 298 | else if (rotate == ROTATE_180){ |
imachooon | 0:ac97d71fe296 | 299 | x = EPD_WIDTH - x; |
imachooon | 0:ac97d71fe296 | 300 | y = EPD_HEIGHT- y; |
imachooon | 0:ac97d71fe296 | 301 | SetAbsolutePixel(frame_buffer, x, y, colored); |
imachooon | 0:ac97d71fe296 | 302 | } |
imachooon | 0:ac97d71fe296 | 303 | else if (rotate == ROTATE_270){ |
imachooon | 0:ac97d71fe296 | 304 | int point_temp = x; |
imachooon | 0:ac97d71fe296 | 305 | x = y; |
imachooon | 0:ac97d71fe296 | 306 | y = EPD_HEIGHT - point_temp; |
imachooon | 0:ac97d71fe296 | 307 | SetAbsolutePixel(frame_buffer, x, y, colored); |
imachooon | 0:ac97d71fe296 | 308 | } |
imachooon | 0:ac97d71fe296 | 309 | } |
imachooon | 0:ac97d71fe296 | 310 | |
imachooon | 0:ac97d71fe296 | 311 | void Epd::SetAbsolutePixel(unsigned char *frame_buffer, int x, int y, int colored){ |
imachooon | 0:ac97d71fe296 | 312 | // To avoid display orientation effects |
imachooon | 0:ac97d71fe296 | 313 | // use EPD_WIDTH instead of self.width |
imachooon | 0:ac97d71fe296 | 314 | // use EPD_HEIGHT instead of self.height |
imachooon | 0:ac97d71fe296 | 315 | if (x < 0 || x >= EPD_WIDTH || y < 0 || y >= EPD_HEIGHT){ |
imachooon | 0:ac97d71fe296 | 316 | return; |
imachooon | 0:ac97d71fe296 | 317 | } |
imachooon | 0:ac97d71fe296 | 318 | if (colored){ |
imachooon | 0:ac97d71fe296 | 319 | frame_buffer[(x + y * EPD_WIDTH) / 8] &= ~(0x80 >> (x % 8)); |
imachooon | 0:ac97d71fe296 | 320 | } |
imachooon | 0:ac97d71fe296 | 321 | else{ |
imachooon | 0:ac97d71fe296 | 322 | frame_buffer[(x + y * EPD_WIDTH) / 8] |= 0x80 >> (x % 8); |
imachooon | 0:ac97d71fe296 | 323 | } |
imachooon | 0:ac97d71fe296 | 324 | } |
imachooon | 0:ac97d71fe296 | 325 | |
imachooon | 0:ac97d71fe296 | 326 | void Epd::DrawLine(unsigned char*frame_buffer, int x0, int y0, int x1, int y1, int colored){ |
imachooon | 0:ac97d71fe296 | 327 | // Bresenham algorithm |
imachooon | 0:ac97d71fe296 | 328 | int dx = x1 - x0 >= 0 ? x1 - x0 : x0 - x1; |
imachooon | 0:ac97d71fe296 | 329 | int sx = x0 < x1 ? 1 : -1; |
imachooon | 0:ac97d71fe296 | 330 | int dy = y1 - y0 <= 0 ? y1 - y0 : y0 - y1; |
imachooon | 0:ac97d71fe296 | 331 | int sy = y0 < y1 ? 1 : -1; |
imachooon | 0:ac97d71fe296 | 332 | int err = dx + dy; |
imachooon | 0:ac97d71fe296 | 333 | while((x0 != x1) && (y0 != y1)){ |
imachooon | 0:ac97d71fe296 | 334 | SetPixel(frame_buffer, x0, y0 , colored); |
imachooon | 0:ac97d71fe296 | 335 | if (2 * err >= dy){ |
imachooon | 0:ac97d71fe296 | 336 | err += dy; |
imachooon | 0:ac97d71fe296 | 337 | x0 += sx; |
imachooon | 0:ac97d71fe296 | 338 | } |
imachooon | 0:ac97d71fe296 | 339 | if (2 * err <= dx){ |
imachooon | 0:ac97d71fe296 | 340 | err += dx; |
imachooon | 0:ac97d71fe296 | 341 | y0 += sy; |
imachooon | 0:ac97d71fe296 | 342 | } |
imachooon | 0:ac97d71fe296 | 343 | } |
imachooon | 0:ac97d71fe296 | 344 | } |
imachooon | 0:ac97d71fe296 | 345 | |
imachooon | 0:ac97d71fe296 | 346 | void Epd::DrawHorizontalLine(unsigned char *frame_buffer, int x, int y, int width, int colored){ |
imachooon | 0:ac97d71fe296 | 347 | for (int i=x; i<x + width; i++){ |
imachooon | 0:ac97d71fe296 | 348 | SetPixel(frame_buffer, i, y, colored); |
imachooon | 0:ac97d71fe296 | 349 | } |
imachooon | 0:ac97d71fe296 | 350 | } |
imachooon | 0:ac97d71fe296 | 351 | |
imachooon | 0:ac97d71fe296 | 352 | void Epd::DrawVerticalLine(unsigned char *frame_buffer, int x, int y, int height, int colored){ |
imachooon | 0:ac97d71fe296 | 353 | for (int i=y; i<y + height; i++){ |
imachooon | 0:ac97d71fe296 | 354 | SetPixel(frame_buffer, x, i, colored); |
imachooon | 0:ac97d71fe296 | 355 | } |
imachooon | 0:ac97d71fe296 | 356 | } |
imachooon | 0:ac97d71fe296 | 357 | |
imachooon | 0:ac97d71fe296 | 358 | void Epd::DrawRectangle(unsigned char *frame_buffer, int x0, int y0, int x1, int y1, int colored){ |
imachooon | 0:ac97d71fe296 | 359 | int min_x = x1 > x0 ? x0 : x1; |
imachooon | 0:ac97d71fe296 | 360 | int max_x = x1 > x0 ? x1 : x0; |
imachooon | 0:ac97d71fe296 | 361 | int min_y = y1 > y0 ? y0 : y1; |
imachooon | 0:ac97d71fe296 | 362 | int max_y = y1 > y0 ? y1 : y0; |
imachooon | 0:ac97d71fe296 | 363 | DrawHorizontalLine(frame_buffer, min_x, min_y, max_x - min_x + 1, colored); |
imachooon | 0:ac97d71fe296 | 364 | DrawHorizontalLine(frame_buffer, min_x, max_y, max_x - min_x + 1, colored); |
imachooon | 0:ac97d71fe296 | 365 | DrawVerticalLine(frame_buffer, min_x, min_y, max_y - min_y + 1, colored); |
imachooon | 0:ac97d71fe296 | 366 | DrawVerticalLine(frame_buffer, max_x, min_y, max_y - min_y + 1, colored); |
imachooon | 0:ac97d71fe296 | 367 | } |
imachooon | 0:ac97d71fe296 | 368 | |
imachooon | 0:ac97d71fe296 | 369 | |
imachooon | 0:ac97d71fe296 | 370 | void Epd::DrawFilledRectangle(unsigned char *frame_buffer, int x0, int y0, int x1, int y1, int colored){ |
imachooon | 0:ac97d71fe296 | 371 | int min_x = x1 > x0 ? x0 : x1; |
imachooon | 0:ac97d71fe296 | 372 | int max_x = x1 > x0 ? x1 : x0; |
imachooon | 0:ac97d71fe296 | 373 | int min_y = y1 > y0 ? y0 : y1; |
imachooon | 0:ac97d71fe296 | 374 | int max_y = y1 > y0 ? y1 : y0; |
imachooon | 0:ac97d71fe296 | 375 | |
imachooon | 0:ac97d71fe296 | 376 | for (int i=min_x; i < max_x+1; i++){ |
imachooon | 0:ac97d71fe296 | 377 | DrawVerticalLine(frame_buffer, i, min_y, max_y - min_y + 1, colored); |
imachooon | 0:ac97d71fe296 | 378 | } |
imachooon | 0:ac97d71fe296 | 379 | } |
imachooon | 0:ac97d71fe296 | 380 | |
imachooon | 0:ac97d71fe296 | 381 | void Epd::DrawCircle(unsigned char *frame_buffer, int x, int y, int radius, int colored){ |
imachooon | 0:ac97d71fe296 | 382 | // Bresenham algorithm |
imachooon | 0:ac97d71fe296 | 383 | int x_pos = -radius; |
imachooon | 0:ac97d71fe296 | 384 | int y_pos = 0; |
imachooon | 0:ac97d71fe296 | 385 | int err = 2 - 2 * radius; |
imachooon | 0:ac97d71fe296 | 386 | if (x >= width || y >= height){ |
imachooon | 0:ac97d71fe296 | 387 | return; |
imachooon | 0:ac97d71fe296 | 388 | } |
imachooon | 0:ac97d71fe296 | 389 | while ( 1 ){ |
imachooon | 0:ac97d71fe296 | 390 | SetPixel(frame_buffer, x - x_pos, y + y_pos, colored); |
imachooon | 0:ac97d71fe296 | 391 | SetPixel(frame_buffer, x + x_pos, y + y_pos, colored); |
imachooon | 0:ac97d71fe296 | 392 | SetPixel(frame_buffer, x + x_pos, y - y_pos, colored); |
imachooon | 0:ac97d71fe296 | 393 | SetPixel(frame_buffer, x - x_pos, y - y_pos, colored); |
imachooon | 0:ac97d71fe296 | 394 | int e2 = err; |
imachooon | 0:ac97d71fe296 | 395 | if (e2 <= y_pos){ |
imachooon | 0:ac97d71fe296 | 396 | y_pos += 1; |
imachooon | 0:ac97d71fe296 | 397 | err += y_pos * 2 + 1; |
imachooon | 0:ac97d71fe296 | 398 | if(-x_pos == y_pos && e2 <= x_pos){ |
imachooon | 0:ac97d71fe296 | 399 | e2 = 0; |
imachooon | 0:ac97d71fe296 | 400 | } |
imachooon | 0:ac97d71fe296 | 401 | } |
imachooon | 0:ac97d71fe296 | 402 | if (e2 > x_pos){ |
imachooon | 0:ac97d71fe296 | 403 | x_pos += 1; |
imachooon | 0:ac97d71fe296 | 404 | err += x_pos * 2 + 1; |
imachooon | 0:ac97d71fe296 | 405 | } |
imachooon | 0:ac97d71fe296 | 406 | if (x_pos > 0){ |
imachooon | 0:ac97d71fe296 | 407 | break; |
imachooon | 0:ac97d71fe296 | 408 | } |
imachooon | 0:ac97d71fe296 | 409 | } |
imachooon | 0:ac97d71fe296 | 410 | } |
imachooon | 0:ac97d71fe296 | 411 | |
imachooon | 0:ac97d71fe296 | 412 | void Epd::DrawFilledCircle(unsigned char* frame_buffer, int x, int y, int radius, int colored){ |
imachooon | 0:ac97d71fe296 | 413 | // Bresenham algorithm |
imachooon | 0:ac97d71fe296 | 414 | int x_pos = -radius; |
imachooon | 0:ac97d71fe296 | 415 | int y_pos = 0; |
imachooon | 0:ac97d71fe296 | 416 | int err = 2 - 2 * radius; |
imachooon | 0:ac97d71fe296 | 417 | if (x >= width || y >= height){ |
imachooon | 0:ac97d71fe296 | 418 | return; |
imachooon | 0:ac97d71fe296 | 419 | } |
imachooon | 0:ac97d71fe296 | 420 | while ( 1 ){ |
imachooon | 0:ac97d71fe296 | 421 | SetPixel(frame_buffer, x - x_pos, y + y_pos, colored); |
imachooon | 0:ac97d71fe296 | 422 | SetPixel(frame_buffer, x + x_pos, y + y_pos, colored); |
imachooon | 0:ac97d71fe296 | 423 | SetPixel(frame_buffer, x + x_pos, y - y_pos, colored); |
imachooon | 0:ac97d71fe296 | 424 | SetPixel(frame_buffer, x - x_pos, y - y_pos, colored); |
imachooon | 0:ac97d71fe296 | 425 | DrawHorizontalLine(frame_buffer, x + x_pos, y + y_pos, 2 * (-x_pos) + 1, colored); |
imachooon | 0:ac97d71fe296 | 426 | DrawHorizontalLine(frame_buffer, x + x_pos, y - y_pos, 2 * (-x_pos) + 1, colored); |
imachooon | 0:ac97d71fe296 | 427 | int e2 = err; |
imachooon | 0:ac97d71fe296 | 428 | if (e2 <= y_pos){ |
imachooon | 0:ac97d71fe296 | 429 | y_pos += 1; |
imachooon | 0:ac97d71fe296 | 430 | err += y_pos * 2 + 1; |
imachooon | 0:ac97d71fe296 | 431 | if(-x_pos == y_pos && e2 <= x_pos){ |
imachooon | 0:ac97d71fe296 | 432 | e2 = 0; |
imachooon | 0:ac97d71fe296 | 433 | } |
imachooon | 0:ac97d71fe296 | 434 | } |
imachooon | 0:ac97d71fe296 | 435 | if (e2 > x_pos){ |
imachooon | 0:ac97d71fe296 | 436 | x_pos += 1; |
imachooon | 0:ac97d71fe296 | 437 | err += x_pos * 2 + 1; |
imachooon | 0:ac97d71fe296 | 438 | } |
imachooon | 0:ac97d71fe296 | 439 | if (x_pos > 0){ |
imachooon | 0:ac97d71fe296 | 440 | break; |
imachooon | 0:ac97d71fe296 | 441 | } |
imachooon | 0:ac97d71fe296 | 442 | } |
imachooon | 0:ac97d71fe296 | 443 | } |
imachooon | 0:ac97d71fe296 | 444 | |
imachooon | 0:ac97d71fe296 | 445 | |
imachooon | 0:ac97d71fe296 | 446 | |
imachooon | 0:ac97d71fe296 | 447 | /** |
imachooon | 0:ac97d71fe296 | 448 | * @brief: this draws a charactor on the frame buffer but not refresh |
imachooon | 0:ac97d71fe296 | 449 | */ |
imachooon | 0:ac97d71fe296 | 450 | void Epd::DrawCharAt(unsigned char *frame_buffer, int x, int y, char ascii_char, sFONT* font, int colored) { |
imachooon | 0:ac97d71fe296 | 451 | int i, j; |
imachooon | 0:ac97d71fe296 | 452 | unsigned int char_offset = (ascii_char - ' ') * font->Height * (font->Width / 8 + (font->Width % 8 ? 1 : 0)); |
imachooon | 0:ac97d71fe296 | 453 | const unsigned char* ptr = &font->table[char_offset]; |
imachooon | 0:ac97d71fe296 | 454 | |
imachooon | 0:ac97d71fe296 | 455 | for (j = 0; j < font->Height; j++) { |
imachooon | 0:ac97d71fe296 | 456 | for (i = 0; i < font->Width; i++) { |
imachooon | 0:ac97d71fe296 | 457 | if (*ptr & (0x80 >> (i % 8))) { |
imachooon | 0:ac97d71fe296 | 458 | SetPixel(frame_buffer, x + i, y + j, colored); |
imachooon | 0:ac97d71fe296 | 459 | } |
imachooon | 0:ac97d71fe296 | 460 | if (i % 8 == 7) { |
imachooon | 0:ac97d71fe296 | 461 | ptr++; |
imachooon | 0:ac97d71fe296 | 462 | } |
imachooon | 0:ac97d71fe296 | 463 | } |
imachooon | 0:ac97d71fe296 | 464 | if (font->Width % 8 != 0) { |
imachooon | 0:ac97d71fe296 | 465 | ptr++; |
imachooon | 0:ac97d71fe296 | 466 | } |
imachooon | 0:ac97d71fe296 | 467 | } |
imachooon | 0:ac97d71fe296 | 468 | } |
imachooon | 0:ac97d71fe296 | 469 | |
imachooon | 0:ac97d71fe296 | 470 | /** |
imachooon | 0:ac97d71fe296 | 471 | * @brief: this displays a string on the frame buffer but not refresh |
imachooon | 0:ac97d71fe296 | 472 | */ |
imachooon | 0:ac97d71fe296 | 473 | void Epd::DrawStringAt(unsigned char *frame_buffer, int x, int y, const char* text, sFONT* font, int colored) { |
imachooon | 0:ac97d71fe296 | 474 | const char* p_text = text; |
imachooon | 0:ac97d71fe296 | 475 | unsigned int counter = 0; |
imachooon | 0:ac97d71fe296 | 476 | int refcolumn = x; |
imachooon | 0:ac97d71fe296 | 477 | |
imachooon | 0:ac97d71fe296 | 478 | /* Send the string character by character on EPD */ |
imachooon | 0:ac97d71fe296 | 479 | while (*p_text != 0) { |
imachooon | 0:ac97d71fe296 | 480 | /* Display one character on EPD */ |
imachooon | 0:ac97d71fe296 | 481 | DrawCharAt(frame_buffer, refcolumn, y, *p_text, font, colored); |
imachooon | 0:ac97d71fe296 | 482 | /* Decrement the column position by 16 */ |
imachooon | 0:ac97d71fe296 | 483 | refcolumn += font->Width; |
imachooon | 0:ac97d71fe296 | 484 | /* Point on the next character */ |
imachooon | 0:ac97d71fe296 | 485 | p_text++; |
imachooon | 0:ac97d71fe296 | 486 | counter++; |
imachooon | 0:ac97d71fe296 | 487 | } |
imachooon | 0:ac97d71fe296 | 488 | } |