2022-08-29 09:17:44 -04:00
|
|
|
//
|
|
|
|
// FILE: I2C_SCANNER.cpp
|
|
|
|
// AUTHOR: Rob Tillaart
|
2022-11-12 11:08:10 -05:00
|
|
|
// VERSION: 0.1.3
|
2022-08-29 09:17:44 -04:00
|
|
|
// DATE: 2022-08-29
|
|
|
|
// PURPOSE: I2C scanner class
|
|
|
|
//
|
2022-11-12 11:08:10 -05:00
|
|
|
// HISTORY: see changelog.md
|
2022-08-29 09:17:44 -04:00
|
|
|
|
|
|
|
|
2022-11-12 11:08:10 -05:00
|
|
|
#include "I2C_SCANNER.h"
|
2022-08-29 09:17:44 -04:00
|
|
|
|
|
|
|
|
|
|
|
I2C_SCANNER::I2C_SCANNER(TwoWire *wire)
|
|
|
|
{
|
|
|
|
_wire = wire;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-30 06:39:55 -04:00
|
|
|
//
|
|
|
|
// CONFIGURATION
|
|
|
|
//
|
|
|
|
bool I2C_SCANNER::begin()
|
|
|
|
{
|
|
|
|
_init();
|
|
|
|
_wire->begin();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-29 09:17:44 -04:00
|
|
|
#if defined (ESP8266) || defined(ESP32)
|
|
|
|
bool I2C_SCANNER::begin(int dataPin, int clockPin)
|
|
|
|
{
|
2022-08-30 06:39:55 -04:00
|
|
|
_init();
|
2022-08-29 09:17:44 -04:00
|
|
|
_wire = &Wire;
|
|
|
|
if ((dataPin < 255) && (clockPin < 255))
|
|
|
|
{
|
|
|
|
_wire->begin(dataPin, clockPin);
|
|
|
|
} else {
|
|
|
|
_wire->begin();
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2022-08-30 06:39:55 -04:00
|
|
|
//
|
|
|
|
// I2C PORT
|
|
|
|
//
|
|
|
|
uint8_t I2C_SCANNER::getWirePortCount()
|
2022-08-29 09:17:44 -04:00
|
|
|
{
|
2022-08-30 06:39:55 -04:00
|
|
|
return _wirePortCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool I2C_SCANNER::setWire(TwoWire *wire)
|
|
|
|
{
|
|
|
|
_wire = wire;
|
2022-08-29 09:17:44 -04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-30 06:39:55 -04:00
|
|
|
// 0 == Wire, 1 = Wire1 etc.
|
|
|
|
bool I2C_SCANNER::setWire(uint8_t n)
|
2022-08-29 09:17:44 -04:00
|
|
|
{
|
2022-08-30 06:39:55 -04:00
|
|
|
if (n == 0) { _wire = &Wire; return true; };
|
|
|
|
#if defined WIRE_IMPLEMENT_WIRE1 || WIRE_INTERFACES_COUNT > 1
|
|
|
|
if (n == 1) { _wire = &Wire1; return true; };
|
|
|
|
#endif
|
|
|
|
#if defined WIRE_IMPLEMENT_WIRE2 || WIRE_INTERFACES_COUNT > 2
|
|
|
|
if (n == 2) { _wire = &Wire2; return true; };
|
|
|
|
#endif
|
|
|
|
#if defined WIRE_IMPLEMENT_WIRE3 || WIRE_INTERFACES_COUNT > 3
|
|
|
|
if (n == 3) { _wire = &Wire3; return true; };
|
|
|
|
#endif
|
|
|
|
#if defined WIRE_IMPLEMENT_WIRE4 || WIRE_INTERFACES_COUNT > 4
|
|
|
|
if (n == 4) { _wire = &Wire4; return true; };
|
|
|
|
#endif
|
|
|
|
#if defined WIRE_IMPLEMENT_WIRE5 || WIRE_INTERFACES_COUNT > 5
|
|
|
|
if (n == 5) { _wire = &Wire5; return true; };
|
|
|
|
#endif
|
|
|
|
return false;
|
2022-08-29 09:17:44 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-30 06:39:55 -04:00
|
|
|
TwoWire* I2C_SCANNER::getWire()
|
|
|
|
{
|
|
|
|
return _wire;
|
|
|
|
}
|
|
|
|
|
2022-08-31 05:08:07 -04:00
|
|
|
//
|
|
|
|
// RESET
|
|
|
|
//
|
|
|
|
int I2C_SCANNER::softwareReset(uint8_t method)
|
|
|
|
{
|
|
|
|
// only support 0 and 1
|
|
|
|
if (method > 1) return -999;
|
|
|
|
if (method == 1)
|
|
|
|
{
|
|
|
|
// from https://github.com/RobTillaart/PCA9634/issues/10#issuecomment-1206326417
|
|
|
|
const uint8_t SW_RESET = 0x03;
|
|
|
|
_wire->beginTransmission(SW_RESET);
|
|
|
|
_wire->write(0xA5);
|
|
|
|
_wire->write(0x5A);
|
|
|
|
return _wire->endTransmission(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
// default
|
|
|
|
// based upon NXP specification - UM10204.pdf - page 16
|
|
|
|
_wire->beginTransmission(0x00);
|
|
|
|
_wire->write(0x06);
|
|
|
|
return _wire->endTransmission(true);
|
|
|
|
}
|
|
|
|
|
2022-08-30 06:39:55 -04:00
|
|
|
|
|
|
|
//
|
|
|
|
// TIMING
|
|
|
|
//
|
2022-08-29 09:17:44 -04:00
|
|
|
bool I2C_SCANNER::setClock(uint32_t clockFrequency)
|
|
|
|
{
|
|
|
|
_wire->setClock(clockFrequency);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-30 06:39:55 -04:00
|
|
|
#if defined(ESP32)
|
|
|
|
uint32_t I2C_SCANNER::getClock()
|
|
|
|
{
|
|
|
|
return _wire->getClock();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// SCANNING
|
|
|
|
//
|
|
|
|
bool I2C_SCANNER::ping(uint8_t address)
|
|
|
|
{
|
|
|
|
return diag(address) == 0;
|
|
|
|
}
|
|
|
|
|
2022-08-31 05:08:07 -04:00
|
|
|
|
2022-08-30 06:39:55 -04:00
|
|
|
int I2C_SCANNER::diag(uint8_t address)
|
|
|
|
{
|
|
|
|
_wire->beginTransmission(address);
|
|
|
|
return _wire->endTransmission();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int32_t I2C_SCANNER::pingTime(uint8_t address)
|
|
|
|
{
|
|
|
|
uint32_t start = micros();
|
|
|
|
int x = diag(address);
|
|
|
|
int32_t duration = (int32_t)(micros() - start);
|
|
|
|
if (x == 0) return duration;
|
|
|
|
return -duration;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t I2C_SCANNER::count(uint8_t start, uint8_t end)
|
|
|
|
{
|
|
|
|
uint8_t cnt = 0;
|
2022-08-31 05:08:07 -04:00
|
|
|
for (uint8_t addr = start; addr <= end; addr++)
|
2022-08-30 06:39:55 -04:00
|
|
|
{
|
|
|
|
if (diag(addr) == 0) cnt++;
|
|
|
|
}
|
|
|
|
return cnt;
|
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// PRIVATE
|
|
|
|
//
|
|
|
|
int I2C_SCANNER::_init()
|
|
|
|
{
|
|
|
|
Wire.begin();
|
|
|
|
_wirePortCount = 1;
|
|
|
|
#if defined WIRE_IMPLEMENT_WIRE1 || WIRE_INTERFACES_COUNT > 1
|
|
|
|
Wire1.begin();
|
|
|
|
_wirePortCount++;
|
|
|
|
#endif
|
|
|
|
#if defined WIRE_IMPLEMENT_WIRE2 || WIRE_INTERFACES_COUNT > 2
|
|
|
|
Wire2.begin();
|
|
|
|
_wirePortCount++;
|
|
|
|
#endif
|
|
|
|
#if defined WIRE_IMPLEMENT_WIRE3 || WIRE_INTERFACES_COUNT > 3
|
|
|
|
Wire3.begin();
|
|
|
|
_wirePortCount++;
|
|
|
|
#endif
|
|
|
|
#if defined WIRE_IMPLEMENT_WIRE4 || WIRE_INTERFACES_COUNT > 4
|
|
|
|
Wire4.begin();
|
|
|
|
_wirePortCount++;
|
|
|
|
#endif
|
|
|
|
#if defined WIRE_IMPLEMENT_WIRE5 || WIRE_INTERFACES_COUNT > 5
|
|
|
|
Wire5.begin();
|
|
|
|
_wirePortCount++;
|
|
|
|
#endif
|
|
|
|
return _wirePortCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-29 09:17:44 -04:00
|
|
|
// -- END OF FILE --
|
|
|
|
|