在内核目录,修改spi的设备树文件
linux/arch/arm64/boot/dts/allwiner/sun50i-h5-nanopi-neo2.dts
&spi1 {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&spi1_pins &spi1_cs_pins>;
cs-gpios = <&pio 0 11 GPIO_ACTIVE_HIGH>; //下文修改成这里设置的IO口号
spidev {
compatible = "myspilcd";
reg = <0>;
status = "okay";
spi-max-frequency = <400000>;
dc-gpios = <&pio 0 18 GPIO_ACTIVE_HIGH>;
reset-gpios = <&pio 0 12 GPIO_ACTIVE_HIGH>;
spi-cpha;
spi-cpol;
buswidth = <8>;
};
};
&pio {
...
spi1_cs_pins: spi1_cs_pins {
pins = "PA11";
function = "gpio_out";
};
};
再修改linux/arch/arm64/boot/dts/allwinner/sunxi-h3-h5.dtsi
...
spi1_pins: spi1 {
pins = "PA15", "PA16", "PA14", "PA11";
function = "spi1";
};
...
保存后,重新编译设备树
make dtbs ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
将arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dtb 文件拷贝到sd卡的第一个的分区,替换原来的的dtb文件,重启板子
spi屏接线:
板上引脚 图中引脚
LED <------> 3.3V2
SCK <------> SPI-CLK
SDA <------> SPI-MOSI
AO <------> IO-5
RESET <------> SDA
CS <------> SCL
GND <------> GND2
VCC <------> 3.3V1
测试代码:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/spi/spi.h>
#include <linux/delay.h>
#include <linux/gpio.h>
typedef struct {
struct gpio_desc *dc;
struct gpio_desc *rest;
}mydata_t;
struct lcd_cmd{
u8 addr;
u8 len;
u32 delay;
}regdatas[] = {
{0x11,0,120},{0xb1,3,0},
{0xb2,3,0},{0xb3,6,0},
{0xb4,1,0},{0xc0,3,0},
{0xc1,1,0},{0xc2,2,0},
{0xc3,2,0},{0xc4,2,0},
{0xc5,1,0},{0x36,1,0},
{0xe0,16,0},{0xe1,16,0},
{0x2a,4,0},{0x2b,4,0},
{0xf0,1,0},{0xf6,1,0},
{0x3a,1,0},{0x29,0,0},
};
static u8 lcd_datas[] = {
0x01,0x2c,0x2d, //b1
0x01,0x2c,0x2d, //b2
0x01,0x2c,0x2d,0x01,0x2c,0x2d, //b3
0x07, //b4
0xa2,0x02,0x84, //c0
0xc5, //c1
0x0a,0x00, //c2
0x8a,0x2a, //c3
0x8a,0xee, //c4
0x0e, //c5
0xc0, //36
0x0f,0x1a,0x0f,0x18,0x2f,0x28,0x20,0x22, //e0
0x1f,0x1b,0x23,0x37,0x00,0x07,0x02,0x10,
0x0f,0x1b,0x0f,0x17,0x33,0x2c,0x29,0x2e, //e1
0x30,0x30,0x39,0x3f,0x00,0x07,0x03,0x10,
0x00,0x00,0x00,0x7f, //2a
0x00,0x00,0x00,0x9f, //2b
0x01, //f0
0x00, //f6
0x05, //3a
};
void reset_lcd(mydata_t *mydata)
{
gpiod_set_value(mydata->rest,0);
msleep(100);
gpiod_set_value(mydata->rest,1);
msleep(100);
}
void write_command(struct spi_device *spi,u8 addr)
{
mydata_t *mydata = spi_get_drvdata(spi);
gpiod_set_value(mydata->dc,0);
spi_write(spi,&addr,1);
}
void write_data(struct spi_device *spi,u8 data)
{
mydata_t *mydata = spi_get_drvdata(spi);
gpiod_set_value(mydata->dc,1);
spi_write(spi,&data,1);
}
void init_lcd(struct spi_device *spi,mydata_t *mydata)
{
int i,j,k = 0;
reset_lcd(mydata);
for(i = 0;i < ARRAY_SIZE(regdatas);i ++)
{
//write command
write_command(spi,regdatas[i].addr);
for(j = 0;j < regdatas[i].len;j ++)
{
write_data(spi,lcd_datas[k++]);
}
if(regdatas[i].delay)
msleep(regdatas[i].delay);
}
}