aboutsummaryrefslogtreecommitdiffstats
path: root/libmaple/usb/usb_callbacks.c
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/usb/usb_callbacks.c
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/usb/usb_callbacks.c')
-rw-r--r--libmaple/usb/usb_callbacks.c44
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;