diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/oled/oled_driver.c | 31 | ||||
| -rw-r--r-- | drivers/oled/oled_driver.h | 14 | 
2 files changed, 41 insertions, 4 deletions
diff --git a/drivers/oled/oled_driver.c b/drivers/oled/oled_driver.c index 643e528946..a54f5fadc3 100644 --- a/drivers/oled/oled_driver.c +++ b/drivers/oled/oled_driver.c @@ -33,6 +33,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #endif // defined(__AVR__)  // Used commands from spec sheet: https://cdn-shop.adafruit.com/datasheets/SSD1306.pdf +// for SH1106: https://www.velleman.eu/downloads/29/infosheets/sh1106_datasheet.pdf +  // Fundamental Commands  #define CONTRAST                0x81  #define DISPLAY_ALL_ON          0xA5 @@ -40,6 +42,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #define NORMAL_DISPLAY          0xA6  #define DISPLAY_ON              0xAF  #define DISPLAY_OFF             0xAE +#define NOP                     0xE3  // Scrolling Commands  #define ACTIVATE_SCROLL         0x2F @@ -53,6 +56,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #define MEMORY_MODE             0x20  #define COLUMN_ADDR             0x21  #define PAGE_ADDR               0x22 +#define PAM_SETCOLUMN_LSB       0x00 +#define PAM_SETCOLUMN_MSB       0x10 +#define PAM_PAGE_ADDR           0xB0 // 0xb0 -- 0xb7  // Hardware Configuration Commands  #define DISPLAY_START_LINE      0x40 @@ -158,7 +164,11 @@ bool oled_init(uint8_t rotation) {      DISPLAY_OFFSET, 0x00,      DISPLAY_START_LINE | 0x00,      CHARGE_PUMP, 0x14, -    MEMORY_MODE, 0x00, }; // Horizontal addressing mode +#if (OLED_IC != OLED_IC_SH1106) +    // MEMORY_MODE is unsupported on SH1106 (Page Addressing only) +    MEMORY_MODE, 0x00, // Horizontal addressing mode +#endif +  };    if (I2C_TRANSMIT_P(display_setup1) != I2C_STATUS_SUCCESS) {      print("oled_init cmd set 1 failed\n");      return false; @@ -219,10 +229,25 @@ void oled_clear(void) {  static void calc_bounds(uint8_t update_start, uint8_t* cmd_array)  { -  cmd_array[1] = OLED_BLOCK_SIZE * update_start % OLED_DISPLAY_WIDTH; -  cmd_array[4] = OLED_BLOCK_SIZE * update_start / OLED_DISPLAY_WIDTH; +  // Calculate commands to set memory addressing bounds. +  uint8_t start_page = OLED_BLOCK_SIZE * update_start / OLED_DISPLAY_WIDTH; +  uint8_t start_column = OLED_BLOCK_SIZE * update_start % OLED_DISPLAY_WIDTH; +#if (OLED_IC == OLED_IC_SH1106) +  // Commands for Page Addressing Mode. Sets starting page and column; has no end bound. +  // Column value must be split into high and low nybble and sent as two commands. +  cmd_array[0] = PAM_PAGE_ADDR | start_page; +  cmd_array[1] = PAM_SETCOLUMN_LSB | ((OLED_COLUMN_OFFSET + start_column) & 0x0f); +  cmd_array[2] = PAM_SETCOLUMN_MSB | ((OLED_COLUMN_OFFSET + start_column) >> 4 & 0x0f); +  cmd_array[3] = NOP; +  cmd_array[4] = NOP; +  cmd_array[5] = NOP; +#else +  // Commands for use in Horizontal Addressing mode. +  cmd_array[1] = start_column; +  cmd_array[4] = start_page;    cmd_array[2] = (OLED_BLOCK_SIZE + OLED_DISPLAY_WIDTH - 1) % OLED_DISPLAY_WIDTH + cmd_array[1];    cmd_array[5] = (OLED_BLOCK_SIZE + OLED_DISPLAY_WIDTH - 1) / OLED_DISPLAY_WIDTH - 1; +#endif  }  static void calc_bounds_90(uint8_t update_start, uint8_t* cmd_array) diff --git a/drivers/oled/oled_driver.h b/drivers/oled/oled_driver.h index abbdde57ed..03dda2e64a 100644 --- a/drivers/oled/oled_driver.h +++ b/drivers/oled/oled_driver.h @@ -19,6 +19,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #include <stdint.h>  #include <stdbool.h> +// an enumeration of the chips this driver supports +#define OLED_IC_SSD1306 0 +#define OLED_IC_SH1106  1  #if defined(OLED_DISPLAY_CUSTOM)    // Expected user to implement the necessary defines @@ -100,7 +103,16 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.    // #define OLED_TARGET_MAP { 48, 32, 16, 0, 56, 40, 24, 8 }  #endif // defined(OLED_DISPLAY_CUSTOM) -// Address to use for tthe i2d oled communication +#if !defined(OLED_IC) +  #define OLED_IC OLED_IC_SSD1306 +#endif + +// the column address corresponding to the first column in the display hardware +#if !defined(OLED_COLUMN_OFFSET) +  #define OLED_COLUMN_OFFSET 0 +#endif + +// Address to use for the i2c oled communication  #if !defined(OLED_DISPLAY_ADDRESS)    #define OLED_DISPLAY_ADDRESS 0x3C  #endif  | 
