• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  *
15  * Description: Provides iot_pwm driver source \n
16  *
17  * History: \n
18  * 2023-10-18, Create file. \n
19  */
20 #include "common_def.h"
21 #include "iot_errno.h"
22 #include "pwm.h"
23 #include "iot_pwm.h"
24 
25 #define IOT_PWM_MIN_DUTY           0
26 #define IOT_PWM_MAX_DUTY           100
27 #define IOT_PWM_DUTY_PART          10
28 #define IOT_PWM_FREQ_PART          2
29 #define IOT_PWM_MAX_DIV_NUM_MAX    8
30 #define IOT_PWM_CFG_OFFEST_TIME    0
31 #define IOT_PWM_CFG_REPEAT_CYCLE   100
32 #define IOT_PWM_CFG_REPEAT_STATE   true
33 
34 static bool g_iot_pwm_inited = false;
35 
IoTPwmInit(unsigned int port)36 unsigned int IoTPwmInit(unsigned int port)
37 {
38     unused(port);
39     if (!g_iot_pwm_inited) {
40         uapi_pwm_init();
41     }
42     g_iot_pwm_inited = true;
43     return IOT_SUCCESS;
44 }
45 
IoTPwmDeinit(unsigned int port)46 unsigned int IoTPwmDeinit(unsigned int port)
47 {
48     unused(port);
49     if (g_iot_pwm_inited) {
50         uapi_pwm_deinit();
51     }
52     g_iot_pwm_inited = false;
53     return IOT_SUCCESS;
54 }
55 
IoTPwmStart(unsigned int port,unsigned short duty,unsigned int freq)56 unsigned int IoTPwmStart(unsigned int port, unsigned short duty, unsigned int freq)
57 {
58     if ((duty >= IOT_PWM_MAX_DUTY) || (duty == IOT_PWM_MIN_DUTY)) {
59         return IOT_FAILURE;
60     }
61 
62     uint32_t clk_freq = uapi_pwm_get_frequency((uint8_t)port);
63     uint32_t div_num = (clk_freq + freq / IOT_PWM_FREQ_PART) / freq;   // 计算分频数
64     if (div_num < IOT_PWM_MAX_DIV_NUM_MAX) {
65         return IOT_FAILURE;
66     }
67     uint32_t high_time = div_num * duty / IOT_PWM_MAX_DUTY;            // 计算高电平时钟个数(向下取整)
68     if (high_time * IOT_PWM_MAX_DUTY / div_num >= (uint32_t)(duty - duty * IOT_PWM_DUTY_PART / IOT_PWM_MAX_DUTY)) {
69     } else if ((high_time + 1) * IOT_PWM_MAX_DUTY / div_num <=
70                 (uint32_t)(duty + duty * IOT_PWM_DUTY_PART / IOT_PWM_MAX_DUTY)) {
71         high_time++;
72     } else {
73         return IOT_FAILURE;
74     }
75     uint32_t low_time = div_num - high_time;
76     pwm_config_t cfg = {
77         .low_time = low_time,
78         .high_time = high_time,
79         .offset_time = IOT_PWM_CFG_OFFEST_TIME,
80         .cycles = IOT_PWM_CFG_REPEAT_CYCLE,
81         .repeat = IOT_PWM_CFG_REPEAT_STATE
82     };
83     if (uapi_pwm_open((uint8_t)port, &cfg) != ERRCODE_SUCC) {
84         return IOT_FAILURE;
85     }
86 
87     if (uapi_pwm_start((uint8_t)port) != ERRCODE_SUCC) {
88         return IOT_FAILURE;
89     }
90     return IOT_SUCCESS;
91 }
92 
IoTPwmStop(unsigned int port)93 unsigned int IoTPwmStop(unsigned int port)
94 {
95     if (uapi_pwm_close((uint8_t)port) != ERRCODE_SUCC) {
96         return IOT_FAILURE;
97     }
98     return IOT_SUCCESS;
99 }