DFU: add actual upload and download support
This commit is contained in:
parent
be10ca901e
commit
f2be0ee6d8
|
@ -52,12 +52,16 @@
|
|||
#include <utility/trace.h>
|
||||
#include <utility/led.h>
|
||||
|
||||
#include <memories/flash/flashd.h>
|
||||
|
||||
#include <usb/device/core/USBD.h>
|
||||
#include <usb/device/core/USBDDriver.h>
|
||||
#include <usb/device/dfu/dfu.h>
|
||||
|
||||
#include "dfu_desc.h"
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Definitions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
@ -105,6 +109,14 @@ static volatile uint8_t isRecActive = 0;
|
|||
/** VBus pin instance. */
|
||||
static const Pin pinVbus = PIN_USB_VBUS;
|
||||
|
||||
/* this needs to be in sync with usb-strings.txt !! */
|
||||
enum dfu_altif {
|
||||
ALTIF_APP,
|
||||
ALTIF_BOOT,
|
||||
ALTIF_RAM,
|
||||
ALTIF_FPGA
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles interrupts coming from PIO controllers.
|
||||
*/
|
||||
|
@ -272,27 +284,99 @@ void USBDDriverCallbacks_InterfaceSettingChanged(unsigned char interface,
|
|||
TRACE_INFO("DFU: IfSettingChgd(if=%u, alt=%u)\n\r", interface, setting);
|
||||
}
|
||||
|
||||
static int upl_first = 1;
|
||||
#define BOOT_FLASH_SIZE (16 * 1024)
|
||||
|
||||
struct flash_part {
|
||||
void *base_addr;
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
static const struct flash_part flash_parts[] = {
|
||||
[ALTIF_BOOT] = {
|
||||
.base_addr = AT91C_IFLASH0,
|
||||
.size = BOOT_FLASH_SIZE,
|
||||
},
|
||||
[ALTIF_APP] = {
|
||||
.base_addr = (AT91C_IFLASH + BOOT_FLASH_SIZE),
|
||||
.size = (AT91C_IFLASH0_SIZE - BOOT_FLASH_SIZE),
|
||||
},
|
||||
[ALTIF_RAM] = {
|
||||
.base_addr = AT91C_IRAM,
|
||||
.size = AT91C_IRAM_SIZE,
|
||||
},
|
||||
[ALTIF_FPGA] = {
|
||||
.base_addr = AT91C_IFLASH1,
|
||||
.size = AT91C_IFLASH1_SIZE,
|
||||
},
|
||||
};
|
||||
|
||||
/* DFU callback */
|
||||
int USBDFU_handle_upload(uint8_t altif, unsigned int offset,
|
||||
uint8_t *buf, unsigned int req_len)
|
||||
{
|
||||
TRACE_INFO("DFU: handle_upload(%u, %u, %u)\n\r", altif, offset, req_len);
|
||||
if (upl_first) {
|
||||
upl_first = 0;
|
||||
return req_len;
|
||||
}
|
||||
struct flash_part *part;
|
||||
void *end, *addr;
|
||||
uint32_t real_len;
|
||||
|
||||
return 4;
|
||||
TRACE_INFO("DFU: handle_upload(%u, %u, %u)\n\r", altif, offset, req_len);
|
||||
|
||||
if (altif > ARRAY_SIZE(flash_parts))
|
||||
return -EINVAL;
|
||||
|
||||
part = &flash_parts[altif];
|
||||
|
||||
addr = part->base_addr + offset;
|
||||
end = part->base_addr + part->size;
|
||||
|
||||
real_len = end - addr;
|
||||
if (req_len < real_len)
|
||||
real_len = req_len;
|
||||
|
||||
memcpy(buf, addr, real_len);
|
||||
|
||||
return real_len;
|
||||
}
|
||||
|
||||
/* DFU callback */
|
||||
int USBDFU_handle_dnload(uint8_t altif, unsigned int offset,
|
||||
uint8_t *buf, unsigned int len)
|
||||
{
|
||||
struct flash_part *part;
|
||||
void *end, *addr;
|
||||
int rc;
|
||||
|
||||
TRACE_INFO("DFU: handle_dnload(%u, %u, %u)\n\r", altif, offset, len);
|
||||
|
||||
if (altif > ARRAY_SIZE(flash_parts))
|
||||
return -EINVAL;
|
||||
|
||||
part = &flash_parts[altif];
|
||||
|
||||
addr = part->base_addr + offset;
|
||||
end = part->base_addr + part->size;
|
||||
|
||||
if (addr + len > end) {
|
||||
TRACE_ERROR("Cannot write beyond end of DFU partition %u\n\r", altif);
|
||||
dfu.status = DFU_STATUS_errADDRESS;
|
||||
return DFU_RET_STALL;
|
||||
}
|
||||
|
||||
switch (altif) {
|
||||
case ALTIF_APP:
|
||||
case ALTIF_FPGA:
|
||||
rc = FLASHD_Write(addr, buf, len);
|
||||
if (rc != 0) {
|
||||
TRACE_ERROR("Error during write of DFU partition %u\n\r", altif);
|
||||
dfu.status = DFU_STATUS_errPROG;
|
||||
return DFU_RET_STALL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
TRACE_WARNING("Write to DFU partition %u not implemented\n\r", altif);
|
||||
dfu.status = DFU_STATUS_errTARGET;
|
||||
break;
|
||||
}
|
||||
|
||||
return DFU_RET_ZLP;
|
||||
}
|
||||
|
||||
|
@ -300,6 +384,9 @@ int USBDFU_handle_dnload(uint8_t altif, unsigned int offset,
|
|||
void dfu_drv_updstatus(void)
|
||||
{
|
||||
TRACE_INFO("DFU: updstatus()\n\r");
|
||||
|
||||
if (dfu.state == DFU_STATE_dfuMANIFEST_SYNC)
|
||||
dfu.state = DFU_STATE_dfuMANIFEST;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in New Issue