Initial commit
This commit is contained in:
commit
23c1df474c
12
CMakeLists.txt
Normal file
12
CMakeLists.txt
Normal file
@ -0,0 +1,12 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
add_library(picoled
|
||||
include/picoled.h
|
||||
include/picoled/SSD1306.h
|
||||
|
||||
src/picoled.cpp
|
||||
src/SSD1306.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(picoled PUBLIC hardware_i2c pico_stdlib)
|
||||
target_include_directories(picoled PUBLIC include)
|
59
include/picoled.h
Normal file
59
include/picoled.h
Normal file
@ -0,0 +1,59 @@
|
||||
#ifndef PICOLED_H
|
||||
#define PICOLED_H
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace picoled
|
||||
{
|
||||
|
||||
class pixel
|
||||
{
|
||||
public:
|
||||
pixel() :
|
||||
pixel(false)
|
||||
{}
|
||||
|
||||
pixel(bool on) :
|
||||
on(on)
|
||||
{}
|
||||
|
||||
bool is_on() const { return on; }
|
||||
void invert() { on = !on; }
|
||||
|
||||
private:
|
||||
bool on;
|
||||
};
|
||||
|
||||
class oled
|
||||
{
|
||||
public:
|
||||
oled(size_t width, size_t height);
|
||||
virtual ~oled();
|
||||
|
||||
oled(const oled&) = delete;
|
||||
oled(oled&&) = delete;
|
||||
|
||||
oled& operator=(const oled&) = delete;
|
||||
oled& operator=(oled&&) = delete;
|
||||
|
||||
pixel& operator()(int x, int y);
|
||||
const pixel& operator()(int x, int y) const;
|
||||
|
||||
void clear();
|
||||
|
||||
size_t get_width() const { return width; }
|
||||
size_t get_height() const { return height; }
|
||||
|
||||
virtual void update() const = 0;
|
||||
|
||||
protected:
|
||||
size_t width;
|
||||
size_t height;
|
||||
|
||||
private:
|
||||
pixel* pixels;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif//PICOLED_H
|
31
include/picoled/SSD1306.h
Normal file
31
include/picoled/SSD1306.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef PICOLED_SSD1306_H
|
||||
#define PICOLED_SSD1306_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <hardware/i2c.h>
|
||||
|
||||
#include "picoled.h"
|
||||
|
||||
namespace picoled
|
||||
{
|
||||
|
||||
class ssd1306 : public oled
|
||||
{
|
||||
public:
|
||||
ssd1306(i2c_inst* i2c, uint8_t address);
|
||||
virtual ~ssd1306();
|
||||
|
||||
void update() const override;
|
||||
|
||||
private:
|
||||
void command(uint8_t cmd) const;
|
||||
|
||||
i2c_inst* i2c;
|
||||
uint8_t address;
|
||||
uint8_t* buffer;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif//PICOLED_SSD1306_H
|
110
src/SSD1306.cpp
Normal file
110
src/SSD1306.cpp
Normal file
@ -0,0 +1,110 @@
|
||||
#include "picoled/SSD1306.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
// https://cdn-shop.adafruit.com/datasheets/SSD1306.pdf
|
||||
namespace
|
||||
{
|
||||
|
||||
constexpr uint8_t MEMORY_MODE = 0x20;
|
||||
constexpr uint8_t COLUMN_ADDRESS = 0x21;
|
||||
constexpr uint8_t PAGE_ADDRESS = 0x22;
|
||||
constexpr uint8_t CONTRAST = 0x81;
|
||||
constexpr uint8_t CHARGE_PUMP = 0x8D;
|
||||
constexpr uint8_t SEGMENT_REMAP = 0xA0;
|
||||
constexpr uint8_t ALLON_RESUME = 0xA4;
|
||||
constexpr uint8_t ALLON = 0xA5;
|
||||
constexpr uint8_t NORMAL_DISPLAY = 0xA6;
|
||||
constexpr uint8_t INVERT_DISPLAY = 0xA7;
|
||||
constexpr uint8_t MULTIPLEX = 0xA8;
|
||||
constexpr uint8_t OFF = 0xAE;
|
||||
constexpr uint8_t ON = 0xAF;
|
||||
constexpr uint8_t COMSCAN_INC = 0xC0;
|
||||
constexpr uint8_t COMSCAN_DEC = 0xC8;
|
||||
constexpr uint8_t OFFSET = 0xD3;
|
||||
constexpr uint8_t CLKDIV = 0xD5;
|
||||
constexpr uint8_t PRECHARGE = 0xD9;
|
||||
constexpr uint8_t COMPINS = 0xDA;
|
||||
constexpr uint8_t VCOM_DETECT = 0xDB;
|
||||
constexpr uint8_t LOW_COLUMN = 0x00;
|
||||
constexpr uint8_t HIGH_COLUMN = 0x10;
|
||||
constexpr uint8_t STARTLINE = 0x40;
|
||||
constexpr uint8_t RIGHT_HSCROLL = 0x26;
|
||||
constexpr uint8_t LEFT_HSCROLL = 0x27;
|
||||
constexpr uint8_t VRIGHT_HSCROLL = 0x29;
|
||||
constexpr uint8_t VLEFT_HSCROLL = 0x2A;
|
||||
constexpr uint8_t SCROLL_OFF = 0x2E;
|
||||
constexpr uint8_t SCROLL_ON = 0x2F;
|
||||
constexpr uint8_t VSCROLL_AREA = 0xA3;
|
||||
|
||||
}
|
||||
|
||||
namespace picoled
|
||||
{
|
||||
|
||||
ssd1306::ssd1306(i2c_inst* i2c, uint8_t address) :
|
||||
oled(128, 64),
|
||||
i2c(i2c),
|
||||
address(address),
|
||||
buffer(new uint8_t[128 * 64 / 8 + 1])
|
||||
{
|
||||
// the user is expected to set GPIO func and pullup
|
||||
// as well as initialize the i2c instance
|
||||
|
||||
command(OFF);
|
||||
command(CLKDIV); command(0x80);
|
||||
command(MULTIPLEX); command(63);
|
||||
command(OFFSET); command(0);
|
||||
command(STARTLINE | 0);
|
||||
command(MEMORY_MODE); command(0);
|
||||
command(SEGMENT_REMAP | 0);
|
||||
command(COMSCAN_DEC);
|
||||
command(COMPINS); command(0x12);
|
||||
command(CONTRAST); command(0xCF);
|
||||
command(PRECHARGE); command(0x22);
|
||||
command(VCOM_DETECT); command(0x40);
|
||||
command(NORMAL_DISPLAY);
|
||||
command(SCROLL_OFF);
|
||||
command(CHARGE_PUMP); command(0x14);
|
||||
command(ALLON_RESUME);
|
||||
command(ON);
|
||||
|
||||
buffer[0] = 0x40;
|
||||
}
|
||||
|
||||
ssd1306::~ssd1306()
|
||||
{
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
void ssd1306::update() const
|
||||
{
|
||||
// clear display to zero
|
||||
memset(&buffer[1], 0, width * height * sizeof(*buffer));
|
||||
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
if (!(*this)(x, y).is_on()) { continue; }
|
||||
|
||||
const int index = (width - x - 1) + (y / 8) * width;
|
||||
const uint8_t bits = 1 << (y & 7);
|
||||
|
||||
// add one to leave room for 0x40 data indicator at beginning of array
|
||||
buffer[index + 1] |= bits;
|
||||
}
|
||||
}
|
||||
|
||||
command(PAGE_ADDRESS); command(0); command(7);
|
||||
command(COLUMN_ADDRESS); command(0); command(width - 1);
|
||||
i2c_write_blocking(i2c, address, buffer, width * height / 8 + 1, false);
|
||||
}
|
||||
|
||||
void ssd1306::command(uint8_t cmd) const
|
||||
{
|
||||
const uint8_t values[2] = { 0x00, cmd };
|
||||
i2c_write_blocking(i2c, address, values, 2, false);
|
||||
}
|
||||
|
||||
}
|
35
src/picoled.cpp
Normal file
35
src/picoled.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
#include "picoled.h"
|
||||
|
||||
namespace picoled
|
||||
{
|
||||
|
||||
oled::oled(size_t width, size_t height) :
|
||||
pixels(new pixel[width * height]),
|
||||
width(width),
|
||||
height(height)
|
||||
{}
|
||||
|
||||
oled::~oled()
|
||||
{
|
||||
delete[] pixels;
|
||||
}
|
||||
|
||||
pixel& oled::operator()(int x, int y)
|
||||
{
|
||||
return pixels[x + y * width];
|
||||
}
|
||||
|
||||
const pixel& oled::operator()(int x, int y) const
|
||||
{
|
||||
return pixels[x + y * width];
|
||||
}
|
||||
|
||||
void oled::clear()
|
||||
{
|
||||
for (int i = 0; i < width * height; i++)
|
||||
{
|
||||
pixels[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user