diff --git a/redbee-econotag/Makefile b/redbee-econotag/Makefile
index 391c9bd42f07c4d2520fb080a1a3e1adec80b2fb..ae4ccfd0a780265afd897e9e6930b8b90f81579d 100644
--- a/redbee-econotag/Makefile
+++ b/redbee-econotag/Makefile
@@ -4,6 +4,12 @@ OBJ = $(SRC:%.c=$(BINDIR)%.o)## defines
 DEP = $(SRC:%.c=$(BINDIR)%.d)
 export ARCH = redbee-econotag_base.a
 
+INCLUDES += -I$(RIOTBOARD)/redbee-econotag/drivers/include
+INCLUDES += -I$(RIOTBASE)/cpu/arm_common/include
+INCLUDES += -I$(RIOTBASE)/cpu/mc1322x/include
+
+.PHONY: $(BINDIR)/$(ARCH)
+
 all: $(BINDIR)$(ARCH)
 	$(MAKE) -C drivers
 
diff --git a/redbee-econotag/README b/redbee-econotag/README
new file mode 100644
index 0000000000000000000000000000000000000000..7cce0fdd0536ab9f6da6205048dc66f544f02f12
--- /dev/null
+++ b/redbee-econotag/README
@@ -0,0 +1,11 @@
+Flashing:
+tools/mc1322x-load.pl -f <path/to/binary> -t /dev/<tty-device>
+
+more information: https://github.com/malvira/libmc1322x/wiki/libmc1322x#loading-images-to-ram-with-mc1322x-loadpl
+
+Erase:
+cd tools/ftditools/
+make
+./bbmc -l redbee-econotag erase
+
+more information: https://github.com/malvira/libmc1322x/wiki/bbmc
\ No newline at end of file
diff --git a/redbee-econotag/board_init.c b/redbee-econotag/board_init.c
index 5a0b03177cb1366c47f0b445a2ba77d1ca91a537..7c157b10382d729df73162b82f8697b321f03eee 100644
--- a/redbee-econotag/board_init.c
+++ b/redbee-econotag/board_init.c
@@ -9,3 +9,11 @@
 void board_init(void) {
     asm("nop");
 }
+
+void bl_init_clks( void ) {
+    // dummy to compile
+}
+
+void bl_init_ports( void ) {
+    // dummy to compile
+}
diff --git a/redbee-econotag/drivers/gpio.c b/redbee-econotag/drivers/gpio.c
new file mode 100644
index 0000000000000000000000000000000000000000..c9b867277a6e6fa082d03b369c494f70b1df430c
--- /dev/null
+++ b/redbee-econotag/drivers/gpio.c
@@ -0,0 +1,74 @@
+/*
+ * gpio.c - GPIO driver for redbee
+ * Copyright (C) 2013 Thomas Eichinger <thomas.eichinger@fu-berlin.de>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 3.  See the file LICENSE for more details.
+ *
+ * This file is part of RIOT.
+ */
+
+#include "gpio.h"
+
+inline void gpio_pad_dir(volatile uint64_t data) 
+{
+        GPIO->PAD_DIR0 = (data & 0xffffffff);
+        GPIO->PAD_DIR1 = (data >> 32);
+}
+
+inline void gpio_data(volatile uint64_t data) 
+{
+        GPIO->DATA0 = (data & 0xffffffff);
+        GPIO->DATA1 = (data >> 32);
+}
+
+inline uint64_t gpio_data_get(volatile uint64_t bits) {
+        uint64_t rdata = 0;
+
+        rdata = GPIO->DATA0 & (bits & 0xffffffff);
+        rdata |= (GPIO->DATA1 & (bits >> 32)) << 32;
+
+        return rdata;
+}
+
+inline void gpio_pad_pu_en(volatile uint64_t data) 
+{
+        GPIO->PAD_PU_EN0 = (data & 0xffffffff);
+        GPIO->PAD_PU_EN1 = (data >> 32);
+}
+
+inline void gpio_data_sel(volatile uint64_t data) 
+{
+        GPIO->DATA_SEL0 = (data & 0xffffffff);
+        GPIO->DATA_SEL1 = (data >> 32);
+}
+
+inline void gpio_pad_pu_sel(volatile uint64_t data) 
+{
+        GPIO->PAD_PU_SEL0 = (data & 0xffffffff);
+        GPIO->PAD_PU_SEL1 = (data >> 32);
+}
+
+inline void gpio_data_set(volatile uint64_t data) 
+{
+        GPIO->DATA_SET0 = (data & 0xffffffff);
+        GPIO->DATA_SET1 = (data >> 32);
+}
+
+inline void gpio_data_reset(volatile uint64_t data) 
+{
+        GPIO->DATA_RESET0 = (data & 0xffffffff);
+        GPIO->DATA_RESET1 = (data >> 32);
+}
+
+inline void gpio_pad_dir_set(volatile uint64_t data) 
+{
+        GPIO->PAD_DIR_SET0 = (data & 0xffffffff);
+        GPIO->PAD_DIR_SET1 = (data >> 32);
+}
+
+inline void gpio_pad_dir_reset(volatile uint64_t data) 
+{
+        GPIO->PAD_DIR_RESET0 = (data & 0xffffffff);
+        GPIO->PAD_DIR_RESET1 = (data >> 32);
+}
\ No newline at end of file
diff --git a/redbee-econotag/drivers/include/gpio.h b/redbee-econotag/drivers/include/gpio.h
new file mode 100644
index 0000000000000000000000000000000000000000..b46051a1a7954ad6cda37a982eb14acd7046a8b8
--- /dev/null
+++ b/redbee-econotag/drivers/include/gpio.h
@@ -0,0 +1,159 @@
+/*
+ * gpio.h - GPIO driver for redbee
+ * Copyright (C) 2013 Thomas Eichinger <thomas.eichinger@fu-berlin.de>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 3.  See the file LICENSE for more details.
+ *
+ * This file is part of RIOT.
+ */
+
+#ifndef GPIO_H
+#define GPIO_H
+
+// TODO: why do we need to include this for macro expansion?
+#include "stdint.h"
+
+/* Structure-based GPIO access
+   Example usage:
+
+   GPIO->FUNC_SEL0 |= 0x00008000; // set a whole register
+
+   GPIO->FUNC_SEL_08 = 2;        // set just one pin
+
+   #define MY_PIN GPIO_08
+   GPIO->FUNC_SEL.MY_PIN = 2;    // same, to allow #define for pin names
+   GPIO->DATA.MY_PIN = 1;
+
+   gpio_set(GPIO_08);            // efficiently set or clear a single output bit
+   gpio_reset(GPIO_08);
+*/
+
+// GPIO to Function Alias macros:
+
+#define ADC0 GPIO_30
+#define ADC1 GPIO_31
+#define ADC2 GPIO_32
+#define ADC3 GPIO_33
+#define ADC4 GPIO_34
+#define ADC5 GPIO_35
+#define ADC6 GPIO_36
+#define ADC7 GPIO_37
+#define TDO GPIO_49
+#define TDI GPIO_48
+#define TCK GPIO_47
+#define TMS GPIO_46
+#define U2RTS GPIO_21
+#define U2CTS GPIO_20
+#define U2RX GPIO_19
+#define U2TX GPIO_18
+#define U1RTS GPIO_17
+#define U1CTS GPIO_16
+#define U1RX GPIO_15
+#define U1TX GPIO_14
+#define SDA GPIO_13
+#define SCL GPIO_12
+#define TMR3 GPIO_11
+#define TMR2 GPIO_10
+#define TMR1 GPIO_09
+#define TMR0 GPIO_08
+#define SCK GPIO_07
+#define MOSI GPIO_06
+#define MISO GPIO_05
+#define SS GPIO_04
+#define BTCK GPIO_03
+#define FSYN GPIO_02
+#define SSIRX GPIO_01
+#define SSITX GPIO_00
+#define KBI7 GPIO_29
+#define KBI6 GPIO_28
+#define KBI5 GPIO_27
+#define KBI4 GPIO_26
+#define KBI3 GPIO_25
+#define KBI2 GPIO_24
+#define KBI1 GPIO_23
+#define KBI0 GPIO_22
+#define TXON GPIO_44
+#define RXON GPIO_45
+#define ANT1 GPIO_42
+#define ANT2 GPIO_43 
+#define VREF2H GPIO_38
+#define VREF2L GPIO_39
+#define VREF1H GPIO_40
+#define VREF1L GPIO_41
+#define MDO0 GPIO_51 
+#define MDO1 GPIO_52
+#define MDO2 GPIO_53
+#define MDO3 GPIO_54
+#define MDO4 GPIO_55
+#define MDO5 GPIO_56
+#define MDO6 GPIO_57
+#define MDO7 GPIO_58
+#define MSEO0 GPIO_59
+#define MSEO1 GPIO_60
+#define RDY GPIO_61
+#define EVTO GPIO_62
+#define MCKO GPIO_50
+#define EVTI GPIO_63
+
+
+#define _V(x,n,i) uint32_t x##_##i : n;
+#define _REP(x,n) \
+        _V(x,n,00) _V(x,n,01) _V(x,n,02) _V(x,n,03) _V(x,n,04) _V(x,n,05) _V(x,n,06) _V(x,n,07) \
+        _V(x,n,08) _V(x,n,09) _V(x,n,10) _V(x,n,11) _V(x,n,12) _V(x,n,13) _V(x,n,14) _V(x,n,15) \
+        _V(x,n,16) _V(x,n,17) _V(x,n,18) _V(x,n,19) _V(x,n,20) _V(x,n,21) _V(x,n,22) _V(x,n,23) \
+        _V(x,n,24) _V(x,n,25) _V(x,n,26) _V(x,n,27) _V(x,n,28) _V(x,n,29) _V(x,n,30) _V(x,n,31) \
+        _V(x,n,32) _V(x,n,33) _V(x,n,34) _V(x,n,35) _V(x,n,36) _V(x,n,37) _V(x,n,38) _V(x,n,39) \
+        _V(x,n,40) _V(x,n,41) _V(x,n,42) _V(x,n,43) _V(x,n,44) _V(x,n,45) _V(x,n,46) _V(x,n,47) \
+        _V(x,n,48) _V(x,n,49) _V(x,n,50) _V(x,n,51) _V(x,n,52) _V(x,n,53) _V(x,n,54) _V(x,n,55) \
+        _V(x,n,56) _V(x,n,57) _V(x,n,58) _V(x,n,59) _V(x,n,60) _V(x,n,61) _V(x,n,62) _V(x,n,63)
+
+struct GPIO_struct {
+#define _IO(x) \
+        union { struct { uint32_t x##0; uint32_t x##1; }; \
+                struct { _REP(x, 1) };  \
+                struct GPIO_##x { _REP(GPIO, 1) } x; };
+#define _IO_2bit(x)     \
+        union { struct { uint32_t x##0; uint32_t x##1; uint32_t x##2; uint32_t x##3; }; \
+                struct { _REP(x, 2) };  \
+                struct GPIO_##x { _REP(GPIO, 2) } x; };
+
+        _IO(PAD_DIR);
+        _IO(DATA);
+        _IO(PAD_PU_EN);
+        _IO_2bit(FUNC_SEL);
+        _IO(DATA_SEL);
+        _IO(PAD_PU_SEL);
+        _IO(PAD_HYST_EN);
+        _IO(PAD_KEEP);
+        _IO(DATA_SET);
+        _IO(DATA_RESET);
+        _IO(PAD_DIR_SET);
+        _IO(PAD_DIR_RESET);
+};
+#undef _IO
+#undef _IO_2bit
+
+/* Build an enum lookup to map GPIO_08 -> 8 */
+#undef _V
+#define _V(x,n,i) __NUM_GPIO_GPIO_##i,
+enum { _REP(0,0) };
+
+/* Macros to set or reset a data pin in the fastest possible way */
+#define gpio_set(gpio_xx) __gpio_set(gpio_xx)
+#define __gpio_set(gpio_xx)                                             \
+        ((__NUM_GPIO_##gpio_xx < 32)                                    \
+         ? (GPIO->DATA_SET0 = (1 << (__NUM_GPIO_##gpio_xx - 0)))        \
+         : (GPIO->DATA_SET1 = (1 << (__NUM_GPIO_##gpio_xx - 32))))
+#define gpio_reset(gpio_xx) __gpio_reset(gpio_xx)
+#define __gpio_reset(gpio_xx)                                           \
+        ((__NUM_GPIO_##gpio_xx < 32)                                    \
+         ? (GPIO->DATA_RESET0 = (1 << (__NUM_GPIO_##gpio_xx - 0)))      \
+         : (GPIO->DATA_RESET1 = (1 << (__NUM_GPIO_##gpio_xx - 32))))
+
+#undef _REP
+#undef _V
+
+static volatile struct GPIO_struct * const GPIO = (void *) (0x80000000);
+
+#endif
\ No newline at end of file
diff --git a/redbee-econotag/drivers/include/uart.h b/redbee-econotag/drivers/include/uart.h
new file mode 100644
index 0000000000000000000000000000000000000000..928a2157a9b90109aad9a5391b29794ba93696af
--- /dev/null
+++ b/redbee-econotag/drivers/include/uart.h
@@ -0,0 +1,139 @@
+/*
+ * uart.h - UART driver for redbee
+ * Copyright (C) 2013 Thomas Eichinger <thomas.eichinger@fu-berlin.de>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 3.  See the file LICENSE for more details.
+ *
+ * This file is part of RIOT.
+ */
+
+#ifndef UART_H
+#define UART_H
+
+/*-----------------------------------------------------------------*/
+/* UART */
+#define UART1_BASE      (0x80005000)
+#define UART2_BASE      (0x8000B000)
+
+struct UART_struct {
+        union {
+                uint32_t CON;
+                struct UART_CON {
+                        uint32_t :16;
+                        uint32_t TST:1;
+                        uint32_t MRXR:1;
+                        uint32_t MTXR:1;
+                        uint32_t FCE:1;
+                        uint32_t FCP:1;
+                        uint32_t XTIM:1;
+                        uint32_t :2;
+                        uint32_t TXOENB:1;
+                        uint32_t CONTX:1;
+                        uint32_t SB:1;
+                        uint32_t ST2:1;
+                        uint32_t EP:1;
+                        uint32_t PEN:1;
+                        uint32_t RXE:1;
+                        uint32_t TXE:1;
+                } CONbits;
+        };
+        union {
+                uint32_t STAT;
+                struct UART_STAT {
+                        uint32_t :24;
+                        uint32_t TXRDY:1;
+                        uint32_t RXRDY:1;
+                        uint32_t RUE:1;
+                        uint32_t ROE:1;
+                        uint32_t TOE:1;
+                        uint32_t FE:1;
+                        uint32_t PE:1;
+                        uint32_t SE:1;
+                } USTATbits;
+        };
+        union {
+                uint32_t DATA;
+                struct UART_DATA {
+                        uint32_t :24;
+                        uint32_t DATA:8;
+                } DATAbits;
+        };
+        union {
+                uint32_t RXCON;
+                struct UART_URXCON {
+                        uint32_t :26;
+                        uint32_t LVL:6;
+                } RXCONbits;
+        };
+        union {
+                uint32_t TXCON;
+                struct UART_TXCON {
+                        uint32_t :26;
+                        uint32_t LVL:6;
+                } TXCONbits;
+        };
+        union {
+                uint32_t CTS;
+                struct UART_CTS {
+                        uint32_t :27;
+                        uint32_t LVL:5;
+                } CTSbits;
+        };
+        union {
+                uint32_t BR;
+                struct UART_BR {
+                        uint32_t INC:16;
+                        uint32_t MOD:16;
+                } BRbits;
+        };
+};
+
+static volatile struct UART_struct * const UART1 = (void *) (UART1_BASE);
+static volatile struct UART_struct * const UART2 = (void *) (UART2_BASE);
+
+void uart_init(volatile struct UART_struct * uart, uint32_t baud);
+void uart_set_baudrate(volatile struct UART_struct * uart, uint32_t baud);
+void uart_flow_ctl(volatile struct UART_struct * uart, uint8_t on);
+
+
+/* The mc1322x has a 32 byte hardware FIFO for transmitted characters.
+ * Currently it is always filled from a larger RAM buffer. It would be
+ * possible to eliminate that overhead by filling directly from a chain
+ * of data buffer pointers, but printf's would be not so easy.
+ */
+#define UART1_TX_BUFFERSIZE 1024
+extern volatile uint32_t  u1_tx_head, u1_tx_tail;
+void uart1_putc(uint8_t c);
+
+/* The mc1322x has a 32 byte hardware FIFO for received characters.
+ * If a larger rx buffersize is specified the FIFO will be extended into RAM.
+ * RAM transfers will occur on interrupt when the FIFO is nearly full.
+ * If a smaller buffersize is specified hardware flow control will be
+ * initiated at that FIFO level.
+ * Set to 32 for no flow control or RAM buffer.
+ */
+#define UART1_RX_BUFFERSIZE 128
+#if UART1_RX_BUFFERSIZE > 32
+extern volatile uint32_t  u1_rx_head, u1_rx_tail;
+#define uart1_can_get() ((u1_rx_head!=u1_rx_tail) || (*UART1_URXCON > 0))
+#else
+#define uart1_can_get() (*UART1_URXCON > 0)
+#endif
+uint8_t uart1_getc(void);
+
+
+#define UART2_TX_BUFFERSIZE 1024
+extern volatile uint32_t  u2_tx_head, u2_tx_tail;
+void uart2_putc(uint8_t c);
+
+#define UART2_RX_BUFFERSIZE 128
+#if UART2_RX_BUFFERSIZE > 32
+extern volatile uint32_t  u2_rx_head, u2_rx_tail;
+#define uart2_can_get() ((u2_rx_head!=u2_rx_tail) || (*UART2_URXCON > 0))
+#else
+#define uart2_can_get() (*UART2_URXCON > 0)
+#endif
+uint8_t uart2_getc(void);
+
+#endif
\ No newline at end of file
diff --git a/redbee-econotag/drivers/redbee_uart.c b/redbee-econotag/drivers/redbee_uart.c
new file mode 100644
index 0000000000000000000000000000000000000000..621d94e060a1942cbb61d3b66f0e61e09d2f5419
--- /dev/null
+++ b/redbee-econotag/drivers/redbee_uart.c
@@ -0,0 +1,204 @@
+/*
+ * redbee_uart.c - UART driver for redbee
+ * Copyright (C) 2013 Thomas Eichinger <thomas.eichinger@fu-berlin.de>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 3.  See the file LICENSE for more details.
+ *
+ * This file is part of RIOT.
+ */
+
+#include "mc1322x.h"
+#include "uart.h"
+#include "gpio.h"
+#include "io.h"
+
+#define MOD_ 9999
+#define CLK_ 24000000
+#define DIV_ 16 /* uart->CON.XTIM = 0 is 16x oversample (datasheet is incorrect) */
+#define BAUTRATE_UART1 115200 
+#define BAUTRATE_UART2 115200
+
+void uart_set_baudrate ( volatile struct UART_struct* uart, uint32_t baudrate ) {
+    uint64_t inc = 0;
+    
+    /* calculate inc following equation 13-1 from datasheet */
+    /* multiply by another 10 to get a fixed point*/
+    inc = ((uint64_t) baudrate * DIV_ * MOD_ * 10 / CLK_) - 10;
+    /* add 5 and div by 10 to get a rounding */
+    inc = (inc + 5) / 10;
+    
+    /* disable UARTx to set baudrate */
+    uart->CONbits.TXE = 0;
+    uart->CONbits.RXE = 0;
+    
+    /* set baudrate */
+    uart->BRbits.INC = inc;
+    uart->BRbits.MOD = MOD_;
+    
+    /* reenable UARTx again */
+    /* uart->CON.XTIM = 0 is 16x oversample (datasheet is incorrect) */
+    uart->CONbits.XTIM = 0;
+    uart->CONbits.TXE = 1;
+    uart->CONbits.RXE = 1;
+}
+
+void uart_flow_ctl ( volatile struct UART_struct* uart, uint8_t on ) {
+    if (on) {
+        /* enable flow control */
+        if (uart == UART1) {
+            /* CTS and RTS directions */
+            GPIO->PAD_DIR_SET.U1CTS = 1;
+            GPIO->PAD_DIR_RESET.U1RTS = 1;
+            /* function select to uart */
+            GPIO->FUNC_SEL.U1CTS = 1;
+            GPIO->FUNC_SEL.U1RTS = 1;
+        }
+        else {
+            /* UART2 */
+            /* CTS and RTS directions */
+            GPIO->PAD_DIR_SET.U2CTS = 1;
+            GPIO->PAD_DIR_RESET.U2RTS = 1;
+            /* function select to uart */
+            GPIO->FUNC_SEL.U2CTS = 1;
+            GPIO->FUNC_SEL.U2RTS = 1;
+        }
+        /* enable flow control */
+        uart->CONbits.FCE = 1;
+    }
+    else {
+        /* disable flow control */
+        uart->CONbits.FCE = 0;
+        if (uart == UART1) {
+            /* CTS and RTS directions */
+            GPIO->PAD_DIR_RESET.U1CTS = 1;
+            GPIO->PAD_DIR_RESET.U1RTS = 1;
+            /* function select to GPIO */
+            GPIO->FUNC_SEL.U1CTS = 3;
+            GPIO->FUNC_SEL.U1RTS = 3;
+        }
+        else {
+            /* CTS and RTS directions */
+            GPIO->PAD_DIR_RESET.U2CTS = 1;
+            GPIO->PAD_DIR_RESET.U2RTS = 1;
+            /* function select to GPIO */
+            GPIO->FUNC_SEL.U2CTS = 3;
+            GPIO->FUNC_SEL.U2RTS = 3;
+        }
+    }
+}
+
+// TODO: clean from u*_(rx|tx)_(head|tail)
+void uart_init ( volatile struct UART_struct* uart, uint32_t baudrate ) {
+    /* enable the uart so we can set the gpio mode */
+    /* has to be enabled before setting the function with GPIO->FUNC_SEL */
+    uart->CONbits.TXE = 1;
+    uart->CONbits.RXE = 1;
+    
+    /* interrupt when this or more bytes are free in the tx buffer */
+    uart->TXCON = 16;
+    
+    if (uart == UART1) {
+        /* TX and RX direction */
+        GPIO->PAD_DIR_SET.U1TX = 1;
+        GPIO->PAD_DIR_RESET.U1RX = 1;
+        
+        /* set function selection to UART */
+        GPIO->FUNC_SEL.U1TX = 1;
+        GPIO->FUNC_SEL.U1RX = 1;
+        
+        UART1->CONbits.TXE = 1;                         /*< enable transmit */
+        UART1->CONbits.RXE = 1;                         /*< enable receive */
+#if UART1_RX_BUFFERSIZE > 32
+        UART1->RXCONbits.LVL = 30;                      /*< interrupt when fifo is nearly full */
+        //u1_rx_head = 0;
+        //u1_rx_tail = 0;
+#elif UART1_RX_BUFFERSIZE < 32
+        UART1->CONbits.FCE = 1;                         /*< enable flowcontrol */
+        UART1->CONbits.MRXR = 1;                        /*< disable Rx interrupt */
+        UART1->CTSbits.LVL = UART1_RX_BUFFERSIZE;       /*< drop cts when tx buffer at trigger level */
+        GPIO->FUNC_SEL1.U1CTS = 1;                      /*< set GPIO 16 to UART1 CTS */
+        GPIO->FUNC_SEL1.U1RTS = 1;                      /*< set GPIO 17 to UART1 RTS */
+#else
+        UART1->CONbits.MRXR = 1;                        /*< disable rx interrupt */
+#endif
+        
+        //u1_tx_head = 0;
+        //u1_tx_tail = 0;
+        
+        //enable_irq(UART1);
+        ITC->INTENABLEbits.UART1 = 1;
+    }
+    else {
+        /* UART2 */
+        /* TX and RX direction */
+        GPIO->PAD_DIR_SET.U2TX = 1;
+        GPIO->PAD_DIR_RESET.U2RX = 1;
+        
+        /* set function selection to UART */
+        GPIO->FUNC_SEL.U2TX = 1;
+        GPIO->FUNC_SEL.U2RX = 1;
+        
+        UART2->CONbits.TXE = 1;                         /*< enable transmit */
+        UART2->CONbits.RXE = 1;                         /*< enable receive */
+#if UART2_RX_BUFFERSIZE > 32
+        UART2->RXCONbits.LVL = 30;                      /*< interrupt when fifo is nearly full */
+        //u2_rx_head = 0;
+        //u2_rx_tail = 0;
+#elif UART2_RX_BUFFERSIZE < 32
+        UART2->CONbits.FCE = 1;                         /*< enable flowcontrol */
+        UART2->CONbits.MRXR = 1;                        /*< disable Rx interrupt */
+        UART2->CTSbits.LVL = UART2_RX_BUFFERSIZE;       /*< drop cts when tx buffer at trigger level */
+        GPIO->FUNC_SEL1.U1CTS = 1;                      /*< set GPIO 16 to UART2 CTS */
+        GPIO->FUNC_SEL1.U1RTS = 1;                      /*< set GPIO 17 to UART2 RTS */
+#else
+        UART2->CONbits.MRXR = 1;                        /*< disable rx interrupt */
+#endif
+        
+       // u2_tx_head = 0;
+        //u2_tx_tail = 0;
+        
+        //enable_irq(UART2);
+        ITC->INTENABLEbits.UART2 = 1;
+    }
+    
+    uart_set_baudrate( uart, baudrate );
+}
+
+static inline uint32_t uart0_puts ( uint8_t *astring, uint32_t length ) {
+    uint32_t i = 0;
+    for (; i<length; i++) {
+        uart1_putc( astring[i] );
+    }
+    
+    return i;
+}
+
+void stdio_flush(void)
+{
+    ITC->INTENABLEbits.UART1 = 0;
+    ITC->INTENABLEbits.UART2 = 0;
+    
+    ITC->INTENABLEbits.UART1 = 1;
+    ITC->INTENABLEbits.UART2 = 1;
+    /** taken from msba2-uart0.c
+    U0IER &= ~BIT1;                             // disable THRE interrupt
+    while(running) {
+        while(!(U0LSR & (BIT5|BIT6))){};        // transmit fifo
+        fifo=0;
+        push_queue();                           // dequeue to fifo
+    }
+    U0IER |= BIT1;                              // enable THRE interrupt
+    */
+}
+
+
+int fw_puts(char *astring,int length)
+{
+    return uart0_puts ( (uint8_t*) astring, (uint32_t) length );
+}
+
+int bl_uart_init(void) {
+    uart_init( UART1, BAUTRATE_UART1 );
+    uart_init( UART2, BAUTRATE_UART2 );
+}
\ No newline at end of file
diff --git a/redbee-econotag/drivers/redbee_uart1.c b/redbee-econotag/drivers/redbee_uart1.c
index 046ed26ab16a5fb38278271fc944caef297e7ef0..a4a53afc4015565c68a013d45f70cad72ec3da65 100644
--- a/redbee-econotag/drivers/redbee_uart1.c
+++ b/redbee-econotag/drivers/redbee_uart1.c
@@ -1,6 +1,7 @@
 /*
- * redbee_uart1.c - UART1 driver for redbee
+ * uart1.c - UART1 driver for redbee
  * Copyright (C) 2013 Oliver Hahm <oliver.hahm@inria.fr>
+ *               2013 Thomas Eichinger <thomas.eichinger@fu-berlin.de>
  *
  * This source code is licensed under the GNU General Public License,
  * Version 3.  See the file LICENSE for more details.
@@ -9,35 +10,39 @@
  */
 
 #include "mc1322x.h"
+#include "board_uart0.h"
+#include "uart.h"
 
-static volatile unsigned int running = 0;
-static volatile unsigned int fifo = 0;
-
-static inline int uart0_puts(char *astring, int length)
-{
-    int i;
-    for (i=0;i<length;i++) {
-        /* TODO: Fix me */
-        while(UART1->TXCON != 0);
-        UART1->DATA = astring[i];
+void uart1_isr ( void ) {
+    if ( UART1->USTATbits.RXRDY == 1 ) {
+#ifdef MODULE_UART0
+        if ( uart0_handler_pid ) {
+            while ( UART1->RXCON != 0 ) {
+                uart0_handle_incoming( UART1->DATA );
+                if ( ++i >= UART0_BUFSIZE ) {
+                    uart0_notify_thread();
+                    i = 0;
+                }
+            }
+            uart0_notify_thread();
+        }
+#endif
     }
-    return length;
 }
 
-int fw_puts(char *astring, int length)
-{
-    return uart0_puts(astring, length);
+void uart1_putc ( uint8_t c ) {
+    /* while uart fifo is full */
+    while ( UART1->TXCON == 0 ) {
+        /* wait */
+    }
+    UART1->DATA = c;
 }
 
-void stdio_flush(void)
-{
-    /* disable TX interrupt */
-    UART1->CONbits.MTXR = 1;
-    while(running) {
-        while(UART1->TXCON != 0);
-        fifo=0;
-        push_queue();                           // dequeue to fifo
+uint8_t uart1_getc ( void ) {
+    /* while uart fifo is empty */
+    while ( UART1->RXCON == 0 ) {
+        /* wait */
     }
-    /* enable TX interrupt */
-    UART1->CONbits.MTXR = 0;
-}
+    
+    return UART1->DATA;
+}
\ No newline at end of file
diff --git a/redbee-econotag/drivers/redbee_uart2.c b/redbee-econotag/drivers/redbee_uart2.c
new file mode 100644
index 0000000000000000000000000000000000000000..a1b2e6bab9a0e399554d74897f24cb35985fd6cd
--- /dev/null
+++ b/redbee-econotag/drivers/redbee_uart2.c
@@ -0,0 +1,48 @@
+/*
+ * uart1.c - UART1 driver for redbee
+ * Copyright (C) 2013 Oliver Hahm <oliver.hahm@inria.fr>
+ *               2013 Thomas Eichinger <thomas.eichinger@fu-berlin.de>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 3.  See the file LICENSE for more details.
+ *
+ * This file is part of RIOT.
+ */
+
+#include "mc1322x.h"
+#include "board_uart0.h"
+#include "uart.h"
+
+void uart2_isr ( void ) {
+    int i = 0;
+    if ( UART2->USTATbits.RXRDY == 1 ) {
+#ifdef MODULE_UART0
+        if ( uart0_handler_pid ) {
+            while ( UART2->RXCON != 0 ) {
+                uart0_handle_incoming( UART2->DATA );
+                if ( ++i >= UART0_BUFSIZE ) {
+                    uart0_notify_thread();
+                    i = 0;
+                }
+            }
+            uart0_notify_thread();
+        }
+#endif
+    }
+}
+
+void uart2_putc ( uint8_t c ) {
+    /* while uart fifo is full */
+    while ( UART2->TXCON == 0 ) {
+        /* wait */
+    }
+    UART2->DATA = c;
+}
+
+uint8_t uart2_getc ( void ) {
+    /* while uart fifo is empty */
+    while ( UART2->RXCON == 0 ) {
+        /* wait */
+    }
+    return UART2->DATA;
+}
\ No newline at end of file
diff --git a/redbee-econotag/tools/ftditools/Makefile b/redbee-econotag/tools/ftditools/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..521d7d14ff292bdadb245ce797f70ca696843a97
--- /dev/null
+++ b/redbee-econotag/tools/ftditools/Makefile
@@ -0,0 +1,17 @@
+INSTALL= /usr/local/bin
+
+################
+
+LDLIBS = -lftdi
+
+TARGETS = bbmc
+
+CFLAGS = -Wall -Wextra #-Werror
+
+all: $(TARGETS)
+
+clean:
+	-rm -f $(TARGETS)
+
+install: all
+	cp bbmc $(INSTALL)
\ No newline at end of file
diff --git a/redbee-econotag/tools/ftditools/bbmc.c b/redbee-econotag/tools/ftditools/bbmc.c
new file mode 100644
index 0000000000000000000000000000000000000000..7e2b6544129e40a208bdfcc4a2c01ff0e9832866
--- /dev/null
+++ b/redbee-econotag/tools/ftditools/bbmc.c
@@ -0,0 +1,531 @@
+/*
+ * Copyright (c) 2010, Mariano Alvira <mar@devl.org> and other contributors
+ * to the MC1322x project (http://mc1322x.devl.org)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of libmc1322x: see http://mc1322x.devl.org
+ * for details. 
+ *
+ *
+ */
+
+/* control reset and VREF2 lines */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <getopt.h>
+#include <ftdi.h>
+
+#define DEBUG 0
+
+#define low(x)  (1 << x)
+#define high(x) (1 << (x + 8))
+
+#define REDBEE_ECONOTAG_RESET    high(2)
+#define REDBEE_ECONOTAG_VREF2L   high(7)
+#define REDBEE_ECONOTAG_VREF2H   high(6) 
+#define REDBEE_ECONOTAG_INTERFACE INTERFACE_A
+
+#define REDBEE_USB_RESET    high(2)
+#define REDBEE_USB_VREF2L   low(5)
+#define REDBEE_USB_VREF2H   low(6)
+#define REDBEE_USB_INTERFACE INTERFACE_B
+
+#define FLEXIBITY_USB_RESET    high(2)
+#define FLEXIBITY_USB_VREF2L   high(7)
+#define FLEXIBITY_USB_VREF2H   high(6)
+#define FLEXIBITY_USB_INTERFACE INTERFACE_A
+
+#define BOARD REDBEE_USB
+
+#define STR(x)         #x
+#define STR2(x)        STR(x)
+#define CAT(x,y)       x##y
+#define CAT2(x, y, z)  x##y##z
+
+#define dir(x)            ( CAT(x,_RESET) | CAT(x,_VREF2L) | CAT(x,_VREF2H))
+#define interface(x)      ( CAT(x,_INTERFACE) )
+#define reset_release(x)  ( CAT(x,_RESET)     )
+#define reset_set(x)      ( 0 )
+#define vref2_normal(x)   ( CAT(x,_VREF2H)    )
+#define vref2_erase(x)    ( CAT(x,_VREF2L)    )
+
+/* fgets input buffer length: for prompts and such */
+#define BUF_LEN 32
+
+struct layout {
+	char *name;
+	char *desc;
+	enum ftdi_interface interface;
+	uint16_t dir;
+	uint16_t reset_release;
+	uint16_t reset_set;
+	uint16_t vref2_normal;
+	uint16_t vref2_erase;
+};
+
+int print_and_prompt( struct ftdi_device_list *devlist );
+int bb_mpsee(struct ftdi_context *ftdic, uint16_t dir, uint16_t val); 
+void reset(struct ftdi_context *ftdic, const struct layout * l);
+void erase(struct ftdi_context *ftdic, const struct layout * l);
+void usage(void);
+
+#define std_layout(x)                        \
+	.interface = interface(x),           \
+        .dir = dir(x),	                     \
+	.reset_release = reset_release(x),   \
+	.reset_set = reset_set(x),	     \
+	.vref2_normal = vref2_normal(x),     \
+	.vref2_erase = vref2_erase(x),     
+	
+static struct layout layouts[] =
+{
+	{ .name = "redbee-econotag",
+	  .desc = "Redbee Econotag",
+	  std_layout(REDBEE_ECONOTAG)
+	},
+	{ .name = "redbee-usb",
+	  .desc = "Redbee USB stick",
+	  std_layout(REDBEE_USB)
+	},
+	{ .name = "flexibity",
+	  .desc = "Flexibity USB Interface",
+	  std_layout(FLEXIBITY_USB)
+	},
+	{ .name = NULL, /* end of table */ },
+};		
+
+struct command {
+	char *name;
+	char *desc;
+	void (*cmd)(struct ftdi_context *ftdic, const struct layout * l);
+};
+	
+static const struct command commands[] =
+{
+	{
+		.name = "reset",
+		.desc = "Toggles reset pin",
+		.cmd = reset,
+	},
+	{
+		.name = "erase",
+		.desc = "Sets VREF2 erase mode; toggles reset; waits 2 sec.; sets normal; toggles reset again",
+		.cmd = erase,
+	},
+	{ .name = NULL, /* end of table */ },
+}; 
+
+struct layout * find_layout(char * str) 
+{
+	uint32_t i = 0;
+	
+	while(layouts[i].name != NULL) {
+		if(strcmp(layouts[i].name, str) == 0) { return &layouts[i]; }
+		i++;
+	}
+
+	return NULL;
+}
+
+static uint32_t vendid = 0x0403; uint32_t prodid = 0x6010;
+
+#if __APPLE__
+static void restore_ftdi_kext(void)
+{
+	system("sudo kextload /System/Library/Extensions/FTDIUSBSerialDriver.kext");
+}
+#endif
+
+int main(int argc, char **argv) 
+{
+	struct ftdi_context ftdic;
+	struct ftdi_device_list *devlist;
+	int dev_index = -1; int num_devs;
+	char layout_str[BUF_LEN];
+	struct layout layout;
+	struct layout *l = NULL;
+	int i, ret;
+
+	/* overrides for layout parameters */
+	int interface      = -1;
+	int dir            = -1;
+	int reset_release  = -1;
+	int reset_set      = -1;
+	int vref2_normal   = -1;
+	int vref2_erase    = -1;
+
+	layout.name = NULL;
+
+	while (1) {
+		int c;
+		int option_index = 0;
+		static struct option long_options[] = {
+			{"layout",        required_argument, 0, 'l'},
+			{"index",         required_argument, 0, 'i'},
+			{"vendor",        required_argument, 0, 'v'},
+			{"product",       required_argument, 0, 'p'},
+			{"dir",           required_argument, 0,  0 },
+			{"reset_release", required_argument, 0,  0 },
+			{"reset_set",     required_argument, 0,  0 },
+			{"vref2_normal",  required_argument, 0,  0 },
+			{"vref2_erase",   required_argument, 0,  0 },
+			{"interface",     required_argument, 0,  0 },
+			{"help",          no_argument,       0, '?'},
+			{0, 0, 0, 0}
+		};
+	
+		c = getopt_long (argc, argv, "i:l:v:p:",
+				 long_options, &option_index);
+		if (c == -1)
+			break;
+		
+		switch (c) {
+			/* process long opts */
+		case 0:
+			if(strcmp(long_options[option_index].name, "interface") == 0) {
+				sscanf(optarg, "%i", &interface);
+			} 
+			if(strcmp(long_options[option_index].name, "dir") == 0) {
+				sscanf(optarg, "%i", &dir);
+			} 
+			if (strcmp(long_options[option_index].name, "reset_release") == 0) {
+				sscanf(optarg, "%i", &reset_release);
+			}
+			if (strcmp(long_options[option_index].name, "reset_set") == 0) {
+				sscanf(optarg, "%i", &reset_set);
+			}
+			if (strcmp(long_options[option_index].name, "vref2_normal") == 0) {
+				sscanf(optarg, "%i", &vref2_normal);
+			}
+			if (strcmp(long_options[option_index].name, "vref2_erase") == 0) {
+				sscanf(optarg, "%i", &vref2_erase);
+			}
+			break;
+			
+		case 'l':
+			strncpy(layout_str, optarg, BUF_LEN);
+			break;
+		case 'i':
+			dev_index = atoi(optarg);
+			break;
+		case 'v':
+			sscanf(optarg, "%i", &vendid);
+			break;
+		case 'p':
+			sscanf(optarg, "%i", &prodid);
+			break;
+		default:
+			usage();
+			break;
+		}    
+	}
+	
+	if( !(l = find_layout(layout_str)) &&
+	    !((interface >= 0) &&
+	      (dir >= 0) &&
+	      (reset_release >= 0) &&
+	      (reset_set >= 0) &&
+	      (vref2_normal >= 0) &&
+	      (vref2_erase >= 0))
+		) {
+		
+		printf("*** You must specify a layout or a complete set of overrides\n");
+		return EXIT_FAILURE;
+	}
+	
+	if(l) {
+		memcpy(&layout, l, sizeof(struct layout));
+	} 
+
+#define override(x) if(x > 0) { layout.x = x; }
+	override(interface);
+	override(dir);
+	override(reset_release); override(reset_set);
+	override(vref2_normal); override(vref2_erase);
+	
+	if ((num_devs = ftdi_usb_find_all(&ftdic, &devlist, vendid, prodid)) < 0)
+	{
+		fprintf(stderr, "ftdi_usb_find_all failed: %d (%s)\n", 
+			num_devs, 
+			ftdi_get_error_string(&ftdic));
+		return EXIT_FAILURE;
+	} 
+	
+	if (ftdi_init(&ftdic) < 0)
+	{
+		fprintf(stderr, "ftdi_init failed\n");
+		return EXIT_FAILURE;
+	}
+
+	if ((ret = ftdi_set_interface(&ftdic, layout.interface)) < 0) {
+		fprintf(stderr, "couldn't set interface %d, err %d (%s)\n", layout.interface, ret, ftdi_get_error_string(&ftdic));
+		return EXIT_FAILURE;
+	}
+
+	printf("Found %d devices with vendor id 0x%04x product id 0x%04x\n", 
+	       num_devs, vendid, prodid);
+	
+	if(num_devs == 0) { return EXIT_SUCCESS; }
+
+	if(num_devs == 1) { dev_index = 0; }
+	while( (dev_index < 0) || (dev_index >= num_devs)){
+		dev_index = print_and_prompt(devlist);
+	}
+	
+	if(layout.name != NULL) {
+		printf("Opening device %d interface %d using layout %s\n", 
+		       dev_index, layout.interface, layout.name);
+	} else {
+		printf("Opening device %d interface %d without a layout.\n", 
+		       dev_index, layout.interface);
+	}
+
+	if( (ret = ftdi_usb_open_desc_index(
+		     &ftdic,
+		     vendid,
+		     prodid,
+		     NULL,
+		     NULL,
+		     dev_index)) < 0) {
+#if __APPLE__
+		if((ret==-5) && (0==system("sudo kextunload /System/Library/Extensions/FTDIUSBSerialDriver.kext"))) {
+			// Try again without the FTDI kext loaded this time
+			atexit(&restore_ftdi_kext);
+			ret = ftdi_usb_open_desc_index(
+				&ftdic,
+				vendid,
+				prodid,
+				NULL,
+				NULL,
+				dev_index
+			);
+		}
+		if(ret)
+#endif // __APPLE__
+		{
+			fprintf(stderr, "couldn't open dev_index %d, err %d (%s)\n", dev_index, ret, ftdi_get_error_string(&ftdic));
+			return EXIT_FAILURE;
+		}
+	}
+
+	
+	for(i = 0; commands[i].name != NULL; i++) {	       
+		if( (argv[optind] != NULL) &&
+		    (strcmp(commands[i].name, argv[optind]) == 0)) { break; }
+	}
+	if(commands[i].name != NULL) {
+		commands[i].cmd(&ftdic, &layout);
+	} else {
+		printf("invalid command\n");
+
+		ftdi_list_free(&devlist);
+		ftdi_deinit(&ftdic);
+
+		return EXIT_FAILURE;
+	}
+
+	printf("done.\n");
+	
+	ftdi_list_free(&devlist);
+	ftdi_deinit(&ftdic);
+	
+	return EXIT_SUCCESS;
+}
+
+void usage(void) 
+{
+	int i;
+	printf(    "Usage: bbmc [options|overrides] -l|--layout layout command \n");
+	printf(    "Commands:\n");
+	for(i = 0; commands[i].name != NULL; i++) {
+		printf(    "           %s: %s\n", commands[i].name, commands[i].desc);
+	}
+	printf("\n");
+	printf(    "Required options:\n");
+	printf(    "           -l|--layout\t specifiy which board layout to use\n");
+	printf(    "                      \t layout is not necessary with a full\n");
+	printf(    "                      \t set of overrides\n");
+	printf(  "\nLayout overrides:\n");
+	printf(    "           --interface\t\t FTDI interface to use\n");
+	printf(    "           --dir\t\t direction (1 is output)\n");
+	printf(    "           --reset_release\t reset release command\n");
+	printf(    "           --reset_set\t\t reset set command\n");
+	printf(    "           --vref2_normal\t vref2 normal\n");
+	printf(    "           --vref2_erase\t vref2 erase\n");
+	printf("\n");
+	printf(    "Layouts:\n");
+	for(i = 0; layouts[i].name != NULL; i++) {
+		printf(    "\t%s: %s\n", layouts[i].name, layouts[i].desc);
+		printf("\n");
+		printf(    "\t\tinterface: \t0x%04x\n", layouts[i].interface);
+		printf(    "\t\tdir: \t\t0x%04x\n", layouts[i].dir);
+		printf(    "\t\treset release: \t0x%04x\n", layouts[i].reset_release);
+		printf(    "\t\treset hold:    \t0x%04x\n", layouts[i].reset_set);
+		printf(    "\t\tvref2 normal:  \t0x%04x\n", layouts[i].vref2_normal);
+		printf(    "\t\tvref2 erase:   \t0x%04x\n", layouts[i].vref2_erase);
+		printf("\n");
+	}
+	printf("\n");
+	printf(    "Options:\n");
+	printf(    "           -i|--index     specifiy which device to use (default 0)\n");
+	printf(    "           -v|--vendor    set vendor id (default 0x0403)\n");
+	printf(    "           -p|--product   set vendor id (default 0x6010)\n");
+}
+
+int print_and_prompt( struct ftdi_device_list *devlist ) 
+{
+	int i, ret;
+	struct ftdi_context ftdic;
+	struct ftdi_device_list *curdev;
+	char manufacturer[128], description[128], serial[128];
+	char input[BUF_LEN]; char *s;
+	int sel = -1;
+
+	printf("\n");
+
+	i = 0;
+	for (curdev = devlist; curdev != NULL; i++)
+	{
+		printf("  [%d]   ", i);
+		if (0 > (ret = ftdi_usb_get_strings(&ftdic, 
+						    curdev->dev, 
+						    manufacturer, 128, 
+						    description, 128, 
+						    serial, 128)))
+		{
+			fprintf(stderr, "ftdi_usb_get_strings failed: %d (%s)\n", 
+				ret, ftdi_get_error_string(&ftdic));
+			return EXIT_FAILURE;
+		}
+		printf("Manufacturer: %s, Description: %s, Serial %s\n", 
+		       manufacturer, description, serial);
+		curdev = curdev->next;
+	}
+
+	printf("\nUse which device? ");
+
+	s = fgets(input, BUF_LEN, stdin);
+	if (s != NULL) {
+		size_t last = strlen (input) - 1;		
+		if (input[last] == '\n') input[last] = '\0';
+	}
+
+	sscanf(s, "%i",&sel);
+
+	return sel;
+}
+
+void reset(struct ftdi_context *ftdic, const struct layout * l) 
+{
+	
+        /* using MPSSE since it give access to high GPIO*/
+	/* set as inputs for now */
+	ftdi_set_bitmode(ftdic, 0 , BITMODE_MPSSE); 
+
+	printf("toggle reset\n");
+
+	bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_normal));
+	bb_mpsee(ftdic, l->dir, (l->reset_set     | l->vref2_normal));
+	bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_normal));
+
+	return;
+
+}
+
+
+void erase(struct ftdi_context *ftdic, const struct layout * l) 
+{
+	printf("setting VREF2 erase\n");
+	
+        /* using MPSSE since it give access to high GPIO*/
+	/* set as inputs for now */
+	ftdi_set_bitmode(ftdic, 0 , BITMODE_MPSSE); 
+
+	bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_normal));
+	bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_erase));
+	
+	printf("toggle reset\n");
+	
+	bb_mpsee(ftdic, l->dir, (l->reset_set     | l->vref2_erase));
+	bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_erase));
+
+	printf("waiting for erase\n");
+
+	sleep(2);
+
+	printf("setting VREF2 normal\n");
+	
+	bb_mpsee(ftdic, l->dir, (l->reset_release | l->vref2_normal));
+
+	reset(ftdic, l);
+
+	return;
+
+}
+
+
+int bb_mpsee(struct ftdi_context *ftdic, uint16_t dir, uint16_t val) 
+{
+	uint8_t buf[3];
+	int ret;
+
+	/* command "set data bits low byte" */
+	buf[0] = 0x80;
+	buf[1] = (val & 0xff);
+	buf[2] = dir & 0xff;
+#if DEBUG
+	fprintf(stderr,"write %x %x %x\n",buf[0],buf[1],buf[2]);
+#endif
+
+	if ((ret = (ftdi_write_data(ftdic, buf, 3))) < 0)
+	{
+		perror("ft2232_write error");
+		fprintf(stderr, "ft2232_write command %x\n", buf[0]);
+		return EXIT_FAILURE;
+	}
+
+
+	/* command "set data bits high byte" */
+	buf[0] = 0x82;         
+	buf[1] = (val >> 8);
+	buf[2] = dir >> 8;
+#if DEBUG
+	fprintf(stderr,"write %x %x %x\n",buf[0],buf[1],buf[2]);
+#endif
+
+	if ((ret = (ftdi_write_data(ftdic, buf, 3))) < 0)
+	{
+		perror("ft2232_write error");
+		fprintf(stderr, "ft2232_write command %x\n", buf[0]);
+		return EXIT_FAILURE;
+	}
+
+	return 0;
+
+}
diff --git a/redbee-econotag/tools/mc1322x-load.c b/redbee-econotag/tools/mc1322x-load.c
new file mode 100644
index 0000000000000000000000000000000000000000..d63df238022b26c8dab3b42b5e61db0f5d64d67c
--- /dev/null
+++ b/redbee-econotag/tools/mc1322x-load.c
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 2012, Maxim Osipov <maxim.osipov@gmail.com>
+ * Copyright (c) 2010, Mariano Alvira <mar@devl.org> and other contributors
+ * to the MC1322x project (http://mc1322x.devl.org)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <termios.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdint.h>
+
+
+char* filename;
+char* second;
+char* term = "/dev/ttyUSB0";
+int baud = B115200;
+int verbose = 0;
+char* rts = "rts";
+char* command;
+int first_delay = 50;
+int second_delay = 100;
+int do_exit = 0;
+int zerolen = 0;
+char *args = NULL;
+
+struct stat sbuf;
+struct termios options;
+char buf[256];
+int pfd;
+int ffd;
+int sfd;
+
+void help(void);
+
+int main(int argc, char **argv)
+{
+  int c = 0;
+  int r = 0;
+  int i = 0;
+  uint32_t s = 0;
+  opterr = 0;
+
+  /* Parse options */
+  while ((c = getopt(argc, argv, "f:s:zt:vu:r:c:a:b:eh")) != -1) {
+    switch (c)
+    {
+      case 'f':
+        filename = optarg;
+        break;
+      case 's':
+        second = optarg;
+        break;
+      case 'z':
+        zerolen = 1;
+        break;
+      case 't':
+        term = optarg;
+        break;
+      case 'v':
+        verbose = 1;
+        break;
+      case 'u':
+        if (strcmp(optarg, "115200")) {
+          baud = B115200;
+        } else if (strcmp(optarg, "57600")) {
+          baud = B115200;
+        } else if (strcmp(optarg, "19200")) {
+          baud = B19200;
+        } else if (strcmp(optarg, "9600")) {
+          baud = B9600;
+        } else {
+          printf("Unknown baud rate %s!\n", optarg);
+          return -1;
+        }
+        break;
+      case 'r':
+        rts = optarg;
+        break;
+      case 'c':
+        command = optarg;
+        break;
+      case 'a':
+        first_delay = atoi(optarg);
+        break;
+      case 'b':
+        second_delay = atoi(optarg);
+        break;
+      case 'e':
+        do_exit = 1;
+        break;
+      case 'h':
+      case '?':
+        help();
+        return 0;
+      default:
+        abort();
+    }
+  }
+  /* Get other arguments */
+  if (optind < argc)
+	args = argv[optind];
+
+  /* Print settings */
+  if (verbose) {
+    printf("Primary file (RAM): %s\n", filename);
+    printf("Secondary file (Flash): %s\n", second);
+    printf("Zero secondary file: %s\n", zerolen == 1 ? "Yes" : "No");
+    printf("Port: %s\n", term);
+    printf("Baud rate: %i\n", baud);
+    printf("Flow control: %s\n", rts);
+    printf("Reset command: %s\n", command);
+    printf("Exit after load: %s\n", do_exit == 1 ? "Yes" : "No");
+    printf("Delay 1: %i\n", first_delay);
+    printf("Delay 2: %i\n", second_delay);
+  }
+
+  /* Open and configure serial port */
+  pfd = open(term, O_RDWR | O_NOCTTY | O_NDELAY);
+  if (pfd == -1) {
+    printf("Cannot open serial port %s!\n", term);
+    return -1;
+  }
+  fcntl(pfd, F_SETFL, FNDELAY);
+  tcgetattr(pfd, &options);
+  cfsetispeed(&options, baud);
+  options.c_cflag |= (CLOCAL | CREAD);
+  options.c_cflag &= ~PARENB;
+  options.c_cflag &= ~CSTOPB;
+  options.c_cflag &= ~CSIZE;
+  options.c_cflag |= CS8;
+  if (strcmp(rts, "rts")) {
+    options.c_cflag &= ~CRTSCTS;
+  } else {
+    options.c_cflag |= CRTSCTS;
+  }
+  options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
+  options.c_oflag &= ~OPOST;
+  tcsetattr(pfd, TCSANOW, &options);
+
+  /* Reset the board if we can */
+  printf("Reset the board to enter bootloader (waiting for CONNECT)...\n");
+  if (command) {
+    printf("Performing reset: %s\n", command);
+    system(command);
+  }
+
+  /* Primary bootloader wait loop */
+  i = 0;
+  while (1) {
+    /* Wait for CONNECT */
+    r = write(pfd, (const void*)"\0", 1);
+    sleep(1);
+    r = read(pfd, &buf[i], sizeof(buf)-1-i);
+    if (r > 0) {
+      buf[i+r] = '\0';
+      printf("%s", &buf[i]); fflush(stdout);
+      if (strstr(&buf[i], "CONNECT")) {
+        printf("\n");
+        break;
+      }
+      i += r;
+      if (i >= sizeof(buf)-1) {
+        i = 0;
+      }
+    } else {
+      printf("."); fflush(stdout);
+    }
+  }
+
+  /* Send primary file */
+  if (!filename) {
+    printf("Please specify firmware file name (-f option)!\n");
+    return -1;
+  }
+  if (stat(filename, &sbuf)) {
+    printf("Cannot open firmware file %s!\n", filename);
+    return -1;
+  }
+  ffd = open(filename, O_RDONLY);
+  if (ffd == -1) {
+    printf("Cannot open firmware file %s!\n", filename);
+    return -1;
+  }
+  s = sbuf.st_size;
+  printf("Sending %s (%i bytes)...\n", filename, s);
+  r = write(pfd, (const void*)&s, 4);
+  i = 0;
+  r = read(ffd, buf, 1);
+  while (r > 0) {
+    do {
+      usleep(first_delay);
+      c = write(pfd, (const void*)buf, r);
+    } while(c < r);
+    i += r;
+    printf("Written %i\r", i); fflush(stdout);
+    r = read(ffd, buf, 1);
+  }
+  printf("\n");
+
+  /* Secondary loader wait loop */
+  if (second || zerolen) {
+    /* Wait for ready */
+    printf("Sending secondary file (waiting for ready)...\n");
+    i = 0;
+    while (1) {
+      sleep(1);
+      r = read(pfd, &buf[i], sizeof(buf)-1-i);
+      if (r > 0) {
+        buf[i+r] = '\0';
+        printf("%s", &buf[i]); fflush(stdout);
+        if (strstr(buf, "ready")) {
+          printf("\n");
+          break;
+        }
+        i += r;
+        if (i >= sizeof(buf)-1) {
+          i = 0;
+        }
+      } else {
+        printf("."); fflush(stdout);
+      }
+    }
+
+    /* Send secondary file */
+    if (second) {
+      if (stat(second, &sbuf)) {
+        printf("Cannot open secondary file %s!\n", second);
+        return -1;
+      }
+      sfd = open(second, O_RDONLY);
+      if (sfd == -1) {
+        printf("Cannot open secondary file %s!\n", second);
+        return -1;
+      }
+      s = sbuf.st_size;
+      printf("Sending %s (%i bytes)...\n", second, s);
+      r = write(pfd, (const void*)&s, 4);
+      i = 0;
+      r = read(sfd, buf, 1);
+      while (r > 0) {
+        do {
+          usleep(second_delay);
+          c = write(pfd, (const void*)buf, r);
+        } while(c < r);
+        i += r;
+        printf("Written %i\r", i); fflush(stdout);
+        r = read(sfd, buf, 1);
+      }
+      printf("\n");
+    } else if (zerolen) {
+      s = 0;
+      printf("Sending %i...\n", s);
+      write(pfd, (const void*)&s, 4);
+    }
+  }
+
+  /* Send the remaining arguments */
+  if (args) {
+    printf("Sending %s\n", args);
+    r = write(pfd, (const void*)args, strlen(args));
+    r = write(pfd, (const void*)",", 1);
+  }
+
+  /* Drop in echo mode */
+  if (!do_exit) {
+    while (1) {
+      r = read(pfd, buf, sizeof(buf));
+      if (r > 0) {
+        buf[r] = '\0';
+        printf("%s", buf); fflush(stdout);
+      }
+    }
+  }
+}
+
+
+void help(void)
+{
+  printf("Example usage: mc1322x-load -f foo.bin -t /dev/ttyS0 -b 9600\n");
+  printf("          or : mc1322x-load -f flasher.bin -s flashme.bin  0x1e000,0x11223344,0x55667788\n");
+  printf("          or : mc1322x-load -f flasher.bin -z  0x1e000,0x11223344,0x55667788\n");
+  printf("       -f required: binary file to load\n");
+  printf("       -s optional: secondary binary file to send\n");
+  printf("       -z optional: send a zero length file as secondary\n");
+  printf("       -t, terminal default: /dev/ttyUSB0\n");
+  printf("       -u, baud rate default: 115200\n");
+  printf("       -r [none|rts] flow control default: rts\n");
+  printf("       -c command to run for autoreset: \n");
+  printf("              e.g. -c 'bbmc -l redbee-econotag -i 0 reset'\n");
+  printf("       -e exit instead of dropping to terminal display\n");
+  printf("       -a first  intercharacter delay, passed to usleep\n");
+  printf("       -b second intercharacter delay, passed to usleep\n");
+  printf("\n");
+  printf("Anything on the command line is sent after all of the files.\n\n");
+}
diff --git a/redbee-econotag/tools/mc1322x-load.pl b/redbee-econotag/tools/mc1322x-load.pl
new file mode 100755
index 0000000000000000000000000000000000000000..bfc1d1ffcdcfceb5a855e57de0017f04c42fd832
--- /dev/null
+++ b/redbee-econotag/tools/mc1322x-load.pl
@@ -0,0 +1,171 @@
+#!/usr/bin/perl -w
+
+use Device::SerialPort;
+use Term::ReadKey;
+use Getopt::Long;
+use Time::HiRes qw(usleep);
+
+use strict;
+
+my $filename = '';
+my $second = '';
+my $term = '/dev/ttyUSB0';
+my $baud = '115200';
+my $verbose;
+my $rts = 'rts';
+my $command = '';
+my $first_delay = 50;
+my $second_delay = 100;
+my $do_exit;
+my $zerolen;
+
+GetOptions ('file=s' => \$filename,
+	    'secondfile=s' => \$second,
+	    'zerolen' => \$zerolen,
+	    'terminal=s' => \$term, 
+	    'verbose' => \$verbose, 
+	    'u|baud=s' => \$baud,
+	    'rts=s' => \$rts,
+	    'command=s' => \$command,
+	    'a=s' => \$first_delay,
+	    'b=s' => \$second_delay,
+	    'exit' => \$do_exit,
+    ) or die 'bad options';
+
+$| = 1;
+
+if($filename eq '') {
+    print "Example usage: mc1322x-load.pl -f foo.bin -t /dev/ttyS0 -b 9600\n";
+    print "          or : mc1322x-load.pl -f flasher.bin -s flashme.bin  0x1e000,0x11223344,0x55667788\n";
+    print "          or : mc1322x-load.pl -f flasher.bin -z  0x1e000,0x11223344,0x55667788\n";
+    print "       -f required: binary file to load\n";
+    print "       -s optional: secondary binary file to send\n";
+    print "       -z optional: send a zero length file as secondary\n";
+    print "       -t, terminal default: /dev/ttyUSB0\n";
+    print "       -u, --baud baud rate default: 115200\n";
+    print "       -r [none|rts] flow control default: rts\n";
+    print "       -c command to run for autoreset: \n";
+    print "              e.g. -c 'bbmc -l redbee-econotag -i 0 reset'\n";
+    print "       -e exit instead of dropping to terminal display\n";
+    print "       -a first  intercharacter delay, passed to usleep\n";
+    print "       -b second intercharacter delay, passed to usleep\n";
+    print "\n";
+    print "anything on the command line is sent\n";
+    print "after all of the files.\n\n";
+    exit;
+}
+
+if (!(-e $filename)) { die "file $filename not found\n"; }
+if (($second ne '') && !(-e $second)) { die "secondary file $second not found\n"; }
+
+my $ob = Device::SerialPort->new ($term) or die "Can't start $term\n";
+    # next test will die at runtime unless $ob
+
+$ob->baudrate($baud);
+$ob->parity('none');
+$ob->databits(8);
+$ob->stopbits(1);
+if($rts eq 'rts') {
+    $ob->handshake('rts');
+} else {
+    $ob->handshake('none');
+}
+$ob->read_const_time(1000); # 1 second per unfulfilled "read" call
+$ob->rts_active(1);
+
+my $s = 0;
+my $reset = 0;
+my $size = 0;
+
+while(1) { 
+    
+    my $c; my $count; my $ret = ''; my $test='';
+    
+    if($s == 1) { print "secondary send...\n"; }
+    
+    $ob->write(pack('C','0'));
+
+    if(($command ne '') &&
+       ($reset eq 0)) {
+	$reset++;
+	system($command);
+    }
+
+    if($s == 1) { 
+	$test = 'ready'; 
+    } else {
+	$test = 'CONNECT';
+    }
+    
+    until($ret =~ /$test$/) {
+	($count,$c) = $ob->read(1);
+	if ($count == 0) { 
+	    print '.';
+	    $ob->write(pack('C','0')); 
+	    next;
+	}
+	$ret .= $c;
+    }
+    print $ret . "\n";
+    
+    if (-e $filename || (defined($zerolen) && ($s == 1))) {
+	
+	if(defined($zerolen) && ($s == 1)) {
+	    $size = 0;
+	} else {
+	    $size = -s $filename;
+	}
+
+	print ("Size: $size bytes\n");
+	$ob->write(pack('V',$size));
+
+	if(($s == 0) ||
+	   ((!defined($zerolen)) && ($s == 1))) {
+	    open(FILE, $filename) or die($!);
+	    print "Sending $filename\n";
+	    
+	    my $i = 1;
+	    while(read(FILE, $c, 1)) {
+		$i++;
+                usleep($first_delay)  if ( $s == 0 ) && ($first_delay != 0);
+                usleep($second_delay) if ( $s == 1 ) && ($second_delay != 0);
+		$ob->write($c);
+	    }
+	}
+    }
+    
+    last if ($s==1);
+    if((-e $second) || defined($zerolen)) {
+	$s=1; $filename = $second;
+    } else {
+	last;
+    }
+
+} 
+
+print "done sending files.\n";
+
+if(scalar(@ARGV)!=0) {
+    print "sending " ;
+    print @ARGV;
+    print ",\n";
+
+    $ob->write(@ARGV);
+    $ob->write(',');
+}
+
+if(defined($do_exit)) {
+    exit;
+}
+
+my $c; my $count;
+while(1) {
+    ($count, $c) = $ob->read(1);
+    print $c if (defined($count) && ($count != 0));
+}
+
+$ob -> close or die "Close failed: $!\n";
+ReadMode 0;
+undef $ob;  # closes port AND frees memory in perl
+exit;
+