mirror of
https://github.com/ArduPilot/ardupilot
synced 2025-01-03 14:38:30 -04:00
AP_OpticalFlow: use I2CDevice interface
This commit is contained in:
parent
106f26d204
commit
46fb57fcf1
@ -427,6 +427,9 @@
|
|||||||
#define HAL_LINUX_UARTS_ON_TIMER_THREAD 0
|
#define HAL_LINUX_UARTS_ON_TIMER_THREAD 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAL_OPTFLOW_PX4FLOW_I2C_ADDRESS
|
||||||
|
#define HAL_OPTFLOW_PX4FLOW_I2C_ADDRESS 0x42
|
||||||
|
#endif
|
||||||
|
|
||||||
#elif CONFIG_HAL_BOARD == HAL_BOARD_EMPTY
|
#elif CONFIG_HAL_BOARD == HAL_BOARD_EMPTY
|
||||||
#define HAL_BOARD_NAME "EMPTY"
|
#define HAL_BOARD_NAME "EMPTY"
|
||||||
|
@ -17,27 +17,31 @@
|
|||||||
/*
|
/*
|
||||||
* AP_OpticalFlow_Linux.cpp - ardupilot library for the PX4Flow sensor.
|
* AP_OpticalFlow_Linux.cpp - ardupilot library for the PX4Flow sensor.
|
||||||
* inspired by the PX4Firmware code.
|
* inspired by the PX4Firmware code.
|
||||||
*
|
*
|
||||||
* @author: Víctor Mayoral Vilches
|
* @author: Víctor Mayoral Vilches
|
||||||
*
|
*
|
||||||
|
* Address range 0x42 - 0x49
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include <AP_HAL/AP_HAL.h>
|
#include <AP_HAL/AP_HAL.h>
|
||||||
|
|
||||||
#include "OpticalFlow.h"
|
#include "OpticalFlow.h"
|
||||||
|
|
||||||
#define PX4FLOW_DEBUG 1
|
#define PX4FLOW_DEBUG 1
|
||||||
|
|
||||||
#if CONFIG_HAL_BOARD == HAL_BOARD_LINUX
|
#if CONFIG_HAL_BOARD == HAL_BOARD_LINUX
|
||||||
|
|
||||||
#define PX4FLOW_I2C_ADDRESS 0x42 // 7-bit address. 8-bit address is 0x84, range 0x42 - 0x49
|
|
||||||
#define PX4FLOW_REG 0x16 // Measure Register 22
|
#define PX4FLOW_REG 0x16 // Measure Register 22
|
||||||
#define I2C_FRAME_SIZE (sizeof(i2c_frame))
|
#define I2C_FRAME_SIZE (sizeof(i2c_frame))
|
||||||
#define I2C_INTEGRAL_FRAME_SIZE (sizeof(i2c_integral_frame))
|
#define I2C_INTEGRAL_FRAME_SIZE (sizeof(i2c_integral_frame))
|
||||||
|
|
||||||
extern const AP_HAL::HAL& hal;
|
extern const AP_HAL::HAL& hal;
|
||||||
|
|
||||||
AP_OpticalFlow_Linux::AP_OpticalFlow_Linux(OpticalFlow &_frontend) :
|
AP_OpticalFlow_Linux::AP_OpticalFlow_Linux(OpticalFlow &_frontend, AP_HAL::OwnPtr<AP_HAL::I2CDevice> dev)
|
||||||
OpticalFlow_backend(_frontend)
|
: OpticalFlow_backend(_frontend)
|
||||||
|
, _dev(std::move(dev))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void AP_OpticalFlow_Linux::init(void)
|
void AP_OpticalFlow_Linux::init(void)
|
||||||
@ -47,50 +51,35 @@ void AP_OpticalFlow_Linux::init(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get pointer to i2c bus semaphore
|
|
||||||
AP_HAL::Semaphore *i2c_sem = hal.i2c->get_semaphore();
|
|
||||||
if (i2c_sem == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// take i2c bus sempahore
|
// take i2c bus sempahore
|
||||||
if (!i2c_sem->take(200)) {
|
if (!_dev->get_semaphore()->take(200)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// read from flow sensor to ensure it is not a ll40ls Lidar (which can be on 0x42)
|
// read from flow sensor to ensure it is not a ll40ls Lidar (which can be on 0x42)
|
||||||
// read I2C_FRAME_SIZE bytes, the ll40ls will error whereas the flow happily returns data
|
// read I2C_FRAME_SIZE bytes, the ll40ls will error whereas the flow happily returns data
|
||||||
uint8_t val[I2C_FRAME_SIZE];
|
uint8_t val[I2C_FRAME_SIZE];
|
||||||
if (hal.i2c->readRegisters(PX4FLOW_I2C_ADDRESS, 0, I2C_FRAME_SIZE, val) != 0) {
|
if (!_dev->read_registers(0, val, I2C_FRAME_SIZE)) {
|
||||||
i2c_sem->give();
|
goto fail;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// success
|
// success
|
||||||
initialised = true;
|
initialised = true;
|
||||||
i2c_sem->give();
|
|
||||||
|
fail:
|
||||||
|
_dev->get_semaphore()->give();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AP_OpticalFlow_Linux::request_measurement()
|
bool AP_OpticalFlow_Linux::request_measurement()
|
||||||
{
|
{
|
||||||
// send measure request to sensor
|
// send measure request to sensor
|
||||||
uint8_t cmd = PX4FLOW_REG;
|
return _dev->write_register(PX4FLOW_REG, 0);
|
||||||
if (hal.i2c->writeRegisters(PX4FLOW_I2C_ADDRESS, cmd, 0, nullptr) != 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AP_OpticalFlow_Linux::read(optical_flow_s* report)
|
bool AP_OpticalFlow_Linux::read(optical_flow_s* report)
|
||||||
{
|
{
|
||||||
// get pointer to i2c bus semaphore
|
|
||||||
AP_HAL::Semaphore *i2c_sem = hal.i2c->get_semaphore();
|
|
||||||
if (i2c_sem == NULL) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// take i2c bus sempahore (non blocking)
|
// take i2c bus sempahore (non blocking)
|
||||||
if (!i2c_sem->take_nonblocking()) {
|
if (!_dev->get_semaphore()->take_nonblocking()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,20 +91,20 @@ bool AP_OpticalFlow_Linux::read(optical_flow_s* report)
|
|||||||
|
|
||||||
// Perform the writing and reading in a single command
|
// Perform the writing and reading in a single command
|
||||||
if (PX4FLOW_REG == 0x00) {
|
if (PX4FLOW_REG == 0x00) {
|
||||||
if (hal.i2c->readRegisters(PX4FLOW_I2C_ADDRESS, 0, I2C_FRAME_SIZE + I2C_INTEGRAL_FRAME_SIZE, val) != 0) {
|
if (!_dev->read_registers(0, val, I2C_FRAME_SIZE + I2C_INTEGRAL_FRAME_SIZE)) {
|
||||||
goto fail_transfer;
|
goto fail_transfer;
|
||||||
}
|
}
|
||||||
memcpy(&f_integral, &(val[I2C_FRAME_SIZE]), I2C_INTEGRAL_FRAME_SIZE);
|
memcpy(&f_integral, &(val[I2C_FRAME_SIZE]), I2C_INTEGRAL_FRAME_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PX4FLOW_REG == 0x16) {
|
if (PX4FLOW_REG == 0x16) {
|
||||||
if (hal.i2c->readRegisters(PX4FLOW_I2C_ADDRESS, 0, I2C_INTEGRAL_FRAME_SIZE, val) != 0) {
|
if (!_dev->read_registers(0, val, I2C_INTEGRAL_FRAME_SIZE)) {
|
||||||
goto fail_transfer;
|
goto fail_transfer;
|
||||||
}
|
}
|
||||||
memcpy(&f_integral, val, I2C_INTEGRAL_FRAME_SIZE);
|
memcpy(&f_integral, val, I2C_INTEGRAL_FRAME_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
i2c_sem->give();
|
_dev->get_semaphore()->give();
|
||||||
|
|
||||||
// reduce error count
|
// reduce error count
|
||||||
if (num_errors > 0) {
|
if (num_errors > 0) {
|
||||||
@ -139,7 +128,7 @@ bool AP_OpticalFlow_Linux::read(optical_flow_s* report)
|
|||||||
|
|
||||||
fail_transfer:
|
fail_transfer:
|
||||||
num_errors++;
|
num_errors++;
|
||||||
i2c_sem->give();
|
_dev->get_semaphore()->give();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,13 +9,15 @@
|
|||||||
#include "OpticalFlow.h"
|
#include "OpticalFlow.h"
|
||||||
|
|
||||||
#include <AP_Common/AP_Common.h>
|
#include <AP_Common/AP_Common.h>
|
||||||
|
#include <AP_HAL/I2CDevice.h>
|
||||||
|
#include <AP_HAL/utility/OwnPtr.h>
|
||||||
#include <AP_Math/AP_Math.h>
|
#include <AP_Math/AP_Math.h>
|
||||||
|
|
||||||
class AP_OpticalFlow_Linux : public OpticalFlow_backend
|
class AP_OpticalFlow_Linux : public OpticalFlow_backend
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// constructor
|
// constructor
|
||||||
AP_OpticalFlow_Linux(OpticalFlow &_frontend);
|
AP_OpticalFlow_Linux(OpticalFlow &_frontend, AP_HAL::OwnPtr<AP_HAL::I2CDevice> dev);
|
||||||
|
|
||||||
// initialise the sensor
|
// initialise the sensor
|
||||||
void init();
|
void init();
|
||||||
@ -70,6 +72,8 @@ private:
|
|||||||
uint8_t quality; // Average of quality of accumulated frames, 0: bad quality, 255: maximum quality
|
uint8_t quality; // Average of quality of accumulated frames, 0: bad quality, 255: maximum quality
|
||||||
} optical_flow_s;
|
} optical_flow_s;
|
||||||
|
|
||||||
|
AP_HAL::OwnPtr<AP_HAL::I2CDevice> _dev;
|
||||||
|
|
||||||
// request the sensor produce a measurement, returns true on success
|
// request the sensor produce a measurement, returns true on success
|
||||||
bool request_measurement();
|
bool request_measurement();
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ OpticalFlow::OpticalFlow(AP_AHRS_NavEKF& ahrs) :
|
|||||||
CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BBBMINI
|
CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_BBBMINI
|
||||||
backend(new AP_OpticalFlow_Onboard(*this, ahrs)),
|
backend(new AP_OpticalFlow_Onboard(*this, ahrs)),
|
||||||
#elif CONFIG_HAL_BOARD == HAL_BOARD_LINUX
|
#elif CONFIG_HAL_BOARD == HAL_BOARD_LINUX
|
||||||
backend(new AP_OpticalFlow_Linux(*this)),
|
backend(new AP_OpticalFlow_Linux(*this, hal.i2c_mgr->get_device(1, HAL_OPTFLOW_PX4FLOW_I2C_ADDRESS))),
|
||||||
#else
|
#else
|
||||||
backend(NULL),
|
backend(NULL),
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user