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.

CC1310: Waking up the CPU using the Sensor Controller

Part Number: CC1310

I would like to put the CPU into Standby, then wake it up using the Sensor Controller, say when a threshold hits a level.

I'm not seeing any examples related to waking up the CPU from Standby using the Sensor Controller. I looked in SimpleLink, but didn't see anything. Are there any out there? 

Thanks

  • The «Multi Channel ADC Sampling» code example will use the fwGenQuickAlertInterrupt(); to wake up the CPU.

    This resource allows the task code running on the Sensor Controller to generate an ALERT callback via the SCIF driver to the application running on the System CPU. If the System CPU is sleeping at that time, it will wake up.

    The application code is pending on a semaphore:

    // Wait for an ALERT callback
    Semaphore_pend(Semaphore_handle(&semScTaskAlert), BIOS_WAIT_FOREVER);
    

    Which will be posted in the Task Alert Callback:

    void scTaskAlertCallback(void) {
    
        // Wake up the OS task
        Semaphore_post(Semaphore_handle(&semScTaskAlert));
    
    } // taskAlertCallback
    

    Siri

  • Thank you. Does the Semaphore_pend call out the CPU into Standby?

    if no, would I call Semaphore_pend the. sleep() ?

  • Semaphores are used to control access to a common resource. They can be used for task synchronization and mutual exclusion. It is not pending on the semaphore itself that makes the device enter standby, but when using TI-RTOs and our power driver, the system will go to standby and stay there if no other tasks are running. That is why normally the system is not explicitly set in standby but let TI-RTOS do it.

    In the example I referred to nothing else is going on while pending on the semaphore, so the device will enter standby, and it will not wake up until the semaphore is posted (in the interrupt, generated by the sensor controller).

    To learn more about the Power driver, and TI-RTOS in general, I recommend you to look at our power driver documentations and the SLAs we have for TI-RTOS:

    https://dev.ti.com/tirex/explore/node?node=ALJuvum8Y71exvwoPdK5-g__pTTHBmu__LATEST

    https://dev.ti.com/tirex/explore/node?node=AJ5GKtlWu9o0mNaNx6ItPQ__pTTHBmu__LATEST

  • Thank you. If the system is in Standby because of a sleep() call, can the Sensor Controller wake up the CPU? If so, how is that done?

  • You set the interrupt the exact same way from the sensor controller.

    Siri

  • Thank you, but I'm not clear on what I should do to wake up from a sleep() call. When the Sensor Controller issues an alert, what function should I call to wake up of the CPU? I assume it is something like Event_pend().

    I am looking at Event_pend / Event_post, but Event_pend is blocking, so it wouldn't seem to make sense to call sleep(), but I would like to use sleep()..

  • Not easy to give specific advice as I do not know how you want your application to run (other than the fact that the sensor controller should wake it from Standby).

    Assume you have a sensor controller task that runs x times a second, and the only thing it does it to check a digital input pin, and if it 0, it will generate an interrupt.

    The code could look something like this:

    U16 inputLevel = 1;
    
    gpioGetInputValue(AUXIO_I_DIO1_INPUT_PIN; inputLevel);
    
    if (inputLevel == 0) {
        fwGenAlertInterrupt();
    } 
    
    // Schedule the next execution
    fwScheduleTask(1);
    

    On the application side you can do something like this:

    void scTaskAlertCallback(void)
    {
        ExecuteSomeCode(A);
    
        // Clear the ALERT interrupt source
        scifClearAlertIntSource();
    
        // Acknowledge the ALERT event
        scifAckAlertEvents();
    }
    
    void *mainThread(void *arg0)
    {
        hPin = PIN_open(&pinState, LedPinTable);
    
        //Initializes the OSAL
        scifOsalInit();
    
        // Registers the task ALERT interrupt callback
        scifOsalRegisterTaskAlertCallback(scTaskAlertCallback);
    
        // Initializes the driver
        scifInit(&scifDriverSetup);
    
        // Set the Sensor Controller sample interval (sample 10 times a second)
        scifStartRtcTicksNow(0x00010000 / 10);
    
        // Start the sensor Controller
        scifStartTasksNbl((1 << (SCIF_MONITOR_BUTTON_TASK_ID)));
    
        while(1)
        {
            sleep(5);
    
            ExecuteSomeCode(B);
        }
    }
    

    In this case, Code B will be executed once every 5 s, and Code A will be executed every time the SC generates an interrupt:

    Another option is to use a semaphore like this:

    void scTaskAlertCallback(void)
    {
        ExecuteSomeCode(A);
    
        // Clear the ALERT interrupt source
        scifClearAlertIntSource();
    
        // Acknowledge the ALERT event
        scifAckAlertEvents();
    
        Semaphore_post(scsSemaphoreHandle);
    }
    
    void *mainThread(void *arg0)
    {
        hPin = PIN_open(&pinState, LedPinTable);
    
        Semaphore_construct(&scsSemaphore, 0, NULL);
        scsSemaphoreHandle = Semaphore_handle(&scsSemaphore);
    
    
        //Initializes the OSAL
        scifOsalInit();
    
        // Registers the task ALERT interrupt callback
        scifOsalRegisterTaskAlertCallback(scTaskAlertCallback);
    
        // Initializes the driver
        scifInit(&scifDriverSetup);
    
        // Set the Sensor Controller sample interval (sample 10 times a second)
        scifStartRtcTicksNow(0x00010000 / 10);
    
        // Start the sensor Controller
        scifStartTasksNbl((1 << (SCIF_MONITOR_BUTTON_TASK_ID)));
    
        while(1)
        {
            Semaphore_pend(scsSemaphoreHandle, BIOS_WAIT_FOREVER);
    
            ExecuteSomeCode(B);
        }
    }
    

    The device will be in standby “forever” (BIOS_WAIT_FOREVER) and wake up and execute Code A in the ISR when woken up by the SC. Since the semaphore is posted in the ISR, Code B will be executed, and then the device will get back to standby.

    A third solution is to replace the BIOS_WAIT_FOREVER with a timeout (for example 5 s)

    Semaphore_pend(scsSemaphoreHandle, 500000);
    

    Code B will then execute every 5 s, and also after an interrupt has occurred (and Code A has been executed):

    BR

    Siri

  • Thank you, that is very helpful.

    You said, "Assume you have a sensor controller task that runs x times a second". We were hoping to avoid polling. Is there another way to wake up the CPU using the sensor controller or something else where we don't poll periodically? I don't think so, but I want to make sure before I move on.

    Also, when the Sensor Controller is in low power mode, what is the expected power consumption? Where is this documented?

    Thank you

  • I do not understand your comment/question “Is there another way to wake up the CPU using the sensor controller or something else where we don't poll periodically?”

    You have not said anything regarding what you are going to use the sensor controller for so I simply made an example there the sensor controller runs x times a second, checking a GPIO, and if the GPIO is at a certain state, I generate an interrupt.

    If you are using the sensor controller, I guess that is because you need the sensor controller to do some stuff (read some sensor etc), and this should be done at a given rate.

    You need to write your own sensor controller code, where you implement the tasks that you want the SC to do, and then you can wake up the CPU the way I have showed in my examples.

    If you are not going to use the sensor controller for anything, you should wake your application on an external interrupt instead.

    For current consumption, please see

    https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/795464/cc2640r2f-power-consumption-of-sensor-controller

  • Let me try again. We want to put the CPU into Standby and wake it up when VDD rises above a certain level. My understanding from your earlier information is we can use the Sensor Controller to periodically have the ADC sample the voltage and wake up the CPU when it is above a certain level.

    Is that the only way to solve that problem, or is there another way?

  • No, you can use the sensor controller for that, but then you will need to configure the sensor controller to sample the ADC at a given rate, just as I in my program configured the Sensor controller to sample a GPIO at a certain rate.

    It was your comment regarding avoid polling that I did not understand. The only "polling" is the sensor controller "polling" some sensors (or for example the ADC). I do not understand what polling you want to avoid.

    Siri

  • I understand. I cannot find a function prototype or source code for fwGenAlertInterrupt()

    I'm getting an undefined symbol error on it. I've looked in the SCS documentation and online, but I haven't seen anything about where it is located. Any help you can offer would be appreciated.

  • if you search the Help View you will find it and see that it is documented under the System CPU Alert Section:

    Enable System CPU Alert:

    It will then pop up under "Available procedures"

  • Thank you, but I had already done that. I can see fwGenAlertInterrupt in the Available procedures list. However, I am still getting this error:

    "../txDataBroadcast.c", line 3112: warning #225-D: function "fwGenAlertInterrupt" declared implicitly
    Finished building: "../txDataBroadcast.c"

    Building target: "test10sec_implant_tirtos_ccs55.out"
    Invoking: Arm Linker
    "C:/ti/ccs1040/ccs/tools/compiler/ti-cgt-arm_20.2.5.LTS/bin/armcl" -mv7M3 --code_state=16 --float_support=none -me --define=DeviceFamily_CC13X0 -g --diag_warning=225 --diag_warning=255 --diag_wrap=off --display_error_number --gen_func_subsections=on -z -m"test10sec_implant_tirtos_ccs55.map" -i"C:/ti/simplelink_cc13x0_sdk_4_10_01_01/source" -i"C:/ti/simplelink_cc13x0_sdk_4_10_01_01/kernel/tirtos/packages" -i"C:/ti/ccs1040/ccs/tools/compiler/ti-cgt-arm_20.2.5.LTS/lib" --diag_wrap=off --display_error_number --warn_sections --xml_link_info="test10sec_implant_tirtos_ccs55_linkInfo.xml" --rom_model -o "test10sec_implant_tirtos_ccs55.out" "./CC1310_LAUNCHXL.obj" "./CC1310_LAUNCHXL_fxns.obj" "./PowerCC26XX_tirtos.obj" "./bmp3_over_i2c.obj" "./ccfg.obj" "./eeprom_over_i2c.obj" "./rtc_over_i2c.obj" "./scif.obj" "./scif_framework.obj" "./scif_osal_tirtos.obj" "./txDataBroadcast.obj" "./smartrf_settings/smartrf_settings.obj" "../cc13x0f128.cmd" -l"ti/display/lib/display.aem3" -l"ti/grlib/lib/ccs/m3/grlib.a" -l"third_party/spiffs/lib/ccs/m3/spiffs_cc26xx.a" -l"ti/drivers/rf/lib/rf_multiMode_cc13x0.aem3" -l"ti/drivers/lib/drivers_cc13x0.aem3" -l"ti/dpl/lib/dpl_cc13x0.aem3" -l"C:/Users/as/workspace_v10/tirtos_builds_CC1310_LAUNCHXL_release_ccs/Debug/configPkg/linker.cmd" -l"ti/devices/cc13x0/driverlib/bin/ccs/driverlib.lib" -llibc.a
    <Linking>

    undefined first referenced
    symbol in file
    --------- ----------------
    fwGenAlertInterrupt ./txDataBroadcast.obj

    This is a list of the files I am copying from the SCS project's source directory to my CCS project directory:

    scif.h and .c

    scif_framework.h and .c

    scif_osal_tirtos.h and .c

    Are there any other files I should copy from the SCS project's source directory or from anywhere else? Is there a pre-built SCS driver file?

    Thank you

  • fwGenAlertInterrupt is for the Sensor Controller code, not the code you run on the cortex. When you issue the fwGenAlertInterrupt you trigger an callback on the cortex side, see below

    See how this is used in the "ADC Window Monitor" example 

  • Ok, I understand now. Thank you.