56 lines
1.5 KiB
C
56 lines
1.5 KiB
C
#include "common.h"
|
|
#include "bus/pwm.h"
|
|
|
|
int PWM_Init(void)
|
|
{
|
|
// PD4: PWM NF-12 Fan Peltier Hot Side
|
|
// 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
|
|
// 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;
|
|
}
|
|
|
|
// Port must be PD4, PD5 or PD7 and the value is
|
|
// expected to be in the range between 0 and 100
|
|
void PWM_SetValue(int port, int value)
|
|
{
|
|
int n;
|
|
|
|
if (port != PD4 && port != PD5 && port != PD7)
|
|
return; // Invalid port
|
|
|
|
n = CLAMP(value, 100, 0) * (PWM_CYCLE_TOP / 100.0f);
|
|
Info("Setting PWM value to %d...", n);
|
|
|
|
switch (port) {
|
|
case PD4: OCR1B = n; break;
|
|
case PD5: OCR1A = n; break;
|
|
case PD7: OCR2 = n; break;
|
|
}
|
|
}
|