tommasta

Wire.cpp

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