@@ -66,8 +66,6 @@ static LPC_CTxxBx_Type *Timers[4] = {
66
66
LPC_CT32B0 , LPC_CT32B1
67
67
};
68
68
69
- static unsigned int pwm_clock_mhz ;
70
-
71
69
void pwmout_init (pwmout_t * obj , PinName pin ) {
72
70
// determine the channel
73
71
PWMName pwm = (PWMName )pinmap_peripheral (pin , PinMap_PWM );
@@ -91,7 +89,12 @@ void pwmout_init(pwmout_t* obj, PinName pin) {
91
89
/* Reset Functionality on MR3 controlling the PWM period */
92
90
timer -> MCR = 1 << 10 ;
93
91
94
- pwm_clock_mhz = SystemCoreClock / 1000000 ;
92
+ if (timer == LPC_CT16B0 || timer == LPC_CT16B1 ) {
93
+ /* Set 16-bit timer prescaler to avoid timer expire for default 20ms
94
+ This can be also modified by user application, but the prescaler value
95
+ might be trade-off to timer accuracy */
96
+ timer -> PR = 30 ;
97
+ }
95
98
96
99
// default to 20ms: standard for servos, and fine for e.g. brightness control
97
100
pwmout_period_ms (obj , 20 );
@@ -116,14 +119,24 @@ void pwmout_write(pwmout_t* obj, float value) {
116
119
LPC_CTxxBx_Type * timer = Timers [tid .timer ];
117
120
uint32_t t_off = timer -> MR3 - (uint32_t )((float )(timer -> MR3 ) * value );
118
121
122
+ // to avoid spike pulse when duty is 0%
123
+ if (value == 0 ) {
124
+ t_off ++ ;
125
+ }
126
+
127
+ timer -> TCR = TCR_RESET ;
119
128
timer -> MR [tid .mr ] = t_off ;
129
+ timer -> TCR = TCR_CNT_EN ;
120
130
}
121
131
122
132
float pwmout_read (pwmout_t * obj ) {
123
133
timer_mr tid = pwm_timer_map [obj -> pwm ];
124
134
LPC_CTxxBx_Type * timer = Timers [tid .timer ];
125
135
126
136
float v = (float )(timer -> MR3 - timer -> MR [tid .mr ]) / (float )(timer -> MR3 );
137
+ if (timer -> MR [tid .mr ] > timer -> MR3 ) {
138
+ v = 0.0f ;
139
+ }
127
140
return (v > 1.0f ) ? (1.0f ) : (v );
128
141
}
129
142
@@ -138,11 +151,11 @@ void pwmout_period_ms(pwmout_t* obj, int ms) {
138
151
// Set the PWM period, keeping the duty cycle the same.
139
152
void pwmout_period_us (pwmout_t * obj , int us ) {
140
153
int i = 0 ;
141
- uint32_t period_ticks = pwm_clock_mhz * us ;
142
154
143
155
timer_mr tid = pwm_timer_map [obj -> pwm ];
144
156
LPC_CTxxBx_Type * timer = Timers [tid .timer ];
145
157
uint32_t old_period_ticks = timer -> MR3 ;
158
+ uint32_t period_ticks = (SystemCoreClock / 1000000 * us ) / (timer -> PR + 1 );
146
159
147
160
timer -> TCR = TCR_RESET ;
148
161
timer -> MR3 = period_ticks ;
@@ -166,9 +179,9 @@ void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) {
166
179
}
167
180
168
181
void pwmout_pulsewidth_us (pwmout_t * obj , int us ) {
169
- uint32_t t_on = (uint32_t )(((uint64_t )SystemCoreClock * (uint64_t )us ) / (uint64_t )1000000 );
170
182
timer_mr tid = pwm_timer_map [obj -> pwm ];
171
183
LPC_CTxxBx_Type * timer = Timers [tid .timer ];
184
+ uint32_t t_on = (uint32_t )((((uint64_t )SystemCoreClock * (uint64_t )us ) / (uint64_t )1000000 ) / (timer -> PR + 1 ));
172
185
173
186
timer -> TCR = TCR_RESET ;
174
187
if (t_on > timer -> MR3 ) {
0 commit comments