硬汉嵌入式论坛

 找回密码
 立即注册
查看: 3706|回复: 12
收起左侧

[技术分享] STM32H750 SPI发送完成标志置1迟到问题。替代软件模拟SWD时序不靠谱。

[复制链接]

747

主题

1049

回帖

3295

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3295
发表于 2019-8-27 01:57:24 | 显示全部楼层 |阅读模式
计划用硬件SPI替代软件模拟来实现SWD时序,程序代码功能验证OK。 SPI时钟25MHz,容易出错。时钟12.5MHz则正常。
但是软件判断SPI数据发送完成会有大概8个bit的延迟。这样一来,硬件SPI的优势全无。
不知道大家有遇到过此类问题没,SPI硬件本身如此,还是代码问题、CASHE问题。

SWD-SPI迟到问题.png
图片是执行如下代码获取:
SWD_SendBits(8, val);       //发送8bit数据
SWD_DIO_OutDisable();    //切换数据线方向为输入(延迟很小的)
ack = SWD_ReadBits(3 + 1 + 1);  // 读4bit,+1个方向转换clk
SWD_DIO_OutEnable();    //切换数据线为输出



void SWD_DIO_OutDisable(void)
{
#if SPI_MODE_ENABLE == 1
     SPI2->CR1 = SPI_CR1_SSI;
     GPIOG->BSRRH = GPIO_PIN_9; /* PG9 = 0 是输入 */  
#else
     PIN_SWDIO_OUT_DISABLE();
#endif
}

void SWD_DIO_OutEnable(void)
{
#if SPI_MODE_ENABLE == 1
     GPIOG->BSRRL = GPIO_PIN_9; /* PG9 = 1 是输出 */
     SPI2->CR1 = SPI_CR1_SSI | SPI_CR1_HDDIR;
#else
     PIN_SWDIO_OUT_ENABLE();
#endif
}

uint32_t SWD_ReadBits(uint8_t _bits)
{
#if SPI_MODE_ENABLE == 1
    uint32_t ret;
   
    _bits--;
   
    SPI2->CFG1 = SPI_MODE_BAUD | _bits;
    SPI2->CR1 = SPI_CR1_SPE | SPI_CR1_SSI;      
    SPI2->CR1 = SPI_CR1_SPE | SPI_CR1_SSI | SPI_CR1_CSTART;
   
    if (_bits > 15)
    {
        *((__IO uint32_t *)&SPI2->TXDR) = 0;
    }
    else if (_bits > 7)
    {
        *((__IO uint16_t *)&SPI2->TXDR) = 0;
    }
    else
    {
        *((__IO uint8_t *)&SPI2->TXDR) = 0;
    }
   
    while ((SPI2->SR & SPI_SR_TXC) == 0);
    SPI2->IFCR = SPI_IFCR_EOTC | SPI_IFCR_TXTFC;
   
    ret = SPI2->RXDR;
    SPI2->CR1 &= ~(SPI_CR1_SPE);
   
    return ret;

#else
    uint8_t bit;
    uint8_t i;
    uint32_t val = 0;
   
    for (i = 0; i < _bits; i++)
    {
        SW_READ_BIT(bit);               /* Read RDATA[0:31] */      
        val >>= 1;                                                            
        val  |= bit << (_bits - 1);  
    }
    return val;
#endif
}




回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106978
QQ
发表于 2019-8-27 08:41:13 | 显示全部楼层
1、SPI等待发送完成标志就是这个样子的,两个连续数据之间的间隔太长,之前好多人提过这个问题,要等待发送空标志,早前做的问题记录:

加快SPI连续读写速度的配置方式
http://www.armbbs.cn/forum.php?mod=viewthread&tid=91095

2、发现H7的SPI没有发送空标志了

可以考虑把H7 SPI的硬件FIFO空间打开,然后判断TXP标志。

回复

使用道具 举报

2

主题

42

回帖

48

积分

新手上路

积分
48
发表于 2019-8-27 08:59:14 | 显示全部楼层
eric2013 发表于 2019-8-27 08:41
1、SPI等待发送完成标志就是这个样子的,两个连续数据之间的间隔太长,之前好多人提过这个问题,要等待发送 ...

硬汉没有参与这个项目吗?你们似乎没在同一个地方呢。
回复

使用道具 举报

747

主题

1049

回帖

3295

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3295
 楼主| 发表于 2019-8-27 09:24:22 | 显示全部楼层
硬件SPI驱动代码使用的是这种半双工双向模式 SPI_DIRECTION_1LINE
SPI 双向.png

回复

使用道具 举报

747

主题

1049

回帖

3295

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3295
 楼主| 发表于 2019-8-27 09:33:13 | 显示全部楼层
SWD协议比较特殊。
每次SPI数据收发都需要改变一下datasize(必须在禁能SPI时修改),比如发8bit,读4bit,再发32bit。
这个给连续DMA操作带来麻烦,几乎不可实现。另外判断发送完成空估计也不行,因为波形还没发完就要硬件切换GPIO方向了。
这个检测发送完成时间必须及时准确。  
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106978
QQ
发表于 2019-8-27 09:38:08 | 显示全部楼层
armfly 发表于 2019-8-27 09:33
SWD协议比较特殊。
每次SPI数据收发都需要改变一下datasize(必须在禁能SPI时修改),比如发8bit,读4bit ...

H7没有发送空标志了,得开硬件FIFO来保证数据的连续收发,否则中间的那个时间将没法避免。需要切换方向的时候再判断TXC或者EOT。

像STLINK-V3用的STM32F7可以将时钟做到24MHz,H7实现应该无压力才对。

回复

使用道具 举报

747

主题

1049

回帖

3295

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3295
 楼主| 发表于 2019-8-27 09:56:09 | 显示全部楼层
eric2013 发表于 2019-8-27 09:38
H7没有发送空标志了,得开硬件FIFO来保证数据的连续收发,否则中间的那个时间将没法避免。需要切换方向的 ...

估计F7的GPIO模拟都可以轻松到达24M.        H7的GOIO模拟到达8.3M.
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106978
QQ
发表于 2019-8-27 10:10:17 | 显示全部楼层
armfly 发表于 2019-8-27 09:56
估计F7的GPIO模拟都可以轻松到达24M.        H7的GOIO模拟到达8.3M.

如果是GPIO模拟的话,F4都可以轻松做到24MHz。

H7只能用硬件SPI来达到最高IO性能了。


回复

使用道具 举报

2

主题

76

回帖

82

积分

初级会员

积分
82
发表于 2019-8-27 11:39:06 | 显示全部楼层
12.5MHz  的速度数据传输应该也可以把
回复

使用道具 举报

747

主题

1049

回帖

3295

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3295
 楼主| 发表于 2019-8-27 11:56:23 | 显示全部楼层
a20084666 发表于 2019-8-27 11:39
12.5MHz  的速度数据传输应该也可以把

这个速度可以接受。
目前关键问题是要解决两次传输之间的等待延迟。
否则整体效率只等效于8M.
回复

使用道具 举报

2

主题

76

回帖

82

积分

初级会员

积分
82
发表于 2019-8-27 13:23:07 | 显示全部楼层
armfly 发表于 2019-8-27 11:56
这个速度可以接受。
目前关键问题是要解决两次传输之间的等待延迟。
否则整体效率只等效于8M.

说的也是,,,
8M速度有点小短
回复

使用道具 举报

747

主题

1049

回帖

3295

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3295
 楼主| 发表于 2019-8-28 00:55:40 | 显示全部楼层
之前判断失误,不是SPI发送完成标志迟到问题。SPI完成标志还算及时,只要1个bit。
实际是写入TXDR寄存器后,SCK延迟一段时间才有波形送出。这个 延迟和波特率正比,大概5个bit左右。

目前暂未找到解决办法。

{
SPI2->CFG1 = SPI_MODE_BAUD | _bits;
SPI2->CR1 = SPI_CR1_SSI | SPI_CR1_HDDIR;
SPI2->CR1 = SPI_CR1_SPE | SPI_CR1_HDDIR | SPI_CR1_SSI;  
if (_bits > 15)
{
   *((__IO uint32_t *)&SPI2->TXDR) = _data;
}
else if (_bits > 7)
{
   *((__IO uint16_t *)&SPI2->TXDR) = _data;
}
else
{
   *((__IO uint8_t *)&SPI2->TXDR) = _data;
}
SPI2->CR1 = SPI_CR1_SPE | SPI_CR1_HDDIR | SPI_CR1_SSI | SPI_CR1_CSTART;

while ((SPI2->SR & SPI_SR_TXC) == 0);
SPI2->IFCR = SPI_IFCR_EOTC | SPI_IFCR_TXTFC;
SPI2->CR1 &= ~(SPI_CR1_SPE);

}



回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106978
QQ
发表于 2019-8-28 10:30:06 | 显示全部楼层
armfly 发表于 2019-8-28 00:55
之前判断失误,不是SPI发送完成标志迟到问题。SPI完成标志还算及时,只要1个bit。
实际是写入TXDR寄存器后 ...

还真有可能这个就是H7模拟IO反应速度慢的原因,写到寄存器后,要等待几个时钟周期IO才输出数据。

可以考虑开启下SPI的硬件FIFO,连续输出的效果应该会好点,因为手册里面SPI DMA章节也是借助FIFO做的标志。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-12 23:26 , Processed in 0.270842 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表