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.

CC1350STK: Sensor Controller I2C together with Task code I2C

Part Number: CC1350STK
Other Parts Discussed in Thread: HDC1000, CC1310

Hi.

I am trying to communicate to BMP280 sensor in CC1350STK. 
I have code in Sensor Controller that successfully reads Pressure data from the sensor and reports raw data back to application.

In the application, I would like to read the ID from the sensor before enabling the task, and also some I2C registers that holds calibration values that are later needed for calculations.
However, when I use I2C_open() and then I2C_close() before enabling the task, I see that the task does not wakes the CPU (probably does not running). When I remove the  I2C_open() and I2C_close() code, the task wakes the CPU every X seconds as configured.

Is there a way to use the I2C in the task, then disable it before calling scifStartTasksNbl() for a SensorController task that also uses I2C??

  • You write "when I use I2C_open() and then I2C_close() before enabling the task", are you here referring to the SCE task? Could you please provide some code showing where you place the I2C_open()/ I2C_close() in relation with the rest of the code.
  • Task Code (after BIOS_Start()):

        I2C_Handle      i2c;
        I2C_Params      i2cParams;
    
        /* Configure the LED pin */
     //   GPIO_setConfig(Board_GPIO_LED0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    
        /* Create I2C for usage */
        I2C_Params_init(&i2cParams);
        i2cParams.bitRate = I2C_400kHz;
    
        i2c = I2C_open(Board_I2C_TMP, &i2cParams);
        if (i2c == NULL) {
            return;
        }
    
        if (hdc1000_detect(i2c) == HDC1000_STATUS_FAILED) {
             ...
        } else {
            ...
        }
    
        I2C_cancel(i2c);
        I2C_close(i2c);
    
        Sce_start();
    }

    Initialization Code (before BIOS_Start()):

    Sce_init(0x00010000, 1, 1);
    Sce_registerAdcCallback(SceCallback);

    When I comment out all I2C code in Task Code, data arrives from Sensor Controller task. When the code is as presented, no data arrives. My Sensor Controller task also uses same I2C bus.
    Is there a way to use the bus before calling Sce_start(); and then release it for the Sensor Controller task?

  • Just to be sure: The I2C code you have before sce_start() works as intended?
  • Yes. Checked it and it works. I can read ID from I2C device in hdc1000_detect() but then no data from SCE task.
    If I remove all I2C code and only leave Sce_start() then I see data arrive.
    Is there anything else need to be done except I2C_cancel() and I2C_close() to release the I2C bus for SCE task?
  • Could you check to see if the bug in the I2C driver covered here: e2e.ti.com/.../2646582 is relevant in your case?
  • Closing this thread due to inactivity.
  • Hi.
    Sorry for long delay, this was on hold for sometime but now it is needed again.
    I tried doing what the post says: adding I2CCC26XX.c and changing those lines but that did not help.
    The code before sce_start() does work good (all the detections) but then no data from sensor controller task.
    If I comment out all this I2C code before sce_start() then the data arrives all the time.

    Thank you...
  • I have to clarify something:

    You write "Task Code (after BIOS_Start())":

    I assume that your code look something like this:

    int main(void)
    {
        /* Call driver init functions. */
        Board_initGeneral();
        Display_init();
    
        /* Initialize sensor node tasks */
        
    
        /* Start BIOS */
        BIOS_start();
    
        return (0);
    }

    and that the code you are giving is given in a task? Is it possible to post a more complete code to show what you are doing to avoid misunderstandings.  

  • Of course....

    int main(void)
    {
        /* Call driver init functions. */
        Board_initGeneral();
    
        I2C_init();
    
        /* Clear LED pins */
        NodeRadioTask_init();
        NodeTask_init();
        data_task_init();
    
        /* Start BIOS */
        BIOS_start();
    
        return (0);
    }

    void data_task_init(void)
    {
        Sce_init(0x00010000, 1, 1);
        Sce_registerAdcCallback(SceCallback);
    }

    Then after BIOS_start() every second inside task this code is called:

       I2C_Handle      i2c;
       I2C_Params      i2cParams;
    
        /* Create I2C for usage */
        I2C_Params_init(&i2cParams);
        i2cParams.bitRate = I2C_400kHz;
    
        i2c = I2C_open(Board_I2C_TMP, &i2cParams);
        if (i2c == NULL) {
            return;
        }
    
        if (hdc1000_detect(i2c) == HDC1000_STATUS_FAILED) {
             ...
        } else {
            ...
        }
    
        I2C_cancel(i2c);
        I2C_close(i2c);
    
        Sce_start();
    }

  • From your original post I got the impression you wanted to read out some details from the sensor before you started the SCE.

    But from this last piece of code indicate that you are trying to access the sensor every second using the I2C driver and at the same time trying to access the sensor using I2C using the SCE.

    Why not read all the data you need either using SCE or the I2C driver, why are you trying to do both?
  • I want to read data ONCE in the task (not SCE task) so I can read device ID, calibration values etc...
    Then I want to release the I2C bus in the task and start the SCE task which periodically uses the I2C bus (every second).
  • Ok, but why do you have a task today that uses the I2C driver once a second? From my point of view it looks like you haven't implemented the code the same way as you say how you want the code to work.
  • Why not? The code that initializes I2C, checks ID and starts the SCE task is called only once after a successful connection to concentrator happens.
    If that connection stops, than SCE task is stopped and no one is accessing the I2C, when the connection will re-establish this code might be called once again, so I think this is implemented ok.

    I also do want to read the ID every time before I start the SCE task, because maybe one of the sensors has failed, so I don't want to read garbage value.
    I have tried moving the I2C code of reading ID's to before BIOS_start(), but it is hanges in i2c_transfer().

    Is it possible to read the I2C bus, release it, then start the SCE task??

  • Hi TER,

    looks to me that using CC1310 LP and Sensors BP I would be able to recreate MoonDrop concepts.
    Could you confirm the h/w above would be enough?

    If yes, on Mon. I should be able to help fixing this post.
  • MoonDrop :
    "I also do want to read the ID every time": Why not do this from SCE and get the main application to stop the SCE task if the sensor for some reason is dead?

    "I have tried moving the I2C code of reading ID's to before BIOS_start()": BIOS_start() starts and active different clocks required