Skip to content

Commit 7f91df1

Browse files
committed
Revert "allow readDataWIRE() to allow passing deferStopWIRE() on the final read."
This reverts commit ff93e56.
1 parent ff93e56 commit 7f91df1

1 file changed

Lines changed: 57 additions & 71 deletions

File tree

libraries/Wire/Wire.h

Lines changed: 57 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
#include "RingBuffer.h"
2828
#include <stddef.h>
2929

30-
// WIRE_HAS_END means Wire has end()
30+
// WIRE_HAS_END means Wire has end()
3131
#define WIRE_HAS_END 1
3232

3333
// NOTE: SAMD21/SAMD51 silicon errata: when I2C master uses SCLSM=1, CTRLB.CMD
@@ -38,37 +38,35 @@
3838

3939
class TwoWire : public Stream
4040
{
41-
public:
42-
TwoWire(SERCOM *s, uint8_t pinSDA, uint8_t pinSCL);
43-
void begin();
44-
void begin(uint8_t, bool enableGeneralCall = false);
45-
void begin(uint16_t, bool enableGeneralCall, uint8_t speed = 0x0,
46-
bool enable10Bit = false);
47-
void end();
48-
void setClock(uint32_t);
49-
50-
void beginTransmission(uint8_t);
51-
// If onComplete is nullptr, this blocks for legacy sync behavior.
52-
// If onComplete is non-null, this enqueues and returns immediately (async).
53-
uint8_t endTransmission(bool stopBit = true,
54-
void (*onComplete)(void *user, int status) = nullptr,
55-
void *user = nullptr);
56-
57-
// If onComplete is nullptr, this blocks for legacy sync behavior.
58-
// If onComplete is non-null, this enqueues and returns immediately (async).
59-
// If rxBuffer is nullptr, the internal buffer is used; otherwise rxBuffer is
60-
// used.
61-
uint8_t requestFrom(uint8_t address, size_t quantity, bool stopBit = true,
62-
uint8_t *rxBuffer = nullptr,
63-
void (*onComplete)(void *user, int status) = nullptr,
64-
void *user = nullptr);
65-
66-
size_t write(uint8_t data);
67-
// 3-arg write: when setExternal=true, data is used directly (zero-copy) and
68-
// quantity is treated as both length and capacity; subsequent write() calls
69-
// return 0. For streaming > WIRE_BUFFER_LENGTH or async usage, call
70-
// setTxBuffer() before write() on every transaction.
71-
size_t write(const uint8_t *data, size_t quantity, bool setExternal = false);
41+
public:
42+
TwoWire(SERCOM *s, uint8_t pinSDA, uint8_t pinSCL);
43+
void begin();
44+
void begin(uint8_t, bool enableGeneralCall = false);
45+
void begin(uint16_t, bool enableGeneralCall, uint8_t speed = 0x0, bool enable10Bit = false);
46+
void end();
47+
void setClock(uint32_t);
48+
49+
void beginTransmission(uint8_t);
50+
// If onComplete is nullptr, this blocks for legacy sync behavior.
51+
// If onComplete is non-null, this enqueues and returns immediately (async).
52+
uint8_t endTransmission(bool stopBit = true,
53+
void (*onComplete)(void *user, int status) = nullptr,
54+
void *user = nullptr);
55+
56+
// If onComplete is nullptr, this blocks for legacy sync behavior.
57+
// If onComplete is non-null, this enqueues and returns immediately (async).
58+
// If rxBuffer is nullptr, the internal buffer is used; otherwise rxBuffer is used.
59+
uint8_t requestFrom(uint8_t address, size_t quantity, bool stopBit = true,
60+
uint8_t *rxBuffer = nullptr,
61+
void (*onComplete)(void *user, int status) = nullptr,
62+
void *user = nullptr);
63+
64+
size_t write(uint8_t data);
65+
// 3-arg write: when setExternal=true, data is used directly (zero-copy) and
66+
// quantity is treated as both length and capacity; subsequent write() calls return 0.
67+
// For streaming > WIRE_BUFFER_LENGTH or async usage, call setTxBuffer() before write()
68+
// on every transaction.
69+
size_t write(const uint8_t *data, size_t quantity, bool setExternal = false);
7270

7371
virtual int available(void);
7472
virtual int read(void);
@@ -93,21 +91,8 @@ class TwoWire : public Stream
9391

9492
inline void onService(void);
9593

96-
#ifdef _DEBUG_
97-
inline SercomTxn *getSlaveTxn(void) { return &slaveTxn; }
98-
inline const SercomTxn *getSlaveTxn(void) const { return &slaveTxn; }
99-
inline SercomTxn *getLoaderTxn(void) { return &loader; }
100-
inline const SercomTxn *getLoaderTxn(void) const { return &loader; }
101-
inline SercomTxn *getActiveTxn(void) {
102-
return sercom ? sercom->getCurrentTxnWIRE() : nullptr;
103-
}
104-
inline const SercomTxn *getActiveTxn(void) const {
105-
return sercom ? sercom->getCurrentTxnWIRE() : nullptr;
106-
}
107-
#endif // _DEBUG_
108-
109-
private:
110-
SERCOM *sercom;
94+
private:
95+
SERCOM *sercom;
11196
uint8_t _uc_pinSDA;
11297
uint8_t _uc_pinSCL;
11398

@@ -117,7 +102,7 @@ class TwoWire : public Stream
117102
static constexpr size_t WIRE_BUFFER_LENGTH = 255;
118103
uint8_t rxBuffer[WIRE_BUFFER_LENGTH];
119104
uint8_t txBuffer[WIRE_BUFFER_LENGTH];
120-
uint8_t *rxBufferPtr;
105+
uint8_t *rxBufferPtr;
121106
size_t rxBufferCapacity;
122107
size_t rxLength;
123108
size_t rxIndex;
@@ -130,12 +115,12 @@ class TwoWire : public Stream
130115
int pendingReceiveLength;
131116
SercomTxn slaveTxn;
132117
SercomTxn loader; // Staging area for building transactions
133-
118+
134119
// Transaction pool for async operations (matches SERCOM queue depth)
135120
static constexpr size_t TXN_POOL_SIZE = 8;
136121
SercomTxn txnPool[TXN_POOL_SIZE];
137122
uint8_t txnPoolHead;
138-
123+
139124
SercomTxn *allocateTxn();
140125
void freeTxn(SercomTxn *txn);
141126

@@ -151,22 +136,22 @@ class TwoWire : public Stream
151136
};
152137

153138
#if WIRE_INTERFACES_COUNT > 0
154-
extern TwoWire Wire;
139+
extern TwoWire Wire;
155140
#endif
156141
#if WIRE_INTERFACES_COUNT > 1
157-
extern TwoWire Wire1;
142+
extern TwoWire Wire1;
158143
#endif
159144
#if WIRE_INTERFACES_COUNT > 2
160-
extern TwoWire Wire2;
145+
extern TwoWire Wire2;
161146
#endif
162147
#if WIRE_INTERFACES_COUNT > 3
163-
extern TwoWire Wire3;
148+
extern TwoWire Wire3;
164149
#endif
165150
#if WIRE_INTERFACES_COUNT > 4
166-
extern TwoWire Wire4;
151+
extern TwoWire Wire4;
167152
#endif
168153
#if WIRE_INTERFACES_COUNT > 5
169-
extern TwoWire Wire5;
154+
extern TwoWire Wire5;
170155
#endif
171156

172157
inline void TwoWire::onService(void)
@@ -176,9 +161,9 @@ inline void TwoWire::onService(void)
176161
bool isMaster = sercom->isMasterWIRE();
177162

178163
if ((!isMaster && !sercom->isSlaveWIRE()) || flags == 0) {
179-
sercom->clearINTFLAG();
180-
return;
181-
}
164+
sercom->clearINTFLAG();
165+
return;
166+
}
182167

183168
if (status & SERCOM_I2CM_STATUS_RXNACK) {
184169
sercom->prepareCommandBitsWIRE(WIRE_MASTER_ACT_STOP);
@@ -212,7 +197,7 @@ inline void TwoWire::onService(void)
212197
err = SercomWireError::LENGTH_ERROR;
213198
if (busState == 0x0)
214199
err = SercomWireError::BUS_STATE_UNKNOWN;
215-
200+
216201
sercom->clearINTFLAG();
217202
sercom->deferStopWIRE(err);
218203
return;
@@ -221,9 +206,9 @@ inline void TwoWire::onService(void)
221206
bool isRead = (txn->config & I2C_CFG_READ);
222207

223208
if (sercom->getTxnIndexWIRE() < sercom->getTxnLengthWIRE()) {
224-
bool more = isRead ? sercom->readDataWIRE() : sercom->sendDataWIRE();
209+
isRead ? sercom->readDataWIRE() : sercom->sendDataWIRE();
225210
awaitingAddressAck = false;
226-
if (!isRead || more) return;
211+
return;
227212
}
228213

229214
if ((txn->config & I2C_CFG_STOP) && !isRead)
@@ -259,7 +244,7 @@ inline void TwoWire::onService(void)
259244
bool prec = (flags & SERCOM_I2CS_INTFLAG_PREC); // Stop detected
260245
bool amatch = (flags & SERCOM_I2CS_INTFLAG_AMATCH); // Address Match detected
261246
bool drdy = (flags & SERCOM_I2CS_INTFLAG_DRDY); // Data Ready detected
262-
247+
263248
// Stop or Restart detected - defer receive callback
264249
if (prec || (amatch && sr && !isMasterRead))
265250
{
@@ -268,23 +253,24 @@ inline void TwoWire::onService(void)
268253
sercom->deferReceiveWIRE(pendingReceiveLength);
269254
return;
270255
}
271-
256+
272257
// Address Match - setup transaction
273258
// AACKEN enabled: address ACK is automatic, no manual ACK/clear needed
274-
else if (amatch) {
259+
else if (amatch)
260+
{
275261
if (isMasterRead) // Master Read / Slave TX
276262
{
277263
// onRequestCallback runs in ISR context here. Deferring to PendSV
278264
// would require stalling DRDY or returning 0xFF until the buffer is filled.
279265
// onRequestCallback is what will set TwoWire::slaveTxn for the transaction.
280266
if (onRequestCallback)
281267
onRequestCallback();
282-
268+
283269
// Ensure callback actually set slaveTxn.length; if not, stall with 0-length txn
284-
if (slaveTxn.length == 0)
270+
if (slaveTxn.length == 0)
285271
return;
286272

287-
if (!(slaveTxn.config & I2C_CFG_READ))
273+
if (!(slaveTxn.config & I2C_CFG_READ))
288274
slaveTxn.config |= I2C_CFG_READ;
289275
}
290276
else // Master Write / Slave RX
@@ -302,12 +288,12 @@ inline void TwoWire::onService(void)
302288

303289
// SCLSM=0 (Smart Mode disabled): AMATCH and DRDY never fire together
304290
// → return now, DRDY will fire in next interrupt
305-
// SCLSM=1 (Smart Mode enabled) + Master Read: AMATCH+DRDY fire together
291+
// SCLSM=1 (Smart Mode enabled) + Master Read: AMATCH+DRDY fire together
306292
// → fall through to handle data immediately
307293
// SCLSM=1 + Master Write: DRDY not set yet
308294
// → return now, DRDY fires later
309295
if (!drdy)
310-
return;
296+
return;
311297
// else: DRDY is set (SCLSM=1 Master Read case), fall through
312298
}
313299

@@ -317,7 +303,7 @@ inline void TwoWire::onService(void)
317303
isMasterRead ? sercom->sendDataWIRE() : sercom->readDataWIRE();
318304

319305
if (!isMasterRead)
320-
rxLength = sercom->getTxnIndexWIRE();
306+
rxLength = sercom->getTxnIndexWIRE();
321307
}
322308
}
323309
}

0 commit comments

Comments
 (0)