赞
踩
板子上通过ZYNQ的I2C-0控制器连接了三片DBF芯片和一片Ti的226测功耗芯片,示意图如下:
如上图所示,三块DBF芯片的I2C地址分别为2,4,8,Ti 226芯片的I2C地址为0x40.现在需要ZYNQ通过I2C总线读写这四块芯片的寄存器数值。
之前调试过cps1848 RapidIO交换芯片,想来既然都是i2c从设备,知道了slave的地址操作过程应该差不多,不过真正调试的时候才发现虽然这些设备都遵循I2C协议,但在i2c的读写时序上还是存在不同,下面将cps1848与dbf的i2c读写时序进行对比,Ti 226的类似。
以上是从1848 datasheet中摘录出的i2c读写时序图,之前调试时采用的是7位地址,即后面两个图。
从图中可以得知,读操作时i2c master先发slave地址(加start共8bit),再发要读写的空间地址(即寄存器offset,共24bit),这两个部分组成第一个message.后一个message包括slave地址(8bit)和接收数据的缓冲区(32bit)。完成整个操作后表示读结束。对应代码如下:
Msgbuf即对应offset,共24bit,msg即为上面提到的message,调用i2c_transfer()发送两个msg正好匹配1848的读时序图。
再来看写操作,先是一个slave地址(8bit),再24bit偏移量,然后是待写入的32bit共同组成一个message.代码如下:
从代码中可以看到,这里把要写入的数据和长度都放入msgbuf中,前面加上24bit offset,最后组装为一个msg发送出去。
搞清楚了i2c读写时序,针对不同芯片只需要根据datasheet时序关系进行代码修改即可,dbf芯片读写时序如下
DBF芯片也支持7地址和10地址操作,显然这里选择7地址改动最小。和1848相比,这里的读操作是先8bit地址,然后8bit要读的数据长度,再8bit offset。通常要读的数据为32bit,所以NUM这里设为固定值0x04,代码改动如下:
要调整的地方就是msgbuf大小变为16bit,内容调整,msg[0]的len也设为2.
写操作也类似调整,代码如下:
Ti 226芯片也根据datasheet修改即可,这里不加赘述。
将DBF驱动代码和226驱动代码编译进内核即可,这里图省事直接obj-y,dbf驱动名称忘了改,沿用1848了。
代码分别如下
- /*
- * CPS1848 bus driver
- *
- * Copyright (C) 2014 CGT Corp.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
- #define DEBUG
-
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/slab.h>
- #include <linux/i2c.h>
- #include <linux/mutex.h>
- #include <linux/delay.h>
-
- #include <linux/serial_core.h>
-
- /* Each client has this additional data */
- #define USER_EEPROM_SIZE 0xFFFF48
- #define USER_XFER_MAX_COUNT 0x8
-
- /* Addresses to scan */
- static const unsigned short cps1848_i2c[] = { 0x3, I2C_CLIENT_END };
-
- static unsigned read_timeout = 25;
- module_param(read_timeout, uint, 0);
- MODULE_PARM_DESC(read_timeout, "Time (in ms) to try reads (default 25)");
-
- static unsigned write_timeout = 25;
- module_param(write_timeout, uint, 0);
- MODULE_PARM_DESC(write_timeout, "Time (in ms) to try writes (default 25)");
-
- struct cps1848_data {
- struct mutex lock;
- u8 *data;
- };
-
- static ssize_t cps1848_eeprom_read( struct i2c_client *client,
- char *buf, unsigned offset, size_t count)
- {
- struct i2c_msg msg[2];
- u8 msgbuf[4];
- unsigned long timeout, transfer_time;
- int status;
-
- memset(msg, 0, sizeof(msg));
-
- //msgbuf[0] = (u8)((offset >> 18) & 0x3f);
- //msgbuf[1] = (u8)((offset >> 10) & 0xff);
- //msgbuf[2] = (u8)((offset >> 2) & 0xff);
-
- msgbuf[0] = 0x04;
- msgbuf[1] = 0x00;
-
- msg[0].addr = client->addr;
- msg[0].buf = msgbuf;
- msg[0].len = 2;
-
- msg[1].addr = client->addr;
- msg[1].flags = I2C_M_RD;
- msg[1].buf = buf;
- msg[1].len = count;
-
- /*
- * Reads fail if the previous write didn't complete yet. We may
- * loop a few times until this one succeeds, waiting at least
- * long enough for one entire page write to work.
- */
- timeout = jiffies + msecs_to_jiffies(read_timeout);
- do {
- transfer_time = jiffies;
-
- status = i2c_transfer(client->adapter, msg, 2);
-
- if (status == 2)
- status = count;
-
- dev_dbg(&client->dev, "read %ld@0x%lx --> %d (%ld)\n",
- count, (unsigned long)offset, status, jiffies);
-
- if (status == count)
- return count;
-
- /* REVISIT: at HZ=100, this is sloooow */
- msleep(1);
- } while (time_before(transfer_time, timeout));
-
- return -ETIMEDOUT;
-
- }
-
-
- static ssize_t cps1848_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t offset, size_t count)
- {
- struct i2c_client *client = kobj_to_i2c_client(kobj);
- struct cps1848_data *data = i2c_get_clientdata(client);
-
- ssize_t retval = 0;
-
- if (offset > USER_EEPROM_SIZE)
- return 0;
-
- if (offset + count > USER_EEPROM_SIZE)
- count = USER_EEPROM_SIZE - offset;
-
- mutex_lock(&data->lock);
-
- dev_dbg(&client->dev, "cps1848 start read %ld@0x%lx ..\n", count, (unsigned long)offset);
-
- while (count > 0) {
- ssize_t status = count>USER_XFER_MAX_COUNT?USER_XFER_MAX_COUNT:count;
- status = cps1848_eeprom_read(client, buf, offset, status);
- if (status <= 0) {
- if (retval == 0)
- retval = status;
- break;
- }
- buf += status;
- offset += status;
- count -= status;
- retval += status;
- }
-
- dev_dbg(&client->dev, "cps1848 end read %ld@0x%lx !\n", retval, (unsigned long)offset);
-
- mutex_unlock(&data->lock);
-
- return retval;
-
- }
-
- static ssize_t cps1848_eeprom_write(
- struct i2c_client *client,
- struct cps1848_data *data,
- char *buf, unsigned offset, size_t count)
- {
- struct i2c_msg msg[1];
- u8 *msgbuf;
- unsigned long timeout, transfer_time;
- int status;
-
- memset(msg, 0, sizeof(msg));
-
- msgbuf = data->data;
-
- // msgbuf[0] = (u8)((offset >> 18) & 0x3f);
- // msgbuf[1] = (u8)((offset >> 10) & 0xff);
- // msgbuf[2] = (u8)((offset >> 2) & 0xff);
-
- msgbuf[0] = 0x04;
- msgbuf[1] = 0x00;
-
- memcpy(msgbuf+2, buf, count);
-
- msg[0].addr = client->addr;
- msg[0].buf = msgbuf;
- msg[0].len = 2 + count;
-
- /*
- * Reads fail if the previous write didn't complete yet. We may
- * loop a few times until this one succeeds, waiting at least
- * long enough for one entire page write to work.
- */
- timeout = jiffies + msecs_to_jiffies(write_timeout);
- do {
- transfer_time = jiffies;
-
- status = i2c_transfer(client->adapter, msg, 1);
-
- if (status == 1)
- status = count;
-
- dev_dbg(&client->dev, "write %ld@0x%lx --> %d (%ld)\n",
- count, (unsigned long)offset, status, jiffies);
-
- if (status == count)
- return count;
-
- /* REVISIT: at HZ=100, this is sloooow */
- msleep(1);
- } while (time_before(transfer_time, timeout));
-
- return -ETIMEDOUT;
- }
-
- static ssize_t cps1848_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t offset, size_t count)
- {
- struct i2c_client *client = kobj_to_i2c_client(kobj);
- struct cps1848_data *data = i2c_get_clientdata(client);
-
- ssize_t retval = 0;
-
- if (offset > USER_EEPROM_SIZE)
- return 0;
-
- if (offset + count > USER_EEPROM_SIZE)
- count = USER_EEPROM_SIZE - offset;
-
- mutex_lock(&data->lock);
-
- dev_dbg(&client->dev, "cps1848 start write %ld@0x%lx ..\n", count, (unsigned long)offset);
-
- while (count > 0) {
- ssize_t status = count>USER_XFER_MAX_COUNT?USER_XFER_MAX_COUNT:count;
- status = cps1848_eeprom_write(client, data, buf, offset, status);
- if (status <= 0) {
- if (retval == 0)
- retval = status;
- break;
- }
- buf += status;
- offset += status;
- count -= status;
- retval += status;
- }
-
- dev_dbg(&client->dev, "cps1848 end write %ld@0x%lx !\n", retval, (unsigned long)offset);
-
- mutex_unlock(&data->lock);
-
- return retval;
-
- }
-
- static struct bin_attribute user_eeprom_attr = {
- .attr = {
- .name = "eeprom",
- .mode = (S_IRUSR | S_IWUSR),
- },
- .size = USER_EEPROM_SIZE,
- .read = cps1848_read,
- .write = cps1848_write,
- };
-
- /* Return 0 if detection is successful, -ENODEV otherwise */
- static int cps1848_detect(struct i2c_client *client, struct i2c_board_info *info)
- {
- struct i2c_adapter *adapter = client->adapter;
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
- dev_dbg(&client->dev, "cps1848 detect error for BYTE access !\n");
- return -ENODEV;
- }
-
- strlcpy(info->type, "eeprom", I2C_NAME_SIZE);
-
- return 0;
- }
-
- static int cps1848_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
- {
- struct i2c_adapter *adapter = client->adapter;
- struct cps1848_data *data;
- int err ;
-
- dev_notice(&client->dev, "CPS1848 driver\n" );
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
- dev_err(&client->dev, "CPS1848 driver: BYTE DATA not supported! \n" );
- return -ENODEV;
- }
-
- if (!(data = kzalloc(sizeof(struct cps1848_data), GFP_KERNEL))) {
- dev_err(&client->dev, "CPS1848 driver: Memory alloc error ! \n" );
- return -ENOMEM;
- }
-
- /* alloc buffer */
- data->data = devm_kzalloc(&client->dev, USER_XFER_MAX_COUNT + 8, GFP_KERNEL);
- if (!data->data) {
- dev_err(&client->dev, "CPS1848 driver: Memory alloc error ! \n" );
- err = -ENOMEM;
- goto exit_kfree;
- }
-
- /* Init real i2c_client */
- i2c_set_clientdata(client, data);
- mutex_init(&data->lock);
-
- err = sysfs_create_bin_file(&client->dev.kobj, &user_eeprom_attr);
- if (err) {
- dev_err(&client->dev, "CPS1848 driver: sysfs create error ! \n" );
- goto exit_kfree;
- }
-
- return 0;
-
- exit_kfree:
- if(data->data)
- kfree(data->data);
- kfree(data);
- return err;
- }
-
- static int cps1848_remove(struct i2c_client *client)
- {
- struct cps1848_data *data = i2c_get_clientdata(client);
-
- sysfs_remove_bin_file(&client->dev.kobj, &user_eeprom_attr);
- if(data->data)
- kfree(data->data);
- kfree(data);
-
- return 0;
- }
-
- static const struct i2c_device_id cps1848_id[] = {
- { "cps1848", 0 },
- { }
- };
- MODULE_DEVICE_TABLE(i2c, cps1848_id);
-
- static struct i2c_driver cps1848_driver = {
- .driver = {
- .name = "cps1848",
- },
- .probe = cps1848_probe,
- .remove = cps1848_remove,
- .id_table = cps1848_id,
-
- .class = I2C_CLASS_SPD,
- .detect = cps1848_detect,
- .address_list = cps1848_i2c,
- };
-
- module_i2c_driver(cps1848_driver);
-
- MODULE_AUTHOR("RobinLee");
- MODULE_DESCRIPTION("CPS1848 driver");
- MODULE_LICENSE("GPL");

- /*
- * cps226 bus driver
- *
- * Copyright (C) 2014 CGT Corp.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
- #define DEBUG
-
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/slab.h>
- #include <linux/i2c.h>
- #include <linux/mutex.h>
- #include <linux/delay.h>
-
- #include <linux/serial_core.h>
-
- /* Each client has this additional data */
- #define USER_EEPROM_SIZE 0xFFFF48
- #define USER_XFER_MAX_COUNT 0x8
-
- /* Addresses to scan */
- static const unsigned short cps226_i2c[] = { 0x3, I2C_CLIENT_END };
-
- static unsigned read_timeout = 25;
- module_param(read_timeout, uint, 0);
- MODULE_PARM_DESC(read_timeout, "Time (in ms) to try reads (default 25)");
-
- static unsigned write_timeout = 25;
- module_param(write_timeout, uint, 0);
- MODULE_PARM_DESC(write_timeout, "Time (in ms) to try writes (default 25)");
-
- struct cps226_data {
- struct mutex lock;
- u8 *data;
- };
-
- static ssize_t cps226_eeprom_read( struct i2c_client *client,
- char *buf, unsigned offset, size_t count)
- {
- struct i2c_msg msg[2];
- u8 msgbuf[4];
- unsigned long timeout, transfer_time;
- int status;
-
- memset(msg, 0, sizeof(msg));
-
- msgbuf[0] = (u8)(offset & 0xff);
-
-
- msg[0].addr = client->addr;
- msg[0].buf = msgbuf;
- msg[0].len = 1;
-
- msg[1].addr = client->addr;
- msg[1].flags = I2C_M_RD;
- msg[1].buf = buf;
- msg[1].len = count;
-
- /*
- * Reads fail if the previous write didn't complete yet. We may
- * loop a few times until this one succeeds, waiting at least
- * long enough for one entire page write to work.
- */
- timeout = jiffies + msecs_to_jiffies(read_timeout);
- do {
- transfer_time = jiffies;
-
- status = i2c_transfer(client->adapter, msg, 2);
-
- if (status == 2)
- status = count;
-
- dev_dbg(&client->dev, "read %ld@0x%lx --> %d (%ld)\n",
- count, (unsigned long)offset, status, jiffies);
-
- if (status == count)
- return count;
-
- /* REVISIT: at HZ=100, this is sloooow */
- msleep(1);
- } while (time_before(transfer_time, timeout));
-
- return -ETIMEDOUT;
-
- }
-
-
- static ssize_t cps226_read(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t offset, size_t count)
- {
- struct i2c_client *client = kobj_to_i2c_client(kobj);
- struct cps226_data *data = i2c_get_clientdata(client);
-
- ssize_t retval = 0;
-
- if (offset > USER_EEPROM_SIZE)
- return 0;
-
- if (offset + count > USER_EEPROM_SIZE)
- count = USER_EEPROM_SIZE - offset;
-
- mutex_lock(&data->lock);
-
- dev_dbg(&client->dev, "cps226 start read %ld@0x%lx ..\n", count, (unsigned long)offset);
-
- while (count > 0) {
- ssize_t status = count>USER_XFER_MAX_COUNT?USER_XFER_MAX_COUNT:count;
- status = cps226_eeprom_read(client, buf, offset, status);
- if (status <= 0) {
- if (retval == 0)
- retval = status;
- break;
- }
- buf += status;
- offset += status;
- count -= status;
- retval += status;
- }
-
- dev_dbg(&client->dev, "cps226 end read %ld@0x%lx !\n", retval, (unsigned long)offset);
-
- mutex_unlock(&data->lock);
-
- return retval;
-
- }
-
- static ssize_t cps226_eeprom_write(
- struct i2c_client *client,
- struct cps226_data *data,
- char *buf, unsigned offset, size_t count)
- {
- struct i2c_msg msg[1];
- u8 *msgbuf;
- unsigned long timeout, transfer_time;
- int status;
-
- memset(msg, 0, sizeof(msg));
-
- msgbuf = data->data;
-
- // msgbuf[0] = (u8)((offset >> 18) & 0x3f);
- // msgbuf[1] = (u8)((offset >> 10) & 0xff);
- // msgbuf[2] = (u8)((offset >> 2) & 0xff);
-
- msgbuf[0] = (u8)(offset & 0xff);
-
- memcpy(msgbuf+1, buf, count);
-
- msg[0].addr = client->addr;
- msg[0].buf = msgbuf;
- msg[0].len = 1 + count;
-
- /*
- * Reads fail if the previous write didn't complete yet. We may
- * loop a few times until this one succeeds, waiting at least
- * long enough for one entire page write to work.
- */
- timeout = jiffies + msecs_to_jiffies(write_timeout);
- do {
- transfer_time = jiffies;
-
- status = i2c_transfer(client->adapter, msg, 1);
-
- if (status == 1)
- status = count;
-
- dev_dbg(&client->dev, "write %ld@0x%lx --> %d (%ld)\n",
- count, (unsigned long)offset, status, jiffies);
-
- if (status == count)
- return count;
-
- /* REVISIT: at HZ=100, this is sloooow */
- msleep(1);
- } while (time_before(transfer_time, timeout));
-
- return -ETIMEDOUT;
- }
-
- static ssize_t cps226_write(struct file *filp, struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t offset, size_t count)
- {
- struct i2c_client *client = kobj_to_i2c_client(kobj);
- struct cps226_data *data = i2c_get_clientdata(client);
-
- ssize_t retval = 0;
-
- if (offset > USER_EEPROM_SIZE)
- return 0;
-
- if (offset + count > USER_EEPROM_SIZE)
- count = USER_EEPROM_SIZE - offset;
-
- mutex_lock(&data->lock);
-
- dev_dbg(&client->dev, "cps226 start write %ld@0x%lx ..\n", count, (unsigned long)offset);
-
- while (count > 0) {
- ssize_t status = count>USER_XFER_MAX_COUNT?USER_XFER_MAX_COUNT:count;
- status = cps226_eeprom_write(client, data, buf, offset, status);
- if (status <= 0) {
- if (retval == 0)
- retval = status;
- break;
- }
- buf += status;
- offset += status;
- count -= status;
- retval += status;
- }
-
- dev_dbg(&client->dev, "cps226 end write %ld@0x%lx !\n", retval, (unsigned long)offset);
-
- mutex_unlock(&data->lock);
-
- return retval;
-
- }
-
- static struct bin_attribute user_eeprom_attr = {
- .attr = {
- .name = "eeprom",
- .mode = (S_IRUSR | S_IWUSR),
- },
- .size = USER_EEPROM_SIZE,
- .read = cps226_read,
- .write = cps226_write,
- };
-
- /* Return 0 if detection is successful, -ENODEV otherwise */
- static int cps226_detect(struct i2c_client *client, struct i2c_board_info *info)
- {
- struct i2c_adapter *adapter = client->adapter;
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
- dev_dbg(&client->dev, "cps226 detect error for BYTE access !\n");
- return -ENODEV;
- }
-
- strlcpy(info->type, "eeprom", I2C_NAME_SIZE);
-
- return 0;
- }
-
- static int cps226_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
- {
- struct i2c_adapter *adapter = client->adapter;
- struct cps226_data *data;
- int err ;
-
- dev_notice(&client->dev, "cps226 driver\n" );
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
- dev_err(&client->dev, "cps226 driver: BYTE DATA not supported! \n" );
- return -ENODEV;
- }
-
- if (!(data = kzalloc(sizeof(struct cps226_data), GFP_KERNEL))) {
- dev_err(&client->dev, "cps226 driver: Memory alloc error ! \n" );
- return -ENOMEM;
- }
-
- /* alloc buffer */
- data->data = devm_kzalloc(&client->dev, USER_XFER_MAX_COUNT + 8, GFP_KERNEL);
- if (!data->data) {
- dev_err(&client->dev, "cps226 driver: Memory alloc error ! \n" );
- err = -ENOMEM;
- goto exit_kfree;
- }
-
- /* Init real i2c_client */
- i2c_set_clientdata(client, data);
- mutex_init(&data->lock);
-
- err = sysfs_create_bin_file(&client->dev.kobj, &user_eeprom_attr);
- if (err) {
- dev_err(&client->dev, "cps226 driver: sysfs create error ! \n" );
- goto exit_kfree;
- }
-
- return 0;
-
- exit_kfree:
- if(data->data)
- kfree(data->data);
- kfree(data);
- return err;
- }
-
- static int cps226_remove(struct i2c_client *client)
- {
- struct cps226_data *data = i2c_get_clientdata(client);
-
- sysfs_remove_bin_file(&client->dev.kobj, &user_eeprom_attr);
- if(data->data)
- kfree(data->data);
- kfree(data);
-
- return 0;
- }
-
- static const struct i2c_device_id cps226_id[] = {
- { "cps226", 0 },
- { }
- };
- MODULE_DEVICE_TABLE(i2c, cps226_id);
-
- static struct i2c_driver cps226_driver = {
- .driver = {
- .name = "cps226",
- },
- .probe = cps226_probe,
- .remove = cps226_remove,
- .id_table = cps226_id,
-
- .class = I2C_CLASS_SPD,
- .detect = cps226_detect,
- .address_list = cps226_i2c,
- };
-
- module_i2c_driver(cps226_driver);
-
- MODULE_AUTHOR("RobinLee");
- MODULE_DESCRIPTION("cps226 driver");
- MODULE_LICENSE("GPL");

devicetree中需要配置四个从设备的地址,如下,dbf名称懒得改了:
/dts-v1/; / { #address-cells = <0x1>; #size-cells = <0x1>; compatible = "xlnx,zynq-7000"; cpus { #address-cells = <0x1>; #size-cells = <0x0>; cpu@0 { compatible = "arm,cortex-a9"; device_type = "cpu"; reg = <0x0>; clocks = <0x1 0x3>; clock-latency = <0x3e8>; cpu0-supply = <0x2>; operating-points = <0xa4cb8 0xf4240 0x5265c 0xf4240>; }; cpu@1 { compatible = "arm,cortex-a9"; device_type = "cpu"; reg = <0x1>; clocks = <0x1 0x3>; }; }; fpga-full { compatible = "fpga-region"; fpga-mgr = <0x3>; #address-cells = <0x1>; #size-cells = <0x1>; ranges; }; pmu@f8891000 { compatible = "arm,cortex-a9-pmu"; interrupts = <0x0 0x5 0x4 0x0 0x6 0x4>; interrupt-parent = <0x4>; reg = <0xf8891000 0x1000 0xf8893000 0x1000>; }; fixedregulator { compatible = "regulator-fixed"; regulator-name = "VCCPINT"; regulator-min-microvolt = <0xf4240>; regulator-max-microvolt = <0xf4240>; regulator-boot-on; regulator-always-on; linux,phandle = <0x2>; phandle = <0x2>; }; amba { u-boot,dm-pre-reloc; compatible = "simple-bus"; #address-cells = <0x1>; #size-cells = <0x1>; interrupt-parent = <0x4>; ranges; adc@f8007100 { compatible = "xlnx,zynq-xadc-1.00.a"; reg = <0xf8007100 0x20>; interrupts = <0x0 0x7 0x4>; interrupt-parent = <0x4>; clocks = <0x1 0xc>; xlnx,channels { #address-cells = <1>; #size-cells = <0>; channel@0 { reg = <0>; }; channel@1 { reg = <1>; }; channel@2 { reg = <2>; }; channel@3 { reg = <3>; }; channel@4{ reg = <4>; }; channel@5{ reg = <5>; }; channel@6{ reg = <6>; }; channel@7{ reg = <7>; }; channel@8 { reg = <8>; }; channel@9 { reg = <9>; }; channel@a { reg = <0xa>; }; channel@b { reg = <0xb>; }; channel@c { reg = <0xc>; }; channel@d { reg = <0xd>; }; channel@e { reg = <0xe>; }; channel@f { reg = <0xf>; }; channel@10 { reg = <0x10>; }; }; }; gpio@e000a000 { compatible = "xlnx,zynq-gpio-1.0"; #gpio-cells = <0x2>; clocks = <0x1 0x2a>; gpio-controller; interrupt-controller; #interrupt-cells = <0x2>; interrupt-parent = <0x4>; interrupts = <0x0 0x14 0x4>; reg = <0xe000a000 0x1000>; }; i2c@e0004000 { compatible = "cdns,i2c-r1p10"; status = "okay"; clocks = <0x1 0x26>; interrupt-parent = <0x4>; interrupts = <0x0 0x19 0x4>; reg = <0xe0004000 0x1000>; #address-cells = <0x1>; #size-cells = <0x0>; clock-frequency = <0x61a80>; cps1848@2 { compatible = "cps1848"; reg = <0x2>; }; cps1848@4 { compatible = "cps1848"; reg = <0x4>; }; cps1848@8 { compatible = "cps1848"; reg = <0x8>; }; cps226@40 { compatible = "cps226"; reg = <0x40>; }; }; i2c@e0005000 { compatible = "cdns,i2c-r1p10"; status = "okay"; clocks = <0x1 0x27>; interrupt-parent = <0x4>; interrupts = <0x0 0x30 0x4>; reg = <0xe0005000 0x1000>; #address-cells = <0x1>; #size-cells = <0x0>; clock-frequency = <0x61a80>; }; interrupt-controller@f8f01000 { compatible = "arm,cortex-a9-gic"; #interrupt-cells = <0x3>; interrupt-controller; reg = <0xf8f01000 0x1000 0xf8f00100 0x100>; num_cpus = <0x2>; num_interrupts = <0x60>; linux,phandle = <0x4>; phandle = <0x4>; }; cache-controller@f8f02000 { compatible = "arm,pl310-cache"; reg = <0xf8f02000 0x1000>; interrupts = <0x0 0x2 0x4>; arm,data-latency = <0x3 0x2 0x2>; arm,tag-latency = <0x2 0x2 0x2>; cache-unified; cache-level = <0x2>; }; memory-controller@f8006000 { compatible = "xlnx,zynq-ddrc-a05"; reg = <0xf8006000 0x1000>; }; ocmc@f800c000 { compatible = "xlnx,zynq-ocmc-1.0"; interrupt-parent = <0x4>; interrupts = <0x0 0x3 0x4>; reg = <0xf800c000 0x1000>; }; serial@e0000000 { compatible = "xlnx,xuartps", "cdns,uart-r1p8"; status = "okay"; clocks = <0x1 0x17 0x1 0x28>; clock-names = "uart_clk", "pclk"; reg = <0xe0000000 0x1000>; interrupts = <0x0 0x1b 0x4>; device_type = "serial"; port-number = <0x0>; }; spi@e0006000 { compatible = "xlnx,zynq-spi-r1p6"; reg = <0xe0006000 0x1000>; status = "okay"; interrupt-parent = <0x4>; interrupts = <0x0 0x1a 0x4>; clocks = <0x1 0x19 0x1 0x22>; clock-names = "ref_clk", "pclk"; #address-cells = <0x1>; #size-cells = <0x0>; is-decoded-cs = <0x0>; num-cs = <0x3>; }; spi@e0007000 { compatible = "xlnx,zynq-spi-r1p6"; reg = <0xe0007000 0x1000>; status = "okay"; interrupt-parent = <0x4>; interrupts = <0x0 0x31 0x4>; clocks = <0x1 0x1a 0x1 0x23>; clock-names = "ref_clk", "pclk"; #address-cells = <0x1>; #size-cells = <0x0>; is-decoded-cs = <0x0>; num-cs = <0x3>; flash@0 { compatible = "micron,n25q128a11","jedec,spi-nor"; reg = <0x1>; spi-max-frequency = <0x9EF21B0>; spi-tx-bus-width = <0x1>; spi-rx-bus-width = <0x1>; #address-cells = <0x1>; #size-cells = <0x1>; partition@dbf { label = "spi-flash"; reg = <0x0 0x1000000>; }; }; }; spi@e000d000 { clock-names = "ref_clk", "pclk"; clocks = <0x1 0xa 0x1 0x2b>; compatible = "xlnx,zynq-qspi-1.0"; status = "okay"; interrupt-parent = <0x4>; interrupts = <0x0 0x13 0x4>; reg = <0xe000d000 0x1000>; #address-cells = <0x1>; #size-cells = <0x0>; is-dual = <0x1>; num-cs = <0x1>; }; ethernet@e000b000 { compatible = "xlnx,ps7-ethernet-1.00.a"; reg = <0xe000b000 0x1000>; status = "okay"; interrupt-parent = <0x3>; interrupts = <0x0 0x16 0x4>; clocks = <0x1 0xd 0x1 0x1e>; clock-names = "ref_clk", "aper_clk"; #address-cells = <0x1>; #size-cells = <0x0>; enet-reset = <0x4 0x2f 0x0>; local-mac-address = [00 0a 35 00 00 00]; phy-mode = "rgmii"; phy-handle = <0x5>; xlnx,eth-mode = <0x1>; xlnx,has-mdio = <0x1>; xlnx,ptp-enet-clock = <0x69f6bcb>; mdio { #address-cells = <0x1>; #size-cells = <0x0>; phy@0 { compatible = "marvell,88e1111"; device_type = "ethernet-phy"; reg = <0x4>; linux,phandle = <0x7>; phandle = <0x7>; }; }; }; slcr@f8000000 { #address-cells = <0x1>; #size-cells = <0x1>; compatible = "xlnx,zynq-slcr", "syscon", "simple-mfd"; reg = <0xf8000000 0x1000>; ranges; linux,phandle = <0x5>; phandle = <0x5>; clkc@100 { #clock-cells = <0x1>; compatible = "xlnx,ps7-clkc"; fclk-enable = <0x1>; clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x", "cpu_3or2x", "cpu_2x", "cpu_1x", "ddr2x", "ddr3x", "dci", "lqspi", "smc", "pcap", "gem0", "gem1", "fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1", "sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1", "dma", "usb0_aper", "usb1_aper", "gem0_aper", "gem1_aper", "sdio0_aper", "sdio1_aper", "spi0_aper", "spi1_aper", "can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper", "uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper", "smc_aper", "swdt", "dbg_trc", "dbg_apb"; reg = <0x100 0x100>; ps-clk-frequency = <0x2faf080>; linux,phandle = <0x1>; phandle = <0x1>; }; rstc@200 { compatible = "xlnx,zynq-reset"; reg = <0x200 0x48>; #reset-cells = <0x1>; syscon = <0x5>; }; pinctrl@700 { compatible = "xlnx,pinctrl-zynq"; reg = <0x700 0x200>; syscon = <0x5>; }; }; dmac@f8003000 { compatible = "arm,pl330", "arm,primecell"; reg = <0xf8003000 0x1000>; interrupt-parent = <0x4>; interrupt-names = "abort", "dma0", "dma1", "dma2", "dma3", "dma4", "dma5", "dma6", "dma7"; interrupts = <0x0 0xd 0x4 0x0 0xe 0x4 0x0 0xf 0x4 0x0 0x10 0x4 0x0 0x11 0x4 0x0 0x28 0x4 0x0 0x29 0x4 0x0 0x2a 0x4 0x0 0x2b 0x4>; #dma-cells = <0x1>; #dma-channels = <0x8>; #dma-requests = <0x4>; clocks = <0x1 0x1b>; clock-names = "apb_pclk"; }; devcfg@f8007000 { compatible = "xlnx,zynq-devcfg-1.0"; interrupt-parent = <0x4>; interrupts = <0x0 0x8 0x4>; reg = <0xf8007000 0x100>; clocks = <0x1 0xc 0x1 0xf 0x1 0x10 0x1 0x11 0x1 0x12>; clock-names = "ref_clk", "fclk0", "fclk1", "fclk2", "fclk3"; syscon = <0x5>; linux,phandle = <0x3>; phandle = <0x3>; }; efuse@f800d000 { compatible = "xlnx,zynq-efuse"; reg = <0xf800d000 0x20>; }; timer@f8f00200 { compatible = "arm,cortex-a9-global-timer"; reg = <0xf8f00200 0x20>; interrupts = <0x1 0xb 0x301>; interrupt-parent = <0x4>; clocks = <0x1 0x4>; }; timer@f8001000 { interrupt-parent = <0x4>; interrupts = <0x0 0xa 0x4 0x0 0xb 0x4 0x0 0xc 0x4>; compatible = "cdns,ttc"; clocks = <0x1 0x6>; reg = <0xf8001000 0x1000>; }; timer@f8002000 { interrupt-parent = <0x4>; interrupts = <0x0 0x25 0x4 0x0 0x26 0x4 0x0 0x27 0x4>; compatible = "cdns,ttc"; clocks = <0x1 0x6>; reg = <0xf8002000 0x1000>; }; timer@f8f00600 { interrupt-parent = <0x4>; interrupts = <0x1 0xd 0x301>; compatible = "arm,cortex-a9-twd-timer"; reg = <0xf8f00600 0x20>; clocks = <0x1 0x4>; }; watchdog@f8005000 { clocks = <0x1 0x2d>; compatible = "cdns,wdt-r1p2"; interrupt-parent = <0x4>; interrupts = <0x0 0x9 0x1>; reg = <0xf8005000 0x1000>; timeout-sec = <0xa>; }; }; chosen { bootargs = "earlycon"; stdout-path = "serial0:115200n8"; }; aliases { ethernet0 = "/amba/ethernet@e000b000"; serial0 = "/amba/serial@e0000000"; spi0 = "/amba/spi@e000d000"; spi1 = "/amba/spi@e0006000"; spi2 = "/amba/spi@e0007000"; }; memory { device_type = "memory"; reg = <0x0 0x40000000>; }; };
应用可以参考1848那样提供读写寄存器接口函数,这里要注意数据高低位转换问题,是否需要使用htonl函数,不同的芯片要求不一样。
DBF芯片代码如下:
- /*
- * cps1848.h
- *
- * Created on: 2018年9月8日
- * Author: Administrator
- */
-
- #ifndef SRC_CPS1848_H_
- #define SRC_CPS1848_H_
-
- int Init_1848();
- unsigned int get_1848_reg(int num,unsigned int offset);
- void set_1848_reg(int num,unsigned int offset, unsigned int data);
-
-
- #endif /* SRC_CPS1848_H_ */

- /*
- * Copyright (c) 2016 CGT Co., Ltd.
- *
- * Authors: Robin Lee <lixiangbin@china-dsp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program;
- *
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdarg.h>
- #include <string.h>
- #include <memory.h>
-
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/ioctl.h>
- #include <sys/poll.h>
- #include <sys/time.h>
- #include <sys/socket.h>
-
- #include <fcntl.h>
- #include <errno.h>
- #include <pthread.h>
- #include <math.h>
- #include <unistd.h>
- #include <signal.h>
-
- #include <termios.h>
- #include <netinet/in.h>
-
- #include "cps1848.h"
-
- /*---------------------------------------------------------------------------------------------------------------------------------------------------
- * global vars
- */
- #define FP_DEV_1 "/sys/class/i2c-dev/i2c-0/device/0-0002/eeprom"
- #define FP_DEV_2 "/sys/class/i2c-dev/i2c-0/device/0-0004/eeprom"
- #define FP_DEV_3 "/sys/class/i2c-dev/i2c-0/device/0-0008/eeprom"
-
- static int global_fd_1 = -1;
- static int global_fd_2 = -1;
- static int global_fd_3 = -1;
-
- //operations of cps1848
- int fd_initial(int num)
- {
-
- int fd = -1;
-
- /*
- Open modem device for reading and writing and not as controlling tty
- because we don't want to get killed if linenoise sends CTRL-C.
- */
- if(num==0)
- {
- printf("Open '%s' .. ", FP_DEV_1);
- fd = open(FP_DEV_1, O_RDWR );
- }
- else if(num==1)
- {
- printf("Open '%s' .. ", FP_DEV_2);
- fd = open(FP_DEV_2, O_RDWR );
- }
- else if(num==2)
- {
- printf("Open '%s' .. ", FP_DEV_3);
- fd = open(FP_DEV_3, O_RDWR );
- }
- else
- {
- printf("Open error.\n");
- return -1;
- }
-
- if (fd <0) {
- printf("failed (err = %d)\n", fd);
- return -1;
- }
-
- printf("Done\n");
-
- return fd;
- }
-
- int fd_exit(int fd,int num)
- {
- if(num==1)
- {
- printf("Close '%s' .. ", FP_DEV_1);
- }
- else if(num==2)
- {
- printf("Close '%s' .. ", FP_DEV_2);
- }
- else
- {
- printf("Close '%s' .. ", FP_DEV_3);
- }
- close(fd);
-
- printf("Done\n");
-
- return 0;
- }
-
- /*---------------------------------------------------------------------------------------------------------------------------------------------------
- * get_1848_reg, set_1848_reg
- */
- unsigned int get_1848_reg(int num,unsigned int offset)
- {
- unsigned int value = 0xffff;
- unsigned int ans=0;
- int fd=-1;
- if(num==0)
- {
- fd=global_fd_1;
- }
- else if(num==1)
- {
- fd=global_fd_2;
- }
- else if( num==2 )
- {
- fd=global_fd_3;
- }
- else
- {
- printf("get_dbf_reg::Invalid param !\n");
- return 0;
- }
-
- if (fd<0) {
- printf("Invalid device handle !\n");
- return value;
- }
-
- if( lseek(fd, offset, SEEK_SET) == (off_t) -1 ) {
- printf("failed for seek to offset 0x%x !\n", offset);
- return value;
- }
-
- if ( read(fd, &value, sizeof(value)) != sizeof(value)) {
- printf("failed for read from offset 0x%x !\n", offset);
- return value;
- }
- //ans=htonl(value);
- return value;
- }
-
- void set_1848_reg(int num,unsigned int offset, unsigned int data)
- {
- unsigned int value = data;
- int fd=-1;
- if(num==0)
- {
- fd=global_fd_1;
- }
- else if(num==1)
- {
- fd=global_fd_2;
- }
- else if( num==2 )
- {
- fd=global_fd_3;
- }
- else
- {
- printf("set_dbf_reg::Invalid param !\n");
- return;
- }
- if (fd<0) {
- printf("Invalid device handle !\n");
- return ;
- }
-
- if( lseek(fd, offset, SEEK_SET) == (off_t) -1 ) {
- printf("failed for seek to offset 0x%x !\n", offset);
- return ;
- }
-
- if ( write(fd, &value, sizeof(value)) != sizeof(value)) {
- // printf("failed for write from offset 0x%x !\n", offset);
- return ;
- }
- return ;
- }
-
- unsigned int regtoul(const char *str)
- {
- int cbase = 10;
- if(str[0]=='0'&&(str[1]=='x'||str[1]=='X')) {
- cbase = 16;
- }
- return strtoul(str, NULL, cbase);
- }
-
- int Init_1848()
- {
- global_fd_1 = fd_initial(0);
- global_fd_2 = fd_initial(1);
- global_fd_3 = fd_initial(2);
- if (global_fd_1<0) {
- printf("\n Invalid First dbf device ! \n");
- return -1;
- }
- if (global_fd_2<0) {
- printf("\n Invalid Second dbf device ! \n");
- return -1;
- }
- if (global_fd_3<0) {
- printf("\n Invalid Third dbf device ! \n");
- return -1;
- }
- return 0;
- }
-
-

Ti 226芯片读写接口如下
- /*
- * cps1848.h
- *
- * Created on: 2018年9月8日
- * Author: Administrator
- */
-
- #ifndef SRC_CPS226_H_
- #define SRC_CPS226_H_
-
- int Init_226();
- unsigned int get_226_reg(unsigned int offset);
- void set_226_reg(unsigned int offset, unsigned int data);
-
-
- #endif /* SRC_CPS1848_H_ */

- /*
- * Copyright (c) 2016 CGT Co., Ltd.
- *
- * Authors: Robin Lee <lixiangbin@china-dsp.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program;
- *
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdarg.h>
- #include <string.h>
- #include <memory.h>
-
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/ioctl.h>
- #include <sys/poll.h>
- #include <sys/time.h>
- #include <sys/socket.h>
-
- #include <fcntl.h>
- #include <errno.h>
- #include <pthread.h>
- #include <math.h>
- #include <unistd.h>
- #include <signal.h>
-
- #include <termios.h>
- #include <netinet/in.h>
-
- #include "cps226.h"
-
- /*---------------------------------------------------------------------------------------------------------------------------------------------------
- * global vars
- */
- #define FP_DEV "/sys/class/i2c-dev/i2c-0/device/0-0040/eeprom"
-
-
- static int global_fd = -1;
-
- //operations of cps1848
- int fd_initial_226()
- {
- int fd = -1;
- /*
- Open modem device for reading and writing and not as controlling tty
- because we don't want to get killed if linenoise sends CTRL-C.
- */
- printf("Open '%s' .. ", FP_DEV);
- fd = open(FP_DEV, O_RDWR );
-
- if (fd <0) {
- printf("failed (err = %d)\n", fd);
- return -1;
- }
-
- printf("Done\n");
-
- return fd;
- }
-
- int fd_exit_226(int fd)
- {
- close(fd);
- printf("Done\n");
-
- return 0;
- }
-
- /*---------------------------------------------------------------------------------------------------------------------------------------------------
- * get_1848_reg, set_1848_reg
- */
- unsigned int get_226_reg(unsigned int offset)
- {
- unsigned int value = 0xffff;
- unsigned int ans=0;
- int fd=-1;
- fd=global_fd;
-
- if (fd<0) {
- printf("Invalid device handle !\n");
- return value;
- }
-
- if( lseek(fd, offset, SEEK_SET) == (off_t) -1 ) {
- printf("failed for seek to offset 0x%x !\n", offset);
- return value;
- }
-
- if ( read(fd, &value, sizeof(value)) != sizeof(value)) {
- printf("failed for read from offset 0x%x !\n", offset);
- return value;
- }
- ans=htonl(value);
- return ans>>16;
- }
-
- void set_226_reg(unsigned int offset, unsigned int data)
- {
- unsigned int value = data;
- int fd=-1;
- fd=global_fd;
- if (fd<0) {
- printf("Invalid device handle !\n");
- return ;
- }
-
- if( lseek(fd, offset, SEEK_SET) == (off_t) -1 ) {
- printf("failed for seek to offset 0x%x !\n", offset);
- return ;
- }
-
- if ( write(fd, &value, sizeof(value)) != sizeof(value)) {
- // printf("failed for write from offset 0x%x !\n", offset);
- return ;
- }
- return ;
- }
-
- unsigned int regtoul_226(const char *str)
- {
- int cbase = 10;
- if(str[0]=='0'&&(str[1]=='x'||str[1]=='X')) {
- cbase = 16;
- }
- return strtoul(str, NULL, cbase);
- }
-
- int Init_226()
- {
- global_fd = fd_initial_226();
- if (global_fd<0)
- {
- printf("\n Invalid 226 device ! \n");
- return -1;
- }
- return 0;
- }
-
-

Linux启动过程中能看到驱动正确加载,显然设备都找到了。
启动应用后能读出DBF芯片原来的ID,并根据槽位号配置新的ID
代码如下:
- /*
- * config_dbf.c
- *
- * Created on: 2018年8月17日
- * Author: Administrator
- */
-
-
- #include "config_dbf.h"
- #include "gpio.h"
- #include "cps1848.h"
-
- extern unsigned int ga_chass;
-
- int config_dbf_id()
- {
- unsigned int _data;
- u32 chip_id;
-
- printf("Change dbf id start\n");
-
- printf("------------Set DBFA ID Register------------\n");
- _data=get_1848_reg(0,0);
- printf("orignial DBFA ID = 0x%x\n",_data);
-
- chip_id = (ga_chass<<4) | 0x1;
- set_1848_reg(0,0,chip_id);
-
- _data=get_1848_reg(0,0);
- printf("config DBFA ID = 0x%x\n",_data);
-
-
- printf("------------Set DBFB ID Register------------\n");
- _data=get_1848_reg(1,0);
- printf("orignial DBFB ID = 0x%x\n",_data);
-
- chip_id = (ga_chass<<4) | 0x2;
- set_1848_reg(1,0,chip_id);
-
- _data=get_1848_reg(1,0);
- printf("config DBFB ID = 0x%x\n",_data);
-
-
- printf("------------Set DBFC ID Register------------\n");
- _data=get_1848_reg(2,0);
- printf("orignial DBFC ID = 0x%x\n",_data);
-
- chip_id = (ga_chass<<4) | 0x3;
- set_1848_reg(2,0,chip_id);
-
- _data=get_1848_reg(2,0);
- printf("config DBFC ID = 0x%x\n",_data);
-
- return 0;
- }
-
- int read_dbf_id()
- {
- unsigned int _data;
- _data=get_1848_reg(0,0);
- printf("DBFA ID = 0x%x\n",_data);//true data is 1002
-
- _data=get_1848_reg(1,0);
- printf("DBFB ID = 0x%x\n",_data);//true data is 1003
-
- _data=get_1848_reg(2,0);
- printf("DBFC ID = 0x%x\n",_data);//true data is 1004
- return 0;
- }
-
- int change_dbf_uart(int id)
- {
- if(id==0)
- {
- SetGpioReg(GPIO_UAET_SELECT_BASE_ADDR,0x0,0);
- }
- else if(id==1)
- {
- SetGpioReg(GPIO_UAET_SELECT_BASE_ADDR,0x0,1);
- }
- else
- {
- SetGpioReg(GPIO_UAET_SELECT_BASE_ADDR,0x0,2);
- }
- return 0;
- }
-
- #if 0
- int bit_226()
- {
- unsigned int val32;
- unsigned short val16;
- unsigned int _data;
- float TempData;
- int Status;
-
- int ret=0;
-
- ret=IICRead_Reg(IIC_SLAVE_ADDR_226,0x05,&_data);
- if(ret<0)
- {
- goto error;
- }
- ret=IICWrite_Reg(IIC_SLAVE_ADDR_226,0x05,0x1400);
- if(ret<0)
- {
- goto error;
- }
- ret=IICRead_Reg(IIC_SLAVE_ADDR_226,0x05,&_data);
- if(ret<0)
- {
- goto error;
- }
- ret=IICWrite_Reg(IIC_SLAVE_ADDR_226,0x02,0x1400);
- if(ret<0)
- {
- goto error;
- }
- ret=IICRead_Reg(IIC_SLAVE_ADDR_226,0x05,&_data);
- if(ret<0)
- {
- goto error;
- }
- val32=_data;
- val16=(val32)&0xFFFF;
-
- ret=IICRead_Reg(IIC_SLAVE_ADDR_226,0x02,&_data);
- if(ret<0)
- {
- goto error;
- }
- val32=_data;
- val16=(val32)&0xFFFF;
- TempData = val16*1.0/1000.0;
- printf("bus voltage is %f V.\n", TempData);
-
- ret=IICRead_Reg(IIC_SLAVE_ADDR_226,0x04,&_data);
- if(ret<0)
- {
- goto error;
- }
-
- val32=_data;
- val16=(val32)&0xFFFF;
- TempData = val16*1.0/1000.0;
- printf("bus current is %f A.\n", TempData);
-
- if(TempData>=15.0)
- {
- printf("-----safe_rst because of Current----\n");
- SetGpioReg(GPIO_DBF_RESET_ADDR,0x0,1);
- SetGpioReg(GPIO_DBF_RESET_ADDR,0x0,0);
- }
-
- ret=IICRead_Reg(IIC_SLAVE_ADDR_226,0x03,&_data);
- if(ret<0)
- {
- goto error;
- }
-
- val32=_data;
- val16=(val32)&0xFFFF;
- TempData = val16*25.0/1000.0;
- printf("power is %f W.\n", TempData);
-
- return 0;
-
- error:
- return -1;
- }
- #endif

Ti 226芯片也能读出功耗了
读功耗代码如下:
- #include <stdio.h>
-
- #include "bit.h"
- #include "config_dbf.h"
- #include "gpio.h"
- #include "cps226.h"
-
- extern unsigned int g_temp[10];
- extern unsigned int g_vcc[9];
- extern unsigned int g_vcc_aux[16];
-
-
- void Show_226_bit()
- {
- unsigned int _data,val32;
- unsigned short val16;
- float temp;
-
- _data=get_226_reg(0x05);
- set_226_reg(0x05,0x14);
- _data=get_226_reg(0x05);
-
- set_226_reg(0x02,0x14);
- val32=get_226_reg(0x05);
- val16=val32&0xffff;
-
-
- val32 = get_226_reg(0x02);
- val16 = (val32)&0xFFFF;
- temp = val16*1.25/1000.0;
- printf("bus voltage is %.3f V. \n",temp);
-
- val32 = get_226_reg(0x04);
- val16 = (val32)&0xFFFF;
-
- temp = val16*1.0/1000.0;
- printf("Current is %.3f A. \n", temp);
-
- if(temp>=15)
- {
- printf("Warning!!! DBF Current Amp Alarm! Reset DBF NOW!!!\n");
- SetGpioReg(GPIO_DBF_RESET_ADDR,0,0x1);
- SetGpioReg(GPIO_DBF_RESET_ADDR,0,0x0);
- }
-
- val32 = get_226_reg(0x03);
- val16 = (val32)&0xFFFF ;
- temp = val16*25.0/1000.0;
- printf("Power is %.3f W. \r\n", temp);
- }

至此I2C驱动调试结束。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。