linux4.15内核ILI9341LCD屏并口16线RGB565驱动

9 篇文章 0 订阅
3 篇文章 0 订阅
本文档详细介绍了如何在Linux 4.15内核中配置和驱动ILI9341 LCD显示屏,包括设备树配置和驱动源码解析。设备树配置部分涉及SPI接口设置和屏幕刷新参数,而驱动源码展示了初始化序列和关键寄存器设置。该驱动适用于16线RGB565接口的ILI9341液晶屏。
摘要由CSDN通过智能技术生成

linux4.15内核ILI9341LCD屏并口16线RGB565驱动

设备树配置

#spi配置
spidev3@0x33 {
		#address-cellss=<1>;
		#size-cells=<1>;
		compatible = "ilitek,ili9341";
		spi-max-frequency = <8000000>;
		buswidth = <9>;
		bgr = <0>;
		reg = <0>;
		reset = <&gpio5 3 0>;
	};
	
	
	#屏幕刷新参数配置
	timing3: timing3 {
				clock-frequency = <6100000>;
				hactive = <240>;
				vactive = <320>;
				hfront-porch = <10>;
				hback-porch = <20>;
				hsync-len = <10>;
				vback-porch = <2>;
				vfront-porch = <4>;
				vsync-len = <2>;

				hsync-active = <0>;
				vsync-active = <0>;
				de-active = <1>;
				pixelclk-active = <0>;
			};

驱动源码

#include <linux/uaccess.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/spi/spi.h>
#include <linux/of_gpio.h>
#include <linux/spi/spidev.h>
#include <linux/device.h>


#define ILI9341_RGB_INTERFACE  0xb0   /* RGB Interface Signal Control */
#define ILI9341_FRC            0xb1   /* Frame Rate Control register */
#define ILI9341_DFC            0xb6   /* Display Function Control register */
#define ILI9341_POWER1         0xc0   /* Power Control 1 register */
#define ILI9341_POWER2         0xc1   /* Power Control 2 register */
#define ILI9341_VCOM1          0xc5   /* VCOM Control 1 register */
#define ILI9341_VCOM2          0xc7   /* VCOM Control 2 register */
#define ILI9341_POWERA         0xcb   /* Power control A register */
#define ILI9341_POWERB         0xcf   /* Power control B register */
#define ILI9341_PGAMMA         0xe0   /* Positive Gamma Correction register */
#define ILI9341_NGAMMA         0xe1   /* Negative Gamma Correction register */
#define ILI9341_DTCA           0xe8   /* Driver timing control A */
#define ILI9341_DTCB           0xea   /* Driver timing control B */
#define ILI9341_POWER_SEQ      0xed   /* Power on sequence register */
#define ILI9341_3GAMMA_EN      0xf2   /* 3 Gamma enable register */
#define ILI9341_INTERFACE      0xf6   /* Interface control register */
#define ILI9341_PRC            0xf7   /* Pump ratio control register */
#define ILI9341_ETMOD	       0xb7   /* Entry mode set */


#define ILI9341_MADCTL_BGR	BIT(3)
#define ILI9341_MADCTL_MV	BIT(5)
#define ILI9341_MADCTL_MX	BIT(6)
#define ILI9341_MADCTL_MY	BIT(7)

#define ILI9341_POWER_B_LEN	3
#define ILI9341_POWER_SEQ_LEN	4
#define ILI9341_DTCA_LEN	3
#define ILI9341_DTCB_LEN	2
#define ILI9341_POWER_A_LEN	5
#define ILI9341_DFC_1_LEN	2
#define ILI9341_FRC_LEN		2
#define ILI9341_VCOM_1_LEN	2
#define ILI9341_DFC_2_LEN	4
#define ILI9341_COLUMN_ADDR_LEN	4
#define ILI9341_PAGE_ADDR_LEN	4
#define ILI9341_INTERFACE_LEN	3
#define ILI9341_PGAMMA_LEN	15
#define ILI9341_NGAMMA_LEN	15
#define ILI9341_CA_LEN		3

#define ILI9341_PIXEL_DPI_16_BITS	(BIT(6) | BIT(4))
#define ILI9341_PIXEL_DPI_18_BITS	(BIT(6) | BIT(5))
#define ILI9341_GAMMA_CURVE_1		BIT(0)
#define ILI9341_IF_WE_MODE		BIT(0)
#define ILI9341_IF_BIG_ENDIAN		0x00
#define ILI9341_IF_DM_RGB		BIT(2)
#define ILI9341_IF_DM_INTERNAL		0x00
#define ILI9341_IF_DM_VSYNC		BIT(3)
#define ILI9341_IF_RM_RGB		BIT(1)
#define ILI9341_IF_RIM_RGB		0x00

#define ILI9341_COLUMN_ADDR		0x00ef
#define ILI9341_PAGE_ADDR		0x013f

#define ILI9341_RGB_EPL			BIT(0)
#define ILI9341_RGB_DPL			BIT(1)
#define ILI9341_RGB_HSPL		BIT(2)
#define ILI9341_RGB_VSPL		BIT(3)
#define ILI9341_RGB_DE_MODE		BIT(6)
#define ILI9341_RGB_DISP_PATH_MEM	BIT(7)

#define ILI9341_DBI_VCOMH_4P6V		0x23
#define ILI9341_DBI_PWR_2_DEFAULT	0x10
#define ILI9341_DBI_PRC_NORMAL		0x20
#define ILI9341_DBI_VCOM_1_VMH_4P25V	0x3e
#define ILI9341_DBI_VCOM_1_VML_1P5V	0x28
#define ILI9341_DBI_VCOM_2_DEC_58	0x86
#define ILI9341_DBI_FRC_DIVA		0x00
#define ILI9341_DBI_FRC_RTNA		0x1b
#define ILI9341_DBI_EMS_GAS		BIT(0)
#define ILI9341_DBI_EMS_DTS		BIT(1)
#define ILI9341_DBI_EMS_GON		BIT(2)

#define NUMARGS(...)  (sizeof((int[]){__VA_ARGS__})/sizeof(int))

#define ili9341_spi_write(spidev, ...)                                              \
	__ili9341_spi_write(spidev, NUMARGS(__VA_ARGS__), __VA_ARGS__)

static void __ili9341_spi_write(struct spi_device *spi, int len, ...)
{
	va_list args;
	unsigned short tmp[256] = {0};
	unsigned short *buf = tmp;
	struct spi_message m;
	struct spi_transfer t = {
		.tx_buf = tmp,
		.len = len*2,
	};
	int i,ret;
	// unsigned char *dbg = tmp;

	if(len <= 0 )
		return;
	
	va_start(args, len);
	*buf++ = (u8)va_arg(args, unsigned int);
	i = len - 1;
	while (i--) {
		*buf = (u8)va_arg(args, unsigned int);
		*buf++ |= 0x100; /* dc=1 */
	}
	va_end(args);

	//va_start(args, len);
	//printk("%s: args(len%d)[",__func__,len);
	//for (i = 0; i < len; i++)
	//	printk("%#x ", (u8)va_arg(args, unsigned int));
	//va_end(args);
	//printk("]\n");

	// printk("%s: send(len%d)[",__func__,len*2);
	// for(i = 0; i < len*2; i++){
	// 	printk("%#x ",*(dbg+i));
	// }
	// printk("]\n");

	spi_message_init(&m);
	spi_message_add_tail(&t,&m);
	ret = spi_sync(spi, &m);
	if(ret)
		printk("%s ret=%d\n",__func__,ret);
}

static int ili9341_probe(struct spi_device *spi) 
{
	struct spi_device *spidev;
	struct device_node *np = spi->dev.of_node;
	int reset;
	int err = -1;
	spidev = spi;
	spidev->bits_per_word = 9;	
	err = spi_setup(spidev);	
	// printk(KERN_ERR "ilitek,ili9341 probe\nmode=%#x bits_per_word=%d  mode_bits=%#x\n",
	// 								spidev->mode,
	// 								spidev->bits_per_word,
	// 								spidev->master->mode_bits);
	/*hardware reset*/
	reset = of_get_named_gpio(np, "reset", 0);
    if (reset < 0)
    {
        printk("reset gpio error\n");
        return -1;
    }
	if(gpio_request(reset, "reset") < 0)
	{
		printk("lcd gpio_request error\n");
        return -1;
	}
	if(gpio_direction_output(reset, 1) < 0)
	{
		printk("lcd gpio_direction_output error\n");
		gpio_free(reset);
		return -1;
	}
	gpio_set_value(reset, 0);
	udelay(10);
	gpio_set_value(reset, 1);
	mdelay(1);
	gpio_set_value(reset, 0);
	mdelay(1);
	gpio_set_value(reset, 1);


	/* startup sequence for MI0283QT-9A */
		ili9341_spi_write(spidev, 0x01); /* software reset */
		mdelay(5);
		ili9341_spi_write(spidev, 0x28); /* display off */
	/* --------------------------------------------------------- */

	ili9341_spi_write(spidev, 0xca, 0xc3, 0x08, 0x50);
	ili9341_spi_write(spidev, ILI9341_POWERB, 0x00, 0xc1, 0x30);
	ili9341_spi_write(spidev, ILI9341_POWER_SEQ, 0x64, 0x03, 0x12, 0x81);
	ili9341_spi_write(spidev, ILI9341_DTCA, 0x85, 0x00, 0x78);
	ili9341_spi_write(spidev, ILI9341_POWERA, 0x39, 0x2c, 0x00, 0x34, 0x02);
	ili9341_spi_write(spidev, ILI9341_PRC, 0x20);
	ili9341_spi_write(spidev, ILI9341_DTCB, 0x00, 0x00);
	ili9341_spi_write(spidev, ILI9341_FRC, 0x00, 0x1b);
	ili9341_spi_write(spidev, ILI9341_DFC, 0x0a, 0xa2);
	ili9341_spi_write(spidev, ILI9341_POWER1, 0x10);
	ili9341_spi_write(spidev, ILI9341_POWER2, 0x10);
	ili9341_spi_write(spidev, ILI9341_VCOM1, 0x45, 0x15);
	ili9341_spi_write(spidev, ILI9341_VCOM2, 0x90);
	ili9341_spi_write(spidev, 0x36, 0xc8);
	ili9341_spi_write(spidev, ILI9341_3GAMMA_EN, 0x00);
	ili9341_spi_write(spidev, ILI9341_RGB_INTERFACE, ILI9341_RGB_DISP_PATH_MEM | ILI9341_RGB_DE_MODE | ILI9341_RGB_DPL);
	ili9341_spi_write(spidev, ILI9341_DFC, 0x0a, 0xa7, 0x27, 0x04);
	ili9341_spi_write(spidev, 0x2a, 0x00, 0x00, (ILI9341_COLUMN_ADDR >> 4) & 0xff, ILI9341_COLUMN_ADDR & 0xff);
	ili9341_spi_write(spidev, 0x2b, 0x00, 0x00, (ILI9341_PAGE_ADDR >> 4) & 0xff, ILI9341_PAGE_ADDR & 0xff);
	ili9341_spi_write(spidev, ILI9341_INTERFACE, ILI9341_IF_WE_MODE, 0x00, ILI9341_IF_DM_RGB | ILI9341_IF_RM_RGB);
	ili9341_spi_write(spidev, 0x3a, ILI9341_PIXEL_DPI_16_BITS);
	ili9341_spi_write(spidev, 0x2c);
	ili9341_spi_write(spidev, 0x26, ILI9341_GAMMA_CURVE_1);
	ili9341_spi_write(spidev, ILI9341_PGAMMA, 0x0f, 0x29, 0x24, 0x0c, 0x0e,0x09, 0x4e, 0x78, 0x3c, 0x09,0x13, 0x05, 0x17, 0x11, 0x00);
	ili9341_spi_write(spidev, ILI9341_NGAMMA, 0x00, 0x16, 0x1b, 0x04, 0x11, 0x07, 0x31, 0x33, 0x42, 0x05, 0x0c, 0x0a, 0x28, 0x2f, 0x0f);
	ili9341_spi_write(spidev, 0x11);
	mdelay(20);
	ili9341_spi_write(spidev, 0x29);
	ili9341_spi_write(spidev, 0x2c);


	return 0;

}

static int ili9341_remove(struct spi_device *spi)
{
	return 0;	
}
static const struct of_device_id ili9341_of_match[] = {
	{ .compatible = "ilitek,ili9341" },
	{ }
};
MODULE_DEVICE_TABLE(of, ili9341_of_match);

static struct spi_driver ili9341_driver = {
	.probe = ili9341_probe,
	.remove = ili9341_remove,
	.driver = {
		.name = "ili9341",
		.owner = THIS_MODULE,
		.of_match_table = ili9341_of_match,
	},
};
module_spi_driver(ili9341_driver);

MODULE_DESCRIPTION("ILITEK ILI9341 Init");
MODULE_LICENSE("GPL v2");

参考资料

资料

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

omnibots

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值