Wire.cpp
Go to the documentation of this file.
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  Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts
20 */
21 
22 extern "C" {
23  #include <stdlib.h>
24  #include <string.h>
25  #include <inttypes.h>
26  #include "utility/twi.h"
27 }
28 
29 #include "Wire.h"
30 
31 // Initialize Class Variables //////////////////////////////////////////////////
32 
34 uint8_t TwoWire::rxBufferIndex = 0;
35 uint8_t TwoWire::rxBufferLength = 0;
36 
37 uint8_t TwoWire::txAddress = 0;
39 uint8_t TwoWire::txBufferIndex = 0;
40 uint8_t TwoWire::txBufferLength = 0;
41 
42 uint8_t TwoWire::transmitting = 0;
45 
46 // Constructors ////////////////////////////////////////////////////////////////
47 
49 {
50 }
51 
52 // Public Methods //////////////////////////////////////////////////////////////
53 
54 void TwoWire::begin(void)
55 {
56  rxBufferIndex = 0;
57  rxBufferLength = 0;
58 
59  txBufferIndex = 0;
60  txBufferLength = 0;
61 
62  twi_init();
63 }
64 
65 void TwoWire::begin(uint8_t address)
66 {
67  twi_setAddress(address);
70  begin();
71 }
72 
74 {
75  begin((uint8_t)address);
76 }
77 
78 void TwoWire::end(void)
79 {
80  twi_disable();
81 }
82 
84 {
85  twi_setFrequency(clock);
86 }
87 
88 uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint32_t iaddress, uint8_t isize, uint8_t sendStop)
89 {
90  if (isize > 0) {
91  // send internal address; this mode allows sending a repeated start to access
92  // some devices' internal registers. This function is executed by the hardware
93  // TWI module on other processors (for example Due's TWI_IADR and TWI_MMR registers)
94 
95  beginTransmission(address);
96 
97  // the maximum size of internal address is 3 bytes
98  if (isize > 3){
99  isize = 3;
100  }
101 
102  // write internal register address - most significant byte first
103  while (isize-- > 0)
104  write((uint8_t)(iaddress >> (isize*8)));
105  endTransmission(false);
106  }
107 
108  // clamp to buffer length
109  if(quantity > BUFFER_LENGTH){
110  quantity = BUFFER_LENGTH;
111  }
112  // perform blocking read into buffer
113  uint8_t read = twi_readFrom(address, rxBuffer, quantity, sendStop);
114  // set rx buffer iterator vars
115  rxBufferIndex = 0;
117 
118  return read;
119 }
120 
121 uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop) {
122  return requestFrom((uint8_t)address, (uint8_t)quantity, (uint32_t)0, (uint8_t)0, (uint8_t)sendStop);
123 }
124 
125 uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity)
126 {
127  return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true);
128 }
129 
130 uint8_t TwoWire::requestFrom(int address, int quantity)
131 {
132  return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true);
133 }
134 
135 uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop)
136 {
137  return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)sendStop);
138 }
139 
141 {
142  // indicate that we are transmitting
143  transmitting = 1;
144  // set address of targeted slave
145  txAddress = address;
146  // reset tx buffer iterator vars
147  txBufferIndex = 0;
148  txBufferLength = 0;
149 }
150 
152 {
153  beginTransmission((uint8_t)address);
154 }
155 
156 //
157 // Originally, 'endTransmission' was an f(void) function.
158 // It has been modified to take one parameter indicating
159 // whether or not a STOP should be performed on the bus.
160 // Calling endTransmission(false) allows a sketch to
161 // perform a repeated start.
162 //
163 // WARNING: Nothing in the library keeps track of whether
164 // the bus tenure has been properly ended with a STOP. It
165 // is very possible to leave the bus in a hung state if
166 // no call to endTransmission(true) is made. Some I2C
167 // devices will behave oddly if they do not see a STOP.
168 //
169 uint8_t TwoWire::endTransmission(uint8_t sendStop)
170 {
171  // transmit buffer (blocking)
172  uint8_t ret = twi_writeTo(txAddress, txBuffer, txBufferLength, 1, sendStop);
173  // reset tx buffer iterator vars
174  txBufferIndex = 0;
175  txBufferLength = 0;
176  // indicate that we are done transmitting
177  transmitting = 0;
178  return ret;
179 }
180 
181 // This provides backwards compatibility with the original
182 // definition, and expected behaviour, of endTransmission
183 //
185 {
186  return endTransmission(true);
187 }
188 
189 // must be called in:
190 // slave tx event callback
191 // or after beginTransmission(address)
192 size_t TwoWire::write(uint8_t data)
193 {
194  if(transmitting){
195  // in master transmitter mode
196  // don't bother if buffer is full
198  setWriteError();
199  return 0;
200  }
201  // put byte in tx buffer
202  txBuffer[txBufferIndex] = data;
203  ++txBufferIndex;
204  // update amount in buffer
206  }else{
207  // in slave send mode
208  // reply to master
209  twi_transmit(&data, 1);
210  }
211  return 1;
212 }
213 
214 // must be called in:
215 // slave tx event callback
216 // or after beginTransmission(address)
217 size_t TwoWire::write(const uint8_t *data, size_t quantity)
218 {
219  if(transmitting){
220  // in master transmitter mode
221  for(size_t i = 0; i < quantity; ++i){
222  write(data[i]);
223  }
224  }else{
225  // in slave send mode
226  // reply to master
227  twi_transmit(data, quantity);
228  }
229  return quantity;
230 }
231 
232 // must be called in:
233 // slave rx event callback
234 // or after requestFrom(address, numBytes)
236 {
237  return rxBufferLength - rxBufferIndex;
238 }
239 
240 // must be called in:
241 // slave rx event callback
242 // or after requestFrom(address, numBytes)
243 int TwoWire::read(void)
244 {
245  int value = -1;
246 
247  // get each successive byte on each call
249  value = rxBuffer[rxBufferIndex];
250  ++rxBufferIndex;
251  }
252 
253  return value;
254 }
255 
256 // must be called in:
257 // slave rx event callback
258 // or after requestFrom(address, numBytes)
259 int TwoWire::peek(void)
260 {
261  int value = -1;
262 
264  value = rxBuffer[rxBufferIndex];
265  }
266 
267  return value;
268 }
269 
270 void TwoWire::flush(void)
271 {
272  // XXX: to be implemented.
273 }
274 
275 // behind the scenes function that is called when data is received
276 void TwoWire::onReceiveService(uint8_t* inBytes, int numBytes)
277 {
278  // don't bother if user hasn't registered a callback
279  if(!user_onReceive){
280  return;
281  }
282  // don't bother if rx buffer is in use by a master requestFrom() op
283  // i know this drops data, but it allows for slight stupidity
284  // meaning, they may not have read all the master requestFrom() data yet
286  return;
287  }
288  // copy twi rx buffer into local read buffer
289  // this enables new reads to happen in parallel
290  for(uint8_t i = 0; i < numBytes; ++i){
291  rxBuffer[i] = inBytes[i];
292  }
293  // set rx iterator vars
294  rxBufferIndex = 0;
295  rxBufferLength = numBytes;
296  // alert user program
297  user_onReceive(numBytes);
298 }
299 
300 // behind the scenes function that is called when data is requested
302 {
303  // don't bother if user hasn't registered a callback
304  if(!user_onRequest){
305  return;
306  }
307  // reset tx buffer iterator vars
308  // !!! this will kill any pending pre-master sendTo() activity
309  txBufferIndex = 0;
310  txBufferLength = 0;
311  // alert user program
312  user_onRequest();
313 }
314 
315 // sets function called on slave write
316 void TwoWire::onReceive( void (*function)(int) )
317 {
318  user_onReceive = function;
319 }
320 
321 // sets function called on slave read
322 void TwoWire::onRequest( void (*function)(void) )
323 {
324  user_onRequest = function;
325 }
326 
327 // Preinstantiate Objects //////////////////////////////////////////////////////
328 
330 
void twi_attachSlaveRxEvent(void(*)(uint8_t *, int))
Definition: twi.c:331
virtual int peek(void)
Definition: Wire.cpp:259
void setWriteError(int err=1)
Definition: Print.h:44
GLvoid *typedef void(GLAPIENTRY *PFNGLGETVERTEXATTRIBDVPROC)(GLuint
static uint8_t transmitting
Definition: Wire.h:45
static void(* user_onRequest)(void)
Definition: Wire.h:46
virtual size_t write(uint8_t)
Definition: Wire.cpp:192
TwoWire Wire
Definition: Wire.cpp:329
static void onRequestService(void)
Definition: Wire.cpp:301
uint8_t twi_writeTo(uint8_t, uint8_t *, uint8_t, uint8_t, uint8_t)
Definition: twi.c:226
void begin()
Definition: Wire.cpp:54
void twi_disable(void)
Definition: twi.c:99
void twi_init(void)
Definition: twi.c:68
uint8_t requestFrom(uint8_t, uint8_t)
Definition: Wire.cpp:125
void end()
Definition: Wire.cpp:78
unsigned int uint32_t
static uint8_t txBufferIndex
Definition: Wire.h:42
GLsizei const GLfloat * value
Definition: Wire.h:33
virtual int available(void)
Definition: Wire.cpp:235
uint8_t endTransmission(void)
Definition: Wire.cpp:184
GLint GLenum GLsizei GLint GLsizei const GLvoid * data
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
GLuint address
static uint8_t rxBuffer[]
Definition: Wire.h:36
static uint8_t rxBufferLength
Definition: Wire.h:38
static uint8_t txBuffer[]
Definition: Wire.h:41
static uint8_t rxBufferIndex
Definition: Wire.h:37
static void onReceiveService(uint8_t *, int)
Definition: Wire.cpp:276
#define BUFFER_LENGTH
Definition: Wire.h:28
uint8_t twi_transmit(const uint8_t *, uint8_t)
Definition: twi.c:302
void onRequest(void(*)(void))
Definition: Wire.cpp:322
void setClock(uint32_t)
Definition: Wire.cpp:83
void beginTransmission(uint8_t)
Definition: Wire.cpp:140
void twi_setFrequency(uint32_t)
Definition: twi.c:127
void twi_attachSlaveTxEvent(void(*)(void))
Definition: twi.c:342
void onReceive(void(*)(int))
Definition: Wire.cpp:316
void twi_setAddress(uint8_t)
Definition: twi.c:115
static void(* user_onReceive)(int)
Definition: Wire.h:47
TwoWire()
Definition: Wire.cpp:48
virtual void flush(void)
Definition: Wire.cpp:270
uint8_t twi_readFrom(uint8_t, uint8_t *, uint8_t, uint8_t)
Definition: twi.c:147
static uint8_t txAddress
Definition: Wire.h:40
static uint8_t txBufferLength
Definition: Wire.h:43
virtual int read(void)
Definition: Wire.cpp:243


arduino_daq
Author(s):
autogenerated on Mon Jun 10 2019 12:46:03