diff --git a/src/bus/pwm.c b/src/bus/pwm.c index 71fe356..cdd89d1 100644 --- a/src/bus/pwm.c +++ b/src/bus/pwm.c @@ -7,19 +7,30 @@ int PWM_Init(void) // PD5: PWM NF-A8 Fan Peltier Cold Side // PD7: PWM NF-R8 Fan Heating Element - DDRD |= BIT(PD4) | BIT(PD5) | BIT(PD7); + DDRD |= BIT(PD4) | BIT(PD5); // | BIT(PD7); - // Fast mode, non-inverting, no prescaling + // Timer1: Fast mode, non-inverting, top=ICR1, prescale /1 TCCR1A = BIT(WGM11) | BIT(COM1A1) | BIT(COM1B1); TCCR1B = BIT(WGM12) | BIT(WGM13) | BIT(CS10); - TCCR2 = BIT(WGM20) | BIT(WGM21) | BIT(COM21) | BIT(CS20); ICR1 = PWM_CYCLE_TOP; // 8000 MHz / 25000 KHz - // TODO: Enable 25 KHz frequency for timer 3 - OCR1A = FAN01_MIN_DUTY; OCR1B = FAN02_MIN_DUTY; - OCR2 = FAN03_MIN_DUTY; + + // ATMega32A does not have more than two outputs for the + // 16-bit timer and the other 8-bit timers don't have modes + // where the value of TOP can be changed. We can only get + // 25 KHz with software PWM on this chip as far as I know. + + // The 328P would allow us to use OCR2A as top but with + // 8-bit this gives us a really low duty step size of 2.5%. + + // Timer2: Fast mode, non-inverting, top=0xFF, prescale /8 + // Top set to 8000000 (f_cpu) / 8 (prescale) / 25000 (f_pwm) - 1 + // TCCR2 = BIT(WGM20) | BIT(WGM21) | BIT(COM21) | BIT(CS21); + // OCR2 = 40 - 1; // XXX: OCR2A=top OCR2B=duty + TCCR2 = 0; + OCR2 = 0; return 0; } diff --git a/src/bus/pwm.h b/src/bus/pwm.h index 959a611..4920ead 100644 --- a/src/bus/pwm.h +++ b/src/bus/pwm.h @@ -8,7 +8,8 @@ #define FAN02 PD5 // NF-A8 Fan Peltier Cold Side Speed #define FAN03 PD7 // NF-R8 Fan Heating Element Speed -#define PWM_CYCLE_TOP (F_CPU / 25000) // 25 KHz +#define PWM_CYCLE_TOP (F_CPU / 25000 - 1) // 8 MHz / 25 KHz + #define FAN01_MIN_DUTY (PWM_CYCLE_TOP * 0.2f) #define FAN02_MIN_DUTY (PWM_CYCLE_TOP * 0.2f) #define FAN03_MIN_DUTY (PWM_CYCLE_TOP * 0.2f) diff --git a/src/main.c b/src/main.c index 5f2ac23..bfbe83d 100644 --- a/src/main.c +++ b/src/main.c @@ -54,9 +54,9 @@ int Init(void) // complicated so it might be worth it to switch to // something like an ATmega328PB. - PWM_SetValue(FAN01, 50); - PWM_SetValue(FAN02, 50); - PWM_SetValue(FAN03, 20); + PWM_SetValue(FAN01, 50); // Fan Peltier Hot side + PWM_SetValue(FAN02, 50); // Fan Peltier Cold Side + // PWM_SetValue(FAN03, 20); // Fan Heating // The I2C_SetChannel command changes the channel // setting of the PCA9546 I2C multiplexer. Any