plus court

Fork of Adafruit-PWM-Servo-Driver by K-Study-Team

AFPSD.cpp

Committer:
llarquere
Date:
2017-11-16
Revision:
4:b439851f9d20

File content as of revision 4:b439851f9d20:

/*************************************************** 
  This is a library for our Adafruit 16-channel PWM & Servo driver
  Pick one up today in the adafruit shop!
  ------> http://www.adafruit.com/products/815
  These displays use I2C to communicate, 2 pins are required to  
  interface. For Arduino UNOs, thats SCL -> Analog 5, SDA -> Analog 4
  Adafruit invests time and resources providing this open source code, 
  please support Adafruit and open-source hardware by purchasing 
  products from Adafruit!
  Written by Limor Fried/Ladyada for Adafruit Industries.  
  BSD license, all text above must be included in any redistribution
 ****************************************************/
 /*****************************
  This program was ported from https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library.
  I also added some functions.
  Shundo Kishi
 *****************************/

#include "AFPSD.h"

AFPSD::AFPSD( const int addr, I2C* i2c ) {
    _i2c = i2c;
    _devaddr = addr;
}

void AFPSD::setPrescale( const uint8_t prescale ) {
uint8_t oldmode = _read8(PCA9685_MODE1);
uint8_t newmode = (oldmode & 0x7F) | 0x10;  // sleep
#ifdef DEBUGI2C
    printf("ps %02X : %02d\n", _devaddr, prescale);
#endif
    _write8(PCA9685_MODE1, newmode);         // go to sleep
    wait_ms(5);
    _write8(PCA9685_PRESCALE, prescale);     // set the prescaler
    _write8(PCA9685_MODE1, oldmode);
    wait_ms(5);
    _write8(PCA9685_MODE1, oldmode | 0xA1);
}

void AFPSD::setPWMFreq( const float freq ) {
    //Serial.print("Attempting to set freq ");
    //Serial.println(freq);
float prescaleval = 25000000;
    prescaleval /= 4096;
    prescaleval /= freq;
    //Serial.print("Estimated pre-scale: "); Serial.println(prescaleval);
uint8_t prescale = floor(prescaleval  + 0.5f) - 1;
    //Serial.print("Final pre-scale: "); Serial.println(prescale);  
    setPrescale(prescale);
}

void AFPSD::setPWM( const uint8_t pin, const uint16_t on, const uint16_t off ) {
    // hmm doesnt work, whyso?  (  Not in AI mode.  See line 54 above.  ( Works now!!  :D  )
char cmd[5];
    cmd[0] = LED0_ON_L + 4 * pin;
    cmd[1] = on;
    cmd[2] = on >> 8;
    cmd[3] = off;
    cmd[4] = off >> 8;
    _i2c->write(_devaddr, cmd, 5);
#ifdef DEBUGI2C
    printf("pwm %02X : %02X %02X %02X %02X %02X\n", _devaddr, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4]);
#endif
    /*write8(LED0_ON_L+4*num, on);
    write8(LED0_ON_H+4*num, on >> 8);
    write8(LED0_OFF_L+4*num, off);
    write8(LED0_OFF_H+4*num, off >> 8);*/
}

// Set pwm duty in us order
void AFPSD::setDuty( const uint8_t pin, uint16_t duty ) {
float pulselength = 10000;   // 10,000 us per second
    duty = 4094 * duty / pulselength;
    setPWM(pin, 0, duty);
}

uint8_t AFPSD::_read8( const char pin ) {
    _i2c->write(_devaddr, &pin, 1);
#ifdef DEBUGI2C
    printf("r8w %02X : %02X\n", _devaddr, pin);
#endif
char rtn;
    _i2c->read(_devaddr, &rtn, 1);
#ifdef DEBUGI2C
    printf("r8r %02X : %02X\n", _devaddr, rtn);
#endif
    return rtn;
}

void AFPSD::_write8( const char pin, const char d ) {
char cmd[2];
    cmd[0] = pin;
    cmd[1] = d;
    _i2c->write(_devaddr, cmd, 2);
#ifdef DEBUGI2C
    printf("w8 %02X : %02X %02X\n", _devaddr, cmd[0], cmd[1]);
#endif
}