mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-06-02 20:28:37 +08:00
fxas21002c: sample at nyquist rate, drop duplicates, throttle temperature updates
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user