@@ -187,3 +187,46 @@ int MagneticSensorI2C::read(uint8_t angle_reg_msb) {
187
187
readValue += ( ( readArray[0 ] & msb_mask ) << lsb_used );
188
188
return readValue;
189
189
}
190
+
191
+ /*
192
+ * Checks whether other devices have locked the bus. Can clear SDA locks.
193
+ * This should be called before sensor.init() on devices that suffer i2c slaves locking sda
194
+ * e.g some stm32 boards with AS5600 chips
195
+ * Takes the sda_pin and scl_pin
196
+ * Returns 0 for OK, 1 for other master and 2 for unfixable sda locked LOW
197
+ */
198
+ int MagneticSensorI2C::checkBus (byte sda_pin, byte scl_pin) {
199
+
200
+ pinMode (scl_pin, INPUT_PULLUP);
201
+ pinMode (sda_pin, INPUT_PULLUP);
202
+ delay (250 );
203
+
204
+ if (digitalRead (scl_pin) == LOW) {
205
+ // Someone else has claimed master!");
206
+ return 1 ;
207
+ }
208
+
209
+ if (digitalRead (sda_pin) == LOW) {
210
+ // slave is communicating and awaiting clocks, we are blocked
211
+ pinMode (scl_pin, OUTPUT);
212
+ for (byte i = 0 ; i < 16 ; i++) {
213
+ // toggle clock for 2 bytes of data
214
+ digitalWrite (scl_pin, LOW);
215
+ delayMicroseconds (20 );
216
+ digitalWrite (scl_pin, HIGH);
217
+ delayMicroseconds (20 );
218
+ }
219
+ pinMode (sda_pin, INPUT);
220
+ delayMicroseconds (20 );
221
+ if (digitalRead (sda_pin) == LOW) {
222
+ // SDA still blocked
223
+ return 2 ;
224
+ }
225
+ _delay (1000 );
226
+ }
227
+ // SDA is clear (HIGH)
228
+ pinMode (sda_pin, INPUT);
229
+ pinMode (scl_pin, INPUT);
230
+
231
+ return 0 ;
232
+ }
0 commit comments