aboutsummaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2011-03-11 01:28:00 +0000
committerDimitri Sokolyuk <demon@dim13.org>2011-03-11 01:28:00 +0000
commitb8335062ae7d19bd27e6131fadcd7d3a116c4992 (patch)
tree3bd226885fb6f2ca24ee300a44d7b51ffb8d2706 /firmware
DimOS RT
Diffstat (limited to 'firmware')
-rw-r--r--firmware/Makefile61
-rw-r--r--firmware/firmware.c104
2 files changed, 165 insertions, 0 deletions
diff --git a/firmware/Makefile b/firmware/Makefile
new file mode 100644
index 0000000..a65993e
--- /dev/null
+++ b/firmware/Makefile
@@ -0,0 +1,61 @@
+# $Id$
+
+PROG = firmware
+SRCS = firmware.c
+HEADERS =
+MCU_TARGET = atmega8
+F_CPU = 16000000
+PRESCALE = 8
+BAUD = 9600
+ORG = 0x1e00
+
+# You should not have to change anything below here.
+
+OBJS = ${SRCS:.c=.o}
+CC = avr-gcc
+CFLAGS = -Wall -Os -mmcu=${MCU_TARGET} \
+ -DF_CPU=${F_CPU} -DPRESCALE=${PRESCALE} -DBAUD=${BAUD}
+LDFLAGS = -Wl,-Map,${PROG}.map,--section-start=.text=${ORG}
+OBJCOPY = avr-objcopy
+OBJDUMP = avr-objdump
+SIZE = avr-size
+
+.SUFFIXES: .elf .lst .hex .bin .srec .ehex .ebin .esrec
+
+all: ${PROG}.elf ${PROG}.lst ${PROG}.hex ${PROG}.ehex size
+
+${SRCS}: ${HEADERS} Makefile
+
+${PROG}.elf: ${OBJS}
+ ${CC} ${CFLAGS} ${LDFLAGS} -o ${.TARGET} ${.ALLSRC}
+
+size: ${PROG}.elf
+ ${SIZE} -C --mcu=${MCU_TARGET} ${.ALLSRC}
+
+clean:
+ rm -f *.o ${PROG}.elf *.bak *.lst *.map *.hex *.bin *srec *.ehex *.ebin *.esrec
+
+.elf.lst:
+ ${OBJDUMP} -h -S ${.ALLSRC} > ${.TARGET}
+
+# Rules for building the .text rom images
+
+.elf.hex:
+ ${OBJCOPY} -j .text -j .data -O ihex ${.ALLSRC} ${.TARGET}
+
+.elf.bin:
+ ${OBJCOPY} -j .text -j .data -O binary ${.ALLSRC} ${.TARGET}
+
+.elf.srec:
+ ${OBJCOPY} -j .text -j .data -O srec ${.ALLSRC} ${.TARGET}
+
+# Rules for building the .eeprom rom images
+
+.elf.ehex:
+ ${OBJCOPY} -j .eeprom --change-section-lma .eeprom=0 -O ihex ${.ALLSRC} ${.TARGET}
+
+.elf.ebin:
+ ${OBJCOPY} -j .eeprom --change-section-lma .eeprom=0 -O binary ${.ALLSRC} ${.TARGET}
+
+.elf.esrec:
+ ${OBJCOPY} -j .eeprom --change-section-lma .eeprom=0 -O srec ${.ALLSRC} ${.TARGET}
diff --git a/firmware/firmware.c b/firmware/firmware.c
new file mode 100644
index 0000000..a0a649b
--- /dev/null
+++ b/firmware/firmware.c
@@ -0,0 +1,104 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2011 Dimitri Sokolyuk <demon@dim13.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <avr/io.h>
+#include <util/setbaud.h> /* depends on BAUD & F_CPU env vars */
+#include <avr/boot.h>
+
+#define TIMEOUT (F_CPU >> 3) /* ca. 2 sec */
+
+union {
+ uint16_t word;
+ uint8_t byte[2];
+} data;
+
+void
+reboot()
+{
+ boot_rww_enable();
+ ((void(*)(void))0)(); /* jump to app */
+}
+
+void
+putch(char c)
+{
+ if (c == '\n')
+ putch('\r'); /* be unix polite */
+
+ loop_until_bit_is_set(UCSRA, UDRE);
+
+ UDR = c;
+}
+
+uint8_t
+getch(void)
+{
+ uint32_t counter = 0;
+
+ do {
+ if (++counter > TIMEOUT)
+ reboot();
+ } while (bit_is_clear(UCSRA, RXC));
+
+ return UDR;
+}
+
+int
+main(void)
+{
+ uint8_t i;
+ uint16_t off;
+
+ UCSRB = _BV(RXEN) | _BV(TXEN);
+ UBRRH = UBRRH_VALUE;
+ UBRRL = UBRRL_VALUE;
+ UCSRA &= ~_BV(U2X);
+
+ putch('+'); /* say hallo */
+
+ if (getch() != 'P') /* wait a while for program request */
+ reboot();
+ putch('p'); /* confirm */
+
+ for (;;) {
+ switch (getch()) {
+ case 'D': /* data request */
+ off = (uint16_t)getch() * SPM_PAGESIZE;
+ for (i = 0; i < SPM_PAGESIZE; i += 2) {
+ data.byte[0] = getch();
+ data.byte[1] = getch();
+ boot_page_fill(off + i, data.word);
+ }
+
+ boot_page_erase(off);
+ boot_spm_busy_wait();
+
+ boot_page_write(off);
+ boot_spm_busy_wait();
+
+ putch('d'); /* confirm */
+ break;
+ case 'R': /* reboot request */
+ reboot();
+ break;
+ default:
+ break;
+ }
+ }
+
+ return 0;
+}