A simple yet powerful library for controlling graphical displays. Multiple display controllers are supported using inheritance.
Dependents: mbed_rifletool Hexi_Bubble_Game Hexi_Catch-the-dot_Game Hexi_Acceleromagnetic_Synth
NOTE: This library is in beta right now. As far as I know, everything here works, but there are many features that are lacking so far. Most notably containers, button handling, and display drivers other than the SSD1306.
Revision 1:f7003ec66a51, committed 2014-03-14
- Comitter:
- neilt6
- Date:
- Fri Mar 14 19:17:44 2014 +0000
- Parent:
- 0:b876cf091464
- Child:
- 2:bbfc18022ee5
- Commit message:
- Added rudimentary ILI9341 support, and SPI support for SSD1306
Changed in this revision
--- a/Abstracts/Canvas.cpp Fri Aug 30 17:09:18 2013 +0000 +++ b/Abstracts/Canvas.cpp Fri Mar 14 19:17:44 2014 +0000 @@ -276,7 +276,7 @@ fillCircleHelper(x+r, y + r, r, 2, h - 2 * r - 1, c); } -void Canvas::drawImage(Image *img, int x, int y) +void Canvas::drawImage(Image* img, int x, int y) { for (int j = 0; j < img->height(); j++) { for (int i = 0; i < img->width(); i++) { @@ -285,7 +285,7 @@ } } -int Canvas::drawChar(char c, Font *fnt, int x, int y) +int Canvas::drawChar(char c, Font* fnt, int x, int y) { //Get the character glyph BitmapImage glyph = fnt->glyph(c); @@ -297,7 +297,7 @@ return glyph.width(); } -void Canvas::drawString(const char *str, Font *fnt, int x, int y) +void Canvas::drawString(const char* str, Font* fnt, int x, int y) { int cursX = 0; int cursY = 0; @@ -326,7 +326,7 @@ } } -void Canvas::drawString(const char *str, Font *fnt, int x, int y, int w, int h) +void Canvas::drawString(const char* str, Font* fnt, int x, int y, int w, int h) { int cursX = 0; int cursY = 0; @@ -419,12 +419,12 @@ } } -int Canvas::width(void) +int Canvas::width() { return m_Width; } -int Canvas::height(void) +int Canvas::height() { return m_Height; }
--- a/Abstracts/Canvas.h Fri Aug 30 17:09:18 2013 +0000 +++ b/Abstracts/Canvas.h Fri Mar 14 19:17:44 2014 +0000 @@ -166,7 +166,7 @@ * @param x The starting X coordinate. * @param y The starting Y coordinate. */ - void drawImage(Image *img, int x, int y); + void drawImage(Image* img, int x, int y); /** Draw a character at the specified coordinates without wrapping * @@ -177,7 +177,7 @@ * * @returns The width of the drawn character. */ - int drawChar(char c, Font *fnt, int x, int y); + int drawChar(char c, Font* fnt, int x, int y); /** Draw a string at the specified coordinates without wrapping * @@ -186,7 +186,7 @@ * @param x The starting X coordinate. * @param y The starting Y coordinate. */ - void drawString(const char *str, Font *fnt, int x, int y); + void drawString(const char* str, Font* fnt, int x, int y); /** Draw a string within the specified rectangle with wrapping * @@ -197,19 +197,19 @@ * @param w The width of the bounding rectangle. * @param h The height of the bounding rectangle. */ - void drawString(const char *str, Font *fnt, int x, int y, int w, int h); + void drawString(const char* str, Font* fnt, int x, int y, int w, int h); /** Get the width of the canvas * * @returns The width of the canvas. */ - int width(void); + int width(); /** Get the height of the canvas * * @returns The height of the canvas. */ - int height(void); + int height(); protected: //The canvas width/height
--- a/Abstracts/Control.cpp Fri Aug 30 17:09:18 2013 +0000 +++ b/Abstracts/Control.cpp Fri Mar 14 19:17:44 2014 +0000 @@ -32,7 +32,7 @@ m_Invalid = true; } -void Control::paint(Canvas *canvas) +void Control::paint(Canvas* canvas) { //Fill the control's content and padding area canvas->fillRect(contentPosX() - m_Padding, contentPosY() - m_Padding , contentWidth() + m_Padding * 2, contentHeight() + m_Padding * 2, m_BgColor); @@ -49,7 +49,7 @@ m_Invalid = false; } -int Control::posX(void) +int Control::posX() { return m_X; } @@ -63,7 +63,7 @@ m_Invalid = true; } -int Control::posY(void) +int Control::posY() { return m_Y; } @@ -77,7 +77,7 @@ m_Invalid = true; } -int Control::width(void) +int Control::width() { return m_Width; } @@ -91,7 +91,7 @@ m_Invalid = true; } -int Control::height(void) +int Control::height() { return m_Height; } @@ -105,7 +105,7 @@ m_Invalid = true; } -int Control::margin(void) +int Control::margin() { return m_Margin; } @@ -119,7 +119,7 @@ m_Invalid = true; } -int Control::border(void) +int Control::border() { return m_Border; } @@ -133,7 +133,7 @@ m_Invalid = true; } -int Control::padding(void) +int Control::padding() { return m_Padding; } @@ -147,27 +147,27 @@ m_Invalid = true; } -int Control::contentPosX(void) +int Control::contentPosX() { return m_X + m_Margin + m_Border + m_Padding; } -int Control::contentPosY(void) +int Control::contentPosY() { return m_Y + m_Margin + m_Border + m_Padding; } -int Control::contentWidth(void) +int Control::contentWidth() { return m_Width - (m_Margin + m_Border + m_Padding) * 2; } -int Control::contentHeight(void) +int Control::contentHeight() { return m_Height - (m_Margin + m_Border + m_Padding) * 2; } -unsigned int Control::foreColor(void) +unsigned int Control::foreColor() { return m_FgColor; } @@ -181,7 +181,7 @@ m_Invalid = true; } -unsigned int Control::backColor(void) +unsigned int Control::backColor() { return m_BgColor; } @@ -195,12 +195,12 @@ m_Invalid = true; } -const char *Control::text(void) +const char* Control::text() { return m_Text; } -void Control::text(const char *text) +void Control::text(const char* text) { //Update the value m_Text = text; @@ -209,12 +209,12 @@ m_Invalid = true; } -Font *Control::font(void) +Font* Control::font() { return m_Font; } -void Control::font(Font *fnt) +void Control::font(Font* fnt) { //Update the value m_Font = fnt; @@ -223,12 +223,12 @@ m_Invalid = true; } -bool Control::invalid(void) +bool Control::invalid() { return m_Invalid; } -void Control::invalidate(void) +void Control::invalidate() { m_Invalid = true; }
--- a/Abstracts/Control.h Fri Aug 30 17:09:18 2013 +0000 +++ b/Abstracts/Control.h Fri Mar 14 19:17:44 2014 +0000 @@ -45,7 +45,7 @@ * * @returns The X coordinate of the control. */ - int posX(void); + int posX(); /** Set the X coordinate of the control * @@ -57,7 +57,7 @@ * * @returns The Y coordinate of the control. */ - int posY(void); + int posY(); /** Set the Y coordinate of the control * @@ -69,7 +69,7 @@ * * @returns The width of the control. */ - int width(void); + int width(); /** Set the width of the control * @@ -81,7 +81,7 @@ * * @returns The height of the control. */ - int height(void); + int height(); /** Set the height of the control * @@ -93,7 +93,7 @@ * * @returns The current margin width. */ - int margin(void); + int margin(); /** Set the margin width * @@ -105,7 +105,7 @@ * * @returns The current border width. */ - int border(void); + int border(); /** Set the border width * @@ -117,7 +117,7 @@ * * @returns The current padding width. */ - int padding(void); + int padding(); /** Set the padding width * @@ -129,31 +129,31 @@ * * @returns The X coordinate of the control's content area. */ - int contentPosX(void); + int contentPosX(); /** Get the Y coordinate of the control's content area * * @returns The Y coordinate of the control's content area. */ - int contentPosY(void); + int contentPosY(); /** Get the width of the control's content area * * @returns The width of the control's content area. */ - int contentWidth(void); + int contentWidth(); /** Get the height of the control's content area * * @returns The height of the control's content area. */ - int contentHeight(void); + int contentHeight(); /** Get the foreground color * * @returns The foreground color as a 32-bit ARGB value. */ - unsigned int foreColor(void); + unsigned int foreColor(); /** Set the foreground color * @@ -165,7 +165,7 @@ * * @returns The background color as a 32-bit ARGB value. */ - unsigned int backColor(void); + unsigned int backColor(); /** Set the background color * @@ -177,41 +177,41 @@ * * @returns The current text of the control. */ - const char *text(void); + const char* text(); /** Set the text of the control * * @param text The new text. */ - void text(const char *text); + void text(const char* text); /** Get the current font of the control * * @returns The current font of the control. */ - Font *font(void); + Font* font(); /** Set the font of the control * * @param fnt The new font. */ - void font(Font *fnt); + void font(Font* fnt); /** Determine whether the control needs to be repainted * * @returns Whether or not the control needs to be repainted. */ - bool invalid(void); + bool invalid(); /** Mark this control as invalid */ - void invalidate(void); + void invalidate(); protected: int m_X, m_Y, m_Width, m_Height, m_Margin, m_Border, m_Padding; unsigned int m_FgColor, m_BgColor; - const char *m_Text; - Font *m_Font; + const char* m_Text; + Font* m_Font; bool m_Invalid; };
--- a/Abstracts/Display.cpp Fri Aug 30 17:09:18 2013 +0000 +++ b/Abstracts/Display.cpp Fri Mar 14 19:17:44 2014 +0000 @@ -21,12 +21,12 @@ m_State = NOT_INITIALIZED; } -void Display::finalize(void) +void Display::finalize() { //Do nothing by default, the super class should override this if needed } -Display::State Display::state(void) +Display::State Display::state() { //Return the display's state return m_State;
--- a/Abstracts/Display.h Fri Aug 30 17:09:18 2013 +0000 +++ b/Abstracts/Display.h Fri Mar 14 19:17:44 2014 +0000 @@ -47,17 +47,17 @@ * 'true' if the device exists on the bus, * 'false' if the device doesn't exist on the bus. */ - virtual bool open(void) = 0; + virtual bool open() = 0; /** Finalize any writes to the Display */ - virtual void finalize(void); + virtual void finalize(); /** Get the current state of the Display * * @returns The current state as a State enum. */ - virtual Display::State state(void); + virtual Display::State state(); /** Set the state of the Display *
--- a/Abstracts/Image.cpp Fri Aug 30 17:09:18 2013 +0000 +++ b/Abstracts/Image.cpp Fri Mar 14 19:17:44 2014 +0000 @@ -22,12 +22,12 @@ m_Height = h; } -int Image::width(void) +int Image::width() { return m_Width; } -int Image::height(void) +int Image::height() { return m_Height; }
--- a/Abstracts/Image.h Fri Aug 30 17:09:18 2013 +0000 +++ b/Abstracts/Image.h Fri Mar 14 19:17:44 2014 +0000 @@ -45,13 +45,13 @@ * * @returns The image width. */ - int width(void); + int width(); /** Get the image height * * @returns The image height. */ - int height(void); + int height(); protected: //The image width/height
--- a/Controls/TextBox.cpp Fri Aug 30 17:09:18 2013 +0000 +++ b/Controls/TextBox.cpp Fri Mar 14 19:17:44 2014 +0000 @@ -26,7 +26,7 @@ backColor(0xFF000000); } -void TextBox::paint(Canvas *canvas) +void TextBox::paint(Canvas* canvas) { //Paint the base class Control::paint(canvas);
--- a/Controls/TextBox.h Fri Aug 30 17:09:18 2013 +0000 +++ b/Controls/TextBox.h Fri Mar 14 19:17:44 2014 +0000 @@ -41,7 +41,7 @@ * * @param canvas Pointer to the canvas to paint on. */ - virtual void paint(Canvas *canvas); + virtual void paint(Canvas* canvas); }; #endif
--- a/Decoders/BitmapImage.cpp Fri Aug 30 17:09:18 2013 +0000 +++ b/Decoders/BitmapImage.cpp Fri Mar 14 19:17:44 2014 +0000 @@ -16,21 +16,21 @@ #include "BitmapImage.h" -BitmapImage::BitmapImage(const char *table) : Image(table[0] * 0xFF + table[1], table[2] * 0xFF + table[3]) +BitmapImage::BitmapImage(const char* table) : Image(table[0] * 0xFF + table[1], table[2] * 0xFF + table[3]) { m_ImageTable = table; m_FgColor = 0xFFFFFFFF; m_BgColor = 0x00000000; } -BitmapImage::BitmapImage(const char *table, unsigned int fg_color) : Image(table[0] * 0xFF + table[1], table[2] * 0xFF + table[3]) +BitmapImage::BitmapImage(const char* table, unsigned int fg_color) : Image(table[0] * 0xFF + table[1], table[2] * 0xFF + table[3]) { m_ImageTable = table; m_FgColor = fg_color; m_BgColor = 0x00000000; } -BitmapImage::BitmapImage(const char *table, unsigned int fg_color, unsigned int bg_color) : Image(table[0] * 0xFF + table[1], table[2] * 0xFF + table[3]) +BitmapImage::BitmapImage(const char* table, unsigned int fg_color, unsigned int bg_color) : Image(table[0] * 0xFF + table[1], table[2] * 0xFF + table[3]) { m_ImageTable = table; m_FgColor = fg_color; @@ -58,7 +58,7 @@ return m_BgColor; } -unsigned int BitmapImage::foreground(void) +unsigned int BitmapImage::foreground() { return m_FgColor; } @@ -68,7 +68,7 @@ m_FgColor = c; } -unsigned int BitmapImage::background(void) +unsigned int BitmapImage::background() { return m_BgColor; } @@ -78,7 +78,7 @@ m_BgColor = c; } -int BitmapImage::bytesPerLine(void) +int BitmapImage::bytesPerLine() { int bpl;
--- a/Decoders/BitmapImage.h Fri Aug 30 17:09:18 2013 +0000 +++ b/Decoders/BitmapImage.h Fri Mar 14 19:17:44 2014 +0000 @@ -30,14 +30,14 @@ * * @param table Pointer to the image table. */ - BitmapImage(const char *table); + BitmapImage(const char* table); /** Create a BitmapImage object from the specified image table with the specified foreground, and an alpha background * * @param table Pointer to the image table. * @param fg_color The foreground color as a 32-bit ARGB value. */ - BitmapImage(const char *table, unsigned int fg_color); + BitmapImage(const char* table, unsigned int fg_color); /** Create a BitmapImage object from the specified image table with the specified foreground and background colors * @@ -45,7 +45,7 @@ * @param fg_color The foreground color as a 32-bit ARGB value. * @param bg_color The background color as a 32-bit ARGB value. */ - BitmapImage(const char *table, unsigned int fg_color, unsigned int bg_color); + BitmapImage(const char* table, unsigned int fg_color, unsigned int bg_color); /** Get the pixel at the specified coordinates * @@ -60,7 +60,7 @@ * * @returns The foreground color as a 32-bit ARGB value. */ - unsigned int foreground(void); + unsigned int foreground(); /** Set the foreground color * @@ -72,7 +72,7 @@ * * @returns The background color as a 32-bit ARGB value. */ - unsigned int background(void); + unsigned int background(); /** Set the background color * @@ -82,12 +82,12 @@ protected: //Pointer to the image table - const char *m_ImageTable; + const char* m_ImageTable; //The foreground and background colors unsigned int m_FgColor, m_BgColor; - int bytesPerLine(void); + int bytesPerLine(); }; #endif
--- a/Decoders/Font.cpp Fri Aug 30 17:09:18 2013 +0000 +++ b/Decoders/Font.cpp Fri Mar 14 19:17:44 2014 +0000 @@ -16,13 +16,13 @@ #include "Font.h" -Font::Font(const char *table) +Font::Font(const char* table) { m_FontTable = table; m_Color = 0xFFFFFFFF; } -Font::Font(const char *table, unsigned int color) +Font::Font(const char* table, unsigned int color) { m_FontTable = table; m_Color = color; @@ -48,7 +48,7 @@ } } -unsigned int Font::color(void) +unsigned int Font::color() { return m_Color; } @@ -58,12 +58,12 @@ m_Color = c; } -int Font::height(void) +int Font::height() { return m_FontTable[1]; } -int Font::measureString(const char *str) +int Font::measureString(const char* str) { int i = 0; int slen = 0; @@ -77,7 +77,7 @@ return slen; } -int Font::measureWord(const char *str) +int Font::measureWord(const char* str) { int i = 0; int wlen = 0;
--- a/Decoders/Font.h Fri Aug 30 17:09:18 2013 +0000 +++ b/Decoders/Font.h Fri Mar 14 19:17:44 2014 +0000 @@ -30,14 +30,14 @@ * * @param table Pointer to the font table. */ - Font(const char *table); + Font(const char* table); /** Create a Font object with the specified color * * @param table Pointer to the font table. * @param color Color for the font as a 32-bit ARGB value. */ - Font(const char *table, unsigned int color); + Font(const char* table, unsigned int color); /** Get the glyph Image for the specified character * @@ -49,7 +49,7 @@ * * @returns The current Font color as a 32-bit ARGB value. */ - unsigned int color(void); + unsigned int color(); /** Set the Font color * @@ -61,7 +61,7 @@ * * @returns The height of the Font glyphs. */ - int height(void); + int height(); /** Measures the width of a string in pixels if drawn with this font * @@ -69,7 +69,7 @@ * * @returns The width of the string in pixels. */ - int measureString(const char *str); + int measureString(const char* str); /** Measures the width of the next word in a string (separated by whitespace) in pixels if drawn with this font * @@ -77,10 +77,10 @@ * * @returns The width of the next word in pixels. */ - int measureWord(const char *str); + int measureWord(const char* str); protected: - const char *m_FontTable; + const char* m_FontTable; unsigned int m_Color; };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Drivers/ILI9341.cpp Fri Mar 14 19:17:44 2014 +0000 @@ -0,0 +1,283 @@ +/* NeatGUI Library + * Copyright (c) 2013 Neil Thiessen + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ILI9341.h" + +ILI9341::ILI9341(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName dc) : Display(240, 320), m_SPI(mosi, miso, sclk), m_CS(cs), m_DC(dc) +{ + //Set the control pins to a known state + m_CS = 1; + m_DC = 1; + + //Set the SPI format to 8-bit + m_SPI.format(8, 3); + + //Set the SPI frequency to 10MHz + m_SPI.frequency(10000000); +} + +bool ILI9341::open() +{ + writeCommand(0x01); + wait_ms(5); + + writeCommand(0xCF); + writeData8(0x00); + writeData8(0x8B); + writeData8(0X30); + + writeCommand(0xED); + writeData8(0x67); + writeData8(0x03); + writeData8(0X12); + writeData8(0X81); + + writeCommand(0xE8); + writeData8(0x85); + writeData8(0x10); + writeData8(0x7A); + + writeCommand(0xCB); + writeData8(0x39); + writeData8(0x2C); + writeData8(0x00); + writeData8(0x34); + writeData8(0x02); + + writeCommand(0xF7); + writeData8(0x20); + + writeCommand(0xEA); + writeData8(0x00); + writeData8(0x00); + + writeCommand(0xC0); /* Power control */ + writeData8(0x1B); /* VRH[5:0] */ + + writeCommand(0xC1); /* Power control */ + writeData8(0x10); /* SAP[2:0];BT[3:0] */ + + writeCommand(0xC5); /* VCM control */ + writeData8(0x3F); + writeData8(0x3C); + + writeCommand(0xC7); /* VCM control2 */ + writeData8(0XB7); + + writeCommand(0x36); /* Memory Access Control */ + writeData8(0x08); + + writeCommand(0x3A); + writeData8(0x55); + + writeCommand(0xB1); + writeData8(0x00); + writeData8(0x1B); + + writeCommand(0xB6); /* Display Function Control */ + writeData8(0x0A); + writeData8(0xA2); + + + writeCommand(0xF2); /* 3Gamma Function Disable */ + writeData8(0x00); + + writeCommand(0x26); /* Gamma curve selected */ + writeData8(0x01); + + writeCommand(0xE0); /* Set Gamma */ + writeData8(0x0F); + writeData8(0x2A); + writeData8(0x28); + writeData8(0x08); + writeData8(0x0E); + writeData8(0x08); + writeData8(0x54); + writeData8(0XA9); + writeData8(0x43); + writeData8(0x0A); + writeData8(0x0F); + writeData8(0x00); + writeData8(0x00); + writeData8(0x00); + writeData8(0x00); + + writeCommand(0XE1); /* Set Gamma */ + writeData8(0x00); + writeData8(0x15); + writeData8(0x17); + writeData8(0x07); + writeData8(0x11); + writeData8(0x06); + writeData8(0x2B); + writeData8(0x56); + writeData8(0x3C); + writeData8(0x05); + writeData8(0x10); + writeData8(0x0F); + writeData8(0x3F); + writeData8(0x3F); + writeData8(0x0F); + + writeCommand(0x11); /* Exit Sleep */ + wait_ms(120); + writeCommand(0x29); /* Display on */ + + //Probe for the ILI9341 using a Zero Length Transfer + /*if (!m_I2C.write(m_Addr, NULL, 0)) { + //Init sequence for 128x64 OLED module + writeCommand(CMD_DISPLAYOFF); + writeCommand(CMD_SETDISPLAYCLOCKDIV); + writeCommand(0x80); + writeCommand(CMD_SETMULTIPLEX); + writeCommand(0x3F); + writeCommand(CMD_SETDISPLAYOFFSET); + writeCommand(0x0); + writeCommand(CMD_SETSTARTLINE | 0x0); + writeCommand(CMD_CHARGEPUMP); + writeCommand(CMD_CHARGEPUMPON); + writeCommand(CMD_MEMORYMODE); + writeCommand(0x00); + writeCommand(CMD_SEGREMAP | 0x1); + writeCommand(CMD_COMSCANDEC); + writeCommand(CMD_SETCOMPINS); + writeCommand(0x12); + writeCommand(CMD_SETCONTRAST); + writeCommand(0xCF); + writeCommand(CMD_SETPRECHARGE); + writeCommand(0xF1); + writeCommand(CMD_SETVCOMDETECT); + writeCommand(0x40); + writeCommand(CMD_DISPLAYALLON_RESUME); + writeCommand(CMD_NORMALDISPLAY); + + //Return success + return true; + } else { + //Return failure + return false; + }*/ + + return true; +} + +void ILI9341::finalize() +{ + //Select low col 0, hi col 0, line 0 + //writeCommand(CMD_SETLOWCOLUMN | 0x0); + //writeCommand(CMD_SETHIGHCOLUMN | 0x0); + //writeCommand(CMD_SETSTARTLINE | 0x0); + + //Make sure the first byte in the buffer is the control byte + //m_Buffer[0] = CONTROL_DATA; + + //Write the buffer + //m_I2C.write(m_Addr, m_Buffer, 1025); +} + +Display::State ILI9341::state() +{ + //Return the base class's state + return Display::state(); +} + +void ILI9341::state(State s) +{ + //Check what the requested state is + if (s == Display::DISPLAY_ON) { + //Turn the display on + //writeCommand(CMD_DISPLAYON); + } else if (s == Display::DISPLAY_OFF) { + //Turn the display off + //writeCommand(CMD_DISPLAYOFF); + } + + //Update the base class + Display::state(s); +} + +void ILI9341::drawPixel(int x, int y, unsigned int c) +{ + //Range check the pixel + if ((x < 0) || (x >= width()) || (y < 0) || (y >= height())) + return; + + //TODO: Clean up this code!!! + + //Set the column + writeCommand(0x2A); + writeData16(x); + writeData16(x); + + //Set the page + writeCommand(0x2B); + writeData16(y); + writeData16(y); + + //Don't know what this does... + writeCommand(0x2C); + + //Woohoo, send the pixel!!! + writeData16(c); + + //TODO: Clean up this code!!! +} + +void ILI9341::writeCommand(char command) +{ + //Pull DC low for Command + m_DC = 0; + + //Pull CS low to select the TFT + m_CS = 0; + + //Write the command byte + m_SPI.write(command); + + //Pull CS high to end the transfer + m_CS = 1; +} + +void ILI9341::writeData8(char data) +{ + //Pull DC high for Data + m_DC = 1; + + //Pull CS low to select the TFT + m_CS = 0; + + //Write the data byte + m_SPI.write(data); + + //Pull CS high to end the transfer + m_CS = 1; +} + +void ILI9341::writeData16(unsigned short data) +{ + //Pull DC high for Data + m_DC = 1; + + //Pull CS low to select the TFT + m_CS = 0; + + //Write the 2 data bytes + m_SPI.write((char)(data >> 8)); + m_SPI.write((char)data); + + //Pull CS high to end the transfer + m_CS = 1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Drivers/ILI9341.h Fri Mar 14 19:17:44 2014 +0000 @@ -0,0 +1,119 @@ +/* NeatGUI Library + * Copyright (c) 2013 Neil Thiessen + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ILI9341_H +#define ILI9241_H + +#include "mbed.h" +#include "Display.h" + +/** ILI9341 class. + * Used for controlling an ILI9341-based TFT display. + */ +class ILI9341 : public Display +{ +public: + /** Create an ILI9341 object connected to the specified SPI pins with the specified /CS and DC pins + * + * @param mosi The SPI data out pin. + * @param miso The SPI data in pin. + * @param sclk The SPI clock pin. + * @param sclk The SPI chip select pin. + * @param sclk The data/command pin. + */ + ILI9341(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName dc); + + /** Probe for the ILI9341 and initialize it if present + * + * @returns + * 'true' if the device exists on the bus, + * 'false' if the device doesn't exist on the bus. + */ + virtual bool open(); + + /** Send the buffer to the ILI9341 + */ + virtual void finalize(); + + /** Get the current state of the ILI9341 + * + * @returns The current state as a Display::State enum. + */ + virtual Display::State state(); + + /** Set the state of the ILI9341 + * + * @param mode The new state as a Display::State enum. + */ + virtual void state(State s); + + //void display(); + + /** Draw a single pixel at the specified coordinates + * + * @param x The X coordinate. + * @param y The Y coordinate. + * @param c The color of the pixel as a 32-bit ARGB value. + */ + virtual void drawPixel(int x, int y, unsigned int c); + +private: + //Commands + /*enum Command { + CMD_SETCONTRAST = 0x81, + CMD_DISPLAYALLON_RESUME = 0xA4, + CMD_DISPLAYALLON = 0xA5, + CMD_NORMALDISPLAY = 0xA6, + CMD_INVERTDISPLAY = 0xA7, + CMD_DISPLAYOFF = 0xAE, + CMD_DISPLAYON = 0xAF, + CMD_SETDISPLAYOFFSET = 0xD3, + CMD_SETCOMPINS = 0xDA, + CMD_SETVCOMDETECT = 0xDB, + CMD_SETDISPLAYCLOCKDIV = 0xD5, + CMD_SETPRECHARGE = 0xD9, + CMD_SETMULTIPLEX = 0xA8, + CMD_SETLOWCOLUMN = 0x00, + CMD_SETHIGHCOLUMN = 0x10, + CMD_SETSTARTLINE = 0x40, + CMD_MEMORYMODE = 0x20, + CMD_COMSCANINC = 0xC0, + CMD_COMSCANDEC = 0xC8, + CMD_SEGREMAP = 0xA0, + CMD_CHARGEPUMP = 0x8D, + CMD_CHARGEPUMPON = 0x14, + CMD_CHARGEPUMPOFF = 0x10, + CMD_ACTIVATE_SCROLL = 0x2F, + CMD_DEACTIVATE_SCROLL = 0x2E, + CMD_SET_VERTICAL_SCROLL_AREA = 0xA3, + CMD_RIGHT_HORIZONTAL_SCROLL = 0x26, + CMD_LEFT_HORIZONTAL_SCROLL = 0x27, + CMD_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL = 0x29, + CMD_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL = 0x2A + };*/ + + //Interface variables + SPI m_SPI; + DigitalOut m_CS; + DigitalOut m_DC; + + //Command and data helpers + void writeCommand(char command); + void writeData8(char data); + void writeData16(unsigned short data); +}; + +#endif
--- a/Drivers/SSD1306.cpp Fri Aug 30 17:09:18 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,148 +0,0 @@ -/* NeatGUI Library - * Copyright (c) 2013 Neil Thiessen - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "SSD1306.h" - -SSD1306::SSD1306(PinName sda, PinName scl, Address addr) : Display(128, 64), m_I2C(sda, scl) -{ - //Set the internal device address - m_Addr = (int)addr; - - //Set the I2C frequency to 400kHz - m_I2C.frequency(400000); -} - -bool SSD1306::open(void) -{ - //Probe for the SSD1306 using a Zero Length Transfer - if (!m_I2C.write(m_Addr, NULL, 0)) { - //Init sequence for 128x64 OLED module - writeCommand(CMD_DISPLAYOFF); - writeCommand(CMD_SETDISPLAYCLOCKDIV); - writeCommand(0x80); - writeCommand(CMD_SETMULTIPLEX); - writeCommand(0x3F); - writeCommand(CMD_SETDISPLAYOFFSET); - writeCommand(0x0); - writeCommand(CMD_SETSTARTLINE | 0x0); - writeCommand(CMD_CHARGEPUMP); - writeCommand(CMD_CHARGEPUMPON); - writeCommand(CMD_MEMORYMODE); - writeCommand(0x00); - writeCommand(CMD_SEGREMAP | 0x1); - writeCommand(CMD_COMSCANDEC); - writeCommand(CMD_SETCOMPINS); - writeCommand(0x12); - writeCommand(CMD_SETCONTRAST); - writeCommand(0xCF); - writeCommand(CMD_SETPRECHARGE); - writeCommand(0xF1); - writeCommand(CMD_SETVCOMDETECT); - writeCommand(0x40); - writeCommand(CMD_DISPLAYALLON_RESUME); - writeCommand(CMD_NORMALDISPLAY); - - //Return success - return true; - } else { - //Return failure - return false; - } -} - -void SSD1306::finalize(void) -{ - //Select low col 0, hi col 0, line 0 - writeCommand(CMD_SETLOWCOLUMN | 0x0); - writeCommand(CMD_SETHIGHCOLUMN | 0x0); - writeCommand(CMD_SETSTARTLINE | 0x0); - - //Make sure the first byte in the buffer is the control byte - m_Buffer[0] = CONTROL_DATA; - - //Write the buffer - m_I2C.write(m_Addr, m_Buffer, 1025); -} - -Display::State SSD1306::state(void) -{ - //Return the base class's state - return Display::state(); -} - -void SSD1306::state(State s) -{ - //Check what the requested state is - if (s == Display::DISPLAY_ON) { - //Turn the display on - writeCommand(CMD_DISPLAYON); - } else if (s == Display::DISPLAY_OFF) { - //Turn the display off - writeCommand(CMD_DISPLAYOFF); - } - - //Update the base class - Display::state(s); -} - -void SSD1306::drawPixel(int x, int y, unsigned int c) -{ - //Range check the pixel - if ((x < 0) || (x >= width()) || (y < 0) || (y >= height())) - return; - - //Make sure the color is fully opaque - if ((c >> 24) != 255) - return; - - //Determine the pixel byte index - unsigned short byteIndex = x + (y / 8) * width(); - - //HACK: Fix the whole 1025 byte i2c buffer thing - byteIndex++; - - //Set or clear the pixel - if ((c & 0x00FFFFFF) > 0) - m_Buffer[byteIndex] |= (1 << (y % 8)); - else - m_Buffer[byteIndex] &= ~(1 << (y % 8)); -} - -void SSD1306::writeCommand(char command) -{ - //Create a temporary buffer - char buff[2]; - - //Load the control byte and 8-bit command - buff[0] = CONTROL_COMMAND; - buff[1] = command; - - //Write the command - m_I2C.write(m_Addr, buff, 2); -} - -void SSD1306::writeData(char data) -{ - //Create a temporary buffer - char buff[2]; - - //Load the control byte and 8-bit data - buff[0] = CONTROL_DATA; - buff[1] = data; - - //Write the data - m_I2C.write(m_Addr, buff, 2); -}
--- a/Drivers/SSD1306.h Fri Aug 30 17:09:18 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,141 +0,0 @@ -/* NeatGUI Library - * Copyright (c) 2013 Neil Thiessen - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef SSD1306_H -#define SSD1306_H - -#include "mbed.h" -#include "Display.h" - -/** SSD1306 class. - * Used for controlling an SSD1306-based OLED display. - */ -class SSD1306 : public Display -{ -public: - /** Represents the different I2C address possibilities for the SSD1306 - */ - enum Address { - ADDRESS_0 = (0x3C << 1), /**< SA0 pin = 0 */ - ADDRESS_1 = (0x3D << 1), /**< SA0 pin = 1 */ - }; - - /** Create an SSD1306 object connected to the specified I2C pins with the specified I2C slave address - * - * @param sda The I2C data pin. - * @param scl The I2C clock pin. - * @param addr The I2C slave address. - */ - SSD1306(PinName sda, PinName scl, Address addr); - - /** Create an SSD1306 object connected to the specified SPI pins with the specified /CS and DC pins - * - * @param mosi The SPI data out pin. - * @param miso The SPI data in pin. - * @param sclk The SPI clock pin. - * @param sclk The SPI chip select pin. - * @param sclk The data/command pin. - */ - //SSD1306(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName dc); - - /** Probe for the SSD1306 and initialize it if present - * - * @returns - * 'true' if the device exists on the bus, - * 'false' if the device doesn't exist on the bus. - */ - virtual bool open(void); - - /** Send the buffer to the SSD1306 - */ - virtual void finalize(void); - - /** Get the current state of the SSD1306 - * - * @returns The current state as a Display::State enum. - */ - virtual Display::State state(void); - - /** Set the state of the SSD1306 - * - * @param mode The new state as a Display::State enum. - */ - virtual void state(State s); - - //void display(void); - - /** Draw a single pixel at the specified coordinates - * - * @param x The X coordinate. - * @param y The Y coordinate. - * @param c The color of the pixel as a 32-bit ARGB value. - */ - virtual void drawPixel(int x, int y, unsigned int c); - -private: - //Commands - enum Command { - CMD_SETCONTRAST = 0x81, - CMD_DISPLAYALLON_RESUME = 0xA4, - CMD_DISPLAYALLON = 0xA5, - CMD_NORMALDISPLAY = 0xA6, - CMD_INVERTDISPLAY = 0xA7, - CMD_DISPLAYOFF = 0xAE, - CMD_DISPLAYON = 0xAF, - CMD_SETDISPLAYOFFSET = 0xD3, - CMD_SETCOMPINS = 0xDA, - CMD_SETVCOMDETECT = 0xDB, - CMD_SETDISPLAYCLOCKDIV = 0xD5, - CMD_SETPRECHARGE = 0xD9, - CMD_SETMULTIPLEX = 0xA8, - CMD_SETLOWCOLUMN = 0x00, - CMD_SETHIGHCOLUMN = 0x10, - CMD_SETSTARTLINE = 0x40, - CMD_MEMORYMODE = 0x20, - CMD_COMSCANINC = 0xC0, - CMD_COMSCANDEC = 0xC8, - CMD_SEGREMAP = 0xA0, - CMD_CHARGEPUMP = 0x8D, - CMD_CHARGEPUMPON = 0x14, - CMD_CHARGEPUMPOFF = 0x10, - CMD_ACTIVATE_SCROLL = 0x2F, - CMD_DEACTIVATE_SCROLL = 0x2E, - CMD_SET_VERTICAL_SCROLL_AREA = 0xA3, - CMD_RIGHT_HORIZONTAL_SCROLL = 0x26, - CMD_LEFT_HORIZONTAL_SCROLL = 0x27, - CMD_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL = 0x29, - CMD_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL = 0x2A - }; - - //Control bytes for the I2C interface - enum I2CControlByte { - CONTROL_COMMAND = 0x00, - CONTROL_DATA = 0x40 - }; - - //I2C interface variables - I2C m_I2C; - int m_Addr; - - //Back buffer - char m_Buffer[1025]; - - //Command and data helpers - void writeCommand(char command); - void writeData(char data); -}; - -#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Drivers/SSD1306_I2C.cpp Fri Mar 14 19:17:44 2014 +0000 @@ -0,0 +1,145 @@ +/* NeatGUI Library + * Copyright (c) 2013 Neil Thiessen + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "SSD1306_I2C.h" + +SSD1306_I2C::SSD1306_I2C(PinName sda, PinName scl, Address addr) : Display(128, 64), m_I2C(sda, scl), m_ADDR((int)addr) +{ + //Set the I2C frequency to 400kHz + m_I2C.frequency(400000); +} + +bool SSD1306_I2C::open() +{ + //Probe for the SSD1306 using a Zero Length Transfer + if (!m_I2C.write(m_ADDR, NULL, 0)) { + //Init sequence for 128x64 OLED module + writeCommand(CMD_DISPLAYOFF); + writeCommand(CMD_SETDISPLAYCLOCKDIV); + writeCommand(0x80); + writeCommand(CMD_SETMULTIPLEX); + writeCommand(0x3F); + writeCommand(CMD_SETDISPLAYOFFSET); + writeCommand(0x0); + writeCommand(CMD_SETSTARTLINE | 0x0); + writeCommand(CMD_CHARGEPUMP); + writeCommand(CMD_CHARGEPUMPON); + writeCommand(CMD_MEMORYMODE); + writeCommand(0x00); + writeCommand(CMD_SEGREMAP | 0x1); + writeCommand(CMD_COMSCANDEC); + writeCommand(CMD_SETCOMPINS); + writeCommand(0x12); + writeCommand(CMD_SETCONTRAST); + writeCommand(0xCF); + writeCommand(CMD_SETPRECHARGE); + writeCommand(0xF1); + writeCommand(CMD_SETVCOMDETECT); + writeCommand(0x40); + writeCommand(CMD_DISPLAYALLON_RESUME); + writeCommand(CMD_NORMALDISPLAY); + + //Return success + return true; + } else { + //Return failure + return false; + } +} + +void SSD1306_I2C::finalize() +{ + //Select low col 0, hi col 0, line 0 + writeCommand(CMD_SETLOWCOLUMN | 0x0); + writeCommand(CMD_SETHIGHCOLUMN | 0x0); + writeCommand(CMD_SETSTARTLINE | 0x0); + + //Make sure the first byte in the buffer is the control byte + m_Buffer[0] = CONTROL_DATA; + + //Write the buffer + m_I2C.write(m_ADDR, m_Buffer, 1025); +} + +Display::State SSD1306_I2C::state() +{ + //Return the base class's state + return Display::state(); +} + +void SSD1306_I2C::state(State s) +{ + //Check what the requested state is + if (s == Display::DISPLAY_ON) { + //Turn the display on + writeCommand(CMD_DISPLAYON); + } else if (s == Display::DISPLAY_OFF) { + //Turn the display off + writeCommand(CMD_DISPLAYOFF); + } + + //Update the base class + Display::state(s); +} + +void SSD1306_I2C::drawPixel(int x, int y, unsigned int c) +{ + //Range check the pixel + if ((x < 0) || (x >= width()) || (y < 0) || (y >= height())) + return; + + //Make sure the color is fully opaque + if ((c >> 24) != 255) + return; + + //Determine the pixel byte index + unsigned short byteIndex = x + (y / 8) * width(); + + //HACK: Fix the whole 1025 byte i2c buffer thing + byteIndex++; + + //Set or clear the pixel + if ((c & 0x00FFFFFF) > 0) + m_Buffer[byteIndex] |= (1 << (y % 8)); + else + m_Buffer[byteIndex] &= ~(1 << (y % 8)); +} + +void SSD1306_I2C::writeCommand(char command) +{ + //Create a temporary buffer + char buff[2]; + + //Load the control byte and 8-bit command + buff[0] = CONTROL_COMMAND; + buff[1] = command; + + //Write the command + m_I2C.write(m_ADDR, buff, 2); +} + +void SSD1306_I2C::writeData(char data) +{ + //Create a temporary buffer + char buff[2]; + + //Load the control byte and 8-bit data + buff[0] = CONTROL_DATA; + buff[1] = data; + + //Write the data + m_I2C.write(m_ADDR, buff, 2); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Drivers/SSD1306_I2C.h Fri Mar 14 19:17:44 2014 +0000 @@ -0,0 +1,141 @@ +/* NeatGUI Library + * Copyright (c) 2013 Neil Thiessen + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SSD1306_I2C_H +#define SSD1306_I2C_H + +#include "mbed.h" +#include "Display.h" + +/** SSD1306_I2C class. + * Used for controlling an SSD1306-based OLED display connected to i2c. + */ +class SSD1306_I2C : public Display +{ +public: + /** Represents the different I2C address possibilities for the SSD1306 + */ + enum Address { + ADDRESS_0 = (0x3C << 1), /**< SA0 pin = 0 */ + ADDRESS_1 = (0x3D << 1), /**< SA0 pin = 1 */ + }; + + /** Create an SSD1306 object connected to the specified I2C pins with the specified I2C slave address + * + * @param sda The I2C data pin. + * @param scl The I2C clock pin. + * @param addr The I2C slave address. + */ + SSD1306_I2C(PinName sda, PinName scl, Address addr); + + /** Create an SSD1306 object connected to the specified SPI pins with the specified /CS and DC pins + * + * @param mosi The SPI data out pin. + * @param miso The SPI data in pin. + * @param sclk The SPI clock pin. + * @param sclk The SPI chip select pin. + * @param sclk The data/command pin. + */ + //SSD1306_SPI(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName dc); + + /** Probe for the SSD1306 and initialize it if present + * + * @returns + * 'true' if the device exists on the bus, + * 'false' if the device doesn't exist on the bus. + */ + virtual bool open(); + + /** Send the buffer to the SSD1306 + */ + virtual void finalize(); + + /** Get the current state of the SSD1306 + * + * @returns The current state as a Display::State enum. + */ + virtual Display::State state(); + + /** Set the state of the SSD1306 + * + * @param mode The new state as a Display::State enum. + */ + virtual void state(State s); + + //void display(); + + /** Draw a single pixel at the specified coordinates + * + * @param x The X coordinate. + * @param y The Y coordinate. + * @param c The color of the pixel as a 32-bit ARGB value. + */ + virtual void drawPixel(int x, int y, unsigned int c); + +private: + //Commands + enum Command { + CMD_SETCONTRAST = 0x81, + CMD_DISPLAYALLON_RESUME = 0xA4, + CMD_DISPLAYALLON = 0xA5, + CMD_NORMALDISPLAY = 0xA6, + CMD_INVERTDISPLAY = 0xA7, + CMD_DISPLAYOFF = 0xAE, + CMD_DISPLAYON = 0xAF, + CMD_SETDISPLAYOFFSET = 0xD3, + CMD_SETCOMPINS = 0xDA, + CMD_SETVCOMDETECT = 0xDB, + CMD_SETDISPLAYCLOCKDIV = 0xD5, + CMD_SETPRECHARGE = 0xD9, + CMD_SETMULTIPLEX = 0xA8, + CMD_SETLOWCOLUMN = 0x00, + CMD_SETHIGHCOLUMN = 0x10, + CMD_SETSTARTLINE = 0x40, + CMD_MEMORYMODE = 0x20, + CMD_COMSCANINC = 0xC0, + CMD_COMSCANDEC = 0xC8, + CMD_SEGREMAP = 0xA0, + CMD_CHARGEPUMP = 0x8D, + CMD_CHARGEPUMPON = 0x14, + CMD_CHARGEPUMPOFF = 0x10, + CMD_ACTIVATE_SCROLL = 0x2F, + CMD_DEACTIVATE_SCROLL = 0x2E, + CMD_SET_VERTICAL_SCROLL_AREA = 0xA3, + CMD_RIGHT_HORIZONTAL_SCROLL = 0x26, + CMD_LEFT_HORIZONTAL_SCROLL = 0x27, + CMD_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL = 0x29, + CMD_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL = 0x2A + }; + + //Control bytes for the I2C interface + enum I2CControlByte { + CONTROL_COMMAND = 0x00, + CONTROL_DATA = 0x40 + }; + + //I2C interface variables + I2C m_I2C; + const int m_ADDR; + + //Back buffer + char m_Buffer[1025]; + + //Command and data helpers + void writeCommand(char command); + void writeData(char data); +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Drivers/SSD1306_SPI.cpp Fri Mar 14 19:17:44 2014 +0000 @@ -0,0 +1,147 @@ +/* NeatGUI Library + * Copyright (c) 2013 Neil Thiessen + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "SSD1306_SPI.h" + +SSD1306_SPI::SSD1306_SPI(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName dc) : Display(128, 64), m_SPI(mosi, miso, sclk), m_CS(cs), m_DC(dc) +{ + //Deselect the display + m_CS = 1; + + //Set the SPI format to 8 bit data, high steady state clock, second edge capture + m_SPI.format(8, 3); + + //Set the SPI frequency to 10MHz + m_SPI.frequency(10000000); +} + +bool SSD1306_SPI::open() +{ + //Init sequence for 128x64 OLED module + writeCommand(CMD_DISPLAYOFF); + writeCommand(CMD_SETDISPLAYCLOCKDIV); + writeCommand(0x80); + writeCommand(CMD_SETMULTIPLEX); + writeCommand(0x3F); + writeCommand(CMD_SETDISPLAYOFFSET); + writeCommand(0x0); + writeCommand(CMD_SETSTARTLINE | 0x0); + writeCommand(CMD_CHARGEPUMP); + writeCommand(CMD_CHARGEPUMPON); + writeCommand(CMD_MEMORYMODE); + writeCommand(0x00); + writeCommand(CMD_SEGREMAP | 0x1); + writeCommand(CMD_COMSCANDEC); + writeCommand(CMD_SETCOMPINS); + writeCommand(0x12); + writeCommand(CMD_SETCONTRAST); + writeCommand(0xCF); + writeCommand(CMD_SETPRECHARGE); + writeCommand(0xF1); + writeCommand(CMD_SETVCOMDETECT); + writeCommand(0x40); + writeCommand(CMD_DISPLAYALLON_RESUME); + writeCommand(CMD_NORMALDISPLAY); + + //Return success + return true; +} + +void SSD1306_SPI::finalize() +{ + //Select low col 0, hi col 0, line 0 + writeCommand(CMD_SETLOWCOLUMN | 0x0); + writeCommand(CMD_SETHIGHCOLUMN | 0x0); + writeCommand(CMD_SETSTARTLINE | 0x0); + + //Set DC to data and select the chip + m_DC = 1; + m_CS = 0; + + //Write the entire buffer at once + for (int i = 0; i < 1024; i++) + m_SPI.write(m_Buffer[i]); + + //Deselect the chip + m_CS = 1; +} + +Display::State SSD1306_SPI::state() +{ + //Return the base class's state + return Display::state(); +} + +void SSD1306_SPI::state(State s) +{ + //Check what the requested state is + if (s == Display::DISPLAY_ON) { + //Turn the display on + writeCommand(CMD_DISPLAYON); + } else if (s == Display::DISPLAY_OFF) { + //Turn the display off + writeCommand(CMD_DISPLAYOFF); + } + + //Update the base class + Display::state(s); +} + +void SSD1306_SPI::drawPixel(int x, int y, unsigned int c) +{ + //Range check the pixel + if ((x < 0) || (x >= width()) || (y < 0) || (y >= height())) + return; + + //Make sure the color is fully opaque + if ((c >> 24) != 255) + return; + + //Determine the pixel byte index + unsigned short byteIndex = x + (y / 8) * width(); + + //Set or clear the pixel + if ((c & 0x00FFFFFF) > 0) + m_Buffer[byteIndex] |= (1 << (y % 8)); + else + m_Buffer[byteIndex] &= ~(1 << (y % 8)); +} + +void SSD1306_SPI::writeCommand(char command) +{ + //Set DC to command and select the display + m_DC = 0; + m_CS = 0; + + //Write the command byte + m_SPI.write(command); + + //Deselect the display + m_CS = 1; +} + +void SSD1306_SPI::writeData(char data) +{ + //Set DC to data and select the display + m_DC = 1; + m_CS = 0; + + //Write the data byte + m_SPI.write(data); + + //Deselect the display + m_CS = 1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Drivers/SSD1306_SPI.h Fri Mar 14 19:17:44 2014 +0000 @@ -0,0 +1,122 @@ +/* NeatGUI Library + * Copyright (c) 2013 Neil Thiessen + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SSD1306_SPI_H +#define SSD1306_SPI_H + +#include "mbed.h" +#include "Display.h" + +/** SSD1306_SPI class. + * Used for controlling an SSD1306-based OLED display connected to SPI. + */ +class SSD1306_SPI : public Display +{ +public: + + /** Create an SSD1306 object connected to the specified SPI pins with the specified /CS and DC pins + * + * @param mosi The SPI data out pin. + * @param miso The SPI data in pin. + * @param sclk The SPI clock pin. + * @param sclk The SPI chip select pin. + * @param sclk The data/command pin. + */ + SSD1306_SPI(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName dc); + + /** Probe for the SSD1306 and initialize it if present + * + * @returns + * 'true' if the device exists on the bus, + * 'false' if the device doesn't exist on the bus. + */ + virtual bool open(); + + /** Send the buffer to the SSD1306 + */ + virtual void finalize(); + + /** Get the current state of the SSD1306 + * + * @returns The current state as a Display::State enum. + */ + virtual Display::State state(); + + /** Set the state of the SSD1306 + * + * @param mode The new state as a Display::State enum. + */ + virtual void state(State s); + + //void display(); + + /** Draw a single pixel at the specified coordinates + * + * @param x The X coordinate. + * @param y The Y coordinate. + * @param c The color of the pixel as a 32-bit ARGB value. + */ + virtual void drawPixel(int x, int y, unsigned int c); + +private: + //Commands + enum Command { + CMD_SETCONTRAST = 0x81, + CMD_DISPLAYALLON_RESUME = 0xA4, + CMD_DISPLAYALLON = 0xA5, + CMD_NORMALDISPLAY = 0xA6, + CMD_INVERTDISPLAY = 0xA7, + CMD_DISPLAYOFF = 0xAE, + CMD_DISPLAYON = 0xAF, + CMD_SETDISPLAYOFFSET = 0xD3, + CMD_SETCOMPINS = 0xDA, + CMD_SETVCOMDETECT = 0xDB, + CMD_SETDISPLAYCLOCKDIV = 0xD5, + CMD_SETPRECHARGE = 0xD9, + CMD_SETMULTIPLEX = 0xA8, + CMD_SETLOWCOLUMN = 0x00, + CMD_SETHIGHCOLUMN = 0x10, + CMD_SETSTARTLINE = 0x40, + CMD_MEMORYMODE = 0x20, + CMD_COMSCANINC = 0xC0, + CMD_COMSCANDEC = 0xC8, + CMD_SEGREMAP = 0xA0, + CMD_CHARGEPUMP = 0x8D, + CMD_CHARGEPUMPON = 0x14, + CMD_CHARGEPUMPOFF = 0x10, + CMD_ACTIVATE_SCROLL = 0x2F, + CMD_DEACTIVATE_SCROLL = 0x2E, + CMD_SET_VERTICAL_SCROLL_AREA = 0xA3, + CMD_RIGHT_HORIZONTAL_SCROLL = 0x26, + CMD_LEFT_HORIZONTAL_SCROLL = 0x27, + CMD_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL = 0x29, + CMD_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL = 0x2A + }; + + //SPI interface variables + SPI m_SPI; + DigitalOut m_CS; + DigitalOut m_DC; + + //Back buffer + char m_Buffer[1024]; + + //Command and data helpers + void writeCommand(char command); + void writeData(char data); +}; + +#endif
--- a/NeatGUI.h Fri Aug 30 17:09:18 2013 +0000 +++ b/NeatGUI.h Fri Mar 14 19:17:44 2014 +0000 @@ -31,6 +31,8 @@ #include "Font.h" //Drivers -#include "SSD1306.h" +#include "ILI9341.h" +#include "SSD1306_I2C.h" +#include "SSD1306_SPI.h" #endif