Add more general SetMosState() and SetPwmValue() functions

This commit is contained in:
2024-09-03 00:28:33 +02:00
parent 4453156641
commit 0110c22455
2 changed files with 97 additions and 130 deletions

View File

@@ -1,7 +1,9 @@
#ifndef MAD_CORE_COMMON_H #ifndef MAD_CORE_COMMON_H
#define MAD_CORE_COMMON_H #define MAD_CORE_COMMON_H
#include <stddef.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdbool.h>
#define UNUSED(s) (void)(s) #define UNUSED(s) (void)(s)
#define BIT(n) (0x1U << (n)) #define BIT(n) (0x1U << (n))

View File

@@ -3,37 +3,25 @@
#include "bus/twi.h" #include "bus/twi.h"
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <assert.h>
// Minimum speed for Noctua fans is 20% // MOSFETS
#define FAN_01_MIN_DUTY (320 / 100 * 20) #define MOS01 PB0 // Peltier Enable
#define FAN_02_MIN_DUTY (320 / 100 * 20) #define MOS02 PB1 // Heating Enable
#define HEATER_MIN_DUTY 0 #define MOS03 PB2 // Lights Enable
// ADS1115 (ADC) // PWM Devices
// PCA9546 (Multiplexer TWI) #define FAN01 PD4 // Fan Peltier Hot Side Speed
// ATH20 (3x) #define FAN02 PD5 // Fan Peltier Cold Side Speed
// BMP280 (3x) #define HOT01 PD7 // Heating Temperature
// PB0 Mosfet 1 Peltier #define FAN01_MIN_DUTY (320 * 0.2f) // 20%
// PB1 Mosfet 2 Heating #define FAN02_MIN_DUTY (320 * 0.2f) // 20%
// PB2 Mosfet 3 Lights #define HOT01_MIN_DUTY 0
// 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
static void SetPinDefaults(void); static void SetPinDefaults(void);
static void SetTWIChannel(int channel); static void SetTWIChannel(int channel);
static void SetFan01Speed(int n); static void SetMosState(int port, bool state);
static void SetFan02Speed(int n); static void SetPwmValue(int port, int value);
static void SetHeaterTemp(int n);
int main(void) int main(void)
{ {
@@ -44,14 +32,27 @@ int main(void)
sei(); sei();
Info("Initializing PWM devices..."); Info("Initializing...");
SetFan01Speed(320); // PWM PB4 // MOS_Enable(MOS03);
SetFan02Speed(320); // PWM PB5 // MOS_Disable(MOS01);
SetHeaterTemp(0); // PWM PB7 // MOS_Disable(MOS02);
SetTWIChannel(0); // I2C MUX
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 (;;) { for (;;) {
Info("PING"); Info("PING");
@@ -61,12 +62,48 @@ int main(void)
return 0; 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) static void SetTWIChannel(int channel)
{ {
unsigned char crb; unsigned char crb;
assert(channel >= 0); // assert(channel >= 0 && channel <= 3);
assert(channel <= 3);
// PCA9546 I2C Multiplexer // PCA9546 I2C Multiplexer
// ======================= // =======================
@@ -112,110 +149,38 @@ static void SetTWIChannel(int channel)
TWI_Wait_ACK(); TWI_Wait_ACK();
TWI_Stop(); 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 if (state == true)
PORTB &= ~BIT(PB0); // Low PORTB |= BIT(port);
else
// PB1: MOSFET #2 (Heating) PORTB &= ~BIT(port);
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.
} }
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); int n;
Info("Setting FAN01 to PWM %d...", n);
OCR1B = (unsigned char) n; // PD4 if (port != PD4 && port != PD5 && port != PD7)
} return; // Invalid port
static void SetFan02Speed(int n) n = CLAMP(value, 100, 0) * 3.6f;
{ Info("Setting PWM value to %d...", n);
// n = CLAMP(n, 320, FAN_02_MIN_DUTY);
Info("Setting FAN02 to PWM %d...", n); switch (port) {
case PD4: OCR1B = n; break;
OCR1A = (unsigned char) n; // PD5 case PD5: OCR1A = n; break;
} case PD7: OCR2 = n; break;
}
static void SetHeaterTemp(int n)
{
// n = CLAMP(n, 320, HEATER_MIN_DUTY);
Info("Setting HEATER to PWM %d...", n);
OCR2 = (unsigned char) n; // PD7
} }