Line data Source code
1 : /* 2 : * Copyright (C) 2015 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 : #include <vector> 21 : 22 : #include <AP_HAL/HAL.h> 23 : #include <AP_HAL/SPIDevice.h> 24 : 25 : namespace Linux { 26 : 27 : class SPIBus; 28 : class SPIDesc; 29 : 30 : struct SPIDesc { 31 48 : SPIDesc(const char *name_, uint16_t bus_, uint16_t subdev_, uint8_t mode_, 32 : uint8_t bits_per_word_, int16_t cs_pin_, uint32_t lowspeed_, 33 : uint32_t highspeed_) 34 48 : : name(name_), bus(bus_), subdev(subdev_), mode(mode_) 35 48 : , bits_per_word(bits_per_word_), cs_pin(cs_pin_), lowspeed(lowspeed_) 36 48 : , highspeed(highspeed_) 37 : { 38 48 : } 39 : 40 : const char *name; 41 : uint16_t bus; 42 : uint16_t subdev; 43 : uint8_t mode; 44 : uint8_t bits_per_word; 45 : int16_t cs_pin; 46 : uint32_t lowspeed; 47 : uint32_t highspeed; 48 : }; 49 : 50 : class SPIDevice : public AP_HAL::SPIDevice { 51 : public: 52 : SPIDevice(SPIBus &bus, SPIDesc &device_desc); 53 : 54 : virtual ~SPIDevice(); 55 : 56 : /* AP_HAL::SPIDevice implementation */ 57 : 58 : /* See AP_HAL::Device::set_speed() */ 59 : bool set_speed(AP_HAL::Device::Speed speed) override; 60 : 61 : /* See AP_HAL::Device::transfer() */ 62 : bool transfer(const uint8_t *send, uint32_t send_len, 63 : uint8_t *recv, uint32_t recv_len) override; 64 : 65 : /* See AP_HAL::SPIDevice::transfer_fullduplex() */ 66 : bool transfer_fullduplex(const uint8_t *send, uint8_t *recv, 67 : uint32_t len) override; 68 : 69 : /* See AP_HAL::SPIDevice::transfer_fullduplex() */ 70 : bool transfer_fullduplex(uint8_t *send_recv, uint32_t len) override; 71 : 72 : /* See AP_HAL::Device::get_semaphore() */ 73 : AP_HAL::Semaphore *get_semaphore() override; 74 : 75 : /* See AP_HAL::Device::register_periodic_callback() */ 76 : AP_HAL::Device::PeriodicHandle register_periodic_callback( 77 : uint32_t period_usec, AP_HAL::Device::PeriodicCb) override; 78 : 79 : /* See AP_HAL::Device::adjust_periodic_callback() */ 80 : bool adjust_periodic_callback( 81 : AP_HAL::Device::PeriodicHandle h, uint32_t period_usec) override; 82 : 83 : protected: 84 : SPIBus &_bus; 85 : SPIDesc &_desc; 86 : AP_HAL::DigitalSource *_cs; 87 : uint32_t _speed; 88 : 89 : /* 90 : * Select device if using userspace CS 91 : */ 92 : void _cs_assert(); 93 : 94 : /* 95 : * Deselect device if using userspace CS 96 : */ 97 : void _cs_release(); 98 : }; 99 : 100 : class SPIDeviceManager : public AP_HAL::SPIDeviceManager { 101 : public: 102 : friend class SPIDevice; 103 : 104 0 : static SPIDeviceManager *from(AP_HAL::SPIDeviceManager *spi_mgr) 105 : { 106 0 : return static_cast<SPIDeviceManager*>(spi_mgr); 107 : } 108 : 109 48 : SPIDeviceManager() 110 48 : { 111 : /* Reserve space up-front for 3 buses */ 112 48 : _buses.reserve(3); 113 48 : } 114 : 115 : /* AP_HAL::SPIDeviceManager implementation */ 116 : AP_HAL::SPIDevice *get_device_ptr(const char *name) override; 117 : 118 : /* 119 : * Stop all SPI threads and block until they are finalized. This doesn't 120 : * free memory because they can still be used by devices, however device 121 : * drivers won't receive any new event 122 : */ 123 : void teardown(); 124 : 125 : /* See AP_HAL::SPIDeviceManager::get_count() */ 126 : uint8_t get_count() override; 127 : 128 : /* See AP_HAL::SPIDeviceManager::get_device_name() */ 129 : const char *get_device_name(uint8_t idx) override; 130 : 131 : protected: 132 : void _unregister(SPIBus &b); 133 : AP_HAL::SPIDevice *_create_device(SPIBus &b, SPIDesc &device_desc) const; 134 : 135 : std::vector<SPIBus*> _buses; 136 : 137 : static const uint8_t _n_device_desc; 138 : static SPIDesc _device[]; 139 : }; 140 : 141 : }