在f1c100s上移植fbtft驱动st7735s小屏幕

这篇具有很好参考价值的文章主要介绍了在f1c100s上移植fbtft驱动st7735s小屏幕。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

内核版本5.4
在使用spi总线接上了一个小网卡,实现了我们开发板对网络的访问之后,我还想接一个小的spi屏幕 1.44寸款,来画一只小企鹅,顺便显示一些系统的调试信息。但是由于我这个开发板向外暴露出来的spi接口就两个,而且有一个已经因为串口的设置而不能使用。所以我们只能让这个小屏幕和enc28j60共用一个spi外设。

内核配置

直接make menuconfig,进入Device Drivers,打开SPI,打开ST7735R的驱动。保存,再make -j16.

接线与修改设备树

我打算让enc28j60使用spi自己的cs作为片选线,然后另外找一个GPIO作为spi屏幕的片选。
那这样的话又得改设备树。我们这个spi屏幕的驱动器芯片是"st7735s"。但是linux有st7735r,这俩
是兼容的,可以直接用。

/ {
	model = "Lichee Pi Nano";
	compatible = "licheepi,licheepi-nano", "allwinner,suniv-f1c100s";

	aliases {
		serial1 = &uart1;
	};

	chosen {
		stdout-path = "serial1:115200n8";
		/delete-node/ framebuffer@0;
	};
	
	reg_vcc3v3: vcc3v3 {
			compatible = "regulator-fixed";
			regulator-name = "vcc3v3";
			regulator-min-microvolt = <3300000>;
			regulator-max-microvolt = <3300000>;
	};

	backlight: backlight {
		compatible = "gpio-backlight";
		gpios = <&pio 4 4 GPIO_ACTIVE_HIGH>;
		default-on;
	};
};

&spi1{
	status = "okay";
	pinctrl-names = "default";
	pinctrl-0 = <&spi1_pins>;
	cs-gpios = <0>,<&pio 4 5 GPIO_ACTIVE_LOW>;
	enc28j60: ethernet@0 {
		compatible = "microchip,enc28j60";
		pinctrl-names = "default";
		pinctrl-0 = <&enc28j60_pins>;
		reg = <0x0>;
		interrupt-parent = <&pio>;
		interrupts = <4 11 IRQ_TYPE_EDGE_FALLING>;
		spi-max-frequency = <12000000>;
	};
	display@1{
		compatible = "okaya,rh128128t", "sitronix,st7735r";
		reg = <0x1>;
		status = "okay";
		spi-max-frequency = <48000000>;
		spi-cpol;
		spi-cpha;
		bgr;
		rotate = <90>;
		fps = <30>;
		buswidth = <8>;
		dc-gpios = <&pio 4 2 GPIO_ACTIVE_HIGH>;
		reset-gpios = <&pio 4 3 GPIO_ACTIVE_LOW>;
		backlight = <&backlight>;
	};
};

我们在spi节点下增加了一个display设备,进入linux主线的设备的DTC绑定信息都是在内核源码中可以找得到的。例如我们要找"sitronix,st7735r"的设备树绑定信息,我们直接打开内核根目录,一搜,就可以在Documentation/devicetree/bindings/display/sitronix,st7735r.yaml找到我们要的信息。

这个yaml给的是最新的drm驱动匹配方式,不过我们目前还是使用比较简单,资料比较多的framebuffer TFT驱动比较好。下一次可以尝试用这个drm驱动。

我们这个spi屏幕由于和enc28j60共用一个spi,所以我们需要指定其片选。我们可以在spi节点下直接设置cs-gpios = <0>,<&pio 4 5 GPIO_ACTIVE_LOW>。这是什么意思呢?第一个<0>代表了对于第一个spi设备,我们使用spi默认的片选引脚。第二个<&pio 4 5 GPIO_ACTIVE_LOW>,代表的是我们指定第二个spi设备的片选引脚为PE5,并且低电平有效。GPIO_ACTIVE_LOW的意思是低电平有效,这样做可以在内核中配置不同设备的正负逻辑。

引脚正负逻辑与代码分析

fbtft设备在申请GPIO时,其实用的是gpio子系统的api。这些api用来用去最后是调用了

struct gpio_desc *of_find_gpio(struct device_node *np, const char *con_id,
			       unsigned int idx, unsigned long *flags)

它调用了

desc = of_get_named_gpiod_flags(np, prop_name, idx, &of_flags);
*flags = of_convert_gpio_flags(of_flags);

来获取设备树下gpio属性的flag。在设置gpio的输出值时,即调用gpiod_set_value时,会调用

static void gpiod_set_value_nocheck(struct gpio_desc *desc, int value)
{
	if (test_bit(FLAG_ACTIVE_LOW, &desc->flags))
		value = !value;
	if (test_bit(FLAG_OPEN_DRAIN, &desc->flags))
		gpio_set_open_drain_value_commit(desc, value);
	else if (test_bit(FLAG_OPEN_SOURCE, &desc->flags))
		gpio_set_open_source_value_commit(desc, value);
	else
		gpiod_set_raw_value_commit(desc, value);
}

所以我们在设备树中配置引脚的正负逻辑,会在这里被处理。如果是正逻辑,直接输出,如果是负逻辑,则需要取反。

配置引脚正负逻辑

为了知道我们到底应该在哪些引脚配置我们的正负逻辑,我们应该直接看源代码,因为压根就没有文档说这些。

static void fbtft_reset(struct fbtft_par *par)
{
	if (!par->gpio.reset)
		return;

	fbtft_par_dbg(DEBUG_RESET, par, "%s()\n", __func__);

	gpiod_set_value_cansleep(par->gpio.reset, 1);
	usleep_range(20, 40);
	gpiod_set_value_cansleep(par->gpio.reset, 0);
	msleep(120);

	gpiod_set_value_cansleep(par->gpio.cs, 1);  /* Activate chip */
}

RESET引脚在低电平的时候将会导致屏幕复位,Chip-Select在低电平时将会使能设备。所以这两个引脚都是负逻辑。我们应当在他们设备树的GPIO后边加一个GPIO_ACTIVE_LOW

上电测试

我上电后,屏幕一直白屏,调试了很久,代码改来改去,TF卡不知道插拔了多少次,也找不到原因。

最后插上逻辑分析仪,逻辑分析仪真的是电子工程师的眼睛,以前屏幕从来就没调通过,这次插了逻辑分析仪,能够分析逻辑后,调试就变得很容易了。一直看波形,发现RESET引脚一直被拉低。才发现原来linux的gpio子系统有这么一套正负逻辑的区别。

配置好之后,屏幕时好时坏。有多时好时坏呢,一插上逻辑分析仪,屏幕就成功初始化。一拔掉逻辑分析仪,这个屏幕又白屏了。最后一联想,就想到逻辑分析仪不是自带上拉吗?是不是因为我的RESET,CS,MOSI,CLK这些引脚都没有上拉?找了两个上拉电阻,一试,屏幕跑起来了!小企鹅出现了!

背光驱动的修改

其实我一开始把PE4的一个引脚设置为背光引脚(这样做似乎不太对,应该用mosfet或者三极管来驱动这个tft,因为电流大了会把f1c100s的引脚给烧了)。但是这个屏幕不知道为什么,就是不亮,亮都不亮一下。于是我就把这根线拔了,直接把TFT的LED引脚连了3V3。但是我觉得这样不够优雅,一定要让linux自己能够设置这个背光。

backlight: backlight {
    compatible = "gpio-backlight";
    gpios = <&pio 4 4 GPIO_ACTIVE_HIGH>;
    default-on;
};

这个backlight会注册一个class,位置在/sys/class/backlight/backlight,这个目录下有一个文件叫brightness,即亮度,可以通过echo 1 > brightness,打开我们的背光。

这里我们把gpio配置为正逻辑,这样1就对应着打开背光,符合人类的操作逻辑。

但是为什么,这个背光不工作呢?设置成1或者0,在调试后,发现

static int gpio_backlight_update_status(struct backlight_device *bl)
{
	struct gpio_backlight *gbl = bl_get_data(bl);
	int brightness = bl->props.brightness;

	if (bl->props.power != FB_BLANK_UNBLANK ||
	    bl->props.fb_blank != FB_BLANK_UNBLANK ||
	    bl->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))
		brightness = 0;

	gpiod_set_value_cansleep(gbl->gpiod, brightness);

	return 0;
}

是它判断这些power fb_blakn state的时候,直接把brightness设置成0了。我们直接去掉这几行代码。但是它调用gpiod_set_value_cansleep(gbl->gpiod, brightness);,我们的gpio也没有输出。

最后看了几遍代码,发现原来是它没有配置好gpio为输出。

static int gpio_backlight_probe_dt(struct platform_device *pdev,
				   struct gpio_backlight *gbl)
{
	struct device *dev = &pdev->dev;
	int ret;

	gbl->def_value = device_property_read_bool(dev, "default-on");

	gbl->gpiod = devm_gpiod_get(dev, NULL, GPIOD_ASIS);
	if (IS_ERR(gbl->gpiod)) {
		ret = PTR_ERR(gbl->gpiod);

		if (ret != -EPROBE_DEFER) {
			dev_err(dev,
				"Error: The gpios parameter is missing or invalid.\n");
		}
		return ret;
	}

	return 0;
}

问题就在gbl->gpiod = devm_gpiod_get(dev, NULL, GPIOD_ASIS);的这个GPIOD_ASIS

/**
 * enum gpiod_flags - Optional flags that can be passed to one of gpiod_* to
 *                    configure direction and output value. These values
 *                    cannot be OR'd.
 *
 * @GPIOD_ASIS:			Don't change anything
 * @GPIOD_IN:			Set lines to input mode
 * @GPIOD_OUT_LOW:		Set lines to output and drive them low
 * @GPIOD_OUT_HIGH:		Set lines to output and drive them high
 * @GPIOD_OUT_LOW_OPEN_DRAIN:	Set lines to open-drain output and drive them low
 * @GPIOD_OUT_HIGH_OPEN_DRAIN:	Set lines to open-drain output and drive them high
 */
enum gpiod_flags {
	GPIOD_ASIS	= 0,
	GPIOD_IN	= GPIOD_FLAGS_BIT_DIR_SET,
	GPIOD_OUT_LOW	= GPIOD_FLAGS_BIT_DIR_SET | GPIOD_FLAGS_BIT_DIR_OUT,
	GPIOD_OUT_HIGH	= GPIOD_FLAGS_BIT_DIR_SET | GPIOD_FLAGS_BIT_DIR_OUT |
			  GPIOD_FLAGS_BIT_DIR_VAL,
	GPIOD_OUT_LOW_OPEN_DRAIN = GPIOD_OUT_LOW | GPIOD_FLAGS_BIT_OPEN_DRAIN,
	GPIOD_OUT_HIGH_OPEN_DRAIN = GPIOD_OUT_HIGH | GPIOD_FLAGS_BIT_OPEN_DRAIN,
};

我们改成GPIOD_OUT_LOW,即成功解决问题。当然,最新的驱动已经修复了这些问题。文章来源地址https://www.toymoban.com/news/detail-687424.html

到了这里,关于在f1c100s上移植fbtft驱动st7735s小屏幕的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 全志F1C100s主线linux入坑记录 (6)音视频播放(视频播放软解)

    百度网站 (1)下载安装声卡补丁 参考挖坑网大神提供的声音驱动以及声音卡驱动补丁文件下载文件下载 全志F1C100s声卡补丁 解压文件打上补丁 (2)配置声卡 修改设备树文件添加声卡节点 内核配置 (3)linux内核编译烧录 可以看到声卡已经挂载了 (4)使用声卡 安装alsa-u

    2024年02月07日
    浏览(55)
  • 7、Lctech Pi(F1C200S)开启RNDIS,通过USB与电脑联网(CherryPi,Mangopi,F1C100S)

    本次主要参考: 荔枝nano开启RNDIS驱动,无需补丁。 https://github.com/peng-zhihui/Planck-Pi#head23 https://github.com/mangopi-sbc/buildroot-mangopi-r https://www.cnblogs.com/listenscience/p/13758272.html (如果方便请给这几位大佬一个关注) 注意代码块之间的空行 本次是摸索出来的,如果用到项目需慎重,有

    2024年02月12日
    浏览(42)
  • modbus采集和 mqtt上报相结合,通过荔枝派(F1c100s芯片模块)实现数据采集连接阿里云物联网平台进行数据上报和下发功能。

    通过荔枝派(F1c100s芯片模块)搭载SDIO-wifi模块,写入了主函数程序。根据读取modbus模拟器的数据,反馈到阿里云物联网平台当中。图中左侧的阿里云物联网平台所显示的温度为66摄氏度,与modbus模拟器的数据是一样的,图片右侧是荔枝派(F1c100s芯片模块)的编程软件X-shell的

    2024年02月15日
    浏览(54)
  • linux(全志F1C100S/F1C200S)系列02:移植LCD st7789驱动,LVGL8.3移植

    st7789V中指定了rst与dc引脚,pio 4 3 对应PE3,pio 4 5对应PE5; 详细配置方式见链接:全志 :gpio使用 需要根据自身硬件配置。 Tips:更改 spi-max-frequency = 32000000 - spi-max-frequency = 100000000; 和 fps = 30; 改为 fps = 60; 感谢楼下老哥提示。 rotate = 90;根据屏幕方向更改。 只需要更改下面的三个地

    2024年01月18日
    浏览(66)
  • 【f1c200s/f1c100s】mangopi自制linux开发板驱动适配进度(PCB、代码开源)

    目前自制的mangopi设备驱动适配已完成部分包含: 基于扫描的gpio-keys子系统适配 LED子系统适配 RGB接口LCD显示屏适配 ft5406触摸屏适配 博通RTL8188EUS无线网卡适配 PWM驱动适配 显示屏背光适配 以下这几项在下载到荔枝派源码时已经适配好了: SPI FLASH驱动 USB驱动 串口驱动 mangopi内

    2024年02月03日
    浏览(87)
  • STM32F1基于STM32CubeMX配置硬件SPI驱动1.8寸TFT LCD128X160 ST7735S屏幕

    📌相关篇《【STM32CubeIDE】STM32F103硬件SPI驱动1.8寸TFT LCD128X160 ST7735S屏幕》 ✨驱动效果就不做演示了,和上面的相关篇一样,主要是为了方便使用MDK Keil开发的使用。所以花了点时间从上面的工程当中做了分离,重新使用STM32CubeMX配置一个方便二次开发移植使用和配置的工程。本

    2024年02月03日
    浏览(49)
  • ESP32C3 移植ST7735 LVGL

    关于lvgl LVGL是一个C语言编写的免费的开源图形库,其提供了用于嵌入式GUI的各种元素。用户可以利用丰富的图形库资源,在消耗极低内存的情况下构建视觉效果丰富多彩的GUI 。只需 64kB 闪存和 8kB RAM 就足以满足简单的用户界面。LVGL 可以驱动单色OLED、TFT 显示器、监视器或任

    2023年04月24日
    浏览(49)
  • Clion开发STM32之驱动开发(ST7735S篇)

    ST7735S数据手册 字库头文件(module_st7735s_font.h) 头文件(module_st7735s.h) 源文件(module_st7735s.c) 实现对应的驱动接口 测试单元

    2024年02月07日
    浏览(54)
  • (三)内核移植--从零开始自制linux掌上电脑(F1C200S)<嵌入式项目>

    目录 一、bootloader、kernel、rootfs联系 二、内核移植 1. 内核源码获取 2. 内核配置与编译 🍍 基础配置与编译 🍍 TF卡分区 🍍 内核烧录 三、参考内容 kernel可以理解为一个 庞大的裸机程序 ,和uboot以及其他比如点灯类似的裸机程序没有本质区别,只是kernel分为 用户态和内核态

    2024年02月15日
    浏览(84)
  • STM32驱动ST7735彩色屏幕(任意分辨率),驱动不了你来打我

    驱动方式 硬件SPI 适用STM32型号 带SPI的任意型号,驱动不了你来打我(内心OS:HAL真好) 特别提醒 以下内容介绍如何使用HAL方式驱动ST7735,所以默认 你已经了解并且会使用STM32CubeMX软件 (如果没有接触过的话建议先安装尝试一下再继续以下内容,不然有种囫囵吞枣的意思了)

    2023年04月15日
    浏览(65)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包