Hi, I'm trying to get an LRA haptic actuator to work with TI's DRV2605L driver chip. The actuator is a
C10-000 from Precision Microdevices.
I've successfully completed the calibration step described in the DRV2605L datasheet, but the haptic effects are weak, and the waveforms don't look like the ones in TI's setup guide. So, there is something I'm overlooking. I'll share the source code of my calibration routine implementation below.
bool DRV2605L::autoCalibrationLRA(float v_rms, float v_peak, float f_lra) {
// This procedure is described in section 8.5.6 of the datasheet
// Step 1. Power on device and pull EN HIGH (done prior to calling this function)
// Step 2. Place device in auto-calibration mode
writeByte(DRV2605L_REG_MODE, 0x07);
// Step 3. Populate the input parameters required by the auto-calibration engine
uint8_t feedback_val = 0;
feedback_val |= (1 << 7); // Set LRA mode
feedback_val |= (2 << 4); // Set Brake Factor to 2x
feedback_val |= (2 << 2); // Set Loop Gain to high
writeByte(DRV2605L_REG_FEEDBACK, feedback_val);
// Set rated voltage register value
float sample_time = 300 * pow(10, -6); // Sample time, default value 300 us
float v_avg_abs = v_rms * sqrt(1 - (4 * sample_time + 300 * pow(10, -6)) * f_lra);
uint8_t ratedv_val = (uint8_t) ((v_avg_abs * 255) / 5.3);
writeByte(DRV2605L_REG_RATEDV, ratedv_val);
// Set overdrive voltage clamp register value
uint8_t overdrive_val = (uint8_t) ((v_peak * 255) / 5.6);
writeByte(DRV2605L_REG_OVERDRIVE, overdrive_val);
uint8_t ctrl4_val = 0;
ctrl4_val |= (3 << 4); // Set auto cal time to 1000ms (min) to 1200ms (max)
writeByte(DRV2605L_REG_CONTROL4, ctrl4_val);
// Set drive-time to a half-period of the actuator
uint8_t ctrl1_val = 0;
float period_lra = 1.0 / f_lra;
uint8_t drive_time = (uint8_t) (((period_lra * 1000.0 / 2.0) -0.5) / 0.1);
ctrl1_val |= (drive_time & 0x1f);
writeByte(DRV2605L_REG_CONTROL1, ctrl1_val);
uint8_t ctrl2_val = 0;
ctrl2_val |= (3 << 4); // Set sample to 300 us
ctrl2_val |= (1 << 2); // Set blanking time to 25 us
ctrl2_val |= (1 << 0); // Set idiss time to 25 us
writeByte(DRV2605L_REG_CONTROL2, ctrl2_val);
// Note: ZC_DET_TIME bit is set to 0 (100 us) when control reg 4 is written
// Step 4. Set the GO bit to start auto-calibration process
writeByte(DRV2605L_REG_GO, 1);
while((readByte(DRV2605L_REG_GO) & 0x01) != 0) {
// Wait for GO bit to clear, as that indicates calibration complete
nrf_delay_ms(2);
}
// Step 5. Check the status of DIAG_RESULT bit
uint8_t status = readByte(DRV2605L_REG_STATUS);
return (status & 0x08) == 0;
}
I'm calling the calibration routine with these values: (2.0, 2.82, 205).
This is the output (my scope locked up every time I plugged my USB stick in, so please pardon the photo):
This is the waveform I'm expecting:
DRV2605 DatasheetDRV2605 Setup Guide