Skip to content

Commit

Permalink
Add drivers for SSD1327 and the SSD1351. (#625)
Browse files Browse the repository at this point in the history
Add color display driver and oled color display driver / template. These are closely related to display and oled_display.
Updated daisy to include the color driver and the OLED color driver.
  • Loading branch information
a7v7 authored Sep 20, 2024
1 parent 98a6626 commit 480ea8e
Show file tree
Hide file tree
Showing 5 changed files with 1,084 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/daisy.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
#include "per/rng.h"
#include "hid/disp/display.h"
#include "hid/disp/oled_display.h"
#include "hid/disp/color_display.h"
#include "hid/disp/oled_color_display.h"
#include "hid/disp/graphics_common.h"
#include "hid/wavplayer.h"
#include "hid/led.h"
Expand Down
233 changes: 233 additions & 0 deletions src/dev/oled_ssd1327.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
#pragma once

#include "per/spi.h"
#include "per/gpio.h"
#include "sys/system.h"

namespace daisy
{

/**
* 4 Wire SPI Transport for SSD1327 OLED display devices
*/
class SSD13274WireSpiTransport
{
public:
struct Config
{
Config()
{
// Initialize using defaults
Defaults();
}
SpiHandle::Config spi_config;
struct
{
dsy_gpio_pin dc; /**< & */
dsy_gpio_pin reset; /**< & */
} pin_config;
void Defaults()
{
// SPI peripheral config
spi_config.periph = SpiHandle::Config::Peripheral::SPI_1;
spi_config.mode = SpiHandle::Config::Mode::MASTER;
spi_config.direction
= SpiHandle::Config::Direction::TWO_LINES_TX_ONLY;
spi_config.datasize = 8;
spi_config.clock_polarity = SpiHandle::Config::ClockPolarity::LOW;
spi_config.clock_phase = SpiHandle::Config::ClockPhase::ONE_EDGE;
spi_config.nss = SpiHandle::Config::NSS::HARD_OUTPUT;
spi_config.baud_prescaler = SpiHandle::Config::BaudPrescaler::PS_8;
// SPI pin config
spi_config.pin_config.sclk = {DSY_GPIOG, 11};
spi_config.pin_config.miso = {DSY_GPIOX, 0};
spi_config.pin_config.mosi = {DSY_GPIOB, 5};
spi_config.pin_config.nss = {DSY_GPIOG, 10};
// SSD1327 control pin config
pin_config.dc = {DSY_GPIOB, 4};
pin_config.reset = {DSY_GPIOB, 15};
}
};
void Init(const Config& config)
{
// Initialize both GPIO
pin_dc_.mode = DSY_GPIO_MODE_OUTPUT_PP;
pin_dc_.pin = config.pin_config.dc;
dsy_gpio_init(&pin_dc_);
pin_reset_.mode = DSY_GPIO_MODE_OUTPUT_PP;
pin_reset_.pin = config.pin_config.reset;
dsy_gpio_init(&pin_reset_);

// Initialize SPI
spi_.Init(config.spi_config);

// Reset and Configure OLED.
dsy_gpio_write(&pin_reset_, 0);
System::Delay(10);
dsy_gpio_write(&pin_reset_, 1);
System::Delay(10);
};
void SendCommand(uint8_t cmd)
{
dsy_gpio_write(&pin_dc_, 0);
spi_.BlockingTransmit(&cmd, 1);
};

void SendData(uint8_t* buff, size_t size)
{
dsy_gpio_write(&pin_dc_, 1);
spi_.BlockingTransmit(buff, size);
};

private:
SpiHandle spi_;
dsy_gpio pin_reset_;
dsy_gpio pin_dc_;
};


/**
* A driver implementation for the SSD1327
*/
template <size_t width, size_t height, typename Transport>
class SSD1327Driver
{
public:
struct Config
{
typename Transport::Config transport_config;
};

void Init(Config config)
{
color_ = 0x0f;
transport_.Init(config.transport_config);

transport_.SendCommand(0x15); // set column address
transport_.SendCommand(0x00); // start column 0
transport_.SendCommand(0x3f); // end column 63*2 (two pixels / byte)

transport_.SendCommand(0x75); // set row address
transport_.SendCommand(0x00); // start row 0
transport_.SendCommand(0x7f); // end row 127

transport_.SendCommand(0x81); // set contrast control
transport_.SendCommand(0x80);

transport_.SendCommand(0xa0); // Set Re-map (0x51)
transport_.SendCommand(0x51); // Column Address Remapping, COM Remapping, Splitting of Odd / Even COM Signals

transport_.SendCommand(0xa1); // start line
transport_.SendCommand(0x00);

transport_.SendCommand(0xa2); // display offset
transport_.SendCommand(0x00);

transport_.SendCommand(0xa4); // normal display
transport_.SendCommand(0xa8); // set multiplex ratio
transport_.SendCommand(0x7f);

transport_.SendCommand(0xb1); // set phase length
transport_.SendCommand(0xf1);

transport_.SendCommand(0xb3); // set dclk
transport_.SendCommand(0x00); // 80Hz:0xc1 / 90Hz:0xe1 / 100Hz:0x00 / 110Hz:0x30 / 120Hz:0x50 / 130Hz:0x70

transport_.SendCommand(0xab); // Function Selection A
transport_.SendCommand(0x01);

transport_.SendCommand(0xb6); // set phase length
transport_.SendCommand(0x0f);

transport_.SendCommand(0xbe); // Set VCOMH
transport_.SendCommand(0x0f);

transport_.SendCommand(0xbc); // Set Pre-charge voltage
transport_.SendCommand(0x08);

transport_.SendCommand(0xd5); // Function Selection B
transport_.SendCommand(0x62); // Enable second pre-charge

transport_.SendCommand(0xfd); // unlock command
transport_.SendCommand(0x12);

System::Delay(200); // wait 200ms
transport_.SendCommand(0xaf); // turn on display
Fill(false);
};

size_t Width() const { return width; };
size_t Height() const { return height; };

void DrawPixel(uint_fast8_t x, uint_fast8_t y, bool on)
{
uint8_t pixel;
uint32_t line = width/2;

if ((x >= width) || (y >= height))
return;

if (on) {
pixel = buffer_[y * line + (x / 2)];
if (x % 2) {
pixel &= 0xf0;
pixel |= color_;
} else {
pixel &= 0x0f;
pixel |= color_ << 4;
}
buffer_[y * line + (x / 2)] = pixel;
}
else {
pixel = buffer_[y * line + (x / 2)];
if (x % 2) {
pixel &= 0xf0;
} else {
pixel &= 0x0f;
}
buffer_[y * line + (x / 2)] = pixel;
}
};

void Fill(bool on)
{
for(size_t i = 0; i < sizeof(buffer_); i++)
{
buffer_[i] = on ? 0xff : 0x00;
}
};

/**
* Update the display
*/
void Update()
{
transport_.SendCommand(0x15); // column
transport_.SendCommand(0x00);
transport_.SendCommand((width/2)-1);

transport_.SendCommand(0x75); // row
transport_.SendCommand(0x00);
transport_.SendCommand(height-1);

//write data
transport_.SendData(buffer_, 8192);
};

void Set_Color(uint8_t in_col)
{
color_ = in_col & 0x0f;
};

protected:
Transport transport_;
uint8_t buffer_[width/2 * height];
uint8_t color_;
};

/**
* A driver for the SSD1327 128x128 OLED displays connected via 4 wire SPI
*/
using SSD13274WireSpi128x128Driver = daisy::SSD1327Driver<128, 128, SSD13274WireSpiTransport>;

}; // namespace daisy
Loading

0 comments on commit 480ea8e

Please sign in to comment.