Skip to content

Commit

Permalink
i2c scanner uses more reliable bit banging
Browse files Browse the repository at this point in the history
ssd1306 oled display test app
  • Loading branch information
Gabriel committed Nov 9, 2020
1 parent 39c042b commit 59729f9
Show file tree
Hide file tree
Showing 24 changed files with 1,719 additions and 27 deletions.
808 changes: 808 additions & 0 deletions system/apps_experiments/102_ssd1306/source/Adafruit_SSD1306.cpp

Large diffs are not rendered by default.

146 changes: 146 additions & 0 deletions system/apps_experiments/102_ssd1306/source/Adafruit_SSD1306.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/*!
* @file Adafruit_SSD1306.h
*
* This is part of for Adafruit's SSD1306 library for monochrome
* OLED displays: http://www.adafruit.com/category/63_98
*
* These displays use I2C or SPI to communicate. I2C requires 2 pins
* (SCL+SDA) and optionally a RESET pin. SPI requires 4 pins (MOSI, SCK,
* select, data/command) and optionally a reset pin. Hardware SPI or
* 'bitbang' software SPI are both supported.
*
* Adafruit invests time and resources providing this open source code,
* please support Adafruit and open-source hardware by purchasing
* products from Adafruit!
*
* Written by Limor Fried/Ladyada for Adafruit Industries, with
* contributions from the open source community.
*
* BSD license, all text above, and the splash screen header file,
* must be included in any redistribution.
*
*/

#ifndef _Adafruit_SSD1306_H_
#define _Adafruit_SSD1306_H_


// ONE of the following three lines must be #defined:
//#define SSD1306_128_64 ///< DEPRECTAED: old way to specify 128x64 screen
#define SSD1306_128_32 ///< DEPRECATED: old way to specify 128x32 screen
//#define SSD1306_96_16 ///< DEPRECATED: old way to specify 96x16 screen
// This establishes the screen dimensions in old Adafruit_SSD1306 sketches
// (NEW CODE SHOULD IGNORE THIS, USE THE CONSTRUCTORS THAT ACCEPT WIDTH
// AND HEIGHT ARGUMENTS).

#include "platform.h"

/// The following "raw" color names are kept for backwards client compatability
/// They can be disabled by predefining this macro before including the Adafruit
/// header client code will then need to be modified to use the scoped enum
/// values directly
#ifndef NO_ADAFRUIT_SSD1306_COLOR_COMPATIBILITY
#define BLACK SSD1306_BLACK ///< Draw 'off' pixels
#define WHITE SSD1306_WHITE ///< Draw 'on' pixels
#define INVERSE SSD1306_INVERSE ///< Invert pixels
#endif
/// fit into the SSD1306_ naming scheme
#define SSD1306_BLACK 0 ///< Draw 'off' pixels
#define SSD1306_WHITE 1 ///< Draw 'on' pixels
#define SSD1306_INVERSE 2 ///< Invert pixels

#define SSD1306_MEMORYMODE 0x20 ///< See datasheet
#define SSD1306_COLUMNADDR 0x21 ///< See datasheet
#define SSD1306_PAGEADDR 0x22 ///< See datasheet
#define SSD1306_SETCONTRAST 0x81 ///< See datasheet
#define SSD1306_CHARGEPUMP 0x8D ///< See datasheet
#define SSD1306_SEGREMAP 0xA0 ///< See datasheet
#define SSD1306_DISPLAYALLON_RESUME 0xA4 ///< See datasheet
#define SSD1306_DISPLAYALLON 0xA5 ///< Not currently used
#define SSD1306_NORMALDISPLAY 0xA6 ///< See datasheet
#define SSD1306_INVERTDISPLAY 0xA7 ///< See datasheet
#define SSD1306_SETMULTIPLEX 0xA8 ///< See datasheet
#define SSD1306_DISPLAYOFF 0xAE ///< See datasheet
#define SSD1306_DISPLAYON 0xAF ///< See datasheet
#define SSD1306_COMSCANINC 0xC0 ///< Not currently used
#define SSD1306_COMSCANDEC 0xC8 ///< See datasheet
#define SSD1306_SETDISPLAYOFFSET 0xD3 ///< See datasheet
#define SSD1306_SETDISPLAYCLOCKDIV 0xD5 ///< See datasheet
#define SSD1306_SETPRECHARGE 0xD9 ///< See datasheet
#define SSD1306_SETCOMPINS 0xDA ///< See datasheet
#define SSD1306_SETVCOMDETECT 0xDB ///< See datasheet

#define SSD1306_SETLOWCOLUMN 0x00 ///< Not currently used
#define SSD1306_SETHIGHCOLUMN 0x10 ///< Not currently used
#define SSD1306_SETSTARTLINE 0x40 ///< See datasheet

#define SSD1306_EXTERNALVCC 0x01 ///< External display voltage source
#define SSD1306_SWITCHCAPVCC 0x02 ///< Gen. display voltage from 3.3V

#define SSD1306_RIGHT_HORIZONTAL_SCROLL 0x26 ///< Init rt scroll
#define SSD1306_LEFT_HORIZONTAL_SCROLL 0x27 ///< Init left scroll
#define SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL 0x29 ///< Init diag scroll
#define SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL 0x2A ///< Init diag scroll
#define SSD1306_DEACTIVATE_SCROLL 0x2E ///< Stop scroll
#define SSD1306_ACTIVATE_SCROLL 0x2F ///< Start scroll
#define SSD1306_SET_VERTICAL_SCROLL_AREA 0xA3 ///< Set scroll range

// Deprecated size stuff for backwards compatibility with old sketches
#if defined SSD1306_128_64
#define SSD1306_LCDWIDTH 128 ///< DEPRECATED: width w/SSD1306_128_64 defined
#define SSD1306_LCDHEIGHT 64 ///< DEPRECATED: height w/SSD1306_128_64 defined
#endif
#if defined SSD1306_128_32
#define SSD1306_LCDWIDTH 128 ///< DEPRECATED: width w/SSD1306_128_32 defined
#define SSD1306_LCDHEIGHT 32 ///< DEPRECATED: height w/SSD1306_128_32 defined
#endif
#if defined SSD1306_96_16
#define SSD1306_LCDWIDTH 96 ///< DEPRECATED: width w/SSD1306_96_16 defined
#define SSD1306_LCDHEIGHT 16 ///< DEPRECATED: height w/SSD1306_96_16 defined
#endif

/*!
@brief Class that stores state and functions for interacting with
SSD1306 OLED displays.
*/
class Adafruit_SSD1306 : public Adafruit_GFX {
public:
// NEW CONSTRUCTORS -- recommended for new projects
Adafruit_SSD1306(uint8_t w, uint8_t h, TwoWire *twi = &Wire,
int8_t rst_pin = -1, uint32_t clkDuring = 400000UL,
uint32_t clkAfter = 100000UL);

bool begin(uint8_t switchvcc = SSD1306_SWITCHCAPVCC, uint8_t i2caddr = 0,
bool reset = true, bool periphBegin = true);
void display(void);
void clearDisplay(void);
void invertDisplay(bool i);
void dim(bool dim);
void drawPixel(int16_t x, int16_t y, uint16_t color);
virtual void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
virtual void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
void startscrollright(uint8_t start, uint8_t stop);
void startscrollleft(uint8_t start, uint8_t stop);
void startscrolldiagright(uint8_t start, uint8_t stop);
void startscrolldiagleft(uint8_t start, uint8_t stop);
void stopscroll(void);
void ssd1306_command(uint8_t c);
bool getPixel(int16_t x, int16_t y);
uint8_t *getBuffer(void);
uint8_t setBuffer(uint8_t*);

private:
inline void SPIwrite(uint8_t d) __attribute__((always_inline));
void drawFastHLineInternal(int16_t x, int16_t y, int16_t w, uint16_t color);
void drawFastVLineInternal(int16_t x, int16_t y, int16_t h, uint16_t color);
void ssd1306_command1(uint8_t c);
void ssd1306_commandList(const uint8_t *c, uint8_t n);

TwoWire *wire;
uint8_t *buffer;
int8_t i2caddr, vccstate, page_end;
int8_t mosiPin, clkPin, dcPin, csPin, rstPin;
uint8_t contrast; // normal contrast setting for this device
};

#endif // _Adafruit_SSD1306_H_
34 changes: 34 additions & 0 deletions system/apps_experiments/102_ssd1306/source/app.lds
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
MEMORY
{
rom (rx) : ORIGIN = 0x0801ed00, LENGTH = 60K
ram (rwx) : ORIGIN = 0x20004800, LENGTH = 16K
null (rwx): ORIGIN = 0x00001000, LENGTH = 4K
}

/* _estack = ORIGIN(ram)+LENGTH(ram)-0x100; */

SECTIONS
{
.text : {
*(.entry)
*(.text*) /* Program code */
*(.rodata*) /* Read only data */
} >rom

.data : {
*(.data*) /* Data memory */
/* *(.dynamic*) */
} >ram AT >rom

.bss : {
*(.bss*) /* Zero-filled run time allocate data memory */
} >ram

.rel.plt : { *(.rel.plt) } > ram
.plt : { *(.plt) } > ram
.got : { *(.got.plt) *(.got) } > ram /* relocation fixed by memory write! */
.dynsym : { *(.dynsym) } > null
.dynstr : { *(.dynstr) } > null

}

82 changes: 82 additions & 0 deletions system/apps_experiments/102_ssd1306/source/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#include <library.h>
#include "../../../os_host/source/framework/Console.h"
#include "../../../os_host/source/framework/SimpleApp.h"
#include "Adafruit_SSD1306.h"

Adafruit_SSD1306 display(128, 64, &Wire);
uint8_t buffer[1024];

void setup()
{
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
display.setBuffer(buffer);

if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
CONSOLE::Print("SSD1306 allocation failed\n");
return;
}

// Show initial display buffer contents on the screen --
// the library initializes this with an Adafruit splash screen.
display.display();
BIOS::SYS::DelayMs(500); // Pause for 2 seconds
}

void loop(BIOS::KEY::EKey key)
{
// buffer[rand() & 1023] = rand();

// display.drawBitmap(0, 0, buffer, 128, 64, 1);
static int i = 0;

// for (int j=0; j<500; j++)
// display.drawPixel(rand() & 127, rand() & 63, i++ & 1);

long t0 = BIOS::SYS::GetTick();
for (int x=0; x<128; x++)
for (int y=0; y<64; y++)
display.drawPixel(x, y, ((x+i)/8 + (y+i/2)/8)&1);
i++;
long t1 = BIOS::SYS::GetTick();
display.display();
long t2 = BIOS::SYS::GetTick();


EVERY(1000)
{
static int lastFrame = 0;
int frames = i - lastFrame;
lastFrame = i;
char info[64];
sprintf(info, "%d fps, draw %d ms, transfer %d ms", frames, t1-t0, t2-t1);
APP::Status(info);
}
}


#ifdef _ARM
__attribute__((__section__(".entry")))
#endif
int _main(void)
{
APP::Init("SSD1306 128x64 oled");
APP::Status("P1: SCL, P2: SDA");

setup();

BIOS::KEY::EKey key;
while ((key = BIOS::KEY::GetKey()) != BIOS::KEY::EKey::Escape)
{
loop(key);
}
Wire.end();
return 0;
}

void _HandleAssertion(const char* file, int line, const char* cond)
{
BIOS::DBG::Print("Assertion failed in ");
BIOS::DBG::Print(file);
BIOS::DBG::Print(" [%d]: %s\n", line, cond);
while (1);
}
Loading

0 comments on commit 59729f9

Please sign in to comment.