void susp_adc();
/* pwm.c */
-#define PWM_MAX 0x1E4 /* This should be different than ADC frequency 125 kHz */
-#define PWM_STEP_SHIFT 2 /* second parameter of pwm_set is shifted by
- * PWM_STEP_SHIFT bits to the right before setting
- * into HW */
-
+/*
+ * The real Timer/Counter 1 frequency should not be too close to the
+ * A/D converter frequency (125 kHz). Note that this is not the Top
+ * value of T/C 1, it is shifted by PWM_STEP_SHIFT as described in pwm.c
+ */
+#define PWM_MAX 0x780
void init_pwm();
void susp_pwm();
void pwm_off(unsigned char n);
#include "lights.h"
+#define PWM_STEP_SHIFT 2 /* sub-LSB precision */
+#define PWM_TOP (((PWM_MAX) + (4 << (PWM_STEP_SHIFT))) >> (PWM_STEP_SHIFT))
+#if PWM_TOP > 0x1FF
+#error PWM_TOP too high
+#endif
+
static uint16_t pwm[N_PWMLEDS];
static volatile unsigned char step;
TCCR1D = 0;
TCCR1B = _BV(CS10); // no clock prescaling
- TC1H = PWM_MAX >> 8;
- OCR1C = PWM_MAX & 0xFF; // TOP value
+ TC1H = PWM_TOP >> 8;
+ OCR1C = PWM_TOP & 0xFF; // TOP value
- TC1H = PWM_MAX >> 8; // PWM3 is inverted
- OCR1D = PWM_MAX & 0xFF;
+ TC1H = PWM_TOP >> 8; // PWM3 is inverted
+ OCR1D = PWM_TOP & 0xFF;
TC1H = 0x00;
OCR1B = OCR1A = 0; // initial stride is 0
uint16_t stride = (pwm[n] + step) >> PWM_STEP_SHIFT;
if (n == 2)
- stride = PWM_MAX - stride;
+ stride = PWM_TOP - stride;
hi = stride >> 8;
lo = stride & 0xFF;
void pwm_set(unsigned char n, uint16_t stride)
{
- if (((stride + (1 << PWM_STEP_SHIFT)) >> PWM_STEP_SHIFT) >= PWM_MAX)
- stride = PWM_MAX << PWM_STEP_SHIFT;
+ if (stride > PWM_MAX)
+ stride = PWM_MAX;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
pwm[n] = stride;