I2C Piezo Haptic Driver with Integrated Boost Converter and Digital Front End
Revision 1:e2c726c628dc, committed 2016-05-30
- Comitter:
- akashvibhute
- Date:
- Mon May 30 06:59:36 2016 +0000
- Parent:
- 0:b85fd3fdfcfa
- Commit message:
- working library
Changed in this revision
drv2665.cpp | Show annotated file Show diff for this revision Revisions of this file |
drv2665.h | Show annotated file Show diff for this revision Revisions of this file |
--- a/drv2665.cpp Wed May 25 03:17:20 2016 +0000 +++ b/drv2665.cpp Mon May 30 06:59:36 2016 +0000 @@ -10,16 +10,35 @@ #include "drv2665.h" #define M_PI 3.14159265358979 +static const uint8_t drv2665_sine_wave_form[] = { + 0x00, 0x10, 0x20, 0x2e, 0x3c, 0x48, 0x53, 0x5b, 0x61, 0x65, 0x66, + 0x65, 0x61, 0x5b, 0x53, 0x48, 0x3c, 0x2e, 0x20, 0x10, + 0x00, 0xf0, 0xe0, 0xd2, 0xc4, 0xb8, 0xad, 0xa5, 0x9f, 0x9b, 0x9a, + 0x9b, 0x9f, 0xa5, 0xad, 0xb8, 0xc4, 0xd2, 0xe0, 0xf0, 0x00, + 0x10, 0x20, 0x2e, 0x3c, 0x48, 0x53, 0x5b, 0x61, 0x65, 0x66, + 0x65, 0x61, 0x5b, 0x53, 0x48, 0x3c, 0x2e, 0x20, 0x10, + 0x00, 0xf0, 0xe0, 0xd2, 0xc4, 0xb8, 0xad, 0xa5, 0x9f, 0x9b, 0x9a, + 0x9b, 0x9f, 0xa5, 0xad, 0xb8, 0xc4, 0xd2, 0xe0, 0xf0, 0x00, + 0x10, 0x20, 0x2e, 0x3c, 0x48, 0x53, 0x5b, 0x61, 0x65, 0x66, + 0x65, 0x61, 0x5b, 0x53, 0x48, 0x3c, 0x2e, 0x20, 0x10, + 0x00, 0xf0, 0xe0, 0xd2, 0xc4, 0xb8, 0xad, 0xa5, 0x9f, 0x9b, 0x9a, + 0x9b, 0x9f, 0xa5, 0xad, 0xb8, 0xc4, 0xd2, 0xe0, 0xf0, 0x00, +}; + DRV2665_DIGITAL::DRV2665_DIGITAL( PinName sda, PinName scl ):i2c_(sda, scl) { + i2c_.frequency(100000); i2c_addr = DRV2665_I2C_ADDRESS << 1; wait_ms(2); //wait 2ms for i2c bus } void DRV2665_DIGITAL::init(uint8_t output_gain, uint8_t idle_timeout) { + write(DRV2665_CTRL_2, DRV2665_DEV_RST); //reset write(DRV2665_CTRL_2, 0); //clear standby - write(DRV2665_CTRL_1, (DRV2665_DIGITAL_IN | output_gain)); //set mode digital, set gain + //write(DRV2665_CTRL_1, (DRV2665_DIGITAL_IN | output_gain)); //set mode digital, set gain + write(DRV2665_CTRL_1, DRV2665_DIGITAL_IN); //set mode digital, set gain + write(DRV2665_CTRL_1, DRV2665_100_VPP_GAIN); //set mode digital, set gain write(DRV2665_CTRL_2, idle_timeout); //set timeout period } @@ -30,19 +49,39 @@ void DRV2665_DIGITAL::outputWave(int8_t waveform[], uint8_t length) { + char reg; + char buff[100]; + + buff[0] = DRV2665_FIFO; + length = 81; + + /* + for(int i=0; i<length; i++) + buff[i+1] = drv2665_sine_wave_form[i]; + + //while(!fifo_check()); + + i2c_.write(i2c_addr, buff, 42); + */ + if(fifo_check()) { + //i2c_.write(i2c_addr, buff, 42); + for(int i=0; i<length; i++) { - write(DRV2665_FIFO, waveform[i]); - wait_us(5); + write(DRV2665_FIFO, drv2665_sine_wave_form[i]); + wait_us(20); } + } else return; + } void DRV2665_DIGITAL::outputSine(uint16_t hz) { int8_t waveform_byte; uint16_t length; + uint8_t repeat = 1; //in the linux driver example, a 41 byte waveform plays back at 8kHz //wavelength 41 -> wave time 125us -> frequency 8kHz @@ -50,28 +89,27 @@ //ie 41 bytes :: 8kHz -> 328 bytes :: 1000Hz //calculations done here are from this factor - length = (1000 * 328) / hz; + //length = (1000 * 328) / hz; - /* + //If the above assumption is incorrect, it could be that the DRV plays //anything in its FIFO at a fix rate of 8ksps in that case, it would mean //a per byte play time of 125us, ie for a 100byte wavelength -> a playback - //time of 1.25ms (800Hz) - //So, 100B :: 800Hz -> 100*800B :: 1Hz - //For 'n' Hz :: (100*800/n) B + //time of 12.5ms (80Hz) + //So, 100B :: 80Hz -> 100*80B :: 1Hz + //For 'n' Hz :: (100*80/n) B - length = (100 * 800) / hz; - */ + length = (100 * 80) / hz; - for(int i=0; i<length; i++) { - waveform_byte = (uint8_t)(102.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 - - write(DRV2665_FIFO, waveform_byte); - wait_us(5); + for(int j=0; j<repeat; j++) { - while(!fifo_check()) - wait_us(5); + for(int i=0; i<length; i++) { + 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 + + write(DRV2665_FIFO, (uint8_t)waveform_byte); + wait_us(20); + } } } @@ -86,8 +124,13 @@ return(false); } -void DRV2665_DIGITAL::en_override(bool en) +void DRV2665_DIGITAL::en_override(uint8_t en) { + char buff[2]; + + buff[0] = DRV2665_BOOST_EN; + buff[1] = en; + write(DRV2665_CTRL_2, DRV2665_BOOST_EN); }
--- a/drv2665.h Wed May 25 03:17:20 2016 +0000 +++ b/drv2665.h Mon May 30 06:59:36 2016 +0000 @@ -39,7 +39,7 @@ #define DRV2665_50_VPP_GAIN 0x01 #define DRV2665_75_VPP_GAIN 0x02 #define DRV2665_100_VPP_GAIN 0x03 -#define DRV2665_DIGITAL_IN 0x00 +#define DRV2665_DIGITAL_IN 0xfb //0x00 #define DRV2665_ANALOG_IN 0x04 #define DRV2665_GAIN_RD_MASK 0x03 @@ -172,7 +172,7 @@ * * To override boot converter to be enabled indefinitely (-> true) or controlled by device logic (-> false) */ - void en_override(bool en); + void en_override(uint8_t en); private: I2C i2c_;