Skip to content

Commit f0fa1fd

Browse files
committed
Revert "Wire library to the 1.5 format"
This reverts commit a31857688bdc270ed65307755ff3b73ef4867982.
1 parent 2dd6b14 commit f0fa1fd

File tree

11 files changed

+1247
-0
lines changed

11 files changed

+1247
-0
lines changed

libraries/Wire/Wire.cpp

+298
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
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 "twi.h"
27+
}
28+
29+
#include "Wire.h"
30+
31+
// Initialize Class Variables //////////////////////////////////////////////////
32+
33+
uint8_t TwoWire::rxBuffer[BUFFER_LENGTH];
34+
uint8_t TwoWire::rxBufferIndex = 0;
35+
uint8_t TwoWire::rxBufferLength = 0;
36+
37+
uint8_t TwoWire::txAddress = 0;
38+
uint8_t TwoWire::txBuffer[BUFFER_LENGTH];
39+
uint8_t TwoWire::txBufferIndex = 0;
40+
uint8_t TwoWire::txBufferLength = 0;
41+
42+
uint8_t TwoWire::transmitting = 0;
43+
void (*TwoWire::user_onRequest)(void);
44+
void (*TwoWire::user_onReceive)(int);
45+
46+
// Constructors ////////////////////////////////////////////////////////////////
47+
48+
TwoWire::TwoWire()
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);
68+
twi_attachSlaveTxEvent(onRequestService);
69+
twi_attachSlaveRxEvent(onReceiveService);
70+
begin();
71+
}
72+
73+
void TwoWire::begin(int address)
74+
{
75+
begin((uint8_t)address);
76+
}
77+
78+
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop)
79+
{
80+
// clamp to buffer length
81+
if(quantity > BUFFER_LENGTH){
82+
quantity = BUFFER_LENGTH;
83+
}
84+
// perform blocking read into buffer
85+
uint8_t read = twi_readFrom(address, rxBuffer, quantity, sendStop);
86+
// set rx buffer iterator vars
87+
rxBufferIndex = 0;
88+
rxBufferLength = read;
89+
90+
return read;
91+
}
92+
93+
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity)
94+
{
95+
return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true);
96+
}
97+
98+
uint8_t TwoWire::requestFrom(int address, int quantity)
99+
{
100+
return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true);
101+
}
102+
103+
uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop)
104+
{
105+
return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)sendStop);
106+
}
107+
108+
void TwoWire::beginTransmission(uint8_t address)
109+
{
110+
// indicate that we are transmitting
111+
transmitting = 1;
112+
// set address of targeted slave
113+
txAddress = address;
114+
// reset tx buffer iterator vars
115+
txBufferIndex = 0;
116+
txBufferLength = 0;
117+
}
118+
119+
void TwoWire::beginTransmission(int address)
120+
{
121+
beginTransmission((uint8_t)address);
122+
}
123+
124+
//
125+
// Originally, 'endTransmission' was an f(void) function.
126+
// It has been modified to take one parameter indicating
127+
// whether or not a STOP should be performed on the bus.
128+
// Calling endTransmission(false) allows a sketch to
129+
// perform a repeated start.
130+
//
131+
// WARNING: Nothing in the library keeps track of whether
132+
// the bus tenure has been properly ended with a STOP. It
133+
// is very possible to leave the bus in a hung state if
134+
// no call to endTransmission(true) is made. Some I2C
135+
// devices will behave oddly if they do not see a STOP.
136+
//
137+
uint8_t TwoWire::endTransmission(uint8_t sendStop)
138+
{
139+
// transmit buffer (blocking)
140+
int8_t ret = twi_writeTo(txAddress, txBuffer, txBufferLength, 1, sendStop);
141+
// reset tx buffer iterator vars
142+
txBufferIndex = 0;
143+
txBufferLength = 0;
144+
// indicate that we are done transmitting
145+
transmitting = 0;
146+
return ret;
147+
}
148+
149+
// This provides backwards compatibility with the original
150+
// definition, and expected behaviour, of endTransmission
151+
//
152+
uint8_t TwoWire::endTransmission(void)
153+
{
154+
return endTransmission(true);
155+
}
156+
157+
// must be called in:
158+
// slave tx event callback
159+
// or after beginTransmission(address)
160+
size_t TwoWire::write(uint8_t data)
161+
{
162+
if(transmitting){
163+
// in master transmitter mode
164+
// don't bother if buffer is full
165+
if(txBufferLength >= BUFFER_LENGTH){
166+
setWriteError();
167+
return 0;
168+
}
169+
// put byte in tx buffer
170+
txBuffer[txBufferIndex] = data;
171+
++txBufferIndex;
172+
// update amount in buffer
173+
txBufferLength = txBufferIndex;
174+
}else{
175+
// in slave send mode
176+
// reply to master
177+
twi_transmit(&data, 1);
178+
}
179+
return 1;
180+
}
181+
182+
// must be called in:
183+
// slave tx event callback
184+
// or after beginTransmission(address)
185+
size_t TwoWire::write(const uint8_t *data, size_t quantity)
186+
{
187+
if(transmitting){
188+
// in master transmitter mode
189+
for(size_t i = 0; i < quantity; ++i){
190+
write(data[i]);
191+
}
192+
}else{
193+
// in slave send mode
194+
// reply to master
195+
twi_transmit(data, quantity);
196+
}
197+
return quantity;
198+
}
199+
200+
// must be called in:
201+
// slave rx event callback
202+
// or after requestFrom(address, numBytes)
203+
int TwoWire::available(void)
204+
{
205+
return rxBufferLength - rxBufferIndex;
206+
}
207+
208+
// must be called in:
209+
// slave rx event callback
210+
// or after requestFrom(address, numBytes)
211+
int TwoWire::read(void)
212+
{
213+
int value = -1;
214+
215+
// get each successive byte on each call
216+
if(rxBufferIndex < rxBufferLength){
217+
value = rxBuffer[rxBufferIndex];
218+
++rxBufferIndex;
219+
}
220+
221+
return value;
222+
}
223+
224+
// must be called in:
225+
// slave rx event callback
226+
// or after requestFrom(address, numBytes)
227+
int TwoWire::peek(void)
228+
{
229+
int value = -1;
230+
231+
if(rxBufferIndex < rxBufferLength){
232+
value = rxBuffer[rxBufferIndex];
233+
}
234+
235+
return value;
236+
}
237+
238+
void TwoWire::flush(void)
239+
{
240+
// XXX: to be implemented.
241+
}
242+
243+
// behind the scenes function that is called when data is received
244+
void TwoWire::onReceiveService(uint8_t* inBytes, int numBytes)
245+
{
246+
// don't bother if user hasn't registered a callback
247+
if(!user_onReceive){
248+
return;
249+
}
250+
// don't bother if rx buffer is in use by a master requestFrom() op
251+
// i know this drops data, but it allows for slight stupidity
252+
// meaning, they may not have read all the master requestFrom() data yet
253+
if(rxBufferIndex < rxBufferLength){
254+
return;
255+
}
256+
// copy twi rx buffer into local read buffer
257+
// this enables new reads to happen in parallel
258+
for(uint8_t i = 0; i < numBytes; ++i){
259+
rxBuffer[i] = inBytes[i];
260+
}
261+
// set rx iterator vars
262+
rxBufferIndex = 0;
263+
rxBufferLength = numBytes;
264+
// alert user program
265+
user_onReceive(numBytes);
266+
}
267+
268+
// behind the scenes function that is called when data is requested
269+
void TwoWire::onRequestService(void)
270+
{
271+
// don't bother if user hasn't registered a callback
272+
if(!user_onRequest){
273+
return;
274+
}
275+
// reset tx buffer iterator vars
276+
// !!! this will kill any pending pre-master sendTo() activity
277+
txBufferIndex = 0;
278+
txBufferLength = 0;
279+
// alert user program
280+
user_onRequest();
281+
}
282+
283+
// sets function called on slave write
284+
void TwoWire::onReceive( void (*function)(int) )
285+
{
286+
user_onReceive = function;
287+
}
288+
289+
// sets function called on slave read
290+
void TwoWire::onRequest( void (*function)(void) )
291+
{
292+
user_onRequest = function;
293+
}
294+
295+
// Preinstantiate Objects //////////////////////////////////////////////////////
296+
297+
TwoWire Wire = TwoWire();
298+

libraries/Wire/Wire.h

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
TwoWire.h - TWI/I2C library for Arduino & Wiring
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+
#ifndef TwoWire_h
23+
#define TwoWire_h
24+
25+
#include <inttypes.h>
26+
#include "Stream.h"
27+
28+
#define BUFFER_LENGTH 32
29+
30+
class TwoWire : public Stream
31+
{
32+
private:
33+
static uint8_t rxBuffer[];
34+
static uint8_t rxBufferIndex;
35+
static uint8_t rxBufferLength;
36+
37+
static uint8_t txAddress;
38+
static uint8_t txBuffer[];
39+
static uint8_t txBufferIndex;
40+
static uint8_t txBufferLength;
41+
42+
static uint8_t transmitting;
43+
static void (*user_onRequest)(void);
44+
static void (*user_onReceive)(int);
45+
static void onRequestService(void);
46+
static void onReceiveService(uint8_t*, int);
47+
public:
48+
TwoWire();
49+
void begin();
50+
void begin(uint8_t);
51+
void begin(int);
52+
void beginTransmission(uint8_t);
53+
void beginTransmission(int);
54+
uint8_t endTransmission(void);
55+
uint8_t endTransmission(uint8_t);
56+
uint8_t requestFrom(uint8_t, uint8_t);
57+
uint8_t requestFrom(uint8_t, uint8_t, uint8_t);
58+
uint8_t requestFrom(int, int);
59+
uint8_t requestFrom(int, int, int);
60+
virtual size_t write(uint8_t);
61+
virtual size_t write(const uint8_t *, size_t);
62+
virtual int available(void);
63+
virtual int read(void);
64+
virtual int peek(void);
65+
virtual void flush(void);
66+
void onReceive( void (*)(int) );
67+
void onRequest( void (*)(void) );
68+
69+
inline size_t write(unsigned long n) { return write((uint8_t)n); }
70+
inline size_t write(long n) { return write((uint8_t)n); }
71+
inline size_t write(unsigned int n) { return write((uint8_t)n); }
72+
inline size_t write(int n) { return write((uint8_t)n); }
73+
using Print::write;
74+
};
75+
76+
extern TwoWire Wire;
77+
78+
#endif
79+

0 commit comments

Comments
 (0)