CC3000 test App
Dependencies: CC3000HostDriver mbed
cc3000.cpp
- Committer:
- dflet
- Date:
- 2013-08-02
- Revision:
- 0:305844973572
File content as of revision 0:305844973572:
/***************************************************************************** * * 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); }