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"); } }