CC3000 test App

Dependencies:   CC3000HostDriver mbed

Revision:
0:305844973572
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cc3000.cpp	Fri Aug 02 15:14:41 2013 +0000
@@ -0,0 +1,583 @@
+/*****************************************************************************
+*
+*  cc3000.c - CC3000 Functions Implementation
+*  Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+*
+*  Redistribution and use in source and binary forms, with or without
+*  modification, are permitted provided that the following conditions
+*  are met:
+*
+*    Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+*    Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the   
+*    distribution.
+*
+*    Neither the name of Texas Instruments Incorporated nor the names of
+*    its contributors may be used to endorse or promote products derived
+*    from this software without specific prior written permission.
+*
+*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*****************************************************************************/
+
+#include "mbed.h"
+#include "cc3000.h"
+//#include <msp430.h>
+#include "wlan.h" 
+#include "evnt_handler.h"    // callback function declaration
+#include "nvmem.h"
+#include "socket.h"
+//#include "common.h"
+#include "netapp.h"
+//#include "common.h"
+
+//#include "demo_config.h"
+#include "spi.h"
+//#include "board.h"
+//#include "dispatcher.h"
+#include "spi_version.h"
+//#include "application_version.h"
+//#include "host_driver_version.h"
+#include "security.h"
+#include "CC3000TestApp.h"
+#include "CC3000Core.h"
+#include "DigitalClass.h"
+
+
+char CheckSocket = 0;
+// Smart Config Prefix - Texas Instruments
+char aucCC3000_prefix[3] = {'T', 'T', 'T'};
+
+signed char sd[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+const unsigned char smartconfigkey[] = {0x73,0x6d,0x61,0x72,0x74,0x63,0x6f,0x6e,0x66,0x69,0x67,0x41,0x45,0x53,0x31,0x36};
+
+//const unsigned char pucUARTExampleAppString[] = {'\f', '\r','E', 'x', 'a', 'm', 'p', 'l', 'e', ' ', 'A', 'p', 'p', ':', 'd', 'r', 'i', 'v', 'e', 'r', ' ', 'v', 'e', 'r', 's', 'i', 'o', 'n', ' ' };
+unsigned char pucIP_Addr[4];
+unsigned char pucIP_DefaultGWAddr[4];
+unsigned char pucSubnetMask[4];
+unsigned char pucDNS[4];
+char digits[100];
+char cc3000state = CC3000_UNINIT;
+
+tNetappIpconfigRetArgs ipinfo;
+
+// Variable to indicate whether the Smart Config Process has finished
+volatile unsigned long ulSmartConfigFinished = 0;
+
+//*****************************************************************************
+//
+//! ConnectUsingSSID
+//!
+//! \param  ssidName is a string of the AP's SSID
+//!
+//! \return none
+//!
+//! \brief  Connect to an Access Point using the specified SSID
+//
+//*****************************************************************************
+int ConnectUsingSSID(char * ssidName)
+{
+                    
+    unsetCC3000MachineState(CC3000_ASSOC);
+    
+    // Disable Profiles and Fast Connect
+    wlan_ioctl_set_connection_policy(0, 0, 0);
+    
+    wlan_disconnect();
+    
+    //__delay_cycles(10000);
+    wait_us(500);
+    
+    // This triggers the CC3000 to connect to specific AP with certain parameters
+    //sends a request to connect (does not necessarily connect - callback checks that for me)
+#ifndef CC3000_TINY_DRIVER
+    wlan_connect(0, ssidName, strlen(ssidName), NULL, NULL, 0);   
+#else
+    wlan_connect(ssidName, strlen(ssidName));
+#endif
+    // We don't wait for connection. This is handled somewhere else (in the main
+    // loop for example).
+    
+    return 0;      
+}
+
+
+//*****************************************************************************
+//
+//! itoa
+//!
+//! @param[in]  integer number to convert
+//!
+//! @param[in/out]  output string
+//!
+//! @return number of ASCII parameters
+//!
+//! @brief  Convert integer to ASCII in decimal base
+//
+//*****************************************************************************
+unsigned short itoa(char cNum, char *cString)
+{
+    char* ptr;
+    char uTemp = cNum;
+    unsigned short length;
+    
+    
+    // value 0 is a special case
+    if (cNum == 0)
+    {
+        length = 1;
+        *cString = '0';
+        
+        return length;
+    }
+    
+    // Find out the length of the number, in decimal base
+    length = 0;
+    while (uTemp > 0)
+    {
+        uTemp /= 10;
+        length++;
+    }
+    
+    // Do the actual formatting, right to left
+    uTemp = cNum;
+    ptr = cString + length;
+    while (uTemp > 0)
+    {
+        --ptr;
+        *ptr = digits[uTemp % 10];
+        uTemp /= 10;
+    }
+    
+    return length;
+}
+
+
+//*****************************************************************************
+//
+//! sendDriverPatch
+//!
+//! \param  pointer to the length
+//!
+//! \return none
+//!
+//! \brief  The function returns a pointer to the driver patch: since there is no patch yet - 
+//!                it returns 0
+//
+//*****************************************************************************
+char *sendDriverPatch(unsigned long *Length)
+{
+    *Length = 0;
+    return NULL;
+}
+
+
+//*****************************************************************************
+//
+//! sendBootLoaderPatch
+//!
+//! \param  pointer to the length
+//!
+//! \return none
+//!
+//! \brief  The function returns a pointer to the boot loader patch: since there is no patch yet -
+//!                it returns 0
+//
+//*****************************************************************************
+char *sendBootLoaderPatch(unsigned long *Length)
+{
+    *Length = 0;
+    return NULL;
+}
+
+//*****************************************************************************
+//
+//! sendWLFWPatch
+//!
+//! \param  pointer to the length
+//!
+//! \return none
+//!
+//! \brief  The function returns a pointer to the FW patch: since there is no patch yet - it returns 0
+//
+//*****************************************************************************
+
+char *sendWLFWPatch(unsigned long *Length)
+{
+    *Length = 0;
+    return NULL;
+}
+
+
+//*****************************************************************************
+//
+//! CC3000_UsynchCallback
+//!
+//! \param  Event type
+//!
+//! \return none
+//!
+//! \brief  The function handles asynchronous events that come from CC3000 device 
+//!          and operates a LED4 to have an on-board indication
+//
+//*****************************************************************************
+
+void CC3000_UsynchCallback(long lEventType, char * data, unsigned char length)
+{
+    if (lEventType == HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE)
+    {
+        ulSmartConfigFinished = 1;      
+    }
+    
+    if (lEventType == HCI_EVNT_WLAN_UNSOL_INIT)
+    {
+        setCC3000MachineState(CC3000_INIT);
+    }
+    if (lEventType == HCI_EVNT_WLAN_UNSOL_CONNECT)
+    {
+              ulCC3000Connected = 1;
+        setCC3000MachineState(CC3000_ASSOC);
+        
+    }
+    
+    if (lEventType == HCI_EVNT_WLAN_UNSOL_DISCONNECT)
+    {
+        ulCC3000Connected = 0;
+        //restartMSP430();
+        unsetCC3000MachineState(CC3000_ASSOC);
+        
+    }
+    if (lEventType == HCI_EVNT_WLAN_UNSOL_DHCP)
+    {
+        setCC3000MachineState(CC3000_IP_ALLOC);        
+    }
+    
+    // This Event is gengerated when the TCP connection is Half closed
+    if (lEventType == HCI_EVNT_BSD_TCP_CLOSE_WAIT)
+    {
+      sd[data[0]] = 1;
+      CheckSocket = 1;
+    }
+}
+
+//*****************************************************************************
+//
+//! initDriver
+//!
+//!  \param  None
+//!
+//!  \return none
+//!
+//!  \brief  The function initializes a CC3000 device and triggers it to start operation
+//
+//*****************************************************************************
+int
+  initDriver(void)
+{
+        // Init GPIO's
+    //pio_init();
+    DigitalClass pio(p9, p10);
+    // Init SPI
+    init_spi();
+    
+    //DispatcherUARTConfigure();
+    
+    // Globally enable interrupts
+    //__enable_interrupt();
+    //  __enable_irq();  
+    //
+    // WLAN On API Implementation
+    //
+    wlan_init( CC3000_AsynchCallback, sendWLFWPatch, sendDriverPatch, sendBootLoaderPatch, ReadWlanInterruptPin, WlanInterruptEnable, WlanInterruptDisable, WriteWlanPin);
+    
+    //
+    // Trigger a WLAN device
+    //
+    wlan_start(0);
+    
+    //
+    // Mask out all non-required events from CC3000
+    //
+
+    wlan_set_event_mask(HCI_EVNT_WLAN_KEEPALIVE|HCI_EVNT_WLAN_ASYNC_PING_REPORT|HCI_EVNT_WLAN_UNSOL_INIT);
+
+    // Generate event to CLI: send a version string
+    char cc3000IP[50];
+    char *ccPtr;
+    unsigned short ccLen;
+        
+    //DispatcherUartSendPacket((const char*)pucUARTExampleAppString, sizeof(pucUARTExampleAppString));
+        
+    ccPtr = &cc3000IP[0];
+    ccLen = itoa(PALTFORM_VERSION, ccPtr);
+    ccPtr += ccLen;
+    *ccPtr++ = '.';
+    //ccLen = itoa(APPLICATION_VERSION, ccPtr);
+    ccPtr += ccLen;
+    *ccPtr++ = '.';
+    ccLen = itoa(SPI_VERSION_NUMBER, ccPtr);
+    ccPtr += ccLen;
+    *ccPtr++ = '.';
+    //ccLen = itoa(DRIVER_VERSION_NUMBER, ccPtr);
+    ccPtr += ccLen;
+    *ccPtr++ = '\r';
+        *ccPtr++ = '\n';
+    *ccPtr++ = '\0';
+        ccLen = strlen(cc3000IP);
+        
+    //DispatcherUartSendPacket((const char*)cc3000IP, strlen(cc3000IP));
+    
+    // CC3000 has been initialized
+    setCC3000MachineState(CC3000_INIT);
+    
+    unsigned long aucDHCP, aucARP, aucKeepalive, aucInactivity;
+    
+    aucDHCP = 14400;
+    aucARP = 3600;      
+    aucKeepalive = 10;
+    aucInactivity = 50;
+    
+    if(netapp_timeout_values(&(aucDHCP), &(aucARP), &(aucKeepalive), &(aucInactivity)) != 0)
+    {
+      while(1);
+    }
+    
+    return(0);
+}
+
+
+//*****************************************************************************
+//
+//!  \brief  Return the highest state which we're in
+//!
+//!  \param  None
+//!
+//!  \return none
+//!
+//
+//*****************************************************************************
+char highestCC3000State()
+{
+    // We start at the highest state and go down, checking if the state
+    // is set.
+    char mask = 0x80;
+    while(!(cc3000state & mask))
+    {
+        mask = mask >> 1;
+    }
+        
+    return mask;
+}
+
+//*****************************************************************************
+//
+//!  \brief  Return the current state bits
+//!
+//!  \param  None
+//!
+//!  \return none
+//!
+//
+//*****************************************************************************
+char currentCC3000State()
+{
+    return cc3000state;
+}
+
+void setCC3000MachineState(char stat)
+{        
+    char bitmask = stat;
+    cc3000state |= bitmask;
+    
+    int i = FIRST_STATE_LED_NUM;
+    
+    // Find LED number which needs to be set
+    while(bitmask < 0x80)
+    {      
+        bitmask  = bitmask << 1;
+        i++;
+    }    
+    turnLedOn(NUM_STATES-i+2);
+
+}
+
+
+//*****************************************************************************
+//
+//!  \brief  Unsets a state from the state machine
+//!  Also handles LEDs
+//!  
+//!  \param  None
+//!
+//!  \return none
+//!  
+//
+//*****************************************************************************
+void unsetCC3000MachineState(char stat)
+{
+    char bitmask = stat;
+    cc3000state &= ~bitmask;
+    
+    int i = FIRST_STATE_LED_NUM;
+    int k = NUM_STATES; // Set to last element in state list
+    
+    // Set all upper bits to 0 as well since state machine cannot have
+    // those states.
+    while(bitmask < 0x80)
+    {
+        cc3000state &= ~bitmask;
+        bitmask = bitmask << 1;
+        i++;
+    }
+    
+    // Turn off all upper state LEDs
+    for(; i > FIRST_STATE_LED_NUM; i--)
+    {
+        turnLedOff(k);
+        k--;
+    }    
+}
+
+//*****************************************************************************
+//
+//!  \brief  Resets the State Machine
+//!  
+//!  \param  None
+//!
+//!  \return none
+//!  
+//
+//*****************************************************************************
+void resetCC3000StateMachine()
+{
+    cc3000state = CC3000_UNINIT;
+
+    // Turn off all Board LEDs
+
+    turnLedOff(CC3000_ON_IND);
+    turnLedOff(CC3000_ASSOCIATED_IND);
+    turnLedOff(CC3000_IP_ALLOC_IND);
+    turnLedOff(CC3000_SERVER_INIT_IND);
+    turnLedOff(CC3000_CLIENT_CONNECTED_IND);
+    turnLedOff(CC3000_SENDING_DATA_IND);
+    turnLedOff(CC3000_UNUSED1_IND);
+    turnLedOff(CC3000_FTC_IND);
+}
+
+//*****************************************************************************
+//
+//!  \brief  Obtains the CC3000 Connection Information from the CC3000
+//!  
+//!  \param  None
+//!
+//!  \return none
+//!  
+//
+//*****************************************************************************
+#ifndef CC3000_TINY_DRIVER
+tNetappIpconfigRetArgs * getCC3000Info()
+{
+    netapp_ipconfig(&ipinfo);
+    return (&ipinfo);
+}
+#endif
+
+//*****************************************************************************
+//
+//! StartSmartConfig
+//!
+//!  \param  None
+//!
+//!  \return none
+//!
+//!  \brief  The function triggers a smart configuration process on CC3000.
+//!            it exists upon completion of the process
+//
+//*****************************************************************************
+
+void StartSmartConfig(void)
+{
+
+    // Reset all the previous configuration
+    //
+    wlan_ioctl_set_connection_policy(0, 0, 0);    
+        wlan_ioctl_del_profile(255);
+    
+    //Wait until CC3000 is dissconected
+    while (ulCC3000Connected == 1)
+    {
+      //__delay_cycles(100);
+      wait_us(5);
+    }
+
+    // Start blinking LED6 during Smart Configuration process
+    turnLedOn(6);
+    wlan_smart_config_set_prefix(aucCC3000_prefix);
+    //wlan_first_time_config_set_prefix(aucCC3000_prefix);
+    turnLedOff(6);
+    
+    // Start the SmartConfig start process
+    wlan_smart_config_start(1);
+    turnLedOn(6);
+    
+    //
+    // Wait for Smart config finished
+    // 
+    while (ulSmartConfigFinished == 0)
+    {
+        //__delay_cycles(6000000);
+        wait_ms(250);                                                                     
+        turnLedOn(6);
+
+        //__delay_cycles(6000000);
+        wait_ms(250);        
+        turnLedOff(6);
+    }
+
+    turnLedOff(6);
+
+    // create new entry for AES encryption key
+    nvmem_create_entry(NVMEM_AES128_KEY_FILEID,16);
+    
+    // write AES key to NVMEM
+    aes_write_key((unsigned char *)(&smartconfigkey[0]));
+    
+    // Decrypt configuration information and add profile
+    wlan_smart_config_process();
+        
+    //
+    // Configure to connect automatically to the AP retrieved in the 
+    // Smart config process
+    //
+    wlan_ioctl_set_connection_policy(0, 0, 1);
+    
+    //
+    // reset the CC3000
+    // 
+    wlan_stop();
+    //__delay_cycles(600000);
+    wait_ms(25);
+    wlan_start(0);
+
+    unsigned char ConnectUsingSmartConfig  = 1; 
+        ulSmartConfigFinished = 0;
+    //
+    // Mask out all non-required events
+    //
+    wlan_set_event_mask(HCI_EVNT_WLAN_KEEPALIVE|HCI_EVNT_WLAN_UNSOL_INIT|HCI_EVNT_WLAN_ASYNC_PING_REPORT);
+}
+