aboutsummaryrefslogtreecommitdiffstats
path: root/core/usb/usb.c
diff options
context:
space:
mode:
authorAJM <poslathian@poslathian.(none)>2010-04-25 17:42:34 -0400
committerbnewbold <bnewbold@robocracy.org>2010-05-20 22:09:16 -0400
commitba9ff3861bbcc17c78086b1887691c324f13ba0e (patch)
tree15e3203954cc568065b219a576a344ebbeaeefdd /core/usb/usb.c
parentfc4b9b386a80d06c73e03d70767643aae3961e2a (diff)
downloadlibrambutan-ba9ff3861bbcc17c78086b1887691c324f13ba0e.tar.gz
librambutan-ba9ff3861bbcc17c78086b1887691c324f13ba0e.zip
added a delay to the resrt slide to allow enough time for graceul closures of the serial port
Diffstat (limited to 'core/usb/usb.c')
-rw-r--r--core/usb/usb.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/core/usb/usb.c b/core/usb/usb.c
index a8298c0..bbea77d 100644
--- a/core/usb/usb.c
+++ b/core/usb/usb.c
@@ -332,6 +332,42 @@ if (wIstr & ISTR_CTR & wInterrupt_Mask)
CTR_LP(); /* low priority ISR defined in the usb core lib */
}
#endif
+
+/* if we are about to reset from the DTR signal, then dont return
+ to user, instead return from the ISR into a wait slide */
+ if (reset_state == RESET_NOW) {
+ reset_state = START;
+ unsigned int target = (unsigned int)usbWaitReset | 0x1;
+
+ asm volatile("mov r0, %[stack_top] \n\t" // Reset the stack
+ "mov sp, r0 \n\t"
+ "mov r0, #1 \n\t"
+ "mov r1, %[target_addr] \n\t"
+ "mov r2, %[cpsr] \n\t"
+ "push {r2} \n\t" // Fake xPSR
+ "push {r1} \n\t" // Target address for PC
+ "push {r0} \n\t" // Fake LR
+ "push {r0} \n\t" // Fake R12
+ "push {r0} \n\t" // Fake R3
+ "push {r0} \n\t" // Fake R2
+ "push {r0} \n\t" // Fake R1
+ "push {r0} \n\t" // Fake R0
+ "mov lr, %[exc_return] \n\t"
+ "bx lr"
+ :
+ : [stack_top] "r" (STACK_TOP),
+ [target_addr] "r" (target),
+ [exc_return] "r" (EXC_RETURN),
+ [cpsr] "r" (DEFAULT_CPSR)
+ : "r0", "r1", "r2");
+ // Should never get here.
+ }
+}
+
+void usbWaitReset(void) {
+ static count=1000000;
+ while (count-- >0);
+ systemHardReset();
}
/* copies data out of sendBuf into the packet memory for