├── LICENSE.md ├── library.json ├── SFE_CC3000_Callbacks.h ├── SFE_CC3000_Client.h ├── common.h ├── utility ├── host_driver_version.h ├── security.h ├── evnt_handler.h ├── cc3000_common.cpp ├── hci.cpp ├── nvmem.h ├── nvmem.c ├── hci.h ├── netapp.h ├── cc3000_common.h └── netapp.cpp ├── .gitignore ├── README.md ├── examples ├── BoardTest │ └── BoardTest.ino ├── ScanTest │ └── ScanTest.ino ├── WebClient │ └── WebClient.ino ├── FastConnect │ └── FastConnect.ino ├── PingTest │ └── PingTest.ino ├── ConnectionTest │ └── ConnectionTest.ino ├── SmartConfig │ └── SmartConfig.ino └── WebClientSD │ └── WebClientSD.ino ├── SFE_CC3000_SPI.h ├── SFE_CC3000.h ├── SFE_CC3000_Callbacks.cpp ├── SFE_CC3000_Client.cpp └── SFE_CC3000_SPI.cpp /LICENSE.md: -------------------------------------------------------------------------------- 1 | License Information 2 | ------------------- 3 | 4 | The hardware is released under [Creative Commons Share-alike 3.0](http://creativecommons.org/licenses/by-sa/3.0/). 5 | 6 | All other code is open source so please feel free to do anything you want with it; you buy me a beer if you use this and we meet someday ([Beerware license](http://en.wikipedia.org/wiki/Beerware)). 7 | -------------------------------------------------------------------------------- /library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SparkFun-CC3000", 3 | "keywords": "wifi, wi-fi, http, web, server, json, rest, spi", 4 | "description": "Arduino library for the TI CC3000 WiFi Shield and SparkFun Breakout Board", 5 | "repository": 6 | { 7 | "type": "git", 8 | "url": "https://github.com/sparkfun/SFE_CC3000_Library.git" 9 | }, 10 | "frameworks": "arduino", 11 | "platforms": "atmelavr" 12 | } 13 | -------------------------------------------------------------------------------- /SFE_CC3000_Callbacks.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file SFE_CC3000_Callbacks.h 3 | * @brief Callback functions for the CC3000 library 4 | * @author Shawn Hymel (SparkFun Electronics) 5 | * 6 | * @copyright This code is public domain but you buy me a beer if you use 7 | * this and we meet someday (Beerware license). 8 | * 9 | * These functions implement the required callbacks for the provided TI CC3000 10 | * library. The Arduino library provides the functions' addresses so the TI 11 | * library can call them. 12 | */ 13 | 14 | #ifndef SFE_CC3000_CALLBACKS_H 15 | #define SFE_CC3000_CALLBACKS_H 16 | 17 | /* Callback functions */ 18 | void cc3000AsyncCallback(long lEventType, char * data, unsigned char length); 19 | char *sendFirmwarePatch(unsigned long *Length); 20 | char *sendDriverPatch(unsigned long *Length); 21 | char *sendBootLoaderPatch(unsigned long *Length); 22 | long readWlanInterruptPin(); 23 | void enableWlanInterrupt(); 24 | void disableWlanInterrupt(); 25 | void writeWlanPin(unsigned char val); 26 | 27 | #endif -------------------------------------------------------------------------------- /SFE_CC3000_Client.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file SFE_CC3000_Client.h 3 | * @brief Library for the SparkFun CC3000 shield and breakout boards 4 | * @author Shawn Hymel (SparkFun Electronics) 5 | * @author Revisions by Jacob Rosenthal (https://github.com/jacobrosenthal) 6 | * 7 | * @copyright This code is public domain but you buy me a beer if you use 8 | * this and we meet someday (Beerware license). 9 | * 10 | * The client library provides functions to connect to servers using sockets. 11 | */ 12 | 13 | #ifndef SFE_CC3000_CLIENT_H 14 | #define SFE_CC3000_CLIENT_H 15 | 16 | #include 17 | 18 | #include "SFE_CC3000.h" 19 | #include "utility/socket.h" // Needed for socket communications 20 | #include "Client.h" 21 | 22 | /* Constants for IP protocol types */ 23 | #define TCP IPPROTO_TCP 24 | #define UDP IPPROTO_UDP 25 | 26 | /* CC3000 Client class */ 27 | class SFE_CC3000_Client : public Client { 28 | public: 29 | SFE_CC3000_Client(SFE_CC3000 &cc3000); 30 | ~SFE_CC3000_Client(); 31 | 32 | int connect( const char *hostname, 33 | uint16_t port = 80); 34 | int connect( IPAddress ip_address, 35 | uint16_t port = 80); 36 | int connectUDP( const char *hostname, 37 | uint16_t port = 80); 38 | int connectUDP( IPAddress ip_address, 39 | uint16_t port = 80); 40 | 41 | virtual size_t write(uint8_t c); 42 | virtual size_t write(const uint8_t *buf, size_t size); 43 | int available(); 44 | int read(); 45 | int read(uint8_t *buf, size_t size); 46 | bool close(); 47 | uint8_t connected(); 48 | 49 | int peek(); 50 | void flush(); 51 | void stop(); 52 | 53 | operator bool(); 54 | 55 | private: 56 | SFE_CC3000 *cc3000_; 57 | int32_t socket_; 58 | }; 59 | 60 | #endif -------------------------------------------------------------------------------- /common.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file common.h 3 | * @brief Global header file for the project (for constant/global definitions) 4 | * @author Shawn Hymel (SparkFun Electronics) 5 | * 6 | * @copyright This code is public domain but you buy me a beer if you use 7 | * this and we meet someday (Beerware license). 8 | */ 9 | 10 | #ifndef COMMON_H 11 | #define COMMON_H 12 | 13 | /* Sets the name of the device. Used by SmartConfig. */ 14 | #define DEVICE_NAME "CC3000" 15 | 16 | /* Debug setting. Set to 0 for no debug output. Set to 1 for debug output 17 | * If you enable debugging, make sure you call Serial.begin()! */ 18 | #define DEBUG 0 19 | 20 | /* Clock divider for SPI */ 21 | #define SPI_CLK_DIV SPI_CLOCK_DIV2 22 | 23 | /* Define success and failure constants for CC3000 library functions. For 24 | * whatever reason, TI assigned 0 as success. */ 25 | #define CC3000_SUCCESS 0 26 | 27 | /* Define other constants used by the CC3000 library */ 28 | #define DISABLE 0 29 | #define ENABLE 1 30 | #define IP_ADDR_LEN 4 // Length of IP address in bytes 31 | 32 | /* Includes needed for defined types */ 33 | #include "utility/netapp.h" 34 | 35 | /* Global variable declarations */ 36 | extern uint8_t g_int_pin; 37 | extern uint8_t g_int_num; 38 | extern uint8_t g_en_pin; 39 | extern uint8_t g_cs_pin; 40 | extern bool g_socket_connected; 41 | extern uint8_t g_saved_data_mode; 42 | extern uint8_t g_saved_bit_order; 43 | extern uint8_t g_saved_clock_div; 44 | extern volatile unsigned long ulSmartConfigFinished; 45 | extern volatile unsigned long ucStopSmartConfig; 46 | extern volatile unsigned long ulCC3000Connected; 47 | extern volatile unsigned long ulCC3000DHCP; 48 | extern volatile unsigned long ulCC3000DHCP_configured; 49 | extern volatile unsigned long OkToDoShutDown; 50 | extern netapp_pingreport_args_t g_ping_report; 51 | 52 | #if (DEBUG == 1) 53 | extern volatile long g_debug_interrupt; 54 | #endif 55 | 56 | #endif -------------------------------------------------------------------------------- /utility/host_driver_version.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * host_driver_version.h - CC3000 Host Driver Implementation. 4 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the 16 | * distribution. 17 | * 18 | * Neither the name of Texas Instruments Incorporated nor the names of 19 | * its contributors may be used to endorse or promote products derived 20 | * from this software without specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 28 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | *****************************************************************************/ 35 | #ifndef __HOST_DRIVER_VERSION_H__ 36 | #define __HOST_DRIVER_VERSION_H__ 37 | 38 | #define DRIVER_VERSION_NUMBER 14 39 | 40 | 41 | 42 | #endif // __VERSION_H__ 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ############# 33 | ## Eagle 34 | ############# 35 | 36 | # Ignore the board and schematic backup files 37 | *.b#? 38 | *.s#? 39 | 40 | 41 | ################# 42 | ## Visual Studio 43 | ################# 44 | 45 | ## Ignore Visual Studio temporary files, build results, and 46 | ## files generated by popular Visual Studio add-ons. 47 | 48 | # User-specific files 49 | *.suo 50 | *.user 51 | *.sln.docstates 52 | 53 | # Build results 54 | [Dd]ebug/ 55 | [Rr]elease/ 56 | *_i.c 57 | *_p.c 58 | *.ilk 59 | *.meta 60 | *.obj 61 | *.pch 62 | *.pdb 63 | *.pgc 64 | *.pgd 65 | *.rsp 66 | *.sbr 67 | *.tlb 68 | *.tli 69 | *.tlh 70 | *.tmp 71 | *.vspscc 72 | .builds 73 | *.dotCover 74 | 75 | ## TODO: If you have NuGet Package Restore enabled, uncomment this 76 | #packages/ 77 | 78 | # Visual C++ cache files 79 | ipch/ 80 | *.aps 81 | *.ncb 82 | *.opensdf 83 | *.sdf 84 | 85 | # Visual Studio profiler 86 | *.psess 87 | *.vsp 88 | 89 | # ReSharper is a .NET coding add-in 90 | _ReSharper* 91 | 92 | # Installshield output folder 93 | [Ee]xpress 94 | 95 | # DocProject is a documentation generator add-in 96 | DocProject/buildhelp/ 97 | DocProject/Help/*.HxT 98 | DocProject/Help/*.HxC 99 | DocProject/Help/*.hhc 100 | DocProject/Help/*.hhk 101 | DocProject/Help/*.hhp 102 | DocProject/Help/Html2 103 | DocProject/Help/html 104 | 105 | # Click-Once directory 106 | publish 107 | 108 | # Others 109 | [Bb]in 110 | [Oo]bj 111 | sql 112 | TestResults 113 | *.Cache 114 | ClientBin 115 | stylecop.* 116 | ~$* 117 | *.dbmdl 118 | Generated_Code #added for RIA/Silverlight projects 119 | 120 | # Backup & report files from converting an old project file to a newer 121 | # Visual Studio version. Backup files are not needed, because we have git ;-) 122 | _UpgradeReport_Files/ 123 | Backup*/ 124 | UpgradeLog*.XML 125 | 126 | 127 | ############ 128 | ## Windows 129 | ############ 130 | 131 | # Windows image file caches 132 | Thumbs.db 133 | 134 | # Folder config file 135 | Desktop.ini 136 | 137 | 138 | ############# 139 | ## Python 140 | ############# 141 | 142 | *.py[co] 143 | 144 | # Packages 145 | *.egg 146 | *.egg-info 147 | dist 148 | build 149 | eggs 150 | parts 151 | bin 152 | var 153 | sdist 154 | develop-eggs 155 | .installed.cfg 156 | 157 | # Installer logs 158 | pip-log.txt 159 | 160 | # Unit test / coverage reports 161 | .coverage 162 | .tox 163 | 164 | #Translations 165 | *.mo 166 | 167 | #Mr Developer 168 | .mr.developer.cfg 169 | 170 | # Mac crap 171 | .DS_Store 172 | 173 | ############# 174 | ## Misc 175 | ############# 176 | Misc/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SFE_CC3000_Library 2 | ============== 3 | 4 | Arduino library for the TI CC3000 WiFi [Shield](https://www.sparkfun.com/products/12071) and [Breakout Board](https://www.sparkfun.com/products/12072). 5 | 6 | Version 7 | ------- 8 | 9 | **v1.6** 10 | 11 | Known Issues 12 | ------------ 13 | 14 | Note that the SFE_CC3000_Library was tested with CC3000 firmware v1.24. 15 | 16 | The following are known problems with the library and are being actively worked on: 17 | 18 | * Tx/Rx buffers for the CC3000 can easily overflow. Buffer checks need to be added to the library. 19 | * AES encryption for SmartConfig is not supported. 20 | * Static IP is not working at this time (only DHCP works). 21 | * HTTP POST requests work but do not print the whole server response to the console. 22 | * The library does not work with any Teensey boards. Only ATmega328- and ATmega2560-based Arduinos have been tested. 23 | * UDP has been tested for transmit only. Receiving UDP packets on the CC3000 is currently not working. 24 | 25 | Getting Started 26 | --------------- 27 | 28 | * Download the Git repository as a ZIP ("Download ZIP" button) 29 | * Unzip 30 | * Copy the entire directory (SFE_CC3000_Library) to /libraries 31 | * Open the Arduino program 32 | * Select File -> Examples -> SFE_CC3000_Library -> WebClient 33 | * Change ap_ssid and ap_password to match your WiFi's SSID and password 34 | * If your WiFi's security is anything other than WPA2, change ap_security to one of WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA, or WLAN_SEC_WPA2 35 | * Plug in your Arduino and CC3000 board 36 | * Go to Tools -> Board and select your Arduino board 37 | * Go to Tools -> Serial Port and select the COM port of your Arduino board 38 | * Click "Upload" 39 | * Go to Tools -> Serial Monitor 40 | * Ensure the baud rate is set at 115200 baud 41 | * The program should connect and print out the HTML of [www.example.com](http://www.example.com) 42 | 43 | Version History 44 | --------------- 45 | 46 | **v1.6** 47 | 48 | * Fixed SD card incompatibility issue. Again. (I broke it in v1.4) 49 | 50 | **v1.5** 51 | 52 | * Added support for ATmega32u4 (Arduino Leonardo) 53 | 54 | **v1.4** 55 | 56 | * Added CS pin de-assertion on init to allow for other non-default CS pins 57 | 58 | **v1.3** 59 | 60 | * Merged pull request from Jacob Rosenthal (https://github.com/jacobrosenthal) 61 | * Changed IP Addresses to conform to Arduino's other networking libraries (e.g. using the IPAddress class) 62 | * Implemented UDP connections 63 | 64 | **v1.2** 65 | 66 | * Added support for the Arduino Mega 67 | 68 | **v1.1** 69 | 70 | * Fixed SD card incompatibility issues 71 | * Added WebClientSD.ino example sketch to show SD card working with CC3000 72 | 73 | **v1.0** 74 | 75 | * Initial release 76 | * Manual connection implemented 77 | * SmartConfig and FastConnect implemented 78 | * Ping implemented 79 | * TCP connections implemented 80 | * Users can perform HTTP GET and HTTP POST 81 | 82 | License 83 | ------- 84 | 85 | This code is beerware; if you see me (or any other SparkFun employee) at the local, and you've found our code helpful, please buy us a round! 86 | 87 | Distributed as-is; no warranty is given. -------------------------------------------------------------------------------- /examples/BoardTest/BoardTest.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************** 2 | BoardTest.ino 3 | CC3000 Board Test 4 | Shawn Hymel @ SparkFun Electronics 5 | November 26, 2014 6 | https://github.com/sparkfun/SFE_CC3000_Library 7 | 8 | Performs an initialization and reads the CC3000's MAC address and 9 | firmware version. The MAC address and firmware version are 10 | displayed to the Serial Monitor. No WiFi connections are made. 11 | 12 | Hardware Connections: 13 | 14 | Uno Pin CC3000 Board Function 15 | 16 | +5V VCC or +5V 5V 17 | GND GND GND 18 | 2 INT Interrupt 19 | 7 EN WiFi Enable 20 | 10 CS SPI Chip Select 21 | 11 MOSI SPI MOSI 22 | 12 MISO SPI MISO 23 | 13 SCK SPI Clock 24 | 25 | Resources: 26 | Include SPI.h and SFE_CC3000.h 27 | 28 | Development environment specifics: 29 | Written in Arduino 1.0.5 30 | Tested with Arduino UNO R3 31 | 32 | This code is beerware; if you see me (or any other SparkFun 33 | employee) at the local, and you've found our code helpful, please 34 | buy us a round! 35 | 36 | Distributed as-is; no warranty is given. 37 | ****************************************************************/ 38 | 39 | #include 40 | #include 41 | 42 | // Pins 43 | #define CC3000_INT 2 // Needs to be an interrupt pin (D2/D3) 44 | #define CC3000_EN 7 // Can be any digital pin 45 | #define CC3000_CS 10 // Preferred is pin 10 on Uno 46 | 47 | // Constants 48 | #define FW_VER_LEN 2 // Length of firmware version in bytes 49 | #define MAC_ADDR_LEN 6 // Length of MAC address in bytes 50 | 51 | // Global Variables 52 | SFE_CC3000 wifi = SFE_CC3000(CC3000_INT, CC3000_EN, CC3000_CS); 53 | 54 | void setup() { 55 | 56 | int i; 57 | unsigned char fw_ver[FW_VER_LEN]; 58 | unsigned char mac_addr[MAC_ADDR_LEN]; 59 | 60 | // Initialize Serial port 61 | Serial.begin(115200); 62 | Serial.println(); 63 | Serial.println("----------------------------"); 64 | Serial.println("SparkFun CC3000 - Board Test"); 65 | Serial.println("----------------------------"); 66 | 67 | // Initialize CC3000 (configure SPI communications) 68 | if ( wifi.init() ) { 69 | Serial.println("CC3000 initialization complete"); 70 | } else { 71 | Serial.println("Something went wrong during CC3000 init!"); 72 | } 73 | 74 | // Read and display CC3000 firmware version 75 | if ( wifi.getFirmwareVersion(fw_ver) ) { 76 | Serial.print("Firmware version: "); 77 | Serial.print(fw_ver[0], DEC); 78 | Serial.print("."); 79 | Serial.print(fw_ver[1], DEC); 80 | Serial.println(); 81 | } else { 82 | Serial.println("Could not read firmware version from CC3000"); 83 | } 84 | 85 | // Read and display CC3000 MAC address 86 | if ( wifi.getMacAddress(mac_addr) ) { 87 | Serial.print("MAC address: "); 88 | for ( i = 0; i < MAC_ADDR_LEN; i++ ) { 89 | if ( mac_addr[i] < 0x10 ) { 90 | Serial.print("0"); 91 | } 92 | Serial.print(mac_addr[i], HEX); 93 | if ( i < MAC_ADDR_LEN - 1 ) { 94 | Serial.print(":"); 95 | } 96 | } 97 | Serial.println(); 98 | } else { 99 | Serial.println("Could not read MAC address from CC3000"); 100 | } 101 | 102 | // Done! 103 | Serial.println("Finished board test"); 104 | 105 | } 106 | 107 | void loop() { 108 | 109 | // Do nothing 110 | delay(1000); 111 | 112 | } -------------------------------------------------------------------------------- /SFE_CC3000_SPI.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file SFE_CC3000_SPI.h 3 | * @brief CC3000 library functions to handle SPI 4 | * @author Texas Instruments 5 | * @author Modified by Shawn Hymel (SparkFun Electronics) 6 | * 7 | * This code was originally written by TI to work with their microcontrollers. 8 | * Most of it has been altered to work with the Arduino. 9 | */ 10 | 11 | /***************************************************************************** 12 | * 13 | * spi.h - CC3000 Host Driver Implementation. 14 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 15 | * 16 | * Redistribution and use in source and binary forms, with or without 17 | * modification, are permitted provided that the following conditions 18 | * are met: 19 | * 20 | * Redistributions of source code must retain the above copyright 21 | * notice, this list of conditions and the following disclaimer. 22 | * 23 | * Redistributions in binary form must reproduce the above copyright 24 | * notice, this list of conditions and the following disclaimer in the 25 | * documentation and/or other materials provided with the 26 | * distribution. 27 | * 28 | * Neither the name of Texas Instruments Incorporated nor the names of 29 | * its contributors may be used to endorse or promote products derived 30 | * from this software without specific prior written permission. 31 | * 32 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 35 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 37 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 38 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 39 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 40 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 41 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 42 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 43 | * 44 | *****************************************************************************/ 45 | 46 | 47 | #ifndef SFE_CC3000_SPI_H 48 | #define SFE_CC3000_SPI_H 49 | 50 | #include 51 | #include 52 | #include 53 | 54 | typedef void (*gcSpiHandleRx)(void *p); 55 | typedef void (*gcSpiHandleTx)(void); 56 | 57 | extern unsigned char wlan_tx_buffer[]; 58 | 59 | //***************************************************************************** 60 | // 61 | // Prototypes for the APIs. 62 | // 63 | //***************************************************************************** 64 | extern void SpiOpen(gcSpiHandleRx pfRxHandler); 65 | extern void SpiClose(void); 66 | extern long SpiFirstWrite(unsigned char *ucBuf, unsigned short usLength); 67 | extern long SpiWrite(unsigned char *pUserBuffer, unsigned short usLength); 68 | extern void SpiWriteDataSynchronous(unsigned char *data, unsigned short size); 69 | extern void SpiReadDataSynchronous(unsigned char *data, unsigned short size); 70 | extern void SpiReadHeader(void); 71 | extern long SpiReadDataCont(void); 72 | extern void SpiResumeSpi(void); 73 | extern void SSIContReadOperation(void); 74 | extern void SpiTriggerRxProcessing(void); 75 | extern uint8_t get_spi_data_mode(void); 76 | extern uint8_t get_spi_bit_order(void); 77 | extern uint8_t get_spi_clock_div(void); 78 | extern void save_spi_params(void); 79 | extern void restore_spi_params(void); 80 | extern void cc3000_ISR(void); 81 | 82 | #endif 83 | 84 | -------------------------------------------------------------------------------- /examples/ScanTest/ScanTest.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************** 2 | ScanTest.ino 3 | CC3000 WiFi AP Scan Test 4 | Shawn Hymel @ SparkFun Electronics 5 | January 5, 2014 6 | https://github.com/sparkfun/SFE_CC3000_Library 7 | 8 | Performs a scan of all SSIDs as seen by the CC3000 and prints the 9 | access points' information to the Serial Monitor. No WiFi 10 | connections are made. 11 | 12 | Hardware Connections: 13 | 14 | Uno Pin CC3000 Board Function 15 | 16 | +5V VCC or +5V 5V 17 | GND GND GND 18 | 2 INT Interrupt 19 | 7 EN WiFi Enable 20 | 10 CS SPI Chip Select 21 | 11 MOSI SPI MOSI 22 | 12 MISO SPI MISO 23 | 13 SCK SPI Clock 24 | 25 | Resources: 26 | Include SPI.h and SFE_CC3000.h 27 | 28 | Development environment specifics: 29 | Written in Arduino 1.0.5 30 | Tested with Arduino UNO R3 31 | 32 | This code is beerware; if you see me (or any other SparkFun 33 | employee) at the local, and you've found our code helpful, please 34 | buy us a round! 35 | 36 | Distributed as-is; no warranty is given. 37 | ****************************************************************/ 38 | 39 | #include 40 | #include 41 | 42 | // Pins 43 | #define CC3000_INT 2 // Needs to be an interrupt pin (D2/D3) 44 | #define CC3000_EN 7 // Can be any digital pin 45 | #define CC3000_CS 10 // Preferred is pin 10 on Uno 46 | 47 | // Global Variables 48 | SFE_CC3000 wifi = SFE_CC3000(CC3000_INT, CC3000_EN, CC3000_CS); 49 | 50 | void setup() { 51 | 52 | int i; 53 | AccessPointInfo ap_info; 54 | 55 | // Initialize Serial port 56 | Serial.begin(115200); 57 | Serial.println(); 58 | Serial.println("---------------------------"); 59 | Serial.println("SparkFun CC3000 - Scan Test"); 60 | Serial.println("---------------------------"); 61 | 62 | // Initialize CC3000 (configure SPI communications) 63 | if ( wifi.init() ) { 64 | Serial.println("CC3000 initialization complete"); 65 | } else { 66 | Serial.println("Something went wrong during CC3000 init!"); 67 | } 68 | 69 | // Perform scan of nearby WAPs 70 | Serial.println("Scanning APs. Waiting for scan to complete."); 71 | if ( wifi.scanAccessPoints(4000) != true ) { 72 | Serial.println("Error scanning APs"); 73 | } 74 | 75 | // Iterate through available WAPs and print their information 76 | Serial.println("Access Points found:"); 77 | Serial.println(); 78 | while ( wifi.getNextAccessPoint(ap_info) ) { 79 | Serial.print("SSID: "); 80 | Serial.println(ap_info.ssid); 81 | Serial.print("MAC address: "); 82 | for ( i = 0; i < BSSID_LENGTH; i++ ) { 83 | if ( ap_info.bssid[i] < 0x10 ) { 84 | Serial.print("0"); 85 | } 86 | Serial.print(ap_info.bssid[i], HEX); 87 | if ( i < BSSID_LENGTH - 1 ) { 88 | Serial.print(":"); 89 | } 90 | } 91 | Serial.println(); 92 | Serial.print("RSSI: "); 93 | Serial.println(ap_info.rssi, DEC); 94 | Serial.print("Security: "); 95 | switch(ap_info.security_mode) { 96 | case WLAN_SEC_UNSEC: 97 | Serial.println("Unsecured"); 98 | break; 99 | case WLAN_SEC_WEP: 100 | Serial.println("WEP"); 101 | break; 102 | case WLAN_SEC_WPA: 103 | Serial.println("WPA"); 104 | break; 105 | case WLAN_SEC_WPA2: 106 | Serial.println("WPA2"); 107 | break; 108 | default: 109 | break; 110 | } 111 | Serial.println(); 112 | } 113 | 114 | // Done! 115 | Serial.println("Finished scan test"); 116 | 117 | } 118 | 119 | void loop() { 120 | 121 | // Do nothing 122 | delay(1000); 123 | 124 | } -------------------------------------------------------------------------------- /SFE_CC3000.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file SFE_CC3000.h 3 | * @brief Library for the SparkFun CC3000 shield and breakout boards 4 | * @author Shawn Hymel (SparkFun Electronics) 5 | * @author Revisions by Jacob Rosenthal (https://github.com/jacobrosenthal) 6 | * 7 | * @copyright This code is public domain but you buy me a beer if you use 8 | * this and we meet someday (Beerware license). 9 | * 10 | * This library interfaces the TI CC3000 to Arduino over SPI. The library relies 11 | * on the Arduino built-in SPI commands. To use the library, instantiate an 12 | * SFE_CC3000 object, call the init() function, and then call connect() with the 13 | * necessary connection details. 14 | */ 15 | 16 | #ifndef SFE_CC3000_H 17 | #define SFE_CC3000_H 18 | 19 | #include 20 | 21 | #include "utility/wlan.h" // Needed for CC3000 #defines 22 | #include "utility/netapp.h" // Needed for struct types 23 | #include "Client.h" 24 | 25 | /* Constants for AP scanning */ 26 | #define SCAN_MIN_DWELL_TIME 20 // Milliseconds 27 | #define SCAN_MAX_DWELL_TIME 30 // Milliseconds 28 | #define SCAN_NUM_PROBE_REQS 2 29 | #define SCAN_CHANNEL_MASK 0x7FF 30 | #define SCAN_RSSI_THRESHOLD -80 31 | #define SCAN_NSR_THRESHOLD 0 32 | #define SCAN_DEFAULT_TX_POWER 205 33 | #define SCAN_NUM_CHANNELS 16 34 | #define SCAN_CHANNEL_TIMEOUT 2000 // Milliseconds 35 | #define BSSID_LENGTH 6 36 | 37 | /* Struct for storing results from AP scan */ 38 | typedef struct ScanResult { 39 | uint32_t num_networks; 40 | uint32_t scan_status; 41 | unsigned is_valid : 1; 42 | unsigned rssi : 7; 43 | unsigned security_mode : 2; 44 | unsigned ssid_length : 6; 45 | uint16_t entry_time; 46 | unsigned char ssid[32]; 47 | unsigned char bssid[6]; 48 | } ScanResult; 49 | 50 | /* Struct for returning results to the user from AP scan */ 51 | typedef struct AccessPointInfo { 52 | unsigned int rssi; 53 | unsigned int security_mode; 54 | char ssid[32]; 55 | unsigned char bssid[6]; 56 | } AccessPointInfo; 57 | 58 | /* Struct for returning connection information to the user */ 59 | typedef struct ConnectionInfo { 60 | unsigned char ip_address[4]; 61 | unsigned char subnet_mask[4]; 62 | unsigned char default_gateway[4]; 63 | unsigned char dhcp_server[4]; 64 | unsigned char dns_server[4]; 65 | unsigned char mac_address[6]; 66 | char ssid[32]; 67 | } ConnectionInfo; 68 | 69 | /* Struct for returning ping reports to the user */ 70 | typedef struct PingReports 71 | { 72 | unsigned long packets_sent; 73 | unsigned long packets_received; 74 | unsigned long min_round_time; 75 | unsigned long max_round_time; 76 | unsigned long avg_round_time; 77 | } PingReport; 78 | 79 | /* CC3000 class */ 80 | class SFE_CC3000 { 81 | public: 82 | SFE_CC3000(uint8_t int_pin, uint8_t en_pin, uint8_t cs_pin); 83 | ~SFE_CC3000(); 84 | bool init(); 85 | bool getFirmwareVersion(unsigned char *fw_ver); 86 | bool getMacAddress(unsigned char *mac_addr); 87 | bool scanAccessPoints(unsigned int scan_time); 88 | bool getNextAccessPoint(AccessPointInfo &ap_info); 89 | bool connect( char *ssid, 90 | unsigned int security, 91 | char *password = NULL, 92 | unsigned int timeout = 0); 93 | bool startSmartConfig(unsigned int timeout = 3000); 94 | bool fastConnect(unsigned int timeout = 3000); 95 | bool disconnect(); 96 | bool dnsLookup(char *hostname, IPAddress *ip_address); 97 | bool ping( IPAddress ip_address, 98 | PingReport &ping_report, 99 | unsigned int attempts = 1, 100 | unsigned int size = 56, 101 | unsigned int timeout = 1000); 102 | bool getDHCPStatus(); 103 | bool getConnectionStatus(); 104 | bool getInitStatus(); 105 | bool getConnectionInfo(ConnectionInfo &info); 106 | private: 107 | bool is_initialized_; 108 | uint32_t num_access_points_; 109 | uint32_t access_point_count_; 110 | ScanResult ap_scan_result_; 111 | tNetappIpconfigRetArgs connection_info_; 112 | }; 113 | 114 | #endif -------------------------------------------------------------------------------- /SFE_CC3000_Callbacks.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file SFE_CC3000_Callbacks.cpp 3 | * @brief Callback functions for the CC3000 library 4 | * @author Shawn Hymel (SparkFun Electronics) 5 | * 6 | * @copyright This code is public domain but you buy me a beer if you use 7 | * this and we meet someday (Beerware license). 8 | * 9 | * These functions implement the required callbacks for the provided TI CC3000 10 | * library. The Arduino library provides the functions' addresses so the TI 11 | * library can call them. 12 | */ 13 | 14 | #include 15 | 16 | #include "common.h" 17 | #include "SFE_CC3000_Callbacks.h" 18 | #include "SFE_CC3000_SPI.h" 19 | #include "utility/evnt_handler.h" 20 | #include "utility/hci.h" 21 | 22 | /** 23 | * @brief Asynchronous callback from CC3000 library - handles events 24 | * 25 | * @param lEventType Event type 26 | * @param data Pointer to the data 27 | * @param length length of data 28 | */ 29 | void cc3000AsyncCallback(long lEventType, char * data, unsigned char length) 30 | { 31 | 32 | if (lEventType == HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE) 33 | { 34 | ulSmartConfigFinished = 1; 35 | ucStopSmartConfig = 1; 36 | } 37 | 38 | if (lEventType == HCI_EVNT_WLAN_UNSOL_CONNECT) 39 | { 40 | ulCC3000Connected = 1; 41 | } 42 | 43 | if (lEventType == HCI_EVNT_WLAN_UNSOL_DISCONNECT) 44 | { 45 | ulCC3000Connected = 0; 46 | ulCC3000DHCP = 0; 47 | ulCC3000DHCP_configured = 0; 48 | } 49 | 50 | if (lEventType == HCI_EVNT_WLAN_UNSOL_DHCP) 51 | { 52 | // Notes: 53 | // 1) IP config parameters are received swapped 54 | // 2) IP config parameters are valid only if status is OK, i.e. ulCC3000DHCP becomes 1 55 | 56 | // only if status is OK, the flag is set to 1 and the addresses are valid 57 | if ( *(data + NETAPP_IPCONFIG_MAC_OFFSET) == 0) 58 | { 59 | ulCC3000DHCP = 1; 60 | } 61 | else 62 | { 63 | ulCC3000DHCP = 0; 64 | } 65 | } 66 | 67 | if (lEventType == HCI_EVENT_CC3000_CAN_SHUT_DOWN) 68 | { 69 | OkToDoShutDown = 1; 70 | } 71 | 72 | if (lEventType == HCI_EVNT_WLAN_ASYNC_PING_REPORT) 73 | { 74 | memcpy(&g_ping_report, data, length); 75 | } 76 | if(lEventType == HCI_EVNT_CONNECT) 77 | { 78 | g_socket_connected = true; 79 | } 80 | if (lEventType == HCI_EVNT_BSD_TCP_CLOSE_WAIT) 81 | { 82 | g_socket_connected = false; 83 | } 84 | } 85 | 86 | /** 87 | * @brief This function provides a pointer to the firmware patch 88 | * 89 | * Since there is no patch in the host, it returns NULL. 90 | * 91 | * @param Length pointer to the length 92 | * 93 | * @return a pointer to the firmware patch 94 | */ 95 | char *sendFirmwarePatch(unsigned long *Length) 96 | { 97 | *Length = 0; 98 | return NULL; 99 | } 100 | 101 | /** 102 | * @brief This function provides a pointer to the driver patch 103 | * 104 | * Since there is no patch in the host, it returns NULL. 105 | * 106 | * @param Length pointer to the length 107 | * 108 | * @return a pointer to the driver patch 109 | */ 110 | char *sendDriverPatch(unsigned long *Length) 111 | { 112 | *Length = 0; 113 | return NULL; 114 | } 115 | 116 | /** 117 | * @brief This function provides a pointer to the bootloader patch 118 | * 119 | * Since there is no patch in the host, it returns NULL. 120 | * 121 | * @param Length pointer to the length 122 | * 123 | * @return a pointer to the bootloader patch 124 | */ 125 | char *sendBootLoaderPatch(unsigned long *Length) 126 | { 127 | *Length = 0; 128 | return NULL; 129 | } 130 | 131 | /** 132 | * @brief Reads the state of the CC3000 interrupt pin 133 | * 134 | * @return the state of the CC3000 interrupt pin 135 | */ 136 | long readWlanInterruptPin() 137 | { 138 | return digitalRead(g_int_pin); 139 | } 140 | 141 | /** 142 | * @brief Enables CC3000 interrupt pin interrupts 143 | */ 144 | void enableWlanInterrupt() 145 | { 146 | attachInterrupt(g_int_num, cc3000_ISR, FALLING); 147 | } 148 | 149 | /** 150 | * @brief Disables CC3000 interrupt pin interrupts 151 | */ 152 | void disableWlanInterrupt() 153 | { 154 | detachInterrupt(g_int_num); 155 | } 156 | 157 | /** 158 | * @brief The TI library calls this to enable or disable the CC3000 EN pin 159 | * 160 | * @param val The value to write to the EN pin (high or low) 161 | */ 162 | void writeWlanPin(unsigned char val) 163 | { 164 | if (val) { 165 | digitalWrite(g_en_pin, HIGH); 166 | } else { 167 | digitalWrite(g_en_pin, LOW); 168 | } 169 | } -------------------------------------------------------------------------------- /examples/WebClient/WebClient.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************** 2 | WebClient.ino 3 | CC3000 WebClient Test 4 | Shawn Hymel @ SparkFun Electronics 5 | March 1, 2014 6 | https://github.com/sparkfun/SFE_CC3000_Library 7 | 8 | Manually connects to a WiFi network and performs an HTTP GET 9 | request on a web page. Prints the contents of the page to 10 | the serial console. 11 | 12 | The security mode is defined by one of the following: 13 | WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA, WLAN_SEC_WPA2 14 | 15 | Hardware Connections: 16 | 17 | Uno Pin CC3000 Board Function 18 | 19 | +5V VCC or +5V 5V 20 | GND GND GND 21 | 2 INT Interrupt 22 | 7 EN WiFi Enable 23 | 10 CS SPI Chip Select 24 | 11 MOSI SPI MOSI 25 | 12 MISO SPI MISO 26 | 13 SCK SPI Clock 27 | 28 | Resources: 29 | Include SPI.h, SFE_CC3000.h, and SFE_CC3000_Client.h 30 | 31 | Development environment specifics: 32 | Written in Arduino 1.0.5 33 | Tested with Arduino UNO R3 34 | 35 | This code is beerware; if you see me (or any other SparkFun 36 | employee) at the local, and you've found our code helpful, please 37 | buy us a round! 38 | 39 | Distributed as-is; no warranty is given. 40 | ****************************************************************/ 41 | 42 | #include 43 | #include 44 | #include 45 | 46 | // Pins 47 | #define CC3000_INT 2 // Needs to be an interrupt pin (D2/D3) 48 | #define CC3000_EN 7 // Can be any digital pin 49 | #define CC3000_CS 10 // Preferred is pin 10 on Uno 50 | 51 | // Connection info data lengths 52 | #define IP_ADDR_LEN 4 // Length of IP address in bytes 53 | 54 | // Constants 55 | char ap_ssid[] = "SSID"; // SSID of network 56 | char ap_password[] = "PASSWORD"; // Password of network 57 | unsigned int ap_security = WLAN_SEC_WPA2; // Security of network 58 | unsigned int timeout = 30000; // Milliseconds 59 | char server[] = "www.example.com"; // Remote host site 60 | 61 | // Global Variables 62 | SFE_CC3000 wifi = SFE_CC3000(CC3000_INT, CC3000_EN, CC3000_CS); 63 | SFE_CC3000_Client client = SFE_CC3000_Client(wifi); 64 | 65 | void setup() { 66 | 67 | ConnectionInfo connection_info; 68 | int i; 69 | 70 | // Initialize Serial port 71 | Serial.begin(115200); 72 | Serial.println(); 73 | Serial.println("---------------------------"); 74 | Serial.println("SparkFun CC3000 - WebClient"); 75 | Serial.println("---------------------------"); 76 | 77 | // Initialize CC3000 (configure SPI communications) 78 | if ( wifi.init() ) { 79 | Serial.println("CC3000 initialization complete"); 80 | } else { 81 | Serial.println("Something went wrong during CC3000 init!"); 82 | } 83 | 84 | // Connect using DHCP 85 | Serial.print("Connecting to SSID: "); 86 | Serial.println(ap_ssid); 87 | if(!wifi.connect(ap_ssid, ap_security, ap_password, timeout)) { 88 | Serial.println("Error: Could not connect to AP"); 89 | } 90 | 91 | // Gather connection details and print IP address 92 | if ( !wifi.getConnectionInfo(connection_info) ) { 93 | Serial.println("Error: Could not obtain connection details"); 94 | } else { 95 | Serial.print("IP Address: "); 96 | for (i = 0; i < IP_ADDR_LEN; i++) { 97 | Serial.print(connection_info.ip_address[i]); 98 | if ( i < IP_ADDR_LEN - 1 ) { 99 | Serial.print("."); 100 | } 101 | } 102 | Serial.println(); 103 | } 104 | 105 | // Make a TCP connection to remote host 106 | Serial.print("Performing HTTP GET of: "); 107 | Serial.println(server); 108 | if ( !client.connect(server, 80) ) { 109 | Serial.println("Error: Could not make a TCP connection"); 110 | } 111 | 112 | // Make a HTTP GET request 113 | client.println("GET /index.html HTTP/1.1"); 114 | client.print("Host: "); 115 | client.println(server); 116 | client.println("Connection: close"); 117 | client.println(); 118 | Serial.println(); 119 | } 120 | 121 | void loop() { 122 | 123 | // If there are incoming bytes, print them 124 | if ( client.available() ) { 125 | char c = client.read(); 126 | Serial.print(c); 127 | } 128 | 129 | // If the server has disconnected, stop the client and wifi 130 | if ( !client.connected() ) { 131 | Serial.println(); 132 | 133 | // Close socket 134 | if ( !client.close() ) { 135 | Serial.println("Error: Could not close socket"); 136 | } 137 | 138 | // Disconnect WiFi 139 | if ( !wifi.disconnect() ) { 140 | Serial.println("Error: Could not disconnect from network"); 141 | } 142 | 143 | // Do nothing 144 | Serial.println("Finished WebClient test"); 145 | while(true){ 146 | delay(1000); 147 | } 148 | } 149 | } -------------------------------------------------------------------------------- /examples/FastConnect/FastConnect.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************** 2 | FastConnect.ino 3 | CC3000 FastConnect Test 4 | Shawn Hymel @ SparkFun Electronics 5 | March 1, 2014 6 | https://github.com/sparkfun/SFE_CC3000_Library 7 | 8 | Connects to the WiFi network profile stored in non-volatile 9 | memory. Performs a ping test to verify functionality. 10 | 11 | NOTE: You must run SmartConfig.ino prior to this sketch in order 12 | to setup a profile. 13 | 14 | Hardware Connections: 15 | 16 | Uno Pin CC3000 Board Function 17 | 18 | +5V VCC or +5V 5V 19 | GND GND GND 20 | 2 INT Interrupt 21 | 7 EN WiFi Enable 22 | 10 CS SPI Chip Select 23 | 11 MOSI SPI MOSI 24 | 12 MISO SPI MISO 25 | 13 SCK SPI Clock 26 | 27 | Resources: 28 | Include SPI.h and SFE_CC3000.h 29 | 30 | Development environment specifics: 31 | Written in Arduino 1.0.5 32 | Tested with Arduino UNO R3 33 | 34 | This code is beerware; if you see me (or any other SparkFun 35 | employee) at the local, and you've found our code helpful, please 36 | buy us a round! 37 | 38 | Distributed as-is; no warranty is given. 39 | ****************************************************************/ 40 | 41 | #include 42 | #include 43 | 44 | // Pins 45 | #define CC3000_INT 2 // Needs to be an interrupt pin (D2/D3) 46 | #define CC3000_EN 7 // Can be any digital pin 47 | #define CC3000_CS 10 // Preferred is pin 10 on Uno 48 | 49 | // Connection info data lengths 50 | #define IP_ADDR_LEN 4 // Length of IP address in bytes 51 | 52 | // Constants 53 | unsigned int timeout = 30000; // Milliseconds 54 | char remote_host[] = "www.sparkfun.com"; // Host to ping 55 | unsigned int num_pings = 3; // Number of times to ping 56 | 57 | // Global Variables 58 | SFE_CC3000 wifi = SFE_CC3000(CC3000_INT, CC3000_EN, CC3000_CS); 59 | 60 | void setup() { 61 | 62 | ConnectionInfo connection_info; 63 | IPAddress ip_addr; 64 | IPAddress remote_ip; 65 | PingReport ping_report = {0}; 66 | int i; 67 | 68 | // Initialize Serial port 69 | Serial.begin(115200); 70 | Serial.println(); 71 | Serial.println("-----------------------------"); 72 | Serial.println("SparkFun CC3000 - FastConnect"); 73 | Serial.println("-----------------------------"); 74 | 75 | // Initialize CC3000 (configure SPI communications) 76 | if ( wifi.init() ) { 77 | Serial.println("CC3000 initialization complete"); 78 | } else { 79 | Serial.println("Something went wrong during CC3000 init!"); 80 | } 81 | 82 | // Connect to WiFi network stored in non-volatile memory 83 | Serial.println("Connecting to network stored in profile..."); 84 | if ( !wifi.fastConnect(timeout) ) { 85 | Serial.println("Error: Could not connect to network"); 86 | } 87 | 88 | // Gather connection details and print IP address 89 | if ( !wifi.getConnectionInfo(connection_info) ) { 90 | Serial.println("Error: Could not obtain connection details"); 91 | } else { 92 | Serial.print("Connected to: "); 93 | Serial.println(connection_info.ssid); 94 | Serial.print("IP Address: "); 95 | for (i = 0; i < IP_ADDR_LEN; i++) { 96 | Serial.print(connection_info.ip_address[i]); 97 | if ( i < IP_ADDR_LEN - 1 ) { 98 | Serial.print("."); 99 | } 100 | } 101 | Serial.println(); 102 | } 103 | 104 | // Perform a DNS lookup to get the IP address of a host 105 | Serial.print("Looking up IP address of: "); 106 | Serial.println(remote_host); 107 | if ( !wifi.dnsLookup(remote_host, &remote_ip) ) { 108 | Serial.println("Error: Could not lookup host by name"); 109 | } else { 110 | Serial.print("IP address found: "); 111 | for (i = 0; i < IP_ADDR_LEN; i++) { 112 | Serial.print(remote_ip[i], DEC); 113 | if ( i < IP_ADDR_LEN - 1 ) { 114 | Serial.print("."); 115 | } 116 | } 117 | Serial.println(); 118 | } 119 | 120 | // Ping IP address of remote host 121 | Serial.print("Pinging "); 122 | for (i = 0; i < IP_ADDR_LEN; i++) { 123 | Serial.print(remote_ip[i], DEC); 124 | if ( i < IP_ADDR_LEN - 1 ) { 125 | Serial.print("."); 126 | } 127 | } 128 | Serial.print(" "); 129 | Serial.print(num_pings, DEC); 130 | Serial.println(" times..."); 131 | if ( !wifi.ping(remote_ip, ping_report, num_pings, 56, 1000) ) { 132 | Serial.println("Error: no ping response"); 133 | } else { 134 | Serial.println("Pong!"); 135 | Serial.println(); 136 | Serial.print("Packets sent: "); 137 | Serial.println(ping_report.packets_sent); 138 | Serial.print("Packets received: "); 139 | Serial.println(ping_report.packets_received); 140 | Serial.print("Min round time (ms): "); 141 | Serial.println(ping_report.min_round_time); 142 | Serial.print("Max round time (ms): "); 143 | Serial.println(ping_report.max_round_time); 144 | Serial.print("Avg round time (ms): "); 145 | Serial.println(ping_report.avg_round_time); 146 | Serial.println(); 147 | } 148 | 149 | // Disconnect 150 | if ( wifi.disconnect() ) { 151 | Serial.println("Disconnected"); 152 | } else { 153 | Serial.println("Error: Could not disconnect from network"); 154 | } 155 | 156 | // Done! 157 | Serial.println("Finished FastConnect test"); 158 | 159 | } 160 | 161 | void loop() { 162 | 163 | // Do nothing 164 | delay(1000); 165 | 166 | } -------------------------------------------------------------------------------- /examples/PingTest/PingTest.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************** 2 | PingTest.ino 3 | CC3000 Ping Test 4 | Shawn Hymel @ SparkFun Electronics 5 | February 1, 2014 6 | https://github.com/sparkfun/SFE_CC3000_Library 7 | 8 | Connects to the access point given by the SSID and password and 9 | waits for a DHCP-assigned IP address. Pings the give website or 10 | IP address and waits for a response. 11 | 12 | The security mode is defined by one of the following: 13 | WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA, WLAN_SEC_WPA2 14 | 15 | Hardware Connections: 16 | 17 | Uno Pin CC3000 Board Function 18 | 19 | +5V VCC or +5V 5V 20 | GND GND GND 21 | 2 INT Interrupt 22 | 7 EN WiFi Enable 23 | 10 CS SPI Chip Select 24 | 11 MOSI SPI MOSI 25 | 12 MISO SPI MISO 26 | 13 SCK SPI Clock 27 | 28 | Resources: 29 | Include SPI.h and SFE_CC3000.h 30 | 31 | Development environment specifics: 32 | Written in Arduino 1.0.5 33 | Tested with Arduino UNO R3 34 | 35 | This code is beerware; if you see me (or any other SparkFun 36 | employee) at the local, and you've found our code helpful, please 37 | buy us a round! 38 | 39 | Distributed as-is; no warranty is given. 40 | ****************************************************************/ 41 | 42 | #include 43 | #include 44 | 45 | // Pins 46 | #define CC3000_INT 2 // Needs to be an interrupt pin (D2/D3) 47 | #define CC3000_EN 7 // Can be any digital pin 48 | #define CC3000_CS 10 // Preferred is pin 10 on Uno 49 | 50 | // Connection info data lengths 51 | #define IP_ADDR_LEN 4 // Length of IP address in bytes 52 | 53 | // Constants 54 | char ap_ssid[] = "SSID"; // SSID of network 55 | char ap_password[] = "PASSWORD"; // Password of network 56 | unsigned int ap_security = WLAN_SEC_WPA2; // Security of network 57 | unsigned int timeout = 30000; // Milliseconds 58 | char remote_host[] = "www.sparkfun.com"; // Host to ping 59 | unsigned int num_pings = 3; // Number of times to ping 60 | 61 | // Global Variables 62 | SFE_CC3000 wifi = SFE_CC3000(CC3000_INT, CC3000_EN, CC3000_CS); 63 | 64 | void setup() { 65 | 66 | ConnectionInfo connection_info; 67 | IPAddress ip_addr; 68 | IPAddress remote_ip; 69 | PingReport ping_report = {0}; 70 | int i; 71 | 72 | // Initialize Serial port 73 | Serial.begin(115200); 74 | Serial.println(); 75 | Serial.println("---------------------------"); 76 | Serial.println("SparkFun CC3000 - Ping Test"); 77 | Serial.println("---------------------------"); 78 | 79 | // Initialize CC3000 (configure SPI communications) 80 | if ( wifi.init() ) { 81 | Serial.println("CC3000 initialization complete"); 82 | } else { 83 | Serial.println("Something went wrong during CC3000 init!"); 84 | } 85 | 86 | // Connect and wait for DHCP-assigned IP address 87 | Serial.print("Connecting to: "); 88 | Serial.println(ap_ssid); 89 | if(!wifi.connect(ap_ssid, ap_security, ap_password, timeout)) { 90 | Serial.println("Error: Could not connect to AP"); 91 | } 92 | 93 | // Gather connection details and print IP address 94 | if ( !wifi.getConnectionInfo(connection_info) ) { 95 | Serial.println("Error: Could not obtain connection details"); 96 | } else { 97 | Serial.println("Connected!"); 98 | Serial.print("IP Address: "); 99 | for (i = 0; i < IP_ADDR_LEN; i++) { 100 | Serial.print(connection_info.ip_address[i]); 101 | if ( i < IP_ADDR_LEN - 1 ) { 102 | Serial.print("."); 103 | } 104 | } 105 | Serial.println(); 106 | } 107 | 108 | // Perform a DNS lookup to get the IP address of a host 109 | Serial.print("Looking up IP address of: "); 110 | Serial.println(remote_host); 111 | if ( !wifi.dnsLookup(remote_host, &remote_ip) ) { 112 | Serial.println("Error: Could not lookup host by name"); 113 | } else { 114 | Serial.print("IP address found: "); 115 | for (i = 0; i < IP_ADDR_LEN; i++) { 116 | Serial.print(remote_ip[i], DEC); 117 | if ( i < IP_ADDR_LEN - 1 ) { 118 | Serial.print("."); 119 | } 120 | } 121 | Serial.println(); 122 | } 123 | 124 | // Ping IP address of remote host 125 | Serial.print("Pinging "); 126 | for (i = 0; i < IP_ADDR_LEN; i++) { 127 | Serial.print(remote_ip[i], DEC); 128 | if ( i < IP_ADDR_LEN - 1 ) { 129 | Serial.print("."); 130 | } 131 | } 132 | Serial.print(" "); 133 | Serial.print(num_pings, DEC); 134 | Serial.println(" times..."); 135 | if ( !wifi.ping(remote_ip, ping_report, 3, 56, 1000) ) { 136 | Serial.println("Error: no ping response"); 137 | } else { 138 | Serial.println("Pong!"); 139 | Serial.println(); 140 | Serial.print("Packets sent: "); 141 | Serial.println(ping_report.packets_sent); 142 | Serial.print("Packets received: "); 143 | Serial.println(ping_report.packets_received); 144 | Serial.print("Min round time (ms): "); 145 | Serial.println(ping_report.min_round_time); 146 | Serial.print("Max round time (ms): "); 147 | Serial.println(ping_report.max_round_time); 148 | Serial.print("Avg round time (ms): "); 149 | Serial.println(ping_report.avg_round_time); 150 | Serial.println(); 151 | } 152 | 153 | // Disconnect 154 | if ( wifi.disconnect() ) { 155 | Serial.println("Disconnected"); 156 | } else { 157 | Serial.println("Error: Could not disconnect from network"); 158 | } 159 | 160 | // Done! 161 | Serial.println("Finished ping test"); 162 | 163 | } 164 | 165 | void loop() { 166 | 167 | // Do nothing 168 | delay(1000); 169 | 170 | } -------------------------------------------------------------------------------- /utility/security.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file security.h 3 | * @brief CC3000 library functions to handle WiFi security 4 | * @author Texas Instruments 5 | * @author Modified by Shawn Hymel (SparkFun Electronics) 6 | * 7 | * Changes to the original code are listed below: 8 | * 9 | * - Changed file name from *.c to *.cpp to force the Arduino compiler to 10 | * treat it as a C++ file 11 | * 12 | * - Added (at the end of the file): 13 | * #ifdef __cplusplus 14 | * } 15 | * #endif 16 | * to close (at the beginning): 17 | * #ifdef __cplusplus 18 | * extern "C" { 19 | * #endif 20 | * 21 | */ 22 | 23 | /***************************************************************************** 24 | * 25 | * security.h - CC3000 Host Driver Implementation. 26 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 27 | * 28 | * Redistribution and use in source and binary forms, with or without 29 | * modification, are permitted provided that the following conditions 30 | * are met: 31 | * 32 | * Redistributions of source code must retain the above copyright 33 | * notice, this list of conditions and the following disclaimer. 34 | * 35 | * Redistributions in binary form must reproduce the above copyright 36 | * notice, this list of conditions and the following disclaimer in the 37 | * documentation and/or other materials provided with the 38 | * distribution. 39 | * 40 | * Neither the name of Texas Instruments Incorporated nor the names of 41 | * its contributors may be used to endorse or promote products derived 42 | * from this software without specific prior written permission. 43 | * 44 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 45 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 46 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 47 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 48 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 49 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 50 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 51 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 52 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 53 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 54 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 55 | * 56 | *****************************************************************************/ 57 | #ifndef __SECURITY__ 58 | #define __SECURITY__ 59 | 60 | #include "nvmem.h" 61 | 62 | //***************************************************************************** 63 | // 64 | // If building with a C++ compiler, make all of the definitions in this header 65 | // have a C binding. 66 | // 67 | //***************************************************************************** 68 | #ifdef __cplusplus 69 | extern "C" { 70 | #endif 71 | 72 | 73 | #define AES128_KEY_SIZE 16 74 | 75 | #ifndef CC3000_UNENCRYPTED_SMART_CONFIG 76 | 77 | 78 | //***************************************************************************** 79 | // 80 | //! aes_encrypt 81 | //! 82 | //! @param[in] key AES128 key of size 16 bytes 83 | //! @param[in\out] state 16 bytes of plain text and cipher text 84 | //! 85 | //! @return none 86 | //! 87 | //! @brief AES128 encryption: 88 | //! Given AES128 key and 16 bytes plain text, cipher text of 16 bytes 89 | //! is computed. The AES implementation is in mode ECB (Electronic 90 | //! Code Book). 91 | //! 92 | //! 93 | //***************************************************************************** 94 | extern void aes_encrypt(unsigned char *state, unsigned char *key); 95 | 96 | //***************************************************************************** 97 | // 98 | //! aes_decrypt 99 | //! 100 | //! @param[in] key AES128 key of size 16 bytes 101 | //! @param[in\out] state 16 bytes of cipher text and plain text 102 | //! 103 | //! @return none 104 | //! 105 | //! @brief AES128 decryption: 106 | //! Given AES128 key and 16 bytes cipher text, plain text of 16 bytes 107 | //! is computed The AES implementation is in mode ECB 108 | //! (Electronic Code Book). 109 | //! 110 | //! 111 | //***************************************************************************** 112 | extern void aes_decrypt(unsigned char *state, unsigned char *key); 113 | 114 | 115 | //***************************************************************************** 116 | // 117 | //! aes_read_key 118 | //! 119 | //! @param[out] key AES128 key of size 16 bytes 120 | //! 121 | //! @return on success 0, error otherwise. 122 | //! 123 | //! @brief Reads AES128 key from EEPROM 124 | //! Reads the AES128 key from fileID #12 in EEPROM 125 | //! returns an error if the key does not exist. 126 | //! 127 | //! 128 | //***************************************************************************** 129 | extern signed long aes_read_key(unsigned char *key); 130 | 131 | //***************************************************************************** 132 | // 133 | //! aes_write_key 134 | //! 135 | //! @param[out] key AES128 key of size 16 bytes 136 | //! 137 | //! @return on success 0, error otherwise. 138 | //! 139 | //! @brief writes AES128 key from EEPROM 140 | //! Writes the AES128 key to fileID #12 in EEPROM 141 | //! 142 | //! 143 | //***************************************************************************** 144 | extern signed long aes_write_key(unsigned char *key); 145 | 146 | #endif //CC3000_UNENCRYPTED_SMART_CONFIG 147 | 148 | #ifdef __cplusplus 149 | } 150 | #endif 151 | 152 | #endif 153 | -------------------------------------------------------------------------------- /examples/ConnectionTest/ConnectionTest.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************** 2 | ConnectionTest.ino 3 | CC3000 Connection Test 4 | Shawn Hymel @ SparkFun Electronics 5 | January 30, 2014 6 | https://github.com/sparkfun/SFE_CC3000_Library 7 | 8 | Connects to the access point given by the SSID and password and 9 | waits for a DHCP-assigned IP address. To use a static IP 10 | address, change the #define USE_DHCP from 1 to 0 and assign an 11 | IP address to static_ip_addr in the Constants section. 12 | 13 | NOTE: Static IP is not working at this time. 14 | 15 | The security mode is defined by one of the following: 16 | WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA, WLAN_SEC_WPA2 17 | 18 | Hardware Connections: 19 | 20 | Uno Pin CC3000 Board Function 21 | 22 | +5V VCC or +5V 5V 23 | GND GND GND 24 | 2 INT Interrupt 25 | 7 EN WiFi Enable 26 | 10 CS SPI Chip Select 27 | 11 MOSI SPI MOSI 28 | 12 MISO SPI MISO 29 | 13 SCK SPI Clock 30 | 31 | Resources: 32 | Include SPI.h and SFE_CC3000.h 33 | 34 | Development environment specifics: 35 | Written in Arduino 1.0.5 36 | Tested with Arduino UNO R3 37 | 38 | This code is beerware; if you see me (or any other SparkFun 39 | employee) at the local, and you've found our code helpful, please 40 | buy us a round! 41 | 42 | Distributed as-is; no warranty is given. 43 | ****************************************************************/ 44 | 45 | #include 46 | #include 47 | 48 | // Pins 49 | #define CC3000_INT 2 // Needs to be an interrupt pin (D2/D3) 50 | #define CC3000_EN 7 // Can be any digital pin 51 | #define CC3000_CS 10 // Preferred is pin 10 on Uno 52 | 53 | // IP address assignment method 54 | #define USE_DHCP 1 // 0 = static IP, 1 = DHCP 55 | 56 | // Connection info data lengths 57 | #define IP_ADDR_LEN 4 // Length of IP address in bytes 58 | #define MAC_ADDR_LEN 6 // Length of MAC address in bytes 59 | 60 | // Constants 61 | char ap_ssid[] = "SSID"; // SSID of network 62 | char ap_password[] = "PASSWORD"; // Password of network 63 | unsigned int ap_security = WLAN_SEC_WPA2; // Security of network 64 | unsigned int timeout = 30000; // Milliseconds 65 | //const char static_ip_addr[] = "0.0.0.0"; 66 | 67 | // Global Variables 68 | SFE_CC3000 wifi = SFE_CC3000(CC3000_INT, CC3000_EN, CC3000_CS); 69 | 70 | void setup() { 71 | 72 | ConnectionInfo connection_info; 73 | int i; 74 | 75 | // Initialize Serial port 76 | Serial.begin(115200); 77 | Serial.println(); 78 | Serial.println("---------------------------------"); 79 | Serial.println("SparkFun CC3000 - Connection Test"); 80 | Serial.println("---------------------------------"); 81 | 82 | // Initialize CC3000 (configure SPI communications) 83 | if ( wifi.init() ) { 84 | Serial.println("CC3000 initialization complete"); 85 | } else { 86 | Serial.println("Something went wrong during CC3000 init!"); 87 | } 88 | 89 | #if (USE_DHCP == 1) 90 | // Connect using DHCP 91 | Serial.print("Connecting to: "); 92 | Serial.println(ap_ssid); 93 | if(!wifi.connect(ap_ssid, ap_security, ap_password, timeout)) { 94 | Serial.println("Error: Could not connect to AP"); 95 | } 96 | #elif (USE_DHCP == 0) 97 | // Connect using static IP 98 | // ***TODO: Connect using static IP 99 | #endif 100 | 101 | // Print out connection details 102 | if( !wifi.getConnectionInfo(connection_info) ) { 103 | Serial.println("Error: Could not obtain connection details"); 104 | } else { 105 | Serial.println("Connected!"); 106 | Serial.println(); 107 | 108 | // Print MAC address 109 | Serial.print("CC3000 MAC Address: "); 110 | for ( i = 0; i < MAC_ADDR_LEN; i++ ) { 111 | if ( connection_info.mac_address[i] < 0x10 ) { 112 | Serial.print("0"); 113 | } 114 | Serial.print(connection_info.mac_address[i], HEX); 115 | if ( i < MAC_ADDR_LEN - 1 ) { 116 | Serial.print(":"); 117 | } 118 | } 119 | Serial.println(); 120 | 121 | // Print IP Address 122 | Serial.print("IP Address: "); 123 | printIPAddr(connection_info.ip_address); 124 | Serial.println(); 125 | 126 | // Print subnet mask 127 | Serial.print("Subnet Mask: "); 128 | printIPAddr(connection_info.subnet_mask); 129 | Serial.println(); 130 | 131 | // Print default gateway 132 | Serial.print("Default Gateway: "); 133 | printIPAddr(connection_info.default_gateway); 134 | Serial.println(); 135 | 136 | // Print DHCP server address 137 | Serial.print("DHCP Server: "); 138 | printIPAddr(connection_info.dhcp_server); 139 | Serial.println(); 140 | 141 | // Print DNS server address 142 | Serial.print("DNS Server: "); 143 | printIPAddr(connection_info.dns_server); 144 | Serial.println(); 145 | 146 | // Print SSID 147 | Serial.print("SSID: "); 148 | Serial.println(connection_info.ssid); 149 | Serial.println(); 150 | } 151 | 152 | // Disconnect 153 | if ( wifi.disconnect() ) { 154 | Serial.println("Disconnected"); 155 | } else { 156 | Serial.println("Error: Could not disconnect from network"); 157 | } 158 | 159 | // Done! 160 | Serial.println("Finished connection test"); 161 | 162 | } 163 | 164 | void loop() { 165 | 166 | // Do nothing 167 | delay(1000); 168 | 169 | } 170 | 171 | // Print out an IP Address in human-readable format 172 | void printIPAddr(unsigned char ip_addr[]) { 173 | int i; 174 | 175 | for (i = 0; i < IP_ADDR_LEN; i++) { 176 | Serial.print(ip_addr[i]); 177 | if ( i < IP_ADDR_LEN - 1 ) { 178 | Serial.print("."); 179 | } 180 | } 181 | } -------------------------------------------------------------------------------- /examples/SmartConfig/SmartConfig.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************** 2 | SmartConfig.ino 3 | CC3000 SmartConfig 4 | Shawn Hymel @ SparkFun Electronics 5 | February 4, 2014 6 | https://github.com/sparkfun/SFE_CC3000_Library 7 | 8 | Deletes any connection profiles stored in the CC3000 and starts 9 | the SmartConfig procedure. During the SmartConfig wait time, 10 | the user needs to open the TI SmartConfig app, fill out the 11 | WiFi information and hit Start. If the configuration happens 12 | successfully, the program will ping a remote host to verify 13 | connection. 14 | 15 | NOTE: Sometimes, the smartphone app will report that the 16 | connection failed, but the CC3000 will have received the data 17 | successfully. Make sure to read the serial output to see if 18 | a connection was made. 19 | 20 | Once a SmartConfig has been accomplished successfully, that 21 | connection profile is stored in the CC3000's non-volatile 22 | memory. The user can run the FastConnect example to re-connect 23 | to the same Access Point on boot. 24 | 25 | Hardware Connections: 26 | 27 | Uno Pin CC3000 Board Function 28 | 29 | +5V VCC or +5V 5V 30 | GND GND GND 31 | 2 INT Interrupt 32 | 7 EN WiFi Enable 33 | 10 CS SPI Chip Select 34 | 11 MOSI SPI MOSI 35 | 12 MISO SPI MISO 36 | 13 SCK SPI Clock 37 | 38 | Resources: 39 | Include SPI.h and SFE_CC3000.h 40 | 41 | Development environment specifics: 42 | Written in Arduino 1.0.5 43 | Tested with Arduino UNO R3 44 | 45 | This code is beerware; if you see me (or any other SparkFun 46 | employee) at the local, and you've found our code helpful, please 47 | buy us a round! 48 | 49 | Distributed as-is; no warranty is given. 50 | ****************************************************************/ 51 | 52 | #include 53 | #include 54 | 55 | // Pins 56 | #define CC3000_INT 2 // Needs to be an interrupt pin (D2/D3) 57 | #define CC3000_EN 7 // Can be any digital pin 58 | #define CC3000_CS 10 // Preferred is pin 10 on Uno 59 | 60 | // Connection info data lengths 61 | #define IP_ADDR_LEN 4 // Length of IP address in bytes 62 | 63 | // Constants 64 | unsigned int timeout = 30000; // Milliseconds 65 | char remote_host[] = "www.sparkfun.com"; // Host to ping 66 | unsigned int num_pings = 3; // Number of times to ping 67 | 68 | // Global Variables 69 | SFE_CC3000 wifi = SFE_CC3000(CC3000_INT, CC3000_EN, CC3000_CS); 70 | 71 | void setup() { 72 | 73 | ConnectionInfo connection_info; 74 | IPAddress ip_addr; 75 | IPAddress remote_ip; 76 | PingReport ping_report = {0}; 77 | int i; 78 | 79 | // Initialize Serial port 80 | Serial.begin(115200); 81 | Serial.println(); 82 | Serial.println("-----------------------------"); 83 | Serial.println("SparkFun CC3000 - SmartConfig"); 84 | Serial.println("-----------------------------"); 85 | 86 | // Initialize CC3000 (configure SPI communications) 87 | if ( wifi.init() ) { 88 | Serial.println("CC3000 initialization complete"); 89 | } else { 90 | Serial.println("Something went wrong during CC3000 init!"); 91 | } 92 | 93 | // Start SmartConfig and wait for IP address from DHCP 94 | Serial.println("Starting SmartConfig"); 95 | Serial.println("Send connection details from app now!"); 96 | Serial.println("Waiting to connect..."); 97 | if ( !wifi.startSmartConfig(timeout) ) { 98 | Serial.println("Error: Could not connect with SmartConfig"); 99 | } 100 | 101 | // Gather connection details and print IP address 102 | if ( !wifi.getConnectionInfo(connection_info) ) { 103 | Serial.println("Error: Could not obtain connection details"); 104 | } else { 105 | Serial.println("Connected!"); 106 | Serial.print("IP Address: "); 107 | for (i = 0; i < IP_ADDR_LEN; i++) { 108 | Serial.print(connection_info.ip_address[i]); 109 | if ( i < IP_ADDR_LEN - 1 ) { 110 | Serial.print("."); 111 | } 112 | } 113 | Serial.println(); 114 | } 115 | 116 | // Perform a DNS lookup to get the IP address of a host 117 | Serial.print("Looking up IP address of: "); 118 | Serial.println(remote_host); 119 | if ( !wifi.dnsLookup(remote_host, &remote_ip) ) { 120 | Serial.println("Error: Could not lookup host by name"); 121 | } else { 122 | Serial.print("IP address found: "); 123 | for (i = 0; i < IP_ADDR_LEN; i++) { 124 | Serial.print(remote_ip[i], DEC); 125 | if ( i < IP_ADDR_LEN - 1 ) { 126 | Serial.print("."); 127 | } 128 | } 129 | Serial.println(); 130 | } 131 | 132 | // Ping IP address of remote host 133 | Serial.print("Pinging "); 134 | for (i = 0; i < IP_ADDR_LEN; i++) { 135 | Serial.print(remote_ip[i], DEC); 136 | if ( i < IP_ADDR_LEN - 1 ) { 137 | Serial.print("."); 138 | } 139 | } 140 | Serial.print(" "); 141 | Serial.print(num_pings, DEC); 142 | Serial.println(" times..."); 143 | if ( !wifi.ping(remote_ip, ping_report, num_pings, 56, 1000) ) { 144 | Serial.println("Error: no ping response"); 145 | } else { 146 | Serial.println("Pong!"); 147 | Serial.println(); 148 | Serial.print("Packets sent: "); 149 | Serial.println(ping_report.packets_sent); 150 | Serial.print("Packets received: "); 151 | Serial.println(ping_report.packets_received); 152 | Serial.print("Min round time (ms): "); 153 | Serial.println(ping_report.min_round_time); 154 | Serial.print("Max round time (ms): "); 155 | Serial.println(ping_report.max_round_time); 156 | Serial.print("Avg round time (ms): "); 157 | Serial.println(ping_report.avg_round_time); 158 | Serial.println(); 159 | } 160 | 161 | // Disconnect 162 | if ( wifi.disconnect() ) { 163 | Serial.println("Disconnected"); 164 | } else { 165 | Serial.println("Error: Could not disconnect from network"); 166 | } 167 | 168 | // Done! 169 | Serial.println("Finished SmartConfig test"); 170 | 171 | } 172 | 173 | void loop() { 174 | 175 | // Do nothing 176 | delay(1000); 177 | 178 | } -------------------------------------------------------------------------------- /utility/evnt_handler.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * evnt_handler.h - CC3000 Host Driver Implementation. 4 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the 16 | * distribution. 17 | * 18 | * Neither the name of Texas Instruments Incorporated nor the names of 19 | * its contributors may be used to endorse or promote products derived 20 | * from this software without specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 28 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | *****************************************************************************/ 35 | #ifndef __EVENT_HANDLER_H__ 36 | #define __EVENT_HANDLER_H__ 37 | #include "hci.h" 38 | #include "socket.h" 39 | 40 | //***************************************************************************** 41 | // 42 | // If building with a C++ compiler, make all of the definitions in this header 43 | // have a C binding. 44 | // 45 | //***************************************************************************** 46 | #ifdef __cplusplus 47 | extern "C" { 48 | #endif 49 | 50 | //***************************************************************************** 51 | // 52 | // Prototypes for the APIs. 53 | // 54 | //***************************************************************************** 55 | 56 | //***************************************************************************** 57 | // 58 | //! hci_event_handler 59 | //! 60 | //! @param pRetParams incoming data buffer 61 | //! @param from from information (in case of data received) 62 | //! @param fromlen from information length (in case of data received) 63 | //! 64 | //! @return none 65 | //! 66 | //! @brief Parse the incoming events packets and issues corresponding 67 | //! event handler from global array of handlers pointers 68 | // 69 | //***************************************************************************** 70 | extern unsigned char *hci_event_handler(void *pRetParams, unsigned char *from, unsigned char *fromlen); 71 | 72 | //***************************************************************************** 73 | // 74 | //! hci_unsol_event_handler 75 | //! 76 | //! @param event_hdr event header 77 | //! 78 | //! @return 1 if event supported and handled 79 | //! 0 if event is not supported 80 | //! 81 | //! @brief Handle unsolicited events 82 | // 83 | //***************************************************************************** 84 | extern long hci_unsol_event_handler(char *event_hdr); 85 | 86 | //***************************************************************************** 87 | // 88 | //! hci_unsolicited_event_handler 89 | //! 90 | //! @param None 91 | //! 92 | //! @return ESUCCESS if successful, EFAIL if an error occurred 93 | //! 94 | //! @brief Parse the incoming unsolicited event packets and issues 95 | //! corresponding event handler. 96 | // 97 | //***************************************************************************** 98 | extern long hci_unsolicited_event_handler(void); 99 | 100 | #define M_BSD_RESP_PARAMS_OFFSET(hci_event_hdr)((char *)(hci_event_hdr) + HCI_EVENT_HEADER_SIZE) 101 | 102 | #define SOCKET_STATUS_ACTIVE 0 103 | #define SOCKET_STATUS_INACTIVE 1 104 | /* Init socket_active_status = 'all ones': init all sockets with SOCKET_STATUS_INACTIVE. 105 | Will be changed by 'set_socket_active_status' upon 'connect' and 'accept' calls */ 106 | #define SOCKET_STATUS_INIT_VAL 0xFFFF 107 | #define M_IS_VALID_SD(sd) ((0 <= (sd)) && ((sd) <= 7)) 108 | #define M_IS_VALID_STATUS(status) (((status) == SOCKET_STATUS_ACTIVE)||((status) == SOCKET_STATUS_INACTIVE)) 109 | 110 | extern unsigned long socket_active_status; 111 | 112 | extern void set_socket_active_status(long Sd, long Status); 113 | extern long get_socket_active_status(long Sd); 114 | 115 | typedef struct _bsd_accept_return_t 116 | { 117 | long iSocketDescriptor; 118 | long iStatus; 119 | sockaddr tSocketAddress; 120 | 121 | } tBsdReturnParams; 122 | 123 | 124 | typedef struct _bsd_read_return_t 125 | { 126 | long iSocketDescriptor; 127 | long iNumberOfBytes; 128 | unsigned long uiFlags; 129 | } tBsdReadReturnParams; 130 | 131 | #define BSD_RECV_FROM_FROMLEN_OFFSET (4) 132 | #define BSD_RECV_FROM_FROM_OFFSET (16) 133 | 134 | 135 | typedef struct _bsd_select_return_t 136 | { 137 | long iStatus; 138 | unsigned long uiRdfd; 139 | unsigned long uiWrfd; 140 | unsigned long uiExfd; 141 | } tBsdSelectRecvParams; 142 | 143 | 144 | typedef struct _bsd_getsockopt_return_t 145 | { 146 | unsigned char ucOptValue[4]; 147 | char iStatus; 148 | } tBsdGetSockOptReturnParams; 149 | 150 | typedef struct _bsd_gethostbyname_return_t 151 | { 152 | long retVal; 153 | long outputAddress; 154 | } tBsdGethostbynameParams; 155 | 156 | //***************************************************************************** 157 | // 158 | // Mark the end of the C bindings section for C++ compilers. 159 | // 160 | //***************************************************************************** 161 | #ifdef __cplusplus 162 | } 163 | #endif // __cplusplus 164 | 165 | #endif // __EVENT_HANDLER_H__ 166 | 167 | -------------------------------------------------------------------------------- /examples/WebClientSD/WebClientSD.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************** 2 | * WebClientSD.ino 3 | * CC3000 WebClient with SD Card Test 4 | * Shawn Hymel @ SparkFun Electronics 5 | * March 27, 2014 6 | * https://github.com/sparkfun/SFE_CC3000_Library 7 | * 8 | * Manually connects to a WiFi network and performs an HTTP GET 9 | * request on a web page. Saves the contents of the site to an SD 10 | * card. Prints the page contents our from the SD card. 11 | * 12 | * IMPORTANT: SD cards use 3.3V logic, so a 5V - 3.3V level shifter 13 | * is required if coming from a 5V Arduino. 14 | * 15 | * The security mode is defined by one of the following: 16 | * WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA, WLAN_SEC_WPA2 17 | * 18 | * Hardware Connections: 19 | * 20 | * Uno Pin CC3000 Board SD Card Function 21 | * 22 | * +5V VCC or +5V 5V 23 | * +3.3V - 4 (3.3V) 3.3V 24 | * GND GND 6 (GND) GND 25 | * 2 INT - Interrupt 26 | * 7 EN - WiFi Enable 27 | * 8 - 2 (CS) SD Chip Select 28 | * 10 CS - WiFi Chip Select 29 | * 11 MOSI 3 (MOSI) SPI MOSI 30 | * 12 MISO 7 (MISO) SPI MISO 31 | * 13 SCK 5 (SCK) SPI Clock 32 | * 33 | * Resources: 34 | * Include SD.h, SPI.h, SFE_CC3000.h, and SFE_CC3000_Client.h 35 | * 36 | * Development environment specifics: 37 | * Written in Arduino 1.0.5 38 | * Tested with Arduino UNO R3 39 | * 40 | * This code is beerware; if you see me (or any other SparkFun 41 | * employee) at the local, and you've found our code helpful, please 42 | * buy us a round! 43 | * 44 | * Distributed as-is; no warranty is given. 45 | ****************************************************************/ 46 | 47 | #include 48 | #include 49 | #include 50 | #include 51 | 52 | // Pins 53 | #define CC3000_INT 2 // Needs to be an interrupt pin (D2/D3) 54 | #define CC3000_EN 7 // Can be any digital pin 55 | #define CC3000_CS 10 // Preferred is pin 10 on Uno 56 | #define SD_CS 8 // Chip select for SD card 57 | 58 | // Connection info data lengths 59 | #define IP_ADDR_LEN 4 // Length of IP address in bytes 60 | 61 | // Constants 62 | char ap_ssid[] = "SSID"; // SSID of network 63 | char ap_password[] = "PASSWORD"; // Password of network 64 | unsigned int ap_security = WLAN_SEC_WPA2; // Security of network 65 | unsigned int timeout = 30000; // Milliseconds 66 | char server[] = "www.example.com"; // Remote host site 67 | char filename[] = "example.txt"; // File name on SD card 68 | 69 | // Global Variables 70 | SFE_CC3000 wifi = SFE_CC3000(CC3000_INT, CC3000_EN, CC3000_CS); 71 | SFE_CC3000_Client client = SFE_CC3000_Client(wifi); 72 | File sd_file; 73 | 74 | void setup() { 75 | 76 | ConnectionInfo connection_info; 77 | char c; 78 | int i; 79 | 80 | // Initialize Serial port 81 | Serial.begin(115200); 82 | Serial.println(); 83 | Serial.println(F("-----------------------------")); 84 | Serial.println(F("SparkFun CC3000 - WebClientSD")); 85 | Serial.println(F("-----------------------------")); 86 | 87 | // Initialize SD card 88 | pinMode(SD_CS, OUTPUT); 89 | if ( !SD.begin(SD_CS) ) { 90 | Serial.println(F("Error: Could not initialize SD card")); 91 | return; 92 | } 93 | else { 94 | Serial.println(F("SD card initialization complete")); 95 | } 96 | 97 | // Initialize CC3000 (configure SPI communications) 98 | if ( wifi.init() ) { 99 | Serial.println(F("CC3000 initialization complete")); 100 | } 101 | else { 102 | Serial.println(F("Something went wrong during CC3000 init!")); 103 | } 104 | 105 | // Connect using DHCP 106 | Serial.print(F("Connecting to SSID: ")); 107 | Serial.println(ap_ssid); 108 | if(!wifi.connect(ap_ssid, ap_security, ap_password, timeout)) { 109 | Serial.println(F("Error: Could not connect to AP")); 110 | } 111 | 112 | // Gather connection details and print IP address 113 | if ( !wifi.getConnectionInfo(connection_info) ) { 114 | Serial.println(F("Error: Could not get connection details")); 115 | } 116 | else { 117 | Serial.print(F("IP Address: ")); 118 | for (i = 0; i < IP_ADDR_LEN; i++) { 119 | Serial.print(connection_info.ip_address[i]); 120 | if ( i < IP_ADDR_LEN - 1 ) { 121 | Serial.print("."); 122 | } 123 | } 124 | Serial.println(); 125 | } 126 | 127 | // Make a TCP connection to remote host 128 | Serial.print(F("Performing HTTP GET of: ")); 129 | Serial.println(server); 130 | if ( !client.connect(server, 80) ) { 131 | Serial.println(F("Error: Could not make a TCP connection")); 132 | return; 133 | } 134 | 135 | // If file on SD already exists, delete it 136 | if ( SD.exists(filename) ) { 137 | Serial.print(filename); 138 | Serial.println(F(" exists. Removing it.")); 139 | if ( !SD.remove(filename) ) { 140 | Serial.println(F("Error: Could not remove file")); 141 | } 142 | } 143 | 144 | // Open a file on the SD card to write to 145 | sd_file = SD.open(filename, FILE_WRITE); 146 | if (sd_file) { 147 | Serial.print(F("Writing web page to ")); 148 | Serial.println(filename); 149 | } 150 | else { 151 | Serial.println(F("Error: Could not open file for writing")); 152 | return; 153 | } 154 | 155 | // Make a HTTP GET request 156 | client.println(F("GET /index.html HTTP/1.1")); 157 | client.print(F("Host: ")); 158 | client.println(server); 159 | client.println(F("Connection: close")); 160 | client.println(); 161 | 162 | // Wait for response to GET 163 | while ( !client.available() ) { 164 | if ( !client.connected() ) { 165 | Serial.println(F("Error: Server closed connection early")); 166 | return; 167 | } 168 | } 169 | 170 | // Print web page to file 171 | while ( client.available() ) { 172 | c = client.read(); 173 | if (sd_file) { 174 | sd_file.print(c); 175 | } 176 | } 177 | 178 | // Close file 179 | if (sd_file) { 180 | sd_file.close(); 181 | } 182 | 183 | // Wait for server to disconnect 184 | while ( client.connected() ) { 185 | delay(1); 186 | } 187 | 188 | // Close socket 189 | if ( !client.close() ) { 190 | Serial.println(F("Error: Could not close socket")); 191 | } 192 | 193 | // Disconnect WiFi 194 | if ( !wifi.disconnect() ) { 195 | Serial.println(F("Error: Could not disconnect from AP")); 196 | } 197 | 198 | // Re-open file and print web page from file to console 199 | sd_file = SD.open(filename, FILE_READ); 200 | if (sd_file) { 201 | Serial.print(F("Reading web page from ")); 202 | Serial.println(filename); 203 | Serial.println(); 204 | while ( sd_file.available() ) { 205 | Serial.write(sd_file.read()); 206 | } 207 | sd_file.close(); 208 | Serial.println(); 209 | } 210 | else { 211 | Serial.println(F("Error: Could not open file for reading")); 212 | } 213 | 214 | // Finished! 215 | Serial.println(F("Finished WebClientSD test")); 216 | } 217 | 218 | void loop() { 219 | 220 | // Do nothing 221 | delay(1000); 222 | } -------------------------------------------------------------------------------- /utility/cc3000_common.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file cc3000_common.cpp 3 | * @brief Defines common functions/macros for the CC3000 library 4 | * @author Texas Instruments 5 | * @author Modified by Shawn Hymel (SparkFun Electronics) 6 | * 7 | * Changes to the original code are listed below: 8 | * 9 | * - Changed file name from *.c to *.cpp to force the Arduino compiler to 10 | * treat it as a C++ file 11 | * 12 | * - Added the following to allow for debugging: 13 | * #include 14 | * #include "../common.h" 15 | * 16 | * - Changed return value of STREAM_TO_UINT16_f to a more explicit conversion 17 | * from a char[] to unsigned short 18 | * 19 | * - Changed return value of STREAM_TO_UINT32_f to a more explicit conversion 20 | * from a char[] to unsigned long 21 | */ 22 | 23 | /***************************************************************************** 24 | * 25 | * cc3000_common.c.c - CC3000 Host Driver Implementation. 26 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 27 | * 28 | * Redistribution and use in source and binary forms, with or without 29 | * modification, are permitted provided that the following conditions 30 | * are met: 31 | * 32 | * Redistributions of source code must retain the above copyright 33 | * notice, this list of conditions and the following disclaimer. 34 | * 35 | * Redistributions in binary form must reproduce the above copyright 36 | * notice, this list of conditions and the following disclaimer in the 37 | * documentation and/or other materials provided with the 38 | * distribution. 39 | * 40 | * Neither the name of Texas Instruments Incorporated nor the names of 41 | * its contributors may be used to endorse or promote products derived 42 | * from this software without specific prior written permission. 43 | * 44 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 45 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 46 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 47 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 48 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 49 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 50 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 51 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 52 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 53 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 54 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 55 | * 56 | *****************************************************************************/ 57 | //***************************************************************************** 58 | // 59 | //! \addtogroup common_api 60 | //! @{ 61 | // 62 | //***************************************************************************** 63 | /****************************************************************************** 64 | * 65 | * Include files 66 | * 67 | *****************************************************************************/ 68 | #include 69 | #include "../common.h" 70 | 71 | #include "cc3000_common.h" 72 | #include "socket.h" 73 | #include "wlan.h" 74 | #include "evnt_handler.h" 75 | 76 | //***************************************************************************** 77 | // 78 | //! __error__ 79 | //! 80 | //! @param pcFilename - file name, where error occurred 81 | //! @param ulLine - line number, where error occurred 82 | //! 83 | //! @return none 84 | //! 85 | //! @brief stub function for ASSERT macro 86 | // 87 | //***************************************************************************** 88 | void 89 | __error__(char *pcFilename, unsigned long ulLine) 90 | { 91 | //TODO full up function 92 | } 93 | 94 | 95 | 96 | //***************************************************************************** 97 | // 98 | //! UINT32_TO_STREAM_f 99 | //! 100 | //! @param p pointer to the new stream 101 | //! @param u32 pointer to the 32 bit 102 | //! 103 | //! @return pointer to the new stream 104 | //! 105 | //! @brief This function is used for copying 32 bit to stream 106 | //! while converting to little endian format. 107 | // 108 | //***************************************************************************** 109 | 110 | unsigned char* UINT32_TO_STREAM_f (unsigned char *p, unsigned long u32) 111 | { 112 | *(p)++ = (unsigned char)(u32); 113 | *(p)++ = (unsigned char)((u32) >> 8); 114 | *(p)++ = (unsigned char)((u32) >> 16); 115 | *(p)++ = (unsigned char)((u32) >> 24); 116 | return p; 117 | } 118 | 119 | //***************************************************************************** 120 | // 121 | //! UINT16_TO_STREAM_f 122 | //! 123 | //! @param p pointer to the new stream 124 | //! @param u32 pointer to the 16 bit 125 | //! 126 | //! @return pointer to the new stream 127 | //! 128 | //! @brief This function is used for copying 16 bit to stream 129 | //! while converting to little endian format. 130 | // 131 | //***************************************************************************** 132 | 133 | unsigned char* UINT16_TO_STREAM_f (unsigned char *p, unsigned short u16) 134 | { 135 | *(p)++ = (unsigned char)(u16); 136 | *(p)++ = (unsigned char)((u16) >> 8); 137 | return p; 138 | } 139 | 140 | //***************************************************************************** 141 | // 142 | //! STREAM_TO_UINT16_f 143 | //! 144 | //! @param p pointer to the stream 145 | //! @param offset offset in the stream 146 | //! 147 | //! @return pointer to the new 16 bit 148 | //! 149 | //! @brief This function is used for copying received stream to 150 | //! 16 bit in little endian format. 151 | // 152 | //***************************************************************************** 153 | 154 | unsigned short STREAM_TO_UINT16_f(char* p, unsigned short offset) 155 | { 156 | return ((unsigned short)p[offset] & 0x00FF) | 157 | (((unsigned short)p[offset + 1] << 8) & 0xFF00); 158 | 159 | /*return (unsigned short)((unsigned short)((unsigned short) 160 | (*(p + offset + 1)) << 8) + (unsigned short)(*(p + offset)));*/ 161 | } 162 | 163 | //***************************************************************************** 164 | // 165 | //! STREAM_TO_UINT32_f 166 | //! 167 | //! @param p pointer to the stream 168 | //! @param offset offset in the stream 169 | //! 170 | //! @return pointer to the new 32 bit 171 | //! 172 | //! @brief This function is used for copying received stream to 173 | //! 32 bit in little endian format. 174 | // 175 | //***************************************************************************** 176 | 177 | unsigned long STREAM_TO_UINT32_f(char* p, unsigned short offset) 178 | { 179 | 180 | /*#if (DEBUG == 1) 181 | unsigned long dest = 0; 182 | 183 | Serial.println("Macro: STREAM_TO_UINT32_f"); 184 | Serial.print("Stream to copy: "); 185 | Serial.print((uint8_t)p[offset + 3], HEX); 186 | Serial.print((uint8_t)p[offset + 2], HEX); 187 | Serial.print((uint8_t)p[offset + 1], HEX); 188 | Serial.println((uint8_t)p[offset], HEX); 189 | dest = ((unsigned long)p[offset] & 0x000000FF) | 190 | (((unsigned long)p[offset + 1] << 8) & 0x0000FF00) | 191 | (((unsigned long)p[offset + 2] << 16) & 0x00FF0000) | 192 | (((unsigned long)p[offset + 3] << 24) & 0xFF000000); 193 | Serial.print("Copied stream: "); 194 | Serial.println(dest, HEX); 195 | #endif*/ 196 | 197 | return ((unsigned long)p[offset] & 0x000000FF) | 198 | (((unsigned long)p[offset + 1] << 8) & 0x0000FF00) | 199 | (((unsigned long)p[offset + 2] << 16) & 0x00FF0000) | 200 | (((unsigned long)p[offset + 3] << 24) & 0xFF000000); 201 | 202 | /*return (unsigned long)((unsigned long)((unsigned long) 203 | (*(p + offset + 3)) << 24) + (unsigned long)((unsigned long) 204 | (*(p + offset + 2)) << 16) + (unsigned long)((unsigned long) 205 | (*(p + offset + 1)) << 8) + (unsigned long)(*(p + offset)));*/ 206 | } 207 | 208 | 209 | 210 | //***************************************************************************** 211 | // 212 | // Close the Doxygen group. 213 | //! @} 214 | // 215 | //***************************************************************************** 216 | -------------------------------------------------------------------------------- /utility/hci.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file hci.cpp 3 | * @brief CC3000 library functions to send commands/data to the CC3000 4 | * @author Texas Instruments 5 | * @author Modified by Shawn Hymel (SparkFun Electronics) 6 | * 7 | * Changes to the original code are listed below: 8 | * 9 | * - Changed file name from *.c to *.cpp to force the Arduino compiler to 10 | * treat it as a C++ file 11 | * - The line 12 | * #include "spi.h" 13 | * changed to 14 | * #include "../SFE_CC3000_SPI.h" 15 | * to use Arduino's built-in SPI functions 16 | */ 17 | 18 | /***************************************************************************** 19 | * 20 | * hci.c - CC3000 Host Driver Implementation. 21 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 22 | * 23 | * Redistribution and use in source and binary forms, with or without 24 | * modification, are permitted provided that the following conditions 25 | * are met: 26 | * 27 | * Redistributions of source code must retain the above copyright 28 | * notice, this list of conditions and the following disclaimer. 29 | * 30 | * Redistributions in binary form must reproduce the above copyright 31 | * notice, this list of conditions and the following disclaimer in the 32 | * documentation and/or other materials provided with the 33 | * distribution. 34 | * 35 | * Neither the name of Texas Instruments Incorporated nor the names of 36 | * its contributors may be used to endorse or promote products derived 37 | * from this software without specific prior written permission. 38 | * 39 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 40 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 41 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 42 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 43 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 45 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 46 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 47 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 48 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 49 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 50 | * 51 | *****************************************************************************/ 52 | 53 | //***************************************************************************** 54 | // 55 | //! \addtogroup hci_app 56 | //! @{ 57 | // 58 | //***************************************************************************** 59 | 60 | #include "cc3000_common.h" 61 | #include "hci.h" 62 | #include "../SFE_CC3000_SPI.h" 63 | #include "evnt_handler.h" 64 | #include "wlan.h" 65 | 66 | #define SL_PATCH_PORTION_SIZE (1000) 67 | 68 | 69 | //***************************************************************************** 70 | // 71 | //! hci_command_send 72 | //! 73 | //! @param usOpcode command operation code 74 | //! @param pucBuff pointer to the command's arguments buffer 75 | //! @param ucArgsLength length of the arguments 76 | //! 77 | //! @return none 78 | //! 79 | //! @brief Initiate an HCI command. 80 | // 81 | //***************************************************************************** 82 | unsigned short 83 | hci_command_send(unsigned short usOpcode, unsigned char *pucBuff, 84 | unsigned char ucArgsLength) 85 | { 86 | unsigned char *stream; 87 | 88 | stream = (pucBuff + SPI_HEADER_SIZE); 89 | 90 | UINT8_TO_STREAM(stream, HCI_TYPE_CMND); 91 | stream = UINT16_TO_STREAM(stream, usOpcode); 92 | UINT8_TO_STREAM(stream, ucArgsLength); 93 | 94 | //Update the opcode of the event we will be waiting for 95 | SpiWrite(pucBuff, ucArgsLength + SIMPLE_LINK_HCI_CMND_HEADER_SIZE); 96 | 97 | return(0); 98 | } 99 | 100 | //***************************************************************************** 101 | // 102 | //! hci_data_send 103 | //! 104 | //! @param usOpcode command operation code 105 | //! @param ucArgs pointer to the command's arguments buffer 106 | //! @param usArgsLength length of the arguments 107 | //! @param ucTail pointer to the data buffer 108 | //! @param usTailLength buffer length 109 | //! 110 | //! @return none 111 | //! 112 | //! @brief Initiate an HCI data write operation 113 | // 114 | //***************************************************************************** 115 | long 116 | hci_data_send(unsigned char ucOpcode, 117 | unsigned char *ucArgs, 118 | unsigned short usArgsLength, 119 | unsigned short usDataLength, 120 | const unsigned char *ucTail, 121 | unsigned short usTailLength) 122 | { 123 | unsigned char *stream; 124 | 125 | stream = ((ucArgs) + SPI_HEADER_SIZE); 126 | 127 | UINT8_TO_STREAM(stream, HCI_TYPE_DATA); 128 | UINT8_TO_STREAM(stream, ucOpcode); 129 | UINT8_TO_STREAM(stream, usArgsLength); 130 | stream = UINT16_TO_STREAM(stream, usArgsLength + usDataLength + usTailLength); 131 | 132 | // Send the packet over the SPI 133 | SpiWrite(ucArgs, SIMPLE_LINK_HCI_DATA_HEADER_SIZE + usArgsLength + usDataLength + usTailLength); 134 | 135 | return(ESUCCESS); 136 | } 137 | 138 | 139 | //***************************************************************************** 140 | // 141 | //! hci_data_command_send 142 | //! 143 | //! @param usOpcode command operation code 144 | //! @param pucBuff pointer to the data buffer 145 | //! @param ucArgsLength arguments length 146 | //! @param ucDataLength data length 147 | //! 148 | //! @return none 149 | //! 150 | //! @brief Prepeare HCI header and initiate an HCI data write operation 151 | // 152 | //***************************************************************************** 153 | void hci_data_command_send(unsigned short usOpcode, unsigned char *pucBuff, 154 | unsigned char ucArgsLength,unsigned short ucDataLength) 155 | { 156 | unsigned char *stream = (pucBuff + SPI_HEADER_SIZE); 157 | 158 | UINT8_TO_STREAM(stream, HCI_TYPE_DATA); 159 | UINT8_TO_STREAM(stream, usOpcode); 160 | UINT8_TO_STREAM(stream, ucArgsLength); 161 | stream = UINT16_TO_STREAM(stream, ucArgsLength + ucDataLength); 162 | 163 | // Send the command over SPI on data channel 164 | SpiWrite(pucBuff, ucArgsLength + ucDataLength + SIMPLE_LINK_HCI_DATA_CMND_HEADER_SIZE); 165 | 166 | return; 167 | } 168 | 169 | //***************************************************************************** 170 | // 171 | //! hci_patch_send 172 | //! 173 | //! @param usOpcode command operation code 174 | //! @param pucBuff pointer to the command's arguments buffer 175 | //! @param patch pointer to patch content buffer 176 | //! @param usDataLength data length 177 | //! 178 | //! @return none 179 | //! 180 | //! @brief Prepeare HCI header and initiate an HCI patch write operation 181 | // 182 | //***************************************************************************** 183 | void 184 | hci_patch_send(unsigned char ucOpcode, unsigned char *pucBuff, char *patch, unsigned short usDataLength) 185 | { 186 | unsigned char *data_ptr = (pucBuff + SPI_HEADER_SIZE); 187 | unsigned short usTransLength; 188 | unsigned char *stream = (pucBuff + SPI_HEADER_SIZE); 189 | 190 | UINT8_TO_STREAM(stream, HCI_TYPE_PATCH); 191 | UINT8_TO_STREAM(stream, ucOpcode); 192 | stream = UINT16_TO_STREAM(stream, usDataLength + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE); 193 | 194 | if (usDataLength <= SL_PATCH_PORTION_SIZE) 195 | { 196 | UINT16_TO_STREAM(stream, usDataLength); 197 | stream = UINT16_TO_STREAM(stream, usDataLength); 198 | memcpy((pucBuff + SPI_HEADER_SIZE) + HCI_PATCH_HEADER_SIZE, patch, usDataLength); 199 | 200 | // Update the opcode of the event we will be waiting for 201 | SpiWrite(pucBuff, usDataLength + HCI_PATCH_HEADER_SIZE); 202 | } 203 | else 204 | { 205 | 206 | usTransLength = (usDataLength/SL_PATCH_PORTION_SIZE); 207 | UINT16_TO_STREAM(stream, usDataLength + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE + usTransLength*SIMPLE_LINK_HCI_PATCH_HEADER_SIZE); 208 | stream = UINT16_TO_STREAM(stream, SL_PATCH_PORTION_SIZE); 209 | memcpy(pucBuff + SPI_HEADER_SIZE + HCI_PATCH_HEADER_SIZE, patch, SL_PATCH_PORTION_SIZE); 210 | usDataLength -= SL_PATCH_PORTION_SIZE; 211 | patch += SL_PATCH_PORTION_SIZE; 212 | 213 | // Update the opcode of the event we will be waiting for 214 | SpiWrite(pucBuff, SL_PATCH_PORTION_SIZE + HCI_PATCH_HEADER_SIZE); 215 | 216 | while (usDataLength) 217 | { 218 | if (usDataLength <= SL_PATCH_PORTION_SIZE) 219 | { 220 | usTransLength = usDataLength; 221 | usDataLength = 0; 222 | 223 | } 224 | else 225 | { 226 | usTransLength = SL_PATCH_PORTION_SIZE; 227 | usDataLength -= usTransLength; 228 | } 229 | 230 | *(unsigned short *)data_ptr = usTransLength; 231 | memcpy(data_ptr + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE, patch, usTransLength); 232 | patch += usTransLength; 233 | 234 | // Update the opcode of the event we will be waiting for 235 | SpiWrite((unsigned char *)data_ptr, usTransLength + sizeof(usTransLength)); 236 | } 237 | } 238 | } 239 | 240 | //***************************************************************************** 241 | // 242 | // Close the Doxygen group. 243 | //! @} 244 | // 245 | // 246 | //***************************************************************************** 247 | -------------------------------------------------------------------------------- /utility/nvmem.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * nvmem.h - CC3000 Host Driver Implementation. 4 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the 16 | * distribution. 17 | * 18 | * Neither the name of Texas Instruments Incorporated nor the names of 19 | * its contributors may be used to endorse or promote products derived 20 | * from this software without specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 28 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | *****************************************************************************/ 35 | #ifndef __NVRAM_H__ 36 | #define __NVRAM_H__ 37 | 38 | #include "cc3000_common.h" 39 | 40 | 41 | //***************************************************************************** 42 | // 43 | // If building with a C++ compiler, make all of the definitions in this header 44 | // have a C binding. 45 | // 46 | //***************************************************************************** 47 | #ifdef __cplusplus 48 | extern "C" { 49 | #endif 50 | 51 | 52 | //***************************************************************************** 53 | // 54 | //! \addtogroup nvmem_api 55 | //! @{ 56 | // 57 | //***************************************************************************** 58 | 59 | /**************************************************************************** 60 | ** 61 | ** Definitions for File IDs 62 | ** 63 | ****************************************************************************/ 64 | /* NVMEM file ID - system files*/ 65 | #define NVMEM_NVS_FILEID (0) 66 | #define NVMEM_NVS_SHADOW_FILEID (1) 67 | #define NVMEM_WLAN_CONFIG_FILEID (2) 68 | #define NVMEM_WLAN_CONFIG_SHADOW_FILEID (3) 69 | #define NVMEM_WLAN_DRIVER_SP_FILEID (4) 70 | #define NVMEM_WLAN_FW_SP_FILEID (5) 71 | #define NVMEM_MAC_FILEID (6) 72 | #define NVMEM_FRONTEND_VARS_FILEID (7) 73 | #define NVMEM_IP_CONFIG_FILEID (8) 74 | #define NVMEM_IP_CONFIG_SHADOW_FILEID (9) 75 | #define NVMEM_BOOTLOADER_SP_FILEID (10) 76 | #define NVMEM_RM_FILEID (11) 77 | 78 | /* NVMEM file ID - user files*/ 79 | #define NVMEM_AES128_KEY_FILEID (12) 80 | #define NVMEM_SHARED_MEM_FILEID (13) 81 | 82 | /* max entry in order to invalid nvmem */ 83 | #define NVMEM_MAX_ENTRY (16) 84 | 85 | 86 | //***************************************************************************** 87 | // 88 | //! nvmem_read 89 | //! 90 | //! @param ulFileId nvmem file id:\n 91 | //! NVMEM_NVS_FILEID, NVMEM_NVS_SHADOW_FILEID, 92 | //! NVMEM_WLAN_CONFIG_FILEID, NVMEM_WLAN_CONFIG_SHADOW_FILEID, 93 | //! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID, 94 | //! NVMEM_MAC_FILEID, NVMEM_FRONTEND_VARS_FILEID, 95 | //! NVMEM_IP_CONFIG_FILEID, NVMEM_IP_CONFIG_SHADOW_FILEID, 96 | //! NVMEM_BOOTLOADER_SP_FILEID, NVMEM_RM_FILEID, 97 | //! and user files 12-15. 98 | //! @param ulLength number of bytes to read 99 | //! @param ulOffset ulOffset in file from where to read 100 | //! @param buff output buffer pointer 101 | //! 102 | //! @return number of bytes read, otherwise error. 103 | //! 104 | //! @brief Reads data from the file referred by the ulFileId parameter. 105 | //! Reads data from file ulOffset till length. Err if the file can't 106 | //! be used, is invalid, or if the read is out of bounds. 107 | //! 108 | //***************************************************************************** 109 | 110 | extern signed long nvmem_read(unsigned long file_id, unsigned long length, unsigned long offset, unsigned char *buff); 111 | 112 | //***************************************************************************** 113 | // 114 | //! nvmem_write 115 | //! 116 | //! @param ulFileId nvmem file id:\n 117 | //! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID, 118 | //! NVMEM_MAC_FILEID, NVMEM_BOOTLOADER_SP_FILEID, 119 | //! and user files 12-15. 120 | //! @param ulLength number of bytes to write 121 | //! @param ulEntryOffset offset in file to start write operation from 122 | //! @param buff data to write 123 | //! 124 | //! @return on success 0, error otherwise. 125 | //! 126 | //! @brief Write data to nvmem. 127 | //! writes data to file referred by the ulFileId parameter. 128 | //! Writes data to file ulOffset till ulLength.The file id will be 129 | //! marked invalid till the write is done. The file entry doesn't 130 | //! need to be valid - only allocated. 131 | //! 132 | //***************************************************************************** 133 | 134 | extern signed long nvmem_write(unsigned long ulFileId, unsigned long ulLength, unsigned long ulEntryOffset, unsigned char *buff); 135 | 136 | 137 | //***************************************************************************** 138 | // 139 | //! nvmem_set_mac_address 140 | //! 141 | //! @param mac mac address to be set 142 | //! 143 | //! @return on success 0, error otherwise. 144 | //! 145 | //! @brief Write MAC address to EEPROM. 146 | //! mac address as appears over the air (OUI first) 147 | //! 148 | //***************************************************************************** 149 | extern unsigned char nvmem_set_mac_address(unsigned char *mac); 150 | 151 | 152 | //***************************************************************************** 153 | // 154 | //! nvmem_get_mac_address 155 | //! 156 | //! @param[out] mac mac address 157 | //! 158 | //! @return on success 0, error otherwise. 159 | //! 160 | //! @brief Read MAC address from EEPROM. 161 | //! mac address as appears over the air (OUI first) 162 | //! 163 | //***************************************************************************** 164 | extern unsigned char nvmem_get_mac_address(unsigned char *mac); 165 | 166 | 167 | //***************************************************************************** 168 | // 169 | //! nvmem_write_patch 170 | //! 171 | //! @param ulFileId nvmem file id:\n 172 | //! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID, 173 | //! @param spLength number of bytes to write 174 | //! @param spData SP data to write 175 | //! 176 | //! @return on success 0, error otherwise. 177 | //! 178 | //! @brief program a patch to a specific file ID. 179 | //! The SP data is assumed to be organized in 2-dimensional. 180 | //! Each line is SP_PORTION_SIZE bytes long. Actual programming is 181 | //! applied in SP_PORTION_SIZE bytes portions. 182 | //! 183 | //***************************************************************************** 184 | extern unsigned char nvmem_write_patch(unsigned long ulFileId, unsigned long spLength, const unsigned char *spData); 185 | 186 | 187 | //***************************************************************************** 188 | // 189 | //! nvmem_read_sp_version 190 | //! 191 | //! @param[out] patchVer first number indicates package ID and the second 192 | //! number indicates package build number 193 | //! 194 | //! @return on success 0, error otherwise. 195 | //! 196 | //! @brief Read patch version. read package version (WiFi FW patch, 197 | //! driver-supplicant-NS patch, bootloader patch) 198 | //! 199 | //***************************************************************************** 200 | #ifndef CC3000_TINY_DRIVER 201 | extern unsigned char nvmem_read_sp_version(unsigned char* patchVer); 202 | #endif 203 | 204 | //***************************************************************************** 205 | // 206 | //! nvmem_create_entry 207 | //! 208 | //! @param ulFileId nvmem file Id:\n 209 | //! * NVMEM_AES128_KEY_FILEID: 12 210 | //! * NVMEM_SHARED_MEM_FILEID: 13 211 | //! * and fileIDs 14 and 15 212 | //! @param ulNewLen entry ulLength 213 | //! 214 | //! @return on success 0, error otherwise. 215 | //! 216 | //! @brief Create new file entry and allocate space on the NVMEM. 217 | //! Applies only to user files. 218 | //! Modify the size of file. 219 | //! If the entry is unallocated - allocate it to size 220 | //! ulNewLen (marked invalid). 221 | //! If it is allocated then deallocate it first. 222 | //! To just mark the file as invalid without resizing - 223 | //! set ulNewLen=0. 224 | //! 225 | //***************************************************************************** 226 | extern signed long nvmem_create_entry(unsigned long file_id, unsigned long newlen); 227 | 228 | 229 | //***************************************************************************** 230 | // 231 | // Mark the end of the C bindings section for C++ compilers. 232 | // 233 | //***************************************************************************** 234 | 235 | 236 | //***************************************************************************** 237 | // 238 | // Close the Doxygen group. 239 | //! @} 240 | // 241 | //***************************************************************************** 242 | 243 | 244 | #ifdef __cplusplus 245 | } 246 | #endif // __cplusplus 247 | 248 | #endif // __NVRAM_H__ 249 | -------------------------------------------------------------------------------- /SFE_CC3000_Client.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file SFE_CC3000_Client.cpp 3 | * @brief Library for the SparkFun CC3000 shield and breakout boards 4 | * @author Shawn Hymel (SparkFun Electronics) 5 | * @author Revisions by Jacob Rosenthal (https://github.com/jacobrosenthal) 6 | * 7 | * @copyright This code is public domain but you buy me a beer if you use 8 | * this and we meet someday (Beerware license). 9 | * 10 | * The client library provides functions to connect to servers using sockets. 11 | */ 12 | 13 | #include 14 | #include 15 | 16 | #include "common.h" 17 | #include "SFE_CC3000.h" 18 | #include "SFE_CC3000_Client.h" 19 | #include "utility/socket.h" 20 | 21 | /** 22 | * @brief Constructor - Instantiates SFE_CC3000_Client object 23 | */ 24 | SFE_CC3000_Client::SFE_CC3000_Client(SFE_CC3000 &cc3000) 25 | { 26 | cc3000_ = &cc3000; 27 | socket_ = -1; 28 | } 29 | 30 | /** 31 | * @brief Destructor 32 | */ 33 | SFE_CC3000_Client::~SFE_CC3000_Client() 34 | { 35 | 36 | } 37 | 38 | /** 39 | * @brief Connects to a remote server using TCP 40 | * 41 | * @param[in] hostname the address of the remote server 42 | * @param[in] port the receiving port of the server (default: 80) 43 | * @return True if connected to remote server. False otherwise. 44 | */ 45 | int SFE_CC3000_Client::connect( const char *hostname, 46 | uint16_t port) 47 | { 48 | IPAddress remote_ip; 49 | 50 | /* If CC3000 is not connected to a network, return false. */ 51 | if ( !cc3000_->getInitStatus() || 52 | !cc3000_->getConnectionStatus() || 53 | !cc3000_->getDHCPStatus() ) { 54 | return false; 55 | } 56 | 57 | /* Perform a DNS lookup of the site */ 58 | if (!cc3000_->dnsLookup(const_cast(hostname), &remote_ip)) { 59 | return false; 60 | } 61 | 62 | /* Connect to remote host using IP address */ 63 | return connect(remote_ip, port); 64 | } 65 | 66 | /** 67 | * @brief Connects to a remote server using TCP 68 | * 69 | * @param[in] IP address of the remote server 70 | * @param[in] port the receiving port of the server (default: 80) 71 | * @return True if connected to remote server. False otherwise. 72 | */ 73 | int SFE_CC3000_Client::connect( IPAddress ip_address, 74 | uint16_t port) 75 | { 76 | sockaddr dest_addr; 77 | int i; 78 | 79 | /* If CC3000 is not connected to a network, return false. */ 80 | if ( !cc3000_->getInitStatus() || 81 | !cc3000_->getConnectionStatus() || 82 | !cc3000_->getDHCPStatus() ) { 83 | return false; 84 | } 85 | 86 | /* Create a socket */ 87 | socket_ = socket(AF_INET, SOCK_STREAM, TCP); 88 | if (socket_ == -1) { 89 | return false; 90 | } 91 | 92 | /* Set address family to AF_INET (only one that works right now) */ 93 | dest_addr.sa_family = AF_INET; 94 | 95 | /* Fill out the destination port */ 96 | dest_addr.sa_data[0] = (port & 0xFF00) >> 8; 97 | dest_addr.sa_data[1] = (port & 0x00FF); 98 | 99 | /* Fill out the destination IP address */ 100 | for (i = 0; i < 4; i++) { 101 | dest_addr.sa_data[i + 2] = ip_address[i]; 102 | } 103 | 104 | /* Set the rest of the dest_addr struct to 0 */ 105 | for (i = 6; i < 14; i++) { 106 | dest_addr.sa_data[i] = 0; 107 | } 108 | 109 | /* Attempt to make a connection with a remote socket */ 110 | if (connect_to_socket(socket_, &dest_addr, sizeof(dest_addr)) != 111 | CC3000_SUCCESS) { 112 | close(); 113 | return false; 114 | } 115 | 116 | return true; 117 | } 118 | 119 | /** 120 | * @brief Writes a single character to the socket 121 | * 122 | * @param[in] c the character to be written 123 | * @return the amount of data (in bytes) written 124 | */ 125 | size_t SFE_CC3000_Client::write(uint8_t c) 126 | { 127 | return write(&c, 1); 128 | } 129 | 130 | /** 131 | * @brief Writes a string of characters to the socket 132 | * 133 | * @param[in] buf buffer of characters 134 | * @param[in] size the size (in bytes) of the buffer 135 | * @return the amount of data (in bytes) written 136 | */ 137 | size_t SFE_CC3000_Client::write(const uint8_t *buf, size_t size) 138 | { 139 | /* If socket does not have a connection, return 0 */ 140 | if (!connected()) { 141 | return 0; 142 | } 143 | 144 | /* Send buffer. Last parameter (flags) is not yet implemented by TI. */ 145 | return send(socket_, buf, size, 0); 146 | } 147 | 148 | /** 149 | * @brief Connects to a remote server using UDP 150 | * 151 | * @param[in] hostname the address of the remote server 152 | * @param[in] port the receiving port of the server (default: 80) 153 | * @return True if connected to remote server. False otherwise. 154 | */ 155 | int SFE_CC3000_Client::connectUDP( const char *hostname, 156 | uint16_t port) 157 | { 158 | IPAddress remote_ip; 159 | 160 | /* If CC3000 is not connected to a network, return false. */ 161 | if ( !cc3000_->getInitStatus() || 162 | !cc3000_->getConnectionStatus() || 163 | !cc3000_->getDHCPStatus() ) { 164 | return false; 165 | } 166 | 167 | /* Perform a DNS lookup of the site */ 168 | if (!cc3000_->dnsLookup(const_cast(hostname), &remote_ip)) { 169 | return false; 170 | } 171 | 172 | Serial.println(remote_ip); 173 | 174 | /* Connect to remote host using IP address */ 175 | return connectUDP(remote_ip, port); 176 | } 177 | 178 | /** 179 | * @brief Connects to a remote server using UDP 180 | * 181 | * @param[in] IP address of the remote server 182 | * @param[in] port the receiving port of the server (default: 80) 183 | * @return True if connected to remote server. False otherwise. 184 | */ 185 | int SFE_CC3000_Client::connectUDP( IPAddress ip_address, 186 | uint16_t port) 187 | { 188 | sockaddr dest_addr; 189 | int i; 190 | 191 | /* If CC3000 is not connected to a network, return false. */ 192 | if ( !cc3000_->getInitStatus() || 193 | !cc3000_->getConnectionStatus() || 194 | !cc3000_->getDHCPStatus() ) { 195 | return false; 196 | } 197 | 198 | /* Create a socket */ 199 | socket_ = socket(AF_INET, SOCK_STREAM, UDP); 200 | if (socket_ == -1) { 201 | return false; 202 | } 203 | 204 | /* Set address family to AF_INET (only one that works right now) */ 205 | dest_addr.sa_family = AF_INET; 206 | 207 | /* Fill out the destination port */ 208 | dest_addr.sa_data[0] = (port & 0xFF00) >> 8; 209 | dest_addr.sa_data[1] = (port & 0x00FF); 210 | 211 | /* Fill out the destination IP address */ 212 | for (i = 0; i < 4; i++) { 213 | dest_addr.sa_data[i + 2] = ip_address[i]; 214 | } 215 | 216 | /* Set the rest of the dest_addr struct to 0 */ 217 | for (i = 6; i < 14; i++) { 218 | dest_addr.sa_data[i] = 0; 219 | } 220 | 221 | /* Attempt to make a connection with a remote socket */ 222 | if (connect_to_socket(socket_, &dest_addr, sizeof(dest_addr)) != 223 | CC3000_SUCCESS) { 224 | close(); 225 | return false; 226 | } 227 | 228 | return true; 229 | } 230 | 231 | /** 232 | * @brief Determines if data is available for reading 233 | * 234 | * @return True if socket contains data to be read. False otherwise. 235 | */ 236 | int SFE_CC3000_Client::available() 237 | { 238 | fd_set readsds; 239 | timeval timeout; 240 | 241 | /* We need something in readsds to tell select() to watch read sockets */ 242 | memset(&readsds, 1, sizeof(readsds)); 243 | 244 | /* Minimum timeout for select() is 5ms */ 245 | timeout.tv_sec = 0; 246 | timeout.tv_usec = 5000; 247 | 248 | /* Call select() to see if there is any data waiting */ 249 | int ret = select(socket_ + 1, &readsds, NULL, NULL, &timeout); 250 | 251 | /* If select() returned anything greater than 0, there's data for us */ 252 | if (ret > 0) { 253 | return true; 254 | } else { 255 | return false; 256 | } 257 | } 258 | 259 | /** 260 | * @brief reads 1 byte from the socket 261 | * 262 | * @return received data. -1 if no data is available 263 | */ 264 | int SFE_CC3000_Client::read() 265 | { 266 | uint8_t b; 267 | 268 | if (recv(socket_, &b, 1, 0) > 0) { 269 | return b; 270 | } else { 271 | return -1; 272 | } 273 | } 274 | 275 | /** 276 | * @brief reads data from the socket 277 | * 278 | * @param[out] buf the buffer onto which the data is written 279 | * @param[in] the length (in bytes) of the buffer 280 | * @return number of bytes received. -1 if an error occurred 281 | */ 282 | int SFE_CC3000_Client::read(uint8_t *buf, size_t size) 283 | { 284 | /* Note: Flags arg is not yet supported by TI library */ 285 | return recv(socket_, buf, size, 0); 286 | } 287 | 288 | /** 289 | * @brief Closes the socket 290 | * 291 | * @return True if socket closed successfully. False otherwise. 292 | */ 293 | bool SFE_CC3000_Client::close() 294 | { 295 | long ret; 296 | 297 | /* Attempt to close the socket and set connected state to false */ 298 | ret = closesocket(socket_); 299 | socket_ = -1; 300 | g_socket_connected = false; 301 | return (ret == CC3000_SUCCESS) ? true : false; 302 | } 303 | 304 | /** 305 | * @brief Gets the status of the socket's connection 306 | * 307 | * @return True if socket is connected. False otherwise. 308 | */ 309 | uint8_t SFE_CC3000_Client::connected() 310 | { 311 | /* If there is no socket, return false */ 312 | if (socket_ == -1) { 313 | return false; 314 | } 315 | 316 | /* If the connection was closed and there is no data, return false */ 317 | if ((!g_socket_connected) && (!available())) { 318 | return false; 319 | } 320 | 321 | return true; 322 | } 323 | 324 | /** 325 | * @brief NOT AVAILABLE IN CC3000 recv currently, necessary for Arduino Client implementation. 326 | * 327 | * @return -1 always 328 | */ 329 | int SFE_CC3000_Client::peek(){ 330 | return -1; 331 | } 332 | 333 | /** 334 | * @brief Discard any bytes that have been written to the client but not yet read. 335 | * 336 | * @return none 337 | */ 338 | void SFE_CC3000_Client::flush(){ 339 | while(available()) 340 | read(); 341 | } 342 | 343 | /** 344 | * @brief Alias for close necessary for Arduino Client implementation. 345 | * 346 | * @return none 347 | */ 348 | void SFE_CC3000_Client::stop(){ 349 | close(); 350 | } 351 | 352 | SFE_CC3000_Client::operator bool() 353 | { 354 | return (cc3000_->getInitStatus() || 355 | cc3000_->getConnectionStatus() || 356 | cc3000_->getDHCPStatus()); 357 | } 358 | -------------------------------------------------------------------------------- /utility/nvmem.c: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * nvmem.c - CC3000 Host Driver Implementation. 4 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the 16 | * distribution. 17 | * 18 | * Neither the name of Texas Instruments Incorporated nor the names of 19 | * its contributors may be used to endorse or promote products derived 20 | * from this software without specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 28 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | *****************************************************************************/ 35 | 36 | //***************************************************************************** 37 | // 38 | //! \addtogroup nvmem_api 39 | //! @{ 40 | // 41 | //***************************************************************************** 42 | 43 | #include 44 | #include 45 | #include "nvmem.h" 46 | #include "hci.h" 47 | #include "socket.h" 48 | #include "evnt_handler.h" 49 | 50 | //***************************************************************************** 51 | // 52 | // Prototypes for the structures for APIs. 53 | // 54 | //***************************************************************************** 55 | 56 | #define NVMEM_READ_PARAMS_LEN (12) 57 | #define NVMEM_CREATE_PARAMS_LEN (8) 58 | #define NVMEM_WRITE_PARAMS_LEN (16) 59 | 60 | //***************************************************************************** 61 | // 62 | //! nvmem_read 63 | //! 64 | //! @param ulFileId nvmem file id:\n 65 | //! NVMEM_NVS_FILEID, NVMEM_NVS_SHADOW_FILEID, 66 | //! NVMEM_WLAN_CONFIG_FILEID, NVMEM_WLAN_CONFIG_SHADOW_FILEID, 67 | //! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID, 68 | //! NVMEM_MAC_FILEID, NVMEM_FRONTEND_VARS_FILEID, 69 | //! NVMEM_IP_CONFIG_FILEID, NVMEM_IP_CONFIG_SHADOW_FILEID, 70 | //! NVMEM_BOOTLOADER_SP_FILEID, NVMEM_RM_FILEID, 71 | //! and user files 12-15. 72 | //! @param ulLength number of bytes to read 73 | //! @param ulOffset ulOffset in file from where to read 74 | //! @param buff output buffer pointer 75 | //! 76 | //! @return number of bytes read, otherwise error. 77 | //! 78 | //! @brief Reads data from the file referred by the ulFileId parameter. 79 | //! Reads data from file ulOffset till length. Err if the file can't 80 | //! be used, is invalid, or if the read is out of bounds. 81 | //! 82 | //***************************************************************************** 83 | 84 | signed long 85 | nvmem_read(unsigned long ulFileId, unsigned long ulLength, unsigned long ulOffset, unsigned char *buff) 86 | { 87 | unsigned char ucStatus = 0xFF; 88 | unsigned char *ptr; 89 | unsigned char *args; 90 | 91 | ptr = tSLInformation.pucTxCommandBuffer; 92 | args = (ptr + HEADERS_SIZE_CMD); 93 | 94 | // Fill in HCI packet structure 95 | args = UINT32_TO_STREAM(args, ulFileId); 96 | args = UINT32_TO_STREAM(args, ulLength); 97 | args = UINT32_TO_STREAM(args, ulOffset); 98 | 99 | // Initiate a HCI command 100 | hci_command_send(HCI_CMND_NVMEM_READ, ptr, NVMEM_READ_PARAMS_LEN); 101 | SimpleLinkWaitEvent(HCI_CMND_NVMEM_READ, &ucStatus); 102 | 103 | // In case there is data - read it - even if an error code is returned 104 | // Note: It is the user responsibility to ignore the data in case of an error code 105 | 106 | // Wait for the data in a synchronous way. Here we assume that the buffer is 107 | // big enough to store also parameters of nvmem 108 | 109 | SimpleLinkWaitData(buff, 0, 0); 110 | 111 | return(ucStatus); 112 | } 113 | 114 | //***************************************************************************** 115 | // 116 | //! nvmem_write 117 | //! 118 | //! @param ulFileId nvmem file id:\n 119 | //! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID, 120 | //! NVMEM_MAC_FILEID, NVMEM_BOOTLOADER_SP_FILEID, 121 | //! and user files 12-15. 122 | //! @param ulLength number of bytes to write 123 | //! @param ulEntryOffset offset in file to start write operation from 124 | //! @param buff data to write 125 | //! 126 | //! @return on success 0, error otherwise. 127 | //! 128 | //! @brief Write data to nvmem. 129 | //! writes data to file referred by the ulFileId parameter. 130 | //! Writes data to file ulOffset till ulLength.The file id will be 131 | //! marked invalid till the write is done. The file entry doesn't 132 | //! need to be valid - only allocated. 133 | //! 134 | //***************************************************************************** 135 | 136 | signed long 137 | nvmem_write(unsigned long ulFileId, unsigned long ulLength, unsigned long 138 | ulEntryOffset, unsigned char *buff) 139 | { 140 | long iRes; 141 | unsigned char *ptr; 142 | unsigned char *args; 143 | 144 | iRes = EFAIL; 145 | 146 | ptr = tSLInformation.pucTxCommandBuffer; 147 | args = (ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE); 148 | 149 | // Fill in HCI packet structure 150 | args = UINT32_TO_STREAM(args, ulFileId); 151 | args = UINT32_TO_STREAM(args, 12); 152 | args = UINT32_TO_STREAM(args, ulLength); 153 | args = UINT32_TO_STREAM(args, ulEntryOffset); 154 | 155 | memcpy((ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE + 156 | NVMEM_WRITE_PARAMS_LEN),buff,ulLength); 157 | 158 | // Initiate a HCI command but it will come on data channel 159 | hci_data_command_send(HCI_CMND_NVMEM_WRITE, ptr, NVMEM_WRITE_PARAMS_LEN, 160 | ulLength); 161 | 162 | SimpleLinkWaitEvent(HCI_EVNT_NVMEM_WRITE, &iRes); 163 | 164 | return(iRes); 165 | } 166 | 167 | 168 | //***************************************************************************** 169 | // 170 | //! nvmem_set_mac_address 171 | //! 172 | //! @param mac mac address to be set 173 | //! 174 | //! @return on success 0, error otherwise. 175 | //! 176 | //! @brief Write MAC address to EEPROM. 177 | //! mac address as appears over the air (OUI first) 178 | //! 179 | //***************************************************************************** 180 | 181 | unsigned char nvmem_set_mac_address(unsigned char *mac) 182 | { 183 | return nvmem_write(NVMEM_MAC_FILEID, MAC_ADDR_LEN, 0, mac); 184 | } 185 | 186 | //***************************************************************************** 187 | // 188 | //! nvmem_get_mac_address 189 | //! 190 | //! @param[out] mac mac address 191 | //! 192 | //! @return on success 0, error otherwise. 193 | //! 194 | //! @brief Read MAC address from EEPROM. 195 | //! mac address as appears over the air (OUI first) 196 | //! 197 | //***************************************************************************** 198 | 199 | unsigned char nvmem_get_mac_address(unsigned char *mac) 200 | { 201 | return nvmem_read(NVMEM_MAC_FILEID, MAC_ADDR_LEN, 0, mac); 202 | } 203 | 204 | //***************************************************************************** 205 | // 206 | //! nvmem_write_patch 207 | //! 208 | //! @param ulFileId nvmem file id:\n 209 | //! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID, 210 | //! @param spLength number of bytes to write 211 | //! @param spData SP data to write 212 | //! 213 | //! @return on success 0, error otherwise. 214 | //! 215 | //! @brief program a patch to a specific file ID. 216 | //! The SP data is assumed to be organized in 2-dimensional. 217 | //! Each line is SP_PORTION_SIZE bytes long. Actual programming is 218 | //! applied in SP_PORTION_SIZE bytes portions. 219 | //! 220 | //***************************************************************************** 221 | 222 | unsigned char nvmem_write_patch(unsigned long ulFileId, unsigned long spLength, const unsigned char *spData) 223 | { 224 | unsigned char status = 0; 225 | unsigned short offset = 0; 226 | unsigned char* spDataPtr = (unsigned char*)spData; 227 | 228 | while ((status == 0) && (spLength >= SP_PORTION_SIZE)) 229 | { 230 | status = nvmem_write(ulFileId, SP_PORTION_SIZE, offset, spDataPtr); 231 | offset += SP_PORTION_SIZE; 232 | spLength -= SP_PORTION_SIZE; 233 | spDataPtr += SP_PORTION_SIZE; 234 | } 235 | 236 | if (status !=0) 237 | { 238 | // NVMEM error occurred 239 | return status; 240 | } 241 | 242 | if (spLength != 0) 243 | { 244 | // if reached here, a reminder is left 245 | status = nvmem_write(ulFileId, spLength, offset, spDataPtr); 246 | } 247 | 248 | return status; 249 | } 250 | 251 | //***************************************************************************** 252 | // 253 | //! nvmem_read_sp_version 254 | //! 255 | //! @param[out] patchVer first number indicates package ID and the second 256 | //! number indicates package build number 257 | //! 258 | //! @return on success 0, error otherwise. 259 | //! 260 | //! @brief Read patch version. read package version (WiFi FW patch, 261 | //! driver-supplicant-NS patch, bootloader patch) 262 | //! 263 | //***************************************************************************** 264 | 265 | #ifndef CC3000_TINY_DRIVER 266 | unsigned char nvmem_read_sp_version(unsigned char* patchVer) 267 | { 268 | unsigned char *ptr; 269 | // 1st byte is the status and the rest is the SP version 270 | unsigned char retBuf[5]; 271 | 272 | ptr = tSLInformation.pucTxCommandBuffer; 273 | 274 | // Initiate a HCI command, no args are required 275 | hci_command_send(HCI_CMND_READ_SP_VERSION, ptr, 0); 276 | SimpleLinkWaitEvent(HCI_CMND_READ_SP_VERSION, retBuf); 277 | 278 | // package ID 279 | *patchVer = retBuf[3]; 280 | // package build number 281 | *(patchVer+1) = retBuf[4]; 282 | 283 | return(retBuf[0]); 284 | } 285 | #endif 286 | 287 | //***************************************************************************** 288 | // 289 | //! nvmem_create_entry 290 | //! 291 | //! @param ulFileId nvmem file Id:\n 292 | //! * NVMEM_AES128_KEY_FILEID: 12 293 | //! * NVMEM_SHARED_MEM_FILEID: 13 294 | //! * and fileIDs 14 and 15 295 | //! @param ulNewLen entry ulLength 296 | //! 297 | //! @return on success 0, error otherwise. 298 | //! 299 | //! @brief Create new file entry and allocate space on the NVMEM. 300 | //! Applies only to user files. 301 | //! Modify the size of file. 302 | //! If the entry is unallocated - allocate it to size 303 | //! ulNewLen (marked invalid). 304 | //! If it is allocated then deallocate it first. 305 | //! To just mark the file as invalid without resizing - 306 | //! set ulNewLen=0. 307 | //! 308 | //***************************************************************************** 309 | 310 | signed long 311 | nvmem_create_entry(unsigned long ulFileId, unsigned long ulNewLen) 312 | { 313 | unsigned char *ptr; 314 | unsigned char *args; 315 | unsigned short retval; 316 | 317 | ptr = tSLInformation.pucTxCommandBuffer; 318 | args = (ptr + HEADERS_SIZE_CMD); 319 | 320 | // Fill in HCI packet structure 321 | args = UINT32_TO_STREAM(args, ulFileId); 322 | args = UINT32_TO_STREAM(args, ulNewLen); 323 | 324 | // Initiate a HCI command 325 | hci_command_send(HCI_CMND_NVMEM_CREATE_ENTRY,ptr, NVMEM_CREATE_PARAMS_LEN); 326 | 327 | SimpleLinkWaitEvent(HCI_CMND_NVMEM_CREATE_ENTRY, &retval); 328 | 329 | return(retval); 330 | } 331 | 332 | 333 | 334 | //***************************************************************************** 335 | // 336 | // Close the Doxygen group. 337 | //! @} 338 | // 339 | //***************************************************************************** 340 | 341 | -------------------------------------------------------------------------------- /utility/hci.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * hci.h - CC3000 Host Driver Implementation. 4 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the 16 | * distribution. 17 | * 18 | * Neither the name of Texas Instruments Incorporated nor the names of 19 | * its contributors may be used to endorse or promote products derived 20 | * from this software without specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 28 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | *****************************************************************************/ 35 | #ifndef __HCI_H__ 36 | #define __HCI_H__ 37 | 38 | #include "cc3000_common.h" 39 | 40 | //***************************************************************************** 41 | // 42 | // If building with a C++ compiler, make all of the definitions in this header 43 | // have a C binding. 44 | // 45 | //***************************************************************************** 46 | #ifdef __cplusplus 47 | extern "C" { 48 | #endif 49 | 50 | 51 | #define SPI_HEADER_SIZE (5) 52 | #define SIMPLE_LINK_HCI_CMND_HEADER_SIZE (4) 53 | #define HEADERS_SIZE_CMD (SPI_HEADER_SIZE + SIMPLE_LINK_HCI_CMND_HEADER_SIZE) 54 | #define SIMPLE_LINK_HCI_DATA_CMND_HEADER_SIZE (5) 55 | #define SIMPLE_LINK_HCI_DATA_HEADER_SIZE (5) 56 | #define SIMPLE_LINK_HCI_PATCH_HEADER_SIZE (2) 57 | 58 | 59 | //***************************************************************************** 60 | // 61 | // Values that can be used as HCI Commands and HCI Packet header defines 62 | // 63 | //***************************************************************************** 64 | #define HCI_TYPE_CMND 0x1 65 | #define HCI_TYPE_DATA 0x2 66 | #define HCI_TYPE_PATCH 0x3 67 | #define HCI_TYPE_EVNT 0x4 68 | 69 | 70 | #define HCI_EVENT_PATCHES_DRV_REQ (1) 71 | #define HCI_EVENT_PATCHES_FW_REQ (2) 72 | #define HCI_EVENT_PATCHES_BOOTLOAD_REQ (3) 73 | 74 | 75 | #define HCI_CMND_WLAN_BASE (0x0000) 76 | #define HCI_CMND_WLAN_CONNECT 0x0001 77 | #define HCI_CMND_WLAN_DISCONNECT 0x0002 78 | #define HCI_CMND_WLAN_IOCTL_SET_SCANPARAM 0x0003 79 | #define HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY 0x0004 80 | #define HCI_CMND_WLAN_IOCTL_ADD_PROFILE 0x0005 81 | #define HCI_CMND_WLAN_IOCTL_DEL_PROFILE 0x0006 82 | #define HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS 0x0007 83 | #define HCI_CMND_EVENT_MASK 0x0008 84 | #define HCI_CMND_WLAN_IOCTL_STATUSGET 0x0009 85 | #define HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START 0x000A 86 | #define HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP 0x000B 87 | #define HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX 0x000C 88 | #define HCI_CMND_WLAN_CONFIGURE_PATCH 0x000D 89 | 90 | 91 | #define HCI_CMND_SOCKET_BASE 0x1000 92 | #define HCI_CMND_SOCKET 0x1001 93 | #define HCI_CMND_BIND 0x1002 94 | #define HCI_CMND_RECV 0x1004 95 | #define HCI_CMND_ACCEPT 0x1005 96 | #define HCI_CMND_LISTEN 0x1006 97 | #define HCI_CMND_CONNECT 0x1007 98 | #define HCI_CMND_BSD_SELECT 0x1008 99 | #define HCI_CMND_SETSOCKOPT 0x1009 100 | #define HCI_CMND_GETSOCKOPT 0x100A 101 | #define HCI_CMND_CLOSE_SOCKET 0x100B 102 | #define HCI_CMND_RECVFROM 0x100D 103 | #define HCI_CMND_GETHOSTNAME 0x1010 104 | #define HCI_CMND_MDNS_ADVERTISE 0x1011 105 | 106 | 107 | #define HCI_DATA_BASE 0x80 108 | 109 | #define HCI_CMND_SEND (0x01 + HCI_DATA_BASE) 110 | #define HCI_CMND_SENDTO (0x03 + HCI_DATA_BASE) 111 | #define HCI_DATA_BSD_RECVFROM (0x04 + HCI_DATA_BASE) 112 | #define HCI_DATA_BSD_RECV (0x05 + HCI_DATA_BASE) 113 | 114 | 115 | #define HCI_CMND_NVMEM_CBASE (0x0200) 116 | 117 | 118 | #define HCI_CMND_NVMEM_CREATE_ENTRY (0x0203) 119 | #define HCI_CMND_NVMEM_SWAP_ENTRY (0x0205) 120 | #define HCI_CMND_NVMEM_READ (0x0201) 121 | #define HCI_CMND_NVMEM_WRITE (0x0090) 122 | #define HCI_CMND_NVMEM_WRITE_PATCH (0x0204) 123 | #define HCI_CMND_READ_SP_VERSION (0x0207) 124 | 125 | #define HCI_CMND_READ_BUFFER_SIZE 0x400B 126 | #define HCI_CMND_SIMPLE_LINK_START 0x4000 127 | 128 | #define HCI_CMND_NETAPP_BASE 0x2000 129 | 130 | #define HCI_NETAPP_DHCP (0x0001 + HCI_CMND_NETAPP_BASE) 131 | #define HCI_NETAPP_PING_SEND (0x0002 + HCI_CMND_NETAPP_BASE) 132 | #define HCI_NETAPP_PING_REPORT (0x0003 + HCI_CMND_NETAPP_BASE) 133 | #define HCI_NETAPP_PING_STOP (0x0004 + HCI_CMND_NETAPP_BASE) 134 | #define HCI_NETAPP_IPCONFIG (0x0005 + HCI_CMND_NETAPP_BASE) 135 | #define HCI_NETAPP_ARP_FLUSH (0x0006 + HCI_CMND_NETAPP_BASE) 136 | #define HCI_NETAPP_SET_DEBUG_LEVEL (0x0008 + HCI_CMND_NETAPP_BASE) 137 | #define HCI_NETAPP_SET_TIMERS (0x0009 + HCI_CMND_NETAPP_BASE) 138 | 139 | 140 | 141 | 142 | 143 | 144 | //***************************************************************************** 145 | // 146 | // Values that can be used as HCI Events defines 147 | // 148 | //***************************************************************************** 149 | #define HCI_EVNT_WLAN_BASE 0x0000 150 | #define HCI_EVNT_WLAN_CONNECT 0x0001 151 | #define HCI_EVNT_WLAN_DISCONNECT \ 152 | 0x0002 153 | #define HCI_EVNT_WLAN_IOCTL_ADD_PROFILE \ 154 | 0x0005 155 | 156 | 157 | #define HCI_EVNT_SOCKET HCI_CMND_SOCKET 158 | #define HCI_EVNT_BIND HCI_CMND_BIND 159 | #define HCI_EVNT_RECV HCI_CMND_RECV 160 | #define HCI_EVNT_ACCEPT HCI_CMND_ACCEPT 161 | #define HCI_EVNT_LISTEN HCI_CMND_LISTEN 162 | #define HCI_EVNT_CONNECT HCI_CMND_CONNECT 163 | #define HCI_EVNT_SELECT HCI_CMND_BSD_SELECT 164 | #define HCI_EVNT_CLOSE_SOCKET HCI_CMND_CLOSE_SOCKET 165 | #define HCI_EVNT_RECVFROM HCI_CMND_RECVFROM 166 | #define HCI_EVNT_SETSOCKOPT HCI_CMND_SETSOCKOPT 167 | #define HCI_EVNT_GETSOCKOPT HCI_CMND_GETSOCKOPT 168 | #define HCI_EVNT_BSD_GETHOSTBYNAME HCI_CMND_GETHOSTNAME 169 | #define HCI_EVNT_MDNS_ADVERTISE HCI_CMND_MDNS_ADVERTISE 170 | 171 | #define HCI_EVNT_SEND 0x1003 172 | #define HCI_EVNT_WRITE 0x100E 173 | #define HCI_EVNT_SENDTO 0x100F 174 | 175 | #define HCI_EVNT_PATCHES_REQ 0x1000 176 | 177 | #define HCI_EVNT_UNSOL_BASE 0x4000 178 | 179 | #define HCI_EVNT_WLAN_UNSOL_BASE (0x8000) 180 | 181 | #define HCI_EVNT_WLAN_UNSOL_CONNECT (0x0001 + HCI_EVNT_WLAN_UNSOL_BASE) 182 | #define HCI_EVNT_WLAN_UNSOL_DISCONNECT (0x0002 + HCI_EVNT_WLAN_UNSOL_BASE) 183 | #define HCI_EVNT_WLAN_UNSOL_INIT (0x0004 + HCI_EVNT_WLAN_UNSOL_BASE) 184 | #define HCI_EVNT_WLAN_TX_COMPLETE (0x0008 + HCI_EVNT_WLAN_UNSOL_BASE) 185 | #define HCI_EVNT_WLAN_UNSOL_DHCP (0x0010 + HCI_EVNT_WLAN_UNSOL_BASE) 186 | #define HCI_EVNT_WLAN_ASYNC_PING_REPORT (0x0040 + HCI_EVNT_WLAN_UNSOL_BASE) 187 | #define HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE (0x0080 + HCI_EVNT_WLAN_UNSOL_BASE) 188 | #define HCI_EVNT_WLAN_KEEPALIVE (0x0200 + HCI_EVNT_WLAN_UNSOL_BASE) 189 | #define HCI_EVNT_BSD_TCP_CLOSE_WAIT (0x0800 + HCI_EVNT_WLAN_UNSOL_BASE) 190 | 191 | #define HCI_EVNT_DATA_UNSOL_FREE_BUFF \ 192 | 0x4100 193 | 194 | #define HCI_EVNT_NVMEM_CREATE_ENTRY \ 195 | HCI_CMND_NVMEM_CREATE_ENTRY 196 | #define HCI_EVNT_NVMEM_SWAP_ENTRY HCI_CMND_NVMEM_SWAP_ENTRY 197 | 198 | #define HCI_EVNT_NVMEM_READ HCI_CMND_NVMEM_READ 199 | #define HCI_EVNT_NVMEM_WRITE (0x0202) 200 | 201 | #define HCI_EVNT_READ_SP_VERSION \ 202 | HCI_CMND_READ_SP_VERSION 203 | 204 | #define HCI_EVNT_INPROGRESS 0xFFFF 205 | 206 | 207 | #define HCI_DATA_RECVFROM 0x84 208 | #define HCI_DATA_RECV 0x85 209 | #define HCI_DATA_NVMEM 0x91 210 | 211 | #define HCI_EVENT_CC3000_CAN_SHUT_DOWN 0x99 212 | 213 | //***************************************************************************** 214 | // 215 | // Prototypes for the structures for APIs. 216 | // 217 | //***************************************************************************** 218 | 219 | #define HCI_DATA_HEADER_SIZE (5) 220 | #define HCI_EVENT_HEADER_SIZE (5) 221 | #define HCI_DATA_CMD_HEADER_SIZE (5) 222 | #define HCI_PATCH_HEADER_SIZE (6) 223 | 224 | #define HCI_PACKET_TYPE_OFFSET (0) 225 | #define HCI_PACKET_ARGSIZE_OFFSET (2) 226 | #define HCI_PACKET_LENGTH_OFFSET (3) 227 | 228 | 229 | #define HCI_EVENT_OPCODE_OFFSET (1) 230 | #define HCI_EVENT_LENGTH_OFFSET (3) 231 | #define HCI_EVENT_STATUS_OFFSET (4) 232 | #define HCI_DATA_LENGTH_OFFSET (3) 233 | 234 | 235 | 236 | 237 | //***************************************************************************** 238 | // 239 | // Prototypes for the APIs. 240 | // 241 | //***************************************************************************** 242 | 243 | //***************************************************************************** 244 | // 245 | //! hci_command_send 246 | //! 247 | //! @param usOpcode command operation code 248 | //! @param pucBuff pointer to the command's arguments buffer 249 | //! @param ucArgsLength length of the arguments 250 | //! 251 | //! @return none 252 | //! 253 | //! @brief Initiate an HCI command. 254 | // 255 | //***************************************************************************** 256 | extern unsigned short hci_command_send(unsigned short usOpcode, 257 | unsigned char *ucArgs, 258 | unsigned char ucArgsLength); 259 | 260 | 261 | //***************************************************************************** 262 | // 263 | //! hci_data_send 264 | //! 265 | //! @param usOpcode command operation code 266 | //! @param ucArgs pointer to the command's arguments buffer 267 | //! @param usArgsLength length of the arguments 268 | //! @param ucTail pointer to the data buffer 269 | //! @param usTailLength buffer length 270 | //! 271 | //! @return none 272 | //! 273 | //! @brief Initiate an HCI data write operation 274 | // 275 | //***************************************************************************** 276 | extern long hci_data_send(unsigned char ucOpcode, 277 | unsigned char *ucArgs, 278 | unsigned short usArgsLength, 279 | unsigned short usDataLength, 280 | const unsigned char *ucTail, 281 | unsigned short usTailLength); 282 | 283 | 284 | //***************************************************************************** 285 | // 286 | //! hci_data_command_send 287 | //! 288 | //! @param usOpcode command operation code 289 | //! @param pucBuff pointer to the data buffer 290 | //! @param ucArgsLength arguments length 291 | //! @param ucDataLength data length 292 | //! 293 | //! @return none 294 | //! 295 | //! @brief Prepare HCI header and initiate an HCI data write operation 296 | // 297 | //***************************************************************************** 298 | extern void hci_data_command_send(unsigned short usOpcode, unsigned char *pucBuff, 299 | unsigned char ucArgsLength, unsigned short ucDataLength); 300 | 301 | //***************************************************************************** 302 | // 303 | //! hci_patch_send 304 | //! 305 | //! @param usOpcode command operation code 306 | //! @param pucBuff pointer to the command's arguments buffer 307 | //! @param patch pointer to patch content buffer 308 | //! @param usDataLength data length 309 | //! 310 | //! @return none 311 | //! 312 | //! @brief Prepare HCI header and initiate an HCI patch write operation 313 | // 314 | //***************************************************************************** 315 | extern void hci_patch_send(unsigned char ucOpcode, unsigned char *pucBuff, char *patch, unsigned short usDataLength); 316 | 317 | 318 | 319 | //***************************************************************************** 320 | // 321 | // Mark the end of the C bindings section for C++ compilers. 322 | // 323 | //***************************************************************************** 324 | #ifdef __cplusplus 325 | } 326 | #endif // __cplusplus 327 | 328 | #endif // __HCI_H__ 329 | -------------------------------------------------------------------------------- /utility/netapp.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * netapp.h - CC3000 Host Driver Implementation. 4 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 13 | * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the 16 | * distribution. 17 | * 18 | * Neither the name of Texas Instruments Incorporated nor the names of 19 | * its contributors may be used to endorse or promote products derived 20 | * from this software without specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 28 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | *****************************************************************************/ 35 | #ifndef __NETAPP_H__ 36 | #define __NETAPP_H__ 37 | 38 | 39 | //***************************************************************************** 40 | // 41 | // If building with a C++ compiler, make all of the definitions in this header 42 | // have a C binding. 43 | // 44 | //***************************************************************************** 45 | #ifdef __cplusplus 46 | extern "C" { 47 | #endif 48 | 49 | //***************************************************************************** 50 | // 51 | //! \addtogroup netapp_api 52 | //! @{ 53 | // 54 | //***************************************************************************** 55 | 56 | typedef struct _netapp_dhcp_ret_args_t 57 | { 58 | unsigned char aucIP[4]; 59 | unsigned char aucSubnetMask[4]; 60 | unsigned char aucDefaultGateway[4]; 61 | unsigned char aucDHCPServer[4]; 62 | unsigned char aucDNSServer[4]; 63 | }tNetappDhcpParams; 64 | 65 | typedef struct _netapp_ipconfig_ret_args_t 66 | { 67 | unsigned char aucIP[4]; 68 | unsigned char aucSubnetMask[4]; 69 | unsigned char aucDefaultGateway[4]; 70 | unsigned char aucDHCPServer[4]; 71 | unsigned char aucDNSServer[4]; 72 | unsigned char uaMacAddr[6]; 73 | unsigned char uaSSID[32]; 74 | }tNetappIpconfigRetArgs; 75 | 76 | 77 | /*Ping send report parameters*/ 78 | typedef struct _netapp_pingreport_args 79 | { 80 | unsigned long packets_sent; 81 | unsigned long packets_received; 82 | unsigned long min_round_time; 83 | unsigned long max_round_time; 84 | unsigned long avg_round_time; 85 | } netapp_pingreport_args_t; 86 | 87 | 88 | //***************************************************************************** 89 | // 90 | //! netapp_config_mac_adrress 91 | //! 92 | //! @param mac device mac address, 6 bytes. Saved: yes 93 | //! 94 | //! @return return on success 0, otherwise error. 95 | //! 96 | //! @brief Configure device MAC address and store it in NVMEM. 97 | //! The value of the MAC address configured through the API will 98 | //! be stored in CC3000 non volatile memory, thus preserved 99 | //! over resets. 100 | // 101 | //***************************************************************************** 102 | extern long netapp_config_mac_adrress( unsigned char *mac ); 103 | 104 | //***************************************************************************** 105 | // 106 | //! netapp_dhcp 107 | //! 108 | //! @param aucIP device mac address, 6 bytes. Saved: yes 109 | //! @param aucSubnetMask device mac address, 6 bytes. Saved: yes 110 | //! @param aucDefaultGateway device mac address, 6 bytes. Saved: yes 111 | //! @param aucDNSServer device mac address, 6 bytes. Saved: yes 112 | //! 113 | //! @return return on success 0, otherwise error. 114 | //! 115 | //! @brief netapp_dhcp is used to configure the network interface, 116 | //! static or dynamic (DHCP).\n In order to activate DHCP mode, 117 | //! aucIP, aucSubnetMask, aucDefaultGateway must be 0. 118 | //! The default mode of CC3000 is DHCP mode. 119 | //! Note that the configuration is saved in non volatile memory 120 | //! and thus preserved over resets. 121 | //! 122 | //! @note If the mode is altered a reset of CC3000 device is required 123 | //! in order to apply changes.\nAlso note that asynchronous event 124 | //! of DHCP_EVENT, which is generated when an IP address is 125 | //! allocated either by the DHCP server or due to static 126 | //! allocation is generated only upon a connection to the 127 | //! AP was established. 128 | //! 129 | //***************************************************************************** 130 | extern long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask,unsigned long *aucDefaultGateway, unsigned long *aucDNSServer); 131 | 132 | 133 | 134 | //***************************************************************************** 135 | // 136 | //! netapp_timeout_values 137 | //! 138 | //! @param aucDHCP DHCP lease time request, also impact 139 | //! the DHCP renew timeout. Range: [0-0xffffffff] seconds, 140 | //! 0 or 0xffffffff == infinity lease timeout. 141 | //! Resolution:10 seconds. Influence: only after 142 | //! reconnecting to the AP. 143 | //! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds. 144 | //! The parameter is saved into the CC3000 NVMEM. 145 | //! The default value on CC3000 is 14400 seconds. 146 | //! 147 | //! @param aucARP ARP refresh timeout, if ARP entry is not updated by 148 | //! incoming packet, the ARP entry will be deleted by 149 | //! the end of the timeout. 150 | //! Range: [0-0xffffffff] seconds, 0 == infinity ARP timeout 151 | //! Resolution: 10 seconds. Influence: on runtime. 152 | //! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds 153 | //! The parameter is saved into the CC3000 NVMEM. 154 | //! The default value on CC3000 is 3600 seconds. 155 | //! 156 | //! @param aucKeepalive Keepalive event sent by the end of keepalive timeout 157 | //! Range: [0-0xffffffff] seconds, 0 == infinity timeout 158 | //! Resolution: 10 seconds. 159 | //! Influence: on runtime. 160 | //! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec 161 | //! The parameter is saved into the CC3000 NVMEM. 162 | //! The default value on CC3000 is 10 seconds. 163 | //! 164 | //! @param aucInactivity Socket inactivity timeout, socket timeout is 165 | //! refreshed by incoming or outgoing packet, by the 166 | //! end of the socket timeout the socket will be closed 167 | //! Range: [0-0xffffffff] sec, 0 == infinity timeout. 168 | //! Resolution: 10 seconds. Influence: on runtime. 169 | //! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec 170 | //! The parameter is saved into the CC3000 NVMEM. 171 | //! The default value on CC3000 is 60 seconds. 172 | //! 173 | //! @return return on success 0, otherwise error. 174 | //! 175 | //! @brief Set new timeout values. Function set new timeout values for: 176 | //! DHCP lease timeout, ARP refresh timeout, keepalive event 177 | //! timeout and socket inactivity timeout 178 | //! 179 | //! @note If a parameter set to non zero value which is less than 20s, 180 | //! it will be set automatically to 20s. 181 | //! 182 | //***************************************************************************** 183 | #ifndef CC3000_TINY_DRIVER 184 | extern long netapp_timeout_values(unsigned long *aucDHCP, unsigned long *aucARP,unsigned long *aucKeepalive, unsigned long *aucInactivity); 185 | #endif 186 | 187 | //***************************************************************************** 188 | // 189 | //! netapp_ping_send 190 | //! 191 | //! @param ip destination IP address 192 | //! @param pingAttempts number of echo requests to send 193 | //! @param pingSize send buffer size which may be up to 1400 bytes 194 | //! @param pingTimeout Time to wait for a response,in milliseconds. 195 | //! 196 | //! @return return on success 0, otherwise error. 197 | //! 198 | //! @brief send ICMP ECHO_REQUEST to network hosts 199 | //! 200 | //! @note If an operation finished successfully asynchronous ping report 201 | //! event will be generated. The report structure is as defined 202 | //! by structure netapp_pingreport_args_t. 203 | //! 204 | //! @warning Calling this function while a previous Ping Requests are in 205 | //! progress will stop the previous ping request. 206 | //***************************************************************************** 207 | 208 | #ifndef CC3000_TINY_DRIVER 209 | extern long netapp_ping_send(unsigned long *ip, unsigned long ulPingAttempts, unsigned long ulPingSize, unsigned long ulPingTimeout); 210 | #endif 211 | 212 | //***************************************************************************** 213 | // 214 | //! netapp_ping_stop 215 | //! 216 | //! @param none 217 | //! 218 | //! @return On success, zero is returned. On error, -1 is returned. 219 | //! 220 | //! @brief Stop any ping request. 221 | //! 222 | //! 223 | //***************************************************************************** 224 | 225 | #ifndef CC3000_TINY_DRIVER 226 | extern long netapp_ping_stop(); 227 | #endif 228 | //***************************************************************************** 229 | // 230 | //! netapp_ping_report 231 | //! 232 | //! @param none 233 | //! 234 | //! @return none 235 | //! 236 | //! @brief Request for ping status. This API triggers the CC3000 to send 237 | //! asynchronous events: HCI_EVNT_WLAN_ASYNC_PING_REPORT. 238 | //! This event will carry the report structure: 239 | //! netapp_pingreport_args_t. This structure is filled in with ping 240 | //! results up till point of triggering API. 241 | //! netapp_pingreport_args_t:\n packets_sent - echo sent, 242 | //! packets_received - echo reply, min_round_time - minimum 243 | //! round time, max_round_time - max round time, 244 | //! avg_round_time - average round time 245 | //! 246 | //! @note When a ping operation is not active, the returned structure 247 | //! fields are 0. 248 | //! 249 | //***************************************************************************** 250 | #ifndef CC3000_TINY_DRIVER 251 | extern void netapp_ping_report(); 252 | #endif 253 | 254 | 255 | //***************************************************************************** 256 | // 257 | //! netapp_ipconfig 258 | //! 259 | //! @param[out] ipconfig This argument is a pointer to a 260 | //! tNetappIpconfigRetArgs structure. This structure is 261 | //! filled in with the network interface configuration. 262 | //! tNetappIpconfigRetArgs:\n aucIP - ip address, 263 | //! aucSubnetMask - mask, aucDefaultGateway - default 264 | //! gateway address, aucDHCPServer - dhcp server address 265 | //! aucDNSServer - dns server address, uaMacAddr - mac 266 | //! address, uaSSID - connected AP ssid 267 | //! 268 | //! @return none 269 | //! 270 | //! @brief Obtain the CC3000 Network interface information. 271 | //! Note that the information is available only after the WLAN 272 | //! connection was established. Calling this function before 273 | //! associated, will cause non-defined values to be returned. 274 | //! 275 | //! @note The function is useful for figuring out the IP Configuration of 276 | //! the device when DHCP is used and for figuring out the SSID of 277 | //! the Wireless network the device is associated with. 278 | //! 279 | //***************************************************************************** 280 | 281 | extern void netapp_ipconfig( tNetappIpconfigRetArgs * ipconfig ); 282 | 283 | 284 | //***************************************************************************** 285 | // 286 | //! netapp_arp_flush 287 | //! 288 | //! @param none 289 | //! 290 | //! @return none 291 | //! 292 | //! @brief Flushes ARP table 293 | //! 294 | //***************************************************************************** 295 | 296 | #ifndef CC3000_TINY_DRIVER 297 | extern long netapp_arp_flush(); 298 | #endif 299 | 300 | 301 | //***************************************************************************** 302 | // 303 | //! netapp_set_debug_level 304 | //! 305 | //! @param[in] level debug level. Bitwise [0-8], 306 | //! 0(disable)or 1(enable).\n Bitwise map: 0 - Critical 307 | //! message, 1 information message, 2 - core messages, 3 - 308 | //! HCI messages, 4 - Network stack messages, 5 - wlan 309 | //! messages, 6 - wlan driver messages, 7 - epprom messages, 310 | //! 8 - general messages. Default: 0x13f. Saved: no 311 | //! 312 | //! @return On success, zero is returned. On error, -1 is returned 313 | //! 314 | //! @brief Debug messages sent via the UART debug channel, this function 315 | //! enable/disable the debug level 316 | //! 317 | //***************************************************************************** 318 | 319 | 320 | #ifndef CC3000_TINY_DRIVER 321 | long netapp_set_debug_level(unsigned long ulLevel); 322 | #endif 323 | //***************************************************************************** 324 | // 325 | // Close the Doxygen group. 326 | //! @} 327 | // 328 | //***************************************************************************** 329 | 330 | 331 | 332 | //***************************************************************************** 333 | // 334 | // Mark the end of the C bindings section for C++ compilers. 335 | // 336 | //***************************************************************************** 337 | #ifdef __cplusplus 338 | } 339 | #endif // __cplusplus 340 | 341 | #endif // __NETAPP_H__ 342 | 343 | -------------------------------------------------------------------------------- /utility/cc3000_common.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file evnt_handler.h 3 | * @brief CC3000 library functions to handle asynchronous events 4 | * @author Texas Instruments 5 | * @author Modified by Shawn Hymel (SparkFun Electronics) 6 | * 7 | * Changes to the original code are listed below: 8 | * 9 | * - Moved "Common Defines" section from .cpp to .h to be accessible 10 | */ 11 | 12 | /***************************************************************************** 13 | * 14 | * cc3000_common.h - CC3000 Host Driver Implementation. 15 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 16 | * 17 | * Redistribution and use in source and binary forms, with or without 18 | * modification, are permitted provided that the following conditions 19 | * are met: 20 | * 21 | * Redistributions of source code must retain the above copyright 22 | * notice, this list of conditions and the following disclaimer. 23 | * 24 | * Redistributions in binary form must reproduce the above copyright 25 | * notice, this list of conditions and the following disclaimer in the 26 | * documentation and/or other materials provided with the 27 | * distribution. 28 | * 29 | * Neither the name of Texas Instruments Incorporated nor the names of 30 | * its contributors may be used to endorse or promote products derived 31 | * from this software without specific prior written permission. 32 | * 33 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 34 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 35 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 36 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 37 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 38 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 39 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 40 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 41 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 42 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 43 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 44 | * 45 | *****************************************************************************/ 46 | #ifndef __COMMON_H__ 47 | #define __COMMON_H__ 48 | 49 | //****************************************************************************** 50 | // Include files 51 | //****************************************************************************** 52 | #include 53 | #include 54 | #include 55 | 56 | //***************************************************************************** 57 | // 58 | // If building with a C++ compiler, make all of the definitions in this header 59 | // have a C binding. 60 | // 61 | //***************************************************************************** 62 | #ifdef __cplusplus 63 | extern "C" { 64 | #endif 65 | 66 | //***************************************************************************** 67 | // ERROR CODES 68 | //***************************************************************************** 69 | #define ESUCCESS 0 70 | #define EFAIL -1 71 | #define EERROR EFAIL 72 | 73 | //***************************************************************************** 74 | // COMMON DEFINES FROM CPP FILE 75 | //***************************************************************************** 76 | 77 | #define FLOW_CONTROL_EVENT_HANDLE_OFFSET (0) 78 | #define FLOW_CONTROL_EVENT_BLOCK_MODE_OFFSET (1) 79 | #define FLOW_CONTROL_EVENT_FREE_BUFFS_OFFSET (2) 80 | #define FLOW_CONTROL_EVENT_SIZE (4) 81 | 82 | #define BSD_RSP_PARAMS_SOCKET_OFFSET (0) 83 | #define BSD_RSP_PARAMS_STATUS_OFFSET (4) 84 | 85 | #define GET_HOST_BY_NAME_RETVAL_OFFSET (0) 86 | #define GET_HOST_BY_NAME_ADDR_OFFSET (4) 87 | 88 | #define ACCEPT_SD_OFFSET (0) 89 | #define ACCEPT_RETURN_STATUS_OFFSET (4) 90 | #define ACCEPT_ADDRESS__OFFSET (8) 91 | 92 | #define SL_RECEIVE_SD_OFFSET (0) 93 | #define SL_RECEIVE_NUM_BYTES_OFFSET (4) 94 | #define SL_RECEIVE__FLAGS__OFFSET (8) 95 | 96 | 97 | #define SELECT_STATUS_OFFSET (0) 98 | #define SELECT_READFD_OFFSET (4) 99 | #define SELECT_WRITEFD_OFFSET (8) 100 | #define SELECT_EXFD_OFFSET (12) 101 | 102 | #define NETAPP_IPCONFIG_IP_OFFSET (0) 103 | #define NETAPP_IPCONFIG_SUBNET_OFFSET (4) 104 | #define NETAPP_IPCONFIG_GW_OFFSET (8) 105 | #define NETAPP_IPCONFIG_DHCP_OFFSET (12) 106 | #define NETAPP_IPCONFIG_DNS_OFFSET (16) 107 | #define NETAPP_IPCONFIG_MAC_OFFSET (20) 108 | #define NETAPP_IPCONFIG_SSID_OFFSET (26) 109 | 110 | #define NETAPP_IPCONFIG_IP_LENGTH (4) 111 | #define NETAPP_IPCONFIG_MAC_LENGTH (6) 112 | #define NETAPP_IPCONFIG_SSID_LENGTH (32) 113 | 114 | 115 | #define NETAPP_PING_PACKETS_SENT_OFFSET (0) 116 | #define NETAPP_PING_PACKETS_RCVD_OFFSET (4) 117 | #define NETAPP_PING_MIN_RTT_OFFSET (8) 118 | #define NETAPP_PING_MAX_RTT_OFFSET (12) 119 | #define NETAPP_PING_AVG_RTT_OFFSET (16) 120 | 121 | #define GET_SCAN_RESULTS_TABlE_COUNT_OFFSET (0) 122 | #define GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET (4) 123 | #define GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET (8) 124 | #define GET_SCAN_RESULTS_FRAME_TIME_OFFSET (10) 125 | #define GET_SCAN_RESULTS_SSID_MAC_LENGTH (38) 126 | 127 | //***************************************************************************** 128 | // COMMON DEFINES 129 | //***************************************************************************** 130 | #define ERROR_SOCKET_INACTIVE -57 131 | 132 | #define WLAN_ENABLE (1) 133 | #define WLAN_DISABLE (0) 134 | 135 | #define MAC_ADDR_LEN (6) 136 | 137 | #define SP_PORTION_SIZE (32) 138 | 139 | /*Defines for minimal and maximal RX buffer size. This size includes the spi 140 | header and hci header. 141 | The maximal buffer size derives from: 142 | MTU + HCI header + SPI header + sendto() agrs size 143 | The minimum buffer size derives from: 144 | HCI header + SPI header + max args size 145 | 146 | This buffer is used for receiving events and data. 147 | The packet can not be longer than MTU size and CC3000 does not support 148 | fragmentation. Note that the same buffer is used for reception of the data 149 | and events from CC3000. That is why the minimum is defined. 150 | The calculation for the actual size of buffer for reception is: 151 | Given the maximal data size MAX_DATA that is expected to be received by 152 | application, the required buffer is: 153 | Using recv() or recvfrom(): 154 | 155 | max(CC3000_MINIMAL_RX_SIZE, MAX_DATA + HEADERS_SIZE_DATA + fromlen 156 | + ucArgsize + 1) 157 | 158 | Using gethostbyname() with minimal buffer size will limit the host name 159 | returned to 99 bytes only. 160 | The 1 is used for the overrun detection 161 | 162 | Buffer size increased to 130 following the add_profile() with WEP security 163 | which requires TX buffer size of 130 bytes: 164 | HEADERS_SIZE_EVNT + WLAN_ADD_PROFILE_WEP_PARAM_LEN + MAX SSID LEN + 4 * MAX KEY LEN = 130 165 | MAX SSID LEN = 32 166 | MAX SSID LEN = 13 (with add_profile only ascii key setting is supported, 167 | therfore maximum key size is 13) 168 | */ 169 | 170 | #define CC3000_MINIMAL_RX_SIZE (130 + 1) 171 | #define CC3000_MAXIMAL_RX_SIZE (1519 + 1) 172 | 173 | /*Defines for minimal and maximal TX buffer size. 174 | This buffer is used for sending events and data. 175 | The packet can not be longer than MTU size and CC3000 does not support 176 | fragmentation. Note that the same buffer is used for transmission of the data 177 | and commands. That is why the minimum is defined. 178 | The calculation for the actual size of buffer for transmission is: 179 | Given the maximal data size MAX_DATA, the required buffer is: 180 | Using Sendto(): 181 | 182 | max(CC3000_MINIMAL_TX_SIZE, MAX_DATA + SPI_HEADER_SIZE 183 | + SOCKET_SENDTO_PARAMS_LEN + SIMPLE_LINK_HCI_DATA_HEADER_SIZE + 1) 184 | 185 | Using Send(): 186 | 187 | max(CC3000_MINIMAL_TX_SIZE, MAX_DATA + SPI_HEADER_SIZE 188 | + HCI_CMND_SEND_ARG_LENGTH + SIMPLE_LINK_HCI_DATA_HEADER_SIZE + 1) 189 | 190 | The 1 is used for the overrun detection */ 191 | 192 | #define CC3000_MINIMAL_TX_SIZE (130 + 1) 193 | #define CC3000_MAXIMAL_TX_SIZE (1519 + 1) 194 | 195 | //TX and RX buffer sizes, allow to receive and transmit maximum data at length 8. 196 | #ifdef CC3000_TINY_DRIVER 197 | #define TINY_CC3000_MAXIMAL_RX_SIZE 44 198 | #define TINY_CC3000_MAXIMAL_TX_SIZE 59 199 | #endif 200 | 201 | /*In order to determine your preferred buffer size, 202 | change CC3000_MAXIMAL_RX_SIZE and CC3000_MAXIMAL_TX_SIZE to a value between 203 | the minimal and maximal specified above. 204 | Note that the buffers are allocated by SPI. 205 | In case you change the size of those buffers, you might need also to change 206 | the linker file, since for example on MSP430 FRAM devices the buffers are 207 | allocated in the FRAM section that is allocated manually and not by IDE. 208 | */ 209 | 210 | #ifndef CC3000_TINY_DRIVER 211 | 212 | #define CC3000_RX_BUFFER_SIZE (CC3000_MINIMAL_RX_SIZE) 213 | #define CC3000_TX_BUFFER_SIZE (CC3000_MINIMAL_TX_SIZE) 214 | 215 | //if defined TINY DRIVER we use smaller RX and TX buffer in order to minimize RAM consumption 216 | #else 217 | #define CC3000_RX_BUFFER_SIZE (TINY_CC3000_MAXIMAL_RX_SIZE) 218 | #define CC3000_TX_BUFFER_SIZE (TINY_CC3000_MAXIMAL_TX_SIZE) 219 | 220 | #endif 221 | 222 | //***************************************************************************** 223 | // Compound Types 224 | //***************************************************************************** 225 | typedef long time_t; 226 | typedef unsigned long clock_t; 227 | typedef long suseconds_t; 228 | 229 | typedef struct timeval timeval; 230 | 231 | struct timeval 232 | { 233 | time_t tv_sec; /* seconds */ 234 | suseconds_t tv_usec; /* microseconds */ 235 | }; 236 | 237 | typedef char *(*tFWPatches)(unsigned long *usLength); 238 | 239 | typedef char *(*tDriverPatches)(unsigned long *usLength); 240 | 241 | typedef char *(*tBootLoaderPatches)(unsigned long *usLength); 242 | 243 | typedef void (*tWlanCB)(long event_type, char * data, unsigned char length ); 244 | 245 | typedef long (*tWlanReadInteruptPin)(void); 246 | 247 | typedef void (*tWlanInterruptEnable)(void); 248 | 249 | typedef void (*tWlanInterruptDisable)(void); 250 | 251 | typedef void (*tWriteWlanPin)(unsigned char val); 252 | 253 | typedef struct 254 | { 255 | unsigned short usRxEventOpcode; 256 | unsigned short usEventOrDataReceived; 257 | unsigned char *pucReceivedData; 258 | unsigned char *pucTxCommandBuffer; 259 | 260 | tFWPatches sFWPatches; 261 | tDriverPatches sDriverPatches; 262 | tBootLoaderPatches sBootLoaderPatches; 263 | tWlanCB sWlanCB; 264 | tWlanReadInteruptPin ReadWlanInterruptPin; 265 | tWlanInterruptEnable WlanInterruptEnable; 266 | tWlanInterruptDisable WlanInterruptDisable; 267 | tWriteWlanPin WriteWlanPin; 268 | 269 | signed long slTransmitDataError; 270 | unsigned short usNumberOfFreeBuffers; 271 | unsigned short usSlBufferLength; 272 | unsigned short usBufferSize; 273 | unsigned short usRxDataPending; 274 | 275 | unsigned long NumberOfSentPackets; 276 | unsigned long NumberOfReleasedPackets; 277 | 278 | unsigned char InformHostOnTxComplete; 279 | }sSimplLinkInformation; 280 | 281 | extern volatile sSimplLinkInformation tSLInformation; 282 | 283 | 284 | //***************************************************************************** 285 | // Prototypes for the APIs. 286 | //***************************************************************************** 287 | 288 | 289 | 290 | //***************************************************************************** 291 | // 292 | //! SimpleLinkWaitEvent 293 | //! 294 | //! @param usOpcode command operation code 295 | //! @param pRetParams command return parameters 296 | //! 297 | //! @return none 298 | //! 299 | //! @brief Wait for event, pass it to the hci_event_handler and 300 | //! update the event opcode in a global variable. 301 | // 302 | //***************************************************************************** 303 | 304 | extern void SimpleLinkWaitEvent(unsigned short usOpcode, void *pRetParams); 305 | 306 | //***************************************************************************** 307 | // 308 | //! SimpleLinkWaitData 309 | //! 310 | //! @param pBuf data buffer 311 | //! @param from from information 312 | //! @param fromlen from information length 313 | //! 314 | //! @return none 315 | //! 316 | //! @brief Wait for data, pass it to the hci_event_handler 317 | //! and update in a global variable that there is 318 | //! data to read. 319 | // 320 | //***************************************************************************** 321 | 322 | extern void SimpleLinkWaitData(unsigned char *pBuf, unsigned char *from, unsigned char *fromlen); 323 | 324 | //***************************************************************************** 325 | // 326 | //! UINT32_TO_STREAM_f 327 | //! 328 | //! \param p pointer to the new stream 329 | //! \param u32 pointer to the 32 bit 330 | //! 331 | //! \return pointer to the new stream 332 | //! 333 | //! \brief This function is used for copying 32 bit to stream 334 | //! while converting to little endian format. 335 | // 336 | //***************************************************************************** 337 | 338 | extern unsigned char* UINT32_TO_STREAM_f (unsigned char *p, unsigned long u32); 339 | 340 | //***************************************************************************** 341 | // 342 | //! UINT16_TO_STREAM_f 343 | //! 344 | //! \param p pointer to the new stream 345 | //! \param u32 pointer to the 16 bit 346 | //! 347 | //! \return pointer to the new stream 348 | //! 349 | //! \brief This function is used for copying 16 bit to stream 350 | //! while converting to little endian format. 351 | // 352 | //***************************************************************************** 353 | 354 | extern unsigned char* UINT16_TO_STREAM_f (unsigned char *p, unsigned short u16); 355 | 356 | //***************************************************************************** 357 | // 358 | //! STREAM_TO_UINT16_f 359 | //! 360 | //! \param p pointer to the stream 361 | //! \param offset offset in the stream 362 | //! 363 | //! \return pointer to the new 16 bit 364 | //! 365 | //! \brief This function is used for copying received stream to 366 | //! 16 bit in little endian format. 367 | // 368 | //***************************************************************************** 369 | 370 | extern unsigned short STREAM_TO_UINT16_f(char* p, unsigned short offset); 371 | 372 | //***************************************************************************** 373 | // 374 | //! STREAM_TO_UINT32_f 375 | //! 376 | //! \param p pointer to the stream 377 | //! \param offset offset in the stream 378 | //! 379 | //! \return pointer to the new 32 bit 380 | //! 381 | //! \brief This function is used for copying received stream to 382 | //! 32 bit in little endian format. 383 | // 384 | //***************************************************************************** 385 | 386 | extern unsigned long STREAM_TO_UINT32_f(char* p, unsigned short offset); 387 | 388 | 389 | //***************************************************************************** 390 | // COMMON MACROs 391 | //***************************************************************************** 392 | 393 | 394 | //This macro is used for copying 8 bit to stream while converting to little endian format. 395 | #define UINT8_TO_STREAM(_p, _val) {*(_p)++ = (_val);} 396 | //This macro is used for copying 16 bit to stream while converting to little endian format. 397 | #define UINT16_TO_STREAM(_p, _u16) (UINT16_TO_STREAM_f(_p, _u16)) 398 | //This macro is used for copying 32 bit to stream while converting to little endian format. 399 | #define UINT32_TO_STREAM(_p, _u32) (UINT32_TO_STREAM_f(_p, _u32)) 400 | //This macro is used for copying a specified value length bits (l) to stream while converting to little endian format. 401 | #define ARRAY_TO_STREAM(p, a, l) {register short _i; for (_i = 0; _i < l; _i++) *(p)++ = ((unsigned char *) a)[_i];} 402 | //This macro is used for copying received stream to 8 bit in little endian format. 403 | #define STREAM_TO_UINT8(_p, _offset, _u8) {_u8 = (unsigned char)(*(_p + _offset));} 404 | //This macro is used for copying received stream to 16 bit in little endian format. 405 | #define STREAM_TO_UINT16(_p, _offset, _u16) {_u16 = STREAM_TO_UINT16_f(_p, _offset);} 406 | //This macro is used for copying received stream to 32 bit in little endian format. 407 | #define STREAM_TO_UINT32(_p, _offset, _u32) {_u32 = STREAM_TO_UINT32_f(_p, _offset);} 408 | #define STREAM_TO_STREAM(p, a, l) {register short _i; for (_i = 0; _i < l; _i++) *(a)++= ((unsigned char *) p)[_i];} 409 | 410 | 411 | 412 | 413 | //***************************************************************************** 414 | // 415 | // Mark the end of the C bindings section for C++ compilers. 416 | // 417 | //***************************************************************************** 418 | #ifdef __cplusplus 419 | } 420 | #endif // __cplusplus 421 | 422 | #endif // __COMMON_H__ 423 | -------------------------------------------------------------------------------- /utility/netapp.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file netapp.cpp 3 | * @brief CC3000 library functions to handle socket connections over WiFi 4 | * @author Texas Instruments 5 | * @author Modified by Shawn Hymel (SparkFun Electronics) 6 | * 7 | * Changes to the original code are listed below: 8 | * 9 | * - Changed file name from *.c to *.cpp to force the Arduino compiler to 10 | * treat it as a C++ file 11 | * 12 | * - Added the following to allow for debugging: 13 | * #include 14 | * #include "../common.h" 15 | */ 16 | 17 | /***************************************************************************** 18 | * 19 | * netapp.c - CC3000 Host Driver Implementation. 20 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 21 | * 22 | * Redistribution and use in source and binary forms, with or without 23 | * modification, are permitted provided that the following conditions 24 | * are met: 25 | * 26 | * Redistributions of source code must retain the above copyright 27 | * notice, this list of conditions and the following disclaimer. 28 | * 29 | * Redistributions in binary form must reproduce the above copyright 30 | * notice, this list of conditions and the following disclaimer in the 31 | * documentation and/or other materials provided with the 32 | * distribution. 33 | * 34 | * Neither the name of Texas Instruments Incorporated nor the names of 35 | * its contributors may be used to endorse or promote products derived 36 | * from this software without specific prior written permission. 37 | * 38 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 39 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 40 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 41 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 42 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 43 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 44 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 45 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 46 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 47 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 48 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 49 | * 50 | *****************************************************************************/ 51 | #include 52 | #include "../common.h" 53 | 54 | #include 55 | #include "netapp.h" 56 | #include "hci.h" 57 | #include "socket.h" 58 | #include "evnt_handler.h" 59 | #include "nvmem.h" 60 | 61 | #define MIN_TIMER_VAL_SECONDS 20 62 | #define MIN_TIMER_SET(t) if ((0 != t) && (t < MIN_TIMER_VAL_SECONDS)) \ 63 | { \ 64 | t = MIN_TIMER_VAL_SECONDS; \ 65 | } 66 | 67 | 68 | #define NETAPP_DHCP_PARAMS_LEN (20) 69 | #define NETAPP_SET_TIMER_PARAMS_LEN (20) 70 | #define NETAPP_SET_DEBUG_LEVEL_PARAMS_LEN (4) 71 | #define NETAPP_PING_SEND_PARAMS_LEN (16) 72 | 73 | 74 | //***************************************************************************** 75 | // 76 | //! netapp_config_mac_adrress 77 | //! 78 | //! @param mac device mac address, 6 bytes. Saved: yes 79 | //! 80 | //! @return return on success 0, otherwise error. 81 | //! 82 | //! @brief Configure device MAC address and store it in NVMEM. 83 | //! The value of the MAC address configured through the API will 84 | //! be stored in CC3000 non volatile memory, thus preserved 85 | //! over resets. 86 | // 87 | //***************************************************************************** 88 | long netapp_config_mac_adrress(unsigned char * mac) 89 | { 90 | return nvmem_set_mac_address(mac); 91 | } 92 | 93 | //***************************************************************************** 94 | // 95 | //! netapp_dhcp 96 | //! 97 | //! @param aucIP device mac address, 6 bytes. Saved: yes 98 | //! @param aucSubnetMask device mac address, 6 bytes. Saved: yes 99 | //! @param aucDefaultGateway device mac address, 6 bytes. Saved: yes 100 | //! @param aucDNSServer device mac address, 6 bytes. Saved: yes 101 | //! 102 | //! @return return on success 0, otherwise error. 103 | //! 104 | //! @brief netapp_dhcp is used to configure the network interface, 105 | //! static or dynamic (DHCP).\n In order to activate DHCP mode, 106 | //! aucIP, aucSubnetMask, aucDefaultGateway must be 0. 107 | //! The default mode of CC3000 is DHCP mode. 108 | //! Note that the configuration is saved in non volatile memory 109 | //! and thus preserved over resets. 110 | //! 111 | //! @note If the mode is altered a reset of CC3000 device is required 112 | //! in order to apply changes.\nAlso note that asynchronous event 113 | //! of DHCP_EVENT, which is generated when an IP address is 114 | //! allocated either by the DHCP server or due to static 115 | //! allocation is generated only upon a connection to the 116 | //! AP was established. 117 | //! 118 | //***************************************************************************** 119 | long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask,unsigned long *aucDefaultGateway, unsigned long *aucDNSServer) 120 | { 121 | signed char scRet; 122 | unsigned char *ptr; 123 | unsigned char *args; 124 | 125 | scRet = EFAIL; 126 | ptr = tSLInformation.pucTxCommandBuffer; 127 | args = (ptr + HEADERS_SIZE_CMD); 128 | 129 | // Fill in temporary command buffer 130 | ARRAY_TO_STREAM(args,aucIP,4); 131 | ARRAY_TO_STREAM(args,aucSubnetMask,4); 132 | ARRAY_TO_STREAM(args,aucDefaultGateway,4); 133 | args = UINT32_TO_STREAM(args, 0); 134 | ARRAY_TO_STREAM(args,aucDNSServer,4); 135 | 136 | // Initiate a HCI command 137 | hci_command_send(HCI_NETAPP_DHCP, ptr, NETAPP_DHCP_PARAMS_LEN); 138 | 139 | // Wait for command complete event 140 | SimpleLinkWaitEvent(HCI_NETAPP_DHCP, &scRet); 141 | 142 | return(scRet); 143 | } 144 | 145 | 146 | //***************************************************************************** 147 | // 148 | //! netapp_timeout_values 149 | //! 150 | //! @param aucDHCP DHCP lease time request, also impact 151 | //! the DHCP renew timeout. Range: [0-0xffffffff] seconds, 152 | //! 0 or 0xffffffff == infinity lease timeout. 153 | //! Resolution:10 seconds. Influence: only after 154 | //! reconnecting to the AP. 155 | //! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds. 156 | //! The parameter is saved into the CC3000 NVMEM. 157 | //! The default value on CC3000 is 14400 seconds. 158 | //! 159 | //! @param aucARP ARP refresh timeout, if ARP entry is not updated by 160 | //! incoming packet, the ARP entry will be deleted by 161 | //! the end of the timeout. 162 | //! Range: [0-0xffffffff] seconds, 0 == infinity ARP timeout 163 | //! Resolution: 10 seconds. Influence: on runtime. 164 | //! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds 165 | //! The parameter is saved into the CC3000 NVMEM. 166 | //! The default value on CC3000 is 3600 seconds. 167 | //! 168 | //! @param aucKeepalive Keepalive event sent by the end of keepalive timeout 169 | //! Range: [0-0xffffffff] seconds, 0 == infinity timeout 170 | //! Resolution: 10 seconds. 171 | //! Influence: on runtime. 172 | //! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec 173 | //! The parameter is saved into the CC3000 NVMEM. 174 | //! The default value on CC3000 is 10 seconds. 175 | //! 176 | //! @param aucInactivity Socket inactivity timeout, socket timeout is 177 | //! refreshed by incoming or outgoing packet, by the 178 | //! end of the socket timeout the socket will be closed 179 | //! Range: [0-0xffffffff] sec, 0 == infinity timeout. 180 | //! Resolution: 10 seconds. Influence: on runtime. 181 | //! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec 182 | //! The parameter is saved into the CC3000 NVMEM. 183 | //! The default value on CC3000 is 60 seconds. 184 | //! 185 | //! @return return on success 0, otherwise error. 186 | //! 187 | //! @brief Set new timeout values. Function set new timeout values for: 188 | //! DHCP lease timeout, ARP refresh timeout, keepalive event 189 | //! timeout and socket inactivity timeout 190 | //! 191 | //! @note If a parameter set to non zero value which is less than 20s, 192 | //! it will be set automatically to 20s. 193 | //! 194 | //***************************************************************************** 195 | 196 | #ifndef CC3000_TINY_DRIVER 197 | long 198 | netapp_timeout_values(unsigned long *aucDHCP, unsigned long *aucARP,unsigned long *aucKeepalive, unsigned long *aucInactivity) 199 | { 200 | signed char scRet; 201 | unsigned char *ptr; 202 | unsigned char *args; 203 | 204 | scRet = EFAIL; 205 | ptr = tSLInformation.pucTxCommandBuffer; 206 | args = (ptr + HEADERS_SIZE_CMD); 207 | 208 | // Set minimal values of timers 209 | MIN_TIMER_SET(*aucDHCP) 210 | MIN_TIMER_SET(*aucARP) 211 | MIN_TIMER_SET(*aucKeepalive) 212 | MIN_TIMER_SET(*aucInactivity) 213 | 214 | // Fill in temporary command buffer 215 | args = UINT32_TO_STREAM(args, *aucDHCP); 216 | args = UINT32_TO_STREAM(args, *aucARP); 217 | args = UINT32_TO_STREAM(args, *aucKeepalive); 218 | args = UINT32_TO_STREAM(args, *aucInactivity); 219 | 220 | // Initiate a HCI command 221 | hci_command_send(HCI_NETAPP_SET_TIMERS, ptr, NETAPP_SET_TIMER_PARAMS_LEN); 222 | 223 | // Wait for command complete event 224 | SimpleLinkWaitEvent(HCI_NETAPP_SET_TIMERS, &scRet); 225 | 226 | return(scRet); 227 | } 228 | #endif 229 | 230 | 231 | //***************************************************************************** 232 | // 233 | //! netapp_ping_send 234 | //! 235 | //! @param ip destination IP address 236 | //! @param pingAttempts number of echo requests to send 237 | //! @param pingSize send buffer size which may be up to 1400 bytes 238 | //! @param pingTimeout Time to wait for a response,in milliseconds. 239 | //! 240 | //! @return return on success 0, otherwise error. 241 | //! 242 | //! @brief send ICMP ECHO_REQUEST to network hosts 243 | //! 244 | //! @note If an operation finished successfully asynchronous ping report 245 | //! event will be generated. The report structure is as defined 246 | //! by structure netapp_pingreport_args_t. 247 | //! 248 | //! @warning Calling this function while a previous Ping Requests are in 249 | //! progress will stop the previous ping request. 250 | //***************************************************************************** 251 | 252 | #ifndef CC3000_TINY_DRIVER 253 | long 254 | netapp_ping_send(unsigned long *ip, unsigned long ulPingAttempts, unsigned long ulPingSize, unsigned long ulPingTimeout) 255 | { 256 | signed char scRet; 257 | unsigned char *ptr, *args; 258 | 259 | scRet = EFAIL; 260 | ptr = tSLInformation.pucTxCommandBuffer; 261 | args = (ptr + HEADERS_SIZE_CMD); 262 | 263 | // Fill in temporary command buffer 264 | args = UINT32_TO_STREAM(args, *ip); 265 | args = UINT32_TO_STREAM(args, ulPingAttempts); 266 | args = UINT32_TO_STREAM(args, ulPingSize); 267 | args = UINT32_TO_STREAM(args, ulPingTimeout); 268 | 269 | // Initiate a HCI command 270 | hci_command_send(HCI_NETAPP_PING_SEND, ptr, NETAPP_PING_SEND_PARAMS_LEN); 271 | 272 | // Wait for command complete event 273 | SimpleLinkWaitEvent(HCI_NETAPP_PING_SEND, &scRet); 274 | 275 | return(scRet); 276 | } 277 | #endif 278 | 279 | //***************************************************************************** 280 | // 281 | //! netapp_ping_report 282 | //! 283 | //! @param none 284 | //! 285 | //! @return none 286 | //! 287 | //! @brief Request for ping status. This API triggers the CC3000 to send 288 | //! asynchronous events: HCI_EVNT_WLAN_ASYNC_PING_REPORT. 289 | //! This event will carry the report structure: 290 | //! netapp_pingreport_args_t. This structure is filled in with ping 291 | //! results up till point of triggering API. 292 | //! netapp_pingreport_args_t:\n packets_sent - echo sent, 293 | //! packets_received - echo reply, min_round_time - minimum 294 | //! round time, max_round_time - max round time, 295 | //! avg_round_time - average round time 296 | //! 297 | //! @note When a ping operation is not active, the returned structure 298 | //! fields are 0. 299 | //! 300 | //***************************************************************************** 301 | 302 | 303 | #ifndef CC3000_TINY_DRIVER 304 | void netapp_ping_report() 305 | { 306 | unsigned char *ptr; 307 | ptr = tSLInformation.pucTxCommandBuffer; 308 | signed char scRet; 309 | 310 | scRet = EFAIL; 311 | 312 | // Initiate a HCI command 313 | hci_command_send(HCI_NETAPP_PING_REPORT, ptr, 0); 314 | 315 | // Wait for command complete event 316 | SimpleLinkWaitEvent(HCI_NETAPP_PING_REPORT, &scRet); 317 | } 318 | #endif 319 | 320 | //***************************************************************************** 321 | // 322 | //! netapp_ping_stop 323 | //! 324 | //! @param none 325 | //! 326 | //! @return On success, zero is returned. On error, -1 is returned. 327 | //! 328 | //! @brief Stop any ping request. 329 | //! 330 | //! 331 | //***************************************************************************** 332 | 333 | #ifndef CC3000_TINY_DRIVER 334 | long netapp_ping_stop() 335 | { 336 | signed char scRet; 337 | unsigned char *ptr; 338 | 339 | scRet = EFAIL; 340 | ptr = tSLInformation.pucTxCommandBuffer; 341 | 342 | // Initiate a HCI command 343 | hci_command_send(HCI_NETAPP_PING_STOP, ptr, 0); 344 | 345 | // Wait for command complete event 346 | SimpleLinkWaitEvent(HCI_NETAPP_PING_STOP, &scRet); 347 | 348 | return(scRet); 349 | } 350 | #endif 351 | 352 | //***************************************************************************** 353 | // 354 | //! netapp_ipconfig 355 | //! 356 | //! @param[out] ipconfig This argument is a pointer to a 357 | //! tNetappIpconfigRetArgs structure. This structure is 358 | //! filled in with the network interface configuration. 359 | //! tNetappIpconfigRetArgs:\n aucIP - ip address, 360 | //! aucSubnetMask - mask, aucDefaultGateway - default 361 | //! gateway address, aucDHCPServer - dhcp server address 362 | //! aucDNSServer - dns server address, uaMacAddr - mac 363 | //! address, uaSSID - connected AP ssid 364 | //! 365 | //! @return none 366 | //! 367 | //! @brief Obtain the CC3000 Network interface information. 368 | //! Note that the information is available only after the WLAN 369 | //! connection was established. Calling this function before 370 | //! associated, will cause non-defined values to be returned. 371 | //! 372 | //! @note The function is useful for figuring out the IP Configuration of 373 | //! the device when DHCP is used and for figuring out the SSID of 374 | //! the Wireless network the device is associated with. 375 | //! 376 | //***************************************************************************** 377 | 378 | #ifndef CC3000_TINY_DRIVER 379 | void netapp_ipconfig( tNetappIpconfigRetArgs * ipconfig ) 380 | { 381 | unsigned char *ptr; 382 | 383 | ptr = tSLInformation.pucTxCommandBuffer; 384 | 385 | // Initiate a HCI command 386 | hci_command_send(HCI_NETAPP_IPCONFIG, ptr, 0); 387 | 388 | // Wait for command complete event 389 | SimpleLinkWaitEvent(HCI_NETAPP_IPCONFIG, ipconfig ); 390 | 391 | } 392 | #else 393 | void netapp_ipconfig( tNetappIpconfigRetArgs * ipconfig ) 394 | { 395 | 396 | } 397 | #endif 398 | 399 | //***************************************************************************** 400 | // 401 | //! netapp_arp_flush 402 | //! 403 | //! @param none 404 | //! 405 | //! @return none 406 | //! 407 | //! @brief Flushes ARP table 408 | //! 409 | //***************************************************************************** 410 | 411 | #ifndef CC3000_TINY_DRIVER 412 | long netapp_arp_flush(void) 413 | { 414 | signed char scRet; 415 | unsigned char *ptr; 416 | 417 | scRet = EFAIL; 418 | ptr = tSLInformation.pucTxCommandBuffer; 419 | 420 | // Initiate a HCI command 421 | hci_command_send(HCI_NETAPP_ARP_FLUSH, ptr, 0); 422 | 423 | // Wait for command complete event 424 | SimpleLinkWaitEvent(HCI_NETAPP_ARP_FLUSH, &scRet); 425 | 426 | return(scRet); 427 | } 428 | #endif 429 | 430 | //***************************************************************************** 431 | // 432 | //! netapp_set_debug_level 433 | //! 434 | //! @param[in] level debug level. Bitwise [0-8], 435 | //! 0(disable)or 1(enable).\n Bitwise map: 0 - Critical 436 | //! message, 1 information message, 2 - core messages, 3 - 437 | //! HCI messages, 4 - Network stack messages, 5 - wlan 438 | //! messages, 6 - wlan driver messages, 7 - epprom messages, 439 | //! 8 - general messages. Default: 0x13f. Saved: no 440 | //! 441 | //! @return On success, zero is returned. On error, -1 is returned 442 | //! 443 | //! @brief Debug messages sent via the UART debug channel, this function 444 | //! enable/disable the debug level 445 | //! 446 | //***************************************************************************** 447 | 448 | 449 | #ifndef CC3000_TINY_DRIVER 450 | long netapp_set_debug_level(unsigned long ulLevel) 451 | { 452 | signed char scRet; 453 | unsigned char *ptr, *args; 454 | 455 | scRet = EFAIL; 456 | ptr = tSLInformation.pucTxCommandBuffer; 457 | args = (ptr + HEADERS_SIZE_CMD); 458 | 459 | // 460 | // Fill in temporary command buffer 461 | // 462 | args = UINT32_TO_STREAM(args, ulLevel); 463 | 464 | 465 | // 466 | // Initiate a HCI command 467 | // 468 | hci_command_send(HCI_NETAPP_SET_DEBUG_LEVEL, ptr, NETAPP_SET_DEBUG_LEVEL_PARAMS_LEN); 469 | 470 | // 471 | // Wait for command complete event 472 | // 473 | SimpleLinkWaitEvent(HCI_NETAPP_SET_DEBUG_LEVEL, &scRet); 474 | 475 | return(scRet); 476 | 477 | } 478 | #endif 479 | -------------------------------------------------------------------------------- /SFE_CC3000_SPI.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file SFE_CC3000_SPI.cpp 3 | * @brief CC3000 library functions to handle SPI 4 | * @author Texas Instruments 5 | * @author Modified by Shawn Hymel (SparkFun Electronics) 6 | * 7 | * This code was originally written by TI to work with their microcontrollers. 8 | * Most of it has been altered to work with the Arduino. 9 | */ 10 | 11 | /***************************************************************************** 12 | * 13 | * spi.c - CC3000 Host Driver Implementation. 14 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ 15 | * 16 | * Redistribution and use in source and binary forms, with or without 17 | * modification, are permitted provided that the following conditions 18 | * are met: 19 | * 20 | * Redistributions of source code must retain the above copyright 21 | * notice, this list of conditions and the following disclaimer. 22 | * 23 | * Redistributions in binary form must reproduce the above copyright 24 | * notice, this list of conditions and the following disclaimer in the 25 | * documentation and/or other materials provided with the 26 | * distribution. 27 | * 28 | * Neither the name of Texas Instruments Incorporated nor the names of 29 | * its contributors may be used to endorse or promote products derived 30 | * from this software without specific prior written permission. 31 | * 32 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 35 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 37 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 38 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 39 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 40 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 41 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 42 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 43 | * 44 | *****************************************************************************/ 45 | 46 | #include 47 | #include 48 | 49 | #include "common.h" 50 | #include "SFE_CC3000_SPI.h" 51 | #include "utility/hci.h" 52 | #include "utility/evnt_handler.h" 53 | 54 | 55 | #define READ 3 56 | #define WRITE 1 57 | 58 | #define HI(value) (((value) & 0xFF00) >> 8) 59 | #define LO(value) ((value) & 0x00FF) 60 | 61 | #define HEADERS_SIZE_EVNT (SPI_HEADER_SIZE + 5) 62 | 63 | #define SPI_HEADER_SIZE (5) 64 | 65 | #define eSPI_STATE_POWERUP (0) 66 | #define eSPI_STATE_INITIALIZED (1) 67 | #define eSPI_STATE_IDLE (2) 68 | #define eSPI_STATE_WRITE_IRQ (3) 69 | #define eSPI_STATE_WRITE_FIRST_PORTION (4) 70 | #define eSPI_STATE_WRITE_EOT (5) 71 | #define eSPI_STATE_READ_IRQ (6) 72 | #define eSPI_STATE_READ_FIRST_PORTION (7) 73 | #define eSPI_STATE_READ_EOT (8) 74 | 75 | 76 | typedef struct 77 | { 78 | gcSpiHandleRx SPIRxHandler; 79 | unsigned short usTxPacketLength; 80 | unsigned short usRxPacketLength; 81 | unsigned long ulSpiState; 82 | unsigned char *pTxPacket; 83 | unsigned char *pRxPacket; 84 | 85 | }tSpiInformation; 86 | 87 | 88 | tSpiInformation sSpiInformation; 89 | 90 | 91 | // buffer for 5 bytes of SPI HEADER 92 | unsigned char tSpiReadHeader[] = {READ, 0, 0, 0, 0}; 93 | 94 | // The magic number that resides at the end of the TX/RX buffer (1 byte after 95 | // the allocated size) for the purpose of detection of the overrun. The location 96 | // of the memory where the magic number resides shall never be written. In case 97 | // it is written - the overrun occurred and either receive function or send 98 | // function will stuck forever. 99 | #define CC3000_BUFFER_MAGIC_NUMBER (0xDE) 100 | 101 | char spi_buffer[CC3000_RX_BUFFER_SIZE]; 102 | unsigned char wlan_tx_buffer[CC3000_TX_BUFFER_SIZE]; 103 | 104 | //***************************************************************************** 105 | // 106 | //! SpiClose 107 | //! 108 | //! @param none 109 | //! 110 | //! @return none 111 | //! 112 | //! @brief Close Spi interface 113 | // 114 | //***************************************************************************** 115 | void SpiClose(void) 116 | { 117 | if (sSpiInformation.pRxPacket) 118 | { 119 | sSpiInformation.pRxPacket = 0; 120 | } 121 | 122 | // Disable Interrupt in GPIOA module... 123 | tSLInformation.WlanInterruptDisable(); 124 | } 125 | 126 | 127 | //***************************************************************************** 128 | // 129 | //! SpiOpen 130 | //! 131 | //! @param none 132 | //! 133 | //! @return none 134 | //! 135 | //! @brief Open Spi interface 136 | // 137 | //***************************************************************************** 138 | void SpiOpen(gcSpiHandleRx pfRxHandler) 139 | { 140 | sSpiInformation.ulSpiState = eSPI_STATE_POWERUP; 141 | sSpiInformation.SPIRxHandler = pfRxHandler; 142 | sSpiInformation.usTxPacketLength = 0; 143 | sSpiInformation.pTxPacket = NULL; 144 | sSpiInformation.pRxPacket = (unsigned char *)spi_buffer; 145 | sSpiInformation.usRxPacketLength = 0; 146 | spi_buffer[CC3000_RX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER; 147 | wlan_tx_buffer[CC3000_TX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER; 148 | 149 | // Enable interrupt on the GPIOA pin of WLAN IRQ 150 | tSLInformation.WlanInterruptEnable(); 151 | 152 | } 153 | 154 | //***************************************************************************** 155 | // 156 | //! SpiFirstWrite 157 | //! 158 | //! @param ucBuf buffer to write 159 | //! @param usLength buffer's length 160 | //! 161 | //! @return none 162 | //! 163 | //! @brief enter point for first write flow 164 | // 165 | //***************************************************************************** 166 | long SpiFirstWrite(unsigned char *ucBuf, unsigned short usLength) 167 | { 168 | // Save SPI settings 169 | save_spi_params(); 170 | 171 | // workaround for first transaction 172 | digitalWrite(g_cs_pin, LOW); 173 | 174 | // Assuming we are running on 24 MHz ~50 micro delay is 1200 cycles; 175 | delayMicroseconds(50); 176 | 177 | // SPI writes first 4 bytes of data 178 | SpiWriteDataSynchronous(ucBuf, 4); 179 | 180 | delayMicroseconds(50); 181 | 182 | SpiWriteDataSynchronous(ucBuf + 4, usLength - 4); 183 | 184 | // From this point on - operate in a regular way 185 | sSpiInformation.ulSpiState = eSPI_STATE_IDLE; 186 | 187 | digitalWrite(g_cs_pin, HIGH); 188 | 189 | // Restore SPI settings 190 | restore_spi_params(); 191 | 192 | return(0); 193 | } 194 | 195 | //***************************************************************************** 196 | // 197 | //! SpiWrite 198 | //! 199 | //! @param pUserBuffer buffer to write 200 | //! @param usLength buffer's length 201 | //! 202 | //! @return none 203 | //! 204 | //! @brief Spi write operation 205 | // 206 | //***************************************************************************** 207 | long SpiWrite(unsigned char *pUserBuffer, unsigned short usLength) 208 | { 209 | unsigned char ucPad = 0; 210 | 211 | // Figure out the total length of the packet in order to figure out if there 212 | // is padding or not 213 | if(!(usLength & 0x0001)) 214 | { 215 | ucPad++; 216 | } 217 | 218 | pUserBuffer[0] = WRITE; 219 | pUserBuffer[1] = HI(usLength + ucPad); 220 | pUserBuffer[2] = LO(usLength + ucPad); 221 | pUserBuffer[3] = 0; 222 | pUserBuffer[4] = 0; 223 | 224 | usLength += (SPI_HEADER_SIZE + ucPad); 225 | 226 | // The magic number that resides at the end of the TX/RX buffer (1 byte after 227 | // the allocated size) for the purpose of detection of the overrun. If the 228 | // magic number is overwritten - buffer overrun occurred - and we will stuck 229 | // here forever! 230 | if (wlan_tx_buffer[CC3000_TX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER) 231 | { 232 | while (1) 233 | ; 234 | } 235 | 236 | if (sSpiInformation.ulSpiState == eSPI_STATE_POWERUP) 237 | { 238 | while (sSpiInformation.ulSpiState != eSPI_STATE_INITIALIZED) 239 | ; 240 | } 241 | 242 | if (sSpiInformation.ulSpiState == eSPI_STATE_INITIALIZED) 243 | { 244 | // This is time for first TX/RX transactions over SPI: the IRQ is down - 245 | // so need to send read buffer size command 246 | SpiFirstWrite(pUserBuffer, usLength); 247 | } 248 | else 249 | { 250 | // We need to prevent here race that can occur in case 2 back to back 251 | // packets are sent to the device, so the state will move to IDLE and once 252 | //again to not IDLE due to IRQ 253 | tSLInformation.WlanInterruptDisable(); 254 | 255 | while (sSpiInformation.ulSpiState != eSPI_STATE_IDLE) 256 | { 257 | ; 258 | } 259 | 260 | sSpiInformation.ulSpiState = eSPI_STATE_WRITE_IRQ; 261 | sSpiInformation.pTxPacket = pUserBuffer; 262 | sSpiInformation.usTxPacketLength = usLength; 263 | 264 | // Save SPI settings 265 | save_spi_params(); 266 | 267 | // Assert the CS line and wait till SSI IRQ line is active and then 268 | // initialize write operation 269 | digitalWrite(g_cs_pin, LOW); 270 | 271 | // Re-enable IRQ - if it was not disabled - this is not a problem... 272 | tSLInformation.WlanInterruptEnable(); 273 | 274 | // check for a missing interrupt between the CS assertion and enabling back the interrupts 275 | if (tSLInformation.ReadWlanInterruptPin() == 0) 276 | { 277 | SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength); 278 | 279 | sSpiInformation.ulSpiState = eSPI_STATE_IDLE; 280 | 281 | digitalWrite(g_cs_pin, HIGH); 282 | 283 | // Restore SPI settings 284 | restore_spi_params(); 285 | } 286 | } 287 | 288 | // Due to the fact that we are currently implementing a blocking situation 289 | // here we will wait till end of transaction 290 | while (eSPI_STATE_IDLE != sSpiInformation.ulSpiState) 291 | ; 292 | 293 | return(0); 294 | } 295 | 296 | //***************************************************************************** 297 | // 298 | //! SpiWriteDataSynchronous 299 | //! 300 | //! @param data buffer to write 301 | //! @param size buffer's size 302 | //! 303 | //! @return none 304 | //! 305 | //! @brief Spi write operation 306 | // 307 | //***************************************************************************** 308 | void SpiWriteDataSynchronous(unsigned char *data, unsigned short size) 309 | { 310 | while (size) 311 | { 312 | SPI.transfer(*data); 313 | size --; 314 | data++; 315 | } 316 | } 317 | 318 | //***************************************************************************** 319 | // 320 | //! SpiReadDataSynchronous 321 | //! 322 | //! @param data buffer to read 323 | //! @param size buffer's size 324 | //! 325 | //! @return none 326 | //! 327 | //! @brief Spi read operation 328 | // 329 | //***************************************************************************** 330 | void SpiReadDataSynchronous(unsigned char *data, unsigned short size) 331 | { 332 | long i = 0; 333 | unsigned char *data_to_send = tSpiReadHeader; 334 | 335 | for (i = 0; i < size; i ++) 336 | { 337 | data[i] = SPI.transfer(0x03); 338 | } 339 | } 340 | 341 | //***************************************************************************** 342 | // 343 | //! SpiReadHeader 344 | //! 345 | //! \param buffer 346 | //! 347 | //! \return none 348 | //! 349 | //! \brief This function enter point for read flow: first we read minimal 5 350 | //! SPI header bytes and 5 Event Data bytes 351 | // 352 | //***************************************************************************** 353 | void SpiReadHeader(void) 354 | { 355 | SpiReadDataSynchronous(sSpiInformation.pRxPacket, 10); 356 | } 357 | 358 | //***************************************************************************** 359 | // 360 | //! SpiReadDataCont 361 | //! 362 | //! @param None 363 | //! 364 | //! @return None 365 | //! 366 | //! @brief This function processes received SPI Header and in accordance with 367 | //! it - continues reading the packet 368 | // 369 | //***************************************************************************** 370 | long SpiReadDataCont(void) 371 | { 372 | long data_to_recv; 373 | unsigned char *evnt_buff, type; 374 | 375 | //determine what type of packet we have 376 | evnt_buff = sSpiInformation.pRxPacket; 377 | data_to_recv = 0; 378 | STREAM_TO_UINT8((char *)(evnt_buff + SPI_HEADER_SIZE), 379 | HCI_PACKET_TYPE_OFFSET, type); 380 | 381 | switch(type) 382 | { 383 | case HCI_TYPE_DATA: 384 | { 385 | // We need to read the rest of data.. 386 | STREAM_TO_UINT16((char *)(evnt_buff + SPI_HEADER_SIZE), 387 | HCI_DATA_LENGTH_OFFSET, data_to_recv); 388 | if (!((HEADERS_SIZE_EVNT + data_to_recv) & 1)) 389 | { 390 | data_to_recv++; 391 | } 392 | 393 | if (data_to_recv) 394 | { 395 | SpiReadDataSynchronous(evnt_buff + 10, data_to_recv); 396 | } 397 | break; 398 | } 399 | case HCI_TYPE_EVNT: 400 | { 401 | // Calculate the rest length of the data 402 | STREAM_TO_UINT8((char *)(evnt_buff + SPI_HEADER_SIZE), 403 | HCI_EVENT_LENGTH_OFFSET, data_to_recv); 404 | data_to_recv -= 1; 405 | 406 | // Add padding byte if needed 407 | if ((HEADERS_SIZE_EVNT + data_to_recv) & 1) 408 | { 409 | 410 | data_to_recv++; 411 | } 412 | 413 | if (data_to_recv) 414 | { 415 | SpiReadDataSynchronous(evnt_buff + 10, data_to_recv); 416 | } 417 | 418 | sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT; 419 | break; 420 | } 421 | } 422 | 423 | return (0); 424 | } 425 | 426 | //***************************************************************************** 427 | // 428 | //! SpiPauseSpi 429 | //! 430 | //! @param none 431 | //! 432 | //! @return none 433 | //! 434 | //! @brief Spi pause operation 435 | // 436 | //***************************************************************************** 437 | void SpiPauseSpi(void) 438 | { 439 | detachInterrupt(g_int_num); 440 | } 441 | 442 | //***************************************************************************** 443 | // 444 | //! SpiResumeSpi 445 | //! 446 | //! @param none 447 | //! 448 | //! @return none 449 | //! 450 | //! @brief Spi resume operation 451 | // 452 | //***************************************************************************** 453 | void SpiResumeSpi(void) 454 | { 455 | attachInterrupt(g_int_num, cc3000_ISR, FALLING); 456 | } 457 | 458 | //***************************************************************************** 459 | // 460 | //! SSIContReadOperation 461 | //! 462 | //! @param none 463 | //! 464 | //! @return none 465 | //! 466 | //! @brief SPI read operation 467 | // 468 | //***************************************************************************** 469 | void SSIContReadOperation(void) 470 | { 471 | // The header was read - continue with the payload read 472 | if (!SpiReadDataCont()) 473 | { 474 | 475 | // All the data was read - finalize handling by switching to the task 476 | // and calling from task Event Handler 477 | SpiTriggerRxProcessing(); 478 | } 479 | } 480 | 481 | //***************************************************************************** 482 | // 483 | //! SpiTriggerRxProcessing 484 | //! 485 | //! @param none 486 | //! 487 | //! @return none 488 | //! 489 | //! @brief Spi RX processing 490 | // 491 | //***************************************************************************** 492 | void SpiTriggerRxProcessing(void) 493 | { 494 | // Trigger Rx processing 495 | SpiPauseSpi(); 496 | digitalWrite(g_cs_pin, HIGH); 497 | 498 | // Restore SPI settings 499 | restore_spi_params(); 500 | 501 | // The magic number that resides at the end of the TX/RX buffer (1 byte 502 | // after the allocated size) for the purpose of detection of the overrun. 503 | // If the magic number is overwritten - buffer overrun occurred - and we 504 | // will stuck here forever! 505 | if (sSpiInformation.pRxPacket[CC3000_RX_BUFFER_SIZE - 1] != 506 | CC3000_BUFFER_MAGIC_NUMBER) 507 | { 508 | while (1) 509 | ; 510 | } 511 | 512 | sSpiInformation.ulSpiState = eSPI_STATE_IDLE; 513 | sSpiInformation.SPIRxHandler(sSpiInformation.pRxPacket + SPI_HEADER_SIZE); 514 | } 515 | 516 | //***************************************************************************** 517 | // Custom functions 518 | //***************************************************************************** 519 | 520 | /** 521 | * @brief Gets the SPI mode from the SPI control register 522 | * 523 | * Returns the SPI mode as given by: 524 | * 0x00 = MODE0 525 | * 0x04 = MODE1 526 | * 0x08 = MODE2 527 | * 0x0C = MODE3 528 | * 529 | * @return The SPI mode 530 | */ 531 | uint8_t get_spi_data_mode(void) { 532 | return (SPCR & SPI_MODE_MASK); 533 | } 534 | 535 | /** 536 | * @brief Gets the bit order (MSB or LSB first) of SPI transactions 537 | * 538 | * @return 1 for MSB first, 0 for LSB first 539 | */ 540 | uint8_t get_spi_bit_order(void) { 541 | return bitRead(SPCR, DORD) ? 0 : 1; 542 | } 543 | 544 | /** 545 | * @brief Gets the clock divider for SPI 546 | * 547 | * Returns the clock divider for SPI based on the SPCR and SPSR registers. 548 | * 0x00 = DIV4 549 | * 0x01 = DIV16 550 | * 0x02 = DIV64 551 | * 0x03 = DIV128 552 | * 0x04 = DIV2 553 | * 0x05 = DIV8 554 | * 0x06 = DIV32 555 | * 0x07 = DIV64 (not implemented in Arduino) 556 | * 557 | * @return value of SPI2X, SPR1, and SPR0 bits as an unsigned 8-bit integer 558 | */ 559 | uint8_t get_spi_clock_div(void) { 560 | uint8_t clock_div; 561 | clock_div = (SPCR & SPI_CLOCK_MASK); 562 | clock_div = clock_div | ((SPSR & SPI_2XCLOCK_MASK) << 2); 563 | return clock_div; 564 | } 565 | 566 | /** 567 | * @brief Saves the current SPI parameters in global variables 568 | */ 569 | void save_spi_params(void) { 570 | 571 | /* Save current SPI settings */ 572 | g_saved_data_mode = get_spi_data_mode(); 573 | g_saved_bit_order = get_spi_bit_order(); 574 | g_saved_clock_div = get_spi_clock_div(); 575 | 576 | /* Set SPI settings for CC3000 */ 577 | SPI.setDataMode(SPI_MODE1); 578 | SPI.setBitOrder(MSBFIRST); 579 | SPI.setClockDivider(SPI_CLK_DIV); 580 | 581 | } 582 | 583 | /** 584 | * @brief Restores the previously saved SPI parameters 585 | */ 586 | void restore_spi_params(void) { 587 | SPI.setDataMode(g_saved_data_mode); 588 | SPI.setBitOrder(g_saved_bit_order); 589 | SPI.setClockDivider(g_saved_clock_div); 590 | } 591 | 592 | /** 593 | * @brief Interrupt Service Routine for GPIO interrupt 594 | */ 595 | void cc3000_ISR(void) 596 | { 597 | if (sSpiInformation.ulSpiState == eSPI_STATE_POWERUP) 598 | { 599 | //This means IRQ line was low call a callback of HCI Layer to inform 600 | //on event 601 | sSpiInformation.ulSpiState = eSPI_STATE_INITIALIZED; 602 | } 603 | else if (sSpiInformation.ulSpiState == eSPI_STATE_IDLE) 604 | { 605 | sSpiInformation.ulSpiState = eSPI_STATE_READ_IRQ; 606 | 607 | // Save SPI settings 608 | save_spi_params(); 609 | 610 | //IRQ line goes down - we are start reception 611 | digitalWrite(g_cs_pin, LOW); 612 | 613 | // Wait for TX/RX Compete which will come as DMA interrupt 614 | SpiReadHeader(); 615 | 616 | sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT; 617 | 618 | SSIContReadOperation(); 619 | } 620 | else if (sSpiInformation.ulSpiState == eSPI_STATE_WRITE_IRQ) 621 | { 622 | SpiWriteDataSynchronous(sSpiInformation.pTxPacket, 623 | sSpiInformation.usTxPacketLength); 624 | 625 | sSpiInformation.ulSpiState = eSPI_STATE_IDLE; 626 | 627 | digitalWrite(g_cs_pin, HIGH); 628 | 629 | // Restore SPI settings 630 | restore_spi_params(); 631 | } 632 | 633 | } --------------------------------------------------------------------------------