summaryrefslogtreecommitdiff
path: root/firmware/src
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
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')
-rw-r--r--firmware/src/dfu/dfu.c34
-rw-r--r--firmware/src/start/Cstartup.S24
2 files changed, 41 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)
diff --git a/firmware/src/start/Cstartup.S b/firmware/src/start/Cstartup.S
index a750039..990dbcb 100644
--- a/firmware/src/start/Cstartup.S
+++ b/firmware/src/start/Cstartup.S
@@ -35,8 +35,12 @@
//*- 1.1 01/Apr/05 JPP : save SPSR
//*-----------------------------------------------------------------------------*/
+/* Enable DFU by press of hardware POI_BOOTLDR switch */
#define CONFIG_DFU_SWITCH
+/* Enable DFU by magic value in RAM and software reset */
+#define CONFIG_DFU_MAGIC
+
//#define DEBUG_LL
#ifdef DEBUG_LL
@@ -301,6 +305,12 @@ InitReset:
.EQU I_BIT, 0x80
.EQU F_BIT, 0x40
+
+#define AT91C_RSTC_RSR 0xFFFFFD04
+#define AT91C_RSTC_RSTTYP_SOFTWARE (0x03 << 8)
+#define DFU_STATE_appDETACH 1
+
+
/*------------------------------------------------------------------------------
//*- Setup the stack for each mode
//*-------------------------------*/
@@ -319,6 +329,20 @@ InitReset:
msr CPSR_c, #ARM_MODE_SVC
mov r13, r0 /* Init stack Sup */
+#ifdef CONFIG_DFU_MAGIC
+ ldr r1, =AT91C_RSTC_RSR
+ ldr r2, [r1]
+ #and r2, r2, AT91C_RSTC_RSTTYP
+ tst r2, #AT91C_RSTC_RSTTYP_SOFTWARE
+ beq dfu_magic_end
+
+ ldr r1, =dfu_state
+ ldr r2, [r1]
+ cmp r2, #DFU_STATE_appDETACH
+ beq _reloc_dfu
+dfu_magic_end:
+#endif
+
# Relocate DFU .data.shared section (Copy from ROM to RAM)
LDR R1, =_etext
LDR R2, =_data_shared
personal git repositories of Harald Welte. Your mileage may vary