diff options
author | Harald Welte <laforge@gnumonks.org> | 2011-07-29 23:30:00 +0200 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2011-07-29 23:30:00 +0200 |
commit | d56bb35e907e2d7c4507b7240e36d8b69d272bce (patch) | |
tree | fbb58dc7ac28c57dc9d8ade0ad0beb938bd19f7d /firmware/src/dfu/dfu.c | |
parent | a23eefc6dc5f45498116f69125f6e12f53a81130 (diff) |
sam7dfu: make sure we can use USB reset to get from DFU -> APP
When we went through a Download -> Manifest cycle, we can switch
back to dfuIDLE. However, we need to memorize that manifest had
already happened and thus should treat a host-initiated bus reset
as trigger to switch back into application mode.
Diffstat (limited to 'firmware/src/dfu/dfu.c')
-rw-r--r-- | firmware/src/dfu/dfu.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/firmware/src/dfu/dfu.c b/firmware/src/dfu/dfu.c index 8425c28..e126539 100644 --- a/firmware/src/dfu/dfu.c +++ b/firmware/src/dfu/dfu.c @@ -69,6 +69,8 @@ #define led2on() AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, OPENPCD_PIO_LED2) #define led2off() AT91F_PIO_SetOutput(AT91C_BASE_PIOA, OPENPCD_PIO_LED2) +static int past_manifest = 0; + static void __dfufunc udp_init(void) { /* Set the PLL USB Divider */ @@ -486,7 +488,16 @@ int __dfufunc dfu_ep0_handler(u_int8_t req_type, u_int8_t req, case DFU_STATE_dfuMANIFEST: switch (req) { case USB_REQ_DFU_GETSTATUS: + /* we don't want to change to WAIT_RST, as it + * would mean that we can not support another + * DFU transaction before doing the actual + * reset. Instead, we switch to idle and note + * that we've already been through MANIFST in + * the global variable 'past_manifest'. + */ + //dfu_state = DFU_STATE_dfuMANIFEST_WAIT_RST; dfu_state = DFU_STATE_dfuIDLE; + past_manifest = 1; handle_getstatus(); break; case USB_REQ_DFU_GETSTATE: @@ -858,12 +869,13 @@ static __dfufunc void dfu_udp_irq(void) cur_config = 0; if (dfu_state == DFU_STATE_dfuMANIFEST_WAIT_RST || - dfu_state == DFU_STATE_dfuMANIFEST) { + dfu_state == DFU_STATE_dfuMANIFEST || + past_manifest) { + /* reset back into the main application */ AT91F_RSTSoftReset(AT91C_BASE_RSTC, AT91C_RSTC_PROCRST| AT91C_RSTC_PERRST| AT91C_RSTC_EXTRST); } - } if (isr & AT91C_UDP_EPINT0) |