/************************************************************************************** * drivers/lcd/ssd1306.h * * Copyright (C) 2015 Alan Carvalho de Assis * Author: Alan Carvalho de Assis * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * 3. Neither the name NuttX nor the names of its contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * **************************************************************************************/ #ifndef __DRIVERS_LCD_SSD1306_H #define __DRIVERS_LCD_SSD1306_H 1 /************************************************************************************** * Included Files **************************************************************************************/ #include #include #include #include #include /************************************************************************************** * Pre-processor Definitions **************************************************************************************/ /* Configuration **********************************************************************/ /* Limitations of the current configuration that I hope to fix someday */ #ifndef CONFIG_SSD1306_NINTERFACES # define CONFIG_SSD1306_NINTERFACES 1 #endif #if CONFIG_SSD1306_NINTERFACES != 1 # warning "This implementation supports only a single SSD1306 device" # undef CONFIG_SSD1306_NINTERFACES # define CONFIG_SSD1306_NINTERFACES 1 #endif #if !defined(CONFIG_LCD_UG2864HSWEG01) && !defined(CONFIG_LCD_UG2832HSWEG04) # error "Unknown and unsupported SSD1306 LCD" #endif #if defined(CONFIG_LCD_PORTRAIT) || defined(CONFIG_LCD_RPORTRAIT) # warning "No support for portrait modes" # undef CONFIG_LCD_LANDSCAPE # define CONFIG_LCD_LANDSCAPE 1 # undef CONFIG_LCD_PORTRAIT # undef CONFIG_LCD_RLANDSCAPE # undef CONFIG_LCD_RPORTRAIT #endif /* SSD1306 Commands *******************************************************************/ #define SSD1306_SETCOLL(ad) (0x00 | ((ad) & 0x0f)) /* Set Lower Column Address: (00h - 0fh) */ #define SSD1306_SETCOLH(ad) (0x10 | ((ad) & 0x0f)) /* Set Higher Column Address: (10h - 1fh) */ #define SSD1306_STARTLINE(ln) (0x40 | ((ln) & 0x3f)) /* Set Display Start Line: (40h - 7fh) */ #define SSD1306_CONTRAST_MODE (0x81) /* Set Contrast Control Register: (Double Bytes Command) */ # define SSD1306_CONTRAST(c) (c) #define SSD1306_SEGREMAP(m) (0xa0 | ((m) & 0x01)) /* Set Segment Re-map: (a0h - a1h) */ # define SSD1306_REMAPRIGHT SSD1306_SEGREMAP(0) /* Right rotation */ # define SSD1306_REMAPPLEFT SSD1306_SEGREMAP(1) /* Left rotation */ #define SSD1306_EDISPOFFON(s) (0xa4 | ((s) & 0x01)) /* Set Entire Display OFF/ON: (a4h - a5h) */ # define SSD1306_EDISPOFF SSD1306_EDISPOFFON(0) /* Display off */ # define SSD1306_EDISPON SSD1306_EDISPOFFON(1) /* Display on */ #define SSD1306_NORMREV(s) (0xa6 | ((s) & 0x01)) /* Set Normal/Reverse Display: (a6h -a7h) */ # define SSD1306_NORMAL SSD1306_NORMREV(0) /* Normal display */ # define SSD1306_REVERSE SSD1306_NORMREV(1) /* Reverse display */ #define SSD1306_MRATIO_MODE (0xa8) /* Set Multiplex Ration: (Double Bytes Command) */ # define SSD1306_MRATIO(d) ((d) & 0x3f) #define SSD1306_DCDC_MODE (0xad) /* Set DC-DC OFF/ON: (Double Bytes Command) */ # define SSD1306_DCDC_OFF (0x8a) # define SSD1306_DCDC_ON (0x8b) #define SSD1306_DISPOFFON(s) (0xae | ((s) & 0x01)) /* Display OFF/ON: (aeh - afh) */ # define SSD1306_DISPOFF SSD1306_DISPOFFON(0) /* Display off */ # define SSD1306_DISPON SSD1306_DISPOFFON(1) /* Display on */ #define SSD1306_PAGEADDR(a) (0xb0 | ((a) & 0x0f)) /* Set Page Address: (b0h - b7h) */ #define SSD1306_SCANDIR(d) (0xc0 | ((d) & 0x08)) /* Set Common Output Scan Direction: (c0h - c8h) */ # define SSD1306_SCANFROMCOM0 SSD1306_SCANDIR(0x00) /* Scan from COM[0] to COM[n-1]*/ # define SSD1306_SCANTOCOM0 SSD1306_SCANDIR(0x08) /* Scan from COM[n-1] to COM[0] */ #define SSD1306_DISPOFFS_MODE (0xd3) /* Set Display Offset: (Double Bytes Command) */ # define SSD1306_DISPOFFS(o) ((o) & 0x3f) #define SSD1306_CLKDIV_SET (0xd5) /* Set Display Clock Divide Ratio/Oscillator Frequency: (Double Bytes Command) */ # define SSD1306_CLKDIV(f,d) ((((f) & 0x0f) << 4) | ((d) & 0x0f)) #define SSD1306_CHRGPER_SET (0xd9) /* Set Dis-charge/Pre-charge Period: (Double Bytes Command) */ # define SSD1306_CHRGPER(d,p) ((((d) & 0x0f) << 4) | ((p) & 0x0f)) #define SSD1306_CMNPAD_CONFIG (0xda) /* Set Common pads hardware configuration: (Double Bytes Command) */ # define SSD1306_CMNPAD(c) ((0x02) | ((c) & 0x10)) #define SSD1306_VCOM_SET (0xdb) /* Set VCOM Deselect Level: (Double Byte Command) */ # define SSD1306_VCOM(v) (v) #define SSD1306_CHRPUMP_SET (0x8d) /* Charge Pump Setting */ # define SSD1306_CHRPUMP_ON (0x14) # define SSD1306_CHRPUMP_OFF (0x10) #define SSD1306_RMWSTART (0xe0) /* Read-Modify-Write: (e0h) */ #define SSD1306_NOP (0xe3) /* NOP: (e3h) */ #define SSD1306_END (0xee) /* End: (eeh) */ #define SSD1306_WRDATA(d) (d) /* Write Display Data */ #define SSD1306_STATUS_BUSY (0x80) /* Read Status */ #define SSD1306_STATUS_ONOFF (0x40) #define SSD1306_RDDATA(d) (d) /* Read Display Data */ /* Color Properties *******************************************************************/ /* Display Resolution * * The SSD1306 display controller can handle a resolution of 132x64. The UG-2864HSWEG01 * on the base board is 128x64; the UG-2832HSWEG04 is 128x32. */ #if defined(CONFIG_LCD_UG2864HSWEG01) # define SSD1306_DEV_NATIVE_XRES 128 /* Only 128 of 131 columns used */ # define SSD1306_DEV_NATIVE_YRES 64 /* 8 pages each 8 rows */ # define SSD1306_DEV_XOFFSET 2 /* Offset to logical column 0 */ # define SSD1306_DEV_PAGES 8 /* 8 pages */ # define SSD1306_DEV_CMNPAD 0x12 /* COM configuration */ #elif defined(CONFIG_LCD_UG2832HSWEG04) # define SSD1306_DEV_NATIVE_XRES 128 /* Only 128 of 131 columns used */ # define SSD1306_DEV_NATIVE_YRES 32 /* 4 pages each 8 rows */ # define SSD1306_DEV_XOFFSET 2 /* Offset to logical column 0 */ # define SSD1306_DEV_PAGES 4 /* 4 pages */ # define SSD1306_DEV_CMNPAD 0x02 /* COM configuration */ #endif #if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE) # define SSD1306_DEV_XRES SSD1306_DEV_NATIVE_XRES # define SSD1306_DEV_YRES SSD1306_DEV_NATIVE_YRES #else # define SSD1306_DEV_XRES SSD1306_DEV_NATIVE_YRES # define SSD1306_DEV_YRES SSD1306_DEV_NATIVE_XRES #endif #define SSD1306_DEV_DUTY (SSD1306_DEV_NATIVE_YRES-1) /* Bytes per logical row and actual device row */ #define SSD1306_DEV_XSTRIDE (SSD1306_DEV_XRES >> 3) #define SSD1306_DEV_YSTRIDE (SSD1306_DEV_YRES >> 3) /* Color depth and format */ #define SSD1306_DEV_BPP 1 #define SSD1306_DEV_COLORFMT FB_FMT_Y1 /* Default contrast */ #define SSD1306_DEV_CONTRAST (128) /* The size of the shadow frame buffer or one row buffer. * * Frame buffer size: 128 columns x 64 rows / 8 bits-per-pixel * Row size: 128 columns x 8 rows-per-page / 8 bits-per-pixel */ #define SSD1306_DEV_FBSIZE (SSD1306_DEV_XSTRIDE * SSD1306_DEV_YRES) #define SSD1306_DEV_ROWSIZE (SSD1306_DEV_XSTRIDE) /* Orientation. There seem to be device differences. */ #if defined(CONFIG_LCD_UG2864HSWEG01) # if defined(CONFIG_LCD_LANDSCAPE) # undef SSD1306_DEV_REVERSEX # undef SSD1306_DEV_REVERSEY # elif defined(CONFIG_LCD_RLANDSCAPE) # define SSD1306_DEV_REVERSEX 1 # define SSD1306_DEV_REVERSEY 1 # endif #elif defined(CONFIG_LCD_UG2832HSWEG04) # if defined(CONFIG_LCD_LANDSCAPE) # define SSD1306_DEV_REVERSEX 1 # undef SSD1306_DEV_REVERSEY # elif defined(CONFIG_LCD_RLANDSCAPE) # undef SSD1306_DEV_REVERSEX # define SSD1306_DEV_REVERSEY 1 # endif #endif /* Bit helpers */ #define LS_BIT (1 << 0) #define MS_BIT (1 << 7) /* Debug ******************************************************************************/ #ifdef CONFIG_DEBUG_LCD # define lcddbg(format, ...) dbg(format, ##__VA_ARGS__) # define lcdvdbg(format, ...) vdbg(format, ##__VA_ARGS__) #else # define lcddbg(x...) # define lcdvdbg(x...) #endif /************************************************************************************** * Public Type Definition **************************************************************************************/ /* This structure describes the state of the SSD1306 driver */ struct ssd1306_dev_s { struct lcd_dev_s dev; /* Publicly visible device structure */ /* Private LCD-specific information follows */ #ifdef CONFIG_LCD_SSD1306_SPI FAR struct spi_dev_s *spi; /* Cached SPI device reference */ #else FAR struct i2c_master_s *i2c; /* Cached SPI device reference */ uint8_t addr; /* 7-bit I2C address */ #endif uint8_t contrast; /* Current contrast setting */ bool on; /* true: display is on */ /* The SSD1306 does not support reading from the display memory in SPI mode. * Since there is 1 BPP and access is byte-by-byte, it is necessary to keep * a shadow copy of the framebuffer memory. At 128x64, this amounts to 1KB. */ uint8_t fb[SSD1306_DEV_FBSIZE]; }; /************************************************************************************** * Public Function Prototypes **************************************************************************************/ void ssd1306_sendbyte(FAR struct ssd1306_dev_s *priv, uint8_t regval); void ssd1306_sendblk(FAR struct ssd1306_dev_s *priv, uint8_t *data, uint8_t len); #ifdef CONFIG_LCD_SSD1306_SPI void ssd1306_select(FAR struct ssd1306_dev_s *priv, bool cs); void ssd1306_cmddata(FAR struct ssd1306_dev_s *priv, bool cmd); static inline void ssd1306_configspi(FAR struct spi_dev_s *spi) #else # define ssd1306_select(priv, cs) # define ssd1306_cmddata(priv, cmd) # define ssd1306_configspi(spi) #endif #endif /* __DRIVERS_LCD_SSD1306_H */