diff --git a/bootloader/bootloader.c b/bootloader/bootloader.c
index e83f4d0f8defa7dc992159224e12acec520e2a94..0438949ecfbe70ef5fb7a1dbc2e2972c443fb2bf 100644
--- a/bootloader/bootloader.c
+++ b/bootloader/bootloader.c
@@ -66,7 +66,7 @@ bool test_banner_echo()
 		}
 	}
 
-	serial_end();
+	//serial_end();
 	return matched == bannerLength;
 }
 
@@ -75,9 +75,9 @@ int main()
 {
 	// Say hello!
 
-	if (test_banner_echo()) {
+//	if (test_banner_echo()) {
 		led_on();
-	}
+//	}
 
     usb_init();
 
diff --git a/bootloader/dfu.c b/bootloader/dfu.c
index 604e1b558be2c4032bfc749b96935536aa8bec7e..2b8b866e7cab90639fcdbf5f534bf455f145f095 100644
--- a/bootloader/dfu.c
+++ b/bootloader/dfu.c
@@ -24,27 +24,76 @@
 #include "usb_dev.h"
 #include "serial.h"
 
+typedef enum {
+	appIDLE = 0,
+	appDETACH,
+	dfuIDLE,
+	dfuDNLOAD_SYNC,
+	dfuDNBUSY,
+	dfuDNLOAD_IDLE,
+	dfuMANIFEST_SYNC,
+	dfuMANIFEST,
+	dfuMANIFEST_WAIT_RESET,
+	dfuUPLOAD_IDLE,
+	dfuERROR
+} dfu_state_t;
+
+typedef enum {
+	OK = 0,
+	errTARGET,
+	errFILE,
+	errWRITE,
+	errERASE,
+	errCHECK_ERASED,
+	errPROG,
+	errVERIFY,
+	errADDRESS,
+	errNOTDONE,
+	errFIRMWARE,
+	errVENDOR,
+	errUSBR,
+	errPOR,
+	errUNKNOWN,
+	errSTALLEDPKT,
+} dfu_status_t;
+
+
+static dfu_state_t dfu_state = dfuIDLE;
+static dfu_status_t dfu_status = OK;
+static unsigned dfu_poll_timeout = 1;
+
+
 void dfu_download(unsigned blockNum, unsigned length, const uint8_t *data)
 {
-
+	serial_phex32(blockNum);
+	serial_putchar(' ');
+	serial_phex32(length);
+	serial_putchar('\n');
 }
 
 void dfu_getstatus(uint8_t *status)
 {
-
+	status[0] = dfu_status;
+	status[1] = dfu_poll_timeout >> 16;
+	status[2] = dfu_poll_timeout >> 8;
+	status[3] = dfu_poll_timeout;
+	status[4] = dfu_state;
+	status[5] = 0;  // iString
 }
 
 void dfu_clrstatus()
 {
-
+	if (dfu_state == dfuERROR) {
+		dfu_state = dfuIDLE;
+	}
 }
 
 uint8_t dfu_getstate()
 {
-	return 0;
+	return dfu_state;
 }
 
 void dfu_abort()
 {
-	
+	dfu_state = dfuIDLE;
 }
diff --git a/bootloader/usb_desc.c b/bootloader/usb_desc.c
index aa29eb6b7c77294b3fb4169c12d066a0b5728892..1da953009add45ae7b9cba60db25f24a67edbfb3 100644
--- a/bootloader/usb_desc.c
+++ b/bootloader/usb_desc.c
@@ -107,7 +107,7 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = {
         0,                                      // bNumEndpoints
         DEVICE_CLASS,                           // bInterfaceClass
         DEVICE_SUBCLASS,                        // bInterfaceSubClass
-        0x00,                                   // bInterfaceProtocol
+        DFU_INTERFACE_PROTOCOL,                 // bInterfaceProtocol
         2,                                      // iInterface
 
         // DFU Functional Descriptor (DFU spec TAble 4.2)
diff --git a/bootloader/usb_desc.h b/bootloader/usb_desc.h
index 2d6d604f75273bd3d5ca3850f4cfd77cd1d941ff..e2e9d2ea9d99e0b0202a8aee67a37b5d77b66b80 100644
--- a/bootloader/usb_desc.h
+++ b/bootloader/usb_desc.h
@@ -47,6 +47,7 @@
 #define EP0_SIZE                  64
 #define NUM_INTERFACE             1
 #define DFU_INTERFACE             0
+#define DFU_INTERFACE_PROTOCOL	  0x02		// DFU Mode
 #define DFU_DETACH_TIMEOUT		  10000		// 10 second timer
 #define DFU_TRANSFER_SIZE		  1024		// Equal to flash erase block size
 #define CONFIG_DESC_SIZE          (9+9+7)
diff --git a/bootloader/usb_dev.c b/bootloader/usb_dev.c
index 9ea9a1c1992fdc660c09006b756e0bdb6b4cd2bc..c85681d114eed07834b430165c06f0a07100ae27 100644
--- a/bootloader/usb_dev.c
+++ b/bootloader/usb_dev.c
@@ -299,8 +299,6 @@ static void usb_control(uint32_t stat)
 
         // clear any leftover pending IN transactions
         ep0_tx_ptr = NULL;
-        if (ep0_tx_data_toggle) {
-        }
         table[index(0, TX, EVEN)].desc = 0;
         table[index(0, TX, ODD)].desc = 0;
 
@@ -309,9 +307,6 @@ static void usb_control(uint32_t stat)
 
         // actually "do" the setup request
         usb_setup();
-
-        // unfreeze the USB, now that we're ready
-        USB0_CTL = USB_CTL_USBENSOFEN; // clear TXSUSPENDTOKENBUSY bit
         break;
 
     case 0x01:  // OUT transaction received from host
@@ -319,7 +314,7 @@ static void usb_control(uint32_t stat)
 
         if (setup.wRequestAndType == 0x0141 && setup.wIndex == 0) {
             // DFU_DNLOAD
-            dfu_download(setup.wValue, setup.wLength, (uint8_t*) b->addr);
+            dfu_download(setup.wValue, setup.wLength, buf);
         }
 
         // give the buffer back