diff --git a/MicroView.cpp b/MicroView.cpp index 6212a58..a7ed534 100644 --- a/MicroView.cpp +++ b/MicroView.cpp @@ -123,119 +123,99 @@ void MicroView::begin() { setColor(WHITE); setDrawMode(NORM); setCursor(0,0); + + RESETLOW; + // Enable 3.3V power to the display pinMode(OLEDPWR, OUTPUT); digitalWrite(OLEDPWR,HIGH); - // Setting up SPI pins - pinMode(MOSI, OUTPUT); - pinMode(SCK, OUTPUT); - - //pinMode(DC, OUTPUT); - pinMode(RESET, OUTPUT); - pinMode(SS, INPUT); - digitalWrite(SS, HIGH); - - ssport = portOutputRegister(digitalPinToPort(SS)); - sspinmask = digitalPinToBitMask(SS); - ssreg = portModeRegister(digitalPinToPort(SS)); - - dcport = portOutputRegister(digitalPinToPort(DC)); - dcpinmask = digitalPinToBitMask(DC); - dcreg = portModeRegister(digitalPinToPort(DC)); - - digitalWrite(RESET, HIGH); - // VDD (3.3V) goes high at start, lets just chill for 5 ms + + // Give some time for power to stabilise + delay(10); + + RESETHIGH; delay(5); - // bring reset low - digitalWrite(RESET, LOW); - + RESETLOW; + // Setup SPI frequency MVSPI.setClockDivider(SPI_CLOCK_DIV2); + // Initialise SPI MVSPI.begin(); - - // wait 10ms - delay(10); + + delay(5); + // bring out of reset - pinMode(RESET,INPUT_PULLUP); - //digitalWrite(RESET, HIGH); + RESETHIGH; + + delay(10); // Init sequence for 64x48 OLED module - command(DISPLAYOFF); // 0xAE - - command(SETDISPLAYCLOCKDIV); // 0xD5 - command(0x80); // the suggested ratio 0x80 - - command(SETMULTIPLEX); // 0xA8 - command(0x2F); - - command(SETDISPLAYOFFSET); // 0xD3 - command(0x0); // no offset - - command(SETSTARTLINE | 0x0); // line #0 - - command(CHARGEPUMP); // enable charge pump - command(0x14); - - command(NORMALDISPLAY); // 0xA6 - command(DISPLAYALLONRESUME); // 0xA4 - + command(DISPLAYOFF); // 0xAE + command(SETDISPLAYCLOCKDIV, 0x80); // 0xD5 / the suggested ratio 0x80 + command(SETMULTIPLEX, 0x2F); // 0xA8 + command(SETDISPLAYOFFSET, 0x0); // 0xD3 / no offset + command(SETSTARTLINE | 0x0); // line #0 + command(CHARGEPUMP, 0x14); // enable charge pump + command(NORMALDISPLAY); // 0xA6 + command(DISPLAYALLONRESUME); // 0xA4 command(SEGREMAP | 0x1); command(COMSCANDEC); + command(SETCOMPINS, 0x12); // 0xDA + command(SETCONTRAST, 0x8F); // 0x81 + command(SETPRECHARGE, 0xF1); // 0xd9 + command(SETVCOMDESELECT, 0x40); // 0xDB + command(DISPLAYON); //--turn on oled panel - command(SETCOMPINS); // 0xDA - command(0x12); + clear(ALL); // Erase hardware memory inside the OLED controller to avoid random data in memory. - command(SETCONTRAST); // 0x81 - command(0x8F); - - command(SETPRECHARGE); // 0xd9 - command(0xF1); - - command(SETVCOMDESELECT); // 0xDB - command(0x40); - - command(DISPLAYON); //--turn on oled panel - clear(ALL); // Erase hardware memory inside the OLED controller to avoid random data in memory. Serial.begin(115200); } -/** \brief SPI command. - - Setup DC and SS pins, then send command via SPI to SSD1306 controller. +/** \brief Send 1 command byte. + + Send 1 command byte via SPI to SSD1306 controller. */ void MicroView::command(uint8_t c) { - // Hardware SPI - *dcreg |= dcpinmask; // Set DC pin to OUTPUT - *dcport &= ~dcpinmask; // DC pin LOW - - *ssreg |= sspinmask; // Set SS pin to OUTPUT - *ssport &= ~sspinmask; // SS LOW - + MVSPI.packetBegin(); MVSPI.transfer(c); + MVSPI.packetEnd(); +} - *ssport |= sspinmask; // SS HIGH - *ssreg &= ~sspinmask; // Set SS pin to INPUT - - *dcreg &= ~dcpinmask; // Set DC to INPUT to avoid high voltage over driving the OLED logic +/** \brief Send 2 command bytes. + + Send 2 command bytes via SPI to SSD1306 controller. +*/ +void MicroView::command(uint8_t c1, uint8_t c2) { + MVSPI.packetBegin(); + MVSPI.transfer(c1); + MVSPI.wait(); + MVSPI.transfer(c2); + MVSPI.packetEnd(); +} + +/** \brief Send 3 command bytes. + + Send 3 command bytes via SPI to SSD1306 controller. +*/ +void MicroView::command(uint8_t c1, uint8_t c2, uint8_t c3) { + MVSPI.packetBegin(); + MVSPI.transfer(c1); + MVSPI.wait(); + MVSPI.transfer(c2); + MVSPI.wait(); + MVSPI.transfer(c3); + MVSPI.packetEnd(); } /** \brief SPI data. - Setup DC and SS pins, then send data via SPI to SSD1306 controller. + Send 1 data byte via SPI to SSD1306 controller. */ void MicroView::data(uint8_t c) { - // Hardware SPI - *dcport |= dcpinmask; // DC HIGH - - *ssreg |= sspinmask; // Set SS pin to OUTPUT - *ssport &= ~sspinmask; // SS LOW - + MVSPI.packetBegin(); + DCHIGH; MVSPI.transfer(c); - - *ssport |= sspinmask; // SS HIGH - *ssreg &= ~sspinmask; // Set SS pin to INPUT - - *dcreg &= ~dcpinmask; // Set DC to INPUT to avoid high voltage over driving the OLED logic + MVSPI.packetEnd(); } /** \brief Set SSD1306 page address. @@ -243,8 +223,7 @@ void MicroView::data(uint8_t c) { Send page address command and address to the SSD1306 OLED controller. */ void MicroView::setPageAddress(uint8_t add) { - add=0xb0|add; - command(add); + command(SETPAGE|add); return; } @@ -253,8 +232,7 @@ void MicroView::setPageAddress(uint8_t add) { Send column address command and address to the SSD1306 OLED controller. */ void MicroView::setColumnAddress(uint8_t add) { - command((0x10|(add>>4))+0x02); - command((0x0f&add)); + command((SETHIGHCOLUMN|(add>>4))+0x02, SETLOWCOLUMN|(0x0f&add)); return; } @@ -268,9 +246,14 @@ void MicroView::clear(uint8_t mode) { for (int i=0;i<8; i++) { setPageAddress(i); setColumnAddress(0); - for (int j=0; j<0x80; j++) { - data(0); + MVSPI.packetBegin(); + DCHIGH; + MVSPI.transfer(0); + for (int j=1; j<0x80; j++) { + MVSPI.wait(); + MVSPI.transfer(0); } + MVSPI.packetEnd(); } } else @@ -290,9 +273,14 @@ void MicroView::clear(uint8_t mode, uint8_t c) { for (int i=0;i<8; i++) { setPageAddress(i); setColumnAddress(0); - for (int j=0; j<0x80; j++) { - data(c); + MVSPI.packetBegin(); + DCHIGH; + MVSPI.transfer(c); + for (int j=1; j<0x80; j++) { + MVSPI.wait(); + MVSPI.transfer(c); } + MVSPI.packetEnd(); } } else @@ -315,11 +303,10 @@ void MicroView::invert(boolean inv) { /** \brief Set contrast. - OLED contract value from 0 to 255. Note: Contrast level is not very obvious. + OLED contrast value from 0 to 255. Note: Contrast level is not very obvious. */ void MicroView::contrast(uint8_t contrast) { - command(SETCONTRAST); // 0x81 - command(contrast); + command(SETCONTRAST, contrast); // 0x81 } /** \brief Transfer display memory. @@ -332,9 +319,14 @@ void MicroView::display(void) { for (i=0; i<6; i++) { setPageAddress(i); setColumnAddress(0); - for (j=0;j<0x40;j++) { - data(screenmemory[i*0x40+j]); + MVSPI.packetBegin(); + DCHIGH; + MVSPI.transfer(screenmemory[i*0x40]); + for (j=1;j<0x40;j++) { + MVSPI.wait(); + MVSPI.transfer(screenmemory[i*0x40+j]); } + MVSPI.packetEnd(); } } @@ -847,14 +839,9 @@ size_t MicroView::write(uint8_t c) { if (stop