linux 添加ili9341屏的驱动
1、修改pinmux
我的板子是MiLK V DUO SPI2默认是做为GPIO,所以先修改为SPI功能
可以修改两个地方,修改一个地方就可以了:
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脚上拉
如果使用的是DRM驱动使用下面的设备树
&spi2 {
status = "okay";
/delete-node/ spidev@0;
ili9341:ili9341@0{
compatible = "adafruit,yx240qv29", "ilitek,ili9341";
/** compatible = "mi,mi0283qt"; **/
reg = <0>;
status = "okay";
spi-max-frequency = <48000000>;
spi-cpol;
spi-cpha;
rotation = <270>;
fps = <30>;
bgr;
buswidth = <8>;
reset = <&porta 23 GPIO_ACTIVE_HIGH>;
dc = <&porta 24 GPIO_ACTIVE_HIGH>;
dc-gpios = <&porta 24 GPIO_ACTIVE_HIGH>;
reset-gpios = <&porta 23 GPIO_ACTIVE_HIGH>;
debug = <0x0>;
};
};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;
}然后编译下载到板子上运行。
运行fb-test
运行fbv显示图片







支付宝打赏
微信打赏 