1 /*
2 * Copyright (c) 2020-2023 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "pwm_test.h"
10 #include "device_resource_if.h"
11 #include "hdf_io_service_if.h"
12 #include "hdf_log.h"
13 #include "osal_mem.h"
14 #include "osal_time.h"
15 #include "securec.h"
16
17 #define HDF_LOG_TAG pwm_test
18 #define SEQ_OUTPUT_DELAY 100 /* Delay time of sequential output, unit: ms */
19 #define OUTPUT_WAVES_DELAY 1 /* Delay time of waves output, unit: second */
20 #define TEST_WAVES_NUMBER 10 /* The number of waves for test. */
21
PwmTesterGetConfig(struct PwmTestConfig * config)22 static int32_t PwmTesterGetConfig(struct PwmTestConfig *config)
23 {
24 int32_t ret;
25 struct HdfSBuf *reply = NULL;
26 struct HdfIoService *service = NULL;
27 const void *buf = NULL;
28 uint32_t len;
29
30 service = HdfIoServiceBind("PWM_TEST");
31 if ((service == NULL) || (service->dispatcher == NULL) || (service->dispatcher->Dispatch == NULL)) {
32 HDF_LOGE("PwmTesterGetConfig: service bind fail!\n");
33 return HDF_ERR_NOT_SUPPORT;
34 }
35
36 reply = HdfSbufObtain(sizeof(*config) + sizeof(uint64_t));
37 if (reply == NULL) {
38 HDF_LOGE("PwmTesterGetConfig: fail to obtain reply!");
39 HdfIoServiceRecycle(service);
40 return HDF_ERR_MALLOC_FAIL;
41 }
42
43 ret = service->dispatcher->Dispatch(&service->object, 0, NULL, reply);
44 if (ret != HDF_SUCCESS) {
45 HDF_LOGE("PwmTesterGetConfig: remote dispatch fail, ret: %d!", ret);
46 HdfIoServiceRecycle(service);
47 HdfSbufRecycle(reply);
48 return ret;
49 }
50
51 if (!HdfSbufReadBuffer(reply, &buf, &len)) {
52 HDF_LOGE("PwmTesterGetConfig: read buf fail!");
53 HdfIoServiceRecycle(service);
54 HdfSbufRecycle(reply);
55 return HDF_ERR_IO;
56 }
57
58 if (len != sizeof(*config)) {
59 HDF_LOGE("PwmTesterGetConfig: config size:%zu, read size:%u!", sizeof(*config), len);
60 HdfIoServiceRecycle(service);
61 HdfSbufRecycle(reply);
62 return HDF_ERR_IO;
63 }
64
65 if (memcpy_s(config, sizeof(*config), buf, sizeof(*config)) != EOK) {
66 HDF_LOGE("PwmTesterGetConfig: memcpy buf fail!");
67 HdfIoServiceRecycle(service);
68 HdfSbufRecycle(reply);
69 return HDF_ERR_IO;
70 }
71
72 HdfIoServiceRecycle(service);
73 HdfSbufRecycle(reply);
74 return HDF_SUCCESS;
75 }
76
PwmTesterGet(void)77 static struct PwmTester *PwmTesterGet(void)
78 {
79 int32_t ret;
80 static struct PwmTester tester;
81
82 OsalMSleep(SEQ_OUTPUT_DELAY);
83 ret = PwmTesterGetConfig(&tester.config);
84 if (ret != HDF_SUCCESS) {
85 HDF_LOGE("PwmTesterGet: read config fail, ret: %d!", ret);
86 return NULL;
87 }
88
89 tester.handle = PwmOpen(tester.config.num);
90 if (tester.handle == NULL) {
91 HDF_LOGE("PwmTesterGet: open pwm device:%u fail!", tester.config.num);
92 return NULL;
93 }
94
95 return &tester;
96 }
97
PwmTesterPut(struct PwmTester * tester)98 static void PwmTesterPut(struct PwmTester *tester)
99 {
100 if (tester == NULL) {
101 HDF_LOGE("PwmTesterPut: tester is null!");
102 return;
103 }
104 PwmClose(tester->handle);
105 tester->handle = NULL;
106 OsalMSleep(SEQ_OUTPUT_DELAY);
107 }
108
PwmSetGetConfigTest(struct PwmTester * tester)109 static int32_t PwmSetGetConfigTest(struct PwmTester *tester)
110 {
111 int32_t ret;
112 struct PwmConfig cfg = {0};
113 uint32_t number;
114
115 number = tester->config.cfg.number;
116 tester->config.cfg.number = ((number > 0) ? 0 : TEST_WAVES_NUMBER);
117 HDF_LOGI("PwmSetGetConfigTest: set number %u!", tester->config.cfg.number);
118 ret = PwmSetConfig(tester->handle, &(tester->config.cfg));
119 if (ret != HDF_SUCCESS) {
120 HDF_LOGE("PwmSetGetConfigTest: [PwmSetConfig] fail, ret: %d!", ret);
121 return ret;
122 }
123
124 OsalSleep(OUTPUT_WAVES_DELAY);
125 tester->config.cfg.number = number;
126 HDF_LOGI("PwmSetGetConfigTest: Set number %u.", tester->config.cfg.number);
127 ret = PwmSetConfig(tester->handle, &(tester->config.cfg));
128 if (ret != HDF_SUCCESS) {
129 HDF_LOGE("PwmSetGetConfigTest: [PwmSetConfig] fail, ret: %d!", ret);
130 return ret;
131 }
132
133 ret = PwmGetConfig(tester->handle, &cfg);
134 if (ret != HDF_SUCCESS) {
135 HDF_LOGE("PwmSetGetConfigTest: [PwmGetConfig] fail, ret: %d!", ret);
136 return ret;
137 }
138
139 if (memcmp(&cfg, &(tester->config.cfg), sizeof(cfg)) != 0) {
140 HDF_LOGE("PwmSetGetConfigTest: [memcmp_s] fail!");
141 return HDF_FAILURE;
142 }
143
144 return HDF_SUCCESS;
145 }
146
PwmSetPeriodTest(struct PwmTester * tester)147 static int32_t PwmSetPeriodTest(struct PwmTester *tester)
148 {
149 int32_t ret;
150 struct PwmConfig cfg = {0};
151 uint32_t period;
152
153 period = tester->config.cfg.period + tester->originCfg.period;
154 ret = PwmSetPeriod(tester->handle, period);
155 if (ret != HDF_SUCCESS) {
156 HDF_LOGE("PwmSetPeriodTest: [PwmSetPeriod] fail, ret: %d!", ret);
157 return ret;
158 }
159
160 ret = PwmGetConfig(tester->handle, &cfg);
161 if (ret != HDF_SUCCESS) {
162 HDF_LOGE("PwmSetPeriodTest: [PwmGetConfig] fail, ret: %d!", ret);
163 return ret;
164 }
165
166 if (cfg.period != period) {
167 HDF_LOGE("PwmSetPeriodTest: fail: cfg.period:%u period:%u!", cfg.period, period);
168 return HDF_FAILURE;
169 }
170
171 return HDF_SUCCESS;
172 }
173
PwmSetDutyTest(struct PwmTester * tester)174 static int32_t PwmSetDutyTest(struct PwmTester *tester)
175 {
176 int32_t ret;
177 struct PwmConfig cfg = {0};
178 uint32_t duty;
179
180 duty = tester->config.cfg.duty+ tester->originCfg.duty;
181 ret = PwmSetDuty(tester->handle, duty);
182 if (ret != HDF_SUCCESS) {
183 HDF_LOGE("PwmSetDutyTest: [PwmSetDuty] fail, ret: %d!", ret);
184 return ret;
185 }
186
187 ret = PwmGetConfig(tester->handle, &cfg);
188 if (ret != HDF_SUCCESS) {
189 HDF_LOGE("PwmSetDutyTest: [PwmGetConfig] fail, ret: %d!", ret);
190 return ret;
191 }
192
193 if (cfg.duty != duty) {
194 HDF_LOGE("PwmSetDutyTest: fail!");
195 return HDF_FAILURE;
196 }
197
198 return HDF_SUCCESS;
199 }
200
PwmSetPolarityTest(struct PwmTester * tester)201 static int32_t PwmSetPolarityTest(struct PwmTester *tester)
202 {
203 int32_t ret;
204 struct PwmConfig cfg = {0};
205
206 tester->config.cfg.polarity = PWM_NORMAL_POLARITY;
207 HDF_LOGI("PwmSetPolarityTest: Test [PwmSetPolarity] polarity %u!", tester->config.cfg.polarity);
208 ret = PwmSetPolarity(tester->handle, tester->config.cfg.polarity);
209 if (ret != HDF_SUCCESS) {
210 HDF_LOGE("PwmSetPolarityTest: [PwmSetPolarity] fail, ret: %d!", ret);
211 return ret;
212 }
213
214 tester->config.cfg.polarity = PWM_INVERTED_POLARITY;
215 HDF_LOGI("PwmSetPolarityTest: Test [PwmSetPolarity] polarity %u!", tester->config.cfg.polarity);
216 ret = PwmSetPolarity(tester->handle, tester->config.cfg.polarity);
217 if (ret != HDF_SUCCESS) {
218 HDF_LOGE("PwmSetPolarityTest: [PwmSetPolarity] fail, ret: %d!", ret);
219 return ret;
220 }
221
222 ret = PwmGetConfig(tester->handle, &cfg);
223 if (ret != HDF_SUCCESS) {
224 HDF_LOGE("PwmSetPolarityTest: [PwmGetConfig] fail, ret: %d!", ret);
225 return ret;
226 }
227
228 if (cfg.polarity != tester->config.cfg.polarity) {
229 HDF_LOGE("PwmSetPolarityTest: fail!");
230 return HDF_FAILURE;
231 }
232
233 return HDF_SUCCESS;
234 }
235
PwmEnableTest(struct PwmTester * tester)236 static int32_t PwmEnableTest(struct PwmTester *tester)
237 {
238 int32_t ret;
239 struct PwmConfig cfg = {0};
240
241 ret = PwmDisable(tester->handle);
242 if (ret != HDF_SUCCESS) {
243 HDF_LOGE("PwmEnableTest: [PwmDisable] fail, ret: %d!", ret);
244 return ret;
245 }
246
247 HDF_LOGI("PwmEnableTest: Test [PwmEnable] enable!");
248 ret = PwmEnable(tester->handle);
249 if (ret != HDF_SUCCESS) {
250 HDF_LOGE("PwmEnableTest: [PwmEnable] fail, ret: %d!", ret);
251 return ret;
252 }
253
254 ret = PwmGetConfig(tester->handle, &cfg);
255 if (ret != HDF_SUCCESS) {
256 HDF_LOGE("PwmEnableTest: [PwmGetConfig] fail, ret: %d!", ret);
257 return ret;
258 }
259
260 if (cfg.status == PWM_DISABLE_STATUS) {
261 HDF_LOGE("PwmEnableTest: fail!");
262 return HDF_FAILURE;
263 }
264
265 return HDF_SUCCESS;
266 }
267
PwmDisableTest(struct PwmTester * tester)268 static int32_t PwmDisableTest(struct PwmTester *tester)
269 {
270 int32_t ret;
271 struct PwmConfig cfg = {0};
272
273 ret = PwmEnable(tester->handle);
274 if (ret != HDF_SUCCESS) {
275 HDF_LOGE("PwmDisableTest: [PwmEnable] fail, ret: %d!", ret);
276 return ret;
277 }
278
279 HDF_LOGI("PwmDisableTest: Test [PwmDisable] disable!");
280 ret = PwmDisable(tester->handle);
281 if (ret != HDF_SUCCESS) {
282 HDF_LOGE("PwmDisableTest: [PwmDisable] fail, ret: %d!", ret);
283 return ret;
284 }
285
286 ret = PwmGetConfig(tester->handle, &cfg);
287 if (ret != HDF_SUCCESS) {
288 HDF_LOGE("PwmDisableTest: [PwmGetConfig] fail, ret: %d!", ret);
289 return ret;
290 }
291
292 if (cfg.status == PWM_ENABLE_STATUS) {
293 HDF_LOGE("PwmDisableTest: fail!");
294 return HDF_FAILURE;
295 }
296
297 return HDF_SUCCESS;
298 }
299
300 #define TEST_PERIOD 2147483647
301 #define TEST_DUTY 2147483647
302 #define TEST_POLARITY 10
PwmReliabilityTest(struct PwmTester * tester)303 static int32_t PwmReliabilityTest(struct PwmTester *tester)
304 {
305 struct PwmConfig cfg = {0};
306
307 (void)PwmSetConfig(tester->handle, &(tester->config.cfg));
308 (void)PwmSetConfig(tester->handle, NULL);
309 (void)PwmSetConfig(NULL, &(tester->config.cfg));
310 (void)PwmGetConfig(tester->handle, &cfg);
311 (void)PwmGetConfig(tester->handle, NULL);
312 (void)PwmGetConfig(NULL, &cfg);
313
314 (void)PwmSetPeriod(tester->handle, 0);
315 (void)PwmSetPeriod(tester->handle, TEST_PERIOD);
316 (void)PwmSetPeriod(NULL, TEST_PERIOD);
317
318 (void)PwmSetDuty(tester->handle, 0);
319 (void)PwmSetDuty(tester->handle, TEST_DUTY);
320 (void)PwmSetDuty(NULL, TEST_DUTY);
321
322 (void)PwmSetPolarity(tester->handle, 0);
323 (void)PwmSetPolarity(tester->handle, TEST_POLARITY);
324 (void)PwmSetPolarity(NULL, TEST_POLARITY);
325
326 (void)PwmEnable(tester->handle);
327 (void)PwmEnable(NULL);
328
329 (void)PwmDisable(tester->handle);
330 (void)PwmDisable(NULL);
331 HDF_LOGI("PwmReliabilityTest: success!");
332 return HDF_SUCCESS;
333 }
334
PwmIfPerformanceTest(struct PwmTester * tester)335 static int32_t PwmIfPerformanceTest(struct PwmTester *tester)
336 {
337 #ifdef __LITEOS__
338 // liteos the accuracy of the obtained time is too large and inaccurate.
339 if (tester == NULL) {
340 return HDF_FAILURE;
341 }
342 return HDF_SUCCESS;
343 #endif
344
345 struct PwmConfig cfg = {0};
346 uint64_t startMs;
347 uint64_t endMs;
348 uint64_t useTime; // ms
349
350 startMs = OsalGetSysTimeMs();
351 PwmGetConfig(tester->handle, &cfg);
352 endMs = OsalGetSysTimeMs();
353
354 useTime = endMs - startMs;
355 HDF_LOGI("PwmIfPerformanceTest: ----->interface performance test:[start - end] < 1ms[%s]\r\n",
356 useTime < 1 ? "yes" : "no");
357 return HDF_SUCCESS;
358 }
359
360 struct PwmTestEntry {
361 int cmd;
362 int32_t (*func)(struct PwmTester *tester);
363 };
364
365 static struct PwmTestEntry g_entry[] = {
366 { PWM_SET_PERIOD_TEST, PwmSetPeriodTest },
367 { PWM_SET_DUTY_TEST, PwmSetDutyTest },
368 { PWM_SET_POLARITY_TEST, PwmSetPolarityTest },
369 { PWM_ENABLE_TEST, PwmEnableTest },
370 { PWM_DISABLE_TEST, PwmDisableTest },
371 { PWM_SET_GET_CONFIG_TEST, PwmSetGetConfigTest },
372 { PWM_RELIABILITY_TEST, PwmReliabilityTest },
373 { PWM_IF_PERFORMANCE_TEST, PwmIfPerformanceTest },
374 };
375
PwmTestExecute(int cmd)376 int32_t PwmTestExecute(int cmd)
377 {
378 uint32_t i;
379 int32_t ret;
380 struct PwmTester *tester = NULL;
381
382 if (cmd > PWM_TEST_CMD_MAX) {
383 HDF_LOGE("PwmTestExecute: invalid cmd:%d!", cmd);
384 return HDF_ERR_NOT_SUPPORT;
385 }
386
387 tester = PwmTesterGet();
388 if (tester == NULL) {
389 HDF_LOGE("PwmTestExecute: get tester fail!");
390 return HDF_ERR_INVALID_OBJECT;
391 }
392
393 // At first test case.
394 if (cmd == PWM_SET_PERIOD_TEST) {
395 ret = PwmGetConfig(tester->handle, &(tester->originCfg));
396 if (ret != HDF_SUCCESS) {
397 HDF_LOGE("PwmTestExecute: [PwmGetConfig] fail, ret: %d!", ret);
398 HDF_LOGI("[PwmTestExecute][======cmd:%d====ret:%d======]", cmd, ret);
399 PwmTesterPut(tester);
400 return ret;
401 }
402 }
403
404 for (i = 0; i < sizeof(g_entry) / sizeof(g_entry[0]); i++) {
405 if (g_entry[i].cmd != cmd || g_entry[i].func == NULL) {
406 continue;
407 }
408 ret = g_entry[i].func(tester);
409 break;
410 }
411
412 // At last test case.
413 if (cmd == PWM_DISABLE_TEST) {
414 PwmSetConfig(tester->handle, &(tester->originCfg));
415 }
416
417 HDF_LOGI("[PwmTestExecute][======cmd:%d====ret:%d======]", cmd, ret);
418 PwmTesterPut(tester);
419 return ret;
420 }
421