SH1106 0.96 OLED module support (SSD1306 compatible) + I2C fixes

This commit is contained in:
v01d 2016-08-13 19:20:20 -03:00
parent c145159c6b
commit 21e930cdba
4 changed files with 56 additions and 22 deletions

View file

@ -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

View file

@ -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 */

View file

@ -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;
}

View file

@ -42,6 +42,7 @@
#include <unistd.h>
#include <errno.h>
#include <debug.h>
#include <string.h>
#include <nuttx/kmalloc.h>
#include <nuttx/i2c/i2c_master.h>
@ -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)