I2C.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /* mbed Microcontroller Library
  2. * Copyright (c) 2006-2015 ARM Limited
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "drivers/I2C.h"
  17. #if DEVICE_I2C
  18. #if DEVICE_I2C_ASYNCH
  19. #include "platform/mbed_power_mgmt.h"
  20. #endif
  21. namespace mbed {
  22. I2C *I2C::_owner = NULL;
  23. SingletonPtr<PlatformMutex> I2C::_mutex;
  24. I2C::I2C(PinName sda, PinName scl) :
  25. #if DEVICE_I2C_ASYNCH
  26. _irq(this), _usage(DMA_USAGE_NEVER), _deep_sleep_locked(false),
  27. #endif
  28. _i2c(), _hz(100000)
  29. {
  30. // No lock needed in the constructor
  31. // The init function also set the frequency to 100000
  32. i2c_init(&_i2c, sda, scl);
  33. // Used to avoid unnecessary frequency updates
  34. _owner = this;
  35. }
  36. void I2C::frequency(int hz)
  37. {
  38. lock();
  39. _hz = hz;
  40. // We want to update the frequency even if we are already the bus owners
  41. i2c_frequency(&_i2c, _hz);
  42. // Updating the frequency of the bus we become the owners of it
  43. _owner = this;
  44. unlock();
  45. }
  46. void I2C::aquire()
  47. {
  48. lock();
  49. if (_owner != this) {
  50. i2c_frequency(&_i2c, _hz);
  51. _owner = this;
  52. }
  53. unlock();
  54. }
  55. // write - Master Transmitter Mode
  56. int I2C::write(int address, const char *data, int length, bool repeated)
  57. {
  58. lock();
  59. aquire();
  60. int stop = (repeated) ? 0 : 1;
  61. int written = i2c_write(&_i2c, address, data, length, stop);
  62. unlock();
  63. return length != written;
  64. }
  65. int I2C::write(int data)
  66. {
  67. lock();
  68. int ret = i2c_byte_write(&_i2c, data);
  69. unlock();
  70. return ret;
  71. }
  72. // read - Master Receiver Mode
  73. int I2C::read(int address, char *data, int length, bool repeated)
  74. {
  75. lock();
  76. aquire();
  77. int stop = (repeated) ? 0 : 1;
  78. int read = i2c_read(&_i2c, address, data, length, stop);
  79. unlock();
  80. return length != read;
  81. }
  82. int I2C::read(int ack)
  83. {
  84. lock();
  85. int ret;
  86. if (ack) {
  87. ret = i2c_byte_read(&_i2c, 0);
  88. } else {
  89. ret = i2c_byte_read(&_i2c, 1);
  90. }
  91. unlock();
  92. return ret;
  93. }
  94. void I2C::start(void)
  95. {
  96. lock();
  97. i2c_start(&_i2c);
  98. unlock();
  99. }
  100. void I2C::stop(void)
  101. {
  102. lock();
  103. i2c_stop(&_i2c);
  104. unlock();
  105. }
  106. void I2C::lock()
  107. {
  108. _mutex->lock();
  109. }
  110. void I2C::unlock()
  111. {
  112. _mutex->unlock();
  113. }
  114. #if DEVICE_I2C_ASYNCH
  115. int I2C::transfer(int address, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length, const event_callback_t &callback, int event, bool repeated)
  116. {
  117. lock();
  118. if (i2c_active(&_i2c)) {
  119. unlock();
  120. return -1; // transaction ongoing
  121. }
  122. lock_deep_sleep();
  123. aquire();
  124. _callback = callback;
  125. int stop = (repeated) ? 0 : 1;
  126. _irq.callback(&I2C::irq_handler_asynch);
  127. i2c_transfer_asynch(&_i2c, (void *)tx_buffer, tx_length, (void *)rx_buffer, rx_length, address, stop, _irq.entry(), event, _usage);
  128. unlock();
  129. return 0;
  130. }
  131. void I2C::abort_transfer(void)
  132. {
  133. lock();
  134. i2c_abort_asynch(&_i2c);
  135. unlock_deep_sleep();
  136. unlock();
  137. }
  138. void I2C::irq_handler_asynch(void)
  139. {
  140. int event = i2c_irq_handler_asynch(&_i2c);
  141. if (_callback && event) {
  142. _callback.call(event);
  143. }
  144. if (event) {
  145. unlock_deep_sleep();
  146. }
  147. }
  148. void I2C::lock_deep_sleep()
  149. {
  150. if (_deep_sleep_locked == false) {
  151. sleep_manager_lock_deep_sleep();
  152. _deep_sleep_locked = true;
  153. }
  154. }
  155. void I2C::unlock_deep_sleep()
  156. {
  157. if (_deep_sleep_locked == true) {
  158. sleep_manager_unlock_deep_sleep();
  159. _deep_sleep_locked = false;
  160. }
  161. }
  162. #endif
  163. } // namespace mbed
  164. #endif