CC3000 Module with AM335x Using Linux

From Texas Instruments Wiki
Jump to: navigation, search

Return to CC3000 Page


Adding a WIFI connection to an embedded system can be done in a number of ways. The approach of using the CC3000 offers the advantage that the MPU does not need to Host a TCP/IP stack as this is run on-board the CC3000 device. In this apps note we demonstrate the use of a simple Linux application running on the AM335x connected to a Texas Instruments(TI) CC3000 module (CC3000MOD). The hardware used for validating functionality consisted of a BeagleBone, a CC3000 module, and an RF cape to fit the CC3000 module to the BeagleBone’s GPIO connectors.

To simplify the way the CC3000 associates to an access point(AP) a protocol specific to TI called SmartConfig is used. In summary, a phone, tablet, or PC already connected to an AP can assist the connection of the CC3000 to the same AP. This is particularly useful for connecting head-less devices where WIFI functionality is needed but traditional methods of controlling the association and network connection are not possible. The use of this method requires an application running on Android, IOS, or Java and is downloadable from CC3000's Main page; refer to the download section, within the software block.



  1. 1x Beaglebone
  2. 1x Beaglebone RF Cape
  3. 1x CC3000EM, orderable from the TI eStore
  4. 1x Wi-fi Access Point
  5. 1x android tablet/smartphone


  1. Download the am335x-evm-sdk from the TI eStore and make sure that the arago-2011.09-armv7-linux-gnueabi-sdk toolchain is installed.
  2. Download the Smart Config Application for Android or iOS.

Hardware Setup

  1. Connect the BB hardware according to the figure below.
  2. Make sure the CC3000 module is facing the right way.
  3. Once this is done, connect the BeagleBone to a computer using a USB micro cable.

CC300 Beaglebone Hardware.png

Otherwise an Android Tablet, iPhone, iPAD is also necessary for the SmartConfig part.

Build System

Ubuntu 10.04 LTS
Distribution: Angstrom v2012.05
Target Kernel: 3.2.34
AM335x SDK version: 05.05 (used for SD card create)
Toolchain: arago-2011.09-armv7-linux-gnueabi-sdk from SDK under /linux-dev-kit

CC3000 Host driver: 1.10.1

Toolchain: arago-2011.09-armv7-linux-gnueabi-sdk found in the am335x-evm-sdk available from the TI website at:

The compiler can be found under $sdk/linux-devkit/arm-arago-linux-gnueabi/bin

Building the Kernel and Preparing SDcard

Derived from below and performed on an Ubuntu 10.04 LTS system.

Please install following missing utilities: diffstat, texi2html, makeinfo, chrpath

$ sudo apt-get install gawk wget git-core diffstat unzip texinfo build-essential
chrpath libsdl1.2-dev xterm

To configure the scripts and download the build metadata, do:

 $ cd ~/setup-scripts
$ MACHINE=beaglebone ./ config beaglebone 

To start kernel build:

$ MACHINE=beaglebone ./ bitbake virtual/kernel
$ MACHINE=beaglebone ./ bitbake systemd-gnome-image

Machine definition for beaglebone is here for interest -


Resultant images from build are here -


To make SD card image from build we are using the SD card utility from the AM335x SDK – any version will be fine.

$ cd /home/user/ti-sdk-am335x-evm-
$ sudo ./

Copy MLO, u-boot.img and uImage from Images folder to the first partition

$ cd ~/setup-scripts/build/tmp-angstrom_v2012_05-eglibc/deploy/images/beaglebone
$ mv MLO*git MLO
$ sudo cp MLO* /mnt/sdc1
$ mv u-boot.img u-boot.bin
$ sudo cp u-boot.bin /mnt/sdc1
$ sudo cp uImage /mnt/sdc1

Unpack the tarball to the root partition of your BeagleBone SD card.

$ sudo tar -xjv -C /media/rootfs -f *rootfs.tar.bz2

This assumes that the SD card has the root filesystem (ext3) partition mounted as /media/rootfs.

Building the Application

Make sure that the toolchain is installed in order to compile the application. Toolchain: arago- 2011.09-armv7-linux-gnueabi-sdk found in the am335x-evm-sdk available from the TI website at

The compiler can be found under $sdk/linux-devkit/arm-arago-linux-gnueabi/bin once it has been installed.
As can be found in the Makefile the compiler options used are:

-D _POSIX_C_SOURCE=2 # for Posix.2 standard and no BSD sockets.

To compile the source code edit the line CC= so that it point to the directory holding the compiler and then issue the make command at the command line.

$ cd /server2
$ make
$ sudo cp ./web /media/rootfs/home/root/
$ eject /media/rootfs/

Running the Demo

Access the BeagleBone using minicom. To do this enter minicom –s into a Linux terminal and then change the settings to point to the right ttyUSB* device. Then save the setup and exit and you will see the BeagleBone login. Navigate to the directory where the application is and start by typing ./web.

The application now starts and you should see a confirmation stating Starting at the command line and then Waiting for SmartConfig. At this point you should have pressed start on the phone.

|       |                  .-.           o o
|   |   |-----.-----.-----.| |   .----..-----.-----.
|       |     | __  |  ---'| '--.|  .-'|     |     |
|   |   |  |  |     |---  ||  --'|  |  |  '  | | | |
'---'---'--'--'--.  |-----''----''--'  '-----'-'-'-'
                 -' |
The Angstrom Distribution beaglebone ttyO0
Angstrom v2012.05 - Kernel 3.2.34
beaglebone login: root
Last login: Sat Jan 1 01:25:10 UTC 2000 on ttyO0
root@beaglebone:~# cd /home/root
root@beaglebone:~# ./web
Waiting for SmartConfig ...

Connect the phone with Smartconfig to the access point you want the CC3000 connected to. Start the smartconfig application and make sure the correct information is filled in. Make sure the Device name is “home_assistant” and DO NOT tick the box next to KEY. As below –

CC3000 Smart Config Phone.png

Once the CC3000 has completed SmartConfig another message appears on the screen stating SmartConfig Complete and the CC3000 should now be connected to the given access point. When the http server is ready the message WebServer running shows at the command line and at this point one can connect to the device by browsing to the device IP. Please note that the ip address will wary with the configuration of your access point. You should then see the following from the console.

SmartConfig Complete
WebServer running
Waiting for client

Using the Http server, a Serversocket is waiting for connections on port 80 with blocking call to accept(). Once a connection has been made a static page (const char page[] in basic_wifi_application.c) is transmitted and the socket is then closed. The program then loops back to the blocking accept() call waiting for another connection.

The Linux Application

The driver is based upon the MSP430 CC3000 Host Driver with the generic content still intact and changes being limited to mostly spi.c and board.c with corresponding header files. The main difference to that of the MSP implementation is that the interrupt has been put into a separate thread making a blocking call to poll(). This is one of the simplest ways of accessing interrupts from user space in Linux and was therefore the natural choice. There are a few minor alterations to driver files (due to types already being defined in Linux) and they are listed below after the board.c and spi.c alterations.


All references to the MSP430 hardware had to be removed and others had to be implemented in a Linux compliant way.

Functions altered:

ReadWlanInterruptPin()                     # read irq pin
WlanInterruptEnable()                      # enable irq
WlanInterruptDisable()                     # disable irq
pio_init()                                 # init gpio and configure pinmux
WriteWlanPin()                             # turn PWR_EN high or low

Functions added were:

gpio_export()                              # expose gpio to userspace.
gpio_unexport()                            # hide gpio from userspace.
gpio_set_dir()                             # set direction of gpio.
gpio_set_edge()                            # set edge on gpio.
gpio_set_value()                           # write value to gpio.
gpio_get_value()                           # get the current value on a gpio.
gpio_fd_open()                             # open a gpio for read/write.
setIRQ_EN()                                # set IRQ enabled flag used to turn on and off interrupts.
getIRQ_EN()                                # get IRQ enabled flag.
pinmux()                                   # set pinmux settings for the beaglebone cape (helper for pio_init()).

Functions removed because they were no longer needed:



The functions kept where:

SpiFirstWrite()                             # As were.
SpiWrite()                                  # As were.
SpiReadHeader()                             # As were.
SpiReadDataCont()                           # As were.
SpiTriggerRxProcessing()                    # As were.
SSIContReadOperation()                      # As were.

Functions altered.

SpiOpen()                                   # Added init of Linux spi structures
SpiClose()                                  # Added removal of spi structures
init_spi()                                  # Configuring the Linux spi settings
SpiPauseSpi()                               # Ignore Spi
SpiResumeSpi()                              # Enable Spi again
SpiWriteDataSynchronous()                   # Main write function using spi_ioc_message
SpiReadDataSynchronous()                    # Main read function using spi_ioc_message
IntSpiGPIOHander()                          # Kept but not an interrupt routine anymore

Functions added were:

err()                                       # error handler

Functions removed because they were no longer needed:


Alterations to Files in the Generic Driver


Struct timeval                              # Removed due to duplicate in Linux
typedef clock_t                             # Removed due to duplicate in Linux
typedef long suseconds_t                    # Removed due to duplicate in Linux


wlan_smart_config_set_prefix() # Removed else statement from if(cNewPrefix)


ENOBUF                                      # changed to CC_ENOBUF
__FD_SETSIZE                                # changed to __CC_FD_SETSIZE
fd_set                                      # changed to cc_fd_Set
fd_mask                                     # removed due to duplicate in Linux
__NFDBITS                                   # removed due to duplicate in Linux
__FDELT(d)                                  # removed due to duplicate in Linux
__FDMASK(d)                                 # removed due to duplicate in Linux
__FDS_BITS                                  # removed due to duplicate in Linux
__FD_ZERO(set)                              # removed due to duplicate in Linux
__FD_SET(d, set)                            # removed due to duplicate in Linux
__FD_CLR(d, set)                            # removed due to duplicate in Linux
__FD_ISSET(d, set)                          # removed due to duplicate in Linux
select()                                    # changed to cc_select
define htonl                                # removed because not big endian
define ntohl                                # removed because not big endian
define hotons(A)                            # removed because not big endian


select()                                    # changed to cc_select()
                                            # added #define _API_USE_BSD_CLOSE
                                            # added #define _API_USE_BSD_READ_WRITE



In order to use SPI from userspace in Linux a module called SPIDEV is used. This needs to be compiled in with the kernel. In the Angstrom Distribution used in this example this was already done. Otherwise If needed to be done manually there are a few things to change.

Kernel: CONFIG_SPIDEV needs to be set in the .config file.

board-am335xevm.c : spi_board_info bone_spi0 info[] structure needs to be altered. Modalias should be “spidev” and some of the other options might need to be changed as well depending on the default setup. Below is a link to a good guide to get spidev working on the beaglebone.

Pin Usage

IRQ Interrupt used by the CC3000 module to request attention from the host. Also serves as an

Ack line

PWR_EN Enables the module
CSn Chip select. Used to frame packages and also serves as an Ack line to the module


Works as regular SPI
N_High Line needed high to mux CSn to the CC3000 module