I2C采用者永远封锁

⚠️
大家好. .感谢来到论坛。令人兴奋的消息!我们现在正在转移到新的论坛平台的过程中,它将提供更好的功能,并包含在主对话网站。所有的帖子和账号已经迁移。我们现在只接受新论坛的流量-请发布任何新的帖子在//www.xmece.com/support.我们会在接下来的几天修复bug /优化搜索和标记。
7个职位/ 0个新职位
最后发表
UnicycleBloke
离线
最后看到:4个月1个星期前
加入:2015-10-26 13:43
I2C采用者永远封锁

我试图让I2C适配器工作,但由于某种原因,当我调用ad_i2c_write_read()时,它永远阻塞。

对于上下文,我使用适配器的方式如下:
- 有一个任务具有处理I2C事务的唯一功能。
—该任务有一个挂起事务的FreeRTOS队列。
-任务从队列中获取下一个事务(如果为空则阻塞),然后执行
事务同步。
—当事务完成时,任务向事务的发起任务发送一个信号。
- 没有其他任务使用I2C外设。

这种设计非常简单,这意味着所有其他线程都可以使用I2C
阻塞。这与我在其他处理器上实现I2C驱动程序的方式相匹配,并且它能够工作
很好。

这个任务看起来像这样(它是c++类的一部分):

空白I2CMasterDriver: task_func_impl ()

//初始化I2C设备。
ad_i2c_init();

//可能有休息或暂停条件。
而(真实)

//如果队列中没有任何内容,则将阻止。
m_queue.receive (m_trans);

//调用者可以传入一个指向数据缓冲区的指针(对于更大的块)。
//如果为null,则指向我们自己的缓冲区。注意:在这一点上这样做
//因为该结构体是按值复制的,任何其他指针都有可能
//无效。
如果(m_trans。数据= = nullptr)

m_trans。data = &m_trans.buffer [0];

//打开我们想要通话的I2C从设备。这是最奇怪的架构
//我从未见过管理奴隶的人。
i2c_device device = ad_i2c_open(NFC_CHIP);

//这是一个阻塞调用。
Int ret_code = ad_i2c_write_read(
设备,
(m_trans.tx_length> 0)?&m_trans.data [0]:nullptr,
m_trans.tx_length,
(m_trans。Rx_length > 0) ?&m_trans.data [m_trans。tx_length]: nullptr,
m_trans.rx_length,
HW_I2C_F_ADD_STOP);

//我们将返回值-通过调度程序-所以恢复数据指针
//表示我们使用自己的缓冲区或外部缓冲区。
如果(m_trans。数据= = &m_trans.buffer [0])

m_trans。数据= nullptr;

//让客户知道我们都完成了。
m_on_complete.emit (m_trans);

//关闭设备,为下一个事务做准备
ad_i2c_close(设备);

下面几行代码包含在我的配置中:

#define dg_configUSE_HW_I2C (1)
定义dg_configI2C_ADAPTER (1)

peripher_init包含以下几行:

hw_gpio_configure_pin(HW_GPIO_PORT_0, HW_GPIO_PIN_0, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_I2C_SCL, true);
hw_gpio_configure_pin(HW_GPIO_PORT_0, HW_GPIO_PIN_1, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_I2C_SDA, true);

以下行包含在platform_devices.h中:

I2C_BUS (I2C1)
I2C_SLAVE_DEVICE_DMA(I2C1, nfc_chip, 0x28, HW_I2C_ADDRESSING_7B, HW_I2C_SPEED_STANDARD, 0)
I2C_BUS_END

此问题是对AD_I2C_WRITE_READ()块的调用,而不是返回。如果我发表评论
排队,以便排队的事务刚刚被抛弃,任务完全按预期工作。
我还遗漏了哪些设置、宏或选项?由于只有一个任务使用I2C,也许我应该使用低级驱动程序……

按照目前的情况,我想我宁愿为它编写自己的裸机驱动程序。有这样的例子吗?

谢谢。

设备:
UnicycleBloke
离线
最后看到:4个月1个星期前
加入:2015-10-26 13:43
看来我需要

似乎我需要在开始事务之前获得总线——这是初始化外围设备本身并启用中断的地方。所以现在不会阻塞了。然而……

电线上什么也没有出来。没有附上设备,但我至少应该看到地址。

谢谢。

UnicycleBloke
离线
最后看到:4个月1个星期前
加入:2015-10-26 13:43
啊!回答了我自己的问题。

啊!回答了我自己的问题。它帮助很多,如果你使引脚输出开放的漏和粘在总线上的设备拉线。

谢谢。

PM_Dialog
离线
最后看到:2周18小时前
工作人员
加入:2018-02-08 11:03
嗨UnicycleBloke,

嗨UnicycleBloke,

我强烈建议您去看看I2C适配器概念(HTML)从DA14680的支持页面。本教程解释了I2C适配器以及如何将DA1468x配置为I2C主设备。适配器未实现为单独的任务,并且应视为应用程序和LLD之间的附加层。建议使用适配器来访问硬件块。

谢谢,PM_Dialog

UnicycleBloke
离线
最后看到:4个月1个星期前
加入:2015-10-26 13:43
谢谢,但我已经

谢谢,但我已经完成了所有这些。我理解I2C适配器概念。不幸的是,我认为设计是理想的。这就是为什么我创建了一个线程到序列式调用的线程,而不停止应用程序中的任何其他线程。它现在运作得很好,并且更适合我的活动驱动应用程序框架。

我还有一个后续问题:如果我使用两个I2C外围设备,适配器似乎会阻止它们上的并发事务。这是真的吗?

谢谢。

PM_Dialog
离线
最后看到:2周18小时前
工作人员
加入:2018-02-08 11:03
嗨UnicycleBloke,

嗨UnicycleBloke,

是的,这是真的!适配器将阻止它们上的并发事务。

谢谢,PM_Dialog

UnicycleBloke
离线
最后看到:4个月1个星期前
加入:2015-10-26 13:43
嗯。谢谢你让我来

嗯。谢谢你告诉我。在我看来,这是一个相当糟糕的设计。