PCA9685: Add string based constructor for PWM Controller

This commit is contained in:
Adelin Dobre 2018-06-29 16:27:28 +03:00 committed by Stefan Andritoiu
parent 33fcb18cce
commit cdc60a5f1a
2 changed files with 112 additions and 12 deletions

View File

@ -28,6 +28,7 @@
#include <string>
#include <stdexcept>
#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<std::string> 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);

View File

@ -26,6 +26,7 @@
#include <string>
#include <mraa/i2c.h>
#include <mraa/gpio.h>
#include <mraa/initio.hpp>
#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;
};