summaryrefslogtreecommitdiffstats
path: root/pressure_control/firmware
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2008-10-09 20:57:51 +0200
committerMichael Buesch <mb@bu3sch.de>2008-10-09 20:57:51 +0200
commit92af9d1735aab816bca994f513314cdcc8b9bd66 (patch)
tree70e346613cb271e78b79167d3993885c0ca5bbef /pressure_control/firmware
parent5522cb6f66bea3b27134f6a4517e8472b7226bda (diff)
downloadcnc-92af9d1735aab816bca994f513314cdcc8b9bd66.tar.xz
cnc-92af9d1735aab816bca994f513314cdcc8b9bd66.zip
Add pressure_control firmware skeleton.
Signed-off-by: Michael Buesch <mb@bu3sch.de>
Diffstat (limited to 'pressure_control/firmware')
-rw-r--r--pressure_control/firmware/Makefile92
-rw-r--r--pressure_control/firmware/calibration.h18
-rw-r--r--pressure_control/firmware/main.c32
-rw-r--r--pressure_control/firmware/util.c78
-rw-r--r--pressure_control/firmware/util.h74
5 files changed, 294 insertions, 0 deletions
diff --git a/pressure_control/firmware/Makefile b/pressure_control/firmware/Makefile
new file mode 100644
index 0000000..30eaaf6
--- /dev/null
+++ b/pressure_control/firmware/Makefile
@@ -0,0 +1,92 @@
+ARCH ?= atmega8
+AVRDUDE_ARCH ?= m8
+AVRDUDE ?= avrdude
+AVRDUDE_SPEED ?= 1
+PROGRAMMER ?= avrisp2
+PROGPORT ?= usb
+
+CC = avr-gcc
+OBJCOPY = avr-objcopy
+SIZE = avr-size
+
+CFLAGS = -mmcu=$(ARCH) -std=gnu99 -g0 -O2 -fomit-frame-pointer -Wall -fpack-struct
+CFLAGS += "-Dinline=inline __attribute__((__always_inline__))"
+
+
+# The fuse bits
+LFUSE = 0xE0
+HFUSE = 0xD9
+
+OBJECTS = main.o util.o
+NAME = pressure_control
+
+BIN = $(NAME).bin
+HEX = $(NAME).hex
+EEP = $(NAME).eep.hex
+
+all: $(HEX)
+
+main.o: util.h
+
+util.o: util.h calibration.h
+
+%.s: %.c
+ $(CC) $(CFLAGS) -S $*.c
+
+$(BIN): $(OBJECTS)
+ $(CC) $(CFLAGS) -o $(BIN) $(OBJECTS) $(LDFLAGS)
+
+$(HEX): $(BIN)
+ $(OBJCOPY) -R.eeprom -O ihex $(BIN) $(HEX)
+# $(OBJCOPY) -j.eeprom --set-section-flags=.eeprom="alloc,load" \
+# --change-section-lma .eeprom=0 -O ihex $(BIN) $(EEP)
+ $(SIZE) $(BIN)
+
+avrdude:
+ $(AVRDUDE) -B $(AVRDUDE_SPEED) -p $(AVRDUDE_ARCH) \
+ -c $(PROGRAMMER) -P $(PROGPORT) -t
+
+install_flash:
+ $(AVRDUDE) -B $(AVRDUDE_SPEED) -p $(AVRDUDE_ARCH) \
+ -c $(PROGRAMMER) -P $(PROGPORT) -U flash:w:$(HEX)
+
+install_eeprom:
+ $(AVRDUDE) -B $(AVRDUDE_SPEED) -p $(AVRDUDE_ARCH) \
+ -c $(PROGRAMMER) -P $(PROGPORT) -U eeprom:w:$(EEP)
+
+install: all install_flash
+
+# Reset the microcontroller through avrdude
+reset:
+ $(AVRDUDE) -B $(AVRDUDE_SPEED) -p $(AVRDUDE_ARCH) \
+ -c $(PROGRAMMER) -P $(PROGPORT) \
+ -U signature:r:/dev/null:i -q -q
+
+writefuse:
+ $(AVRDUDE) -B 100 -p $(AVRDUDE_ARCH) \
+ -c $(PROGRAMMER) -P $(PROGPORT) -q -q \
+ -U lfuse:w:$(LFUSE):m \
+ -U hfuse:w:$(HFUSE):m
+
+clean:
+ -rm -f *~ *.o $(BIN)
+
+distclean: clean
+ -rm -f *.s $(HEX) $(EEP)
+
+help:
+ @echo "Makefile"
+ @echo ""
+ @echo "Targets:"
+ @echo " all - build the firmware (default target)"
+ @echo " clean - remove object files"
+ @echo " distclean - remove object, binary and hex files"
+ @echo ""
+ @echo "Targets that operate on the device through avrdude:"
+ @echo " install - flash the program code"
+ @echo " writefuse - write the fuse bits"
+ @echo " reset - pull the external device reset pin"
+ @echo " avrdude - run avrdude in interactive mode"
+ @echo ""
+ @echo "Generic targets:"
+ @echo " *.s - create an assembly file from a *.c file"
diff --git a/pressure_control/firmware/calibration.h b/pressure_control/firmware/calibration.h
new file mode 100644
index 0000000..eb2f532
--- /dev/null
+++ b/pressure_control/firmware/calibration.h
@@ -0,0 +1,18 @@
+#ifndef CALIBRATION_H_
+#define CALIBRATION_H_
+
+/****************************************************************************
+ * Microcontroller CPU speed calibration *
+ ****************************************************************************/
+
+/* CPU frequency in HZ */
+#define CPU_HZ 16000000
+/* 1ms timer calibration */
+#define DELAY_1MS_TIMERFREQ (1 << CS01) /* == CPU_FREQ/8 */
+#define DELAY_1MS_LOOP 80
+#define DELAY_1MS_LOOP_TIMES 25
+/* 1us delayloop calibration */
+#define DELAY_1US_LOOP 4
+
+
+#endif /* CALIBRATION_H_ */
diff --git a/pressure_control/firmware/main.c b/pressure_control/firmware/main.c
new file mode 100644
index 0000000..949e5cb
--- /dev/null
+++ b/pressure_control/firmware/main.c
@@ -0,0 +1,32 @@
+/*
+ * Pneumatic pressure controller.
+ *
+ * Copyright (C) 2008 Michael Buesch <mb@bu3sch.de>
+ *
+ * This program 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
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "util.h"
+
+
+int main(void)
+{
+ cli();
+ //TODO
+ sei();
+
+ while (1) {
+ //TODO
+ }
+}
diff --git a/pressure_control/firmware/util.c b/pressure_control/firmware/util.c
new file mode 100644
index 0000000..3cecc46
--- /dev/null
+++ b/pressure_control/firmware/util.c
@@ -0,0 +1,78 @@
+/*
+ * Utility functions
+ *
+ * Copyright (C) 2008 Michael Buesch <mb@bu3sch.de>
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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.
+ */
+
+#include "util.h"
+#include "calibration.h"
+
+#include <avr/io.h>
+#include <avr/sleep.h>
+
+
+void mdelay(uint16_t msecs)
+{
+ uint8_t timer, i;
+
+ TCCR0 = DELAY_1MS_TIMERFREQ;
+ do {
+ /* Delay one millisecond */
+ for (i = DELAY_1MS_LOOP_TIMES; i; i--) {
+ TCNT0 = 0;
+ do {
+ timer = TCNT0;
+ } while (timer < DELAY_1MS_LOOP);
+ }
+ } while (--msecs);
+ TCCR0 = 0;
+}
+
+void udelay(uint16_t usecs)
+{
+ uint8_t tmp;
+
+ __asm__ __volatile__(
+ "1: \n"
+ " ldi %1, %2 \n"
+ "2: \n"
+ " dec %1 \n"
+ " brne 2b \n"
+ " dec %A3 \n"
+ " brne 1b \n"
+ " cp %B3, __zero_reg__ \n"
+ " breq 3f \n"
+ " dec %B3 \n"
+ " ldi %A3, 0xFF \n"
+ " rjmp 1b \n"
+ "3: \n"
+ : "=d" (usecs),
+ "=d" (tmp)
+ : "M" (DELAY_1US_LOOP),
+ "0" (usecs)
+ );
+}
+
+void panic(const prog_char *msg)
+{
+//TODO
+ infinite_sleep();
+}
+
+void infinite_sleep(void)
+{
+ cli();
+ set_sleep_mode(SLEEP_MODE_PWR_DOWN);
+ while (1)
+ sleep_mode();
+}
diff --git a/pressure_control/firmware/util.h b/pressure_control/firmware/util.h
new file mode 100644
index 0000000..758f6f8
--- /dev/null
+++ b/pressure_control/firmware/util.h
@@ -0,0 +1,74 @@
+#ifndef UTIL_H_
+#define UTIL_H_
+
+#include <stdint.h>
+#include <avr/eeprom.h>
+#include <avr/interrupt.h>
+#include <avr/pgmspace.h>
+
+/* Some of these macros are derived from the Linux Kernel sources. */
+
+#define likely(x) __builtin_expect(!!(x), 1)
+#define unlikely(x) __builtin_expect(!!(x), 0)
+
+#define offsetof(type, member) ((size_t)&((type *)0)->member)
+
+#define min(a, b) ((a) < (b) ? (a) : (b))
+#define max(a, b) ((a) > (b) ? (a) : (b))
+
+#define abs(x) ({ \
+ __typeof__(x) __x = (x); \
+ (__x < 0) ? -__x : __x; \
+ })
+
+#define lo8(x) ((uint8_t)(x))
+#define hi8(x) ((uint8_t)((x) >> 8))
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+/* Memory barrier.
+ * The CPU doesn't have runtime reordering, so we just
+ * need a compiler memory clobber. */
+#define mb() __asm__ __volatile__("" : : : "memory")
+
+/* Convert something indirectly to a string */
+#define __stringify(x) #x
+#define stringify(x) __stringify(x)
+
+/* Assertions */
+void panic(const prog_char *msg) __attribute__((noreturn));
+#define BUILD_BUG_ON(x) ((void)sizeof(char[1 - 2 * !!(x)]))
+#define BUG_ON(x) \
+ do { \
+ if (unlikely(x)) \
+ panic(PSTR(__FILE__ \
+ stringify(__LINE__))); \
+ } while (0)
+
+void infinite_sleep(void) __attribute__((noreturn));
+
+/* Delay */
+void mdelay(uint16_t msecs);
+void udelay(uint16_t usecs);
+
+typedef _Bool bool;
+
+/* IRQ handling.
+ * We use a macro for irq_disable_save(), because stupid gcc is not
+ * able to properly optimize an inline function that returns a value.
+ */
+#define irq_disable_save() ({ \
+ uint8_t sreg_flags = SREG; \
+ cli(); \
+ sreg_flags; \
+ })
+
+static inline void irq_restore(uint8_t sreg_flags)
+{
+ mb();
+ SREG = sreg_flags;
+}
+
+#define irqs_disabled() (!(SREG & (1 << SREG_I)))
+
+#endif /* UTIL_H_ */
bues.ch cgit interface