summaryrefslogtreecommitdiff
path: root/tube-rotator
diff options
context:
space:
mode:
Diffstat (limited to 'tube-rotator')
-rw-r--r--tube-rotator/Makefile46
-rw-r--r--tube-rotator/stepper.c169
-rw-r--r--tube-rotator/stepper.h59
-rw-r--r--tube-rotator/tube-rotator.c81
4 files changed, 355 insertions, 0 deletions
diff --git a/tube-rotator/Makefile b/tube-rotator/Makefile
new file mode 100644
index 0000000..c75c022
--- /dev/null
+++ b/tube-rotator/Makefile
@@ -0,0 +1,46 @@
+##
+## spreadspace avr utils
+##
+##
+## Copyright (C) 2014 Christian Pointner <equinox@spreadspace.org>
+##
+## This file is part of spreadspace avr utils.
+##
+## spreadspace avr utils is free software: you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## any later version.
+##
+## spreadspace avr utils is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with spreadspace avr utils. If not, see <http://www.gnu.org/licenses/>.
+##
+
+NAME := tube-rotator
+BOARD_TYPE := teenstep
+OBJ := $(NAME).o stepper.o
+LIBS := util led lufa-descriptor-usbserial anyio
+EXTERNAL_LIBS := lufa
+RESET_FUNC := ../tools/reset_lufa_cdc
+RESET_PARAM := '!'
+
+LUFA_PATH := ../contrib/LUFA-120219
+LUFA_OPTS = -D USB_DEVICE_ONLY
+LUFA_OPTS += -D DEVICE_STATE_AS_GPIOR=0
+LUFA_OPTS += -D ORDERED_EP_CONFIG
+LUFA_OPTS += -D FIXED_CONTROL_ENDPOINT_SIZE=8
+LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1
+LUFA_OPTS += -D USE_FLASH_DESCRIPTORS
+LUFA_OPTS += -D USE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
+LUFA_OPTS += -D INTERRUPT_CONTROL_ENDPOINT
+
+LUFA_OPTS += -D USB_MANUFACTURER="L\"equinox\"" -D USB_MANUFACTURER_LEN=7
+LUFA_OPTS += -D USB_PRODUCT="L\"realraum tube rotator\"" -D USB_PRODUCT_LEN=21
+
+LUFA_COMPONENTS := USB USBCLASS SERIAL
+
+include ../include.mk
diff --git a/tube-rotator/stepper.c b/tube-rotator/stepper.c
new file mode 100644
index 0000000..8b718ae
--- /dev/null
+++ b/tube-rotator/stepper.c
@@ -0,0 +1,169 @@
+/*
+ * spreadspace avr utils
+ *
+ *
+ * Copyright (C) 2014 Christian Pointner <equinox@spreadspace.org>
+ *
+ * This file is part of spreadspace avr utils.
+ *
+ * spreadspace avr utils is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * spreadspace avr utils is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with spreadspace avr utils. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <avr/sfr_defs.h>
+#include <avr/interrupt.h>
+#include <util/atomic.h>
+#include <math.h>
+
+#include "stepper.h"
+
+uint8_t step_table [] =
+{
+ 2, // 0010
+ 6, // 0110
+ 4, // 0100
+ 5, // 0101
+ 1, // 0001
+ 9, // 1001
+ 8, // 1000
+ 10, // 1010
+};
+
+#define STEPPER_PORT PORTF
+#define STEPPER_DDR DDRF
+#define STEPPER_FIRST_BIT 4
+#define STEPPER_ENABLE_A_BIT 0
+#define STEPPER_ENABLE_B_BIT 1
+#define LENGTH_STEP_TABLE (sizeof(step_table)/sizeof(uint8_t))
+#define STEPPER_OUTPUT_BITMASK (~(0xF << STEPPER_FIRST_BIT ))
+
+volatile uint16_t target_speed;
+uint16_t current_speed;
+stepper_state_t current_state;
+
+void stepper_init(void)
+{
+ target_speed = STEPPER_SPEED_DEFAULT;
+ STEPPER_PORT &= ~(0xF << STEPPER_FIRST_BIT | 1<<STEPPER_ENABLE_A_BIT | 1<<STEPPER_ENABLE_B_BIT);
+ STEPPER_DDR |= (0xF << STEPPER_FIRST_BIT) | (1<<STEPPER_ENABLE_A_BIT) | (1<<STEPPER_ENABLE_B_BIT);
+ stepper_stop();
+}
+
+void stepper_start(void)
+{
+ if(current_state == stepper_running) return;
+
+ current_speed = STEPPER_SPEED_MIN;
+ STEPPER_PORT |= (1<<STEPPER_ENABLE_A_BIT) | (1<<STEPPER_ENABLE_B_BIT);
+ TCNT1 = 0;
+ OCR1A = current_speed;
+ TCCR1A = 0; // prescaler 1:64, WGM = 4 (CTC)
+ TCCR1B = 1<<WGM12 | 1<<CS11 | 1<<CS10; //
+ TIMSK1 = 1<<OCIE1A;
+ current_state = stepper_running;
+}
+
+void stepper_stop(void)
+{
+ STEPPER_PORT &= ~(0xF << STEPPER_FIRST_BIT | 1<<STEPPER_ENABLE_A_BIT | 1<<STEPPER_ENABLE_B_BIT);
+ TCCR1B = 0; // no clock source
+ TIMSK1 = 0; // disable timer interrupt
+ current_state = stepper_stopped;
+}
+
+static inline void stepper_handle(void)
+{
+ static uint8_t step_idx = 0;
+
+ uint8_t stepper_output = step_table[step_idx];
+ stepper_output <<= STEPPER_FIRST_BIT;
+ STEPPER_PORT = (STEPPER_PORT & STEPPER_OUTPUT_BITMASK ) | stepper_output;
+ step_idx++;
+ step_idx %= LENGTH_STEP_TABLE;
+
+ if(step_idx != 0 && step_idx % 8) {
+ if(current_speed > target_speed)
+ OCR1A = (uint16_t)((STEPPER_SPEED_CONVERT_VALUE/(--current_speed)) - 1);
+ else if(current_speed < target_speed)
+ OCR1A = (uint16_t)((STEPPER_SPEED_CONVERT_VALUE/(++current_speed)) - 1);
+ }
+}
+
+ISR(TIMER1_COMPA_vect)
+{
+ stepper_handle();
+}
+
+stepper_state_t stepper_get_state(void)
+{
+ return current_state;
+}
+
+const char* stepper_state_to_string(stepper_state_t state)
+{
+ switch(state) {
+ case stepper_running: return "running";
+ case stepper_stopped: return "stopped";
+ }
+ return "?";
+}
+
+void stepper_set_speed(uint16_t new_speed)
+{
+ if(new_speed >= STEPPER_SPEED_MIN && new_speed <= STEPPER_SPEED_MAX) {
+ ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
+ target_speed = new_speed;
+ }
+ }
+}
+
+void stepper_inc_speed(void)
+{
+ ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
+ target_speed = (target_speed >= STEPPER_SPEED_MAX) ? STEPPER_SPEED_MAX : target_speed + 1;
+ }
+}
+
+void stepper_dec_speed(void)
+{
+ ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
+ target_speed = (target_speed <= STEPPER_SPEED_MIN) ? STEPPER_SPEED_MIN : target_speed - 1;
+ }
+}
+
+uint16_t stepper_get_speed(void)
+{
+ return target_speed;
+}
+
+void stepper_set_speed_rpm(uint8_t new_rpm)
+{
+ stepper_set_speed( (uint16_t)lround( ( (double)(64.0 * 800.0 * (double)STEPPER_SPEED_CONVERT_VALUE) / (double)(60.0 * (double)F_CPU) ) * (double)new_rpm) );
+}
+
+uint8_t stepper_get_speed_rpm(void)
+{
+ return (uint8_t)lround( ( (double)(60.0 * (double)F_CPU) / (double)(64.0 * 800.0 * (double)STEPPER_SPEED_CONVERT_VALUE) ) * (double)(target_speed) );
+}
+
+void stepper_inc_speed_rpm(void)
+{
+ uint8_t rpm = stepper_get_speed_rpm();
+ stepper_set_speed_rpm((rpm >= 255) ? 255 : rpm+1);
+}
+
+void stepper_dec_speed_rpm(void)
+{
+ uint8_t rpm = stepper_get_speed_rpm();
+ stepper_set_speed_rpm((rpm <= 1) ? 1 : rpm-1);
+}
diff --git a/tube-rotator/stepper.h b/tube-rotator/stepper.h
new file mode 100644
index 0000000..5b5a315
--- /dev/null
+++ b/tube-rotator/stepper.h
@@ -0,0 +1,59 @@
+/*
+ * spreadspace avr utils
+ *
+ *
+ * Copyright (C) 2014 Christian Pointner <equinox@spreadspace.org>
+ *
+ * This file is part of spreadspace avr utils.
+ *
+ * spreadspace avr utils is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * spreadspace avr utils is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with spreadspace avr utils. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef R3TUBE_stepper_h_INCLUDED
+#define R3TUBE_stepper_h_INCLUDED
+
+#define STEPPER_SPEED_MIN 150
+#define STEPPER_SPEED_MAX 700
+#define STEPPER_SPEED_CONVERT_VALUE (uint32_t)(105000)
+
+#define STEPPER_SPEED_30RPM 168
+#define STEPPER_SPEED_40RPM 224
+#define STEPPER_SPEED_50RPM 281
+#define STEPPER_SPEED_60RPM 336
+#define STEPPER_SPEED_70RPM 393
+#define STEPPER_SPEED_80RPM 451
+#define STEPPER_SPEED_90RPM 507
+#define STEPPER_SPEED_100RPM 561
+
+#define STEPPER_SPEED_DEFAULT STEPPER_SPEED_60RPM
+
+typedef enum { stepper_stopped = 0, stepper_running = 1 } stepper_state_t;
+
+void stepper_init(void);
+void stepper_start(void);
+void stepper_stop(void);
+stepper_state_t stepper_get_state(void);
+const char* stepper_state_to_string(stepper_state_t state);
+
+void stepper_set_speed(uint16_t new_speed);
+void stepper_inc_speed(void);
+void stepper_dec_speed(void);
+uint16_t stepper_get_speed(void);
+
+void stepper_set_speed_rpm(uint8_t new_rpm);
+uint8_t stepper_get_speed_rpm(void);
+void stepper_inc_speed_rpm(void);
+void stepper_dec_speed_rpm(void);
+
+#endif
diff --git a/tube-rotator/tube-rotator.c b/tube-rotator/tube-rotator.c
new file mode 100644
index 0000000..065dd2f
--- /dev/null
+++ b/tube-rotator/tube-rotator.c
@@ -0,0 +1,81 @@
+/*
+ * spreadspace avr utils
+ *
+ *
+ * Copyright (C) 2014 Christian Pointner <equinox@spreadspace.org>
+ *
+ * This file is part of spreadspace avr utils.
+ *
+ * spreadspace avr utils is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * spreadspace avr utils is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with spreadspace avr utils. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <avr/io.h>
+#include <avr/wdt.h>
+#include <avr/interrupt.h>
+#include <avr/power.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "util.h"
+#include "led.h"
+#include "anyio.h"
+
+#include "stepper.h"
+
+void handle_cmd(uint8_t cmd)
+{
+ switch(cmd) {
+ case '!': reset2bootloader(); break;
+ case 'r': led_on(); stepper_start(); break;
+ case 's': stepper_stop(); led_off(); break;
+ case '*': stepper_inc_speed(); break;
+ case '+': stepper_inc_speed_rpm(); break;
+ case '-': stepper_dec_speed_rpm(); break;
+ case '_': stepper_dec_speed(); break;
+ case '3': stepper_set_speed_rpm(30); break;
+ case '4': stepper_set_speed_rpm(40); break;
+ case '5': stepper_set_speed_rpm(50); break;
+ case '6': stepper_set_speed_rpm(60); break;
+ case '7': stepper_set_speed_rpm(70); break;
+ case '8': stepper_set_speed_rpm(80); break;
+ case '9': stepper_set_speed_rpm(90); break;
+ case '0': stepper_set_speed_rpm(100); break;
+ case '1': stepper_set_speed_rpm(110); break;
+ case '2': stepper_set_speed_rpm(120); break;
+ }
+ printf("state: %s, %3d rpm\r", stepper_state_to_string(stepper_get_state()), stepper_get_speed_rpm());
+}
+
+int main(void)
+{
+ MCUSR &= ~(1 << WDRF);
+ wdt_disable();
+
+ cpu_init();
+ jtag_disable();
+ led_init();
+ anyio_init(115200, 0);
+
+ stepper_init();
+ sei();
+
+ for(;;) {
+ anyio_task();
+
+ int16_t bytes_received = anyio_bytes_received();
+ if(bytes_received > 0)
+ handle_cmd(fgetc(stdin));
+ }
+}