2020-05-30 17:10:34 +00:00
|
|
|
#include "display.h"
|
|
|
|
|
2020-05-31 13:36:49 +00:00
|
|
|
#include <Arduino.h>
|
|
|
|
#include <string.h>
|
2020-05-30 17:10:34 +00:00
|
|
|
|
|
|
|
void temporary(){
|
|
|
|
|
|
|
|
const uint8_t resetPin = 4;
|
|
|
|
|
|
|
|
// Adafruit_SSD1306 display(width, height, &Wire, resetPin);
|
|
|
|
Display display(resetPin);
|
|
|
|
|
|
|
|
|
|
|
|
// / address for I2C 128x32
|
|
|
|
// display.begin(SSD1306_SWITCHCAPVCC, 0x3C)
|
2020-05-30 17:17:45 +00:00
|
|
|
display.begin();
|
2020-05-30 17:10:34 +00:00
|
|
|
|
|
|
|
// display.clearDisplay();
|
2020-05-31 13:36:49 +00:00
|
|
|
display.clear(); // no need to call display() after to apply
|
2020-05-30 17:10:34 +00:00
|
|
|
|
|
|
|
// display.drawPixel(x, y, SSD1306_WHITE)
|
|
|
|
// display.drawPixel(x, y, SSD1306_BLACK)
|
|
|
|
|
2020-05-30 17:29:36 +00:00
|
|
|
// display.display()
|
2020-05-30 17:10:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Display::send_command(const uint8_t c){
|
|
|
|
_wire->beginTransmission(_i2caddr);
|
|
|
|
_wire->write((uint8_t) 0x00);
|
|
|
|
_wire->write(c);
|
|
|
|
_wire->endTransmission();
|
|
|
|
}
|
|
|
|
|
2020-05-31 13:36:49 +00:00
|
|
|
void Display::send_commands(const uint8_t *cc, uint8_t n){
|
2020-05-30 17:10:34 +00:00
|
|
|
_wire->beginTransmission(_i2caddr);
|
|
|
|
_wire->write((uint8_t) 0x00);
|
|
|
|
uint8_t written = 1;
|
|
|
|
while(n--){
|
|
|
|
if( written >= WIRE_MAX ){
|
|
|
|
_wire->endTransmission();
|
|
|
|
_wire->beginTransmission(_i2caddr);
|
|
|
|
_wire->write((uint8_t) 0x00);
|
|
|
|
written = 1;
|
|
|
|
}
|
|
|
|
_wire->write(pgm_read_byte(cc++));
|
|
|
|
written++;
|
|
|
|
}
|
|
|
|
_wire->endTransmission();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-05-31 13:36:49 +00:00
|
|
|
Display::Display(const uint8_t resetPin){
|
2020-05-30 17:10:34 +00:00
|
|
|
_rstPin = resetPin;
|
|
|
|
_wire = &Wire;
|
2020-05-31 20:13:05 +00:00
|
|
|
_buffer = (uint8_t*) malloc(_width * ((_height + 7) / 8));
|
2020-05-30 17:17:45 +00:00
|
|
|
}
|
2020-05-30 17:10:34 +00:00
|
|
|
|
2020-05-30 17:17:45 +00:00
|
|
|
void Display::begin(){
|
2020-05-31 13:36:49 +00:00
|
|
|
_wire->begin();
|
2020-05-30 17:10:34 +00:00
|
|
|
|
|
|
|
// reset sequence
|
|
|
|
if( _rstPin >= 0 ){
|
2020-05-31 13:36:49 +00:00
|
|
|
pinMode(_rstPin, OUTPUT);
|
|
|
|
digitalWrite(_rstPin, HIGH);
|
2020-05-30 17:10:34 +00:00
|
|
|
delay(1);
|
2020-05-31 13:36:49 +00:00
|
|
|
digitalWrite(_rstPin, LOW);
|
2020-05-30 17:10:34 +00:00
|
|
|
delay(10);
|
2020-05-31 13:36:49 +00:00
|
|
|
digitalWrite(_rstPin, HIGH);
|
2020-05-30 17:10:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TRANSACTION_START
|
|
|
|
|
|
|
|
// init sequence
|
|
|
|
static const uint8_t PROGMEM init1[] = {
|
|
|
|
DSP_DISPLAYOFF,
|
|
|
|
DSP_SETDISPLAYCLOCKDIV,
|
|
|
|
0x80, // suggested ratio
|
|
|
|
DSP_SETMULTIPLEX
|
|
|
|
};
|
|
|
|
send_commands(init1, sizeof(init1));
|
|
|
|
send_command(_height - 1);
|
|
|
|
|
|
|
|
static const uint8_t PROGMEM init2[] = {
|
|
|
|
DSP_SETDISPLAYOFFSET,
|
|
|
|
0x0,
|
|
|
|
DSP_SETSTARTLINE | 0x0,
|
|
|
|
DSP_CHARGEPUMP
|
|
|
|
};
|
2020-05-31 13:36:49 +00:00
|
|
|
send_commands(init2, sizeof(init2));
|
2020-05-30 17:10:34 +00:00
|
|
|
send_command(0x14);
|
|
|
|
|
|
|
|
static const uint8_t PROGMEM init3[] = {
|
|
|
|
DSP_MEMORYMODE,
|
|
|
|
0x00,
|
|
|
|
DSP_SEGREMAP | 0x1,
|
|
|
|
DSP_COMSCANDEC
|
|
|
|
};
|
2020-05-31 13:36:49 +00:00
|
|
|
send_commands(init3, sizeof(init3));
|
2020-05-30 17:10:34 +00:00
|
|
|
|
2020-05-31 13:36:49 +00:00
|
|
|
send_command(DSP_SETCOMPINS);
|
|
|
|
send_command(_comPin);
|
|
|
|
send_command(DSP_SETCONTRAST);
|
|
|
|
send_command(_contrast);
|
2020-05-30 17:10:34 +00:00
|
|
|
send_command(DSP_SETPRECHARGE);
|
|
|
|
send_command(0xF1);
|
|
|
|
|
|
|
|
static const uint8_t PROGMEM init5[] = {
|
2020-05-31 13:36:49 +00:00
|
|
|
DSP_SETVCOMDETECT,
|
2020-05-30 17:10:34 +00:00
|
|
|
0x40,
|
|
|
|
DSP_DISPLAYALLON_RESUME,
|
|
|
|
DSP_NORMALDISPLAY,
|
|
|
|
DSP_DEACTIVATE_SCROLL,
|
2020-05-30 17:40:24 +00:00
|
|
|
DSP_DISPLAYON
|
2020-05-30 17:10:34 +00:00
|
|
|
};
|
2020-05-31 13:36:49 +00:00
|
|
|
send_commands(init5, sizeof(init5));
|
2020-05-30 17:10:34 +00:00
|
|
|
|
|
|
|
TRANSACTION_END
|
|
|
|
|
|
|
|
return;
|
2020-05-30 17:29:36 +00:00
|
|
|
}
|
|
|
|
|
2020-05-31 20:13:05 +00:00
|
|
|
#define swap(a, b) \
|
|
|
|
(((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b))) ///< No-temp-var swap operation
|
|
|
|
|
2020-05-30 17:29:36 +00:00
|
|
|
void Display::clear(){
|
2020-05-31 20:13:05 +00:00
|
|
|
memset(_buffer, 0, _width * ((_height + 7) / 8));
|
|
|
|
}
|
|
|
|
|
|
|
|
void Display::setPixel(int16_t x, int16_t y, const bool white){
|
|
|
|
if( x > _width || y > _height || x < 0 || y < 0 ){
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// swap(x, y);
|
|
|
|
// x = _width - x - 1;
|
|
|
|
// y = _height - y - 1;
|
|
|
|
|
|
|
|
if( white ){
|
|
|
|
_buffer[x + (y/8)*_width] |= (1 << (y&7));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
_buffer[x + (y/8)*_width] &= ~(1 << (y&7));
|
|
|
|
}
|
|
|
|
|
|
|
|
void Display::apply(){
|
2020-05-30 17:29:36 +00:00
|
|
|
TRANSACTION_START
|
|
|
|
|
|
|
|
static const uint8_t PROGMEM dlist1[] = {
|
|
|
|
DSP_PAGEADDR,
|
|
|
|
0, // Page start address
|
|
|
|
0xFF, // Page end (not really, but works here)
|
|
|
|
DSP_COLUMNADDR,
|
|
|
|
0 // Column start address
|
|
|
|
};
|
|
|
|
send_commands(dlist1, sizeof(dlist1));
|
|
|
|
send_command(_width - 1); // Column end address
|
|
|
|
|
2020-05-31 20:13:05 +00:00
|
|
|
uint16_t count = _width * ((_height + 7) / 8);
|
|
|
|
uint8_t* ptr = _buffer;
|
2020-05-30 17:29:36 +00:00
|
|
|
_wire->beginTransmission(_i2caddr);
|
|
|
|
_wire->write((uint8_t) 0x40);
|
2020-05-31 20:13:05 +00:00
|
|
|
uint8_t written = 1;
|
2020-05-30 17:29:36 +00:00
|
|
|
while(count--){
|
|
|
|
if( written >= WIRE_MAX ){
|
|
|
|
_wire->endTransmission();
|
|
|
|
_wire->beginTransmission(_i2caddr);
|
|
|
|
_wire->write((uint8_t) 0x40);
|
|
|
|
written = 1;
|
|
|
|
}
|
2020-05-31 20:13:05 +00:00
|
|
|
_wire->write(*ptr++);
|
|
|
|
written++;
|
2020-05-30 17:29:36 +00:00
|
|
|
}
|
|
|
|
_wire->endTransmission();
|
|
|
|
|
|
|
|
TRANSACTION_END
|
2020-05-31 13:36:49 +00:00
|
|
|
}
|
|
|
|
|
2020-05-31 20:13:05 +00:00
|
|
|
void Display::setTitle(const String title){
|
|
|
|
// todo
|
|
|
|
}
|
|
|
|
|
2020-05-31 13:36:49 +00:00
|
|
|
// draws a progress bar to a fixed location
|
2020-05-31 20:13:05 +00:00
|
|
|
// the progress value is between 0 and 1023
|
|
|
|
void Display::progress(const short progress, const uint8_t startLine, const uint8_t endLine, const bool absolute){
|
|
|
|
// top line
|
|
|
|
for( uint8_t i = 0 ; i < 128 ; i++ ){
|
|
|
|
setPixel(i, startLine, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
// bottom line
|
|
|
|
for( uint8_t i = 0 ; i < 128 ; i++ ){
|
|
|
|
setPixel(i, endLine, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
// center tip
|
|
|
|
for( uint8_t i = startLine+2 ; i < endLine-1 ; i++ ){
|
|
|
|
setPixel(64, endLine, true);
|
|
|
|
}
|
|
|
|
|
2020-06-01 15:11:15 +00:00
|
|
|
int16_t scaledProgress = (progress+7) / 8;
|
2020-05-31 20:13:05 +00:00
|
|
|
|
|
|
|
// draw absolute progression
|
|
|
|
if( absolute ){
|
2020-06-01 15:11:15 +00:00
|
|
|
for( uint8_t x = 0 ; x < scaledProgress && x < 128 ; x++ ){
|
2020-05-31 20:13:05 +00:00
|
|
|
for( uint8_t y = startLine+1 ; y < endLine ; y++ ){
|
|
|
|
setPixel(x, y, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2020-05-31 13:36:49 +00:00
|
|
|
|
2020-05-31 20:13:05 +00:00
|
|
|
// draw left relative progression
|
|
|
|
if( progress < 512 ){
|
|
|
|
|
2020-06-01 15:11:15 +00:00
|
|
|
for( int16_t x = 64 ; x > scaledProgress && x >= 0 ; x-- ){
|
2020-05-31 20:13:05 +00:00
|
|
|
for( uint8_t y = startLine+1 ; y < endLine ; y++ ){
|
|
|
|
setPixel(x, y, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// draw right relative progression
|
|
|
|
} else {
|
|
|
|
|
2020-06-01 15:11:15 +00:00
|
|
|
for( uint8_t x = 64 ; x < scaledProgress && x < 128 ; x++ ){
|
2020-05-31 20:13:05 +00:00
|
|
|
for( uint8_t y = startLine+1 ; y < endLine ; y++ ){
|
|
|
|
setPixel(x, y, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2020-05-30 17:10:34 +00:00
|
|
|
}
|