I2CDevice.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. /*
  2. * This file is free software: you can redistribute it and/or modify it
  3. * under the terms of the GNU General Public License as published by the
  4. * Free Software Foundation, either version 3 of the License, or
  5. * (at your option) any later version.
  6. *
  7. * This file is distributed in the hope that it will be useful, but
  8. * WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. * See the GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License along
  13. * with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. #include "I2CDevice.h"
  16. #include <AP_HAL/AP_HAL.h>
  17. #include <AP_Math/AP_Math.h>
  18. #include "Util.h"
  19. #if HAL_USE_I2C == TRUE && defined(HAL_I2C_DEVICE_LIST)
  20. #include "Scheduler.h"
  21. #include "hwdef/common/stm32_util.h"
  22. #include <AP_InternalError/AP_InternalError.h>
  23. #include "ch.h"
  24. #include "hal.h"
  25. static const struct I2CInfo {
  26. struct I2CDriver *i2c;
  27. uint8_t dma_channel_rx;
  28. uint8_t dma_channel_tx;
  29. ioline_t scl_line;
  30. ioline_t sda_line;
  31. } I2CD[] = { HAL_I2C_DEVICE_LIST };
  32. using namespace ChibiOS;
  33. extern const AP_HAL::HAL& hal;
  34. I2CBus I2CDeviceManager::businfo[ARRAY_SIZE(I2CD)];
  35. #ifndef HAL_I2C_BUS_BASE
  36. #define HAL_I2C_BUS_BASE 0
  37. #endif
  38. // default to 100kHz clock for maximum reliability. This can be
  39. // changed in hwdef.dat
  40. #ifndef HAL_I2C_MAX_CLOCK
  41. #define HAL_I2C_MAX_CLOCK 100000
  42. #endif
  43. // values calculated with STM32CubeMX tool, PCLK=54MHz
  44. #define HAL_I2C_F7_100_TIMINGR 0x20404768
  45. #define HAL_I2C_F7_400_TIMINGR 0x6000030D
  46. /*
  47. enable clear (toggling SCL) on I2C bus timeouts which leave SDA stuck low
  48. */
  49. #ifndef HAL_I2C_CLEAR_ON_TIMEOUT
  50. #define HAL_I2C_CLEAR_ON_TIMEOUT 1
  51. #endif
  52. // get a handle for DMA sharing DMA channels with other subsystems
  53. void I2CBus::dma_init(void)
  54. {
  55. chMtxObjectInit(&dma_lock);
  56. dma_handle = new Shared_DMA(I2CD[busnum].dma_channel_tx, I2CD[busnum].dma_channel_rx,
  57. FUNCTOR_BIND_MEMBER(&I2CBus::dma_allocate, void, Shared_DMA *),
  58. FUNCTOR_BIND_MEMBER(&I2CBus::dma_deallocate, void, Shared_DMA *));
  59. }
  60. // Clear Bus to avoid bus lockup
  61. void I2CBus::clear_all()
  62. {
  63. for (uint8_t i=0; i<ARRAY_SIZE(I2CD); i++) {
  64. clear_bus(i);
  65. }
  66. }
  67. /*
  68. clear a stuck bus (bus held by a device that is holding SDA low) by
  69. clocking out pulses on SCL to let the device complete its
  70. transaction
  71. */
  72. void I2CBus::clear_bus(uint8_t busidx)
  73. {
  74. #if HAL_I2C_CLEAR_ON_TIMEOUT
  75. const struct I2CInfo &info = I2CD[busidx];
  76. const iomode_t mode_saved = palReadLineMode(info.scl_line);
  77. palSetLineMode(info.scl_line, PAL_MODE_OUTPUT_PUSHPULL);
  78. for(uint8_t j = 0; j < 20; j++) {
  79. palToggleLine(info.scl_line);
  80. hal.scheduler->delay_microseconds(10);
  81. }
  82. palSetLineMode(info.scl_line, mode_saved);
  83. #endif
  84. }
  85. #if HAL_I2C_CLEAR_ON_TIMEOUT
  86. /*
  87. read SDA on a bus, to check if it may be stuck
  88. */
  89. uint8_t I2CBus::read_sda(uint8_t busidx)
  90. {
  91. const struct I2CInfo &info = I2CD[busidx];
  92. const iomode_t mode_saved = palReadLineMode(info.sda_line);
  93. palSetLineMode(info.sda_line, PAL_MODE_INPUT);
  94. uint8_t ret = palReadLine(info.sda_line);
  95. palSetLineMode(info.sda_line, mode_saved);
  96. return ret;
  97. }
  98. #endif
  99. // setup I2C buses
  100. I2CDeviceManager::I2CDeviceManager(void)
  101. {
  102. for (uint8_t i=0; i<ARRAY_SIZE(I2CD); i++) {
  103. businfo[i].busnum = i;
  104. businfo[i].dma_init();
  105. /*
  106. setup default I2C config. As each device is opened we will
  107. drop the speed to be the minimum speed requested
  108. */
  109. businfo[i].busclock = HAL_I2C_MAX_CLOCK;
  110. #if defined(STM32F7) || defined(STM32H7)
  111. if (businfo[i].busclock <= 100000) {
  112. businfo[i].i2ccfg.timingr = HAL_I2C_F7_100_TIMINGR;
  113. businfo[i].busclock = 100000;
  114. } else {
  115. businfo[i].i2ccfg.timingr = HAL_I2C_F7_400_TIMINGR;
  116. businfo[i].busclock = 400000;
  117. }
  118. #else
  119. businfo[i].i2ccfg.op_mode = OPMODE_I2C;
  120. businfo[i].i2ccfg.clock_speed = businfo[i].busclock;
  121. if (businfo[i].i2ccfg.clock_speed <= 100000) {
  122. businfo[i].i2ccfg.duty_cycle = STD_DUTY_CYCLE;
  123. } else {
  124. businfo[i].i2ccfg.duty_cycle = FAST_DUTY_CYCLE_2;
  125. }
  126. #endif
  127. }
  128. }
  129. I2CDevice::I2CDevice(uint8_t busnum, uint8_t address, uint32_t bus_clock, bool use_smbus, uint32_t timeout_ms) :
  130. _retries(2),
  131. _address(address),
  132. _use_smbus(use_smbus),
  133. _timeout_ms(timeout_ms),
  134. bus(I2CDeviceManager::businfo[busnum])
  135. {
  136. set_device_bus(busnum+HAL_I2C_BUS_BASE);
  137. set_device_address(address);
  138. asprintf(&pname, "I2C:%u:%02x",
  139. (unsigned)busnum, (unsigned)address);
  140. if (bus_clock < bus.busclock) {
  141. #if defined(STM32F7) || defined(STM32H7)
  142. if (bus_clock <= 100000) {
  143. bus.i2ccfg.timingr = HAL_I2C_F7_100_TIMINGR;
  144. bus.busclock = 100000;
  145. }
  146. #else
  147. bus.i2ccfg.clock_speed = bus_clock;
  148. bus.busclock = bus_clock;
  149. if (bus_clock <= 100000) {
  150. bus.i2ccfg.duty_cycle = STD_DUTY_CYCLE;
  151. }
  152. #endif
  153. hal.console->printf("I2C%u clock %ukHz\n", busnum, unsigned(bus.busclock/1000));
  154. }
  155. }
  156. I2CDevice::~I2CDevice()
  157. {
  158. #if 0
  159. printf("I2C device bus %u address 0x%02x closed\n",
  160. (unsigned)bus.busnum, (unsigned)_address);
  161. #endif
  162. free(pname);
  163. }
  164. /*
  165. allocate DMA channel, nothing to do, as we don't keep the bus active between transactions
  166. */
  167. void I2CBus::dma_allocate(Shared_DMA *ctx)
  168. {
  169. }
  170. /*
  171. deallocate DMA channel
  172. */
  173. void I2CBus::dma_deallocate(Shared_DMA *)
  174. {
  175. }
  176. bool I2CDevice::transfer(const uint8_t *send, uint32_t send_len,
  177. uint8_t *recv, uint32_t recv_len)
  178. {
  179. if (!bus.semaphore.check_owner()) {
  180. hal.console->printf("I2C: not owner of 0x%x for addr 0x%02x\n", (unsigned)get_bus_id(), _address);
  181. return false;
  182. }
  183. #if defined(STM32F7) || defined(STM32H7)
  184. if (_use_smbus) {
  185. bus.i2ccfg.cr1 |= I2C_CR1_SMBHEN;
  186. } else {
  187. bus.i2ccfg.cr1 &= ~I2C_CR1_SMBHEN;
  188. }
  189. #else
  190. if (_use_smbus) {
  191. bus.i2ccfg.op_mode = OPMODE_SMBUS_HOST;
  192. } else {
  193. bus.i2ccfg.op_mode = OPMODE_I2C;
  194. }
  195. #endif
  196. if (_split_transfers) {
  197. /*
  198. splitting the transfer() into two pieces avoids a stop condition
  199. with SCL low which is not supported on some devices (such as
  200. LidarLite blue label)
  201. */
  202. if (send && send_len) {
  203. if (!_transfer(send, send_len, nullptr, 0)) {
  204. return false;
  205. }
  206. }
  207. if (recv && recv_len) {
  208. if (!_transfer(nullptr, 0, recv, recv_len)) {
  209. return false;
  210. }
  211. }
  212. } else {
  213. // combined transfer
  214. if (!_transfer(send, send_len, recv, recv_len)) {
  215. return false;
  216. }
  217. }
  218. return true;
  219. }
  220. bool I2CDevice::_transfer(const uint8_t *send, uint32_t send_len,
  221. uint8_t *recv, uint32_t recv_len)
  222. {
  223. i2cAcquireBus(I2CD[bus.busnum].i2c);
  224. bus.bouncebuffer_setup(send, send_len, recv, recv_len);
  225. for(uint8_t i=0 ; i <= _retries; i++) {
  226. int ret;
  227. // calculate a timeout as twice the expected transfer time, and set as min of 4ms
  228. uint32_t timeout_ms = 1+2*(((8*1000000UL/bus.busclock)*(send_len+recv_len))/1000);
  229. timeout_ms = MAX(timeout_ms, _timeout_ms);
  230. // we get the lock and start the bus inside the retry loop to
  231. // allow us to give up the DMA channel to an SPI device on
  232. // retries
  233. bus.dma_handle->lock();
  234. i2cStart(I2CD[bus.busnum].i2c, &bus.i2ccfg);
  235. osalDbgAssert(I2CD[bus.busnum].i2c->state == I2C_READY, "i2cStart state");
  236. osalSysLock();
  237. hal.util->persistent_data.i2c_count++;
  238. osalSysUnlock();
  239. if(send_len == 0) {
  240. ret = i2cMasterReceiveTimeout(I2CD[bus.busnum].i2c, _address, recv, recv_len, chTimeMS2I(timeout_ms));
  241. } else {
  242. ret = i2cMasterTransmitTimeout(I2CD[bus.busnum].i2c, _address, send, send_len,
  243. recv, recv_len, chTimeMS2I(timeout_ms));
  244. }
  245. i2cSoftStop(I2CD[bus.busnum].i2c);
  246. osalDbgAssert(I2CD[bus.busnum].i2c->state == I2C_STOP, "i2cStart state");
  247. bus.dma_handle->unlock();
  248. if (I2CD[bus.busnum].i2c->errors & I2C_ISR_LIMIT) {
  249. AP::internalerror().error(AP_InternalError::error_t::i2c_isr);
  250. break;
  251. }
  252. #ifdef STM32_I2C_ISR_LIMIT
  253. AP_HAL::Util::PersistentData &pd = hal.util->persistent_data;
  254. pd.i2c_isr_count += I2CD[bus.busnum].i2c->isr_count;
  255. #endif
  256. if (ret == MSG_OK) {
  257. bus.bouncebuffer_finish(send, recv, recv_len);
  258. i2cReleaseBus(I2CD[bus.busnum].i2c);
  259. return true;
  260. }
  261. #if HAL_I2C_CLEAR_ON_TIMEOUT
  262. if (ret == MSG_TIMEOUT && I2CBus::read_sda(bus.busnum) == 0) {
  263. I2CBus::clear_bus(bus.busnum);
  264. }
  265. #endif
  266. }
  267. bus.bouncebuffer_finish(send, recv, recv_len);
  268. i2cReleaseBus(I2CD[bus.busnum].i2c);
  269. return false;
  270. }
  271. bool I2CDevice::read_registers_multiple(uint8_t first_reg, uint8_t *recv,
  272. uint32_t recv_len, uint8_t times)
  273. {
  274. return false;
  275. }
  276. /*
  277. register a periodic callback
  278. */
  279. AP_HAL::Device::PeriodicHandle I2CDevice::register_periodic_callback(uint32_t period_usec, AP_HAL::Device::PeriodicCb cb)
  280. {
  281. return bus.register_periodic_callback(period_usec, cb, this);
  282. }
  283. /*
  284. adjust a periodic callback
  285. */
  286. bool I2CDevice::adjust_periodic_callback(AP_HAL::Device::PeriodicHandle h, uint32_t period_usec)
  287. {
  288. return bus.adjust_timer(h, period_usec);
  289. }
  290. AP_HAL::OwnPtr<AP_HAL::I2CDevice>
  291. I2CDeviceManager::get_device(uint8_t bus, uint8_t address,
  292. uint32_t bus_clock,
  293. bool use_smbus,
  294. uint32_t timeout_ms)
  295. {
  296. bus -= HAL_I2C_BUS_BASE;
  297. if (bus >= ARRAY_SIZE(I2CD)) {
  298. return AP_HAL::OwnPtr<AP_HAL::I2CDevice>(nullptr);
  299. }
  300. auto dev = AP_HAL::OwnPtr<AP_HAL::I2CDevice>(new I2CDevice(bus, address, bus_clock, use_smbus, timeout_ms));
  301. return dev;
  302. }
  303. /*
  304. get mask of bus numbers for all configured I2C buses
  305. */
  306. uint32_t I2CDeviceManager::get_bus_mask(void) const
  307. {
  308. return ((1U << ARRAY_SIZE(I2CD)) - 1) << HAL_I2C_BUS_BASE;
  309. }
  310. /*
  311. get mask of bus numbers for all configured internal I2C buses
  312. */
  313. uint32_t I2CDeviceManager::get_bus_mask_internal(void) const
  314. {
  315. // assume first bus is internal
  316. return get_bus_mask() & HAL_I2C_INTERNAL_MASK;
  317. }
  318. /*
  319. get mask of bus numbers for all configured external I2C buses
  320. */
  321. uint32_t I2CDeviceManager::get_bus_mask_external(void) const
  322. {
  323. // assume first bus is internal
  324. return get_bus_mask() & ~HAL_I2C_INTERNAL_MASK;
  325. }
  326. #endif // HAL_USE_I2C