diff options
author | AJM <poslathian@poslathian.(none)> | 2010-06-09 15:52:29 -0400 |
---|---|---|
committer | AJM <poslathian@poslathian.(none)> | 2010-06-09 15:52:29 -0400 |
commit | 8afc89be1da70c2776333b3858532c6b753e11ce (patch) | |
tree | 35999d67dfd3f31f0d531f849336148f8d6c9daf /libmaple/usb/usb_callbacks.c | |
parent | a89cddd05ea3fb09513a8fb96b9cd963efbffab3 (diff) | |
download | librambutan-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/usb/usb_callbacks.c')
-rw-r--r-- | libmaple/usb/usb_callbacks.c | 44 |
1 files changed, 44 insertions, 0 deletions
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; |