olikraus / u8g2

U8glib library for monochrome displays, version 2
Other
4.91k stars 1.03k forks source link

pico with fystec mini 12864 v2.1 #2385

Closed MechaPhoton closed 4 months ago

MechaPhoton commented 4 months ago

Hi, I'm having some issues with my LCD, using the hello world example the text is briefly visible but after a fraction of a second is replaced by a solid white screen and never returns. my neopixel backlights are working correctly.

LCD:fystec mini 12864 v2.1 LCD controller: ST7567 IDE: vscode extension: platformIO board: pico

link to LCD board circuit

plaformio.ini

[env:pico]
platform = https://github.com/maxgerhardt/platform-raspberrypi.git
board = pico
framework = arduino  
board_build.core = earlephilhower  
lib_deps =   
    u8g2=https://github.com/olikraus/U8g2_Arduino/archive/master.zip  
    adafruit/Adafruit NeoPixel@^1.12.0  

main.cpp

#include <Arduino.h>
#include <U8g2lib.h>
#include <SPI.h>
#include <Adafruit_NeoPixel.h>

U8G2_ST7567_OS12864_F_4W_HW_SPI u8g2(U8G2_R2, /* cs=*/ 5, /* dc=*/ 4, /* reset=*/ 11);  
Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, 20, NEO_RGB);

void setup() {
  Serial.begin(9600);
  while (!Serial) {}
  SPI.setCS(5);
  SPI.setSCK(2);
  SPI.setTX(3);

  u8g2.begin(); 
  u8g2.setContrast(180);
  u8g2.setFont(u8g2_font_6x10_tf);
  u8g2.setFontRefHeightExtendedText();
  u8g2.setDrawColor(1);
  u8g2.setFontPosTop();
  u8g2.setFontDirection(0);
  Serial.println("u8g2 init");

  strip.begin();
  strip.setBrightness(50);
  strip.setPixelColor(0, strip.Color(110, 250, 250));
  strip.setPixelColor(1, strip.Color(110, 250, 250));
  strip.setPixelColor(2, strip.Color(110, 250, 250));
  strip.show();
  Serial.println("LED init");
}

void loop() {
  u8g2.clearDisplay();
  u8g2.drawHLine(1,1,10);
  u8g2.drawHLine(1+5,2,5);
  u8g2.setFont(u8g2_font_ncenB10_tr);
  u8g2.drawStr(0,24,"Hello World!");
  u8g2.sendBuffer();
}

what I tried next is to use the porting instructions mentioned in issue 2159 however this gives me the same behavior.

same platformio.ino

main.cpp

#include <Arduino.h>
#include <U8g2lib.h>
#include <SPI.h>
#include <Adafruit_NeoPixel.h>

uint8_t u8x8_byte_pico_hw_spi();
uint8_t u8x8_gpio_and_delay_pico();
void display_sequence();
void draw_display();
u8g2_t u8g2;
Adafruit_NeoPixel strip = Adafruit_NeoPixel(3, 20, NEO_RGB);

#define SPI_PORT spi0
#define PIN_CS 5
#define PIN_SCK 2
#define PIN_MOSI 3
#define SPI_SPEED 4000 * 1000
#define PIN_DC 4
#define PIN_RST 11

void setup() {
  Serial.begin(9600);
  while (!Serial) {}
  strip.begin();
  strip.setBrightness(50);
  strip.setPixelColor(0, strip.Color(110, 250, 250));
  strip.setPixelColor(1, strip.Color(110, 250, 250));
  strip.setPixelColor(2, strip.Color(110, 250, 250));
  strip.show();
  Serial.println("LED init");
}

void loop() {
  void draw_display();
  delay(100);
}

void draw_display() {
  char hey[10] = "Hello";
  u8g2_ClearBuffer(&u8g2);
  u8g2_ClearDisplay(&u8g2);
  u8g2_SetFont(&u8g2, u8g2_font_t0_11_te);
  u8g2_SetDrawColor(&u8g2, 1);
  u8g2_DrawStr(&u8g2, 10, 10, hey);
  u8g2_UpdateDisplay(&u8g2);
}

uint8_t u8x8_byte_pico_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) {
  uint8_t *data;
  switch (msg) {
  case U8X8_MSG_BYTE_SEND:
    data = (uint8_t *)arg_ptr;
    spi_write_blocking(SPI_PORT, data, arg_int);
    break;
  case U8X8_MSG_BYTE_INIT:
    u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
    break;
  case U8X8_MSG_BYTE_SET_DC:
    u8x8_gpio_SetDC(u8x8, arg_int);
    break;
  case U8X8_MSG_BYTE_START_TRANSFER:
    u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
    u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO,u8x8->display_info->post_chip_enable_wait_ns, NULL);
    break;
  case U8X8_MSG_BYTE_END_TRANSFER:
    u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
    u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
    break;
  default:
    return 0;
  }
  return 1;
}

uint8_t u8x8_gpio_and_delay_pico(u8x8_t *u8x8, uint8_t msg,uint8_t arg_int, void *arg_ptr) {
  switch (msg) {
  case U8X8_MSG_GPIO_AND_DELAY_INIT: 
    spi_init(SPI_PORT, SPI_SPEED);
    gpio_set_function(PIN_CS, GPIO_FUNC_SIO);
    gpio_set_function(PIN_SCK, GPIO_FUNC_SPI);
    gpio_set_function(PIN_MOSI, GPIO_FUNC_SPI);
    gpio_init(PIN_RST);
    gpio_init(PIN_DC);
    gpio_init(PIN_CS);
    gpio_set_dir(PIN_RST, GPIO_OUT);
    gpio_set_dir(PIN_DC, GPIO_OUT);
    gpio_set_dir(PIN_CS, GPIO_OUT);
    gpio_put(PIN_RST, 1);
    gpio_put(PIN_CS, 1);
    gpio_put(PIN_DC, 0);
    break;                  
  case U8X8_MSG_DELAY_NANO: // delay arg_int * 1 nano second
    sleep_us(arg_int); // 1000 times slower, though generally fine in practice given rp2040 has no `sleep_ns()`
    break;
  case U8X8_MSG_DELAY_100NANO: // delay arg_int * 100 nano seconds
    sleep_us(arg_int);
    break;
  case U8X8_MSG_DELAY_10MICRO: // delay arg_int * 10 micro seconds
    sleep_us(arg_int * 10);
    break;
  case U8X8_MSG_DELAY_MILLI: // delay arg_int * 1 milli second
    sleep_ms(arg_int);
    break;
  case U8X8_MSG_GPIO_CS: // CS (chip select) pin: Output level in arg_int
    gpio_put(PIN_CS, arg_int);
    break;
  case U8X8_MSG_GPIO_DC: // DC (data/cmd, A0, register select) pin: Output level
    gpio_put(PIN_DC, arg_int);
    break;
  case U8X8_MSG_GPIO_RESET: // Reset pin: Output level in arg_int
    gpio_put(PIN_RST, arg_int);  // printf("U8X8_MSG_GPIO_RESET %d\n", arg_int);
    break;
  default:
    u8x8_SetGPIOResult(u8x8, 1); // default return value
    break;
  }
  return 0;
}

void display_sequence(){
  u8g2_Setup_st7567_os12864_f(&u8g2 , U8G2_R2, u8x8_byte_pico_hw_spi, u8x8_gpio_and_delay_pico);
  u8g2_InitDisplay(&u8g2); // send init sequence to the display, display is in sleep mode after this,
  u8g2_SetPowerSave(&u8g2, 0); 
  u8g2_SetContrast(&u8g2,180);
  draw_display();
}

some differences between my failed attempt and issue 2159 successful solution that I've identified: I am using platform io and they are using pico SDK I am using st7567 vs SSD1305 In their provided image they don't appear to have the reset pin plugged in to Pico pin 11 I am using draw_display in my void loop(), which I understand to be the equivalent of their int main(), whereas they are using display_sequence(); I do not have stdio_init_all(); in my loop(), this function is not supported by earlephilhower core.

maybe I need to change something in my u8x8_byte_pico_hw_spi or u8x8_gpio_and_delay_pico to account for the difference in LCD's maybe I need to change something in u8x8_d_st7567.c to account for the specifics of this board.

I have tried changing the draw color to 0 I have tried without the delay(100) in loop() I have tried with display_sequence() in loop()

any help appreciated, thank you.

olikraus commented 4 months ago

It is difficult to support any none-Arduino IDE, but here are some ideas:

void loop() {
  u8g2.clearDisplay();
  u8g2.drawHLine(1,1,10);
  u8g2.drawHLine(1+5,2,5);
  u8g2.setFont(u8g2_font_ncenB10_tr);
  u8g2.drawStr(0,24,"Hello World!");
  u8g2.sendBuffer();
}

Try to add a delay, just to see, whether the flashing was caused by the same code.

Another test could be to repeat the begin statements, like this:

void loop() {
  u8g2.begin(); 
  u8g2.setContrast(180);
  u8g2.setFont(u8g2_font_6x10_tf);
  u8g2.setFontRefHeightExtendedText();
  u8g2.setDrawColor(1);
  u8g2.setFontPosTop();
  u8g2.setFontDirection(0);

  u8g2.clearDisplay();
  u8g2.drawHLine(1,1,10);
  u8g2.drawHLine(1+5,2,5);
  u8g2.setFont(u8g2_font_ncenB10_tr);
  u8g2.drawStr(0,24,"Hello World!");
  u8g2.sendBuffer();
}

One more point: "SPI.setCS(5);" should not be used. There might be a conflict with the CS signal from U8g2 and the hardware generated CS signal from the SPI interface. So it is probably better to disable hardware chip select.

MechaPhoton commented 4 months ago

Thank you for getting back to me Oli, and thank you for an excellent library. It is working correctly in Arduino IDE which is good enough for now. I'm also using MUIU8g2 in my project and it is making it so easy. I couldn't be happier.

feel free to close.