#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%.
	// Ideal would be two 16-bit timers with two outputs each.

	// 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;
}

// Value in range 0-100 is expected
void PWM_SetValue(int port, int value)
{
	int n;

	if (port != FAN01 && port != FAN02 && port != FAN03)
		return; // Invalid port

	n = CLAMP(value, 100, 0) * (PWM_CYCLE_TOP / 100.0f);

	Info("Setting duty cycle for %s to %d/%d...",
		(port == FAN01) ? "FAN01" :
		(port == FAN02) ? "FAN02" :
		(port == FAN03) ? "FAN03" :
		"UNKNOWN", n, PWM_CYCLE_TOP);

	switch (port) {
	case PD4: OCR1B = n; break;
	case PD5: OCR1A = n; break;
	case PD7: OCR2  = n; break;
	}
}
