Hi all,
Going a bit crazy here, seem to be farther behind than I was when I started working on this. Long story short, I’ve got a Newhaven OLED display, 128x32, attached to a Boron over SPI. It’s on a PCB with a few other bits and pieces, but right now I’m testing it in isolation. Earlier today, I had something that vaguely resembled a chopped up version of the image I want, but I’m now at the point that I can’t actually get an image on the screen at all. Can’t even get garbage. I’ve scoped the signal, and it’s definitely there. Rise and fall times aren’t great, but that may be my cheap USB scope more than anything. The code is loosely based on Adafruit’s SSD1305 driver, please note that this is test software and ended up with everything dumped in one file.
#include <Particle.h>
#include <SPI.h>
#define oled_cs_pin A4
#define oled_dc_pin D4
#define oled_reset D7
#define SSD1305_LCDWIDTH 128
#define SSD1305_LCDHEIGHT 32
#define SSD1305_SETLOWCOLUMN 0x00
#define SSD1305_SETHIGHCOLUMN 0x10
#define SSD1305_MEMORYMODE 0x20
#define SSD1305_SETCOLADDR 0x21
#define SSD1305_SETPAGEADDR 0x22
#define SSD1305_SETSTARTLINE 0x40
#define SSD1305_SETCONTRAST 0x81
#define SSD1305_SETBRIGHTNESS 0x82
#define SSD1305_SETLUT 0x91
#define SSD1305_SEGREMAP 0xA0
#define SSD1305_DISPLAYALLON_RESUME 0xA4
#define SSD1305_DISPLAYALLON 0xA5
#define SSD1305_NORMALDISPLAY 0xA6
#define SSD1305_INVERTDISPLAY 0xA7
#define SSD1305_SETMULTIPLEX 0xA8
#define SSD1305_DISPLAYDIM 0xAC
#define SSD1305_MASTERCONFIG 0x8E // AD
#define SSD1305_DISPLAYOFF 0xAE
#define SSD1305_DISPLAYON 0xAF
#define SSD1305_SETPAGESTART 0xB0
#define SSD1305_COMSCANINC 0xC0
#define SSD1305_COMSCANDEC 0xC8
#define SSD1305_SETDISPLAYOFFSET 0xD3
#define SSD1305_SETDISPLAYCLOCKDIV 0xD5
#define SSD1305_SETAREACOLOR 0xD8
#define SSD1305_SETPRECHARGE 0xD9
#define SSD1305_SETCOMPINS 0xDA
#define SSD1305_SETVCOMLEVEL 0xDB
__SPISettings spi_settings{1*MHZ, MSBFIRST, SPI_MODE0};
static uint8_t buffer[SSD1305_LCDHEIGHT * SSD1305_LCDWIDTH / 8] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xF8,
0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xF0, 0x18, 0x08, 0x08, 0x18, 0xF0, 0xE0, 0x00, 0xE0, 0xF0,
0x18, 0x08, 0x88, 0x98, 0x90, 0x00, 0xE0, 0xF0, 0x18, 0x08, 0x88, 0x98, 0x90, 0x00, 0xF8, 0xF8,
0x00, 0xF8, 0xF8, 0x70, 0xC0, 0x00, 0xF8, 0xF8, 0x00, 0xE0, 0xF0, 0x18, 0x08, 0x88, 0x98, 0x90,
0x00, 0x00, 0x00, 0x00, 0xF8, 0xF8, 0x88, 0x88, 0x88, 0x00, 0xE0, 0xF8, 0x18, 0xF8, 0xE0, 0x00,
0x00, 0xF8, 0xF8, 0x00, 0xF8, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xF8, 0x00, 0x00, 0x00,
0xF8, 0xF8, 0x00, 0xF8, 0xF8, 0x88, 0x88, 0x88, 0xF8, 0x70, 0x00, 0xF8, 0xF8, 0x88, 0x88, 0x88,
0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F,
0x08, 0x08, 0x08, 0x08, 0x00, 0x03, 0x07, 0x0C, 0x08, 0x08, 0x0C, 0x07, 0x03, 0x00, 0x03, 0x07,
0x0C, 0x08, 0x08, 0x0F, 0x07, 0x00, 0x03, 0x07, 0x0C, 0x08, 0x08, 0x0F, 0x07, 0x00, 0x0F, 0x0F,
0x00, 0x0F, 0x0F, 0x00, 0x01, 0x07, 0x0F, 0x0F, 0x00, 0x03, 0x07, 0x0C, 0x08, 0x08, 0x0F, 0x07,
0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0E, 0x0F, 0x03, 0x02, 0x03, 0x0F, 0x0E,
0x00, 0x0F, 0x0F, 0x00, 0x0F, 0x0F, 0x08, 0x08, 0x08, 0x08, 0x00, 0x07, 0x0F, 0x08, 0x08, 0x08,
0x0F, 0x07, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x01, 0x07, 0x0E, 0x08, 0x0F, 0x0F, 0x08, 0x08, 0x08,
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF8, 0x0C, 0x04, 0x04, 0x0C, 0x08, 0x00, 0xF0,
0xF8, 0x0C, 0x04, 0x04, 0x0C, 0xF8, 0xF0, 0x00, 0xFC, 0xFC, 0x38, 0xE0, 0x80, 0xFC, 0xFC, 0x00,
0x04, 0x04, 0xFC, 0xFC, 0x04, 0x04, 0x00, 0xF0, 0xFC, 0x0C, 0xFC, 0xF0, 0x00, 0x00, 0xF0, 0xF8,
0x0C, 0x04, 0x04, 0x0C, 0x08, 0x00, 0x04, 0x04, 0xFC, 0xFC, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00,
0x38, 0x7C, 0x64, 0xE4, 0xC4, 0xCC, 0x88, 0x00, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0xFC, 0x00,
0xFC, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0x78, 0x00, 0xFC, 0xFC, 0x84, 0x84, 0x84, 0xFC, 0x78, 0x00,
0xF0, 0xF8, 0x0C, 0x04, 0x04, 0x0C, 0xF8, 0xF0, 0x00, 0xFC, 0xFC, 0x44, 0x44, 0xC4, 0xFC, 0x38,
0x00, 0x04, 0x04, 0xFC, 0xFC, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x04, 0x04, 0x06, 0x02, 0x00, 0x01,
0x03, 0x06, 0x04, 0x04, 0x06, 0x03, 0x01, 0x00, 0x07, 0x07, 0x00, 0x00, 0x03, 0x07, 0x07, 0x00,
0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x07, 0x07, 0x01, 0x01, 0x01, 0x07, 0x07, 0x00, 0x01, 0x03,
0x06, 0x04, 0x04, 0x06, 0x02, 0x00, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x06, 0x04, 0x04, 0x04, 0x07, 0x03, 0x00, 0x03, 0x07, 0x04, 0x04, 0x04, 0x07, 0x03, 0x00,
0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x03, 0x06, 0x04, 0x04, 0x06, 0x03, 0x01, 0x00, 0x07, 0x07, 0x00, 0x00, 0x00, 0x03, 0x07,
0x04, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
SYSTEM_THREAD(ENABLED);
void setup() {
SPI.begin();
Serial.begin(57600);
delay(1000);
pinMode(oled_cs_pin, OUTPUT);
pinMode(oled_dc_pin, OUTPUT);
pinMode(oled_reset, OUTPUT);
digitalWrite(oled_reset, LOW);
delay(5);
digitalWrite(oled_reset, HIGH);
delay(5);
digitalWrite(oled_cs_pin, LOW);
digitalWrite(oled_dc_pin, LOW);
delay(1);
while(SPI.beginTransaction(spi_settings) < 0);
Command(SSD1305_DISPLAYOFF);
Command(SSD1305_SETDISPLAYCLOCKDIV);
Command(0x10);
Command(SSD1305_SETMULTIPLEX);
Command(0x1F);
Command(SSD1305_SETPRECHARGE);
Command(0xD2);
Command(SSD1305_SEGREMAP | 0x01);
Command(SSD1305_COMSCANDEC);
Command(SSD1305_SETCOMPINS);
Command(0x12);
Command(SSD1305_SETVCOMLEVEL);
Command(0x08);
Command(SSD1305_SETPAGEADDR);
Command(0x03);
Command(0x07);
Command(SSD1305_SETCOLADDR);
Command(0x04);
Command(0x83);
Command(SSD1305_DISPLAYALLON_RESUME);
Command(SSD1305_NORMALDISPLAY);
Command(SSD1305_SETSTARTLINE|0x20);
Command(SSD1305_DISPLAYON);
SPI.endTransaction();
Serial.println("Setup complete.");
digitalWrite(oled_cs_pin, HIGH);
}
void loop() {
digitalWrite(oled_cs_pin, LOW);
while(SPI.beginTransaction(spi_settings) < 0);
uint16_t x = 0;
for(int page = 4; page < 8; page++){
digitalWrite(oled_dc_pin, LOW);
Command(SSD1305_SETPAGESTART + page);
Command(SSD1305_SETLOWCOLUMN | 0);
Command(SSD1305_SETHIGHCOLUMN | 0);
delay(1);
digitalWrite(oled_dc_pin, HIGH);
for(uint8_t w = 0; w <128; w++){
SPI.transfer(buffer[x++]);
}
}
digitalWrite(oled_cs_pin, HIGH);
SPI.endTransaction();
delay(150);
}
void Command(uint8_t comm){
digitalWrite(oled_dc_pin, LOW);
SPI.transfer(comm);
}
I’m running the Boron on 1.1.1 through Workbench. Anyone have a thought or two? Oh, the non-standard CS pin is right, I’ve got a MicroSD card on the same bus.
Thanks,
Peter