I have been using the CC3100 SDK to develop a project and have had it running successfully for a while. I recently decided to power he MSP430F5529LP LaunchPad from a USB charger and that is when things started getting weird. I have tried running the same code as before but now the I2C clock looks like a disorganized mess.
If, however, I comment out the functions that set up the CC3100 and CLI_WRITE and only run the I2C code I have no issue (the clock setting does not affect anything . The same applies if I disable the I2C code and run the other half of the code. The confusing part is the code DID WORK for the better part of a day with almost no issues (only issue was AP connection dropped after ~5 minutes). If anyone has any possible insight as to what may have happened to cause this I would be happy to hear ANY suggestions. I have tried Reinstalling CCS, the SDK and even reflashed the CC3100BOOST.
Thankfully
Kas
My Code:
/* * main.c - TCP socket sample application * * Copyright (C) 2014 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. * */ /* * Application Name - TCP socket * Application Overview - This is a sample application demonstrating how to open * and use a standard TCP socket with CC3100. * Application Details - http://processors.wiki.ti.com/index.php/CC31xx_TCP_Socket_Application * doc\examples\tcp_socket.pdf */ #include "simplelink.h" #include "cli_uart.h" #include <msp430.h> #define APPLICATION_VERSION "1.0.0" /**/ #define LOOP_FOREVER(line_number) \ {\ while(1); \ } #define ASSERT_ON_ERROR(line_number, error_code) \ {\ /* Handling the error-codes is specific to the application */ \ if (error_code < 0) return error_code; \ /* else, continue w/ execution */ \ } /* * Values for below macros shall be modified per the access-point's (AP) properties * SimpleLink device will connect to following AP when the application is executed */ // #define SSID_NAME "" /* AP name to connect to. */ // #define SEC_TYPE SL_SEC_TYPE_WPA /* Security type of the Access piont */ // #define PASSKEY "" /* Password in case of secure AP */ // #define IP_ADDR //TODO: Change to a passed in value // #define PORT_NUM 5001 /* Port number to be used */ #define SSID_NAME "" /* AP name to connect to. */ #define SEC_TYPE SL_SEC_TYPE_WPA /* Security type of the Access piont */ #define PASSKEY "" /* Password in case of secure AP */ #define IP_ADDR //TODO: Change to a passed in value #define PORT_NUM 5001 /* Port number to be used */ // #define SSID_NAME "" /* AP name to connect to. */ // #define SEC_TYPE SL_SEC_TYPE_WPA /* Security type of the Access point */ // #define PASSKEY "" /* Password in case of secure AP */ //#define IP_ADDR //TODO: Change to a passed in value //#define PORT_NUM 5001 /* Port number to be used */ #define IP_ADDR 0x6b15d6c7//Plotly #define PORT_NUM 80//Plotly /* Port number to be used */ #define BUF_SIZE 1400 #define NO_OF_PACKETS 10 #define SUCCESS 0 /* Status bits - These are used to set/reset the corresponding bits in a 'status_variable' */ typedef enum{ STATUS_BIT_CONNECTION = 0, /* If this bit is: * 1 in a 'status_variable', the device is connected to the AP * 0 in a 'status_variable', the device is not connected to the AP */ STATUS_BIT_IP_AQUIRED /* If this bit is: * 1 in a 'status_variable', the device has acquired an IP * 0 in a 'status_variable', the device has not acquired an IP */ }e_StatusBits; /* Application specific status/error codes */ typedef enum{ DEVICE_NOT_IN_STATION_MODE = -0x7D0, /* Choosing this number to avoid overlap w/ host-driver's error codes */ STATUS_CODE_MAX = -0xBB8 }e_AppStatusCodes; #define SET_STATUS_BIT(status_variable, bit) status_variable |= (1<<(bit)) #define CLR_STATUS_BIT(status_variable, bit) status_variable &= ~(1<<(bit)) #define GET_STATUS_BIT(status_variable, bit) (0 != (status_variable & (1<<(bit)))) #define IS_CONNECTED(status_variable) GET_STATUS_BIT(status_variable, \ STATUS_BIT_CONNECTION) #define IS_IP_AQUIRED(status_variable) GET_STATUS_BIT(status_variable, \ STATUS_BIT_IP_AQUIRED) /* * GLOBAL VARIABLES -- Start */ union { UINT8 BsdBuf[BUF_SIZE]; UINT32 demobuf[BUF_SIZE/4]; } uBuf; UINT8 g_Status = 0; /****************************************CARRIED OVER START*/ unsigned char *PTxData; // Pointer to TX data unsigned char TXByteCtr; unsigned char *PRxData; // Pointer to RX data unsigned char RXByteCtr; unsigned char RxBuffer[128]; // Allocate 128 byte of RAM char multiple; char stopBit = FALSE; /****************************************CARRIED OVER END*/ char xValue[] = "\0\0\0\0\0\0"; unsigned char errorArray[] = "\0\0\0\0\0\0\0\0\0\0"; int connectedToAP = 0; int connetcedToSocket = 0; /* * GLOBAL VARIABLES -- End */ /* * STATIC FUNCTION DEFINITIONS -- Start */ void clearErrorArray(); static INT32 configureSimpleLinkToDefaultState(); static INT32 establishConnectionWithAP(); void configureCC3x00(); void startCC3x00(); void connectCC3x00(); //static INT16 BsdTcpServer(UINT16 Port); static INT16 BsdTcpClient(UINT16 Port); static INT16 packetTx(UINT16 socketID, unsigned char* message, int length, char closeSocket); static INT32 initializeAppVariables(); static void displayBanner(); int intToChars(int number, char* chars); int charToInt(signed char value); void hexByteToChar(char byteIn, char* nibbleA, char* nibbleB); int plotlyPlotString(int xVal, int yVal, char* dataStream); void I2CInit(); void I2CTx(unsigned char* TxData, unsigned char numBytes, char stop); void I2CRx(unsigned char* RxBuffer, unsigned char numBytes); int mpl3115aInit(); int mpl3115aRead(); /* * STATIC FUNCTION DEFINITIONS -- End */ /* * ASYNCHRONOUS EVENT HANDLERS -- Start */ /*! \brief This function handles WLAN events \param[in] pWlanEvent is the event passed to the handler \return None \note \warning */ void SimpleLinkWlanEventHandler(SlWlanEvent_t *pWlanEvent)//TODO: Look at all the possible events that can occur and decide if other events need to be handled { switch(pWlanEvent->Event) { case SL_WLAN_CONNECT_EVENT: { SET_STATUS_BIT(g_Status, STATUS_BIT_CONNECTION); intToChars(pWlanEvent->Event, errorArray); CLI_Write(" STATUS_BIT_CONNECTION Value: "); CLI_Write(errorArray); CLI_Write("\r\n\r\n"); clearErrorArray(); /* * Information about the connected AP (like name, MAC etc) will be * available in 'sl_protocol_wlanConnectAsyncResponse_t' - Applications * can use it if required * * sl_protocol_wlanConnectAsyncResponse_t *pEventData = NULL; * pEventData = &pWlanEvent->EventData.STAandP2PModeWlanConnected; * */ } break; case SL_WLAN_DISCONNECT_EVENT: { sl_protocol_wlanConnectAsyncResponse_t* pEventData = NULL; CLR_STATUS_BIT(g_Status, STATUS_BIT_CONNECTION); CLR_STATUS_BIT(g_Status, STATUS_BIT_IP_AQUIRED); pEventData = &pWlanEvent->EventData.STAandP2PModeDisconnected; /* If the user has initiated 'Disconnect' request, 'reason_code' is * SL_USER_INITIATED_DISCONNECTION */ if(SL_USER_INITIATED_DISCONNECTION == pEventData->reason_code)//TODO: Add connection flag here to be checked in main loop and reconnect should a connection error occur { CLI_Write(" Device disconnected from the AP on application's request \n\r"); intToChars(pWlanEvent->Event, errorArray); CLI_Write(" Error Code A.0: "); CLI_Write(errorArray); CLI_Write("\r\n\r\n"); clearErrorArray(); connectedToAP = 0; intToChars(pEventData->reason_code, errorArray); CLI_Write(" Error Code A.1: "); CLI_Write(errorArray); CLI_Write("\r\n\r\n"); clearErrorArray(); } else { CLI_Write(" Device disconnected from the AP on an ERROR..!! \n\r"); connectedToAP = 0; intToChars(pWlanEvent->Event, errorArray); CLI_Write(" Error Code A.2: "); CLI_Write(errorArray); CLI_Write("\r\n\r\n"); clearErrorArray(); connectedToAP = 0; intToChars(pEventData->reason_code, errorArray); CLI_Write(" Error Code A.3: "); CLI_Write(errorArray); CLI_Write("\r\n\r\n"); clearErrorArray(); } } break; default: { CLI_Write(" [WLAN EVENT] Unexpected event \n\r"); connectedToAP = 0; intToChars(pWlanEvent->Event, errorArray); CLI_Write(" Error Code B: "); CLI_Write(errorArray); CLI_Write("\r\n\r\n"); clearErrorArray(); } break; } } /*! \brief This function handles events for IP address acquisition via DHCP indication \param[in] pNetAppEvent is the event passed to the handler \return None \note \warning */ void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *pNetAppEvent) { switch(pNetAppEvent->Event) { case SL_NETAPP_IPV4_ACQUIRED: { SET_STATUS_BIT(g_Status, STATUS_BIT_IP_AQUIRED); intToChars(pNetAppEvent->Event, errorArray); CLI_Write(" Event Value: "); CLI_Write(errorArray); CLI_Write("\r\n\r\n"); clearErrorArray(); intToChars(STATUS_BIT_IP_AQUIRED, errorArray); CLI_Write(" STATUS_BIT_IP_AQUIRED Value: "); CLI_Write(errorArray); CLI_Write("\r\n\r\n"); clearErrorArray(); /* * Information about the connection (like IP, gateway address etc) * will be available in 'SlIpV4AcquiredAsync_t' * Applications can use it if required * * SlIpV4AcquiredAsync_t *pEventData = NULL; * pEventData = &pNetAppEvent->EventData.ipAcquiredV4; * */ } break; default: { CLI_Write(" [NETAPP EVENT] Unexpected event \n\r"); intToChars(pNetAppEvent->Event, errorArray); CLI_Write(" Error Code C: "); CLI_Write(errorArray); CLI_Write("\r\n\r\n"); clearErrorArray(); } break; } } /*! \brief This function handles callback for the HTTP server events \param[in] pServerEvent - Contains the relevant event information \param[in] pServerResponse - Should be filled by the user with the relevant response information \return None \note \warning */ void SimpleLinkHttpServerCallback(SlHttpServerEvent_t *pHttpEvent, SlHttpServerResponse_t *pHttpResponse) { /* Unused in this application */ CLI_Write(" [HTTP EVENT] Unexpected event \n\r"); } /*! \brief This function handles general error events indication \param[in] pDevEvent is the event passed to the handler \return None */ void SimpleLinkGeneralEventHandler(SlDeviceEvent_t *pDevEvent) { /* * Most of the general errors are not FATAL are are to be handled * appropriately by the application */ CLI_Write(" [GENERAL EVENT] \n\r"); intToChars(pDevEvent->Event, errorArray); CLI_Write(" Error Code D: "); CLI_Write(errorArray); CLI_Write("\r\n\r\n"); clearErrorArray(); } /*! \brief This function handles socket events indication \param[in] pSock is the event passed to the handler \return None */ void SimpleLinkSockEventHandler(SlSockEvent_t *pSock) { switch( pSock->Event ) { case SL_NETAPP_IPV4_ACQUIRED: //TODO: Fill in needed code here (set flag) break; case SL_NETAPP_SOCKET_TX_FAILED: /* * TX Failed * * Information about the socket descriptor and status will be * available in 'SlSockEventData_t' - Applications can use it if * required * * SlSockEventData_t *pEventData = NULL; * pEventData = & pSock->EventData; */ switch( pSock->EventData.status ) { case SL_ECLOSE: CLI_Write(" [SOCK EVENT] Close socket operation failed to transmit all queued packets\n\r"); connetcedToSocket = 0; intToChars(pSock->Event, errorArray); CLI_Write(" Error Code E: "); CLI_Write(errorArray); CLI_Write("\r\n\r\n"); clearErrorArray(); break; default: CLI_Write(" [SOCK EVENT] Unexpected event 1\n\r"); connetcedToSocket = 0; intToChars(pSock->Event, errorArray); CLI_Write(" Error Code F: "); CLI_Write(errorArray); CLI_Write("\r\n\r\n"); clearErrorArray(); break; } break; default: CLI_Write(" [SOCK EVENT] Unexpected event 2\n\r"); connetcedToSocket = 0; intToChars(pSock->Event, errorArray); CLI_Write(" Error Code G: "); CLI_Write(errorArray); CLI_Write("\r\n\r\n"); clearErrorArray(); break; } } /* * ASYNCHRONOUS EVENT HANDLERS -- End */ void clearErrorArray(){ char i; for(i = 0; i < 12; i++){ errorArray[i] = '\0'; } } /*! \brief This function configure the SimpleLink device in its default state. It: - Sets the mode to STATION - Configures connection policy to Auto and AutoSmartConfig - Deletes all the stored profiles - Enables DHCP - Disables Scan policy - Sets Tx power to maximum - Sets power policy to normal - Unregisters mDNS services \param[in] none \return On success, zero is returned. On error, negative is returned */ static INT32 configureSimpleLinkToDefaultState() { SlVersionFull ver = {0}; UINT8 val = 1; UINT8 configOpt = 0; UINT8 configLen = 0; UINT8 power = 0; INT32 retVal = -1; INT32 mode = -1; mode = sl_Start(0, 0, 0); ASSERT_ON_ERROR(__LINE__, mode); /* If the device is not in station-mode, try configuring it in staion-mode */ if (ROLE_STA != mode) { if (ROLE_AP == mode) { /* If the device is in AP mode, we need to wait for this event before doing anything */ while(!IS_IP_AQUIRED(g_Status)) { _SlNonOsMainLoopTask(); } } /* Switch to STA role and restart */ retVal = sl_WlanSetMode(ROLE_STA); ASSERT_ON_ERROR(__LINE__, retVal); retVal = sl_Stop(0xFF); ASSERT_ON_ERROR(__LINE__, retVal); retVal = sl_Start(0, 0, 0); ASSERT_ON_ERROR(__LINE__, retVal); /* Check if the device is in station again */ if (ROLE_STA != retVal) { /* We don't want to proceed if the device is not coming up in station-mode */ return DEVICE_NOT_IN_STATION_MODE; } } /* Get the device's version-information */ configOpt = SL_DEVICE_GENERAL_VERSION; configLen = sizeof(ver); retVal = sl_DevGet(SL_DEVICE_GENERAL_CONFIGURATION, &configOpt, &configLen, (unsigned char *)(&ver)); ASSERT_ON_ERROR(__LINE__, retVal); /* Set connection policy to Auto + SmartConfig (Device's default connection policy) */ retVal = sl_WlanPolicySet(SL_POLICY_CONNECTION, SL_CONNECTION_POLICY(1, 0, 0, 0, 1), NULL, 0); ASSERT_ON_ERROR(__LINE__, retVal); /* Remove all profiles */ retVal = sl_WlanProfileDel(0xFF); ASSERT_ON_ERROR(__LINE__, retVal); /* * Device in station-mode. Disconnect previous connection if any * The function returns 0 if 'Disconnected done', negative number if already disconnected * Wait for 'disconnection' event if 0 is returned, Ignore other return-codes */ retVal = sl_WlanDisconnect(); if(0 == retVal) { /* Wait */ while(IS_CONNECTED(g_Status)) { _SlNonOsMainLoopTask(); } } /* Enable DHCP client*/ retVal = sl_NetCfgSet(SL_IPV4_STA_P2P_CL_DHCP_ENABLE,1,1,&val); ASSERT_ON_ERROR(__LINE__, retVal); /* Disable scan */ configOpt = SL_SCAN_POLICY(0); retVal = sl_WlanPolicySet(SL_POLICY_SCAN , configOpt, NULL, 0); ASSERT_ON_ERROR(__LINE__, retVal); /* Set Tx power level for station mode Number between 0-15, as dB offset from max power - 0 will set maximum power */ power = 0; retVal = sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, WLAN_GENERAL_PARAM_OPT_STA_TX_POWER, 1, (unsigned char *)&power); ASSERT_ON_ERROR(__LINE__, retVal); /* Set PM policy to normal */ retVal = sl_WlanPolicySet(SL_POLICY_PM , SL_NORMAL_POLICY, NULL, 0); ASSERT_ON_ERROR(__LINE__, retVal); /* Unregister mDNS services */ retVal = sl_NetAppMDNSUnRegisterService(0, 0); ASSERT_ON_ERROR(__LINE__, retVal); retVal = sl_Stop(0xFF); ASSERT_ON_ERROR(__LINE__, retVal); retVal = initializeAppVariables(); ASSERT_ON_ERROR(__LINE__, retVal); return retVal; /* Success */ } /*! \brief Connecting to a WLAN Access point This function connects to the required AP (SSID_NAME). The function will return once we are connected and have acquired IP address \param[in] None \return 0 on success, negative error-code on error \note \warning If the WLAN connection fails or we don't acquire an IP address, We will be stuck in this function forever. */ static INT32 establishConnectionWithAP() { SlSecParams_t secParams = {0}; INT32 retVal = 0; secParams.Key = PASSKEY; secParams.KeyLen = strlen(PASSKEY); secParams.Type = SEC_TYPE; retVal = sl_WlanConnect(SSID_NAME, strlen(SSID_NAME), 0, &secParams, 0); ASSERT_ON_ERROR(__LINE__, retVal); /* Wait */ while((!IS_CONNECTED(g_Status)) || (!IS_IP_AQUIRED(g_Status))) { _SlNonOsMainLoopTask(); } connectedToAP = 1;//TODO: remove flag return SUCCESS; } /****************************************************************************************************************************************/ /* * Following function configures the device to default state by cleaning * the persistent settings stored in NVMEM (viz. connection profiles & * policies, power policy etc) * * Applications may choose to skip this step if the developer is sure * that the device is in its default state at start of application * * Note that all profiles and persistent settings that were done on the * device will be lost */ void configureCC3x00(){ INT32 retVal = -1; retVal = configureSimpleLinkToDefaultState(); if(retVal < 0) { if (DEVICE_NOT_IN_STATION_MODE == retVal) { CLI_Write(" Failed to configure the device in its default state \n\r"); } LOOP_FOREVER(__LINE__); } CLI_Write(" Device is configured in default state \n\r"); } /* * Assumption is that the device is configured in station mode already * and it is in its default state */ /* Initializing the CC3100 device */ void startCC3x00(){ INT32 retVal = -1; retVal = sl_Start(0, 0, 0); if ((retVal < 0) || (ROLE_STA != retVal) ) { CLI_Write(" Failed to start the device \n\r"); LOOP_FOREVER(__LINE__); } CLI_Write(" Device started as STATION \n\r"); } /* Connecting to WLAN AP - Set with static parameters defined at the top After this call we will be connected and have IP address */ void connectCC3x00(){ INT32 retVal = -1; retVal = establishConnectionWithAP(); if(retVal < 0) { CLI_Write(" Failed to establish connection w/ an AP \n\r"); LOOP_FOREVER(__LINE__); } CLI_Write(" Connection established w/ AP and IP is acquired \n\r"); } /*! \brief Opening a client side socket and sending data This function opens a TCP socket and tries to connect to a Server IP_ADDR waiting on port PORT_NUM. If the socket connection is successful then the function will send 1000 TCP packets to the server. \param[in] port number on which the server will be listening on \return 0 on success, -1 on Error. \note \warning A server must be waiting with an open TCP socket on the right port number before calling this function. Otherwise the socket creation will fail. */ static INT16 BsdTcpClient(UINT16 Port) { SlSockAddrIn_t Addr; UINT16 AddrSize = 0; INT16 SockID = 0; INT16 Status = 0; Addr.sin_family = SL_AF_INET; Addr.sin_port = sl_Htons((UINT16)Port); Addr.sin_addr.s_addr = sl_Htonl((UINT32)IP_ADDR);//TODO: Change this as a passed in value(Keep as defined for current version) AddrSize = sizeof(SlSockAddrIn_t); SockID = sl_Socket(SL_AF_INET,SL_SOCK_STREAM, 0); if( SockID < 0 ) { /* error */ return -1; } CLI_Write(" Establishing connection with TCP server \n\r"); Status = sl_Connect(SockID, ( SlSockAddr_t *)&Addr, AddrSize); if( Status < 0 ) { sl_Close(SockID); CLI_Write(" Failed to establish connection with TCP server \n\r"); return -1; } CLI_Write(" Connection with TCP server established successfully \n\r"); connetcedToSocket = 1;//TODO: remove flag return SockID; } static INT16 packetTx(UINT16 socketID, unsigned char* message, int length, char closeSocket){ INT16 Status = 0; INT8 sent = -1; INT8 i = 0; INT16 j = 0; CLI_Write(" - Initiating message transmit\n\r"); while((sent == -1) && (i < 6)){ Status = sl_Send(socketID, message, length, 0 ); sent = Status; i++; if (sent != 0){ for (j = 0; j < 1000; j++); } } if( Status < 0 ) { CLI_Write(" Error while sending the data \n\r"); sl_Close(socketID); return -1; } CLI_Write(" - Message transmitted\n\r"); //// if (closeSocket == 1){ // sl_Close(socketID);//TODO: Remove close socket //// } return 0; } /*! \brief This function initializes the application variables \param[in] None \return 0 on success, negative error-code on error */ static INT32 initializeAppVariables() { g_Status = 0; memset(uBuf.BsdBuf, 0, sizeof(uBuf)); return SUCCESS; } /*! \brief This function displays the application's banner \param None \return None */ static void displayBanner() { CLI_Write("\n\r\n\r"); CLI_Write(" TCP socket application - Version "); CLI_Write(APPLICATION_VERSION); CLI_Write("\n\r*******************************************************************************\n\r"); } int intToChars(int number, char* chars){ int val = number; int i = 0; int j = 0; int num; int neg = 0; char temp; if (val < 0){ val = 0 - val; neg = 1; } if (val == 0){ chars[0] = '0'; i = 1; } while(val != 0){ num = val/10; chars[i] = (char)(val - (num * 10) + 0x30); val = num; i++; } i--;//Remove extra count int f; if (i % 2 != 0){ f = i / 2 + 1; } else { f = i / 2; } for (j = 0; j < f; j++){ temp = chars[j]; chars[j] = chars[i - j]; chars[i - j] = temp; } if (neg){ for (j = i; j >= 0; j--){ chars[j + 1] = chars[j]; } chars[0] = '-'; i++;//increase count to account for negitive sign } return i + 1; //Counting from zero so add one for true length } //Converts Hex representation to characters int charToInt(signed char value){ int mambo = 0; if (value < 0){ value = 0 - value; mambo = 0 - (int)value; } else{ mambo = (int)value; } return mambo; } void hexByteToChar(char byteIn, char* nibbleA, char* nibbleB) { switch(byteIn & 0xF0){ case 0x0: *nibbleA = '0'; break; case 0x10: *nibbleA = '1'; break; case 0x20: *nibbleA = '2'; break; case 0x30: *nibbleA = '3'; break; case 0x40: *nibbleA = '4'; break; case 0x50: *nibbleA = '5'; break; case 0x60: *nibbleA = '6'; break; case 0x70: *nibbleA = '7'; break; case 0x80: *nibbleA = '8'; break; case 0x90: *nibbleA = '9'; break; case 0xA0: *nibbleA = 'A'; break; case 0xB0: *nibbleA = 'B'; break; case 0xC0: *nibbleA = 'C'; break; case 0xD0: *nibbleA = 'D'; break; case 0xE0: *nibbleA = 'E'; break; case 0xF0: *nibbleA = 'F'; break; } switch (byteIn & 0x0F){ case 0x00: *nibbleB = '0'; break; case 0x01: *nibbleB = '1'; break; case 0x02: *nibbleB = '2'; break; case 0x03: *nibbleB = '3'; break; case 0x04: *nibbleB = '4'; break; case 0x05: *nibbleB = '5'; break; case 0x06: *nibbleB = '6'; break; case 0x07: *nibbleB = '7'; break; case 0x08: *nibbleB = '8'; break; case 0x09: *nibbleB = '9'; break; case 0x0A: *nibbleB = 'A'; break; case 0x0B: *nibbleB = 'B'; break; case 0x0C: *nibbleB = 'C'; break; case 0x0D: *nibbleB = 'D'; break; case 0x0E: *nibbleB = 'E'; break; case 0x0F: *nibbleB = 'F'; break; } } int plotlyPlotString(int xVal, int yVal, char* dataStream){ const char start[] = "\r\n{\"x\":"; const char middle[] = ",\"y\":"; const char end[] = "}\r\n"; // char xValue[] = "\0\0\0\0\0\0"; char yValue[] = "\0\0\0\0\0\0"; intToChars(xVal, xValue); intToChars(yVal, yValue); int offset = 4; strncpy(dataStream + offset, start, sizeof(start) - 1); offset = offset + sizeof(start) - 1; strncpy(dataStream + offset, xValue, strlen(xValue)); offset = offset + strlen(xValue); strncpy(dataStream + offset, middle, sizeof(middle) - 1); offset = offset + sizeof(middle) - 1; strncpy(dataStream + offset, yValue, strlen(yValue)); offset = offset + strlen(yValue); strncpy(dataStream + offset, end, sizeof(end)); //Leave out the -1 inorder to include the null terminator int streamLength; char streamDataLen[] = "\0\0\0\0\0"; streamLength = sizeof(start) - 2 + strlen(xValue) + sizeof(middle) + strlen(yValue) + sizeof(end) - 3; intToChars(streamLength, streamDataLen); char happyDay[4]; hexByteToChar(streamDataLen[0], happyDay, happyDay + 1); hexByteToChar(streamDataLen[1], happyDay + 2, happyDay + 3); strncpy(dataStream, happyDay, 4); return streamLength; } void I2CInit(){ WDTCTL = WDTPW + WDTHOLD; // Stop WDT P4SEL |= 0x06; // Assign I2C pins to USCI_B0 UCB1CTL1 |= UCSWRST; // Enable SW reset UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode UCB1CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset UCB1BR0 = 10; // fSCL = SMCLK/12 = ~100kHz UCB1BR1 = 0; UCB1I2CSA = 0x60; // Slave Address is 048h UCB1CTL1 &= ~UCSWRST; // Clear SW reset, resume operation UCB1IE |= UCTXIE; // Enable TX interrupt UCB1IE |= UCRXIE; // Enable RX interrupt } void I2CTx(unsigned char* TxData, unsigned char numBytes, char stop){ unsigned int i; stopBit = stop; for(i=0;i<10;i++); // Delay required between transaction PTxData = (unsigned char *)TxData; // TX array start address // Place breakpoint here to see each // transmit operation. TXByteCtr = numBytes; // Load TX byte counter UCB1CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition __bis_SR_register(LPM0_bits + GIE); // Enter LPM0, enable interrupts __no_operation(); // Remain in LPM0 until all data if(stop){ UCB1CTL1 |= UCTXSTP; } // is TX'd while (UCB1CTL1 & UCTXSTP); // Ensure stop condition got sent } void I2CRx(unsigned char* RxBuffer, unsigned char numBytes){ PRxData = (unsigned char *)RxBuffer; // Start of RX buffer RXByteCtr = numBytes; // Load RX byte counter if (numBytes > 1){ multiple = 1; } else { multiple = 0; } while (UCB1CTL1 & UCTXSTP); // Ensure stop condition got sent UCB1CTL1 &= ~UCTR; UCB1CTL1 |= UCTXSTT; // I2C start condition if (multiple == 0){ while(UCB1CTL1 & UCTXSTT); // Start condition sent? UCB1CTL1 |= UCTXSTP; } __bis_SR_register(LPM0_bits + GIE); // Enter LPM0, enable interrupts // Remain in LPM0 until all data is RX'd __no_operation(); } int mpl3115aInit(){ char initialized = 1; unsigned char WHO_AM_I[] = {0x0C}; //R C4 unsigned char CTRL_REG1_SET1[] = {0x26, 0x38}; unsigned char CTRL_REG2_SET[] = {0x27, 0x00}; unsigned char CTRL_REG3_SET[] = {0x28, 0x11}; unsigned char CTRL_REG4_SET[] = {0x29, 0x00}; unsigned char CTRL_REG5_SET[] = {0x2A, 0x00}; unsigned char PT_DATA_CFG_SET[] = {0x13, 0x07}; unsigned char CTRL_REG1_GET[] = {0x26}; unsigned char CTRL_REG1_SET2[] = {0x26, 0x39}; unsigned char CTRL_REG2_GET[] = {0x27}; I2CTx(WHO_AM_I, sizeof(WHO_AM_I), FALSE); I2CRx(RxBuffer, 1); if (RxBuffer[0] == 0xC4){ P4OUT |= 0x80; P1OUT &= 0xFE; } else { P1OUT |= 0x01; P4OUT &= 0x7F; initialized = 0; } I2CTx(CTRL_REG1_SET1, sizeof(CTRL_REG1_SET1), TRUE); I2CTx(CTRL_REG2_SET, sizeof(CTRL_REG2_SET), TRUE); I2CTx(CTRL_REG3_SET, sizeof(CTRL_REG3_SET), TRUE); I2CTx(CTRL_REG4_SET, sizeof(CTRL_REG4_SET), TRUE); I2CTx(CTRL_REG5_SET, sizeof(CTRL_REG5_SET), TRUE); I2CTx(PT_DATA_CFG_SET, sizeof(PT_DATA_CFG_SET), TRUE); I2CTx(CTRL_REG1_GET, sizeof(CTRL_REG1_GET), FALSE); I2CRx(RxBuffer, 1); if (RxBuffer[0] == 0x38){ P4OUT |= 0x80; P1OUT &= 0xFE; } else { P1OUT |= 0x01; P4OUT &= 0x7F; initialized = 0; } I2CTx(CTRL_REG1_SET2, sizeof(CTRL_REG1_SET2), TRUE); I2CTx(CTRL_REG1_GET, sizeof(CTRL_REG1_GET), FALSE); I2CRx(RxBuffer, 1); if (RxBuffer[0] == 0x39){ P4OUT |= 0x80; P1OUT &= 0xFE; } else { P1OUT |= 0x01; P4OUT &= 0x7F; initialized = 0; } I2CTx(CTRL_REG2_GET, sizeof(CTRL_REG2_GET), FALSE); I2CRx(RxBuffer, 1); if (RxBuffer[0] == 0x00){ P4OUT |= 0x80; P1OUT &= 0xFE; } else { P1OUT |= 0x01; P4OUT &= 0x7F; initialized = 0; } return initialized; } int mpl3115aRead(){ unsigned char OUT_P_MSB[] = {0x01}; unsigned char DR_STATUS[] = {0x06}; char readPresTemp = 0; I2CTx(DR_STATUS, sizeof(DR_STATUS), FALSE); I2CRx(RxBuffer, 1); if ((RxBuffer[0] == 0x0E) || (RxBuffer[0] == 0xEE)){ P4OUT |= 0x80; P1OUT &= 0xFE; readPresTemp = 1; } else { P1OUT |= 0x01; P4OUT &= 0x7F; readPresTemp = 0; } if (readPresTemp){ I2CTx(OUT_P_MSB, sizeof(OUT_P_MSB), FALSE); I2CRx(RxBuffer, 5); Delay(50); } return readPresTemp; } int main(void) { INT32 retVal = -1; int temperatureInt; int streamLength; int packetLength; char dataStream[30]; int xVal = 0; P1OUT &= 0xFE; P1DIR |= 0x01; P4OUT &= 0x7F; P4DIR |= 0x80; retVal = initializeAppVariables(); ASSERT_ON_ERROR(__LINE__, retVal); stopWDT(); initClk(); CLI_Configure(); CLI_Write(" \f\r\n"); displayBanner(); configureCC3x00(); startCC3x00(); connectCC3x00(); INT16 socketIDD; socketIDD = BsdTcpClient(PORT_NUM); packetTx(socketIDD, openStream, (sizeof(openStream) - 1), 0); int dataAvilable; CLI_Write(" Initilizing I2C"); I2CInit(); Delay(700); CLI_Write(" Complete \r\n"); Delay(500); CLI_Write(" Initilizing MPL3115A"); mpl3115aInit(); Delay(700); CLI_Write(" Complete\r\n"); while (1) { dataAvilable = mpl3115aRead(); if (dataAvilable == 1){ temperatureInt = charToInt((signed char)RxBuffer[3]); streamLength = plotlyPlotString(xVal, temperatureInt, dataStream); packetLength = streamLength + 6; packetTx(socketIDD, dataStream, packetLength, 0); CLI_Write("\r\n"); CLI_Write(dataStream); CLI_Write("\r\n"); xVal++; } Delay(20); } } //------------------------------------------------------------------------------- // The USCI_B0 data ISR is used to move received data from the I2C slave // to the MSP430 memory. It is structured such that it can be used to receive // any 2+ number of bytes by pre-loading RXByteCtr with the byte count. //------------------------------------------------------------------------------- #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector = USCI_B1_VECTOR __interrupt void USCI_B1_ISR(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCI_B0_ISR (void) #else #error Compiler not supported! #endif { switch(__even_in_range(UCB1IV,12)) { case 0: break; // Vector 0: No interrupts case 2: break; // Vector 2: ALIFG case 4: break; // Vector 4: NACKIFG case 6: break; // Vector 6: STTIFG case 8: break; // Vector 8: STPIFG case 10: // Vector 10: RXIFG RXByteCtr--; // Decrement RX byte counter if (RXByteCtr) { *PRxData++ = UCB1RXBUF; // Move RX data to address PRxData if (RXByteCtr == 1 && multiple == 1) // Only one byte left? UCB1CTL1 |= UCTXSTP; // Generate I2C stop condition } else { *PRxData = UCB1RXBUF; // Move final RX data to PRxData __bic_SR_register_on_exit(LPM0_bits); // Exit active CPU } break; case 12: // Vector 12: TXIFG if (TXByteCtr) // Check TX byte counter { UCB1TXBUF = *PTxData++; // Load TX buffer TXByteCtr--; // Decrement TX byte counter } else { if (stopBit){ UCB1CTL1 |= UCTXSTP; // I2C stop condition //Set a stop flag if this should be sent out or not } UCB1IFG &= ~UCTXIFG; // Clear USCI_B0 TX int flag __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0 } default: break; } }