SITL: factor out an I2C command/response class from simulated MaxSonar sensor
This commit is contained in:
parent
1c19a228ac
commit
6bc8ff2ee8
@ -125,3 +125,37 @@ int SITL::I2CRegisters_8Bit::rdwr(I2C::i2c_rdwr_ioctl_data *&data)
|
||||
|
||||
return -1;
|
||||
};
|
||||
|
||||
|
||||
int SITL::I2CCommandResponseDevice::rdwr(I2C::i2c_rdwr_ioctl_data *&data)
|
||||
{
|
||||
const uint32_t now = AP_HAL::millis();
|
||||
|
||||
struct I2C::i2c_msg &msg = data->msgs[0];
|
||||
if (msg.flags == I2C_M_RD) {
|
||||
// driver is attempting to receive reading...
|
||||
if (now - cmd_take_reading_received_ms < command_processing_time_ms()) {
|
||||
// not sure we ought to be returning -1 here - what does
|
||||
// the real device do? return stale data? garbage data?
|
||||
return -1;
|
||||
}
|
||||
if (msg.len != 2) {
|
||||
AP_HAL::panic("Unxpected message length (%u)", msg.len);
|
||||
}
|
||||
|
||||
const uint16_t value = reading();
|
||||
|
||||
msg.buf[0] = value >> 8;
|
||||
msg.buf[1] = value & 0xff;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const uint8_t cmd = msg.buf[0];
|
||||
if (cmd != command_take_reading()) {
|
||||
AP_HAL::panic("Unknown command (%u)", cmd);
|
||||
}
|
||||
cmd_take_reading_received_ms = now;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -50,6 +50,25 @@ protected:
|
||||
uint8_t byte[256];
|
||||
};
|
||||
|
||||
/*
|
||||
for devices that take a command then will provide data to a read();
|
||||
for example, MCU writes 0x07 to device then expects to be able to
|
||||
read 2 bytes from it.
|
||||
*/
|
||||
class I2CCommandResponseDevice {
|
||||
public:
|
||||
int rdwr(I2C::i2c_rdwr_ioctl_data *&data);
|
||||
|
||||
protected:
|
||||
|
||||
// time taken for device to process command:
|
||||
uint16_t command_processing_time_ms() const { return 20; }
|
||||
virtual uint8_t command_take_reading() const = 0;
|
||||
virtual uint16_t reading() const = 0;
|
||||
|
||||
uint32_t cmd_take_reading_received_ms;
|
||||
};
|
||||
|
||||
class I2CDevice {
|
||||
public:
|
||||
virtual void init() {}
|
||||
|
@ -1,45 +0,0 @@
|
||||
#include "SIM_MaxSonarI2CXL.h"
|
||||
|
||||
#include <SITL/SITL.h>
|
||||
#include <SITL/SIM_Aircraft.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int SITL::MaxSonarI2CXL::rdwr(I2C::i2c_rdwr_ioctl_data *&data)
|
||||
{
|
||||
const uint32_t now = AP_HAL::millis();
|
||||
|
||||
struct I2C::i2c_msg &msg = data->msgs[0];
|
||||
if (msg.flags == I2C_M_RD) {
|
||||
// driver is attempting to receive reading...
|
||||
if (now - cmd_take_reading_received_ms < 20) {
|
||||
// not sure we ought to be returning -1 here - what does
|
||||
// the real device do? return stale data? garbage data?
|
||||
return -1;
|
||||
}
|
||||
if (msg.len != 2) {
|
||||
AP_HAL::panic("Unxpected message length (%u)", msg.len);
|
||||
}
|
||||
|
||||
const uint16_t range_cm = rangefinder_range * 100;
|
||||
|
||||
msg.buf[0] = range_cm >> 8;
|
||||
msg.buf[1] = range_cm & 0xff;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const uint8_t CMD_TAKE_READING = 0x51;
|
||||
const uint8_t cmd = msg.buf[0];
|
||||
if (cmd != CMD_TAKE_READING) {
|
||||
AP_HAL::panic("Unknown command (%u)", cmd);
|
||||
}
|
||||
cmd_take_reading_received_ms = now;
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
void SITL::MaxSonarI2CXL::update(const Aircraft &aircraft)
|
||||
{
|
||||
rangefinder_range = aircraft.rangefinder_range();
|
||||
}
|
@ -4,16 +4,26 @@
|
||||
|
||||
namespace SITL {
|
||||
|
||||
class MaxSonarI2CXL : public I2CDevice
|
||||
class MaxSonarI2CXL : public I2CDevice, public I2CCommandResponseDevice
|
||||
{
|
||||
public:
|
||||
|
||||
void update(const class Aircraft &aircraft) override;
|
||||
// methods to make I2CCommandResponseDevice happy:
|
||||
uint8_t command_take_reading() const override { return 0x51; }
|
||||
uint16_t reading() const override {
|
||||
return rangefinder_range * 100;
|
||||
};
|
||||
|
||||
void update(const class Aircraft &aircraft) override {
|
||||
rangefinder_range = aircraft.rangefinder_range();
|
||||
}
|
||||
|
||||
int rdwr(I2C::i2c_rdwr_ioctl_data *&data) override {
|
||||
return I2CCommandResponseDevice::rdwr(data);
|
||||
}
|
||||
|
||||
int rdwr(I2C::i2c_rdwr_ioctl_data *&data) override;
|
||||
|
||||
private:
|
||||
uint32_t cmd_take_reading_received_ms;
|
||||
|
||||
float rangefinder_range;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user