diff --git a/zh-cn/device-dev/driver/driver-peripherals-vibrator-des.md b/zh-cn/device-dev/driver/driver-peripherals-vibrator-des.md index a00c2accba4ee0bb683b4f6442f73ba2cfc9dcab..2681f157134ea465b1cf1e24477a3c7df23b0527 100755 --- a/zh-cn/device-dev/driver/driver-peripherals-vibrator-des.md +++ b/zh-cn/device-dev/driver/driver-peripherals-vibrator-des.md @@ -57,9 +57,11 @@ | 接口名 | 功能描述 | | -------------------------------------- | ------------------------------------------------ | -| int32_t StartOnce(uint32_t duration) | 按照指定持续时间触发振动马达,duration为振动持续时长。 | -| int32_t Start(const char *effectType) | 按照指定预置效果启动马达,effectType表示预置的预置效果。 | -| int32_t Stop(enum VibratorMode mode) | 按照指定的振动模式停止马达振动。 | +| int32_t StartOnce(uint32_t duration) | 按照指定持续时间触发振动马达,duration为振动持续时长。 | +| int32_t Start(const char *effectType) | 按照指定预置效果启动马达,effectType表示预置的预置效果。 | +| int32_t Stop(enum VibratorMode mode) | 按照指定的振动模式停止马达振动。 | +| int32_t EnableVibratorModulation(uint32_t duration, int32_t intensity, int32_t frequency) | 按照指定振幅、频率、持续时间触发振动马达。duration为振动持续时长,intensity为振动强度,frequency为振动频率。 | +| int32_t GetVibratorInfo(struct VibratorInfo **vibratorInfo); | 获取马达信息,包括是否支持振幅和频率的设置及振幅和频率的设置范围 。 | ### 开发步骤 @@ -90,13 +92,13 @@ Vibrator驱动模型为上层马达硬件服务层提供稳定的马达控制能 int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply) { int32_t loop; - + for (loop = 0; loop < sizeof(g_vibratorCmdHandle) / sizeof(g_vibratorCmdHandle[0]); ++loop) { if ((cmd == g_vibratorCmdHandle[loop].cmd) && (g_vibratorCmdHandle[loop].func != NULL)) { return g_vibratorCmdHandle[loop].func(data, reply); } } - + return HDF_SUCCESS; } @@ -105,34 +107,34 @@ Vibrator驱动模型为上层马达硬件服务层提供稳定的马达控制能 { struct VibratorDriverData *drvData = NULL; CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(device, HDF_FAILURE); - + drvData = (struct VibratorDriverData *)OsalMemCalloc(sizeof(*drvData)); CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_MALLOC_FAIL); - + drvData->ioService.Dispatch = DispatchVibrator; drvData->device = device; device->service = &drvData->ioService; g_vibratorDrvData = drvData; - + return HDF_SUCCESS; } - + /* 马达驱动初始化入口函数*/ int32_t InitVibratorDriver(struct HdfDeviceObject *device) { struct VibratorDriverData *drvData = NULL; - + drvData->mode = VIBRATOR_MODE_BUTT; drvData->state = VIBRATOR_STATE_IDLE; ...... if (CreateVibratorHaptic(device) != HDF_SUCCESS) { - HDF_LOGE("%s: init workQueue fail!", __func__); + HDF_LOGE("%s: init workQueue failed!", __func__); return HDF_FAILURE; } - + return HDF_SUCCESS; } - + /* 释放马达驱动初始化时分配的资源 */ void ReleaseVibratorDriver(struct HdfDeviceObject *device) { @@ -168,7 +170,7 @@ Vibrator驱动模型为上层马达硬件服务层提供稳定的马达控制能 - 创建马达效果模型。 - ```hcs + ```c /* 创建马达效果模型,分配资源,解析马达效果HCS配置 */ int32_t CreateVibratorHaptic(struct HdfDeviceObject *device) { @@ -181,7 +183,7 @@ Vibrator驱动模型为上层马达硬件服务层提供稳定的马达控制能 hapticData->supportHaptic = false; if (OsalMutexInit(&hapticData->mutex) != HDF_SUCCESS) { - HDF_LOGE("%s: fail to init mutex", __func__); + HDF_LOGE("%s: failed to init mutex", __func__); goto EXIT; } @@ -189,7 +191,7 @@ Vibrator驱动模型为上层马达硬件服务层提供稳定的马达控制能 /* 解析马达效果HCS配置 */ if (ParserVibratorHapticConfig(device->property) != HDF_SUCCESS) { - HDF_LOGE("%s: parser haptic config fail!", __func__); + HDF_LOGE("%s: parser haptic config failed!", __func__); goto EXIT; } @@ -235,7 +237,7 @@ Vibrator驱动模型为上层马达硬件服务层提供稳定的马达控制能 马达硬件服务调用StartOnce接口动态配置持续振动时间;调用StartEffect接口启动静态配置的振动效果,为驱动开发者提供抽象的配置接口能力。 ```c - /* 按照指定持续时间触发振动马达,duration为振动持续时长 */ + /* 按照指定持续时间触发振动马达,duration为振动持续时长。 */ static int32_t StartOnce(struct HdfSBuf *data, struct HdfSBuf *reply) { uint32_t duration; @@ -250,14 +252,14 @@ Vibrator驱动模型为上层马达硬件服务层提供稳定的马达控制能 /* 根据振动效果的模式创建定时器 */ ret = StartHaptic(&config); if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: start haptic fail!", __func__); + HDF_LOGE("%s: start haptic failed!", __func__); return ret; } return HDF_SUCCESS; } - /* 按照预置效果启动马达,effectType表示预置的预置效果 */ + /* 按照预置效果启动马达,effectType表示预置的预置效果。 */ static int32_t StartEffect(struct HdfSBuf *data, struct HdfSBuf *reply) { int32_t ret; @@ -272,7 +274,7 @@ Vibrator驱动模型为上层马达硬件服务层提供稳定的马达控制能 ret = StartHaptic(&config); if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: start haptic fail!", __func__); + HDF_LOGE("%s: start haptic failed!", __func__); return ret; } @@ -287,10 +289,10 @@ Vibrator驱动模型为上层马达硬件服务层提供稳定的马达控制能 struct VibratorDriverData *drvData = GetVibratorDrvData(); (void)reply; ...... - /* 停止马达效果振动,销毁马达定时器 */ + /* 停止马达效果振动,销毁马达定时器。 */ ret = StopHaptic(); if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: stop haptic fail!", __func__); + HDF_LOGE("%s: stop haptic failed!", __func__); return ret; } @@ -300,6 +302,58 @@ Vibrator驱动模型为上层马达硬件服务层提供稳定的马达控制能 return HDF_SUCCESS; } + + /* 按照指定振幅、频率、持续时间触发振动马达。duration为振动持续时长,intensity为振动强度,frequency为振动频率。 */ + static int32_t EnableModulationParameter(struct HdfSBuf *data, struct HdfSBuf *reply) + { + (void)reply; + struct VibratorEffectCfg config; + struct VibratorDriverData *drvData; + uint32_t duration; + int32_t intensity; + int32_t frequency; + int32_t ret; + ..... + (void)OsalMutexLock(&drvData->mutex); + drvData->mode = VIBRATOR_MODE_ONCE; + (void)OsalMutexUnlock(&drvData->mutex); + /* 设置振幅和频率 */ + ret = drvData->ops.SetParameter(intensity, frequency); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: set parameter failed", __func__); + return HDF_FAILURE; + } + + config.cfgMode = VIBRATOR_MODE_ONCE; + config.duration = duration; + config.effect = NULL; + + ret = StartHaptic(&config); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: start haptic failed", __func__); + return HDF_FAILURE; + } + + return HDF_SUCCESS; + } + + /* 获取马达信息,包括是否支持振幅和频率的设置及振幅和频率的设置范围。 */ + static int32_t GetVibratorInfo(struct HdfSBuf *data, struct HdfSBuf *reply) + { + (void)data; + struct VibratorDriverData *drvData; + + drvData = GetVibratorDrvData(); + CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_INVALID_PARAM); + CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(reply, HDF_ERR_INVALID_PARAM); + + if (!HdfSbufWriteBuffer(reply, &drvData->vibratorInfo, sizeof(drvData->vibratorInfo))) { + HDF_LOGE("%s: write sbuf failed", __func__); + return HDF_FAILURE; + } + + return HDF_SUCCESS; + } ``` 4. 马达驱动模型提供给开发者马达驱动差异化接口,开发者实现差异化接口。 @@ -319,50 +373,181 @@ Vibrator驱动模型为上层马达硬件服务层提供稳定的马达控制能 drvData->ops.Start = ops->Start; drvData->ops.StartEffect = ops->StartEffect; drvData->ops.Stop = ops->Stop; + drvData->ops.SetParameter = ops->SetParameter; + (void)OsalMutexUnlock(&drvData->mutex); + + return HDF_SUCCESS; + } + + /* 注册马达信息接口 */ + int32_t RegisterVibratorInfo(struct VibratorInfo *vibratorInfo) + { + struct VibratorDriverData *drvData = GetVibratorDrvData(); + + CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(vibratorInfo, HDF_FAILURE); + CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_FAILURE); + + (void)OsalMutexLock(&drvData->mutex); + if (memcpy_s(&drvData->vibratorInfo, sizeof(drvData->vibratorInfo), vibratorInfo, sizeof(*vibratorInfo)) != EOK) { + HDF_LOGE("%s: Memcpy vibrator config failed", __func__); + return HDF_FAILURE; + } (void)OsalMutexUnlock(&drvData->mutex); return HDF_SUCCESS; } ``` + + - 马达驱动模型提供给开发者马达驱动差异化接口,具体实现如下: ```c - /* 按照指定持续时间触发线性马达的振动 */ - static int32_t StartLinearVibrator() + /* 按照指定的振动模式停止马达的振动 */ + static int32_t StopModulationParameter() { - int32_t ret; - struct VibratorLinearDriverData *drvData = GetLinearVibratorData(); - CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_FAILURE); - ...... - ret = GpioWrite(drvData->gpioNum, GPIO_VAL_LOW); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: pull gpio%d to %d level failed", __func__, drvData->gpioNum, GPIO_VAL_LOW); - return ret; + 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_STANDBY; + 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_RTPIN; + value[DRV2605L_VALUE_INDEX] = (uint8_t)&drvData->drv2605lCfgData->vibratorAttr.defaultIntensity; + if (WriteDrv2605l(&drvData->drv2605lCfgData->vibratorBus.i2cCfg, value, sizeof(value)) != HDF_SUCCESS) { + HDF_LOGE("%s: i2c addr [%0X] write failed", __func__, value[DRV2605L_ADDR_INDEX]); + } + + value[DRV2605L_ADDR_INDEX] = (uint8_t)DRV2605_REG_LRARESON; + value[DRV2605L_VALUE_INDEX] = (uint8_t)&drvData->drv2605lCfgData->vibratorAttr.defaultFrequency; + 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_SUCCESS; - } - /* 按照预置振动效果触发线性马达的振动 */ - static int32_t StartEffectLinearVibrator(uint32_t effectType) - { - (void)effectType; - HDF_LOGE("%s: vibrator set build-in effect no support!", __func__); return HDF_SUCCESS; } - /* 按照指定的振动模式停止线性马达的振动 */ - static int32_t StopLinearVibrator() + /* 设置马达振幅和频率 */ + static void SetModulationParameter(int32_t intensity, int32_t frequency) { - int32_t ret; - struct VibratorLinearDriverData *drvData = GetLinearVibratorData(); + uint8_t value[DRV2605L_VALUE_BUTT]; + struct Drv2605lDriverData *drvData = NULL; + drvData = GetDrv2605lDrvData(); + CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_FAILURE); - ...... - ret = GpioWrite(drvData->gpioNum, GPIO_VAL_HIGH); - if (ret != HDF_SUCCESS) { - HDF_LOGE("%s: pull gpio%d to %d level failed", __func__, drvData->gpioNum, GPIO_VAL_HIGH); - return ret; + + if (intensity != 0) { + value[DRV2605L_ADDR_INDEX] = (uint8_t)DRV2605_REG_RTPIN; + value[DRV2605L_VALUE_INDEX] = (uint8_t)INTENSITY_MAPPING_VALUE(intensity); + 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; + } + } else { + HDF_LOGD("%s: the setting of intensity 0 is not supported and \ + will be set as the system default intensity", __func__); + } + + if (frequency != 0) { + value[DRV2605L_ADDR_INDEX] = (uint8_t)DRV2605_REG_LRARESON; + value[DRV2605L_VALUE_INDEX] = (uint8_t)FREQUENCY_MAPPING_VALUE(frequency); + 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; + } + } else { + HDF_LOGD("%s: the setting of frequency 0 is not supported and \ + will be set as the system default frequency", __func__); } - return HDF_SUCCESS; } - ``` \ No newline at end of file + ``` + +### 调测验证 + +驱动开发完成后,在传感器单元测试里面开发自测试用例,验证驱动基本功能。测试环境采用开发者自测试平台。 + +``` +/* 用例执行前,初始化马达接口实例。 */ +void HdfVibratorTest::SetUpTestCase() +{ + g_vibratorDev = NewVibratorInterfaceInstance(); +} +/* 用例资源释放 */ +void HdfVibratorTest::TearDownTestCase() +{ + if(g_vibratorDev != nullptr){ + FreeVibratorInterfaceInstance(); + g_vibratorDev = nullptr; + } +} + +/* 测试单次振动 */ +HWTEST_F(HdfVibratorTest, PerformOneShotVibratorDuration_001, TestSize.Level1) +{ + ASSERT_NE(nullptr, g_vibratorDev); + + int32_t startRet = g_vibratorDev->StartOnce(g_duration); + EXPECT_EQ(startRet, HDF_SUCCESS); + + OsalMSleep(g_sleepTime1); + + int32_t endRet = g_vibratorDev->Stop(VIBRATOR_MODE_ONCE); + EXPECT_EQ(endRet, HDF_SUCCESS); +} +/* 测试预置效果振动 */ +HWTEST_F(HdfVibratorTest, ExecuteVibratorEffect_002, TestSize.Level1) +{ + ASSERT_NE(nullptr, g_vibratorDev); + + int32_t startRet = g_vibratorDev->Start(g_builtIn); + EXPECT_EQ(startRet, HDF_SUCCESS); + + OsalMSleep(g_sleepTime1); + + int32_t endRet = g_vibratorDev->Stop(VIBRATOR_MODE_PRESET); + EXPECT_EQ(endRet, HDF_SUCCESS); +} +/* 获取马达信息,包括是否支持振幅和频率的设置及振幅和频率的设置范围。 */ +HWTEST_F(HdfVibratorTest, GetVibratorInfo_001, TestSize.Level1) +{ + ASSERT_NE(nullptr, g_vibratorDev); + + int32_t startRet = g_vibratorDev->GetVibratorInfo(&g_vibratorInfo); + EXPECT_EQ(startRet, HDF_SUCCESS); + EXPECT_NE(g_vibratorInfo, nullptr); + + printf("intensity = %d, intensityMaxValue = %d, intensityMinValue = %d\n\t", + g_vibratorInfo->isSupportIntensity, g_vibratorInfo->intensityMaxValue, g_vibratorInfo->intensityMinValue); + printf("frequency = %d, frequencyMaxValue = %d, frequencyMinValue = %d\n\t", + g_vibratorInfo->isSupportFrequency, g_vibratorInfo->frequencyMaxValue, g_vibratorInfo->frequencyMinValue); +} +/* 按照指定振幅、频率、持续时间触发振动马达。duration为振动持续时长,intensity为振动强度,frequency为振动频率。 */ +HWTEST_F(HdfVibratorTest, EnableVibratorModulation_001, TestSize.Level1) +{ + int32_t startRet; + ASSERT_NE(nullptr, g_vibratorDev); + EXPECT_GT(g_duration, 0); + + if ((g_vibratorInfo->isSupportIntensity == 1) || (g_vibratorInfo->isSupportFrequency == 1)) { + EXPECT_GE(g_intensity1, g_vibratorInfo->intensityMinValue); + EXPECT_LE(g_intensity1, g_vibratorInfo->intensityMaxValue); + EXPECT_GE(g_frequency1, g_vibratorInfo->frequencyMinValue); + EXPECT_LE(g_frequency1, g_vibratorInfo->frequencyMaxValue); + + startRet = g_vibratorDev->EnableVibratorModulation(g_duration, g_intensity1, g_frequency1); + EXPECT_EQ(startRet, HDF_SUCCESS); + OsalMSleep(g_sleepTime1); + startRet = g_vibratorDev->Stop(VIBRATOR_MODE_ONCE); + EXPECT_EQ(startRet, HDF_SUCCESS); + } +} +``` +