}
break;
case LPC_TIMER_MODE_PWM:
+ /* Make sure we have a PWM cycle length */
if (conf->match[ conf->config[1] ] == 0) {
- return -EINVAL; /* Force use of Channel 3 for PWM cycle length */
+ return -EINVAL;
}
- /* Activate selected PWM channels 0 to 2 */
- timer->regs->pwm_ctrl = (conf->config[0] & 0x07);
- /* Use Channel 3 for PWM cycle length as recommended in the manual */
+ /* Activate selected PWM channels 0 to 3 */
+ timer->regs->pwm_ctrl = (conf->config[0] & 0x0F);
timer->regs->match_ctrl &= ~(LPC_TIMER_MATCH_ERASE(conf->config[1]));
timer->regs->match_ctrl |= (LPC_TIMER_RESET_ON_MATCH << LPC_TIMER_MATCH_SHIFT(conf->config[1]));
for (i = 0; i < NUM_CHANS; i++) {
#define LPC_TIMER_INTERRUPT_ON_MATCH 0x01
#define LPC_TIMER_RESET_ON_MATCH 0x02
#define LPC_TIMER_STOP_ON_MATCH 0x04
-#define LPC_TIMER_MATCH_ERASE(x) (0x07 << ((x) * 3))
-#define LPC_TIMER_MATCH_SHIFT(x) ((x) * 3)
+#define LPC_TIMER_MATCH_ERASE(x) (0x07 << (((x) & 0x03) * 3))
+#define LPC_TIMER_MATCH_SHIFT(x) (((x) & 0x03) * 3)
/* Capture internal configuration */
#define LPC_TIMER_CAP_ON_RISING_EDGE 0x01
#define LPC_TIMER_CAP_ON_FALLING_EDGE 0x02
#define LPC_TIMER_INTERRUPT_ON_CAPTURE 0x04
-#define LPC_TIMER_CAPTURE_ERASE(x) (0x07 << ((x) * 3))
-#define LPC_TIMER_CAPTURE_SHIFT(x) ((x) * 3)
+#define LPC_TIMER_CAPTURE_ERASE(x) (0x07 << (((x) & 0x03) * 3))
+#define LPC_TIMER_CAPTURE_SHIFT(x) (((x) & 0x03) * 3)
/* Match external configuration */
#define LPC_TIMER_NOTHING_ON_MATCH 0x00
#define LPC_TIMER_CLEAR_ON_MATCH 0x01
#define LPC_COUNTER_CLEAR_ON_CHAN3_RISE 0x06
#define LPC_COUNTER_CLEAR_ON_CHAN3_FALL 0x07
/* PWM */
-#define LPC_PWM_CHANNEL_ENABLE(x) (0x01 << (x))
+#define LPC_PWM_CHANNEL_ENABLE(x) (0x01 << ((x) & 0x03))
/* Notes:
* In counter or PWM mode, the config is done using config[0] for enabled channels and config[1] holds
* the channel number used to control PWM cycle.
+ * Note that the manual recommends Channel 3 be used for PWM cycle length.
* The field "reset_on_capture" must be set to LPC_COUNTER_CLEAR_ON_EVENT_EN ored with one
* of the LPC_COUNTER_CLEAR_ON_CHAN*_* to activate the clear timer on event functionality
*/