46 static inline void pad_set_output(
int timer_num) {
48 case 0: GPIO->DATA_SEL.TMR0_PIN = 1; GPIO->PAD_DIR.TMR0_PIN = 1;
break;
49 case 1: GPIO->DATA_SEL.TMR1_PIN = 1; GPIO->PAD_DIR.TMR1_PIN = 1;
break;
50 case 2: GPIO->DATA_SEL.TMR2_PIN = 1; GPIO->PAD_DIR.TMR2_PIN = 1;
break;
51 case 3: GPIO->DATA_SEL.TMR3_PIN = 1; GPIO->PAD_DIR.TMR3_PIN = 1;
break;
56 static inline void pad_set_zero(
int timer_num) {
58 case 0: GPIO->DATA_RESET.TMR0_PIN = 1; GPIO->FUNC_SEL.TMR0_PIN = 0;
break;
59 case 1: GPIO->DATA_RESET.TMR1_PIN = 1; GPIO->FUNC_SEL.TMR1_PIN = 0;
break;
60 case 2: GPIO->DATA_RESET.TMR2_PIN = 1; GPIO->FUNC_SEL.TMR2_PIN = 0;
break;
61 case 3: GPIO->DATA_RESET.TMR3_PIN = 1; GPIO->FUNC_SEL.TMR3_PIN = 0;
break;
66 static inline void pad_set_one(
int timer_num) {
68 case 0: GPIO->DATA_SET.TMR0_PIN = 1; GPIO->FUNC_SEL.TMR0_PIN = 0;
break;
69 case 1: GPIO->DATA_SET.TMR1_PIN = 1; GPIO->FUNC_SEL.TMR1_PIN = 0;
break;
70 case 2: GPIO->DATA_SET.TMR2_PIN = 1; GPIO->FUNC_SEL.TMR2_PIN = 0;
break;
71 case 3: GPIO->DATA_SET.TMR3_PIN = 1; GPIO->FUNC_SEL.TMR3_PIN = 0;
break;
76 static inline void pad_set_normal(
int timer_num) {
78 case 0: GPIO->FUNC_SEL.TMR0_PIN = 1;
break;
79 case 1: GPIO->FUNC_SEL.TMR1_PIN = 1;
break;
80 case 2: GPIO->FUNC_SEL.TMR2_PIN = 1;
break;
81 case 3: GPIO->FUNC_SEL.TMR3_PIN = 1;
break;
92 uint32_t pwm_init_ex(
int timer_num, uint32_t rate, uint32_t duty,
int enable_timer)
95 volatile struct TMR_struct *
timer = TMR_ADDR(timer_num);
97 uint32_t period, guard;
100 TMR0->ENBL &= ~(1 << timer_num);
103 for (log_divisor = 0; log_divisor < 8; log_divisor++)
105 int denom = (rate * (1 << log_divisor));
106 period = (REF_OSC + denom/2) / denom;
110 if (log_divisor >= 8)
119 guard = 32 >> log_divisor;
120 if (guard < 2) guard = 2;
123 if (period < ((guard * 3) / 2))
127 pwm_info[timer_num].period = period;
128 pwm_info[timer_num].guard = guard;
129 actual_rate = REF_OSC / (period * (1 << log_divisor));
132 pwm_duty_ex(timer_num, duty);
133 timer->SCTRLbits = (
struct TMR_SCTRL) {
136 timer->CSCTRLbits = (
struct TMR_CSCTRL) {
139 timer->COMP1 = timer->CMPLD1;
140 timer->CNTR = timer->LOAD;
141 timer->CTRLbits = (
struct TMR_CTRL) {
143 .PRIMARY_CNT_SOURCE = 8 + log_divisor,
148 pad_set_output(timer_num);
149 pad_set_normal(timer_num);
152 TMR0->ENBL |= (1 << timer_num);
165 void pwm_duty_ex(
int timer_num, uint32_t duty)
167 uint16_t comp1, load;
168 volatile struct TMR_struct *timer = TMR_ADDR(timer_num);
169 uint32_t period = pwm_info[timer_num].period;
171 duty = (duty * period + 32767) / 65536;
192 pad_set_zero(timer_num);
193 pwm_info[timer_num].pad_forced = 1;
197 if (duty >= period) {
198 pad_set_one(timer_num);
199 pwm_info[timer_num].pad_forced = 1;
203 if (pwm_info[timer_num].pad_forced) {
204 pad_set_normal(timer_num);
205 pwm_info[timer_num].pad_forced = 0;
208 comp1 = (period - duty) - 1;
209 load = (65536 - duty);
212 uint32_t old_INTCNTL = ITC->INTCNTL;
215 if (TMR0->ENBL & (1 << timer_num))
223 "ldrh %[tmp1], %[comp] \n\t"
224 "ldrh %[tmp2], %[count] \n\t"
225 "sub %[tmp1], %[tmp1], %[tmp2] \n\t"
226 "lsl %[tmp1], %[tmp1], #16 \n\t"
227 "lsr %[tmp1], %[tmp1], #16 \n\t"
228 "cmp %[tmp1], %[guard] \n\t"
231 "strh %[ld1], %[cmpld] \n\t"
232 "strh %[ld2], %[load] \n\t"
236 [cmpld]
"=m" (timer->CMPLD1),
237 [load]
"=m" (timer->LOAD)
239 [comp]
"m" (timer->COMP1),
240 [count]
"m" (timer->CNTR),
243 [guard]
"l" (pwm_info[timer_num].guard)
248 timer->CMPLD1 = comp1;
253 ITC->INTCNTL = old_INTCNTL;