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.

CC3000 send() failing with packets larger than ~128 bytes?

Other Parts Discussed in Thread: MSP430FR5739

Hello again,

I'm having difficulty sending packets from my CC3000 with a size larger than 128 bytes.   The documentation on the CC3000 send() function seems to indicate that the maximum size of a data packet is about 1400 bytes, but I can't get anywhere near that.  When I call the send function with a size greater than ~128 bytes, the microcontroller hangs and requires a hard-reset.  On my client side, no data is received and the "read" request eventually times out.

I'm modifying the sensor example.  I'm trying to use the ADC to convert data from a microphone at ~22.05 kHz and send the raw data in packets of reasonable size to my computer for audio output.  The only real modification I made was to server.c:

At the top:

#define PACKET_SAMPLES 64 // 64 shorts = 128 bytes OK.  128 shorts = 256 bytes fails send()
unsigned short packetPrefix = 0x0DBE; // ( '\r', 0xBE' )
unsigned short packetSuffix = 0xEF00; // ( 0xEF, 0x00 )
unsigned short dataPacket[ PACKET_SAMPLES + 2 ]; // 132 bytes
volatile unsigned int adcVal = 0;

And further down:

// Check whether we received the DATA command from the client
// telling us to begin sending data to it.
if(strncmp(requestBuffer,"DATA",strlen("DATA")) == 0)
{
    // Set up the microphone pin for input to ADC
    P3OUT &= ~BIT0; // Set P3.0 to low
    P3DIR &= ~BIT0; // Set P3.0 to Input
    P3REN |= BIT0; // Enables a pulldown resistor on P3.0
    P3SEL0 &= ~BIT0; // Enable GPIO on P3.0
    P3SEL1 &= ~BIT0; // Enable GPIO on P3.0
    P3DIR &= ~BIT0; // Set P3.0 to Input... again?

    // Copy the packet prefix and suffix
    dataPacket[ 0 ] = packetPrefix;
    dataPacket[ ( sizeof( dataPacket ) / sizeof( short ) ) - 1 ] = packetSuffix;

    while(currentCC3000State() & CC3000_CLIENT_CONNECTED)
    {
        // Start Sending Data to server
        // Send data to CC3000
        hci_unsolicited_event_handler();
        unsolicicted_events_timer_disable();
        toggleLed(CC3000_SENDING_DATA_IND);
       
        // Set up ADC to sample from microphone pin
        ADC10CTL0 &= ~ADC10ENC; // Ensure ENC is clear
        ADC10CTL0 = ADC10ON + ADC10SHT_5; // Set up 96 ADC10CLK cycles for sample and hold
        ADC10CTL1 = ADC10SHP + ADC10CONSEQ_0; // Consider setting this to ADC10CONSEQ_2
        ADC10CTL2 = ADC10RES; // Set 10 bit resolution
       
        ADC10MCTL0 = ADC10INCH_13; // Select P3.0 as ADC input
        ADC10IV = 0x00; // Clear all ADC10 channel int flags
       
        // Fill the data packet
        for( pidx = 0; pidx < PACKET_SAMPLES; pidx++ )
        {
            ADC10IFG = 0;
            ADC10CTL0 &= ~ADC10ENC;
            ADC10CTL0 &= ~ADC10SC;
            ADC10CTL0 |= ADC10ENC + ADC10SC ; // Start conversion

            while( ADC10CTL1 & BUSY ); // Wait for conversion to finish...

            adcVal = ADC10MEM0<<4; // Shift this right four
            dataPacket[ 1 + pidx ] = ( short )adcVal;
            __no_operation(); // Debug?
        }

        __no_operation();
 
        bytesSent = send(clientDescriptor, (unsigned char *)dataPacket, sizeof(dataPacket), 0);
        if (bytesSent != sizeof(dataPacket))
        {
            bytesSent = send(clientDescriptor, (unsigned char *)dataPacket, sizeof(dataPacket), 0);
            if (bytesSent != sizeof(dataPacket))
            {
                // Check if socket is still available
                curSocket = getsockopt(clientDescriptor, SOL_SOCKET, SOCKOPT_NONBLOCK , &optval, (socklen_t*)&optlen);
                if (curSocket != 0)
                {
                    closesocket(clientDescriptor);
                    terminalPrint("Client Disconnected\r\n");
                    clientDescriptor = -1;
                    unsetCC3000MachineState(CC3000_CLIENT_CONNECTED);
                }
            }
        }
       
        unsolicicted_events_timer_init();
}

Let me know if you see anything blatently wrong.  One thing I think might be an issue is the fact that this application seems to fill the ram almost entirely.  I can't actually allocate a 1k array (512 shorts) in the stack because the 16k of RAM appears to be mostly used...  This would be great because there appears to be quite a bit of overhead involved with actually sending a packet from the CC3000 (the ADC conversion rate is not the factor keeping me from real-time operation -- the packet rate is...)

Thanks in advance for any help!

-Griff

  • Hello Griff,

    Have you tried setting break points to see just where the code hangs?

    What is the size of pidx?

    Thanks,

  • Greenja,

    Good thought.  I just went back and double-checked.  It is indeed hanging on send().  pidx goes from 0 to 127 (from the for loop, when PACKET_SAMPLES = 128, and dataPacket has size 128 + 2 = 130 (260 bytes) ) which indexes dataPacket well within its bounds.  There seems to be no memory errors...

    -Griff

  • In the send() function, is there a limit to what the data length size can be?

  • Greenja,

    Yes, I checked that first.  It appears to be a maximum size of 1460 bytes (according to socket.h).  I can't even get it to send 256 bytes...

    -Griff

  • Unfortunately I don't have the device or software.  There is probably a simpler way to do this, but you can add a condition where you test for the count to be 128 and then step through the function to see what is going on. 

  • greenja,

    I didn't really think I could step into the external libraries within CCS, but as it turns out -- I was wrong!  I stepped into the send function and found out that I have a failure within SpiWrite.  Specifically, I enter this condition within spi.c (part of the "CC3000 Spi" library) and get "stuck here forever."

    // The magic number that resides at the end of the TX/RX buffer (1 byte after the allocated size)
    // for the purpose of detection of the overrun. If the magic number is overriten - buffer overrun
    // occurred - and we will stuck here forever!
    if (wlan_tx_buffer[CC3000_TX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER)
    {
        while (1)
        ;
    }

    Still trying to figure out what this means, and how I got here -- I gotta head out for a while; anyone have any brilliant ideas?

    -Griff

  • Do a search for that CC3000_BUFFER_MAGIC_NUMBER or comment out the while statement and see what happens.

    Also, find and change what the CC3000TX_BUFFER_SIZE is to something much larger.

  • Alright!  I fixed it!

    In order to send larger packets, you'll need to increase the size of the transmit buffer.  Same applies to the receive buffer with recv().

    This is a two step-process.  First, change the value of CC3000TX_BUFFER_SIZE in CC3000_Common.h within the CC3000HostDriver project.  First, determine the size that the buffer should be as explained here: (http://processors.wiki.ti.com/index.php/CC3000_Host_Programming_Guide#TX_and_RX_buffers).  

    The calculation for the actual size of buffer for reception and transmission is as follows:

    Given the maximal data payload size that is expected to be received by application, the required buffer is

    max(CC3000 MINIMAL RX BUFFER SIZE, DESIRED PAYLOAD DATA + HCI DATA HEADER SIZE + SPI HEADER SIZE + RECVFROM ARG LENGTH + 1)

    E.g. For using RX data payload of 30 Bytes, the RX buffer size will be:
    max(119, 30 + 5 + 5 + 24) = 119.

    E.g. For using RX data payload of 100 Bytes, the RX buffer size will be:
    max(119, 100 + 5 + 5 + 24) = 134.

    I need to send packets of 512 shorts (1024 bytes), so my Tx buffer size should be 1058 bytes. There's probably a better way to do this, but I just changed line 122:

    // #define CC3000_TX_BUFFER_SIZE (CC3000_MINIMAL_TX_SIZE)
    #define CC3000_TX_BUFFER_SIZE  1058

    Then rebuild the CC3000HostDriver.

    If you try to rebuild your binary now, in my case SensorApplication, you'll get a linker error, something like this:

    "../lnk_msp430fr5739.cmd", line 124: error #10099-D: program will not fit into
       available memory.  run placement with alignment fails for section
       ".FRAM_DATA" size 0x49a .  Available memory ranges:
       FRAM_DATA    size: 0xf0         unused: 0xf0         max hole: 0xf0      
    >> Compilation failure

    The TX and RX buffer are stored in a special memory segment called "FRAM_DATA".  You'll need to increase the size of this memory segment.  Do this by editing your lnk_msp430fr5739.cmd file (I found it in Source/CCS/SensorApplication/).  You'll notice that FRAM_DATA has length 0x00F0 (240 bytes).  We need to increase this size to the required size (in this case 0x049A).  This causes a difference of 0x049A - 0x00F0 = 0X03AA

    We need to change the FRAM origin and length to make up for this change in FRAM_DATA length.  We simply add 0x03AA to FRAM origin and subtract 0x03AA from length. The final change looks like:

    FRAM_DATA : origin = 0xC200, length = 0x049a
    FRAM : origin = 0xC69A, length = 0x38E6

    Rebuild SensorApplication and all should be well!

    Thanks for the help!

    -Griff