imx6ull 驱动ssd1306 oled屏

imx6ull 驱动ssd1306 oled屏记录

该文记录使用imx6ull点亮oled屏的过程,参考资料来自于网络,./ 默认为内核顶层目录。

硬件

板子使用的韦东山的mini板,使用的I2C2,SDA和SCL分别位于引出排针J7的26 25脚,使用3.3v供电,oled为中景圆I2C接口的0.96寸oled(驱动芯片为ssd 1306)。

linux驱动

在linux内核中带有已经带有该系列oled屏的驱动,用户只需要打开相关配置,修改设备树即可初步点亮该oled屏。

内核驱动源码位置:

100ask_imx6ull-sdk/Linux-4.9.88/drivers/video/fbdev/ssd1307fb.c

默认配置下,该驱动不会编译到内核,需要make menuconfig下 输入 /ssd1307搜索配置所在路径,按该路径打开该配置,保存配置后,查看linux内核的顶层目录下的.config文件,CONFIG_FB_SSD1307=y,表示已开启,接着make zImage -j4编译内核,然后把arch/arm/boot/zImage拷贝到开发板的/boot目录下,下次上电则会使用新的内核文件zImage启动。

设备树修改

所使用的设备树文件路径:arch/arm/boot/dts/100ask_imx6ull-14x14.dts

结合参考链接以及Linux-4.9.88/Documentation/devicetree/bindings/display/ssd1307fb.txt 文档,在I2C2节点下添加设备。

错误的修改

&i2c2 {
    clock_frequency = <100000>;
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_i2c2>;
    status = "okay";

    codec: wm8960@1a {
        compatible = "wlf,wm8960";
        reg = <0x1a>;
        clocks = <&clks IMX6UL_CLK_SAI2>;
        clock-names = "mclk";
        wlf,shared-lrclk;
        };
         sii902x: sii902x@39 {
                 compatible = "SiI,sii902x";
                 pinctrl-names = "default";
                 reset-names="sii902x";
                 pinctrl-0 = <&pinctrl_sii902x>;
                 resets = <&sii902x_reset>;
                 interrupt-parent = <&gpio1>;
                 interrupts = <18 IRQ_TYPE_EDGE_FALLING>;
                 mode_str ="1280x720M@60";
                 bits-per-pixel = <16>;
                 reg = <0x39>;
                 status = "okay";    
         };
         
         gt9xx@5d {
                compatible = "goodix,gt9xx";
                reg = <0x5d>;
                status = "okay";
                interrupt-parent = <&gpio1>;
                interrupts = <5 IRQ_TYPE_EDGE_FALLING>;
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_tsc_reset &pinctrl_touchscreen_int>;
                /*pinctrl-1 = <&pinctrl_tsc_irq>;*/
                /*pinctrl-names = "default", "int-output-low", "int-output-high", "int-input";
                pinctrl-0 = <&ts_int_default>;
                pinctrl-1 = <&ts_int_output_low>;
                pinctrl-2 = <&ts_int_output_high>;
                pinctrl-3 = <&ts_int_input>;
                */
                reset-gpios = <&gpio5 2 GPIO_ACTIVE_LOW>;
                irq-gpios = <&gpio1 5 IRQ_TYPE_EDGE_FALLING>;
                irq-flags = <2>;                /*1:rising 2: falling*/
         .....
         
         ssd1306: oled@3c {
            compatible = "solomon,ssd1306fb-i2c";
            reg = <0x3c>;
            solomon,height = <64>;
            solomon,width = <128>;
            reset-gpios = <&gpio5 2>;
            reset-active-low;
            /*pwms = <&pwm 4 3000>;
            reset-gpios = <&gpio2 7>;
            reset-active-low;
            solomon,com-lrremap;
            solomon,com-invdir;
            solomon,com-offset = <0>;*/
        };
}

参考内核中的文档,修改出来的设备树无法正常点亮oled屏,启动时出现下列log

[    1.203903] ssd1307fb 1-003c: probe
[    1.203977] OF: /soc/aips-bus@02100000/i2c@021a4000/oled@3c: arguments longer than property
[    1.204044] ssd1307fb: probe of 1-003c failed with error -22
[    1.204295] i2c-core: driver [ssd1307fb] registered
[    1.207599] imx-sdma 20ec000.sdma: loaded firmware 3.3
[    1.217637] i2c-core: driver [pfuze100-regulator] registered
[    1.219341] 2020000.serial: ttymxc0 at MMIO 0x2020000 (irq = 20, base_baud = 5000000) is a IMX
[    1.936661] console [ttymxc0] enabled

根据log及源码分析:

  1. log显示arguments longer than property,表示有多余参数,查看源码,发现没有对 reset-active-low 字段的处理,故删除。

  2. log显示 ssd1307fb: probe of 1-003c failed with error -22 ,从驱动源码的probe函数中可以看到,返回的错误类型有两种,其中EINVAL的值正好为22,根据猜测为reset gpio相关配置出错,返回错误码的代码段如下:

par->reset = of_get_named_gpio(client->dev.of_node,
					 "reset-gpios", 0);
	if (!gpio_is_valid(par->reset)) {
		printk("[%s:%d] ERROR########\n", __FUNCTION__, __LINE__);
		ret = -EINVAL;
		goto fb_alloc_error;
	}

参考设备树中其他节点中reset-gpios选项的配置,修改设备树。

正确修改

&i2c2 {
    clock_frequency = <100000>;
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_i2c2>;
    status = "okay";
    ....
    ssd1306: oled@3c {
            compatible = "solomon,ssd1306fb-i2c";
            reg = <0x3c>;
            solomon,height = <64>;
            solomon,width = <128>;
            reset-gpios = <&gpio5 2 GPIO_ACTIVE_LOW>;
            /*reset-active-low;
            pwms = <&pwm 4 3000>;
            reset-gpios = <&gpio2 7>;
            reset-active-low;
            solomon,com-lrremap;
            solomon,com-invdir;
            solomon,com-offset = <0>;*/
        };
}

修改正确后,make dtbs编译设备树,并把编译好的./arch/arm/boot/dts/100ask_imx6ull-14x14.dtb拷贝到/boot目录下,重启后,使用的就是修改后的设备树了。

linux内核中的oled驱动加载成功后,oled屏显示的是雪花图(乱码)。

参考链接

https://en.wiki.sipeed.com/soft/Lichee/zh/Zero-Doc/Contribution/article_2.html?highlight=oled

  • 22
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值