@@ -137,16 +137,23 @@ void pwmout_write(pwmout_t* obj, float value) {
137
137
uint32_t t_on = (uint32_t )((float )(pwm -> MATCHREL0 + 1 ) * value );
138
138
if (t_on > 0 ) {
139
139
pwm -> MATCHREL1 = t_on - 1 ;
140
- pwm -> CTRL &= ~(1 << 2 );
140
+
141
+ // Un-halt the timer and ensure the new pulse-width takes immediate effect if necessary
142
+ if (pwm -> CTRL & (1 << 2 )) {
143
+ pwm -> MATCH1 = pwm -> MATCHREL1 ;
144
+ pwm -> CTRL &= ~(1 << 2 );
145
+ }
141
146
} else {
147
+ // Halt the timer and force the output low
142
148
pwm -> CTRL |= (1 << 2 ) | (1 << 3 );
143
149
pwm -> OUTPUT = 0x00000000 ;
144
150
}
145
151
}
146
152
147
153
float pwmout_read (pwmout_t * obj ) {
148
- uint32_t t_off = obj -> pwm -> MATCHREL0 + 1 ;
149
- uint32_t t_on = obj -> pwm -> MATCHREL1 + 1 ;
154
+ LPC_SCT0_Type * pwm = obj -> pwm ;
155
+ uint32_t t_off = pwm -> MATCHREL0 + 1 ;
156
+ uint32_t t_on = (!(pwm -> CTRL & (1 << 2 ))) ? pwm -> MATCHREL1 + 1 : 0 ;
150
157
float v = (float )t_on /(float )t_off ;
151
158
return (v > 1.0f ) ? (1.0f ) : (v );
152
159
}
@@ -163,17 +170,27 @@ void pwmout_period_ms(pwmout_t* obj, int ms) {
163
170
void pwmout_period_us (pwmout_t * obj , int us ) {
164
171
LPC_SCT0_Type * pwm = obj -> pwm ;
165
172
uint32_t t_off = pwm -> MATCHREL0 + 1 ;
166
- uint32_t t_on = pwm -> MATCHREL1 + 1 ;
173
+ uint32_t t_on = (!( pwm -> CTRL & ( 1 << 2 ))) ? pwm -> MATCHREL1 + 1 : 0 ;
167
174
float v = (float )t_on /(float )t_off ;
168
175
uint32_t period_ticks = (uint32_t )(((uint64_t )SystemCoreClock * (uint64_t )us ) / (uint64_t )1000000 );
169
176
uint32_t pulsewidth_ticks = period_ticks * v ;
170
177
pwm -> MATCHREL0 = period_ticks - 1 ;
171
178
if (pulsewidth_ticks > 0 ) {
172
179
pwm -> MATCHREL1 = pulsewidth_ticks - 1 ;
173
- pwm -> CTRL &= ~(1 << 2 );
180
+
181
+ // Un-halt the timer and ensure the new period & pulse-width take immediate effect if necessary
182
+ if (pwm -> CTRL & (1 << 2 )) {
183
+ pwm -> MATCH0 = pwm -> MATCHREL0 ;
184
+ pwm -> MATCH1 = pwm -> MATCHREL1 ;
185
+ pwm -> CTRL &= ~(1 << 2 );
186
+ }
174
187
} else {
188
+ // Halt the timer and force the output low
175
189
pwm -> CTRL |= (1 << 2 ) | (1 << 3 );
176
190
pwm -> OUTPUT = 0x00000000 ;
191
+
192
+ // Ensure the new period will take immediate effect when the timer is un-halted
193
+ pwm -> MATCH0 = pwm -> MATCHREL0 ;
177
194
}
178
195
}
179
196
@@ -189,8 +206,14 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
189
206
LPC_SCT0_Type * pwm = obj -> pwm ;
190
207
if (us > 0 ) {
191
208
pwm -> MATCHREL1 = (uint32_t )(((uint64_t )SystemCoreClock * (uint64_t )us ) / (uint64_t )1000000 ) - 1 ;
192
- pwm -> CTRL &= ~(1 << 2 );
209
+
210
+ // Un-halt the timer and ensure the new pulse-width takes immediate effect if necessary
211
+ if (pwm -> CTRL & (1 << 2 )) {
212
+ pwm -> MATCH1 = pwm -> MATCHREL1 ;
213
+ pwm -> CTRL &= ~(1 << 2 );
214
+ }
193
215
} else {
216
+ // Halt the timer and force the output low
194
217
pwm -> CTRL |= (1 << 2 ) | (1 << 3 );
195
218
pwm -> OUTPUT = 0x00000000 ;
196
219
}
0 commit comments