early testing of epaper and rotary encoder

Dependents:   e-ink-test_menu

Committer:
RogerJKelly
Date:
Mon Mar 04 21:43:23 2019 +0000
Revision:
1:75b1993d74b1
Parent:
0:ac97d71fe296
Early testing of epaper display and encoder

Who changed what in which revision?

UserRevisionLine numberNew 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;
imachooon 0:ac97d71fe296 63 rotate = ROTATE_0;
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 */
RogerJKelly 1:75b1993d74b1 137 void Epd::SetLut(const unsigned char* lut)
RogerJKelly 1:75b1993d74b1 138 {
imachooon 0:ac97d71fe296 139 SendCommand(WRITE_LUT_REGISTER);
imachooon 0:ac97d71fe296 140 /* the length of look-up table is 30 bytes */
imachooon 0:ac97d71fe296 141 for (int i = 0; i < 30; i++) {
imachooon 0:ac97d71fe296 142 SendData(lut[i]);
imachooon 0:ac97d71fe296 143 }
imachooon 0:ac97d71fe296 144 }
imachooon 0:ac97d71fe296 145
imachooon 0:ac97d71fe296 146
imachooon 0:ac97d71fe296 147 /**
imachooon 0:ac97d71fe296 148 * @brief: put an image buffer to the frame memory.
imachooon 0:ac97d71fe296 149 * this won't update the display.
imachooon 0:ac97d71fe296 150 */
imachooon 0:ac97d71fe296 151 void Epd::SetFrameMemory(
imachooon 0:ac97d71fe296 152 const unsigned char* image_buffer,
imachooon 0:ac97d71fe296 153 int x,
imachooon 0:ac97d71fe296 154 int y,
imachooon 0:ac97d71fe296 155 int image_width,
imachooon 0:ac97d71fe296 156 int image_height
imachooon 0:ac97d71fe296 157 ) {
imachooon 0:ac97d71fe296 158 int x_end;
imachooon 0:ac97d71fe296 159 int y_end;
imachooon 0:ac97d71fe296 160
imachooon 0:ac97d71fe296 161 if (
imachooon 0:ac97d71fe296 162 image_buffer == NULL ||
imachooon 0:ac97d71fe296 163 x < 0 || image_width < 0 ||
imachooon 0:ac97d71fe296 164 y < 0 || image_height < 0
imachooon 0:ac97d71fe296 165 ) {
imachooon 0:ac97d71fe296 166 return;
imachooon 0:ac97d71fe296 167 }
imachooon 0:ac97d71fe296 168 /* x point must be the multiple of 8 or the last 3 bits will be ignored */
imachooon 0:ac97d71fe296 169 x &= 0xF8;
imachooon 0:ac97d71fe296 170 image_width &= 0xF8;
RogerJKelly 1:75b1993d74b1 171 //if (x + image_width >= this->width) {
RogerJKelly 1:75b1993d74b1 172 if (x + image_width >= EPD_WIDTH) {
RogerJKelly 1:75b1993d74b1 173 x_end = EPD_WIDTH - 1;
imachooon 0:ac97d71fe296 174 } else {
imachooon 0:ac97d71fe296 175 x_end = x + image_width - 1;
imachooon 0:ac97d71fe296 176 }
RogerJKelly 1:75b1993d74b1 177 //if (y + image_height >= this->height) {
RogerJKelly 1:75b1993d74b1 178 if (y + image_height >= EPD_HEIGHT) {
RogerJKelly 1:75b1993d74b1 179 y_end = EPD_HEIGHT - 1;
imachooon 0:ac97d71fe296 180 } else {
imachooon 0:ac97d71fe296 181 y_end = y + image_height - 1;
imachooon 0:ac97d71fe296 182 }
imachooon 0:ac97d71fe296 183 SetMemoryArea(x, y, x_end, y_end);
imachooon 0:ac97d71fe296 184 SetMemoryPointer(x, y);
imachooon 0:ac97d71fe296 185 SendCommand(WRITE_RAM);
imachooon 0:ac97d71fe296 186 /* send the image data */
RogerJKelly 1:75b1993d74b1 187 for (int j = 0; j < y_end - y + 1; j++)
RogerJKelly 1:75b1993d74b1 188 {
RogerJKelly 1:75b1993d74b1 189 for (int i = 0; i < (x_end - x + 1) / 8; i++)
RogerJKelly 1:75b1993d74b1 190 {
imachooon 0:ac97d71fe296 191 SendData(image_buffer[i + j * (image_width / 8)]);
imachooon 0:ac97d71fe296 192 }
imachooon 0:ac97d71fe296 193 }
imachooon 0:ac97d71fe296 194 }
imachooon 0:ac97d71fe296 195
imachooon 0:ac97d71fe296 196 /**
imachooon 0:ac97d71fe296 197 * @brief: clear the frame memory with the specified color.
imachooon 0:ac97d71fe296 198 * this won't update the display.
imachooon 0:ac97d71fe296 199 */
imachooon 0:ac97d71fe296 200 void Epd::ClearFrameMemory(unsigned char color) {
RogerJKelly 1:75b1993d74b1 201 //SetMemoryArea(0, 0, this->width - 1, this->height - 1);
RogerJKelly 1:75b1993d74b1 202 SetMemoryArea(0, 0, EPD_WIDTH - 1, EPD_HEIGHT - 1);
imachooon 0:ac97d71fe296 203 SetMemoryPointer(0, 0);
imachooon 0:ac97d71fe296 204 SendCommand(WRITE_RAM);
imachooon 0:ac97d71fe296 205 /* send the color data */
RogerJKelly 1:75b1993d74b1 206 for (int i = 0; i < EPD_WIDTH / 8 * EPD_WIDTH; i++) {
imachooon 0:ac97d71fe296 207 SendData(color);
imachooon 0:ac97d71fe296 208 }
imachooon 0:ac97d71fe296 209 }
imachooon 0:ac97d71fe296 210
imachooon 0:ac97d71fe296 211 /**
imachooon 0:ac97d71fe296 212 * @brief: update the display
imachooon 0:ac97d71fe296 213 * there are 2 memory areas embedded in the e-paper display
imachooon 0:ac97d71fe296 214 * but once this function is called,
imachooon 0:ac97d71fe296 215 * the the next action of SetFrameMemory or ClearFrame will
imachooon 0:ac97d71fe296 216 * set the other memory area.
imachooon 0:ac97d71fe296 217 */
imachooon 0:ac97d71fe296 218 void Epd::DisplayFrame(void) {
imachooon 0:ac97d71fe296 219 SendCommand(DISPLAY_UPDATE_CONTROL_2);
imachooon 0:ac97d71fe296 220 SendData(0xC4);
imachooon 0:ac97d71fe296 221 SendCommand(MASTER_ACTIVATION);
imachooon 0:ac97d71fe296 222 SendCommand(TERMINATE_FRAME_READ_WRITE);
imachooon 0:ac97d71fe296 223 WaitUntilIdle();
imachooon 0:ac97d71fe296 224 }
imachooon 0:ac97d71fe296 225
imachooon 0:ac97d71fe296 226 /**
imachooon 0:ac97d71fe296 227 * @brief: private function to specify the memory area for data R/W
imachooon 0:ac97d71fe296 228 */
imachooon 0:ac97d71fe296 229 void Epd::SetMemoryArea(int x_start, int y_start, int x_end, int y_end) {
imachooon 0:ac97d71fe296 230 SendCommand(SET_RAM_X_ADDRESS_START_END_POSITION);
imachooon 0:ac97d71fe296 231 /* x point must be the multiple of 8 or the last 3 bits will be ignored */
imachooon 0:ac97d71fe296 232 SendData((x_start >> 3) & 0xFF);
imachooon 0:ac97d71fe296 233 SendData((x_end >> 3) & 0xFF);
imachooon 0:ac97d71fe296 234 SendCommand(SET_RAM_Y_ADDRESS_START_END_POSITION);
imachooon 0:ac97d71fe296 235 SendData(y_start & 0xFF);
imachooon 0:ac97d71fe296 236 SendData((y_start >> 8) & 0xFF);
imachooon 0:ac97d71fe296 237 SendData(y_end & 0xFF);
imachooon 0:ac97d71fe296 238 SendData((y_end >> 8) & 0xFF);
imachooon 0:ac97d71fe296 239 }
imachooon 0:ac97d71fe296 240
imachooon 0:ac97d71fe296 241 /**
imachooon 0:ac97d71fe296 242 * @brief: private function to specify the start point for data R/W
imachooon 0:ac97d71fe296 243 */
imachooon 0:ac97d71fe296 244 void Epd::SetMemoryPointer(int x, int y) {
imachooon 0:ac97d71fe296 245 SendCommand(SET_RAM_X_ADDRESS_COUNTER);
imachooon 0:ac97d71fe296 246 /* x point must be the multiple of 8 or the last 3 bits will be ignored */
imachooon 0:ac97d71fe296 247 SendData((x >> 3) & 0xFF);
imachooon 0:ac97d71fe296 248 SendCommand(SET_RAM_Y_ADDRESS_COUNTER);
imachooon 0:ac97d71fe296 249 SendData(y & 0xFF);
imachooon 0:ac97d71fe296 250 SendData((y >> 8) & 0xFF);
imachooon 0:ac97d71fe296 251 WaitUntilIdle();
imachooon 0:ac97d71fe296 252 }
imachooon 0:ac97d71fe296 253
imachooon 0:ac97d71fe296 254
imachooon 0:ac97d71fe296 255 /**
imachooon 0:ac97d71fe296 256 * @brief: After this command is transmitted, the chip would enter the
imachooon 0:ac97d71fe296 257 * deep-sleep mode to save power.
imachooon 0:ac97d71fe296 258 * The deep sleep mode would return to standby by hardware reset.
imachooon 0:ac97d71fe296 259 * You can use Epd::Init() to awaken
imachooon 0:ac97d71fe296 260 */
imachooon 0:ac97d71fe296 261 void Epd::Sleep() {
imachooon 0:ac97d71fe296 262 SendCommand(DEEP_SLEEP_MODE);
imachooon 0:ac97d71fe296 263 WaitUntilIdle();
imachooon 0:ac97d71fe296 264 }
imachooon 0:ac97d71fe296 265
RogerJKelly 1:75b1993d74b1 266 /******************************
imachooon 0:ac97d71fe296 267 void Epd::SetRotate(int rotate){
imachooon 0:ac97d71fe296 268 if (rotate == ROTATE_0){
imachooon 0:ac97d71fe296 269 rotate = ROTATE_0;
imachooon 0:ac97d71fe296 270 width = EPD_WIDTH;
imachooon 0:ac97d71fe296 271 height = EPD_HEIGHT;
imachooon 0:ac97d71fe296 272 }
imachooon 0:ac97d71fe296 273 else if (rotate == ROTATE_90){
imachooon 0:ac97d71fe296 274 rotate = ROTATE_90;
imachooon 0:ac97d71fe296 275 width = EPD_HEIGHT;
imachooon 0:ac97d71fe296 276 height = EPD_WIDTH;
imachooon 0:ac97d71fe296 277 }
imachooon 0:ac97d71fe296 278 else if (rotate == ROTATE_180){
imachooon 0:ac97d71fe296 279 rotate = ROTATE_180;
imachooon 0:ac97d71fe296 280 width = EPD_WIDTH;
imachooon 0:ac97d71fe296 281 height = EPD_HEIGHT;
imachooon 0:ac97d71fe296 282 }
imachooon 0:ac97d71fe296 283 else if (rotate == ROTATE_270){
imachooon 0:ac97d71fe296 284 rotate = ROTATE_270;
imachooon 0:ac97d71fe296 285 width = EPD_HEIGHT;
imachooon 0:ac97d71fe296 286 height = EPD_WIDTH;
imachooon 0:ac97d71fe296 287 }
imachooon 0:ac97d71fe296 288 }
RogerJKelly 1:75b1993d74b1 289 **************************************/
imachooon 0:ac97d71fe296 290
RogerJKelly 1:75b1993d74b1 291 /**
RogerJKelly 1:75b1993d74b1 292 * @brief: clear the image
RogerJKelly 1:75b1993d74b1 293 */
RogerJKelly 1:75b1993d74b1 294 void Epd::Clear(unsigned char* frame_buffer, int colored) {
RogerJKelly 1:75b1993d74b1 295 for (int x = 0; x < this->width; x++) {
RogerJKelly 1:75b1993d74b1 296 for (int y = 0; y < this->height; y++) {
RogerJKelly 1:75b1993d74b1 297 DrawAbsolutePixel(frame_buffer, x, y, colored);
RogerJKelly 1:75b1993d74b1 298 }
RogerJKelly 1:75b1993d74b1 299 }
RogerJKelly 1:75b1993d74b1 300 }
RogerJKelly 1:75b1993d74b1 301 /**
RogerJKelly 1:75b1993d74b1 302 * @brief: this draws a pixel by absolute coordinates.
RogerJKelly 1:75b1993d74b1 303 * this function won't be affected by the rotate parameter.
RogerJKelly 1:75b1993d74b1 304 */
RogerJKelly 1:75b1993d74b1 305 void Epd::DrawAbsolutePixel(unsigned char* frame_buffer, int x, int y, int colored) {
RogerJKelly 1:75b1993d74b1 306 if (x < 0 || x >= EPD_WIDTH || y < 0 || y >= EPD_HEIGHT) {
imachooon 0:ac97d71fe296 307 return;
imachooon 0:ac97d71fe296 308 }
RogerJKelly 1:75b1993d74b1 309 if (IF_INVERT_COLOR) {
RogerJKelly 1:75b1993d74b1 310 if (colored) {
RogerJKelly 1:75b1993d74b1 311 frame_buffer[(x + y * this->width) / 8] |= 0x80 >> (x % 8);
RogerJKelly 1:75b1993d74b1 312 } else {
RogerJKelly 1:75b1993d74b1 313 frame_buffer[(x + y * this->width) / 8] &= ~(0x80 >> (x % 8));
RogerJKelly 1:75b1993d74b1 314 }
RogerJKelly 1:75b1993d74b1 315 } else {
RogerJKelly 1:75b1993d74b1 316 if (colored) {
RogerJKelly 1:75b1993d74b1 317 frame_buffer[(x + y * this->width) / 8] &= ~(0x80 >> (x % 8));
RogerJKelly 1:75b1993d74b1 318 } else {
RogerJKelly 1:75b1993d74b1 319 frame_buffer[(x + y * this->width) / 8] |= 0x80 >> (x % 8);
RogerJKelly 1:75b1993d74b1 320 }
imachooon 0:ac97d71fe296 321 }
imachooon 0:ac97d71fe296 322 }
imachooon 0:ac97d71fe296 323
RogerJKelly 1:75b1993d74b1 324 /**
RogerJKelly 1:75b1993d74b1 325 * @brief: Getters and Setters
RogerJKelly 1:75b1993d74b1 326 */
RogerJKelly 1:75b1993d74b1 327 int Epd::GetWidth(void)
RogerJKelly 1:75b1993d74b1 328 {
RogerJKelly 1:75b1993d74b1 329 return this->width;
RogerJKelly 1:75b1993d74b1 330 }
RogerJKelly 1:75b1993d74b1 331
RogerJKelly 1:75b1993d74b1 332 void Epd::SetWidth(int width)
RogerJKelly 1:75b1993d74b1 333 {
RogerJKelly 1:75b1993d74b1 334 this->width = width % 8 ? width + 8 - (width % 8) : width;
RogerJKelly 1:75b1993d74b1 335 }
RogerJKelly 1:75b1993d74b1 336
RogerJKelly 1:75b1993d74b1 337 int Epd::GetHeight(void)
RogerJKelly 1:75b1993d74b1 338 {
RogerJKelly 1:75b1993d74b1 339 return this->height;
RogerJKelly 1:75b1993d74b1 340 }
RogerJKelly 1:75b1993d74b1 341
RogerJKelly 1:75b1993d74b1 342 void Epd::SetHeight(int height)
RogerJKelly 1:75b1993d74b1 343 {
RogerJKelly 1:75b1993d74b1 344 this->height = height;
RogerJKelly 1:75b1993d74b1 345 }
RogerJKelly 1:75b1993d74b1 346
RogerJKelly 1:75b1993d74b1 347 int Epd::GetRotate(void)
RogerJKelly 1:75b1993d74b1 348 {
RogerJKelly 1:75b1993d74b1 349 return this->rotate;
RogerJKelly 1:75b1993d74b1 350 }
RogerJKelly 1:75b1993d74b1 351
RogerJKelly 1:75b1993d74b1 352 void Epd::SetRotate(int rotate)
RogerJKelly 1:75b1993d74b1 353 {
RogerJKelly 1:75b1993d74b1 354 this->rotate = rotate;
RogerJKelly 1:75b1993d74b1 355 }
RogerJKelly 1:75b1993d74b1 356
RogerJKelly 1:75b1993d74b1 357
RogerJKelly 1:75b1993d74b1 358 // RJK - adjusted for partial updates
RogerJKelly 1:75b1993d74b1 359 void Epd::SetPixel(unsigned char* frame_buffer, int x, int y, int colored)
RogerJKelly 1:75b1993d74b1 360 {
RogerJKelly 1:75b1993d74b1 361 if (x < 0 || x >= EPD_WIDTH || y < 0 || y >= EPD_HEIGHT){
RogerJKelly 1:75b1993d74b1 362 return;
RogerJKelly 1:75b1993d74b1 363 }
RogerJKelly 1:75b1993d74b1 364 if (this->rotate == ROTATE_0)
RogerJKelly 1:75b1993d74b1 365 {
RogerJKelly 1:75b1993d74b1 366 if(x < 0 || x >= this->width || y < 0 || y >= this->height)
RogerJKelly 1:75b1993d74b1 367 {
RogerJKelly 1:75b1993d74b1 368 return;
RogerJKelly 1:75b1993d74b1 369 }
RogerJKelly 1:75b1993d74b1 370 //SetAbsolutePixel(frame_buffer, x, y, colored);
RogerJKelly 1:75b1993d74b1 371 DrawAbsolutePixel(frame_buffer, x, y, colored);
RogerJKelly 1:75b1993d74b1 372 }
RogerJKelly 1:75b1993d74b1 373 else if (this->rotate == ROTATE_90)
RogerJKelly 1:75b1993d74b1 374 {
RogerJKelly 1:75b1993d74b1 375 if(x < 0 || x >= this->height || y < 0 || y >= this->width)
RogerJKelly 1:75b1993d74b1 376 {
RogerJKelly 1:75b1993d74b1 377 return;
RogerJKelly 1:75b1993d74b1 378 }
RogerJKelly 1:75b1993d74b1 379 int point_temp = x;
RogerJKelly 1:75b1993d74b1 380 //x = EPD_WIDTH - y;
RogerJKelly 1:75b1993d74b1 381 x = this->width - y;
RogerJKelly 1:75b1993d74b1 382 y = point_temp;
RogerJKelly 1:75b1993d74b1 383 //SetAbsolutePixel(frame_buffer, x, y, colored);
RogerJKelly 1:75b1993d74b1 384 DrawAbsolutePixel(frame_buffer, x, y, colored);
RogerJKelly 1:75b1993d74b1 385 }
RogerJKelly 1:75b1993d74b1 386 else if (this->rotate == ROTATE_180)
RogerJKelly 1:75b1993d74b1 387 {
RogerJKelly 1:75b1993d74b1 388 if(x < 0 || x >= this->width || y < 0 || y >= this->height)
RogerJKelly 1:75b1993d74b1 389 {
RogerJKelly 1:75b1993d74b1 390 return;
RogerJKelly 1:75b1993d74b1 391 }
RogerJKelly 1:75b1993d74b1 392 //x = EPD_WIDTH - x;
RogerJKelly 1:75b1993d74b1 393 //y = EPD_HEIGHT- y;
RogerJKelly 1:75b1993d74b1 394 x = this->width - x;
RogerJKelly 1:75b1993d74b1 395 y = this->height - y;
RogerJKelly 1:75b1993d74b1 396 //SetAbsolutePixel(frame_buffer, x, y, colored);
RogerJKelly 1:75b1993d74b1 397 DrawAbsolutePixel(frame_buffer, x, y, colored);
RogerJKelly 1:75b1993d74b1 398 }
RogerJKelly 1:75b1993d74b1 399 else if (this->rotate == ROTATE_270)
RogerJKelly 1:75b1993d74b1 400 {
RogerJKelly 1:75b1993d74b1 401 if(x < 0 || x >= this->height || y < 0 || y >= this->width)
RogerJKelly 1:75b1993d74b1 402 {
RogerJKelly 1:75b1993d74b1 403 return;
RogerJKelly 1:75b1993d74b1 404 }
RogerJKelly 1:75b1993d74b1 405 int point_temp = x;
RogerJKelly 1:75b1993d74b1 406 x = y;
RogerJKelly 1:75b1993d74b1 407 //y = EPD_HEIGHT - point_temp;
RogerJKelly 1:75b1993d74b1 408 y = this->height - point_temp;
RogerJKelly 1:75b1993d74b1 409 //SetAbsolutePixel(frame_buffer, x, y, colored);
RogerJKelly 1:75b1993d74b1 410 DrawAbsolutePixel(frame_buffer, x, y, colored);
RogerJKelly 1:75b1993d74b1 411 }
RogerJKelly 1:75b1993d74b1 412 }
RogerJKelly 1:75b1993d74b1 413
RogerJKelly 1:75b1993d74b1 414 /************************************************************************************
RogerJKelly 1:75b1993d74b1 415 void Epd::xSetAbsolutePixel(unsigned char *frame_buffer, int x, int y, int colored)
RogerJKelly 1:75b1993d74b1 416 {
imachooon 0:ac97d71fe296 417 // To avoid display orientation effects
imachooon 0:ac97d71fe296 418 // use EPD_WIDTH instead of self.width
imachooon 0:ac97d71fe296 419 // use EPD_HEIGHT instead of self.height
RogerJKelly 1:75b1993d74b1 420 //if (x < 0 || x >= EPD_WIDTH || y < 0 || y >= EPD_HEIGHT){
RogerJKelly 1:75b1993d74b1 421 // RJK - try with self width and height for partial refresh
RogerJKelly 1:75b1993d74b1 422 if (x < 0 || x >= this->width || y < 0 || y >= this->height) {
imachooon 0:ac97d71fe296 423 return;
imachooon 0:ac97d71fe296 424 }
imachooon 0:ac97d71fe296 425 if (colored){
imachooon 0:ac97d71fe296 426 frame_buffer[(x + y * EPD_WIDTH) / 8] &= ~(0x80 >> (x % 8));
imachooon 0:ac97d71fe296 427 }
imachooon 0:ac97d71fe296 428 else{
imachooon 0:ac97d71fe296 429 frame_buffer[(x + y * EPD_WIDTH) / 8] |= 0x80 >> (x % 8);
imachooon 0:ac97d71fe296 430 }
imachooon 0:ac97d71fe296 431 }
RogerJKelly 1:75b1993d74b1 432 ***************************************************************************************/
imachooon 0:ac97d71fe296 433 void Epd::DrawLine(unsigned char*frame_buffer, int x0, int y0, int x1, int y1, int colored){
imachooon 0:ac97d71fe296 434 // Bresenham algorithm
imachooon 0:ac97d71fe296 435 int dx = x1 - x0 >= 0 ? x1 - x0 : x0 - x1;
imachooon 0:ac97d71fe296 436 int sx = x0 < x1 ? 1 : -1;
imachooon 0:ac97d71fe296 437 int dy = y1 - y0 <= 0 ? y1 - y0 : y0 - y1;
imachooon 0:ac97d71fe296 438 int sy = y0 < y1 ? 1 : -1;
imachooon 0:ac97d71fe296 439 int err = dx + dy;
imachooon 0:ac97d71fe296 440 while((x0 != x1) && (y0 != y1)){
imachooon 0:ac97d71fe296 441 SetPixel(frame_buffer, x0, y0 , colored);
imachooon 0:ac97d71fe296 442 if (2 * err >= dy){
imachooon 0:ac97d71fe296 443 err += dy;
imachooon 0:ac97d71fe296 444 x0 += sx;
imachooon 0:ac97d71fe296 445 }
imachooon 0:ac97d71fe296 446 if (2 * err <= dx){
imachooon 0:ac97d71fe296 447 err += dx;
imachooon 0:ac97d71fe296 448 y0 += sy;
imachooon 0:ac97d71fe296 449 }
imachooon 0:ac97d71fe296 450 }
imachooon 0:ac97d71fe296 451 }
imachooon 0:ac97d71fe296 452
imachooon 0:ac97d71fe296 453 void Epd::DrawHorizontalLine(unsigned char *frame_buffer, int x, int y, int width, int colored){
imachooon 0:ac97d71fe296 454 for (int i=x; i<x + width; i++){
imachooon 0:ac97d71fe296 455 SetPixel(frame_buffer, i, y, colored);
imachooon 0:ac97d71fe296 456 }
imachooon 0:ac97d71fe296 457 }
imachooon 0:ac97d71fe296 458
imachooon 0:ac97d71fe296 459 void Epd::DrawVerticalLine(unsigned char *frame_buffer, int x, int y, int height, int colored){
imachooon 0:ac97d71fe296 460 for (int i=y; i<y + height; i++){
imachooon 0:ac97d71fe296 461 SetPixel(frame_buffer, x, i, colored);
imachooon 0:ac97d71fe296 462 }
imachooon 0:ac97d71fe296 463 }
imachooon 0:ac97d71fe296 464
imachooon 0:ac97d71fe296 465 void Epd::DrawRectangle(unsigned char *frame_buffer, int x0, int y0, int x1, int y1, int colored){
imachooon 0:ac97d71fe296 466 int min_x = x1 > x0 ? x0 : x1;
imachooon 0:ac97d71fe296 467 int max_x = x1 > x0 ? x1 : x0;
imachooon 0:ac97d71fe296 468 int min_y = y1 > y0 ? y0 : y1;
imachooon 0:ac97d71fe296 469 int max_y = y1 > y0 ? y1 : y0;
imachooon 0:ac97d71fe296 470 DrawHorizontalLine(frame_buffer, min_x, min_y, max_x - min_x + 1, colored);
imachooon 0:ac97d71fe296 471 DrawHorizontalLine(frame_buffer, min_x, max_y, max_x - min_x + 1, colored);
imachooon 0:ac97d71fe296 472 DrawVerticalLine(frame_buffer, min_x, min_y, max_y - min_y + 1, colored);
imachooon 0:ac97d71fe296 473 DrawVerticalLine(frame_buffer, max_x, min_y, max_y - min_y + 1, colored);
imachooon 0:ac97d71fe296 474 }
imachooon 0:ac97d71fe296 475
imachooon 0:ac97d71fe296 476
imachooon 0:ac97d71fe296 477 void Epd::DrawFilledRectangle(unsigned char *frame_buffer, int x0, int y0, int x1, int y1, int colored){
imachooon 0:ac97d71fe296 478 int min_x = x1 > x0 ? x0 : x1;
imachooon 0:ac97d71fe296 479 int max_x = x1 > x0 ? x1 : x0;
imachooon 0:ac97d71fe296 480 int min_y = y1 > y0 ? y0 : y1;
imachooon 0:ac97d71fe296 481 int max_y = y1 > y0 ? y1 : y0;
imachooon 0:ac97d71fe296 482
imachooon 0:ac97d71fe296 483 for (int i=min_x; i < max_x+1; i++){
imachooon 0:ac97d71fe296 484 DrawVerticalLine(frame_buffer, i, min_y, max_y - min_y + 1, colored);
imachooon 0:ac97d71fe296 485 }
imachooon 0:ac97d71fe296 486 }
imachooon 0:ac97d71fe296 487
imachooon 0:ac97d71fe296 488 void Epd::DrawCircle(unsigned char *frame_buffer, int x, int y, int radius, int colored){
imachooon 0:ac97d71fe296 489 // Bresenham algorithm
imachooon 0:ac97d71fe296 490 int x_pos = -radius;
imachooon 0:ac97d71fe296 491 int y_pos = 0;
imachooon 0:ac97d71fe296 492 int err = 2 - 2 * radius;
imachooon 0:ac97d71fe296 493 if (x >= width || y >= height){
imachooon 0:ac97d71fe296 494 return;
imachooon 0:ac97d71fe296 495 }
imachooon 0:ac97d71fe296 496 while ( 1 ){
imachooon 0:ac97d71fe296 497 SetPixel(frame_buffer, x - x_pos, y + y_pos, colored);
imachooon 0:ac97d71fe296 498 SetPixel(frame_buffer, x + x_pos, y + y_pos, colored);
imachooon 0:ac97d71fe296 499 SetPixel(frame_buffer, x + x_pos, y - y_pos, colored);
imachooon 0:ac97d71fe296 500 SetPixel(frame_buffer, x - x_pos, y - y_pos, colored);
imachooon 0:ac97d71fe296 501 int e2 = err;
imachooon 0:ac97d71fe296 502 if (e2 <= y_pos){
imachooon 0:ac97d71fe296 503 y_pos += 1;
imachooon 0:ac97d71fe296 504 err += y_pos * 2 + 1;
imachooon 0:ac97d71fe296 505 if(-x_pos == y_pos && e2 <= x_pos){
imachooon 0:ac97d71fe296 506 e2 = 0;
imachooon 0:ac97d71fe296 507 }
imachooon 0:ac97d71fe296 508 }
imachooon 0:ac97d71fe296 509 if (e2 > x_pos){
imachooon 0:ac97d71fe296 510 x_pos += 1;
imachooon 0:ac97d71fe296 511 err += x_pos * 2 + 1;
imachooon 0:ac97d71fe296 512 }
imachooon 0:ac97d71fe296 513 if (x_pos > 0){
imachooon 0:ac97d71fe296 514 break;
imachooon 0:ac97d71fe296 515 }
imachooon 0:ac97d71fe296 516 }
imachooon 0:ac97d71fe296 517 }
imachooon 0:ac97d71fe296 518
imachooon 0:ac97d71fe296 519 void Epd::DrawFilledCircle(unsigned char* frame_buffer, int x, int y, int radius, int colored){
imachooon 0:ac97d71fe296 520 // Bresenham algorithm
imachooon 0:ac97d71fe296 521 int x_pos = -radius;
imachooon 0:ac97d71fe296 522 int y_pos = 0;
imachooon 0:ac97d71fe296 523 int err = 2 - 2 * radius;
imachooon 0:ac97d71fe296 524 if (x >= width || y >= height){
imachooon 0:ac97d71fe296 525 return;
imachooon 0:ac97d71fe296 526 }
imachooon 0:ac97d71fe296 527 while ( 1 ){
imachooon 0:ac97d71fe296 528 SetPixel(frame_buffer, x - x_pos, y + y_pos, colored);
imachooon 0:ac97d71fe296 529 SetPixel(frame_buffer, x + x_pos, y + y_pos, colored);
imachooon 0:ac97d71fe296 530 SetPixel(frame_buffer, x + x_pos, y - y_pos, colored);
imachooon 0:ac97d71fe296 531 SetPixel(frame_buffer, x - x_pos, y - y_pos, colored);
imachooon 0:ac97d71fe296 532 DrawHorizontalLine(frame_buffer, x + x_pos, y + y_pos, 2 * (-x_pos) + 1, colored);
imachooon 0:ac97d71fe296 533 DrawHorizontalLine(frame_buffer, x + x_pos, y - y_pos, 2 * (-x_pos) + 1, colored);
imachooon 0:ac97d71fe296 534 int e2 = err;
imachooon 0:ac97d71fe296 535 if (e2 <= y_pos){
imachooon 0:ac97d71fe296 536 y_pos += 1;
imachooon 0:ac97d71fe296 537 err += y_pos * 2 + 1;
imachooon 0:ac97d71fe296 538 if(-x_pos == y_pos && e2 <= x_pos){
imachooon 0:ac97d71fe296 539 e2 = 0;
imachooon 0:ac97d71fe296 540 }
imachooon 0:ac97d71fe296 541 }
imachooon 0:ac97d71fe296 542 if (e2 > x_pos){
imachooon 0:ac97d71fe296 543 x_pos += 1;
imachooon 0:ac97d71fe296 544 err += x_pos * 2 + 1;
imachooon 0:ac97d71fe296 545 }
imachooon 0:ac97d71fe296 546 if (x_pos > 0){
imachooon 0:ac97d71fe296 547 break;
imachooon 0:ac97d71fe296 548 }
imachooon 0:ac97d71fe296 549 }
imachooon 0:ac97d71fe296 550 }
imachooon 0:ac97d71fe296 551
imachooon 0:ac97d71fe296 552
imachooon 0:ac97d71fe296 553
imachooon 0:ac97d71fe296 554 /**
imachooon 0:ac97d71fe296 555 * @brief: this draws a charactor on the frame buffer but not refresh
imachooon 0:ac97d71fe296 556 */
imachooon 0:ac97d71fe296 557 void Epd::DrawCharAt(unsigned char *frame_buffer, int x, int y, char ascii_char, sFONT* font, int colored) {
imachooon 0:ac97d71fe296 558 int i, j;
imachooon 0:ac97d71fe296 559 unsigned int char_offset = (ascii_char - ' ') * font->Height * (font->Width / 8 + (font->Width % 8 ? 1 : 0));
imachooon 0:ac97d71fe296 560 const unsigned char* ptr = &font->table[char_offset];
imachooon 0:ac97d71fe296 561
imachooon 0:ac97d71fe296 562 for (j = 0; j < font->Height; j++) {
imachooon 0:ac97d71fe296 563 for (i = 0; i < font->Width; i++) {
imachooon 0:ac97d71fe296 564 if (*ptr & (0x80 >> (i % 8))) {
imachooon 0:ac97d71fe296 565 SetPixel(frame_buffer, x + i, y + j, colored);
imachooon 0:ac97d71fe296 566 }
imachooon 0:ac97d71fe296 567 if (i % 8 == 7) {
imachooon 0:ac97d71fe296 568 ptr++;
imachooon 0:ac97d71fe296 569 }
imachooon 0:ac97d71fe296 570 }
imachooon 0:ac97d71fe296 571 if (font->Width % 8 != 0) {
imachooon 0:ac97d71fe296 572 ptr++;
imachooon 0:ac97d71fe296 573 }
imachooon 0:ac97d71fe296 574 }
imachooon 0:ac97d71fe296 575 }
imachooon 0:ac97d71fe296 576
imachooon 0:ac97d71fe296 577 /**
imachooon 0:ac97d71fe296 578 * @brief: this displays a string on the frame buffer but not refresh
imachooon 0:ac97d71fe296 579 */
imachooon 0:ac97d71fe296 580 void Epd::DrawStringAt(unsigned char *frame_buffer, int x, int y, const char* text, sFONT* font, int colored) {
imachooon 0:ac97d71fe296 581 const char* p_text = text;
imachooon 0:ac97d71fe296 582 unsigned int counter = 0;
imachooon 0:ac97d71fe296 583 int refcolumn = x;
imachooon 0:ac97d71fe296 584
imachooon 0:ac97d71fe296 585 /* Send the string character by character on EPD */
imachooon 0:ac97d71fe296 586 while (*p_text != 0) {
imachooon 0:ac97d71fe296 587 /* Display one character on EPD */
imachooon 0:ac97d71fe296 588 DrawCharAt(frame_buffer, refcolumn, y, *p_text, font, colored);
imachooon 0:ac97d71fe296 589 /* Decrement the column position by 16 */
imachooon 0:ac97d71fe296 590 refcolumn += font->Width;
imachooon 0:ac97d71fe296 591 /* Point on the next character */
imachooon 0:ac97d71fe296 592 p_text++;
imachooon 0:ac97d71fe296 593 counter++;
imachooon 0:ac97d71fe296 594 }
imachooon 0:ac97d71fe296 595 }