IMX8QXP SPI CS片选连续传输模式

在开发项目中,更换了SPI安全芯片后无法通信。分析波形发现CS片选信号在每个字节数据传输完成后拉高,而安全芯片要求在整个数据传输后才拉高。IMX8QXP的手册表明有两种传输模式,连续传输模式下CS保持asserted。内核代码显示默认开启DMA传输,关闭DMA后可以使用SPI连续传输模式,从而使安全芯片恢复正常通信。
摘要由CSDN通过智能技术生成

问题背景

        在开发项目中,换了一个spi安全芯片,发现不能进行通信,查看spi信号波形,时钟,发送数据,片选都是正常的,但没有回复数据。安全芯片技术正常通过查看CS片选波形信号,提出CS片选信号不能在每个字节数据传输完成后拉高,需要整个数据传输完成后才能拉高。查看之前的spi驱动,是安全芯片模块厂商提供的,说明spi驱动有改动过,没有使用IMX8QXP的LPSPI驱动。

不连续传输模式

        通过测量波形信号,可以看出每个字节数据完成后CS(绿色)有拉高的动作,黄色为时钟信号。 

连续传输模式

        可以看出,数据发送完成后CS片选(绿色)才会拉高。

 手册说明

        为何会有这两种传输模式呢?IMX8QXP手册中有Transmit Command Register的描述:

         但设置CONT为1时,使能连续传输模式,这样CS片选就会一直asserted。为0时,CS片选会在每个字节后面拉高。

内核代码

        内核中,spi默认开启dma传输,所以这里不会设置temp |= TCR_CONT。

static void fsl_lpspi_set_cmd(struct fsl_lpspi_data *fsl_lpspi)
{
	u32 temp = 0;

	if (!fsl_lpspi->is_slave) {
		temp |= fsl_lpspi->config.bpw - 1;
		temp |= fsl_lpspi->config.prescale << 27;
		temp |= (fsl_lpspi->config.mode & 0x3) << 30;
		temp |= (fsl_lpspi->config.chip_select & 0x3) << 24;

		/*
		 * Set TCR_CONT will keep SS asserted after current transfer.
		 * For the first transfer, clear TCR_CONTC to assert SS.
		 * For subsequent transfer, set TCR_CONTC to keep SS asserted.
		 */
		if (!fsl_lpspi->usedma) {
			temp |= TCR_CONT;
			if (fsl_lpspi->is_first_byte)
				temp &= ~TCR_CONTC;
			else
				temp |= TCR_CONTC;
		}
	} else {
		temp |= fsl_lpspi->config.bpw - 1;
		temp |= (fsl_lpspi->config.mode & 0x3) << 30;
	}
	writel(temp, fsl_lpspi->base + IMX7ULP_TCR);

	dev_dbg(fsl_lpspi->dev, "TCR=0x%x\n", temp);
}

关闭SPI DMA

        dts中有描述dma信息:

    lpspi2: lpspi@5a020000 {
        compatible = "fsl,imx7ulp-spi";
        reg = <0x0 0x5a020000 0x0 0x10000>;
        interrupts = <GIC_SPI 218 IRQ_TYPE_LEVEL_HIGH>;
        interrupt-parent = <&gic>;
        clocks = <&clk IMX8QXP_SPI2_CLK>,
             <&clk IMX8QXP_SPI2_IPG_CLK>;
        clock-names = "per", "ipg";
        assigned-clocks = <&clk IMX8QXP_SPI2_CLK>;
        assigned-clock-rates = <20000000>;
        power-domains = <&pd_dma_lpspi2>;
        dma-names = "tx","rx";
        dmas = <&edma2 5 0 0>, <&edma2 4 0 1>;
        status = "disabled";
    };
&lpspi2 {
        #address-cells = <1>;
        #size-cells = <0>;
        fsl,spi-num-chipselects = <1>;
        cs-gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_lpspi2>;
        assigned-clock-rates = <128000000>;
        status = "okay";

        spidev2:spidev@0 {
             compatible = "rohm,dh2228fv";
             spi-max-frequency = <50000000>;
             reg = <0>;
        };
};

        把dts中的dma信息删除掉编译不会报错,但启动报错:

[    1.028078] fsl_lpspi 5a020000.lpspi: failed to enable clock
[    1.033817] fsl_lpspi: probe of 5a020000.lpspi failed with error -22

        暂不知道怎么关闭DMA,取巧的办法是在fsl_lpspi_can_dma函数返回false:

static bool fsl_lpspi_can_dma(struct spi_controller *controller,
			      struct spi_device *spi,
			      struct spi_transfer *transfer)
{
	unsigned int bytes_per_word;
	return false;

	if (!controller->dma_rx)
		return false;

	bytes_per_word = fsl_lpspi_bytes_per_word(transfer->bits_per_word);
	if (bytes_per_word != 1 && bytes_per_word != 2 && bytes_per_word != 4)
		return false;

	return true;
}

        这样关闭SPI DMA方式,转而使用SPI连续传输模式。接着安全芯片就能进行愉快的通信了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值