various DFU fixes
* make RET_* constants public as DFU_RET_* * support GET_DESCRIPTOR on the DFU interface descriptor * use static buffer for getstatus()
This commit is contained in:
parent
f04ca88a27
commit
b45eec0ed4
|
@ -25,6 +25,17 @@ struct USBStringDescriptor {
|
|||
|
||||
#ifdef BOARD_USB_DFU
|
||||
|
||||
#include <usb/common/dfu/usb_dfu.h>
|
||||
|
||||
/* for board-specific config */
|
||||
#include <board.h>
|
||||
|
||||
struct dfu_desc {
|
||||
USBConfigurationDescriptor ucfg;
|
||||
USBInterfaceDescriptor uif[BOARD_DFU_NUM_IF];
|
||||
struct usb_dfu_func_descriptor func_dfu;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* USB DFU functional descriptor */
|
||||
#define DFU_FUNC_DESC { \
|
||||
.bLength = USB_DT_DFU_SIZE, \
|
||||
|
@ -84,6 +95,9 @@ extern const struct USBStringDescriptor USBDFU_string3;
|
|||
(const unsigned char *) &USBDFU_string2, \
|
||||
(const unsigned char *) &USBDFU_string3,
|
||||
|
||||
const struct dfu_desc dfu_cfg_descriptor;
|
||||
const USBDDriverDescriptors dfu_descriptors;
|
||||
|
||||
#else /* BOARD_USB_DFU */
|
||||
|
||||
/* no DFU bootloader is being used */
|
||||
|
@ -115,4 +129,8 @@ void USBDFU_DFU_RequestHandler(const USBGenericRequest *request);
|
|||
|
||||
void USBDFU_Initialize(const USBDDriverDescriptors *pDescriptors, unsigned char *pInterfaces);
|
||||
|
||||
#define DFU_RET_NOTHING 0
|
||||
#define DFU_RET_ZLP 1
|
||||
#define DFU_RET_STALL 2
|
||||
|
||||
#endif
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include <usb/common/core/USBInterfaceDescriptor.h>
|
||||
#include <usb/common/core/USBGenericDescriptor.h>
|
||||
#include <usb/common/core/USBGetDescriptorRequest.h>
|
||||
#include <usb/device/core/USBD.h>
|
||||
#include <usb/common/dfu/usb_dfu.h>
|
||||
#include <usb/device/dfu/dfu.h>
|
||||
|
@ -37,10 +38,6 @@
|
|||
/// Standard device driver instance.
|
||||
static USBDDriver usbdDriver;
|
||||
|
||||
#define RET_NOTHING 0
|
||||
#define RET_ZLP 1
|
||||
#define RET_STALL 2
|
||||
|
||||
__dfudata struct dfu dfu = {
|
||||
.state = DFU_STATE_appIDLE,
|
||||
.past_manifest = 0,
|
||||
|
@ -48,7 +45,8 @@ __dfudata struct dfu dfu = {
|
|||
|
||||
static __dfufunc void handle_getstatus(void)
|
||||
{
|
||||
struct dfu_status dstat;
|
||||
/* has to be static as USBD_Write is async ? */
|
||||
static struct dfu_status dstat;
|
||||
|
||||
dfu_drv_updstatus();
|
||||
|
||||
|
@ -58,6 +56,8 @@ static __dfufunc void handle_getstatus(void)
|
|||
dstat.iString = 0;
|
||||
/* FIXME: set dstat.bwPollTimeout */
|
||||
|
||||
TRACE_DEBUG("handle_getstatus(%u, %u)\n\r", dstat.bStatus, dstat.bState);
|
||||
|
||||
USBD_Write(0, (char *)&dstat, sizeof(dstat), NULL, 0);
|
||||
}
|
||||
|
||||
|
@ -65,9 +65,23 @@ static void __dfufunc handle_getstate(void)
|
|||
{
|
||||
uint8_t u8 = dfu.state;
|
||||
|
||||
TRACE_DEBUG("handle_getstate(%u)\n\r", dfu.state);
|
||||
|
||||
USBD_Write(0, (char *)&u8, sizeof(u8), NULL, 0);
|
||||
}
|
||||
|
||||
static void TerminateCtrlInWithNull(void *pArg,
|
||||
unsigned char status,
|
||||
unsigned int transferred,
|
||||
unsigned int remaining)
|
||||
{
|
||||
USBD_Write(0, // Endpoint #0
|
||||
0, // No data buffer
|
||||
0, // No data buffer
|
||||
(TransferCallback) 0,
|
||||
(void *) 0);
|
||||
}
|
||||
|
||||
/* this function gets daisy-chained into processing EP0 requests */
|
||||
void USBDFU_DFU_RequestHandler(const USBGenericRequest *request)
|
||||
{
|
||||
|
@ -76,7 +90,32 @@ void USBDFU_DFU_RequestHandler(const USBGenericRequest *request)
|
|||
uint16_t val = USBGenericRequest_GetValue(request);
|
||||
int rc, ret;
|
||||
|
||||
/* only process actual DFU specific messages */
|
||||
TRACE_DEBUG("type=0x%x, recipient=0x%x val=0x%x len=%u\n",
|
||||
USBGenericRequest_GetType(request),
|
||||
USBGenericRequest_GetRecipient(request),
|
||||
val, len);
|
||||
|
||||
/* check for GET_DESCRIPTOR on DFU */
|
||||
if (USBGenericRequest_GetType(request) == USBGenericRequest_STANDARD &&
|
||||
USBGenericRequest_GetRecipient(request) == USBGenericRequest_DEVICE &&
|
||||
USBGenericRequest_GetRequest(request) == USBGenericRequest_GETDESCRIPTOR &&
|
||||
USBGetDescriptorRequest_GetDescriptorType(request) == USB_DT_DFU) {
|
||||
uint16_t length = sizeof(struct usb_dfu_func_descriptor);
|
||||
const USBDeviceDescriptor *pDevice;
|
||||
int terminateWithNull;
|
||||
|
||||
if (USBD_IsHighSpeed())
|
||||
pDevice = usbdDriver.pDescriptors->pHsDevice;
|
||||
else
|
||||
pDevice = usbdDriver.pDescriptors->pFsDevice;
|
||||
|
||||
terminateWithNull = ((length % pDevice->bMaxPacketSize0) == 0);
|
||||
USBD_Write(0, &dfu_cfg_descriptor.func_dfu, length,
|
||||
terminateWithNull ? TerminateCtrlInWithNull : 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* forward all non-DFU specific messages to core handler*/
|
||||
if (USBGenericRequest_GetType(request) != USBGenericRequest_CLASS ||
|
||||
USBGenericRequest_GetRecipient(request) != USBGenericRequest_INTERFACE) {
|
||||
TRACE_DEBUG("std_ho_usbd ");
|
||||
|
@ -93,12 +132,13 @@ void USBDFU_DFU_RequestHandler(const USBGenericRequest *request)
|
|||
handle_getstate();
|
||||
break;
|
||||
case USB_REQ_DFU_DETACH:
|
||||
TRACE_DEBUG("\r\n====dfu_detach\n\r");
|
||||
dfu.state = DFU_STATE_appDETACH;
|
||||
ret = RET_ZLP;
|
||||
ret = DFU_RET_ZLP;
|
||||
goto out;
|
||||
break;
|
||||
default:
|
||||
ret = RET_STALL;
|
||||
ret = DFU_RET_STALL;
|
||||
}
|
||||
break;
|
||||
case DFU_STATE_appDETACH:
|
||||
|
@ -111,7 +151,7 @@ void USBDFU_DFU_RequestHandler(const USBGenericRequest *request)
|
|||
break;
|
||||
default:
|
||||
dfu.state = DFU_STATE_appIDLE;
|
||||
ret = RET_STALL;
|
||||
ret = DFU_RET_STALL;
|
||||
goto out;
|
||||
break;
|
||||
}
|
||||
|
@ -122,7 +162,7 @@ void USBDFU_DFU_RequestHandler(const USBGenericRequest *request)
|
|||
case USB_REQ_DFU_DNLOAD:
|
||||
if (len == 0) {
|
||||
dfu.state = DFU_STATE_dfuERROR;
|
||||
ret = RET_STALL;
|
||||
ret = DFU_RET_STALL;
|
||||
goto out;
|
||||
}
|
||||
dfu.state = DFU_STATE_dfuDNLOAD_SYNC;
|
||||
|
@ -134,7 +174,7 @@ void USBDFU_DFU_RequestHandler(const USBGenericRequest *request)
|
|||
break;
|
||||
case USB_REQ_DFU_ABORT:
|
||||
/* no zlp? */
|
||||
ret = RET_ZLP;
|
||||
ret = DFU_RET_ZLP;
|
||||
break;
|
||||
case USB_REQ_DFU_GETSTATUS:
|
||||
handle_getstatus();
|
||||
|
@ -144,7 +184,7 @@ void USBDFU_DFU_RequestHandler(const USBGenericRequest *request)
|
|||
break;
|
||||
default:
|
||||
dfu.state = DFU_STATE_dfuERROR;
|
||||
ret = RET_STALL;
|
||||
ret = DFU_RET_STALL;
|
||||
goto out;
|
||||
break;
|
||||
}
|
||||
|
@ -160,7 +200,7 @@ void USBDFU_DFU_RequestHandler(const USBGenericRequest *request)
|
|||
break;
|
||||
default:
|
||||
dfu.state = DFU_STATE_dfuERROR;
|
||||
ret = RET_STALL;
|
||||
ret = DFU_RET_STALL;
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
|
@ -173,7 +213,7 @@ void USBDFU_DFU_RequestHandler(const USBGenericRequest *request)
|
|||
break;
|
||||
default:
|
||||
dfu.state = DFU_STATE_dfuERROR;
|
||||
ret = RET_STALL;
|
||||
ret = DFU_RET_STALL;
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
|
@ -185,7 +225,7 @@ void USBDFU_DFU_RequestHandler(const USBGenericRequest *request)
|
|||
break;
|
||||
case USB_REQ_DFU_ABORT:
|
||||
dfu.state = DFU_STATE_dfuIDLE;
|
||||
ret = RET_ZLP;
|
||||
ret = DFU_RET_ZLP;
|
||||
break;
|
||||
case USB_REQ_DFU_GETSTATUS:
|
||||
handle_getstatus();
|
||||
|
@ -195,7 +235,7 @@ void USBDFU_DFU_RequestHandler(const USBGenericRequest *request)
|
|||
break;
|
||||
default:
|
||||
dfu.state = DFU_STATE_dfuERROR;
|
||||
ret = RET_STALL;
|
||||
ret = DFU_RET_STALL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -209,7 +249,7 @@ void USBDFU_DFU_RequestHandler(const USBGenericRequest *request)
|
|||
break;
|
||||
default:
|
||||
dfu.state = DFU_STATE_dfuERROR;
|
||||
ret = RET_STALL;
|
||||
ret = DFU_RET_STALL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -233,7 +273,7 @@ void USBDFU_DFU_RequestHandler(const USBGenericRequest *request)
|
|||
break;
|
||||
default:
|
||||
dfu.state = DFU_STATE_dfuERROR;
|
||||
ret = RET_STALL;
|
||||
ret = DFU_RET_STALL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -251,7 +291,7 @@ void USBDFU_DFU_RequestHandler(const USBGenericRequest *request)
|
|||
case USB_REQ_DFU_ABORT:
|
||||
dfu.state = DFU_STATE_dfuIDLE;
|
||||
/* no zlp? */
|
||||
ret = RET_ZLP;
|
||||
ret = DFU_RET_ZLP;
|
||||
break;
|
||||
case USB_REQ_DFU_GETSTATUS:
|
||||
handle_getstatus();
|
||||
|
@ -261,7 +301,7 @@ void USBDFU_DFU_RequestHandler(const USBGenericRequest *request)
|
|||
break;
|
||||
default:
|
||||
dfu.state = DFU_STATE_dfuERROR;
|
||||
ret = RET_STALL;
|
||||
ret = DFU_RET_STALL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -277,11 +317,11 @@ void USBDFU_DFU_RequestHandler(const USBGenericRequest *request)
|
|||
dfu.state = DFU_STATE_dfuIDLE;
|
||||
dfu.status = DFU_STATUS_OK;
|
||||
/* no zlp? */
|
||||
ret = RET_ZLP;
|
||||
ret = DFU_RET_ZLP;
|
||||
break;
|
||||
default:
|
||||
dfu.state = DFU_STATE_dfuERROR;
|
||||
ret = RET_STALL;
|
||||
ret = DFU_RET_STALL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -289,12 +329,12 @@ void USBDFU_DFU_RequestHandler(const USBGenericRequest *request)
|
|||
|
||||
out:
|
||||
switch (ret) {
|
||||
case RET_NOTHING:
|
||||
case DFU_RET_NOTHING:
|
||||
break;
|
||||
case RET_ZLP:
|
||||
case DFU_RET_ZLP:
|
||||
USBD_Write(0, 0, 0, 0, 0);
|
||||
break;
|
||||
case RET_STALL:
|
||||
case DFU_RET_STALL:
|
||||
USBD_Stall(0);
|
||||
break;
|
||||
}
|
||||
|
@ -302,6 +342,9 @@ out:
|
|||
|
||||
void USBDFU_Initialize(const USBDDriverDescriptors *pDescriptors, unsigned char *pInterfaces)
|
||||
{
|
||||
/* We already start in DFU idle mode */
|
||||
dfu.state = DFU_STATE_dfuIDLE;
|
||||
|
||||
USBDDriver_Initialize(&usbdDriver, pDescriptors, pInterfaces);
|
||||
|
||||
USBD_Init();
|
||||
|
|
Loading…
Reference in New Issue