大家好,
我在外部处理器配置中操作了DA14580。它由使用GTL 5-Wire SPI协议的UC(SPI Master)控制。我不断遇到僵局的问题。在通过BLE上流式传输某些数据(因此UC和DA之间的大量流量),我遇到DA和UC希望同时发送的状态。更具体地说,da被困在spi_hci_write_func()
function. It drives the DREADY signal high and waits for an SPI transfer (spi_wait_for_transfer()
):
...
spi_dready_high(); // Assert dready to request transmit
do {
spi_wait_for_transfer(); // Wait for SPI transaction from SPI master device
...
但是,UC试图同时发送消息,并陷入困境spi_send_hci_msg()
功能,等待减速信号降低:
...
// disable dready interrupt
dready_irq_disable();
// Polling DREADY to detect if data is being received
while(dready_get_status());
...
The following happens:
- UC禁用DA在DA断言的变量信号之前的中断。
- 降低信号变高,但在UC侧不会触发中断。
- Instead, the uC waits for the dready signal to go low.
- The dready signal won't go low, since the DA is waiting for an SPI transmission.
--> Deadlock
I'm wondering how the protocol intends to avoid running into the deadlock described above. From what it looks like there is no mechanism that prevents that situation.
谢谢!
mabraun
edit: tried to make problem description more comprehensive
Hi mabraun,
有一个在transferin序列g data over the SPI bus the signals and the data exchanged by the devices are not only the DREADY in order to prevent this condition, there are flow_on and flow_off data that should be exchanged before the two devices can transfer data over the SPI bus. You can have a look at the UM-B-013 in order to check the protocol in detail. There is a specific procedure before the master can talk to slave and vice versa in order to avoid this kind of deadlock, before the master can transmit should check if the slave is available (if the last message send from slave was a flow on byte) before invoking the spi_send_hci_msg() and disabling the interrupts.
Thanks MT_dialog
嗨mt_dialog,
Thanks for your reply. I am well aware of the flow_on/flow_off principle, I have read through UM-B-013 carefully. It is worth clarifying that I used the source code provided in the proximity reporter example from SDK5 (for both the host and the DA), which is why the flow control mechanism is (or should be) properly implemented. The problem I'm having is not related to the flow control mechanism and is even addressed in section 6.2.3 of UM-B-013:
突出显示的示例正是我遇到的问题:主师愿发送消息(0x05),从而想要发送流关闭字节。它继续:
However, the behaviour described above (bold) doesn't seem to be implemented on the DA side (see spi_hci.c):
BOOL SPI_HCI_FLOW_OFF_FUNC(void)
{
uint8_t tmp;
// First check if no transmission is ongoing
if((spi_cs_getf()== 0))
{
return false;
}
NVIC_DisableIRQ(SPI_IRQn); // Disable SPI interrupt to CPU
spi_dready_high(); // Assert dready to request transmit
do {
spi_wait_for_transfer(); // Wait for SPI transaction from SPI master device
tmp = spi_rxtxreg_read(); // Get byte from SPI
} while (tmp != DREADY_ACK); // If DREADY is not acknowledged, try again
[...]
}
的代码above first checks if a transmission is ongoing,THEN它断言了树脂,then它无限期地等待SPI转移(或DREADY_ACK BYTE)。此行为不对应:
Let's look at the uC (host) side: Section 6.2.3 also states that
的代码from spi_hci_msg.c looks like this:
void spi_send_hci_msg(uint16_t大小,uint8_t * msg_ptr)
{
uint16_t i;
// disable dready interrupt
nvic_disableirq(gpio0_irqn);
// Polling DREADY to detect if data is being received
while(GPIO_GetPinStatus(SPI_GPIO_PORT, SPI_DREADY_PIN));
spi_cs_high();//关闭CS.
spi_cs_low(); // Open CS
spi_access(0x05);
[...]
}
的代码FIRST禁用所打断,thenIT调查减少,then它提取SPI芯片选择线路低。如果在中断禁用后的变量高,则UC将无限期地等待1,再次降低,并且将不需要提供可排除的IRQ请求。此外,CS线不会阻止这种情况发生,因为它在停用减速中断后被拉低。
我在这里错过了什么?
对不起长篇帖子,但我想确保我被正确理解。
Cheers!
Hi mabraun,
请原谅我,万一我有点不对,你注意到,当来自主人的持续交易时,从而奴隶已经发送了一个流程,主人已经发送了0x08才能确认,所以主人是准备发送数据并禁用IRQ,然后将从中联的从设备发出flow_off以便发送数据,因此在禁用CS的时间(很高),调整引脚会变高(很高,所以它避免了SPI_CS_GETF中的CS检查)函数)由于已经拉高了,主设备卡在轮询过程中,从而停止了从掌握从主站的0x08消息。
Have you experienced this kind of issue in your application and if you did, do you have a capture of the SPI transactions ?
Thanks MT_dialog
嗨mt_dialog,
yes, you got it exactly right. In the attached image you'll find 4 signals:
1. SPI CLK (yellow)
2. SPI MISO(蓝色)
3. SPI CS(粉红色)
4. DREADY (green)
My scope only has 4 channels, so I couldn't capture the MOSI line.
在屏幕截图的开头,您可以看到flow_off通信:2个spi字节,包含dready_ack和flow_on字节。之后,主机启动传输(注意,在Orteady处于非活动状态时,CS行如何变为低电平)。在此(成功)传输之后,从站断言了减排信号(因为它想要发送Flow_off消息),并且主服务器也希望发送消息并将CS线路低。(为了更好的可视化,我搬了
spi_cs_low()
代码行之前while(dready_get_status());
. Otherwise you wouldn't see the CS line being pulled low.) Notice how both DREADY and CS are asserted (CS low, DREADY high) at almost the same time, but no subsequent SPI communication is visible. That is when the deadlock happens.Thanks for your help!
mabraun
Hi mabraun,
I ve checked with the support team and as far as they could tell me is, this scenario is likely to happen, there is no timeout or any other mechanism that would prevent the 580 from sending a flow off command while the host just started sending data and that the deadlock seems that it can occur, rarely but its possible. Because we ve never ecountered this kind of issue, when operating over SPI can you make sure that this deadlock is for sure the reason for the stalling of your system, can you provide a more complete capture of your signals, in order to make sure that the 0x05 is left from the host (MOSI signal) or if you are able to debug, have you confirmed that this is where the code stucks in both sides (spi_send_hci_msg() and spi_hci_flow_of_func() ) ?
Thanks 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:Zoomed-in view of the first byte sent by the Master, marking the beginning of a message (0x05).
4.png:静电鉴于主设备发送的消息结束(CS被拉高)。之后,发生死锁:从奴隶想要发送流程(开始通过断言有条件),Master想要发送下一条消息。请注意:违反我以前的帖子,我做了不是move the
spi_cs_low()
代码行之前while(dready_get_status())
, which is why you cannot see the CS line being pulled low. This is the original code behaviour. The problem, however, remains the same: The master is stuck in spi_send_hci_msg(), waiting for the DREADY signal to go low. The slave is stuck in spi_hci_flow_off_func(), waiting for an SPI transfer.Please let me know if you need any additional information.
Thanks for your help,
mabraun
对此有任何更新?您是否能够提供5-Wire SPI协议的固定实施?
谢谢,
mabraun
Hi mabraun,
At the time being the issue is filed as a change request, so far we have a possible solution in order to overcome this deadlock but its going to take some time in order to test it and evaluate any issues or limitations. I will have more about this withing this or next week, i will let you know.
对此造成的不便,我们深表歉意。
Thanks MT_dialog
嗨mt_dialog,
thanks for your update, that is great news. Please keep me posted.
Regards,
mabraun