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

Hi all,

I'm operating a DA14580 in the external processor configuration. It is controlled by a uC (SPI master) using the GTL 5-wire SPI protocol. I keep having the problem of running into a deadlock. When streaming some data over BLE (hence a lot of traffic between the uC and the DA), I run into a state where both the DA and the uC want to transmit at the same time. More specifically, the DA gets stuck in thespi_hci_write_func()功能。它驱动高信号高并等待SPI转移(spi_wait_for_transfer()):

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

However, the uC tries to send a message at the same time and gets stuck in thespi_send_hci_msg()function, waiting for the DREADY signal to go low:

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

以下发生:
- The uC disables the dready interrupt, just before the DA asserts the dready signal.
- The dready signal goes high, but no interrupt is triggered on the uC side.
- 而是,UC等待降低的降低信号。
- 由于DA正在等待SPI传输,但是变量信号不会低。
- >僵局

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

Thanks!
Mabraun.

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

Keywords:
Device:
mt_dialog.
离线
最后一次露面:2个月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年6个月前
加入:2015-11-16 15:57
Hi MT_dialog,

Hi MT_dialog,

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

防止来自主站和从站的同时传输(即主人
发送0x05开始字节以同时开始传输消息和从站
将流量关闭字节发送以后发送另一个消息)
,主人必须承认
DREADY request by the slave.

The highlighted example is exactly the problem I'm experiencing: master wants to send message (0x05), slave wants to send flow off byte. It continues:

为此,当主设备检测到有效的时,它会发送
acknowledgement byte (ACK, chosen to be 0x08) to inform the slave that it can go on to send the
流关闭字节(或任何其他数据)。此功能如图3所示。在任何一条减速边缘上,
the master has to acknowledge that it detected it and enable the slave device to send data.如果是
master does not acknowledge the DREADY rising edge, the slave waits until the Chip Select line is
不活动(这将指示主服务器已完成发送消息),请激活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);//如果没有确认已知,请再试一次
[...]
}

上面的代码首先检查传输是否正在进行中,然后it asserts the DREADY line,然后it waits for an SPI transfer (or the DREADY_ACK byte) indefinitely. This behaviour doesn't correspond to:

如果是master does not acknowledge the DREADY rising edge, the slave waits until the Chip Select line is inactive (which will indicate that the master has finished sending the message), activate DREADY again, and wait for the acknowledgement to proceed to transmit.

让我们来看看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(); // Close CS
spi_cs_low();//打开CS.
spi_access(0x05);
[...]
}

编码第一的禁用减少中断,然后it polls for DREADY,然后it pulls the SPI chip select line low. If DREADY goes high right after the interrupt has been disabled, the uC will wait indefinitely for DREADY to go low again and the DREADY irq request will not be serviced. Also, the CS line does not prevent this from happening, as it is pulled low after deactivating the DREADY interrupt.

Am I missing something here?

Sorry for the long post, but I want to make sure I'm being understood correctly.

干杯!

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

嗨mabraun,

Please excuse me in case i got something wrong, you ve noticed that when there is an ongoing transaction from the master, so the slave has send a flow on, and the master has send a 0x08 in order to acknowledge it, so the master is ready to send data and disables the IRQ and after that immidiatelly the slave issues a flow_off in order to send data, so the DREADY pin gets high at the time that the CS is disabled (is high so it evades the CS check in the spi_cs_getf() function) since the DREADY is pulled high the master is stuck in the polling procedure and the slave is stuck waiting for a 0x08 message that will never come from the master.

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

谢谢mt_dialog.

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

Hi MT_dialog,

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

In the beginning of the screenshot you can see the flow_off communication: 2 SPI bytes, containing the DREADY_ACK and the FLOW_ON bytes. After that, the master initiates a transmission (notice how the CS line goes low while DREADY is inactive). After that (successful) transmission, the slave asserts the DREADY signal (because it wants to send a flow_off message), and the master wants to send a message as well and pulls the CS line low. (for better visualization I moved thespi_cs_low()code line beforewhile(dready_get_status());。否则,您将无法看到CS线被拉低。)注意,在几乎同时,在几乎同时被断言(CS低,降低高),但不会看到随后的SPI通信。那是僵局发生的时候。

谢谢你的帮助!
Mabraun.

附件:
mt_dialog.
离线
最后一次露面:2个月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年6个月前
加入:2015-11-16 15:57
Hi MT_dialog,

Hi MT_dialog,

thanks for your reply. In my current setup I am able to debug both sides, which is why I know that both sides are indeed stuck in spi_send_hci_msg() and spi_hci_flow_off_func().

I attached 4 more screen captures. I captured all 5 signal lines (all displayed in purple), in the following order: CLK, MOSI, MISO, CS, DREADY. Additionally, I used a protocol analyzer to interpret the MOSI and MISO lines, shown in blue on the screenshots. Bus 1 corresponds to MOSI, Bus2 to MISO.

1.png:Overall view on the problematic sequence resulting in the deadlock.

2.PNG:Zoomed-in view of the Flow-On sequence. DREADY is high, Master acknowledges it (0x08) and Slave sends FlowOn byte (0x06).

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

4.png:放大视图发送的消息的结束the Master (CS is pulled high). Afterwards, the deadlock occurs: Slave wants to send FlowOff (which begins by asserting DREADY), Master wants to send the next message. Please note: In contrary to my previous post, I didnot移动spi_cs_low()code line beforewhile(dready_get_status()),这就是为什么您无法看到CS线被拉低。这是原始的代码行为。但是,问题仍然是相同的:主机卡在spi_send_hci_msg()中,等待降低的降低信号。从站粘贴在SPI_HCI_FLOW_OFF_FUNC()中,等待SPI传输。

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

谢谢你的帮助,
Mabraun.

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

对此有任何更新?你会be able to provide a fixed implementation of the 5-wire SPI protocol?

谢谢,
Mabraun.

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

嗨mabraun,

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

We are sorry for any inconvenience.

谢谢mt_dialog.

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

Hi MT_dialog,

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

问候,
Mabraun.