大家好,
我在经营外部处理器配置的DA14580。它是由一个UC(SPI主站)使用GTL 5线SPI协议进行控制。我一直有运行到死锁的问题。当流过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信号变低:
......
//禁用减少中断
dready_irq_disable();
//调用减排时间来检测是否正在收到数据
而(dready_get_status());
......
以下发生:
- 而uC禁止DREADY中断时,DA断言DREADY信号之前。
- 该DREADY信号变高,但没有触发中断在UC侧。
- 而是,UC等待降低的降低信号。
- 由于DA正在等待SPI传输,但是变量信号不会低。
- >僵局
我想知道协议如何旨在避免跑到上述僵局中。从它看起来像没有阻止这种情况的机制。
谢谢!
Mabraun.
编辑:试图提出问题描述更全面
设备:

嗨mabraun,
在通过SPI总线传输数据时有一个顺序。设备交换的信号和数据不仅可怕。为了防止这种情况,在两个设备通过SPI总线传输数据之前,还应交换接通和断开数据。您可以查看UM-B-013以详细检查协议。为了避免这种死锁,在主设备可以与从设备对话之前,有一个特定的过程,反之亦然。在主设备可以传输之前,在调用spi_send_hci_msg()和禁用中断之前,应该检查从设备是否可用(如果从设备发送的最后一条消息是字节流)。
谢谢mt_dialog.
嗨mt_dialog,
感谢您的回复。我很清楚flow_on / flow_off原则,我仔细阅读了UM-B-013。值得澄清的是,我使用了从SDK5(对于主机和DA)中提供的Proximity Reporter示例中提供的源代码,这就是为什么正确实现流量控制机制(或应该)的原因。我拥有的问题与流量控制机制无关,甚至在UM-B-013的第6.2.3节中解决:
高亮的例子正是我所遇到的问题:主人要发送消息(0×05),从想要发送流出字节。它继续:
然而,上述行为(粗体)似乎并未在DA端实施(见spi_hci.c):
布尔spi_hci_flow_off_func(无效)
{
UINT8_T TMP;
//首先检查是否正在进行传输
如果((spi_cs_getf()== 0))
{
返回false;
}
NVIC_DisableIRQ(SPI_IRQn);//禁用对CPU的SPI中断
spi_dready_high();// asserd teready请求传输
做 {
spi_wait_for_transfer();//等待SPI主设备的SPI事务
tmp = spi_rxtxreg_read();//从spi获取byte
} whiled(tmp!= dready_ack);//如果没有确认已知,请再试一次
[...]
}
上面的代码首先检查传输是否正在进行中,然后它断言DREADY线,然后它等待一个SPI传输(或DREADY_ACK字节)无限期。此行为不符合下列条件:
让我们来看看UC(主机)方:第6.2.3节也是指出的
spi_hci_msg.c的代码如下所示:
空隙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(0×05);
[...]
}
代码第一的禁用减少中断,然后它轮询DREADY,然后它拉的SPI片选线低。如果DREADY变高权中断已被禁用后,uC中会无限期地等待DREADY再去低,DREADY IRQ请求将不会被服务。此外,CS线不防止这种情况发生,因为它是停用DREADY中断后拉低。
我在这里错过了什么?
很抱歉的长期职位,但我要确保我被正确理解。
干杯!
嗨mabraun,
请原谅我的情况下,我有什么不对,你已经注意到,当有来自主正在进行的交易,这样从具有发送的流量,而主是为了承认它发送一个0x08的,所以高手准备发送,以发送数据资料,并禁止IRQ和后immidiatelly从问题flow_off,所以DREADY销得高点的时间,即CS被禁止(很高,因此逃避在spi_cs_getf的CS检查()函数),因为DREADY被拉高主卡在轮询过程中和从被卡住等待一个0x08的信息永远不会来自主站。
您是否在应用程序中遇到过这种问题,如果您所做的话,您是否捕获了SPI交易?
谢谢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字节。在这之后,主机发起的传输(通知CS线如何变低而DREADY是不活动的)。该(成功的)传输后,从断言DREADY信号(因为它要发送flow_off消息),并且主要发送的消息,以及并拉动CS线低。(以便更好地观察我感动
spi_cs_low()代码前行而(dready_get_status());。否则,您将无法看到CS线被拉低。)注意,在几乎同时,在几乎同时被断言(CS低,降低高),但不会看到随后的SPI通信。那是僵局发生的时候。谢谢你的帮助!
Mabraun.
嗨mabraun,
与支持团队一起检查,就可以告诉我,这种情况很可能会发生,没有超时或任何其他机制,可以阻止580在主机刚开始发送数据时发送流脱机命令并且僵局似乎可能发生,但很少但它可能发生。因为我们从来没有默克这种问题,当通过SPI经营时,你可以确保这个死锁是为了确定你的系统停滞的原因,可以提供更完整的信号捕获,以确保0x05从主机(MOSI信号)留下,或者如果您能够调试,请确认这是代码在两侧粘所的位置(SPI_SEND_HCI_MSG()和SPI_HCI_FLOW_OF_FUNC())?
谢谢mt_dialog.
嗨mt_dialog,
感谢您的回复。在我目前的设置,我能够调试两面,这就是为什么我知道双方确实停留在spi_send_hci_msg()和spi_hci_flow_off_func()。
我连着4个屏幕抓图。我捕获的所有5条信号线(所有紫色显示),按以下顺序:CLK,MOSI,MISO,CS,DREADY。此外,我使用的协议分析器解释MOSI和MISO线,以蓝色显示在屏幕截图。公交1个对应于MOSI,总线2到MISO。
1.png:对导致死锁问题的顺序总体视图。
2.PNG:放大视图流动对序列。DREADY高,万事达确认它(0x08的)和从器件发送FlowOn字节(0×06)。
3.png:静音视图主机发送的第一个字节,标记消息的开头(0x05)。
4.png:放大视图由主站发送的消息的结束的(CS被拉高)。此后,发生死锁:从站要发送FlowOff(这通过声明DREADY开始),硕士想要发送的一条消息。请注意:在违背我以前的帖子,我也不是移动
spi_cs_low()代码前行而(dready_get_status()),这就是为什么你看不到CS线被拉低的原因。这是最初的代码行为。然而,问题仍然是:主机卡在spi_send_hci_msg()中,等待可怕的信号变低。从机卡在spi_hci_flow_off_func()中,等待spi传输。如果您需要任何其他信息,请告诉我。
谢谢你的帮助,
Mabraun.
对此有任何更新?您将能够提供5线SPI协议的固定实现?
谢谢
Mabraun.
嗨mabraun,
当时这个问题被提交为更改请求,到目前为止我们有一个可能的解决方案,以克服这种僵局,但它需要花一些时间来测试并评估任何问题或局限性。我将更多地对此或下周有关这个的信息,我会告诉你。
对此造成的不便,我们深表歉意。
谢谢mt_dialog.
嗨mt_dialog,
谢谢你的更新,这是一个很棒的新闻。请保持让我知道最新消息。
当做
Mabraun.