最近在使用GD32F405VGT6的时候,偶然发现了一个小BUG(也不排除是某些地方配置问题,但概率较低)。
所使用的SPI 接收CRC校验一直是正确的,这次配置了一下看门狗,就频繁报CRC错误了。但是数据以及读取CRC、计算CRC均正确。
spi_i2s_data_transmit(SPI0, 0); //启动最后一次数据发收
spi_crc_next(SPI0); //使能CRC发送接收
代码如上所示,CRC状态错误在spi_crc_next(SPI0)语句后发生。该语句前状态为0x80,表示正在收发最后一个数据;该语句后状态立即变为0x53,表示出现了接收溢出和CRC校验错误、发送缓冲区空、接收缓冲区非空。正常情况应该是在该语句后状态为0x82,表示正在收发,发送缓冲和接收缓冲都是空的。
在上述两句代码前后加上__disable_irq()、__enable_irq()不起任何作用,说明不是由于中断导致操作不连续。
虽然发生了CRC校验错误和接收溢出错误,但是所有接收到的数据、读取的CRC、计算的CRC都是正确的。因此直接对比CRC数值,而不是判断CRC状态,可临时修正该问题。
各位老铁有什么好的想法和建议,欢迎留言。
后记:
进一步分析,应该是spi_crc_next所写入的CRCNT位所在的寄存器SPI_CTL0,在某些情况下不能在 SPI使能时进行写操作,否则会产生意想不到的效果。
GD32的资料比较简略,这块没有涉及。在STM32的资料中有详细的操作步骤,并没有要求配置CRCNT时必须要禁用SPI;而且写CRCNT位是在SPI操作的中间,突然禁用SPI,也不太合理。会不会是GD32的一个BUG?
为了避免在SPI操作时写CRCNT,可以考虑在倒数第二个数据接收后,直接读取CRC寄存器,然后跟最后一个CRC数据进行对比。