olikraus / u8glib

Arduino Monochrom Graphics Library for LCDs and OLEDs
https://github.com/olikraus/u8glib/wiki
Other
1.25k stars 314 forks source link

Issue with ssd1306 128x64 displays on the TEENSY3.x #338

Open olikraus opened 9 years ago

olikraus commented 9 years ago

Originally reported on Google Code with ID 339

On the attached photo you can see the backsides of two 128x64 displays with ssd1306
controller.
The display color of the right one is white and the color of the left one is yellow/blue.
Both displays are working with hardware SPI on the ARDUINO DUE, but only the white
ones (on the right of the photo) are working with the TEENSY3.0! I tried it with software
SPI (native u8glib) and an own com procedure for hardware SPI, but only the white displays
(I tested several displays of both types) are working on the Teensy3.0!? I'am very
confused now!

For the sake of completeness here's my com procedure for hw SPI on the TEENSY3.0 (it's
a slightly modified version of this port: https://github.com/FriedCircuits/Ug8lib_Teensy):

#if defined(__MK20DX256__)|| defined(__MK20DX128__) 
#include <Arduino.h>
#include "u8glib.h"
#include <SPI.h>

uint8_t u8g_com_hw_spi_fn1(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr)
{
  switch(msg)
  {
    case U8G_COM_MSG_STOP:
      //STOP THE DEVICE
    break;

    case U8G_COM_MSG_INIT:
        //INIT HARDWARE INTERFACES, TIMERS, GPIOS...
        pinMode(3, OUTPUT);
        //For hardware SPI
        pinMode(10, OUTPUT);
        SPI.begin();
        SPI.setClockDivider(SPI_CLOCK_DIV2);

        pinMode(2, OUTPUT);
        digitalWrite(2, HIGH);
        // VDD (3.3V) goes high at start, lets just chill for a ms
        delay(1);
        // bring reset low
        digitalWrite(2, LOW);
        // wait 10ms
        delay(10);
        // bring out of reset
        digitalWrite(2, HIGH);

        //pinMode(MOSI, OUTPUT);
        //pinMode(SCK, OUTPUT);

        /*
        clkport     = portOutputRegister(digitalPinToPort(SCK));
        clkpinmask  = digitalPinToBitMask(SCK);
        mosiport    = portOutputRegister(digitalPinToPort(MOSI));
        mosipinmask = digitalPinToBitMask(MOSI);
        csport      = portOutputRegister(digitalPinToPort(10));
        cspinmask   = digitalPinToBitMask(10);
        dcport      = portOutputRegister(digitalPinToPort(3));
        dcpinmask   = digitalPinToBitMask(3);
        */

    break;

    case U8G_COM_MSG_ADDRESS:  
      //SWITCH FROM DATA TO COMMAND MODE (arg_val == 0 for command mode)
      if (arg_val != 0)
      {
          digitalWrite(3, HIGH);
      }
      else
      {
          digitalWrite(3, LOW);
      }

    break;

    case U8G_COM_MSG_CHIP_SELECT:
        if(arg_val == 0)
        {
            digitalWrite(10, HIGH);
        }
        else{
            digitalWrite(10, LOW);
        }
    break;

    case U8G_COM_MSG_RESET:
      //TOGGLE THE RESET PIN ON THE DISPLAY BY THE VALUE IN arg_val
      digitalWrite(2, arg_val);
    break;

    case U8G_COM_MSG_WRITE_BYTE:
      //WRITE BYTE TO DEVICE
      SPI.transfer(arg_val);

    break;

    case U8G_COM_MSG_WRITE_SEQ:
    case U8G_COM_MSG_WRITE_SEQ_P:
    {
      //WRITE A SEQUENCE OF BYTES TO THE DEVICE
      register uint8_t *ptr = static_cast<uint8_t *>(arg_ptr);
      while(arg_val > 0){
        SPI.transfer(*ptr++);
        arg_val--;
      }
     }
    break;

  }
  return 1;
}
#endif

Reported by michadies on 2015-05-08 20:02:51


olikraus commented 9 years ago
Not sure what I can do here.
The controller may be different: SH1106 instead of the SSD1306. Also power supply and
the logic levels are important. Maybe it is working with a 5V Arduino.

Also note that these OLEDs often do not have proper level shifters, but are designed
for 5V ports.

Reported by olikraus on 2015-05-09 05:45:56

olikraus commented 9 years ago
I'm now facing also problems with the white Displays.
Is it possible that there is a timing problem?
Might I have to add additional delays in my com procedure?

uint8_t u8g_com_hw_spi_fn1(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr)
{
  switch(msg)
  {
    case U8G_COM_MSG_STOP: //STOP THE DEVICE
    break;
    case U8G_COM_MSG_INIT:
    pinMode(3, OUTPUT); //DC
    pinMode(10, OUTPUT); //CS
    SPI.begin();
    SPI.setClockDivider(SPI_CLOCK_DIV2);
    pinMode(2, OUTPUT); //RES
    digitalWrite(2, HIGH);
    delay(1);
    digitalWrite(2, LOW);
    delay(10);
    digitalWrite(2, HIGH);
    break;
    case U8G_COM_MSG_ADDRESS: //SWITCH FROM DATA TO COMMAND MODE (arg_val == 0 for
command mode)
    if (arg_val) digitalWrite(3, HIGH);
    else digitalWrite(3, LOW);
    break;
    case U8G_COM_MSG_CHIP_SELECT:
    if (!arg_val) digitalWrite(10, HIGH);
    else digitalWrite(10, LOW);
    break;
    case U8G_COM_MSG_RESET: //TOGGLE THE RESET PIN ON THE DISPLAY BY THE VALUE IN arg_val
    digitalWrite(2, arg_val);
    break;
    case U8G_COM_MSG_WRITE_BYTE: //WRITE BYTE TO DEVICE
    SPI.transfer(arg_val);
    break;
    case U8G_COM_MSG_WRITE_SEQ:
    case U8G_COM_MSG_WRITE_SEQ_P: //WRITE A SEQUENCE OF BYTES TO THE DEVICE
    {
      register uint8_t *ptr = static_cast<uint8_t *>(arg_ptr);
      while(arg_val > 0){
        SPI.transfer(*ptr++);
        arg_val--;
        }
    }
    break;
  }
  return 1;
}

Reported by michadies on 2015-05-10 10:42:46