diff --git a/src/bus/pwm.c b/src/bus/pwm.c index 21db7c4..9f15fc6 100644 --- a/src/bus/pwm.c +++ b/src/bus/pwm.c @@ -7,17 +7,6 @@ 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); - - // TIMER1: Fast mode, non-inverting, top=ICR1, prescale /1 - - TCCR1A = BIT(WGM11) | BIT(COM1A1) | BIT(COM1B1); - TCCR1B = BIT(WGM12) | BIT(WGM13) | BIT(CS10); - ICR1 = PWM_CYCLE_TOP; // 8000 MHz / 25000 KHz - - OCR1A = FAN01_MIN_DUTY; - OCR1B = FAN02_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 @@ -27,14 +16,91 @@ int PWM_Init(void) // 8-bit this gives us a really low duty step size of 2.5%. // Ideal would be two 16-bit timers with two outputs each. + DDRD |= BIT(PD4) | BIT(PD5) | BIT(PD7); + // PORTD &= ~BIT(PD7); // Turn off PD7 + + // TCCR1A Timer1 Control Register A + // 7 6 5 4 3 2 1 0 + // COM1A1 COM1A0 COM1B1 COM1B0 FOC1A FOC1B WGM11 WGM10 + + // TCCR1B Timer1 Control Register B + // 7 6 5 4 3 2 1 0 + // CNC1 ICES1 – WGM13 WGM12 CS12 CS11 CS10 + + // The COM1A1:0 and COM1B1:0 control the Output + // Compare pins (OC1A and OC1B respectively) behavior. + // If one or both of the COM1A1:0 bits are written to + // one, the OC1A output overrides the normal port + // functionality of the I/O pin it is connected to. + + // If one or both of the COM1B1:0 bit are written to + // one, the OC1B output overrides the normal port + // functionality of the I/O pin it is connected to. + // However, note that the Data Direction Register + // (DDR) bit corresponding to the OC1A or OC1B pin + // must be set in order to enable the output driver. + + // COM1B1:0: Compare Output Mode, Fast PWM + // COM1A1/ COM1A0/ Description + // COM1B1 COM1B0 + // 0 0 OC1A/OC1B disconnected. + // 0 1 WGM13:0 = 15: Toggle OC1A on match, + // OC1B disconnected. For other WGM13:0 + // settings OC1A/OC1B disconnected. + // 1 0 Clear OC1A/OC1B on match and set at + // BOTTOM (non-inverting). + // 1 1 Set OC1A/OC1B on match and clear at + // BOTTOM (inverting mode). + + // A special case occurs when OCR1A/OCR1B equals TOP + // and COM1A1/COM1B1 is set. In this case the compare + // match is ignored, but the set or clear is done at + // BOTTOM. + + // FOC1A/FOC1B: Force Output Compare for Compare unit A/B + // For ensuring compatibility with future devices, these + // bits must be set to zero when TCCR1A is written when + // operating in a PWM mode. + + // WGM11:0: Waveform Generation Mode + // Combined with the WGM13:2 bits found in the TCCR1B + // Register, these bits control the counting sequence of + // the counter, the source for maximum (TOP) counter + // value, and what type of waveform generation to be used. + // See page 115 of the ATMega32A data sheet for all modes. + + // Mode WGM13 WGM12 WGM11 WGM10 Timer Mode TOP + // 14 1 1 1 0 Fast PWM ICR1 + + // CS12:0: Clock Select + + // CS12 CS11 CS10 Description + // 0 0 0 No clock source. + // 0 0 1 clk I/O /1 no prescaling. + // 0 1 0 clk I/O /8 from prescaler. + // 0 1 1 clk I/O /64 from prescaler. + // 1 0 0 clk I/O /256 from prescaler. + // 1 0 1 clk I/O /1024 from prescaler. + // 1 1 0 External clock on T1 falling edge. + // 1 1 1 External clock on T1 rising edge. + + // TIMER1: Fast mode, non-inverting, top=ICR1, prescale /1 + + TCCR1A = BIT(WGM11) | BIT(COM1A1) | BIT(COM1B1); + TCCR1B = BIT(WGM12) | BIT(WGM13) | BIT(CS10); + ICR1 = PWM_CYCLE_TOP; // 8000 MHz / 25000 KHz + + OCR1B = FAN01_MIN_DUTY; // PD4 + OCR1A = FAN02_MIN_DUTY; // PD5 + // TIMER2: Fast mode, non-inverting, top=0xFF, prescale /8 + // TOP set to 8000000 (f_cpu) / 8 (prescale) / 25000 (f_pwm) - 1 - // 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 + // OCR2 = 40 - 1; // XXX: OCR2A=TOP OCR2B=duty - TCCR2 = 0; - OCR2 = 0; + TCCR2 = 0; // Normal operation + OCR2 = FAN03_MIN_DUTY; // PD7 return 0; } diff --git a/src/main.c b/src/main.c index 3353d30..16c6290 100644 --- a/src/main.c +++ b/src/main.c @@ -35,7 +35,7 @@ int Init(void) Info("Initializing..."); // The watchdog timer is clocked from a separate - // on-chip oscillator which runs at 1MHz. Eight + // on-chip oscillator which runs at 1 MHz. Eight // different clock cycle periods can be selected // to determine the reset period. If the reset // period expires, the chip resets and executes