Basic I2C Driver for the TI DRV2605 Haptic Driver. Currently only supports Open-Loop ERM operation using internal Immersion TouchSense 2200 software/library, although user can use the Read/Write Byte methods to manually set registers and control the device.

Dependents:   DRV2605L_Haptic_Driver_Demo IoT_Haptic_Noise_Irritator DuelingTanks

Committer:
electromotivated
Date:
Wed Oct 21 01:02:59 2015 +0000
Revision:
0:3b2b4f34aaca
v1 Upload;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
electromotivated 0:3b2b4f34aaca 1 #include "DRV2605.h"
electromotivated 0:3b2b4f34aaca 2
electromotivated 0:3b2b4f34aaca 3 DRV2605::DRV2605(PinName sda, PinName scl): i2c(sda, scl){
electromotivated 0:3b2b4f34aaca 4 wait_us(250); // Device datasheet specified wait time before I2C
electromotivated 0:3b2b4f34aaca 5 // comms should be used
electromotivated 0:3b2b4f34aaca 6 }
electromotivated 0:3b2b4f34aaca 7
electromotivated 0:3b2b4f34aaca 8 void DRV2605::i2cWriteByte(char reg, char value){
electromotivated 0:3b2b4f34aaca 9 char buff[2] = {reg, value};
electromotivated 0:3b2b4f34aaca 10 i2c.write(SLAVE_ADDR_7_BIT<<1, buff, 2);
electromotivated 0:3b2b4f34aaca 11 }
electromotivated 0:3b2b4f34aaca 12
electromotivated 0:3b2b4f34aaca 13 uint8_t DRV2605::i2cReadByte(char reg){
electromotivated 0:3b2b4f34aaca 14 char result; // Temp result storage
electromotivated 0:3b2b4f34aaca 15 i2c.write(SLAVE_ADDR_7_BIT<<1, &reg, 1, true);
electromotivated 0:3b2b4f34aaca 16 i2c.read(SLAVE_ADDR_7_BIT<<1, &result, 1);
electromotivated 0:3b2b4f34aaca 17
electromotivated 0:3b2b4f34aaca 18 return result;
electromotivated 0:3b2b4f34aaca 19 }
electromotivated 0:3b2b4f34aaca 20
electromotivated 0:3b2b4f34aaca 21 void DRV2605::mode(Mode mode){
electromotivated 0:3b2b4f34aaca 22 i2cWriteByte(MODE, mode);
electromotivated 0:3b2b4f34aaca 23 }
electromotivated 0:3b2b4f34aaca 24
electromotivated 0:3b2b4f34aaca 25 int DRV2605::init(float actuator_peak_voltage, Library lib){
electromotivated 0:3b2b4f34aaca 26 int result =
electromotivated 0:3b2b4f34aaca 27 auto_cal_open_loop(actuator_peak_voltage); // Perform Open-Loop ERM Cal
electromotivated 0:3b2b4f34aaca 28 i2cWriteByte(LIBRARY_SELECTION, lib); // Select ROM Library
electromotivated 0:3b2b4f34aaca 29 mode(STANDBY); // Put device into low- power mode
electromotivated 0:3b2b4f34aaca 30 return result; // Cal/Init Result 0: Pass 1: Fail
electromotivated 0:3b2b4f34aaca 31 }
electromotivated 0:3b2b4f34aaca 32
electromotivated 0:3b2b4f34aaca 33 uint8_t DRV2605::diagnostics(){
electromotivated 0:3b2b4f34aaca 34 mode(DIAG);
electromotivated 0:3b2b4f34aaca 35 i2cWriteByte(GO, 1);
electromotivated 0:3b2b4f34aaca 36 while(i2cReadByte(GO)); // Wait for GO bit to clear
electromotivated 0:3b2b4f34aaca 37
electromotivated 0:3b2b4f34aaca 38 return i2cReadByte(STATUS); // Return Status Reg Value
electromotivated 0:3b2b4f34aaca 39 }
electromotivated 0:3b2b4f34aaca 40
electromotivated 0:3b2b4f34aaca 41 void DRV2605::play_waveform(int waveform_effect){
electromotivated 0:3b2b4f34aaca 42 mode(INTERNAL_TRIG); // Bring device out of standby and set to internal trigger
electromotivated 0:3b2b4f34aaca 43 i2cWriteByte(WAVEFORM_SEQUENCER_1, waveform_effect); // Load waveform index to play
electromotivated 0:3b2b4f34aaca 44 i2cWriteByte(WAVEFORM_SEQUENCER_2, 0); // Insert stop condition so we don't play other registers if filled
electromotivated 0:3b2b4f34aaca 45 i2cWriteByte(GO, 0x01); // Set GO bit to start playback
electromotivated 0:3b2b4f34aaca 46 }
electromotivated 0:3b2b4f34aaca 47
electromotivated 0:3b2b4f34aaca 48 void DRV2605::load_waveform_sequence(int effect1, int effect2,
electromotivated 0:3b2b4f34aaca 49 int effect3, int effect4,
electromotivated 0:3b2b4f34aaca 50 int effect5, int effect6,
electromotivated 0:3b2b4f34aaca 51 int effect7, int effect8){
electromotivated 0:3b2b4f34aaca 52 i2cWriteByte(WAVEFORM_SEQUENCER_1, effect1);
electromotivated 0:3b2b4f34aaca 53 i2cWriteByte(WAVEFORM_SEQUENCER_2, effect2);
electromotivated 0:3b2b4f34aaca 54 i2cWriteByte(WAVEFORM_SEQUENCER_3, effect3);
electromotivated 0:3b2b4f34aaca 55 i2cWriteByte(WAVEFORM_SEQUENCER_4, effect4);
electromotivated 0:3b2b4f34aaca 56 i2cWriteByte(WAVEFORM_SEQUENCER_5, effect5);
electromotivated 0:3b2b4f34aaca 57 i2cWriteByte(WAVEFORM_SEQUENCER_6, effect6);
electromotivated 0:3b2b4f34aaca 58 i2cWriteByte(WAVEFORM_SEQUENCER_7, effect7);
electromotivated 0:3b2b4f34aaca 59 i2cWriteByte(WAVEFORM_SEQUENCER_8, effect8);
electromotivated 0:3b2b4f34aaca 60 }
electromotivated 0:3b2b4f34aaca 61
electromotivated 0:3b2b4f34aaca 62 void DRV2605::play(){
electromotivated 0:3b2b4f34aaca 63 i2cWriteByte(MODE, INTERNAL_TRIG); // Internal Trigger Mode
electromotivated 0:3b2b4f34aaca 64 i2cWriteByte(GO, 1);
electromotivated 0:3b2b4f34aaca 65 }
electromotivated 0:3b2b4f34aaca 66
electromotivated 0:3b2b4f34aaca 67 uint8_t DRV2605::auto_cal_open_loop(float actuator_peak_voltage){
electromotivated 0:3b2b4f34aaca 68 // Exit Standby Mode; Enter Auto- Cal Mode
electromotivated 0:3b2b4f34aaca 69 mode(AUTO_CAL);
electromotivated 0:3b2b4f34aaca 70
electromotivated 0:3b2b4f34aaca 71 /* Set the following registers to the appropriate values:
electromotivated 0:3b2b4f34aaca 72 • Rated Voltage (0x16)
electromotivated 0:3b2b4f34aaca 73 • Overdrive Voltage (0x17)
electromotivated 0:3b2b4f34aaca 74 • Feedback Control (0x1A) – Bits [1:0] can be left blank and will be
electromotivated 0:3b2b4f34aaca 75 populated by the auto-calibration engine
electromotivated 0:3b2b4f34aaca 76 • Control 1 (0x1B), Control 2 (0x1C), and Control 3 (0x1D)
electromotivated 0:3b2b4f34aaca 77 • Mode (0x01) – Set mode to Auto-Calibration
electromotivated 0:3b2b4f34aaca 78 • Auto-calibration Memory Interface (0x1E) – the auto-calibration time
electromotivated 0:3b2b4f34aaca 79 can be increased to improve calibration, but can be left as default
electromotivated 0:3b2b4f34aaca 80 for the initial calibration
electromotivated 0:3b2b4f34aaca 81 */
electromotivated 0:3b2b4f34aaca 82 // Rated Voltage (0x16) not referenced for open-loop operation, skip calc
electromotivated 0:3b2b4f34aaca 83
electromotivated 0:3b2b4f34aaca 84 // Calc and Set Overdrive Voltage Register (0x17)
electromotivated 0:3b2b4f34aaca 85 int od_clamp = (int)(((actuator_peak_voltage*255)/5.6)+0.5);
electromotivated 0:3b2b4f34aaca 86 i2cWriteByte(OVERDRIVE_CLAMP_VOLTAGE,
electromotivated 0:3b2b4f34aaca 87 i2cReadByte(OVERDRIVE_CLAMP_VOLTAGE) | od_clamp);
electromotivated 0:3b2b4f34aaca 88
electromotivated 0:3b2b4f34aaca 89 // Set Feedback Control Register (0x1A), use default values
electromotivated 0:3b2b4f34aaca 90
electromotivated 0:3b2b4f34aaca 91
electromotivated 0:3b2b4f34aaca 92 // Set Control 1 Register (0x1B), use default values
electromotivated 0:3b2b4f34aaca 93
electromotivated 0:3b2b4f34aaca 94
electromotivated 0:3b2b4f34aaca 95 // Set Control 2 Register (0x1C), use default values
electromotivated 0:3b2b4f34aaca 96
electromotivated 0:3b2b4f34aaca 97 // Set Control3 Register (0x1D), Set to ERM Open-Loop Operation
electromotivated 0:3b2b4f34aaca 98 i2cWriteByte(CONTROL3, 0xA0);
electromotivated 0:3b2b4f34aaca 99
electromotivated 0:3b2b4f34aaca 100 // Set Control 4 Register (0x1E)
electromotivated 0:3b2b4f34aaca 101 i2cWriteByte(CONTROL4,
electromotivated 0:3b2b4f34aaca 102 i2cReadByte(CONTROL4 | 0x30)); // Max Calibration Time
electromotivated 0:3b2b4f34aaca 103
electromotivated 0:3b2b4f34aaca 104 // Device already set to Auto- Cal Mode at top of this code block
electromotivated 0:3b2b4f34aaca 105
electromotivated 0:3b2b4f34aaca 106 // Start auto- calibration
electromotivated 0:3b2b4f34aaca 107 i2cWriteByte(GO, 0x01);
electromotivated 0:3b2b4f34aaca 108
electromotivated 0:3b2b4f34aaca 109 // Wait for calibration to complete
electromotivated 0:3b2b4f34aaca 110 while(i2cReadByte(GO));
electromotivated 0:3b2b4f34aaca 111
electromotivated 0:3b2b4f34aaca 112 // Read and return DIAG_RESULT in Status Register (0x00)
electromotivated 0:3b2b4f34aaca 113 return (i2cReadByte(STATUS)); // Return the Diag_Result Bit Result
electromotivated 0:3b2b4f34aaca 114 }
electromotivated 0:3b2b4f34aaca 115