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.

CC3200 通过SPI DMA接收的数据发送给TCP,出现大量误码的问题

Other Parts Discussed in Thread: CC3200

使用的是CC3200 LaunchPad,通过参考官方SPI-DMA的例程,再结合TCP例程写的一个程序。

实现的功能是,把CC3200作为从机,接收主机发来的数据,将数据再发送给TCP

定义了一个1024字节大小的数组,每次SPI-DMA接收1024个字节,然后把这1024个字节发送给TCP。

当我主机发送的速度很慢时,每秒几百字节时,用上位机可以看到TCP接收的数据接收了几数组一直都是正确的。

但是当我使用FPGA作为主机高速传输FPGA的速度为1.5MHZ时,用上位机可以看到TCP接收的数据前面一二组是正确的,但是后面的数据就全是错误的了。

并且当我使用FPGA作为主机传输的时候,上位机显示无线接收的速度才80K/B,这又是什么原因?

下面是我接收SPI-DMA数据和发送给TCP的部分程序

int WSPITransfer(unsigned long ulBase, int iSockID)
{
int iStatus;
while(1)
{
memset(g_ucRxBuff, 0x0, sizeof(g_ucRxBuff));
memset(g_ucTxBuff, 0x0, sizeof(g_ucTxBuff));
Slave_Receive(g_ucRxBuff, g_ucTxBuff, 1024);
iStatus=sl_Send(iSockID,g_ucRxBuff,1024,0);//将接收到的数据发送给TCP服务器
if(iStatus<=0)
{//错误处理
ASSERT_ON_ERROR(sl_Close(iSockID));
UART_PRINT("发送数据失败\n\r");
break;
}
}
return(iStatus);
}

  • 1、在程序中注意首先SPI接收到正确的数据,

    2、TCP将接收的数据完整的发送到IP端口,

    通常容易出问题的点是SPI传输的数据通过sl_send发送需要一段时间,此时新的SPI数据完成的接收导致数据出错,在TCP的传输中可以使用阻塞模式,等待TCP的数据完全传输后再接收新的SPI数据,保证接收和发送的数据一致

  • 因为FPGA作为主机发送的数据是源源不断过来的

    那如果设置为阻塞模式,等待TCP的数据完全传输后再接收新的SPI数据的话,会不会由于这段等待时间,丢失FPGA发送的数据。

  • 一开始我的程序是设置为非阻塞模式,查了下资料,CC3200默认状态为阻塞模式,那我将下面设置为非阻塞模式的函数删掉就是恢复默认变回阻塞模式了吧。

    实验了一下效果还是不行,还是会传输一定数据后,数据就都错了。

    SPI收到的数据是正确的。

    至于TCP发送数据的完整性,我认为会不会就是FPGA发送给CC3200的速度太快,SPI接收的速度,和发送给TCP的速度跟不上,所以导致TCP发送的数据不完整?如果是这个原因,我要怎么保证,SPI接收的速度和TCP发送速度一致?

    int BsdTcpClient(unsigned short usPort)

    {
    // int iCounter;
    // short sTestBufLen;
    SlSockAddrIn_t sAddr;
    int iAddrSize;
    int iSockID;
    int iStatus;
    // long lLoopCount = 0;

    // filling the buffer(填充缓冲区)
    // for (iCounter=0 ; iCounter<BUF_SIZE ; iCounter++)
    // {
    // g_cBsdBuf[iCounter] = (char)(iCounter % 10);
    // }

    // sTestBufLen = BUF_SIZE;

    //filling the TCP server socket address 填充TCP服务器套接字地址
    sAddr.sin_family = SL_AF_INET;
    sAddr.sin_port = sl_Htons((unsigned short)usPort);
    sAddr.sin_addr.s_addr = sl_Htonl((unsigned int)g_ulDestinationIp);

    iAddrSize = sizeof(SlSockAddrIn_t);

    // creating a TCP socket
    iSockID = sl_Socket(SL_AF_INET,SL_SOCK_STREAM, 0);//创建TCP套接字
    if( iSockID < 0 )
    {
    ASSERT_ON_ERROR(SOCKET_CREATE_ERROR);
    }

    // connecting to TCP server
    iStatus = sl_Connect(iSockID, ( SlSockAddr_t *)&sAddr, iAddrSize); //连接TCP服务器
    if( iStatus < 0 )
    {
    // error
    sl_Close(iSockID);
    ASSERT_ON_ERROR(CONNECT_ERROR);
    }
    //设置非阻塞模式
    long lNonBlocking=1;
    iStatus=sl_SetSockOpt(iSockID,SL_SOL_SOCKET,
    SL_SO_NONBLOCKING, &lNonBlocking,sizeof(lNonBlocking));
    if(iStatus<0)
    {
    sl_Close(iSockID);
    UART_PRINT("TCP Client faild\n\r");
    }
    //SPI 无线数据传输
    iStatus=WSPITransfer(GSPI_BASE,iSockID);
    if(iStatus<0)
    {
    UART_PRINT("WSPI Transfer failed\n\r");
    }

    iStatus = sl_Close(iSockID);//关闭TCP套接字
    //closing the socket after sending 1000 packets
    ASSERT_ON_ERROR(iStatus);

    return SUCCESS;
    }

  • 至于TCP发送数据的完整性,我认为会不会就是FPGA发送给CC3200的速度太快,SPI接收的速度,和发送给TCP的速度跟不上,所以导致TCP发送的数据不完整?如果是这个原因,我要怎么保证,SPI接收的速度和TCP发送速度一致?

    这个问题需要看你当前的网络状态下最大可允许的TCP传输速度是多少,需要将SPI的传输数据限定在这个无线速率之内,否则SPI的数据量大于无线传输的数据量肯定会导致数据出错的

  • 抱歉,我后来又再尝试了一下,似乎是SPI数据有问题。

    这次我用STM32给我的CC3200发送数据,不停地发送0x52,数组大小也是1024,SPI DMA还是一次接收1024个字节,有了更直观的发现。

    我发现同一数组内的1024个字节数据是相同的,但是并不是每个数组的数据都是正确的。并且我发送的0x52十六进制表示为0101 0010,我收到的错误的数据数组内都会是这八个的不同组合。也就是说我有可能收到00101001,10010010等等。

    但是我还是可以确定不管是STM32还是FPGA,我发送的数据准确性是没有问题。甚至CC3200发送给TCP的数据准确性应该也是没问题的。问题就出在CC3200SPI DMA接收数据,对数据进行处理的时候出现的问题。

    请问有没有更好的办法处理SPI-DMA收到的数据

  • 问题已解决。FPGA作为主机发送数据时,每个字节的间隙太小,CC3200截取八位数据读数的时候发生错位。

    稍微调大了FPGA发送每八个比特数据后的间隙就解决了这个问题。