Handle SET_ADDRESS according to DFUSE specs.

This commit is contained in:
Uwe Bonnes 2017-03-03 13:12:14 +01:00
parent 1f31099d46
commit 1d8ebcd75f
1 changed files with 14 additions and 9 deletions

View File

@ -48,6 +48,7 @@ static struct {
uint32_t addr; uint32_t addr;
uint16_t blocknum; uint16_t blocknum;
} prog; } prog;
static uint8_t current_error;
const struct usb_device_descriptor dev = { const struct usb_device_descriptor dev = {
.bLength = USB_DT_DEVICE_SIZE, .bLength = USB_DT_DEVICE_SIZE,
@ -149,7 +150,8 @@ static uint8_t usbdfu_getstatus(uint32_t *bwPollTimeout)
/* Device will reset when read is complete */ /* Device will reset when read is complete */
usbdfu_state = STATE_DFU_MANIFEST; usbdfu_state = STATE_DFU_MANIFEST;
return DFU_STATUS_OK; return DFU_STATUS_OK;
case STATE_DFU_ERROR:
return current_error;
default: default:
return DFU_STATUS_OK; return DFU_STATUS_OK;
} }
@ -159,23 +161,17 @@ static void
usbdfu_getstatus_complete(usbd_device *dev, struct usb_setup_data *req) usbdfu_getstatus_complete(usbd_device *dev, struct usb_setup_data *req)
{ {
(void)req; (void)req;
(void)dev;
switch(usbdfu_state) { switch(usbdfu_state) {
case STATE_DFU_DNBUSY: case STATE_DFU_DNBUSY:
flash_unlock(); flash_unlock();
if(prog.blocknum == 0) { if(prog.blocknum == 0) {
uint32_t addr = get_le32(prog.buf + 1); int32_t addr = get_le32(prog.buf + 1);
if ((addr < app_address) || (addr >= max_address)) {
flash_lock();
usbd_ep_stall_set(dev, 0, 1);
return;
}
switch(prog.buf[0]) { switch(prog.buf[0]) {
case CMD_ERASE: case CMD_ERASE:
dfu_check_and_do_sector_erase(addr); dfu_check_and_do_sector_erase(addr);
case CMD_SETADDR:
prog.addr = addr;
} }
} else { } else {
uint32_t baseaddr = prog.addr + uint32_t baseaddr = prog.addr +
@ -218,6 +214,15 @@ static int usbdfu_control_request(usbd_device *dev,
prog.blocknum = req->wValue; prog.blocknum = req->wValue;
prog.len = *len; prog.len = *len;
memcpy(prog.buf, *buf, *len); memcpy(prog.buf, *buf, *len);
if ((req->wValue == 0) && (prog.buf[0] == CMD_SETADDR)) {
uint32_t addr = get_le32(prog.buf + 1);
if ((addr < app_address) || (addr >= max_address)) {
current_error = DFU_STATUS_ERR_TARGET;
usbdfu_state = STATE_DFU_ERROR;
return 1;
} else
prog.addr = addr;
}
usbdfu_state = STATE_DFU_DNLOAD_SYNC; usbdfu_state = STATE_DFU_DNLOAD_SYNC;
return 1; return 1;
} }