2020-08-03 00:24:27 -03:00
|
|
|
/*
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
/*
|
|
|
|
Simulated i2c buses and devices
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include <GCS_MAVLink/GCS.h>
|
|
|
|
#include <SITL/SITL.h>
|
|
|
|
|
|
|
|
#include "SIM_I2C.h"
|
|
|
|
#include "SIM_ToshibaLED.h"
|
2020-08-03 00:23:10 -03:00
|
|
|
#include "SIM_MaxSonarI2CXL.h"
|
2020-10-20 19:41:31 -03:00
|
|
|
#include "SIM_BattMonitor_SMBus_Maxell.h"
|
2020-11-11 00:03:49 -04:00
|
|
|
#include "SIM_BattMonitor_SMBus_Rotoye.h"
|
2020-12-10 20:21:49 -04:00
|
|
|
#include "SIM_Airspeed_DLVR.h"
|
2021-01-03 20:51:04 -04:00
|
|
|
#include "SIM_Temperature_TSYS01.h"
|
2021-01-10 20:10:01 -04:00
|
|
|
#include "SIM_ICM40609.h"
|
2021-07-11 22:55:35 -03:00
|
|
|
#include "SIM_MS5525.h"
|
2021-07-13 00:26:37 -03:00
|
|
|
#include "SIM_MS5611.h"
|
2020-08-03 00:24:27 -03:00
|
|
|
|
|
|
|
#include <signal.h>
|
|
|
|
|
|
|
|
using namespace SITL;
|
|
|
|
|
|
|
|
enum class IOCtlType {
|
|
|
|
RDWR = 0,
|
|
|
|
};
|
|
|
|
|
|
|
|
class IgnoredI2CDevice : public I2CDevice
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
int rdwr(I2C::i2c_rdwr_ioctl_data *&data) override {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
static IgnoredI2CDevice ignored;
|
|
|
|
|
|
|
|
static ToshibaLED toshibaled;
|
2020-08-03 00:23:10 -03:00
|
|
|
static MaxSonarI2CXL maxsonari2cxl;
|
2021-01-13 07:02:20 -04:00
|
|
|
static MaxSonarI2CXL maxsonari2cxl_2;
|
2020-10-20 19:41:31 -03:00
|
|
|
static Maxell maxell;
|
2020-11-11 00:03:49 -04:00
|
|
|
static Rotoye rotoye;
|
2020-12-10 20:21:49 -04:00
|
|
|
static Airspeed_DLVR airspeed_dlvr;
|
2021-01-03 20:51:04 -04:00
|
|
|
static TSYS01 tsys01;
|
2021-01-10 20:10:01 -04:00
|
|
|
static ICM40609 icm40609;
|
2021-07-11 22:55:35 -03:00
|
|
|
static MS5525 ms5525;
|
2021-07-13 00:26:37 -03:00
|
|
|
static MS5611 ms5611;
|
2020-08-03 00:24:27 -03:00
|
|
|
|
|
|
|
struct i2c_device_at_address {
|
|
|
|
uint8_t bus;
|
|
|
|
uint8_t addr;
|
|
|
|
I2CDevice &device;
|
|
|
|
} i2c_devices[] {
|
2021-01-03 04:12:20 -04:00
|
|
|
{ 0, 0x70, maxsonari2cxl },
|
2021-01-13 07:02:20 -04:00
|
|
|
{ 0, 0x71, maxsonari2cxl_2 },
|
2021-01-10 20:10:01 -04:00
|
|
|
{ 1, 0x01, icm40609 },
|
2020-08-03 00:24:27 -03:00
|
|
|
{ 1, 0x55, toshibaled },
|
|
|
|
{ 1, 0x38, ignored }, // NCP5623
|
|
|
|
{ 1, 0x39, ignored }, // NCP5623C
|
|
|
|
{ 1, 0x40, ignored }, // KellerLD
|
2021-07-11 22:55:35 -03:00
|
|
|
{ 1, 0x76, ms5525 },
|
2021-01-03 20:51:04 -04:00
|
|
|
{ 1, 0x77, tsys01 },
|
2021-01-04 01:39:08 -04:00
|
|
|
{ 1, 0x0B, rotoye },
|
2021-06-08 02:22:42 -03:00
|
|
|
{ 2, 0x0B, maxell },
|
2020-12-10 20:21:49 -04:00
|
|
|
{ 2, 0x28, airspeed_dlvr },
|
2021-07-13 00:26:37 -03:00
|
|
|
{ 2, 0x77, ms5611 },
|
2020-08-03 00:24:27 -03:00
|
|
|
};
|
|
|
|
|
2020-10-20 19:41:31 -03:00
|
|
|
void I2C::init()
|
|
|
|
{
|
|
|
|
for (auto &i : i2c_devices) {
|
|
|
|
i.device.init();
|
|
|
|
}
|
2021-01-02 22:34:53 -04:00
|
|
|
|
|
|
|
// sanity check the i2c_devices structure to ensure we don't have
|
|
|
|
// two devices at the same address on the same bus:
|
|
|
|
for (uint8_t i=0; i<ARRAY_SIZE(i2c_devices)-1; i++) {
|
|
|
|
const auto &dev_i = i2c_devices[i];
|
|
|
|
for (uint8_t j=i+1; j<ARRAY_SIZE(i2c_devices); j++) {
|
|
|
|
const auto &dev_j = i2c_devices[j];
|
|
|
|
if (dev_i.bus == dev_j.bus &&
|
|
|
|
dev_i.addr == dev_j.addr) {
|
|
|
|
AP_HAL::panic("Two devices at the same address on the same bus");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-10-20 19:41:31 -03:00
|
|
|
}
|
|
|
|
|
2020-08-03 00:24:27 -03:00
|
|
|
void I2C::update(const class Aircraft &aircraft)
|
|
|
|
{
|
|
|
|
for (auto daa : i2c_devices) {
|
|
|
|
daa.device.update(aircraft);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int I2C::ioctl_rdwr(i2c_rdwr_ioctl_data *data)
|
|
|
|
{
|
2021-01-03 20:23:26 -04:00
|
|
|
const uint8_t addr = data->msgs[0].addr;
|
|
|
|
const uint8_t bus = data->msgs[0].bus;
|
|
|
|
for (auto &dev_at_address : i2c_devices) {
|
|
|
|
if (dev_at_address.addr != addr) {
|
|
|
|
continue;
|
2020-08-03 00:24:27 -03:00
|
|
|
}
|
2021-01-03 20:23:26 -04:00
|
|
|
if (dev_at_address.bus != bus) {
|
|
|
|
continue;
|
2020-08-03 00:24:27 -03:00
|
|
|
}
|
2021-01-03 20:23:26 -04:00
|
|
|
return dev_at_address.device.rdwr(data);
|
2020-08-03 00:24:27 -03:00
|
|
|
}
|
2021-01-03 20:23:26 -04:00
|
|
|
// ::fprintf(stderr, "Unhandled i2c message: bus=%u addr=0x%02x flags=%u len=%u\n", msg.bus, msg.addr, msg.flags, msg.len);
|
|
|
|
return -1; // ?!
|
2020-08-03 00:24:27 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
int I2C::ioctl(uint8_t ioctl_type, void *data)
|
|
|
|
{
|
|
|
|
switch ((IOCtlType) ioctl_type) {
|
|
|
|
case IOCtlType::RDWR:
|
|
|
|
return ioctl_rdwr((i2c_rdwr_ioctl_data*)data);
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|