2412418_zh-CN

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

2412418_zh-CN

2412418_zh-CN

spi:spi_nxp_lpspi:DMA 模式,返回 -EIO 或损坏的数据

大家好

我最近在使用 SPI DMA 进行多传感器通信时遇到了一个问题,SPI 事务返回 -EIO 或数据损坏。深入研究驱动程序后,我发现 DMA 模式下,spi_nxp_lpspi 在每次传输开始时启用两个 LPSPI DMA 请求使能位,但在结束时只禁用其中一个。无论两个 DMA 通道中哪个先完成,都会在不清除自身 DER 位的情况下完成 SPI 上下文,因此每次传输都会将一个请求使能泄漏到下一个请求中。

在 drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_dma.c 中,transceive_dma() (:346) 中这两个位同时被启用:

			if (channel == dma_data->dma_tx.channel) {
				spi_mcux_issue_TCR(spi_dev);
				dma_data->state = LPSPI_TRANSFER_STATE_TX_DONE;
				base->DER &= ~LPSPI_DER_TDDE_MASK;
			} else {
				dma_data->state = LPSPI_TRANSFER_STATE_RX_DONE;
				base->DER &= ~LPSPI_DER_RDDE_MASK;
			}

在 lpspi_dma_callback() 中,第一个完成的通道会清除它自己的位(:249–:253):

			if (channel == dma_data->dma_tx.channel) {
				spi_mcux_issue_TCR(spi_dev);
				dma_data->state = LPSPI_TRANSFER_STATE_TX_DONE;
				base->DER &= ~LPSPI_DER_TDDE_MASK;
			} else {
				dma_data->state = LPSPI_TRANSFER_STATE_RX_DONE;
				base->DER &= ~LPSPI_DER_RDDE_MASK;
			}

如果我清除这两个位,所有交易似乎都能顺利完成,没有任何警告。以下是我使用的补丁。

@@ lpspi_dma_callback()
 	case LPSPI_TRANSFER_STATE_TX_DONE:
 	case LPSPI_TRANSFER_STATE_RX_DONE:
 		dma_data->state = LPSPI_TRANSFER_STATE_RX_TX_DONE;
 		/* TX and RX both done here. */
+		base->DER &= ~(LPSPI_DER_TDDE_MASK | LPSPI_DER_RDDE_MASK);
 		spi_context_complete(ctx, spi_dev, 0);
 		spi_context_cs_control(ctx, false);
 		break;
@@
 error:
+	base->DER &= ~(LPSPI_DER_TDDE_MASK | LPSPI_DER_RDDE_MASK);
 	LOG_ERR("DMA callback error with channel %d.", channel);
 	spi_context_complete(ctx, spi_dev, ret);
 	spi_context_cs_control(ctx, false);

附件是我使用的测试应用程序。该应用程序内置了上述解决方案。


我的问题是,驱动程序为什么只清除一个比特位,而不是两个比特位都清除?


标记 (1)
无评分
版本历史
最后更新:
2 周之前
更新人: