Library for TI's DRV 2605

Dependents:   sonar_vibrator

DRV2605.cpp

Committer:
takuhachisu
Date:
2017-11-20
Revision:
2:08f047da9397
Parent:
1:0747096351be

File content as of revision 2:08f047da9397:

#include "DRV2605.h"

DRV2605::DRV2605(I2C &i2c, ActuatorType at, BrakeFactor bf, LoopGain lg,
                 uint8_t rv, uint8_t ocv, AutoCalTime act, uint8_t dt,
                 SampleTime st, uint8_t bt, uint8_t it)
{
    _i2c =  &i2c;

    // After powerup, wait at least 250 µs before the DRV2605 device accepts
    // I2C commands
    wait_us(250);

    // Assert the EN pin (logic high).
    // This is skipped because EN pin is connected to Vdd

    // To remove the device from standby mode
    mode(Mode_AUTO_CAL);

    // Auto calibratoin procedure
    // Populate the input parameters required by the auto-calibration engine:
    // Feedback Control Register;
    i2cWriteByte(FEEDBACK_CONTROL, i2cReadByte(FEEDBACK_CONTROL) | at | bf | lg);

    // Rated Voltage Register;
    i2cWriteByte(RATED_VOLTAGE, rv);

    // Overdrive Clamp Voltage Register;
    i2cWriteByte(OVERDRIVE_CLAMP_VOLTAGE, ocv);

    // Control4 Register;
    i2cWriteByte(CONTROL4, i2cReadByte(FEEDBACK_CONTROL) | act);

    // Control1 Register;
    i2cWriteByte(CONTROL1, i2cReadByte(FEEDBACK_CONTROL) | dt);

    // Control2 Register (only for LRA)
    if(at == LRA)
        i2cWriteByte(CONTROL2, i2cReadByte(FEEDBACK_CONTROL) | st | (bt << 2) | it);

    // Start auto- calibration
    i2cWriteByte(GO, 0x01);
    // Wait for calibration to complete
    while(i2cReadByte(GO));
}

void DRV2605::i2cWriteByte(char reg, char value)
{
    char buff[2] = {reg, value};
    _i2c->write(DRV2605_SLAVE_ADDR<<1, buff, 2);
}

uint8_t DRV2605::i2cReadByte(char reg)
{
    char result;                                    // Temp result storage
    _i2c->write(DRV2605_SLAVE_ADDR<<1, &reg, 1, true);
    _i2c->read(DRV2605_SLAVE_ADDR<<1, &result, 1);

    return result;
}

void DRV2605::mode(uint8_t mode)
{
    i2cWriteByte(MODE, mode);
}

uint8_t DRV2605::diagnostics()
{
    mode(Mode_DIAG);
    i2cWriteByte(GO, 1);
    while(i2cReadByte(GO));

    return i2cReadByte(STATUS);
}

void DRV2605::dataFormatRTP(bool isSigned)
{
    // Control3 Register (0x1D)
    if(isSigned)
        i2cWriteByte(CONTROL3, i2cReadByte(CONTROL3) & ~(1 << 3));
    else
        i2cWriteByte(CONTROL3, i2cReadByte(CONTROL3) | (1 << 3));
}

void DRV2605::setLibrary(uint8_t lib)
{
    i2cWriteByte(LIBRARY_SELECTION, lib);     // Select ROM Library
}

void DRV2605::setWaveform(int effect)
{
    i2cWriteByte(WAVEFORM_SEQUENCER_1, effect);          // Load waveform index to play
    i2cWriteByte(WAVEFORM_SEQUENCER_2, 0);               // Insert stop condition so we don't play other registers if filled
}

void DRV2605::setWaveformSequence(int effect1, int effect2,
                                  int effect3, int effect4,
                                  int effect5, int effect6,
                                  int effect7, int effect8)
{
    i2cWriteByte(WAVEFORM_SEQUENCER_1, effect1);
    i2cWriteByte(WAVEFORM_SEQUENCER_2, effect2);
    i2cWriteByte(WAVEFORM_SEQUENCER_3, effect3);
    i2cWriteByte(WAVEFORM_SEQUENCER_4, effect4);
    i2cWriteByte(WAVEFORM_SEQUENCER_5, effect5);
    i2cWriteByte(WAVEFORM_SEQUENCER_6, effect6);
    i2cWriteByte(WAVEFORM_SEQUENCER_7, effect7);
    i2cWriteByte(WAVEFORM_SEQUENCER_8, effect8);
}

void DRV2605::play()
{
    i2cWriteByte(GO, 1);
}

void DRV2605::stop()
{
    i2cWriteByte(GO, 0);
}

void DRV2605::playRtp(uint8_t rtp)
{
    i2cWriteByte(REAL_TIME_PLAYBACK, rtp);
}

float DRV2605::batteryVoltage(void)
{
    return (float)i2cReadByte(VBAT_VOLTAGE_MONITOR) / 255.0 * 5.6;
}