zynq7000的I2C控制器是cadence公司的IP,做一个驱动如果从阅读数据手册开始,效率会很低,因此首先找到了其Linux的I2C驱动文件i2c_cadence.c,话一部分时间阅读两遍后,会了解Zynq7000的I2C控制器工作流程和操作方法。
开始是基于Linux的驱动进行移植的,进展不是很顺利,主要是Linux驱动中的数据收发均是在中断中完成,并加入了Linux自身的驱动框架。为了方便的调试驱动,先调试无中断情况下的功能,然后在将中断、FIFO等加入以提高效率是一个比较不错的方法。为了快速的调试通过I2C驱动,这里考虑了其Uboot中的驱动文件。
Zynq7000的I2C控制器Uboot下的驱动文件是zynq_i2c.c,此文件设计非常容易理解,文件中一共有7个函数,其中有用的是如下5个函数,通过阅读以下五个函数,可以很容易了解I2C的操作过程,而且可以直接在驱动中使用**read、**write函数进行测试。
zynq_i2c_init zynq_i2c_wait zynq_i2c_probe zynq_i2c_read zynq_i2c_write |
因此这里直接使用uboot中代码进行测试。通过查阅所用zynq7000电路板的原理图,查阅其中的I2C总线号、管脚分配、所挂载的I2C设备及设备地址。这样就可以使用uboot中的读写函数进行测试。虽然读写函数是针对epprom设计,但是读写其他的设备如RTC芯片、触摸屏控制器等均是可以的。
为了可以让系统调用相关函数,这里从s5pv210处理器的bsp中拷贝一个i2c驱动的模板,删除其与芯片相关内容,将uboot的内容原封不动的拷贝到此文件中。并在makefile中修改源文件包含路径,是系统可以编译此文件。
其次在halBusInit加入如下代码:
PLW_I2C_FUNCS pi2cfunc; API_I2cLibInit(); pi2cfunc = i2cBusFuns(0); /* 注册I2C通道0 */ API_I2cAdapterCreate("/bus/i2c/0", pi2cfunc, 10, 1); |
随后将I2C读写的测试程序代码放入i2cBusFuns函数里面,这样在系统启动后就会调用这些代码,通过printk输出信息可以了解其工作过程是否正确。在验证I2C代码可以对I2C设备进行正常读写后,开始修改这些函数使之可以纳入SylixOS的驱动框架中。
首先是修改其数据发送函数zynq_i2c_write,这里将发送设备内部寄存器地址和数据的两段操作合并成为一段,随后测试函数是否能够正常工作,知道正常工作为止。
之后将zynq_i2c_write函数带入zynq_i2c_read函数,替换其中的地址发送部分,测试函数能否工作,使之可以工作。在测试此函数时遇到一些波折,就是hold位的设置,需要挪到zynq_i2c_write后面执行,否则无法进行正常的I2C设备数据读取,测试能够正常工作后将zynq_i2c_write函数从zynq_i2c_read函数中删除。
完成上述工作后,就好办多了。将数据cdnsI2cTransferMsg里面的收发函数分别使用上述zynq_i2c_write、zynq_i2c_read替换,至此,驱动已经能够正常工作。编译系统,使用SylixOS下标准的I2C总线操作函数进行测试。
文章评论(0条评论)
登录后参与讨论