Exemple #1
0
static int ssd1306_setpower(FAR struct lcd_dev_s *dev, int power)
{
  struct ssd1306_dev_s *priv = (struct ssd1306_dev_s *)dev;
  DEBUGASSERT(priv && (unsigned)power <= CONFIG_LCD_MAXPOWER);

  lcdvdbg("power: %d [%d]\n", power, priv->on ? CONFIG_LCD_MAXPOWER : 0);

  /* Lock and select device */

  ssd1306_select(priv, true);

  if (power <= 0)
    {
      /* Turn the display off */

      (void)ssd1306_sendbyte(priv, SSD1306_DISPOFF);
      priv->on = false;
    }
  else
    {
      /* Turn the display on */

      (void)ssd1306_sendbyte(priv, SSD1306_DISPON);
      priv->on = true;
    }

  /* De-select and unlock the device */

  ssd1306_select(priv, false);
  return OK;
}
Exemple #2
0
void ssd1306_fill(FAR struct lcd_dev_s *dev, uint8_t color)
{
  FAR struct ssd1306_dev_s  *priv = &g_oleddev;
  unsigned int page;

  /* Make an 8-bit version of the selected color */

  if (color & 1)
    {
      color = 0xff;
    }
  else
    {
      color = 0;
    }

  /* Initialize the framebuffer */

  memset(priv->fb, color, SSD1306_DEV_FBSIZE);

  /* Lock and select device */

  ssd1306_select(priv, true);

  /* Visit each page */

  for (page = 0; page < SSD1306_DEV_PAGES; page++)
    {
      /* Select command transfer */

      ssd1306_cmddata(priv, true);

      /* Set the column address to the XOFFSET value */

      ssd1306_sendbyte(priv, SSD1306_SETCOLL(SSD1306_DEV_XOFFSET));
      ssd1306_sendbyte(priv, SSD1306_SETCOLH(0));

      /* Set the page address */

      ssd1306_sendbyte(priv, SSD1306_PAGEADDR(page));

      /* Select data transfer */

      ssd1306_cmddata(priv, false);

      /* Transfer one page of the selected color */

      ssd1306_sendblk(priv, &priv->fb[page * SSD1306_DEV_XRES],
                         SSD1306_DEV_XRES);
    }

  /* De-select and unlock the device */

  ssd1306_select(priv, false);
}
Exemple #3
0
static int ssd1306_setcontrast(struct lcd_dev_s *dev, unsigned int contrast)
{
  struct ssd1306_dev_s *priv = (struct ssd1306_dev_s *)dev;
  unsigned int scaled;

  lcdvdbg("contrast: %d\n", contrast);
  DEBUGASSERT(priv);

  /* Verify the contrast value */

#ifdef CONFIG_DEBUG
  if (contrast > CONFIG_LCD_MAXCONTRAST)
    {
      return -EINVAL;
    }
#endif

  /* Scale contrast:  newcontrast = 255 * contrast / CONFIG_LCD_MAXCONTRAST
   * Where contrast is in the range {1,255}
   */

#if CONFIG_LCD_MAXCONTRAST != 255
  scaled = ((contrast << 8) - 1) / CONFIG_LCD_MAXCONTRAST;
#else
  scaled = contrast;
#endif

  /* Lock and select device */

  ssd1306_select(priv, true);

  /* Select command transfer */

  ssd1306_cmddata(priv, true);

  /* Set the contrast */

  (void)ssd1306_sendbyte(priv, SSD1306_CONTRAST_MODE);    /* Set contrast control register */
  (void)ssd1306_sendbyte(priv, SSD1306_CONTRAST(scaled)); /* Data 1: Set 1 of 256 contrast steps */
  priv->contrast = contrast;

  /* De-select and unlock the device */

  ssd1306_select(priv, false);
  return OK;
}
Exemple #4
0
unsigned char ssd1306_data(unsigned char data)
{
	unsigned char	buf[2];

	buf[0] = 0x40;		// [7] : continuation bit
				// [6] : data / command selection bit
	buf[1] = data;
	ssd1306_select();
	return HalI2CWrite(sizeof(buf), buf);
}
Exemple #5
0
FAR struct lcd_dev_s *ssd1306_initialize(FAR struct i2c_master_s *dev, unsigned int devno)
#endif
{
  FAR struct ssd1306_dev_s  *priv = &g_oleddev;

  lcdvdbg("Initializing\n");
  DEBUGASSERT(spi && devno == 0);

#ifdef CONFIG_LCD_SSD1306_SPI
  priv->spi = dev;

  /* Configure the SPI */

  ssd1306_configspi(priv->spi);

#else
  /* Remember the I2C configuration */

  priv->i2c  = dev;
  priv->addr = CONFIG_SSD1306_I2CADDR;
#endif

  /* Lock and select device */

  ssd1306_select(priv, true);

  /* Select command transfer */

  ssd1306_cmddata(priv, true);

  /* Configure OLED SPI or I/O, must be delayed 1-10ms */

  up_mdelay(5);

  /* Configure the device */

  ssd1306_sendbyte(priv, SSD1306_DISPOFF);          /* Display off 0xae */
  ssd1306_sendbyte(priv, SSD1306_SETCOLL(0));       /* Set lower column address 0x00 */
  ssd1306_sendbyte(priv, SSD1306_SETCOLH(0));       /* Set higher column address 0x10 */
  ssd1306_sendbyte(priv, SSD1306_STARTLINE(0));     /* Set display start line 0x40 */
  //ssd1306_sendbyte(priv, SSD1306_PAGEADDR(0));    /* Set page address  (Can ignore) */
  ssd1306_sendbyte(priv, SSD1306_CONTRAST_MODE);    /* Contrast control 0x81 */
  ssd1306_sendbyte(priv, SSD1306_CONTRAST(SSD1306_DEV_CONTRAST));  /* Default contrast 0xCF */
  ssd1306_sendbyte(priv, SSD1306_REMAPPLEFT);       /* Set segment remap left 95 to 0 | 0xa1 */
  //ssd1306_sendbyte(priv, SSD1306_EDISPOFF);       /* Normal display off 0xa4 (Can ignore) */
  ssd1306_sendbyte(priv, SSD1306_NORMAL);           /* Normal (un-reversed) display mode 0xa6 */
  ssd1306_sendbyte(priv, SSD1306_MRATIO_MODE);      /* Multiplex ratio 0xa8 */
  ssd1306_sendbyte(priv, SSD1306_MRATIO(SSD1306_DEV_DUTY));  /* Duty = 1/64 or 1/32 */
  //ssd1306_sendbyte(priv, SSD1306_SCANTOCOM0);     /* Com scan direction: Scan from COM[n-1] to COM[0] (Can ignore) */
  ssd1306_sendbyte(priv, SSD1306_DISPOFFS_MODE);    /* Set display offset 0xd3 */
  ssd1306_sendbyte(priv, SSD1306_DISPOFFS(0));
  ssd1306_sendbyte(priv, SSD1306_CLKDIV_SET);       /* Set clock divider 0xd5 */
  ssd1306_sendbyte(priv, SSD1306_CLKDIV(8, 0));     /* 0x80 */

  ssd1306_sendbyte(priv, SSD1306_CHRGPER_SET);      /* Set pre-charge period 0xd9 */
  ssd1306_sendbyte(priv, SSD1306_CHRGPER(0x0f, 1)); /* 0xf1 or 0x22 Enhanced mode */

  ssd1306_sendbyte(priv, SSD1306_CMNPAD_CONFIG);    /* Set common pads / set com pins hardware configuration 0xda */
  ssd1306_sendbyte(priv, SSD1306_CMNPAD(SSD1306_DEV_CMNPAD)); /* 0x12 or 0x02 */

  ssd1306_sendbyte(priv, SSD1306_VCOM_SET);         /* set vcomh 0xdb */
  ssd1306_sendbyte(priv, SSD1306_VCOM(0x40));

  ssd1306_sendbyte(priv, SSD1306_CHRPUMP_SET);      /* Set Charge Pump enable/disable 0x8d ssd1306 */
  ssd1306_sendbyte(priv, SSD1306_CHRPUMP_ON);       /* 0x14 close 0x10 */

  //ssd1306_sendbyte(priv, SSD1306_DCDC_MODE);      /* DC/DC control mode: on (SSD1306 Not supported) */
  //ssd1306_sendbyte(priv, SSD1306_DCDC_ON);

  ssd1306_sendbyte(priv, SSD1306_DISPON);           /* Display ON 0xaf */

  /* De-select and unlock the device */

  ssd1306_select(priv, false);

  /* Clear the display */

  up_mdelay(100);
  ssd1306_fill(&priv->dev, SSD1306_Y1_BLACK);
  return &priv->dev;
}
Exemple #6
0
static int ssd1306_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer,
                          size_t npixels)
{
  /* Because of this line of code, we will only be able to support a single UG device */

  FAR struct ssd1306_dev_s *priv = (FAR struct ssd1306_dev_s *)&g_oleddev;
  FAR uint8_t *fbptr;
  FAR uint8_t *ptr;
  uint8_t devcol;
  uint8_t fbmask;
  uint8_t page;
  uint8_t usrmask;
  int pixlen;
  uint8_t i;

  lcdvdbg("row: %d col: %d npixels: %d\n", row, col, npixels);
  DEBUGASSERT(buffer);

  /* Clip the run to the display */

  pixlen = npixels;
  if ((unsigned int)col + (unsigned int)pixlen > (unsigned int)SSD1306_DEV_XRES)
    {
      pixlen = (int)SSD1306_DEV_XRES - (int)col;
    }

  /* Verify that some portion of the run remains on the display */

  if (pixlen <= 0 || row > SSD1306_DEV_YRES)
    {
      return OK;
    }

  /* Perform coordinate conversion for reverse landscape mode.
   * If the rows are reversed then rows are are a mirror reflection of
   * top to bottom.
   */

#ifdef SSD1306_DEV_REVERSEY
  row = (SSD1306_DEV_YRES-1) - row;
#endif

  /* If the column is switched then the start of the run is the mirror of
   * the end of the run.
   *
   *            col+pixlen-1
   *     col    |
   *  0  |      |                    XRES
   *  .  S>>>>>>E                    .
   *  .                    E<<<<<<S  .
   *                       |      |
   *                       |      `-(XRES-1)-col
   *                       ` (XRES-1)-col-(pixlen-1)
   */

#ifdef SSD1306_DEV_REVERSEX
  col  = (SSD1306_DEV_XRES-1) - col;
  col -= (pixlen - 1);
#endif

  /* Get the page number.  The range of 64 lines is divided up into eight
   * pages of 8 lines each.
   */

  page = row >> 3;

  /* Update the shadow frame buffer memory. First determine the pixel
   * position in the frame buffer memory.  Pixels are organized like
   * this:
   *
   *  --------+---+---+---+---+-...-+-----+
   *  Segment | 0 | 1 | 2 | 3 | ... | 131 |
   *  --------+---+---+---+---+-...-+-----+
   *     D0   |   | X |   |   |     |     |
   *     D1   |   | X |   |   |     |     |
   *     D2   |   | X |   |   |     |     |
   *     D3   |   | X |   |   |     |     |
   *     D4   |   | X |   |   |     |     |
   *     D5   |   | X |   |   |     |     |
   *     D6   |   | X |   |   |     |     |
   *     D7   |   | X |   |   |     |     |
   *  --------+---+---+---+---+-...-+-----+
   *
   * So, in order to draw a white, horizontal line, at row 45. we
   * would have to modify all of the bytes in page 45/8 = 5.  We
   * would have to set bit 45%8 = 5 in every byte in the page.
   */

  fbmask  = 1 << (row & 7);
  fbptr   = &priv->fb[page * SSD1306_DEV_XRES + col];
#ifdef SSD1306_DEV_REVERSEX
  ptr     = fbptr + (pixlen - 1);
#else
  ptr     = fbptr;
#endif

#ifdef CONFIG_NX_PACKEDMSFIRST
  usrmask = MS_BIT;
#else
  usrmask = LS_BIT;
#endif

  for (i = 0; i < pixlen; i++)
    {
      /* Set or clear the corresponding bit */

#ifdef SSD1306_DEV_REVERSEX
      if ((*buffer & usrmask) != 0)
        {
          *ptr-- |= fbmask;
        }
      else
        {
          *ptr-- &= ~fbmask;
        }
#else
      if ((*buffer & usrmask) != 0)
        {
          *ptr++ |= fbmask;
        }
      else
        {
          *ptr++ &= ~fbmask;
        }
#endif

      /* Inc/Decrement to the next source pixel */

#ifdef CONFIG_NX_PACKEDMSFIRST
      if (usrmask == LS_BIT)
        {
          buffer++;
          usrmask = MS_BIT;
        }
      else
        {
          usrmask >>= 1;
        }
#else
      if (usrmask == MS_BIT)
        {
          buffer++;
          usrmask = LS_BIT;
        }
      else
        {
          usrmask <<= 1;
        }
#endif
    }

  /* Offset the column position to account for smaller horizontal
   * display range.
   */

  devcol = col + SSD1306_DEV_XOFFSET;

  /* Lock and select device */

  ssd1306_select(priv, true);

  /* Select command transfer */

  ssd1306_cmddata(priv, true);

  /* Set the starting position for the run */
  /* Set the column address to the XOFFSET value */

  ssd1306_sendbyte(priv, SSD1306_SETCOLL(devcol & 0x0f));
  ssd1306_sendbyte(priv, SSD1306_SETCOLH(devcol >> 4));

  /* Set the page address */

  ssd1306_sendbyte(priv, SSD1306_PAGEADDR(page));

  /* Select data transfer */

  ssd1306_cmddata(priv, false);

  /* Then transfer all of the data */

  ssd1306_sendblk(priv, fbptr, pixlen);

  /* De-select and unlock the device */

  ssd1306_select(priv, false);
  return OK;
}