Hans Kreuk / DRV2605_KickStartMyHeart

Fork of DRV2605 by Bryce Williams

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DRV2605.cpp Source File

DRV2605.cpp

00001 #include "DRV2605.h"
00002 
00003 DRV2605::DRV2605(PinName sda, PinName scl): i2c(sda, scl){
00004         wait_us(250);   // Device datasheet specified wait time before I2C
00005                         // comms should be used
00006 }
00007 
00008 void DRV2605::i2cWriteByte(char reg, char value){
00009     char buff[2] = {reg, value};
00010     i2c.write(SLAVE_ADDR_7_BIT<<1, buff, 2);
00011 }
00012 
00013 uint8_t DRV2605::i2cReadByte(char reg){
00014     char result;                                    // Temp result storage
00015     i2c.write(SLAVE_ADDR_7_BIT<<1, &reg, 1, true);  
00016     i2c.read(SLAVE_ADDR_7_BIT<<1, &result, 1);
00017     
00018     return result;         
00019 }
00020 
00021 void DRV2605::mode(Mode mode){
00022     i2cWriteByte(MODE, mode);
00023 }
00024 
00025 int DRV2605::init(float actuator_peak_voltage, Library lib){
00026     int result = 
00027         auto_cal_open_loop(actuator_peak_voltage); // Perform Open-Loop ERM Cal
00028     i2cWriteByte(LIBRARY_SELECTION, lib);     // Select ROM Library
00029     mode(STANDBY);                            // Put device into low- power mode
00030     return result;                            // Cal/Init Result 0: Pass 1: Fail
00031 }
00032 
00033 uint8_t DRV2605::diagnostics(){
00034     mode(DIAG);
00035     i2cWriteByte(GO, 1);
00036     while(i2cReadByte(GO));     // Wait for GO bit to clear
00037     
00038     return i2cReadByte(STATUS); // Return Status Reg Value
00039 }
00040 
00041 void DRV2605::play_waveform(int waveform_effect){
00042     mode(INTERNAL_TRIG);                                 // Bring device out of standby and set to internal trigger
00043     i2cWriteByte(WAVEFORM_SEQUENCER_1, waveform_effect); // Load waveform index to play
00044     i2cWriteByte(WAVEFORM_SEQUENCER_2, 0);               // Insert stop condition so we don't play other registers if filled
00045     i2cWriteByte(GO, 0x01);                              // Set GO bit to start playback
00046 }
00047 
00048 void DRV2605::load_waveform_sequence(int effect1, int effect2, 
00049                                      int effect3, int effect4,
00050                                      int effect5, int effect6, 
00051                                      int effect7, int effect8){
00052     i2cWriteByte(WAVEFORM_SEQUENCER_1, effect1);
00053     i2cWriteByte(WAVEFORM_SEQUENCER_2, effect2);
00054     i2cWriteByte(WAVEFORM_SEQUENCER_3, effect3);
00055     i2cWriteByte(WAVEFORM_SEQUENCER_4, effect4);
00056     i2cWriteByte(WAVEFORM_SEQUENCER_5, effect5);
00057     i2cWriteByte(WAVEFORM_SEQUENCER_6, effect6);
00058     i2cWriteByte(WAVEFORM_SEQUENCER_7, effect7);
00059     i2cWriteByte(WAVEFORM_SEQUENCER_8, effect8);                                         
00060 }
00061 
00062 void DRV2605::play(){
00063     i2cWriteByte(MODE, INTERNAL_TRIG);      // Internal Trigger Mode
00064     i2cWriteByte(GO, 1);
00065 }
00066 
00067 uint8_t DRV2605::kick_start_my_heart(int inten, int dur) { //inten range 1-10, dur range 1-8 
00068 //intensity values(1-123) refer to dvr2605_waveform.pdf, page60
00069     int left_over;
00070     uint8_t res;
00071     for ( int ind=0x04; ind<=(dur+0x003); ind++ ) {
00072         i2cWriteByte(ind, inten);
00073         left_over=ind;
00074         } 
00075     for (int ind=(left_over+1); ind<=0x0B; ind++) {
00076         i2cWriteByte(ind, 0);
00077         }
00078         res=diagnostics();
00079         printf("%X", res);
00080         play();
00081         return res;
00082         }
00083         
00084 
00085 uint8_t DRV2605::auto_cal_open_loop(float actuator_peak_voltage){
00086     // Exit Standby Mode; Enter Auto- Cal Mode
00087     mode(AUTO_CAL);
00088     
00089     /* Set the following registers to the appropriate values:
00090         • Rated Voltage (0x16)
00091         • Overdrive Voltage (0x17)
00092         • Feedback Control (0x1A) – Bits [1:0] can be left blank and will be
00093           populated by the auto-calibration engine
00094         • Control 1 (0x1B), Control 2 (0x1C), and Control 3 (0x1D)
00095         • Mode (0x01) – Set mode to Auto-Calibration
00096         • Auto-calibration Memory Interface (0x1E) – the auto-calibration time 
00097           can be increased to improve calibration, but can be left as default 
00098           for the initial calibration
00099     */ 
00100     // Rated Voltage (0x16) not referenced for open-loop operation, skip calc
00101     
00102     // Calc and Set Overdrive Voltage Register (0x17)
00103     int od_clamp = (int)(((actuator_peak_voltage*255)/5.6)+0.5);
00104     i2cWriteByte(OVERDRIVE_CLAMP_VOLTAGE,
00105                  i2cReadByte(OVERDRIVE_CLAMP_VOLTAGE) | od_clamp);
00106     
00107     // Set Feedback Control Register (0x1A), use default values
00108     
00109     
00110     // Set Control 1 Register (0x1B), use default values
00111     
00112     
00113     // Set Control 2 Register (0x1C), use default values
00114     
00115     // Set Control3 Register (0x1D), Set to ERM Open-Loop Operation 
00116     i2cWriteByte(CONTROL3, 0xA0);   
00117 
00118     // Set Control 4 Register (0x1E)                
00119     i2cWriteByte(CONTROL4,
00120                  i2cReadByte(CONTROL4 | 0x30)); // Max Calibration Time
00121     
00122     // Device already set to Auto- Cal Mode at top of this code block
00123     
00124     // Start auto- calibration
00125     i2cWriteByte(GO, 0x01);
00126     
00127     // Wait for calibration to complete
00128     while(i2cReadByte(GO));
00129     
00130     // Read and return DIAG_RESULT in Status Register (0x00)
00131     return (i2cReadByte(STATUS)); // Return the Diag_Result Bit Result
00132 }
00133