mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-15 12:53:34 +08:00
ADC: replace ioctl with uorb message (#14087)
This commit is contained in:
+34
-55
@@ -31,10 +31,11 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <uORB/Subscription.hpp>
|
||||
|
||||
#include "ADC.hpp"
|
||||
|
||||
ADC::ADC(uint32_t base_address, uint32_t channels) :
|
||||
CDev(ADC0_DEVICE_PATH),
|
||||
ScheduledWorkItem(MODULE_NAME, px4::wq_configurations::hp_default),
|
||||
_sample_perf(perf_alloc(PC_ELAPSED, MODULE_NAME": sample")),
|
||||
_base_address(base_address)
|
||||
@@ -90,39 +91,14 @@ int ADC::init()
|
||||
return ret_init;
|
||||
}
|
||||
|
||||
/* create the device node */
|
||||
int ret_cdev = CDev::init();
|
||||
|
||||
if (ret_cdev != PX4_OK) {
|
||||
PX4_ERR("CDev init failed");
|
||||
return ret_cdev;
|
||||
}
|
||||
|
||||
// schedule regular updates
|
||||
ScheduleOnInterval(kINTERVAL, kINTERVAL);
|
||||
|
||||
return PX4_OK;
|
||||
}
|
||||
|
||||
ssize_t ADC::read(cdev::file_t *filp, char *buffer, size_t len)
|
||||
{
|
||||
const size_t maxsize = sizeof(px4_adc_msg_t) * _channel_count;
|
||||
|
||||
if (len > maxsize) {
|
||||
len = maxsize;
|
||||
}
|
||||
|
||||
/* block interrupts while copying samples to avoid racing with an update */
|
||||
lock();
|
||||
memcpy(buffer, _samples, len);
|
||||
unlock();
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
void ADC::Run()
|
||||
{
|
||||
lock();
|
||||
hrt_abstime now = hrt_absolute_time();
|
||||
|
||||
/* scan the channel set and sample each */
|
||||
@@ -132,13 +108,13 @@ void ADC::Run()
|
||||
|
||||
update_adc_report(now);
|
||||
update_system_power(now);
|
||||
unlock();
|
||||
}
|
||||
|
||||
void ADC::update_adc_report(hrt_abstime now)
|
||||
{
|
||||
adc_report_s adc = {};
|
||||
adc.timestamp = now;
|
||||
adc.device_id = BUILTIN_ADC_DEVID;
|
||||
|
||||
unsigned max_num = _channel_count;
|
||||
|
||||
@@ -146,11 +122,20 @@ void ADC::update_adc_report(hrt_abstime now)
|
||||
max_num = (sizeof(adc.channel_id) / sizeof(adc.channel_id[0]));
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < max_num; i++) {
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < max_num; i++) {
|
||||
adc.channel_id[i] = _samples[i].am_channel;
|
||||
adc.channel_value[i] = _samples[i].am_data * 3.3f / px4_arch_adc_dn_fullcount();
|
||||
adc.raw_data[i] = _samples[i].am_data;
|
||||
}
|
||||
|
||||
for (; i < PX4_MAX_ADC_CHANNELS; ++i) { // set unused channel id to -1
|
||||
adc.channel_id[i] = -1;
|
||||
}
|
||||
|
||||
adc.v_ref = px4_arch_adc_reference_v();
|
||||
adc.resolution = px4_arch_adc_dn_fullcount();
|
||||
|
||||
_to_adc_report.publish(adc);
|
||||
}
|
||||
|
||||
@@ -252,35 +237,29 @@ uint32_t ADC::sample(unsigned channel)
|
||||
|
||||
int ADC::test()
|
||||
{
|
||||
int fd = px4_open(ADC0_DEVICE_PATH, O_RDONLY);
|
||||
uORB::Subscription adc_sub_test{ORB_ID(adc_report)};
|
||||
adc_report_s adc;
|
||||
|
||||
if (fd < 0) {
|
||||
PX4_ERR("can't open ADC device %d", errno);
|
||||
px4_usleep(20000); // sleep 20ms and wait for adc report
|
||||
|
||||
if (adc_sub_test.update(&adc)) {
|
||||
PX4_INFO_RAW("DeviceID: %d\n", adc.device_id);
|
||||
PX4_INFO_RAW("Resolution: %d\n", adc.resolution);
|
||||
PX4_INFO_RAW("Voltage Reference: %f\n", (double)adc.v_ref);
|
||||
|
||||
for (unsigned i = 0; i < PX4_MAX_ADC_CHANNELS; ++i) {
|
||||
PX4_INFO_RAW("%d: %d ", adc.channel_id[i], adc.raw_data[i]);
|
||||
}
|
||||
|
||||
PX4_INFO_RAW("\n");
|
||||
|
||||
PX4_INFO_RAW("\t ADC test successful.\n");
|
||||
|
||||
return 0;
|
||||
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < 20; i++) {
|
||||
px4_adc_msg_t data[ADC_TOTAL_CHANNELS];
|
||||
ssize_t count = px4_read(fd, data, sizeof(data));
|
||||
|
||||
if (count < 0) {
|
||||
PX4_ERR("read error");
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned channels = count / sizeof(data[0]);
|
||||
|
||||
for (unsigned j = 0; j < channels; j++) {
|
||||
printf("%d: %u ", data[j].am_channel, data[j].am_data);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
px4_usleep(100000);
|
||||
}
|
||||
|
||||
px4_close(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ADC::custom_command(int argc, char *argv[])
|
||||
|
||||
@@ -60,7 +60,7 @@ using namespace time_literals;
|
||||
|
||||
#define ADC_TOTAL_CHANNELS 32
|
||||
|
||||
class ADC : public ModuleBase<ADC>, public cdev::CDev, public px4::ScheduledWorkItem
|
||||
class ADC : public ModuleBase<ADC>, public px4::ScheduledWorkItem
|
||||
{
|
||||
public:
|
||||
ADC(uint32_t base_address = SYSTEM_ADC_BASE, uint32_t channels = ADC_CHANNELS);
|
||||
@@ -76,7 +76,7 @@ public:
|
||||
/** @see ModuleBase */
|
||||
static int print_usage(const char *reason = nullptr);
|
||||
|
||||
int init() override;
|
||||
int init();
|
||||
|
||||
int test();
|
||||
|
||||
@@ -84,8 +84,6 @@ private:
|
||||
|
||||
void Run() override;
|
||||
|
||||
ssize_t read(cdev::file_t *filp, char *buffer, size_t len) override;
|
||||
|
||||
/**
|
||||
* Sample a single channel and return the measured value.
|
||||
*
|
||||
|
||||
@@ -42,6 +42,8 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <systemlib/px4_macros.h>
|
||||
#include <uORB/topics/adc_report.h>
|
||||
|
||||
/* Define the PX4 low level format ADC and the maximum
|
||||
* number of channels that can be returned by a lowlevel
|
||||
@@ -49,14 +51,14 @@
|
||||
* but no more than PX4_MAX_ADC_CHANNELS.
|
||||
*
|
||||
*/
|
||||
#define PX4_MAX_ADC_CHANNELS 12
|
||||
#define PX4_MAX_ADC_CHANNELS arraySize(adc_report_s::channel_id)
|
||||
typedef struct __attribute__((packed)) px4_adc_msg_t {
|
||||
uint8_t am_channel; /* The 8-bit ADC Channel */
|
||||
int32_t am_data; /* ADC convert result (4 bytes) */
|
||||
} px4_adc_msg_t;
|
||||
|
||||
|
||||
#define ADC0_DEVICE_PATH "/dev/adc0"
|
||||
#define BUILTIN_ADC_DEVID 0xffffffff // TODO: integrate into existing ID management
|
||||
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
@@ -308,16 +308,17 @@ void RCInput::Run()
|
||||
adc_report_s adc;
|
||||
|
||||
if (_adc_sub.update(&adc)) {
|
||||
const unsigned adc_chans = sizeof(adc.channel_id) / sizeof(adc.channel_id[0]);
|
||||
|
||||
for (unsigned i = 0; i < adc_chans; i++) {
|
||||
for (unsigned i = 0; i < PX4_MAX_ADC_CHANNELS; ++i) {
|
||||
if (adc.channel_id[i] == ADC_RC_RSSI_CHANNEL) {
|
||||
float adc_volt = adc.raw_data[i] *
|
||||
adc.v_ref /
|
||||
adc.resolution;
|
||||
|
||||
if (_analog_rc_rssi_volt < 0.0f) {
|
||||
_analog_rc_rssi_volt = adc.channel_value[i];
|
||||
_analog_rc_rssi_volt = adc_volt;
|
||||
}
|
||||
|
||||
_analog_rc_rssi_volt = _analog_rc_rssi_volt * 0.995f + adc.channel_value[i] * 0.005f;
|
||||
_analog_rc_rssi_volt = _analog_rc_rssi_volt * 0.995f + adc_volt * 0.005f;
|
||||
|
||||
/* only allow this to be used if we see a high RSSI once */
|
||||
if (_analog_rc_rssi_volt > 2.5f) {
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <float.h>
|
||||
|
||||
#include <board_config.h>
|
||||
#include <drivers/drv_adc.h>
|
||||
#include <drivers/drv_hrt.h>
|
||||
#include <drivers/drv_rc_input.h>
|
||||
#include <lib/perf/perf_counter.h>
|
||||
|
||||
Reference in New Issue
Block a user