summaryrefslogtreecommitdiff
path: root/firmware/src/dfu/dfu.c
diff options
context:
space:
mode:
authorlaforge <laforge@6dc7ffe9-61d6-0310-9af1-9938baff3ed1>2006-09-23 14:49:43 +0000
committerlaforge <laforge@6dc7ffe9-61d6-0310-9af1-9938baff3ed1>2006-09-23 14:49:43 +0000
commit460ece8365600e1a8fdb124c2f68de6aabf1fa62 (patch)
tree21f3e26aad4886bfa425e377ea859d67ec0a6c83 /firmware/src/dfu/dfu.c
parentd23fda3be353e64852ae04fd03f1cfc4326fec7f (diff)
- Implement runtime DFU switching and reset-after-update. This means
we can now reflash without any buttons or replugging of the device git-svn-id: https://svn.openpcd.org:2342/trunk@222 6dc7ffe9-61d6-0310-9af1-9938baff3ed1
Diffstat (limited to 'firmware/src/dfu/dfu.c')
-rw-r--r--firmware/src/dfu/dfu.c34
1 files changed, 17 insertions, 17 deletions
diff --git a/firmware/src/dfu/dfu.c b/firmware/src/dfu/dfu.c
index 7e7c575..56f7ef0 100644
--- a/firmware/src/dfu/dfu.c
+++ b/firmware/src/dfu/dfu.c
@@ -195,7 +195,7 @@ static void __dfufunc udp_ep0_send_stall(void)
static u_int8_t *ptr = (u_int8_t *) AT91C_IFLASH + SAM7DFU_SIZE;
static __dfudata u_int8_t dfu_status;
-static __dfudata u_int32_t dfu_state = DFU_STATE_appIDLE;
+__dfudata u_int32_t dfu_state = DFU_STATE_appIDLE;
static u_int32_t pagebuf32[AT91C_IFLASH_PAGE_SIZE/4];
static int __dfufunc handle_dnload(u_int16_t val, u_int16_t len)
@@ -376,9 +376,9 @@ int __dfufunc dfu_ep0_handler(u_int8_t req_type, u_int8_t req,
ret = RET_STALL;
goto out;
}
+ dfu_state = DFU_STATE_dfuDNLOAD_SYNC;
ptr = (u_int8_t *) AT91C_IFLASH + SAM7DFU_SIZE;
ret = handle_dnload(val, len);
- dfu_state = DFU_STATE_dfuDNLOAD_SYNC;
break;
case USB_REQ_DFU_UPLOAD:
ptr = (u_int8_t *) AT91C_IFLASH + SAM7DFU_SIZE;
@@ -433,8 +433,8 @@ int __dfufunc dfu_ep0_handler(u_int8_t req_type, u_int8_t req,
case DFU_STATE_dfuDNLOAD_IDLE:
switch (req) {
case USB_REQ_DFU_DNLOAD:
- ret = handle_dnload(val, len);
dfu_state = DFU_STATE_dfuDNLOAD_SYNC;
+ ret = handle_dnload(val, len);
break;
case USB_REQ_DFU_ABORT:
dfu_state = DFU_STATE_dfuIDLE;
@@ -798,6 +798,14 @@ static __dfufunc void dfu_udp_irq(void)
/* Configure endpoint 0 */
pUDP->UDP_CSR[0] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL);
cur_config = 0;
+
+ if (dfu_state == DFU_STATE_dfuMANIFEST_WAIT_RST ||
+ dfu_state == DFU_STATE_dfuMANIFEST) {
+ AT91F_RSTSoftReset(AT91C_BASE_RSTC, AT91C_RSTC_PROCRST|
+ AT91C_RSTC_PERRST|
+ AT91C_RSTC_EXTRST);
+ }
+
}
if (isr & AT91C_UDP_EPINT0)
@@ -817,22 +825,14 @@ static void dfu_switch(void)
AT91PS_AIC pAic = AT91C_BASE_AIC;
DEBUGE("\r\nsam7dfu: switching to DFU mode\r\n");
- AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, OPENPCD_PIO_LED1);
- AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, OPENPCD_PIO_LED2);
- led1off();
- led2off();
-
- flash_init();
- /* disable all non-usb (and non-dbgu) interrupts */
- pAic->AIC_IDCR = ~((1 << AT91C_ID_UDP)|(1 << AT91C_ID_SYS));
+ dfu_state = DFU_STATE_appDETACH;
+ AT91F_RSTSoftReset(AT91C_BASE_RSTC, AT91C_RSTC_PROCRST|
+ AT91C_RSTC_PERRST|AT91C_RSTC_EXTRST);
- pAic->AIC_SVR[AT91C_ID_UDP] = (unsigned int) &dfu_udp_irq;
- dfu_state = DFU_STATE_dfuIDLE;
- dfu_status = DFU_STATUS_OK;
- //AT91F_DBGU_Printk("You may now start the DFU up/download process\r\n");
- AT91F_DBGU_Printk("\r\nTHIS DOES NOT WORK YET, "
- " PLEASE PUSH THE BUTTON WHILE POWERING UP\r\n");
+ /* We should never reach here, but anyway avoid returning to the
+ * caller since he doesn't expect us to do so */
+ while (1) ;
}
void __dfufunc dfu_main(void)
personal git repositories of Harald Welte. Your mileage may vary