Line data Source code
1 : /* 2 : * Copyright (C) 2020 Peter Barker. All rights reserved. 3 : * 4 : * This file is free software: you can redistribute it and/or modify it 5 : * under the terms of the GNU General Public License as published by the 6 : * Free Software Foundation, either version 3 of the License, or 7 : * (at your option) any later version. 8 : * 9 : * This file is distributed in the hope that it will be useful, but 10 : * WITHOUT ANY WARRANTY; without even the implied warranty of 11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 : * See the GNU General Public License for more details. 13 : * 14 : * You should have received a copy of the GNU General Public License along 15 : * with this program. If not, see <http://www.gnu.org/licenses/>. 16 : */ 17 : #pragma once 18 : 19 : #include <inttypes.h> 20 : 21 : #include <AP_HAL/HAL.h> 22 : #if CONFIG_HAL_BOARD == HAL_BOARD_SITL 23 : 24 : #include <AP_HAL/I2CDevice.h> 25 : 26 : #include "AP_HAL_SITL_Namespace.h" 27 : #include "Semaphores.h" 28 : 29 : class I2CBus; 30 : 31 : class HALSITL::I2CDevice : public AP_HAL::I2CDevice { 32 : public: 33 : static I2CDevice *from(AP_HAL::I2CDevice *dev) { 34 : return static_cast<I2CDevice*>(dev); 35 : } 36 : 37 : /* AP_HAL::I2CDevice implementation */ 38 : 39 : I2CDevice(I2CBus &bus, uint8_t address); 40 : 41 79748 : ~I2CDevice() {} 42 : 43 : /* See AP_HAL::I2CDevice::set_address() */ 44 0 : void set_address(uint8_t address) override { _address = address; } 45 : 46 : /* See AP_HAL::I2CDevice::set_retries() */ 47 52634 : void set_retries(uint8_t retries) override { _retries = retries; } 48 : 49 : /* AP_HAL::Device implementation */ 50 : 51 : /* See AP_HAL::Device::set_speed(): Empty implementation, not supported. */ 52 10 : bool set_speed(enum Device::Speed speed) override { return true; } 53 : 54 : /* See AP_HAL::Device::transfer() */ 55 : bool transfer(const uint8_t *send, uint32_t send_len, 56 : uint8_t *recv, uint32_t recv_len) override; 57 : 58 : bool read_registers_multiple(uint8_t first_reg, uint8_t *recv, 59 : uint32_t recv_len, uint8_t times) override; 60 : 61 : /* See AP_HAL::Device::get_semaphore() */ 62 : AP_HAL::Semaphore *get_semaphore() override; 63 : 64 : /* See AP_HAL::Device::register_periodic_callback() */ 65 : AP_HAL::Device::PeriodicHandle register_periodic_callback( 66 : uint32_t period_usec, AP_HAL::Device::PeriodicCb) override; 67 : 68 : /* See AP_HAL::Device::adjust_periodic_callback() */ 69 : bool adjust_periodic_callback( 70 : AP_HAL::Device::PeriodicHandle h, uint32_t period_usec) override; 71 : 72 : /* set split transfers flag */ 73 0 : void set_split_transfers(bool set) override { 74 0 : _split_transfers = set; 75 0 : } 76 : 77 : static void sitl_update(); 78 : 79 : // the following must be identical to the structure in SITL/SIM_I2C.h! 80 : #define I2C_M_RD 1 81 : #define I2C_RDWR 0 82 : struct i2c_msg { 83 : uint8_t bus; 84 : uint8_t addr; 85 : uint8_t flags; 86 : uint8_t *buf; 87 : uint16_t len; // FIXME: what type should this be? 88 : }; 89 : struct i2c_rdwr_ioctl_data { 90 : i2c_msg *msgs; 91 : uint8_t nmsgs; 92 : }; 93 : // end "the following" 94 : 95 : protected: 96 : I2CBus &_bus; 97 : uint8_t _address; 98 : uint8_t _retries; 99 : bool _split_transfers = false; 100 : 101 : bool _transfer(const uint8_t *send, uint32_t send_len, 102 : uint8_t *recv, uint32_t recv_len); 103 : }; 104 : 105 : class HALSITL::I2CDeviceManager : public AP_HAL::I2CDeviceManager { 106 : public: 107 : friend class I2CDevice; 108 : 109 : static I2CDeviceManager *from(AP_HAL::I2CDeviceManager *i2c_mgr) 110 : { 111 : return static_cast<I2CDeviceManager*>(i2c_mgr); 112 : } 113 : 114 : I2CDeviceManager(); 115 505 : ~I2CDeviceManager() {}; 116 : 117 : void _timer_tick(); // in lieu of a thread-per-bus 118 : 119 : /* AP_HAL::I2CDeviceManager implementation */ 120 : AP_HAL::I2CDevice *get_device_ptr(uint8_t bus, uint8_t address, 121 : uint32_t bus_clock=400000, 122 : bool use_smbus = false, 123 : uint32_t timeout_ms=4) override; 124 : 125 : protected: 126 : 127 : #define NUM_SITL_I2C_BUSES 4 128 : static I2CBus buses[]; 129 : }; 130 : #endif //#if CONFIG_HAL_BOARD == HAL_BOARD_SITL