Line data Source code
1 : /* 2 : * Copyright (C) 2015-2016 Intel Corporation. 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_Namespace.h" 22 : #include "Device.h" 23 : #include "utility/OwnPtr.h" 24 : 25 : namespace AP_HAL { 26 : 27 : class I2CDevice : public Device { 28 : public: 29 46280 : I2CDevice() : Device(BUS_TYPE_I2C) { } 30 : 31 39874 : virtual ~I2CDevice() { } 32 : 33 : /* Device implementation */ 34 : 35 : /* See Device::set_speed() */ 36 : virtual bool set_speed(Device::Speed speed) override = 0; 37 : 38 : /* See Device::transfer() */ 39 : virtual bool transfer(const uint8_t *send, uint32_t send_len, 40 : uint8_t *recv, uint32_t recv_len) override = 0; 41 : 42 : /* 43 : * Read location from device multiple times, advancing the buffer each 44 : * time 45 : */ 46 : virtual bool read_registers_multiple(uint8_t first_reg, uint8_t *recv, 47 : uint32_t recv_len, uint8_t times) = 0; 48 : 49 : /* See Device::get_semaphore() */ 50 : virtual Semaphore *get_semaphore() override = 0; 51 : 52 : /* See Device::register_periodic_callback() */ 53 : virtual Device::PeriodicHandle register_periodic_callback( 54 : uint32_t period_usec, Device::PeriodicCb) override = 0; 55 : 56 : /* See Device::adjust_periodic_callback() */ 57 : virtual bool adjust_periodic_callback( 58 : Device::PeriodicHandle h, uint32_t period_usec) override = 0; 59 : 60 : /* 61 : * Force I2C transfers to be split between send and receive parts, with a 62 : * stop condition between them. Setting this allows to conveniently 63 : * continue using the read_* and transfer() methods on those devices. 64 : * 65 : * Some platforms may have transfers always split, in which case 66 : * this method is not needed. 67 : */ 68 0 : virtual void set_split_transfers(bool set) {}; 69 : }; 70 : 71 : class I2CDeviceManager { 72 : public: 73 : /* Get a pointer to a newly-allocated I2CDevice handle. Lifetime 74 : * is externally handled */ 75 : virtual AP_HAL::I2CDevice *get_device_ptr(uint8_t bus, uint8_t address, 76 : uint32_t bus_clock=400000, 77 : bool use_smbus = false, 78 : uint32_t timeout_ms=4) = 0; 79 : /* Get a device handle. Lifetime is handled by OwnPtr system. 80 : * Progressively being eliminated */ 81 20940 : OwnPtr<AP_HAL::I2CDevice> get_device(uint8_t bus, uint8_t address, 82 : uint32_t bus_clock=400000, 83 : bool use_smbus = false, 84 : uint32_t timeout_ms=4) { 85 20940 : return AP_HAL::OwnPtr<AP_HAL::I2CDevice>(get_device_ptr(bus, address, bus_clock, use_smbus, timeout_ms)); 86 : } 87 : ; 88 : /* 89 : get mask of bus numbers for all configured I2C buses 90 : */ 91 2109 : virtual uint32_t get_bus_mask(void) const { return 0x0F; } 92 : 93 : /* 94 : get mask of bus numbers for all configured external I2C buses 95 : */ 96 6282 : virtual uint32_t get_bus_mask_external(void) const { return 0x0F; } 97 : 98 : /* 99 : get mask of bus numbers for all configured internal I2C buses 100 : */ 101 6282 : virtual uint32_t get_bus_mask_internal(void) const { return 0x01; } 102 : }; 103 : 104 : /* 105 : convenient macros for iterating over I2C bus numbers 106 : */ 107 : #define FOREACH_I2C_MASK(i,mask) for (uint32_t _bmask=mask, i=0; i<32; i++) if ((1U<<i)&_bmask) 108 : #define FOREACH_I2C_EXTERNAL(i) FOREACH_I2C_MASK(i,hal.i2c_mgr->get_bus_mask_external()) 109 : #define FOREACH_I2C_INTERNAL(i) FOREACH_I2C_MASK(i,hal.i2c_mgr->get_bus_mask_internal()) 110 : #define FOREACH_I2C(i) FOREACH_I2C_MASK(i,hal.i2c_mgr->get_bus_mask()) 111 : 112 : }