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.

[PC(Client) to CC3100(Server) TCP communication] Communication delay is too severe.

Other Parts Discussed in Thread: CC3100, CC3200

Hello. 

I wanted to implement a high-speed communication.

CC3100 is TCP Throughput 13Mhz, UDP Throughput 16Mhz in datasheet.

UDP Throughput is ok.

about 1.6~1.8ms ( Packet size 1442 Bytes).

However, TCP is not.

about 200ms ( Packet size 1452 Bytes )

I do not know why the TCP slow speed.

-lab condition-

STM32F407 + CC3100(Eva)

SPI : 21Mhz (about 20Mhz)

Commu : TCP, UDP Communication

PC : 802.11 B/G/N WiressLan(Usb Type)  / TCP Client Program (Modbus client)

PC(STAtion) <-> CC3100(AP) : Between about 30~50cm

Examples used "SPI_debug_tool", "tcp_socket", "udp_socket", "Getting_started with wlan ap" 

<UDP Wireshark Capture>

sned to data (CC3100 -> PC)

about 1.5~1.8ms

<TCP Wireshark Capture>

 

Speed is also a problem, but a strange one more point.

269. PSH ACK ( PC->CC3100(Receive) )

270. PSH ACK ( CC3100(Send) -> PC )

271. ACK ( PC -> CC3100(ACK) )

total 210ms 

303. PSH ACK ( PC->CC3100(Receive) )

304. ACK ( CC3100(ACK) -> PC )

305. PSH ACK ( CC3100(Send) -> PC )

306. ACK ( PC -> CC3100(ACK) )

total 200ms

ACK Frame This is not regular.

The same result came out above.

Question.

1. ACK Frame parts that make this one exist in the Stack?

2. ACK Frame or affect the TCP communication speed? 

3. Did ACK Frame is sent from hardware?

4. Method of increasing the speed of the TCP is?  (Can you come up to much?)

  • Hi Cho,

    It looks to me like that your PC is waiting 200 ms to ACK the packets from the CC3200, right?

    Perhaps there are some server setting to be changed on that end?

    Also, try seeing the throughput when the CC3200 is doing all of the sending, or all of the receiving

    -Aaron
  • Hi Aaron.

    Note has your answer.

    I had to solve the above problems.

    "Delayed ACK" function was being used on a PC.

    Did not use the "Delayed ACK" TCP speed comes less than 3ms.

    There are further questions.
    TCP communication from a Client (PC) and sends the data to the Server (CC3100).

    And it gives the ACK sent from the PC to the Server (CC3100).

    The delay time of the ACK is about 1ms.

    Is there any way to reduce or eliminate the 1ms is?
  • Hi Cho,

    This depends on the server you are using and its configuration. I wouldn't be able to say how to configure your server to go faster. If you want to maximize throughput, increase the packet size.

    -Aaron
  • Hi Aaron!

    First, the server(CC3100) to upload the settings to a file.

    I had made the experiment by setting an example.

    Second, the TCP communication photos using an oscilloscope.

    In the above picture proceeds to receive the next transmission.

    CC3100 MCU data transfer at up to a total of 1.3ms.

    However, Wireshark takes about 3ms ~ 4ms.

    I also believed that the delay in this part of the CC3100 Flow.

    What do you think?

    int wifi_test(unsigned char b)
    {
        SlPingStartCommand_t PingParams = {0}; 
        SlPingReport_t Report = {0};
    
        _u8 SecType = 0;
        _i32 mode = ROLE_STA;
        _i32 retVal = -1;
    
        retVal = initializeAppVariables();
        ASSERT_ON_ERROR(retVal);
    
        CLR_STATUS_BIT(g_Status, STATUS_BIT_PING_DONE);
        g_PingPacketsRecv = 0;
    
        /*
         * Following function configures the device to default state by cleaning
         * the persistent settings stored in NVMEM (viz. connection profiles &
         * policies, power policy etc)
         *
         * Applications may choose to skip this step if the developer is sure
         * that the device is in its default state at start of application
         *
         * Note that all profiles and persistent settings that were done on the
         * device will be lost
         */
        retVal = configureSimpleLinkToDefaultState();
    
    		
        if(retVal < 0)
        {
            if (DEVICE_NOT_IN_STATION_MODE == retVal)
                UART_printf(" Failed to configure the device in its default state \n\r");
    
            LOOP_FOREVER();
        }
    
        UART_printf(" Device is configured in default state \n\r");
    
        /*
         * Assumption is that the device is configured in station mode already
         * and it is in its default state
         */
        mode = sl_Start(0, 0, 0);
    		 UART_printf(" sl_Start \n\r");
        if (ROLE_AP == mode)
        {
            /* If the device is in AP mode, we need to wait for this event before doing anything */
            while(!IS_IP_ACQUIRED(g_Status)) { _SlNonOsMainLoopTask(); }
        }
        else
        {
            /* Configure CC3100 to start in AP mode */
            retVal = sl_WlanSetMode(ROLE_AP);
            if(retVal < 0)
                LOOP_FOREVER();
    
            /* Configure the SSID of the CC3100 */
            retVal = sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SSID,
                    pal_Strlen(SSID_AP_MODE), (_u8 *)SSID_AP_MODE);
            if(retVal < 0)
                LOOP_FOREVER();
    
            SecType = SEC_TYPE_AP_MODE;
            /* Configure the Security parameter the AP mode */
            retVal = sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SECURITY_TYPE, 1,
                    (_u8 *)&SecType);
            if(retVal < 0)
                LOOP_FOREVER();
    
            retVal = sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_PASSWORD, pal_Strlen(PASSWORD_AP_MODE),
                    (_u8 *)PASSWORD_AP_MODE);
            if(retVal < 0)
                LOOP_FOREVER();
    
            retVal = sl_Stop(SL_STOP_TIMEOUT);
            if(retVal < 0)
                LOOP_FOREVER();
    
            CLR_STATUS_BIT(g_Status, STATUS_BIT_IP_ACQUIRED);
    
            mode = sl_Start(0, 0, 0);
            if (ROLE_AP == mode)
            {
                /* If the device is in AP mode, we need to wait for this event before doing anything */
                while(!IS_IP_ACQUIRED(g_Status)) { _SlNonOsMainLoopTask(); }
            }
            else
            {
                UART_printf(" Device couldn't be configured in AP mode \n\r");
                LOOP_FOREVER();
            }
        }
    
        UART_printf(" Device started as Access Point\n\r");
    
        /* Wait */
        UART_printf(" Waiting for clients to connect...!\n\r");
        while((!IS_IP_LEASED(g_Status)) || (!IS_STA_CONNECTED(g_Status))) { _SlNonOsMainLoopTask(); }
        UART_printf(" Client connected to the device \n\r");
        UART_printf(" Pinging...! \n\r");
    
        /* Set the ping parameters */
        PingParams.PingIntervalTime = PING_INTERVAL;
        PingParams.PingSize = PING_SIZE;
        PingParams.PingRequestTimeout = PING_REQUEST_TIMEOUT;
        PingParams.TotalNumberOfAttempts = PING_ATTEMPT;
        PingParams.Flags = 0;
        PingParams.Ip = g_StationIP; /* Fill the station IP address connected to CC3100 */
    
        /* Ping client connected to CC3100 */
        retVal = sl_NetAppPingStart((SlPingStartCommand_t*)&PingParams, SL_AF_INET,
                           (SlPingReport_t*)&Report, SimpleLinkPingReport);
    		
    		
    		
    		
        if(retVal < 0)
            LOOP_FOREVER();
    
        /* Wait */
        while(!IS_PING_DONE(g_Status)) { _SlNonOsMainLoopTask(); }
    
        if (0 == g_PingPacketsRecv)
        {
            UART_printf(" A STATION couldn't connect to the device \n\r");
            ASSERT_ON_ERROR(LAN_CONNECTION_FAILED);
        }
    
    			BsdTcpServer(502);
    
    		#if defined (UDP_Side)
    //		BsdUdpClient(1515);
    //		BsdUdpServer(1515);
    		#endif
    		
        return SUCCESS;
    		
    }
    
    
    static _i32 configureSimpleLinkToDefaultState()
    {
        SlVersionFull   ver = {0};
        _WlanRxFilterOperationCommandBuff_t  RxFilterIdMask = {0};
    
        _u8           val = 1;
        _u8           configOpt = 0;
        _u8           configLen = 0;
        _u8           power = 0;
    
        _i32          retVal = -1;
        _i32          mode = -1;
    
        mode = sl_Start(0, 0, 0);
    		        
        ASSERT_ON_ERROR(mode);
    		
    
    //    /* If the device is not in station-mode, try configuring it in station-mode */
    //    if (ROLE_STA != mode)
    //    {
    //			    
    //        if (ROLE_AP == mode)
    //        {
    
    //            /* If the device is in AP mode, we need to wait for this event before doing anything */
    //            while(!IS_IP_ACQUIRED(g_Status)) { _SlNonOsMainLoopTask(); }
    //        }
    //    
    //        /* Switch to STA role and restart */
    //        retVal = sl_WlanSetMode(ROLE_STA);
    //        ASSERT_ON_ERROR(retVal);
    
    //        retVal = sl_Stop(SL_STOP_TIMEOUT);
    //        ASSERT_ON_ERROR(retVal);
    
    //        retVal = sl_Start(0, 0, 0);
    //        ASSERT_ON_ERROR(retVal);
    
    //        /* Check if the device is in station again */
    //        if (ROLE_STA != retVal)
    //        {
    //            /* We don't want to proceed if the device is not coming up in station-mode */
    //            ASSERT_ON_ERROR(DEVICE_NOT_IN_STATION_MODE);
    //        }
    //    }
    
        /* Get the device's version-information */
        configOpt = SL_DEVICE_GENERAL_VERSION;
        configLen = sizeof(ver);
    
    	
        retVal = sl_DevGet(SL_DEVICE_GENERAL_CONFIGURATION, &configOpt, &configLen, (_u8 *)(&ver));
        ASSERT_ON_ERROR(retVal);
    ///////////////////////////////////////////////////////////////////////////////////////////////////////		
    
        /* Set connection policy to Auto + SmartConfig (Device's default connection policy) */
        retVal = sl_WlanPolicySet(SL_POLICY_CONNECTION, SL_CONNECTION_POLICY(1, 0, 0, 0, 1), NULL, 0);
        ASSERT_ON_ERROR(retVal);
    
        /* Remove all profiles */
        retVal = sl_WlanProfileDel(0xFF);
        ASSERT_ON_ERROR(retVal);
    
        /*
         * Device in station-mode. Disconnect previous connection if any
         * The function returns 0 if 'Disconnected done', negative number if already disconnected
         * Wait for 'disconnection' event if 0 is returned, Ignore other return-codes
         */
        retVal = sl_WlanDisconnect();
    
        if(0 == retVal)
        {
            /* Wait */
            while(IS_CONNECTED(g_Status)) {  }
        }
    
        /* Enable DHCP client*/
        retVal = sl_NetCfgSet(SL_IPV4_STA_P2P_CL_DHCP_ENABLE,1,1,&val);
        ASSERT_ON_ERROR(retVal);
    
    		
    		
        /* Set Tx power level for station mode
           Number between 0-15, as dB offset from maximum power - 0 will set maximum power */
        power = 0;
        retVal = sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, WLAN_GENERAL_PARAM_OPT_STA_TX_POWER, 1, (_u8 *)&power);
        ASSERT_ON_ERROR(retVal);
    
        /* Set PM policy to normal */
        retVal = sl_WlanPolicySet(SL_POLICY_PM , SL_NORMAL_POLICY, NULL, 0);
        ASSERT_ON_ERROR(retVal);
    
        /* Unregister mDNS services */
        retVal = sl_NetAppMDNSUnRegisterService(0, 0);
        ASSERT_ON_ERROR(retVal);
    
        /* Remove  all 64 filters (8*8) */
        pal_Memset(RxFilterIdMask.FilterIdMask, 0xFF, 8);
        retVal = sl_WlanRxFilterSet(SL_REMOVE_RX_FILTER, (_u8 *)&RxFilterIdMask,
                           sizeof(_WlanRxFilterOperationCommandBuff_t));
        ASSERT_ON_ERROR(retVal);
    
        retVal = sl_Stop(SL_STOP_TIMEOUT);
        ASSERT_ON_ERROR(retVal);
    
        retVal = initializeAppVariables();
        ASSERT_ON_ERROR(retVal);
    
        return retVal; /* Success */
    }
    
    
    static _i32 BsdTcpServer(_u16 Port) //init
    {
    
        SlSockAddrIn_t  Addr;
        SlSockAddrIn_t  LocalAddr;
    
    
    
    
        _u16           idx = 0;
    
        for (idx=0 ; idx<BUF_SIZE ; idx++)
        {
    //        uBuf.BsdBuf[idx] = (_u8)(idx % 10);
    			uBuf.BsdBuf[idx] = 0xFF;
        }
    
        LocalAddr.sin_family = SL_AF_INET;
        LocalAddr.sin_port = sl_Htons((_u16)Port);
        LocalAddr.sin_addr.s_addr = 0;
    
        sm.SockID = sl_Socket(SL_AF_INET,SL_SOCK_STREAM, 0);
        if( sm.SockID < 0 )
        {
            UART_printf(" [TCP Server] Create socket Error \n\r");
            ASSERT_ON_ERROR(sm.SockID);
        }
    
        sm.AddrSize = sizeof(SlSockAddrIn_t);
        sm.Status = sl_Bind(sm.SockID, (SlSockAddr_t *)&LocalAddr, sm.AddrSize);
        if( sm.Status < 0 )
        {
            sl_Close(sm.SockID);
            UART_printf(" [TCP Server] Socket address assignment Error \n\r");
            ASSERT_ON_ERROR(sm.Status);
        }
    
        sm.Status = sl_Listen(sm.SockID, 0);
        if( sm.Status < 0 )
        {
            sl_Close(sm.SockID);
            UART_printf(" [TCP Server] Listen Error \n\r");
            ASSERT_ON_ERROR(sm.Status);
        }
    
    
    		
        sm.newSockID = sl_Accept(sm.SockID, ( struct SlSockAddr_t *)&Addr,(SlSocklen_t*)&sm.AddrSize);
        if( sm.newSockID < 0 )
        {
            sl_Close(sm.SockID);
            UART_printf(" [TCP Server] Accept connection Error \n\r");
            ASSERT_ON_ERROR(sm.newSockID);
        }
    
    while(1)
    {
    			sl_Recv(sm.newSockID, uBuf.BsdBuf, BUF_SIZE, 0); //BsdBuf[BUF_SIZE]; BUF_SIZE = 1400;
    			sl_Send(sm.newSockID, uBuf.BsdBuf, BUF_SIZE, 0);
    }
    }