drivers/optical_flow/paw3902: properly discard samples after mode change

- respect mode 2 shutter requirements from datasheet (should not operate with Shutter < 0x01F4 in Mode 2)
 - sensor reset is handled by mode change
This commit is contained in:
Daniel Agar
2021-05-02 18:39:54 -04:00
parent b1ebd16c61
commit 177ee4cbca
2 changed files with 24 additions and 48 deletions
+22 -46
View File
@@ -84,8 +84,6 @@ int PAW3902::init()
return PX4_ERROR; return PX4_ERROR;
} }
Reset();
// force to low light mode (1) initially // force to low light mode (1) initially
ChangeMode(Mode::LowLight, true); ChangeMode(Mode::LowLight, true);
@@ -150,24 +148,6 @@ bool PAW3902::DataReadyInterruptDisable()
return px4_arch_gpiosetevent(_drdy_gpio, false, false, false, nullptr, nullptr) == 0; return px4_arch_gpiosetevent(_drdy_gpio, false, false, false, nullptr, nullptr) == 0;
} }
bool PAW3902::Reset()
{
DataReadyInterruptDisable();
// Power on reset
RegisterWrite(Register::Power_Up_Reset, 0x5A);
usleep(1000);
// Read from registers 0x02, 0x03, 0x04, 0x05 and 0x06 one time regardless of the motion state
RegisterRead(Register::Motion);
RegisterRead(Register::Delta_X_L);
RegisterRead(Register::Delta_X_H);
RegisterRead(Register::Delta_Y_L);
RegisterRead(Register::Delta_Y_H);
return true;
}
void PAW3902::exit_and_cleanup() void PAW3902::exit_and_cleanup()
{ {
DataReadyInterruptDisable(); DataReadyInterruptDisable();
@@ -183,6 +163,7 @@ bool PAW3902::ChangeMode(Mode newMode, bool force)
// Issue a soft reset // Issue a soft reset
RegisterWrite(Register::Power_Up_Reset, 0x5A); RegisterWrite(Register::Power_Up_Reset, 0x5A);
px4_usleep(1000);
uint32_t interval_us = 0; uint32_t interval_us = 0;
@@ -206,6 +187,10 @@ bool PAW3902::ChangeMode(Mode newMode, bool force)
break; break;
} }
EnableLed();
_discard_reading = 3;
if (DataReadyInterruptConfigure()) { if (DataReadyInterruptConfigure()) {
// backup schedule as a watchdog timeout // backup schedule as a watchdog timeout
ScheduleDelayed(500_ms); ScheduleDelayed(500_ms);
@@ -214,17 +199,6 @@ bool PAW3902::ChangeMode(Mode newMode, bool force)
ScheduleOnInterval(interval_us); ScheduleOnInterval(interval_us);
} }
// Discard the first three motion data.
for (int i = 0; i < 3; i++) {
RegisterRead(Register::Motion);
RegisterRead(Register::Delta_X_L);
RegisterRead(Register::Delta_X_H);
RegisterRead(Register::Delta_Y_L);
RegisterRead(Register::Delta_Y_H);
}
EnableLed();
_mode = newMode; _mode = newMode;
} }
@@ -232,11 +206,6 @@ bool PAW3902::ChangeMode(Mode newMode, bool force)
_low_to_superlow_counter = 0; _low_to_superlow_counter = 0;
_low_to_bright_counter = 0; _low_to_bright_counter = 0;
_superlow_to_low_counter = 0; _superlow_to_low_counter = 0;
// Approximate Resolution = (Register Value + 1) * (50 / 8450) ≈ 0.6% of data point in Figure 19
// The maximum register value is 0xA8. The minimum register value is 0.
uint8_t resolution = RegisterRead(Register::Resolution);
PX4_DEBUG("Resolution: %X", resolution);
PX4_DEBUG("Resolution is approx: %.3f", (double)((resolution + 1.0f) * (50.0f / 8450.0f)));
return true; return true;
} }
@@ -582,9 +551,9 @@ void PAW3902::ModeSuperLowLight()
void PAW3902::EnableLed() void PAW3902::EnableLed()
{ {
// Enable LED_N controls // Enable LED_N controls
RegisterWriteVerified(0x7F, 0x14); RegisterWrite(0x7F, 0x14);
RegisterWriteVerified(0x6F, 0x1c); RegisterWrite(0x6F, 0x1c);
RegisterWriteVerified(0x7F, 0x00); RegisterWrite(0x7F, 0x00);
} }
uint8_t PAW3902::RegisterRead(uint8_t reg, int retries) uint8_t PAW3902::RegisterRead(uint8_t reg, int retries)
@@ -663,11 +632,17 @@ void PAW3902::RunImpl()
// update for next iteration // update for next iteration
_previous_collect_timestamp = timestamp_sample; _previous_collect_timestamp = timestamp_sample;
if (_discard_reading > 0) {
_discard_reading--;
ResetAccumulatedData();
return;
}
// check SQUAL & Shutter values // check SQUAL & Shutter values
// To suppress false motion reports, discard Delta X and Delta Y values if the SQUAL and Shutter values meet the condition // To suppress false motion reports, discard Delta X and Delta Y values if the SQUAL and Shutter values meet the condition
// Bright Mode, SQUAL < 0x19, Shutter ≥ 0x1FF0 // Bright Mode, SQUAL < 0x19, Shutter ≥ 0x1FF0
// Low Light Mode, SQUAL < 0x46, Shutter ≥ 0x1FF0 // Low Light Mode, SQUAL < 0x46, Shutter ≥ 0x1FF0
// Super Low Light Mode, SQUAL < 0x55, Shutter ≥ 0x0BC0 // Super Low Light Mode, SQUAL < 0x55, Shutter ≥ 0x0BC0
const uint16_t shutter = (buf.data.Shutter_Upper << 8) | buf.data.Shutter_Lower; const uint16_t shutter = (buf.data.Shutter_Upper << 8) | buf.data.Shutter_Lower;
bool data_valid = true; bool data_valid = true;
@@ -677,7 +652,6 @@ void PAW3902::RunImpl()
if ((buf.data.SQUAL < 0x19) && (shutter >= 0x1FF0)) { if ((buf.data.SQUAL < 0x19) && (shutter >= 0x1FF0)) {
// false motion report, discarding // false motion report, discarding
perf_count(_false_motion_perf); perf_count(_false_motion_perf);
ResetAccumulatedData();
data_valid = false; data_valid = false;
} }
@@ -699,7 +673,6 @@ void PAW3902::RunImpl()
if ((buf.data.SQUAL < 0x46) && (shutter >= 0x1FF0)) { if ((buf.data.SQUAL < 0x46) && (shutter >= 0x1FF0)) {
// false motion report, discarding // false motion report, discarding
perf_count(_false_motion_perf); perf_count(_false_motion_perf);
ResetAccumulatedData();
data_valid = false; data_valid = false;
} }
@@ -732,11 +705,14 @@ void PAW3902::RunImpl()
if ((buf.data.SQUAL < 0x55) && (shutter >= 0x0BC0)) { if ((buf.data.SQUAL < 0x55) && (shutter >= 0x0BC0)) {
// false motion report, discarding // false motion report, discarding
perf_count(_false_motion_perf); perf_count(_false_motion_perf);
ResetAccumulatedData();
data_valid = false; data_valid = false;
} }
if (shutter < 0x03E8) { if (shutter < 0x01F4) {
// should not operate with Shutter < 0x01F4 in Mode 2
ChangeMode(Mode::LowLight);
} else if (shutter < 0x03E8) {
// SuperLowLight -> LowLight // SuperLowLight -> LowLight
_superlow_to_low_counter++; _superlow_to_low_counter++;
+2 -2
View File
@@ -90,8 +90,6 @@ private:
void RegisterWrite(uint8_t reg, uint8_t data); void RegisterWrite(uint8_t reg, uint8_t data);
bool RegisterWriteVerified(uint8_t reg, uint8_t data, int retries = 5); bool RegisterWriteVerified(uint8_t reg, uint8_t data, int retries = 5);
bool Reset();
void EnableLed(); void EnableLed();
void ModeBright(); void ModeBright();
@@ -124,6 +122,8 @@ private:
matrix::Dcmf _rotation; matrix::Dcmf _rotation;
int _discard_reading{3};
int _flow_sum_x{0}; int _flow_sum_x{0};
int _flow_sum_y{0}; int _flow_sum_y{0};