Move PWM and MOSFET implementations into separate module files
This commit is contained in:
35
src/bus/mosfet.c
Normal file
35
src/bus/mosfet.c
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "bus/mosfet.h"
|
||||||
|
|
||||||
|
int MOS_Init(void)
|
||||||
|
{
|
||||||
|
// PB0: MOSFET #1 Peltier
|
||||||
|
DDRB |= BIT(PB0); // Output
|
||||||
|
PORTB &= ~BIT(PB0); // Low
|
||||||
|
|
||||||
|
// PB1: MOSFET #2 Heating
|
||||||
|
DDRB |= BIT(PB1); // Output
|
||||||
|
PORTB &= ~BIT(PB1); // Low
|
||||||
|
|
||||||
|
// PB2: MOSFET #3 Lights
|
||||||
|
DDRB |= BIT(PB2); // Output
|
||||||
|
PORTB |= BIT(PB2); // High
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MOS_Enable(int port)
|
||||||
|
{
|
||||||
|
if (port != MOS01 && port != MOS02 && port != MOS03)
|
||||||
|
return; // Invalid port
|
||||||
|
|
||||||
|
PORTB |= BIT(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MOS_Disable(int port)
|
||||||
|
{
|
||||||
|
if (port != MOS01 && port != MOS02 && port != MOS03)
|
||||||
|
return; // Invalid port
|
||||||
|
|
||||||
|
PORTB &= ~BIT(port);
|
||||||
|
}
|
||||||
15
src/bus/mosfet.h
Normal file
15
src/bus/mosfet.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#ifndef MAD_BUS_MOSFET_H
|
||||||
|
#define MAD_BUS_MOSFET_H
|
||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
|
|
||||||
|
// MOSFETS
|
||||||
|
#define MOS01 PB0 // Peltier Enable
|
||||||
|
#define MOS02 PB1 // Heating Enable
|
||||||
|
#define MOS03 PB2 // Lights Enable
|
||||||
|
|
||||||
|
int MOS_Init(void);
|
||||||
|
void MOS_Enable(int port);
|
||||||
|
void MOS_Disable(int port);
|
||||||
|
|
||||||
|
#endif // MAD_BUS_MOSFET_H
|
||||||
44
src/bus/pwm.c
Normal file
44
src/bus/pwm.c
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
#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);
|
||||||
|
|
||||||
|
// 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 = PWM_CYCLE_TOP; // 8000 MHz / 25000 KHz
|
||||||
|
|
||||||
|
// TODO: Enable 25 KHz frequency for timer 3
|
||||||
|
|
||||||
|
OCR1A = FAN01_MIN_DUTY;
|
||||||
|
OCR1B = FAN02_MIN_DUTY;
|
||||||
|
OCR2 = FAN03_MIN_DUTY;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
19
src/bus/pwm.h
Normal file
19
src/bus/pwm.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#ifndef MAD_BUS_PWM_H
|
||||||
|
#define MAD_BUS_PWM_H
|
||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
|
|
||||||
|
// PWM Devices
|
||||||
|
#define FAN01 PD4 // NF-12 Fan Peltier Hot Side Speed
|
||||||
|
#define FAN02 PD5 // NF-A8 Fan Peltier Cold Side Speed
|
||||||
|
#define FAN03 PD7 // NF-R8 Fan Heating Element Speed
|
||||||
|
|
||||||
|
#define PWM_CYCLE_TOP (F_CPU / 25000) // 25 KHz
|
||||||
|
#define FAN01_MIN_DUTY (PWM_CYCLE_TOP * 0.2f)
|
||||||
|
#define FAN02_MIN_DUTY (PWM_CYCLE_TOP * 0.2f)
|
||||||
|
#define FAN03_MIN_DUTY (PWM_CYCLE_TOP * 0.2f)
|
||||||
|
|
||||||
|
int PWM_Init(void);
|
||||||
|
void PWM_SetValue(int port, int value);
|
||||||
|
|
||||||
|
#endif // MAD_BUS_PWM_H
|
||||||
@@ -105,3 +105,56 @@ int TWI_Stop(void)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int TWI_SetChannel(int channel)
|
||||||
|
{
|
||||||
|
unsigned char crb;
|
||||||
|
|
||||||
|
// assert(channel >= 0 && channel <= 3);
|
||||||
|
|
||||||
|
// PCA9546 I2C Multiplexer
|
||||||
|
// =======================
|
||||||
|
|
||||||
|
Info("Switching I2C channel to %d...", channel);
|
||||||
|
|
||||||
|
// Excerpts taken from the PCA9546A datasheet:
|
||||||
|
// https://www.ti.com/lit/ds/symlink/pca9546a.pdf
|
||||||
|
|
||||||
|
// Following a start condition, the bus master
|
||||||
|
// must output the address of the slave it is
|
||||||
|
// accessing.
|
||||||
|
|
||||||
|
// 7 6 5 4 | 3 2 1 0
|
||||||
|
// 1 1 1 0 | A2 A1 A0 RW
|
||||||
|
// FIXED_____ | SELECTABLE____
|
||||||
|
|
||||||
|
TWI_Start(0x70, 0);
|
||||||
|
TWI_Wait_ACK();
|
||||||
|
|
||||||
|
// Following the successful acknowledgment of
|
||||||
|
// the slave address, the bus master sends a byte
|
||||||
|
// which is stored in the control register.
|
||||||
|
|
||||||
|
// 7 6 5 4 | 3 2 1 0
|
||||||
|
// X X X X | B3 B2 B1 B0
|
||||||
|
// UNUSED____ | CHANNEL_______
|
||||||
|
|
||||||
|
crb = (1 << channel);
|
||||||
|
|
||||||
|
// crb = 0x01; // Channel 0 | 00000001
|
||||||
|
// crb = 0x02 // Channel 1 | 00000010
|
||||||
|
// crb = 0x04 // Channel 2 | 00000100
|
||||||
|
// crb = 0x08 // Channel 3 | 00001000
|
||||||
|
|
||||||
|
TWI_Write(crb);
|
||||||
|
|
||||||
|
// When a channel is selected, the channel
|
||||||
|
// becomes active after a stop condition has been
|
||||||
|
// placed on the I2C bus. A stop condition always
|
||||||
|
// must occur right after the acknowledge cycle.
|
||||||
|
|
||||||
|
TWI_Wait_ACK();
|
||||||
|
TWI_Stop();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,14 @@
|
|||||||
#ifndef MAD_CORE_BUS_TWI_H
|
#ifndef MAD_CORE_BUS_TWI_H
|
||||||
#define MAD_CORE_BUS_TWI_H
|
#define MAD_CORE_BUS_TWI_H
|
||||||
|
|
||||||
|
// Sensors
|
||||||
|
#define AHT01 0x0 // Upper Sensor TWI Channel
|
||||||
|
#define AHT02 0x1 // Middle Sensor TWI Channel
|
||||||
|
#define AHT03 0x2 // Lower Sensor TWI Channel
|
||||||
|
|
||||||
int TWI_Init(void);
|
int TWI_Init(void);
|
||||||
int TWI_Start(unsigned char addr, unsigned char mode);
|
int TWI_Start(unsigned char addr, unsigned char mode);
|
||||||
|
int TWI_SetChannel(int channel);
|
||||||
int TWI_Write(unsigned char data);
|
int TWI_Write(unsigned char data);
|
||||||
int TWI_Wait_ACK(void);
|
int TWI_Wait_ACK(void);
|
||||||
int TWI_Stop(void);
|
int TWI_Stop(void);
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "bus/usart.h"
|
#include "bus/usart.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
static void Puts(const char *str)
|
static void Puts(const char *str)
|
||||||
{
|
{
|
||||||
|
|||||||
182
src/main.c
182
src/main.c
@@ -1,194 +1,40 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "bus/usart.h"
|
#include "bus/usart.h"
|
||||||
|
#include "bus/mosfet.h"
|
||||||
|
#include "bus/pwm.h"
|
||||||
#include "bus/twi.h"
|
#include "bus/twi.h"
|
||||||
|
|
||||||
#include <avr/interrupt.h>
|
#include <avr/interrupt.h>
|
||||||
|
|
||||||
// MOSFETS
|
|
||||||
#define MOS01 PB0 // Peltier Enable
|
|
||||||
#define MOS02 PB1 // Heating Enable
|
|
||||||
#define MOS03 PB2 // Lights Enable
|
|
||||||
|
|
||||||
// PWM Devices
|
|
||||||
#define FAN01 PD4 // NF-12 Fan Peltier Hot Side Speed
|
|
||||||
#define FAN02 PD5 // NF-A8 Fan Peltier Cold Side Speed
|
|
||||||
#define FAN03 PD7 // NF-R8 Fan Heating Element Speed
|
|
||||||
|
|
||||||
// Sensors
|
|
||||||
#define AHT01 0x0 // Upper Sensor TWI Channel
|
|
||||||
#define AHT02 0x1 // Middle Sensor TWI Channel
|
|
||||||
#define AHT03 0x2 // Lower Sensor TWI Channel
|
|
||||||
|
|
||||||
#define PWM_CYCLE_TOP (F_CPU / 25000) // 25 KHz
|
|
||||||
#define FAN01_MIN_DUTY (PWM_CYCLE_TOP * 0.2f)
|
|
||||||
#define FAN02_MIN_DUTY (PWM_CYCLE_TOP * 0.2f)
|
|
||||||
#define FAN03_MIN_DUTY (PWM_CYCLE_TOP * 0.2f)
|
|
||||||
|
|
||||||
static void SetPinDefaults(void);
|
|
||||||
static void SetTwiChannel(int channel);
|
|
||||||
static void SetMosState(int port, bool state);
|
|
||||||
static void SetPwmValue(int port, int value);
|
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
SetPinDefaults();
|
|
||||||
|
|
||||||
USART_Init();
|
USART_Init();
|
||||||
TWI_Init();
|
|
||||||
|
|
||||||
sei();
|
sei();
|
||||||
|
|
||||||
Info("Initializing...");
|
Info("Initializing...");
|
||||||
|
|
||||||
// MOS_Enable(MOS03);
|
MOS_Init();
|
||||||
|
PWM_Init();
|
||||||
|
TWI_Init();
|
||||||
|
|
||||||
|
MOS_Enable(MOS03);
|
||||||
// MOS_Disable(MOS01);
|
// MOS_Disable(MOS01);
|
||||||
// MOS_Disable(MOS02);
|
|
||||||
|
|
||||||
// PWM_Set(FAN01, 50);
|
PWM_SetValue(FAN01, 50);
|
||||||
// PWM_Set(FAN02, 50);
|
PWM_SetValue(FAN02, 50);
|
||||||
// PWM_Set(FAN03, 0);
|
PWM_SetValue(FAN03, 20);
|
||||||
|
|
||||||
SetMosState(MOS01, false);
|
// TODO: Set FAN03 timer frequency
|
||||||
SetMosState(MOS02, false);
|
// TODO: Implement ADS1115 and AHT20
|
||||||
SetMosState(MOS03, true);
|
|
||||||
|
|
||||||
SetPwmValue(FAN01, 50);
|
TWI_SetChannel(AHT01); // I2C Mux
|
||||||
SetPwmValue(FAN02, 50);
|
|
||||||
SetPwmValue(FAN03, 20);
|
|
||||||
|
|
||||||
SetTwiChannel(0); // I2C Mux
|
|
||||||
|
|
||||||
Info("Running idle loop...");
|
Info("Running idle loop...");
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
Info("PING");
|
// Info("PING");
|
||||||
Sleep(1000);
|
Sleep(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 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);
|
|
||||||
|
|
||||||
// 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 = PWM_CYCLE_TOP; // 8000 MHz / 25000 KHz
|
|
||||||
|
|
||||||
// TODO: Get 25 KHz frequency for timer 3
|
|
||||||
|
|
||||||
OCR1A = FAN01_MIN_DUTY;
|
|
||||||
OCR1B = FAN02_MIN_DUTY;
|
|
||||||
OCR2 = FAN03_MIN_DUTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void SetTwiChannel(int channel)
|
|
||||||
{
|
|
||||||
unsigned char crb;
|
|
||||||
|
|
||||||
// assert(channel >= 0 && channel <= 3);
|
|
||||||
|
|
||||||
// PCA9546 I2C Multiplexer
|
|
||||||
// =======================
|
|
||||||
|
|
||||||
Info("Switching I2C channel to %d...", channel);
|
|
||||||
|
|
||||||
// Excerpts taken from the PCA9546A datasheet:
|
|
||||||
// https://www.ti.com/lit/ds/symlink/pca9546a.pdf
|
|
||||||
|
|
||||||
// Following a start condition, the bus master
|
|
||||||
// must output the address of the slave it is
|
|
||||||
// accessing.
|
|
||||||
|
|
||||||
// 7 6 5 4 | 3 2 1 0
|
|
||||||
// 1 1 1 0 | A2 A1 A0 RW
|
|
||||||
// FIXED_____ | SELECTABLE____
|
|
||||||
|
|
||||||
TWI_Start(0x70, 0);
|
|
||||||
TWI_Wait_ACK();
|
|
||||||
|
|
||||||
// Following the successful acknowledgment of
|
|
||||||
// the slave address, the bus master sends a byte
|
|
||||||
// which is stored in the control register.
|
|
||||||
|
|
||||||
// 7 6 5 4 | 3 2 1 0
|
|
||||||
// X X X X | B3 B2 B1 B0
|
|
||||||
// UNUSED____ | CHANNEL_______
|
|
||||||
|
|
||||||
crb = (1 << channel);
|
|
||||||
|
|
||||||
// crb = 0x01; // Channel 0 | 00000001
|
|
||||||
// crb = 0x02 // Channel 1 | 00000010
|
|
||||||
// crb = 0x04 // Channel 2 | 00000100
|
|
||||||
// crb = 0x08 // Channel 3 | 00001000
|
|
||||||
|
|
||||||
TWI_Write(crb);
|
|
||||||
|
|
||||||
// When a channel is selected, the channel
|
|
||||||
// becomes active after a stop condition has been
|
|
||||||
// placed on the I2C bus. A stop condition always
|
|
||||||
// must occur right after the acknowledge cycle.
|
|
||||||
|
|
||||||
TWI_Wait_ACK();
|
|
||||||
TWI_Stop();
|
|
||||||
|
|
||||||
Info("TWI channel was switched to %d!", channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Port must be in the range between PB0 and PB2
|
|
||||||
static void SetMosState(int port, bool state)
|
|
||||||
{
|
|
||||||
if (port != PB0 && port != PB1 && port != PB2)
|
|
||||||
return; // Invalid port
|
|
||||||
|
|
||||||
Info("Setting MOS state to %s...", state ? "on" : "off");
|
|
||||||
|
|
||||||
if (state == true)
|
|
||||||
PORTB |= BIT(port);
|
|
||||||
else
|
|
||||||
PORTB &= ~BIT(port);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user