aboutsummaryrefslogtreecommitdiffstats
path: root/libmaple/usb
diff options
context:
space:
mode:
authorAJM <poslathian@poslathian.(none)>2010-06-09 22:25:14 -0400
committerAJM <poslathian@poslathian.(none)>2010-06-09 22:25:14 -0400
commitbe5593982965b22518c0605ef951574b4b97c871 (patch)
tree7d2b7dc51726b73474d00e0fa189ecd81fc380b5 /libmaple/usb
parent8afc89be1da70c2776333b3858532c6b753e11ce (diff)
downloadlibrambutan-be5593982965b22518c0605ef951574b4b97c871.tar.gz
librambutan-be5593982965b22518c0605ef951574b4b97c871.zip
added a somewhat broken version of the reset magic number scheme.
current version gets stuck in the isr somewhere. not sure why or where. must debug.
Diffstat (limited to 'libmaple/usb')
-rw-r--r--libmaple/usb/usb.c5
-rw-r--r--libmaple/usb/usb_callbacks.c148
-rw-r--r--libmaple/usb/usb_callbacks.h11
-rw-r--r--libmaple/usb/usb_config.h1
4 files changed, 89 insertions, 76 deletions
diff --git a/libmaple/usb/usb.c b/libmaple/usb/usb.c
index 09b51ea..9755618 100644
--- a/libmaple/usb/usb.c
+++ b/libmaple/usb/usb.c
@@ -335,8 +335,7 @@ if (wIstr & ISTR_CTR & wInterrupt_Mask)
}
void usbWaitReset(void) {
- int count = program_delay*100000000;
- delay(program_delay*10);
+ delay(RESET_DELAY);
systemHardReset();
}
@@ -350,7 +349,7 @@ void usbWaitReset(void) {
*/
int16 usbSendBytes(uint8* sendBuf, uint16 len) {
- if (reset_state != START || bDeviceState != CONFIGURED) {
+ if (((line_dtr_rts & 0x02) != 0) || bDeviceState != CONFIGURED) {
return -1; /* indicates to caller to stop trying, were not connected */
}
diff --git a/libmaple/usb/usb_callbacks.c b/libmaple/usb/usb_callbacks.c
index cacfd02..4cdaf73 100644
--- a/libmaple/usb/usb_callbacks.c
+++ b/libmaple/usb/usb_callbacks.c
@@ -38,8 +38,8 @@ volatile uint8 recvBufIn = 0;
volatile uint8 recvBufOut = 0;
volatile uint8 maxNewBytes = VCOM_RX_EPSIZE;
-RESET_STATE reset_state = START;
-uint8 program_delay = 1;
+RESET_STATE reset_state = DTR_UNSET;
+uint8 line_dtr_rts = 0;
void vcomDataTxCb(void) {
/* do whatever after data has been sent to host */
@@ -63,44 +63,55 @@ void vcomDataRxCb(void) {
uint8 newBytes = GetEPRxCount(VCOM_RX_ENDP);
/* assert (newBytes <= maxNewBytes); */
+ /* todo, not checking very carefully for edge cases. USUALLY,
+ if we emit the reset pulse and send 4 bytes, then newBytes
+ should be 4. But its POSSIBLE that this would be violated
+ in some cases */
- 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.
+ /* magic number, {0x31, 0x45, 0x41, 0x46} is "1EAF" */
+ char chkBuf[4];
+ char cmpBuf[4] = {0x31, 0x45, 0x41, 0x46};
+ if (reset_state == DTR_NEGEDGE) {
+ reset_state = DTR_LOW;
+ if (newBytes >= 4) {
+ unsigned int target = (unsigned int)usbWaitReset | 0x1;
+
+ PMAToUserBufferCopy(chkBuf,VCOM_RX_ADDR,4);
+
+ int i;
+ USB_Bool cmpMatch = TRUE;
+ for (i=0; i<4; i++) {
+ if (chkBuf[i] != cmpBuf[i]) {
+ cmpMatch = FALSE;
+ }
+ }
+
+ if (cmpMatch) {
+ 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 */
+ }
+ }
}
@@ -256,40 +267,43 @@ RESULT usbNoDataSetup(u8 request) {
/* to reset the board, pull both dtr and rts low
then pulse dtr by itself */
new_signal = pInformation->USBwValues.bw.bb0 & (CONTROL_LINE_DTR | CONTROL_LINE_RTS);
+ line_dtr_rts = new_signal & 0x03;
+
switch (reset_state) {
/* no default, covered enum */
- case START:
- if (new_signal == 0) {
- reset_state = NDTR_NRTS;
- }
- break;
-
- case NDTR_NRTS:
- if (new_signal == CONTROL_LINE_DTR) {
- reset_state = DTR_NRTS;
- } else if (new_signal == 0) {
- reset_state = NDTR_NRTS;
- } else {
- reset_state = START;
- }
- break;
-
- case DTR_NRTS:
- if (new_signal == 0) {
- /* dont reset here, otherwise
- well likely crash the host! */
- reset_state = RESET_NOW;
- } else {
- reset_state = START;
- }
- break;
- case RESET_NEXT:
- reset_state = RESET_NOW;
+ case DTR_UNSET:
+ if ((new_signal & CONTROL_LINE_DTR) == 0 ) {
+ reset_state = DTR_LOW;
+ } else {
+ reset_state = DTR_HIGH;
+ }
break;
- case RESET_NOW:
- /* do nothing, wait for reset */
+
+ case DTR_HIGH:
+ if ((new_signal & CONTROL_LINE_DTR) == 0 ) {
+ reset_state = DTR_NEGEDGE;
+ } else {
+ reset_state = DTR_HIGH;
+ }
+ break;
+
+ case DTR_NEGEDGE:
+ if ((new_signal & CONTROL_LINE_DTR) == 0 ) {
+ reset_state = DTR_LOW;
+ } else {
+ reset_state = DTR_HIGH;
+ }
+ break;
+
+ case DTR_LOW:
+ if ((new_signal & CONTROL_LINE_DTR) == 0 ) {
+ reset_state = DTR_LOW;
+ } else {
+ reset_state = DTR_HIGH;
+ }
break;
}
+
return USB_SUCCESS;
}
}
diff --git a/libmaple/usb/usb_callbacks.h b/libmaple/usb/usb_callbacks.h
index d77a9fd..a94de11 100644
--- a/libmaple/usb/usb_callbacks.h
+++ b/libmaple/usb/usb_callbacks.h
@@ -26,15 +26,14 @@ typedef struct {
} USB_Line_Coding;
typedef enum {
- START,
- NDTR_NRTS,
- DTR_NRTS,
- RESET_NEXT,
- RESET_NOW
+ DTR_UNSET,
+ DTR_HIGH,
+ DTR_NEGEDGE,
+ DTR_LOW
} RESET_STATE;
extern RESET_STATE reset_state; /* tracks DTR/RTS */
-extern uint8 program_delay;
+extern uint8 line_dtr_rts;
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/libmaple/usb/usb_config.h b/libmaple/usb/usb_config.h
index e1eabb3..06c81ff 100644
--- a/libmaple/usb/usb_config.h
+++ b/libmaple/usb/usb_config.h
@@ -9,6 +9,7 @@
#define VCOM_ID_PRODUCT 0x0004
#define USB_CONFIG_MAX_POWER (100 >> 1)
+#define RESET_DELAY (100)
/* choose addresses to give endpoints the max 64 byte buffers */
#define USB_BTABLE_ADDRESS 0x00