fxas21002c: sample at nyquist rate, drop duplicates, throttle temperature updates

This commit is contained in:
Daniel Agar
2020-05-19 13:54:19 -04:00
parent 10d67efd13
commit e73380f726
2 changed files with 41 additions and 48 deletions
+35 -44
View File
@@ -106,8 +106,7 @@ FXAS21002C::init()
return PX4_OK; return PX4_OK;
} }
void void FXAS21002C::reset()
FXAS21002C::reset()
{ {
/* write 0 0 0 000 00 = 0x00 to CTRL_REG1 to place FXOS21002 in Standby /* write 0 0 0 000 00 = 0x00 to CTRL_REG1 to place FXOS21002 in Standby
* [6]: RST=0 * [6]: RST=0
@@ -133,12 +132,9 @@ FXAS21002C::reset()
set_samplerate(FXAS21002C_DEFAULT_RATE); set_samplerate(FXAS21002C_DEFAULT_RATE);
set_range(FXAS21002C_DEFAULT_RANGE_DPS); set_range(FXAS21002C_DEFAULT_RANGE_DPS);
set_onchip_lowpass_filter(FXAS21002C_DEFAULT_ONCHIP_FILTER_FREQ); set_onchip_lowpass_filter(FXAS21002C_DEFAULT_ONCHIP_FILTER_FREQ);
_read = 0;
} }
void void FXAS21002C::write_checked_reg(unsigned reg, uint8_t value)
FXAS21002C::write_checked_reg(unsigned reg, uint8_t value)
{ {
write_reg(reg, value); write_reg(reg, value);
@@ -149,8 +145,7 @@ FXAS21002C::write_checked_reg(unsigned reg, uint8_t value)
} }
} }
void void FXAS21002C::modify_reg(unsigned reg, uint8_t clearbits, uint8_t setbits)
FXAS21002C::modify_reg(unsigned reg, uint8_t clearbits, uint8_t setbits)
{ {
uint8_t val = read_reg(reg); uint8_t val = read_reg(reg);
val &= ~clearbits; val &= ~clearbits;
@@ -158,8 +153,7 @@ FXAS21002C::modify_reg(unsigned reg, uint8_t clearbits, uint8_t setbits)
write_checked_reg(reg, val); write_checked_reg(reg, val);
} }
int int FXAS21002C::set_range(unsigned max_dps)
FXAS21002C::set_range(unsigned max_dps)
{ {
uint8_t bits = CTRL_REG0_FS_250_DPS; uint8_t bits = CTRL_REG0_FS_250_DPS;
float new_range_scale_dps_digit; float new_range_scale_dps_digit;
@@ -202,8 +196,7 @@ FXAS21002C::set_range(unsigned max_dps)
return OK; return OK;
} }
void void FXAS21002C::set_standby(int rate, bool standby_true)
FXAS21002C::set_standby(int rate, bool standby_true)
{ {
uint8_t c = 0; uint8_t c = 0;
uint8_t s = 0; uint8_t s = 0;
@@ -224,8 +217,7 @@ FXAS21002C::set_standby(int rate, bool standby_true)
usleep(wait_ms * 1000); usleep(wait_ms * 1000);
} }
int int FXAS21002C::set_samplerate(unsigned frequency)
FXAS21002C::set_samplerate(unsigned frequency)
{ {
uint8_t bits = 0; uint8_t bits = 0;
@@ -274,8 +266,7 @@ FXAS21002C::set_samplerate(unsigned frequency)
return OK; return OK;
} }
void void FXAS21002C::set_onchip_lowpass_filter(int frequency_hz)
FXAS21002C::set_onchip_lowpass_filter(int frequency_hz)
{ {
int high = 256 / (800 / _current_rate); int high = 256 / (800 / _current_rate);
int med = high / 2 ; int med = high / 2 ;
@@ -310,15 +301,13 @@ FXAS21002C::set_onchip_lowpass_filter(int frequency_hz)
set_standby(_current_rate, false); set_standby(_current_rate, false);
} }
void void FXAS21002C::start()
FXAS21002C::start()
{ {
/* start polling at the specified rate */ /* start polling at the specified rate */
ScheduleOnInterval((1_s / FXAS21002C_DEFAULT_RATE) - FXAS21002C_TIMER_REDUCTION, 10000); ScheduleOnInterval((1_s / FXAS21002C_DEFAULT_RATE) - FXAS21002C_TIMER_REDUCTION);
} }
void void FXAS21002C::check_registers()
FXAS21002C::check_registers(void)
{ {
uint8_t v; uint8_t v;
@@ -347,15 +336,11 @@ FXAS21002C::check_registers(void)
_checked_next = (_checked_next + 1) % FXAS21002C_NUM_CHECKED_REGISTERS; _checked_next = (_checked_next + 1) % FXAS21002C_NUM_CHECKED_REGISTERS;
} }
void void FXAS21002C::RunImpl()
FXAS21002C::RunImpl()
{ {
// start the performance counter // start the performance counter
perf_begin(_sample_perf); perf_begin(_sample_perf);
/* status register and data as read back from the device */
RawGyroReport raw_gyro_report{};
check_registers(); check_registers();
if (_register_wait != 0) { if (_register_wait != 0) {
@@ -367,6 +352,7 @@ FXAS21002C::RunImpl()
} }
/* fetch data from the sensor */ /* fetch data from the sensor */
RawGyroReport raw_gyro_report{};
const hrt_abstime timestamp_sample = hrt_absolute_time(); const hrt_abstime timestamp_sample = hrt_absolute_time();
_interface->read(FXAS21002C_STATUS, (uint8_t *)&raw_gyro_report, sizeof(raw_gyro_report)); _interface->read(FXAS21002C_STATUS, (uint8_t *)&raw_gyro_report, sizeof(raw_gyro_report));
@@ -377,40 +363,45 @@ FXAS21002C::RunImpl()
return; return;
} }
int16_t x_raw = swap16(raw_gyro_report.x);
int16_t y_raw = swap16(raw_gyro_report.y);
int16_t z_raw = swap16(raw_gyro_report.z);
// don't publish duplicated reads
if ((x_raw == _gyro_prev[0]) && (y_raw == _gyro_prev[1]) && (z_raw == _gyro_prev[2])) {
perf_count(_duplicates);
perf_end(_sample_perf);
return;
} else {
_gyro_prev[0] = x_raw;
_gyro_prev[1] = y_raw;
_gyro_prev[2] = z_raw;
}
// report the error count as the number of bad register reads. This allows the higher level
_px4_gyro.set_error_count(perf_event_count(_bad_registers));
_px4_gyro.update(timestamp_sample, x_raw, y_raw, z_raw);
if (hrt_elapsed_time(&_last_temperature_update) > 100_ms) {
/* /*
* The TEMP register contains an 8-bit 2's complement temperature value with a range * The TEMP register contains an 8-bit 2's complement temperature value with a range
* of 128 °C to +127 °C and a scaling of 1 °C/LSB. The temperature data is only * of 128 °C to +127 °C and a scaling of 1 °C/LSB. The temperature data is only
* compensated (factory trim values applied) when the device is operating in the Active * compensated (factory trim values applied) when the device is operating in the Active
* mode and actively measuring the angular rate. * mode and actively measuring the angular rate.
*/ */
if ((_read % _current_rate) == 0) {
const float temperature = read_reg(FXAS21002C_TEMP) * 1.0f; const float temperature = read_reg(FXAS21002C_TEMP) * 1.0f;
_px4_gyro.set_temperature(temperature); _px4_gyro.set_temperature(temperature);
_last_temperature_update = timestamp_sample;
} }
// report the error count as the number of bad
// register reads. This allows the higher level
// code to decide if it should use this sensor based on
// whether it has had failures
_px4_gyro.set_error_count(perf_event_count(_bad_registers));
int16_t x_raw = swap16(raw_gyro_report.x);
int16_t y_raw = swap16(raw_gyro_report.y);
int16_t z_raw = swap16(raw_gyro_report.z);
_px4_gyro.update(timestamp_sample, x_raw, y_raw, z_raw);
_read++;
/* stop the perf counter */ /* stop the perf counter */
perf_end(_sample_perf); perf_end(_sample_perf);
} }
void void FXAS21002C::print_status()
FXAS21002C::print_status()
{ {
I2CSPIDriverBase::print_status(); I2CSPIDriverBase::print_status();
printf("gyro reads: %u\n", _read);
perf_print_counter(_sample_perf); perf_print_counter(_sample_perf);
perf_print_counter(_errors); perf_print_counter(_errors);
perf_print_counter(_bad_registers); perf_print_counter(_bad_registers);
+3 -1
View File
@@ -216,13 +216,15 @@ private:
unsigned _current_rate{800}; unsigned _current_rate{800};
unsigned _read{0}; int16_t _gyro_prev[3] {};
perf_counter_t _sample_perf; perf_counter_t _sample_perf;
perf_counter_t _errors; perf_counter_t _errors;
perf_counter_t _bad_registers; perf_counter_t _bad_registers;
perf_counter_t _duplicates; perf_counter_t _duplicates;
hrt_abstime _last_temperature_update{0};
uint8_t _register_wait{0}; uint8_t _register_wait{0};
/* this is used to support runtime checking of key /* this is used to support runtime checking of key