This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/MSP432P401R: No source available for "0xfffffff8" during debug

Part Number: MSP432P401R
Other Parts Discussed in Thread: CC3100BOOST, CC3100MODBOOST, MSP432WARE, CC3100, SEGGER, CC3200, ENERGIA

Tool/software: Code Composer Studio

Hi,

I'm continuing my effort to port the "CC3100BOOST_MQTT-TwitterLED_MSP432P401R" example to GNU C++ and I have been able to get it to successfully build, but when I attempt to run a a debug session to load the code, I am getting a No source available for "0xfffffff8" error and the session does not show the run arrow I've tried this with a number of projects but I am not getting anywhere past this.  Is there something that I should look at?

In this latest attempt, I just imported a fresh version of the MQTT project and changed it to the GNU compiler.  I'm thinking I am missing something here and need assistance.

Cheers,

Jon

  • Hi,
    Thanks for posting to the forum.
    Can you also add details on what hardware you are using on the MSP side? Is this the MSP-EXP432P401R Red LaunchPad?
    Also you mentioned "continued effort". Was there a different post you were being helped with?

    -Priya
  • That address looks like an exception return.  I've seen this behaviour using the gcc toolchain.  my version of gdb gets confused like the above too.  this happens when an exception is taken.

  • Priya,

    I appreciate the response.  I had created another post to address and issue I had with compiling  "CC3100BOOST_MQTT-TwitterLED_MSP432P401R" example but with GCC and TI-RTOS and was able to get passed that so I considered the issue resolved for the most part. 

    However, now I am seeing the issue that I had posted when just running the example but with GNU v4.9.3 Linaro compiler and not TI-RTOS at this time.  

    This is a link to my previous post is titled.  Sorry, I am not sure how to add links easily.

    " Compiler/CC3100MODBOOST: CCS/CC3100MODBOOST :MQTT with TI-RTOS and MSP432"

    Should I continue the conversation there?

    I'm using a pre production MSP432 Launchpad (Black version) with a CC3100MODBOOST which works just fine with the Twitter Example. However, the project I am working on is based on GNU C++11 so I am attempting to port over the code from the Twitter example to a GNU C++ project.  

    NOTE: I do see the same behavior with the Red version of the MSP432 Launchpad as well.  

    I can get past all of the compiler issues I had seen thus far, but I can not seem to run this without hitting the "No source available for "0xfffffff8" error when starting a Debug session to load the code. I know the hardware works since I can still load the Twitter example I had worked on, but each attempt beyond the example code will not run.

    Any thoughts?

    Cheers,

    Jon

  • Jon Morss said:
    I can get past all of the compiler issues I had seen thus far, but I can not seem to run this without hitting the "No source available for "0xfffffff8" error when starting a Debug session to load the code.

    Can you post a screen shot of the CCS debugger, as want to see if there is any other stack backtrace information which may give a clue as to what has happened.

    Also, since you are using TI-RTOS if you use the RTOS Object View (ROV) -> BIOS -> Scan for errors are any errors reported?

    If you attach the problematic project I could try and debug where the crash is coming from.

  • Chester,

    I appreciate the response. I thought I sent a response last night but I an not see it. I do not see an option to include a screen shot or to list code like when I initially posted this so I'll just include what I can.

    Currently I have set the TI-RTOS stuff aside and am just using the "CC3100BOOST_MQTT-TwitterLED_MSP432P401R" example from MSP432Ware but changing the compiler to GNU v4.9.3 Linaro and setting the environment for C++. Outside of some issues pointed out during compiling the project due to using GNU gcc, the code is the same as in the example. I do have other working GNU v4.9.3 Linaro C++ projects even using TI-RTOS so I am not sure why this is not working.

    This is the error that I see when running a debug session and clicking on the XDS110 Debug Probe listing. NOTE: At this point I can pause the Debug session since it appears to be stuck in the Default_Handler loop.

    Texas Instruments XDS110 USB Debug Probe/CORTEX_M4_0 (Suspended)
    Default_Handler() at startup_msp432p401r_gcc.c:200 0x0000EA4
    0XFFFFFFF8 (no symbols are defined for 0xFFFFFFF8)

    If I click on the Default_Handler line, the Disassembly windows shows the address listed which is at the Default_handler in the startup file.
    This is between SystemInit() and SystemCoreClocksUpdate()

    This is what I see in the Console with verbose enabled when starting the debug session:

    CORTEX_M4_0: GEL Output: Memory Map Initialization Complete
    CORTEX_M4_0: GEL Output: Halting Watchdog Timer
    CORTEX_M4_0: WARNING : On MSP432P401R hitting a breakpoint cannot be detected by the debugger when the device is in low power mode.
    Click the pause button during debug to check if the device is held at the breakpoint.
    CORTEX_M4_0: Flash Programmer: Verbose output enabled
    CORTEX_M4_0: Flash Programmer: DLL Version 2.2.1.0
    CORTEX_M4_0: Flash Programmer: Hard reset
    CORTEX_M4_0: Writing Flash @ Address 0x00000000 of Length 0x00007ff0
    CORTEX_M4_0: Flash Programmer: Uploading RAM loader to device
    CORTEX_M4_0: Flash Programmer: Device init finished
    CORTEX_M4_0: Flash Programmer: Erasing main memory
    CORTEX_M4_0: Flash Programmer: Mass erase finished
    CORTEX_M4_0: Flash Programmer: Writing 32752 bytes to flash memory 0x00000000
    CORTEX_M4_0: Flash Programmer: Write speed 18.9 kB/sec
    CORTEX_M4_0: Flash Programmer: Exit flash programming
    CORTEX_M4_0: Writing Flash @ Address 0x00007ff0 of Length 0x00007ff0
    CORTEX_M4_0: Flash Programmer: Writing 32752 bytes to flash memory 0x00007ff0
    CORTEX_M4_0: Flash Programmer: Write speed 14.4 kB/sec
    CORTEX_M4_0: Flash Programmer: Exit flash programming
    CORTEX_M4_0: Writing Flash @ Address 0x0000ffe0 of Length 0x00007ff0
    CORTEX_M4_0: Flash Programmer: Writing 32752 bytes to flash memory 0x0000ffe0
    CORTEX_M4_0: Flash Programmer: Write speed 14.7 kB/sec
    CORTEX_M4_0: Flash Programmer: Exit flash programming
    CORTEX_M4_0: Writing Flash @ Address 0x00017fd0 of Length 0x00006a10
    CORTEX_M4_0: Flash Programmer: Writing 27152 bytes to flash memory 0x00017fd0
    CORTEX_M4_0: Flash Programmer: Write speed 13.8 kB/sec
    CORTEX_M4_0: Flash Programmer: Exit flash programming
    CORTEX_M4_0: Writing Flash @ Address 0x0001e9e0 of Length 0x00000978
    CORTEX_M4_0: Flash Programmer: Writing 2424 bytes to flash memory 0x0001e9e0
    CORTEX_M4_0: Flash Programmer: Write speed 11.7 kB/sec
    CORTEX_M4_0: Flash Programmer: Exit flash programming
    CORTEX_M4_0: Writing Flash @ Address 0x0001f358 of Length 0x000000e4
    CORTEX_M4_0: Flash Programmer: Writing 228 bytes to flash memory 0x0001f358
    CORTEX_M4_0: Flash Programmer: Write speed 1.4 kB/sec
    CORTEX_M4_0: Flash Programmer: Exit flash programming
    CORTEX_M4_0: Flash Programmer: Hard reset
    CORTEX_M4_0: Flash Programmer: Release Watchdog timer
  • Jon Morss said:
    I do not see an option to include a screen shot or to list code like when I initially posted this so I'll just include what I can.

    When replying if you click the "Use rich formatting" link you will have the option to insert images, files or syntax highlighted code.

    Jon Morss said:
    If I click on the Default_Handler line, the Disassembly windows shows the address listed which is at the Default_handler in the startup file.
    This is between SystemInit() and SystemCoreClocksUpdate()

    If the Default_handler gets called it means an interrupt occurred for which no user handler was registered.

    Since the project worked with the TI compiler, the chances are that the startup file for the TI compiler had one more one interrupt handlers registered in the g_pfnVectors array, but the corresponding change to add the interrupt handlers to the g_pfnVectors array in the startup file for the GCC compiler has not been made.

    See Diagnosing Software Faults in Stellaris® Microcontrollers for how to find out which peripheral interrupt source caused the Default Interrupt Handler to be called, in case the cause isn't obvious by comparing the contents of the g_pfnVectors array between the working TI compiler project and the non-working GCC compiler project.

  • Chester,
    I appreciate the reply, however I am dealing with a MSP432 not a Tiva family MCU. There is no g_pfnVectors but a "interruptVectors" instead. Thanks for the info anyways.

    Yeah, I was looking at the differences between my project startup and the original project startup file and there are plenty of differences. The original startup had defined only a few Interrupt Handlers where as the new project defines (or rather redefines) most of them so perhaps that is causing some sort of conflict. Also, unlike the Tiva version of the startup file, the startup for these MSP32/CC3100 projects are not c++ friendly and do not have "#ifdef __cplusplus" entries so that might be another issue.
    I'll work with this and see where I get with making some changes.

    Thanks,

    Jon
  • Jon Morss said:
    however I am dealing with a MSP432 not a Tiva family MCU.

    Thanks for pointing out my mistake, I was looking at another Tiva project when I posted my response and got confused.

    Jon Morss said:
    The original startup had defined only a few Interrupt Handlers where as the new project defines (or rather redefines) most of them so perhaps that is causing some sort of conflict.

    Looking at the TI compiler startup_msp432p401r_ccs.c from the MSP432ware 3.50.00.02 CC3100BOOST_MQTT-TwitterLED_MSP432P401R shows the following peripheral interrupt handlers being installed:

        SysTick_Handler,                        /* The SysTick handler       */
        TA1_0_IRQHandler,                       /* TA1_0 ISR                 */
        EUSCIA0_IRQHandler,                     /* EUSCIA0 ISR               */
        PORT1_IRQHandler,                       /* PORT1 ISR                 */
        PORT2_IRQHandler,                       /* PORT2 ISR                 */

    The startup_msp432p401r_gcc.c differs from the TI compiler startup_msp432p401r_ccs.c, in that the GCC start-up file defines the interrupt handlers as external functions but with a "weak" default handler named Default_Handler. That means if the GCC linker encounters a (non-weak) interrupt handler in the linked objects that the interrupt handler from the linked objects gets referenced in the interruptVectors[] array, otherwise the Default_Handler gets referenced in the interruptVectors.

    That allows interrupt handlers to be registered in the interruptVectors[] array in startup_msp432p401r_gcc.c without having to change the startup_msp432p401r_gcc.c  file, by ensuring the names of the interrupt handler functions match those expected by the startup_msp432p401r_gcc.c file.

    The names of the peripheral interrupt handlers in the CC3100BOOST_MQTT-TwitterLED_MSP432P401R example match the names in the startup_msp432p401r_gcc.c file. When the CC3100BOOST_MQTT-TwitterLED_MSP432P401R example was set to use the GNU v4.9.3 compiler, running nm on the executable showed that the peripheral interrupt handlers had been referenced in the interruptVectors[] array since the addresses of the functions were different from the Default_Handler:

    $ /cygdrive/C/ti/ccs720/ccsv7/tools/compiler/gcc-arm-none-eabi-4_9-2015q3/bin/arm-none-eabi-nm.exe CC3100BOOST_MQTT-TwitterLED_MSP432P401R.out  | egrep "(Default_Handler|SysTick_Handler|TA1_0_IRQHandler|EUSCIA0_IRQHandler|PORT1_IRQHandler|PORT2_IRQHandler)"
    00000d90 T Default_Handler
    000015f8 T EUSCIA0_IRQHandler
    00000910 T PORT1_IRQHandler
    000015b0 T PORT2_IRQHandler
    0000bbf0 T SysTick_Handler
    000009a8 T TA1_0_IRQHandler

    Jon Morss said:
    Also, unlike the Tiva version of the startup file, the startup for these MSP32/CC3100 projects are not c++ friendly and do not have "#ifdef __cplusplus" entries so that might be another issue

    If the interrupt handlers are given C++ linkage the names will be mangled and not match the names expected by the startup_msp432p401r_gcc.c. E.g. the cli_uart.c example file, which contains the EUSCIA0_IRQHandler interrupt handler was re-named to cli_uart.cpp to compile it as C++. That causes the EUSCIA0_IRQHandler handler to be given a C++ mangled named and NOT be referenced in the interruptVectors[] array, as shown by the address of the weak symbol EUSCIA0_IRQHandler then having the same address as the Default_Handler function:

    $ /cygdrive/C/ti/ccs720/ccsv7/tools/compiler/gcc-arm-none-eabi-4_9-2015q3/bin/arm-none-eabi-nm.exe CC3100BOOST_MQTT-TwitterLED_MSP432P401R.out  | egrep "(Default_Handler|SysTick_Handler|TA1_0_IRQHandler|EUSCIA0_IRQHandler|PORT1_IRQHandler|PORT2_IRQHandler)"
    000015f8 T _Z18EUSCIA0_IRQHandlerv
    00000d90 T Default_Handler
    00000d90 W EUSCIA0_IRQHandler
    00000910 T PORT1_IRQHandler
    000015b0 T PORT2_IRQHandler
    0000bbfc T SysTick_Handler
    000009a8 T TA1_0_IRQHandler

    Inside the cli_uart.cpp file the EUSCIA0_IRQHandler was given C linkage:

    extern "C" void EUSCIA0_IRQHandler(void)
    {

    And the EUSCIA0_IRQHandler was then referenced in the interruptVectors[] array :

    $ /cygdrive/C/ti/ccs720/ccsv7/tools/compiler/gcc-arm-none-eabi-4_9-2015q3/bin/arm-none-eabi-nm.exe CC3100BOOST_MQTT-TwitterLED_MSP432P401R.out  | egrep "(Default_Handler|SysTick_Handler|TA1_0_IRQHandler|EUSCIA0_IRQHandler|PORT1_IRQHandler|PORT2_IRQHandler)"
    00000d90 T Default_Handler
    000015f8 T EUSCIA0_IRQHandler
    00000910 T PORT1_IRQHandler
    000015b0 T PORT2_IRQHandler
    0000bbfc T SysTick_Handler
    000009a8 T TA1_0_IRQHandler

    I.e. your problem of the Default_Handler function getting called in the GCC version of the project might be due to the interrupt handlers being given C++ linkage.

  • Chester,

    I appreciate the info.

    To get beyond the name mangling as well as some compile time errors, I changed the startup_msp432p401r_gcc.c to the following:

    /******************************************************************************
    * 
    *  Copyright (C) 2012 - 2016 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.  
    * 
    *  MSP432P401R Interrupt Vector Table
    * 
    *****************************************************************************/
    
    #include <stdint.h>
    
    /* Entry point for the application. */
    #ifdef __cpluplus
    extern "C" int _mainCRTStartup();
    #else
    extern int _mainCRTStartup();
    #endif
    
    /* External declaration for system initialization function                  */
    #ifdef __cpluplus
    extern "C" void SystemInit(void);
    #else
    extern void SystemInit(void);
    #endif
    
    #ifdef __cpluplus
    extern "C" {
    #endif
    extern uint32_t __data_load__;
    extern uint32_t __data_start__;
    extern uint32_t __data_end__;
    extern uint32_t __StackTop;
    #ifdef __cplusplus
    }
    #endif /* __cplusplus */
    
    typedef void( *pFunc )( void );
    
    /* Forward declaration of the default fault handlers. */
    void Default_Handler(void);
    extern void Reset_Handler       (void) __attribute__((weak));
    
    /* Cortex-M4 Processor Exceptions */
    #ifdef __cpluplus
    extern "C" {
    #endif
    extern void NMI_Handler         (void) __attribute__((weak, alias("Default_Handler")));
    extern void HardFault_Handler   (void) __attribute__((weak, alias("Default_Handler")));
    extern void MemManage_Handler   (void) __attribute__((weak, alias("Default_Handler")));
    extern void BusFault_Handler    (void) __attribute__((weak, alias("Default_Handler")));
    extern void UsageFault_Handler  (void) __attribute__((weak, alias("Default_Handler")));
    extern void SVC_Handler         (void) __attribute__((weak, alias("Default_Handler")));
    extern void DebugMon_Handler    (void) __attribute__((weak, alias("Default_Handler")));
    extern void PendSV_Handler      (void) __attribute__((weak, alias("Default_Handler")));
    #ifdef __cplusplus
    }
    #endif /* __cplusplus */
    
    /* device specific interrupt handler */
    /* External declarations for the interrupt handlers used by the application. */
    #ifdef __cpluplus
    extern "C" {
    #endif
    extern void SysTick_Handler(void);
    extern void PORT1_IRQHandler(void);
    extern void TA1_0_IRQHandler(void);
    extern void PORT2_IRQHandler(void);
    extern void EUSCIA0_IRQHandler(void);
    #ifdef __cplusplus
    }
    #endif /* __cplusplus */
    /* To be added by user */
    
    /* Interrupt vector table.  Note that the proper constructs must be placed on this to */
    /* ensure that it ends up at physical address 0x0000.0000 or at the start of          */
    /* the program if located at a start address other than 0.
     *                            */
    #ifdef __cpluplus
    extern "C" {
    void (* const interruptVectors[])(void) __attribute__ ((section (".intvecs"))) =
    {
    #else
    void (* const interruptVectors[])(void) __attribute__ ((section (".intvecs"))) =
    {
    #endif
        (pFunc)&__StackTop,
                                               /* The initial stack pointer */
        Reset_Handler,                         /* The reset handler         */
        NMI_Handler,                           /* The NMI handler           */
        HardFault_Handler,                     /* The hard fault handler    */
    	Default_Handler,                     /* The MPU fault handler     */
    	Default_Handler,                      /* The bus fault handler     */
    	Default_Handler,                    /* The usage fault handler   */
        0,                                     /* Reserved                  */
        0,                                     /* Reserved                  */
        0,                                     /* Reserved                  */
        0,                                     /* Reserved                  */
    	Default_Handler,                           /* SVCall handler            */
        Default_Handler,                      /* Debug monitor handler     */
        0,                                     /* Reserved                  */
    	Default_Handler,                        /* The PendSV handler        */
        SysTick_Handler,                       /* The SysTick handler       */
    	Default_Handler,                        /* PSS ISR                   */
    	Default_Handler,                         /* CS ISR                    */
    	Default_Handler,                        /* PCM ISR                   */
    	Default_Handler,                      /* WDT ISR                   */
    	Default_Handler,                        /* FPU ISR                   */
    	Default_Handler,                      /* FLCTL ISR                 */
    	Default_Handler,                    /* COMP0 ISR                 */
    	Default_Handler,                    /* COMP1 ISR                 */
    	Default_Handler,                      /* TA0_0 ISR                 */
    	Default_Handler,                      /* TA0_N ISR                 */
        TA1_0_IRQHandler,                      /* TA1_0 ISR                 */
    	Default_Handler,                      /* TA1_N ISR                 */
    	Default_Handler,                      /* TA2_0 ISR                 */
    	Default_Handler,                      /* TA2_N ISR                 */
    	Default_Handler,                      /* TA3_0 ISR                 */
    	Default_Handler,                      /* TA3_N ISR                 */
        EUSCIA0_IRQHandler,                    /* EUSCIA0 ISR               */
    	Default_Handler,                    /* EUSCIA1 ISR               */
    	Default_Handler,                    /* EUSCIA2 ISR               */
    	Default_Handler,                    /* EUSCIA3 ISR               */
    	Default_Handler,                    /* EUSCIB0 ISR               */
    	Default_Handler,                    /* EUSCIB1 ISR               */
    	Default_Handler,                    /* EUSCIB2 ISR               */
    	Default_Handler,                    /* EUSCIB3 ISR               */
    	Default_Handler,                      /* ADC14 ISR                 */
    	Default_Handler,                   /* T32_INT1 ISR              */
    	Default_Handler,                   /* T32_INT2 ISR              */
    	Default_Handler,                   /* T32_INTC ISR              */
    	Default_Handler,                     /* AES ISR                   */
    	Default_Handler,                      /* RTC ISR                   */
    	Default_Handler,                    /* DMA_ERR ISR               */
    	Default_Handler,                   /* DMA_INT3 ISR              */
    	Default_Handler,                   /* DMA_INT2 ISR              */
    	Default_Handler,                   /* DMA_INT1 ISR              */
    	Default_Handler,                   /* DMA_INT0 ISR              */
        PORT1_IRQHandler,                      /* PORT1 ISR                 */
        PORT2_IRQHandler,                      /* PORT2 ISR                 */
    	Default_Handler,                      /* PORT3 ISR                 */
    	Default_Handler,                      /* PORT4 ISR                 */
    	Default_Handler,                      /* PORT5 ISR                 */
    	Default_Handler                       /* PORT6 ISR                 */
    };
    
    /* Forward declaration of the default fault handlers. */
    /* This is the code that gets called when the processor first starts execution */
    /* following a reset event.  Only the absolutely necessary set is performed,   */
    /* after which the application supplied entry() routine is called.  Any fancy  */
    /* actions (such as making decisions based on the reset cause register, and    */
    /* resetting the bits in that register) are left solely in the hands of the    */
    /* application.                                                                */
    void Reset_Handler(void)
    {
    
    	    /* Call system initialization routine */
    		SystemInit();
    
    	    /* Jump to the main initialization routine. */
    	    _mainCRTStartup();
    }
    
    /* This is the code that gets called when the processor receives an unexpected  */
    /* interrupt.  This simply enters an infinite loop, preserving the system state */
    /* for examination by a debugger.                                               */
    void Default_Handler(void)
    {
    	/* Enter an infinite loop. */
    	while(1)
    	{
    	}
    }
    

    This what the main.cpp looks like:

    *
     * main.c - MQTT Twitter Controlled RGB LED 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     -   MQTT Twitter Controlled RGB LED
     * Application Overview -   This is a sample application demonstrating how
     *                          to connect to an MQTT broker and publish/subscribe
     *                          to topics. A web server was created to search
     *                          for all public tweets containing the hashtag
     *                          #MSP432LaunchPad and a RGB(#, #, #) control command.
     *                          The web server publishes the RGB() command to all
     *                          LaunchPads running the demo. The application also
     *                          publishes the device's MAC Address when push
     *                          button S1 is pressed on the LaunchPad. The web
     *                          server then tweets the received MAC Address on
     *                          the MSP LaunchPad Twitter account.
     *
     *                          Refer to README.txt for more information
     */
    
    // Standard includes
    
    extern "C" {
    #include <stdlib.h>
    #include <string.h>
    
    #include "driverlib.h"
    #include "simplelink.h"
    #include "sl_common.h"
    #include "MQTTClient.h"
    }
    /*
     * 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       "<Your_AP's_SSID>"       /* Access point name to connect to. */
    #define SSID_NAME       "MYSSID"       /* Access point name to connect to. */
    #define SEC_TYPE        SL_SEC_TYPE_WPA_WPA2     /* Security type of the Access piont */
    //#define PASSKEY         "<Your_AP's_Password>"   /* Password in case of secure AP */
    #define PASSKEY         "MYPASSWD"   /* Password in case of secure AP */
    #define PASSKEY_LEN     pal_Strlen(PASSKEY)      /* Password length in case of secure AP */
    
    /*
     * MQTT server and topic properties that shall be modified per application
     */
    //#define MQTT_BROKER_SERVER  "iot.eclipse.org"
    //#define SUBSCRIBE_TOPIC "/msp/cc3100/demo"
    //#define PUBLISH_TOPIC "/msp/cc3100/demo/fromLP"
    
    #define MQTT_BROKER_SERVER  "MYIP"
    
    #define SUBSCRIBE_TOPIC "/test/topic"
    #define PUBLISH_TOPIC "/msp/cc3100/demo/fromLP"
    //#define PUBLISH_TOPIC "/test/topic"
    
    
    
    #define APPLICATION_VERSION "Version: v1.0"
    #define APPLICATION_AUTHOR "Author: Jon Morss"
    
    // MQTT message buffer size
    #define BUFF_SIZE 32
    
    #define MCLK_FREQUENCY 48000000
    #define PWM_PERIOD 255
    
    #define SL_STOP_TIMEOUT        0xFF
    
    #define SMALL_BUF           32
    #define MAX_SEND_BUF_SIZE   512
    #define MAX_SEND_RCV_SIZE   1024
    
    /* Application specific status/error codes */
    typedef enum{
        DEVICE_NOT_IN_STATION_MODE = -0x7D0,        /* Choosing this number to avoid overlap with host-driver's error codes */
        HTTP_SEND_ERROR = DEVICE_NOT_IN_STATION_MODE - 1,
        HTTP_RECV_ERROR = HTTP_SEND_ERROR - 1,
        HTTP_INVALID_RESPONSE = HTTP_RECV_ERROR -1,
        STATUS_CODE_MAX = -0xBB8
    }e_AppStatusCodes;
    
    #define min(X,Y) ((X) < (Y) ? (X) : (Y))
    
    
    /*
     * GLOBAL VARIABLES -- Start
     */
    /* Button debounce state variables */
    volatile unsigned int S1buttonDebounce = 0;
    volatile unsigned int S2buttonDebounce = 0;
    volatile int publishID = 0;
    
    unsigned char macAddressVal[SL_MAC_ADDR_LEN];
    unsigned char macAddressLen = SL_MAC_ADDR_LEN;
    
    char macStr[18];        // Formatted MAC Address String
    char uniqueID[9];       // Unique ID generated from TLV RAND NUM and MAC Address
    
    
    Network n;
    Client hMQTTClient;     // MQTT Client
    
    _u32  g_Status = 0;
    struct{
        _u8 Recvbuff[MAX_SEND_RCV_SIZE];
        _u8 SendBuff[MAX_SEND_BUF_SIZE];
    
        _u8 HostName[SMALL_BUF];
        _u8 CityName[SMALL_BUF];
    
        _u32 DestinationIP;
        _i16 SockID;
    }g_AppData;
    
    /* Port mapper configuration register */
    const uint8_t port_mapping[] =
    {
        //Port P2:
        PM_TA0CCR1A, PM_TA0CCR2A, PM_TA0CCR3A, PM_NONE, PM_TA1CCR1A, PM_NONE, PM_NONE, PM_NONE
    };
    
    /* TimerA UpMode Configuration Parameter */
    const Timer_A_UpModeConfig upConfig =
    {
            TIMER_A_CLOCKSOURCE_SMCLK,              // SMCLK Clock Source
            TIMER_A_CLOCKSOURCE_DIVIDER_8,          // SMCLK/8 = 6MHz
            90000,                                  // 15ms debounce period
            TIMER_A_TAIE_INTERRUPT_DISABLE,         // Disable Timer interrupt
            TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE ,    // Enable CCR0 interrupt
            TIMER_A_DO_CLEAR                        // Clear value
    };
    
    /*
     * GLOBAL VARIABLES -- End
     */
    
    
    /*
     * STATIC FUNCTION DEFINITIONS -- Start
     */
    static _i32 establishConnectionWithAP();
    static _i32 configureSimpleLinkToDefaultState();
    static _i32 initializeAppVariables();
    static void displayBanner();
    static void messageArrived(MessageData*);
    static void generateUniqueID();
    
    
    /*
     * 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)
    {
        if(pWlanEvent == NULL)
            CLI_Write((unsigned char *)" [WLAN EVENT] NULL Pointer Error \n\r");
    
        switch(pWlanEvent->Event)
        {
            case SL_WLAN_CONNECT_EVENT:
            {
                SET_STATUS_BIT(g_Status, STATUS_BIT_CONNECTION);
    
                /*
                 * Information about the connected AP (like name, MAC etc) will be
                 * available in 'slWlanConnectAsyncResponse_t' - Applications
                 * can use it if required
                 *
                 * slWlanConnectAsyncResponse_t *pEventData = NULL;
                 * pEventData = &pWlanEvent->EventData.STAandP2PModeWlanConnected;
                 *
                 */
            }
            break;
    
            case SL_WLAN_DISCONNECT_EVENT:
            {
                slWlanConnectAsyncResponse_t*  pEventData = NULL;
    
                CLR_STATUS_BIT(g_Status, STATUS_BIT_CONNECTION);
                CLR_STATUS_BIT(g_Status, STATUS_BIT_IP_ACQUIRED);
    
                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)
                {
                    CLI_Write((unsigned char *)" Device disconnected from the AP on application's request \n\r");
                }
                else
                {
                    CLI_Write((unsigned char *)" Device disconnected from the AP on an ERROR..!! \n\r");
                }
            }
            break;
    
            default:
            {
                CLI_Write((unsigned char *)" [WLAN EVENT] Unexpected event \n\r");
            }
            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)
    {
        if(pNetAppEvent == NULL)
            CLI_Write((unsigned char *)" [NETAPP EVENT] NULL Pointer Error \n\r");
    
        switch(pNetAppEvent->Event)
        {
            case SL_NETAPP_IPV4_IPACQUIRED_EVENT:
            {
                SET_STATUS_BIT(g_Status, STATUS_BIT_IP_ACQUIRED);
    
                /*
                 * Information about the connected AP's IP, gateway, DNS etc
                 * will be available in 'SlIpV4AcquiredAsync_t' - Applications
                 * can use it if required
                 *
                 * SlIpV4AcquiredAsync_t *pEventData = NULL;
                 * pEventData = &pNetAppEvent->EventData.ipAcquiredV4;
                 * <gateway_ip> = pEventData->gateway;
                 *
                 */
            }
            break;
    
            default:
            {
                CLI_Write((unsigned char *)" [NETAPP EVENT] Unexpected event \n\r");
            }
            break;
        }
    }
    
    /*!
        \brief This function handles callback for the HTTP server events
    
        \param[in]      pHttpEvent - Contains the relevant event information
        \param[in]      pHttpResponse - Should be filled by the user with the
                        relevant response information
    
        \return         None
    
        \note
    
        \warning
    */
    void SimpleLinkHttpServerCallback(SlHttpServerEvent_t *pHttpEvent,
                                      SlHttpServerResponse_t *pHttpResponse)
    {
        /*
         * This application doesn't work with HTTP server - Hence these
         * events are not handled here
         */
        CLI_Write((unsigned char *)" [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((unsigned char *)" [GENERAL EVENT] \n\r");
    }
    
    /*!
        \brief This function handles socket events indication
    
        \param[in]      pSock is the event passed to the handler
    
        \return         None
    */
    void SimpleLinkSockEventHandler(SlSockEvent_t *pSock)
    {
        if(pSock == NULL)
            CLI_Write((unsigned char *)" [SOCK EVENT] NULL Pointer Error \n\r");
    
        switch( pSock->Event )
        {
            case SL_SOCKET_TX_FAILED_EVENT:
            {
                /*
                * 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((unsigned char *)" [SOCK EVENT] Close socket operation failed to transmit all queued packets\n\r");
                    break;
    
    
                    default:
                        CLI_Write((unsigned char *)" [SOCK EVENT] Unexpected event \n\r");
                    break;
                }
            }
            break;
    
            default:
                CLI_Write((unsigned char *)" [SOCK EVENT] Unexpected event \n\r");
            break;
        }
    }
    /*
     * ASYNCHRONOUS EVENT HANDLERS -- End
     */
    
    
    /*
     * Application's entry point
     */
    int main(int argc, char** argv)
    {
        _i32 retVal = -1;
    
        retVal = initializeAppVariables();
        ASSERT_ON_ERROR(retVal);
    
        /* Stop WDT and initialize the system-clock of the MCU */
        stopWDT();
        initClk();
    
        /* GPIO Setup for Pins 2.0-2.2 */
        MAP_PMAP_configurePorts((const uint8_t *) port_mapping, PMAP_P2MAP, 1,
            PMAP_DISABLE_RECONFIGURATION);
    
        MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2,
            GPIO_PIN0 | GPIO_PIN1 | GPIO_PIN2, GPIO_PRIMARY_MODULE_FUNCTION);
    
        /* Confinguring P1.1 & P1.4 as an input and enabling interrupts */
        GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN1 | GPIO_PIN4);
        GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN1 | GPIO_PIN4);
        GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN1 | GPIO_PIN4);
        GPIO_interruptEdgeSelect(GPIO_PORT_P1, GPIO_PIN1 | GPIO_PIN4, GPIO_HIGH_TO_LOW_TRANSITION);
        GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN1 | GPIO_PIN4);
    
        GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0);
        GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
    
        /* Configure TimerA0 for RGB LED*/
        TA0CCR0 = PWM_PERIOD;                   // PWM Period
        TA0CCTL1 = OUTMOD_7;                    // CCR1 reset/set
        TA0CCR1 = PWM_PERIOD * (0/255);                 // CCR1 PWM duty cycle
        TA0CCTL2 = OUTMOD_7;                    // CCR2 reset/set
        TA0CCR2 = PWM_PERIOD * (0/255);                 // CCR2 PWM duty cycle
        TA0CCTL3 = OUTMOD_7;                    // CCR3 reset/set
        TA0CCR3 = PWM_PERIOD * (0/255);                 // CCR3 PWM duty cycle
        TA0CTL = TASSEL__SMCLK | MC__UP | TACLR;  // SMCLK, up mode, clear TAR
    
        /* Configuring TimerA1 for Up Mode */
        Timer_A_configureUpMode(TIMER_A1_BASE, &upConfig);
    
        Interrupt_enableInterrupt(INT_TA1_0);
        Interrupt_enableInterrupt(INT_PORT1);
        Interrupt_enableMaster();
    
        /* Configure command line interface */
        CLI_Configure();
    
        displayBanner();
    
        /*
         * 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
         */
        retVal = configureSimpleLinkToDefaultState();
        if(retVal < 0)
        {
            if (DEVICE_NOT_IN_STATION_MODE == retVal)
                CLI_Write((unsigned char *)" Failed to configure the device in its default state \n\r");
    
            LOOP_FOREVER();
        }
    
        CLI_Write((unsigned char *)" 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
         */
        retVal = sl_Start(0, 0, 0);
        if ((retVal < 0) ||
            (ROLE_STA != retVal) )
        {
            CLI_Write((unsigned char *)" Failed to start the device \n\r");
            LOOP_FOREVER();
        }
    
        CLI_Write((unsigned char *)" Device started as STATION \n\r");
    
        /* Connecting to WLAN AP */
        retVal = establishConnectionWithAP();
        if(retVal < 0)
        {
            CLI_Write((unsigned char *)" Failed to establish connection w/ an AP \n\r");
            LOOP_FOREVER();
        }
    
        CLI_Write((unsigned char *)" Connection established w/ AP and IP is acquired \n\r");
    
        // Obtain MAC Address
        sl_NetCfgGet(SL_MAC_ADDRESS_GET,NULL,&macAddressLen,(unsigned char *)macAddressVal);
    
        // Print MAC Addres to be formatted string
        snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
                macAddressVal[0], macAddressVal[1], macAddressVal[2], macAddressVal[3], macAddressVal[4], macAddressVal[5]);
    
        // Generate 32bit unique ID from TLV Random Number and MAC Address
        generateUniqueID();
    
        int rc = 0;
        unsigned char buf[100];
        unsigned char readbuf[100];
        int mqtt_port = 8883;
    
        NewNetwork(&n);
        rc = ConnectNetwork(&n, MQTT_BROKER_SERVER, mqtt_port);
    
        if (rc != 0) {
            CLI_Write((unsigned char *)" Failed to connect to MQTT broker \n\r");
            LOOP_FOREVER();
        }
        CLI_Write((unsigned char *)" Connected to MQTT broker \n\r");
    
        MQTTClient(&hMQTTClient, &n, 1000, buf, 100, readbuf, 100);
        MQTTPacket_connectData cdata = MQTTPacket_connectData_initializer;
        cdata.MQTTVersion = 3;
        cdata.clientID.cstring = uniqueID;
        rc = MQTTConnect(&hMQTTClient, &cdata);
    
        if (rc != 0) {
            CLI_Write((unsigned char *)" Failed to start MQTT client \n\r");
            LOOP_FOREVER();
        }
        CLI_Write((unsigned char *)" Started MQTT client successfully \n\r");
    
        rc = MQTTSubscribe(&hMQTTClient, SUBSCRIBE_TOPIC, QOS0, messageArrived);
    
        if (rc != 0) {
            CLI_Write((unsigned char *)" Failed to subscribe to /msp/cc3100/demo topic \n\r");
            LOOP_FOREVER();
        }
        //CLI_Write((unsigned char *)" Subscribed to /msp/cc3100/demo topic \n\r");
        CLI_Write((unsigned char *)" Subscribed to ");
        CLI_Write((unsigned char *)SUBSCRIBE_TOPIC);
        CLI_Write((unsigned char *)" topic \n\r");
    
        rc = MQTTSubscribe(&hMQTTClient, uniqueID, QOS0, messageArrived);
    
        if (rc != 0) {
            CLI_Write((unsigned char *)" Failed to subscribe to uniqueID topic \n\r");
            LOOP_FOREVER();
        }
        //CLI_Write((unsigned char *)" Subscribed to uniqueID topic \n\r");
        CLI_Write((unsigned char *)" Subscribed to ");
        CLI_Write((unsigned char *)uniqueID);
        CLI_Write((unsigned char *)" topic \n\r");
    
        while(1){
            rc = MQTTYield(&hMQTTClient, 10);
            if (rc != 0) {
                CLI_Write((unsigned char *)" MQTT failed to yield \n\r");
                LOOP_FOREVER();
            }
    
            if (publishID) {
                int rc = 0;
                MQTTMessage msg;
                msg.dup = 0;
                msg.id = 0;
                msg.payload = uniqueID;
                msg.payloadlen = 8;
                msg.qos = QOS0;
                msg.retained = 0;
                rc = MQTTPublish(&hMQTTClient, PUBLISH_TOPIC, &msg);
    
                if (rc != 0) {
                    CLI_Write((unsigned char *)" Failed to publish unique ID to MQTT broker \n\r");
                    LOOP_FOREVER();
                }
                CLI_Write((unsigned char *)" Published unique ID successfully \n\r");
                CLI_Write((unsigned char *)PUBLISH_TOPIC);
                CLI_Write((unsigned char *)"\n\r");
    
                publishID = 0;
            }
    
            Delay(10);
        }
    }
    
    static void generateUniqueID() {
        CRC32_setSeed(TLV->RANDOM_NUM_1, CRC32_MODE);
        CRC32_set32BitData(TLV->RANDOM_NUM_2);
        CRC32_set32BitData(TLV->RANDOM_NUM_3);
        CRC32_set32BitData(TLV->RANDOM_NUM_4);
        int i;
        for (i = 0; i < 6; i++)
        CRC32_set8BitData(macAddressVal[i], CRC32_MODE);
    
        uint32_t crcResult = CRC32_getResult(CRC32_MODE);
        sprintf(uniqueID, "%06X", uint16_t(crcResult));
    }
    
    //****************************************************************************
    //
    //!    \brief MQTT message received callback - Called when a subscribed topic
    //!                                            receives a message.
    //! \param[in]                  data is the data passed to the callback
    //!
    //! \return                        None
    //
    //****************************************************************************
    static void messageArrived(MessageData* data) {
        char buf[BUFF_SIZE];
        CLI_Write((unsigned char *)"Message arrrived \n\r");
        char *tok;
        long color;
    
        // Check for buffer overflow
        if (data->topicName->lenstring.len >= BUFF_SIZE) {
    //      UART_PRINT("Topic name too long!\n\r");
            return;
        }
        if (data->message->payloadlen >= BUFF_SIZE) {
    //      UART_PRINT("Payload too long!\n\r");
            return;
        }
    
        strncpy(buf, data->topicName->lenstring.data,
            min(BUFF_SIZE, data->topicName->lenstring.len));
        buf[data->topicName->lenstring.len] = 0;
    
    
    
        strncpy(buf, (const char *)data->message->payload,
            min(BUFF_SIZE, data->message->payloadlen));
        buf[data->message->payloadlen] = 0;
    
        tok = strtok(buf, " ");
        color = strtol(tok, NULL, 10);
        TA0CCR1 = PWM_PERIOD * (color/255.0);                 // CCR1 PWM duty cycle
        tok = strtok(NULL, " ");
        color = strtol(tok, NULL, 10);
        TA0CCR2 = PWM_PERIOD * (color/255.0);                // CCR2 PWM duty cycle
        tok = strtok(NULL, " ");
        color = strtol(tok, NULL, 10);
        TA0CCR3 = PWM_PERIOD * (color/255.0);                  // CCR3 PWM duty cycle
    
        return;
    }
    
    /*
     * Port 1 interrupt handler. This handler is called whenever the switch attached
     * to P1.1 is pressed.
     */
    
    extern "C" void PORT1_IRQHandler(void)
    {
        uint32_t status = GPIO_getEnabledInterruptStatus(GPIO_PORT_P1);
        GPIO_clearInterruptFlag(GPIO_PORT_P1, status);
    
        if (status & GPIO_PIN1)
        {
            if (S1buttonDebounce == 0)
            {
                S1buttonDebounce = 1;
    
                GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN0);
    
                // Publish the unique ID
                publishID = 1;
                CLI_Write((unsigned char *)"** PublishID \n\r ");
                CLI_Write((unsigned char *)publishID);
                CLI_Write((unsigned char *)"\n\r");
    
                MAP_Timer_A_startCounter(TIMER_A1_BASE, TIMER_A_UP_MODE);
            }
        }
        if (status & GPIO_PIN4)
        {
            if (S2buttonDebounce == 0)
            {
                S2buttonDebounce = 1;
    
                CLI_Write((unsigned char *)" MAC Address: \n\r ");
                CLI_Write((unsigned char *)macStr);
                CLI_Write((unsigned char *)"\n\r");
    
                MAP_Timer_A_startCounter(TIMER_A1_BASE, TIMER_A_UP_MODE);
            }
        }
    }
    
    extern "C" void TA1_0_IRQHandler(void)
    {
        GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0);
        if (P1IN & GPIO_PIN1)
        {
            S1buttonDebounce = 0;
        }
        if (P1IN & GPIO_PIN4)
        {
            S2buttonDebounce = 0;
        }
    
        if ((P1IN & GPIO_PIN1) && (P1IN & GPIO_PIN4))
        {
            Timer_A_stopTimer(TIMER_A1_BASE);
        }
        MAP_Timer_A_clearCaptureCompareInterrupt(TIMER_A1_BASE,
                    TIMER_A_CAPTURECOMPARE_REGISTER_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
               - Remove all filters
    
        \param[in]      none
    
        \return         On success, zero is returned. On error, negative is returned
    */
    static _i32 configureSimpleLinkToDefaultState()
    {
        SlVersionFull   ver = {{0}};
        _WlanRxFilterOperationCommandBuff_t  RxFilterIdMask = {{0}};
    
        _u8           val = 1;
        _u8           configOpt = 0;
        _u8           configLen = 0;
        _u8           power = 0;
    
        _i32          retVal = -1;
        _i32          mode = -1;
    
        mode = sl_Start(0, 0, 0);
        ASSERT_ON_ERROR(mode);
    
        /* If the device is not in station-mode, try configuring it in station-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_ACQUIRED(g_Status)) { _SlNonOsMainLoopTask(); }
            }
    
            /* Switch to STA role and restart */
            retVal = sl_WlanSetMode(ROLE_STA);
            ASSERT_ON_ERROR(retVal);
    
            retVal = sl_Stop(SL_STOP_TIMEOUT);
            ASSERT_ON_ERROR(retVal);
    
            retVal = sl_Start(0, 0, 0);
            ASSERT_ON_ERROR(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 */
                ASSERT_ON_ERROR(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, (_u8 *)(&ver));
        ASSERT_ON_ERROR(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(retVal);
    
        /* Remove all profiles */
        retVal = sl_WlanProfileDel(0xFF);
        ASSERT_ON_ERROR(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(retVal);
    
        /* Disable scan */
        configOpt = SL_SCAN_POLICY(0);
        retVal = sl_WlanPolicySet(SL_POLICY_SCAN , configOpt, NULL, 0);
        ASSERT_ON_ERROR(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, (_u8 *)&power);
        ASSERT_ON_ERROR(retVal);
    
        /* Set PM policy to normal */
        retVal = sl_WlanPolicySet(SL_POLICY_PM , SL_NORMAL_POLICY, NULL, 0);
        ASSERT_ON_ERROR(retVal);
    
        /* Unregister mDNS services */
        retVal = sl_NetAppMDNSUnRegisterService(0, 0);
        ASSERT_ON_ERROR(retVal);
    
        /* Remove  all 64 filters (8*8) */
        pal_Memset(RxFilterIdMask.FilterIdMask, 0xFF, 8);
        retVal = sl_WlanRxFilterSet(SL_REMOVE_RX_FILTER, (_u8 *)&RxFilterIdMask,
                           sizeof(_WlanRxFilterOperationCommandBuff_t));
        ASSERT_ON_ERROR(retVal);
    
        retVal = sl_Stop(SL_STOP_TIMEOUT);
        ASSERT_ON_ERROR(retVal);
    
        retVal = initializeAppVariables();
        ASSERT_ON_ERROR(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 _i32 establishConnectionWithAP()
    {
        SlSecParams_t secParams = {0};
        _i32 retVal = 0;
    
        secParams.Key = (_i8* )PASSKEY;
        secParams.KeyLen = PASSKEY_LEN;
        secParams.Type = ( _u8)SEC_TYPE;
    
        retVal = sl_WlanConnect((_i8* )SSID_NAME, pal_Strlen((_i8* )SSID_NAME), 0, &secParams, 0);
        ASSERT_ON_ERROR(retVal);
    
        /* Wait */
        while((!IS_CONNECTED(g_Status)) || (!IS_IP_ACQUIRED(g_Status))) { _SlNonOsMainLoopTask(); }
    
        return SUCCESS;
    }
    
    /*!
        \brief This function initializes the application variables
    
        \param[in]  None
    
        \return     0 on success, negative error-code on error
    */
    static _i32 initializeAppVariables()
    {
        g_Status = 0;
        pal_Memset(&g_AppData, 0, sizeof(g_AppData));
    
        return SUCCESS;
    }
    
    /*!
        \brief This function displays the application's banner
    
        \param      None
    
        \return     None
    */
    static void displayBanner()
    {
        CLI_Write((unsigned char *) "\n\r\n\r");
        CLI_Write((unsigned char *)"\n\r*******************************************************************************\n\r");
        CLI_Write((unsigned char *)" MQTT TEST \n\r");
        CLI_Write((unsigned char *)APPLICATION_VERSION);
        CLI_Write((unsigned char *) "\n\r");
        CLI_Write((unsigned char *)APPLICATION_AUTHOR);
        CLI_Write((unsigned char *)"\n\r*******************************************************************************\n\r");
        CLI_Write((unsigned char *) "\n\r\n\r");
    }
    

    Also to note, in simplelink.h, there is a missing 'extern "C"' so I added this at line 391.

    #include "wlan_rx_filters.h"
    
    #ifdef    __cplusplus
    extern "C"
    {
    #endif
    
    /* Async functions description*/
    
    /*!

    I still run into the same issue with getting stuck in the "Default_Handler"

  • what exactly is the problem you are running into?

    When the msp432 takes an exception it will lay down an exception stack saving various registers (see "infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/Babefdjc.html").  It then stashes an EXC_RETURN value into LR.

    That is what you are seeing and the debugger is trying to  fetch.  Of course there is no source there.   The problem is the debugger gets confused.

    you can safely ignore this.  How is it getting in your way?

    Oh by the way, you are taking an exception.  That is what is precipitating all of this.  Have you figured out what the processor isn't happy about?

    you need to look at various h/w registers that will tell you what exception you took.

  • Eric,

    "what exactly is the problem you are running into?"

    Uh, I thought that was rather obvious.

    When I run the example as is from MSP432Ware, I am able to compile and then run a Debug session to load the code and then I usually see the "Green Arrow" run button at which point I click it and the code runs.  In this particular case, when switching to the GNU gcc compiler, I am able to finally compile the code and then run the debug session, but I do not see the "Green Arrow" run button highlighted to run the code but instead end up in the the Default_Handler. The code does not run.  Why do I have to reexplain this????

    "you can safely ignore this.  How is it getting in your way?"

    I don't know, hence I am posting here.

    "Oh by the way, you are taking an exception.  That is what is precipitating all of this.  Have you figured out what the processor isn't happy about?

    you need to look at various h/w registers that will tell you what exception you took."

    N.S.!  Again, this I know which is why I am posting here.  If I knew the answer to this, I would be posting the solution.  

    Frustrating! 

  • I run the arm tool chain to compile.

    I use the gdb that comes with that tool chain. I don't use Code Composer because it gets in the way.

    When I run into the 0xfffffff8 can't display source code problem. I'm able to simple single step using gdb "si" or "ni" commands.

    Like I've said, the debugger is confused, that is why you don't have a green run button. There is no source there, so I don't see how you can get the debugger to behave correctly. It doesn't seem to know about EXC_RETURN (it should).

    See if you can single step or single step instruction.

    If that doesn't work, you can try installing the ARM toolchain which includes GDB and try that. You are already using that too chain (gnu gcc). Byte the bullet and switch to full command line and get away from Code Composer.

    Right now it looks like you are going around in circles. Sorry if this isn't what you want to hear.

    The FFFFFFF8 is an EXC_RETURN and is special. It means you took an exception. That is where I would start.
  • Eric,

    Thanks, but yes that is not the answer I was looking for or even expected. I suppose what I am looking for is why the debugger is getting confused? I sort of expected when posting an issue on the TI CCS forum, I would get something more inline with either "You shouldn't do that" or "That has been fixed in version such and such". Not "Byte the bullet and switch to full command line and get away from Code Composer." That is an odd answer coming from this forum and not very promising.

    I'll see if I can find a solution on my own, or have to make a design decision real soon.
  • Jon Morss said:
    Eric,

    Thanks, but yes that is not the answer I was looking for or even expected. I suppose what I am looking for is why the debugger is getting confused? I sort of expected when posting an issue on the TI CCS forum, I would get something more inline with either "You shouldn't do that" or "That has been fixed in version such and such". Not "Byte the bullet and switch to full command line and get away from Code Composer." That is an odd answer coming from this forum and not very promising.

    I'll see if I can find a solution on my own, or have to make a design decision real soon.

    I'm sorry that  I'm not offering the answer you like.  I am trying to give you a sense of the reality that I'm familar with in this area.

    If you get a good answer back from the CCS folks great.  My experience is that is low probablity, sorry but that's my experience.  I've asked TI for various things and on multiple occasions and haven't had much satisfaction.  Now to be fair, there have been a few instances where TI has come through for me, but mostly not.  Don't get me wrong, I love TI hardware.

    So given Code Composers complexity I'm trying to give you at least one way around the problem.  I'm not saying byte the bullet and deal.  I'm saying here is one possible (out of hopefully a few more) way around the problem so you can continue to make progress.

    I'm sorry if it came off different than I intended

  • Sounds like you have already gone through your share of frustrations with this.  

    Okay, although I had installed GNU GCC ARM package through Resource Explorer from the IDE, I pulled down the 'MSP432-GCC-OPENSOURCE:' bits form the TI website and installed them separately.  I compared the startup scripts from my project and the Blinking LED example and notice something added in the Blinking LED example that was missing from my startup script.  

    This had a comment stating:

    // Copy the data segment initializers from flash to SRAM.

    Once I added this to the startup script in my project, I was able to get passed the " No source available for "0xfffffff8" during debug" and at least the beginning of the program runs.  It is still getting hung up at Initializing the CC3100, but this is certainly a bit further than where I was.

    This is what the Reset_Handler looks like now:

    void Reset_Handler(void) {
    	uint32_t *pui32Src, *pui32Dest;
    
    	//
    	// Copy the data segment initializers from flash to SRAM.
    	//
    	pui32Src = &__data_load__;
    	for (pui32Dest = &__data_start__; pui32Dest < &__data_end__;) {
    		*pui32Dest++ = *pui32Src++;
    	}
    
    	/* Call system initialization routine */
    	SystemInit();
    
    	/* Jump to the main initialization routine. */
    	_mainCRTStartup();
    
    }
    

    At least now I can set breakpoints and walk through the code but have not found what is causing the CC3100 to not initialize completely.  The Green LED on the CC3100 does light up when the code runs but that is as far as it gets.

    If I can get passed this , then I think I am golden.

  • Jon Morss said:

    Sounds like you have already gone through your share of frustrations with this.  

    Yep.  At some level above the hardware I don't use TI stuff anymore.  Basically I use the hardware and the debugging tools.  For primary debugging I use the Segger Jlink (they rock by the way).  I also have used the TI on board XDS110-ET and the standalone XDS110 but mostly have found using TI software to be more trouble than its worth.  (Sorry TI, I've tried to help get this changed but that too has been too painful).

    Jon Morss said:

    Okay, although I had installed GNU GCC ARM package through Resource Explorer from the IDE, I pulled down the 'MSP432-GCC-OPENSOURCE:' bits form the TI website and installed them separately.  I compared the startup scripts from my project and the Blinking LED example and notice something added in the Blinking LED example that was missing from my startup script.  

    I'm using this one: //launchpad.net/gcc-arm-embedded and in particular the 4.9 series (there is something in the 5 series that tickles a bug in the way my main software is put together, I'm a principle developer for TinyOS and gcc 5 and TinyOS don't play well, very strange).

    Jon Morss said:

    This had a comment stating:

    // Copy the data segment initializers from flash to SRAM.

    Once I added this to the startup script in my project, I was able to get passed the " No source available for "0xfffffff8" during debug" and at least the beginning of the program runs.  It is still getting hung up at Initializing the CC3100, but this is certainly a bit further than where I was.

    This is what the Reset_Handler looks like now:

    void Reset_Handler(void) {
    	uint32_t *pui32Src, *pui32Dest;
    
    	//
    	// Copy the data segment initializers from flash to SRAM.
    	//
    	pui32Src = &__data_load__;
    	for (pui32Dest = &__data_start__; pui32Dest < &__data_end__;) {
    		*pui32Dest++ = *pui32Src++;
    	}
    
    	/* Call system initialization routine */
    	SystemInit();
    
    	/* Jump to the main initialization routine. */
    	_mainCRTStartup();
    
    }
    

    At least now I can set breakpoints and walk through the code but have not found what is causing the CC3100 to not initialize completely.  The Green LED on the CC3100 does light up when the code runs but that is as far as it gets.

    If I can get passed this , then I think I am golden.

    progress is good.  Glad to have helped.  Keep in mind if your code takes a fault you will again see the same behaviour.  I handle all the stuff you are starting to find and mention above.

    Here is a pointer to how I do startup:

    //github.com/MamMark/mm/blob/master/tos/platforms/dev6a/startup.c

    The dev6a platform is a TI EXP-MSP432P401R red (v2) experimenter board.

  • Eric,

    Thanks. Yeah, I just got past the first hurdle and ran into the same "No source available for "0xfffffff8"" further down stream, so I still have some work to do. I tried moving to the CC3200 SDK mqtt_client example but with TI-RTOS and am running into a whole new slew of issues there. I need to rethink my project since I have just a couple of weeks left to complete it, but was really hoping to have a MQTT solution.

    I can always try to use Energia I guess.

    Cheers,

    Jon
  • Jon Morss said:
    Eric,

    Thanks. Yeah, I just got past the first hurdle and ran into the same "No source available for "0xfffffff8"" further down stream, so I still have some work to do. I tried moving to the CC3200 SDK mqtt_client example but with TI-RTOS and am running into a whole new slew of issues there. I need to rethink my project since I have just a couple of weeks left to complete it, but was really hoping to have a MQTT solution.

    I can always try to use Energia I guess.

    Cheers,

    Jon

    first you will hit the "No source, fffffff8" any time you hit an exception.  you really want a toolchain that can handle that.

    next, my experience with Engergia is good.  It is worth a shot.