ADC: replace ioctl with uorb message (#14087)

This commit is contained in:
SalimTerryLi
2020-03-20 18:23:32 +08:00
committed by GitHub
parent 40af5b0fbe
commit dc8e775d8f
30 changed files with 345 additions and 486 deletions
@@ -36,12 +36,11 @@
using namespace time_literals;
AEROFC_ADC::AEROFC_ADC(uint8_t bus) :
I2C("AEROFC_ADC", ADC0_DEVICE_PATH, bus, SLAVE_ADDR, 400000),
I2C("AEROFC_ADC", AEROFC_ADC_DEVICE_PATH, bus, SLAVE_ADDR, 400000),
ScheduledWorkItem(MODULE_NAME, px4::device_bus_to_wq(get_device_id())),
_sample_perf(perf_alloc(PC_ELAPSED, MODULE_NAME": sample"))
{
_sample.am_channel = 1;
pthread_mutex_init(&_sample_mutex, nullptr);
}
AEROFC_ADC::~AEROFC_ADC()
@@ -95,26 +94,16 @@ error:
return -EIO;
}
ssize_t AEROFC_ADC::read(file *filp, char *buffer, size_t len)
{
if (len < sizeof(_sample)) {
return -ENOSPC;
}
if (len > sizeof(_sample)) {
len = sizeof(_sample);
}
pthread_mutex_lock(&_sample_mutex);
memcpy(buffer, &_sample, len);
pthread_mutex_unlock(&_sample_mutex);
return len;
}
void AEROFC_ADC::Run()
{
uint8_t buffer[2] {};
/*
* https://github.com/intel-aero/intel-aero-fpga/blob/master/aero_sample/adc/adc.html
* https://github.com/intel-aero/meta-intel-aero/wiki/95-(References)-FPGA
* https://github.com/intel-aero/intel-aero-fpga/blob/master/aero_rtf_kit/RTL/adc.v
*/
perf_begin(_sample_perf);
uint8_t buffer[10] {};
buffer[0] = ADC_CHANNEL_REG;
int ret = transfer(buffer, 1, buffer, sizeof(buffer));
@@ -123,12 +112,24 @@ void AEROFC_ADC::Run()
return;
}
pthread_mutex_lock(&_sample_mutex);
_sample.am_data = (buffer[0] | (buffer[1] << 8));
pthread_mutex_unlock(&_sample_mutex);
}
adc_report_s adc_report;
adc_report.device_id = this->get_device_id();
adc_report.timestamp = hrt_absolute_time();
adc_report.v_ref = 3.0f;
adc_report.resolution = 1 << 12;
uint32_t px4_arch_adc_dn_fullcount()
{
return 1 << 12; // 12 bit ADC
}
unsigned i;
for (i = 0; i < MAX_CHANNEL; ++i) {
adc_report.channel_id[i] = i;
adc_report.raw_data[i] = (buffer[i * 2] | (buffer[i * 2 + 1] << 8));
}
for (; i < PX4_MAX_ADC_CHANNELS; ++i) { // set unused channel id to -1
adc_report.channel_id[i] = -1;
}
_to_adc_report.publish(adc_report);
perf_end(_sample_perf);
}
@@ -37,18 +37,20 @@
#include <drivers/drv_hrt.h>
#include <lib/cdev/CDev.hpp>
#include <lib/perf/perf_counter.h>
#include <px4_arch/adc.h>
#include <px4_platform_common/px4_config.h>
#include <px4_platform_common/defines.h>
#include <px4_platform_common/log.h>
#include <drivers/device/i2c.h>
#include <drivers/drv_adc.h>
#include <px4_platform_common/px4_work_queue/ScheduledWorkItem.hpp>
#include <uORB/Publication.hpp>
#include <uORB/topics/adc_report.h>
#define SLAVE_ADDR 0x50
#define ADC_ENABLE_REG 0x00
#define ADC_CHANNEL_REG 0x05
#define ADC_CHANNEL_REG 0x03
#define MAX_CHANNEL 5
#define AEROFC_ADC_DEVICE_PATH "/dev/aerofc_adc"
class AEROFC_ADC : public device::I2C, public px4::ScheduledWorkItem
{
@@ -57,14 +59,12 @@ public:
~AEROFC_ADC() override;
int init() override;
ssize_t read(file *filp, char *buffer, size_t len) override;
private:
int probe() override;;
void Run() override;
px4_adc_msg_t _sample{};
pthread_mutex_t _sample_mutex;
uORB::Publication<adc_report_s> _to_adc_report{ORB_ID(adc_report)};
perf_counter_t _sample_perf;
};
@@ -63,30 +63,7 @@ static AEROFC_ADC *instance = nullptr;
static int test()
{
int fd = px4_open(ADC0_DEVICE_PATH, O_RDONLY);
if (fd < 0) {
PX4_ERR("can't open ADC device");
return PX4_ERROR;
}
px4_adc_msg_t data[MAX_CHANNEL];
ssize_t count = px4_read(fd, data, sizeof(data));
if (count < 0) {
PX4_ERR("read error");
px4_close(fd);
return PX4_ERROR;
}
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_close(fd);
PX4_INFO("test is currently unavailable");
return 0;
}