全志平台A40I : TWI2通讯验证

简介: 全志平台A40I : TWI2通讯验证

前言:

在本文中,简单的介绍如何在全志Android平台上通过I2C协议检测特定的硬件设备。将从硬件连接的确认开始,接着介绍必要的系统配置,然后是对照数据手册进行的详细设置,最后实现一个简单的I2C驱动来识别DMT C0A9加密芯片。

全志平台A40I : I2C通讯问题调试笔记

  1. 确认硬件I2C2的连接接口
TWI2_SCK=PB20
   TWI2_SDA=PB21

  1. 确认sys_config.fex的配置
[twi2]
twi2_used        = 1
twi2_scl         = port:PB20<2><default><default><default>
twi2_sda         = port:PB21<2><default><default><default>
  1. 确认datasheet
TWI2_SCK=PB20_SELECT的010
TWI2_SDA=PB21_SELECT的010

  1. 确认dts文件
    如果没有twi2则需要添加 , 并且新增对应驱动的配置
    dts配置写法不同, 不然会导致匹配不到compatible 从而执行不了probe函数 当前kernel版本是需要去掉@38的。
twi2: twi@0x01c2b400 {
      interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
      status = "okay";
      dmt_c0a9 {
     //dmt_c0a9@38 {
         compatible = "dmt,dmt_c0a9";
         reg = <0x38>;
         status = "okay";
      };
};
  1. 确认dts编译出来的文件是否被编译到
    xxxx\boot\dts.xxx.dtb.dts
twi2: twi@0x01c2b400 {
      interrupts = <0 4 4>;
   status = "okay";
      dmt_c0a9 {
         compatible = "dmt,dmt_c0a9";
         reg = <0x38>;
         status = "okay";
      };
  };
  1. 确认I2C的function被配置成功
a40-p1:/proc/sys/debug/sunxi_pinctrl # cat sunxi_pin_configure
pin[PB20] funciton: 2
pin[PB20] data: 0
pin[PB20] dlevel: 1
pin[PB20] pull: 0
a40-p1:/proc/sys/debug/sunxi_pinctrl # echo PB21 > sunxi_pin
a40-p1:/proc/sys/debug/sunxi_pinctrl # cat sunxi_pin_configure
pin[PB21] funciton: 2
pin[PB21] data: 0
pin[PB21] dlevel: 1
pin[PB21] pull: 0
  1. 确认系统能够探测到硬件I2C地址
a40-p1:/proc/sys/debug/sunxi_pinctrl # i2cdetect -ya 2
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- 38 -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
  1. 写个简单的驱动c0a9
//1.测试读写
    static int dmt_c0a9_read(struct dmt_c0a9_dev *dmt_c0a9, u8 *buf, u32 len)
    {
        int ret;
        printk(KERN_INFO "Entering: %s\n", __func__);
        // Reading data using i2c_master_recv
        ret = i2c_master_recv(dmt_c0a9->client, buf, len);
        if (ret < 0)
        {
            dev_err(dmt_c0a9->dev, "i2c_master_recv failed with ret = %d\n", ret);
        }
        else if (ret != len)
        {
            dev_err(dmt_c0a9->dev, "Expected %d bytes, received %d bytes\n", len, ret);
        }
        printk(KERN_INFO "Exiting: %s with ret = %d\n", __func__, ret);
        return ret;
    }
    static int dmt_c0a9_write(struct dmt_c0a9_dev *dmt_c0a9, u8 *buf, u32 len)
    {
        int ret;
        printk(KERN_INFO "Entering: %s\n", __func__);
        // Writing data using i2c_master_send
        ret = i2c_master_send(dmt_c0a9->client, buf, len);
        if (ret < 0)
        {
            dev_err(dmt_c0a9->dev, "i2c_master_send failed with ret = %d\n", ret);
        }
        else if (ret != len)
        {
            dev_err(dmt_c0a9->dev, "Expected %d bytes to be sent, actually sent %d bytes\n", len, ret);
        }
        printk(KERN_INFO "Exiting: %s with ret = %d\n", __func__, ret);
        return ret;
    }
    static int dmt_c0a9_test(struct dmt_c0a9_dev *dmt_c0a9)
    {
        int ret;
        printk(KERN_INFO "Entering: %s\n", __func__);
        // Writing data to I2C device
        ret = dmt_c0a9_write(dmt_c0a9, txbuf, 32);
        if (ret)
        {
            dev_err(dmt_c0a9->dev, "Write operation failed with ret = %d\n", ret);
            return ret;
        }
        // Reading data from I2C device
        ret = dmt_c0a9_read(dmt_c0a9, rxbuf, 32);
        if (ret)
        {
            dev_err(dmt_c0a9->dev, "Read operation failed with ret = %d\n", ret);
            return ret;
        }
        // Data processing and verification can be done here
        printk(KERN_INFO "Exiting: %s with ret = %d\n", __func__, ret);
        return 0;
    }
      //2.测试c0a9的驱动能够探测到I2C地址0
  static int dmt_c0a9_probe(struct i2c_client *client, const struct i2c_device_id *id)
  {
      int ret;
      u8 dummy_data = 0;
      
      printk(KERN_INFO "Entering: %s\n", __func__);
  
      // 尝试向设备发送一个字节的数据以检测其存在性
      ret = i2c_master_send(client, &dummy_data, 1);
      if (ret == 1) {
          printk(KERN_INFO "Device found at address 0x38\n");
          return 0; // Device exists
      } else {
          printk(KERN_INFO "No device found at address 0x38\n");
          //未检测到DMT C0A9设备 - 触发内核重启
          panic("DMT C0A9 not detected - triggering kernel panic");
          return -ENODEV; // Device does not exist
      }
  }

总结:

通过本文的介绍,学习了在全志平台上检测I2C设备并通过驱动控制的整个过程。

相关文章
|
2月前
|
监控 安全 数据安全/隐私保护
企业组网:构建智慧型网络基础设施,驱动未来商业发
随着数字化进程,企业组网演变为创新与竞争力的关键。智慧型网络基础设施助力企业内部协作效率提升,外部市场拓展及应对未来挑战。核心要素包括前瞻网络架构、高性能硬件、智能化软件和全面安全。实施策略涉及明确需求、制定方案、精细化实施、全面测试及持续优化,确保网络稳定、高效、安全。
29 3
企业组网:构建智慧型网络基础设施,驱动未来商业发
|
2月前
|
Linux Android开发
全志平台A40I : I2C通讯问题调试笔记
全志平台A40I : I2C通讯问题调试笔记
63 0
|
2月前
|
调度
【技术探讨】无线通信模块拉距测试,是否一定要带笔记本电脑?
对于Sub-G的无线模块通常通信距离较远可以达到公里级甚至数公里之远,而笔记本的续航时间通常是2-3个小时,很多用户测试到一半,不得不提前终止测试,回去给笔记本电脑充电
|
Linux
高通平台开发系列讲解(网络篇)内外部拨号方式区别
高通平台开发系列讲解(网络篇)内外部拨号方式区别
245 0
高通平台开发系列讲解(网络篇)内外部拨号方式区别
|
小程序 物联网 机器人
基于STM32+ESP8266设计物联网产品(重点:支持微信小程序一键配网连接腾讯云平台)
基于STM32+ESP8266设计物联网产品(重点:支持微信小程序一键配网连接腾讯云平台)
1261 0
基于STM32+ESP8266设计物联网产品(重点:支持微信小程序一键配网连接腾讯云平台)
|
应用服务中间件 网络安全 nginx
专网环境TRTC视频平台通讯解决方案
PC客户端处于专网无法与TRTC视频平台通讯(客户必须要外网)
9864 0
专网环境TRTC视频平台通讯解决方案