I think it's very important that the user not have to recompile or download branches in order to use these modules. The individual sensor settings should be configured in a text file that is uploaded via GCS. It should be something that can be explained in a simply, for which we could indeed offer several configuration files for commonly used I2C sensors. Otherwise, the average user will simply feel overwhelmed by the process.
This is my idea for working with generic sensor reading:
//Generic I2C addressing
if( i2cStep == WAIT_STATE_0 ){
// Block for WAIT_DELAY_0 [ms].
xDelay = WAIT_DELAY_0 / portTICK_RATE_MS;
vTaskDelay(xDelay);
}
else if( i2cStep == WAIT_STATE_1 ){
// Block for WAIT_DELAY_1 [ms].
xDelay = WAIT_DELAY_1 / portTICK_RATE_MS;
vTaskDelay(xDelay);
}
else if( i2cStep == WAIT_STATE_2 ){
// Block for WAIT_DELAY_2 [ms].
xDelay = WAIT_DELAY_2 / portTICK_RATE_MS;
vTaskDelay(xDelay);
}
else if ( i2cStep == WAIT_STATE_3 ){
// Block for WAIT_DELAY_3 [ms].
xDelay = WAIT_DELAY_3 / portTICK_RATE_MS;
vTaskDelay(xDelay);
}
else if (pass==FIRST_PASS){
if ( i2cStep == CONFIG_REG_0 ){
GenericI2CSetConfig(0, 0, 0, 0, 0);
}
else if ( i2cStep == CONFIG_REG_1 ){
GenericI2CSetConfig(0, 0, 0, 0, 0);
}
else if ( i2cStep == CONFIG_REG_2 ){
GenericI2CSetConfig(0, 0, 0, 0, 0);
}
else if ( i2cStep == CONFIG_REG_3 ){
GenericI2CSetConfig(0, 0, 0, 0, 0);
}
}
else{
if ( i2cStep == WRITE_REG_0 ){
WriteGenericRegisters(0x00, NUM_REGISTERS_WRITE_REG_0, bufferTemp);
}
else if ( i2cStep == WRITE_REG_1 ){
WriteGenericRegisters(0x00, NUM_REGISTERS_WRITE_REG_1, bufferTemp);
}
else if ( i2cStep == READ_REG_0 ){
ReadGenericRegisters(0x00, NUM_REGISTERS_READ_REG_0, bufferTemp);
decipherGenericI2Cresponse(bufferTemp, 0, 0, 0, 0);
}
else if ( i2cStep == READ_REG_1 ){
ReadGenericRegisters(0x00, NUM_REGISTERS_READ_REG_1, bufferTemp);
decipherGenericI2Cresponse(bufferTemp, 0, 0, 0, 0);
}
}
(Don't mind all the 0's, they're just placeholders so that it compiles correctly and doesn't complain.)
This is just a rough sketch that shows where I'd like to go with this. My idea is that there are likely only a fixed number of different wait times likely to occur with any given I2C chip. For instance, the HMC5883 requires an initial 8.3 ms wait, and then after that 67.7 ms wait cycles between reads.
After that, there will be a vector of i2cStep values which states which order things will be followed. So it might say to WRITE_REG, then WAIT_STATE_3, then READ_REG, then WAIT_STATE_4, then loop back to the beginning of the vector to start over again. This gives a lot of flexibility, although at the expense of RAM (which is in short supply on the CC).
So, in the interests of having a concrete example, let's assume that we're using the HMC5883. The Operational Examples on pg. 18 show that the chip can be configured by
- Waiting 0.0083 [s]
- Writing 0x02 0x00
- Waiting 0.067 [s]
- Reading
- Clocking out 6 bytes
WAIT_DELAY_0=9; //in ms, rounded up WAIT_DELAY_1=68; //in ms, rounded up CONFIG_REG_0=0x02; CONFIG_REG_1=0x00; NUM_REGISTERS_READ_REG_0=6;
And then you create the initial "flat" vector...:
firstPassVector={WAIT_STATE_0, CONFIG_REG_0, CONFIG_REG_1};
and then the "loop" vector:
loopVector={WAIT_STATE_1, READ_REG_0};
Thoughts? Especially for how to reduce RAM consumption to a minimum?
P.S. Yeah, there's a bug in the fact that I'm calling CONFIG_REG_0 and giving it a value, too. It's too late for me to fix it, but tomorrow I'll certainly add some sort of VALUE_CONFIG_REG_0 to fix it)
P.S.S. There's a second bug in the way waits are implemented, it should likely be vTaskDelayUntil()



Luxembourg
United States
Australia







