Library for TI's DRV 2605

Dependents:   sonar_vibrator

DRV2605.cpp

Committer:
takuhachisu
Date:
2017-11-10
Revision:
0:d47ac72f4048
Child:
1:0747096351be

File content as of revision 0:d47ac72f4048:

#include "DRV2605.h"

DRV2605::DRV2605(I2C &i2c, bool isERM)
{
    wait_us(250);   // Device datasheet specified wait time before I2C
    _i2c =  &i2c;
    
    // comms should be used
    // Exit Standby Mode; Enter Auto- Cal Mode
    mode(Mode_AUTO_CAL);
    
    /* Set the following registers to the appropriate values:
        • Rated Voltage (0x16)
        • Overdrive Voltage (0x17)
        • Feedback Control (0x1A) – Bits [1:0] can be left blank and will be
          populated by the auto-calibration engine
        • Control 1 (0x1B), Control 2 (0x1C), and Control 3 (0x1D)
        • Mode (0x01) – Set mode to Auto-Calibration
        • Auto-calibration Memory Interface (0x1E) – the auto-calibration time
          can be increased to improve calibration, but can be left as default
          for the initial calibration
    */
    
    // Rated Voltage (0x16), use default values

    // Calc and Set Overdrive Voltage Register (0x17), use default values

    // Set Feedback Control Register (0x1A)
    if(isERM)
        i2cWriteByte(FEEDBACK_CONTROL, i2cReadByte(FEEDBACK_CONTROL) | Actuator_ERM); // set ERM
    else
        i2cWriteByte(FEEDBACK_CONTROL, i2cReadByte(FEEDBACK_CONTROL) | Actuator_LRA); // set LRA

    // Set Control 1 Register (0x1B), use default values

    // Set Control 2 Register (0x1C), use default values

    // Set Control 3 Register (0x1D), set data format for RTP unsinged
    i2cWriteByte(CONTROL3, i2cReadByte(CONTROL3) | 0x08); // set unsigned

    // Set Control 4 Register (0x1E), use default values

    // Device already set to Auto- Cal Mode at top of this code block

    if(isERM){
        // 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(char mode)
{
    i2cWriteByte(MODE, mode);
}

uint8_t DRV2605::diagnostics()
{
    mode(Mode_DIAG);
    i2cWriteByte(GO, 1);
    while(i2cReadByte(GO));     // Wait for GO bit to clear

    return i2cReadByte(STATUS); // Return Status Reg Value
}

void DRV2605::setLibrary(char 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(char rtp)
{
    i2cWriteByte(REAL_TIME_PLAYBACK, rtp);
}

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