Closed joshgalvan closed 8 months ago
Hi Josh (@joshgalvan ),
I think you might be the first person to ask about FSYNC...
All I can say is:
So, it may be a question of wading through the datasheet:
The FSYNC_CONFIG register and bits are defined. Likewise for DELAY_TIME and its bits.
I hope this helps. Please send us a Pull Request if you get this going!
Best wishes, Paul
Thank you for the insight!
I've implemented everything and have assured that I am correctly setting the FSYNC_CONFIG register with 0b1000_0000, but am unable to gather the delay time from DELAY_TIMEH and DELAY_TIMEL.
In my main loop I raise my FSYNC pin for 1ms, then lower it, then once there is data (via myICM.dataReady()
), I try to print it with:
ICM_20948_Status_e ICM_20948::readFSYNCDelay(uint16_t *read) {
status = ICM_20948_get_delay(&_device, read);
return status;
}
ICM_20948_Status_e ICM_20948_get_delay(ICM_20948_Device_t *pdev, uint16_t *delay) {
ICM_20948_Status_e retval = ICM_20948_Stat_Ok;
uint8_t delay_h;
uint8_t delay_l;
if (delay == NULL) {
return ICM_20948_Stat_ParamErr;
}
ICM_20948_set_bank(pdev, 0);
retval = ICM_20948_execute_r(pdev, AGB0_REG_DELAY_TIMEH, &delay_h, 1);
if (retval != ICM_20948_Stat_Ok) {
return retval;
}
retval = ICM_20948_execute_r(pdev, AGB0_REG_DELAY_TIMEL, &delay_l, 1);
if (retval != ICM_20948_Stat_Ok) {
return retval;
}
pdev->_delay_h = delay_h;
pdev->_delay_l = delay_l;
*delay = (uint16_t)(delay_h << 8) | delay_l;
return retval;
}
I'm not trying to use FSYNC as an interrupt and I can't seem to find anything else to configure to collect the delay properly.
This is my setup()
and loop()
:
void setup()
{
SERIAL_PORT.begin(115200);
while (!SERIAL_PORT)
{
};
WIRE_PORT.begin();
WIRE_PORT.setClock(400000);
pinMode(FSYNC, INPUT);
//myICM.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
bool initialized = false;
while (!initialized)
{
myICM.begin(WIRE_PORT, AD0_VAL);
myICM.enableFSYNCDetection();
SERIAL_PORT.print(F("Initialization of the sensor returned: "));
SERIAL_PORT.println(myICM.statusString());
if (myICM.status != ICM_20948_Stat_Ok)
{
SERIAL_PORT.println("Trying again...");
delay(500);
}
else
{
initialized = true;
}
}
// uint8_t fsync_config;
// myICM.readFSYNCConfig(&fsync_config);
// SERIAL_PORT.print("fsync_config: ");
// SERIAL_PORT.println(fsync_config, BIN); // prints 10000000
// while (1) {
// delay(10);
// }
}
void loop()
{
digitalWrite(FSYNC, HIGH);
delay(1);
digitalWrite(FSYNC, LOW);
if (myICM.dataReady())
{
myICM.readFSYNCDelay(&fs_delay);
myICM.getAGMT(); // The values are only updated when you call 'getAGMT'
// printRawAGMT( myICM.agmt ); // Uncomment this to see the raw values, taken directly from the agmt structure
printScaledAGMT(&myICM); // This function takes into account the scale settings from when the measurement was made to calculate the values with units
Serial.println(fs_delay);
Serial.println(myICM._device._delay_l); // Yes I made _device public to print it easier
Serial.println(myICM._device._delay_h);
delay(30);
}
else
{
SERIAL_PORT.println("Waiting for data");
delay(500);
}
}
The GPIO I'm using to assert the FSYNC pin on the ICM is going through a level shifter, so I'm going to check that everything is working there next, but just wanted some insight on if you think this is good.
It was an issue with the level shifter, everything works. I don't exactly have time to do a full PR for the FSYNC code but this is what I wrote:
ICM_20948_Status_e ICM_20948::enableFSYNCDetection(bool enable) {
ICM_20948_FSYNC_CONFIG_t reg;
status = ICM_20948_fsync_config(&_device, NULL, ®);
if (status != ICM_20948_Stat_Ok) {
return status;
}
reg.DELAY_TIME_EN = enable;
status = ICM_20948_fsync_config(&_device, ®, NULL);
if (status != ICM_20948_Stat_Ok) {
return status;
}
ICM_20948_INT_PIN_CFG_t int_reg;
status = ICM_20948_int_pin_cfg(&_device, NULL, &int_reg); // read phase
if (status != ICM_20948_Stat_Ok)
{
return status;
}
int_reg.ACTL_FSYNC = 0;
int_reg.FSYNC_INT_MODE_EN = 1;
status = ICM_20948_int_pin_cfg(&_device, &int_reg, NULL); // write phase
if (status != ICM_20948_Stat_Ok)
{
return status;
}
return status;
}
ICM_20948_Status_e ICM_20948::readFSYNCDelay(uint16_t *computed_time) {
uint8_t delay_h;
uint8_t delay_l;
status = ICM_20948_get_delay(&_device, &delay_h, &delay_l);
if (status != ICM_20948_Stat_Ok) {
return status;
}
// From datasheet @ 8.17: Delay time in us = (DELAY_TIMEH * 256 + DELAY_TIMEL) * 0.9645
*computed_time = (delay_h * 256 + delay_l) * 0.9645;
return status;
}
And then in C backbone:
ICM_20948_Status_e ICM_20948_fsync_config(ICM_20948_Device_t *pdev, ICM_20948_FSYNC_CONFIG_t *write, ICM_20948_FSYNC_CONFIG_t *read) {
ICM_20948_Status_e retval = ICM_20948_Stat_Ok;
retval = ICM_20948_set_bank(pdev, 2); // Must be in the right bank
if (write != NULL) {
retval = ICM_20948_execute_w(pdev, AGB2_REG_FSYNC_CONFIG, (uint8_t *)write, sizeof(ICM_20948_FSYNC_CONFIG_t));
if (retval != ICM_20948_Stat_Ok) {
return retval;
}
}
if (read != NULL) {
retval = ICM_20948_execute_r(pdev, AGB2_REG_FSYNC_CONFIG, (uint8_t *)read, sizeof(ICM_20948_FSYNC_CONFIG_t));
if (retval != ICM_20948_Stat_Ok) {
return retval;
}
}
return retval;
}
ICM_20948_Status_e ICM_20948_get_delay(ICM_20948_Device_t *pdev, uint8_t *delay_h, uint8_t *delay_l) {
ICM_20948_Status_e retval = ICM_20948_Stat_Ok;
if (delay_h == NULL || delay_l == NULL) {
return ICM_20948_Stat_ParamErr;
}
retval = ICM_20948_set_bank(pdev, 0);
if (retval != ICM_20948_Stat_Ok) {
return retval;
}
// Read high byte
retval = ICM_20948_execute_r(pdev, AGB0_REG_DELAY_TIMEH, delay_h, 1);
if (retval != ICM_20948_Stat_Ok) {
return retval;
}
// Read low byte
retval = ICM_20948_execute_r(pdev, AGB0_REG_DELAY_TIMEL, delay_l, 1);
if (retval != ICM_20948_Stat_Ok) {
return retval;
}
return retval;
}
I've also written functions to modify and read GYRO_CONFIG_1 and GYRO_SMPLRT_DIV because the FSYNC delay is the time between your pulse to the FSYNC pin and the next gyro ODR, so reading and configuring the gyro is helpful.
Hello!
I can't seem to find the ability to get the FSYNC delay from a gyro event (I'm pretty sure gyro is the only sensor that can output an FSYNC delay timestamp), and I also don't see anywhere to enable FSYNC.
Would you mind pointing me in the right direction within the library to get this working?
Thank you!