void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT resetCC3000StateMachine(); // Start CC3000 State Machine initDriver(); // Initialize Board and CC3000 unsolicicted_events_timer_init(); // Initialize CC3000 Unsolicited Events Timer __enable_interrupt(); // Enable interrupts for UART DefaultWifiConnection(); // Do a default connection while (1) { hci_unsolicited_event_handler(); // Handle any un-solicited event if required - the function shall be triggered few times in a second unsolicicted_events_timer_init(); if(currentCC3000State() & CC3000_IP_ALLOC) { turnLedOn(CC3000_IP_ALLOC_IND); unsolicicted_events_timer_disable(); // Attempt to start data server initServer(); if(currentCC3000State() & CC3000_SERVER_INIT) { waitForConnection(); } else//Wait for a bit, and try again. { __delay_cycles(100000); } unsolicicted_events_timer_init(); } } }
__interrupt void Timer_B (void) { // Check whether button is still pressed. If so, Smart Config // should be performed. if(!(switchIsPressed())) { // Button is still pressed, so Smart Config should be done runSmartConfig = 1; if(currentCC3000State() & CC3000_IP_ALLOC) { // Since accept and the server is blocking, // we will indicate in non-volatile FRAM that // Smart Config should be run at startup. SetFTCflag(); // Clear Smart Config profile stored flag until connection established. To use the default SSID for connection, press S1 and then the reset button. *SmartConfigProfilestored = 0xFF; restartMSP430(); } } // Restore Switch Interrupt RestoreSwitch(); StopDebounceTimer(); }
tNetappIpconfigRetArgs * getCC3000Info() { if(!(currentCC3000State() & CC3000_SERVER_INIT)) { // If we're not blocked by accept or others, obtain the latest netapp_ipconfig(&ipinfo); } return &ipinfo; }
//***************************************************************************************************************************** //***************************************************************************************************************************** //***************************************************************************************************************************** void waitForConnection(void) { setup_data_packet_header(); //RESET ADC and DMA: refresh_ADC(); ADC_STATE = HALTED; //RESET DMA STATE. refresh_DMA(); DMA_STATE = HALTED; if(currentCC3000State() & CC3000_SERVER_INIT) // Check whether the server functionality is successfully initialized { while(1) // Begin waiting for client and handle the connection { hci_unsolicited_event_handler(); addrlen = sizeof(clientaddr); // accept blocks until we receive a connection while ( (clientDescriptor == -1) || (clientDescriptor == -2) ) { clientDescriptor = accept(serverSocket, (sockaddr *) &clientaddr, &addrlen); } hci_unsolicited_event_handler(); if(clientDescriptor >= 0) // Connection Accepted, Wait for data exchange { setCC3000MachineState(CC3000_CLIENT_CONNECTED); unsolicicted_events_timer_disable(); //********************** // Important Function. Manages incoming Message aswell as initiating outgoing message. incomingPacketManager(); //********************** } else if(clientDescriptor == SOCKET_INACTIVE_ERR) { clientDescriptor = -1; // Reinitialize the server shutdownServer(); initServer(); } if(bytesRecvd < 0){check_socket_connection();} //If the recieve function goes inactive, shuts down. This checks for that case hci_unsolicited_event_handler(); } } }
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) { setCC3000MachineState(CC3000_ASSOC); } if (lEventType == HCI_EVNT_WLAN_UNSOL_DISCONNECT) { if(currentCC3000State() & CC3000_SERVER_INIT) { // We're waiting for a client to connect. However, // because we just received the disconnect event, we're stuck // because of the blocking nature of accept. We restart the MSP430 // so the CC3000 will wait to associate again. // terminalPrint("Restarting MSP430...\r\n"); restartMSP430(); } unsetCC3000MachineState(CC3000_ASSOC); } if (lEventType == HCI_EVNT_WLAN_UNSOL_DHCP) { setCC3000MachineState(CC3000_IP_ALLOC); } }
//***************************************************************************** // //! \brief returns a pointer to the RX buffer at the specific position //! //! \param pos is the location in the RX buffer to which pointer will point //! //! \return a pointer to the RX UART buffer // //***************************************************************************** void runUARTTerminal() { char validPos = 0; char * ftcPrefixptr; if(uartRXByte(bytesInUart()-1) != '\b' && uartRXByte(bytesInUart()-1) != 0x7F) { sendByte(uartRXByte(bytesInUart()-1)); } else { // Do backspace only if it doesn't erase '>' // Note that the backspace is itself in the buffer if(bytesInUart() > 1) { // Echo Backspace and remove latest byte sendByte(uartRXByte(bytesInUart()-1)); // Erase Backspace from buffer removeLastByteinBuf(); // Erase last character removeLastByteinBuf(); } else { // Erase Backspace from buffer removeLastByteinBuf(); } } switch(uartRXByte(bytesInUart()-1)) { case '\r': case '\n': // Erase \r or \n from buffer removeLastByteinBuf(); // Skip all non characters validPos = 0; while(uartRXByte(validPos) < 'A' && validPos <= bytesInUart() ) validPos++; // Process Command if(validPos <= bytesInUart()) { sendString("\n"); // help command if(checkCommand(uartRXBytePointer(validPos),"help") == 1) { printCommandList(); } else if(checkCommand(uartRXBytePointer(validPos),"assoc") == 1) { // Disable RX interrupt so it does not interfere // with GUI's command UCA1IE &= ~UCRXIE; validPos += strlen("assoc"); while(uartRXByte(validPos) < 'A' && validPos <= bytesInUart()) validPos++; *ptrSSIDInd = FLASH_FLAG_SET; memset((char *)ptrSSID, 0, MAX_SSID_LEN); memcpy(ptrSSID,uartRXBytePointer(validPos),MAX_SSID_LEN); sendString("OK\r\n"); // If server is running, accept is blocking us. We can // therefore just restart the MSP430. Since the SSID indicator // has been set, at startup it will attempt to associate to the // AP requested by the user. if(currentCC3000State() & CC3000_SERVER_INIT) { terminalPrint("Restarting MSP430...\r\n"); restartMSP430(); } else { // Associate command ConnectUsingSSID((char *)ptrSSID, (unsigned char *)ptrPASSPHRASE, (long)ptrSECURITY); //ConnectUsingSSID((char *)ptrSSID, (unsigned char *)ptrPASSPHRASE, (unsigned long)ptrSECURITY); } UCA1IE |= UCRXIE; // Enable RX interrupt } else if(checkCommand(uartRXBytePointer(validPos),"stat") == 1) { #ifdef SENSOR_APP_VERSION terminalPrint("Sensor App Version: "); terminalPrint(SENSOR_APP_VERSION); terminalPrint("\r\n"); #endif //#ifndef CC3000_TINY_DRIVER // printConnectionInfo(getCC3000Info()); //#endif } else if(checkCommand(uartRXBytePointer(validPos),"prfx") == 1) { // parameter sent with prfx should be 3 letters // that are the prefix. If they're not, we issue an error validPos += strlen("prfx"); while(uartRXByte(validPos) < 'A' && validPos <= bytesInUart() ) validPos++; if(validPos <= bytesInUart()) { // Verify letters if(isUppercaseChar(uartRXByte(validPos)) && isUppercaseChar(uartRXByte(validPos+1)) && isUppercaseChar(uartRXByte(validPos+2))) { // Wait for 3 characters from UART ftcPrefixptr = (char *)(&aucCC3000_prefix[0]); *ftcPrefixptr = uartRXByte(validPos); ftcPrefixptr = (char *)(&aucCC3000_prefix[1]); *ftcPrefixptr = uartRXByte(validPos+1); ftcPrefixptr = (char *)(&aucCC3000_prefix[2]); *ftcPrefixptr = uartRXByte(validPos+2); // Send new prefix to CC3000 wlan_smart_config_set_prefix((char *)aucCC3000_prefix); char prfStr[4]; prfStr[0] = aucCC3000_prefix[0]; prfStr[1] = aucCC3000_prefix[1]; prfStr[2] = aucCC3000_prefix[2]; prfStr[3] = '\0'; //turnLedOff(CC3000_UNUSED1_IND); sendString("\r\nSmart Config Prefix changed to: "); sendString (prfStr); sendString("\r\n"); } else { sendString("Prefix Error"); } } else { sendString("Prefix Error"); } } else { sendString("Invalid or incomplete command. Type help for command list"); } } // Send '>' sendString("\r\n> "); resetUARTBuffer(); break; } }
//***************************************************************************** // //! checkWiFiConnected //! //! \param None //! //! \return TRUE if connected, FALSE if not //! //! \brief Checks to see that WiFi is still connected. If not associated //! with an AP for 5 consecutive retries, it will reset the board. // //***************************************************************************** unsigned char checkWiFiConnected(void) { unsigned char ipInfoFlagSet = 0; if(!(currentCC3000State() & CC3000_ASSOC)) //try to associate with an Access Point { // // Check whether Smart Config was run previously. If it was, we // use it to connect to an access point. Otherwise, we connect to the // default. // if((isFTCSet() == 0)&&(ConnectUsingSmartConfig==0)&&(*SmartConfigProfilestored != SMART_CONFIG_SET)) { // Smart Config not set, check whether we have an SSID // from the assoc terminal command. If not, use fixed SSID. //sendString("== ConnectUsingSSID==\r\n"); ConnectUsingSSID(SSID); } unsolicicted_events_timer_init(); // Wait until connection is finished //sendString("== Wait until connection is finished==\r\n"); while (!(currentCC3000State() & CC3000_ASSOC)) { WDTCTL = WDT_ARST_1000; __delay_cycles(100); // Handle any un-solicited event if required - the function will get triggered // few times in a second hci_unsolicited_event_handler(); // Check if user pressed button to do Smart Config if(runSmartConfig == 1) break; } } // Handle un-solicited events - will be triggered few times per second hci_unsolicited_event_handler(); WDTCTL = WDTPW + WDTHOLD; // Check if we are in a connected state. If so, set flags and LED if(currentCC3000State() & CC3000_IP_ALLOC) { unsolicicted_events_timer_disable(); // Turn our timer off since isr-driven routines set LEDs too... if (obtainIpInfoFlag == FALSE) { //sendString("== CC3000_IP_ALLOC_IND==\r\n"); obtainIpInfoFlag = TRUE; // Set flag so we don't constantly turn the LED on turnLedOn(CC3000_IP_ALLOC_IND); ipInfoFlagSet = 1; unsolicicted_events_timer_init(); } if (obtainIpInfoFlag == TRUE) { WDTCTL = WDT_ARST_1000; //If Smart Config was performed, we need to send complete notification to the configure (Smart Phone App) if (ConnectUsingSmartConfig==1) { mdnsAdvertiser(1,DevServname, sizeof(DevServname)); ConnectUsingSmartConfig = 0; *SmartConfigProfilestored = SMART_CONFIG_SET; } //Start mDNS timer in order to send mDNS Advertisement every 30 seconds mDNS_packet_trigger_timer_enable(); unsolicicted_events_timer_init(); } WDTCTL = WDTPW + WDTHOLD; if( ipInfoFlagSet == 1) { // Initialize an Exosite connection //sendString("== Exosite Activate ==\r\n"); cloud_status = Exosite_Activate(); ipInfoFlagSet = 0; } return TRUE; } return FALSE; }
//***************************************************************************** // incomingPacketManager //This function waits for an incoming message, and then extracts the //value from the message. If the message is an config one, then it will assign //the config info to a global variable. The function will return the next action //to be taken. // Packet Structure: <Command 1 Byte><Size of data 2 bytes><Missed Data 2 bytes><Data 2 bytes> //***************************************************************************** void incomingPacketManager(void){ char requestBuffer[SERVER_RECV_BUF_SIZE] = {NULL}; bytesRecvd = recv(clientDescriptor, requestBuffer, sizeof(requestBuffer), 0); switch(requestBuffer[0]) { case Config: //RESET ADC and DMA: refresh_ADC(); ADC_STATE = HALTED; //RESET DMA STATE. refresh_DMA(); DMA_STATE = HALTED; //Extracts the required Data from config. confirmationPacket_ptr = &config_data; *confirmationPacket_ptr = requestBuffer[6]; confirmationPacket_ptr++; *confirmationPacket_ptr = requestBuffer[5]; generalConfirmationPacket[1] = 0; //First Byte of Data Size generalConfirmationPacket[2] = 2; //Second Byte of Data Size generalConfirmationPacket[3] = 0; //First Byte of Data lost generalConfirmationPacket[4] = 0; //Second Byte of Data Size confirmationPacket_ptr = &ammount_packets_to_be_sent; generalConfirmationPacket[6] = *confirmationPacket_ptr; confirmationPacket_ptr++; generalConfirmationPacket[5] = *confirmationPacket_ptr; bytesSent = send(clientDescriptor, (unsigned char *)generalConfirmationPacket, sizeof(generalConfirmationPacket), 0); turnLedOff(CC3000_SENDING_DATA_IND); toggleLed(CC3000_SENDING_DATA_IND); __delay_cycles(100000); toggleLed(CC3000_SENDING_DATA_IND); if (bytesSent != sizeof(generalConfirmationPacket)){check_socket_connection();} deviceconfigured = FALSE; break; case Start: if(deviceconfigured == FALSE){ configure_channel(&config_data);//This is where I configure the device to operate differently. deviceconfigured = TRUE; } if(DMA_STATE == HALTED){ //VIMP: The stop state must stop the DMA DMA0CTL += DMAEN; DMA_STATE = RUNNING; __delay_cycles(1000); } if(ADC_STATE == HALTED){ ADC10CTL0 |= ADC10ENC + ADC10SC; ADC_STATE = RUNNING; //VIMP: The stop state must stop the ADC __delay_cycles(100000); } for(i=0; i<ammount_packets_to_be_sent; i++){ while(DMA0_State != DONE && DMA1_State != DONE); //Waits while buffers are populated //This checks which buffer is full, and toggles the operation. if(sendingBuffer_ptr == buffer0_ptr){ //Buffer0 is fill or done DMA0_State = NOT_DONE; // Reset for next usage DMA1CTL += DMAEN; // Start or enable DMA1 buffer filling process } else{ //Buffer1 is fill or done DMA1_State = NOT_DONE; // Reset for next usage DMA0CTL += DMAEN; // Start or enable DMA0 buffer filling process } //********************************************************************************************* //This is a pointer manipulation method to include the missed ADC cycles into the packet header. sendingBuffer_ptr +=4; temp_ptr = &missed_samples; *sendingBuffer_ptr = *temp_ptr; temp_ptr++; sendingBuffer_ptr--; *sendingBuffer_ptr = *temp_ptr; sendingBuffer_ptr -=3; missed_samples = 0; //********************************************************************************************* if(currentCC3000State() & CC3000_CLIENT_CONNECTED){ bytesSent = send(clientDescriptor, sendingBuffer_ptr, ammount_of_samples_in_packet+packet_header_size, 0); toggleLed(CC3000_SENDING_DATA_IND); if (bytesSent != ammount_of_samples_in_packet+packet_header_size){ check_socket_connection(); } } if (clientDescriptor == -1){break;} } break; case Stop: //RESET ADC: refresh_ADC(); ADC_STATE = HALTED; //RESET DMA. refresh_DMA(); DMA_STATE = HALTED; // The confirmation packet being sent back contains no relevant information. generalConfirmationPacket[1] = 0; //First Byte of Data Size generalConfirmationPacket[2] = 2; //Second Byte of Data Size generalConfirmationPacket[3] = 0; //First Byte of Data lost generalConfirmationPacket[4] = 0; //Second Byte of Data Size generalConfirmationPacket[5] = 0; generalConfirmationPacket[6] = 0; bytesSent = send(clientDescriptor, (unsigned char *)generalConfirmationPacket, sizeof(generalConfirmationPacket), 0); turnLedOff(CC3000_SENDING_DATA_IND); toggleLed(CC3000_SENDING_DATA_IND); __delay_cycles(100000); toggleLed(CC3000_SENDING_DATA_IND); if (bytesSent != sizeof(generalConfirmationPacket)){check_socket_connection();} break; default: break; } }