当前位置:首页 > 技术 > LINUX > 正文内容

linux 添加ili9341屏的驱动

watrt11个月前 (09-09)LINUX2660

1、修改pinmux

我的板子是MiLK V DUO SPI2默认是做为GPIO,所以先修改为SPI功能

image.png

可以修改两个地方,修改一个地方就可以了:

u-boot-2021.10/board/cvitek/cv180x/board.c

pinmux_config(PINMUX_SPI2); //sdk默认把这里注释了,取消掉
PINMUX_CONFIG(SPINOR_CS_X, XGPIOA_24); //添加,这里的默认管脚功能并不是GPIO,修改之
PINMUX_CONFIG(SPINOR_MISO, XGPIOA_23); //添加,这里也一样
cvi_board_init();

build/boards/cv180x/cv1800b_milkv_duo_sd/u-boot/cvi_board_init.c

int cvi_board_init(void)
{
	// sensor i2c1 reset mclk
	PINMUX_CONFIG(PAD_MIPIRX0P, CAM_MCLK0); // MCLK0
	PINMUX_CONFIG(PAD_MIPIRX1P, IIC1_SDA); // I2C 2
	PINMUX_CONFIG(PAD_MIPIRX0N, IIC1_SCL);
	PINMUX_CONFIG(PAD_MIPIRX1N, XGPIOC_8);

	// all default gpio
	PINMUX_CONFIG(SPINOR_HOLD_X, XGPIOA_26);
	PINMUX_CONFIG(SPINOR_SCK, XGPIOA_22);
	PINMUX_CONFIG(SPINOR_MOSI, XGPIOA_25);
	PINMUX_CONFIG(SPINOR_WP_X, XGPIOA_27);
	PINMUX_CONFIG(SPINOR_MISO, XGPIOA_23);
	PINMUX_CONFIG(SPINOR_CS_X, XGPIOA_24);
	PINMUX_CONFIG(IIC0_SDA, XGPIOA_29);
	PINMUX_CONFIG(IIC0_SCL, XGPIOA_28);
	// sd1
	PINMUX_CONFIG(SD1_D3, PWR_GPIO_18);
	PINMUX_CONFIG(SD1_D2, PWR_GPIO_19);
	PINMUX_CONFIG(SD1_D1, PWR_GPIO_20);
	PINMUX_CONFIG(SD1_D0, PWR_GPIO_21);
	//PINMUX_CONFIG(SD1_CMD, PWR_GPIO_22);
	//PINMUX_CONFIG(SD1_CLK, PWR_GPIO_23);

  pinmux_config(PINMUX_SPI2); //打开SPI2
  PINMUX_CONFIG(SPINOR_CS_X, XGPIOA_24);  //做为GPIO脚CS脚
  PINMUX_CONFIG(SPINOR_MISO, XGPIOA_23);  //做为GPIO脚REST脚
	//default to gpio
	PINMUX_CONFIG(PAD_MIPIRX1P, XGPIOC_9);
	PINMUX_CONFIG(PAD_MIPIRX0N, XGPIOC_10);
	PINMUX_CONFIG(USB_VBUS_DET, XGPIOB_6);
	PINMUX_CONFIG(PWR_SEQ2, PWR_GPIO_4);
	return 0;
}

2、配置设备树

/dts-v1/;
#include "cv180x_base_riscv.dtsi"
#include "cv180x_asic_qfn.dtsi"
#include "cv180x_asic_sd.dtsi"
#include "cv180x_default_memmap.dtsi"

&mipi_rx{
	snsr-reset = <&portc 8 GPIO_ACTIVE_LOW>, <&portc 8 GPIO_ACTIVE_LOW>, <&portc 8 GPIO_ACTIVE_LOW>;
};
&spi2 {
	status = "okay";
	/delete-node/ spidev@0;
	ili9341:ili9341@0{
		compatible = "adafruit,yx240qv29", "ilitek,ili9341";    //驱动
		reg = <0>;
		status = "okay";
	        spi-max-frequency = <80000000>;
		spi-cpol;
		spi-cpha;
		rotate = <270>;
		fps = <30>;
		bgr;
		buswidth = <8>;
		dc = <&porta 24 GPIO_ACTIVE_HIGH>; 
		reset = <&porta 23 GPIO_ACTIVE_HIGH>;
		debug = <0x0>;
	};
  };
/ {

};

因为我这个板子SPI以前是做GPIO的所有要添加SPI脚上拉

build/boards/default/dts/cv180x/cv180x_base.dtsi

spi2:spi2@041A0000 {
		compatible = "snps,dw-apb-ssi";
		reg = <0x0 0x041A0000 0x0 0x10000>;
		clocks = <&clk CV180X_CLK_SPI>;
		#address-cells = <1>;
		#size-cells = <0>;
		bias-pull-up; //添加这个地方,作用是上拉
	};

3、配置内核

CONFIG_SPI=y
CONFIG_SPI_MASTER=y
CONFIG_SPI_DESIGNWARE=y
CONFIG_SPI_DW_MMIO=y
CONFIG_SPI_SPIDEV=y
CONFIG_FB=y
CONFIG_FB_TFT=y
CONFIG_FB_TFT_ILI9341=y

下面这些不是必须配置的如果你要显示控制台就需要配置。

CONFIG_TTY=y
CONFIG_VT=y
CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
CONFIG_VT_HW_CONSOLE_BINDING=y
CONFIG_FB=y
CONFIG_FB_CMDLINE=y
CONFIG_FB_NOTIFY=y
CONFIG_FONT_SUPPORT=y
CONFIG_FONTS=y
CONFIG_FONT_8x16=y
CONFIG_VGA_CONSOLE=y
CONFIG_DUMMY_CONSOLE=y
CONFIG_DUMMY_CONSOLE_COLUMNS=80
CONFIG_DUMMY_CONSOLE_ROWS=25
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y

配置上Uboot启动时打印控制台信息到屏上

修改:u-boot-2021.10/include/configs/cv180x-asic.h文件

修改配置:#define CONSOLEDEV "tty0\0"   大约221行左右

4、修改源码

找到ili9341驱动文件:"duo-buildroot-sdk/linux_5.10/drivers/staging/fbtft/fbtft-core.c""

修改fbtft_request_one_gpio函数

static int fbtft_request_one_gpio(struct fbtft_par *par,
                  const char *name, int index,
                  struct gpio_desc **gpiop)
{
    struct device *dev = par->info->device;
    struct device_node *node = dev->of_node;
    int gpio, flags, ret = 0;
    enum of_gpio_flags of_flags;

    if (of_find_property(node, name, NULL)) {
        gpio = of_get_named_gpio_flags(node, name, index, &of_flags);
        if (gpio == -ENOENT)
            return 0;
        if (gpio == -EPROBE_DEFER)
            return gpio;
        if (gpio < 0) {
            dev_err(dev,
                "failed to get '%s' from DT\n", name);
            return gpio;
        }

         //active low translates to initially low 
        flags = (of_flags & OF_GPIO_ACTIVE_LOW) ? GPIOF_OUT_INIT_LOW :
                            GPIOF_OUT_INIT_HIGH;
        ret = devm_gpio_request_one(dev, gpio, flags,
                        dev->driver->name);
        if (ret) {
            dev_err(dev,
                "gpio_request_one('%s'=%d) failed with %d\n",
                name, gpio, ret);
            return ret;
        }

        *gpiop = gpio_to_desc(gpio);
        fbtft_par_dbg(DEBUG_REQUEST_GPIOS, par, "%s: '%s' = GPIO%d\n",
                            __func__, name, gpio);
    }

    return ret;
}

继续:fbtft_reset函数

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);
	msleep(10);
	gpiod_set_value_cansleep(par->gpio.reset, 0);
	msleep(200);
	gpiod_set_value_cansleep(par->gpio.reset, 1);
	msleep(10);
}

下面这个地方我没有修改已经可以正常运行了。"duo-buildroot-sdk/linux_5.10/drivers/staging/fbtft/fbtft-bus.c"文件中的:fbtft_write_vmem16_bus8函数

int fbtft_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len)
{
	u16 *vmem16;
	__be16 *txbuf16 = par->txbuf.buf;
	size_t remain;
	size_t to_copy;
	size_t tx_array_size;
	int i;
	int ret = 0;
	size_t startbyte_size = 0;
 
	fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "%s(offset=%zu, len=%zu)\n",
		      __func__, offset, len);
 
	remain = len / 2;
	vmem16 = (u16 *)(par->info->screen_buffer + offset);
 
	if (par->gpio.dc)
	{
		//printk("dc拉高!\n");
		gpiod_set_value(par->gpio.dc, 1);
	}
	/* non buffered write */
	if (!par->txbuf.buf)
		return par->fbtftops.write(par, vmem16, len);
 
	/* buffered write */
	tx_array_size = par->txbuf.len / 2;
 
	if (par->startbyte) {
		txbuf16 = par->txbuf.buf + 1;
		tx_array_size -= 2;
		*(u8 *)(par->txbuf.buf) = par->startbyte | 0x2;
		startbyte_size = 1;
	}
 
	while (remain) {
		to_copy = min(tx_array_size, remain);
		dev_dbg(par->info->device, "to_copy=%zu, remain=%zu\n",
			to_copy, remain - to_copy);
 
		for (i = 0; i < to_copy; i++)
			txbuf16[i] = cpu_to_be16(vmem16[i]);
 
		vmem16 = vmem16 + to_copy;
		ret = par->fbtftops.write(par, par->txbuf.buf,
						startbyte_size + to_copy * 2);
		if (ret < 0)
			return ret;
		remain -= to_copy;
	}
 
	return ret;
}

然后编译下载到板子上运行。

image.png

image.png

运行fb-test

image.png

运行fbv显示图片

image.png

分享给朋友:

相关文章

为自己打造Linux小系统

为自己打造Linux小系统

 一、前言Linux操作系统至1991.10.5号诞生以来,就源其开源性和自由性得到了很多技术大牛的青睐,每个Linux爱好者都为其贡献了自己的一份力,不管是在Linux内核还是开源软件等方面,都为我们后来人提供了一个良好的学习和研究环境。做为一个Linuxer,感谢各位前辈们为我们提供一个自由的空间,让我们也能够在学习的同时去研究Linux。本文主要通过裁剪现有Linux系统,打造一个属于自己的Linux小系统,让其能够装载网卡驱动,并配置IP地址,实现网络功能。二、原理启动流程介绍...

mkfs 参数

mkfs 参数

#mkfs.jffs2 -r rootfs -o fs.jffs2 -e 0x20000 --pad=0x500000 -s 0x800 –n -l即可生成 rootfs.jffs2Mkfs.jffs2各参数的意义如下:-r:指定要做成image的目录名。-o:指定输出image的文件名。-e:每一块要擦除的block size,默认是64KB.要注意,不同的flash, 其block size会不一样,三星的K9F2G08U0A的block size为0x20000(从其datasheet里可...

使用buildroot构建根文件系统

使用buildroot构建根文件系统

使用buildroot构建根文件系统buildroot可用于构建小型的linux根文件系统。大小最小可低至2M,与内核一起可以放入最小8M的spi flash中。buildroot中可以方便地加入第三方软件包(其实已经内置了很多),省去了手工交叉编译的烦恼。下载安装首先安装一些依赖,比如linux头文件:apt-get install linux-headers-$(uname -r)然后下载安装:wget https://buildroot.org/do...

关于CentOS 下 httpd 修改默认的目录后 403 错误的 解决

关于CentOS 下 httpd 修改默认的目录后 403 错误的 解决

step 1 : 首先改你要设置的目录权限       chmod -R 755 /home/html          -------------->>  /home/html   是你存放你的页面的目录   这里我顺便记录下关于selinux 的命令吧    getenforce=>查看 selinux的状态&nbs...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。