Add firmware for the ATUSB IEEE 802.15.4 USB Adapter
[linux-libre-firmware.git] / atusb / boot.c
diff --git a/atusb/boot.c b/atusb/boot.c
new file mode 100644 (file)
index 0000000..6826ac6
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * fw/boot.c - DFU boot loader for ATUSB
+ *
+ * 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.
+ */
+
+
+#include <stdint.h>
+
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <avr/pgmspace.h>
+
+#define F_CPU   8000000UL
+#include <util/delay.h>
+
+#include "usb.h"
+#include "dfu.h"
+
+#include "board.h"
+#include "spi.h"
+#include "atusb/ep0.h"
+
+
+#define        MS_TO_LOOPS(ms) ((uint32_t) (ms)*335)
+
+
+static void (*run_payload)(void) = 0;
+
+
+int main(void)
+{
+       /*
+        * pgm_read_byte gets cached and there doesn't seem to be any other
+        * way to dissuade gcc from doing this.
+        */
+       volatile int zero = 0;
+       uint32_t loop = 0;
+
+       board_init();
+       reset_rf();
+
+       /* now we should be at 8 MHz */
+
+       usb_init();
+       dfu_init();
+
+       /* move interrupt vectors to the boot loader */
+       MCUCR = 1 << IVCE;
+       MCUCR = 1 << IVSEL;
+
+       sei();
+
+       led(1);
+
+       while (loop != MS_TO_LOOPS(2500)) {
+               if (dfu.state == dfuIDLE && pgm_read_byte(zero) != 0xff)
+                       loop++;
+               else
+                       loop = 0;
+       }
+
+       led(0);
+
+       cli();
+
+       usb_reset();
+       run_payload();
+
+       while (1);      /* not reached */
+}