你好,
我在外部处理器配置中操作DA14580。它由uC (SPI主)使用GTL 5线SPI协议控制。我总是遇到陷入僵局的问题。当通过BLE传输一些数据时(因此uC和DA之间有大量的流量),我遇到DA和uC都想同时传输的状态。更确切地说,地方检察官被困在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在DA断言可怕的信号之前禁用可怕的中断。
—可怕的信号变高,但uC侧没有触发中断。
- 而是,UC等待降低的降低信号。
- 由于DA正在等待SPI传输,但是变量信号不会低。
- >僵局
我想知道协议如何旨在避免跑到上述僵局中。从它看起来像没有阻止这种情况的机制。
谢谢!
Mabraun.
编辑:试图提出问题描述更全面
设备:
嗨mabraun,
在SPI总线上传输数据的序列,通过设备交换的信号和数据不仅是指天气,以防止这种情况,存在FLOW_ON和FLOW_OFF数据,应该在两个设备可以传输数据之前交换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节中解决:
突出显示的例子正是我正在经历的问题:主服务器想要发送消息(0x05),从服务器想要发送流关闭字节。它仍在继续:
但是,上面描述的行为(粗体)似乎在DA侧面(见SPI_HCI.C):
bool spi_hci_flow_off_func(空白)
{
UINT8_T TMP;
//首先检查是否正在进行传输
如果((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字节)。这种行为并不对应于:
让我们来看看UC(主机)方:第6.2.3节也是指出的
spi_hci_msg.c的代码如下所示:
Void spi_send_hci_msg(uint16_t size, uint8_t *msg_ptr)
{
uint16_t我;
//禁用减少中断
NVIC_DisableIRQ (GPIO0_IRQn);
//调用减排时间来检测是否正在收到数据
while(gpio_getpinstatus(spi_gpio_port,spi_dready_pin));
spi_cs_high ();/ /关闭计算机
spi_cs_low();//打开CS.
spi_access (0 x05);
[...]
}
代码初禁用减少中断,然后它投票给DREADY,然后它拉SPI芯片选择线低。如果DREADY在中断被禁用后马上变高,uC将无限期地等待DREADY再次变低,并且DREADY的irq请求将不会得到服务。同样,CS线也不能阻止这种情况发生,因为它在停用DREADY中断后被拉低。
我是不是漏掉了什么?
很抱歉这么长时间,但我想确保我的理解是正确的。
干杯!
嗨mabraun,
请原谅我如果我错了,你已经注意到,当有一个正在进行的事务从主,所以奴隶发送流量,和主发送(为了承认它的存在,所以主人准备发送数据和禁用IRQ immidiatelly奴隶问题后flow_off为了发送数据,所以所销得到高当时CS是禁用的(高所以躲避CS检查在spi_cs_getf()函数)所以来被高主卡在轮询程序和奴隶阻塞、等待(永远不会从主来的消息。
您是否在应用程序中遇到过这种问题,如果您所做的话,您是否捕获了SPI交易?
谢谢mt_dialog.
嗨MT_dialog,
是的,你完全正确。在附加图像中,您将找到4个信号:
1. SPI CLK(黄色)
2.SPI味噌(蓝色)
3.SPI CS(粉色)
4.减少(绿色)
我的范围只有4个频道,所以我无法捕获MOSI线。
在屏幕截图的开始,你可以看到flow_off通信:2个SPI字节,包含DREADY_ACK和FLOW_ON字节。在此之后,主机启动一个传输(注意当DREADY不活动时,CS线路是如何变低的)。在(成功)传输之后,从服务器断言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高,Master确认它(0x08), Slave发送FlowOn字节(0x06)。
3. png:静音视图主机发送的第一个字节,标记消息的开头(0x05)。
4. png:放大主发送的消息的结尾(CS被拉高)。之后,死锁发生:Slave想要发送FlowOff(它以断言DREADY开始),Master想要发送下一个消息。请注意:与我之前的帖子相反,我做了不搬运
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.