GY-63_MS5611/libraries/PCA9635/PCA9635.cpp

226 lines
4.5 KiB
C++
Raw Normal View History

2016-04-24 02:26:22 -04:00
//
// FILE: PCA9635.cpp
// AUTHOR: Rob Tillaart
// DATE: 23-apr-2016
2021-04-25 13:56:44 -04:00
// VERSION: 0.3.1
2020-11-27 05:28:57 -05:00
// PURPOSE: Arduino library for PCA9635 I2C LED driver
// URL: https://github.com/RobTillaart/PCA9635
2016-04-24 02:26:22 -04:00
//
2021-01-29 06:31:58 -05:00
// HISTORY:
2021-04-25 13:56:44 -04:00
// 0.3.1 2021-04-25 fix writeN by aspyra
2021-01-29 06:31:58 -05:00
// 0.3.0 2021-01-18 support Wire1..WireN
// 0.2.2 2021-01-13 refactor + fix register index error.
// 0.2.1 2021-01-05 arduino-CI + unit test
// 0.2.0 2020-05-26 major refactor; ESP32 support
// 0.1.2 2020-05-07 fix for PCA9635_MODE1
// 0.1.1 2016-04-24 set autoincr in constructor
// 0.1.0 2016-04-23 initial BETA version
2016-04-24 02:26:22 -04:00
2021-01-29 06:31:58 -05:00
#include "PCA9635.h"
2016-04-24 02:26:22 -04:00
2020-11-27 05:28:57 -05:00
2021-01-29 06:31:58 -05:00
//////////////////////////////////////////////////////////////
//
// Constructor
//
PCA9635::PCA9635(const uint8_t deviceAddress, TwoWire *wire)
2016-04-24 02:26:22 -04:00
{
2020-11-27 05:28:57 -05:00
_address = deviceAddress;
2021-01-29 06:31:58 -05:00
_wire = wire;
2020-11-27 05:28:57 -05:00
}
2021-01-29 06:31:58 -05:00
2020-11-27 05:28:57 -05:00
#if defined (ESP8266) || defined(ESP32)
2021-01-29 06:31:58 -05:00
bool PCA9635::begin(uint8_t sda, uint8_t scl)
2020-11-27 05:28:57 -05:00
{
2021-01-29 06:31:58 -05:00
_wire = &Wire;
if ((sda < 255) && (scl < 255))
{
_wire->begin(sda, scl);
} else {
_wire->begin();
}
if (! isConnected()) return false;
2020-11-27 05:28:57 -05:00
reset();
2021-01-29 06:31:58 -05:00
return true;
2020-11-27 05:28:57 -05:00
}
#endif
2021-01-29 06:31:58 -05:00
bool PCA9635::begin()
2020-11-27 05:28:57 -05:00
{
2021-01-29 06:31:58 -05:00
_wire->begin();
if (! isConnected()) return false;
2020-11-27 05:28:57 -05:00
reset();
2021-01-29 06:31:58 -05:00
return true;
2020-11-27 05:28:57 -05:00
}
2021-01-29 06:31:58 -05:00
bool PCA9635::isConnected()
{
_wire->beginTransmission(_address);
_error = _wire->endTransmission();
return (_error == 0);
}
2020-11-27 05:28:57 -05:00
void PCA9635::reset()
{
_data = 0;
_error = 0;
writeReg(PCA9635_MODE1, 0x81); // AUTOINCR | NOSLEEP | ALLADRR
2016-04-24 02:26:22 -04:00
}
2021-01-29 06:31:58 -05:00
2016-04-24 02:26:22 -04:00
// write value to single PWM registers
2020-11-27 05:28:57 -05:00
uint8_t PCA9635::write1(uint8_t channel, uint8_t value)
2016-04-24 02:26:22 -04:00
{
2020-11-27 05:28:57 -05:00
return writeN(channel, &value, 1);
2016-04-24 02:26:22 -04:00
}
2021-01-29 06:31:58 -05:00
2016-04-24 02:26:22 -04:00
// write three values in consecutive PWM registers
// typically for RGB values
2020-11-27 05:28:57 -05:00
uint8_t PCA9635::write3(uint8_t channel, uint8_t R, uint8_t G, uint8_t B)
2016-04-24 02:26:22 -04:00
{
2020-11-27 05:28:57 -05:00
uint8_t arr[3] = { R, G, B };
return writeN(channel, arr, 3);
2016-04-24 02:26:22 -04:00
}
2021-01-29 06:31:58 -05:00
2016-04-24 02:26:22 -04:00
// write count values in consecutive PWM registers
2021-04-25 13:56:44 -04:00
// checks if [channel + count - 1 > 15]
2020-11-27 05:28:57 -05:00
uint8_t PCA9635::writeN(uint8_t channel, uint8_t* arr, uint8_t count)
2016-04-24 02:26:22 -04:00
{
2021-04-25 13:56:44 -04:00
if (channel + count > 16)
2020-11-27 05:28:57 -05:00
{
_error = PCA9635_ERR_WRITE;
return PCA9635_ERROR;
}
uint8_t base = PCA9635_PWM(channel);
2021-01-29 06:31:58 -05:00
_wire->beginTransmission(_address);
_wire->write(base);
2020-11-27 05:28:57 -05:00
for(uint8_t i = 0; i < count; i++)
{
2021-01-29 06:31:58 -05:00
_wire->write(arr[i]);
2020-11-27 05:28:57 -05:00
}
2021-01-29 06:31:58 -05:00
_error = _wire->endTransmission();
2020-11-27 05:28:57 -05:00
if (_error != 0)
{
_error = PCA9635_ERR_I2C;
return PCA9635_ERROR;
}
return PCA9635_OK;
2016-04-24 02:26:22 -04:00
}
2021-01-29 06:31:58 -05:00
2020-11-27 05:28:57 -05:00
uint8_t PCA9635::writeMode(uint8_t reg, uint8_t value)
2016-04-24 02:26:22 -04:00
{
2020-11-27 05:28:57 -05:00
if ((reg == PCA9635_MODE1) || (reg == PCA9635_MODE2))
{
writeReg(reg, value);
2021-01-29 06:31:58 -05:00
return PCA9635_OK;
2020-11-27 05:28:57 -05:00
}
_error = PCA9635_ERR_REG;
return PCA9635_ERROR;
2016-04-24 02:26:22 -04:00
}
2021-01-29 06:31:58 -05:00
// Note 0xFF can also mean an error.... check error flag..
2016-04-24 02:26:22 -04:00
uint8_t PCA9635::readMode(uint8_t reg)
{
2020-11-27 05:28:57 -05:00
if ((reg == PCA9635_MODE1) || (reg == PCA9635_MODE2))
{
2021-01-29 06:31:58 -05:00
_error = PCA9635_OK;
2020-11-27 05:28:57 -05:00
uint8_t value = readReg(reg);
return value;
}
_error = PCA9635_ERR_REG;
return PCA9635_ERROR;
2016-04-24 02:26:22 -04:00
}
2021-01-29 06:31:58 -05:00
2020-11-27 05:28:57 -05:00
uint8_t PCA9635::setLedDriverMode(uint8_t channel, uint8_t mode)
2016-04-24 02:26:22 -04:00
{
2020-11-27 05:28:57 -05:00
if (channel > 15)
{
_error = PCA9635_ERR_CHAN;
return PCA9635_ERROR;
}
if (mode > 3)
{
_error = PCA9635_ERR_MODE;
return PCA9635_ERROR;
}
uint8_t reg = PCA9635_LEDOUT_BASE + (channel >> 2);
// some bit magic
uint8_t shift = (channel & 0x03) * 2; // 0,2,4,6 places
uint8_t setmask = mode << shift;
uint8_t clrmask = ~(0x03 << shift);
uint8_t value = (readReg(reg) & clrmask) | setmask;
writeReg(reg, value);
return PCA9635_OK;
2016-04-24 02:26:22 -04:00
}
2021-01-29 06:31:58 -05:00
2020-11-27 05:28:57 -05:00
// returns 0..3 if OK, other values indicate an error
2016-04-24 02:26:22 -04:00
uint8_t PCA9635::getLedDriverMode(uint8_t channel)
{
2020-11-27 05:28:57 -05:00
if (channel > 15)
{
_error = PCA9635_ERR_CHAN;
2016-04-24 02:26:22 -04:00
return PCA9635_ERROR;
2020-11-27 05:28:57 -05:00
}
uint8_t reg = PCA9635_LEDOUT_BASE + (channel >> 2);
uint8_t shift = (channel & 0x03) * 2; // 0,2,4,6 places
uint8_t value = (readReg(reg) >> shift ) & 0x03;
return value;
2016-04-24 02:26:22 -04:00
}
2021-01-29 06:31:58 -05:00
2020-11-27 05:28:57 -05:00
// note error flag is reset after read!
2016-04-24 02:26:22 -04:00
int PCA9635::lastError()
{
2020-11-27 05:28:57 -05:00
int e = _error;
_error = 0;
return e;
2016-04-24 02:26:22 -04:00
}
2020-11-27 05:28:57 -05:00
/////////////////////////////////////////////////////
//
// PRIVATE
//
2021-01-29 06:31:58 -05:00
uint8_t PCA9635::writeReg(uint8_t reg, uint8_t value)
2016-04-24 02:26:22 -04:00
{
2021-01-29 06:31:58 -05:00
_wire->beginTransmission(_address);
_wire->write(reg);
_wire->write(value);
_error = _wire->endTransmission();
if (_error == 0) _error = PCA9635_OK;
else _error = PCA9635_ERR_I2C;
return _error;
2016-04-24 02:26:22 -04:00
}
2020-11-27 05:28:57 -05:00
2016-04-24 02:26:22 -04:00
uint8_t PCA9635::readReg(uint8_t reg)
{
2021-01-29 06:31:58 -05:00
_wire->beginTransmission(_address);
_wire->write(reg);
_error = _wire->endTransmission();
if (_wire->requestFrom(_address, (uint8_t)1) != 1)
2020-11-27 05:28:57 -05:00
{
_error = PCA9635_ERROR;
return 0;
}
2021-01-29 06:31:58 -05:00
_error = PCA9635_OK;
_data = _wire->read();
2020-11-27 05:28:57 -05:00
return _data;
2016-04-24 02:26:22 -04:00
}
2020-11-27 05:28:57 -05:00
// -- END OF FILE --