GY-63_MS5611/libraries/I2C_SCANNER/I2C_SCANNER.cpp
2023-12-05 16:33:52 +01:00

215 lines
3.7 KiB
C++

//
// FILE: I2C_SCANNER.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.3.0
// DATE: 2022-08-29
// PURPOSE: Arduino class to implement an I2C scanner.
#include "I2C_SCANNER.h"
I2C_SCANNER::I2C_SCANNER(TwoWire *wire)
{
_wire = wire;
}
//
// CONFIGURATION
//
bool I2C_SCANNER::begin()
{
_init();
return true;
}
//
// I2C PORT
//
uint8_t I2C_SCANNER::getWirePortCount()
{
return _wirePortCount;
}
// 0 == Wire, 1 = Wire1 etc.
bool I2C_SCANNER::setWire(uint8_t n)
{
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;
}
bool I2C_SCANNER::setWire(TwoWire *wire)
{
_wire = wire;
return true;
}
TwoWire* I2C_SCANNER::getWire()
{
return _wire;
}
//
// 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);
}
//
// TIMING
//
bool I2C_SCANNER::setClock(uint32_t clockFrequency)
{
_wire->setClock(clockFrequency);
return true;
}
#if defined(ESP32)
uint32_t I2C_SCANNER::getClock()
{
return _wire->getClock();
}
#endif
//
// SCANNING
//
uint16_t I2C_SCANNER::ping(uint8_t address, uint16_t count)
{
if (count == 0) count = 1;
uint16_t success = 0;
while (count > 0)
{
count--;
if (diag(address) == 0) success++;
}
return success;
}
int I2C_SCANNER::diag(uint8_t address)
{
_wire->beginTransmission(address);
int x = _wire->endTransmission();
return x;
}
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;
for (uint8_t addr = start; addr <= end; addr++)
{
if (diag(addr) == 0) cnt++;
}
return cnt;
}
bool I2C_SCANNER::setWireTimeout(uint32_t timeOut)
{
if (_timeout != timeOut)
{
_timeout = timeOut;
// not all platforms support this.
// _wire->setWireTimeout(timeOut);
return true;
}
return false;
}
uint32_t I2C_SCANNER::getWireTimeout()
{
return _timeout;
}
////////////////////////////////////////////////////
//
// 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;
}
// -- END OF FILE --