summaryrefslogtreecommitdiff
path: root/firmware/VirtualSerial.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/VirtualSerial.c')
-rw-r--r--firmware/VirtualSerial.c301
1 files changed, 159 insertions, 142 deletions
diff --git a/firmware/VirtualSerial.c b/firmware/VirtualSerial.c
index cc06237..05bff31 100644
--- a/firmware/VirtualSerial.c
+++ b/firmware/VirtualSerial.c
@@ -37,10 +37,23 @@
#include "VirtualSerial.h"
#include <util/delay.h>
#include <avr/interrupt.h>
+#include <errno.h>
+#include <stdlib.h>
static int running = true;
+static bool auto_mode = false;
+static volatile bool temp_valid = false;
+static volatile double current_temp = 0.0f;
+static volatile double target_temp = 0.0f;
+static volatile uint16_t temp_read_count = 0;
+static volatile bool compressor_running = false;
+
+float EEMEM eeprom_target_temperature = 4.0f;
+
+#define HYSTERESIS (0.5)
void CheckACMStatus(void);
+void handle_command(const char *buf);
/** LUFA CDC Class driver interface configuration and state information. This structure is
* passed to all CDC Class driver functions, so that multiple instances of the same class
@@ -71,104 +84,96 @@ USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface =
*/
static FILE USBSerialStream;
-static volatile uint8_t lock_timer_ticks;
+#define LM74_SIO PD4
+#define LM74_SCL PD5
+#define LM74_CS PD3
+#define LM74_DBG PD6
-void lock_timer_setup(void)
+/**
+ * Data is clocked out on the falling edge of the serial clock (SC), while data is clocked in on the rising edge of SC.
+ */
+static int lm74_transaction(double *out)
{
- OCR1A = 128;
+ uint16_t tmp = 0;
+
+ PORTD &= ~_BV(LM74_CS);
+ for(int i = 0; i < 16; i++) {
+ tmp <<= 1;
+ PORTD |= _BV(LM74_SCL);
+ if (PIND & (1 << LM74_SIO))
+ tmp |= 1;
+ PORTD &= ~_BV(LM74_SCL);
+ }
+ PORTD |= _BV(LM74_CS);
- // CTC mode
- TCCR1A = (1 << WGM12);
+ /* Replay the data for debugging
+ PORTD &= ~_BV(LM74_CS);
+ for(int i = 0; i < 16; i++) {
+ if(tmp & (0x8000 >> i)) {
+ PORTD |= (1 << LM74_DBG);
+ }
+ else {
+ PORTD &= ~(1 << LM74_DBG);
+ }
+ PORTD |= _BV(LM74_SCL);
+ PORTD &= ~_BV(LM74_SCL);
+ }
+ PORTD |= _BV(LM74_CS);
+ */
- // Prescaler
- TCCR1B = (1 << CS12);
+ // Check for invalid reading
+ if((tmp & (1 << 2)) == 0) {
+ return 1;
+ }
- // Enable interrupt
- TIMSK1 = (1 << OCIE1A);
+ // Dump the three last bits
+ tmp >>= 3;
+
+ *out = ((double)tmp) * 0.0625;
+ return 0;
}
-void lock_timer_reset(void)
+static void lm74_init(void)
{
- lock_timer_ticks = 0;
-}
+ PORTD |= (1 << LM74_SCL) | (1 << LM74_CS);
+ PORTD |= (1 << LM74_DBG);
-#define LM74_SIO PD4
-#define LM74_SCL PD5
-#define LM74_CS PD3
+ DDRD |= (1 << LM74_SCL) | (1 << LM74_CS);
+ DDRD |= (1 << LM74_DBG);
+ DDRD &= ~(1 << LM74_SIO);
+}
-/**
- * Data is clocked out on the falling edge of the serial clock (SC), while data is clocked in on the rising edge of SC.
- */
-void lm74_transaction(uint8_t out1, uint8_t out2, uint8_t *in1, uint8_t *in2)
+static void temp_timer_setup(void)
{
-/*
- for(int i = 0; i < 8; i++)
- {
- PORTD |= (out1 & 0x01) << LM74_SIO;
- PORTD |= _BV(LM74_SCL);
- PORTD &= ~_BV(LM74_SCL);
- out1 >>= 1;
- }
+ OCR1A = 16000;
+ OCR1A = 128;
- for(int i = 0; i < 8; i++)
- {
- PORTD |= (out2 & 0x01) << LM74_SIO;
- PORTD |= _BV(LM74_SCL);
- PORTD &= ~_BV(LM74_SCL);
- out2 >>= 1;
- }
-*/
-/*
- for(int i = 0; i < 16; i++)
- {
-// PORTD |= (out2 & 0x01) << LM74_SIO;
- PORTD |= _BV(LM74_SCL);
- _delay_ms(10);
- PORTD &= ~_BV(LM74_SCL);
- _delay_ms(10);
- }
-*/
- uint16_t temp;
-
- PORTD &= ~_BV(LM74_CS);
- _delay_us(100);
- for(int i=0; i<16; i++) {
- temp <<= 1;
- PORTD |= _BV(LM74_SCL);
- _delay_us(100);
-// if (SIO == true)
-// temp |= 1;
- PORTD &= ~_BV(LM74_SCL);
- _delay_us(100);
- }
+ // Disable all "compare output mode" pins, set CTC mode (Clear Timer on Compare)
+ TCCR1A = (1 << WGM12);
- PORTD |= _BV(LM74_CS);
+ // Select clk_IO as source, divived by 256
+ TCCR1B = (1 << CS12);
+
+ // Enable interrupt
+ TIMSK1 = (1 << OCIE1A);
}
-void lm74_init(void)
+/** Compressor
+ *
+ */
+
+static void start_compressor(void)
{
- PORTD |= (1 << LM74_SCL) | (1 << LM74_CS);
-
- DDRD |= (1 << LM74_SCL) | (1 << LM74_CS);
- DDRD &= ~(1 << LM74_SIO);
-
- PORTD |= (1 << LM74_SIO); // Enable pull-up
-
- uint8_t d1, d2;
- _delay_ms(100);
- lm74_transaction(0x5a, 0xa5, &d1, &d2);
- _delay_ms(100);
- lm74_transaction(0x5a, 0xa5, &d1, &d2);
- _delay_ms(100);
- lm74_transaction(0x5a, 0xa5, &d1, &d2);
- _delay_ms(100);
- lm74_transaction(0x5a, 0xa5, &d1, &d2);
- _delay_ms(100);
- lm74_transaction(0x5a, 0xa5, &d1, &d2);
- _delay_ms(100);
- lm74_transaction(0x5a, 0xa5, &d1, &d2);
- _delay_ms(100);
- lm74_transaction(0x5a, 0xa5, &d1, &d2);
+ compressor_running = true;
+ PORTB |= 1 << PB4;
+ PORTB |= 1 << PB0;
+}
+
+static void stop_compressor(void)
+{
+ compressor_running = false;
+ PORTB &= ~(1 << PB4);
+ PORTB &= ~(1 << PB0);
}
/** Main program entry point. This routine contains the overall program flow, including initial
@@ -179,31 +184,36 @@ int main(void)
DDRB = 1 << PB0 | 1 << PB4 | 0 << PB5;
PORTB = 0 << PB0;
- // Disables pull-ups
- PORTD = 0;
-
SetupHardware();
lm74_init();
- lock_timer_setup();
+ target_temp = eeprom_read_float(&eeprom_target_temperature);
+
+ temp_timer_setup();
/* Create a regular character stream for the interface so that it can be used with the stdio.h functions */
CDC_Device_CreateStream(&VirtualSerial_CDC_Interface, &USBSerialStream);
-// LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
+// LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
sei();
+ int last_temp_read_count = temp_read_count;
while(running)
{
wdt_reset();
- _delay_ms(250);
+// _delay_ms(250);
// PORTB ^= 1 << PB0; // Toggle external LED
// CheckPinStatus();
CheckACMStatus();
+ if(auto_mode && temp_read_count != last_temp_read_count) {
+ last_temp_read_count = temp_read_count;
+ handle_command("status");
+ }
+
CDC_Device_USBTask(&VirtualSerial_CDC_Interface);
USB_USBTask();
}
@@ -218,63 +228,53 @@ int main(void)
void handle_command(const char *buf)
{
- if (strcmp("cola", buf) == 0)
+ if (strcmp("reboot", buf) == 0 || strcmp("reset", buf) == 0)
{
- PORTB ^= 1 << PB5;
- fputs("mmm! LED toggeled\r\n", &USBSerialStream);
+ fputs("Rebooting!\r\n", &USBSerialStream);
+ running = false;
}
-
- else if (strcmp("reboot", buf) == 0 || strcmp("reset", buf) == 0)
+ if (strcmp("on", buf) == 0)
{
- fputs("Rebooting!\r\n", &USBSerialStream);
- running = false;
+ start_compressor();
}
-
- else if (strcmp("toggle", buf) == 0)
+ else if (strcmp("off", buf) == 0)
{
- fputs("Toggling Magnet Lock\r\n", &USBSerialStream);
- PORTB ^= 1 << PB4;
+ stop_compressor();
}
-
- else if (strcmp("lock", buf) == 0)
+ else if (strcmp("auto", buf) == 0)
{
- fputs("status: locked\n", &USBSerialStream);
- PORTB |= 1 << PB4;
+ auto_mode = !auto_mode;
}
-
- else if (strcmp("unlock", buf) == 0)
+ else if (strncmp("set ", buf, 4) == 0)
{
- fputs("status: unlocked\n", &USBSerialStream);
- PORTB &= ~(1 << PB4);
- lock_timer_reset();
- }
+ double d;
- else if (strcmp("doorstatus", buf) == 0)
- {
- if (PINB & (1 << PB5))
- fputs("doorstatus: open\n", &USBSerialStream);
- else
- fputs("doorstatus: closed\n", &USBSerialStream);
- }
+ errno = 0;
+ d = strtod(&buf[4], NULL);
- else if (strcmp("on", buf) == 0)
- {
- PORTB |= 1 << PB4;
- PORTB |= 1 << PB0;
- }
+ if(errno != 0)
+ {
+ fprintf(&USBSerialStream, "Invalid temperature\r\n");
+ return;
+ }
- else if (strcmp("off", buf) == 0)
- {
- PORTB &= ~(1 << PB4);
- PORTB &= ~(1 << PB0);
+ target_temp = d;
+ eeprom_update_float(&eeprom_target_temperature, (float)target_temp);
+ fprintf(&USBSerialStream, "Target temperature set to: %f\r\n", target_temp);
}
-
- else if (strcmp("temp", buf) == 0)
+ else if (strcmp("status", buf) == 0)
{
- uint8_t data = 0x5a;
-
- uint8_t d1, d2;
- lm74_transaction(0x5a, 0xa5, &d1, &d2);
+ if(temp_valid)
+ {
+ fprintf(&USBSerialStream, "Temp: %f\r\n", current_temp);
+ }
+ else
+ {
+ fprintf(&USBSerialStream, "Temp: Invalid reading\r\n");
+ }
+ fprintf(&USBSerialStream, "Temp-Count: %u\r\n", temp_read_count);
+ fprintf(&USBSerialStream, "Compressor: %s\r\n", compressor_running ? "running" : "off");
+ fprintf(&USBSerialStream, "Target-Temp: %f\r\n", target_temp);
}
}
@@ -386,19 +386,36 @@ void EVENT_USB_Device_ControlRequest(void)
ISR(TIMER1_COMPA_vect)
{
-return;
- if(PINB & (1 << PB5))
- PORTB |= 1 << PB4;
+ double t = 0;
- if(lock_timer_ticks == 0xff)
- return;
+ temp_read_count++;
- if(lock_timer_ticks < 30)
- {
- ++lock_timer_ticks;
- return;
+ int i;
+ for(i = 0; i < 10; i++) {
+ if(lm74_transaction(&t) == 0) {
+ break;
}
+ }
+ if(i == 10) {
+ temp_valid = false;
+ return;
+ }
+
+ temp_valid = true;
+ current_temp = t;
- PORTB |= 1 << PB4;
- lock_timer_ticks = 0xff;
+ /**
+ * target = 30, hysteresis = 0.5
+ *
+ * target =
+ *
+ */
+
+ if(current_temp < (target_temp - HYSTERESIS)) {
+ stop_compressor();
+ }
+
+ if(current_temp > (target_temp + HYSTERESIS)) {
+ start_compressor();
+ }
}