This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

C6748使用EDMA3控制SPI通信不正常

在使用EDMA3进行SPI通信时会出现开启spi的rx传输后会出现接收buffer多出未知的三个字节数据。当前我是这样配置的:

1.SPI为slave模式 cs=2

2.spi使用的edma3通道为EDMA3_CHA_SPI0_TX, EDMA3_CHA_SPI0_RX用于发送和接收

3.初始化EDMA3的过程是: 设置传输完成中断和错误中断=》请求DMA通道=》设置中断回调函数=》开启RX的DMA(不开TXDMA)

4.中断处理函数中刚开始能正常接收数据,后来在接收到特定数据后我使用EDMA3DisableTransfer(SOC_EDMA30CC_0_REGS, EDMA3_CHA_SPI0_RX, EDMA3_TRIG_MODE_EVENT) 把rx关闭,同时用EDMA3EnableTransfer开启TX 的DMA传输。待数据全部发送完成后在tx的完成中断中使用EDMA3DisableTransfer(SOC_EDMA30CC_0_REGS, EDMA3_CHA_SPI0_TX, EDMA3_TRIG_MODE_EVENT)关闭TX,然后再EDMA3EnableTransfer开启RX。这时会出现一个奇怪的问题,当再次发生rx的DMA完成中断时接收buffer的的前三个字节数据并不是master发送过来的。

请教一下我这样使用EDMA3有什么问题吗?为什么会多出几个字节,我已经用示波器测量过这三个字节确实不是master发送出来的。

  • 我的代码结构大概是这样的:

    spi_setup(DEFAULT_SPI_BUS, DEFAULT_SPI_CS, DEFAULT_SPI_MODE, NULL);  //setup spi0 (slave mode) cs=2

    IntRegister(C674X_MASK_INT4, spi_edma3_com_isr);
    IntRegister(C674X_MASK_INT5, spi_edma3_err_isr);

    IntEventMap(C674X_MASK_INT4, SYS_INT_EDMA3_0_CC0_INT1);
    IntEventMap(C674X_MASK_INT5, SYS_INT_EDMA3_0_CC0_ERRINT);

    IntEnable(C674X_MASK_INT4);
    IntEnable(C674X_MASK_INT5);

    /* Request DMA Channel and TCC for SPI Transmit*/
    EDMA3RequestChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA, \
    EDMA3_CHA_SPI0_TX, EDMA3_CHA_SPI0_TX, 0);

    /* Request DMA Channel and TCC for SPI Receive*/
    EDMA3RequestChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA, \
    EDMA3_CHA_SPI0_RX, EDMA3_CHA_SPI0_RX, 0);

    /* Registering Callback Function for Transmission. */
    cb_Fxn[EDMA3_CHA_SPI0_TX] = &spi_edma_callback;
    /* Registering Callback Function for Reception. */
    cb_Fxn[EDMA3_CHA_SPI0_RX] = &spi_edma_callback;

     //set the PaRAM entries of EDMA3 for the Receive Channel of SPI0.   只开启rx的dma,设置传输8个字节。

    spi_edma_rx((unsigned char *)dma_rx, 8);

    spi_int_enable(spi, SPI_DMA_REQUEST_ENA_INT);

    *************************************************************************************************************

    spi_edma3_com_isr:     //spi_edma_callback

    static void spi_edma_callback(unsigned int tccnum, unsigned int status)
    {

    if(tccnum == EDMA3_CHA_SPI0_TX)
    {
    EDMA3DisableTransfer(SOC_EDMA30CC_0_REGS, EDMA3_CHA_SPI0_TX, EDMA3_TRIG_MODE_EVENT);

    spi_edma_rx((unsigned char *)dma_rx, 8); //执行完这句后再次产生rx中断会发现dma_rx这个buffer中的前3个字节并不是master发出来的。

    }

    }
    else if(tccnum == EDMA3_CHA_SPI0_RX)
    { //能正常跑到这里,数据接收也正确
    EDMA3DisableTransfer(SOC_EDMA30CC_0_REGS, EDMA3_CHA_SPI0_RX, EDMA3_TRIG_MODE_EVENT);

    spi_edma_tx(data, 8);

    }
    } 能否在DMA的完成中断的处理函数中那样做TX和RX的切换?这样切换后发现有错误中断产生,但是

    能emr、 qemr、 ccerr这3个寄存器值都是0。如果我只进行rx的dma接收不做tx切换就不会出现问题。

  • 3个字不对,应该是cache数据不同步的问题吧

  • 你好,aytyy@163.com,可以共同讨论吗

  • 你的中断函数可以进入,能讨论一下吗,我的中断函数进不去

  • zy,

    从SPI的block diagram来看,你说的三个奇怪的数是合理的。

    因为你只是停止了EDMA接收通道,而SPI的接收通道还是继续在接收。从SPI的接收路径来看,有3个数据寄存器,在你重新打开EDMA的RX之前,这三个寄存器都是在前面就接收了的数据的。

    你可以查看SPIBUF的RXOVR状态验证一下。

  • 那个我现在也遇到这样的问题了,在发送完成后接收的数据有问题,那个RXOVR置1报错了,请问一下您是怎么解决的呢?


  • hello,tony,我也遇到了类似问题,请问怎么解决?我尝试采用SPIDisable才关闭SPI接收数据,但还是不稳定。