notro / fbtft

Linux Framebuffer drivers for small TFT LCD display modules. Development has moved to https://git.kernel.org/cgit/linux/kernel/git/gregkh/staging.git/tree/drivers/staging/fbtft?h=staging-testing
1.85k stars 496 forks source link

ssd1306 won't work on latest kernel #455

Closed voloviq closed 3 years ago

voloviq commented 7 years ago

Hello Notro, I would like to sharing with You my experience regarding to display which base on ssd1306 chip with latest kernel 4.11. So first of all I use display from link https://www.aliexpress.com/item/free-shipping-1pcs-0-96-inch-OLED-display-module-128X64-OLED-for-arduino-I2C-IIC-SPI/32596911712.html?spm=2114.01010208.3.28.A2FcZI&ws_ab_test=searchweb0_0,searchweb201602_1_10065_10068_10136_10137_10138_10060_10062_10141_10056_10055_10054_122_10059_10099_10103_10102_10096_10148_10052_10053_10050_10107_10142_10051_10143_10084_10083_10080_10082_10081_10110_10111_10112_10113_10114_10037_10032_10078_10079_10077_10073_10070_10123_10124,searchweb201603_6,afswitch_1,ppcSwitch_5,single_sort_0_default&btsid=61cdea72-4776-4161-988f-f2872d545476&algo_expid=5a019786-da81-4635-886f-615567d420d1-3&algo_pvid=5a019786-da81-4635-886f-615567d420d1 in SPI 4 wire mode. In this kernel I use following dts code

&spi0 {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&spi0_pins>;

        ssd1306@0 {
        compatible = "solomon,ssd1306";
        reg = <0>;
            pinctrl-0 = <&ssd1306_pins>;

            spi-max-frequency = <6000000>;
            txbuflen = <32768>;
            bgr = <0>;
        bpp = <1>;
        height = <128>;
        width = <64>;
        page-offset = <0>;
        com-lrremap;
        com-invdir;
        com-offset = <0>;
        rotate = <0>;
            fps = <30>;
            buswidth = <8>;

            dc-gpios = <&pio 6 11 GPIO_ACTIVE_LOW>;
        reset-gpios = <&pio 6 9 GPIO_ACTIVE_LOW>;
            debug = <0>;
        };
};

and of course Your driver fb_ssd1306. And now what works and what not works.

  1. SPI0 work very well - send everything what is needed
  2. DTS seems to be works well also.
[   25.053290] fbtft_of_value: width = 64
[   25.057064] fbtft_of_value: height = 128
[   25.061066] fbtft_of_value: buswidth = 8
[   25.064997] fbtft_of_value: bpp = 1
[   25.068488] fbtft_of_value: debug = 0
[   25.072182] fbtft_of_value: rotate = 0
[   25.075935] fbtft_of_value: fps = 30
[   25.079509] fbtft_of_value: txbuflen = 32768
[   30.250520] graphics fb0: fb_ssd1306 frame buffer, 64x128, 16 KiB video memory, 4 KiB buffer memory, fps=33, spi32766.0 at 6 MHz
  1. Console is pass to this display, so I should see console on it.
  2. After initialization over I see that some mesh order dots blinking only in first page address (only on first 8 rows and all columns), rest is mesh without changing anything.
  3. After issue cat /dev/urandom > /dev/fb0 all first 8 rows (128columns) blink on, rest untouched
  4. After issue cat /dev/zero > /dev/fb0 all first 8 rows (128columns) blink off, rest untouched

Now my investigation.

Command 0x20, 0x01 which switch to vertical continuous mode not working. So I check than 0x20, 0x00 horizontal which not working as well, so finally I check 0x20, 0x02 page addressing mode which works well. Base on it I modify a little bit Your code to

static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
{
    u16 *vmem16 = (u16 *)par->info->screen_buffer;
    u32 xres = par->info->var.xres;
    u32 yres = par->info->var.yres;
    u8 *buf = par->txbuf.buf;
    int x, y, i;
    int ret = 0;

    /*for (x = 0; x < xres; x++) 
    {
        for (y = 0; y < yres / 8; y++) 
        {
            *buf = 0x00;
            for (i = 0; i < 8; i++)
            {
                *buf |= (vmem16[(y * 8 + i) * xres + x] ? 1 : 0) << i;
            }
            buf++;
        }
    }*/

         /* Write data */
         //xxxgpio_set_value(par->gpio.dc, 1);
         //xxxret = par->fbtftops.write(par, par->txbuf.buf,
                                   //xxxpar->info->var.xres * par->info->var.yres /
                                   //xxx8);
         //xxxif (ret < 0)
                 //xxxdev_err(par->info->device, "write failed and returned: %d\n",
                         //xxxret);

    for (y = 0; y < (xres/8); y++)
    {
                for (x = 0; x < yres; x++)
                {
                        *buf = 0x00;
                        for (i = 0; i < 8; i++)
                        {
                                *buf |= (vmem16[((x * xres)+i) + y*(xres/8)] ? 1 : 0) << i;
            }
                        buf++;
        }
    }

    for(i=0; i<(xres/8); i++)
        {
                gpio_set_value(par->gpio.dc, 0);
                write_reg(par, 0xb0+i);
                write_reg(par, 0x02);
                write_reg(par, 0x10);
                gpio_set_value(par->gpio.dc, 1);
                ret = par->fbtftops.write(par, par->txbuf.buf+(yres*i), yres);

                if (ret < 0)
                {
                        dev_err(par->info->device, "write failed and returned: %d\n", ret);
            }
        }

    return ret;
}

And above code works well, I mean I see proper ascii characters on screen but only vertical (which is not my goal). When I provide from keyboard character I see them on screen perfectly. Unfortunately I'm not able to switch somehow to horizontal mode because I don't know how the data are organized in par->info->screen_buffer buffer.

Of course when I switch in dts fbtft_of_value: width = 128 and fbtft_of_value: height = 64 my code generate overrun error - obvious (this is only testing code, not final).

And now my polite request to You. I have a few question for which I can't find information in net.

  1. How data are organized in par->info->screen_buffer buffer?
  2. Do set bpp in dts have influence on data organization in par->info->screen_buffer buffer?
  3. How to write a good universal code which will support horizontal and vertical characters presenting?
  4. Do my dts looks well, I not missing something significant?
  5. Why vertical and horizontal addressing won't work?

Thanks in advanced for any help Best Regards Voloviq

voloviq commented 7 years ago

Hello again,

I think I found a solution and understand most of the topics I asked. Tomorrow or later I add which lines needs to be modified at page addressing display mode.

github-actions[bot] commented 3 years ago

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days.