aboutsummaryrefslogtreecommitdiffstats
path: root/libmaple
diff options
context:
space:
mode:
authorAJM <poslathian@poslathian.(none)>2010-06-09 15:52:29 -0400
committerAJM <poslathian@poslathian.(none)>2010-06-09 15:52:29 -0400
commit8afc89be1da70c2776333b3858532c6b753e11ce (patch)
tree35999d67dfd3f31f0d531f849336148f8d6c9daf /libmaple
parenta89cddd05ea3fb09513a8fb96b9cd963efbffab3 (diff)
downloadlibrambutan-8afc89be1da70c2776333b3858532c6b753e11ce.tar.gz
librambutan-8afc89be1da70c2776333b3858532c6b753e11ce.zip
first approach at modding the reset scheme
now we reset from recv bytes. After receiving the DTR/RTS toggle the next byte in from usb is parsed as the program_delay. For now, this just delays the reset for a period to close the serial port gracefully. Later, this delay will perhaps inform the bootloader of how long to live for...
Diffstat (limited to 'libmaple')
-rw-r--r--libmaple/usb/usb.c33
-rw-r--r--libmaple/usb/usb_callbacks.c44
-rw-r--r--libmaple/usb/usb_callbacks.h1
3 files changed, 47 insertions, 31 deletions
diff --git a/libmaple/usb/usb.c b/libmaple/usb/usb.c
index 6c144ba..09b51ea 100644
--- a/libmaple/usb/usb.c
+++ b/libmaple/usb/usb.c
@@ -332,40 +332,11 @@ if (wIstr & ISTR_CTR & wInterrupt_Mask)
}
#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);
+ int count = program_delay*100000000;
+ delay(program_delay*10);
systemHardReset();
}
diff --git a/libmaple/usb/usb_callbacks.c b/libmaple/usb/usb_callbacks.c
index 5c4a386..cacfd02 100644
--- a/libmaple/usb/usb_callbacks.c
+++ b/libmaple/usb/usb_callbacks.c
@@ -5,6 +5,7 @@
#include "descriptors.h"
#include "usb_config.h"
#include "usb.h"
+#include "usb_hardware.h"
ONE_DESCRIPTOR Device_Descriptor = {
(uint8*)&usbVcomDescriptor_Device,
@@ -38,6 +39,7 @@ volatile uint8 recvBufOut = 0;
volatile uint8 maxNewBytes = VCOM_RX_EPSIZE;
RESET_STATE reset_state = START;
+uint8 program_delay = 1;
void vcomDataTxCb(void) {
/* do whatever after data has been sent to host */
@@ -61,6 +63,48 @@ void vcomDataRxCb(void) {
uint8 newBytes = GetEPRxCount(VCOM_RX_ENDP);
/* assert (newBytes <= maxNewBytes); */
+
+ if (reset_state == RESET_NOW) {
+ /* todo, check for magic bytes */
+ /* for now just grab the new byte as the delay argument */
+ /* if theres anything in the recv buffer clear it,
+ then wait for the command byte and the delay argument.
+ if we dont get it, then just reset. todo, if we dont
+ get it, then revert back to user code */
+
+
+ reset_state = START;
+ unsigned int target = (unsigned int)usbWaitReset | 0x1;
+
+ PMAToUserBufferCopy(&program_delay,VCOM_RX_ADDR,1);
+
+ 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.
+
+ }
+
+
+
if (recvBufIn + newBytes < VCOM_RX_EPSIZE) {
PMAToUserBufferCopy(&vcomBufferRx[recvBufIn],VCOM_RX_ADDR,newBytes);
recvBufIn += newBytes;
diff --git a/libmaple/usb/usb_callbacks.h b/libmaple/usb/usb_callbacks.h
index ed57fa1..d77a9fd 100644
--- a/libmaple/usb/usb_callbacks.h
+++ b/libmaple/usb/usb_callbacks.h
@@ -34,6 +34,7 @@ typedef enum {
} RESET_STATE;
extern RESET_STATE reset_state; /* tracks DTR/RTS */
+extern uint8 program_delay;
extern volatile uint8 countTx;
extern uint8 vcomBufferRx[VCOM_RX_EPSIZE]; /* no reason this has to be VCOM_RX_EPSIZE, could be bigger */
extern volatile uint8 recvBufIn; /* the FIFO in index to the recvbuffer */