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.

CC3100 - stream data hangs

Other Parts Discussed in Thread: CC3100, MSP430FR5969

Hi Everyone,

I'm doing a test on the CC3100 and it hangs when I stream data from host through CC3100 to a telnet client.

I set the CC3100 in AP mode, a telnet server with port #23, use Teraterm from 64-bit windows 7 to connect to the cc3100. After a connection establish between host tenet server and Teraterm telnet client, the host streams 16 bytes of data per packet in interval of 88 milliseconds. The test runs about 4 minutes then hangs.

My host MCU is PIC24EP512GU810. There is no OS. I use getting_started_with_wlan_ap example with some modification to stream data from a telnet connection, SPI interface.

I attached a sniffer from 1 run using WireShark. The test ran correctly up to packet #3291 which acknowledged packet #3190.

I stepped through the driver and discovered it stopped at driver.c line #1232: VERIFY_PROTOCOL(SyncCnt < SL_SYNC_SCAN_THRESHOLD);

The driver hung at: #define _SlDrvAssert(line )  { while(1); }

The functions and macro are defined as following:

#define SL_PROTOCOL_HANDLING        SL_HANDLING_ASSERT 

#define VERIFY_PROTOCOL(expr)                   _SL_ASSERT(expr)

#define _SlDrvAssert(line )  { while(1); }

#define _SL_ASSERT(expr)            { if(!(expr)){_SlDrvAssert(__LINE__); } }

Does anyone know how to fix the issue with CC3100 driver?

Thanks in advance!

telnetStreamHung.zip
  • Hi,

    We are not familiar with such an issue.
    Will it be possible for you to send us your code, or at least a part of it recreating the issue, so we can debug the issue?

    If not, are you able to capture the spi data received when the problem happens? can you please provide a SPI dump of the receive buffer while you are stuck trying to read data from the SPI in driver.c?

    Thanks,
    Alon

  • Hi Alon,

    This is my code. 

    _i32 wifi_service_socket(_i16 *serverSockID, _i16 *clientSockID,
                             WIFI_SOCKET_STATUS_E *sockStatus)
    {
        SlSockAddrIn_t  Addr;
        SlSockAddrIn_t  LocalAddr;
    
        _u16 idx = 0;
        _u16 AddrSize = 0;
    
        _i16 i = 0;
        _i32 Status = 0;
        _i16 recvSize = 0;
    
        *sockStatus = WIFI_SOCKET_INACTIVE;
    
        recvSize = BUF_SIZE;
        if (NETWORK_NO_SOCKET == *clientSockID) {
            *clientSockID = sl_Accept(*serverSockID, ( struct SlSockAddr_t *)&Addr,
                                      (SlSocklen_t*)&AddrSize);
    
            if (0 < *clientSockID) {
                *sockStatus = WIFI_SOCKET_CONNECT;
    
                return SUCCESS;
            }
        }
    
        if ((SL_EAGAIN == *clientSockID) ||
            (SL_ENSOCK == *clientSockID) ||
            (SL_POOL_IS_EMPTY == *clientSockID) ||
            (SL_INEXE == *clientSockID)) {
            CLI_Write(" [TCP Server] SL_EAGAIN\n\r");
            *clientSockID = NETWORK_NO_SOCKET;
        }
        else if (0 > *clientSockID) {
            sl_Close(*clientSockID);
            *serverSockID = NETWORK_NO_SOCKET;
    
            send_uart_string_hex(SERIALIN, (char *)clientSockID, 1);
            CLI_Write(" [TCP Server] Accept connection Error \n\r");
            ASSERT_ON_ERROR(*clientSockID);
        }
        else {
    
            /* Connection had been made */
            Status = sl_Recv(*clientSockID, &(uBuf.BsdBuf[BUF_SIZE - recvSize]), recvSize, 0);
            if (0 < Status) {
    
                /* There is data */
                *sockStatus = WIFI_SOCKET_DATA;
                g_recvSize  = Status;
    
            }
            else if ((Status != SL_EAGAIN) && (Status != SL_POOL_IS_EMPTY)) {
                /* connection closed */
                CLI_Write("status == 0\n\r");
    
                /* Already disconnected */
                Status = sl_Close(*clientSockID);
                *clientSockID = NETWORK_NO_SOCKET;
    
                *sockStatus = WIFI_SOCKET_DISCONNECT;
            }
            else {
                /* Timeout ??? */
                *sockStatus = WIFI_SOCKET_TIMEOUT;
            }
        }
    
        return SUCCESS;
    }
    
    void telnet_server_service_request(void)
    {
        signed short retVal = 0;
    
        WIFI_SOCKET_STATUS_E sockStatus = 0;
    
        __eds__ unsigned char *temp_data_out_ptr = NULL;
        TELNET_SERVER_CB *telnet_cb_ptr, *top_telnet_ptr;
    
    
        top_telnet_ptr = &telnet_server_cb[TELNET_PORT_CT];
        for (telnet_cb_ptr = &telnet_server_cb[0];
            telnet_cb_ptr < top_telnet_ptr; telnet_cb_ptr++) {
    
            wifi_service_socket(&g_telnet_SockID,
                                &telnet_cb_ptr->tcp_socket_index,
                                &sockStatus);
    
            switch (sockStatus) {
                case WIFI_SOCKET_CONNECT:
                    /* Connected */
                    send_uart_string(SERIALIN, "TN Conn\r\n", 9);
                    telnet_cb_ptr->telnet_session_state = TELNET_CONNECTED;
    
                    ImsNetConnected = TRUE;
    
                    break;
                case WIFI_SOCKET_DISCONNECT:
                    /* Disconnected */
                    reset_single_telnet_cb(telnet_cb_ptr);
    
                    // if no telnet connect ???
                    ImsNetConnected = FALSE;
                    break;
                case WIFI_SOCKET_DATA:
    
                    if (TELNET_CONNECTED == telnet_cb_ptr->telnet_session_state) {
                        /* Has data */
                        wifi_read_data_eds(&telnet_cb_ptr->cmd_in_ptr,
                                           telnet_cb_ptr->cmd_top,
                                           telnet_cb_ptr->cmd_base,
                                           &telnet_cb_ptr->cmd_ct);
                    }
                    else {
                        telnet_cb_ptr->telnet_session_state = TELNET_DISCONN_REQUESTED;
                    }
    
                    break;
                case WIFI_SOCKET_TIMEOUT:
                    /* Timeout */
                    break;
                case WIFI_SOCKET_INACTIVE:
                    break;
    
                default:
                    break;
            }
    
            switch (telnet_cb_ptr->telnet_session_state) {
                case TELNET_CONNECTED:
                    if (0 < telnet_cb_ptr->cmd_ct) {
    
                        telnet_process_cmd(telnet_cb_ptr);
                    }
    
                    if (telnet_cb_ptr->data_ct) {
    
                        retVal = wifi_write_data_eds(telnet_cb_ptr->data_out_ptr,
                                                     telnet_cb_ptr->data_top,
                                                     telnet_cb_ptr->data_base,
                                                     telnet_cb_ptr->data_ct,
                                                     telnet_cb_ptr->tcp_socket_index);
    
                        if (0 < retVal) {
                            telnet_cb_ptr->data_ct -= retVal;
    
                            temp_data_out_ptr = telnet_cb_ptr->data_out_ptr + retVal;
                            if (temp_data_out_ptr >= telnet_cb_ptr->data_top) {
                                telnet_cb_ptr->data_out_ptr = telnet_cb_ptr->data_base +
                                                              (retVal -
                                                               (telnet_cb_ptr->data_top - telnet_cb_ptr->data_out_ptr));
                            }
                            else {
                                telnet_cb_ptr->data_out_ptr = temp_data_out_ptr;
                            }
                        }
                        else {
                            //????
                            telnet_cb_ptr->data_ct = 0;
                        }
                    }
                    break;
    
                case TELNET_DISCONN_REQUESTED:
                    if (0 == telnet_cb_ptr->data_ct) {
                        retVal = sl_Close(telnet_cb_ptr->tcp_socket_index);
                        if (0 == retVal) {
                            telnet_cb_ptr->telnet_session_state = TELNET_DISCONN_SENT;
                            telnet_cb_ptr->telnetTmrTick = TEN_S_PER_TEN_MS;
                        }
                    }
                    break;
                default:
                    break;
            }
        }
    }
    
    _i32 wifi_write_data_eds(__eds__ _u8 *src_ptr, __eds__ _u8 *top_ptr,
                             __eds__ _u8 *base_ptr, _u16 dataLength,
                             _i16 clientSockID)
    {
        _i32 retVal = -1;
        _i16 i = 0;
        _u8 *dstDataPtr = NULL;
    
        dstDataPtr = &uBuf.BsdBuf[0];
    
        for (i = 0; i < BUF_SIZE && i < dataLength; i++, dstDataPtr++) {
    
            *dstDataPtr = *src_ptr;
    
            src_ptr++;
            if (src_ptr == top_ptr) {
                src_ptr = base_ptr;
            }
        }
    
        retVal = sl_Send(clientSockID, &(uBuf.BsdBuf[0]), i, 0);
    
        return retVal;
    }
    
    

    Thanks,

    Dennis

  • Hi Dennis,

    The zip package you shared only contain the wireshark logs. If possible please share the source code for us to help recreating the issue.

    Regards,
    Ankur
  • Ankur,
    The TI maintenance team broke my link to a source file last week, see my Dec 04 post. They changed the way to post message. How can we attached, upload a file though this forum?

    Here is the code

    _i32 wifi_service_socket(_i16 *serverSockID, _i16 *clientSockID,
                             WIFI_SOCKET_STATUS_E *sockStatus)
    {
        SlSockAddrIn_t  Addr;
        SlSockAddrIn_t  LocalAddr;
    
        _u16 idx = 0;
        _u16 AddrSize = 0;
    
        _i16 i = 0;
        _i32 Status = 0;
        _i16 recvSize = 0;
    
        *sockStatus = WIFI_SOCKET_INACTIVE;
    
        recvSize = BUF_SIZE;
        if (NETWORK_NO_SOCKET == *clientSockID) {
            *clientSockID = sl_Accept(*serverSockID, ( struct SlSockAddr_t *)&Addr,
                                      (SlSocklen_t*)&AddrSize);
    
            if (0 < *clientSockID) {
                *sockStatus = WIFI_SOCKET_CONNECT;
    
                return SUCCESS;
            }
        }
    
        if ((SL_EAGAIN == *clientSockID) ||
            (SL_ENSOCK == *clientSockID) ||
            (SL_POOL_IS_EMPTY == *clientSockID) ||
            (SL_INEXE == *clientSockID)) {
            CLI_Write(" [TCP Server] SL_EAGAIN\n\r");
            *clientSockID = NETWORK_NO_SOCKET;
        }
        else if (0 > *clientSockID) {
            sl_Close(*clientSockID);
            *serverSockID = NETWORK_NO_SOCKET;
    
            send_uart_string_hex(SERIALIN, (char *)clientSockID, 1);
            CLI_Write(" [TCP Server] Accept connection Error \n\r");
            ASSERT_ON_ERROR(*clientSockID);
        }
        else {
    
            /* Connection had been made */
            Status = sl_Recv(*clientSockID, &(uBuf.BsdBuf[BUF_SIZE - recvSize]), recvSize, 0);
            if (0 < Status) {
    
                /* There is data */
                *sockStatus = WIFI_SOCKET_DATA;
                g_recvSize  = Status;
    
            }
            else if ((Status != SL_EAGAIN) && (Status != SL_POOL_IS_EMPTY)) {
                /* connection closed */
                CLI_Write("status == 0\n\r");
    
                /* Already disconnected */
                Status = sl_Close(*clientSockID);
                *clientSockID = NETWORK_NO_SOCKET;
    
                *sockStatus = WIFI_SOCKET_DISCONNECT;
            }
            else {
                /* Timeout ??? */
                *sockStatus = WIFI_SOCKET_TIMEOUT;
            }
        }
    
        return SUCCESS;
    }
    
    void telnet_server_service_request(void)
    {
        signed short retVal = 0;
    
        WIFI_SOCKET_STATUS_E sockStatus = 0;
    
        __eds__ unsigned char *temp_data_out_ptr = NULL;
        TELNET_SERVER_CB *telnet_cb_ptr, *top_telnet_ptr;
    
    
        top_telnet_ptr = &telnet_server_cb[TELNET_PORT_CT];
        for (telnet_cb_ptr = &telnet_server_cb[0];
            telnet_cb_ptr < top_telnet_ptr; telnet_cb_ptr++) {
    
            wifi_service_socket(&g_telnet_SockID,
                                &telnet_cb_ptr->tcp_socket_index,
                                &sockStatus);
    
            switch (sockStatus) {
                case WIFI_SOCKET_CONNECT:
                    /* Connected */
                    send_uart_string(SERIALIN, "TN Conn\r\n", 9);
                    telnet_cb_ptr->telnet_session_state = TELNET_CONNECTED;
    
                    ImsNetConnected = TRUE;
    
                    break;
                case WIFI_SOCKET_DISCONNECT:
                    /* Disconnected */
                    reset_single_telnet_cb(telnet_cb_ptr);
    
                    // if no telnet connect ???
                    ImsNetConnected = FALSE;
                    break;
                case WIFI_SOCKET_DATA:
    
                    if (TELNET_CONNECTED == telnet_cb_ptr->telnet_session_state) {
                        /* Has data */
                        wifi_read_data_eds(&telnet_cb_ptr->cmd_in_ptr,
                                           telnet_cb_ptr->cmd_top,
                                           telnet_cb_ptr->cmd_base,
                                           &telnet_cb_ptr->cmd_ct);
                    }
                    else {
                        telnet_cb_ptr->telnet_session_state = TELNET_DISCONN_REQUESTED;
                    }
    
                    break;
                case WIFI_SOCKET_TIMEOUT:
                    /* Timeout */
                    break;
                case WIFI_SOCKET_INACTIVE:
                    break;
    
                default:
                    break;
            }
    
            switch (telnet_cb_ptr->telnet_session_state) {
                case TELNET_CONNECTED:
                    if (0 < telnet_cb_ptr->cmd_ct) {
    
                        telnet_process_cmd(telnet_cb_ptr);
                    }
    
                    if (telnet_cb_ptr->data_ct) {
    
                        retVal = wifi_write_data_eds(telnet_cb_ptr->data_out_ptr,
                                                     telnet_cb_ptr->data_top,
                                                     telnet_cb_ptr->data_base,
                                                     telnet_cb_ptr->data_ct,
                                                     telnet_cb_ptr->tcp_socket_index);
    
                        if (0 < retVal) {
                            telnet_cb_ptr->data_ct -= retVal;
    
                            temp_data_out_ptr = telnet_cb_ptr->data_out_ptr + retVal;
                            if (temp_data_out_ptr >= telnet_cb_ptr->data_top) {
                                telnet_cb_ptr->data_out_ptr = telnet_cb_ptr->data_base +
                                                              (retVal -
                                                               (telnet_cb_ptr->data_top - telnet_cb_ptr->data_out_ptr));
                            }
                            else {
                                telnet_cb_ptr->data_out_ptr = temp_data_out_ptr;
                            }
                        }
                        else {
                            //????
                            telnet_cb_ptr->data_ct = 0;
                        }
                    }
                    break;
    
                case TELNET_DISCONN_REQUESTED:
                    if (0 == telnet_cb_ptr->data_ct) {
                        retVal = sl_Close(telnet_cb_ptr->tcp_socket_index);
                        if (0 == retVal) {
                            telnet_cb_ptr->telnet_session_state = TELNET_DISCONN_SENT;
                            telnet_cb_ptr->telnetTmrTick = TEN_S_PER_TEN_MS;
                        }
                    }
                    break;
                default:
                    break;
            }
        }
    }
    
    _i32 wifi_write_data_eds(__eds__ _u8 *src_ptr, __eds__ _u8 *top_ptr,
                             __eds__ _u8 *base_ptr, _u16 dataLength,
                             _i16 clientSockID)
    {
        _i32 retVal = -1;
        _i16 i = 0;
        _u8 *dstDataPtr = NULL;
    
        dstDataPtr = &uBuf.BsdBuf[0];
    
        for (i = 0; i < BUF_SIZE && i < dataLength; i++, dstDataPtr++) {
    
            *dstDataPtr = *src_ptr;
    
            src_ptr++;
            if (src_ptr == top_ptr) {
                src_ptr = base_ptr;
            }
        }
    
        retVal = sl_Send(clientSockID, &(uBuf.BsdBuf[0]), i, 0);
    
        return retVal;
    }
    

    Regards,

    Dennis

  • Hi Dennis,

    I tested the scenario you described in your post on mysetup using MSP430 but couldn't reproduce the issue. Test ran for 45 minutes without any issue.
    I couldn't test your code as it's partial with many dependencies.
    Can you share the captured spi data received/send when the issue occurs?

    Regards,
    Ankur
  • Hi Dannis,

    I hope you were able to resolve the issue. I am closing this thread, if issue still exists please open a new thread with a link to this one for reference.

    Regards,
    Ankur
  • I also had this issue this past weekend. I am running the CC3100 with the MSP430FR5969. I am sending short UDP messages to a server and then going into LPM3. The process repeats after every sleep period. My test ran for a longer period of time, so maybe it will help, although my sleep periods are pretty long. I sent 74 messages over the course of many hours before I got hung up here.

    Perhaps SL_ERROR would be better to use than SL_ASSERT so that the application code can decide what to do if the error occurred.

    What causes this error though? My serial port monitor shows that my last message was sent, connection was closed, and the device was disconnected from the ap. I would normally get two more messages that the CC3100 was turned off and that the MSP was going to sleep.

    I intend to add the watchdog function once my application code is more stable, but I wouldn't want the watchdog to have to have to come to the rescue every day.