First commit
authorKevin Townsend <kevin@ktownsend.com>
Tue, 3 Jul 2012 17:30:06 +0000 (19:30 +0200)
committerKevin Townsend <kevin@ktownsend.com>
Tue, 3 Jul 2012 17:30:06 +0000 (19:30 +0200)
drivers/displays/tft/hw/s6b33b6x.c [new file with mode: 0644]
drivers/displays/tft/hw/s6b33b6x.h [new file with mode: 0644]

diff --git a/drivers/displays/tft/hw/s6b33b6x.c b/drivers/displays/tft/hw/s6b33b6x.c
new file mode 100644 (file)
index 0000000..49a3ba7
--- /dev/null
@@ -0,0 +1,409 @@
+/**************************************************************************/
+/*!
+    @file     s6b33b6x.c
+    @author   K. Townsend (www.adafruit.com)
+
+    @section  DESCRIPTION
+
+    Driver for S6B33B6X 128x128 pixel RGB OLED displays.
+
+    This driver uses a 3 or 4-pin SPI interface and 16-bit RGB565 colours.
+
+    @section  LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, Adafruit Industries
+    All rights reserved.
+
+    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 of the copyright holders 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 ''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 HOLDER 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.
+*/
+/**************************************************************************/
+#include "s6b33b6x.h"
+#include "core/systick/systick.h"
+
+static volatile lcdOrientation_t lcdOrientation = LCD_ORIENTATION_PORTRAIT;
+static lcdProperties_t s6b33b6xProperties = { 128, 128, false, false, false, false, false };
+
+/*************************************************/
+/* Private Methods                               */
+/*************************************************/
+
+#define CMD(c)        do { CLR_DC; CLR_CS; s6b33b6xSendByte( c, 1 ); SET_CS; } while (0)
+#define DATA(c)       do { SET_DC; CLR_CS; s6b33b6xSendByte( c, 0 ); SET_CS; } while (0)
+#define DELAY(ms)     do { systickDelay( ms / CFG_SYSTICK_DELAY_IN_MS ); } while(0)
+
+/**************************************************************************/
+/*!
+    @brief Simulates an SPI write using GPIO.
+
+    @param[in]  byte
+                The byte to send
+    @param[in]  command
+                1 if this is a command, 0 if it is data
+*/
+/**************************************************************************/
+void s6b33b6xSendByte(uint8_t byte, uint8_t command)
+{
+  int8_t i;
+
+  // Make sure clock pin starts high (CPOL = 1)
+  SET_SCK;
+
+#if defined S6B33B6X_BUS_SPI3
+  CLR_SCK;
+  if (command)
+  {
+    CLR_SID;
+  }
+  else
+  {
+    SET_SID;
+  }
+  // Read on rising edge (CPHA = 1)
+  SET_SCK
+#endif
+
+  for (i=0; i<8; i++)
+  {
+    // Set clock pin low
+    CLR_SCK;
+    // Set data pin high or low depending on the value of the current bit
+    if((byte & 0x80) == 0x80)
+    {
+      SET_SID;
+    }
+    else
+    {
+      CLR_SID;
+    }
+    // Set clock pin high (CPHA = 1, read on rising edge)
+    SET_SCK;
+    byte = (byte << 1);
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Sets the cursor to the specified X/Y position
+*/
+/**************************************************************************/
+void s6b33b6xSetCursor(uint8_t x, uint8_t y)
+{
+  if ((x >= s6b33b6xProperties.width) || (y >= s6b33b6xProperties.height))
+    return;
+
+  CMD(S6B33B6X_CMD_ROWADDRESSAREASET);
+  CMD(2+y);     // Start Address
+  CMD(129);   // End Address (129)
+
+  CMD(S6B33B6X_CMD_COLUMNADDRESSAREASET);
+  CMD(2+x);   // Start Address
+  CMD(129);   // End Address (129)
+}
+
+/*************************************************/
+/* Public Methods                                */
+/*************************************************/
+
+/**************************************************************************/
+/*!
+    @brief  Configures any pins or HW and initialises the LCD controller
+*/
+/**************************************************************************/
+void lcdInit(void)
+{
+  gpioInit();
+
+  // Make sure CS starts high
+  SET_CS;
+
+  // Make sure clock pin starts high (CPOL = 1)
+  SET_SCK;
+
+  // Set all pins to output
+  gpioSetDir(S6B33B6X_SCK_PORT, S6B33B6X_SCK_PIN, gpioDirection_Output);
+  gpioSetDir(S6B33B6X_SID_PORT, S6B33B6X_SID_PIN, gpioDirection_Output);
+  gpioSetDir(S6B33B6X_RST_PORT, S6B33B6X_RST_PIN, gpioDirection_Output);
+  gpioSetDir(S6B33B6X_CS_PORT, S6B33B6X_CS_PIN, gpioDirection_Output);
+
+#if !defined S6B33B6X_BUS_SPI3
+  gpioSetDir(S6B33B6X_DC_PORT, S6B33B6X_DC_PIN, gpioDirection_Output);
+#endif
+
+  // Reset the LCD
+  SET_RST;
+  DELAY(20);
+  CLR_RST;
+  DELAY(50);
+  SET_RST;
+  DELAY(20);
+
+  // Init sequence
+  CMD(S6B33B6X_CMD_STANDBYMODEOFF);
+  DELAY(50);
+  CMD(S6B33B6X_CMD_OSCILLATIONMODESET);
+  CMD(0x01);
+  CMD(S6B33B6X_CMD_DCDCCONTROL);
+  CMD(0x0f);
+  CMD(S6B33B6X_CMD_DCDCAMPONOFFSET);
+  CMD(0x0f);
+  DELAY(50);
+  CMD(S6B33B6X_CMD_TEMPCOMPENSATIONSET);
+  CMD(0x01);
+  CMD(0x2e);
+  CMD(S6B33B6X_CMD_RAMSKIPAREASET);
+  CMD(0x00);
+  CMD(S6B33B6X_CMD_SPECIFIEDDISPLAYPATTERN);
+  CMD(0x00);
+  CMD(S6B33B6X_CMD_DRIVEROUTPUTMODESET);
+  CMD(0x03);
+  CMD(S6B33B6X_CMD_DCDCCLOCKDIVISIONSET);
+  CMD(0x22);
+  CMD(S6B33B6X_CMD_ADDRESSINGMODESET);
+  CMD(0x1d);
+  CMD(S6B33B6X_CMD_ROWVECTORMODESET);
+  CMD(0x0e);
+  CMD(S6B33B6X_CMD_ENTRYMODESET);
+  CMD(0x80);
+  CMD(S6B33B6X_CMD_ROWADDRESSAREASET);
+  CMD(0x00);
+  CMD(0x83);
+  CMD(S6B33B6X_CMD_COLUMNADDRESSAREASET);
+  CMD(0x00);
+  CMD(0x83);
+  CMD(S6B33B6X_CMD_NBLOCKINVERSIONSET);
+  CMD(0x8d);
+  CMD(S6B33B6X_CMD_CONTRASTCONTROL);
+  CMD(0x45);
+  CMD(0x2b);
+  CMD(0x69);
+  CMD(0x22);
+  CMD(0x11);
+  CMD(S6B33B6X_CMD_PARTIALDISPLAYMODESET);
+  CMD(0x00);
+  CMD(S6B33B6X_CMD_PARTIALDISPLAYSTARTLINE);
+  CMD(0x00);
+  CMD(S6B33B6X_CMD_PARTIALDISPLAYENDLINE);
+  CMD(0x9f);
+  CMD(0x59);
+  CMD(0x00);
+  CMD(0x00);
+  CMD(0x9f);
+  CMD(0x00);
+  CMD(S6B33B6X_CMD_DISPLAYON);
+  DELAY(500);
+
+  // Clear screen
+  lcdFillRGB(COLOR_RED);
+}
+
+/**************************************************************************/
+/*!
+    @brief  Enables or disables the LCD backlight
+*/
+/**************************************************************************/
+void lcdBacklight(bool state)
+{
+  // ToDo: Add BL pin and toggle here
+}
+
+/**************************************************************************/
+/*!
+    @brief  Renders a simple test pattern on the LCD
+*/
+/**************************************************************************/
+void lcdTest(void)
+{
+  uint32_t i,j;
+  s6b33b6xSetCursor(0, 0);
+
+  for(i=0;i<128;i++)
+  {
+    for(j=0;j<128;j++)
+    {
+      if(i>111){DATA(COLOR_WHITE>>8);DATA((uint8_t)COLOR_WHITE);}
+      else if(i>95){DATA(COLOR_BLUE>>8);DATA((uint8_t)COLOR_BLUE);}
+      else if(i>79){DATA(COLOR_GREEN>>8);DATA((uint8_t)COLOR_GREEN);}
+      else if(i>63){DATA(COLOR_CYAN>>8);DATA((uint8_t)COLOR_CYAN);}
+      else if(i>47){DATA(COLOR_RED>>8);DATA((uint8_t)COLOR_RED);}
+      else if(i>31){DATA(COLOR_MAGENTA>>8);DATA((uint8_t)COLOR_MAGENTA);}
+      else if(i>15){DATA(COLOR_YELLOW>>8);DATA((uint8_t)COLOR_YELLOW);}
+      else {DATA(COLOR_BLACK>>8);DATA((uint8_t)COLOR_BLACK);}
+    }
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Fills the LCD with the specified 16-bit color
+*/
+/**************************************************************************/
+void lcdFillRGB(uint16_t data)
+{
+  uint16_t x,y;
+
+  s6b33b6xSetCursor(0, 0);
+
+  for(x=0;x<128;x++)
+  {
+    for(y=0;y<128;y++)
+    {
+      DATA(data>>8);
+      DATA(data & 0xFF);
+    }
+  }
+}
+
+/**************************************************************************/
+/*!
+    @brief  Draws a single pixel at the specified X/Y location
+*/
+/**************************************************************************/
+void lcdDrawPixel(uint16_t x, uint16_t y, uint16_t color)
+{
+  if ((x >= s6b33b6xProperties.width) || (y >= s6b33b6xProperties.height))
+    return;
+
+  s6b33b6xSetCursor((uint8_t)x, (uint8_t)y);
+  DATA(color >> 8);
+  DATA(color);
+}
+
+/**************************************************************************/
+/*!
+    @brief  Draws an array of consecutive RGB565 pixels (much
+            faster than addressing each pixel individually)
+*/
+/**************************************************************************/
+void lcdDrawPixels(uint16_t x, uint16_t y, uint16_t *data, uint32_t len)
+{
+  // ToDo
+}
+
+/**************************************************************************/
+/*!
+    @brief  Optimised routine to draw a horizontal line faster than
+            setting individual pixels
+*/
+/**************************************************************************/
+void lcdDrawHLine(uint16_t x0, uint16_t x1, uint16_t y, uint16_t color)
+{
+  // ToDo
+}
+
+/**************************************************************************/
+/*!
+    @brief  Optimised routine to draw a vertical line faster than
+            setting individual pixels
+*/
+/**************************************************************************/
+void lcdDrawVLine(uint16_t x, uint16_t y0, uint16_t y1, uint16_t color)
+{
+  // Not supported
+}
+
+/**************************************************************************/
+/*!
+    @brief  Gets the 16-bit color of the pixel at the specified location
+*/
+/**************************************************************************/
+uint16_t lcdGetPixel(uint16_t x, uint16_t y)
+{
+  // Not supported
+  return 0;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Sets the LCD orientation to horizontal and vertical
+*/
+/**************************************************************************/
+void lcdSetOrientation(lcdOrientation_t orientation)
+{
+  // Not supported
+}
+
+/**************************************************************************/
+/*!
+    @brief  Gets the current screen orientation (horizontal or vertical)
+*/
+/**************************************************************************/
+lcdOrientation_t lcdGetOrientation(void)
+{
+  return lcdOrientation;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Gets the width in pixels of the LCD screen (varies depending
+            on the current screen orientation)
+*/
+/**************************************************************************/
+uint16_t lcdGetWidth(void)
+{
+  return s6b33b6xProperties.width;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Gets the height in pixels of the LCD screen (varies depending
+            on the current screen orientation)
+*/
+/**************************************************************************/
+uint16_t lcdGetHeight(void)
+{
+  return s6b33b6xProperties.height;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Scrolls the contents of the LCD screen vertically the
+            specified number of pixels using a HW optimised routine
+*/
+/**************************************************************************/
+void lcdScroll(int16_t pixels, uint16_t fillColor)
+{
+  // Not Supported
+}
+
+/**************************************************************************/
+/*!
+    @brief  Gets the controller's 16-bit (4 hexdigit) ID
+*/
+/**************************************************************************/
+uint16_t lcdGetControllerID(void)
+{
+  return 0x33b6;
+}
+
+/**************************************************************************/
+/*!
+    @brief  Returns the LCDs 'lcdProperties_t' that describes the LCDs
+            generic capabilities and dimensions
+*/
+/**************************************************************************/
+lcdProperties_t lcdGetProperties(void)
+{
+  return s6b33b6xProperties;
+}
diff --git a/drivers/displays/tft/hw/s6b33b6x.h b/drivers/displays/tft/hw/s6b33b6x.h
new file mode 100644 (file)
index 0000000..7caaaaf
--- /dev/null
@@ -0,0 +1,133 @@
+/**************************************************************************/
+/*!
+    @file     s6b33b6x.h
+    @author   K. Townsend (www.adafruit.com)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, Adafruit Industries
+    All rights reserved.
+
+    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 of the copyright holders 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 ''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 HOLDER 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 __S6B33B6X_H__
+#define __S6B33B6X_H__
+
+#include "projectconfig.h"
+#include "drivers/displays/tft/lcd.h"
+#include "core/gpio/gpio.h"
+
+/*=========================================================================
+    SPI modes
+    -----------------------------------------------------------------------
+    The display supports both 3-pin and 4-pin SPI modes
+
+    3-PIN MODE      Saves one GPIO pin (D/C) by adding the D/C bit before
+                    every transfer, meaning that 9 bits are sent every frame
+                    instead of 8.  You have slightly slower performance
+                    but use less pins. Requires 3 GPIO pins (SCK, SID, RST)
+
+    4-PIN MODE      Uses a normal SPI interface with 8-bits per transfer,
+                    plus a dedicated D/C pin to indicate if this is a
+                    command or data byte. Requires 4 GPIO pins (SCK, SID,
+                    RST, DC).
+
+    To select one of the SPI modes, make sure the pins are correctly
+    set on the display and uncomment the appropriate define below.
+    -----------------------------------------------------------------------*/
+    // #define S6B33B6X_BUS_SPI3
+    #define S6B33B6X_BUS_SPI4
+/*=========================================================================*/
+
+// Control pins
+#define S6B33B6X_SCK_PORT                (2) // SCK
+#define S6B33B6X_SCK_PIN                 (1)
+#define S6B33B6X_SID_PORT                (2) // DATAIN/MOSI
+#define S6B33B6X_SID_PIN                 (2)
+#define S6B33B6X_CS_PORT                 (2) // CS
+#define S6B33B6X_CS_PIN                  (3)
+#define S6B33B6X_RST_PORT                (2) // RST
+#define S6B33B6X_RST_PIN                 (4)
+#define S6B33B6X_DC_PORT                 (2) // D/I (only required for 4-pin SPI)
+#define S6B33B6X_DC_PIN                  (5)
+
+// These registers allow fast single cycle clear+set of bits (see section 8.5.1 of LPC1343 UM)
+#define S6B33B6X_GPIO2DATA_SCK          (*(pREG32 (GPIO_GPIO2_BASE + ((1 << S6B33B6X_SCK_PIN) << 2))))
+#define S6B33B6X_GPIO2DATA_SID          (*(pREG32 (GPIO_GPIO2_BASE + ((1 << S6B33B6X_SID_PIN) << 2))))
+#define S6B33B6X_GPIO2DATA_CS           (*(pREG32 (GPIO_GPIO2_BASE + ((1 << S6B33B6X_CS_PIN) << 2))))
+#define S6B33B6X_GPIO2DATA_RST          (*(pREG32 (GPIO_GPIO2_BASE + ((1 << S6B33B6X_RST_PIN) << 2))))
+#define S6B33B6X_GPIO2DATA_DC           (*(pREG32 (GPIO_GPIO2_BASE + ((1 << S6B33B6X_DC_PIN) << 2))))
+
+// Macros for control line state
+#define CLR_SCK                         do { S6B33B6X_GPIO2DATA_SCK = (0); } while (0)
+#define SET_SCK                         do { S6B33B6X_GPIO2DATA_SCK = (1 << S6B33B6X_SCK_PIN); } while (0)
+#define CLR_SID                         do { S6B33B6X_GPIO2DATA_SID = (0); } while (0)
+#define SET_SID                         do { S6B33B6X_GPIO2DATA_SID = (1 << S6B33B6X_SID_PIN); } while (0)
+#define CLR_CS                          do { S6B33B6X_GPIO2DATA_CS  = (0); } while (0)
+#define SET_CS                          do { S6B33B6X_GPIO2DATA_CS  = (1 << S6B33B6X_CS_PIN); } while (0)
+#define CLR_RST                         do { S6B33B6X_GPIO2DATA_RST = (0); } while (0)
+#define SET_RST                         do { S6B33B6X_GPIO2DATA_RST = (1 << S6B33B6X_RST_PIN); } while (0)
+#define CLR_DC                          do { S6B33B6X_GPIO2DATA_DC  = (0); } while (0)
+#define SET_DC                          do { S6B33B6X_GPIO2DATA_DC  = (1 << S6B33B6X_DC_PIN); } while (0)
+
+// S6B33B6X Commands
+enum
+{
+  S6B33B6X_CMD_NOP                      = 0x00,
+  S6B33B6X_CMD_OSCILLATIONMODESET       = 0x02,
+  S6B33B6X_CMD_DRIVEROUTPUTMODESET      = 0x10,
+  S6B33B6X_CMD_MONITORSIGNALCONTROL     = 0x18,
+  S6B33B6X_CMD_DCDCCONTROL              = 0x20,
+  S6B33B6X_CMD_DCDCCLOCKDIVISIONSET     = 0x24,
+  S6B33B6X_CMD_DCDCAMPONOFFSET          = 0x26,
+  S6B33B6X_CMD_TEMPCOMPENSATIONSET      = 0x28,
+  S6B33B6X_CMD_CONTRASTCONTROL          = 0x2A,
+  S6B33B6X_CMD_STANDBYMODEOFF           = 0x2C,
+  S6B33B6X_CMD_STANDBYMODEON            = 0x2D,
+  S6B33B6X_CMD_ADDRESSINGMODESET        = 0x30,
+  S6B33B6X_CMD_ROWVECTORMODESET         = 0x32,
+  S6B33B6X_CMD_NBLOCKINVERSIONSET       = 0x34,
+  S6B33B6X_CMD_DRIVINGMODESET           = 0x36,
+  S6B33B6X_CMD_ENTRYMODESET             = 0x40,
+  S6B33B6X_CMD_ROWADDRESSAREASET        = 0x42,
+  S6B33B6X_CMD_COLUMNADDRESSAREASET     = 0x43,
+  S6B33B6X_CMD_RAMSKIPAREASET           = 0x45,
+  S6B33B6X_CMD_DISPLAYOFF               = 0x50,
+  S6B33B6X_CMD_DISPLAYON                = 0x51,
+  S6B33B6X_CMD_SPECIFIEDDISPLAYPATTERN  = 0x53,
+  S6B33B6X_CMD_PARTIALDISPLAYMODESET    = 0x55,
+  S6B33B6X_CMD_PARTIALDISPLAYSTARTLINE  = 0x56,
+  S6B33B6X_CMD_PARTIALDISPLAYENDLINE    = 0x57,
+  S6B33B6X_CMD_OTPMODEOFF               = 0xEA,
+  S6B33B6X_CMD_OTPMODEON                = 0xEB,
+  S6B33B6X_CMD_OFFSETVOLUMESET          = 0xED,
+  S6B33B6X_CMD_OTPWRITEENABLE           = 0xEF
+};
+
+void s6b33b6xSetCursor(uint8_t x, uint8_t y);
+void s6b33b6xSendByte(uint8_t byte, uint8_t command);
+
+#endif
This page took 0.037758 seconds and 4 git commands to generate.