diff --git a/vibrator/chipset/drv2605l/vibrator_drv2605l_driver.c b/vibrator/chipset/drv2605l/vibrator_drv2605l_driver.c index e4b879dcdab0e19b160c1562c9931326015fd88b..c1869b6e47c997c9928af6a207b28c05c3e3a2c7 100644 --- a/vibrator/chipset/drv2605l/vibrator_drv2605l_driver.c +++ b/vibrator/chipset/drv2605l/vibrator_drv2605l_driver.c @@ -178,6 +178,13 @@ static int32_t InitDrv2605lChip(struct VibratorCfgData *drv2605lCfgData) return HDF_FAILURE; } + value[DRV2605L_ADDR_INDEX] = (uint8_t)DRV2605_REG_LIBRARY; + value[DRV2605L_VALUE_INDEX] = (uint8_t)DRV2605_LIBRARY_LRA; + if (WriteDrv2605l(&drv2605lCfgData->vibratorBus.i2cCfg, value, sizeof(value)) != HDF_SUCCESS) { + HDF_LOGE("%s: i2c addr [%0X] write failed", __func__, value[DRV2605L_ADDR_INDEX]); + return HDF_FAILURE; + } + return HDF_SUCCESS; } @@ -216,7 +223,7 @@ static int32_t SetModulationParameter(uint16_t intensity, int16_t frequency) return HDF_SUCCESS; } -static int32_t StartModulationParameter() +static int32_t StartModulationParameter(void) { uint8_t value[DRV2605L_VALUE_BUTT]; struct Drv2605lDriverData *drvData = NULL; @@ -234,7 +241,7 @@ static int32_t StartModulationParameter() return HDF_SUCCESS; } -static int32_t StopModulationParameter() +static int32_t StopModulationParameter(void) { uint8_t value[DRV2605L_VALUE_BUTT]; struct Drv2605lDriverData *drvData = NULL; @@ -267,6 +274,58 @@ static int32_t StopModulationParameter() return HDF_SUCCESS; } +static int32_t SetEffectId(uint8_t effectId) { + HDF_LOGE("%s: 2605 effectId = %d", __func__, effectId); + uint8_t value[DRV2605L_VALUE_BUTT]; + struct Drv2605lDriverData *drvData = NULL; + drvData = GetDrv2605lDrvData(); + + CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_FAILURE); + CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData->drv2605lCfgData, HDF_FAILURE); + + value[DRV2605L_ADDR_INDEX] = (uint8_t)DRV2605_REG_WAVESEQ1; + value[DRV2605L_VALUE_INDEX] = effectId; + if (WriteDrv2605l(&drvData->drv2605lCfgData->vibratorBus.i2cCfg, value, sizeof(value)) != HDF_SUCCESS) { + HDF_LOGE("%s: i2c addr [%0X] write failed", __func__, value[DRV2605L_ADDR_INDEX]); + return HDF_FAILURE; + } + + value[DRV2605L_ADDR_INDEX] = (uint8_t)DRV2605_REG_OVERDRIVE; + value[DRV2605L_VALUE_INDEX] = (uint8_t)DRV2605_TIME_OFFSET; + if (WriteDrv2605l(&drvData->drv2605lCfgData->vibratorBus.i2cCfg, value, sizeof(value)) != HDF_SUCCESS) { + HDF_LOGE("%s: i2c addr [%0X] write failed", __func__, value[DRV2605L_ADDR_INDEX]); + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +static int32_t EnablePrimitiveEffect(void) { + HDF_LOGE("%s: 2605 init", __func__); + + uint8_t value[DRV2605L_VALUE_BUTT]; + struct Drv2605lDriverData *drvData = NULL; + drvData = GetDrv2605lDrvData(); + + CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_FAILURE); + CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData->drv2605lCfgData, HDF_FAILURE); + + value[DRV2605L_ADDR_INDEX] = (uint8_t)DRV2605_REG_MODE; + value[DRV2605L_VALUE_INDEX] = (uint8_t)DRV2605_MODE_INTTRIG; + if (WriteDrv2605l(&drvData->drv2605lCfgData->vibratorBus.i2cCfg, value, sizeof(value)) != HDF_SUCCESS) { + HDF_LOGE("%s: i2c addr [%0X] write failed", __func__, value[DRV2605L_ADDR_INDEX]); + return HDF_FAILURE; + } + + value[DRV2605L_ADDR_INDEX] = (uint8_t)DRV2605_REG_GO; + value[DRV2605L_VALUE_INDEX] = (uint8_t)DRV2605_SET_OFF_GO; + if (WriteDrv2605l(&drvData->drv2605lCfgData->vibratorBus.i2cCfg, value, sizeof(value)) != HDF_SUCCESS) { + HDF_LOGE("%s: i2c addr [%0X] write failed", __func__, value[DRV2605L_ADDR_INDEX]); + return HDF_FAILURE; + } + + return HDF_SUCCESS; +} + static int32_t DispatchDrv2605l(struct HdfDeviceIoClient *client, int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply) { @@ -305,6 +364,8 @@ int32_t InitDrv2605lDriver(struct HdfDeviceObject *device) ops.SetParameter = SetModulationParameter; ops.Start = StartModulationParameter; ops.Stop = StopModulationParameter; + ops.SetEffectId = SetEffectId; + ops.EnablePrimitiveEffect = EnablePrimitiveEffect; ops.StartEffect = NULL; drvData->drv2605lCfgData = (struct VibratorCfgData *)OsalMemCalloc(sizeof(*drvData->drv2605lCfgData)); diff --git a/vibrator/chipset/drv2605l/vibrator_drv2605l_driver.h b/vibrator/chipset/drv2605l/vibrator_drv2605l_driver.h index d323ceb7b968c1dcbe66c9a5de5dbd829cbadd86..dd28a5bdd57fcbb248213091f4e2a628b78b85fe 100644 --- a/vibrator/chipset/drv2605l/vibrator_drv2605l_driver.h +++ b/vibrator/chipset/drv2605l/vibrator_drv2605l_driver.h @@ -25,16 +25,28 @@ #define DRV2605_REG_MODE 0x01 // Mode register #define DRV2605_MODE_REALTIME 0x05 // Real-time playback (RTP) mode -#define DRV2605_MODE_STANDBY 0x45 // Software standby mode +#define DRV2605_MODE_INTTRIG 0x00 // Internal trigger mode +#define DRV2605_MODE_STANDBY 0x40 // Software standby mode #define DRV2605_REG_CONTROL3 0x1D // Control3 Register #define DRV2605_MODE_OPEN_LOOP 0xA9 // Open Loop -#define DRV2605_REG_FEEDBACK 0x1A // Feedback control register -#define DRV2605_MODE_LRA 0xB6 // LRA Mode +#define DRV2605_REG_FEEDBACK 0x1A // Feedback control register +#define DRV2605_MODE_LRA 0xB6 // LRA Mode -#define DRV2605_REG_RTPIN 0x02 // Real-time playback input register -#define DRV2605_REG_LRARESON 0x20 // LRA open loop period +#define DRV2605_REG_RTPIN 0x02 // Real-time playback input register +#define DRV2605_REG_LRARESON 0x20 // LRA open loop period + +#define DRV2605_REG_LIBRARY 0x03 // Waveform library selection register +#define DRV2605_LIBRARY_LRA 0x06 // LRA Library + +#define DRV2605_REG_WAVESEQ1 0x04 // Waveform sequence register 1 + +#define DRV2605_REG_OVERDRIVE 0x0D // Overdrive time offset register +#define DRV2605_TIME_OFFSET 0X8A // time offset of the overdrive + +#define DRV2605_REG_GO 0x0C // Go register +#define DRV2605_SET_OFF_GO 0X01 // set off Go #define INTENSITY_MAPPING_VALUE(value) {0XA8 + ((value) * (0XFF - 0XA8)) / 100} diff --git a/vibrator/hal/include/vibrator_controller.h b/vibrator/hal/include/vibrator_controller.h index 2f252f282ed1ab873fcf0630bf2667a0a88aeb68..5cae038bfb46231a732e4f7f85aa8f905d872ac9 100644 --- a/vibrator/hal/include/vibrator_controller.h +++ b/vibrator/hal/include/vibrator_controller.h @@ -27,6 +27,7 @@ enum VibratorIoCmd { VIBRATOR_IO_STOP = 2, VIBRATOR_IO_GET_INFO = 3, VIBRATOR_IO_ENABLE_MODULATION_PARAMETER = 4, + VIBRATOR_IO_ENABLE_PRIMITIVE_EFFECT = 5, VIBRATOR_IO_END, }; diff --git a/vibrator/hal/src/vibrator_controller.c b/vibrator/hal/src/vibrator_controller.c index 35ec483e3da6b48a2e81dcc1dbbbd7647b220744..a122d892f7166eac91e7781506d0cdac5d013f86 100644 --- a/vibrator/hal/src/vibrator_controller.c +++ b/vibrator/hal/src/vibrator_controller.c @@ -304,6 +304,42 @@ static int32_t Stop(enum VibratorMode mode) return ret; } +static int32_t EnablePrimitiveEffect(uint8_t effect) +{ + int32_t ret; + + if (effect == 0 || (effect > EFFECT_ID_SHARP_CLICK_30 && effect < EFFECT_ID_STRONG_CLICK_1_100) || + effect > EFFECT_ID_SHARP_TICK_2_80) { + HDF_LOGE("%{public}s: invalid effect ID[%{public}d]", __func__, effect); + return HDF_FAILURE; + } + + struct VibratorDevice *priv = GetVibratorDevicePriv(); + (void)OsalMutexLock(&priv->mutex); + struct HdfSBuf *msg = HdfSbufObtainDefaultSize(); + if (msg == NULL) { + HDF_LOGE("%s: get sbuf failed", __func__); + (void)OsalMutexUnlock(&priv->mutex); + return HDF_FAILURE; + } + + if (!HdfSbufWriteUint8(msg, effect)) { + HDF_LOGE("%s: write effect ID failed", __func__); + HdfSbufRecycle(msg); + (void)OsalMutexUnlock(&priv->mutex); + return HDF_FAILURE; + } + + ret = SendVibratorMsg(VIBRATOR_IO_ENABLE_PRIMITIVE_EFFECT, msg, NULL); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%{public}s: Vibrator send cmd failed, ret[%{public}d]", __func__, ret); + } + HdfSbufRecycle(msg); + (void)OsalMutexUnlock(&priv->mutex); + + return ret; +} + const struct VibratorInterface *NewVibratorInterfaceInstance(void) { static struct VibratorInterface vibratorDevInstance; @@ -320,6 +356,7 @@ const struct VibratorInterface *NewVibratorInterfaceInstance(void) vibratorDevInstance.GetVibratorInfo = GetVibratorInfo; vibratorDevInstance.GetEffectInfo = GetEffectInfo; vibratorDevInstance.EnableVibratorModulation = EnableVibratorModulation; + vibratorDevInstance.EnablePrimitiveEffect = EnablePrimitiveEffect; priv->ioService = HdfIoServiceBind(VIBRATOR_SERVICE_NAME); if (priv->ioService == NULL) { diff --git a/vibrator/interfaces/include/vibrator_if.h b/vibrator/interfaces/include/vibrator_if.h index f9b598f58d9a0e3e1ccd74da223a8909b23eeb96..e770920a1c83d6925f136b9ed4e71aaba251f554 100644 --- a/vibrator/interfaces/include/vibrator_if.h +++ b/vibrator/interfaces/include/vibrator_if.h @@ -158,6 +158,18 @@ struct VibratorInterface { * @version 1.1 */ int32_t (*IsVibratorRunning)(bool state); + /** + * @brief Obtains whether the vibrator is currently vibrating.. + * + * @param effect Indicates waveform library effect ID. + * + * @return Returns 0 if the operation is successful. + * @return Returns negative value if the get failed. + * + * @since 3.2 + * @version 1.1 + */ + int32_t (*EnablePrimitiveEffect)(uint8_t effect); }; /** diff --git a/vibrator/interfaces/include/vibrator_type.h b/vibrator/interfaces/include/vibrator_type.h index e7ef1f38269ca5e60f5c2dd6a9ca5480dc8c7c5d..ec42249ababff55a7e75c7dd1601cb89a61bea6d 100644 --- a/vibrator/interfaces/include/vibrator_type.h +++ b/vibrator/interfaces/include/vibrator_type.h @@ -45,6 +45,29 @@ extern "C" { #endif #endif /* __cplusplus */ +/** + * @brief Enumerates the effect ids. + * + * @since 3.2 + */ +enum EffectId { + EFFECT_ID_STRONG_CLICK_100 = 1, + EFFECT_ID_STRONG_CLICK_60 = 2, + EFFECT_ID_STRONG_CLICK_30 = 3, + EFFECT_ID_SHARP_CLICK_100 = 4, + EFFECT_ID_SHARP_CLICK_60 = 5, + EFFECT_ID_SHARP_CLICK_30 = 6, + EFFECT_ID_STRONG_CLICK_1_100 = 17, + EFFECT_ID_STRONG_CLICK_2_80 = 18, + EFFECT_ID_STRONG_CLICK_3_60 = 19, + EFFECT_ID_STRONG_CLICK_4_30 = 17, + EFFECT_ID_MEDIUM_CLICK_1_100 = 21, + EFFECT_ID_MEDIUM_CLICK_2_80 = 22, + EFFECT_ID_MEDIUM_CLICK_3_60 = 23, + EFFECT_ID_SHARP_TICK_1_100 = 24, + EFFECT_ID_SHARP_TICK_2_80 = 25, +}; + /** * @brief Enumerates the return values of the vibrator module. * diff --git a/vibrator/test/unittest/common/hdf_vibrator_test.cpp b/vibrator/test/unittest/common/hdf_vibrator_test.cpp index 7e9ee321af5ff8fb3ef8731b8a4484e6ee403bbf..5f34e13df457a8f144603fbe242d7ff2d1035adc 100644 --- a/vibrator/test/unittest/common/hdf_vibrator_test.cpp +++ b/vibrator/test/unittest/common/hdf_vibrator_test.cpp @@ -29,6 +29,7 @@ namespace { uint32_t g_noDuration = 0; uint32_t g_sleepTime1 = 2000; uint32_t g_sleepTime2 = 5000; + uint32_t g_sleepTime3 = 50; int32_t g_intensity1 = 30; int32_t g_intensity2 = -30; int32_t g_frequency1 = 200; @@ -372,4 +373,40 @@ HWTEST_F(HdfVibratorTest, EnableVibratorModulation_004, TestSize.Level1) startRet = g_vibratorDev->EnableVibratorModulation(g_duration, g_intensity1, g_frequency2); EXPECT_EQ(startRet, VIBRATOR_NOT_FREQUENCY); } +} + +/** + * @tc.name: EnablePrimitiveEffect_001 + * @tc.desc: Start the vibration corresponding to the effect library based on the set ID. + * Validity check of input parameters. + * @tc.type: FUNC + * @tc.require: AR000FK1JN,AR000FK1J0,AR000FK1JP + */ +HWTEST_F(HdfVibratorTest, EnablePrimitiveEffect_001, TestSize.Level1) +{ + ASSERT_NE(nullptr, g_vibratorDev); + + int32_t startRet = g_vibratorDev->EnablePrimitiveEffect(EFFECT_ID_STRONG_CLICK_100); + EXPECT_EQ(startRet, VIBRATOR_NOT_FREQUENCY); + + OsalMSleep(g_sleepTime3); + + int32_t endRet = g_vibratorDev->Stop(VIBRATOR_MODE_ONCE); + EXPECT_EQ(endRet, HDF_SUCCESS); + +} + +/** + * @tc.name: EnablePrimitiveEffect_002 + * @tc.desc: Start the vibration corresponding to the effect library based on the set ID. + * Validity check of input parameters. + * @tc.type: FUNC + * @tc.require: AR000FK1JN,AR000FK1J0,AR000FK1JP + */ +HWTEST_F(HdfVibratorTest, EnablePrimitiveEffect_002, TestSize.Level1) +{ + ASSERT_NE(nullptr, g_vibratorDev); + + int32_t startRet = g_vibratorDev->EnablePrimitiveEffect(0); + EXPECT_EQ(startRet, HDF_FAILURE); } \ No newline at end of file