derived from Aidafruit SSD1306 library

Dependents:   Test_SSD1306 L152RE_OLED_SSD1306 EcranZumo

Fork of SSD1306 by Jonathan Gaul

Files at this revision

API Documentation at this revision

Comitter:
Byrn
Date:
Tue Feb 05 21:21:22 2013 +0000
Parent:
1:1d58d378221c
Child:
3:1d9df877c90a
Commit message:
commit before initial publish

Changed in this revision

ssd1306.cpp Show annotated file Show diff for this revision Revisions of this file
ssd1306.h Show annotated file Show diff for this revision Revisions of this file
--- a/ssd1306.cpp	Tue Feb 05 17:18:23 2013 +0000
+++ b/ssd1306.cpp	Tue Feb 05 21:21:22 2013 +0000
@@ -10,29 +10,14 @@
 {
 }
 
-void SSD1306::set_low_column(int v)
-{
-    _send_command(SSD1306_SETLOWCOLUMN | v);
-}
-
-void SSD1306::set_high_column(int v)
-{
-    _send_command(SSD1306_SETHIGHCOLUMN | v);
-}
-
-void SSD1306::set_start_line(int v)
-{
-    _send_command(SSD1306_SETSTARTLINE | v);
-}
-
 void SSD1306::off()
 {
-    _send_command(SSD1306_DISPLAYOFF);
+    _send_command(0xAE);
 }
 
 void SSD1306::on()
 {
-    _send_command(SSD1306_DISPLAYON);
+    _send_command(0xAF);
 }
 
 void SSD1306::sleep()
@@ -53,7 +38,7 @@
 void SSD1306::set_display_offset(unsigned char value)
 {
     _send_command(0xD3);
-    _send_command(value); 
+    _send_command(value & 0x3F); 
 }
 
 void SSD1306::set_contrast(unsigned char value) 
@@ -67,14 +52,15 @@
     _send_command(0x40 | value);
 }
 
-void SSD1306::set_horizontal_flip(unsigned char value)
+void SSD1306::set_segment_remap(unsigned char value)
 {
     _send_command(value ? 0xA1 : 0xA0);
 }
 
 void SSD1306::set_multiplex_ratio(unsigned char value)
 {
-    _send_command(0xA8 | value);
+    _send_command(0xA8);
+    _send_command(value & 0x3F);
 }
 
 void SSD1306::set_com_output_scan_direction(unsigned char value)
@@ -85,7 +71,127 @@
 void SSD1306::set_com_pins_hardware_configuration(unsigned char sequential, unsigned char lr_remap)
 {
     _send_command(0xDA);
-    _send_command(0x02 | ((sequential & 1) << 5) | ((lr_remap & 1) << 6));
+    _send_command(0x02 | ((sequential & 1) << 4) | ((lr_remap & 1) << 5));
+}
+
+void SSD1306::start_horizontal_scroll(unsigned char direction, unsigned char start, unsigned char end, unsigned char interval) 
+{
+    _send_command(direction ? 0x27 : 0x26);
+    _send_command(0x00);
+    _send_command(start & 0x07);
+    switch (interval) {
+        case   2: _send_command(0x07); break; // 111b
+        case   3: _send_command(0x04); break; // 100b
+        case   4: _send_command(0x05); break; // 101b
+        case   5: _send_command(0x00); break; // 000b
+        case  25: _send_command(0x06); break; // 110b
+        case  64: _send_command(0x01); break; // 001b
+        case 128: _send_command(0x02); break; // 010b
+        case 256: _send_command(0x03); break; // 011b
+        default:
+            // default to 2 frame interval
+            _send_command(0x07); break;
+    }
+    _send_command(end & 0x07);
+    _send_command(0x00);
+    _send_command(0xFF);
+    
+    // activate scroll
+    _send_command(0x2F);
+}
+
+void SSD1306::start_vertical_and_horizontal_scroll(unsigned char direction, unsigned char start, unsigned char end, unsigned char interval, unsigned char vertical_offset)
+{
+    _send_command(direction ? 0x2A : 0x29);
+    _send_command(0x00);
+    _send_command(start & 0x07);
+    switch (interval) {
+        case   2: _send_command(0x07); break; // 111b
+        case   3: _send_command(0x04); break; // 100b
+        case   4: _send_command(0x05); break; // 101b
+        case   5: _send_command(0x00); break; // 000b
+        case  25: _send_command(0x06); break; // 110b
+        case  64: _send_command(0x01); break; // 001b
+        case 128: _send_command(0x02); break; // 010b
+        case 256: _send_command(0x03); break; // 011b
+        default:
+            // default to 2 frame interval
+            _send_command(0x07); break;
+    }
+    _send_command(end & 0x07);
+    _send_command(vertical_offset);    
+    
+    // activate scroll
+    _send_command(0x2F);
+}
+
+void SSD1306::stop_scroll()
+{
+    // all scroll configurations are removed from the display when executing this command.
+    _send_command(0x2E);
+}
+
+void SSD1306::pam_set_start_address(unsigned char address)
+{
+    // "Set Lower Column Start Address for Page Addressing Mode"
+    _send_command(address & 0x0F);
+    
+    // "Set Higher Column Start Address for Page Addressing Mode"
+    _send_command((address << 4) & 0x0F);
+}
+
+void SSD1306::set_memory_addressing_mode(unsigned char mode)
+{
+    _send_command(0x20);
+    _send_command(mode & 0x3);
+}
+
+void SSD1306::hv_set_column_address(unsigned char start, unsigned char end)
+{
+    _send_command(0x21);
+    _send_command(start & 0x7F);
+    _send_command(end & 0x7F);
+}
+
+void SSD1306::hv_set_page_address(unsigned char start, unsigned char end)
+{
+    _send_command(0x22);
+    _send_command(start & 0x07);
+    _send_command(end & 0x07);
+}
+
+void SSD1306::pam_set_page_start(unsigned char address)
+{
+    _send_command(0xB0 | (address & 0x07));
+}
+
+void SSD1306::set_display_clock_ratio_and_frequency(unsigned char ratio, unsigned char frequency)
+{
+    _send_command(0xD5);
+    _send_command((ratio & 0x0F) | ((frequency & 0x0F) << 4));
+}
+
+void SSD1306::set_precharge_period(unsigned char phase1, unsigned char phase2)
+{
+    _send_command(0xD9);
+    _send_command((phase1 & 0x0F) | ((phase2 & 0x0F ) << 4));
+}
+
+void SSD1306::set_vcomh_deselect_level(unsigned char level)
+{
+    _send_command(0xDB);
+    _send_command((level & 0x03) << 4);
+}
+
+void SSD1306::nop()
+{
+    _send_command(0xE3);
+}
+
+void SSD1306::set_charge_pump_enable(unsigned char enable)
+{
+    _send_command(0x8D);
+    _send_command(enable ? 0x14 : 0x10);
 }
 
 void SSD1306::initialise()
@@ -98,78 +204,36 @@
     _reset = 1;
     
     off();
-    
-    set_low_column(0);
-    set_high_column(0);
-    set_start_line(0);
-    
-    _send_command(0xAE);  // turn off
-    _send_command(0x00);  // set low column address
-    _send_command(0x10);  // set high column address
-    _send_command(0x40);  // set start line address
-    
+
+    set_display_clock_ratio_and_frequency(0, 8);
+    set_multiplex_ratio(0x3F); // 1/64 duty
+    set_precharge_period(0xF, 0x01);
+    set_display_offset(0);    
+    set_display_start_line(0);  
+    set_charge_pump_enable(1);    
+    set_memory_addressing_mode(0); // horizontal addressing mode
+    set_segment_remap(1);
+    set_com_output_scan_direction(1);
+    set_com_pins_hardware_configuration(1, 0);
     set_contrast(0xFF);
-    
-    _send_command(0xA1);  // set segment re-map 95 to 0
-    _send_command(0xA6);  // set normal display
-    _send_command(0xA8);  // set multiplex ratio (1-64);
-    _send_command(0x3F);  // 1/64 duty
-    _send_command(0xD3);  // set display offset
-    _send_command(0x00);  // -- no offset
-    _send_command(0xD5);  // set display clock divide ratio/oscillator frequency
-    _send_command(0x80);  // -- set divide ratio
-    _send_command(0xD9);  // set precharge period;
-    _send_command(0xF1);
-    _send_command(0xDA);  // set com pins hardware config
-    _send_command(0x12);
-    _send_command(0xDB);  // set vcomh
-    _send_command(0x40); 
-    _send_command(0x8D);  // set charge pump enable/disable
-    _send_command(0x14);  // enable  (0x10 disable)
-    _send_command(0xAF);  // switch panel on
-    
-    set_inverse(1);
+    set_vcomh_deselect_level(1);
     
-    /*
-    _send_command(SSD1306_SETCONTRAST);
-    _send_command(0xCF); // chargepump, could be 0x9F for external 9V
-    
-    _send_command(0xA1); // setment remap 95 to 0 (??)
-    
-    invert(0);
-    
-    _send_command(SSD1306_DISPLAYALLON_RESUME);
-    _send_command(SSD1306_SETMULTIPLEX);    
-    _send_command(0x3F); // 1/64 duty
-    
-    set_display_offset(0);
+    wake();
+    set_inverse(0);
     
-    _send_command(SSD1306_SETDISPLAYCLOCKDIV);
-    _send_command(0x80); // suggested value = 0x80
-    _send_command(SSD1306_SETPRECHARGE);
-    _send_command(0xF1); // dc/dc, could be 0x22 for external 9V
-    _send_command(SSD1306_SETCOMPINS);
-    _send_command(0x12); // disable COM left/right remap
-    _send_command(SSD1306_SETVCOMDETECT);
-    _send_command(0x40); // apparently, 0x20 is default...
-    _send_command(SSD1306_MEMORYMODE);
-    _send_command(0x0); // act like KS0108
+    hv_set_column_address(0, 127);
+    hv_set_page_address(0, 7);
     
-    // left-to-right scan
-    _send_command(SSD1306_SEGREMAP | 0x1);
-    _send_command(SSD1306_COMSCANDEC);
-    _send_command(SSD1306_CHARGEPUMP);
-    _send_command(0x14); // disable, for external 9v 0x10 disable
-    */
-    // turn it on
-    // on();
+    pam_set_start_address(0);
+    pam_set_page_start(0);
+    
+    // set_precharge_period(2, 2);
 }
 
 void SSD1306::update()
 {
-    set_low_column(0);
-    set_high_column(0);
-    set_start_line(0);
+    hv_set_column_address(0, 127);
+    hv_set_page_address(0, 7);
     
     for (int i = 0; i < 1024; i++)
         _send_data(_screen[i]);
@@ -275,4 +339,3 @@
     _spi.write(value);
     _cs = 1;
 }
-
--- a/ssd1306.h	Tue Feb 05 17:18:23 2013 +0000
+++ b/ssd1306.h	Tue Feb 05 21:21:22 2013 +0000
@@ -8,7 +8,7 @@
 
 /** SSD1306 Controller Driver
  *
- * Information taken from the datasheet at: 
+ * Information taken from the datasheet at:
  *   http://www.adafruit.com/datasheets/SSD1306.pdf
  */
 class SSD1306
@@ -20,46 +20,174 @@
      *  @param dc The connected DC pin.
      *  @param clk The connected CLK pin.
      *  @param data The connected Data pin.
+     */
     SSD1306(PinName cs, PinName rs, PinName dc, PinName clk, PinName data);
 
+    // ----- HARDWARE CONTROL -----
+
+    /** Initialise the display with defaults.*/
     void initialise();
+    
+    /** Force a refresh of the display.  Copies the buffer to the controller. */
     void update();
 
+    /** Turn the whole display off.  This will reset all configuration settings on the controller to their defaults. */
     void off();
+    
+    /** Turn the whole display on.  Used during initialisation. */
     void on();
+
+    /** Sends the display to sleep, but leaves RAM intact. */
+    void sleep();
+
+    /** Wakes up this display following a sleep() call.
+     *  @see sleep()
+     */
+    void wake();
+
+    /** Set the display contrast.
+     *  @param value The contrast, from 1 to 256.
+     */
+    void set_contrast(unsigned char value); // 1-256
+    
+    /** Set the display to normal or inverse.
+     *  @param value 0 for normal mode, or 1 for inverse mode.
+     */
+    void set_inverse(unsigned char value); // 0 or 1
     
-    // Sends the display to sleep, but leaves RAM intact
-    void sleep();
+    /** Set the display start line.  This is the line at which the display will start rendering.
+     *  @param value A value from 0 to 63 denoting the line to start at.
+     */
+    void set_display_start_line(unsigned char value); // 0-63
+    
+    /** Set the segment remap state.  This allows the module to be addressed as if flipped horizontally.
+      * NOTE: Changing this setting has no effect on data already in the module's GDDRAM.
+      * @param value 0 = column address 0 = segment 0 (the default), 1 = column address 127 = segment 0 (flipped).
+      */
+    void set_segment_remap(unsigned char value); // 0 or 1
+    
+    /** Set the vertical shift by COM.
+      * @param value The number of rows to shift, from 0 - 63.
+      */
+    void set_display_offset(unsigned char value); // 0-63
+    
+    /** Set the multiplex ratio.
+     *  @param value MUX will be set to (value+1). Valid values range from 15 to 63 - MUX 16 to 64.
+     */
+    void set_multiplex_ratio(unsigned char value); // 15-63 (value+1 mux)
+    
+    /** Set COM output scan direction.  If the display is active, this will immediately vertically
+      * flip the display.
+      * @param value 0 = Scan from COM0 (default), 1 = reversed (scan from COM[N-1]).
+      */
+    void set_com_output_scan_direction(unsigned char value); // 0 or 1
     
-    // 
-    void wake();
-   
-    void set_low_column(int value);
-    void set_high_column(int value);
-    void set_start_line(int value);    
+    /** Set COM pins hardware configuration.
+      * @param sequential 0 = Sequental COM pin configuration, 1 = Alternative COM pin configuration (default).
+      * @param lr_remap 0 = Disable COM left/right remap (default), 1 = enable COM left/right remap.
+      */
+    void set_com_pins_hardware_configuration(unsigned char sequential, unsigned char lr_remap); // 0 or 1 for both parametrs
+
+    /** Set up and start a continuous horizontal scroll.
+      * Once you have set up the scrolling, you can deactivate it with stop_scroll().
+      * @param direction 0 for right, 1 for left.
+      * @param start Start page address, 0 - 5.
+      * @param end End page address, 0 - 5.
+      * @param interval Interval in frame frequency.  Valid values are: 2, 3, 4, 5, 25, 64, 128, 256.
+      * @see stop_scrol
+      */
+    void start_horizontal_scroll(unsigned char direction, unsigned char start, unsigned char end, unsigned char interval);
+
+    /** Set up and start a continuous horizontal and vertical scroll.
+      * NOTE: No continuous vertical scroll is available.
+      * Once you have set up the scrolling, you can deactivate it with stop_scroll().
+      * @param direction 0 for vertical and right horizontal scroll, 1 for vertical and left horizontal scroll.
+      * @param start Start page address, 0 - 5.
+      * @param end End page address, 0 - 5.
+      * @param interval Interval in frame frequency.  Valid values are: 2, 3, 4, 5, 25, 64, 128, 256.
+      * @param vertical_offset Offset of vertical scroll, 1 - 63.
+      * @see stop_scroll
+      */
+    void start_vertical_and_horizontal_scroll(unsigned char direction, unsigned char start, unsigned char end, unsigned char interval, unsigned char vertical_offset);
+    
+    /** Deactivate the continuous scroll set up with start_horizontal_scroll() or 
+      * start_vertical_and_horizontal_scroll().
+      * @see set_horizontal_scroll, set_vertical_and_horizontal_scroll
+      */
+    void stop_scroll();
+    
+    // ----- ADDRESSING -----
+    
+    /** Set memory addressing mode to the given value.
+      * @param mode 0 for Horizontal addressing mode, 1 for Vertical addressing mode, or 2 for Page addressing mode (PAM).  2 is the default.
+      */
+    void set_memory_addressing_mode(unsigned char mode);
+    
+    /** Page Addressing Mode: Set the column start address register for
+      * page addressing mode.
+      * @param address The address (full byte).
+      */
+    void pam_set_start_address(unsigned char address);       
+    
+    /** Set the GDDRAM page start address for page addressing mode.
+      * @param address The start page, 0 - 7.
+      */
+    void pam_set_page_start(unsigned char address);
+    
+    /** Set page start and end address for horizontal/vertical addressing mode.
+      * @param start The start page, 0 - 7.
+      * @param end The end page, 0 - 7.
+      */
+    void hv_set_page_address(unsigned char start, unsigned char end);
+    
+    /** Set column address range for horizontal/vertical addressing mode.
+      * @param start Column start address, 0 - 127.
+      * @param end Column end address, 0 - 127.
+      */
+    void hv_set_column_address(unsigned char start, unsigned char end);
+    
+    // ----- TIMING & DRIVING -----
+    /** Set the display clock divide ratio and the oscillator frequency.
+      * @param ratio The divide ratio, default is 0.
+      * @param frequency The oscillator frequency, 0 - 127. Default is 8.  
+      */
+    void set_display_clock_ratio_and_frequency(unsigned char ratio, unsigned char frequency);
+    
+    /** Set the precharge period.
+      * @param phase1 Phase 1 period in DCLK clocks.  1 - 15, default is 2.
+      * @param phase2 Phase 2 period in DCLK clocks.  1 - 15, default is 2.
+      */
+    void set_precharge_period(unsigned char phase1, unsigned char phase2);
+    
+    /** Set the Vcomh deselect level.
+      * @param level 0 = 0.65 x Vcc, 1 = 0.77 x Vcc (default), 2 = 0.83 x Vcc.
+      */
+    void set_vcomh_deselect_level(unsigned char level);
+    
+    /** Perform a "no operation".
+      */
+    void nop();
+    
+    /** Enable/disable charge pump.
+      @param enable 0 to disable, 1 to enable the internal charge pump.
+      */
+    void set_charge_pump_enable(unsigned char enable);
+    
+    // ----- BUFFER EDITING -----
 
     void clear();
     void set_pixel(int x, int y);
     void clear_pixel(int x, int y);
     void line(int x0, int y0, int x1, int y1);
-    
+
     void draw_string(char *font, int x, int y, const char *string);
     void draw_char(char *font, int x, int y, char c);
-    
-    void set_contrast(unsigned char value); // 1-256
-    void set_inverse(unsigned char value); // 0 or 1
-    void set_display_start_line(unsigned char value); // 0-63
-    void set_horizontal_flip(unsigned char value); // 0 or 1
-    void set_display_offset(unsigned char value); // 0-63
-    void set_multiplex_ratio(unsigned char value); // 15-63 (value+1 mux)
-    void set_com_output_scan_direction(unsigned char value); // 0 or 1
-    void set_com_pins_hardware_configuration(unsigned char sequential, unsigned char lr_remap); // 0 or 1 for both parametrs
 
 private:
     SPI _spi;
     DigitalOut _cs, _reset, _dc;
-    char _screen[1024];
-
+    unsigned char _screen[1024];
+    
     int _cursor_x, _cursor_y;
 
     void _send_command(unsigned char code);
@@ -69,39 +197,4 @@
 #define SSD1306_LCDWIDTH 128
 #define SSD1306_LCDHEIGHT 64
 
-#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
-
-#define SSD1306_EXTERNALVCC 0x1
-#define SSD1306_SWITCHCAPVCC 0x2
-
 #endif