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.

BOOSTXL-CC3120MOD: High current consumption while unconnected

Part Number: BOOSTXL-CC3120MOD
Other Parts Discussed in Thread: CC3120BOOST, CODECOMPOSER, CC3120, CC3100BOOST, INA126, CC3100, UNIFLASH, MSP432WARE

Hello TIers,

I have a MSP-EXP432P4111 Launchpad and a CC3120BOOST BoosterPack running the SimpleLink MSP432P4 SDK (2.20.0.12) and the SimpleLink SDK WiFi Plugin (1.60.0.07) on the latest CodeComposer Studio (8).

I have created a project derived from the power_measurement_MSP_EXP432P4111_tirtos_css project that transmits 1 packet (16 bytes) every 60 seconds using a UDP socket. The system uses the deepSleepPolicy to enable going to LPM3 and initialPerfLevel=0, so MCLK runs at 12 MHz.  On the CC3120 I have removed the nHIB, PWR and RST associated resistors to ensure that the LEDs don't activate, and I use the intermittently connected profile to minimize consumption, i.e. I call sl_Start and sl_Stop. So far the system works fine and I receive the packets on the other side.

Now, in this scenario I would expect an average current of 100uA based on previous results using the MSP432P401R Launchpad (red) and the CC3100BOOST BoosterPack. However, when measuring with an IMETER-BOOST (INA126) in the Launchpad 3V3 connector I am getting around 1mA, but if I measure on the CC3120BOOST module using the J6 jumper, I get the expected average of 90uA. 

Now, I believe that there is some sort of pin or peripheral misconfiguration that causes leakage, but I am unable to find where. Of course, during measurement the TXD/RXD and the JTAG headers are disconnected from the target. 

Do you have any ideas what may be going on? Is there any special pin configuration in the MSP432P4111 (i.e. due to the LCD)?

Thanks in advance!

Pere

  • Please, find attached next some measurements of the current consumption in the 3V3 pins of the MSP432P4111 Launchpad:

    As it can be seen, the average current consumption is 1mA.

    Best,

    Pere

  • Hi Pere,

    To clarify, it sounds like you are trying to measure the current consumption of the CC3120 device from the MSP432P4111 LaunchPad 3V3 pin to the ground pin and comparing it to measuring across the CC3120BP J6 jumper. Please let me know if I am wrong in this understanding.

    The 3V3 header pin on the LaunchPad and BoosterPack is connected not only to the LEDs on the CC3120 BP, but the LEDs, debugger, and other things like the temperature sensor on the MSP432P4111 LP. That's likely where you're losing most of your current. You can check out the schematics available on the LP and BP tool pages.

    Is there a reason you want to measure across this 3V3 pin? It doesn't seem accurate if you're trying to measure the current consumption of the CC3120 device (and the serial flash on this BoosterPack). If you want to be sure you have minimized leakage current, check out the Measuring Current Consumption With a DC Power Analyzer section of the CC3120/CC3220 Power Measurement App Note: http://www.ti.com/lit/swra502

    Best regards,
    Sarah
  • Hello Sarah,

    Thanks for your quick answer and the provided documentation! I will take a look.

    Regarding your question, my intention is to measure the current consumption of the whole system, i.e. MSP432P4111 LaunchPad + CC3100 BoosterPack + RTOS, before starting to develop our own board for a specific application. Basically, we need to make sure that we will be able to meet the battery duration requirements given the on/off connectivity model.

    Now, I am well aware that there may be additional currents due to side components (i.e., LEDs, etc.) of the LaunchPad/BoosterPack or wrong GPIO configuration on the RTOS. However, as mentioned earlier, with the MSP432P401R LaunchPad and CC3100 BoosterPack we could achieve the expected current consumption (~100uA) after removing the side components (i.e., I disconnected the LED jumpers on the MSP432P401R and removed the LEDs on the CC3100 BoosterPack).

    What I am doing to measure the current consumption is:
    1) Remove the 3V jumper from the XDS110-ET to the MSP432P4111 (see next image, yellow) and place the INA126 in series to be able to measure the voltage drop caused by the current flowing through a 0.1 Ohm resistor.
    2) Program the test firmware using Code Composer Studio and remove power from the LaunchPad.
    3) Unplug the remaining XDS110-ET jumpers for the JTAG and UART (see next image, green) to ensure that the MSP432P4111 is isolated.
    4) Power the system back and let it boot up to avoid measuring the current consumption transient.
    5) Measure the current consumption with the INA126.

    As you can see in the previous post, the average consumption of the whole system is 1 mA when it should be around 10 times less, i.e., 20uA during off and 175 mA peak for the transmission). However, if I repeat the above process without the CC3100 BoosterPack and with a proper firmware (i.e., one that configures the pins and just goes to LPM3) I measure around 20 uA, which is what I would expect given the sensitivity of the INA126.

    So, to me, the problem seems to be a current leakage related to the pin configuration during the sleep modes.

    The GPIO pin configuration that I am using is the following:

    GPIO_PinConfig gpioPinConfigs[] = {
    /* Input pins */
    /* MSP_EXP432P4111_GPIO_S1 */
    GPIOMSP432_P1_1 | GPIO_CFG_IN_PU | GPIO_CFG_IN_INT_FALLING,
    /* MSP_EXP432P4111_GPIO_S2 */
    GPIOMSP432_P1_4 | GPIO_CFG_IN_PU | GPIO_CFG_IN_INT_FALLING,
    /* MSP_EXP432P4111_HOST_IRQ */
    GPIOMSP432_P2_5 | GPIO_CFG_IN_PD | GPIO_CFG_IN_INT_RISING,
    
    /* Output pins */
    /* MSP_EXP432P4111_GPIO_LED_RED */
    GPIOMSP432_P1_0 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_LOW,
    /* MSP_EXP432P4111_GPIO_LED_RED1 */
    GPIOMSP432_P2_0 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_LOW,
    /* MSP_EXP432P4111_GPIO_LED_GREEN */
    GPIOMSP432_P2_1 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_LOW,
    /* MSP_EXP432P4111_GPIO_LED_BLUE */
    GPIOMSP432_P2_2 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_LOW,
    
    /* MSP_EXP432P4111_nHIB_pin */
    GPIOMSP432_P4_1 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_HIGH,
    /* MSP_EXP432P4111_CS_pin */
    GPIOMSP432_P3_0 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH | GPIO_CFG_OUT_HIGH
    };

    And the power configuration is the following:

    const PowerMSP432_ConfigV1 PowerMSP432_config = {
    .policyInitFxn = &PowerMSP432_initPolicy,
    .policyFxn = &PowerMSP432_deepSleepPolicy,
    .initialPerfLevel = 0,
    .enablePolicy = true,
    .enablePerf = true,
    .enableParking = true
    };

    I have tried using enableParking = true and enableParking = false without any significant difference. Is there any specific pin that I should take a look at? In the CC3120 BoosterPack schematic I see many miscellaneous and test pins that may be interfering with the MSP432P4111 Launchpad.

    Sorry for the long post and thanks in advance!

    Best,
    Pere

  • Hello again,

    To progress I have separated the MSP432P4111 LaunchPad and the CC3120 BoosterPack and connected only the necessary pins: 3V3, GND, nHIB, CLK, IRQ, nCS, MOSI, MISO. This minimal setup is operational, i.e. I can send packets successfully, but the high current consumption of about 1 mA is still present.

    Also, I have tried commenting out the code related to the Wi-Fi configuration and communication and measuring the current consumption. If I don't call sl_Start at all then the current is in the expected range (i.e., around 22 uA), but if I call sl_Start once then the current consumption goes as before (i.e., around 1 mA) and it does not matter if I call sl_Stop.

    Based on these two additional tests I believe that the sl_Stop function implementation for the platform may not be releasing some hardware constraint, either GPIO or SPI, thus not allowing the CPU to go to sleep.

    What do you think?

    Pere
  • Hi Pere,

    What do you see when you measure your setup over the 3V3 pin with the J6 jumper removed? That removes all power to our CC3120 device, so we can determine if the extra current consumption you're seeing is the NWP or something else on the MSP432 LP.

    Best regards,
    Sarah
  • Hello Sarah,

    When I do as you say there are two options:

    1) With code that interacts with the radio (i.e. call to sl_Start): the consumption is high (>2 mA) as the drivers are trying to talk with the radio without success and it gets stuck busy waiting.

    2) Without code that interacts with the radio (i.e. no call to sl_Start): the consumption is low (~20 uA) as the code is only blinking the leds.

    I am adding a few more current consumption captures while running the exact same code:

    1) Mesuring on CC3120 VBAT_CC (J6) during transmit and idle. The measurements are as expected.

    2) Measuring across 3V3 on the MSP432P4111 Launchpad. CC3120 BoosterPack is powered directy with 3V3 from LaunchPad to VBAT_CC (J6) and J8 is left unconnected. When the MSP432 is in sleep and CC3120 is off the PWD LED on the CC3120 is off. When the MSP432 and the CC3120 are active (i.e. going to transmit) the PWR LED is a little bright. 

    As it can be seen, there is around 1 mA and much more noise compared to the first situation. Checking the resistors on the MSP432 and CC3120 (>10kOhm), 1 mA seems too much for a leakage at 3V3.

    My current believe is that there is something going on with the SPI/GPIO/CC3120 drivers, i.e. not being closed so that the MSP432 does not go to sleep. To test I've tried to change the initialPerfLevel from 0 (12 MHz) to 2 (48 MHz) and I've seen the current going from around 1 mA (as seen before) to around 2 mA (as seen next), meaning that it depends on the CPU clock. 

    What do you think?

    Thanks!

    Pere

  • Hi Pere,

    It seems more likely that the MSP432 is not going to sleep.

    1) Make sure you have the latest servicepack flashed to the CC3120 BP. You can find the servicepack in the SDK at \tools\cc31xx_tools\servicepack-cc3x20
    2) Are you getting a return value for sl_Stop? Are you calling it with a timeout value? We have a recommended value in the power_measurement example of 200 msec. sl_Stop does close the SPI driver, so that should not be keeping you awake if this is successful.
    3) Are you running any other peripherals besides the SPI and GPIOs? Other peripherals can keep the MCU awake.

    Best regards,
    Sarah
  • Hello again,

    1) I have updated the CC3120 BP with the last SP using the UniFlash tool and the results are the same.

    2) Regarding sl_Stop, if I call sl_Stop with timeout (i.e., from 200 to 750) I typically get a SL_API_ABORTED (-2005) response; calling sl_Start afterwards makes the code hang. Contrarily, if I call sl_Stop without timeout (i.e., 0), everything works as expected, but I still get a high current consumption.

    3) No, I am only calling Power_init, GPIO_init and SPI_init before calling sl_Start the first time. 

    Indeed, it looks like the MSP432 is only going to LPM0, where current consumption is in the order of 1mA. However, I am unsure why this may be happening given the fact that I do not use other peripheral. 

    Do you have a working project that you can share to test?

    Pere

  • Hello again,

    I am trying the power_measurement_MSP_EXP432P4111_tirtos project to ensure that I did not overlook something obvious.

    If I let the project as it is, the intermittently connected case (4) works just fine, but the current consumption is around 2 mA, as the CPU is running at 48 MHz and is only going to LPM0 (as PowerMSP432_config policyFxn to PowerMSP432_sleepPolicy and the initialPerfLevel to 2).

    If I set the PowerMSP432_config policyFxn to PowerMSP432_deepSleepPolicy and the initialPerfLevel to 0 (I also set the wifiMSP432HWAttrs .spiBitRate to 1 MHz as SMCLK is only 3 MHz) I start getting -2005 return values when the devices tries to go to sleep. I've also tried to change the .spiBitRate to 1.5 MHz and 750 kHz, but same results (i.e., -2005 return values).

    However, if I set SL_STOP_TIMEOUT to 0 then the code works just fine (no -2005 return values), but the current consumption is around 1 mA as with my project.

    I've also tried the power_measurement_MSP_EXP432P4111_nortos project with similar results, i.e. 1 mA current consumption. Based on that, I would assume that there is something going on with the MSP432Ware and the CC3120 drivers. Most probably the CC3120 drivers are not releasing some hardware constraint, thus not allowing the CPU to go to LPM3 as expected.

    Can you please double-check on your end?

    Thanks,
    Pere

  • Hello Sarah,

    Digging a little deeper into the MSP432P4 SDK (version 2.20.00.12) source code I can confirm it is a problem in the SPIMSP432DMA implementation.

    There are plenty of #if macros around the code that handle the case when DeviceFamily_ID equals DeviceFamily_ID_MSP432P401x when calling the Power_setConstraint and Power_releaseConstraint functions, but the case when DeviceFamily_ID_MSP432P4x1xT is not considered.

    This would explain why the MSP432P4111 CPU does not go to LPM3 and is always consuming around 1mA, whereas for the MSP432P401x it goes to LPM3 and takes around 20 uA in my scope.

    So the question at hand now is: when will a new version of the MSP432P4 SDK be released with a fix that takes the MSP432P4111 family into account?

    Thanks!
    Pere
  • Hi Pere,

    I've looped in another engineer from the MSP432 team that should be able to help you further with the MCU. I'm sorry for the delay!

    Best regards,
    Sarah
  • I am having a little trouble finding the project that you reference.  A couple possible sources for the issue might simply be the configuration of the IO or possibly the specific instance of the P5.3 on the launchpad which is connected to a temperature sensor.

        /*
         * Put all GPIOs in lowest power configuration. This is done by
         * MSP432-specific driverlib calls
         */
        MAP_GPIO_setOutputLowOnPin(GPIO_PORT_PA, PIN_ALL16);
        MAP_GPIO_setOutputLowOnPin(GPIO_PORT_PB, PIN_ALL16);
        MAP_GPIO_setOutputLowOnPin(GPIO_PORT_PC, PIN_ALL16);
        MAP_GPIO_setOutputLowOnPin(GPIO_PORT_PD, PIN_ALL16);
        MAP_GPIO_setOutputLowOnPin(GPIO_PORT_PE, PIN_ALL16);
        MAP_GPIO_setOutputLowOnPin(GPIO_PORT_PJ, PIN_ALL16);
        MAP_GPIO_setAsOutputPin(GPIO_PORT_PA, PIN_ALL16);
        MAP_GPIO_setAsOutputPin(GPIO_PORT_PB, PIN_ALL16);
        MAP_GPIO_setAsOutputPin(GPIO_PORT_PC, PIN_ALL16);
        MAP_GPIO_setAsOutputPin(GPIO_PORT_PD, PIN_ALL16);
        MAP_GPIO_setAsOutputPin(GPIO_PORT_PE, PIN_ALL16);
        MAP_GPIO_setAsOutputPin(GPIO_PORT_PJ, PIN_ALL16);
    
    #ifdef __MSP_EXP432P4111_H
        /*
         * Set P5.3 as analog input (connected to Temp Sensor on
         * MSP_EXP432P4111 LaunchPad)
         */
        MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5,
            GPIO_PIN3, GPIO_TERTIARY_MODULE_FUNCTION);
    #endif
    
        /*
         * Turn off PSS high-side supervisors to consume lower power in deep sleep
         */
        MAP_PSS_disableHighSide();

    I have also attached part of a project which implements the LPM3 transitions for the MSP432P401 as an example.

    ulpMeasure.c
    /*
     * Copyright (c) 2018, Texas Instruments Incorporated
     * All rights reserved.
     *
     * 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.
     */
     /*
     *  ======== ulpMeasure.c ========
     *  This file contains the following:
     *  
     *  ADCBuf callback
     *      The ADCBuf callback function is called everytime either the 'ping' or 
     *      'pong' of the DMA is completed.  Within the callback the number of 
     *      callbacks is monitored and passed along with the address of the most
     *      recent data array through the message queue to the calculation thread
     *      which computes the RMS and frequency of the signal across multiple ADC
     *      acquistions/DMA transfers.  The idea is that the acquisition size can
     *      exceed the 1024 DMA size limit by managing the transfers and performing
     *      cumulative computations until the desired data set size is acquired.
     *      The usage of the 'no block' message queue flag ensures that the queue 
     *      does not pend within the ISR.
     * 
     *  measurementThread
     *      The measurement thread calls the initialization of the RTC as well as
     *      initializes the ADC/DMA and the diplay driver.  Two semaphores are used
     *      to control the flow of the program: startMeasure and completeMeasure.  
     *      The startMeasure is posted from the RTC callback (hwi) and starts the 
     *      measurement, the next measurement will not start until the RTC posts
     *      again (1 second interval).  The measurementComplete is posted from 
     *      computationThread and indicates that both the ADC/DMA as well as the 
     *      computation is complete and that the data can be presented to the 
     *      display.  The ADC and the display are both closed and the power 
     *      constraint is released to allow the device to enter deepsleep0 (LPM3)
     *      while waiting for the next RTC hwi.
     *      
     *  RTC initialization and callback
     *      The RTC initialization sets the deepsleep power policy to allow LPM3.
     *      The RTC time interval is set to 1 second so that once a second the 
     *      data acquisition and computation are performed.  Once the measurement
     *      and computation are complete the device is allowed to return to LPM3
     *      to conserve power.
     */
    #include <stdint.h>
    #include <string.h>
    #include <stdbool.h>
    
    /* CMSIS Header File */
    #include <arm_math.h>
    
    /* POSIX Header files */
    #include <pthread.h>
    #include <semaphore.h>
    #include <mqueue.h>
    #include <errno.h>
    
    /* Driver Header files */
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/Power.h>
    #include <ti/drivers/power/PowerMSP432.h>
    #include <ti/drivers/ADCBuf.h>
    #include <ti/drivers/adcbuf/ADCBufMSP432.h>
    
    /* Driverlib Header files */
    #include <ti/devices/msp432p4xx/driverlib/driverlib.h>
    
    #include <ti/sysbios/hal/Hwi.h>
    #include <ti/display/Display.h>
    
    /* Example/Board Header files */
    #include "Board.h"
    #include "ulpMeasure.h"
    
    /*
     * Pend upon startMeasure which will be posted from RTC.  Post to
     * computeMeasure when the data collection is completed.
     */
    sem_t startMeasure;
    sem_t measureComplete;
    
    /* Power Policy Object*/
    Power_NotifyObj notifyObj;
    
    extern Display_Handle display;
    extern pthread_mutex_t resultMutex;
    
    extern volatile float rmsCalculation;
    extern volatile float rmsFrequency;
    
    q15_t pingSampleBuffer[ADCDMA_BUFFERSIZE];
    q15_t pongSampleBuffer[ADCDMA_BUFFERSIZE];
    uint32_t ADCDMA_SampleCount;
    
    /*******************************************************************************
     *                         LOCAL FUNCTIONS
     ******************************************************************************/
    static void RTC_C_Init(void);
    static void RTC_C_IRQHandler(uintptr_t arg);
    
    /*
     * This function is called whenever a buffer is full.
     * The content of the buffer is then converted into human-readable format and
     * sent to the PC via UART.
     *
     */
    void adcBufCallback(ADCBuf_Handle handle, ADCBuf_Conversion *conversion,
        void *completedADCBuffer, uint32_t completedChannel)
    {
        ADCBufMSP432_Object  *object = handle->object;
        mqd_t *mqdes = (mqd_t *)conversion->arg;
        int     msg;
        int retc;
    
        /*
         * need to use the mailbox to tell the computeMeasure which group is
         * being supplied, the first or the second.
         *
         * The reception takes place in computation.c
         */
    
        msg = (int)ADCDMA_SampleCount;
        retc = mq_send(*mqdes, (char*)&msg, sizeof(msg),0);
        if(retc != EAGAIN)
        {
            msg = (int)completedADCBuffer;
            retc = mq_send(*mqdes, (char*)&msg, sizeof(msg),0);
            if(retc != EAGAIN)
            {
                ADCDMA_SampleCount++;
            }
        }
        if(ADCDMA_SampleCount == NUMBER_OF_ADC_BUFFERS)
        {
            MAP_Timer_A_stopTimer(object->timerAddr);
        }
    }
    
    /*
     *  ======== measurementThread ========
     */
    void *measurementThread(void *arg0)
    {
        ADCBuf_Handle adcBuf;
        ADCBuf_Params adcBufParams;
        ADCBuf_Conversion continuousConversion;
    
        int retc;
    
        retc = sem_init(&startMeasure, 0, 0);
        if (retc == -1) {
            while (1);
        }
        retc = sem_init(&measureComplete, 0, 0);
        if (retc == -1) {
            while (1);
        }
    
        /* Set up an ADCBuf peripheral in ADCBuf_RECURRENCE_MODE_CONTINUOUS */
        ADCBuf_Params_init(&adcBufParams);
        adcBufParams.callbackFxn = adcBufCallback;
        adcBufParams.recurrenceMode = ADCBuf_RECURRENCE_MODE_CONTINUOUS;
        adcBufParams.returnMode = ADCBuf_RETURN_MODE_CALLBACK;
        adcBufParams.samplingFrequency = SAMPLE_FREQEUNCY;
    
        /* Configure the conversion struct */
        continuousConversion.arg = arg0;
        continuousConversion.adcChannel = Board_ADCBUF0CHANNEL3;
        continuousConversion.sampleBuffer = pingSampleBuffer;
        continuousConversion.sampleBufferTwo = pongSampleBuffer;
        continuousConversion.samplesRequestedCount = ADCDMA_BUFFERSIZE;
    
        RTC_C_Init();
    
        while(1)
        {
            sem_wait(&startMeasure);
            ADCDMA_SampleCount = 0;
            /*
             * re-open and close ADC driver with each aquisition to reinitialize
             * the DMA ping-pong
             */
            adcBuf = ADCBuf_open(Board_ADCBUF0, &adcBufParams);
            if (!adcBuf){
                /* AdcBuf did not open correctly. */
                while(1);
            }
            ADCBuf_control(adcBuf, ADCBufMSP432_CMD_ENTER_ADC_ULTRA_LOW_POWER_MODE, 0);
            /*
             * this function enables the reference burst feature.  This means that the
             * reference is only available during the S&H time and that the measurement
             * time is 'increased' by the time required for the reference to be ready.
             *
             */
            MAP_ADC14_setResolution(ADC_12BIT);
            MAP_ADC14_setResultFormat(ADC_SIGNED_BINARY);
            MAP_ADC14_disableReferenceBurst();
            /* Start converting. */
            if (ADCBuf_convert(adcBuf, &continuousConversion, 1) !=
                ADCBuf_STATUS_SUCCESS)
            {
                /* Did not start conversion process correctly. */
                while(1);
            }
            sem_wait(&measureComplete);
            ADCBuf_close(adcBuf);
    
            display = Display_open(Display_Type_UART, NULL);
            if (display == NULL) {
                /* Failed to open display driver */
                while(1);
            }
    
            pthread_mutex_lock(&resultMutex);
            Display_printf(display, 0, 0, "Frequency: %f\n RMS: %f\n", rmsFrequency, rmsCalculation);
            pthread_mutex_unlock(&resultMutex);
            Display_close(display);
            Power_releaseConstraint(PowerMSP432_DISALLOW_DEEPSLEEP_0);
        }
    }
    
    /* Callback function for Power Policy Manager to perform specific tasks on
     * LMP3 Entry and Wake. During LPM3 Entry, the GPIO for AFE Power Enable and
     * Sensor Enable are made low to reduce current consumption. Also since
     * enableparking is disabled, the unused IO's are configured to output low
     * state so that current consumption is reduced. During LPM3 exit the GPIO for
     * AFE Power Enable and Sensor Enable are made High.
     * */
    unsigned int notifyDeepSleepFxn(unsigned int eventType, unsigned int eventArg,
     unsigned int clientArg)
    {
        if(PowerMSP432_ENTERING_DEEPSLEEP == eventType)
        {
            /* Put all GPIOs in lowest power configuration. This is done by MSP432 specific driverlib accesses*/
            MAP_GPIO_setOutputLowOnPin(GPIO_PORT_PA, PIN_ALL16);
            MAP_GPIO_setOutputLowOnPin(GPIO_PORT_PB, PIN_ALL16);
            MAP_GPIO_setOutputLowOnPin(GPIO_PORT_PC, PIN_ALL16);
            MAP_GPIO_setOutputLowOnPin(GPIO_PORT_PD, PIN_ALL16);
            MAP_GPIO_setOutputLowOnPin(GPIO_PORT_PE, PIN_ALL16);
            MAP_GPIO_setOutputLowOnPin(GPIO_PORT_PJ, PIN_ALL16);
            MAP_GPIO_setAsOutputPin(GPIO_PORT_PA, PIN_ALL16);
            MAP_GPIO_setAsOutputPin(GPIO_PORT_PB, PIN_ALL16);
            MAP_GPIO_setAsOutputPin(GPIO_PORT_PC, PIN_ALL16);
            MAP_GPIO_setAsOutputPin(GPIO_PORT_PD, PIN_ALL16);
            MAP_GPIO_setAsOutputPin(GPIO_PORT_PE, PIN_ALL16);
            MAP_GPIO_setAsOutputPin(GPIO_PORT_PJ, PIN_ALL16);
    
        #ifdef __MSP_EXP432P4111_H
            /* Set P5.3 as analog input (connected to Temp Sensor on MSP_EXP432P4111 LaunchPad) */
            MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5, GPIO_PIN3, GPIO_TERTIARY_MODULE_FUNCTION);
        #endif
    
            /* Turn off PSS high-side supervisors to consume lower power after deep sleep */
            MAP_PSS_disableHighSide();
        }
        else
        {
            /*
             * Enable UART pins
             */
            MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,
                    GPIO_PIN2, GPIO_PRIMARY_MODULE_FUNCTION);
            MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,
                    GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION);
            /*
             * Enable ADC pins
             */
            MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5,
                    GPIO_PIN4, GPIO_TERTIARY_MODULE_FUNCTION);
            MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5,
                    GPIO_PIN5, GPIO_TERTIARY_MODULE_FUNCTION);
    
        }
    
        return NULL;
    }
    
    void RTC_C_Init(void)
    {
        Hwi_Handle myHwi;
        Hwi_Params hwiParams;
    
        /* Configuring pins for peripheral/crystal LFXT */
        MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_PJ,
                GPIO_PIN0 | GPIO_PIN1, GPIO_PRIMARY_MODULE_FUNCTION);
    
        /* Starting LFXT in non-bypass mode without a timeout */
        MAP_CS_startLFXT(false);
        MAP_CS_initClockSignal(CS_BCLK, CS_LFXTCLK_SELECT, CS_CLOCK_DIVIDER_1);
    
        Power_setPolicy((Power_PolicyFxn)PowerMSP432_deepSleepPolicy);
    
        /*
         * allowing down to deepsleep_0 = LPM3
         */
        Power_setConstraint(PowerMSP432_DISALLOW_DEEPSLEEP_1);
    
        /* Register for entering shutdown notifications */
        Power_registerNotify(&notifyObj, PowerMSP432_ENTERING_DEEPSLEEP | PowerMSP432_AWAKE_DEEPSLEEP,
            (Power_NotifyFxn)notifyDeepSleepFxn, 0);
    
        /* RTC, 1s period */
        MAP_RTC_C_setPrescaleValue(RTC_C_PRESCALE_0,0x00);
        MAP_RTC_C_setPrescaleValue(RTC_C_PRESCALE_1,0x00);
        RTC_C->PS1CTL = RTC_C_PS1CTL_RT1IP_7;
        MAP_RTC_C_enableInterrupt(RTC_C_PRESCALE_TIMER1_INTERRUPT);
        MAP_Interrupt_enableInterrupt(INT_RTC_C);
    
        /* Create RTOS hwi */
        Hwi_Params_init(&hwiParams);
        hwiParams.arg = 5;
        hwiParams.priority = 0x40;
        myHwi = Hwi_create(INT_RTC_C, RTC_C_IRQHandler, &hwiParams, NULL);
    
        if (myHwi == NULL)
        {
            while (1);
        }
    
        /* Start the RTC */
        MAP_RTC_C_startClock();
    }
    
    void RTC_C_IRQHandler(uintptr_t arg)
    {
        uint32_t status;
    
        status = MAP_RTC_C_getEnabledInterruptStatus();
        MAP_RTC_C_clearInterruptFlag(status);
    
        /*
         * reset scalers for the next second
         */
        if(status & RTC_C_PRESCALE_TIMER1_INTERRUPT)
        {
            MAP_RTC_C_holdClock();
            MAP_RTC_C_setPrescaleValue(RTC_C_PRESCALE_0,0x00);
            MAP_RTC_C_setPrescaleValue(RTC_C_PRESCALE_1,0x00);
            /* Re-start RTC Clock */
            MAP_RTC_C_startClock();
            /* Post to the Task */
            sem_post(&startMeasure);
        }
    }
    

    Regards,

    Chris

  • Dear Chris,

    I don't think it is the GPIO configuration or the sensor, as my results show a dependency on the CPU operating frequency.

    If I run at power level 2 (48 MHz) the current consumption is higher compared to power level 1 (12 MHz).

    To progress, could you please execute the power_measurement project on a MSP432P4111 Lanchpad and CC3120 radio transceiver and measure the current consumption?+

    Thanks,

    Pere

  • I am still confused about the project you are referring to.  I will ask me colleagues but if you can provide a link or reference that would help me.  

    In the earlier description I thought you were looking to explain why the current was on the order of 1mA and not 10uA.  I do not understand the context of the 48Mhz and 12Mhz.  This will result in greater than 1mA.

    Regards,

    Chris

  • Hello Chris,

    The project that I am refering to is the following:
    dev.ti.com/.../
    I am using the TI-RTOS version, but I have tried the No RTOS version as well with the same results.

    The measured current consumption is around 1 mA when the system operates at initialPerfLevel=0 (MCLK runs at 12 MHz), so my point is that the CPU is not going to LPM3 as requested by my code, but instead is going to LPM0 due to some peripheral blocking the transition to such state. If you check the MSP432P4111 datasheet (page 42) you will see that in LPM0 the consumption at 12 MHz with LDO is betwen 850 and 950 uA, which is consistent with what I am measuring.

    As mentioned in one of my earlier messages, this seems to be related to the MSP432P4 SDK (version 2.20.00.12) drivers, in particular the SPIMSP432DMA. If you check the source code, you will see that there are plenty of #if macros around the code that handle the case when DeviceFamily_ID equals DeviceFamily_ID_MSP432P401x when calling the Power_setConstraint and Power_releaseConstraint functions, but the case when DeviceFamily_ID_MSP432P4x1xT is not considered.

    Kind regards,
    Pere
  • Hello Chris,

    Any news on that matter?

    Best,

    Pere

  • I am still working to understand how the communication (SPI) is closed from the application.  I have taken the example and moved to performance level 0 and changed the power policy to the deep sleep policy.  Entering the intermittent mode I am measuring about 10uA on the MSP432 board and when I add the CC3120 boosterpack the current jumps to about 10mA (there are two LEDs on the boosterpack which are illuminated).  

    Also, attached is the board description file I am using.

    Regards,

    Chris

    MSP_EXP432P4111.c
    /*
     * Copyright (c) 2017, Texas Instruments Incorporated
     * All rights reserved.
     *
     * 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.
     */
    
    /*
     *  ======== MSP_EXP432P4111.c ========
     *  This file is responsible for setting up the board specific items for the
     *  MSP_EXP432P4111 board.
     */
    
    #include <stdbool.h>
    #include <stddef.h>
    #include <stdint.h>
    
    #include <ti/drivers/Power.h>
    #include <ti/drivers/power/PowerMSP432.h>
    
    #include <ti/devices/msp432p4xx/inc/msp.h>
    #include <ti/devices/msp432p4xx/driverlib/rom.h>
    #include <ti/devices/msp432p4xx/driverlib/rom_map.h>
    #include <ti/devices/msp432p4xx/driverlib/adc14.h>
    #include <ti/devices/msp432p4xx/driverlib/dma.h>
    #include <ti/devices/msp432p4xx/driverlib/gpio.h>
    #include <ti/devices/msp432p4xx/driverlib/i2c.h>
    #include <ti/devices/msp432p4xx/driverlib/interrupt.h>
    #include <ti/devices/msp432p4xx/driverlib/pmap.h>
    #include <ti/devices/msp432p4xx/driverlib/ref_a.h>
    #include <ti/devices/msp432p4xx/driverlib/spi.h>
    #include <ti/devices/msp432p4xx/driverlib/timer_a.h>
    #include <ti/devices/msp432p4xx/driverlib/timer32.h>
    #include <ti/devices/msp432p4xx/driverlib/uart.h>
    #include <ti/devices/msp432p4xx/driverlib/wdt_a.h>
    
    #include "MSP_EXP432P4111.h"
    
    /*
     *  =============================== ADC ===============================
     */
    #include <ti/drivers/ADC.h>
    #include <ti/drivers/adc/ADCMSP432.h>
    
    /* ADC objects */
    ADCMSP432_Object adcMSP432Objects[MSP_EXP432P4111_ADCCOUNT];
    
    /* ADC configuration structure */
    const ADCMSP432_HWAttrsV1 adcMSP432HWAttrs[MSP_EXP432P4111_ADCCOUNT] = {
        {
            .adcPin = ADCMSP432_P5_5_A0,
            .refVoltage = ADCMSP432_REF_VOLTAGE_INT_2_5V,
            .resolution = ADC_14BIT
        },
        {
            .adcPin = ADCMSP432_P5_4_A1,
            .refVoltage = ADCMSP432_REF_VOLTAGE_INT_1_45V,
            .resolution = ADC_8BIT
        }
    };
    
    const ADC_Config ADC_config[MSP_EXP432P4111_ADCCOUNT] = {
        {
            .fxnTablePtr = &ADCMSP432_fxnTable,
            .object = &adcMSP432Objects[MSP_EXP432P4111_ADC0],
            .hwAttrs = &adcMSP432HWAttrs[MSP_EXP432P4111_ADC0]
        },
        {
            .fxnTablePtr = &ADCMSP432_fxnTable,
            .object = &adcMSP432Objects[MSP_EXP432P4111_ADC1],
            .hwAttrs = &adcMSP432HWAttrs[MSP_EXP432P4111_ADC1]
        }
    };
    
    const uint_least8_t ADC_count = MSP_EXP432P4111_ADCCOUNT;
    
    /*
     *  =============================== ADCBuf ===============================
     */
    #include <ti/drivers/ADCBuf.h>
    #include <ti/drivers/adcbuf/ADCBufMSP432.h>
    
    /* ADC objects */
    ADCBufMSP432_Object adcbufMSP432Objects[MSP_EXP432P4111_ADCBUFCOUNT];
    
    ADCBufMSP432_Channels adcBuf0MSP432Channels[MSP_EXP432P4111_ADCBUF0CHANNELCOUNT
    ] = {
        {
            .adcPin = ADCBufMSP432_P5_5_A0,
            .refSource = ADCBufMSP432_VREFPOS_INTBUF_VREFNEG_VSS,
            .refVoltage = 2500000
        },
        {
            .adcPin = ADCBufMSP432_P5_4_A1,
            .refSource = ADCBufMSP432_VREFPOS_INTBUF_VREFNEG_VSS,
            .refVoltage = 2500000
        }
    };
    
    /* ADC configuration structure */
    const ADCBufMSP432_HWAttrs adcbufMSP432HWAttrs[MSP_EXP432P4111_ADCBUFCOUNT] = {
        {
            .intPriority = ~0,
            .channelSetting = adcBuf0MSP432Channels,
            .adcTimerTriggerSource = ADCBufMSP432_TIMERA1_CAPTURECOMPARE2
        }
    };
    
    const ADCBuf_Config ADCBuf_config[MSP_EXP432P4111_ADCBUFCOUNT] = {
        {
            .fxnTablePtr = &ADCBufMSP432_fxnTable,
            .object = &adcbufMSP432Objects[MSP_EXP432P4111_ADCBUF0],
            .hwAttrs = &adcbufMSP432HWAttrs[MSP_EXP432P4111_ADCBUF0]
        }
    };
    
    const uint_least8_t ADCBuf_count = MSP_EXP432P4111_ADCBUFCOUNT;
    
    /*
     *  ============================= Capture =============================
     */
    #include <ti/drivers/Capture.h>
    #include <ti/drivers/capture/CaptureMSP432.h>
    
    CaptureMSP432_Object captureMSP432Objects[MSP_EXP432P4111_CAPTURECOUNT];
    
    const CaptureMSP432_HWAttrs captureMSP432HWAttrs[MSP_EXP432P4111_CAPTURECOUNT]
        = {
        /* Timer_A1 */
        {
            .timerBaseAddress = TIMER_A1_BASE,
            .clockSource = TIMER_A_CLOCKSOURCE_ACLK,
            .clockDivider = TIMER_A_CLOCKSOURCE_DIVIDER_64,
            .capturePort = CaptureMSP432_P7_7_TA1,
            .intPriority = ~0
        },
        /* Timer_A2 */
        {
            .timerBaseAddress = TIMER_A2_BASE,
            .clockSource = TIMER_A_CLOCKSOURCE_ACLK,
            .clockDivider = TIMER_A_CLOCKSOURCE_DIVIDER_64,
            .capturePort = CaptureMSP432_P6_7_TA2,
            .intPriority = ~0
        },
        /* Timer_A3 */
        {
            .timerBaseAddress = TIMER_A3_BASE,
            .clockSource = TIMER_A_CLOCKSOURCE_ACLK,
            .clockDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1,
            .capturePort = CaptureMSP432_P8_2_TA3,
            .intPriority = ~0
        }
        };
    
    const Capture_Config Capture_config[MSP_EXP432P4111_CAPTURECOUNT] = {
        {
            .fxnTablePtr = &CaptureMSP432_captureFxnTable,
            .object = &captureMSP432Objects[MSP_EXP432P4111_CAPTURE_TA1],
            .hwAttrs = &captureMSP432HWAttrs[MSP_EXP432P4111_CAPTURE_TA1]
        },
        {
            .fxnTablePtr = &CaptureMSP432_captureFxnTable,
            .object = &captureMSP432Objects[MSP_EXP432P4111_CAPTURE_TA2],
            .hwAttrs = &captureMSP432HWAttrs[MSP_EXP432P4111_CAPTURE_TA2]
        },
        {
            .fxnTablePtr = &CaptureMSP432_captureFxnTable,
            .object = &captureMSP432Objects[MSP_EXP432P4111_CAPTURE_TA3],
            .hwAttrs = &captureMSP432HWAttrs[MSP_EXP432P4111_CAPTURE_TA3]
        }
    };
    
    const uint_least8_t Capture_count = MSP_EXP432P4111_CAPTURECOUNT;
    
    /*
     *  =============================== DMA ===============================
     */
    #include <ti/drivers/dma/UDMAMSP432.h>
    
    #if defined(__TI_COMPILER_VERSION__)
    #pragma DATA_ALIGN(dmaControlTable, 256)
    #elif defined(__IAR_SYSTEMS_ICC__)
    #pragma data_alignment=256
    #elif defined(__GNUC__)
    __attribute__ ((aligned (256)))
    #endif
    static DMA_ControlTable dmaControlTable[8];
    
    /*
     *  ======== dmaErrorHwi ========
     *  This is the handler for the uDMA error interrupt.
     */
    static void dmaErrorHwi(uintptr_t arg)
    {
        int status = MAP_DMA_getErrorStatus();
        MAP_DMA_clearErrorStatus();
    
        /* Suppress unused variable warning */
        (void)status;
    
        while(1)
        {
            ;
        }
    }
    
    UDMAMSP432_Object udmaMSP432Object;
    
    const UDMAMSP432_HWAttrs udmaMSP432HWAttrs = {
        .controlBaseAddr = (void *)dmaControlTable,
        .dmaErrorFxn = (UDMAMSP432_ErrorFxn)dmaErrorHwi,
        .intNum = INT_DMA_ERR,
        .intPriority = (~0)
    };
    
    const UDMAMSP432_Config UDMAMSP432_config = {
        .object = &udmaMSP432Object,
        .hwAttrs = &udmaMSP432HWAttrs
    };
    
    /*
     *  ============================= Display =============================
     */
    #include <ti/display/Display.h>
    #include <ti/display/DisplayUart.h>
    #define MAXPRINTLEN 1024
    
    DisplayUart_Object displayUartObject;
    
    static char displayBuf[MAXPRINTLEN];
    
    const DisplayUart_HWAttrs displayUartHWAttrs = {
        .uartIdx = MSP_EXP432P4111_UARTA0,
        .baudRate = 115200,
        .mutexTimeout = (unsigned int)(-1),
        .strBuf = displayBuf,
        .strBufLen = MAXPRINTLEN
    };
    
    #ifndef BOARD_DISPLAY_USE_UART_ANSI
    #define BOARD_DISPLAY_USE_UART_ANSI 0
    #endif
    
    const Display_Config Display_config[] = {
        {
    #  if (BOARD_DISPLAY_USE_UART_ANSI)
            .fxnTablePtr = &DisplayUartAnsi_fxnTable,
    #  else /* Default to minimal UART with no cursor placement */
            .fxnTablePtr = &DisplayUartMin_fxnTable,
    #  endif
            .object = &displayUartObject,
            .hwAttrs = &displayUartHWAttrs
        }
    };
    
    const uint_least8_t Display_count = sizeof(Display_config) /
                                        sizeof(Display_Config);
    
    /*
     *  ======== MSP_EXP432P4111_initGeneral ========
     */
    void MSP_EXP432P4111_initGeneral(void)
    {
        Power_init();
    }
    
    /*
     *  =============================== GPIO ===============================
     */
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/gpio/GPIOMSP432.h>
    
    /*
     * Array of Pin configurations
     * NOTE: The order of the pin configurations must coincide with what was
     *       defined in MSP_EXP432P4111.h
     * NOTE: Pins not used for interrupts should be placed at the end of the
     *       array.  Callback entries can be omitted from callbacks array to
     *       reduce memory usage.
     */
    GPIO_PinConfig gpioPinConfigs[] = {
        /* Input pins */
        /*
         * NOTE: Specifying FALLING edge triggering for these buttons to ensure the
         * interrupts are signaled immediately.  See the description of the
         * PowerMSP432 driver's automatic pin parking feature for this rationale.
         */
        /* MSP_EXP432P4111_GPIO_S1 */
        GPIOMSP432_P1_1 | GPIO_CFG_IN_PU | GPIO_CFG_IN_INT_FALLING,
        /* MSP_EXP432P4111_GPIO_S2 */
        GPIOMSP432_P1_4 | GPIO_CFG_IN_PU | GPIO_CFG_IN_INT_FALLING,
        /* MSP_EXP432P4111_HOST_IRQ */
        GPIOMSP432_P2_5 | GPIO_CFG_IN_PD | GPIO_CFG_IN_INT_RISING,
    
        /* Output pins */
        /* MSP_EXP432P4111_GPIO_LED1 */
        GPIOMSP432_P1_0 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH |
        GPIO_CFG_OUT_LOW,
        /* MSP_EXP432P4111_GPIO_LED_RED */
        GPIOMSP432_P2_0 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH |
        GPIO_CFG_OUT_LOW,
        /* MSP_EXP432P4111_GPIO_LED_GREEN */
        GPIOMSP432_P2_1 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH |
        GPIO_CFG_OUT_LOW,
        /* MSP_EXP432P4111_GPIO_LED_BLUE */
        GPIOMSP432_P2_2 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH |
        GPIO_CFG_OUT_LOW,
        /* MSP_EXP432P4111_nHIB_pin */
        GPIOMSP432_P4_1 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH |
        GPIO_CFG_OUT_LOW,
        /* MSP_EXP432P4111_CS_pin */
        GPIOMSP432_P3_0 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_HIGH |
        GPIO_CFG_OUT_HIGH,
    
        GPIOMSP432_P5_4 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_LOW |
        GPIO_CFG_OUT_HIGH,
        /* MSP_EXP432P4111_SPI_CS2 */
        GPIOMSP432_P5_5 | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_LOW |
        GPIO_CFG_OUT_HIGH,
    };
    
    /*
     * Array of callback function pointers
     * NOTE: The order of the pin configurations must coincide with what was
     *       defined in MSP_EXP432P4111.h
     * NOTE: Pins not used for interrupts can be omitted from callbacks array to
     *       reduce memory usage (if placed at end of gpioPinConfigs array).
     */
    GPIO_CallbackFxn gpioCallbackFunctions[] = {
        /* MSP_EXP432P4111_GPIO_S1 */
        NULL,
        /* MSP_EXP432P4111_GPIO_S2 */
        NULL,
        /* MSP_EXP432P4111_HOST_IRQ */
        NULL
    };
    
    const GPIOMSP432_Config GPIOMSP432_config = {
        .pinConfigs = (GPIO_PinConfig *)gpioPinConfigs,
        .callbacks = (GPIO_CallbackFxn *)gpioCallbackFunctions,
        .numberOfPinConfigs = sizeof(gpioPinConfigs) / sizeof(GPIO_PinConfig),
        .numberOfCallbacks = sizeof(gpioCallbackFunctions) /
                             sizeof(GPIO_CallbackFxn),
        .intPriority = (~0)
    };
    
    /*
     *  =============================== I2C ===============================
     */
    #include <ti/drivers/I2C.h>
    #include <ti/drivers/i2c/I2CMSP432.h>
    
    I2CMSP432_Object i2cMSP432Objects[MSP_EXP432P4111_I2CCOUNT];
    
    const I2CMSP432_HWAttrsV1 i2cMSP432HWAttrs[MSP_EXP432P4111_I2CCOUNT] = {
        {
            .baseAddr = EUSCI_B0_BASE,
            .intNum = INT_EUSCIB0,
            .intPriority = (~0),
            .clockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK,
            .dataPin = I2CMSP432_P1_6_UCB0SDA,
            .clkPin = I2CMSP432_P1_7_UCB0SCL
        },
        {
            .baseAddr = EUSCI_B1_BASE,
            .intNum = INT_EUSCIB1,
            .intPriority = (~0),
            .clockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK,
            .dataPin = I2CMSP432_P6_4_UCB1SDA,
            .clkPin = I2CMSP432_P6_5_UCB1SCL
        }
    };
    
    const I2C_Config I2C_config[MSP_EXP432P4111_I2CCOUNT] = {
        {
            .fxnTablePtr = &I2CMSP432_fxnTable,
            .object = &i2cMSP432Objects[MSP_EXP432P4111_I2CB0],
            .hwAttrs = &i2cMSP432HWAttrs[MSP_EXP432P4111_I2CB0]
        },
        {
            .fxnTablePtr = &I2CMSP432_fxnTable,
            .object = &i2cMSP432Objects[MSP_EXP432P4111_I2CB1],
            .hwAttrs = &i2cMSP432HWAttrs[MSP_EXP432P4111_I2CB1]
        }
    };
    
    const uint_least8_t I2C_count = MSP_EXP432P4111_I2CCOUNT;
    
    /*
     *  =============================== I2CSlave ===============================
     */
    #include <ti/drivers/I2CSlave.h>
    #include <ti/drivers/i2cslave/I2CSlaveMSP432.h>
    
    I2CSlaveMSP432_Object i2cSlaveMSP432Objects[MSP_EXP432P4111_I2CSLAVECOUNT];
    
    const I2CSlaveMSP432_HWAttrs i2cSlaveMSP432HWAttrs[
        MSP_EXP432P4111_I2CSLAVECOUNT] = {
        {
            .baseAddr = EUSCI_B0_BASE,
            .intNum = INT_EUSCIB0,
            .intPriority = ~0,
            .slaveAddress = 0x48,
            .dataPin = I2CSLAVEMSP432_P1_6_UCB0SDA,
            .clkPin = I2CSLAVEMSP432_P1_7_UCB0SCL
        }
    };
    
    const I2CSlave_Config I2CSlave_config[MSP_EXP432P4111_I2CSLAVECOUNT] = {
        {
            .fxnTablePtr = &I2CSlaveMSP432_fxnTable,
            .object = &i2cSlaveMSP432Objects[MSP_EXP432P4111_I2CSLAVEB0],
            .hwAttrs = &i2cSlaveMSP432HWAttrs[MSP_EXP432P4111_I2CSLAVEB0]
        }
    };
    
    const uint_least8_t I2CSlave_count = MSP_EXP432P4111_I2CSLAVECOUNT;
    
    /*
     *  =============================== NVS ===============================
     */
    #include <ti/drivers/NVS.h>
    #include <ti/drivers/nvs/NVSMSP432.h>
    
    #define SECTORSIZE       0x1000
    #define NVS_REGIONS_BASE 0x1FB000
    #define REGIONSIZE       (SECTORSIZE * 4)
    
    /*
     * Reserve flash sectors for NVS driver use
     * by placing an uninitialized byte array
     * at the desired flash address.
     */
    #if defined(__TI_COMPILER_VERSION__)
    
    /*
     * Place uninitialized array at NVS_REGIONS_BASE
     */
    #pragma LOCATION(flashBuf, NVS_REGIONS_BASE);
    #pragma NOINIT(flashBuf);
    static char flashBuf[REGIONSIZE];
    
    #elif defined(__IAR_SYSTEMS_ICC__)
    
    /*
     * Place uninitialized array at NVS_REGIONS_BASE
     */
    __no_init static char flashBuf[REGIONSIZE] @ NVS_REGIONS_BASE;
    
    #elif defined(__GNUC__)
    
    /*
     * Place the flash buffers in the .nvs section created in the gcc linker file.
     * The .nvs section enforces alignment on a sector boundary but may
     * be placed anywhere in flash memory.  If desired the .nvs section can be set
     * to a fixed address by changing the following in the gcc linker file:
     *
     * .nvs (FIXED_FLASH_ADDR) (NOLOAD) : AT (FIXED_FLASH_ADDR) {
     *      *(.nvs)
     * } > REGION_TEXT
     */
    __attribute__ ((section (".nvs")))
    static char flashBuf[REGIONSIZE];
    
    #endif
    
    NVSMSP432_Object nvsMSP432Objects[MSP_EXP432P4111_NVSCOUNT];
    
    const NVSMSP432_HWAttrs nvsMSP432HWAttrs[MSP_EXP432P4111_NVSCOUNT] = {
        {
            .regionBase = (void *)flashBuf,
            .regionSize = REGIONSIZE,
        },
    };
    
    const NVS_Config NVS_config[MSP_EXP432P4111_NVSCOUNT] = {
        {
            .fxnTablePtr = &NVSMSP432_fxnTable,
            .object = &nvsMSP432Objects[MSP_EXP432P4111_NVSMSP4320],
            .hwAttrs = &nvsMSP432HWAttrs[MSP_EXP432P4111_NVSMSP4320],
        },
    };
    
    const uint_least8_t NVS_count = MSP_EXP432P4111_NVSCOUNT;
    
    /*
     *  =============================== Power ===============================
     */
    const PowerMSP432_ConfigV1 PowerMSP432_config = {
        .policyInitFxn = &PowerMSP432_initPolicy,
        //.policyFxn = &PowerMSP432_sleepPolicy,
        .policyFxn = &PowerMSP432_deepSleepPolicy,
        .initialPerfLevel = 0,
        .enablePolicy = true,
        .enablePerf = true,
        .enableParking = true
    };
    
    /*
     *  =============================== PWM ===============================
     */
    #include <ti/drivers/PWM.h>
    #include <ti/drivers/pwm/PWMTimerMSP432.h>
    
    PWMTimerMSP432_Object pwmTimerMSP432Objects[MSP_EXP432P4111_PWMCOUNT];
    
    const PWMTimerMSP432_HWAttrsV2 pwmTimerMSP432HWAttrs[MSP_EXP432P4111_PWMCOUNT]
        = {
        {
            .clockSource = TIMER_A_CLOCKSOURCE_SMCLK,
            .pwmPin = PWMTimerMSP432_P2_1_TA1CCR1A
        },
        {
            .clockSource = TIMER_A_CLOCKSOURCE_SMCLK,
            .pwmPin = PWMTimerMSP432_P2_2_TA1CCR2A
        }
        };
    
    const PWM_Config PWM_config[MSP_EXP432P4111_PWMCOUNT] = {
        {
            .fxnTablePtr = &PWMTimerMSP432_fxnTable,
            .object = &pwmTimerMSP432Objects[MSP_EXP432P4111_PWM_TA1_1],
            .hwAttrs = &pwmTimerMSP432HWAttrs[MSP_EXP432P4111_PWM_TA1_1]
        },
        {
            .fxnTablePtr = &PWMTimerMSP432_fxnTable,
            .object = &pwmTimerMSP432Objects[MSP_EXP432P4111_PWM_TA1_2],
            .hwAttrs = &pwmTimerMSP432HWAttrs[MSP_EXP432P4111_PWM_TA1_2]
        }
    };
    
    const uint_least8_t PWM_count = MSP_EXP432P4111_PWMCOUNT;
    
    /*
     *  =============================== SPI ===============================
     */
    #include <ti/drivers/SPI.h>
    #include <ti/drivers/spi/SPIMSP432DMA.h>
    
    SPIMSP432DMA_Object spiMSP432DMAObjects[MSP_EXP432P4111_SPICOUNT];
    
    const SPIMSP432DMA_HWAttrsV1 spiMSP432DMAHWAttrs[MSP_EXP432P4111_SPICOUNT] = {
        {
            .baseAddr = EUSCI_B0_BASE,
            .bitOrder = EUSCI_B_SPI_MSB_FIRST,
            .clockSource = EUSCI_B_SPI_CLOCKSOURCE_SMCLK,
            .defaultTxBufValue = 0,
            .dmaIntNum = INT_DMA_INT1,
            .intPriority = (~0),
            .rxDMAChannelIndex = DMA_CH1_EUSCIB0RX0,
            .txDMAChannelIndex = DMA_CH0_EUSCIB0TX0,
            .clkPin = SPIMSP432DMA_P1_5_UCB0CLK,
            .simoPin = SPIMSP432DMA_P1_6_UCB0SIMO,
            .somiPin = SPIMSP432DMA_P1_7_UCB0SOMI,
            .stePin = SPIMSP432DMA_P1_4_UCB0STE,
            .pinMode = EUSCI_SPI_3PIN,
            .minDmaTransferSize = 10
        },
        {
            .baseAddr = EUSCI_B2_BASE,
            .bitOrder = EUSCI_B_SPI_MSB_FIRST,
            .clockSource = EUSCI_B_SPI_CLOCKSOURCE_SMCLK,
            .defaultTxBufValue = 0,
            .dmaIntNum = INT_DMA_INT2,
            .intPriority = (~0),
            .rxDMAChannelIndex = DMA_CH5_EUSCIB2RX0,
            .txDMAChannelIndex = DMA_CH4_EUSCIB2TX0,
            .clkPin = SPIMSP432DMA_P3_5_UCB2CLK,
            .simoPin = SPIMSP432DMA_P3_6_UCB2SIMO,
            .somiPin = SPIMSP432DMA_P3_7_UCB2SOMI,
            .stePin = SPIMSP432DMA_P3_4_UCB2STE,
            .pinMode = EUSCI_SPI_3PIN,
            .minDmaTransferSize = 10
        },
        {
            .baseAddr = EUSCI_A1_BASE,
            .bitOrder = EUSCI_A_SPI_MSB_FIRST,
            .clockSource = EUSCI_A_SPI_CLOCKSOURCE_SMCLK,
            .defaultTxBufValue = 0,
            .dmaIntNum = INT_DMA_INT2,
            .intPriority = (~0),
            .rxDMAChannelIndex = DMA_CH3_EUSCIA1RX,
            .txDMAChannelIndex = DMA_CH2_EUSCIA1TX,
            .clkPin = SPIMSP432DMA_P2_5_UCA1CLK,
            .simoPin = SPIMSP432DMA_P2_6_UCA1SIMO,
            .somiPin = SPIMSP432DMA_P2_7_UCA1SOMI,
            .stePin = SPIMSP432DMA_P2_3_UCA1STE,
            .pinMode = EUSCI_SPI_4PIN_UCxSTE_ACTIVE_LOW,
            .minDmaTransferSize = 10
        },
        {
            .baseAddr = EUSCI_B2_BASE,
            .bitOrder = EUSCI_B_SPI_MSB_FIRST,
            .clockSource = EUSCI_B_SPI_CLOCKSOURCE_SMCLK,
            .defaultTxBufValue = 0,
            .dmaIntNum = INT_DMA_INT3,
            .intPriority = (~0),
            .rxDMAChannelIndex = DMA_CH5_EUSCIB2RX0,
            .txDMAChannelIndex = DMA_CH4_EUSCIB2TX0,
            .clkPin = SPIMSP432DMA_P3_5_UCB2CLK,
            .simoPin = SPIMSP432DMA_P3_6_UCB2SIMO,
            .somiPin = SPIMSP432DMA_P3_7_UCB2SOMI,
            .stePin = SPIMSP432DMA_P2_4_UCB2STE,
            .pinMode = EUSCI_SPI_4PIN_UCxSTE_ACTIVE_LOW,
            .minDmaTransferSize = 10
        }
    };
    
    const SPI_Config SPI_config[MSP_EXP432P4111_SPICOUNT] = {
        {
            .fxnTablePtr = &SPIMSP432DMA_fxnTable,
            .object = &spiMSP432DMAObjects[MSP_EXP432P4111_SPIB0],
            .hwAttrs = &spiMSP432DMAHWAttrs[MSP_EXP432P4111_SPIB0]
        },
        {
            .fxnTablePtr = &SPIMSP432DMA_fxnTable,
            .object = &spiMSP432DMAObjects[MSP_EXP432P4111_SPIB2],
            .hwAttrs = &spiMSP432DMAHWAttrs[MSP_EXP432P4111_SPIB2]
        },
        {
            .fxnTablePtr = &SPIMSP432DMA_fxnTable,
            .object = &spiMSP432DMAObjects[MSP_EXP432P4111_SPIB3],
            .hwAttrs = &spiMSP432DMAHWAttrs[MSP_EXP432P4111_SPIB3]
        },
        {
            .fxnTablePtr = &SPIMSP432DMA_fxnTable,
            .object = &spiMSP432DMAObjects[MSP_EXP432P4111_SPIB4],
            .hwAttrs = &spiMSP432DMAHWAttrs[MSP_EXP432P4111_SPIB4]
        }
    };
    
    const uint_least8_t SPI_count = MSP_EXP432P4111_SPICOUNT;
    
    /*
     *  =============================== Timer ===============================
     */
    #include <ti/drivers/Timer.h>
    #include <ti/drivers/timer/TimerMSP432.h>
    
    TimerMSP432_Object timerMSP432Objects[MSP_EXP432P4111_TIMERCOUNT];
    
    const TimerMSP432_HWAttrs timerMSP432HWAttrs[MSP_EXP432P4111_TIMERCOUNT] = {
        /* Timer32_0 */
        {
            .timerBaseAddress = TIMER32_0_BASE,
            .clockSource = TIMER_A_CLOCKSOURCE_SMCLK,
            .intNum = INT_T32_INT1,
            .intPriority = ~0
        },
        {
            .timerBaseAddress = TIMER32_1_BASE,
            .clockSource = TIMER_A_CLOCKSOURCE_SMCLK,
            .intNum = INT_T32_INT2,
            .intPriority = ~0
        },
        /* Timer_A1 */
        {
            .timerBaseAddress = TIMER_A1_BASE,
            .clockSource = TIMER_A_CLOCKSOURCE_ACLK,
            .intNum = INT_TA1_0,
            .intPriority = ~0
        },
        /* Timer_A2 */
        {
            .timerBaseAddress = TIMER_A2_BASE,
            .clockSource = TIMER_A_CLOCKSOURCE_ACLK,
            .intNum = INT_TA2_0,
            .intPriority = ~0
        },
        /* Timer_A3 */
        {
            .timerBaseAddress = TIMER_A3_BASE,
            .clockSource = TIMER_A_CLOCKSOURCE_ACLK,
            .intNum = INT_TA3_0,
            .intPriority = ~0
        }
    };
    
    const Timer_Config Timer_config[MSP_EXP432P4111_TIMERCOUNT] = {
        {
            .fxnTablePtr = &TimerMSP432_Timer32_fxnTable,
            .object = &timerMSP432Objects[MSP_EXP432P4111_TIMER_T32_0],
            .hwAttrs = &timerMSP432HWAttrs[MSP_EXP432P4111_TIMER_T32_0]
        },
        {
            .fxnTablePtr = &TimerMSP432_Timer32_fxnTable,
            .object = &timerMSP432Objects[MSP_EXP432P4111_TIMER_T32_1],
            .hwAttrs = &timerMSP432HWAttrs[MSP_EXP432P4111_TIMER_T32_1]
        },
        {
            .fxnTablePtr = &TimerMSP432_Timer_A_fxnTable,
            .object = &timerMSP432Objects[MSP_EXP432P4111_TIMER_TA_1],
            .hwAttrs = &timerMSP432HWAttrs[MSP_EXP432P4111_TIMER_TA_1]
        },
        {
            .fxnTablePtr = &TimerMSP432_Timer_A_fxnTable,
            .object = &timerMSP432Objects[MSP_EXP432P4111_TIMER_TA_2],
            .hwAttrs = &timerMSP432HWAttrs[MSP_EXP432P4111_TIMER_TA_2]
        },
        {
            .fxnTablePtr = &TimerMSP432_Timer_A_fxnTable,
            .object = &timerMSP432Objects[MSP_EXP432P4111_TIMER_TA_3],
            .hwAttrs = &timerMSP432HWAttrs[MSP_EXP432P4111_TIMER_TA_3]
        }
    };
    
    const uint_least8_t Timer_count = MSP_EXP432P4111_TIMERCOUNT;
    
    /*
     *  =============================== UART ===============================
     */
    #include <ti/drivers/UART.h>
    #include <ti/drivers/uart/UARTMSP432.h>
    
    UARTMSP432_Object uartMSP432Objects[MSP_EXP432P4111_UARTCOUNT];
    unsigned char uartMSP432RingBuffer[MSP_EXP432P4111_UARTCOUNT][32];
    
    /*
     * The baudrate dividers were determined by using the MSP432 baudrate
     * calculator
     * http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSP430BaudRateConverter/index.html
     */
    const UARTMSP432_BaudrateConfig uartMSP432Baudrates[] = {
        /* {baudrate, input clock, prescalar, UCBRFx, UCBRSx, oversampling} */
        {
            .outputBaudrate = 115200,
            .inputClockFreq = 24000000,
            .prescalar = 13,
            .hwRegUCBRFx = 0,
            .hwRegUCBRSx = 37,
            .oversampling = 1
        },
        {115200, 12000000,  6,  8,  32, 1},
        {115200, 6000000,   3,  4,   2, 1},
        {115200, 3000000,   1, 10,   0, 1},
        {9600,   24000000, 156,  4,   0, 1},
        {9600,   12000000, 78,  2,   0, 1},
        {9600,   6000000,  39,  1,   0, 1},
        {9600,   3000000,  19,  8,  85, 1},
        {9600,   32768,     3,  0, 146, 0}
    };
    
    const UARTMSP432_HWAttrsV1 uartMSP432HWAttrs[MSP_EXP432P4111_UARTCOUNT] = {
        {
            .baseAddr = EUSCI_A0_BASE,
            .intNum = INT_EUSCIA0,
            .intPriority = (~0),
            .clockSource = EUSCI_A_UART_CLOCKSOURCE_SMCLK,
            .bitOrder = EUSCI_A_UART_LSB_FIRST,
            .numBaudrateEntries = sizeof(uartMSP432Baudrates) /
                                  sizeof(UARTMSP432_BaudrateConfig),
            .baudrateLUT = uartMSP432Baudrates,
            .ringBufPtr = uartMSP432RingBuffer[MSP_EXP432P4111_UARTA0],
            .ringBufSize = sizeof(uartMSP432RingBuffer[MSP_EXP432P4111_UARTA0]),
            .rxPin = UARTMSP432_P1_2_UCA0RXD,
            .txPin = UARTMSP432_P1_3_UCA0TXD
        },
        {
            .baseAddr = EUSCI_A2_BASE,
            .intNum = INT_EUSCIA2,
            .intPriority = (~0),
            .clockSource = EUSCI_A_UART_CLOCKSOURCE_SMCLK,
            .bitOrder = EUSCI_A_UART_LSB_FIRST,
            .numBaudrateEntries = sizeof(uartMSP432Baudrates) /
                                  sizeof(UARTMSP432_BaudrateConfig),
            .baudrateLUT = uartMSP432Baudrates,
            .ringBufPtr = uartMSP432RingBuffer[MSP_EXP432P4111_UARTA2],
            .ringBufSize = sizeof(uartMSP432RingBuffer[MSP_EXP432P4111_UARTA2]),
            .rxPin = UARTMSP432_P3_2_UCA2RXD,
            .txPin = UARTMSP432_P3_3_UCA2TXD
        }
    };
    
    const UART_Config UART_config[MSP_EXP432P4111_UARTCOUNT] = {
        {
            .fxnTablePtr = &UARTMSP432_fxnTable,
            .object = &uartMSP432Objects[MSP_EXP432P4111_UARTA0],
            .hwAttrs = &uartMSP432HWAttrs[MSP_EXP432P4111_UARTA0]
        },
        {
            .fxnTablePtr = &UARTMSP432_fxnTable,
            .object = &uartMSP432Objects[MSP_EXP432P4111_UARTA2],
            .hwAttrs = &uartMSP432HWAttrs[MSP_EXP432P4111_UARTA2]
        }
    };
    
    const uint_least8_t UART_count = MSP_EXP432P4111_UARTCOUNT;
    
    /*
     *  =============================== Watchdog ===============================
     */
    #include <ti/drivers/Watchdog.h>
    #include <ti/drivers/watchdog/WatchdogMSP432.h>
    
    WatchdogMSP432_Object watchdogMSP432Objects[MSP_EXP432P4111_WATCHDOGCOUNT];
    
    const WatchdogMSP432_HWAttrs
        watchdogMSP432HWAttrs[MSP_EXP432P4111_WATCHDOGCOUNT] = {
        {
            .baseAddr = WDT_A_BASE,
            .intNum = INT_WDT_A,
            .intPriority = (~0),
            .clockSource = WDT_A_CLOCKSOURCE_SMCLK,
            .clockDivider = WDT_A_CLOCKDIVIDER_8192K
        }
    };
    
    const Watchdog_Config Watchdog_config[MSP_EXP432P4111_WATCHDOGCOUNT] = {
        {
            .fxnTablePtr = &WatchdogMSP432_fxnTable,
            .object = &watchdogMSP432Objects[MSP_EXP432P4111_WATCHDOG],
            .hwAttrs = &watchdogMSP432HWAttrs[MSP_EXP432P4111_WATCHDOG]
        }
    };
    
    const uint_least8_t Watchdog_count = MSP_EXP432P4111_WATCHDOGCOUNT;
    
    /*
     *  =============================== WiFi ===============================
     *
     * This is the configuration structure for the WiFi module that will be used
     * as part of the SimpleLink SDK WiFi plugin. These are configured for SPI mode.
     */
    #include <ti/drivers/net/wifi/porting/MSP432WIFI.h>
    
    const WIFIMSP432_HWAttrsV1 wifiMSP432HWAttrs =
    {
        .spiIndex = MSP_EXP432P4111_SPIB0,
        .hostIRQPin = MSP_EXP432P4111_HOST_IRQ,
        .nHIBPin = MSP_EXP432P4111_nHIB_pin,
        .csPin = MSP_EXP432P4111_CS_pin,
        .maxDMASize = 1024,
        .spiBitRate = 3000000
    };
    
    const uint_least8_t WiFi_count = 1;
    
    const WiFi_Config WiFi_config[1] =
    {
        {
            .hwAttrs = &wifiMSP432HWAttrs,
        }
    };
    

  • Thanks Chris, I will try to reproduce your results and provide feedback.

    Best,

    Pere

  • Hi Pere,

    Did this get resolved?

    Todd

    [9/24 Update: Marking this as TI Thinks Resolved due to no activity from original poster.]