ADC: replace ioctl with uorb message (#14087)

This commit is contained in:
SalimTerryLi
2020-03-20 11:23:32 +01:00
committed by GitHub
parent 40af5b0fbe
commit dc8e775d8f
30 changed files with 345 additions and 486 deletions
+34 -55
View File
@@ -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[])
+2 -4
View File
@@ -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.
*
+4 -2
View File
@@ -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
+6 -5
View File
@@ -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) {
+1
View File
@@ -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>