diff --git a/src/pca9685/pca9685.cxx b/src/pca9685/pca9685.cxx index 79745983..8aaa2579 100644 --- a/src/pca9685/pca9685.cxx +++ b/src/pca9685/pca9685.cxx @@ -28,6 +28,7 @@ #include #include +#include "upm_string_parser.hpp" #include "pca9685.hpp" using namespace upm; @@ -54,9 +55,9 @@ PCA9685::PCA9685(int bus, uint8_t address, bool raw) ": mraa_i2c_init() failed"); return; } - + mraa_result_t rv; - + if ( (rv = mraa_i2c_address(m_i2c, m_addr)) != MRAA_SUCCESS) { throw std::runtime_error(std::string(__FUNCTION__) + @@ -71,6 +72,96 @@ PCA9685::PCA9685(int bus, uint8_t address, bool raw) enableRestart(true); } +PCA9685::PCA9685(std::string initStr) : mraaIo(initStr) +{ + mraa_io_descriptor* descs = mraaIo.getMraaDescriptors(); + + std::vector upmTokens; + + if(mraaIo.getLeftoverStr() != "") { + upmTokens = UpmStringParser::parse(mraaIo.getLeftoverStr()); + } + + if(!descs->i2cs) + { + throw std::invalid_argument(std::string(__FUNCTION__) + + ": mraa_i2c_init() failed"); + } + else + { + if( !(m_i2c = descs->i2cs[0]) ) + { + throw std::invalid_argument(std::string(__FUNCTION__) + + ": mraa_i2c_init() failed"); + } + } + + // enable auto-increment mode by default + enableAutoIncrement(true); + + // enable restart by default. + enableRestart(true); + + std::string::size_type sz; + + for (std::string tok : upmTokens) { + if(tok.substr(0,10) == "writeByte:") { + uint8_t reg = std::stoi(tok.substr(10),&sz,0); + tok = tok.substr(10); + uint8_t byte = std::stoi(tok.substr(sz+1),nullptr,0); + writeByte(reg, byte); + } + if(tok.substr(0,10) == "writeWord:") { + uint8_t reg = std::stoi(tok.substr(10),&sz,0); + tok = tok.substr(10); + uint16_t word = std::stoi(tok.substr(sz+1),nullptr,0); + writeWord(reg, word); + } + if(tok.substr(0,10) == "modeSleep:") { + bool sleep = std::stoi(tok.substr(10),nullptr,0); + setModeSleep(sleep); + } + if(tok.substr(0,14) == "autoIncrement:") { + bool ai = std::stoi(tok.substr(14),nullptr,0); + enableAutoIncrement(ai); + } + if(tok.substr(0,10) == "ledFullOn:") { + uint8_t led = std::stoi(tok.substr(10),&sz,0); + tok = tok.substr(10); + bool val = std::stoi(tok.substr(sz+1),nullptr,0); + ledFullOn(led, val); + } + if(tok.substr(0,11) == "ledFullOff:") { + uint8_t led = std::stoi(tok.substr(11),&sz,0); + tok = tok.substr(11); + bool val = std::stoi(tok.substr(sz+1),nullptr,0); + ledFullOff(led, val); + } + if(tok.substr(0,10) == "ledOnTime:") { + uint8_t led = std::stoi(tok.substr(10),&sz,0); + tok = tok.substr(10); + uint16_t time = std::stoi(tok.substr(sz+1),nullptr,0); + ledOnTime(led, time); + } + if(tok.substr(0,11) == "ledOffTime:") { + uint8_t led = std::stoi(tok.substr(11),&sz,0); + tok = tok.substr(11); + uint16_t time = std::stoi(tok.substr(sz+1),nullptr,0); + ledOnTime(led, time); + } + if(tok.substr(0,9) == "prescale:") { + uint8_t prescale = std::stoi(tok.substr(9),nullptr,0); + setPrescale(prescale); + } + if(tok.substr(0,15) == "prescaleFromHz:") { + float hz = std::stof(tok.substr(15),&sz); + tok = tok.substr(15); + float oscFreq = std::stof(tok.substr(sz+1),nullptr); + setPrescaleFromHz(hz, oscFreq); + } + } +} + PCA9685::~PCA9685() { setModeSleep(true); @@ -139,7 +230,7 @@ bool PCA9685::setModeSleep(bool sleep) writeByte(REG_MODE1, mode1); - // Need a delay of 500us after turning sleep mode off for the oscillator + // Need a delay of 500us after turning sleep mode off for the oscillator // to stabilize if (!sleep) usleep(500); diff --git a/src/pca9685/pca9685.hpp b/src/pca9685/pca9685.hpp index 4ad39e83..d87df4fb 100644 --- a/src/pca9685/pca9685.hpp +++ b/src/pca9685/pca9685.hpp @@ -26,6 +26,7 @@ #include #include #include +#include #define PCA9685_I2C_BUS 0 #define PCA9685_DEFAULT_I2C_ADDR 0x60 @@ -37,7 +38,7 @@ #define PCA9685_ALL_LED 0xff namespace upm { - + /** * @brief PCA9685 PWM Controller * @defgroup pca9685 libupm-pca9685 @@ -150,7 +151,7 @@ namespace upm { REG_PRESCALE = 0xfe, REG_TESTMODE = 0xff // don't use } PCA9685_REG_T; - + /** * MODE1 bits */ @@ -163,7 +164,7 @@ namespace upm { MODE1_EXTCLK = 0x40, // external clock enable MODE1_RESTART = 0x80 // restart status } PCA9685_MODE1_T; - + /** * MODE2 bits */ @@ -176,7 +177,7 @@ namespace upm { MODE2_RESERVE1 = 0x40, // reserved MODE2_RESERVE2 = 0x80 // reserved } PCA9685_MODE2_T; - + /** * PCA9685 constructor * @@ -185,6 +186,13 @@ namespace upm { */ PCA9685(int bus, uint8_t address = PCA9685_DEFAULT_I2C_ADDR, bool raw = false); + /** + * Instantiates a PCA9685 PWM Controller object based on a given string. + * + * @param initStr string containing specific information for PCA9685 initialization. + */ + PCA9685(std::string initStr); + /** * PCA9685 destructor */ @@ -230,7 +238,7 @@ namespace upm { * Puts the device in or out of the sleep mode. The device is always * in the sleep mode upon power-up. * - * @param sleep True to put the device in the sleep mode, false to put out + * @param sleep True to put the device in the sleep mode, false to put out * @return True if successful */ bool setModeSleep(bool sleep); @@ -255,7 +263,7 @@ namespace upm { bool ledFullOff(uint8_t led, bool val); /** - * Sets the 'LED on' time (0-4,095). See the PCA9685 datasheet for details. + * Sets the 'LED on' time (0-4,095). See the PCA9685 datasheet for details. * * @param led LED number; valid values are 0-15, PCA9685_ALL_LED * @param time 12-bit value at which point the LED turns on @@ -264,7 +272,7 @@ namespace upm { bool ledOnTime(uint8_t led, uint16_t time); /** - * Sets the 'LED off' time (0-4,095). See the PCA9685 datasheet for details. + * Sets the 'LED off' time (0-4,095). See the PCA9685 datasheet for details. * * @param led LED number; valid values are 0-15, PCA9685_ALL_LED * @param time 12-bit value at which point the LED turns off @@ -287,10 +295,10 @@ namespace upm { * prescale can only be set when the device is in the sleep mode. * * @param hz Desired frequency in Hz - * @param oscFreq Oscillator frequency; default is 25 MHz + * @param oscFreq Oscillator frequency; default is 25 MHz * @return True if successful */ - bool setPrescaleFromHz(float hz, + bool setPrescaleFromHz(float hz, float oscFreq=PCA9685_INTERNAL_OSC); /** @@ -312,6 +320,7 @@ namespace upm { bool enableAutoIncrement(bool ai); bool m_restartEnabled; + mraa::MraaIo mraaIo; mraa_i2c_context m_i2c; uint8_t m_addr; };