Rev 128 | Blame | Compare with Previous | Last modification | View Log | RSS feed
#include <avr/io.h>
#include <stdlib.h>
#include <avr/pgmspace.h>
#include "wire.h"
#include "avrutil.h"
#include <util/delay.h>
#include <string.h>
#include "oled.h"
#define OLED_SETCONTRAST 0x81
#define OLED_DISPLAYALLON_RESUME 0xA4
#define OLED_DISPLAYALLON 0xA5
#define OLED_NORMALDISPLAY 0xA6
#define OLED_INVERTDISPLAY 0xA7
#define OLED_DISPLAYOFF 0xAE
#define OLED_DISPLAYON 0xAF
#define OLED_SETDISPLAYOFFSET 0xD3
#define OLED_SETCOMPINS 0xDA
#define OLED_SETVCOMDETECT 0xDB
#define OLED_SETDISPLAYCLOCKDIV 0xD5
#define OLED_SETPRECHARGE 0xD9
#define OLED_SETMULTIPLEX 0xA8
#define OLED_SETLOWCOLUMN 0x00
#define OLED_SETHIGHCOLUMN 0x10
#define OLED_SETSTARTLINE 0x40
#define OLED_MEMORYMODE 0x20
#define OLED_COMSCANINC 0xC0
#define OLED_COMSCANDEC 0xC8
#define OLED_SEGREMAP 0xA0
#define OLED_CHARGEPUMP 0x8D
/**
* Color is simply true (white) or false (black)
*/
void oled_drawPixel(uint8_t* buffer, uint16_t x, uint16_t y, uint8_t color) {
if (color)
buffer[x+ (y/8)*oled.width] |= _BV((y%8));
else
buffer[x+ (y/8)*oled.width] &= ~_BV((y%8));
}
void oled_invert(uint8_t i) {
if (i)
oled_cmd(OLED_INVERTDISPLAY);
else
oled_cmd(OLED_NORMALDISPLAY);
}
uint8_t* oled_getBuffer(void) {
return oled.buffer;
}
uint8_t* oled_init(uint8_t width, uint8_t height, uint8_t vccstate, uint8_t address) {
oled.i2c_addr = address;
oled.width = width;
oled.height = height;
oled.buffer = malloc((oled.height * oled.width / 8) * sizeof(uint8_t));
//Reset high, (1), Low (10), High
// Init Sequence
oled_cmd(OLED_DISPLAYOFF);
oled_cmd(OLED_SETDISPLAYCLOCKDIV);
oled_cmd(0x80); // ratio
oled_cmd(OLED_SETMULTIPLEX);
oled_cmd(0x3F);
oled_cmd(OLED_SETDISPLAYOFFSET);
oled_cmd(0x0);
oled_cmd(OLED_SETSTARTLINE | 0x0); // line 0
oled_cmd(OLED_CHARGEPUMP);
(vccstate) ? oled_cmd(0x14) : oled_cmd(0x10);
oled_cmd(OLED_MEMORYMODE);
oled_cmd(0x00);
oled_cmd(OLED_SEGREMAP | 0x01);
oled_cmd(OLED_COMSCANDEC);
oled_cmd(OLED_SETCOMPINS);
oled_cmd(0x12);
oled_cmd(OLED_SETCONTRAST);
(vccstate) ? oled_cmd(0xCF) : oled_cmd(0x9F);
oled_cmd(OLED_SETPRECHARGE);
(vccstate) ? oled_cmd(0xF1) : oled_cmd(0x22);
oled_cmd(OLED_SETVCOMDETECT);
oled_cmd(0x40);
oled_cmd(OLED_DISPLAYALLON_RESUME);
oled_cmd(OLED_NORMALDISPLAY);
oled_cmd(OLED_DISPLAYON);
return oled.buffer;
}
inline void oled_cmd(uint8_t cmd) {
const uint8_t CONTROL = 0x00;
oled_write(CONTROL, cmd);
}
inline void oled_data(uint8_t data) {
const uint8_t CONTROL = 0x04;
oled_write(CONTROL, data);
}
void oled_write(uint8_t control, uint8_t data) {
i2c_beginTransmission(oled.i2c_addr);
i2c_writeByte(control);
i2c_writeByte(data);
i2c_endTransmission(1);
}
void oled_clear(void) {
memset(oled.buffer, 0, (oled.width*oled.height/8));
}
void oled_power(uint8_t pwr) {
if (pwr)
oled_cmd(OLED_DISPLAYON);
else
oled_cmd(OLED_DISPLAYOFF);
}
void oled_display(void) {
oled_cmd(OLED_SETLOWCOLUMN | 0x0);
oled_cmd(OLED_SETHIGHCOLUMN | 0x0);
oled_cmd(OLED_SETSTARTLINE | 0x0);
uint16_t i;
for (i=0; i<(oled.width * oled.height / 8); i++) {
// @todo: Get twi to send 17 bytes
// Need to fix this up
// my twi lib can only send 4 bytes at a time...
// though can change to 15 if needed
// still not enough to send full block
uint8_t x;
for (x=0; x<16; x++) {
i2c_beginTransmission(oled.i2c_addr);
i2c_writeByte(0x40);
i2c_writeByte(oled.buffer[i]);
i2c_endTransmission(1);
i++;
}
i--;
}
}