This thread has been locked.

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

CCS/CC1310: TI-RTOS: Problem with Sensor Controller or Power management

Part Number: CC1310

Tool/software: Code Composer Studio

Hello.

There was an inexplicable problem for me with the Sensor Controller.

Briefly about the problem - Incorrect measurement results are periodically read.

Briefly about the program. The sensor controller reads the TDC from the pins. A modified example for taken as a basis in SCS - cap_touch_ulpsense (Capasitive Touch).

The main program initializes the RTC channel 1, for accurate samples of the 75ms interval. Initializes the RF core and sensor controller. In the main loop, the sensor controller program is launched, data that is read by the interrupt scTaskAlertCallback is expected. After this mainSemaphore is expected in the main cycle and after 75 ms everything repeats.

In this case, incorrect data is observed.

  

   1..2..1... is incorrect

But if, before starting the sensor controller, insert any RF command (e.g. RF_cmdNop) and immediately send it to sleep RF_yield, then the sensor controller starts issuing the correct values at each start. I don’t understand this situation at all !!!  

Because calling the RF core from sleep causes increased power consumption.

How can I make the sensor sensor work properly without calling RF _yield ???

/*
 *  ======== empty.c ========
 */

/* For usleep() */
#include <unistd.h>
#include <stdint.h>
#include <stddef.h>
#include "scif.h"
#include "xRf.h"


#include <ti/sysbios/knl/Semaphore.h>
#include <ti/sysbios/knl/Event.h>
#include <ti/sysbios/BIOS.h>
#include <xdc/runtime/Error.h>
#include <ti/devices/DeviceFamily.h>
#include DeviceFamily_constructPath(driverlib/interrupt.h)
#include DeviceFamily_constructPath(driverlib/aon_rtc.h)
#include DeviceFamily_constructPath(driverlib/aon_event.h)
#include DeviceFamily_constructPath(driverlib/sys_ctrl.h)


void RTC_IRQ_Config(void);
void scInit(void);
void scRunOnes(void);

#define     CLOCK_75MS      75
#define     _1_MS_VALUE_    0x40

uint32_t    period_wakeup = (CLOCK_75MS * _1_MS_VALUE_);
uint32_t    rtc_now;

// --- Semaphore ---
Semaphore_Handle mainSemaphore;

uint16_t    rawdata[8];
Semaphore_Handle scSemaphore;


// !!! if uncomment, data from SC normalize
#define NORMAL_DATA_1

/*
 *  ======== mainThread ========
 */
void *mainThread(void *arg0)
{
    // main semaphore for wakeup
    Semaphore_Params params;
    Semaphore_Params_init(&params);
    params.mode = Semaphore_Mode_BINARY;
    mainSemaphore = Semaphore_create(0, &params, Error_IGNORE);

    // init CH1 RTC for my wakeup
    RTC_IRQ_Config();

    //init RF
    RF_openRadio();

    // Init Sensocontroller
    scInit();

    //--- main loop ---
    while (1) {

        scRunOnes();

        Semaphore_pend(mainSemaphore, BIOS_WAIT_FOREVER );

    }
    //-----------------

}


void scTaskAlertCallback(void)
{
    // Clear the ALERT interrupt source
    scifClearAlertIntSource();

    //Access Sensor Controller task data structures here ...
    memcpy((void*)rawdata,(void*)scifTaskData.capacitiveTouch.output.raw, sizeof rawdata);

    // Acknowledge the ALERT event
    scifAckAlertEvents();

    // data ready
    Semaphore_post(scSemaphore);
}


void scRunOnes(void)
{
#ifdef NORMAL_DATA_1
    RF_runCmd(rfHandle, (RF_Op*)&RF_cmdNop, RF_PriorityNormal, 0, 0);
    RF_yield(rfHandle);
#endif

    // Reset all data structures except configuration
    scifResetTaskStructs(1 << SCIF_CAPACITIVE_TOUCH_TASK_ID, (1 << SCIF_STRUCT_INPUT) | (1 << SCIF_STRUCT_OUTPUT));

    // Start the "Capacitive Touch" Sensor Controller task
    scifExecuteTasksOnceNbl(1 << SCIF_CAPACITIVE_TOUCH_TASK_ID);

    // wait data...
    Semaphore_pend(scSemaphore,BIOS_WAIT_FOREVER);
}


void scInit(void)
{
    // for SC
    Semaphore_Params params;
    Semaphore_Params_init(&params);
    params.mode = Semaphore_Mode_BINARY;
    scSemaphore = Semaphore_create(0, &params, Error_IGNORE);

    scifOsalInit();
    scifOsalRegisterTaskAlertCallback(scTaskAlertCallback);
    // Initialize the SCIF driver
    scifInit(&scifDriverSetup);
}


void CC_RtcReChargeCompareValue()
{
    AONRTCCompareValueSet(AON_RTC_CH1, rtc_now + period_wakeup);
    SysCtrlAonSync();
}


void RTC_IRQ_Handler(void)
{
    rtc_now = AONRTCCompareValueGet(AON_RTC_CH1);
    CC_RtcReChargeCompareValue();  // recharge RTC compare value
    Semaphore_post(mainSemaphore); // wakeup main loop
}


void RTC_IRQ_Config(void)
{
    AONRTCEventClear(AON_RTC_CH1);
    AONRTCChannelEnable(AON_RTC_CH1);
    AONRTCCombinedEventConfig(AON_RTC_CH0 | AON_RTC_CH1);
    AONEventMcuWakeUpSet(AON_EVENT_MCU_WU1, AON_EVENT_RTC_CH1);
    SysCtrlAonSync();

    rtc_now = AONRTCCompareValueGet(AON_RTC_CH1);
    CC_RtcReChargeCompareValue();
}

source_codes.zip

  • Hi Igor,

    Can you confirm whether you are you using TI-RTOS or NoRTOS?

  • I am using TI-RTOS. (SimpleLink CC13x0 SDK v3.20.0.23)

  • Are you using a custom board or LaunchPad?

  • We use custom hardware, but it doesn’t matter at all, on the launchpad this problem is also reproduced.

    It depends more on the MCU itself (RTOS?) than on the custom hardware.

  • Hi Igor,

    I believe I found out what the problem is. From the TDC resource documentation in Sensor Controller Studio:

    Note that the TI-provided Power driver (used in SimpleLink SDKs for CC13xx and CC26xx devices) uses the TDC for RCOSC calibration, and that the Peripheral Sharing resource must be used to handle this safely.

    So what seems to happen is that when opening the RF driver RCOSC calibration is opted in, which will be done by the CM3 every time it returns from some low power mode. This causes both the Sensor Controller and the CM3 to use the TDC peripheral at the same time some times (very race condition-y), and hence causes very weird results depending on the timing between the two MCUs.

    The result is, as indicated by the quoted documentation, to use Peripheral Sharing in your Sensor Controller project. In your Execution Code, the following is needed to be added:

    // Acquire the TDC peripheral as it may be used by the Power driver to calibrate RCOSC.
    // This must be at the top.
    fwAcquirePeripheral(PERIPHERAL_TDC);
    
    // Enable COMPA, including 2 uA through internal 400 kOhm in parallel with external
    // 1.2 MOhm = 0.6 V reference voltage for COMPA
    compaEnableWithCapTouchRef();
    compaSelectGpioRef(AUXIO_AXS_CAP_TOUCH_REF);
    
    // ... rest of the code ...
    
    // Disable COMPA, ISRC and TDC
    tdcDisable();
    isrcDisable();
    compaDisable();
    
    // Release the TDC peripheral after we are done using it.
    fwReleasePeripheral(PERIPHERAL_TDC);
    
    fwGenAlertInterrupt();

    I was able to initially reproduce the issue with your code, and adding the peripheral sharing to the Sensor Controller code fixed the issue.

  • Thanks so much for the quick reply. It really helped.