大家好,
我在外部处理器配置中操作了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.
编辑:试图提出问题描述更全面
设备:
嗨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(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线不会阻止这种情况发生,因为它在停用减速中断后被拉低。
我在这里错过了什么?
对不起长篇帖子,但我想确保我被正确理解。
干杯!
嗨mabraun,
请原谅我,万一我有点不对,你注意到,当来自主人的持续交易时,从而奴隶已经发送了一个流程,主人已经发送了0x08才能确认,所以主人是准备发送数据并禁用IRQ,然后将从中联的从设备发出flow_off以便发送数据,因此在禁用CS的时间(很高),调整引脚会变高(很高,所以它避免了SPI_CS_GETF中的CS检查)函数)由于已经拉高了,主设备卡在轮询过程中,从而停止了从掌握从主站的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字节。之后,主机启动传输(注意,在Orteady处于非活动状态时,CS行如何变为低电平)。在此(成功)传输之后,从站断言了减排信号(因为它想要发送Flow_off消息),并且主服务器也希望发送消息并将CS线路低。(为了更好的可视化,我搬了
spi_cs_low()
代码行之前while(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,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.
对此有任何更新?您是否能够提供5-Wire SPI协议的固定实施?
谢谢,
Mabraun.
嗨mabraun,
当时这个问题被提交为更改请求,到目前为止我们有一个可能的解决方案,以克服这种僵局,但它需要花一些时间来测试并评估任何问题或局限性。我将更多地对此或下周有关这个的信息,我会告诉你。
对此造成的不便,我们深表歉意。
谢谢mt_dialog.
嗨mt_dialog,
谢谢你的更新,这是一个很棒的新闻。请保持让我知道最新消息。
问候,
Mabraun.