WaveShare e-paper module (epd1in54). Monochrome version

e-Paper Module

Description

Waveshare 1.54 e-paper module imported from offiicial code https://www.waveshare.com/wiki/1.54inch_e-Paper_Module Codes are referenced from official Arduino code and Raspberry pi code.

SPI is used for communication between ePaper module and mbed.

Following shapes can be used:

  • primitive shape (square, circle, line)
  • font (variable sizes)

Pull request are appreciated (Note that the original code is copyrighted by (C) Waveshare )

Example Output

Display output with example code will be like following image:

/media/uploads/imachooon/img_20180216_223238.jpg

Example Code

include the mbed library with this snippet

#include "mbed.h"
#include "epd1in54.h"
#include "m41t62_rtc.h"
// Control
PinName rst;
PinName dc;
PinName busy;
// SPI communication
PinName mosi;
PinName miso;
PinName sclk;
PinName cs;

DigitalOut myled(LED1);

unsigned char frame_black[EPD_HEIGHT*EPD_WIDTH/8];


int main() {
    mosi = p5;
    miso = p6;
    sclk = p7;
    cs = p8;
    rst = p9;
    dc = p10;
    busy = p11;
    
    memset(frame_black, 0xFF, sizeof(unsigned char)*EPD_HEIGHT*EPD_WIDTH/8);

    Epd epd = Epd(mosi, miso, sclk, cs, dc, rst, busy);
    if (epd.Init(lut_full_update) != 0){
        return -1;
    }

    /* Draw something to the frame buffer */
    // For simplicity, the arguments are explicit numerical coordinates
    epd.DrawRectangle(frame_black, 10, 60, 50, 110, COLORED);
    epd.DrawLine(frame_black, 10, 60, 50, 110, COLORED);
    epd.DrawLine(frame_black, 50, 60, 10, 110, COLORED);
    epd.DrawCircle(frame_black, 120, 80, 30, COLORED);
    epd.DrawFilledRectangle(frame_black, 10, 130, 50, 180, COLORED);
    epd.DrawFilledRectangle(frame_black, 0, 6, 200, 26, COLORED);
    epd.DrawFilledCircle(frame_black, 120, 150, 30, COLORED);

    /*Write strings to the buffer */
    epd.DrawStringAt(frame_black, 30, 30, "e-Paper Demo", &Font16, COLORED);
    epd.DrawStringAt(frame_black, 28, 10, "Hello world!", &Font16, UNCOLORED);


    
    /* Display the frame_buffer */
    epd.SetFrameMemory(frame_black, 0, 0, epd.width, epd.height);
    epd.DisplayFrame();
    epd.Sleep();

    
    while(1) {
        myled = 1;
        wait(0.5);
        myled = 0;
        wait(0.5);
    }
}

Committer:
imachooon
Date:
Fri Feb 16 21:30:08 2018 +0000
Revision:
0:ac97d71fe296
initial commit

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 */
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 }