10 posts / 0 new
Last post
mabraun
Offline
Last seen:3 years 5 months ago
Joined:2015-11-16 15:57
SPI GTL僵局

大家好,

我在外部处理器配置中操作了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

关键词:
设备:
MT_dialog
Offline
Last seen:1 month 3 weeks ago
Staff
Joined:2015-06-08 11:34
Hi mabraun,

Hi mabraun,

在通过SPI总线传输数据时有一个顺序设备交换的信号和数据不仅可怕为了防止这种情况,在两个设备可以通过SPI总线传输数据之前,应该交换流开和流关数据。您可以查看UM-B-013以详细检查协议。为了避免这种死锁,在主设备与从设备进行通信之前有一个特定的过程,在主设备进行传输之前,在调用spi\u send\u hci\u msg()并禁用中断之前,应该检查从设备是否可用(如果从设备发送的最后一条消息是字节流)。

Thanks MT_dialog

mabraun
Offline
Last seen:3 years 5 months ago
Joined:2015-11-16 15:57
嗨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:

To prevent the event of simultaneous transmissions from both master and slave(i.e. the master
sends the 0x05 start byte to begin the transmission of a message and the slave at the same time
sends a flow off byte to subsequently transmit another message)
,主acknowledge the
从站的可调整请求。

突出显示的示例正是我遇到的问题:主师愿发送消息(0x05),从而想要发送流关闭字节。它继续:

为此,当主机检测到恐惧处于活动状态时,它会发送一个
确认字节(ACK,选择为0x08)以通知奴隶可以继续发送
flow off byte (or any other data). This functionality is shown in Figure 3. On any DREADY rising edge,
主人必须承认它检测到它并使从设备能够发送数据。If the
Master不承认已升起的升高边缘,从而等待芯片选择线
inactive (which will indicate that the master has finished sending the message), activate DREADY
again, and wait for the acknowledgement to proceed to transmit.

但是,上面描述的行为(粗体)似乎没有在DA端实现(请参见spi\u 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);//禁用对CPU的SPI中断
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

On any DREADY rising edge, the master has to acknowledge that it detected it and enable the slave device to send data.

代码from spi_hci_msg.c looks like this:

void spi\u send\u hci\u msg(uint16\u t size,uint8\u t*msg\u 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!

MT_dialog
Offline
Last seen:1 month 3 weeks ago
Staff
Joined:2015-06-08 11:34
Hi mabraun,

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

mabraun
Offline
Last seen:3 years 5 months ago
Joined:2015-11-16 15:57
嗨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.

谢谢你的帮助!
mabraun

Attachment:
MT_dialog
Offline
Last seen:1 month 3 weeks ago
Staff
Joined:2015-06-08 11:34
Hi 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

mabraun
Offline
Last seen:3 years 5 months ago
Joined:2015-11-16 15:57
嗨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 thespi_cs_low()代码行之前while(dready_get_status()),这就是为什么你看不到CS线被拉低的原因。这是最初的代码行为。然而,问题仍然是一样的:主机卡在spi\u send\u hci\u msg()中,等待可怕的信号变低。从机卡在spi\u hci\u flow\u off\u func()中,等待spi传输。

Please let me know if you need any additional information.

谢谢你的帮助,
mabraun

Attachment:
mabraun
Offline
Last seen:3 years 5 months ago
Joined:2015-11-16 15:57
对此有任何更新?Will you

对此有任何更新?您是否能够提供5-Wire SPI协议的固定实施?

谢谢,
mabraun

MT_dialog
Offline
Last seen:1 month 3 weeks ago
Staff
Joined:2015-06-08 11:34
Hi 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

mabraun
Offline
Last seen:3 years 5 months ago
Joined:2015-11-16 15:57
嗨mt_dialog,

嗨mt_dialog,

thanks for your update, that is great news. Please keep me posted.

当做,
mabraun