- code cleaned up in many points for a better readability - removed SPIPreinit and I2CPreinit classes - moved various method implementations from .h files to the corresponding .cpp ones - the splash() and clearDisplay() methods now directly update the display; no more need to call the display() method after them

Dependencies:   Adafruit_GFX mbed

Fork of Adafruit_GFX by Neal Horman

Revision:
17:396d9b7eb7d5
Parent:
16:7fb1d4d3525d
--- a/Adafruit_SSD1306.cpp	Tue Nov 11 22:08:20 2014 +0000
+++ b/Adafruit_SSD1306.cpp	Thu Sep 03 20:27:40 2015 +0000
@@ -18,84 +18,56 @@
 
 /*
  *  Modified by Neal Horman 7/14/2012 for use in mbed
+ *  Edited by Francesco Adamo 2015/09/03: 
+ *	 - code cleaned up in many points for a better readability
+ *	 - removed SPIPreinit and I2CPreinit classes
+ *	 - moved various method implementations from .h files to the corresponding .cpp ones
+ *	 - the splash() and clearDisplay() methods now directly update the display; no more need to call the display() method after them
+ *	
  */
 
 #include "mbed.h"
 #include "Adafruit_SSD1306.h"
 
-#define SSD1306_SETCONTRAST 0x81
-#define SSD1306_DISPLAYALLON_RESUME 0xA4
-#define SSD1306_DISPLAYALLON 0xA5
-#define SSD1306_NORMALDISPLAY 0xA6
-#define SSD1306_INVERTDISPLAY 0xA7
-#define SSD1306_DISPLAYOFF 0xAE
-#define SSD1306_DISPLAYON 0xAF
-#define SSD1306_SETDISPLAYOFFSET 0xD3
-#define SSD1306_SETCOMPINS 0xDA
-#define SSD1306_SETVCOMDETECT 0xDB
-#define SSD1306_SETDISPLAYCLOCKDIV 0xD5
-#define SSD1306_SETPRECHARGE 0xD9
-#define SSD1306_SETMULTIPLEX 0xA8
-#define SSD1306_SETLOWCOLUMN 0x00
-#define SSD1306_SETHIGHCOLUMN 0x10
-#define SSD1306_SETSTARTLINE 0x40
-#define SSD1306_MEMORYMODE 0x20
-#define SSD1306_COMSCANINC 0xC0
-#define SSD1306_COMSCANDEC 0xC8
-#define SSD1306_SEGREMAP 0xA0
-#define SSD1306_CHARGEPUMP 0x8D
+Adafruit_SSD1306::Adafruit_SSD1306(PinName RST, uint8_t rawHeight, uint8_t rawWidth) : Adafruit_GFX(rawWidth, rawHeight), rst(RST,false)
+{
+	buffer.resize(rawHeight * rawWidth / 8);
+};
 
 void Adafruit_SSD1306::begin(uint8_t vccstate)
 {
     rst = 1;
-    // VDD (3.3V) goes high at start, lets just chill for a ms
     wait_ms(1);
-    // bring reset low
     rst = 0;
-    // wait 10ms
     wait_ms(10);
-    // bring out of reset
     rst = 1;
     // turn on VCC (9V?)
-
+	wait_ms(10);
+	
     command(SSD1306_DISPLAYOFF);
     command(SSD1306_SETDISPLAYCLOCKDIV);
-    command(0x80);                                  // the suggested ratio 0x80
-
+    command(0x80); // the suggested ratio 0x8
     command(SSD1306_SETMULTIPLEX);
-    command(_rawHeight-1);
-
+    command(_rawHeight - 1);
     command(SSD1306_SETDISPLAYOFFSET);
-    command(0x0);                                   // no offset
-
-    command(SSD1306_SETSTARTLINE | 0x0);            // line #0
-
+    command(0x00);                                   // no offset
+    command(SSD1306_SETSTARTLINE);            // line #0
     command(SSD1306_CHARGEPUMP);
     command((vccstate == SSD1306_EXTERNALVCC) ? 0x10 : 0x14);
-
     command(SSD1306_MEMORYMODE);
     command(0x00);                                  // 0x0 act like ks0108
-
     command(SSD1306_SEGREMAP | 0x1);
-
     command(SSD1306_COMSCANDEC);
-
     command(SSD1306_SETCOMPINS);
-    command(_rawHeight == 32 ? 0x02 : 0x12);        // TODO - calculate based on _rawHieght ?
-
+    command(_rawHeight == 32 ? 0x02 : 0x12);        // TODO - calculate based on _rawHeight ?
     command(SSD1306_SETCONTRAST);
     command(_rawHeight == 32 ? 0x8F : ((vccstate == SSD1306_EXTERNALVCC) ? 0x9F : 0xCF) );
-
     command(SSD1306_SETPRECHARGE);
     command((vccstate == SSD1306_EXTERNALVCC) ? 0x22 : 0xF1);
-
     command(SSD1306_SETVCOMDETECT);
     command(0x40);
-
     command(SSD1306_DISPLAYALLON_RESUME);
-
     command(SSD1306_NORMALDISPLAY);
-    
     command(SSD1306_DISPLAYON);
 }
 
@@ -146,7 +118,8 @@
 // Clear the display buffer. Requires a display() call at some point afterwards
 void Adafruit_SSD1306::clearDisplay(void)
 {
-	std::fill(buffer.begin(),buffer.end(),0);
+	std::fill(buffer.begin(), buffer.end(), 0);
+	display();
 }
 
 void Adafruit_SSD1306::splash(void)
@@ -226,5 +199,129 @@
 		, &adaFruitLogo[0] + (_rawHeight == 32 ? sizeof(adaFruitLogo)/2 : sizeof(adaFruitLogo))
 		, buffer.begin()
 		);
+	display();
 #endif
 }
+
+
+	/** Create a SSD1306 SPI transport display driver instance with the specified DC, RST, and CS pins, as well as the display dimensions
+	 *
+	 * Required parameters
+	 * @param spi - a reference to an initialized SPI object
+	 * @param DC (Data/Command) pin name
+	 * @param RST (Reset) pin name
+	 * @param CS (Chip Select) pin name
+	 *
+	 * Optional parameters
+	 * @param rawHeight - the vertical number of pixels for the display, defaults to 32
+	 * @param rawWidth - the horizontal number of pixels for the display, defaults to 128
+	 */
+Adafruit_SSD1306_SPI::Adafruit_SSD1306_SPI(PinName MOSI, PinName CLK, PinName CS, PinName DC, PinName RST, uint8_t rawHeight, uint8_t rawWidth)
+   : Adafruit_SSD1306(RST, rawHeight, rawWidth)
+   , cs(CS, true)
+   , dc(DC, false)
+   , mspi(MOSI, NC, CLK)
+{
+   	mspi.frequency(1000000);
+   	mspi.format(8, 3);
+    begin();
+    splash();
+};
+
+uint8_t Adafruit_SSD1306_SPI::command(uint8_t c)
+{
+    cs = 1;
+    dc = 0;
+    cs = 0;
+    mspi.write(c);
+    cs = 1;
+    
+    return c;
+};
+
+void Adafruit_SSD1306_SPI::data(uint8_t c)
+{
+    cs = 1;
+    dc = 1;
+    cs = 0;
+    mspi.write(c);
+    cs = 1;
+};
+
+
+void Adafruit_SSD1306_SPI::sendDisplayBuffer()
+{
+	cs = 1;
+	dc = 1;
+	cs = 0;
+
+	for(uint16_t i=0, q = buffer.size(); i < q; i++)
+		mspi.write(buffer[i]);
+
+	if(height() == 32)
+	{
+		for(uint16_t i=0, q = buffer.size(); i<q; i++)
+			mspi.write(0);
+	}
+
+	cs = 1;
+};
+
+
+	/** Create a SSD1306 I2C transport display driver instance with the specified RST pin name, the I2C address, as well as the display dimensions
+	 *
+	 * Required parameters
+	 * @param i2c - A reference to an initialized I2C object
+	 * @param RST - The Reset pin name
+	 *
+	 * Optional parameters
+	 * @param i2cAddress - The i2c address of the display
+	 * @param rawHeight - The vertical number of pixels for the display, defaults to 32
+	 * @param rawWidth - The horizonal number of pixels for the display, defaults to 128
+	 */
+	Adafruit_SSD1306_I2C::Adafruit_SSD1306_I2C(PinName SDA, PinName SCL, PinName RST, uint8_t i2cAddress, uint8_t rawHeight, uint8_t rawWidth)
+	    : Adafruit_SSD1306(RST, rawHeight, rawWidth)
+	    , mi2c(SDA, SCL)
+	    , mi2cAddress(i2cAddress)
+	    {
+	    	mi2c.frequency(400000);
+        	mi2c.start();
+		    begin();
+		    splash();
+	    };
+
+uint8_t Adafruit_SSD1306_I2C::command(uint8_t c)
+	{
+		char buff[2];
+		buff[0] = 0; // Command Mode
+		buff[1] = c;
+		mi2c.write(mi2cAddress, buff, sizeof(buff));
+		
+		return c;
+	}
+
+void Adafruit_SSD1306_I2C::data(uint8_t c)
+	{
+		char buff[2];
+		buff[0] = 0x40; // Data Mode
+		buff[1] = c;
+		mi2c.write(mi2cAddress, buff, sizeof(buff));
+	};
+
+
+void Adafruit_SSD1306_I2C::sendDisplayBuffer()
+	{
+		char buff[17];
+		buff[0] = 0x40; // Data Mode
+
+		// send display buffer in 16 byte chunks
+		for(uint16_t i=0, q=buffer.size(); i<q; i+=16 ) 
+		{	uint8_t x ;
+
+			// TODO - this will segfault if buffer.size() % 16 != 0
+			for(x=1; x<sizeof(buff); x++) 
+				buff[x] = buffer[i+x-1];
+
+			mi2c.write(mi2cAddress, buff, sizeof(buff));
+		}
+	};