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

linux 添加ili9341屏的驱动

Watrt1年前 (2023-09-09)LINUX5350

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

分享给朋友:

相关文章

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里可...

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

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

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

荔枝派nano(f1c100s)的SPI-Flash系统编译创建全过程

荔枝派nano(f1c100s)的SPI-Flash系统编译创建全过程

前言本文的目标是创建一个运行在SPI-Flash上的精简系统,附带填一些前人没有提及的坑。在开始之前,请先通读官方教程的即食部分(U-Boot)、Linux编译和SPI-Flash系统的创建部分的教程,并搭建好编译工具链。以下我假设你已经按照上面的教程下载好了U-Boot和Linux内核,并且到Buildroot的官网下载好了Buildroot(但没按教程创建config文件)。SPI-Flash的分区结构以下是我这里的分区结构。你可以自由的分配后面两个分区的大小。ID  S...

Deepin Linux修复grub引导

Deepin Linux修复grub引导

环境说明:一直使用的是Win7+Deepin 15.5。后来全新安装了Win 10,需要修复grub第一步:在Windows操作系统下使用深度官方的U盘启动制作器 制作U盘第二步:开机U盘启动进入Deepin linux安装界面,待进入到安装界面选择语言时,按住Crtl+Alt+F2/F1进入Linux tty终端。并执行以下命令完成修复sudo fdisk -l/*根据查询结果确定deepin 的/目录和/boot目录所在的分区编号*/sudo mount&nbs...

发表评论

访客

看不清,换一张

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