Linux Kernel实现GPIO模拟SPI与I2C
模拟SPI和I2C和硬件支持的还是有一些差别,速度上会有极大的限制。
但是可以很好的解决我们硬件外设不够用的情况,但是又可以使用Linux内核中的驱动来搭配使用。
1. GPIO 模拟I2C
需要先设置内核的支持
在内核源码目录下,先进行图形化界面配置 menuconfig
配置 Device Drivers > I2C support
新建一个设备树文件,添加如下内容
#include <dt-bindings/pinctrl/rockchip.h>
/{
aliases {
i2c6 = &i2c6;
};
i2c6:i2c6_gpio{
#address-cells = <1>;
#size-cells = <1>;
compatible = "i2c-gpio";
pinctrl-names = "default";
pinctrl-0 = <&i2c6_soft>;
gpios = <&gpio4 RK_PA1 GPIO_ACTIVE_HIGH>, /* SDA */
<&gpio4 RK_PA3 GPIO_ACTIVE_HIGH>; /* SCL */ //先SDA后SCL顺序是死的不要变
i2c-gpio,delay-us = <5>;
status = "disabled";
};
};
&pinctrl {
i2c6{
i2c6_soft:i2c6-soft{
rockchip,pins = <4 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>,
<4 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
};
注意:aliases节点必须写,总线使用aliases节点中定义的顺序去初始化总线外设等。
使用方法(触摸示例):
&i2c6{
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&i2c6_soft &gpio0_pc5 &gpio0_pa5>;
clock-frequency = <100000>;
focaltech@38{
status = "okay";
compatible = "focaltech,fts";
reg = <0x38>;//I2C地址
interrupt-parent = <&gpio0>;
interrupts = <RK_PC5 IRQ_TYPE_LEVEL_LOW>;
focaltech,reset-gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>;
focaltech,irq-gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
focaltech,max-touch-number = <5>;//最大触摸数量-多点触摸配置
focaltech,display-coords = <0 0 240 320>;//分辨率
};
};
2. GPIO模拟SPI
需要先设置内核的支持
在内核源码目录下,先进行图形化界面配置 menuconfig
配置 Device Drivers > SPI support
#include <dt-bindings/pinctrl/rockchip.h>
/{
aliases {
spi5 = &spi5;
};
spi5:spi5_gpio{
compatible = "spi-gpio";
#address-cells = <0x1>;
ranges;
pinctrl-names = "default";
pinctrl-0 = <&spi6_soft>;
sck-gpios = <&gpio4 RK_PA0 0>;
mosi-gpios = <&gpio3 RK_PD7 0>;
miso-gpios = <&gpio3 RK_PA1 0>;
cs-gpios = <&gpio3 RK_PA2 0>;
num-chipselects = <1>;
status = "disabled";
};
};
&pinctrl {
spi5{
spi5_soft:spi5-soft{
rockchip,pins = <3 RK_PD7 RK_FUNC_GPIO &pcfg_pull_none>,
<4 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
};
注意:aliases节点必须写总线使用aliases节点中定义的顺序去初始化总线外设等。
使用方法(屏幕驱动示例):
&spi5{
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&spi5_soft &gpio3_pd6 &gpio4_pa2 &gpio0_pc0>;
#address-cells = <1>;
#size-cells = <0>;
tft: lcd@0{
compatible = "sitronix,st7789v";
spi-max-frequency = <100000000>;//40Mh
// spi-max-frequency = <80000000>;
reg = <0>;//SPI序号
spi-cpol;
spi-cpha;
rotate = <90>;// 旋转角度,lcd驱动里会读取并设置对应寄存器
fps = <30>;
width = <240>;
height = <320>;
invert;
// bgr = <0>;
buswidth = <8>;//SPI 8位数据长度
led-gpios = <&gpio3 RK_PA4 GPIO_ACTIVE_LOW>;//BL
dc-gpios = <&gpio3 RK_PA7 GPIO_ACTIVE_LOW>;//DC
reset-gpios = <&gpio3 RK_PB5 GPIO_ACTIVE_HIGH>;//RES
cs-gpios = <&gpio3 RK_PA5 GPIO_ACTIVE_LOW>;//CS
// debug = <0x7>;
};
};
评论区