10个帖子/ 0新
最后一篇
Mabraun.
离线
最后一次露面:3年5个月前
加入:2015-11-16 15:57
SPI GTL僵局

大家好,

我在外部处理器配置中操作了DA14580。它由使用GTL 5-Wire SPI协议的UC(SPI Master)控制。我不断遇到僵局的问题。在通过BLE上流式传输某些数据(因此UC和DA之间的大量流量),我遇到DA和UC希望同时发送的状态。更具体地说,da被困在spi_hci_write_func()功能。它驱动高信号高并等待SPI转移(spi_wait_for_transfer()):

......
spi_dready_high();// asserd teready请求传输
做 {
spi_wait_for_transfer();//等待SPI主设备的SPI事务
......

但是,UC试图同时发送消息,并陷入困境spi_send_hci_msg()功能,等待减速信号降低:

......
//禁用减少中断
dready_irq_disable();
//调用减排时间来检测是否正在收到数据
while(dready_get_status());
......

以下发生:
- UC禁用DA在DA断言的变量信号之前的中断。
- 降低信号变高,但在UC侧不会触发中断。
- 而是,UC等待降低的降低信号。
- 由于DA正在等待SPI传输,但是变量信号不会低。
- >僵局

我想知道协议如何旨在避免跑到上述僵局中。从它看起来像没有阻止这种情况的机制。

谢谢!
Mabraun.

编辑:试图提出问题描述更全面

关键词:
设备:
mt_dialog.
离线
最后一次露面:1个月1周前
职员
加入:2015-06-08 11:34
嗨mabraun,

嗨mabraun,

有一个序列通过SPI总线传输数据信号和数据交换的设备不仅所为了防止这种情况,还有flow_on flow_off数据前应交换两个设备可以通过SPI总线传输数据。您可以查看一下UM-B-013,以便详细检查协议。有一个特定的程序主人跟奴隶之前,反之亦然为了避免这种僵局,主传输之前应该检查如果奴隶可用(如果从奴隶是一个流的最后一条消息发送字节)之前调用spi_send_hci_msg()和禁用中断。

谢谢mt_dialog.

Mabraun.
离线
最后一次露面:3年5个月前
加入:2015-11-16 15:57
嗨mt_dialog,

嗨mt_dialog,

感谢您的回复。我很清楚flow_on / flow_off原则,我仔细阅读了UM-B-013。值得澄清的是,我使用了从SDK5(对于主机和DA)中提供的Proximity Reporter示例中提供的源代码,这就是为什么正确实现流量控制机制(或应该)的原因。我拥有的问题与流量控制机制无关,甚至在UM-B-013的第6.2.3节中解决:

防止来自主站和从站的同时传输(即主人
发送0x05开始字节以同时开始传输消息和从站
将流量关闭字节发送以后发送另一个消息)
,主人必须承认
从站的可调整请求。

突出显示的示例正是我遇到的问题:主师愿发送消息(0x05),从而想要发送流关闭字节。它继续:

为了做到这一点,当主服务器检测到DREADY是活动的,它发送一个
确认字节(ACK,选择为0x08)以通知奴隶可以继续发送
流关闭字节(或任何其他数据)。此功能如图3所示。在任何一条减速边缘上,
主人必须承认它检测到它并使从设备能够发送数据。如果是
Master不承认已升起的升高边缘,从而等待芯片选择线
不活动(这将指示主服务器已完成发送消息),请激活Dready
再次,并等待确认进行传输。

然而,上面描述的行为(粗体)似乎并没有在DA端实现(参见spi_hci.c):

BOOL SPI_HCI_FLOW_OFF_FUNC(void)
{
UINT8_T TMP;
//首先检查是否正在进行传输
if((spi_cs_getf()== 0))
{
返回false;
}
NVIC_DisableIRQ (SPI_IRQn);//禁用SPI中断到CPU
spi_dready_high();// asserd teready请求传输
做 {
spi_wait_for_transfer();//等待SPI主设备的SPI事务
tmp = spi_rxtxreg_read();//从spi获取byte
} whiled(tmp!= dready_ack);//如果没有确认已知,请再试一次
[...]
}

上面的代码首先检查传输是否正在进行中,然后它断言了树脂,然后它无限期地等待SPI转移(或DREADY_ACK BYTE)。此行为不对应:

如果主设备不确认已上升沿,则从设备等待,直到芯片选择行处于非活动状态(这将指示主服务器已完成发送消息),再次激活开关,并等待确认以继续传输。

让我们来看看UC(主机)方:第6.2.3节也是指出的

在任何一条减少的边缘上,主设备必须确认它检测到它并使从设备能够发送数据。

spi_hci_msg.c的代码如下所示:

void spi_send_hci_msg(uint16_t大小,uint8_t * msg_ptr)
{
uint16_t i;
//禁用减少中断
nvic_disableirq(gpio0_irqn);
//调用减排时间来检测是否正在收到数据
while(gpio_getpinstatus(spi_gpio_port,spi_dready_pin));
spi_cs_high();//关闭CS.
spi_cs_low();//打开CS.
spi_access(0x05);
[...]
}

代码第一的禁用减少中断,然后IT调查减少,然后它提取SPI芯片选择线路低。如果在中断禁用后的变量高,则UC将无限期地等待1,再次降低,并且将不需要提供可排除的IRQ请求。此外,CS线不会阻止这种情况发生,因为它在停用减速中断后被拉低。

我在这里错过了什么?

对不起长篇帖子,但我想确保我被正确理解。

干杯!

mt_dialog.
离线
最后一次露面:1个月1周前
职员
加入:2015-06-08 11:34
嗨mabraun,

嗨mabraun,

请原谅我,万一我有点不对,你注意到,当来自主人的持续交易时,从而奴隶已经发送了一个流程,主人已经发送了0x08才能确认,所以主人是准备发送数据并禁用IRQ,然后将从中联的从设备发出flow_off以便发送数据,因此在禁用CS的时间(很高),调整引脚会变高(很高,所以它避免了SPI_CS_GETF中的CS检查)函数)由于已经拉高了,主设备卡在轮询过程中,从而停止了从掌握从主站的0x08消息。

您是否在应用程序中遇到过这种问题,如果您所做的话,您是否捕获了SPI交易?

谢谢mt_dialog.

Mabraun.
离线
最后一次露面:3年5个月前
加入:2015-11-16 15:57
嗨mt_dialog,

嗨mt_dialog,

是的,你完全正确。在附加图像中,您将找到4个信号:
1. SPI CLK(黄色)
2. SPI MISO(蓝色)
3. SPI CS(粉红色)
4.减少(绿色)
我的范围只有4个频道,所以我无法捕获MOSI线。

在屏幕截图的开头,您可以看到flow_off通信:2个spi字节,包含dready_ack和flow_on字节。之后,主机启动传输(注意,在Orteady处于非活动状态时,CS行如何变为低电平)。在此(成功)传输之后,从站断言了减排信号(因为它想要发送Flow_off消息),并且主服务器也希望发送消息并将CS线路低。(为了更好的可视化,我搬了spi_cs_low()代码行之前while(dready_get_status());。否则,您将无法看到CS线被拉低。)注意,在几乎同时,在几乎同时被断言(CS低,降低高),但不会看到随后的SPI通信。那是僵局发生的时候。

谢谢你的帮助!
Mabraun.

附件:
mt_dialog.
离线
最后一次露面:1个月1周前
职员
加入:2015-06-08 11:34
嗨mabraun,

嗨mabraun,

与支持团队一起检查,就可以告诉我,这种情况很可能会发生,没有超时或任何其他机制,可以阻止580在主机刚开始发送数据时发送流脱机命令并且僵局似乎可能发生,但很少但它可能发生。因为我们从来没有默克这种问题,当通过SPI经营时,你可以确保这个死锁是为了确定你的系统停滞的原因,可以提供更完整的信号捕获,以确保0x05从主机(MOSI信号)留下,或者如果您能够调试,请确认这是代码在两侧粘所的位置(SPI_SEND_HCI_MSG()和SPI_HCI_FLOW_OF_FUNC())?

谢谢mt_dialog.

Mabraun.
离线
最后一次露面:3年5个月前
加入:2015-11-16 15:57
嗨mt_dialog,

嗨mt_dialog,

感谢您的回复。在我当前的设置中,我能够调试双方,这就是为什么我知道双方都确实被困在spi_send_hci_msg()和spi_hci_flow_off_func()中。

我附上了4个屏幕捕获。我捕获了所有5条信号线(全部显示在紫色),按以下顺序:CLK,MOSI,MISO,CS,Dready。此外,我使用协议分析器来解释MOSI和MISO线,以蓝色显示在屏幕截图上。总线1对应于MOSI,BUS2到MISO。

1.png:关于有问题的序列的总体观点导致死锁。

2.PNG:放大鉴于流动序列。Dready很高,主机确认它(0x08)和从站发送Flowon字节(0x06)。

3.PNG:静音视图主机发送的第一个字节,标记消息的开头(0x05)。

4.png:静电鉴于主设备发送的消息结束(CS被拉高)。之后,发生死锁:从奴隶想要发送流程(开始通过断言有条件),Master想要发送下一条消息。请注意:违反我以前的帖子,我做了不是移动spi_cs_low()代码行之前while(dready_get_status())这就是为什么你看不到CS线被拉低的原因。这是原始代码的行为。然而,问题仍然是一样的:主服务器卡在spi_send_hci_msg()中,等待DREADY信号降低。slave被卡在spi_hci_flow_off_func()中,等待SPI传输。

如果您需要任何其他信息,请告诉我。

谢谢你的帮助,
Mabraun.

附件:
Mabraun.
离线
最后一次露面:3年5个月前
加入:2015-11-16 15:57
对此有任何更新?你会

对此有任何更新?您是否能够提供5-Wire SPI协议的固定实施?

谢谢,
Mabraun.

mt_dialog.
离线
最后一次露面:1个月1周前
职员
加入:2015-06-08 11:34
嗨mabraun,

嗨mabraun,

当时这个问题被提交为更改请求,到目前为止我们有一个可能的解决方案,以克服这种僵局,但它需要花一些时间来测试并评估任何问题或局限性。我将更多地对此或下周有关这个的信息,我会告诉你。

对此造成的不便,我们深表歉意。

谢谢mt_dialog.

Mabraun.
离线
最后一次露面:3年5个月前
加入:2015-11-16 15:57
嗨mt_dialog,

嗨mt_dialog,

谢谢你的更新,这是一个很棒的新闻。请保持让我知道最新消息。

问候,
Mabraun.