Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

t6963 not quite working #197

Closed
asfarley opened this issue Feb 15, 2017 · 8 comments
Closed

t6963 not quite working #197

asfarley opened this issue Feb 15, 2017 · 8 comments

Comments

@asfarley
Copy link

Hi,

I'm having some trouble getting this library working for a t6963 controller using a 240x128 display. I'm using a FRDM-K22F board (Arm Cortex-M4).

The LCD responds to some commands (u8g2_InitDisplay seems to clear the display) but other commands don't seem to be working. u8g2_ClearDisplay results in some garbage on the screen insteaed of clearing it:
oled garbage

The function u8g2_DrawStr has no visible effect.

My LCD actually has an RA6963 module built in but I believe it's equivalent to T6963. I initially tried u8x8 but it looks like u8x8 isn't compatible with the t6963 so I've switched to u8g2.

Any idea what could be going wrong here?

My initialization:

u8g2_Setup_t6963_240x128_1(&u8g2, U8G2_R0, u8x8_byte_8bit_8080mode, u8x8_gpio_and_delay_frdmk22f);  // init u8g2 structure
u8g2_InitDisplay(&u8g2); // send init sequence to the display, display is in sleep mode after this,
u8g2_SetPowerSave(&u8g2, 1); // wake up display
u8g2_SetFont(&u8g2, u8g2_font_8x13_tf);

And my delay/gpio callback:

uint8_t u8x8_gpio_and_delay_frdmk22f(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
  switch(msg)
  {
    case U8X8_MSG_GPIO_AND_DELAY_INIT:  // called once during init phase of u8g2/u8x8
      break;                            // can be used to setup pins
    case U8X8_MSG_DELAY_NANO:           // delay arg_int * 1 nano second
      WAIT1_Waitns(arg_int);
      break;
    case U8X8_MSG_DELAY_100NANO:        // delay arg_int * 100 nano seconds
      WAIT1_Waitns(100*arg_int);
      break;
    case U8X8_MSG_DELAY_10MICRO:        // delay arg_int * 10 micro seconds
      WAIT1_Waitus(10*arg_int);
      break;
    case U8X8_MSG_DELAY_MILLI:          // delay arg_int * 1 milli second
      WAIT1_Waitms(arg_int);
      break;
    case U8X8_MSG_DELAY_I2C:                // arg_int is the I2C speed in 100KHz, e.g. 4 = 400 KHz
      break;                            // arg_int=1: delay by 5us, arg_int = 4: delay by 1.25us
    case U8X8_MSG_GPIO_D0:              // D0 or SPI clock pin: Output level in arg_int
      Bit6_PutVal(arg_int);
    //case U8X8_MSG_GPIO_SPI_CLOCK:
      break;
    case U8X8_MSG_GPIO_D1:              // D1 or SPI data pin: Output level in arg_int
      Bit4_PutVal(arg_int);
    //case U8X8_MSG_GPIO_SPI_DATA:
      break;
    case U8X8_MSG_GPIO_D2:              // D2 pin: Output level in arg_int
      Bit3_PutVal(arg_int);
      break;
    case U8X8_MSG_GPIO_D3:              // D3 pin: Output level in arg_int
      Bit9_PutVal(arg_int);
      break;
    case U8X8_MSG_GPIO_D4:              // D4 pin: Output level in arg_int
      Bit8_PutVal(arg_int);
      break;
    case U8X8_MSG_GPIO_D5:              // D5 pin: Output level in arg_int
      Bit10_PutVal(arg_int);
      break;
    case U8X8_MSG_GPIO_D6:              // D6 pin: Output level in arg_int
      Bit7_PutVal(arg_int);
      break;
    case U8X8_MSG_GPIO_D7:              // D7 pin: Output level in arg_int
      Bit12_PutVal(arg_int);
      break;
    case U8X8_MSG_GPIO_E:               // E/WR pin: Output level in arg_int
      Bit5_PutVal(arg_int); //???
	  //Bit2_PutVal(arg_int);
      break;
    case U8X8_MSG_GPIO_CS:              // CS (chip select) pin: Output level in arg_int
      Bit11_PutVal(arg_int); // not inverted
      break;
    case U8X8_MSG_GPIO_DC:              // DC (data/cmd, A0, register select) pin: Output level in arg_int
      Bit1_PutVal(!arg_int); // inverted
      break;
    case U8X8_MSG_GPIO_RESET:           // Reset pin: Output level in arg_int
      Bit13_PutVal(arg_int); // not inverted
      break;
    case U8X8_MSG_GPIO_CS1:             // CS1 (chip select) pin: Output level in arg_int
      break;
    case U8X8_MSG_GPIO_CS2:             // CS2 (chip select) pin: Output level in arg_int
      break;
    case U8X8_MSG_GPIO_I2C_CLOCK:       // arg_int=0: Output low at I2C clock pin
      break;                            // arg_int=1: Input dir with pullup high for I2C clock pin
    case U8X8_MSG_GPIO_I2C_DATA:            // arg_int=0: Output low at I2C data pin
      break;                            // arg_int=1: Input dir with pullup high for I2C data pin
    case U8X8_MSG_GPIO_MENU_SELECT:
      //u8x8_SetGPIOResult(u8x8, /* get menu select pin state */ 0);
      break;
    case U8X8_MSG_GPIO_MENU_NEXT:
      //u8x8_SetGPIOResult(u8x8, /* get menu next pin state */ 0);
      break;
    case U8X8_MSG_GPIO_MENU_PREV:
      //u8x8_SetGPIOResult(u8x8, /* get menu prev pin state */ 0);
      break;
    case U8X8_MSG_GPIO_MENU_HOME:
      //u8x8_SetGPIOResult(u8x8, /* get menu home pin state */ 0);
      break;
    default:
      u8x8_SetGPIOResult(u8x8, 1);          // default return value
      break;
  }
  return 1;
}
@asfarley
Copy link
Author

asfarley commented Feb 15, 2017

A couple of observations:

  1. In case U8X8_MSG_GPIO_E, I get the same results on the LCD whether I use this:
    Bit5_PutVal(arg_int);
    or this:
    Bit5_PutVal(!arg_int);

However, if I comment out this line entirely, the display shows nothing/does not respond at all.

  1. If I comment out the D0-D7 GPIO lines, I get the same results as if I commented out the U8X8_MSG_GPIO_E case (i.e. no response).

This seems to confirm that the ~WR and data lines are doing something, just not what I expect.

  1. u8g2_SetPowerSave(&u8g2, 1) gives the same results as u8g2_SetPowerSave(&u8g2, 0), i.e., garbage on the screen when u8g2_ClearDisplay is called.

@olikraus
Copy link
Owner

Did you tie the ~RD line to +5V?
Also ensure, that FS0 and FS1 are connected to GND.
The pin behind U8X8_MSG_GPIO_E is the ~WR pin of the display.

Can you also sent the complete code for the text output (not just the init part). Remember to use the first/next loop.

@asfarley
Copy link
Author

  1. Previously I was just setting ~RD to logic-high with the MCU but now I've tied it high on the breadboard. In my case logic-high is 3.3V though (I'm using NHD-240128WG-BTMI-VZ which can take 3.3V).

  2. The data sheet for the OLED only shows a single FS line which is tied to GND (selection of 8x8 font, according to the data sheet). There is also a signal MD2 for column-size selection which I've tied to GND (for 40 columns).

  3. Yes, U8X8_MSG_GPIO_E manipulates the pin connected to ~WR

  4. I've tried rendering loops using both the firstPage/nextPage method and the clear/send buffer method:

LED1_On();
u8g2_FirstPage(&u8g2);
LED1_Off();

do{
u8g2_SetFont(&u8g2, u8g2_font_ncenB14_tr);
u8g2_DrawStr(&u8g2, 0, 15, "Hello World!");
} while ( u8g2_NextPage(&u8g2) );

WAIT1_Waitms(1000);

and

LED1_On();
u8g2_ClearBuffer(&u8g2);
LED1_Off();

u8g2_SetFont(&u8g2, u8g2_font_ncenB14_tr);
u8g2_DrawStr(&u8g2, 0, 15, "Hello World!");

u8g2_SendBuffer(&u8g2);
WAIT1_Waitms(1000);

I did alter the constructor depending on whether the firstPage/nextPage or ClearBuffer/SendBuffer method was used (u8g2_Setup_t6963_240x128_1 vs u8g2_Setup_t6963_240x128_f). Both seem to give the same results.

@olikraus
Copy link
Owner

Hmm.. Still there could be a wiring problem (i mean, all Dx line must be connected correctly), but the DC pin should not be inverted....

    case U8X8_MSG_GPIO_DC:              // DC (data/cmd, A0, register select) pin: Output level in arg_int
      Bit1_PutVal(!arg_int); // inverted

@asfarley
Copy link
Author

asfarley commented Feb 16, 2017

Somehow I've burned out my board while testing so I'm waiting on a new one. In the meantime, a couple of questions:

  1. You suggested tying RD to logic-high; the RA6963 datasheet indicates that RD needs to be driven low in order to check the controller status to see if it's ready to recieve before writing data. See page 13 of the RA6963 datasheet. Doesn't this indicate that RD needs to be connected/driven correctly?
    http://www.newhavendisplay.com/app_notes/RA6963.pdf

  2. What's the meaning of a font-selection pin when the u8g2 has a SetFont call? I noticed that my application crashes if I don't call SetFont, which is a bit surprising - I expected that it would just use the default font configured in the driver.

@olikraus
Copy link
Owner

  1. The status is never checked, so RD can stay high. Instead of checking the busy flag of the status register u8g2 has corresponding delays.
  2. The FS not only selects the font, but also changes the memory layout. However u8g2 expects a specific fixed memory format.

@asfarley
Copy link
Author

Ok, solved. There were several issues:

  1. Some of my GPIO weren't quite swinging between 0 and 3.3 when toggling for some reason. Switching to other pins on my MCU fixed that issue.

  2. I was originally doing this as part of initialization:
    u8g2_SetPowerSave(&u8g2, 1); // wake up display
    It seems like this actually disables the display, so I reversed it:
    u8g2_SetPowerSave(&u8g2, 0); // wake up display

  3. Using a 0,0 offset writes to a location offscreen. Changing to an offset of 20,20 yields visible text.

For anybody else using the RA6963 without doing the status check, I can confirm - it seems to work fine without it.

@olikraus
Copy link
Owner

Great, thanks for the feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants