diff --git a/drivers/lcd/Kconfig b/drivers/lcd/Kconfig index 97618eba04b..b3abcaeabd8 100644 --- a/drivers/lcd/Kconfig +++ b/drivers/lcd/Kconfig @@ -285,8 +285,21 @@ config UG9664HSWAG01_POWER endif +config LCD_SH1106_OLED_132 + bool "Generic 0.96'' OLED Display Module (SH1106/SSD1306)" + default n + select LCD_SSD1306 + ---help--- + 0.96'' OLED Display Module, featuring an SH1106, typically advertised as + SSD1306. Mostly similar to "UG2864HSWEG01" although it uses the full + 132x28 pixels. + + Required LCD driver settings: + LCD_MAXCONTRAST should be 255, but any value >0 and <=255 will be accepted. + LCD_MAXPOWER should be 1: 0=off, 1=on + config LCD_UG2864HSWEG01 - bool "UG-2864HSWEG01 OLED Display Module" + bool "UG-2864HSWEG01 OLED Display Module (SSD1306)" default n select LCD_SSD1306 ---help--- @@ -301,7 +314,7 @@ config LCD_UG2864HSWEG01 SPI_CMDDATA - Include support for cmd/data selection. config LCD_UG2832HSWEG04 - bool "UG-2832HSWEG04 OLED Display Module" + bool "UG-2832HSWEG04 OLED Display Module (SSD1306)" default n depends on !LCD_UG2864HSWEG01 select LCD_SSD1306 @@ -323,22 +336,22 @@ config LCD_SSD1306 if LCD_SSD1306 choice - prompt "UG-2832HSWEG04 Interface" + prompt "SSD1306 Interface" default LCD_SSD1306_SPI config LCD_SSD1306_SPI - bool "UG-2832HSWEG04 on SPI Interface" + bool "SSD1306 on SPI Interface" select SPI ---help--- Enables support for the SPI interface. config LCD_SSD1306_I2C - bool "UG-2832HSWEG04 on I2C Interface" + bool "SSD1306 on I2C Interface" select I2C ---help--- Enables support for the I2C interface -endchoice # UG-2832HSWEG04 Interface +endchoice # SSD1306 Interface endif # LCD_SSD1306 if LCD_SSD1306_SPI @@ -369,13 +382,13 @@ endif # LCD_SSD1306_SPI if LCD_SSD1306_I2C config SSD1306_I2CADDR - int "UG-2832HSWEG04 I2C Address" + int "SSD1306 I2C Address" default 120 ---help--- I2C Address of SSD1306 config SSD1306_I2CFREQ - int "UG-2832HSWEG04 I2C Frequency" + int "SSD1306 I2C Frequency" default 400000 ---help--- I2C Frequency to communicate with SSD1306 diff --git a/drivers/lcd/ssd1306.h b/drivers/lcd/ssd1306.h index 696371ebfbc..7a22c95acb7 100644 --- a/drivers/lcd/ssd1306.h +++ b/drivers/lcd/ssd1306.h @@ -64,7 +64,7 @@ # define CONFIG_SSD1306_NINTERFACES 1 #endif -#if !defined(CONFIG_LCD_UG2864HSWEG01) && !defined(CONFIG_LCD_UG2832HSWEG04) +#if !defined(CONFIG_LCD_SH1106_OLED_132) && !defined(CONFIG_LCD_UG2864HSWEG01) && !defined(CONFIG_LCD_UG2832HSWEG04) # error "Unknown and unsupported SSD1306 LCD" #endif @@ -149,6 +149,12 @@ # define SSD1306_DEV_XOFFSET 2 /* Offset to logical column 0 */ # define SSD1306_DEV_PAGES 4 /* 4 pages */ # define SSD1306_DEV_CMNPAD 0x02 /* COM configuration */ +#elif defined(CONFIG_LCD_SH1106_OLED_132) +# define SSD1306_DEV_NATIVE_XRES 132 /* Full 132 columns used */ +# define SSD1306_DEV_NATIVE_YRES 64 /* 8 pages each 8 rows */ +# define SSD1306_DEV_XOFFSET 0 /* Offset to logical column 0 */ +# define SSD1306_DEV_PAGES 8 /* 8 pages */ +# define SSD1306_DEV_CMNPAD 0x12 /* COM configuration */ #endif #if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE) @@ -163,7 +169,12 @@ /* Bytes per logical row and actual device row */ +#if defined(CONFIG_LCD_SH1106_OLED_132) +#define SSD1306_DEV_XSTRIDE ((SSD1306_DEV_XRES >> 3) + 4) +#else #define SSD1306_DEV_XSTRIDE (SSD1306_DEV_XRES >> 3) +#endif + #define SSD1306_DEV_YSTRIDE (SSD1306_DEV_YRES >> 3) /* Color depth and format */ @@ -202,6 +213,14 @@ # undef SSD1306_DEV_REVERSEX # define SSD1306_DEV_REVERSEY 1 # endif +#elif defined(CONFIG_LCD_SH1106_OLED_132) +# if defined(CONFIG_LCD_LANDSCAPE) +# undef SSD1306_DEV_REVERSEX +# define SSD1306_DEV_REVERSEY 1 +# elif defined(CONFIG_LCD_RLANDSCAPE) +# define SSD1306_DEV_REVERSEX 1 +# undef SSD1306_DEV_REVERSEY +# endif #endif /* Bit helpers */ diff --git a/drivers/lcd/ssd1306_base.c b/drivers/lcd/ssd1306_base.c index 96a50c369d1..d26808e93d6 100644 --- a/drivers/lcd/ssd1306_base.c +++ b/drivers/lcd/ssd1306_base.c @@ -885,7 +885,7 @@ FAR struct lcd_dev_s *ssd1306_initialize(FAR struct i2c_master_s *dev, unsigned /* Clear the display */ up_mdelay(100); - ssd1306_fill(&priv->dev, SSD1306_Y1_BLACK); + ssd1306_fill(&priv->dev, CONFIG_NX_BGCOLOR); return &priv->dev; } diff --git a/drivers/lcd/ssd1306_i2c.c b/drivers/lcd/ssd1306_i2c.c index d6de937e35c..93391eba84f 100644 --- a/drivers/lcd/ssd1306_i2c.c +++ b/drivers/lcd/ssd1306_i2c.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -67,7 +68,7 @@ void ssd1306_sendbyte(FAR struct ssd1306_dev_s *priv, uint8_t regval) */ struct i2c_msg_s msg; - uint8_t txbuffer[1]; + uint8_t txbuffer[2]; int ret; #ifdef CONFIG_LCD_SSD1306_REGDEBUG @@ -78,7 +79,8 @@ void ssd1306_sendbyte(FAR struct ssd1306_dev_s *priv, uint8_t regval) * address followed by one byte of data. */ - txbuffer[0] = regval; + txbuffer[0] = 0x00; + txbuffer[1] = regval; /* Setup 8-bit SSD1306 address write message */ @@ -86,7 +88,7 @@ void ssd1306_sendbyte(FAR struct ssd1306_dev_s *priv, uint8_t regval) msg.addr = priv->addr; /* 7-bit address */ msg.flags = 0; /* Write transaction, beginning with START */ msg.buffer = txbuffer; /* Transfer from this address */ - msg.length = 1; /* Send one byte following the address + msg.length = 2; /* Send one byte following the address * (then STOP) */ /* Perform the transfer */ @@ -106,6 +108,8 @@ void ssd1306_sendbyte(FAR struct ssd1306_dev_s *priv, uint8_t regval) * ****************************************************************************/ +static uint8_t blk_buffer[SSD1306_DEV_XRES + 1]; + void ssd1306_sendblk(FAR struct ssd1306_dev_s *priv, uint8_t *data, uint8_t len) { /* 8-bit data read sequence: @@ -116,16 +120,14 @@ void ssd1306_sendblk(FAR struct ssd1306_dev_s *priv, uint8_t *data, uint8_t len) struct i2c_msg_s msg; int ret; - /* Setup 8-bit SSD1306 address write message */ + blk_buffer[0] = 0x40; + memcpy(&blk_buffer[1], data, len); - msg.frequency = CONFIG_SSD1306_I2CFREQ; /* I2C frequency */ - msg.addr = priv->addr; /* 7-bit address */ - msg.flags = 0; /* Write transaction, beginning with START */ - msg.buffer = data; /* Transfer from this address */ - msg.length = len; /* Send one byte following the address - * (then STOP) */ - - /* Perform the transfer */ + msg.frequency = CONFIG_SSD1306_I2CFREQ; + msg.addr = priv->addr; + msg.flags = 0; + msg.buffer = blk_buffer; + msg.length = len + 1; ret = I2C_TRANSFER(priv->i2c, &msg, 1); if (ret < 0)