Wire.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. /*
  2. TwoWire.cpp - TWI/I2C library for Wiring & Arduino
  3. Copyright (c) 2006 Nicholas Zambetti. All right reserved.
  4. This library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. This library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with this library; if not, write to the Free Software
  14. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  15. Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts
  16. */
  17. extern "C" {
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <inttypes.h>
  21. #include "twi.h"
  22. }
  23. #include "Wire.h"
  24. // Initialize Class Variables //////////////////////////////////////////////////
  25. uint8_t TwoWire::rxBuffer[BUFFER_LENGTH];
  26. uint8_t TwoWire::rxBufferIndex = 0;
  27. uint8_t TwoWire::rxBufferLength = 0;
  28. uint8_t TwoWire::txAddress = 0;
  29. uint8_t TwoWire::txBuffer[BUFFER_LENGTH];
  30. uint8_t TwoWire::txBufferIndex = 0;
  31. uint8_t TwoWire::txBufferLength = 0;
  32. uint8_t TwoWire::transmitting = 0;
  33. void (*TwoWire::user_onRequest)(void);
  34. void (*TwoWire::user_onReceive)(int);
  35. // Constructors ////////////////////////////////////////////////////////////////
  36. TwoWire::TwoWire()
  37. {
  38. }
  39. // Public Methods //////////////////////////////////////////////////////////////
  40. void TwoWire::begin(void)
  41. {
  42. rxBufferIndex = 0;
  43. rxBufferLength = 0;
  44. txBufferIndex = 0;
  45. txBufferLength = 0;
  46. twi_init();
  47. }
  48. void TwoWire::begin(uint8_t address)
  49. {
  50. twi_setAddress(address);
  51. twi_attachSlaveTxEvent(onRequestService);
  52. twi_attachSlaveRxEvent(onReceiveService);
  53. begin();
  54. }
  55. void TwoWire::begin(int address)
  56. {
  57. begin((uint8_t)address);
  58. }
  59. void TwoWire::setClock(uint32_t frequency)
  60. {
  61. TWBR = ((F_CPU / frequency) - 16) / 2;
  62. }
  63. uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop)
  64. {
  65. // clamp to buffer length
  66. if(quantity > BUFFER_LENGTH){
  67. quantity = BUFFER_LENGTH;
  68. }
  69. // perform blocking read into buffer
  70. uint8_t read = twi_readFrom(address, rxBuffer, quantity, sendStop);
  71. // set rx buffer iterator vars
  72. rxBufferIndex = 0;
  73. rxBufferLength = read;
  74. return read;
  75. }
  76. uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity)
  77. {
  78. return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true);
  79. }
  80. uint8_t TwoWire::requestFrom(int address, int quantity)
  81. {
  82. return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true);
  83. }
  84. uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop)
  85. {
  86. return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)sendStop);
  87. }
  88. void TwoWire::beginTransmission(uint8_t address)
  89. {
  90. // indicate that we are transmitting
  91. transmitting = 1;
  92. // set address of targeted slave
  93. txAddress = address;
  94. // reset tx buffer iterator vars
  95. txBufferIndex = 0;
  96. txBufferLength = 0;
  97. }
  98. void TwoWire::beginTransmission(int address)
  99. {
  100. beginTransmission((uint8_t)address);
  101. }
  102. //
  103. // Originally, 'endTransmission' was an f(void) function.
  104. // It has been modified to take one parameter indicating
  105. // whether or not a STOP should be performed on the bus.
  106. // Calling endTransmission(false) allows a sketch to
  107. // perform a repeated start.
  108. //
  109. // WARNING: Nothing in the library keeps track of whether
  110. // the bus tenure has been properly ended with a STOP. It
  111. // is very possible to leave the bus in a hung state if
  112. // no call to endTransmission(true) is made. Some I2C
  113. // devices will behave oddly if they do not see a STOP.
  114. //
  115. uint8_t TwoWire::endTransmission(uint8_t sendStop)
  116. {
  117. // transmit buffer (blocking)
  118. int8_t ret = twi_writeTo(txAddress, txBuffer, txBufferLength, 1, sendStop);
  119. // reset tx buffer iterator vars
  120. txBufferIndex = 0;
  121. txBufferLength = 0;
  122. // indicate that we are done transmitting
  123. transmitting = 0;
  124. return ret;
  125. }
  126. // This provides backwards compatibility with the original
  127. // definition, and expected behaviour, of endTransmission
  128. //
  129. uint8_t TwoWire::endTransmission(void)
  130. {
  131. return endTransmission(true);
  132. }
  133. // must be called in:
  134. // slave tx event callback
  135. // or after beginTransmission(address)
  136. size_t TwoWire::write(uint8_t data)
  137. {
  138. if(transmitting){
  139. // in master transmitter mode
  140. // don't bother if buffer is full
  141. if(txBufferLength >= BUFFER_LENGTH){
  142. setWriteError();
  143. return 0;
  144. }
  145. // put byte in tx buffer
  146. txBuffer[txBufferIndex] = data;
  147. ++txBufferIndex;
  148. // update amount in buffer
  149. txBufferLength = txBufferIndex;
  150. }else{
  151. // in slave send mode
  152. // reply to master
  153. twi_transmit(&data, 1);
  154. }
  155. return 1;
  156. }
  157. // must be called in:
  158. // slave tx event callback
  159. // or after beginTransmission(address)
  160. size_t TwoWire::write(const uint8_t *data, size_t quantity)
  161. {
  162. if(transmitting){
  163. // in master transmitter mode
  164. for(size_t i = 0; i < quantity; ++i){
  165. write(data[i]);
  166. }
  167. }else{
  168. // in slave send mode
  169. // reply to master
  170. twi_transmit(data, quantity);
  171. }
  172. return quantity;
  173. }
  174. // must be called in:
  175. // slave rx event callback
  176. // or after requestFrom(address, numBytes)
  177. int TwoWire::available(void)
  178. {
  179. return rxBufferLength - rxBufferIndex;
  180. }
  181. // must be called in:
  182. // slave rx event callback
  183. // or after requestFrom(address, numBytes)
  184. int TwoWire::read(void)
  185. {
  186. int value = -1;
  187. // get each successive byte on each call
  188. if(rxBufferIndex < rxBufferLength){
  189. value = rxBuffer[rxBufferIndex];
  190. ++rxBufferIndex;
  191. }
  192. return value;
  193. }
  194. // must be called in:
  195. // slave rx event callback
  196. // or after requestFrom(address, numBytes)
  197. int TwoWire::peek(void)
  198. {
  199. int value = -1;
  200. if(rxBufferIndex < rxBufferLength){
  201. value = rxBuffer[rxBufferIndex];
  202. }
  203. return value;
  204. }
  205. void TwoWire::flush(void)
  206. {
  207. // XXX: to be implemented.
  208. }
  209. // behind the scenes function that is called when data is received
  210. void TwoWire::onReceiveService(uint8_t* inBytes, int numBytes)
  211. {
  212. // don't bother if user hasn't registered a callback
  213. if(!user_onReceive){
  214. return;
  215. }
  216. // don't bother if rx buffer is in use by a master requestFrom() op
  217. // i know this drops data, but it allows for slight stupidity
  218. // meaning, they may not have read all the master requestFrom() data yet
  219. if(rxBufferIndex < rxBufferLength){
  220. return;
  221. }
  222. // copy twi rx buffer into local read buffer
  223. // this enables new reads to happen in parallel
  224. for(uint8_t i = 0; i < numBytes; ++i){
  225. rxBuffer[i] = inBytes[i];
  226. }
  227. // set rx iterator vars
  228. rxBufferIndex = 0;
  229. rxBufferLength = numBytes;
  230. // alert user program
  231. user_onReceive(numBytes);
  232. }
  233. // behind the scenes function that is called when data is requested
  234. void TwoWire::onRequestService(void)
  235. {
  236. // don't bother if user hasn't registered a callback
  237. if(!user_onRequest){
  238. return;
  239. }
  240. // reset tx buffer iterator vars
  241. // !!! this will kill any pending pre-master sendTo() activity
  242. txBufferIndex = 0;
  243. txBufferLength = 0;
  244. // alert user program
  245. user_onRequest();
  246. }
  247. // sets function called on slave write
  248. void TwoWire::onReceive( void (*function)(int) )
  249. {
  250. user_onReceive = function;
  251. }
  252. // sets function called on slave read
  253. void TwoWire::onRequest( void (*function)(void) )
  254. {
  255. user_onRequest = function;
  256. }
  257. // Preinstantiate Objects //////////////////////////////////////////////////////
  258. TwoWire Wire = TwoWire();