GY-63_MS5611/libraries/PCA9553/PCA9553.cpp
2023-09-25 20:49:28 +02:00

241 lines
4.2 KiB
C++

//
// FILE: PCA9553.cpp
// AUTHOR: Rob Tillaart
// DATE: 2023-07-16
// VERSION: 0.2.1
// PURPOSE: Arduino library for for I2C PCA9553 4 channel PWM
// URL: https://github.com/RobTillaart/PCA9553
#include "PCA9553.h"
//////////////////////////////////////////////////////////////
//
// Constructor
//
PCA9553::PCA9553(const uint8_t deviceAddress, TwoWire *wire)
{
_address = deviceAddress;
_wire = wire;
_outputCount = 4;
_error = PCA9553_OK;
}
#if defined (ESP8266) || defined(ESP32)
bool PCA9553::begin(int sda, int scl)
{
if ((sda < 255) && (scl < 255))
{
_wire->begin(sda, scl);
} else {
_wire->begin();
}
if (! isConnected()) return false;
return true;
}
#endif
bool PCA9553::begin()
{
_wire->begin();
if (! isConnected()) return false;
return true;
}
bool PCA9553::isConnected()
{
_wire->beginTransmission(_address);
_error = _wire->endTransmission();
return (_error == 0);
}
uint8_t PCA9553::reset()
{
// not most efficient
setPrescaler(0, 0); // 44 Hz
setPrescaler(1, 0); // 44 Hz
setPWM(0, 128); // 50%
setPWM(1, 128); // 50%
for (int pin = 0; pin < _outputCount; pin++)
{
setOutputMode(pin, 0); // LOW
}
return PCA9553_OK;
}
uint8_t PCA9553::getAddress()
{
return _address;
}
uint8_t PCA9553::outputCount()
{
return _outputCount;
}
/////////////////////////////////////////////////////
//
// GPIO
//
uint8_t PCA9553::getInput()
{
return readReg(PCA9553_INPUT);
}
void PCA9553::pinMode(uint8_t pin, uint8_t mode)
{
if (mode != OUTPUT) setOutputMode(pin, PCA9553_MODE_HIGH);
}
void PCA9553::digitalWrite(uint8_t pin, uint8_t val)
{
if (val == LOW) setOutputMode(pin, PCA9553_MODE_LOW);
else setOutputMode(pin, PCA9553_MODE_HIGH);
}
uint8_t PCA9553::digitalRead(uint8_t pin)
{
uint8_t value = readReg(PCA9553_INPUT);
if ((value >> pin) & 0x01) return HIGH;
return LOW;
}
/////////////////////////////////////////////////////
//
// PRESCALERS
//
void PCA9553::setPrescaler(uint8_t gen, uint8_t psc)
{
if (gen == 0) writeReg(PCA9553_PSC0, psc);
else writeReg(PCA9553_PSC1, psc);
}
uint8_t PCA9553::getPrescaler(uint8_t gen)
{
if (gen == 0) return readReg(PCA9553_PSC0);
else return readReg(PCA9553_PSC1);
}
/////////////////////////////////////////////////////
//
// PWM
//
void PCA9553::setPWM(uint8_t gen, uint8_t pwm)
{
if (gen == 0) writeReg(PCA9553_PWM0, pwm);
else writeReg(PCA9553_PWM1, pwm);
}
uint8_t PCA9553::getPWM(uint8_t gen)
{
if (gen == 0) return readReg(PCA9553_PWM0);
else return readReg(PCA9553_PWM1);
}
/////////////////////////////////////////////////////
//
// OUTPUT MODE - MUX SELECTION
//
uint8_t PCA9553::setOutputMode(uint8_t pin, uint8_t mode)
{
if (pin >= _outputCount)
{
_error = PCA9553_ERR_CHAN;
return _error;
}
if (mode > 3)
{
_error = PCA9553_ERR_MODE;
return _error;
}
uint8_t reg = PCA9553_LS0;
uint8_t ledSelect = readReg(reg);
ledSelect &= ~(0x03 << (pin * 2));
ledSelect |= (mode << (pin * 2));
return writeReg(reg, ledSelect);
}
uint8_t PCA9553::getOutputMode(uint8_t pin)
{
if (pin >= _outputCount)
{
_error = PCA9553_ERR_CHAN;
return _error;
}
uint8_t reg = PCA9553_LS0;
uint8_t ledSelect = readReg(reg);
uint8_t mode = (ledSelect >> (pin * 2)) & 0x03;
return mode;
}
uint8_t PCA9553::getLastError()
{
uint8_t e = _error;
_error = PCA9553_OK;
return e;
}
/////////////////////////////////////////////////////
//
// PRIVATE
//
uint8_t PCA9553::writeReg(uint8_t reg, uint8_t value)
{
_wire->beginTransmission(_address);
_wire->write(reg);
_wire->write(value);
_error = _wire->endTransmission();
if (_error == 0) _error = PCA9553_OK;
else _error = PCA9553_ERR_I2C;
return _error;
}
uint8_t PCA9553::readReg(uint8_t reg)
{
_wire->beginTransmission(_address);
_wire->write(reg);
_error = _wire->endTransmission();
if (_error == 0) _error = PCA9553_OK;
else
{
_error = PCA9553_ERR_I2C;
return 0;
}
if (_wire->requestFrom(_address, (uint8_t)1) != 1)
{
_error = PCA9553_ERR_I2C;
return 0;
}
_error = PCA9553_OK;
return _wire->read();
}
// -- END OF FILE --