@@ -140,38 +140,50 @@ void TwoWire::begin(uint8_t addr) {
140
140
_running = true ;
141
141
}
142
142
143
+ // See: https://github.com/earlephilhower/arduino-pico/issues/979#issuecomment-1328237128
144
+ #pragma GCC push_options
145
+ #pragma GCC optimize ("O0")
143
146
void TwoWire::onIRQ () {
144
147
// Make a local copy of the IRQ status up front. If it changes while we're
145
148
// running the IRQ callback will fire again after returning. Avoids potential
146
149
// race conditions
147
- volatile uint32_t irqstat = _i2c->hw ->intr_stat ;
150
+ uint32_t irqstat = _i2c->hw ->intr_stat ;
151
+ if (irqstat == 0 ) {
152
+ return ;
153
+ }
148
154
149
155
// First, pull off any data available
150
156
if (irqstat & (1 << 2 )) {
151
157
// RX_FULL
152
- if (_slaveStartDet && ( _buffLen < (int )sizeof (_buff) )) {
158
+ if (_buffLen < (int )sizeof (_buff)) {
153
159
_buff[_buffLen++] = _i2c->hw ->data_cmd & 0xff ;
154
160
} else {
155
161
_i2c->hw ->data_cmd ;
156
162
}
157
163
}
158
- // RESTART_DET
159
- if (irqstat & (1 << 12 )) {
160
- if (_onReceiveCallback && _buffLen ) {
161
- _onReceiveCallback (_buffLen );
164
+ // RD_REQ
165
+ if (irqstat & (1 << 5 )) {
166
+ if (_onRequestCallback ) {
167
+ _onRequestCallback ( );
162
168
}
163
- _buffLen = 0 ;
164
- _buffOff = 0 ;
165
- _slaveStartDet = false ;
166
- _i2c->hw ->clr_restart_det ;
169
+ _i2c->hw ->clr_rd_req ;
170
+ }
171
+ // TX_ABRT
172
+ if (irqstat & (1 << 6 )) {
173
+ _i2c->hw ->clr_tx_abrt ;
167
174
}
168
175
// START_DET
169
176
if (irqstat & (1 << 10 )) {
170
- _buffLen = 0 ;
171
- _buffOff = 0 ;
172
177
_slaveStartDet = true ;
173
178
_i2c->hw ->clr_start_det ;
174
179
}
180
+ // RESTART_DET
181
+ if (irqstat & (1 << 12 )) {
182
+ if (_onReceiveCallback && _buffLen) {
183
+ _onReceiveCallback (_buffLen);
184
+ }
185
+ _i2c->hw ->clr_restart_det ;
186
+ }
175
187
// STOP_DET
176
188
if (irqstat & (1 << 9 )) {
177
189
if (_onReceiveCallback && _buffLen) {
@@ -182,18 +194,8 @@ void TwoWire::onIRQ() {
182
194
_slaveStartDet = false ;
183
195
_i2c->hw ->clr_stop_det ;
184
196
}
185
- // TX_ABRT
186
- if (irqstat & (1 << 6 )) {
187
- _i2c->hw ->clr_tx_abrt ;
188
- }
189
- // RD_REQ
190
- if (irqstat & (1 << 5 )) {
191
- if (_onRequestCallback) {
192
- _onRequestCallback ();
193
- }
194
- _i2c->hw ->clr_rd_req ;
195
- }
196
197
}
198
+ #pragma GCC pop_options
197
199
198
200
void TwoWire::end () {
199
201
if (!_running) {
0 commit comments