diff --git a/whirl/fw/Makefile b/whirl/fw/Makefile new file mode 100644 index 0000000..27db280 --- /dev/null +++ b/whirl/fw/Makefile @@ -0,0 +1,152 @@ +# +# Makefile - Makefile of the Whirl firmware +# +# Written 2012 by Werner Almesberger +# Copyright 2012 by Werner Almesberger +# +# 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. +# + +SHELL = /bin/bash + +NAME = whirl + +CFLAGS = -g -mmcu=$(CHIP) \ + -DBOOT_ADDR=$(BOOT_ADDR) \ + -Wall -Wextra -Wshadow -Werror -Wno-unused-parameter \ + -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes \ + -I../../ben-wpan/atusb/fw/include/ + +CHIP = atmega168 +HOST = jlime +BOOT_ADDR = 0x3800 + +AVR_PREFIX = $(BIN_PATH) avr- +CC = $(AVR_PREFIX)gcc +OBJCOPY = $(AVR_PREFIX)objcopy +#OBJDUMP = $(AVR_PREFIX)objdump +SIZE = $(AVR_PREFIX)size + +OBJS = $(NAME).o $(COMMON_OBJS) +BOOT_OBJS = boot.o $(COMMON_OBJS) +COMMON_OBJS = + +# ----- Verbosity control ----------------------------------------------------- + +CC_normal := $(CC) +BUILD_normal := +DEPEND_normal := $(CPP) $(CFLAGS) -MM -MG + +CC_quiet = @echo " CC " $@ && $(CC_normal) +BUILD_quiet = @echo " BUILD " $@ && $(BUILD_normal) +DEPEND_quiet = @$(DEPEND_normal) + +ifeq ($(V),1) + CC = $(CC_normal) + BUILD = $(BUILD_normal) + DEPEND = $(DEPEND_normal) +else + CC = $(CC_quiet) + BUILD = $(BUILD_quiet) + DEPEND = $(DEPEND_quiet) +endif + +# ----- Rules ----------------------------------------------------------------- + +.PHONY: all clean nosecrets upload prog version.c +.PHONY: prog-app prog-read + +all: $(NAME).bin boot.bin + +$(NAME).elf: $(OBJS) + $(MAKE) version.o + $(CC) $(CFLAGS) -o $@ $(OBJS) version.o + +boot.elf: $(BOOT_OBJS) + $(CC) $(CFLAGS) -o $@ $(BOOT_OBJS) \ + -Wl,--section-start=.text=$(BOOT_ADDR) + +%.bin: %.elf + $(BUILD) $(OBJCOPY) -j .text -j .data -O binary $< $@ + @echo "build #`cat .version`, `ls -l $@`" + +%.hex: %.elf + $(BUILD) $(OBJCOPY) -j .text -j .data -O ihex $< $@ + $(SIZE) $@ + +# ----- Cleanup --------------------------------------------------------------- + +clean: + rm -f $(NAME).bin $(NAME).elf + rm -f $(OBJS) $(OBJS:.o=.d) + rm -f boot.hex boot.elf + rm -f $(BOOT_OBJS) $(BOOT_OBJS:.o=.d) + rm -f version.c version.d version.o + +# ----- Build version --------------------------------------------------------- + +version.c: + @if [ -f .version ]; then \ + v=`cat .version`; \ + expr $$v + 1 >.version; \ + else \ + echo 0 >.version; \ + fi + @[ -s .version ] || echo 0 >.version + @echo '/* MACHINE-GENERATED. DO NOT EDIT ! */' >version.c + @echo '#include "version.h"' >>version.c + @echo "const char *build_date = \"`date`\";" >>version.c + @echo "const uint16_t build_number = `cat .version`;" \ + >>version.c + +# ----- Dependencies ---------------------------------------------------------- + +MKDEP = \ + $(DEPEND) $< | \ + sed \ + -e 's|^$(basename $(notdir $<)).o:|$@:|' \ + -e '/^\(.*:\)\? */{p;s///;s/ *\\\?$$/ /;s/ */:\n/g;H;}' \ + -e '$${g;p;}' \ + -e d >$(basename $@).d; \ + [ "$${PIPESTATUS[*]}" = "0 0" ] || \ + { rm -f $(basename $@).d; exit 1; } + +%.o: %.c + $(CC) $(CFLAGS) -Os -c $< + $(MKDEP) + +-include $(OBJS:.o=.d) + +# ----- Programming and device control ---------------------------------------- + +upload: $(NAME).bin boot.hex + scp $(NAME).bin boot.hex avrdude-antorcha.conf $(HOST): + +# lfuse: external clock, slow start-up +# hfuse: 4 kB boot loader, reset into boot loader +# lock: allow everything but SPM to the boot loader +# Note: when trying to program 0xef, we get back 0x2f, failing +# verification. So we just program 0x2f. + +prog-app: + ssh $(HOST) avrdude -F -p $(CHIP) \ + -L avrdude-antorcha.conf -c nanonote_antorcha -e \ + -U flash:w:antorcha.bin:r +# -U lfuse:w:0x60:m + +prog: + ssh $(HOST) avrdude -F -p $(CHIP) \ + -L avrdude-antorcha.conf -c nanonote_antorcha -e \ + -U flash:w:boot.hex:i \ + -U efuse:w:0x00:m \ + -U lfuse:w:0xe2:m +# -U lfuse:w:0x60:m \ +# -U hfuse:w:0xd8:m \ +# -U lock:w:0x2f:m + +prog-read: + ssh $(HOST) avrdude -F -p $(CHIP) -c nanonote_antorcha \ + -U flash:r:mcu.bin:r diff --git a/whirl/fw/boot.c b/whirl/fw/boot.c new file mode 100644 index 0000000..18cee63 --- /dev/null +++ b/whirl/fw/boot.c @@ -0,0 +1,82 @@ +#include + +#define F_CPU 8000000UL +#include + +#include "io.h" + + +#define HIGH(port) \ + (MASK(port, CARD_nPWR) | \ + MASK(port, SW_N) | MASK(port, SW_E) | MASK(port, SW_S) | \ + MASK(port, SW_W) | MASK(port, SW_SW)) + +#define OUTPUTS(port) \ + (MASK(port, CARD_nPWR) | MASK(port, CARD_CLK) | \ + MASK(port, LED_DS) | MASK(port, LED_LCLK) | MASK(port, LED_SCLK)) + + +/* + * @@@ For testing, connect the LED bar via the 8:10 card slot, so that it + * can be disconnected without soldering. + */ + +#define SCLK CARD_DAT1 +#define LCLK CARD_DAT0 +#define DS CARD_CLK + + +static void send(uint16_t pattern) +{ + uint8_t i; + + for (i = 0; i != 16; i++) { + if (pattern & 0x8000) + SET(DS); + else + CLR(DS); + SET(SCLK); + CLR(SCLK); + pattern <<= 1; + } + SET(LCLK); + CLR(LCLK); +} + + +int main(void) +{ + uint16_t n = 0; + + PORTB = HIGH(B); + PORTC = HIGH(C); + PORTD = HIGH(D); + DDRB = OUTPUTS(B); + DDRC = OUTPUTS(C); + DDRD = OUTPUTS(D); + +#if 0 + PORTB = 0xff; + PORTC = 0xff; + PORTD = 0xff; +#endif + + CLR(CARD_nPWR); + CLR(SCLK); + CLR(LCLK); + OUT(SCLK); + OUT(LCLK); + OUT(DS); + +#if 0 + while (1) { + SET(DS); + CLR(DS); + } +#endif + while (1) { + send(n); + n++; + _delay_ms(100); + } +} diff --git a/whirl/fw/io.h b/whirl/fw/io.h new file mode 100644 index 0000000..c0e2ff1 --- /dev/null +++ b/whirl/fw/io.h @@ -0,0 +1,66 @@ +/* + * fw/io.h - I/O helper macros + * + * Written 2012 by Werner Almesberger + * Copyright 2012 Werner Almesberger + * + * 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. + */ + +#ifndef IO_H +#define IO_H + +#include + + +#define LED_DS D, 1 +#define LED_LCLK D, 2 +#define LED_SCLK D, 4 + +#define CARD_nPWR B, 6 +#define CARD_DAT2 B, 2 +#define CARD_DAT3 B, 1 +#define CARD_CMD B, 3 +#define CARD_CLK B, 0 +#define CARD_DAT0 B, 4 +#define CARD_DAT1 B, 5 + +#define SW_N C, 3 +#define SW_E C, 4 +#define SW_S C, 0 +#define SW_W C, 2 +#define SW_SW C, 1 + +#define ADC_X 6 +#define ADC_Y 7 + +#define __SET(port, bit) PORT##port |= 1 << (bit) +#define __CLR(port, bit) PORT##port &= ~(1 << (bit)) +#define __OUT(port, bit) DDR##port |= 1 << (bit) +#define __IN(port, bit) DDR##port &= ~(1 << (bit)) +#define __PIN(port, bit) ((PIN##port >> (bit)) & 1) + +#define SET(...) __SET(__VA_ARGS__) +#define CLR(...) __CLR(__VA_ARGS__) +#define OUT(...) __OUT(__VA_ARGS__) +#define IN(...) __IN(__VA_ARGS__) +#define PIN(...) __PIN(__VA_ARGS__) + +#define __SEL_BB(v) (v) +#define __SEL_CC(v) (v) +#define __SEL_DD(v) (v) + +#define __SEL_BC(v) (0) +#define __SEL_BD(v) (0) +#define __SEL_CB(v) (0) +#define __SEL_CD(v) (0) +#define __SEL_DB(v) (0) +#define __SEL_DC(v) (0) + +#define __MASK(sel, port, bit) __SEL_##sel##port(1 << (bit)) +#define MASK(...) __MASK(__VA_ARGS__) + +#endif /* IO_H */ diff --git a/whirl/fw/version.h b/whirl/fw/version.h new file mode 100644 index 0000000..8fd6a2c --- /dev/null +++ b/whirl/fw/version.h @@ -0,0 +1,23 @@ +/* + * fw/version.h - Automatically generated version string + * + * Written 2008, 2011 by Werner Almesberger + * Copyright 2008, 2011 Werner Almesberger + * + * 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. + */ + + +#ifndef VERSION_H +#define VERSION_H + +#include + + +extern const char *build_date; +extern const uint16_t build_number; + +#endif /* !VERSION_H */ diff --git a/whirl/fw/whirl.c b/whirl/fw/whirl.c new file mode 100644 index 0000000..eb5de02 --- /dev/null +++ b/whirl/fw/whirl.c @@ -0,0 +1,4 @@ +int main(void) +{ + while (1); +}