diff --git a/src/common.h b/src/common.h index d410e90..e2c3f5f 100644 --- a/src/common.h +++ b/src/common.h @@ -1,7 +1,9 @@ #ifndef MAD_CORE_COMMON_H #define MAD_CORE_COMMON_H +#include #include +#include #define UNUSED(s) (void)(s) #define BIT(n) (0x1U << (n)) diff --git a/src/main.c b/src/main.c index 54abbc5..a880416 100644 --- a/src/main.c +++ b/src/main.c @@ -3,37 +3,25 @@ #include "bus/twi.h" #include -#include -// Minimum speed for Noctua fans is 20% -#define FAN_01_MIN_DUTY (320 / 100 * 20) -#define FAN_02_MIN_DUTY (320 / 100 * 20) -#define HEATER_MIN_DUTY 0 +// MOSFETS +#define MOS01 PB0 // Peltier Enable +#define MOS02 PB1 // Heating Enable +#define MOS03 PB2 // Lights Enable -// ADS1115 (ADC) -// PCA9546 (Multiplexer TWI) -// ATH20 (3x) -// BMP280 (3x) +// PWM Devices +#define FAN01 PD4 // Fan Peltier Hot Side Speed +#define FAN02 PD5 // Fan Peltier Cold Side Speed +#define HOT01 PD7 // Heating Temperature -// PB0 Mosfet 1 Peltier -// PB1 Mosfet 2 Heating -// PB2 Mosfet 3 Lights - -// PD4 PWM Peltier Hot Side -// PD5 PWM Peltier Cold Side -// PD7 PWM Heating - -// PC0 TWI Multiplexer SCL -// PC1 TWI Multiplexer SDA - -// PD0 Serial USART RX -// PD1 Serial USART TX +#define FAN01_MIN_DUTY (320 * 0.2f) // 20% +#define FAN02_MIN_DUTY (320 * 0.2f) // 20% +#define HOT01_MIN_DUTY 0 static void SetPinDefaults(void); static void SetTWIChannel(int channel); -static void SetFan01Speed(int n); -static void SetFan02Speed(int n); -static void SetHeaterTemp(int n); +static void SetMosState(int port, bool state); +static void SetPwmValue(int port, int value); int main(void) { @@ -44,14 +32,27 @@ int main(void) sei(); - Info("Initializing PWM devices..."); + Info("Initializing..."); - SetFan01Speed(320); // PWM PB4 - SetFan02Speed(320); // PWM PB5 - SetHeaterTemp(0); // PWM PB7 - SetTWIChannel(0); // I2C MUX + // MOS_Enable(MOS03); + // MOS_Disable(MOS01); + // MOS_Disable(MOS02); - Info("Running update loop..."); + // PWM_Set(FAN01, 50); + // PWM_Set(FAN02, 50); + // PWM_Set(HOT01, 50); + + SetMosState(MOS01, false); + SetMosState(MOS02, false); + SetMosState(MOS03, true); + + SetPwmValue(FAN01, 50); + SetPwmValue(FAN02, 50); + SetPwmValue(HOT01, 0); + + SetTWIChannel(0); // I2C Mux + + Info("Running idle loop..."); for (;;) { Info("PING"); @@ -61,12 +62,48 @@ int main(void) return 0; } +static void SetPinDefaults(void) +{ + // Initialize Pin Outputs + // ====================== + + // PB0: MOSFET #1 (Peltier) + + DDRB |= BIT(PB0); // Out + PORTB &= ~BIT(PB0); // Low + + // PB1: MOSFET #2 (Heating) + + DDRB |= BIT(PB1); // Out + PORTB &= ~BIT(PB1); // Low + + // PB2: MOSFET #3 (Lights) + + DDRB |= BIT(PB2); // Out + PORTB |= BIT(PB2); // High + + // PD4: PWM Peltier Hot Side + // PD5: PWM Peltier Cold Side + // PD7: PWM Heating + + DDRD |= BIT(PD4) | BIT(PD5) | BIT(PD7); + + // Fast mode, non-inverting, no prescaling + TCCR1A = BIT(WGM11) | BIT(COM1A1) | BIT(COM1B1); + TCCR1B = BIT(WGM12) | BIT(WGM13) | BIT(CS10); + TCCR2 = BIT(WGM20) | BIT(WGM21) | BIT(COM21) | BIT(CS20); + ICR1 = 320; // 8000 MHz / 25000 KHz + + OCR1A = FAN01_MIN_DUTY; + OCR1B = FAN02_MIN_DUTY; + OCR2 = HOT01_MIN_DUTY; +} + static void SetTWIChannel(int channel) { unsigned char crb; - assert(channel >= 0); - assert(channel <= 3); + // assert(channel >= 0 && channel <= 3); // PCA9546 I2C Multiplexer // ======================= @@ -112,110 +149,38 @@ static void SetTWIChannel(int channel) TWI_Wait_ACK(); TWI_Stop(); - Info("TWI channel was switched to %d.", channel); + Info("TWI channel was switched to %d!", channel); } -static void SetPinDefaults(void) +// Port must be in the range between PB0 and PB2 +static void SetMosState(int port, bool state) { - // Initialize Pin Outputs - // ====================== + if (port != PB0 && port != PB1 && port != PB2) + return; // Invalid port - // PB0: MOSFET #1 (Peltier) + Info("Setting MOS state to %s...", state ? "on" : "off"); - DDRB |= BIT(PB0); // Out - PORTB &= ~BIT(PB0); // Low - - // PB1: MOSFET #2 (Heating) - - DDRB |= BIT(PB1); // Out - PORTB &= ~BIT(PB1); // Low - - // PB2: MOSFET #3 (Lights) - - DDRB |= BIT(PB2); // Out - PORTB &= ~BIT(PB2); // High - - // PD4: PWM Peltier Hot Side - // PD5: PWM Peltier Cold Side - // PD7: PWM Heating - - DDRD |= BIT(PD4) | BIT(PD5) | BIT(PD7); - - // Fast mode, non-inverting, no prescaling - TCCR1A = BIT(WGM11) | BIT(COM1A1) | BIT(COM1B1); - TCCR1B = BIT(WGM12) | BIT(WGM13) | BIT(CS10); - TCCR2 = BIT(WGM20) | BIT(WGM21) | BIT(COM21) | BIT(CS20); - ICR1 = 320; // 8000 MHz / 25000 KHz - - // PD4 OC1A Timer1 CompareA - OCR1A = FAN_01_MIN_DUTY; - - // PD5 OC1B Timer1 CompareB - OCR1B = FAN_02_MIN_DUTY; - - // PD7 OC2 Timer2 Compare - OCR2 = HEATER_MIN_DUTY; - - // TODO: Update documentation below from ATMega32A sheet... - // Had to skip the TCR0 timer and use TCR1 and TCR2 instead. - - // TCCR0 8-bit Timer/Counter Register - // 7 6 5 4 3 2 1 0 - // FOC0 WGM00 COM01 COM00 WGM01 CS02 CS01 CS00 - - // Waveform Generation Mode Bit - // Mode WGM01 WGM00 Counter Mode - // 0 0 0 Normal - // 1 0 1 PWM Phase Correct - // 2 1 0 CTC - // 3 1 1 PWM Fast - - // Compare Output Mode, Fast PWM Mode - // COM01 COM00 Description - // 0 0 Normal port operation, OC0 disconnected. - // 0 1 Reserved. - // 1 0 Clear OC0 on match, set OC0 at BOTTOM, (non-inverting mode). - // 1 1 Set OC0 on match, clear OC0 at BOTTOM, (inverting mode). - - // Compare Output Mode, Phase Correct PWM Mode - // COM01 COM00 Description - // 0 0 Normal port operation, OC0 disconnected. - // 0 1 Reserved. - // 1 0 Clear OC0 on match when up-counting, set when downcounting. - // 1 1 Set OC0 on match when up-counting, clear when downcounting. - - // Clock Select Bit - // CS02 CS01 CS00 Description - // 0 0 0 No clock source (Timer/Counter stopped). - // 0 0 1 clk I/O 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 source on T0 pin. Clock on falling edge. - // 1 1 1 External clock source on T0 pin. Clock on rising edge. + if (state == true) + PORTB |= BIT(port); + else + PORTB &= ~BIT(port); } -static void SetFan01Speed(int n) +// Port must be PD4, PD5 or PD7 and the value is +// expected to be in the range between 0 and 100. +static void SetPwmValue(int port, int value) { - // n = CLAMP(n, 320, FAN_01_MIN_DUTY); - Info("Setting FAN01 to PWM %d...", n); + int n; - OCR1B = (unsigned char) n; // PD4 -} - -static void SetFan02Speed(int n) -{ - // n = CLAMP(n, 320, FAN_02_MIN_DUTY); - Info("Setting FAN02 to PWM %d...", n); - - OCR1A = (unsigned char) n; // PD5 -} - -static void SetHeaterTemp(int n) -{ - // n = CLAMP(n, 320, HEATER_MIN_DUTY); - Info("Setting HEATER to PWM %d...", n); - - OCR2 = (unsigned char) n; // PD7 + if (port != PD4 && port != PD5 && port != PD7) + return; // Invalid port + + n = CLAMP(value, 100, 0) * 3.6f; + Info("Setting PWM value to %d...", n); + + switch (port) { + case PD4: OCR1B = n; break; + case PD5: OCR1A = n; break; + case PD7: OCR2 = n; break; + } }