#include "display.h" #include #include 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) display.begin(); // display.clearDisplay(); display.clear(); // no need to call display() after to apply // display.drawPixel(x, y, SSD1306_WHITE) // display.drawPixel(x, y, SSD1306_BLACK) // display.display() } void Display::send_command(const uint8_t c){ _wire->beginTransmission(_i2caddr); _wire->write((uint8_t) 0x00); _wire->write(c); _wire->endTransmission(); } void Display::send_commands(const uint8_t *cc, uint8_t n){ _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(); } Display::Display(const uint8_t resetPin){ _rstPin = resetPin; _wire = &Wire; _buffer = (uint8_t*) malloc(_width * ((_height + 7) / 8)); } void Display::begin(){ _wire->begin(); // reset sequence if( _rstPin >= 0 ){ pinMode(_rstPin, OUTPUT); digitalWrite(_rstPin, HIGH); delay(1); digitalWrite(_rstPin, LOW); delay(10); digitalWrite(_rstPin, HIGH); } 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 }; send_commands(init2, sizeof(init2)); send_command(0x14); static const uint8_t PROGMEM init3[] = { DSP_MEMORYMODE, 0x00, DSP_SEGREMAP | 0x1, DSP_COMSCANDEC }; send_commands(init3, sizeof(init3)); send_command(DSP_SETCOMPINS); send_command(_comPin); send_command(DSP_SETCONTRAST); send_command(_contrast); send_command(DSP_SETPRECHARGE); send_command(0xF1); static const uint8_t PROGMEM init5[] = { DSP_SETVCOMDETECT, 0x40, DSP_DISPLAYALLON_RESUME, DSP_NORMALDISPLAY, DSP_DEACTIVATE_SCROLL, DSP_DISPLAYON }; send_commands(init5, sizeof(init5)); TRANSACTION_END return; } #define swap(a, b) \ (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b))) ///< No-temp-var swap operation void Display::clear(){ 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(){ 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 uint16_t count = _width * ((_height + 7) / 8); uint8_t* ptr = _buffer; _wire->beginTransmission(_i2caddr); _wire->write((uint8_t) 0x40); uint8_t written = 1; while(count--){ if( written >= WIRE_MAX ){ _wire->endTransmission(); _wire->beginTransmission(_i2caddr); _wire->write((uint8_t) 0x40); written = 1; } _wire->write(*ptr++); written++; } _wire->endTransmission(); TRANSACTION_END } void Display::setTitle(const String title){ // todo } // draws a progress bar to a fixed location // 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); } int16_t scaledProgress = (progress+7) / 8; // draw absolute progression if( absolute ){ for( uint8_t x = 0 ; x < scaledProgress && x < 128 ; x++ ){ for( uint8_t y = startLine+1 ; y < endLine ; y++ ){ setPixel(x, y, true); } } return; } // draw left relative progression if( progress < 512 ){ for( int16_t x = 64 ; x > scaledProgress && x >= 0 ; x-- ){ for( uint8_t y = startLine+1 ; y < endLine ; y++ ){ setPixel(x, y, true); } } // draw right relative progression } else { for( uint8_t x = 64 ; x < scaledProgress && x < 128 ; x++ ){ for( uint8_t y = startLine+1 ; y < endLine ; y++ ){ setPixel(x, y, true); } } } }