summaryrefslogtreecommitdiff
path: root/firmware/src/dfu
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/src/dfu')
-rw-r--r--firmware/src/dfu/dfu.c38
1 files changed, 28 insertions, 10 deletions
diff --git a/firmware/src/dfu/dfu.c b/firmware/src/dfu/dfu.c
index 09c8784..c5f706e 100644
--- a/firmware/src/dfu/dfu.c
+++ b/firmware/src/dfu/dfu.c
@@ -31,6 +31,8 @@
#include <os/pcd_enumerate.h>
#include "../openpcd.h"
+#define SAM7DFU_SIZE 0x1000
+
/* If debug is enabled, we need to access debug functions from flash
* and therefore have to omit flashing */
#define DEBUG_DFU
@@ -56,8 +58,8 @@ static void __dfufunc udp_init(void)
AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_UDP;
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_UDP);
- /* Enable UDP PullUp (USB_DP_PUP) : enable & Clear of the corresponding PIO
- * Set in PIO mode and Configure in Output */
+ /* Enable UDP PullUp (USB_DP_PUP) : enable & Clear of the
+ * corresponding PIO Set in PIO mode and Configure in Output */
AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, OPENPCD_PIO_UDP_PUP);
}
@@ -150,8 +152,8 @@ static void __dfufunc udp_ep0_send_stall(void)
static u_int8_t status;
-static u_int8_t *ptr = (u_int8_t *)0x00101000;
-static __dfudata u_int32_t dfu_state;
+static u_int8_t *ptr = AT91C_IFLASH + SAM7DFU_SIZE;
+static __dfudata u_int32_t dfu_state = DFU_STATE_appIDLE;
static u_int8_t pagebuf[AT91C_IFLASH_PAGE_SIZE];
static u_int16_t page_from_ramaddr(const void *addr)
@@ -179,7 +181,8 @@ static int __dfufunc handle_dnload(u_int16_t val, u_int16_t len)
DEBUGE("download ");
if (len > AT91C_IFLASH_PAGE_SIZE) {
- /* Too big */
+ /* Too big. Not that we'd really care, but it's a
+ * DFU protocol violation */
dfu_state = DFU_STATE_dfuERROR;
status = DFU_STATUS_errADDRESS;
udp_ep0_send_stall();
@@ -196,6 +199,12 @@ static int __dfufunc handle_dnload(u_int16_t val, u_int16_t len)
dfu_state = DFU_STATE_dfuMANIFEST_SYNC;
return 0;
}
+ if (ptr + len > AT91C_IFLASH + AT91C_IFLASH_SIZE) {
+ dfu_state = DFU_STATE_dfuERROR;
+ status = DFU_STATUS_errADDRESS;
+ udp_ep0_send_stall();
+ return -EINVAL;
+ }
udp_ep0_recv_data(pagebuf, sizeof(pagebuf));
@@ -234,8 +243,8 @@ static __dfufunc int handle_upload(u_int16_t val, u_int16_t len)
return -EINVAL;
}
- if (ptr + len > AT91C_IFLASH_SIZE)
- len = AT91C_IFLASH_SIZE - (u_int32_t) ptr;
+ if (ptr + len > AT91C_IFLASH + AT91C_IFLASH_SIZE)
+ len = AT91C_IFLASH + AT91C_IFLASH_SIZE - (u_int32_t) ptr;
udp_ep0_send_data((char *)ptr, len);
ptr+= len;
@@ -273,6 +282,7 @@ static __dfufunc void handle_getstatus(void)
dstat.bStatus = status;
dstat.bState = dfu_state;
dstat.iString = 0;
+ /* FIXME: set dstat.bwPollTimeout */
udp_ep0_send_data((char *)&dstat, sizeof(dstat));
}
@@ -322,11 +332,12 @@ int __dfufunc dfu_ep0_handler(u_int8_t req_type, u_int8_t req,
dfu_state = DFU_STATE_dfuERROR;
goto send_stall;
}
+ ptr = AT91C_IFLASH + SAM7DFU_SIZE;
handle_dnload(val, len);
dfu_state = DFU_STATE_dfuDNLOAD_SYNC;
break;
case USB_REQ_DFU_UPLOAD:
- ptr = 0x00101000; /* Flash base address for app */
+ ptr = AT91C_IFLASH + SAM7DFU_SIZE;
dfu_state = DFU_STATE_dfuUPLOAD_IDLE;
handle_upload(val, len);
break;
@@ -697,13 +708,16 @@ static __dfufunc void dfu_udp_ep0_handler(void)
udp_ep0_send_stall();
break;
default:
- DEBUGE("DEFAULT(req=0x%02x, type=0x%02x) ", bRequest, bmRequestType);
+ DEBUGE("DEFAULT(req=0x%02x, type=0x%02x) ",
+ bRequest, bmRequestType);
if ((bmRequestType & 0x3f) == USB_TYPE_DFU) {
- dfu_ep0_handler(bmRequestType, bRequest, wValue, wLength);
+ dfu_ep0_handler(bmRequestType, bRequest,
+ wValue, wLength);
} else
udp_ep0_send_stall();
break;
}
+ DEBUGE("\r\n");
}
/* minimal USB IRQ handler in DFU mode */
@@ -747,9 +761,12 @@ static void dfu_switch(void)
void __dfufunc dfu_main(void)
{
AT91F_DBGU_Init();
+ DEBUGE("sam7dfu startup\r\n");
udp_init();
+ dfu_state = DFU_STATE_dfuIDLE;
+
/* This implements
AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_UDP,
OPENPCD_IRQ_PRIO_UDP,
@@ -771,6 +788,7 @@ void __dfufunc dfu_main(void)
flash_init();
+ DEBUGE("sam7dfu entering main loop\r\n");
/* do nothing, since all of DFU is interrupt driven */
while (1) ;
}
personal git repositories of Harald Welte. Your mileage may vary