CC3000 Host Programming Guide

From Texas Instruments Wiki
Jump to: navigation, search

Return to CC3000 Main page

This wiki addresses the software package that is provided by TI for an external microcontroller that acts as a host processor. The software package implements the CC3000 host driver and a demonstration application.


Contents

Assumptions

Familiarity with:

  • Standard SPI operation
  • Quick Start application

CC3000 Host Driver Architecture Overview

Overview

The CC3000 device is designed to be a WLAN peripheral, which is simple to integrate and easy to use. For this purpose, the CC3000 integrates a fully-featured 802.11 protocol stack, personal security supplicant for 802.11, and an internet protocol (IP) networking stack. The host driver is designed to enable access to the CC3000 hardware with minimal burden to the host platform.

The key properties of the CC3000's host driver are:

  • Modular: allows easy configuration and adjustment of the host driver content to meet required functionality and capabilities while minimizing its footprint
  • Readable: the source code is well documented.
  • Portable: minimal platform and operating system (OS) dependencies

System Block Diagram

The figure below shows the CC3000 host driver modules
Cc3000 driver diagram.PNG

Description

The system has two demarcation lines:
• CC3000 user application programming interfaces (APIs)
• Transport layer APIs

This document focuses on the user APIs and architecture and the serial peripheral interface (SPI). The CC3000 user APIs define interfaces (I/Fs) exposed to the end user that allow interaction with the CC3000 device. Interaction with the device occurs over an SPI transport layer according to the device-specific APIs. APIs reside on top of an encapsulation layer called the host controlled interface (HCI). APIs are defined in a manner that is agnostic to the SPI layer.

The user APIs are organized into four silos to reflect the four different entities that correspond within the device (see figure below). These are:

  • WLAN APIs, which interact with the underlying entity that is responsible for 802.11 protocol implementation
  • Network stacks APIs, which interact with the embedded network stack. These APIs comply with the well-known Berkeley socket APIs and are easy to use.
  • Embedded network application APIs, which interact with the embedded networking application delivered as a complementary part of the on-chip content. These include basic networking applications that the user can leverage (for example, ping utility and DNS).
  • Nonvolatile memory (NVMEM) APIs, which configure the external CC3000 device EEPROM, where most of the configuration is stored.
Note: The sample applications make use of these NVMEM APIs to write the system configuration assuming that they are run on a non-configured device. Therefore, it is up to the user to write system configuration information (using the NVMEM APIs) only when there is a change.

Cc3000 host api.PNG

Each API group has associated commands and events. Events include two main types: unsolicited events and events triggered by the device.

  • Unsolicited events are not triggered by the CC3000 host driver and are initiated on the CC3000 device (for example, one unsolicited event, Init Complete, comes after the WLAN_EN line is asserted and the CC3000 finishes its initialization process).
  • Triggered events are those incoming to the CC3000 host driver as a result of a command sent to the device.

By Structure

API Function Calls

API function calls are commands issued by the user from the application layer that trigger an activity of the device. The resulting behavior is function-specific and determined by the definition of the function and the context to which it is applied. The description of each API function reflects its expected behavior and use context. Unless otherwise specified, all functions have a return code that is delivered from the device using a command completion sequence specified in the events section.

*Queuing of commands or events is not available as part of the CC3000 host driver. As a result, only one outstanding command is processed at a time.
*ALL API function calls are blocking unless stated otherwise; thus, the user context is blocked until the API call executes. This does not imply, for example, that the function call does not return until the whole process triggered by the API command is finished. The function call returns as soon as the command is passed over transport to the device and the command response event is received (as described in the Command Response Events section).

Events

An event is a device-triggered behavior that results in an interruption of the host processor. Two types of events are generated by the CC3000 device:

  • Command response events
  • Unsolicited events

Command Response Events

Command response events are generated as a result of a command issued to the device when the command has reached the point that either the command is completed or the long-term process is triggered. It is used by the device to return control to the caller with the appropriate result. Command response events carry an opcode that corresponds to the opcode of the command (API) that generates them and a status that reflects the return code of the calling function.

Unsolicited Events

The system provides unsolicited events triggered by the device. These events are generated asynchronously to indicate an occurrence of a system event. The following figure shows the basic event sequences:
Unsolicited Events Sequence.jpg

Unsolicited events that are generated by the device have their own unique opcode.

A callback function that corresponds to the event is invoked and carries on event handling thereafter, if the callback is registered by the user application.

All unsolicited events can be masked using a special command that controls the event mask. Command completion events cannot be masked (because they deliver the result code and thus are required to maintain API integrity) and are not passed to the user application.


Unsolicited Events list

The following lists all of the asynchronous events that can be generated by CC3000 device:

  • HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE – Notification that the first-time configuration process is complete
  • HCI_EVNT_WLAN_KEEPALIVE – Periodic keep-alive event between the CC3000 and the host microcontroller unit (MCU)
  • HCI_EVNT_WLAN_UNSOL_CONNECT – WLAN-connected event
  • HCI_EVNT_WLAN_UNSOL_DISCONNECT – Notification that CC3000 device is disconnected from the access point (AP)
  • HCI_EVNT_WLAN_UNSOL_DHCP – Notification of a Dynamic Host Configuration Protocol (DHCP) state change
  • HCI_EVNT_WLAN_UNSOL_INIT – Notification that the CC3000 device finished the initialization process
  • HCI_EVNT_WLAN_ASYNC_PING_REPORT – Notification of ping results
  • HCI_EVNT_ASYNC_ARP_WAITING – Event indicating that ARP request was sent out by the device. Wait until the HCI_EVNT_ASYNC_ARP_DONE event is received.
  • HCI_EVNT_ASYNC_ARP_DONE – ARP response is received by the device. Stop waiting and send the data.
Unsolicited ARP events

With the SDK release v1.14, the unsolicited ARP events HCI_EVNT_ASYNC_ARP_WAITING and HCI_EVNT_ASYNC_ARP_DONE should be used for controlling the TCP/UDP traffic. An example to use these events with the UDP sendto API (in a loop) is given below. Here, the first sendto call will initiate an ARP request to the remote device (This generates the event HCI_EVNT_ASYNC_ARP_WAITING at the host). The application should wait until the ARP response is received(i.e. until the HCI_EVNT_ASYNC_ARP_DONE event is received at the host).

Note: Use of these events is not required for multicast/broadcast transactions.

enum 
{
    ARP_INIT = 1,
    ARP_IN_PROGRESS = 2,
    ARP_DONE
} ulArpStatus;

void CC3000_UsynchCallback(long lEventType, char * data, unsigned char length)
{
    if (lEventType == HCI_EVNT_ASYNC_ARP_DONE)
    {
       ulArpStatus = ARP_DONE;
    }

    if (lEventType == HCI_EVNT_ASYNC_ARP_WAITING)
    {
       ulArpStatus = ARP_IN_PROGRESS;
    }  
}

void start_udp_client()
{
    unsigned char firstSend = 1;
    ulArpStatus = ARP_INIT;
    .
    .
    .

    while(1)
    {
        sendto(ulSocket,sendBuf, sizeof(sendBuf),0,&tSocketAddr,sizeof(sockaddr));
        
        if(firstSend == 1)
        {   
            while(ulArpStatus == ARP_INIT || ulArpStatus == ARP_IN_PROGRESS);              
            firstSend = 0;
        }
    }
}

Special Events

There is one exceptional unsolicited event for which a callback is not possible: The purpose of the unsolicited Number Of Completed Packets event is to notify the host driver that data packet transmission has occurred. For more information, see the section on Data Transmission and Reception.

Callbacks

Callbacks are user-provided functions that carry a predefined template and deliver unsolicited events to a user-controlled implementation or to trigger a system behavior of the user application. The number of callbacks used by the CC3000 driver is minimized to avoid any processing overhead incurred by the callback mechanism. The callbacks inform on asynchronous events that occur during operation. It is impossible to call an API function from the callback context. The callbacks supported by the CC3000 driver are:

  • Init callback
Allows processing on initialization completion and enables an asynchronous initialization procedure for the device. In systems with other activities to commence in parallel with CC3000 system initialization, init callback provides notification that the device is ready to connect and resume WLAN networking-related activity.
  • API event callback
Delivers system-triggered events to the user for user-specific handling.
  • Patch callback
Provides the CC3000 device with an initialization script if it is stored in the host file system by the user application. The user can provide a callback function for the event handler of the patch request event that comes from the CC3000 device.


Example Breakthrough of the API Function Call

Overview

This section provides a brief guided code overview, including a discussion of function calls within an example API function call, starting from the highest layer (API call) to the lowest layer (SPI interaction).

API Call Example

For example, consider an implementation of a socket API:

When a socket function call is executed, the API function socket encapsulates all of the required API-specific parameters in the packet to be sent over the SPI and passes those parameters to the host-controller interface (HCI) layer. The HCI layer adds HCI-specific parameters to the packet and passes the packet to the SPI transport layer. An SPI transport layer sends the packet over the SPI based on the SPI protocol. The following figure shows the resulting packet
API packet structure.jpg

From the code perspective, the following code is within the API call:

socket(int domain, int type, int protocol)
{
    unsigned short int arg_len;
    int ret;
    unsigned char *ptr;
    bsd_socket_args_t *args;

    arg_len = 0;
    ret = EFAIL;
    ptr = tSLInformation.pucTxCommandBuffer;
    args = (bsd_socket_args_t *)(ptr + HEADERS_SIZE_CMD);

    //
    // Fill in HCI packet structure
    //
    arg_len = sizeof(bsd_socket_args_t);

    args->domaint = domain;
    args->protocol = protocol;
    args->type = type;

    //
    // Initiate a HCI command
    //
	hci_command_send(HCI_CMND_SOCKET, ptr, arg_len);

    //
    // Since we are in blocking state - wait for event complete
    //
    SimpleLinkWaitEvent(HCI_CMND_SOCKET, &ret);

    //
    // Process the event
    //
    errno = ret;

    set_socket_active_status(ret, SOCKET_STATUS_ACTIVE);

    return(ret);
}

You can see that socket parameters, such as socket type and socket domain are inserted into the buffer at the offset:

args = (bsd_socket_args_t *)(ptr + HEADERS_SIZE_CMD);
args->domaint = domain;

As soon as preparation is complete, the packet is passed to the HCI layer, which updates the HCI layer header of the packet:

hci_command_send(HCI_CMND_SOCKET, ptr, arg_len);

The function returns only after the Command Complete event returns from the CC3000 device:

SimpleLinkWaitEvent(HCI_CMND_SOCKET, &ret);

Note the use of the sizeof operator:

arg_len = sizeof(bsd_socket_args_t);

It is assumed that the arguments bsd_socket_args_t are of packed type and int is defined as 4 bytes. While porting the code to a different MCU, you must stay within these assumptions, or replace each int variable with an explicit long type.

HCI Layer Example

The HCI layer encapsulates a packet received from the API with the opcode total length and submits it for transmission to the SPI transport layer as follows.

unsigned short
hci_command_send(unsigned short usOpcode, unsigned char *pucBuff,
                     unsigned char ucArgsLength)
{
    hci_cmnd_hdr_t *hci_cmnd_hdr_ptr;

    hci_cmnd_hdr_ptr = (hci_cmnd_hdr_t *)(pucBuff + SPI_HEADER_SIZE);

    hci_cmnd_hdr_ptr->ucType = HCI_TYPE_CMND;
    hci_cmnd_hdr_ptr->usOpcode = usOpcode;
    hci_cmnd_hdr_ptr->ucLength = ucArgsLength;

    //
    // Update the opcode of the event we will be waiting for
    //
    SpiWrite(pucBuff, ucArgsLength + sizeof(hci_cmnd_hdr_t));


    return(0);
} 

The function receives as an argument an opcode of the command to be sent, a pointer to the buffer, and the length of arguments as part of the buffer. First, space for the SPI header is made at the beginning of the buffer, and then the required fields in the buffer are filled. Because the offset of arguments within the buffer is the same for all commands, there is enough room left for the HCI parameters. Pay attention to the use of the sizeof parameter in the function. Ensure that the structures are packed and int is 4 bytes long or otherwise change the int type to the long type.


CC3000 Serial Port Interface

This section is a brief overview for the CC3000 serial port interface.
NoteNote: Please refer to the cc3000 Serial Port Interface's detailed description. This page will address, master write /read operations, bytes explanation, and provide you with sample code.

Overview

The SPI is based on the five-line, master/slave communication model as shown in the following figure:
Masterslave communication model.jpg

The lines are described as follows:

I/O Description
CLCK(1) Clock (~0 to 16 MHz) from host to slave
nCS(2) nCS (active low) signal from host to slave
MOSI Data from host to slave
IRQ(3) Interrupt from slave to host
MISO Data from slave to host


  • (1)CLCK provides a clock to the SPI interface on the CC3000 device.
  • (2)nCS selects a CC3000 device, indicating that a master wants to communicate to the CC3000 device.
  • (3)IRQ is a dual-purpose slave to the master direction line: in SPI IDLE state while no data transfer is active, driving IRQ low indicates to the master that the CC3000 device has data to pass to it; driving IRQ low following nCS deassertion indicates that the CC3000 device is ready to receive data. All behaviors are explained in detail in the following sections.

Protocol Description

The SPI protocol is used to communicate with the CC3000 device from the host MCU that is acting as the SPI master while the CC3000 device is the SPI slave. The protocol is an extension of the existing standard SPI. The endianness on transport is assumed to be most-significant bit (MSB) first.

The clock and phase settings for the SPI are configured such that the data is sampled on the falling edge of the clock cycle. Note that different MCU may use different naming conventions in order to configure SPI clock phase and polarity, For example, MSP430 uses UCCKPL and UCCKPH for clock polarity and phase respectively. Both are set to 0, indicating that the data is sampled on the falling edge of the clock cycle. The more generic convention is CPOL and CPHA, however, in order to configure sampling on the falling edge of the clock cycle, CPHA is set to 1.

All data sent or received over the SPI interface must be 16-bit aligned. A padding byte is added where required. Each packet passing on the SPI bus consists of a 5-byte SPI header followed by user data and optionally by a padding byte so that the whole length is 16-bit aligned, as shown in the next Figure.
SPI header.jpg


The first byte of the header is an operation opcode (READ or WRITE) followed by two bytes that indicate the size of the payload length (including the alignment byte). Two busy bytes then follow to conclude the header.

The data payload directly follows the last byte of the header. The padding byte is added when the length of the payload part of the packet is even.

NoteNote: Please refer to the cc3000 Serial Port Interface's detailed description. This page will address, master write /read operations, bytes explanation, and provide you with sample implementation.

CC3000 NVMEM API’s

Overview

CC3000 uses internal NVMEM (EEPROM) in order to store system related parameters and use them when appropriate. Given this new feature, it is now possible for a host application to use and manage a part of the CC3000 internal EEPROM for its own purposes. Thus, the EEPROM is divided into two main sections, system files and user files. The system files remain as before. The user files make use of the remaining space.

The EEPROM stores radio frequency (RF) calibration parameters, network configuration parameters, and patches. Most NVMEM locations are not written directly by the CC3000 host driver but rather indirectly by API calls that trigger NVMEM changes. Special API functions allow read or write operations on the NVMEM by the CC3000 host driver.

NoteNote: The structure mentioned here applies to service pack 1.10 and above. For older service pack such as 1.7, please refer to EEPROM user interface up to service pack 1p7.

EEPROM structure overview

The end of system files section is address 0x6A30. Taking into account the 32KB EEPROM size, the remaining size for the user files section is 5584 bytes. However, the two first file entries are used for CC3000 internal use as the following table describes:

 

File ID
(numerical)
File ID File address(offset)
File Size (bytes)
Real Used Size (bytes)
Parameter
0 NVMEM_NVS_FILEID 0x50 0x1A0 0x1A RF Calibration results table(generated automatically by TX Bip)
1 NVMEM_NVS_SHADOW_FILEID 0x1F0 0x1A0 0x1A  
2 NVMEM_WLAN_CONFIG_FILEID 0x390 0x1000 0x64 WLAN configuration
3 NVMEM_WLAN_CONFIG_SHADOW_FILEID 0x1390 0x1000 0x64  
4 NVMEM_WLAN_DRIVER_SP_FILEID  0x2390 0x2000 variable WLAN Driver ROM Patches
5 NVMEM_WLAN_FW_SP_FILEID 0x4390 0x2000 variable WLAN FW Patches
6 NVMEM_MAC_FILEID 0x6390 0x10 0x10 6 bytes of MAC address
7 NVMEM_FRONTEND_VARS_FILEID 0x63A0 0x10 0x10  
8 NVMEM_IP_CONFIG_FILEID 0x63B0 0x40 0x40 IP configuration
9 NVMEM_IP_CONFIG_SHADOW_FILEID 0x63F0 0x40 0x40  
10 NVMEM_BOOTLOADER_SP_FILEID 0x6430 0x400 variable Bootloader Patches
11 NVMEM_RM_FILEID 0x6830 0x200 0x7F Radio parameters
12 NVMEM_AES128_KEY_FILEID 0x6A30 0x10 0x10 AES128 key file
13 NVMEM_SHARED_MEM_FILEID 0x6A40 0x50 0x44 Host-CC3000 shared memory file
14 NVMEM_USER_FILE_1_FILEID 0x6A90 variable variable 1st user file
15 NVMEM_USER_FILE_2_FILEID variable variable variable 2nd user file


The fileIDs can be grouped as follow

  1. Offsets 0, 1, 3, 7, 9: CC3000 generated section: Refers to the part of NVMEM that is self-generated by the CC3000 device or to the section that is generally updated by module vendors.
  2. Offsets 2, 6, 8, 11: Customer's configurable section: Refers to the section that is, mainly indirectly, configured by the customer.
  3. Offsets 4, 5, 10: TI service pack section: Programmed with the help of APIs but with content provided by TI.
  4. Offsets 12, 13: These two sections are used for smart config
    NoteNote: It is advised not to address this file for other purposes even when not using encrypted Smart Config.
    • NVMEM_AES128_KEY_FILEID: used by CC3000 to store the AES128 key used during Smart Config procedure in case the procedure is encrypted.
    • 'NVMEM_SHARED_MEM_FILEID': used by CC3000 to interact with the Host during Smart Config procedure.
  5. Offsets 14, 15: User Files
    Taking all the above into account, the user is left with 5488 bytes divided into up to 2 files: NVMEM_USER_FILE_1_FILEID and NVMEM_USER_FILE_2_FILEID.

EEPROM data consists of several files accessible either directly or indirectly. The indirect approach triggers the CC3000 host, which at the end writes to EEPROM. The direct approach triggers CC3000 NVMEM API calls to directly write to the file within EEPROM. Each file has a unique ID and, depending on the file, either a constant or variable size. The following files are modified by customers by triggering the appropriate APIs (indirect approach):

  • NVMEM_WLAN_CONFIG_FILEID, by adding or removing WLAN policies, as described , by adding or removing WLAN profiles, both described in the EEPROM Update section.
  • NVMEM_IP_CONFIG_FILEID, by changing the IP configuration by the help of Netapp IP Configuration APIs, see EEPROM Update section.
  • NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_BOOTLOADER_SP_FILEID, and NVMEM_WLAN_FW_SP_FILEID can be written using either method.
The content of these files is a patch provided by Texas Instruments for different parts of the CC3000 device. Patches can be upgraded but only using the files provided by TI.

EEPROM Update

MAC Address update process

The EEPROM can be updated directly using NVMEM APIs of the CC3000 device and indirectly using different APIs that invoke updates, such as the addition of profiles, which stores a profile in the NVMEM. It is recommended that most EEPROM content not be altered directly. The file that can be altered using NVMEM_Write operation is: MAC Address file – file ID NVMEM_MAC_FILEID.

The following figure shows the MAC update process.
MAC update process.png

Patches Update Process – Download of Patches from Host

CC3000 patches can be sored in the CC3000 Host and downloaded from it. Please refer to the CC3000 Patch Programmer application and guide.

CC3000 WLAN API

Overview

CC3000 WLAN APIs provide a way for the application to trigger the connection process, update WLAN policy, and perform scans to discover the WLAN AP. This section describes basic activities required to implement WLAN operations. The following basic operations are required to be performed on the CC3000 device related to WLAN.

  • First-time configuration: Required to configure the CC3000 product to connect to the AP; assumes that no I/O ports exist on the product.
  • WLAN connection creation and disconnection
  • WLAN profiles definition and policy definition
  • WLAN scan configuration and read of WLAN scan results

Creating Profiles and Policies

WLAN policy defines three options available to connect the CC3000 device to the AP:

  • If Auto Connect is turned on, the C3000 device tries to connect to any AP it detects during scanning. To set this option, use wlan_ioctl_set_connection_policy(1, 0, 0).
  • If Fast Connect is set, the CC3000 device tries to automatically reconnect to the last AP connected to each time the connection fails or the device is rebooted. To set this option, use wlan_ioctl_set_connection_policy(0, 1, 0).
  • If Use Profiles is set, the CC3000 device tries to connect to an AP from profiles. To turn this option on, use wlan_ioctl_set_connection_policy(0, 0, 1).

NoteNote: The device must be reset before a policy can be applied. Profiles must first be added to the CC3000 device before they can be used.

A WLAN profile provides the information required to connect to a given AP, including the SSID, security parameters, and AP keys. Each profile describes one AP. Because profiles are stored in the NVMEM, they are preserved during device reset. To add a profile, use the following API: wlan_add_profile(SSID, security params, priority) ;

Up to 7 profiles are supported.
If several profiles configured the device chose the highest priority profile, within each priority group, device will chose profile based on security policy, signal strength, etc parameters.
All the profiles are stored in CC3000 NVMEM.

Creating WLAN Connection

The following methods can be used to create a WLAN connection:

  • The first-time configuration feature of the CC3000 device. This is a simple way to create a profile. Afterward, if the policy allows connecting with profiles, connection is established automatically.
  • Connecting explicitly to a given AP
  • Using WLAN policy and profiles to define which AP to connect to and then creating a connection indirectly by letting the CC3000 device scan and select the AP according to those definitions. No matter by what means the connection was created, an API netapp_ipconfig can be used to get an information on current AP the device is connected to and on the IP settings of the device.

First time configuration

The first-time configuration is used to set up a WLAN configuration of the device when the final product (for example, a sensor connected to the CC3000 device) has no input/output capability. For more information on the first-time configuration process, see the CC3000 First-Time Configuration Guide Wiki.

The first-time configuration provides a means to create a profile that is stored in the CC3000 NVMEM. The connection behavior depends on the policy. The following figure shows a generic flow of operation for the first-time configuration and assumes that the device wants to connect automatically to the AP described by the profile.
FirstTimeConfig process.PNG

Please note that there is currently a limitation in First Time Configuration: Up to 3 First Time Configuration profiles can be stored in the non-volitile memory. Attempt to run 4-th time First Time Configuration, may succeed, yet the profile will not be stored in the NVMEM and device will not be able to establish a connection. Note also that running first time configuration twice to the same AP, will create 2 different profiles.

Creating WLAN Connection explicitly

If the SSID of the AP to connect is known, the CC3000 device can be required to connect explicitly to this AP. The application can require one-time configuration to the AP, in which case the policy must be set to all zero, or it can require connecting to the same AP each time. The following figure shows the sequence required to connect explicitly to the AP one time.
Creating an explicit connection to AP.png
 
*Please Note: Using explicit connection to AP configured with security type WEP, please confirm that the key is set as ASCII and not as HEX.


Using WLAN policy and profiles

WLAN policy determines how the CC3000 device automatically connects to the AP. More specifically, the wlan_set_connection_policy controls the following:

  • If Auto Connect is turned on, the CC3000 device tries to connect to any AP it detects during scanning.
  • If Fast Connect is set, the CC3000 device tries to reconnect automatically to the AP with which it was last connected.
  • If Use Profiles is set, the CC3000 device tries to connect to an AP from profiles.
Profiles describe an AP: Each profile includes the SSID of the AP together with the security parameters required to connect to the AP. To add a profile and connect to the AP using the profile, the flow shown in the figure below can be used.
Connecting by a help of policy and profiles.png


NoteNote: Multiple profiles were added In the flow shown in the figure below. In this situation, connection is attempted to the highest priority AP. If connection to the highest priority AP fails, connection is attempted to the next highest-priority AP, and so on until a connection is successful.

Performing WLAN scan

A WLAN scan detects nearby APs along with the received signal-strength indication (RSSI) at which the APs are heard and allows the CC3000 device to connect to the detected APs (see figure below). The first WLAN scans must be enabled using the wlan_ioctl_set_scan_params WLAN API; the following scan results can then be read using the wlan_ioctl_get_scan_results WLAN API.

Enabling and reading scan results.png

CC3000 Socket API

Overview

Socket layer APIs establish TCP/IP connectivity between devices, assuming that the underlying WLAN transport is initialized and connected. Because all API socket layer APIs are blocking by nature, the socket layer APIs are almost identical to the standard BSD layer APIs.

NoteNote: Socket operations must follow a successful WLAN connection.

Data Transmission and reception

Data Transmission Overview

Data transmission occurs through the socket layer interface using the standard commands, Send and Sendto, that are part of the BSD API. Selecting which command to use depends on the socket type: for TCP, use Send; for UDP, use Sendto. The fact that Send and Sendto are blocking APIs does not guarantee that the data has been sent over the air on return from the function call rather than received and stored in the CC3000 internal TX queue. Moreover, the CC3000 host driver and the CC3000 device exchange information on the number of free buffers during device initialization. From that point on, the CC3000 host driver does not submit for transmission packets if there are no free buffers on the CC3000 side. The following figure shows how this is achieved:
Registration process.jpg


At initialization the number of free buffers is stored in a variable on the CC3000 host driver side. Each attempt to send tests the variable. If its value is more than 0, sending the packet proceeds and the value of the variable is reduced by 1. Otherwise, the packet must wait in a busy loop until the value becomes greater than 0. The number of completed packets event comes as an unsolicited event; thus, a frequency of the transmission operation influences a frequency of calls for the unsolicited event handler.

Data Reception Overview

Data reception is achieved using the Recv or Receive_from command, depending on the socket type. Use Recv for TCP sockets; use Recv_from for UDP sockets.

Concatenation is not supported by the CC3000 host driver. If the socket transmits packets of length N, the reception flow expects to read up to N bytes.
Receive/Receive_from commands function as blocking APIs: The function returns either on timeout of socket activity or when data is received. If it is required to poll for data presence on a given socket, select functionality can be used, as shown in the figure below.
Take action based on return sockets.jpg

The following code describes the use of the select functionality:
FD_ZERO( &readSet );
FD_ZERO( &writeSet );
FD_ZERO( &exceptSet );

FD_SET( ReadSock,  &readSet);
FD_SET(WriteSock,   &writeSet);

rc = select( MAX(ReadSock, WriteSock)+1, &readSet, &writeSet, &exceptSet, timeout );

// perform send on the write socket if it is ready to receive next chunk of data
if (FD_ISSET(WriteSock, &writeSet) )
{
….
}

// perform read on read socket if data available
if (FD_ISSET(ReadSock,  &readSet))
{
// perform receive
} 

TCP Socket API

Client TCP socket connection

The following figure shows the flow required to open a regular TCP client connection.
TCP socket connection.png

Server TCP sockets connection

The main distinction between a client connection and a server connection is that when establishing the server TCP connection, a stage occurs during which the device listens on the server socket for incoming connections. The connection is established only after a request arrives. On the other hand, the client TCP connection is established as soon as connect() is called. The following shows the flow used to establish a server connection.
Server side connection establishment flow.png
 
*Please Note that The accept() API call is now supports the non-blocking mode of operation.

 Using non-blocking accept() mode, the host user application will not be stalled while the TCP connection with the remote client has not been established yet.

 For more information please refer to: Non blocking accept wiki page.

Sending and Receiving data over TCP socket

Data is transmitted and received over TCP sockets after a connection is established. The BSD API Send and Recv commands are used with TCP sockets; Sendto and Recvfrom API commands are used transmit and receive data with UDP sockets.

Because the data is sent over the TCP connection-oriented socket, the peer device ACKs the data only once when TCP_WINDOW is full or after timeout expires. Usually TCP_WINDOW is 1 KB; thus, sending a TCP packet that is too short significantly decreases network performance.

UDP Socket API

Client UDP socket connection

Because of the connectionless nature of the UDP, the client UDP connection requires only the creation of the socket (see figure below).
Client UDP connection.png

Please note that it is recommended to run a gethostbyname bsd command before the first ever transmission of data over the new socket.In case DNS server, which is required by gethostbyname is unavailable, it is recommended to run netapp_ping_send API command which is available in the group of netapp API's.

Server UDP socket connection

Running the UDP server requires only that the bind operation be performed on the created socket. The Sendto and Recvfrom API commands are used to send or receive data (see figure below).
Server UDP connection.png
 

 

TX complete indication

The TX complete feature's main functionality is to indicate the host whenever it is safe to shutdown CC3000.

For more detailed description you may refer to TX Complete Feature.



CC3000 NETWORK CONFIGURATION API

Overview

Configuration API is provided in order to allow host to perform basic configuration of CC3000 device such as:

  • Configuring IP address either static or DHCP.
  • Setting up the MAC address of the device.
  • Reading the current network status.

Configuring MAC and IP Address

Configuring the MAC address requires running the NVMEM Write API call with file ID 6.

The IP address has two possible configurations: Assignment of the static IP address or using DHCP.

For the static IP configuration, the NetappDHCP API call is triggered with a non-0 IP address and subnetmask parameters. Otherwise, the 0 IP address is passed to the API call and informs a device that DHCP must be used. The following figure shows the required behavior.
Configuring MAC and ip address.png


Reading network status

A user application might want to read the network status of the connection; for example, an IP address received by the DHCP or the AP of a device connected using profiles (if more than one profile is defined).

The following API call can be used to read the network status of the connection:

void netapp_ipconfig( tNetappIpconfigRetArgs * ipconfig )

Where the pointer to the tNetappIpconfigRetArgs points to the structure filled with the configuration on return from the function call. For details on the structure, see the CC3000 API Doxygen Documentation.

void netapp_ipconfig( tNetappIpconfigRetArgs * ipconfig )


Appendix


CC3000 Build Options

CC3000 Host Driver is compiled with optimization feature enabled in both, IAR and CCS IDE.

The setup configuration is described in the following table:

       

   IAR   CCS
         MSP430     Stellaris     MSP430
IDE version     5.50.2       6.40.2         5.2
Platform version MSP430F5739 LM4F232H5QD MSP430F5739
SW Release version    1.12.6.10      4.12.6.10     1.12.6.10
Optimization flag high-balanced   high-balanced        -O2



The optimization configuration on IAR is applied as described in the following figure.

Cc3000 configuration.PNG
 

The optimization configuration on CCS is applied as described in the following figure.

Cc3000 configuration CCS.PNG


Remote Debug Capabilities

In order to expedite debugging and support, it is now possible to fetch logging information from the CC3000 internals.

The logging information is divided into two levels, driver and firmware. Each level is retrieved via a separate hardware pin that is available from CC3000 chipset.

The procedure that the customer needs to follow is very simple and does not require any special technical knowledge.

NoteNote: For more information please refer to: Logger Capabilities page.

Memory consumption 


Flash consumption

In general, the flash memory contains code and constant variables only.

The CC3000 host driver code size in MSP430F5739 (when compiled in IAR high balanced option) is ~7.2 KB.

The programmer must take into account the additional code required by the application when calculating the total amount of code for the program.

RAM consumption

The RAM size breaks down into global variables, buffers and stack.

Stack

The stack size is derived from the most demanding API. Please note that the full call stack needs to be considered. The programmer must take into account the additional stack required by the application and configure it accordingly prior to compilation. Failing to do so may result in stack overrun during run-time.
In addition, different platforms may yield different stack size requirements.
The stack size required for the CC3000 host driver on MSP430F5739, using IAR high balanced optimization is ~190 bytes.

Global variables

The global variables used by the Host Driver and the SPI include explicit and implicit declarations. Implicit declarations denote global variables that are included automatically by the linker during link time.
The global variables size required for the CC3000 host driver in MSP430F5739, using IAR high balanced optimization is 99 bytes.

TX and RX buffers

The buffer structure is as follows:

Buffers.PNG
 

The CC3000 host driver supports flexible buffers size for TX and RX.

The size can be varied from a pre-defined minimum value to a pre-defined maximum value.

The buffers size is set during compilation time.

The TX buffer is used for sending commands and data to the CC3000.

The RX buffer is used for receiving events and data from the CC3000.

These buffers are composed of an SPI header, an HCI header, arguments and payload.

The most demanding API in terms of buffer consumption consumes 119 bytes. I.e. the minimal size for RX and TX buffers is 119 bytes each.


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.


Given the maximal payload data size that is expected to be transmitted by application, the required buffer is
max(CC3000 MINIMAL TX BUFFER SIZE, DESIRED PAYLOAD DATA + HCI DATA HEADER SIZE + SPI HEADER SIZE + SENDTO ARG LENGTH + 1)

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


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

The extra ‘1’ in the equations is used for overrun detection during runtime.


Note: The maximum TX and RX payload size is 1468 bytes each (excluding the arguments size, HCI header and SPI header). It is the user responsibility to make sure the buffer size is not exceeded.

Note: In MSP430F5739 the TX and RX buffers are located in FRAM because of the MSP limited RAM size. Not every flash type can be used for TX and RX buffers.


Tiny Driver Compilation Option

Certain MCU have limited RAM and Flash size, therefore a Tiny Driver Compilation option exist.

Tiny driver target is low cost MCU with small size of RAM and Flash: 512B RAM, 16KB flash.

Using The Tiny Driver Compilation option will create a tiny version of our host driver with lower data, stack and code consumption.

Doing that by removing non mandatory API (Using Compilation flag).

Reduce overall RAM consumption size to ~256b and driver code size as much as possible.

For more information please refer to: Tiny Driver Support wiki page.

Site Map