In the near future, a moisture level sensor for your houseplants could send a message to your smartphone. Your fridge may tell you when you are low on eggs, or you might direct your house lights to turn themselves on when you’re almost home. In a nutshell, this is what the Internet of Things (IoT) is all about: smart devices that collect and process data, which are connected by various wireless and wired technologies. Wi-Fi, now a ubiquitous technology, is a requirement for many IoT enabled products.
Due to the complexity of the standard Wi-Fi 802.11 protocols, it’s common to offload Wi-Fi processing to a standalone chip, instead of implementing it using discrete components. There are a number of Wi-Fi System-on-a-Chip (SoC) solutions. Some are complete programmable devices, typically including a programmable Cortex-M0 or Cortex-M3 core, where no other processing unit (e.g. another MCU) is needed. Others are meant to interface with a main MCU via I2C, SPI, or UART. In either case, the Wi-Fi SoC takes care of all the Wi-Fi handling issues, facilitating hardware and software design.
Two popular SoCs are the Expressif ESP8266 and the Texas Instruments CC3100/CC3200. The ESP8266 includes a RISC core and can operate as a standalone unit. The CC3100 interfaces with a host MCU, while the CC3200 combines the CC3100 with a Cortex-M3 core.
While a single unit solution like the ESP8266 is appealing for some (mainly due to its low cost), a multiple-chip design such as the CC3100 with a separate MCU lets the designer select the best MCU for the job. Besides, some Cortex-M0 MCUs are priced less than $1 in large quantities.
An ESP8266 sample kit can be purchased for as low as $3, although more robust designs cost more. The documentation and software support have had a reputation for being notoriously poor, although the situation has improved markedly as the maker and hobbyist communities have embraced the device. The TI CC3100/CC3200 is at the opposite end of the spectrum when it comes to documentation and software support.
Comparing the CC3100 and the ESP8266, the Expressif’s firmware is less mature and the company doesn’t have a long term track record. For many embedded products, continual device availability is an important factor. In addition, the TI devices are Wi-Fi Certified.
The CC3100 is part of TI’s SimpleLink Wi-Fi family. It’s a complete SoC with an embedded CPU, including firmware support for TCP/IP, Wi-Fi, and other services. The CC3100 interfaces with a microcontroller host over either UART or SPI. Note that TI sells a “booster board” with the CC3100 and supporting circuitry; nothing else is needed except the host MCU. It also comes with software drivers and examples.
Here, we’re going to use the booster pack with an ST-Nucleo board from STMicroelectronics. The ST-Nucleo comes in different versions depending on choice of STM32F Cortex-M device. For this exercise, I chose the ST-Nucleo F411RE with the high-performance Cortex-M4 core.
A Wi-Fi-capable consumer product must be certified by a country’s responsible agency, which is the FCC in the U.S. The CC3100 is chip-level Wi-Fi Certified by the Wi-Fi Alliance group. A variant, called CC3100MOD contains the CC3100 and other components including an antenna. It allows the CC3100 Wi-Fi certification to be transferred to end-user products, saving some time.
In the following example, I connected the STM32F411 ST-Nucleo to the CC3100 booster pack using the SPI interface, selected because it’s a synchronous interface that can be clocked up to 20 MHz. The hardware connections between the MCU and the CC3100 consist of:
Beside the four SPI pins, the interface requires two additional pins: nHib, an input that lets the CC3100 put the CC3100 into hibernation mode; and IRQ, an input that informs the MCU that data is available from the CC3100 (the CC3100 also has a Reset input that’s not used in the booster pack).
The ST-Nucleo board brings out the STM32F’s I/O pins to a set of Arduino form-factor compatible header pins. Additional pins are brought out to a set of proprietary “Morpho” connectors. Like most Cortex-M MCUs, the STM32F411 can assign different pins to a peripheral subsystem such as the SPI, and almost any GPIO pins can be used for I/O. Here, I used the pin assignments shown, but they can be altered by changing the interface code. Individual jumper wires connect the pins from the ST-Nucleo board to the pins on the TI CC3100 booster pack.
The SimpleLink API defines the interface to the CC3100 firmware. There are six sets of APIs:
- Device – manages hardware devices
- WLAN – manages WLAN, 802.11 protocols
- Socket – BSD socket API for user applications
- NetApp – provides different networking services, such as HTTP and DHCP
- NetCfg – provides network configurations, such as Mac addresses, and manages DHCP IP addresses
- File system – provides access to the serial flash attached to the CC3100, which is required for storing networking and user data
TI provides the SimpleLink API driver source code for free. To work with the CC3100, users must port this code to run on the host MCU, after which the API functions can be used in their applications.
Porting the SimpleLink API driver code
The TI code is written in standard C, and has a high degree of portability. At the lowest level, communication with the CC3100 is done via a proprietary protocol over the SPI or UART interface. The specifics of this protocol aren’t important, as you’ll be using the API functions, which hide these details.
I build the code with the ImageCraft JumpStart C for Cortex-M, but there shouldn’t be any issues if you choose other standard-compliant C compilers. One issue I encountered was that one of the interface structures needed to be compiled with no structure padding (in Standard C, the compiler usually pads a field member larger than 8 bits to the machine’s “natural” alignment for best performance). A coarse examination of the SimpleLink source code shows that this can probably be rewritten to eliminate the requirement, but as most compilers already support options to change the structure members’ alignment, this isn’t a big problem. However, if the driver code does in fact access the larger field member (e.g. a 16- or 32-bit member) on an unaligned address, this could be an issue on processors such as the M0, where unaligned access to 16- or 32-bit objects is unsupported.
Porting the code involves changing the content of one header file (user.h) to enable and disable desired features. To port to a particular host MCU, you must to provide about half-a-dozen hardware-specific functions, such as to write a byte stream to the SPI interface, to initialize the CC3100, etc. TI provides many examples and documentation on the device and the SimpleLink API. Note that porting to other vendors’ MCUs shouldn’t be that difficult.
With all the features, the code can be compiled to under 20 kbytes, leaving plenty of space except in the lowest end MCUs. The default is a single execution thread, but you can also configure the code to run under a multitasking OS.
You’ll find the examples in the ImageCraft Github repository. A demo program shows how to communicate with the ST-Nucleo board with a terminal program over a USB cable, which you connect to a Wi-Fi access point. Once connected, it’ll ping the Google server, display its IP address, and then wait for an HTTP connection. You can then use your smartphone browser to browse to the device and display its home page.
The source code is written using JumpStart C for Cortex-M and the JumpStart API (to simplify the code to access the STM32F411’s peripheral systems and GPIO), but can be converted for use with other compilers and platforms.