From 7b703bbd125e920f65197b9439234ead6903167c Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Mon, 9 Dec 2013 22:34:07 +0100 Subject: Restructure code a bit --- .gitignore | 11 +++-- Makefile | 2 +- bridge.c | 72 +++++++++++++++++++++++++++++++++ bridge.h | 9 +++++ command.c | 82 ++++++++++++++++++++++++++++++++++++- controller.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++ controller.h | 9 +++++ ferment.c | 130 ----------------------------------------------------------- main.c | 14 +++++++ 9 files changed, 298 insertions(+), 136 deletions(-) create mode 100644 bridge.c create mode 100644 bridge.h create mode 100644 controller.c create mode 100644 controller.h delete mode 100644 ferment.c create mode 100644 main.c diff --git a/.gitignore b/.gitignore index 6769eb2..39274f6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,11 @@ *.o -*.flash -*.eeprom -*.map +*.elf +*.eep +*.lss +*.lst *.orig +*.hex +*.sym +*.map *.?#? +/.dep diff --git a/Makefile b/Makefile index 4adeef6..e7d7a19 100644 --- a/Makefile +++ b/Makefile @@ -73,7 +73,7 @@ FORMAT = ihex # Target file name (without extension). -TARGET = ferment +TARGET = main # Object files directory diff --git a/bridge.c b/bridge.c new file mode 100644 index 0000000..5f1806b --- /dev/null +++ b/bridge.c @@ -0,0 +1,72 @@ +#include +#include + +#include "bridge.h" + +/* port D + * + * 4 1- (NMOS, inverted) + * 5 1+ (PMOS) + * 6 2- (NMOS, inverted) + * 7 2+ (PMOS) + * + */ + +#define D_1_MINUS (1 << 4) +#define D_1_PLUS (1 << 5) +#define D_2_MINUS (1 << 6) +#define D_2_PLUS (1 << 7) + +enum bridge_state { + BRIDGE_OFF, + BRIDGE_HEATING, + BRIDGE_COOLING +}; + +static enum bridge_state bridge_state; + +/* Turns the H-bridge off, putting the output + * into high impedance mode. */ +void bridge_off(void) +{ + if (bridge_state == BRIDGE_OFF) + return; + + PORTD |= D_1_MINUS | D_2_MINUS; + PORTD &= ~(D_1_PLUS | D_2_PLUS); + _delay_ms(100); + bridge_state = BRIDGE_OFF; +} + +/* Turns the H-bridge on, setting 1+ 2- */ +void bridge_on_heat(void) +{ + if (bridge_state == BRIDGE_HEATING) + return; + + bridge_off(); + bridge_state = BRIDGE_HEATING; + PORTD |= D_1_PLUS; + PORTD &= ~D_2_MINUS; +} + +/* Turns the H-bridge on, setting 1- 2+ */ +void bridge_on_cool(void) +{ + if (bridge_state == BRIDGE_COOLING) + return; + + bridge_off(); + bridge_state = BRIDGE_COOLING; + PORTD |= D_2_PLUS; + PORTD &= ~D_1_MINUS; +} + +/* Initializes the output port needed for the H-bridge */ +void bridge_init(void) +{ + PORTD |= D_1_MINUS | D_2_MINUS; + PORTD &= ~(D_1_PLUS | D_2_PLUS); + DDRD |= D_1_PLUS | D_1_MINUS | D_2_PLUS | D_2_MINUS; + bridge_state = BRIDGE_OFF; +} diff --git a/bridge.h b/bridge.h new file mode 100644 index 0000000..21bbfc3 --- /dev/null +++ b/bridge.h @@ -0,0 +1,9 @@ +#ifndef BRIDGE_H +#define BRIDGE_H + +void bridge_off(void); +void bridge_on_heat(void); +void bridge_on_cool(void); +void bridge_init(void); + +#endif diff --git a/command.c b/command.c index 41472c7..7d8c515 100644 --- a/command.c +++ b/command.c @@ -1,10 +1,88 @@ #include #include +#include +#include +#include +#include "controller.h" #include "serial.h" -uint16_t serial_rx_cb(char *buffer, uint16_t len) +static void handle_set(char *buffer, uint16_t len) { - return 1; + const char *error_msg = "ERR Invalid number for temperature\r\n"; + const char *error_msg2 = "ERR Temperature out of range.\r\n"; + const char *success_msg = "OK Temperature set.\r\n"; + const char *input; + char *endptr; + long temperature; + + if (len < 2) { + serial_send(error_msg, strlen(error_msg), 0); + return; + } + + input = buffer + 1; + temperature = strtol(input, &endptr, 10); + if (input[0] == '\r' || input[0] == '\n' || + (endptr[0] != '\r' && endptr[0] != '\n')) { + serial_send(error_msg, strlen(error_msg), 0); + return; + } + + if (controller_set(temperature)) { + serial_send(error_msg2, strlen(error_msg2), 0); + return; + } + + serial_send(success_msg, strlen(success_msg), 0); } +static void handle_off(char *buffer, uint16_t len) +{ + const char *success_msg = "OK Powered down.\r\n"; + + controller_off(); + serial_send(success_msg, strlen(success_msg), 0); +} + +static void handle_get(char *buffer, uint16_t len) +{ + char response[128]; + + snprintf(response, sizeof(response), "OK t=%ld\r\n", controller_get()); + serial_send(response, strlen(response), 0); +} + +uint16_t serial_rx_cb(char *buffer, uint16_t len) +{ + const char *error_msg = "ERR Unknown command\r\n"; + switch(buffer[len-1]) { + case '\r': + case '\n': + serial_send("\r\n", 2, 0); + break; + default: + /* If we didn't get a line break, just echo and return */ + serial_send(&buffer[len-1], 1, 0); + return 0; + } + + switch(buffer[0]) { + case 's': + case 'S': + handle_set(buffer, len); + break; + case 'g': + case 'G': + handle_get(buffer, len); + break; + case 'o': + case 'O': + handle_off(buffer, len); + break; + default: + serial_send(error_msg, strlen(error_msg), 0); + } + + return len; +} diff --git a/controller.c b/controller.c new file mode 100644 index 0000000..29ac0ab --- /dev/null +++ b/controller.c @@ -0,0 +1,105 @@ +#include +#include + +#include "controller.h" + +#include "bridge.h" + +static void adc_init(void) +{ + /* Configure the ADC */ + ADMUX = (1 << REFS1) | (1 << REFS0); + /* select channel x (0 for now) */ + ADMUX |= 0x0; + ADCSRA = (1 << ADEN) | (1 << ADIE) + | (1 << ADPS2) | (1 << ADPS1) + | (1 << ADPS0); +} + +/* Initializes TIMER1 */ +static void timer_init(void) +{ + TCCR1B = (1 << WGM12) | (1 << CS12) | (1 << CS10); + OCR1A = 7200; + TIMSK|=(1< 974) + return 1; + + controller_target_temp = target; + controller_num_iterations = 1; + controller_active = 1; + return 0; +} + +long controller_get(void) +{ + return controller_measured_temp; +} + +void controller_off(void) +{ + controller_active = 0; + bridge_off(); +} + +ISR(TIMER1_COMPA_vect) +{ + /* Start adc measurement */ + ADCSRA |= (1< controller_target_temp + 20) { + /* Heating required */ + bridge_on_heat(); + return; + } + + /* Temperature is roughly okay, turn bridge off until next + * measurement. */ + bridge_off(); +} diff --git a/controller.h b/controller.h new file mode 100644 index 0000000..0b65a73 --- /dev/null +++ b/controller.h @@ -0,0 +1,9 @@ +#ifndef CONTROLLER_H +#define CONTROLLER_H + +void controller_init(void); +int controller_set(long target); +long controller_get(void); +void controller_off(void); + +#endif diff --git a/ferment.c b/ferment.c deleted file mode 100644 index 1d282d2..0000000 --- a/ferment.c +++ /dev/null @@ -1,130 +0,0 @@ -//#define F_CPU 7372800UL -#include -#include -#include -#include -#include -#include -#include -#include - -#include "serial.h" -#include "stdio.h" -#include "pid.h" - -/* port D - * - * 4 1- (NMOS, inverted) - * 5 1+ (PMOS) - * 6 2- (NMOS, inverted) - * 7 2+ (PMOS) - * - */ - -#define D_1_MINUS (1 << 4) -#define D_1_PLUS (1 << 5) -#define D_2_MINUS (1 << 6) -#define D_2_PLUS (1 << 7) - -const int target_temp = 30; -volatile uint16_t adc_res; -volatile uint8_t adc_new; - -struct PID_DATA pid_data; - -/* Turns the H-bridge off, putting the output - * into high impedance mode. */ -static void bridge_off(void) -{ - PORTD |= D_1_MINUS | D_2_MINUS; - PORTD &= ~(D_1_PLUS | D_2_PLUS); -} - -/* Turns the H-bridge on, setting 1+ 2- */ -static void bridge_on_heat(void) -{ - bridge_off(); - _delay_ms(100); - PORTD |= D_1_PLUS; - PORTD &= ~D_2_MINUS; -} - -/* Turns the H-bridge on, setting 1- 2+ */ -static void bridge_on_cool(void) -{ - bridge_off(); - _delay_ms(100); - PORTD |= D_2_PLUS; - PORTD &= ~D_1_MINUS; -} - -/* Initializes the output port needed for the H-bridge */ -static void bridge_init(void) -{ - bridge_off(); - DDRD |= D_1_PLUS | D_1_MINUS | D_2_PLUS | D_2_MINUS; -} - -/* initializes ADC */ -static void adc_init(void) -{ - adc_new = 0; - ADMUX = (1 << REFS1) | (1 << REFS0); - /* select channel x (0 for now) */ - ADMUX |= 0x0; - ADCSRA = (1 << ADEN) | (1 << ADIE) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); -} - -/* reads ADC */ -static void start_temp_conv(void) -{ - ADCSRA |= (1< + +#include "serial.h" +#include "controller.h" + +int main(void) +{ + serial_init(); + serial_toggle_verbose(); + controller_init(); + + sei(); + for (;;) ; +} -- cgit v1.2.1