Fork of Smoothie to port to mbed non-LPC targets.

Dependencies:   mbed

Fork of Smoothie by Stéphane Cachat

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DFU.cpp Source File

DFU.cpp

00001 #include "DFU.h"
00002 
00003 // #include <LPC17xx.h>
00004 #include "lpc17xx_wdt.h"
00005 
00006 #include <stdio.h>
00007 #include <mri.h>
00008 #include <cstring>
00009 
00010 DFU::DFU(USB *u)
00011 {
00012     usb = u;
00013     dfu_descriptor = {
00014         DL_DFU_FUNCTIONAL_DESCRIPTOR,
00015         DT_DFU_FUNCTIONAL_DESCRIPTOR,
00016         DFU_BMATTRIBUTES_WILLDETACH | DFU_BMATTRIBUTES_CANDOWNLOAD | DFU_BMATTRIBUTES_CANUPLOAD,
00017         2000,               // wDetachTimeout
00018         512,                // wTransferSize
00019         DFU_VERSION_1_1,    // bcdDFUVersion
00020     };
00021     dfu_interface = {
00022         DL_INTERFACE,
00023         DT_INTERFACE,
00024         0,                          // bInterfaceNumber: filled out during addInterface()
00025         0,                          // bAlternateSetting
00026         0,                          // bNumEndpoints
00027         DFU_INTERFACE_CLASS,        // bInterfaceClass
00028         DFU_INTERFACE_SUBCLASS,     // bInterfaceSubClass
00029         DFU_INTERFACE_PROTOCOL_RUNTIME, // bInterfaceProtocol
00030         0,                          // iInterface
00031 
00032         0, 0, 0,                    // dummy padding
00033         this,                       // callback
00034     };
00035 
00036     usbdesc_string_l(13) s = usbstring("Smoothie DFU");
00037     memcpy(&dfu_string, &s, sizeof(dfu_string));
00038 
00039     usb->addInterface(&dfu_interface);
00040     usb->addDescriptor(&dfu_descriptor);
00041     dfu_interface.iInterface = usb->addString(&dfu_string);
00042 
00043     prep_for_detach = 0;
00044 }
00045 
00046 bool DFU::USBEvent_Request(CONTROL_TRANSFER &control)
00047 {
00048     printf("Got DFU Control Request: %d length %d\n", control.setup.bRequest, control.setup.wLength);
00049     switch (control.setup.bRequest)
00050     {
00051         case  DFU_DETACH:
00052         {
00053 //             usb->disconnect();
00054             prep_for_detach = 128;
00055             WDT_Init(WDT_CLKSRC_IRC, WDT_MODE_RESET);
00056             WDT_Start(250000); // 0.25 seconds
00057             //             for (;;);
00058             return true;
00059         }
00060         case DFU_GETSTATUS:
00061         {
00062 //             __debugbreak();
00063             dfu_status = {
00064                 0,      // status OK
00065                 500,    // bwPollTimeout
00066                 0,      // state appIdle
00067                 0       // iString
00068             };
00069             control.direction = DEVICE_TO_HOST;
00070             control.ptr = (uint8_t *) &dfu_status;
00071             control.remaining = sizeof(dfu_status);
00072             return true;
00073         }
00074         case DFU_CLRSTATUS:
00075         {
00076             return true;
00077         }
00078         case DFU_GETSTATE:
00079         {
00080             dfu_status.bState = 0; // appIdle
00081             control.direction = DEVICE_TO_HOST;
00082             control.ptr = (uint8_t *) &dfu_status.bState;
00083             control.remaining = 1;
00084             return true;
00085         }
00086         case DFU_ABORT:
00087         {
00088             return true;
00089         }
00090     }
00091     return false;
00092 }
00093 
00094 bool DFU::USBEvent_RequestComplete(CONTROL_TRANSFER &control, uint8_t *buf, uint32_t length)
00095 {
00096     return false;
00097 }
00098 
00099 void DFU::on_module_loaded()
00100 {
00101     register_for_event(ON_IDLE);
00102 }
00103 
00104 void DFU::on_idle(void* argument)
00105 {
00106     if (prep_for_detach)
00107     {
00108         prep_for_detach--;
00109         if (prep_for_detach == 0)
00110         {
00111             usb->disconnect();
00112             for (;;);
00113         }
00114     }
00115 }