Akash Vibhute / DRV2665
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers drv2665.cpp Source File

drv2665.cpp

00001 /**
00002  *  DRV2665 library
00003  *
00004  *  @author Akash Vibhute
00005  *  @author < akash . roboticist [at] gmail . com >
00006  *  @version 0.1
00007  *  @date May/24/2016
00008  */
00009 
00010 #include "drv2665.h"
00011 #define M_PI 3.14159265358979
00012 
00013 static const uint8_t drv2665_sine_wave_form[] = {
00014     0x00, 0x10, 0x20, 0x2e, 0x3c, 0x48, 0x53, 0x5b, 0x61, 0x65, 0x66,
00015     0x65, 0x61, 0x5b, 0x53, 0x48, 0x3c, 0x2e, 0x20, 0x10,
00016     0x00, 0xf0, 0xe0, 0xd2, 0xc4, 0xb8, 0xad, 0xa5, 0x9f, 0x9b, 0x9a,
00017     0x9b, 0x9f, 0xa5, 0xad, 0xb8, 0xc4, 0xd2, 0xe0, 0xf0, 0x00,
00018     0x10, 0x20, 0x2e, 0x3c, 0x48, 0x53, 0x5b, 0x61, 0x65, 0x66,
00019     0x65, 0x61, 0x5b, 0x53, 0x48, 0x3c, 0x2e, 0x20, 0x10,
00020     0x00, 0xf0, 0xe0, 0xd2, 0xc4, 0xb8, 0xad, 0xa5, 0x9f, 0x9b, 0x9a,
00021     0x9b, 0x9f, 0xa5, 0xad, 0xb8, 0xc4, 0xd2, 0xe0, 0xf0, 0x00,
00022     0x10, 0x20, 0x2e, 0x3c, 0x48, 0x53, 0x5b, 0x61, 0x65, 0x66,
00023     0x65, 0x61, 0x5b, 0x53, 0x48, 0x3c, 0x2e, 0x20, 0x10,
00024     0x00, 0xf0, 0xe0, 0xd2, 0xc4, 0xb8, 0xad, 0xa5, 0x9f, 0x9b, 0x9a,
00025     0x9b, 0x9f, 0xa5, 0xad, 0xb8, 0xc4, 0xd2, 0xe0, 0xf0, 0x00,
00026 };
00027 
00028 DRV2665_DIGITAL::DRV2665_DIGITAL( PinName sda, PinName scl ):i2c_(sda, scl)
00029 {
00030     i2c_.frequency(100000);
00031     i2c_addr = DRV2665_I2C_ADDRESS << 1;
00032     wait_ms(2); //wait 2ms for i2c bus
00033 }
00034 
00035 void DRV2665_DIGITAL::init(uint8_t output_gain, uint8_t idle_timeout)
00036 {
00037     write(DRV2665_CTRL_2, DRV2665_DEV_RST); //reset
00038     write(DRV2665_CTRL_2, 0); //clear standby
00039     //write(DRV2665_CTRL_1, (DRV2665_DIGITAL_IN | output_gain)); //set mode digital, set gain
00040     write(DRV2665_CTRL_1, DRV2665_DIGITAL_IN); //set mode digital, set gain
00041     write(DRV2665_CTRL_1, DRV2665_100_VPP_GAIN); //set mode digital, set gain
00042     write(DRV2665_CTRL_2, idle_timeout); //set timeout period
00043 }
00044 
00045 void DRV2665_DIGITAL::reset()
00046 {
00047     write(DRV2665_CTRL_2, DRV2665_DEV_RST);
00048 }
00049 
00050 void DRV2665_DIGITAL::outputWave(int8_t waveform[], uint8_t length)
00051 {
00052     char reg;
00053     char buff[100];
00054     
00055     buff[0] = DRV2665_FIFO;
00056     length = 81;
00057     
00058     /*
00059     for(int i=0; i<length; i++)
00060         buff[i+1] = drv2665_sine_wave_form[i];
00061     
00062     //while(!fifo_check());
00063     
00064     i2c_.write(i2c_addr, buff, 42);
00065     */
00066     
00067     if(fifo_check()) {
00068         //i2c_.write(i2c_addr, buff, 42);
00069         
00070         for(int i=0; i<length; i++) {
00071             write(DRV2665_FIFO, drv2665_sine_wave_form[i]);
00072             wait_us(20);
00073         }
00074         
00075     } else
00076         return;
00077         
00078 }
00079 
00080 void DRV2665_DIGITAL::outputSine(uint16_t hz)
00081 {
00082     int8_t waveform_byte;
00083     uint16_t length;
00084     uint8_t repeat = 1;
00085 
00086     //in the linux driver example, a 41 byte waveform plays back at 8kHz
00087     //wavelength 41 -> wave time 125us -> frequency 8kHz
00088     //hence per byte sampling time = 125us / 41 = 3.04878049
00089     //ie 41 bytes :: 8kHz -> 328 bytes :: 1000Hz
00090     //calculations done here are from this factor
00091 
00092     //length = (1000 * 328) / hz;
00093     
00094     
00095     //If the above assumption is incorrect, it could be that the DRV plays 
00096     //anything in its FIFO at a fix rate of 8ksps in that case, it would mean 
00097     //a per byte play time of 125us, ie for a 100byte wavelength -> a playback
00098     //time of 12.5ms (80Hz)
00099     //So, 100B :: 80Hz -> 100*80B :: 1Hz
00100     //For 'n' Hz :: (100*80/n) B
00101 
00102     length = (100 * 80) / hz;
00103     
00104     
00105     for(int j=0; j<repeat; j++) {
00106 
00107         for(int i=0; i<length; i++) {
00108             waveform_byte = 100.0 * sin( 2*M_PI * i/(length-1) ); //102 is the max +ve / -ve value, typecasting in uint8 turns -ve values into 2's complement required by the driver
00109 
00110             write(DRV2665_FIFO, (uint8_t)waveform_byte);
00111             wait_us(20);
00112         }
00113     }
00114 }
00115 
00116 bool DRV2665_DIGITAL::fifo_check()
00117 {
00118     uint8_t reply;
00119     reply = read(DRV2665_STATUS);
00120 
00121     if((reply & 0x01) == 0)
00122         return(true);
00123     else
00124         return(false);
00125 }
00126 
00127 void DRV2665_DIGITAL::en_override(uint8_t en)
00128 {
00129     char buff[2];
00130     
00131     buff[0] = DRV2665_BOOST_EN;
00132     buff[1] = en;
00133     
00134     write(DRV2665_CTRL_2, DRV2665_BOOST_EN);
00135 }
00136 
00137 uint8_t DRV2665_DIGITAL::read(char reg)
00138 {
00139     //Create a temporary buffer
00140     char buff[2];
00141 
00142     //Select the register
00143     i2c_.write(i2c_addr, &reg, 1, true);
00144 
00145     //Read the 16-bit register
00146     i2c_.read(i2c_addr, buff, 2);
00147 
00148     //Return the combined 16-bit value
00149     return (buff[0] << 8) | buff[1];
00150 }
00151 
00152 void DRV2665_DIGITAL::write(char reg, uint8_t data)
00153 {
00154     //Create a temporary buffer
00155     char buff[2];
00156 
00157     //Load the register address and 16-bit data
00158     buff[0] = reg;
00159     buff[1] = data;
00160 
00161     //Write the data
00162     i2c_.write(i2c_addr, buff, 2);
00163 }