http://www.ebay.com/itm/281648238188?_t ... 2749.l2649
The controller can also do I2C and a couple other connections, but I went with SPI for faster updates. As it turns out, SPI provides plenty of bandwidth. With a SPI clock speed of 32 MHz, I can rewrite the entire screen ~930 times per second. I'm not sure if the LED pixels update that fast or not, would need a high speed camera to test. It looks smooth though.
There are libraries out there for this controller for the Arduino, so between reading through those and reading the datasheet, I came up with code to use this display with the Netburner.
A couple notes:
1) There is no data to read from the controller, so there is no MISO line. It does use three SPI lines (CLK, MOSI, and CS) plus two additional GPIO, one to reset the display, and one to specify if the data coming into the display is commands or display data.
2) The controller supports a resolution of 132x64, but the display is only 128x64. The displayed data is centered in the array, so if you set the command bits to flip the screen horizontally or vertically, the image will still be complete.
3) Writing data to the screen requires you to send a command byte to specify where you want to write the data, then you can write data to the location, up to the end of the line.
Code: Select all
//Demo of a 1.3" OLED display via SPI 3 on a NANO54415. 128x64 pixels
#include "predef.h"
#include <stdio.h>
#include <ctype.h>
#include <startnet.h>
#include <autoupdate.h>
#include <pins.h>
#include <dspi.h>
extern "C" {
void UserMain(void * pd);
}
const char * AppName="OLED Display Demo";
OS_SEM DSPI_SEM;
void SendToOLED(bool IsData, BYTE *data, int count) {
if (IsData) { //Data
Pins[39].set();
} else { //Commands
Pins[39].clr();
}
DSPIStart(3, data, NULL, count, &DSPI_SEM); //Send data via DSPI
OSSemPend( &DSPI_SEM, 0 );
}
void SendToOLED(bool IsData, BYTE b) {
BYTE data[1];
data[0] = b;
SendToOLED(IsData, data, 1);
}
void gotoXY(BYTE page, BYTE column) {
if (column > 127) column = 127;
if (page > 7) page = 7;
column = column + 2; //Panel is 128 pixels wide, controller RAM has space for 132. It's centered so add an offset to ram address.
SendToOLED(false, 0xB0 + page); //Set Page Address: (B0H - B7H)
SendToOLED(false, column & 0x0F); //Set Lower column address
SendToOLED(false, 0x10 | (column >> 4)); //Set Higher column address
}
void UserMain(void * pd) {
InitializeStack();
OSChangePrio(MAIN_PRIO);
EnableAutoUpdate();
Pins[34].function(PIN_34_DSPI3_SOUT); //SPI3 MOSI, connects to pin "D1"
Pins[36].function(PIN_36_DSPI3_PCS0); //SPI3 CS0, connects to pin "CS"
Pins[38].function(PIN_38_DSPI3_SCK); //SPI3 CLK, connects to pin "D0"
Pins[37].function(PIN_37_GPIO); //OLED Reset pin
Pins[39].function(PIN_39_GPIO); //OLED Data/Command pin
Pins[37].clr(); //Reset display
OSTimeDly(5);
Pins[37].set();
OSTimeDly(2);
OSSemInit(&DSPI_SEM, 0);
DSPIInit(3, 2000000, 8, 0xFE, 1, 1); //Device is on SPI3 and we'll use 2 MHz
SendToOLED(false, 0xAE); //Set Display OFF (sleep mode)
for (int i = 0; i < 8; i++) { //For each of the 8 pages
gotoXY(i, 0);
for (int j = 0; j < 128; j++) { //For each of the 128 columns wide
SendToOLED(true, 0x00); //Set the byte to zero to clear any display data that was there
}
}
SendToOLED(false, 0xAF); //Set Display ON (normal mode)
iprintf("Application started\n");
bool flipflop = false;
int currentpage = 0;
while (1) {
gotoXY(currentpage, 0);
for (int i=0; i<128; i++) {
if (flipflop) {
SendToOLED(true, 0xFF); //Write all white
} else {
SendToOLED(true, i); //Write binary value
}
}
currentpage++;
if (currentpage == 8) {
currentpage = 0;
flipflop = !flipflop;
}
OSTimeDly(20);
}
}