You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
4.7 KiB
108 lines
4.7 KiB
#ifndef _PCA9685_H_
|
|
#define _PCA9685_H_
|
|
|
|
#include <stdint.h>
|
|
#include <iostream>
|
|
#include <unistd.h>
|
|
#include <math.h>
|
|
#include "../../communication/i2c/i2c.hpp"
|
|
|
|
// https://www.nxp.com/docs/en/data-sheet/PCA9685.pdf
|
|
|
|
// REGISTER ADDRESSES
|
|
#define PCA9685_REG_MODE1 0x00 /**< Mode Register 1 */
|
|
#define PCA9685_REG_MODE2 0x01 /**< Mode Register 2 */
|
|
#define PCA9685_SUBADR1 0x02 /**< I2C-bus subaddress 1 */
|
|
#define PCA9685_SUBADR2 0x03 /**< I2C-bus subaddress 2 */
|
|
#define PCA9685_SUBADR3 0x04 /**< I2C-bus subaddress 3 */
|
|
#define PCA9685_ALLCALLADR 0x05 /**< LED All Call I2C-bus address */
|
|
|
|
#define PCA9685_LED_PWM_REG_START 0x06 // Start register of the fisrt LED's PWM Register wich also corresponds to LED0_ON_L
|
|
#define PCA9685_PWM_ON_H_OFFSET 0x01 // PWM ON HIGH Register for the selected LED
|
|
#define PCA9685_PWM_OFF_L_OFFSET 0x02 // PWM OFF LOW Register for the selected LED
|
|
#define PCA9685_PWM_OFF_H_OFFSET 0x03 // PWM OFF HIGH Register for the selected LED
|
|
#define PCA9685_LED_NEXT_OFFSET 0x04 // Register ON LOW of the next LED
|
|
|
|
#define PCA9685_LED_FULL_OFF_BIT 0x04 // Bit no to set on the LED OFF HIGH gerister of the selected LED to turn the LED fully OFF
|
|
#define PCA9685_LED_FULL_ON_BIT 0x04 // Bit no to set on the LED ON HIGH gerister of the selected LED to turn the LED fully ON
|
|
|
|
#define PCA9685_ALL_ON_L 0xFA // load all the LEDn_ON registers, low
|
|
#define PCA9685_ALL_ON_H 0xFB // load all the LEDn_ON registers, high
|
|
#define PCA9685_ALL_OFF_L 0xFC // load all the LEDn_OFF registers, low
|
|
#define PCA9685_ALL_OFF_H 0xFD // load all the LEDn_OFF registers,high
|
|
#define PCA9685_REG_PRESCALE 0xFE // Prescaler Register for PWM output frequency
|
|
#define PCA9685_TESTMODE 0xFF // defines the test mode to be entered
|
|
|
|
// MODE1 bits
|
|
#define PCA9685_MODE1_ALLCAL 0x01 /**< respond to LED All Call I2C-bus address */
|
|
#define PCA9685_MODE1_SUB3 0x02 /**< respond to I2C-bus subaddress 3 */
|
|
#define PCA9685_MODE1_SUB2 0x04 /**< respond to I2C-bus subaddress 2 */
|
|
#define PCA9685_MODE1_SUB1 0x08 /**< respond to I2C-bus subaddress 1 */
|
|
#define PCA9685_MODE1_SLEEP 0x10 /**< Low power mode. Oscillator off */
|
|
#define PCA9685_MODE1_AI 0x20 /**< Auto-Increment enabled */
|
|
#define PCA9685_MODE1_EXTCLK 0x40 /**< Use EXTCLK pin clock */
|
|
#define PCA9685_MODE1_RESTART 0x80 /**< Restart enabled */
|
|
|
|
// MODE2 bits
|
|
#define PCA9685_MODE2_OUTNE_0 0x01 /**< Active LOW output enable input */
|
|
#define PCA9685_MODE2_OUTNE_1 0x02 /**< Active LOW output enable input - high impedience */
|
|
#define PCA9685_MODE2_OUTDRV 0x04 /**< totem pole structure vs open-drain */
|
|
#define PCA9685_MODE2_OCH 0x08 /**< Outputs change on ACK vs STOP */
|
|
#define PCA9685_MODE2_INVRT 0x10 /**< Output logic state inverted */
|
|
|
|
#define PCA9685_I2C_ADDRESS 0x40 /**< Default PCA9685 I2C Slave Address */
|
|
#define PCA9685_FREQUENCY_OSCILLATOR 25000000 /**< Int. osc. frequency in datasheet */
|
|
#define PCA9685_OSC_STAB_TIME_US 500 // Delay to allow time for oscillator to stabilize 500 us
|
|
#define PCA9685_PRESCALE_MIN 3 /**< minimum prescale value */
|
|
#define PCA9685_PRESCALE_MAX 255 /**< maximum prescale value */
|
|
#define PCA9685_PRESCALE_DEF 200 // Default prescaler value | Datasheet Page : 25
|
|
|
|
class Pca9685
|
|
{
|
|
public:
|
|
enum errors
|
|
{
|
|
dutyCycleTooSlow, // Selected duty cycle is too big
|
|
dutyCycleTooFast, // Selected duty cycle is too small
|
|
freqTooFast, // Selected PWM frequency is too fast
|
|
freqTooSlow, // Selected PWM frequency is too slow
|
|
freqIsNull, // Oscillator frequency can't be 0 or inferior to 0
|
|
freqOver50Mhz, // Oscillator frequency cant't be higher than 50 MHz
|
|
onDutySetTooBig, // On Duty Cyle if greater than alowed maximum of 4095
|
|
offDutySetTooBig, // Off Duty Cyle if greater than alowed maximum of 4095
|
|
onOffDutySetTooBig, // Cumulation of the On & Off Duty Cyle if greater than alowed maximum of 4095
|
|
onEqaulOff, // On & Off count cylces can't be equal to each other
|
|
dutyCycle100Prcnt, // Duty cycle can't be greater than 100 percent
|
|
portInvalid // This port number doesn't exist
|
|
};
|
|
|
|
Pca9685(I2C* i2c);
|
|
void setPwmFreq(float frequency);
|
|
void setPwmRaw(uint8_t preScale);
|
|
void turnAllOff();
|
|
void turnAllOn();
|
|
uint8_t compensatePrescale(uint8_t preScale);
|
|
float getPwmFreq();
|
|
void setOnDutyPercent(uint8_t ledNo, uint8_t percent);
|
|
void setDutyRaw(uint8_t ledNo, uint16_t on, uint16_t off);
|
|
void setOnOff(uint8_t ledNo, bool onOff);
|
|
void confClk(bool internExtern, uint32_t freq);
|
|
void setOutputMode(bool mode);
|
|
void reset();
|
|
void sleep();
|
|
void wakeup();
|
|
void throwError(errors errNo);
|
|
private:
|
|
uint8_t m_currentLED;
|
|
uint8_t m_curMode;
|
|
float m_currentPwmFreq;
|
|
uint8_t m_currentPrescale;
|
|
uint8_t m_isExternalClock;
|
|
float m_oscillatorFreq;
|
|
I2C* i2c_pca9685;
|
|
};
|
|
|
|
|
|
#endif// _PCA9685_H_
|
|
|