|
|
|
@ -1,3 +1,5 @@
@@ -1,3 +1,5 @@
|
|
|
|
|
/// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
|
|
|
|
|
|
|
|
|
|
#include <AP_HAL.h> |
|
|
|
|
#if (CONFIG_HAL_BOARD == HAL_BOARD_APM1 || CONFIG_HAL_BOARD == HAL_BOARD_APM2) |
|
|
|
|
|
|
|
|
@ -11,6 +13,7 @@ extern const AP_HAL::HAL& hal;
@@ -11,6 +13,7 @@ extern const AP_HAL::HAL& hal;
|
|
|
|
|
|
|
|
|
|
ADCSource::ADCSource(uint8_t pin, float prescale) : |
|
|
|
|
_pin(pin), |
|
|
|
|
_stop_pin(ANALOG_INPUT_NONE), |
|
|
|
|
_sum_count(0), |
|
|
|
|
_sum(0), |
|
|
|
|
_prescale(prescale) |
|
|
|
@ -42,30 +45,39 @@ float ADCSource::read_latest() {
@@ -42,30 +45,39 @@ float ADCSource::read_latest() {
|
|
|
|
|
*/ |
|
|
|
|
float ADCSource::voltage_average(void) |
|
|
|
|
{ |
|
|
|
|
float vcc_mV = hal.analogin->channel(ANALOG_INPUT_BOARD_VCC)->read_average(); |
|
|
|
|
float v = read_average(); |
|
|
|
|
// constrain Vcc reading so that a bad Vcc doesn't throw off
|
|
|
|
|
// the reading of other sources too badly
|
|
|
|
|
if (vcc_mV < 4000) { |
|
|
|
|
vcc_mV = 4000; |
|
|
|
|
} else if (vcc_mV > 6000) { |
|
|
|
|
vcc_mV = 6000; |
|
|
|
|
} |
|
|
|
|
return v * vcc_mV * 9.765625e-7; // 9.765625e-7 = 1.0/(1024*1000)
|
|
|
|
|
float vcc_mV = hal.analogin->channel(ANALOG_INPUT_BOARD_VCC)->read_average(); |
|
|
|
|
float v = read_average(); |
|
|
|
|
// constrain Vcc reading so that a bad Vcc doesn't throw off
|
|
|
|
|
// the reading of other sources too badly
|
|
|
|
|
if (vcc_mV < 4000) { |
|
|
|
|
vcc_mV = 4000; |
|
|
|
|
} else if (vcc_mV > 6000) { |
|
|
|
|
vcc_mV = 6000; |
|
|
|
|
} |
|
|
|
|
return v * vcc_mV * 9.765625e-7; // 9.765625e-7 = 1.0/(1024*1000)
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ADCSource::set_pin(uint8_t pin) { |
|
|
|
|
_pin = pin; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ADCSource::set_stop_pin(uint8_t pin) { |
|
|
|
|
_stop_pin = pin; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ADCSource::set_settle_time(uint16_t settle_time_ms)
|
|
|
|
|
{ |
|
|
|
|
_settle_time_ms = settle_time_ms; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* read_average is called from the normal thread (not an interrupt). */ |
|
|
|
|
float ADCSource::_read_average() { |
|
|
|
|
uint16_t sum; |
|
|
|
|
uint8_t sum_count; |
|
|
|
|
|
|
|
|
|
if (_sum_count == 0) { |
|
|
|
|
// avoid blocking waiting for new samples
|
|
|
|
|
return _last_average; |
|
|
|
|
// avoid blocking waiting for new samples
|
|
|
|
|
return _last_average; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Read and clear in a critical section */ |
|
|
|
@ -86,8 +98,16 @@ float ADCSource::_read_average() {
@@ -86,8 +98,16 @@ float ADCSource::_read_average() {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ADCSource::setup_read() { |
|
|
|
|
if (_stop_pin != ANALOG_INPUT_NONE) { |
|
|
|
|
uint8_t digital_pin = hal.gpio->analogPinToDigitalPin(_stop_pin); |
|
|
|
|
hal.gpio->pinMode(digital_pin, GPIO_OUTPUT); |
|
|
|
|
hal.gpio->write(digital_pin, 1); |
|
|
|
|
} |
|
|
|
|
if (_settle_time_ms != 0) { |
|
|
|
|
_read_start_time_ms = hal.scheduler->millis(); |
|
|
|
|
} |
|
|
|
|
if (_pin == ANALOG_INPUT_BOARD_VCC) { |
|
|
|
|
ADCSRB = (ADCSRB & ~(1 << MUX5)); |
|
|
|
|
ADCSRB = (ADCSRB & ~(1 << MUX5)); |
|
|
|
|
ADMUX = _BV(REFS0)|_BV(MUX4)|_BV(MUX3)|_BV(MUX2)|_BV(MUX1); |
|
|
|
|
} else if (_pin == ANALOG_INPUT_NONE) { |
|
|
|
|
/* noop */ |
|
|
|
@ -97,6 +117,22 @@ void ADCSource::setup_read() {
@@ -97,6 +117,22 @@ void ADCSource::setup_read() {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ADCSource::stop_read() { |
|
|
|
|
if (_stop_pin != ANALOG_INPUT_NONE) { |
|
|
|
|
uint8_t digital_pin = hal.gpio->analogPinToDigitalPin(_stop_pin); |
|
|
|
|
hal.gpio->pinMode(digital_pin, GPIO_OUTPUT); |
|
|
|
|
hal.gpio->write(digital_pin, 0); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool ADCSource::reading_settled()
|
|
|
|
|
{ |
|
|
|
|
if (_settle_time_ms != 0 && (hal.scheduler->millis() - _read_start_time_ms) < _settle_time_ms) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* new_sample is called from an interrupt. It always has access to
|
|
|
|
|
* _sum and _sum_count. Lock out the interrupts briefly with |
|
|
|
|
* cli/sei to read these variables from outside an interrupt. */ |
|
|
|
|