Skip to content

Commit f56cbfa

Browse files
committed
Merge pull request #133 from xiongyihui/master
fix 16bit timer pwm output
2 parents b74e0c8 + 6501b16 commit f56cbfa

File tree

1 file changed

+10
-6
lines changed
  • libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX

1 file changed

+10
-6
lines changed

libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/pwmout_api.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,6 @@ static LPC_CTxxBx_Type *Timers[4] = {
6666
LPC_CT32B0, LPC_CT32B1
6767
};
6868

69-
static unsigned int pwm_clock_mhz;
70-
7169
void pwmout_init(pwmout_t* obj, PinName pin) {
7270
// determine the channel
7371
PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
@@ -92,8 +90,6 @@ void pwmout_init(pwmout_t* obj, PinName pin) {
9290
/* Reset Functionality on MR3 controlling the PWM period */
9391
timer->MCR = 1 << 10;
9492

95-
pwm_clock_mhz = SystemCoreClock / 1000000;
96-
9793
// default to 20ms: standard for servos, and fine for e.g. brightness control
9894
pwmout_period_ms(obj, 20);
9995
pwmout_write (obj, 0);
@@ -141,11 +137,18 @@ void pwmout_period_ms(pwmout_t* obj, int ms) {
141137
// Set the PWM period, keeping the duty cycle the same.
142138
void pwmout_period_us(pwmout_t* obj, int us) {
143139
int i = 0;
144-
uint32_t period_ticks = pwm_clock_mhz * us;
140+
uint32_t period_ticks = (uint32_t)(((uint64_t)SystemCoreClock * (uint64_t)us) / (uint64_t)1000000);
145141

146142
timer_mr tid = pwm_timer_map[obj->pwm];
147143
LPC_CTxxBx_Type *timer = Timers[tid.timer];
148144
uint32_t old_period_ticks = timer->MR3;
145+
146+
// for 16bit timer, set prescaler to avoid overflow
147+
uint16_t high_period_ticks = period_ticks >> 16;
148+
if ((high_period_ticks) && (timer == LPC_CT16B0 || timer == LPC_CT16B1)) {
149+
timer->PR = high_period_ticks;
150+
period_ticks /= (high_period_ticks + 1);
151+
}
149152

150153
timer->TCR = TCR_RESET;
151154
timer->MR3 = period_ticks;
@@ -169,13 +172,14 @@ void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) {
169172
}
170173

171174
void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
172-
uint32_t t_on = (uint32_t)(((uint64_t)SystemCoreClock * (uint64_t)us) / (uint64_t)1000000);
173175
timer_mr tid = pwm_timer_map[obj->pwm];
174176
LPC_CTxxBx_Type *timer = Timers[tid.timer];
177+
uint32_t t_on = (uint32_t)(((uint64_t)SystemCoreClock * (uint64_t)us) / (uint64_t)1000000 / (timer->PR + 1));
175178

176179
timer->TCR = TCR_RESET;
177180
if (t_on > timer->MR3) {
178181
pwmout_period_us(obj, us);
182+
t_on = (uint32_t)(((uint64_t)SystemCoreClock * (uint64_t)us) / (uint64_t)1000000 / (timer->PR + 1));
179183
}
180184
uint32_t t_off = timer->MR3 - t_on;
181185
timer->MR[tid.mr] = t_off;

0 commit comments

Comments
 (0)