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.

RTOS/CC1350: I2C writes fail after 'CPU Reset' but not after 'Board Reset'

Part Number: CC1350

Tool/software: TI-RTOS

In the firmware for my system, based on the WSN  DM Sensor Node example, I have created a new file to control any sensors since it was getting a bit cluttered in the main task.

In this file there is a function, sensorCtrl_init() which is there to initialise the I2C, pins, interrupts, and SCE tasks. The sensor related clocks are initialised in a different function, sensorCtrl_clkInit(), which is called from NodeTask_init() since I was getting a HWI exception when doing it from NodeTaskFunction(). I believe that is to be expected though.

I've noticed something unusual with my regular sensorCtrl_init() function. It seems like it will happily perform the sensor I2C setup transactions the first time I debug the code, but will fail if I pause, hit CPU reset, and run again. If I instead use the dropdown in CCS to choose 'board reset' I don't  have the same problem. 

I'm concerned that this will be in issue if for any the device needs to perform a reset of itself. How do I avoid this happening? My init function code is below:

void sensorCtrl_init(void)
{

    // Initialise interrupt pin
    pinHandle = PIN_open(&pinState, sensorPinTable);
    if (!pinHandle)
    {
        System_abort("Int pin init error");
    }

    // Initialise interrupt pin callbacks
    if (PIN_registerIntCb(pinHandle, &accIntCb) != 0)
    {
        System_abort("Int register error");
    }

    // Initialise I2C
    I2C_Params_init(&i2cParams);
    i2cParams.bitRate = I2C_400kHz;
    i2c = I2C_open(Board_I2C_TMP, &i2cParams);
    if (i2c == NULL) {
        System_abort("I2C open error");
    }

    // initialise I2C sensors
    i2cWrite(LIS3DH_REG_CTRL1, LIS3DH_ODR_25HZ | LIS3DH_Z_EN | LIS3DH_X_EN | LIS3DH_Y_EN);
    //i2cWrite(LIS3DH_REG_CTRL2, 0x00 | 0x00); // HFP mode (2b) | cutoff (2b)
    i2cWrite(LIS3DH_REG_CTRL3, 0x10);
    i2cWrite(LIS3DH_REG_CTRL4, 0x08); // HR mode

    // Accel. interrupt setup
    i2cWrite(LIS3DH_REG_INT1THS, 20);
    i2cWrite(LIS3DH_REG_INT1DUR, 1);
    i2cWrite(LIS3DH_REG_INT1CFG, ZHIE);

    i2cRead(LIS3DH_REG_OUT_Z_L | LIS3DH_MUTLIREAD, 2);

    int16_t z_accel = (rxBuffer[0] ) | (rxBuffer[1] << 8);

    // Close the I2C while it's not in use
    // Peripheral doesn't need to run to receive device pin interrupts - re-open it when an accelerometer int. is generated
    I2C_close(i2c);

    // Initialize the Sensor Controller
    scifOsalInit();
    scifOsalRegisterCtrlReadyCallback(scCtrlReadyCallback);
    scifOsalRegisterTaskAlertCallback(scTaskAlertCallback);
    scifInit(&scifDriverSetup);

    // Set the Sensor Controller task tick interval
    uint32_t rtc_Hz = 120;  // xHz RTC
    scifStartRtcTicksNow(0x00010000 / rtc_Hz);

}
void i2cWrite(uint8_t reg, uint8_t value)
{
    uint8_t txBuffer[2] = {reg, value};
    i2cTransaction.slaveAddress = LIS3DH_DEFAULT_ADDRESS;
    i2cTransaction.writeBuf = txBuffer;
    i2cTransaction.writeCount = 2;
    i2cTransaction.readBuf = NULL;
    i2cTransaction.readCount = 0;

    uint8_t status = I2C_transfer(i2c, &i2cTransaction);

    if (!status) {
        System_abort("I2C write fail");
    }
}

  • Hey Craig,

    The CPU reset option does not reinitialize the entire system. It is recommended to use Board Reset then hit Restart to jump to main when you want to reset the device and start over.
  • Hi Brocklobsta,

    I sort of figured that's what was happening based on the error. From the perspective of a system resetting itself, say with a watchdog or fault handler or something, are there different levels of software-triggered reset that will have to be considered to ensure that error isn't self-inflicted when the system is deployed and running?