I2CDevice.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  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. #include "I2CDevice.h"
  18. #include <algorithm>
  19. #include <assert.h>
  20. #include <dirent.h>
  21. #include <errno.h>
  22. #include <fcntl.h>
  23. #include <limits.h>
  24. #include <linux/i2c-dev.h>
  25. /*
  26. * linux/i2c-dev.h is a kernel header, but some distros rename it to
  27. * linux/i2c-dev.h.kernel when i2c-tools is installed. The header provided by
  28. * i2c-tools is old/broken and contains some symbols defined in
  29. * linux/i2c.h. The i2c.h will be only included if a well-known symbol is not
  30. * defined. This is a workaround while distros propagate the real fix like
  31. * http://lists.opensuse.org/archive/opensuse-commit/2015-10/msg00918.html (or
  32. * do like Archlinux that installs only the kernel header).
  33. */
  34. #ifndef I2C_SMBUS_BLOCK_MAX
  35. #include <linux/i2c.h>
  36. #endif
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include <sys/ioctl.h>
  40. #include <sys/stat.h>
  41. #include <unistd.h>
  42. #include <vector>
  43. #include <AP_HAL/AP_HAL.h>
  44. #include <AP_Math/AP_Math.h>
  45. #include "PollerThread.h"
  46. #include "Scheduler.h"
  47. #include "Semaphores.h"
  48. #include "Thread.h"
  49. #include "Util.h"
  50. /* Workaround broken header from i2c-tools */
  51. #ifndef I2C_RDRW_IOCTL_MAX_MSGS
  52. #define I2C_RDRW_IOCTL_MAX_MSGS 42
  53. #endif
  54. namespace Linux {
  55. static const AP_HAL::HAL &hal = AP_HAL::get_HAL();
  56. /*
  57. * TODO: move to Util or other upper class to be used by others
  58. *
  59. * Return pointer to the next char if @s starts with @prefix, otherwise
  60. * returns nullptr.
  61. */
  62. static inline char *startswith(const char *s, const char *prefix)
  63. {
  64. size_t len = strlen(prefix);
  65. if (strncmp(s, prefix, len) == 0) {
  66. return (char *) s + len;
  67. }
  68. return nullptr;
  69. }
  70. /* Private struct to maintain for each bus */
  71. class I2CBus : public TimerPollable::WrapperCb {
  72. public:
  73. ~I2CBus();
  74. /*
  75. * TimerPollable::WrapperCb methods to take
  76. * and release semaphore while calling the callback
  77. */
  78. void start_cb() override;
  79. void end_cb() override;
  80. int open(uint8_t n);
  81. PollerThread thread;
  82. Semaphore sem;
  83. int fd = -1;
  84. uint8_t bus;
  85. uint8_t ref;
  86. };
  87. I2CBus::~I2CBus()
  88. {
  89. if (fd >= 0) {
  90. ::close(fd);
  91. }
  92. }
  93. void I2CBus::start_cb()
  94. {
  95. sem.take(HAL_SEMAPHORE_BLOCK_FOREVER);
  96. }
  97. void I2CBus::end_cb()
  98. {
  99. sem.give();
  100. }
  101. int I2CBus::open(uint8_t n)
  102. {
  103. char path[sizeof("/dev/i2c-XXX")];
  104. int r;
  105. if (fd >= 0) {
  106. return -EBUSY;
  107. }
  108. r = snprintf(path, sizeof(path), "/dev/i2c-%u", n);
  109. if (r < 0 || r >= (int)sizeof(path)) {
  110. return -EINVAL;
  111. }
  112. fd = ::open(path, O_RDWR | O_CLOEXEC);
  113. if (fd < 0) {
  114. return -errno;
  115. }
  116. bus = n;
  117. return fd;
  118. }
  119. I2CDevice::I2CDevice(I2CBus &bus, uint8_t address)
  120. : _bus(bus)
  121. , _address(address)
  122. {
  123. set_device_bus(bus.bus);
  124. set_device_address(address);
  125. }
  126. I2CDevice::~I2CDevice()
  127. {
  128. // Unregister itself from the I2CDeviceManager
  129. I2CDeviceManager::from(hal.i2c_mgr)->_unregister(_bus);
  130. }
  131. bool I2CDevice::transfer(const uint8_t *send, uint32_t send_len,
  132. uint8_t *recv, uint32_t recv_len)
  133. {
  134. if (_split_transfers && send_len > 0 && recv_len > 0) {
  135. return transfer(send, send_len, nullptr, 0) &&
  136. transfer(nullptr, 0, recv, recv_len);
  137. }
  138. struct i2c_msg msgs[2] = { };
  139. unsigned nmsgs = 0;
  140. assert(_bus.fd >= 0);
  141. if (send && send_len != 0) {
  142. msgs[nmsgs].addr = _address;
  143. msgs[nmsgs].flags = 0;
  144. msgs[nmsgs].buf = const_cast<uint8_t*>(send);
  145. msgs[nmsgs].len = send_len;
  146. nmsgs++;
  147. }
  148. if (recv && recv_len != 0) {
  149. msgs[nmsgs].addr = _address;
  150. msgs[nmsgs].flags = I2C_M_RD;
  151. msgs[nmsgs].buf = recv;
  152. msgs[nmsgs].len = recv_len;
  153. nmsgs++;
  154. }
  155. /* interpret it as an input error if nothing has to be done */
  156. if (!nmsgs) {
  157. return false;
  158. }
  159. struct i2c_rdwr_ioctl_data i2c_data = { };
  160. i2c_data.msgs = msgs;
  161. i2c_data.nmsgs = nmsgs;
  162. int r;
  163. unsigned retries = _retries;
  164. do {
  165. r = ::ioctl(_bus.fd, I2C_RDWR, &i2c_data);
  166. } while (r == -1 && retries-- > 0);
  167. return r != -1;
  168. }
  169. bool I2CDevice::read_registers_multiple(uint8_t first_reg, uint8_t *recv,
  170. uint32_t recv_len, uint8_t times)
  171. {
  172. const uint8_t max_times = I2C_RDRW_IOCTL_MAX_MSGS / 2;
  173. first_reg |= _read_flag;
  174. while (times > 0) {
  175. uint8_t n = MIN(times, max_times);
  176. struct i2c_msg msgs[2 * n];
  177. struct i2c_rdwr_ioctl_data i2c_data = { };
  178. memset(msgs, 0, 2 * n * sizeof(*msgs));
  179. i2c_data.msgs = msgs;
  180. i2c_data.nmsgs = 2 * n;
  181. for (uint8_t i = 0; i < i2c_data.nmsgs; i += 2) {
  182. msgs[i].addr = _address;
  183. msgs[i].flags = 0;
  184. msgs[i].buf = &first_reg;
  185. msgs[i].len = 1;
  186. msgs[i + 1].addr = _address;
  187. msgs[i + 1].flags = I2C_M_RD;
  188. msgs[i + 1].buf = recv;
  189. msgs[i + 1].len = recv_len;
  190. recv += recv_len;
  191. };
  192. int r;
  193. unsigned retries = _retries;
  194. do {
  195. r = ::ioctl(_bus.fd, I2C_RDWR, &i2c_data);
  196. } while (r == -1 && retries-- > 0);
  197. if (r == -1) {
  198. return false;
  199. }
  200. times -= n;
  201. }
  202. return true;
  203. }
  204. AP_HAL::Semaphore *I2CDevice::get_semaphore()
  205. {
  206. return &_bus.sem;
  207. }
  208. AP_HAL::Device::PeriodicHandle I2CDevice::register_periodic_callback(
  209. uint32_t period_usec, AP_HAL::Device::PeriodicCb cb)
  210. {
  211. TimerPollable *p = _bus.thread.add_timer(cb, &_bus, period_usec);
  212. if (!p) {
  213. AP_HAL::panic("Could not create periodic callback");
  214. }
  215. if (!_bus.thread.is_started()) {
  216. char name[16];
  217. snprintf(name, sizeof(name), "ap-i2c-%u", _bus.bus);
  218. _bus.thread.set_stack_size(AP_LINUX_SENSORS_STACK_SIZE);
  219. _bus.thread.start(name, AP_LINUX_SENSORS_SCHED_POLICY,
  220. AP_LINUX_SENSORS_SCHED_PRIO);
  221. }
  222. return static_cast<AP_HAL::Device::PeriodicHandle>(p);
  223. }
  224. bool I2CDevice::adjust_periodic_callback(
  225. AP_HAL::Device::PeriodicHandle h, uint32_t period_usec)
  226. {
  227. return _bus.thread.adjust_timer(static_cast<TimerPollable*>(h), period_usec);
  228. }
  229. I2CDeviceManager::I2CDeviceManager()
  230. {
  231. /* Reserve space up-front for 4 buses */
  232. _buses.reserve(4);
  233. }
  234. AP_HAL::OwnPtr<AP_HAL::I2CDevice>
  235. I2CDeviceManager::get_device(std::vector<const char *> devpaths, uint8_t address)
  236. {
  237. const char *dirname = "/sys/class/i2c-dev/";
  238. struct dirent *de = nullptr;
  239. DIR *d;
  240. d = opendir(dirname);
  241. if (!d) {
  242. AP_HAL::panic("Could not get list of I2C buses");
  243. }
  244. for (de = readdir(d); de; de = readdir(d)) {
  245. char *str_device, *abs_str_device;
  246. const char *p;
  247. if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) {
  248. continue;
  249. }
  250. if (asprintf(&str_device, "%s/%s", dirname, de->d_name) < 0) {
  251. continue;
  252. }
  253. abs_str_device = realpath(str_device, nullptr);
  254. if (!abs_str_device || !(p = startswith(abs_str_device, "/sys/devices/"))) {
  255. free(abs_str_device);
  256. free(str_device);
  257. continue;
  258. }
  259. auto t = std::find_if(std::begin(devpaths), std::end(devpaths),
  260. [p](const char *prefix) {
  261. return startswith(p, prefix) != nullptr;
  262. });
  263. free(abs_str_device);
  264. free(str_device);
  265. if (t != std::end(devpaths)) {
  266. unsigned int n;
  267. /* Found the bus, try to create the device now */
  268. if (sscanf(de->d_name, "i2c-%u", &n) != 1) {
  269. AP_HAL::panic("I2CDevice: can't parse %s", de->d_name);
  270. }
  271. if (n > UINT8_MAX) {
  272. AP_HAL::panic("I2CDevice: bus with number n=%u higher than %u",
  273. n, UINT8_MAX);
  274. }
  275. closedir(d);
  276. return get_device(n, address);
  277. }
  278. }
  279. /* not found */
  280. closedir(d);
  281. return nullptr;
  282. }
  283. AP_HAL::OwnPtr<AP_HAL::I2CDevice>
  284. I2CDeviceManager::get_device(uint8_t bus, uint8_t address,
  285. uint32_t bus_clock,
  286. bool use_smbus,
  287. uint32_t timeout_ms)
  288. {
  289. for (uint8_t i = 0, n = _buses.size(); i < n; i++) {
  290. if (_buses[i]->bus == bus) {
  291. return _create_device(*_buses[i], address);
  292. }
  293. }
  294. /* Bus not found for this device, create a new one */
  295. AP_HAL::OwnPtr<I2CBus> b{new I2CBus()};
  296. if (!b) {
  297. return nullptr;
  298. }
  299. if (b->open(bus) < 0) {
  300. return nullptr;
  301. }
  302. auto dev = _create_device(*b, address);
  303. if (!dev) {
  304. return nullptr;
  305. }
  306. _buses.push_back(b.leak());
  307. return dev;
  308. }
  309. /* Create a new device increasing the bus reference */
  310. AP_HAL::OwnPtr<AP_HAL::I2CDevice>
  311. I2CDeviceManager::_create_device(I2CBus &b, uint8_t address) const
  312. {
  313. auto dev = AP_HAL::OwnPtr<AP_HAL::I2CDevice>(new I2CDevice(b, address));
  314. if (!dev) {
  315. return nullptr;
  316. }
  317. b.ref++;
  318. return dev;
  319. }
  320. void I2CDeviceManager::_unregister(I2CBus &b)
  321. {
  322. assert(b.ref > 0);
  323. if (--b.ref > 0) {
  324. return;
  325. }
  326. for (auto it = _buses.begin(); it != _buses.end(); it++) {
  327. if ((*it)->bus == b.bus) {
  328. _buses.erase(it);
  329. delete &b;
  330. break;
  331. }
  332. }
  333. }
  334. void I2CDeviceManager::teardown()
  335. {
  336. for (auto it = _buses.begin(); it != _buses.end(); it++) {
  337. /* Try to stop thread - it may not even be started yet */
  338. (*it)->thread.stop();
  339. }
  340. for (auto it = _buses.begin(); it != _buses.end(); it++) {
  341. /* Try to join thread - failing is normal if thread was not started */
  342. (*it)->thread.join();
  343. }
  344. }
  345. /*
  346. get mask of bus numbers for all configured I2C buses
  347. */
  348. uint32_t I2CDeviceManager::get_bus_mask(void) const
  349. {
  350. return HAL_LINUX_I2C_BUS_MASK;
  351. }
  352. /*
  353. get mask of bus numbers for all configured internal I2C buses
  354. */
  355. uint32_t I2CDeviceManager::get_bus_mask_internal(void) const
  356. {
  357. return HAL_LINUX_I2C_INTERNAL_BUS_MASK;
  358. }
  359. /*
  360. get mask of bus numbers for all configured external I2C buses
  361. */
  362. uint32_t I2CDeviceManager::get_bus_mask_external(void) const
  363. {
  364. return HAL_LINUX_I2C_EXTERNAL_BUS_MASK;
  365. }
  366. }