1 /*
2 * pwm_hi35xx.h
3 *
4 * hi35xx pwm driver implement.
5 *
6 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19 #ifndef PWM_HI35XX_H
20 #define PWM_HI35XX_H
21
22 #include "hdf_base.h"
23
24 #define PWM_CLK_HZ 3000000 // 3MHz
25 #define PWM_CLK_PERIOD 333 // 333ns
26
27 #define PWM_MAX_HZ 1500000 // 1.5MHz
28 #define PWM_MIN_PERIOD 666 // 666ns
29
30 #define PWM_MIN_HZ 0.045 // 0.045Hz
31 #define PWM_MAX_PERIOD 22222222222 // 22222222222ns > 4294967295ns (UINT32_MAX)
32
33 #define PWM_ENABLE 1
34 #define PWM_DISABLE 0
35
36 #define PWM_INV_OFFSET 1
37 #define PWM_KEEP_OFFSET 2
38
39 #define PWM_DEFAULT_PERIOD 0x3E7 // 999
40 #define PWM_DEFAULT_POLARITY 0
41 #define PWM_DEFAULT_DUTY_CYCLE 0x14D // 333
42
43 struct HiPwmRegs {
44 volatile uint32_t cfg0;
45 volatile uint32_t cfg1;
46 volatile uint32_t cfg2;
47 volatile uint32_t ctrl;
48 volatile uint32_t state0;
49 volatile uint32_t state1;
50 volatile uint32_t state2;
51 };
52
HiPwmDisable(struct HiPwmRegs * reg)53 static inline void HiPwmDisable(struct HiPwmRegs *reg)
54 {
55 if (reg == NULL) {
56 return;
57 }
58 reg->ctrl &= ~1;
59 }
60
HiPwmAlwaysOutput(struct HiPwmRegs * reg)61 static inline void HiPwmAlwaysOutput(struct HiPwmRegs *reg)
62 {
63 if (reg == NULL) {
64 return;
65 }
66 /* keep the pwm always output */
67 reg->ctrl |= ((1 << PWM_KEEP_OFFSET) | PWM_ENABLE);
68 }
69
HiPwmOutputNumberSquareWaves(struct HiPwmRegs * reg,uint32_t number)70 static inline void HiPwmOutputNumberSquareWaves(struct HiPwmRegs *reg, uint32_t number)
71 {
72 uint32_t mask;
73
74 if (reg == NULL) {
75 return;
76 }
77 /* pwm output number square waves */
78 reg->cfg2 = number;
79 mask = ~(1 << PWM_KEEP_OFFSET);
80 reg->ctrl &= mask;
81 reg->ctrl |= PWM_ENABLE;
82 }
83
HiPwmSetPolarity(struct HiPwmRegs * reg,uint8_t polarity)84 static inline void HiPwmSetPolarity(struct HiPwmRegs *reg, uint8_t polarity)
85 {
86 uint32_t mask;
87
88 if (reg == NULL) {
89 return;
90 }
91 mask = ~(1 << PWM_INV_OFFSET);
92 reg->ctrl &= mask;
93 reg->ctrl |= (polarity << PWM_INV_OFFSET);
94 }
95
HiPwmSetPeriod(struct HiPwmRegs * reg,uint32_t period)96 static inline void HiPwmSetPeriod(struct HiPwmRegs *reg, uint32_t period)
97 {
98 if (reg == NULL) {
99 return;
100 }
101 reg->cfg0 = period / PWM_CLK_PERIOD;
102 }
103
HiPwmSetDuty(struct HiPwmRegs * reg,uint32_t duty)104 static inline void HiPwmSetDuty(struct HiPwmRegs *reg, uint32_t duty)
105 {
106 if (reg == NULL) {
107 return;
108 }
109 reg->cfg1 = duty / PWM_CLK_PERIOD;
110 }
111
112 #endif /* PWM_HI35XX_H */
113