antiprism / libu8g2arm

Other
9 stars 5 forks source link

Example for SPI usage #5

Open karlo922 opened 6 months ago

karlo922 commented 6 months ago

Hi,

I'm unsure how to include a SPI display with your lib - could you provide a small example maybe?

antiprism commented 6 months ago

Hi

I don't have any equipment available to test on at the moment, but you should be able to follow the ex_init_c.c example, and for hardware SPI you could try something like

// U8g2 Setup for example display with HW SPI
  u8g2_Setup_sh1106_128x64_noname_f(&u8g2, U8G2_R0,
                                        u8x8_byte_arm_linux_hw_spi,
                                        u8x8_arm_linux_gpio_and_delay);
  // I am unsure if the SPI pins need to be set to U8X8_PIN_NONE for U8g2
  // e.g. U8X8_MSG_GPIO_CS, U8X8_MSG_GPIO_DC, U8X8_PIN_RESET,
  // U8X8_MSG_GPIO_SPI_CLOCK,  U8X8_MSG_GPIO_SPI_CLOCK
  // The following is from the I2C example
  //u8x8_SetPin(p_u8x8, U8X8_PIN_I2C_CLOCK, U8X8_PIN_NONE);
  //u8x8_SetPin(p_u8x8, U8X8_PIN_I2C_DATA, U8X8_PIN_NONE);
  //u8x8_SetPin(p_u8x8, U8X8_PIN_RESET, U8X8_PIN_NONE);

  // U8g2arm needs an extra call for hardware I2C to set the bus number
  // (and for hardware SPI to set the bus number and CS number)
  if (!u8g2arm_arm_init_hw_spi(p_u8x8, /* bus_number = */ 0, /* cs_number = */ 0)) {
    fprintf(stderr, "could not initialise SPI device");
    exit(1);
  }

Otherwise, if you are using C++, you could follow ex_init_runtime.cpp, and specify your display and its parameters with strings (see also https://github.com/antiprism/libu8g2arm/blob/main/src/include/U8g2Controller.h)

Adrian.

karlo922 commented 6 months ago

I got further... but it's still not working.

Your expample is missing that there is a third argument of u8g2arm_arm_init_hw_spi it also needs the "speed_mhz" so I tried:

#include <libu8g2arm/u8g2.h>
#include <libu8g2arm/u8g2arm.h>

#include <stdio.h>

u8g2_t u8g2;

int main()
{
  u8x8_t *p_u8x8 = u8g2_GetU8x8(&u8g2);

  // U8g2 Setup for example display with HW I2C
  u8g2_Setup_s1d15e06_160100_1(&u8g2, U8G2_R0,
                                        u8x8_byte_arm_linux_hw_spi,
                                        u8x8_arm_linux_gpio_and_delay);
  u8x8_SetPin(p_u8x8, U8X8_PIN_CS, 4 );
  u8x8_SetPin(p_u8x8, U8X8_MSG_GPIO_DC, 27 );
  u8x8_SetPin(p_u8x8, U8X8_PIN_RESET,  U8X8_PIN_NONE);

  // U8g2arm needs an extra call for hardware I2C to set the bus number
  // (and for hardware SPI to set the bus number and CS number)
  if (!u8g2arm_arm_init_hw_spi(p_u8x8, 0, 0, 1)) {
    fprintf(stderr, "could not initialise SPI device");
    exit(1);
  }

  // U8g2 begin
  u8g2_InitDisplay(&u8g2);
  u8g2_ClearDisplay(&u8g2);
  u8g2_SetPowerSave(&u8g2, 0);

  // Draw something to the display
  u8g2_ClearBuffer(&u8g2);                    // clear the internal memory
  u8g2_SetFont(&u8g2, u8g2_font_ncenB08_tr);  // choose a suitable font
  u8g2_DrawStr(&u8g2, 0, 10, "Hello World!"); // write string to internal mem
  u8g2_SendBuffer(&u8g2); // transfer internal memory to the display

  // Leave it on the screen for a time
  sleep(5);

  // Clear the screen
  u8g2_ClearBuffer(&u8g2); // clear the internal memory
  u8g2_SendBuffer(&u8g2);  // transfer internal memory to the display

  return 0;
}

It will start the SPI but it does 2 things wrongly:

  1. CS is not inverted, but I enabled this in the u8g2 constructor for my display so CS=1 if enabled, not =0
  2. DC ("A0" pin which will be "1" for display data and "0" for commands) is not triggered at all. I connected DC to "GPIO27" on my rsapberry and hoped my call will work, but it does not. Do you have an idea how to set a GPIO to that DC-pin?
antiprism commented 6 months ago

Hi

  1. the cs_number is the second number in the device name, i.e. with your code your display will be accessed through /dev/spidev0.0

  2. I don't know why GPIO27 wouldn't work for DC, but I normally connect my SPI displays like this https://github.com/antiprism/mpd_oled/blob/master/doc/wiring_spi.png You could try that and see if it works.

There may well be errors in the library. I tested with a lot of displays and setups but I probably didn't test everything. I also mostly tested with the C++ setup code like in ex_init_runtime.cpp rather than the example setup you are using.

Adrian.