序言
任务:
用rk3328-evb中的两个gpio模拟I2C,slave模式是基本,master作为拓展。
目标:
- 功能成功
- 速率可设
- 主从模式
- 挂在设备树上
平台:
RK3328-evb,arm64,ddr4,硬件信息可以从开源网站中获取
rock-chip开源官网
固件烧录
烧录也是通过开源网的教程中慢慢琢磨,固件烧录过程遇到挺多的问题,把遇到一些问题贴出来,如果大家遇到了有好的解决方法,希望告知。
RK3328烧录过程遇到问题
内核模块动态加载
内核驱动调试过程最好做成模块,然后通过动态加载也就是单独编译出来然后insert进内核,我总结了三种便捷的交叉编译方式,我主要使用V2.0,编译过程是在虚拟机中,而内核模块加载是加载在目标机上,所以注意交叉编译相关内容。
V1.0:整个kernel 编译模块
Makefile:
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- rockchip_linux_defconfig
kernel/:
make modules ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
rk3328-evb:
insmod(rmmod)
mknod /dev/i2c_ldq c 225 0
V2.0:编译指定模块
Makefile:
ifneq ($(KERNELRELEASE),)
obj-m:= led.o
else
KDIR := /home/ldq/kernel
PWD := $(shell pwd)
CROSS_COMPILE=/opt/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-5.3-linaro/bin/aarch64-linux-android-
ARCH =arm64
default:
make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=$(CROSS_COMPILE) ARCH=$(ARCH)
rm -rf *.o *.cmd *.mod.c *.order *.symvers
endif
clean:
rm -rf *.o *.cmd *.mod.c *.ko *.order *.symvers
V3.0:代码行直接使用
make -C /home/ldq/kernel M=/home/ldq/kernel/drivers/char/hello modules CROSS_COMPILE=/opt/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-5.3-linaro/bin/aarch64-linux-android- ARCH=arm64
手册阅读
- GRF:pin复用,尤其是我们要用到的GPIO口是否被其他驱动复用到其他设备上,导致GPIO寄存器无法配置有效
- GPIO寄存器:通过配置GPIO的direction和data来完成GPIO配置
I2C协议
外围设备都具有一个七位的“从器件专用码”,高四位厂家信息,由厂家定义。低三位地址信息,由使用者自己定义。所以不需要外部的片选。多种slc频率,但是保持在100k或以下,不过这个都是比较旧的资料,不知道现在是什么速率。
- 空闲状态:SCL和SDA保持高电平
- 起始位:SCL高 SDA高转低跳变
- 终止位:SCL高 SDA低转高跳
发送端发送一个字节后,由接收端反馈一个应答信号,低电平为有效应答(ACK),高电平位无效电平(NACK),要求在第九个SCL时钟信号低电平期间,拉低,并且在第九个SCL时钟高电平期间,保持低。
如果接收器是主控器,则在它收到最后一个字节后,发送一个NACK信号,以通知被控发送器结束数据发送,并释放SDA线,以便主控接收器发送一个停止信号P。
- 在SCL低电平期间SDA做变化,SCL高电平期间SDA保持电平,这样的数据才有效
- 同步——每一位数据都有一个时钟脉冲相对应
工作流程
- 主设备发出起始电平
- 主设备发出设备地址、读写位,然后释放总线等待从设备拉低应答
- 发送所要读取的slave的内部寄存器,等待应答
- 发送数据
发送停止位
● 写入从设备
- 主设备发出起始电平 start
- 主设备发出设备地址、写位,然后释放总线等待从设备拉低应答 write
- 发送所要写的slave的内部寄存器,等待应答 read ack
- 发送数据 write read ack
- 发送停止位,从设备进入内部写入周期,所以两次写之间需要一个大概10ms的延迟。
● 读从设备
- 主设备发出起始电平 start
- 主设备发出设备地址、读位 bit[0:7]
- 发送所要读取的slave的内部寄存器 bit[0:7]
- 重新发送起始电平,即restart start
- 重新发送slave地址+read bit set;
- 读取数据
主机接收器在接收到最后一个字节后,也不会发出ACK信号。于是,从机发送器释放SDA线,以允许主机发出P信号结束传输。 - 发送停止位
设备树
作用:
- 板级的信息获取抽象到驱动中,而具体信息在设备树上,通过修改设备树节点的信息,来使得驱动支持普通信息发生改变的不同开发板(比如管教的物理地址),但是如果驱动逻辑发生改变,还是要重写驱动
设备树就是为驱动服务的
注释
- 节点名可以引用 &pinctrl,pinctrl:
- KEY
未完待续……
版权声明:本文为jilingqiang6814原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。