我正在尝试获得I2C适配器工作,但由于某种原因,当我调用AD_I2C_WRITE_READ()时它是永恒阻止的。
对于上下文,我以以下方式使用适配器:
- 有一个任务具有处理I2C事务的唯一功能。
- 任务有一个待处理事务的Freertos队列。
- 任务从队列中获取下一个事务(如果为空的块),然后执行
同步交易。
- 当交易完成后,任务向交易的始发任务发送信号。
- 没有其他任务使用I2C外设。
这种设计很简单,意味着所有其他线程都可以使用I2C
阻止。这与我在其他处理器上实现了I2C驱动程序的方式匹配,它有效
很好。
任务看起来像这样(它是C ++类的一部分):
void i2cmasterdriver :: task_func_impl()
{
//初始化I2C设备。
ad_i2c_init();
//可能有休息或暂停条件。
而(真实)
{
//如果队列中没有任何内容,则将阻止。
m_queue.receive(m_trans);
//呼叫者可以将指向数据缓冲区(对于较大的块)传递。
//如果null,我们将此指向自己的缓冲区。注意:此时执行此项
//由于该结构被值复制,并且可能会有任何其他指针
//无效。
if(m_trans.data == 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);
//我们将返回值 - 通过调度程序 - 因此恢复数据指针
//表示我们使用了自己的缓冲区或外部缓冲区。
if(m_trans.data ==&m_trans.buffer [0])
{
m_trans.data = nullptr;
}
//让客户知道我们都完成了。
m_on_complete.emit(m_trans);
//关闭设备以准备下一个事务。
ad_i2c_close(设备);
}
}
我的配置中包含以下行:
#define dg_configuse_hw_i2c(1)
#define dg_configi2c_adapter(1)
以下行包含在periph_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,也许我应该使用低级驱动程序......
事情发生的方式,我想我宁愿只写下自己的裸金属司机。有哪些例子可用吗?
谢谢。
在开始交易之前,我似乎需要获得公共汽车 - 这就是外围设备本身的原因并启用中断。所以它现在没有阻止。然而....
没有什么在电线上出来。没有附加设备,但我至少应该看到地址。
谢谢。
啊!回答了我自己的问题。如果您使引脚输出打开漏极并将设备放在总线上以拉动线路,则会有很多帮助。
谢谢。
嗨单自然克里克,
我强烈建议你看看I2C适配器概念(HTML)从DA14680的支持页面。本教程解释了I2C适配器以及如何将DA1468x配置为I2C主设备。适配器未实现为单独的任务,并且应视为应用程序和LLD之间的附加层。建议使用适配器来访问硬件块。
谢谢,PM_DIALOG.
谢谢,但我已经完成了所有这些。我理解I2C适配器概念。不幸的是,我认为设计是理想的。这就是为什么我创建了一个线程到序列式调用的线程,而不停止应用程序中的任何其他线程。它现在运作得很好,并且更适合我的活动驱动应用程序框架。
我有一个跟进问题:如果我要使用两个I2C外围设备,它似乎是适配器会阻止它们上的并发事务。真的吗?
谢谢。
嗨单自然克里克,
是的,这是真的!适配器将防止并行交易。
谢谢,PM_DIALOG.
唔。谢谢你让我知道。这对我来说看起来非常糟糕。