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.

LAUNCHXL-CC3235SF: Can't enter Low Power mode after SlNetIfWifi_getConnectionStatus() is called

Part Number: LAUNCHXL-CC3235SF
Other Parts Discussed in Thread: CC3235SF

Hi folks,

I've been using the power_measurement example that comes with SimpleLink SDK and noticed that when I introduce a call to SNTP_getTime() the device doesn't seem to enter the low power state I expect. This one is most definitely a trap that I have fallen into and I assume I am missing something pretty basic here. 

How do I maintain an Ultra Low Power state, assuming the TCP stack is kept on the Network Processor and the MCU only needs to wakeup to handle network events behind the TCP stack? I get the same outcome with FreeRTOS or TIRTOS, to illustrate this and with using SL_WLAN_IOT_LOW_POWER_POLICY:

Without the call to SNTP_getTime()I get 640uA, which is great:

 

Adding a call to SNTP_getTime() and successfully receiving network time (graph after time sync is received, now 60mA steady):


 

Any pointers appreciated.

 

EDIT TO ORIGINAL POST: Please see further below, after investigating it appears a call to SlNetIfWifi_getConnectionStatus() creates this situation.

 

Regards,

Will.

 

  • Hi Will,

    My initial thought here is that after you get the time you should be able to go back to sleep. Are you sure you're enabling the power policy after you're done?

    Jesu

  • Thanks,

    That's exactly right, I've got this just after the call to time sync:

        while (1) {
            Power_enablePolicy();
            sleep(10);
        }
    

    Is the device falling back to some other default power config? Even explicitly calling the power config with SL_WLAN_IOT_LOW_POWER_POLICY doesn't do anything.

    What am I missing?

  • <Bump> ....

    This issue is pretty straightforward to repro, I am attaching the projects that replicates this case under CCS10, containing both power_measurement_CC3235SF_LAUNCHXL_tirtos_ccs and tirtos_builds_CC3235SF_LAUNCHXL_release_ccs as a dependency.

    I have imported the power measurement project straight from simplelink_cc32xx_sdk_4_10_00_07, and inserted a call to time sync. As I was debugging I ended up importing source/ti/net/sntp/sntp.c in this project (has no bearing on the outcome if you link with source/ti/net/sntp/lib/ccs/m4/sntp_release.a regardless).

    To reproduce (adjust WiFi credentials first):

    - Comment out the call to SNTP_getTime() line 1423 in power_measure.c. Compile and load onto CC3235SF LaunchPad, great, we see microAmps.

    - Add SNTP_getTime() line 1423 in power_measure.c. Compile and load onto CC3235SF LaunchPad. The SoC no longer enters Ultra Low Power mode and operates in the tens of milliamps range - I must stress, this is measured after successfully getting time and looping around Power_enablePolicy() / sleep().

    What is causing this please, why isn't the device able to fall back to the originally set Power Policy?

    Regards,
    Will.

    power_measurement_CC3235SF_LAUNCHXL_no_low_power-small.tar.gz

  • Hi Will,

    I cannot see your code as I'm not working on a Linux machine. Could you confirm you're SNTP_getTime is returning with the time? The current you're seeing indicates to me the NWP remains active on RX. Maybe the NWP stays stuck waiting to hear a response from the server? If SNTP_getTime is indeed working I will need to take a deeper look. getTime closes the socket after it's done so it should not be causing the NWP to remain active. 

    Please confirm and provide code in zip format if the problem persist.

    Jesu

  • @Jesu,

    I believe the OP and follow ups should answer your queries, did I miss something?

    "Adding a call to SNTP_getTime() and successfully receiving network time (graph after time sync is received, now 60mA steady)"

    "I must stress, this is measured after successfully getting time and looping around Power_enablePolicy() / sleep()."

    I am sorry you were unable to unpack the files, please find them re-attached to this post.

    To also clarify, SNTP_getTime()illustrates this issue but it isn't in and of itself the cause. A single call to SlNetUtil_getHostByName() is sufficient to demonstrate this case, or paired calls to SlNetSock_create() / SlNetSock_close() as per SNTP_getTime() internally.

    Regards,
    Will.

    power_measurement_CC3235SF_LAUNCHXL_tirtos_ccs-resend.zip

  • To further elaborate on this, and by reading and tracing through the SimpleLink SDK, this call is made in the chain:

    SlNetIfWifi_getConnectionStatus(NULL);

    which in turn calls

     sl_WlanGet(SL_WLAN_CONNECTION_INFO, &Opt, &Size, (uint8_t *)&connectionParams);

    which ultimately causes the device to never re-enter Low Power.

    By experimenting and by-passing the call for getting connection status and 'hacking" as follows, I can get the device to enter and maintain its lowest WiFi connected power state:

    int32_t _getConnectionStatus(void *ifContext) {
        UART_PRINT("Hacking connection is good");
    
        return 1;
    }
    
    ....
    
    SlNetIfConfigWifi.ifGetConnectionStatus = _getConnectionStatus;
    

    Can you please provide some insight as to why this is and, how to correctly proceed if I am not using the SDK appropriately.

    Thanks.

  • Hi WIll,

    I apologize for the delay. I had some trouble getting your example up and running. It seems that the project properties (e.g. linker and include options) were not present. As an alternative, I tried testing this with the tcpechotls example that calls startSNTP. I figured it would be easier to include Power.h and call Power_enablePolicy than to deal with all the file transfer, linker includes... etc of adding SNTP functionality to the power_measurement example. Needless to say I was not able to reproduce your behavior. The device seemed to have entered LPDS after startSNTP returned. I've attached my file if it helps. The changes I made were very simple to the example. 

    Where does the sl_WlanGet call originate from on the application side? If you are just looping sleep and enable policy calls after startSNTP I can't imagine where sl_WlanGet would be getting called from. 

    On a side note... I'm going to be out of the office for the next 2 weeks so I will not be able to get back to you. I will let one of my team members know of this thread.

    Jesu

  • Hi Jesu,

    Regarding your query, see prior post details. Please trace the SDK calls for SNTP_getTime(), landing on SlNetUtil_getHostByName() and so forth as detailed above. Again, SNTP_getTime() is not at fault but it will allow you to replicate this case by observing which underlying call creates the condition.

    Sadly, we don't see your zip file attached. Still, we imported tcpechotls_CC3235SF_LAUNCHXL_tirtos_ccs in CCS10. No project settings were changed. We edited startsntp.c to insert a power policy as SL_WLAN_IOT_LOW_POWER_POLICY with 300ms intervals and paused execution just after time sync is received. Please see the source file attached which you can copy and paste into your own project.

    /*
     * 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.
     */
    
    #include <time.h>
    #include <unistd.h>
    
    #include <ti/display/Display.h>
    #include <ti/net/sntp/sntp.h>
    
    #include <ti/net/slnetif.h>
    #include <ti/net/slnetutils.h>
    #include <ti/net/slnetsock.h>
    #include <ti/net/slnet.h>
    #include <ti/drivers/net/wifi/slnetifwifi.h>
    
    
    #include <ti/drivers/Power.h>
    
    
    #define TIME_BASEDIFF        ((((uint32_t)70 * 365 + 17) * 24 * 3600))
    #define TIME_NTP_TO_LOCAL(t) ((t) - TIME_BASEDIFF)
    
    #define NTP_SERVERS 1
    #define NTP_SERVER_PORT 123
    
    /*  Time to wait for reply from server (seconds) */
    #define NTP_REPLY_WAIT_TIME 5
    
    /* Must wait at least 15 sec to retry NTP server (RFC 4330) */
    #define NTP_POLL_TIME 15
    
    extern Display_Handle display;
    
    /*
     *  ======== startSNTP ========
     */
    void startSNTP(void)
    {
        uint64_t ntpTimeStamp;
        uint32_t currentTime;
        int32_t retval = 0;
        time_t ts;
        SlNetSock_Timeval_t timeval;
        struct timespec tspec;
    
        /* Set timeout value for NTP server reply */
        timeval.tv_sec = NTP_REPLY_WAIT_TIME;
        timeval.tv_usec = 0;
    
    
        SlWlanPmPolicyParams_t PmPolicyParams;
        memset(&PmPolicyParams, 0, sizeof(SlWlanPmPolicyParams_t));
        PmPolicyParams.MaxSleepTimeMs = 300;
    
        int ret = sl_WlanPolicySet(SL_WLAN_POLICY_PM,
                               SL_WLAN_IOT_LOW_POWER_POLICY,
                               (uint8_t *) &PmPolicyParams,
                               sizeof(PmPolicyParams));
        if (ret < 0)
        {
            Display_printf(display, 0, 0,
                          " Could not set  SL_WLAN_LONG_SLEEP_INTERVAL_POLICY, err=%d", ret);
        }
    
    
        do {
            /* Get the time use the built in NTP server list: */
            retval = SNTP_getTime(NULL, 0, &timeval, &ntpTimeStamp);
            if (retval != 0) {
                Display_printf(display, 0, 0,
                    "startSNTP: couldn't get time (%d), will retry in %d secs ...",
                    retval, NTP_POLL_TIME);
                Power_enablePolicy();
                sleep(NTP_POLL_TIME);
                Display_printf(display, 0, 0, "startSNTP: retrying ...");
            }
            currentTime = ntpTimeStamp >> 32;
    
            currentTime = TIME_NTP_TO_LOCAL(currentTime);
        } while (retval < 0);
    
    
        while(1) {
            Power_enablePolicy();
            Display_printf(display, 0, 0,
                    "Just after SNTP, measure....\n\r", ctime(&ts));
            sleep(2);
        }
    
    
        tspec.tv_nsec = 0;
        tspec.tv_sec = currentTime;
        if (clock_settime(CLOCK_REALTIME, &tspec) != 0) {
            Display_printf(display, 0, 0,
                    "startSNTP: Failed to set current time\n");
            while(1);
        }
    
        ts = time(NULL);
        Display_printf(display, 0, 0,
                "startSNTP: Current time: %s\n\r", ctime(&ts));
    
    
    }
    

    By using tcpechotls_CC3235SF_LAUNCHXL_tirtos_ccs and using the file attached above:

    - Comment out SNTP_getTime() line 97 in startsntp.c, we get 733uA - fantastic:

    - Add SNTP_getTime() line 97 in startsntp.c, now >60mA steady:

    DUT:


    With regards to:

     The device seemed to have entered LPDS after startSNTP returned

    How did you confirm that the device did enter its lowest WiFi Connected power state? Could you please post your own measurements back as per steps above?

    Best Regards,
    Will.

  • Is someone from TI looking into this please?

  •  ,  : apologies for the tags. You both commented on another thread for this hardware. It'd be great if we can make some progress on this after a couple weeks now


    Are you able to confirm / disprove SlNetIfWifi_getConnectionStatus() call breaks low power / not for you?

    hopefully not and you can point out what we might have wrong here?
    thanks so much in advance

  • Hi Will,

    I am sorry, I am not able to help you with this issue.

    bwt... I don't see any reason why use API (SlNetIfWifi_getConnectionStatus()). Because all information you can have already from asynchronous events.

    btw2 ... I am not a TI employee

    Jan

  • Indeed,  we can't also see why this call seems to create this situation and it would be good to get some feedback from TI on this. Thanks heaps .

  • Ti, , can we have your attention on this please.

    The exact steps to repro are posted above, please share your own findings and measurements with workaround/fix.

  • Hey Will,

    Very sorry for the delay. I recently got back into the office. I will look into this and get back to you before the end of the day. 

    Jesu

  • Hi Will,

    Like I said before I could not reproduce your steps (refer to previous comments) when running the tcpechotls example. Unfortunately I don't have access to power measurement due to COVID-19 but I can confirm I'm entering low power mode because the debugger disconnects. You can test this yourself by importing the tcpechotls example and replacing the tcpechoTLS.c file with the one attached.

    Jesu

    /*
     * Copyright (c) 2017-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.
     */
    
    /*
     *    ======== tcpEchoTLS.c ========
     */
    
    #include <string.h>
    #include <stdint.h>
    #include <unistd.h>
    
    #include <time.h>
    #include <pthread.h>
    
    /* BSD support */
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <sys/socket.h>
    
    #include <ti/net/slnetsock.h>
    #include <ti/net/slnetif.h>
    #include <ti/drivers/Power.h>
    
    #include <ti/display/Display.h>
    
    /* TI-DRIVERS Header files */
    #include "ti_drivers_config.h"
    
    /* Example/Board Header file */
    #include "certs/certificate.h"
    
    /* Secure object names */
    #define ROOT_CA_CERT_FILE     "DummyCA"
    #define PRIVATE_KEY_FILE      "DummyKey"
    #define TRUSTED_CERT_FILE     "DummyTrustedCert"
    
    #define TCPPACKETSIZE 256
    #define NUMTCPWORKERS 2
    
    extern Display_Handle display;
    
    extern void startSNTP(void);
    extern void *TaskCreate(void (*pFun)(), char *Name, int Priority,
            uint32_t StackSize, uintptr_t Arg1, uintptr_t Arg2, uintptr_t Arg3);
    
    /*
     *  ======== tcpWorker ========
     *  Task to handle TCP connection. Can be multiple Tasks running
     *  this function.
     */
    void tcpWorker(uint32_t arg0, uint32_t arg1)
    {
        int  clientFd = (int)arg0;
        int  bytesRcvd;
        int  bytesSent;
        char buffer[TCPPACKETSIZE];
    
        Display_printf(display, 0, 0, "tcpWorker: start clientFd = 0x%x\n",
                clientFd);
    
        while ((bytesRcvd = recv(clientFd, buffer, TCPPACKETSIZE, 0)) > 0) {
            bytesSent = send(clientFd, buffer, bytesRcvd, 0);
            if (bytesSent < 0 || bytesSent != bytesRcvd) {
                Display_printf(display, 0, 0, "send failed.\n");
                break;
            }
        }
        Display_printf(display, 0, 0, "tcpWorker stop clientFd = 0x%x\n", clientFd);
    
        close(clientFd);
    }
    
    /*
     *  ======== tcpHandler ========
     *  Creates new Task to handle new TCP connections.
     */
    void tcpHandler(uint32_t arg0, uint32_t arg1)
    {
        void *             thread = NULL;
        int                status = 0;
        int                clientFd;
        int                serverFd;
        uint16_t           clientSd;
        uint16_t           serverSd;
        socklen_t          sdlen = sizeof(serverSd);
        struct sockaddr_in localAddr;
        struct sockaddr_in clientAddr;
        int                optval;
        int                optlen = sizeof(optval);
        socklen_t          addrlen = sizeof(clientAddr);
        SlNetSockSecAttrib_t *secAttribHdl = NULL;
    
        Display_printf(display, 0, 0, "TCP Echo TLS example started\n");
    
        /*  Use SNTP to get the current time, as needed for SSL authentication */
        startSNTP();
    
    
        while(1){
            sleep(5);
            Power_enablePolicy();
        }
    
        serverFd = socket(AF_INET, SOCK_STREAM, 0);
        if (serverFd == -1) {
            Display_printf(display, 0, 0, "tcpHandler: socket failed\n");
            goto shutdown;
        }
    
    //    Power_enablePolicy();
    
        status = SlNetIf_loadSecObj(SLNETIF_SEC_OBJ_TYPE_CERTIFICATE,
                ROOT_CA_CERT_FILE, strlen(ROOT_CA_CERT_FILE), srvCAPem,
                srvCAPemLen, SLNETIF_ID_1);
        status |= SlNetIf_loadSecObj(SLNETIF_SEC_OBJ_TYPE_CERTIFICATE,
                TRUSTED_CERT_FILE, strlen(TRUSTED_CERT_FILE), srvCertPem,
                srvCertPemLen, SLNETIF_ID_1);
        status |= SlNetIf_loadSecObj(SLNETIF_SEC_OBJ_TYPE_RSA_PRIVATE_KEY,
                PRIVATE_KEY_FILE, strlen(PRIVATE_KEY_FILE)-1, srvKeyPem,
                srvKeyPemLen, SLNETIF_ID_1);
        if(status < 0) {
            Display_printf(display, 0, 0, "tcpHandler: failed to load objects\n");
            goto shutdown;
        }
    
        if (getsockopt(serverFd, SLNETSOCK_LVL_SOCKET, SLNETSOCK_OPSOCK_SLNETSOCKSD,
                &serverSd, &sdlen) < 0) {
            Display_printf(display, 0, 0, "tcpHandler: getsockopt failed\n");
            goto shutdown;
        }
    
        secAttribHdl = SlNetSock_secAttribCreate();
        /*status |= SlNetSock_secAttribSet(secAttribHdl,
                SLNETSOCK_SEC_ATTRIB_PEER_ROOT_CA, ROOT_CA_CERT_FILE,
                sizeof(ROOT_CA_CERT_FILE));*/
        status |= SlNetSock_secAttribSet(secAttribHdl,
                SLNETSOCK_SEC_ATTRIB_PRIVATE_KEY, PRIVATE_KEY_FILE,
                sizeof(PRIVATE_KEY_FILE));
        /* Setting up a chain (root set first) */
      /*  status |= SlNetSock_secAttribSet(secAttribHdl,
                SLNETSOCK_SEC_ATTRIB_LOCAL_CERT, ROOT_CA_CERT_FILE,
                sizeof(ROOT_CA_CERT_FILE));*/
        status |= SlNetSock_secAttribSet(secAttribHdl,
                SLNETSOCK_SEC_ATTRIB_LOCAL_CERT, TRUSTED_CERT_FILE,
                sizeof(TRUSTED_CERT_FILE));
    
        status |= SlNetSock_startSec(serverSd, secAttribHdl,
                SLNETSOCK_SEC_BIND_CONTEXT_ONLY | SLNETSOCK_SEC_IS_SERVER);
        if(status < 0) {
            Display_printf(display, 0, 0,
                    "tcpHandler: startSec failed to bind context\n");
            goto shutdown;
        }
    
        memset(&localAddr, 0, sizeof(localAddr));
        localAddr.sin_family = AF_INET;
        localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
        localAddr.sin_port = htons(arg0);
    
        status = bind(serverFd, (struct sockaddr *)&localAddr, sizeof(localAddr));
        if (status == -1) {
            Display_printf(display, 0, 0, "tcpHandler: bind failed\n");
            goto shutdown;
        }
    
        status = listen(serverFd, NUMTCPWORKERS);
        if (status == -1) {
            Display_printf(display, 0, 0, "tcpHandler: listen failed\n");
            goto shutdown;
        }
    
        optval = 1;
        if (setsockopt(serverFd, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0) {
            Display_printf(display, 0, 0, "tcpHandler: setsockopt failed\n");
            goto shutdown;
        }
    
        while ((clientFd =
                accept(serverFd, (struct sockaddr *)&clientAddr, &addrlen)) != -1) {
    
            Display_printf(display, 0, 0,
                    "tcpHandler: Creating thread clientFd = %x\n", clientFd);
    
            if (getsockopt(clientFd, SLNETSOCK_LVL_SOCKET,
                    SLNETSOCK_OPSOCK_SLNETSOCKSD,
                    &clientSd, &sdlen) < 0) {
                Display_printf(display, 0, 0, "tcpHandler: getsockopt failed\n");
                goto shutdown;
            }
    
            status = SlNetSock_startSec(clientSd, secAttribHdl,
                    SLNETSOCK_SEC_START_SECURITY_SESSION_ONLY |
                    SLNETSOCK_SEC_IS_SERVER);
            if(status < 0) {
                Display_printf(display, 0, 0,
                        "tcpHandler: startSec failed to start session\n");
                goto shutdown;
            }
    
            thread = TaskCreate(tcpWorker, NULL, 3, 2048, (uintptr_t) clientFd,
                    0, 0);
    
            if (!thread) {
                Display_printf(display, 0, 0,
                        "tcpHandler: Error - Failed to create new Task.\n");
                close(clientFd);
            }
    
            /* addrlen is a value-result param, must reset for next accept call */
            addrlen = sizeof(clientAddr);
        }
    
        Display_printf(display, 0, 0, "tcpHandler: accept failed.\n");
    
    shutdown:
        if (serverFd != -1) {
            close(serverFd);
        }
        if (secAttribHdl != NULL) {
            SlNetSock_secAttribDelete(secAttribHdl);
        }
    }
    

  • Thanks,

    I think you are misunderstanding.

    The board does enter LPDS initially but it is later, when further calls are made, which we've described at length, that power consumption jumps - and remains forever high. The JTAG disconnection is by no means an indicator.

    How can we progress this please?

    Regards,
    Will.

  • Hi Will,

    I was able to get my hands on some power measurement HW to run my test with more certainty and I can confirm I'm getting sub 1mA current after enabling the power policy when startSNTP returns. May I suggest you try working with the code I attached? I'm not getting the behavior you describe with startSNTP. 

    Jesu

  • Hi ,

    I don't believe your code was shared with us. I am reposting the steps here for your convenience, with a video to demonstrate the case.

    1- Import tcpechotls_CC3235SF_LAUNCHXL_tirtos_ccs, do not change any project settings

    2- Add this file to the project which only adds SL_WLAN_IOT_LOW_POWER_POLICY and checkpoints for current measurements: 

    /*
     * 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.
     */
    
    #include <time.h>
    #include <unistd.h>
    
    #include <ti/display/Display.h>
    #include <ti/net/sntp/sntp.h>
    
    #include <ti/net/slnetif.h>
    #include <ti/net/slnetutils.h>
    #include <ti/net/slnetsock.h>
    #include <ti/net/slnet.h>
    #include <ti/drivers/net/wifi/slnetifwifi.h>
    
    
    #include <ti/drivers/Power.h>
    
    
    #define TIME_BASEDIFF        ((((uint32_t)70 * 365 + 17) * 24 * 3600))
    #define TIME_NTP_TO_LOCAL(t) ((t) - TIME_BASEDIFF)
    
    #define NTP_SERVERS 1
    #define NTP_SERVER_PORT 123
    
    /*  Time to wait for reply from server (seconds) */
    #define NTP_REPLY_WAIT_TIME 5
    
    /* Must wait at least 15 sec to retry NTP server (RFC 4330) */
    #define NTP_POLL_TIME 15
    
    extern Display_Handle display;
    
    /*
     *  ======== startSNTP ========
     */
    void startSNTP(void)
    {
        uint64_t ntpTimeStamp;
        uint32_t currentTime;
        int32_t retval = 0;
        time_t ts;
        SlNetSock_Timeval_t timeval;
        struct timespec tspec;
    
        /* Set timeout value for NTP server reply */
        timeval.tv_sec = NTP_REPLY_WAIT_TIME;
        timeval.tv_usec = 0;
    
    
        SlWlanPmPolicyParams_t PmPolicyParams;
        memset(&PmPolicyParams, 0, sizeof(SlWlanPmPolicyParams_t));
        PmPolicyParams.MaxSleepTimeMs = 300;
    
        int ret = sl_WlanPolicySet(SL_WLAN_POLICY_PM,
                               SL_WLAN_IOT_LOW_POWER_POLICY,
                               (uint8_t *) &PmPolicyParams,
                               sizeof(PmPolicyParams));
        if (ret < 0)
        {
            Display_printf(display, 0, 0,
                          " Could not set  SL_WLAN_LONG_SLEEP_INTERVAL_POLICY, err=%d", ret);
        }
    
        Power_enablePolicy();
    
        Display_printf(display, 0, 0,
                "Power policy enabled, pausing for 10s to show you Low Current OK < 1mA...\n\r", ctime(&ts));
    
        sleep(10);
    
        do {
            /* Get the time use the built in NTP server list: */
            retval = SNTP_getTime(NULL, 0, &timeval, &ntpTimeStamp);
            if (retval != 0) {
                Display_printf(display, 0, 0,
                    "startSNTP: couldn't get time (%d), will retry in %d secs ...",
                    retval, NTP_POLL_TIME);
                Power_enablePolicy();
                sleep(NTP_POLL_TIME);
                Display_printf(display, 0, 0, "startSNTP: retrying ...");
            }
            currentTime = ntpTimeStamp >> 32;
    
            currentTime = TIME_NTP_TO_LOCAL(currentTime);
        } while (retval < 0);
    
    
        Display_printf(display, 0, 0,
                "Just after SNTP, Low Power broken forever > 10mA !!! \n\r", ctime(&ts));
    
        while(1) {
            Power_enablePolicy();
            sleep(2);
        }
    
    
        tspec.tv_nsec = 0;
        tspec.tv_sec = currentTime;
        if (clock_settime(CLOCK_REALTIME, &tspec) != 0) {
            Display_printf(display, 0, 0,
                    "startSNTP: Failed to set current time\n");
            while(1);
        }
    
        ts = time(NULL);
        Display_printf(display, 0, 0,
                "startSNTP: Current time: %s\n\r", ctime(&ts));
    
    
    }
    

    3- Run and observe power draw in the 10s pause before call to SNTP, and then after.

    Here's the video: drive.google.com/.../view

    Can you share with us where you are measuring power draw from, and what SDK / Service Pack you are using. Here is ours:

    This is using simplelink_cc32xx_sdk_4_10_00_07, service pack sp_4.6.0.1_3.1.0.5_3.1.0.25.bin. Our board is RevA, Version details:

             ==============================================
             CHIP: 0x31100019
             MAC:  3.1.0.5
             PHY:  3.1.0.25
             NWP:  4.6.0.1
             ROM:  8738
             HOST: 3.0.1.61
  • Hi Will,

    Interested, non-TI, bystander here working on a project which also intends to use LPDS so I've been subscribed to this thread for a while.

    Out of interest, I know the original report with SNTP_GetTime() says that call successfully returns, but does the alternative trigger SlNetIfWifi_getConnectionStatus() also return suggesting it's the mere act of calling it which stops LPDS bein re-entered, and which might mean other calls have a similar effect. Or does execution stop within it?

    Back when it was SNTP_GetTime(), were you doing anything with the obtained time?

    Cheers, Ralph.

  • Hey Ralph,

    Sure,  as you say, just calling SlNetIfWifi_getConnectionStatus() seems to break Low Power, but I haven't investigated it any further. It's non-blocking and returns fine from what I have seen. It's unclear to me if other calls might have a similar effect. What I can say however and, even with the hack I posted earlier in this thread, logging the power draw over time shows it jumps up in the tens of milliamps for minutes at a time and then settles back down, even if the NWP holds a connection fine and no reconnect or network activity takes place. I can't see why this is.

    The cut down example above for TI to repro doesn't do anything with the time that is returned from SNTP, we want it to be as basic as can be to demonstrate it. Obviously the real firmware we are working on does use it, but as you can appreciate that's a moot point right now as Low Power doesn't work for us.

    Keen to see if you can share your experience.

    Cheers,
    Will.

  • Hi ,


    Do you have any comments regarding the repro steps and video posted above?

    What do you suggest so this can be progressed?

    Regards,
    Will.

  • Hey Will,

    I could finally reproduce the issue here. Not sure what I was doing differently before but oddly with the same test I get ~63mA on average. It seems like even when sleep is called the NWP stays awake which causes the current to remain high. Image below shows start up then sleep current after SNTP returns.

    I'm in the process of capturing some NWP logs to see what could be going wrong and working with some teammates in the background to identify the root cause.

    Jesu

  • Hi Jesu,

    Thanks for sharing your findings, I really appreciate the feedback.

    Let me know what we can do to help, happy to assist.

    Regards,
    Will.

  • Hey Will,

    I have good news. I was able to find the root cause and a solution that I verified via power measurement. Turns out sl_WlanGet in SlNetIfWifi_getConnectionStatus was causing some memory issues that we addressed via service pack. The service pack will be released in our next CC32XX SDK which should be coming out in the next week or two. Sorry for the delay.

    Jesu

  • That's great news, thanks Jesu.

    Would it be possible to share the service pack for testing on our end before it is officially released, that would be great?

    Regards,
    Will.

  • Hi Will,

    Let me respond to you privately on E2E. I will send you a friend request.

    Jesu

  • Hi ,

    Any chance of a test Service Pack please? What is the ETA on an SDK release?

    Regards,
    Will. 

  • Hey Will,

    The SDK was released last Friday. Download link below:

    https://www.ti.com/tool/download/SIMPLELINK-CC32XX-SDK

    The landing page lags a bit.

    Good luck!

    Jesu