From 8afc89be1da70c2776333b3858532c6b753e11ce Mon Sep 17 00:00:00 2001 From: AJM Date: Wed, 9 Jun 2010 15:52:29 -0400 Subject: 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... --- libmaple/usb/usb.c | 33 ++------------------------------- libmaple/usb/usb_callbacks.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ libmaple/usb/usb_callbacks.h | 1 + support/scripts/reset.py | 8 ++++++-- 4 files changed, 53 insertions(+), 33 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 */ diff --git a/support/scripts/reset.py b/support/scripts/reset.py index e4d0e99..7594845 100755 --- a/support/scripts/reset.py +++ b/support/scripts/reset.py @@ -2,9 +2,9 @@ import serial import os - +from struct import pack try: - ser = serial.Serial('/dev/maple', baudrate=115200) + ser = serial.Serial('/dev/ttyACM0', baudrate=115200) ser.open() # pull dtr and rts low @@ -13,6 +13,10 @@ try: # toggle DTR ser.setDTR(1) + ser.setDTR(0) + + programDelay = pack("b",35) + ser.write(programDelay) # close ser.close() -- cgit v1.2.3