不知道算不算是一个ch582的bug

Ch582作为spi slave,用dma发送接收的时候

如果ch582先是dma接收,然后转为dma发送,则第一次发送是从dma缓冲区第8个字节开始发送,而不是第一个字节开发发送

从第二次以后发送就正常了,不知道是怎么回事。下面的是代码


int main()

{

    UINT8 i;

    UINT16 bEnd;

    UINT16 bStart;

    UINT16 n;

    UINT16 k;

    UINT16 len;



    SetSysClock(CLK_SOURCE_PLL_60MHz);


    /* 配置串口调试 */

    DebugInit();

    PRINT("SpiTest Start @ChipID=%02X\r\n", R8_CHIP_ID);

//#if 0

    /* 设备模式 */

    //GPIO12:CS

    //GPIO13:CLK

    //GPIO14:MOSI

    //GPIO15:MISO

    PRINT("1.spi0 mul slave mode \n");

//    GPIOA_ModeCfg(GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15, GPIO_ModeIN_PU);

    GPIOA_ModeCfg(GPIO_Pin_12 | GPIO_Pin_13| GPIO_Pin_14 | GPIO_Pin_15, GPIO_ModeIN_Floating); //在pcb上已经有上拉电阻了


    SPI0_SlaveInit();

    R8_SPI0_CTRL_MOD |= RB_SPI_MST_SCK_MOD;


    PRINT("R8_SPI0_CTRL_MOD=%x\r\n",R8_SPI0_CTRL_MOD); //空闲时 SCK 为高电平

    len = 30;

    for(i=0;i

        spiBuffrevW[i] = i;

    for(i=0;i

        PRINT("%02x ", spiBuffrevW[i]);

    PRINT("\r\n");

    while (1)

    {

        //接收3次

        for(n = 0;n<3;n++)

        {

            PRINT("recv=\r\n");

            R8_SPI0_CTRL_MOD |= RB_SPI_MOSI_OE;

            R8_SPI0_CTRL_MOD &= ~RB_SPI_MISO_OE;

            R8_SPI0_CTRL_MOD |= RB_SPI_FIFO_DIR;

            R16_SPI0_DMA_BEG = (uint32_t)spiBuffrev;

            R16_SPI0_DMA_END = (uint32_t)(spiBuffrev + len);

            R16_SPI0_TOTAL_CNT = len;

            R8_SPI0_INT_FLAG = RB_SPI_IF_CNT_END | RB_SPI_IF_DMA_END;

            R8_SPI0_CTRL_CFG |= RB_SPI_DMA_ENABLE |RB_SPI_DMA_LOOP;

            bStart = 0;

            while (1)

            {

                bEnd = GPIOA_ReadPortPin(GPIO_Pin_12);//检测cs引脚是否拉高,如果拉高了则结束

                if(bEnd==0)

                    bStart = 1;

                if(bStart && bEnd  //如果先检测到cs拉低,然后检测到拉高则结束

                        || (R8_SPI0_INT_FLAG & RB_SPI_IF_CNT_END))

                    break;

            }

            R8_SPI0_FIFO_COUNT = 0;

            R8_SPI0_FIFO_COUNT1 = 0;

            R8_SPI0_CTRL_CFG &= ~RB_SPI_DMA_ENABLE;

            int i;

            PRINT("fin=%x ",bEnd);

            for(i=0;i

                PRINT("%02x ", spiBuffrev[i]);

            PRINT("\r\n");

        }


        //作为设备模式发送3次

        //spi master第一次接收到的值从8开始  08 09 0A 0B 0C 0D 0E 0F ....

        //spi master第二次接收到的值从0开始  00 01 02 03 04 05 06 07 ....

        //spi master第三次接收到的值从0开始  00 01 02 03 04 05 06 07 ....

        //发送序列通过逻辑分析仪查看过了,应该不是spi master端的问题

        for(n = 0;n<3;n++)

        {

            PRINT("Send=%p \r\n",spiBuffrevW);


            PRINT("Send:%p cnt=%x cnt1=%x\r\n",spiBuffrevW,R8_SPI0_FIFO_COUNT,R8_SPI0_FIFO_COUNT1);

            for(i=0;i

                spiBuffrevW[i] = i; //初始化发送值,00 01 02 03 04 05 06 07 ....

            R8_SPI0_CTRL_MOD |= RB_SPI_MISO_OE;

            R8_SPI0_CTRL_MOD &= ~RB_SPI_MOSI_OE;

            R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR;

            R16_SPI0_DMA_BEG = (uint32_t)spiBuffrevW;

            R16_SPI0_DMA_END = (uint32_t)(spiBuffrevW+ len);

            R16_SPI0_TOTAL_CNT = len;

            R8_SPI0_INT_FLAG = RB_SPI_IF_CNT_END | RB_SPI_IF_DMA_END;

            R8_SPI0_CTRL_CFG |= RB_SPI_DMA_ENABLE |RB_SPI_DMA_LOOP;

            bStart = 0; //cs引脚是否拉底过

            while (1)

            {

                bEnd = GPIOA_ReadPortPin(GPIO_Pin_12); //检测cs引脚是否拉高,如果拉高了则结束

                if(bEnd==0)

                    bStart = 1;

                if(bStart && bEnd || (R8_SPI0_INT_FLAG & RB_SPI_IF_CNT_END))

                    break;

            }

            R8_SPI0_CTRL_CFG &= ~RB_SPI_DMA_ENABLE;

            PRINT("Send:cnt=%x cnt1=%x\r\n",R8_SPI0_FIFO_COUNT,R8_SPI0_FIFO_COUNT1);

            PRINT("fin=%x\r\n",bEnd);

        }

   }

    PRINT("END ...\n");


    while(1);

//#endif


    while(1);

}


您提供的代码有部分缺失,请提供能复现现象的工程发送到邮箱rzz@wch.cn


今天又测试了一下,发现了一个规律:

就是ch582作为slave用spi dma发送数据给host的时候,对两次发送的时间间隔有要求,如果间隔太小,就会出错

这个间隔和上一次spi clk的频率有关,频率越高需要的时间间隔越小

如果spi频率为10k,那么间隔需要500ms

如果spi频率为1M,则时间间隔需要1us,也就是两次发送之间要DelayUs(1)

如果spi频率为4M,则两次发送之间不需要delay


下面我再测试一下交替接收和发送的情况


只有登录才能回复,可以选择微信账号登录