@@ -38,113 +38,132 @@ extern "C" {
38
38
#error Wire library is not supported on this board
39
39
#endif
40
40
41
+ // Private Methods /////////////////////////////////////////////////////////////
41
42
// Constructors ////////////////////////////////////////////////////////////////
42
43
43
- TwoWire::TwoWire (uint8_t rxBufferSize, uint8_t txBufferSize) :
44
- rxBuffer{new uint8_t [rxBufferSize]},
45
- txBuffer{new uint8_t [txBufferSize]}
44
+ TwoWireBase::TwoWireBase (uint8_t rxBufferSize, uint8_t txBufferSize) :
45
+ twiMaster{new TwiMaster},
46
+ rxBufferSize{rxBufferSize},
47
+ rxBuffer{new uint8_t [rxBufferSize]},
48
+ txBufferSize{txBufferSize},
49
+ txBuffer{new uint8_t [txBufferSize]}
46
50
{
47
- this ->txBufferSize = txBufferSize;
48
- this ->rxBufferSize = rxBufferSize;
49
51
}
50
52
51
- // Public Methods //////////////////////////////////////////////////////////////
53
+ TwoWireBase::TwoWireBase (TwiMaster* twiPtr, uint8_t rxBufferSize, uint8_t txBufferSize, uint8_t * rxBuffer, uint8_t * txBuffer) :
54
+ twiMaster{twiPtr},
55
+ rxBufferSize{rxBufferSize},
56
+ rxBuffer{rxBuffer},
57
+ txBufferSize{txBufferSize},
58
+ txBuffer{txBuffer}
59
+ {
60
+ }
52
61
53
- void TwoWire::begin ( int sda, int scl )
62
+ inline TwiMaster& TwoWireBase::getTwiMaster ( )
54
63
{
55
- twi.init (sda, scl);
56
- flush ();
64
+ return *twiMaster;
57
65
}
66
+ inline void TwoWireBase::releaseTwiMaster ()
67
+ {
68
+ twiMaster.release ();
69
+ }
70
+
71
+ // Public Methods //////////////////////////////////////////////////////////////
58
72
59
- void TwoWire::pins (int sda, int scl)
73
+ void TwoWireBase::begin (int sda, int scl)
60
74
{
75
+ lastSdaPin = sda;
76
+ lastSclPin = scl;
77
+ getTwiMaster ().init (sda, scl);
78
+ flush ();
61
79
}
62
80
63
- void TwoWire ::begin (void )
81
+ void TwoWireBase ::begin (void )
64
82
{
65
- begin (SDA, SCL );
83
+ begin (lastSdaPin, lastSclPin );
66
84
}
67
85
68
- uint8_t TwoWire::status ( )
86
+ void TwoWireBase::pins ( int sda, int scl )
69
87
{
70
- return twi.status ();
88
+ lastSdaPin = sda;
89
+ lastSclPin = scl;
71
90
}
72
91
73
- void TwoWire::begin ( int address )
92
+ uint8_t TwoWireBase::status ( )
74
93
{
75
- begin (( uint8_t )address );
94
+ return getTwiMaster (). status ( );
76
95
}
77
96
78
- void TwoWire ::setClock (uint32_t frequency)
97
+ void TwoWireBase ::setClock (uint32_t frequency)
79
98
{
80
- twi .setClock (frequency);
99
+ getTwiMaster () .setClock (frequency);
81
100
}
82
101
83
- void TwoWire ::setClockStretchLimit (uint32_t limit)
102
+ void TwoWireBase ::setClockStretchLimit (uint32_t limit)
84
103
{
85
- twi .setClockStretchLimit (limit);
104
+ getTwiMaster () .setClockStretchLimit (limit);
86
105
}
87
106
88
- size_t TwoWire ::requestFrom (uint8_t address, size_t size, bool sendStop)
107
+ size_t TwoWireBase ::requestFrom (uint8_t address, size_t size, bool sendStop)
89
108
{
90
109
if (size > rxBufferSize)
91
110
{
92
111
size = rxBufferSize;
93
112
}
94
- size_t read = (twi .readFrom (address, rxBuffer.get (), size, sendStop) == 0 ) ? size : 0 ;
113
+ size_t read = (getTwiMaster () .readFrom (address, rxBuffer.get (), size, sendStop) == 0 ) ? size : 0 ;
95
114
rxBufferIndex = 0 ;
96
115
rxBufferLength = read ;
97
116
return read ;
98
117
}
99
118
100
- uint8_t TwoWire ::requestFrom (uint8_t address, uint8_t quantity, uint8_t sendStop)
119
+ uint8_t TwoWireBase ::requestFrom (uint8_t address, uint8_t quantity, uint8_t sendStop)
101
120
{
102
121
return requestFrom (address, static_cast <size_t >(quantity), static_cast <bool >(sendStop));
103
122
}
104
123
105
- uint8_t TwoWire ::requestFrom (uint8_t address, uint8_t quantity)
124
+ uint8_t TwoWireBase ::requestFrom (uint8_t address, uint8_t quantity)
106
125
{
107
126
return requestFrom (address, static_cast <size_t >(quantity), true );
108
127
}
109
128
110
- uint8_t TwoWire ::requestFrom (int address, int quantity)
129
+ uint8_t TwoWireBase ::requestFrom (int address, int quantity)
111
130
{
112
131
return requestFrom (static_cast <uint8_t >(address), static_cast <size_t >(quantity), true );
113
132
}
114
133
115
- uint8_t TwoWire ::requestFrom (int address, int quantity, int sendStop)
134
+ uint8_t TwoWireBase ::requestFrom (int address, int quantity, int sendStop)
116
135
{
117
136
return requestFrom (static_cast <uint8_t >(address), static_cast <size_t >(quantity), static_cast <bool >(sendStop));
118
137
}
119
138
120
- void TwoWire ::beginTransmission (uint8_t address)
139
+ void TwoWireBase ::beginTransmission (uint8_t address)
121
140
{
122
141
transmitting = 1 ;
123
142
txAddress = address;
124
143
txBufferIndex = 0 ;
125
144
txBufferLength = 0 ;
126
145
}
127
146
128
- void TwoWire ::beginTransmission (int address)
147
+ void TwoWireBase ::beginTransmission (int address)
129
148
{
130
149
beginTransmission ((uint8_t )address);
131
150
}
132
151
133
- uint8_t TwoWire ::endTransmission (uint8_t sendStop)
152
+ uint8_t TwoWireBase ::endTransmission (uint8_t sendStop)
134
153
{
135
- int8_t ret = twi .writeTo (txAddress, txBuffer.get (), txBufferLength, sendStop);
154
+ int8_t ret = getTwiMaster () .writeTo (txAddress, txBuffer.get (), txBufferLength, sendStop);
136
155
txBufferIndex = 0 ;
137
156
txBufferLength = 0 ;
138
157
transmitting = 0 ;
139
158
return ret;
140
159
}
141
160
142
- uint8_t TwoWire ::endTransmission (void )
161
+ uint8_t TwoWireBase ::endTransmission (void )
143
162
{
144
163
return endTransmission (true );
145
164
}
146
165
147
- size_t TwoWire ::write (uint8_t data)
166
+ size_t TwoWireBase ::write (uint8_t data)
148
167
{
149
168
if (transmitting)
150
169
{
@@ -165,7 +184,7 @@ size_t TwoWire::write(uint8_t data)
165
184
return 1 ;
166
185
}
167
186
168
- size_t TwoWire ::write (const uint8_t *data, size_t quantity)
187
+ size_t TwoWireBase ::write (const uint8_t *data, size_t quantity)
169
188
{
170
189
if (transmitting)
171
190
{
@@ -185,7 +204,7 @@ size_t TwoWire::write(const uint8_t *data, size_t quantity)
185
204
return quantity;
186
205
}
187
206
188
- int TwoWire ::available (void )
207
+ int TwoWireBase ::available (void )
189
208
{
190
209
int result = rxBufferLength - rxBufferIndex;
191
210
@@ -199,7 +218,7 @@ int TwoWire::available(void)
199
218
return result;
200
219
}
201
220
202
- int TwoWire ::read (void )
221
+ int TwoWireBase ::read (void )
203
222
{
204
223
int value = -1 ;
205
224
if (rxBufferIndex < rxBufferLength)
@@ -210,7 +229,7 @@ int TwoWire::read(void)
210
229
return value;
211
230
}
212
231
213
- int TwoWire ::peek (void )
232
+ int TwoWireBase ::peek (void )
214
233
{
215
234
int value = -1 ;
216
235
if (rxBufferIndex < rxBufferLength)
@@ -220,16 +239,144 @@ int TwoWire::peek(void)
220
239
return value;
221
240
}
222
241
223
- void TwoWire ::flush (void )
242
+ void TwoWireBase ::flush (void )
224
243
{
225
244
rxBufferIndex = 0 ;
226
245
rxBufferLength = 0 ;
227
246
txBufferIndex = 0 ;
228
247
txBufferLength = 0 ;
229
248
}
230
249
231
- // Preinstantiate Objects //////////////////////////////////////////////////////
250
+ // Master-only Constructors ////////////////////////////////////////////////////
251
+
252
+ TwoWireMaster::TwoWireMaster (uint8_t rxBufferSize, uint8_t txBufferSize)
253
+ : TwoWireBase(rxBufferSize, txBufferSize)
254
+ {}
232
255
256
+ TwoWireMaster::TwoWireMaster (uint8_t rxBufferSize, uint8_t txBufferSize, uint8_t * rxBuffer, uint8_t * txBuffer)
257
+ : TwoWireBase(new TwiMaster{}, rxBufferSize, txBufferSize, rxBuffer, txBuffer)
258
+ {}
259
+
260
+ // Master-or-Slave Constructors ////////////////////////////////////////////////
261
+
262
+ TwoWireMasterOrSlave::TwoWireMasterOrSlave (uint8_t rxBufferSize, uint8_t txBufferSize, uint8_t * rxBuffer, uint8_t * txBuffer)
263
+ : TwoWireBase(&twiMasterSingleton, rxBufferSize, txBufferSize, rxBuffer, txBuffer)
264
+ {}
265
+
266
+ TwoWireMasterOrSlave::~TwoWireMasterOrSlave ()
267
+ {
268
+ releaseTwiMaster ();
269
+ }
270
+
271
+ // Master-or-Slave Public Methods //////////////////////////////////////////////
272
+
273
+ void TwoWireMasterOrSlave::begin (int sda, int scl, uint8_t address)
274
+ {
275
+ twi_setAddress (address);
276
+ twi_attachSlaveTxEventWithTarget (onRequestService);
277
+ twi_attachSlaveRxEventWithTarget (onReceiveService);
278
+ begin (sda, scl);
279
+ }
280
+
281
+ void TwoWireMasterOrSlave::begin (uint8_t address)
282
+ {
283
+ twi_setAddress (address);
284
+ twi_attachSlaveTxEventWithTarget (onRequestService);
285
+ twi_attachSlaveRxEventWithTarget (onReceiveService);
286
+ begin ();
287
+ }
288
+ void TwoWireMasterOrSlave::begin (int address)
289
+ {
290
+ begin ((uint8_t )address);
291
+ }
292
+
293
+ void TwoWireMasterOrSlave::onReceiveService (uint8_t * inBytes, size_t numBytes, void * targetObject)
294
+ {
295
+ auto & instance = *(TwoWireMasterOrSlave*)targetObject;
296
+
297
+ // return if targetObject (an instance of TwoWireMasterOrSlave) was not set/received correctly
298
+ // don't bother if user hasn't registered a callback
299
+ if (targetObject == nullptr || !instance.user_onReceive )
300
+ {
301
+ return ;
302
+ }
303
+ // // don't bother if rx buffer is in use by a master requestFrom() op
304
+ // // i know this drops data, but it allows for slight stupidity
305
+ // // meaning, they may not have read all the master requestFrom() data yet
306
+ // if(rxBufferIndex < rxBufferLength){
307
+ // return;
308
+ // }
309
+
310
+ // copy twi rx buffer into local read buffer
311
+ // this enables new reads to happen in parallel
312
+ for (uint8_t i = 0 ; i < numBytes; ++i)
313
+ {
314
+ instance.rxBuffer [i] = inBytes[i];
315
+ }
316
+
317
+ // set rx iterator vars
318
+ instance.rxBufferIndex = 0 ;
319
+ instance.rxBufferLength = numBytes;
320
+
321
+ // alert user program
322
+ instance.user_onReceive (numBytes);
323
+ }
324
+
325
+ void TwoWireMasterOrSlave::onRequestService (void * targetObject)
326
+ {
327
+ auto & instance = *(TwoWireMasterOrSlave*)targetObject;
328
+
329
+ // return if targetObject (an instance of TwoWireMasterOrSlave) was not set/received correctly
330
+ // don't bother if user hasn't registered a callback
331
+ if (targetObject == nullptr || !instance.user_onRequest )
332
+ {
333
+ return ;
334
+ }
335
+
336
+ // reset tx buffer iterator vars
337
+ // !!! this will kill any pending pre-master sendTo() activity
338
+ instance.txBufferIndex = 0 ;
339
+ instance.txBufferLength = 0 ;
340
+
341
+ // alert user program
342
+ instance.user_onRequest ();
343
+ }
344
+
345
+ void TwoWireMasterOrSlave::onReceive (void (*function)(int ))
346
+ {
347
+ // arduino api compatibility fixer:
348
+ // really hope size parameter will not exceed 2^31 :)
349
+ static_assert (sizeof (int ) == sizeof (size_t ), " something is wrong in Arduino kingdom" );
350
+ user_onReceive = reinterpret_cast <void (*)(size_t )>(function);
351
+ }
352
+
353
+ void TwoWireMasterOrSlave::onReceive (void (*function)(size_t ))
354
+ {
355
+ user_onReceive = function;
356
+ twi_enableSlaveModeWithTarget (this );
357
+ }
358
+
359
+ void TwoWireMasterOrSlave::onRequest (void (*function)(void ))
360
+ {
361
+ user_onRequest = function;
362
+ twi_enableSlaveModeWithTarget (this );
363
+ }
364
+
365
+ // Preinstantiate Objects //////////////////////////////////////////////////////
233
366
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_TWOWIRE)
234
- TwoWire Wire;
367
+ static uint8_t _rxBuffer[I2C_BUFFER_LENGTH];
368
+ static uint8_t _txBuffer[I2C_BUFFER_LENGTH];
369
+
370
+ TwoWire Wire{I2C_BUFFER_LENGTH, I2C_BUFFER_LENGTH, _rxBuffer, _txBuffer};
371
+
372
+ TwoWireMasterOrSlave::TwoWireMasterOrSlave ()
373
+ : TwoWireBase(&twiMasterSingleton, I2C_BUFFER_LENGTH, I2C_BUFFER_LENGTH, _txBuffer, _rxBuffer)
374
+ {}
375
+
376
+ #else
377
+
378
+ TwoWireMasterOrSlave::TwoWireMasterOrSlave ()
379
+ : TwoWireBase(&twiMasterSingleton, I2C_BUFFER_LENGTH, I2C_BUFFER_LENGTH, new uint8_t [I2C_BUFFER_LENGTH], new uint8_t [I2C_BUFFER_LENGTH])
380
+ {}
381
+
235
382
#endif
0 commit comments