• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Talkweb 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 <stdlib.h>
10 #include <stdio.h>
11 #ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
12 #include "hcs_macro.h"
13 #include "hdf_config_macro.h"
14 #else
15 #include "device_resource_if.h"
16 #endif
17 #include "hdf_device_desc.h"
18 #include "pwm_core.h"
19 #include "hdf_log.h"
20 #include "hdf_base_hal.h"
21 #include "stm32f4xx_ll_tim.h"
22 
23 #define GPIO_STR_MAX_LENGTH 32
24 
25 typedef enum {
26     PWM_CH1 = 0,
27     PWM_CH2,
28     PWM_CH3,
29     PWM_CH4,
30     PWM_CH_MAX
31 } PWM_CH;
32 
33 typedef enum {
34     PWM_TIM1 = 0,
35     PWM_TIM2,
36     PWM_TIM3,
37     PWM_TIM4,
38     PWM_TIM5,
39     PWM_TIM6,
40     PWM_TIM7,
41     PWM_TIM8,
42     PWM_TIM9,
43     PWM_TIM10,
44     PWM_TIM11,
45     PWM_TIM12,
46     PWM_TIM13,
47     PWM_TIM14,
48     PWM_TIM_MAX
49 } PWM_TIM;
50 
51 typedef struct {
52     PWM_CH pwmCh;
53     PWM_TIM pwmTim;
54     uint32_t prescaler;
55     uint32_t timPeroid;
56     uint32_t realHz;
57 } PwmResource;
58 
59 typedef struct {
60     LL_TIM_InitTypeDef timInitStruct;
61     LL_TIM_OC_InitTypeDef timOcInitStruct;
62 } PwmConfig;
63 
64 typedef struct {
65     struct IDeviceIoService ioService;
66     PwmConfig stPwmCfg;
67     struct PwmConfig *cfg;
68     PwmResource resource;
69 } PwmDevice;
70 
71 typedef struct {
72     uint32_t period;
73     uint32_t duty;
74     PWM_TIM pwmCh;
75     PWM_TIM pwmTim;
76 } PwmFreqArg;
77 
78 static TIM_TypeDef* g_stTimMap[PWM_TIM_MAX] = {
79     TIM1,
80     TIM2,
81     TIM3,
82     TIM4,
83     TIM5,
84     TIM6,
85     TIM7,
86     TIM8,
87     TIM9,
88     TIM10,
89     TIM11,
90     TIM12,
91     TIM13,
92     TIM14,
93 };
94 
95 static uint32_t g_stChannelMap[PWM_CH_MAX] = {
96     LL_TIM_CHANNEL_CH1,
97     LL_TIM_CHANNEL_CH2,
98     LL_TIM_CHANNEL_CH3,
99     LL_TIM_CHANNEL_CH4,
100 };
101 
102 static uint32_t g_stTimIrqMap[PWM_TIM_MAX] = {
103     TIM1_CC_IRQn,
104     TIM2_IRQn,
105     TIM3_IRQn,
106     TIM4_IRQn,
107     TIM5_IRQn,
108     TIM6_DAC_IRQn,
109     TIM7_IRQn,
110     TIM8_CC_IRQn,
111     TIM1_BRK_TIM9_IRQn,
112     TIM1_UP_TIM10_IRQn,
113     TIM1_TRG_COM_TIM11_IRQn,
114     TIM8_BRK_TIM12_IRQn,
115     TIM8_UP_TIM13_IRQn,
116     TIM8_TRG_COM_TIM14_IRQn,
117 };
118 
119 static uint32_t g_stTimFreq[PWM_TIM_MAX] = { // tim2-tim7, tim12-tim14 is 84M,TIM1、TIM8~TIM11 is 168M
120     168000000,
121     84000000,
122     84000000,
123     84000000,
124     84000000,
125     84000000,
126     84000000,
127     168000000,
128     168000000,
129     168000000,
130     168000000,
131     84000000,
132     84000000,
133 };
134 
135 #define PER_SEC_NSEC          1000000000
136 
137 static int32_t PwmDevSetConfig(struct PwmDev *pwm, struct PwmConfig *config);
138 static int32_t PwmDevOpen(struct PwmDev *pwm);
139 static int32_t PwmDevClose(struct PwmDev *pwm);
140 
141 struct PwmMethod g_pwmmethod = {
142     .setConfig = PwmDevSetConfig,
143     .open = PwmDevOpen,
144     .close = PwmDevClose,
145 };
146 
InitPwmClock(PWM_TIM tim)147 static void InitPwmClock(PWM_TIM tim)
148 {
149     switch (tim) {
150         case PWM_TIM1:
151             LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM1);
152             break;
153         case PWM_TIM2:
154             LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2);
155             break;
156         case PWM_TIM3:
157             LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM3);
158             break;
159         case PWM_TIM4:
160             LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM4);
161             break;
162         case PWM_TIM5:
163             LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM5);
164             break;
165         case PWM_TIM6:
166             LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM6);
167             break;
168         case PWM_TIM7:
169             LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM7);
170             break;
171         case PWM_TIM8:
172             LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM8);
173             break;
174         case PWM_TIM9:
175             LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM9);
176             break;
177         case PWM_TIM10:
178             LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM10);
179             break;
180         case PWM_TIM11:
181             LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM11);
182             break;
183         case PWM_TIM12:
184             LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM12);
185             break;
186         case PWM_TIM13:
187             LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM13);
188             break;
189         case PWM_TIM14:
190             LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM14);
191             break;
192         default:
193             break;
194     }
195 }
196 
197 #ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
198 #define PWM_FIND_CONFIG(node, name, resource) \
199     do { \
200         if (strcmp(HCS_PROP(node, match_attr), name) == 0) { \
201             uint8_t tim = HCS_PROP(node, pwmTim); \
202             uint8_t ch = HCS_PROP(node, pwmCh); \
203             uint8_t prescaler = HCS_PROP(node, prescaler); \
204             resource->pwmCh = ch; \
205             resource->pwmTim = tim; \
206             resource->prescaler = prescaler; \
207             result = HDF_SUCCESS; \
208         } \
209     } while (0)
210 #define PLATFORM_CONFIG HCS_NODE(HCS_ROOT, platform)
211 #define PLATFORM_PWM_CONFIG HCS_NODE(HCS_NODE(HCS_ROOT, platform), pwm_config)
GetPwmDeviceResource(PwmDevice * device,const char * deviceMatchAttr)212 static uint32_t GetPwmDeviceResource(PwmDevice *device, const char *deviceMatchAttr)
213 {
214     int32_t result = HDF_FAILURE;
215     PwmResource *resource = NULL;
216     if (device == NULL || deviceMatchAttr == NULL) {
217         HDF_LOGE("%s: device or deviceMatchAttr is NULL", __func__);
218         return HDF_ERR_INVALID_PARAM;
219     }
220     resource = &device->resource;
221 #if HCS_NODE_HAS_PROP(PLATFORM_CONFIG, pwm_config)
222     HCS_FOREACH_CHILD_VARGS(PLATFORM_PWM_CONFIG, PWM_FIND_CONFIG, deviceMatchAttr, resource);
223 #endif
224     if (result != HDF_SUCCESS) {
225         HDF_LOGE("resourceNode %s is NULL\r\n", deviceMatchAttr);
226     }
227 
228     return result;
229 }
230 #else
GetPwmDeviceResource(PwmDevice * device,const struct DeviceResourceNode * resourceNode)231 static int32_t GetPwmDeviceResource(PwmDevice *device, const struct DeviceResourceNode *resourceNode)
232 {
233     struct DeviceResourceIface *dri = NULL;
234     PwmResource *resource = NULL;
235 
236     if (device == NULL || resourceNode == NULL) {
237         HDF_LOGE("resource or device is NULL\r\n");
238         return HDF_ERR_INVALID_PARAM;
239     }
240 
241     resource = &device->resource;
242     if (resource == NULL) {
243         HDF_LOGE("resource is NULL\r\n");
244         return HDF_ERR_INVALID_OBJECT;
245     }
246 
247     dri = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
248     if (dri == NULL || dri->GetUint8 == NULL || dri->GetUint32 == NULL) {
249         HDF_LOGE("DeviceResourceIface is invalid\r\n");
250         return HDF_ERR_INVALID_PARAM;
251     }
252 
253     if (dri->GetUint8(resourceNode, "pwmTim", &resource->pwmTim, 0) != HDF_SUCCESS) {
254         HDF_LOGE("read pwmPin fail\r\n");
255         return HDF_ERR_INVALID_PARAM;
256     }
257 
258     if (resource->pwmTim == PWM_TIM6 || resource->pwmTim == PWM_TIM7) {
259         HDF_LOGE("unsupport tim\r\n");
260         return HDF_ERR_INVALID_PARAM;
261     }
262 
263     if (dri->GetUint8(resourceNode, "pwmCh", &resource->pwmCh, 0) != HDF_SUCCESS) {
264         HDF_LOGE("read pwmCh fail\r\n");
265         return HDF_FAILURE;
266     }
267 
268     if (dri->GetUint32(resourceNode, "prescaler", &resource->prescaler, 0) != HDF_SUCCESS) {
269         HDF_LOGE("read prescaler fail\r\n");
270         return HDF_FAILURE;
271     }
272 
273     return HDF_SUCCESS;
274 }
275 #endif
276 
AttachPwmDevice(struct PwmDev * host,const struct HdfDeviceObject * device)277 static int32_t AttachPwmDevice(struct PwmDev *host, const struct HdfDeviceObject *device)
278 {
279     int32_t ret;
280     PwmDevice *pwmDevice = NULL;
281 #ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
282     if (device == NULL || host == NULL) {
283 #else
284     if (device == NULL || device->property == NULL || host == NULL) {
285 #endif
286         HDF_LOGE("%s: param is NULL\r\n", __func__);
287         return HDF_ERR_INVALID_PARAM;
288     }
289     pwmDevice = (PwmDevice *)OsalMemAlloc(sizeof(PwmDevice));
290     if (pwmDevice == NULL) {
291         HDF_LOGE("%s: OsalMemAlloc pwmDevice error\r\n", __func__);
292         return HDF_ERR_MALLOC_FAIL;
293     }
294 #ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
295     ret = GetPwmDeviceResource(pwmDevice, device->deviceMatchAttr);
296 #else
297     ret = GetPwmDeviceResource(pwmDevice, device->property);
298 #endif
299     if (ret != HDF_SUCCESS) {
300         (void)OsalMemFree(pwmDevice);
301         return HDF_FAILURE;
302     }
303     host->priv = pwmDevice;
304     host->num = pwmDevice->resource.pwmTim;
305 
306     return HDF_SUCCESS;
307 }
308 
309 static int32_t PwmDriverBind(struct HdfDeviceObject *device);
310 static int32_t PwmDriverInit(struct HdfDeviceObject *device);
311 static void PwmDriverRelease(struct HdfDeviceObject *device);
312 
313 struct HdfDriverEntry g_pwmDriverEntry = {
314     .moduleVersion = 1,
315     .moduleName = "ST_HDF_PLATFORM_PWM",
316     .Bind = PwmDriverBind,
317     .Init = PwmDriverInit,
318     .Release = PwmDriverRelease,
319 };
320 HDF_INIT(g_pwmDriverEntry);
321 
322 static int32_t PwmDriverBind(struct HdfDeviceObject *device)
323 {
324     struct PwmDev *devService = NULL;
325     if (device == NULL) {
326         HDF_LOGE("hdfDevice object is null!\r\n");
327         return HDF_FAILURE;
328     }
329 
330     devService = (struct PwmDev *)OsalMemCalloc(sizeof(struct PwmDev));
331     if (devService == NULL) {
332         HDF_LOGE("malloc pwmDev failed\n");
333         return HDF_ERR_MALLOC_FAIL;
334     }
335     device->service = &devService->service;
336     devService->device = device;
337 
338     return HDF_SUCCESS;
339 }
340 
341 static int32_t PwmDriverInit(struct HdfDeviceObject *device)
342 {
343     int32_t ret;
344     struct PwmDev *host = NULL;
345 
346     if (device == NULL) {
347         HDF_LOGE("%s: device is NULL\r\n", __func__);
348         return HDF_ERR_INVALID_OBJECT;
349     }
350 
351     host = (struct PwmDev *)device->service;
352     if (host == NULL) {
353         HDF_LOGE("%s: host is NULL\r\n", __func__);
354         return HDF_ERR_MALLOC_FAIL;
355     }
356 
357     ret = AttachPwmDevice(host, device);
358     if (ret != HDF_SUCCESS) {
359         HDF_LOGE("%s:attach error\r\n", __func__);
360         return HDF_DEV_ERR_ATTACHDEV_FAIL;
361     }
362 
363     host->method = &g_pwmmethod;
364     ret = PwmDeviceAdd(device, host);
365     if (ret != HDF_SUCCESS) {
366         PwmDeviceRemove(device, host);
367         OsalMemFree(host->device);
368         OsalMemFree(host);
369         return HDF_DEV_ERR_NO_DEVICE;
370     }
371 
372     return HDF_SUCCESS;
373 }
374 
375 static void PwmDriverRelease(struct HdfDeviceObject *device)
376 {
377     struct PwmDev *host = NULL;
378 
379     if (device == NULL || device->service == NULL) {
380         HDF_LOGE("device is null\r\n");
381         return;
382     }
383 
384     host = (struct PwmDev *)device->service;
385     if (host->device != NULL) {
386         host->method = NULL;
387         OsalMemFree(host->device);
388         OsalMemFree(host);
389         host->device = NULL;
390         host = NULL;
391     }
392 
393     device->service = NULL;
394     host = NULL;
395 
396     return;
397 }
398 
399 static int32_t InitPwmFreqAndPeriod(const struct PwmConfig *config, PwmFreqArg* arg, const PwmResource *resource)
400 {
401     if (arg == NULL) {
402         HDF_LOGE("null ptr\r\n");
403         return HDF_FAILURE;
404     }
405 
406     uint32_t freq = 0;
407     uint32_t period = 0;
408     uint32_t duty = 0;
409     uint32_t realHz = 0;
410 
411     if (config->period != 0) {
412         freq = (uint32_t)(PER_SEC_NSEC / config->period);
413     } else {
414         HDF_LOGE("invalid div\r\n");
415         return HDF_FAILURE;
416     }
417 
418     realHz = (uint32_t)(((double)g_stTimFreq[arg->pwmTim]) / ((double)(resource->prescaler + 1)));
419 
420     if (freq != 0) {
421         period = (uint32_t)(realHz / freq);
422     } else {
423         HDF_LOGE("invalid div\r\n");
424         return HDF_FAILURE;
425     }
426 
427     if (period != 0) {
428         duty = (uint32_t)(((double)config->duty / (double)config->period) * period);
429     } else {
430         HDF_LOGE("invalid div\r\n");
431         return HDF_FAILURE;
432     }
433 
434     arg->period = period;
435     arg->duty = duty;
436 
437     return HDF_SUCCESS;
438 }
439 
440 static void InitTimPwm(const PwmFreqArg* arg, const struct PwmConfig *config,
441     PwmConfig *pwmCfg, const PwmResource *resource)
442 {
443     if (arg == NULL) {
444         HDF_LOGE("null ptr\r\n");
445         return;
446     }
447 
448     pwmCfg->timInitStruct.Autoreload = arg->period - 1; // if period is 1000 20KHz/1000=20Hz,period is 50ms
449     pwmCfg->timInitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
450     pwmCfg->timInitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
451     pwmCfg->timInitStruct.Prescaler = resource->prescaler;
452     LL_TIM_Init(g_stTimMap[arg->pwmTim], &pwmCfg->timInitStruct);
453     LL_TIM_EnableARRPreload(g_stTimMap[arg->pwmTim]);
454     LL_TIM_SetClockSource(g_stTimMap[arg->pwmTim], LL_TIM_CLOCKSOURCE_INTERNAL);
455     LL_TIM_SetTriggerOutput(g_stTimMap[arg->pwmTim], LL_TIM_TRGO_RESET);
456     LL_TIM_DisableMasterSlaveMode(g_stTimMap[arg->pwmTim]);
457 
458     pwmCfg->timOcInitStruct.OCMode = LL_TIM_OCMODE_PWM1; // PWM1 mode
459     pwmCfg->timOcInitStruct.OCState = LL_TIM_OCSTATE_DISABLE;
460     pwmCfg->timOcInitStruct.CompareValue = arg->duty;
461     if (config->polarity == PWM_NORMAL_POLARITY) {
462         pwmCfg->timOcInitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH;
463     } else {
464         pwmCfg->timOcInitStruct.OCPolarity = LL_TIM_OCPOLARITY_LOW;
465     }
466     pwmCfg->timOcInitStruct.OCIdleState = LL_TIM_OCPOLARITY_LOW;
467 
468     LL_TIM_OC_Init(g_stTimMap[arg->pwmTim], g_stChannelMap[arg->pwmCh], &pwmCfg->timOcInitStruct);
469     LL_TIM_OC_DisableFast(g_stTimMap[arg->pwmTim], g_stChannelMap[arg->pwmCh]);
470 
471     if (arg->pwmTim == PWM_TIM1 || arg->pwmTim == PWM_TIM8) {
472         LL_TIM_BDTR_InitTypeDef bdtrInitStruct = {0};
473         bdtrInitStruct.OSSRState = LL_TIM_OSSR_DISABLE;
474         bdtrInitStruct.OSSIState = LL_TIM_OSSI_DISABLE;
475         bdtrInitStruct.LockLevel = LL_TIM_LOCKLEVEL_OFF;
476         bdtrInitStruct.DeadTime = 0; // dead area time 200ns 0x28
477         bdtrInitStruct.BreakState = LL_TIM_BREAK_ENABLE;
478         bdtrInitStruct.BreakPolarity = LL_TIM_BREAK_POLARITY_HIGH;
479         bdtrInitStruct.AutomaticOutput = LL_TIM_AUTOMATICOUTPUT_ENABLE;
480         LL_TIM_BDTR_Init(g_stTimMap[arg->pwmTim], &bdtrInitStruct);
481     }
482 
483     NVIC_SetPriority(g_stTimIrqMap[arg->pwmTim], NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 1, 1));
484     NVIC_EnableIRQ(g_stTimIrqMap[arg->pwmTim]);
485 
486     if (arg->pwmTim == PWM_TIM1 || arg->pwmTim == PWM_TIM8) {
487         LL_TIM_EnableAutomaticOutput(g_stTimMap[arg->pwmTim]);
488         LL_TIM_GenerateEvent_UPDATE(g_stTimMap[arg->pwmTim]);
489     }
490     LL_TIM_EnableCounter(g_stTimMap[arg->pwmTim]);
491     LL_TIM_CC_EnableChannel(g_stTimMap[arg->pwmTim], g_stChannelMap[arg->pwmCh]);
492     LL_TIM_OC_EnablePreload(g_stTimMap[arg->pwmTim], g_stChannelMap[arg->pwmCh]);
493 
494     return;
495 }
496 
497 static void DeInitTimPwm(PWM_TIM pwmId, PWM_CH pwmCh)
498 {
499     LL_TIM_DeInit(g_stTimMap[pwmId]);
500     LL_TIM_OC_DisableClear(g_stTimMap[pwmId], g_stChannelMap[pwmCh]);
501     NVIC_DisableIRQ(g_stTimIrqMap[pwmId]);
502 
503     LL_TIM_DisableCounter(g_stTimMap[pwmId]);
504     LL_TIM_CC_DisableChannel(g_stTimMap[pwmId], g_stChannelMap[pwmCh]);
505     LL_TIM_OC_DisablePreload(g_stTimMap[pwmId], g_stChannelMap[pwmCh]);
506 
507     if (pwmId == PWM_TIM1 || pwmId == PWM_TIM8) {
508         LL_TIM_DisableAutomaticOutput(g_stTimMap[pwmId]);
509     }
510 
511     return;
512 }
513 
514 static int32_t PwmDevSetConfig(struct PwmDev *pwm, struct PwmConfig *config)
515 {
516     PwmDevice *prvPwm = NULL;
517     PwmConfig *pwmCfg = NULL;
518     PWM_TIM pwmId;
519     PWM_CH pwmCh;
520     PwmResource *resource = NULL;
521 
522     if (pwm == NULL || config == NULL || (config->period > PER_SEC_NSEC)) {
523         HDF_LOGE("%s\r\n", __FUNCTION__);
524         return HDF_FAILURE;
525     }
526 
527     prvPwm = (struct PwmDevice *)PwmGetPriv(pwm);
528     if (prvPwm == NULL) {
529         return HDF_FAILURE;
530     }
531     resource = &prvPwm->resource;
532     if (resource == NULL) {
533         return HDF_FAILURE;
534     }
535     pwmCfg = &prvPwm->stPwmCfg;
536     if (pwmCfg == NULL) {
537         return HDF_FAILURE;
538     }
539     pwmId = prvPwm->resource.pwmTim;
540     pwmCh = prvPwm->resource.pwmCh;
541 
542     if (config->status == PWM_ENABLE_STATUS) {
543         PwmFreqArg arg = {0};
544         arg.pwmCh = pwmCh;
545         arg.pwmTim = pwmId;
546         if (InitPwmFreqAndPeriod(config, &arg, resource) != HDF_SUCCESS) {
547             HDF_LOGE("calculate freq and period failed!\r\n");
548             return HDF_FAILURE;
549         }
550 
551         InitPwmClock(pwmId);
552         InitTimPwm(&arg, config, pwmCfg, resource);
553     } else {
554         DeInitTimPwm(pwmId, pwmCh);
555     }
556 
557     return HDF_SUCCESS;
558 }
559 
560 static int32_t PwmDevOpen(struct PwmDev *pwm)
561 {
562     if (pwm == NULL) {
563         HDF_LOGE("%s\r\n", __FUNCTION__);
564         return HDF_ERR_INVALID_PARAM;
565     }
566 
567     return HDF_SUCCESS;
568 }
569 
570 static int32_t PwmDevClose(struct PwmDev *pwm)
571 {
572     PwmDevice *prvPwm = NULL;
573     PWM_TIM pwmId;
574     PWM_CH pwmCh;
575     if (pwm == NULL) {
576         HDF_LOGE("%s\r\n", __FUNCTION__);
577         return HDF_ERR_INVALID_PARAM;
578     }
579     prvPwm = (PwmDevice *)PwmGetPriv(pwm);
580     if (prvPwm == NULL) {
581         HDF_LOGE("%s\r\n", __FUNCTION__);
582         return HDF_DEV_ERR_NO_DEVICE;
583     }
584 
585     pwmId = prvPwm->resource.pwmTim;
586     pwmCh = prvPwm->resource.pwmCh;
587     LL_TIM_DeInit(g_stTimMap[pwmId]);
588     LL_TIM_OC_DisableClear(g_stTimMap[pwmId], g_stChannelMap[pwmCh]);
589     NVIC_DisableIRQ(g_stTimIrqMap[pwmId]);
590 
591     return HDF_SUCCESS;
592 }