Add SH1106 OLED support (#5787)
* modify oled_driver to support SH1106 also: - improve mechanism to specify which OLED IC we use - comment calc_bounds() - give OLED_COLUMN_OFFSET a default value - inline comment re: OLED MEMORY_MODE and SH1106 - update docs/feature_oled_driver.h for SH1106 support and related changes - docs: OLED: note we have tested SSD1306 on ARM boards (per @XScorpion2) - define out MEMORY_MODE when using SH1106 OLED driver * document that SSD1306 128x64 on AVR works Per @XScorpion2: https://github.com/qmk/qmk_firmware/pull/5787#discussion_r291837842
This commit is contained in:
		
							parent
							
								
									b92387b749
								
							
						
					
					
						commit
						e6a81133dd
					
				
					 3 changed files with 67 additions and 16 deletions
				
			
		| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue