From 14a3924fb29bbf2e5517636699f8726ec7013b81 Mon Sep 17 00:00:00 2001 From: Tyler Gibson Date: Fri, 18 Sep 2015 20:28:55 -0700 Subject: [PATCH] eboled: Sparkfun OLED Block Improvements Signed-off-by: Tyler Gibson Signed-off-by: Mihai Tudor Panu --- examples/javascript/eboled.js | 137 +++++++-- src/lcd/eboled.cxx | 508 +++++++++++++++++++++++++++++----- src/lcd/eboled.h | 233 +++++++++++++++- src/lcd/license.txt | 24 ++ 4 files changed, 799 insertions(+), 103 deletions(-) create mode 100644 src/lcd/license.txt diff --git a/examples/javascript/eboled.js b/examples/javascript/eboled.js index 598507e1..bf999deb 100644 --- a/examples/javascript/eboled.js +++ b/examples/javascript/eboled.js @@ -5,6 +5,9 @@ * Author: Jon Trulson * Copyright (c) 2015 Intel Corporation. * + * Author: Tyler Gibson + * Copyright (c) 2015 Microsoft Corporation. + * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -25,27 +28,123 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +var lcdObj = require('jsupm_i2clcd'); +var oled = new lcdObj.EBOLED(); + +var sample = 0; +var samples = 13; + function exit() { - lcd = null; - lcdObj.cleanUp(); - lcdObj = null; - process.exit(0); + oled = null; + lcdObj.cleanUp(); + lcdObj = null; + process.exit(0); } -// Load i2clcd module -var lcdObj = require('jsupm_i2clcd'); - -var lcd = new lcdObj.EBOLED(); - -lcd.clear(); -lcd.setCursor(2, 0); -lcd.write("Hello"); -lcd.setCursor(3, 5); -lcd.write("World!"); - -console.log("Sleeping for 5 seconds..."); -setTimeout(exit, 5000); - - +setInterval( function() +{ + if(sample>samples) + { + exit(); + } + oled.clearScreenBuffer(); + runSample(sample++); + oled.refresh(); +}, 1500); +function runSample(sample) +{ + switch(sample) { + case 0: + // x/y coords are 0 based, using 1 here for padding. + oled.setCursor(1,1); + // nowrap = 0, wrapping = 1 + oled.setTextWrap(1); + oled.write("HELLO WORLD! Mixed with #123 and y's, g's and q's."); + break; + case 1: + oled.setCursor(12, 1); + //multiply text size, only integers + oled.setTextSize(3); + oled.write("BOO!"); + oled.setTextSize(1); + break; + case 2: + oled.drawRectangleFilled(0,0,48,9); + oled.setCursor(1,1); + // 0=Black, 1=White, 2=Xor (Toggle) + oled.setTextColor(2); + oled.write("Cutout"); + break; + case 3: + var total = Math.random()*100; + for(var stars=0; stars * Copyright (c) 2015 Intel Corporation. * + * Author: Tyler Gibson + * Copyright (c) 2015 Microsoft Corporation. + * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -29,15 +32,23 @@ using namespace upm; using namespace std; -EBOLED::EBOLED(int spi, int CD, int reset) : +static uint16_t screenBuffer[BUFFER_SIZE]; + +EBOLED::EBOLED(int spi, int CD, int reset) : m_spi(spi), m_gpioCD(CD), m_gpioRST(reset) { m_name = "EBOLED"; - + m_textColor = COLOR_WHITE; + m_textWrap = 0; + m_textSize = 1; + m_cursorX = 0; + m_cursorY = 0; + m_gpioCD.dir(mraa::DIR_OUT); m_gpioRST.dir(mraa::DIR_OUT); - m_spi.frequency(1000000); + //1000000 is standard. + m_spi.frequency(10000000); // reset the device m_gpioRST.write(1); @@ -53,40 +64,48 @@ EBOLED::EBOLED(int spi, int CD, int reset) : command(CMD_SETMULTIPLEX); command(0x2f); - + command(CMD_SETDISPLAYOFFSET); command(0x0); // no offset - + command(CMD_SETSTARTLINE | 0x0); // line #0 - + command(CMD_CHARGEPUMP); // enable charge pump command(0x14); - + command(CMD_NORMALDISPLAY); command(CMD_DISPLAYALLONRESUME); - + command(CMD_SEGREMAP | 0x1); // reverse mapping (SEG0==COL127) command(CMD_COMSCANDEC); - + command(CMD_SETCOMPINS); // custom COM PIN mapping command(0x12); - + command(CMD_SETCONTRAST); command(0x8f); - + command(CMD_SETPRECHARGE); command(0xf1); - + command(CMD_SETVCOMDESELECT); command(0x40); - + command(CMD_DISPLAYON); - usleep(4500); - - clear(); - setAddressingMode(PAGE); + + setAddressingMode(HORIZONTAL); + + //Set Page Address range, required for horizontal addressing mode. + command(CMD_SETPAGEADDRESS); // triple-byte cmd + command(0x00); //Initial page address + command(0x05); //Final page address + + //Set Column Address range, required for horizontal addressing mode. + command(CMD_SETCOLUMNADDRESS); // triple-byte cmd + command(0x20); // this display has a horizontal offset of 20 columns + command(0x5f); // 64 columns wide - 0 based 63 offset } EBOLED::~EBOLED() @@ -94,68 +113,117 @@ EBOLED::~EBOLED() clear(); } -mraa::Result EBOLED::draw(uint8_t* bdata, int bytes) +mraa::Result EBOLED::refresh() { - mraa::Result error = mraa::SUCCESS; + mraa::Result error = mraa::SUCCESS;; - setAddressingMode(HORIZONTAL); - - command(CMD_SETCOLUMNADDRESS); // triple-byte cmd - command(0x20); // this display has a horizontal offset of 20 columns - command(0x20 + 0x40); // 64 columns wide - - for (int idx = 0; idx < bytes; idx++) - error = data(bdata[idx]); - - // reset addressing mode - setAddressingMode(PAGE); + m_gpioCD.write(1); // data mode + for(int i=0; i OLED_WIDTH - temp_cursorX - 6)) + { + m_cursorY += m_textSize * 9; + temp_cursorX = m_cursorX; + } + } + } + return mraa::SUCCESS;; } -mraa::Result EBOLED::setCursor(int row, int column) -{ - mraa::Result error = mraa::SUCCESS; +mraa::Result EBOLED::setCursor (int row, int column) { + m_cursorX = column; + m_cursorY = row; + return mraa::SUCCESS;; +} - // set page address - error = command(CMD_SETPAGESTARTADDR | (row & 0x07)); +void EBOLED::setTextColor (uint8_t textColor) { + m_textColor = textColor; +} - // set column address - error = command(CMD_SETLOWCOLUMN | (column & 0x0f)); - // ediblock oled starts at col 20 apparently... - error = command(CMD_SETHIGHCOLUMN | ((column >> 4) & 0x0f) + 0x02); +void EBOLED::setTextSize (uint8_t size) { + m_textSize = (size > 0) ? size : 1; +} - return error; +void EBOLED::setTextWrap (uint8_t wrap) { + m_textWrap = wrap; +} + +void EBOLED::drawChar (uint8_t x, uint8_t y, uint8_t data, uint8_t color, uint8_t size) { + if( (x >= OLED_WIDTH) || // Clip right + (y >= OLED_HEIGHT) || // Clip bottom + ((x + 6 * size - 1) < 0) || // Clip left + ((y + 8 * size - 1) < 0)) // Clip top + return; + + if (data < 0x20 || data > 0x7F) { + data = 0x20; // space + } + + for (int8_t i=0; i<6; i++ ) { + uint8_t line; + if (i == 6) + line = 0x0; + else + { + //32 offset to align standard ASCII range to index + line = BasicFont[data - 32][i+1]; + for (int8_t j = 0; j<8; j++) + { + if (line & 0x1) + { + if (size == 1) // default size + drawPixel(x+i, y+j, color); + else + drawRectangleFilled(x+(i*size), y+(j*size), size, size, color); // big size + } + line >>= 1; + } + } + } } mraa::Result EBOLED::clear() { - mraa::Result error = mraa::SUCCESS; - uint8_t columnIdx, rowIdx; - - for (rowIdx = 0; rowIdx < 8; rowIdx++) - { - setCursor(rowIdx, 0); - - // clear all columns (8 * 8 pixels per char) - for (columnIdx = 0; columnIdx < 8; columnIdx++) - error = writeChar(' '); - } - - home(); - - return mraa::SUCCESS; + mraa::Result error = mraa::SUCCESS;; + + m_gpioCD.write(1); // data mode + for(int i=0; i=OLED_WIDTH || y<0 || y>=OLED_HEIGHT) + return; - if (value < 0x20 || value > 0x7F) { - value = 0x20; // space + /* Screenbuffer is uint16 array, but pages are 8bit high so each buffer + * index is two columns. This means the index is based on x/2 and + * OLED_WIDTH/2 = VERT_COLUMNS. + * + * Then to set the appropriate bit, we need to shift based on the y + * offset in relation to the page and then adjust for high/low based + * on the x position. + */ + + switch(color) + { + case COLOR_XOR: + screenBuffer[(x/2) + ((y/8) * VERT_COLUMNS)] ^= (1<<(y%8+(x%2 * 8))); + return; + case COLOR_WHITE: + screenBuffer[(x/2) + ((y/8) * VERT_COLUMNS)] |= (1<<(y%8+(x%2 * 8))); + return; + case COLOR_BLACK: + screenBuffer[(x/2) + ((y/8) * VERT_COLUMNS)] &= ~(1<<(y%8+(x%2 * 8))); + return; + } +} + +void EBOLED::drawLine(int8_t x0, int8_t y0, int8_t x1, int8_t y1, uint8_t color) +{ + int16_t steep = abs(y1 - y0) > abs(x1 - x0); + + if (steep) { + swap(x0, y0); + swap(x1, y1); } - for (uint8_t idx = 0; idx < 8; idx++) { - rv = data(BasicFont[value - 32][idx]); + if (x0 > x1) { + swap(x0, x1); + swap(y0, y1); } - return rv; + int16_t dx, dy; + dx = x1 - x0; + dy = abs (y1 - y0); + + int16_t err = dx / 2; + int16_t ystep; + + if (y0 < y1) { + ystep = 1; + } else { + ystep = -1; + } + + for (; x0 <= x1; x0++) { + if (steep) { + drawPixel(y0, x0, color); + } else { + drawPixel(x0, y0, color); + } + err -= dy; + if (err < 0) { + y0 += ystep; + err += dx; + } + } +} + +void EBOLED::drawLineHorizontal(int8_t x, int8_t y, uint8_t width, uint8_t color) +{ + drawLine(x, y, x+width-1, y, color); +} + +void EBOLED::drawLineVertical(int8_t x, int8_t y, uint8_t height, uint8_t color) +{ + drawLine(x, y, x, y+height-1, color); +} + +void EBOLED::drawRectangle(int8_t x, int8_t y, uint8_t width, uint8_t height, uint8_t color) +{ + drawLineHorizontal(x, y, width, color); + drawLineHorizontal(x, y+height-1, color); + + uint8_t innerHeight = height - 2; + if(innerHeight > 0) + { + drawLineVertical(x, y+1, innerHeight, color); + drawLineVertical(x+width-1, y+1, innerHeight, color); + } +} + +void EBOLED::drawRoundedRectangle(int8_t x, int8_t y, int8_t width, int8_t height, int16_t radius, uint8_t color) { + // smarter version + drawLineHorizontal(x+radius , y , width-2*radius, color); // Top + drawLineHorizontal(x+radius , y+height-1, width-2*radius, color); // Bottom + drawLineVertical( x , y+radius , height-2*radius, color); // Left + drawLineVertical( x+width-1 , y+radius , height-2*radius, color); // Right + // draw four corners + drawRoundCorners(x+radius , y+radius , radius, 1, color); + drawRoundCorners(x+width-radius-1, y+radius , radius, 2, color); + drawRoundCorners(x+width-radius-1, y+height-radius-1, radius, 4, color); + drawRoundCorners(x+radius , y+height-radius-1, radius, 8, color); +} + +void EBOLED::drawRectangleFilled(int8_t x, int8_t y, uint8_t width, uint8_t height, uint8_t color) +{ + for (uint8_t i=x; i= y1 >= y0) + if (y0 > y1) { + swap(y0, y1); swap(x0, x1); + } + if (y1 > y2) { + swap(y2, y1); swap(x2, x1); + } + if (y0 > y1) { + swap(y0, y1); swap(x0, x1); + } + + if(y0 == y2) { // Handle awkward all-on-same-line case as its own thing + a = b = x0; + if(x1 < a) a = x1; + else if(x1 > b) b = x1; + if(x2 < a) a = x2; + else if(x2 > b) b = x2; + drawLineHorizontal(a, y0, b-a+1, color); + return; + } + + int16_t + dx01 = x1 - x0, + dy01 = y1 - y0, + dx02 = x2 - x0, + dy02 = y2 - y0, + dx12 = x2 - x1, + dy12 = y2 - y1; + int32_t + sa = 0, + sb = 0; + + // For upper part of triangle, find scanline crossings for segments + // 0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1 + // is included here (and second loop will be skipped, avoiding a /0 + // error there), otherwise scanline y1 is skipped here and handled + // in the second loop...which also avoids a /0 error here if y0=y1 + // (flat-topped triangle). + if(y1 == y2) last = y1; // Include y1 scanline + else last = y1-1; // Skip it + + for(y=y0; y<=last; y++) { + a = x0 + sa / dy01; + b = x0 + sb / dy02; + sa += dx01; + sb += dx02; + /* longhand: + a = x0 + (x1 - x0) * (y - y0) / (y1 - y0); + b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); + */ + if(a > b) swap(a,b); + drawLineHorizontal(a, y, b-a+1, color); + } + + // For lower part of triangle, find scanline crossings for segments + // 0-2 and 1-2. This loop is skipped if y1=y2. + sa = dx12 * (y - y1); + sb = dx02 * (y - y0); + for(; y<=y2; y++) { + a = x1 + sa / dy12; + b = x0 + sb / dy02; + sa += dx12; + sb += dx02; + /* longhand: + a = x1 + (x2 - x1) * (y - y1) / (y2 - y1); + b = x0 + (x2 - x0) * (y - y0) / (y2 - y0); + */ + if(a > b) swap(a,b); + drawLineHorizontal(a, y, b-a+1, color); + } +} + +void EBOLED::drawCircle(int16_t x0, int16_t y0, int16_t radius, uint8_t color) +{ + int16_t f = 1 - radius; + int16_t ddF_x = 1; + int16_t ddF_y = -2 * radius; + int16_t x = 0; + int16_t y = radius; + + drawPixel(x0 , y0+radius, color); + drawPixel(x0 , y0-radius, color); + drawPixel(x0+radius, y0 , color); + drawPixel(x0-radius, y0 , color); + + while (x= 0) + { + y--; + ddF_y += 2; + f += ddF_y; + } + x++; + + ddF_x += 2; + f += ddF_x; + + drawPixel(x0 + x, y0 + y, color); + drawPixel(x0 - x, y0 + y, color); + drawPixel(x0 + x, y0 - y, color); + drawPixel(x0 - x, y0 - y, color); + drawPixel(x0 + y, y0 + x, color); + drawPixel(x0 - y, y0 + x, color); + drawPixel(x0 + y, y0 - x, color); + drawPixel(x0 - y, y0 - x, color); + } +} + +void EBOLED::drawRoundCorners( int8_t x0, int8_t y0, int16_t radius, uint8_t cornername, uint8_t color) { + int16_t f = 1 - radius; + int16_t ddF_x = 1; + int16_t ddF_y = -2 * radius; + int16_t x = 0; + int16_t y = radius; + + while (x= 0) { + y--; + ddF_y += 2; + f += ddF_y; + } + x++; + ddF_x += 2; + f += ddF_x; + if (cornername & 0x4) { + drawPixel(x0 + x, y0 + y, color); + drawPixel(x0 + y, y0 + x, color); + } + if (cornername & 0x2) { + drawPixel(x0 + x, y0 - y, color); + drawPixel(x0 + y, y0 - x, color); + } + if (cornername & 0x8) { + drawPixel(x0 - y, y0 + x, color); + drawPixel(x0 - x, y0 + y, color); + } + if (cornername & 0x1) { + drawPixel(x0 - y, y0 - x, color); + drawPixel(x0 - x, y0 - y, color); + } + } +} + +void EBOLED::drawCircleFilled(int8_t x0, int8_t y0, int16_t radius, uint8_t color) { + drawLineVertical(x0, y0-radius, 2*radius+1, color); + drawRoundedCornersFilled(x0, y0, radius, 3, 0, color); +} + +void EBOLED::drawRoundedCornersFilled(int8_t x0, int8_t y0, int16_t radius, uint8_t cornername, int16_t delta, uint8_t color) { + + int16_t f = 1 - radius; + int16_t ddF_x = 1; + int16_t ddF_y = -2 * radius; + int16_t x = 0; + int16_t y = radius; + + while (x= 0) { + y--; + ddF_y += 2; + f += ddF_y; + } + x++; + ddF_x += 2; + f += ddF_x; + + if (cornername & 0x1) { + drawLineVertical(x0+x, y0-y, 2*y+1+delta, color); + drawLineVertical(x0+y, y0-x, 2*x+1+delta, color); + } + if (cornername & 0x2) { + drawLineVertical(x0-x, y0-y, 2*y+1+delta, color); + drawLineVertical(x0-y, y0-x, 2*x+1+delta, color); + } + } +} + +void EBOLED::fillScreen(uint8_t color) +{ + drawRectangleFilled(0, 0, OLED_WIDTH-1, OLED_HEIGHT-1, color); } mraa::Result EBOLED::setAddressingMode(displayAddressingMode mode) @@ -195,9 +554,14 @@ mraa::Result EBOLED::command(uint8_t cmd) return mraa::SUCCESS; } -mraa::Result EBOLED::data(uint8_t data) +mraa::Result EBOLED::data(uint16_t data) { - m_gpioCD.write(1); // data mode - m_spi.writeByte(data); + m_spi.write_word(data); return mraa::SUCCESS; } + +void EBOLED::clearScreenBuffer() +{ + for(int i=0; i * Copyright (c) 2015 Intel Corporation. * + * Author: Tyler Gibson + * Copyright (c) 2015 Microsoft Corporation. + * + * Credits to Adafruit. + * Based on Adafruit ST7735 library, see original license in license.txt file. + * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -35,6 +41,8 @@ #define EBOLED_DEFAULT_CD 36 #define EBOLED_DEFAULT_RESET 48 +#define swap(a, b) { uint8_t t = a; a = b; b = t; } + namespace upm { /** @@ -60,6 +68,15 @@ namespace upm * * @snippet eboled.cxx Interesting */ + + const uint8_t COLOR_WHITE = 0x01; + const uint8_t COLOR_BLACK = 0x00; + const uint8_t COLOR_XOR = 0x02; + const uint8_t OLED_WIDTH = 0x40; // 64 pixels + const uint8_t VERT_COLUMNS = 0x20; // half width for hi/lo 16bit writes. + const uint8_t OLED_HEIGHT = 0x30; // 48 pixels + const int BUFFER_SIZE = 192; + class EBOLED : public LCD { // SSD commands @@ -73,7 +90,7 @@ namespace upm CMD_SETPAGEADDRESS = 0x22, CMD_SETSTARTLINE = 0x40, // 0x40 - 0x7f CMD_SETCONTRAST = 0x81, - CMD_CHARGEPUMP = 0x8d, + CMD_CHARGEPUMP = 0x8d, CMD_SEGREMAP = 0xa0, CMD_DISPLAYALLONRESUME = 0xa4, CMD_DISPLAYALLON = 0xa5, @@ -102,28 +119,28 @@ namespace upm * @param reset reset pin * @param address the slave address the lcd is registered on */ - EBOLED(int spi=EBOLED_DEFAULT_SPI_BUS, int CD=EBOLED_DEFAULT_CD, + EBOLED(int spi=EBOLED_DEFAULT_SPI_BUS, int CD=EBOLED_DEFAULT_CD, int reset=EBOLED_DEFAULT_RESET); - + /** * EBOLED Destructor */ ~EBOLED(); /** - * Draw an image, see examples/python/make_oled_pic.py for an - * explanation on how the pixels are mapped to bytes + * Draw the buffer to screen, see examples/python/make_oled_pic.py for an + * explanation on how the pixels are mapped to bytes. * * @param data the buffer to write * @param bytes the number of bytes to write * @return result of operation */ - mraa::Result draw(uint8_t* data, int bytes); + mraa::Result refresh(); /** * Write a string to LCD * - * @param msg the std::string to write to display, note only ascii + * @param msg the std::string to write to display, note only ascii * chars are supported * @return result of operation */ @@ -132,12 +149,45 @@ namespace upm /** * Set cursor to a coordinate * - * @param row the row to set cursor to. This device supports 6 rows. - * @param column the column to set cursor to. This device support - * 64 columns + * @param y Axis on the vertical scale. This device supports 6 rows. + * @param x Axis on the horizontal scale This device supports 64 columns + * * @return result of operation */ - mraa::Result setCursor(int row, int column); + mraa::Result setCursor (int row, int column); + + /** + * Sets a text color for a message + * + * @param textColor Font color: COLOR_WHITE, COLOR_BLACK or COLOR_XOR + */ + void setTextColor (uint8_t textColor); + + /** + * Sets the size of the font + * + * @param size Font size + */ + void setTextSize (uint8_t size); + + /** + * Wraps a printed message + * + * @param wrap True (1) or false (0) + */ + void setTextWrap (uint8_t wrap); + + /** + * Write a single character to the screen. + * + * @param x Axis on the horizontal scale + * @param y Axis on the vertical scale + * @param data Character to write + * @param color Character color + * @param bg Character background color + * @param size Size of the font + */ + void drawChar (uint8_t x, uint8_t y, uint8_t data, uint8_t color, uint8_t size); /** * Clear display @@ -146,6 +196,8 @@ namespace upm */ mraa::Result clear(); + void clearScreenBuffer(); + /** * Return to coordinate 0,0 * @@ -153,9 +205,160 @@ namespace upm */ mraa::Result home(); + /** + * Write a single pixel to the screen buffer. + * Can do an specific color write or toggle (xor) a pixel. + * + * @param x the x position of the pixel + * @param y the y position of the pixel + * @param color pixel is COLOR_WHITE, COLOR_BLACK or COLOR_XOR + */ + void drawPixel (int8_t x, int8_t y, uint8_t color=COLOR_WHITE); + + /** + * Draw a line to the screen buffer. + * + * @param x0 the x position of the beginning of the line + * @param y0 the y position of the beginning of the line + * @param x1 the x position of the end of the line + * @param y1 the y position of the end of the line + * @param color line is COLOR_WHITE, COLOR_BLACK or COLOR_XOR + */ + void drawLine (int8_t x0, int8_t y0, int8_t x1, int8_t y1, uint8_t color = COLOR_WHITE); + + /** + * Draw a horizontal line to the screen buffer. + * + * @param x the x position of the beginning of the line + * @param y the y position of the beginning of the line + * @param width is the horizontal length of the line + * @param color line is COLOR_WHITE, COLOR_BLACK or COLOR_XOR + */ + void drawLineHorizontal (int8_t x, int8_t y, uint8_t width, uint8_t color = COLOR_WHITE); + + /** + * Draw a vertical line to the screen buffer. + * + * @param x the x position of the beginning of the line + * @param y the y position of the beginning of the line + * @param width is the vertical length of the line + * @param color line is COLOR_WHITE, COLOR_BLACK or COLOR_XOR + */ + void drawLineVertical (int8_t x, int8_t y, uint8_t height, uint8_t color = COLOR_WHITE); + + /** + * Draw a rectangle to the screen buffer. + * + * @param x the left edge + * @param y the top edge + * @param width sets the right edge + * @param height bottom edge + * @param color outline is COLOR_WHITE, COLOR_BLACK or COLOR_XOR + */ + void drawRectangle (int8_t x, int8_t y, uint8_t width, uint8_t height, uint8_t color = COLOR_WHITE); + + /** + * Draw a rectangle with rounded corners to the screen buffer. + * + * @param x the left edge + * @param y the top edge + * @param width sets the right edge + * @param height bottom edge + * @param radius of the rounded corners + * @param color outline is COLOR_WHITE, COLOR_BLACK or COLOR_XOR + */ + void drawRoundedRectangle(int8_t x, int8_t y, int8_t width, int8_t height, int16_t radius, uint8_t color); + + /** + * Draw a filled rectangle to the screen buffer. + * + * @param x the left edge + * @param y the top edge + * @param width sets the right edge + * @param height bottom edge + * @param color fill color is COLOR_WHITE, COLOR_BLACK or COLOR_XOR + */ + void drawRectangleFilled (int8_t x, int8_t y, uint8_t width, uint8_t height, uint8_t color = COLOR_WHITE); + + /** + * Draw a triangle to the screen buffer. + * + * @param x0 the x coordinate of the first corner + * @param y0 the y coordinate of the first corner + * @param x1 the x coordinate of the second corner + * @param y1 the y coordinate of the second corner + * @param x2 the x coordinate of the third corner + * @param y2 the y coordinate of the third corner + * @param color outline is COLOR_WHITE, COLOR_BLACK or COLOR_XOR + */ + void drawTriangle (int8_t x0, int8_t y0, int8_t x1, int8_t y1, int8_t x2, int8_t y2, uint8_t color = COLOR_WHITE); + + /** + * Draw a filled triangle to the screen buffer. + * + * @param x0 the x coordinate of the first corner + * @param y0 the y coordinate of the first corner + * @param x1 the x coordinate of the second corner + * @param y1 the y coordinate of the second corner + * @param x2 the x coordinate of the third corner + * @param y2 the y coordinate of the third corner + * @param color fill color is COLOR_WHITE, COLOR_BLACK or COLOR_XOR + */ + void drawTriangleFilled ( int8_t x0, int8_t y0, int8_t x1, int8_t y1, int8_t x2, int8_t y2, uint8_t color); + + /** + * Draw a circle to the screen buffer. + * + * @param x0 the x coordinate of the circle's center + * @param y0 the y coordinate of the circle's center + * @param radius the radius of the circle + * @param color outline is COLOR_WHITE, COLOR_BLACK or COLOR_XOR + */ + void drawCircle (int16_t x0, int16_t y0, int16_t radius, uint8_t color = COLOR_WHITE); + + /** + * Draw a quarter circle arc to the screen buffer. + * + * @param x0 the x coordinate of the arc's center + * @param y0 the y coordinate of the arc's center + * @param radius the radius of the arc + * @param cornername denotes which of the 4 quarters to draw - 1,2,4,8 + * @param color outline is COLOR_WHITE, COLOR_BLACK or COLOR_XOR + */ + void drawRoundCorners( int8_t x0, int8_t y0, int16_t radius, uint8_t cornername, uint8_t color); + + /** + * Draw a filled circle to the screen buffer. + * + * @param x0 the x coordinate of the circle's center + * @param y0 the y coordinate of the circle's center + * @param radius the radius of the circle + * @param color outline is COLOR_WHITE, COLOR_BLACK or COLOR_XOR + */ + void drawCircleFilled(int8_t x0, int8_t y0, int16_t radius, uint8_t color); + + /** + * Draw a quarter pie to the screen buffer. + * + * @param x0 the x coordinate of the arc's center + * @param y0 the y coordinate of the arc's center + * @param radius the radius of the arc + * @param cornername denotes which of the 4 quarters to draw - 1,2,4,8 + * @param color fill color is COLOR_WHITE, COLOR_BLACK or COLOR_XOR + */ + void drawRoundedCornersFilled(int8_t x0, int8_t y0, int16_t radius, uint8_t cornername, int16_t delta, uint8_t color); + + /** + * Fill the screen buffer with specified color. + * + * @param color fill color is COLOR_WHITE, COLOR_BLACK or COLOR_XOR + */ + void fillScreen (uint8_t color=COLOR_WHITE); + + protected: mraa::Result command(uint8_t cmd); - mraa::Result data(uint8_t data); + mraa::Result data(uint16_t data); mraa::Result writeChar(uint8_t value); mraa::Result setAddressingMode(displayAddressingMode mode); @@ -164,5 +367,11 @@ namespace upm mraa::Gpio m_gpioRST; // reset pin mraa::Spi m_spi; + + uint8_t m_cursorX; + uint8_t m_cursorY; + uint8_t m_textSize; + uint8_t m_textColor; + uint8_t m_textWrap; }; } diff --git a/src/lcd/license.txt b/src/lcd/license.txt new file mode 100644 index 00000000..7492e93a --- /dev/null +++ b/src/lcd/license.txt @@ -0,0 +1,24 @@ +Software License Agreement (BSD License) + +Copyright (c) 2012 Adafruit Industries. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +- Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE.