• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2021 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("%s: HdfIoServiceBind failed\n", __func__);
33         return HDF_ERR_NOT_SUPPORT;
34     }
35 
36     reply = HdfSbufObtain(sizeof(*config) + sizeof(uint64_t));
37     if (reply == NULL) {
38         HDF_LOGE("%s: failed to obtain reply", __func__);
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("%s: remote dispatch failed", __func__);
46         HdfIoServiceRecycle(service);
47         HdfSbufRecycle(reply);
48         return ret;
49     }
50 
51     if (!HdfSbufReadBuffer(reply, &buf, &len)) {
52         HDF_LOGE("%s: read buf failed", __func__);
53         HdfIoServiceRecycle(service);
54         HdfSbufRecycle(reply);
55         return HDF_ERR_IO;
56     }
57 
58     if (len != sizeof(*config)) {
59         HDF_LOGE("%s: config size:%zu, read size:%u", __func__, 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("%s: memcpy buf failed", __func__);
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 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("%s: read config failed:%d", __func__, ret);
86         return NULL;
87     }
88 
89     tester.handle = PwmOpen(tester.config.num);
90     if (tester.handle == NULL) {
91         HDF_LOGE("%s: open pwm device:%u failed", __func__, 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("%s: tester is NULL", __func__);
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("%s: Set number %u.", __func__, tester->config.cfg.number);
118     ret = PwmSetConfig(tester->handle, &(tester->config.cfg));
119     if (ret != HDF_SUCCESS) {
120         HDF_LOGE("%s: [PwmSetConfig] failed, ret %d.", __func__, ret);
121         return ret;
122     }
123 
124     OsalSleep(OUTPUT_WAVES_DELAY);
125     tester->config.cfg.number = number;
126     HDF_LOGI("%s: Set number %u.", __func__, tester->config.cfg.number);
127     ret = PwmSetConfig(tester->handle, &(tester->config.cfg));
128     if (ret != HDF_SUCCESS) {
129         HDF_LOGE("%s: [PwmSetConfig] failed, ret %d.", __func__, ret);
130         return ret;
131     }
132 
133     ret = PwmGetConfig(tester->handle, &cfg);
134     if (ret != HDF_SUCCESS) {
135         HDF_LOGE("%s: [PwmGetConfig] failed, ret %d.", __func__, ret);
136         return ret;
137     }
138 
139     if (memcmp(&cfg, &(tester->config.cfg), sizeof(cfg)) != 0) {
140         HDF_LOGE("%s: [memcmp_s] failed.", __func__);
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("%s: [PwmSetPeriod] failed, ret %d.", __func__, ret);
157         return ret;
158     }
159 
160     ret = PwmGetConfig(tester->handle, &cfg);
161     if (ret != HDF_SUCCESS) {
162         HDF_LOGE("%s: [PwmGetConfig] failed, ret %d.", __func__, ret);
163         return ret;
164     }
165 
166     if (cfg.period != period) {
167         HDF_LOGE("%s: failed: cfg.period:%d period:%d", __func__, 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("%s: [PwmSetDuty] failed, ret %d.", __func__, ret);
184         return ret;
185     }
186 
187     ret = PwmGetConfig(tester->handle, &cfg);
188     if (ret != HDF_SUCCESS) {
189         HDF_LOGE("%s: [PwmGetConfig] failed, ret %d.", __func__, ret);
190         return ret;
191     }
192 
193     if (cfg.duty != duty) {
194         HDF_LOGE("%s: failed.", __func__);
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("%s: Test [PwmSetPolarity] polarity %u.", __func__, tester->config.cfg.polarity);
208     ret = PwmSetPolarity(tester->handle, tester->config.cfg.polarity);
209     if (ret != HDF_SUCCESS) {
210         HDF_LOGE("%s: [PwmSetPolarity] failed, ret %d.", __func__, ret);
211         return ret;
212     }
213 
214     tester->config.cfg.polarity = PWM_INVERTED_POLARITY;
215     HDF_LOGI("%s: Test [PwmSetPolarity] polarity %u.", __func__, tester->config.cfg.polarity);
216     ret = PwmSetPolarity(tester->handle, tester->config.cfg.polarity);
217     if (ret != HDF_SUCCESS) {
218         HDF_LOGE("%s: [PwmSetPolarity] failed, ret %d.", __func__, ret);
219         return ret;
220     }
221 
222     ret = PwmGetConfig(tester->handle, &cfg);
223     if (ret != HDF_SUCCESS) {
224         HDF_LOGE("%s: [PwmGetConfig] failed, ret %d.", __func__, ret);
225         return ret;
226     }
227 
228     if (cfg.polarity != tester->config.cfg.polarity) {
229         HDF_LOGE("%s: failed.", __func__);
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("%s: [PwmDisable] failed, ret %d.", __func__, ret);
244         return ret;
245     }
246 
247     HDF_LOGI("%s: Test [PwmEnable] enable.", __func__);
248     ret = PwmEnable(tester->handle);
249     if (ret != HDF_SUCCESS) {
250         HDF_LOGE("%s: [PwmEnable] failed, ret %d.", __func__, ret);
251         return ret;
252     }
253 
254     ret = PwmGetConfig(tester->handle, &cfg);
255     if (ret != HDF_SUCCESS) {
256         HDF_LOGE("%s: [PwmGetConfig] failed, ret %d.", __func__, ret);
257         return ret;
258     }
259 
260     if (cfg.status == PWM_DISABLE_STATUS) {
261         HDF_LOGE("%s: failed", __func__);
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("%s: [PwmEnable] failed, ret %d.", __func__, ret);
276         return ret;
277     }
278 
279     HDF_LOGI("%s: Test [PwmDisable] disable.", __func__);
280     ret = PwmDisable(tester->handle);
281     if (ret != HDF_SUCCESS) {
282         HDF_LOGE("%s: [PwmDisable] failed, ret %d.", __func__, ret);
283         return ret;
284     }
285 
286     ret = PwmGetConfig(tester->handle, &cfg);
287     if (ret != HDF_SUCCESS) {
288         HDF_LOGE("%s: [PwmGetConfig] failed, ret %d.", __func__, ret);
289         return ret;
290     }
291 
292     if (cfg.status == PWM_ENABLE_STATUS) {
293         HDF_LOGE("%s: failed.", __func__);
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)PwmGetConfig(tester->handle, &cfg);
310     (void)PwmGetConfig(tester->handle, NULL);
311 
312     (void)PwmSetPeriod(tester->handle, 0);
313     (void)PwmSetPeriod(tester->handle, TEST_PERIOD);
314 
315     (void)PwmSetDuty(tester->handle, 0);
316     (void)PwmSetDuty(tester->handle, TEST_DUTY);
317 
318     (void)PwmSetPolarity(tester->handle, 0);
319     (void)PwmSetPolarity(tester->handle, TEST_POLARITY);
320 
321     (void)PwmEnable(tester->handle);
322     (void)PwmEnable(tester->handle);
323 
324     (void)PwmDisable(tester->handle);
325     (void)PwmDisable(tester->handle);
326     HDF_LOGI("%s: success.", __func__);
327     return HDF_SUCCESS;
328 }
329 
PwmIfPerformanceTest(struct PwmTester * tester)330 static int32_t PwmIfPerformanceTest(struct PwmTester *tester)
331 {
332 #ifdef __LITEOS__
333     // liteos the accuracy of the obtained time is too large and inaccurate.
334     if (tester == NULL) {
335         return HDF_FAILURE;
336     }
337     return HDF_SUCCESS;
338 #endif
339 
340     struct PwmConfig cfg = {0};
341     uint64_t startMs;
342     uint64_t endMs;
343     uint64_t useTime;    // ms
344 
345     startMs = OsalGetSysTimeMs();
346     PwmGetConfig(tester->handle, &cfg);
347     endMs = OsalGetSysTimeMs();
348 
349     useTime = endMs - startMs;
350     HDF_LOGI("----->interface performance test:[start:%lld(ms) - end:%lld(ms) = %lld (ms)] < 1ms[%d]\r\n",
351         startMs, endMs, useTime, useTime < 1 ? true : false);
352     return HDF_SUCCESS;
353 }
354 
355 struct PwmTestEntry {
356     int cmd;
357     int32_t (*func)(struct PwmTester *tester);
358 };
359 
360 static struct PwmTestEntry g_entry[] = {
361     { PWM_SET_PERIOD_TEST, PwmSetPeriodTest },
362     { PWM_SET_DUTY_TEST, PwmSetDutyTest },
363     { PWM_SET_POLARITY_TEST, PwmSetPolarityTest },
364     { PWM_ENABLE_TEST, PwmEnableTest },
365     { PWM_DISABLE_TEST, PwmDisableTest },
366     { PWM_SET_GET_CONFIG_TEST, PwmSetGetConfigTest },
367     { PWM_RELIABILITY_TEST, PwmReliabilityTest },
368     { PWM_IF_PERFORMANCE_TEST, PwmIfPerformanceTest },
369 };
370 
PwmTestExecute(int cmd)371 int32_t PwmTestExecute(int cmd)
372 {
373     uint32_t i;
374     int32_t ret;
375     struct PwmTester *tester = NULL;
376 
377     if (cmd > PWM_TEST_CMD_MAX) {
378         HDF_LOGE("%s: invalid cmd:%d", __func__, cmd);
379         return HDF_ERR_NOT_SUPPORT;
380     }
381 
382     tester = PwmTesterGet();
383     if (tester == NULL) {
384         HDF_LOGE("%s: get tester failed", __func__);
385         return HDF_ERR_INVALID_OBJECT;
386     }
387 
388     // At first test case.
389     if (cmd == PWM_SET_PERIOD_TEST) {
390         ret = PwmGetConfig(tester->handle, &(tester->originCfg));
391         if (ret != HDF_SUCCESS) {
392             HDF_LOGE("%s: [PwmGetConfig] failed, ret %d.", __func__, ret);
393             HDF_LOGI("[%s][======cmd:%d====ret:%d======]", __func__, cmd, ret);
394             PwmTesterPut(tester);
395             return ret;
396         }
397     }
398 
399     for (i = 0; i < sizeof(g_entry) / sizeof(g_entry[0]); i++) {
400         if (g_entry[i].cmd != cmd || g_entry[i].func == NULL) {
401             continue;
402         }
403         ret = g_entry[i].func(tester);
404         break;
405     }
406 
407     // At last test case.
408     if (cmd == PWM_DISABLE_TEST) {
409         PwmSetConfig(tester->handle, &(tester->originCfg));
410     }
411 
412     HDF_LOGI("[%s][======cmd:%d====ret:%d======]", __func__, cmd, ret);
413     PwmTesterPut(tester);
414     return ret;
415 }
416