@@ -140,38 +140,50 @@ void TwoWire::begin(uint8_t addr) {
140140 _running = true ;
141141}
142142
143+ // See: https://github.com/earlephilhower/arduino-pico/issues/979#issuecomment-1328237128
144+ #pragma GCC push_options
145+ #pragma GCC optimize ("O0")
143146void TwoWire::onIRQ () {
144147 // Make a local copy of the IRQ status up front. If it changes while we're
145148 // running the IRQ callback will fire again after returning. Avoids potential
146149 // 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+ }
148154
149155 // First, pull off any data available
150156 if (irqstat & (1 << 2 )) {
151157 // RX_FULL
152- if (_slaveStartDet && ( _buffLen < (int )sizeof (_buff) )) {
158+ if (_buffLen < (int )sizeof (_buff)) {
153159 _buff[_buffLen++] = _i2c->hw ->data_cmd & 0xff ;
154160 } else {
155161 _i2c->hw ->data_cmd ;
156162 }
157163 }
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 ( );
162168 }
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 ;
167174 }
168175 // START_DET
169176 if (irqstat & (1 << 10 )) {
170- _buffLen = 0 ;
171- _buffOff = 0 ;
172177 _slaveStartDet = true ;
173178 _i2c->hw ->clr_start_det ;
174179 }
180+ // RESTART_DET
181+ if (irqstat & (1 << 12 )) {
182+ if (_onReceiveCallback && _buffLen) {
183+ _onReceiveCallback (_buffLen);
184+ }
185+ _i2c->hw ->clr_restart_det ;
186+ }
175187 // STOP_DET
176188 if (irqstat & (1 << 9 )) {
177189 if (_onReceiveCallback && _buffLen) {
@@ -182,18 +194,8 @@ void TwoWire::onIRQ() {
182194 _slaveStartDet = false ;
183195 _i2c->hw ->clr_stop_det ;
184196 }
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- }
196197}
198+ #pragma GCC pop_options
197199
198200void TwoWire::end () {
199201 if (!_running) {
0 commit comments