driver-peripherals-vibrator-des.md 22.8 KB
Newer Older
Mr-YX's avatar
Mr-YX 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
# Vibrator

## 概述

### 功能简介

为了快速开发传感器驱动,基于HDF(Hardware Driver Foundation)驱动框架开发了马达(Vibrator)驱动模型。马达驱动模型,屏蔽设备驱动与系统交互的实现,为硬件服务层提供统一稳定的驱动接口能力,为驱动开发者提供开放的接口和解析接口的能力,用于不同操作系统马达设备部件的部署指导和马达设备部件驱动的开发。马达驱动模型如图1所示:

**图 1** 马达驱动模型图

![Vibrator驱动模型图](figures/Vibrator驱动模型图.png)

### 基本概念

系统通过调用马达实现对设备的振动控制。目前,马达只有两种振动方式:

- 单次振动

  单次振动是指按照指定的时间控制振动时长。

- 周期振动

  周期振动是指按照预置的效果模式控制振动。例如:预置效果为“haptic.clock.timer” = [600, 600, 200, 600],等待600ms,振动600ms,等待200ms,振动600ms。

### 运作机制

通过介绍马达驱动模型的加载以及运行流程,对模型内部关键组件以及关联组件之间的关系进行了划分,整体加载流程如图2所示:

**图2** 马达驱动运行图

![Vibrator驱动运行图](figures/Vibrator驱动运行图.png)

马达驱动模型以标准系统Hi3516DV300产品为例,介绍整个驱动加载及运行流程:

1. 从device_info.hcs配置文件中的Vibrator Host读取Vibrator管理配置信息。
2. 解析Vibrator管理配置信息,并关联对应马达抽象驱动。
3. 从linear_vibrator_config.hcs配置文件中读取Vibrator数据配置信息。
4. 解析Vibrator数据配置信息,并关联对应Haptic驱动。
5. 客户端下发Vibrator Stub控制到服务端。
6. Vibrator Stub控制调用马达服务。
7. 初始化马达抽象驱动接口。
8. Haptic中起线程,解析效果模块。
9. Haptic调用马达抽象驱动中的Start接口。
10. 马达抽象驱动调用马达差异化驱动中的Start接口。

## 开发指导

### 场景介绍

当设备需要设置不同的振动效果时,可以调用Vibrator模块,例如,设备的按键可以设置不同强度和时长的振动,闹钟和来电可以设置不同强度和时长的单次或周期性振动。

### 接口说明

马达驱动模型支持静态HCS配置和动态参数两种振动效果配置能力。马达硬件服务调用StartOnce接口动态配置持续振动;调用Start接口启动静态配置的振动效果。马达驱动模型对HDI开放的API接口能力,如下表所示。

**表 1** 马达驱动模型对外API接口能力介绍

| 接口名                                  | 功能描述                                           |
| -------------------------------------- | ------------------------------------------------ |
60 61 62 63 64
| 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); | 获取马达信息,包括是否支持振幅和频率的设置及振幅和频率的设置范围 。 |
Mr-YX's avatar
Mr-YX 已提交
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94

### 开发步骤

Vibrator驱动模型为上层马达硬件服务层提供稳定的马达控制能力接口,包括马达一次振动、马达效果配置震动、马达停止。基于HDF驱动框架开发的马达驱动模型,实现跨操作系统迁移、器件差异配置等功能。具体的开发步骤如下:

1. 基于HDF驱动框架,按照驱动Driver Entry程序,完成马达抽象驱动开发,主要由Bind、Init、Release、Dispatch函数接口实现,配置资源和HCS解析。

   - 调用HDF_INIT将驱动入口注册到HDF框架中,在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出马达驱动模型,使用HCS作为配置描述源码。HCS配置字段详细介绍参考[配置管理](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/driver/driver-hdf-manage.md)。其中Driver Entry入口函数定义如下:

     ```c
     /* 注册马达抽象驱动入口数据结构体对象 */
     struct HdfDriverEntry g_vibratorDriverEntry = {
         .moduleVersion = 1, // 马达模块版本号
         .moduleName = "HDF_VIBRATOR", // 马达模块名,要与device_info.hcs文件里的马达moduleName字段值一样
         .Bind = BindVibratorDriver, // 马达绑定函数
         .Init = InitVibratorDriver, // 马达初始化函数
         .Release = ReleaseVibratorDriver, // 马达资源释放函数
     };
     
     HDF_INIT(g_vibratorDriverEntry);
     ```

   - 基于HDF驱动框架,按照驱动Driver Entry程序,完成马达抽象驱动开发,主要由Bind、Init、Release、Dispatch函数接口实现。

     ```c
     /* 马达驱动对外发布的能力 */
     static int32_t DispatchVibrator(struct HdfDeviceIoClient *client,
         int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
     {
         int32_t loop;
95

Mr-YX's avatar
Mr-YX 已提交
96 97 98 99 100
         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);
             }
         }
101

Mr-YX's avatar
Mr-YX 已提交
102 103 104 105 106 107 108 109
         return HDF_SUCCESS;
     }
     
     /* 马达驱动对外提供的服务绑定到HDF框架 */
     int32_t BindVibratorDriver(struct HdfDeviceObject *device)
     {
         struct VibratorDriverData *drvData = NULL;
         CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(device, HDF_FAILURE);
110

Mr-YX's avatar
Mr-YX 已提交
111 112
         drvData = (struct VibratorDriverData *)OsalMemCalloc(sizeof(*drvData));
         CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_MALLOC_FAIL);
113

Mr-YX's avatar
Mr-YX 已提交
114 115 116 117
         drvData->ioService.Dispatch = DispatchVibrator;
         drvData->device = device;
         device->service = &drvData->ioService;
         g_vibratorDrvData = drvData;
118

Mr-YX's avatar
Mr-YX 已提交
119 120
         return HDF_SUCCESS;
     }
121

Mr-YX's avatar
Mr-YX 已提交
122 123 124 125
     /* 马达驱动初始化入口函数*/
     int32_t InitVibratorDriver(struct HdfDeviceObject *device)
     {
         struct VibratorDriverData *drvData = NULL;
126

Mr-YX's avatar
Mr-YX 已提交
127 128 129 130
         drvData->mode = VIBRATOR_MODE_BUTT;
         drvData->state = VIBRATOR_STATE_IDLE;
         ......
         if (CreateVibratorHaptic(device) != HDF_SUCCESS) {
131
             HDF_LOGE("%s: init workQueue failed!", __func__);
Mr-YX's avatar
Mr-YX 已提交
132 133
             return HDF_FAILURE;
         }
134

Mr-YX's avatar
Mr-YX 已提交
135 136
         return HDF_SUCCESS;
     }
137

Mr-YX's avatar
Mr-YX 已提交
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
     /* 释放马达驱动初始化时分配的资源 */
     void ReleaseVibratorDriver(struct HdfDeviceObject *device)
     {
         struct VibratorDriverData *drvData = NULL;
         ......
         (void)DestroyVibratorHaptic();
         (void)OsalMutexDestroy(&drvData->mutex);
         (void)OsalMemFree(drvData);
         g_vibratorDrvData = NULL;
     }
     ```

   - 在系统启动过程中,HDF设备管理模块通过设备HCS配置信息,加载马达抽象驱动,并对外发布马达驱动接口。

     ```c
     /* 马达设备HCS配置 */
     vibrator :: host {
                 hostName = "vibrator_host";
                 device_vibrator :: device {
                     device0 :: deviceNode {
                         policy = 2; // 驱动服务发布的策略
                         priority = 100; // 驱动启动优先级(0-200),值越大优先级越低,建议配置100,优先级相同则不保证device的加载顺序
                         preload = 0; // 驱动按需加载字段,0表示加载,2表示不加载
                         permission = 0664; // 驱动创建设备节点权限
                         moduleName = "HDF_VIBRATOR"; // 驱动名称,该字段的值必须和驱动入口结构的moduleName值一致
                         serviceName = "hdf_misc_vibrator"; // 驱动对外发布服务的名称,必须唯一 
                         deviceMatchAttr = "hdf_vibrator_driver"; // 驱动私有数据匹配的关键字,必须和驱动私有数据配置表中的match_attr值相等
                     }
                 }
     ```

2. 创建马达效果模型,解析马达效果HCS配置。

   - 创建马达效果模型。

173
     ```c
Mr-YX's avatar
Mr-YX 已提交
174 175 176 177 178 179 180 181 182 183 184 185
     /* 创建马达效果模型,分配资源,解析马达效果HCS配置 */
     int32_t CreateVibratorHaptic(struct HdfDeviceObject *device)
     {
         struct VibratorHapticData *hapticData = NULL;
         CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(device, HDF_FAILURE);
     
         hapticData = (struct VibratorHapticData *)OsalMemCalloc(sizeof(*hapticData));
         CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(hapticData, HDF_ERR_MALLOC_FAIL);
         g_vibratorHapticData = hapticData;
         hapticData->supportHaptic = false;
     
         if (OsalMutexInit(&hapticData->mutex) != HDF_SUCCESS) {
186
             HDF_LOGE("%s: failed to init mutex", __func__);
Mr-YX's avatar
Mr-YX 已提交
187 188 189 190 191 192 193
             goto EXIT;
         }
     
         DListHeadInit(&hapticData->effectSeqHead);
     
         /* 解析马达效果HCS配置 */
         if (ParserVibratorHapticConfig(device->property) != HDF_SUCCESS) {
194
             HDF_LOGE("%s: parser haptic config failed!", __func__);
Mr-YX's avatar
Mr-YX 已提交
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
             goto EXIT;
         }
     
         return HDF_SUCCESS;
     EXIT:
         OsalMemFree(hapticData);
         return HDF_FAILURE;
     }
     ```

   - 马达效果模型使用HCS作为配置描述源码,hcs配置文件字段详细介绍参考[配置管理](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/driver/driver-hdf-manage.md)

     ```hcs
     /* 马达数据配置模板(vibrator_config.hcs) */
     root {
         vibratorConfig {
             boardConfig {
                 match_attr = "hdf_vibrator_driver"; // 需要和马达设备配置match_attr字段保持一致
                 vibratorAttr {
                     /* 0:转子;1:线性 */
                     deviceType = 1; // 设备类型
                     supportPreset = 1; // 支持的预设类型
                 }
                 vibratorHapticConfig {
                     haptic_clock_timer {
                         effectName = "haptic.clock.timer";
                         type = 1; // 0:内置模式;1:时间序列
                         seq = [600, 600, 200, 600]; // 时间序列
                     }
                     haptic_default_effect {
                         effectName = "haptic.default.effect";
                         type = 0;
                         seq = [0, 3, 800, 1];
                     }
                 }
             }
         }
     }
     ```

3. 完成马达振动和停止接口开发,会根据振动效果的模式创建和销毁定时器。

   马达硬件服务调用StartOnce接口动态配置持续振动时间;调用StartEffect接口启动静态配置的振动效果,为驱动开发者提供抽象的配置接口能力。

   ```c
240
   /* 按照指定持续时间触发振动马达,duration为振动持续时长。 */
Mr-YX's avatar
Mr-YX 已提交
241 242 243 244 245 246 247 248 249 250 251 252 253 254
   static int32_t StartOnce(struct HdfSBuf *data, struct HdfSBuf *reply)
   {
       uint32_t duration;
       int32_t ret;
       struct VibratorEffectCfg config;
       struct VibratorDriverData *drvData = GetVibratorDrvData();
       (void)reply;
       ...... 
       config.cfgMode = VIBRATOR_MODE_ONCE;
       config.duration = duration;
       config.effect = NULL;
       /* 根据振动效果的模式创建定时器 */
       ret = StartHaptic(&config);
       if (ret != HDF_SUCCESS) {
255
           HDF_LOGE("%s: start haptic failed!", __func__);
Mr-YX's avatar
Mr-YX 已提交
256 257 258 259 260 261
           return ret;
       }
   
       return HDF_SUCCESS;
   }
   
262
   /* 按照预置效果启动马达,effectType表示预置的预置效果。 */
Mr-YX's avatar
Mr-YX 已提交
263 264 265 266 267 268 269 270 271 272 273 274 275 276
   static int32_t StartEffect(struct HdfSBuf *data, struct HdfSBuf *reply)
   {
       int32_t ret;
       const char *effect = NULL;
       struct VibratorEffectCfg config;
       struct VibratorDriverData *drvData = GetVibratorDrvData();
       (void)reply;
       ......
       config.cfgMode = VIBRATOR_MODE_PRESET;
       config.duration = 0;
       config.effect = effect;
   
       ret = StartHaptic(&config);
       if (ret != HDF_SUCCESS) {
277
           HDF_LOGE("%s: start haptic failed!", __func__);
Mr-YX's avatar
Mr-YX 已提交
278 279 280 281 282 283 284 285 286 287 288 289 290 291
           return ret;
       }
   
       return HDF_SUCCESS;
   }
   
   /* 按照指定的振动模式停止马达振动 */
   static int32_t Stop(struct HdfSBuf *data, struct HdfSBuf *reply)
   {
       int32_t ret;
       int32_t mode;
       struct VibratorDriverData *drvData = GetVibratorDrvData();
       (void)reply;
       ......
292
       /* 停止马达效果振动,销毁马达定时器。 */
Mr-YX's avatar
Mr-YX 已提交
293 294
       ret = StopHaptic();
       if (ret != HDF_SUCCESS) {
295
           HDF_LOGE("%s: stop haptic failed!", __func__);
Mr-YX's avatar
Mr-YX 已提交
296 297 298 299 300 301 302 303 304
           return ret;
       }
   
       (void)OsalMutexLock(&drvData->mutex);
       drvData->mode = VIBRATOR_MODE_BUTT;
       (void)OsalMutexUnlock(&drvData->mutex);
   
       return HDF_SUCCESS;
   }
305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356
   
   /* 按照指定振幅、频率、持续时间触发振动马达。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;
   }
Mr-YX's avatar
Mr-YX 已提交
357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375
   ```

4. 马达驱动模型提供给开发者马达驱动差异化接口,开发者实现差异化接口。

   - 在差异化器件驱动初始化成功时,注册差异实现接口,方便实现器件差异的驱动接口。

     ```c
     /* 注册马达差异化实现接口 */
     int32_t RegisterVibrator(struct VibratorOps *ops)
     {
         struct VibratorDriverData *drvData = GetVibratorDrvData();
     
         CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(ops, HDF_FAILURE);
         CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_FAILURE);
     
         (void)OsalMutexLock(&drvData->mutex);
         drvData->ops.Start = ops->Start;
         drvData->ops.StartEffect = ops->StartEffect;
         drvData->ops.Stop = ops->Stop;
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394
         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;
         }
Mr-YX's avatar
Mr-YX 已提交
395 396 397 398 399 400
         (void)OsalMutexUnlock(&drvData->mutex);
     
         return HDF_SUCCESS;
     }
     ```

401 402
     

Mr-YX's avatar
Mr-YX 已提交
403 404 405
   - 马达驱动模型提供给开发者马达驱动差异化接口,具体实现如下:

     ```c
406 407
     /* 按照指定的振动模式停止马达的振动 */
     static int32_t StopModulationParameter()
Mr-YX's avatar
Mr-YX 已提交
408
     {
409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432
         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]);
Mr-YX's avatar
Mr-YX 已提交
433 434 435 436 437
         }
     
         return HDF_SUCCESS;
     }
     
438 439
     /* 设置马达振幅和频率 */
     static void SetModulationParameter(int32_t intensity, int32_t frequency)
Mr-YX's avatar
Mr-YX 已提交
440
     {
441 442 443 444
         uint8_t value[DRV2605L_VALUE_BUTT];
      struct Drv2605lDriverData *drvData = NULL;
         drvData = GetDrv2605lDrvData();
     
Mr-YX's avatar
Mr-YX 已提交
445
         CHECK_VIBRATOR_NULL_PTR_RETURN_VALUE(drvData, HDF_FAILURE);
446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468
     
         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__);
Mr-YX's avatar
Mr-YX 已提交
469 470
         }
     }
471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553
     ```

### 调测验证

驱动开发完成后,在传感器单元测试里面开发自测试用例,验证驱动基本功能。测试环境采用开发者自测试平台。

```
/* 用例执行前,初始化马达接口实例。 */
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);
    }
}
```