[app][mdebug] avoid getting stuck if IN ACK is lost

If the host receives the IN response packet but the ACK from the host
is lost, we'd be stuck until the next IN, which wouldn't come because
the host does a simple send-request / read-response thing.  Instead,
don't wait for IN txns to complete unless there's already one outstanding.

This allows us to read the next request, at which point the host will
start an IN txn for the response, which will cause the previous IN txn
to complete.
This commit is contained in:
Brian Swetland
2015-08-02 19:27:47 -07:00
parent 70a0631c5f
commit 148308cfcd
2 changed files with 35 additions and 5 deletions

View File

@@ -31,7 +31,9 @@
#include "swd.h"
static event_t txevt = EVENT_INITIAL_VALUE(txevt, 0, 0);
#define TX_AHEAD 1
static event_t txevt = EVENT_INITIAL_VALUE(txevt, TX_AHEAD, 0);
static event_t rxevt = EVENT_INITIAL_VALUE(rxevt, 0, 0);
static udc_request_t *txreq;
@@ -63,22 +65,45 @@ static void tx_complete(udc_request_t *req, unsigned actual, int status) {
event_signal(&txevt, 0);
}
#if TX_AHEAD
void usb_xmit(void *data, unsigned len) {
//printf(">%d>\n", len);
event_wait(&txevt);
event_unsignal(&txevt);
txreq->buffer = data;
txreq->length = len;
txstatus = 1;
udc_request_queue(txept, txreq);
//printf(">%d>QUEUED\n", len);
}
#else
void usb_xmit(void *data, unsigned len) {
//printf(">%d>\n", len);
event_unsignal(&txevt);
txreq->buffer = data;
txreq->length = len;
txstatus = 1;
udc_request_queue(txept, txreq);
event_wait(&txevt);
//printf(">%d>%s\n", len, txstatus ? "ERR" : "");
}
#endif
unsigned usb_recv(void *data, unsigned len) {
//printf("<%d<\n", len);
event_unsignal(&rxevt);
rxreq->buffer = data;
rxreq->length = len;
rxstatus = 1;
udc_request_queue(rxept, rxreq);
event_wait(&rxevt);
#if 0
if (rxstatus) {
printf("<%d<ERR\n", len);
} else {
printf("<%d<%d\n", len, rxactual);
}
#endif
return rxactual;
}

View File

@@ -163,11 +163,15 @@ done:
}
}
static u32 rxbuffer[1024];
static u32 txbuffer[1024+1];
// io buffers in AHB SRAM
static u32 *rxbuffer = (void*) 0x20001000;
static u32 *txbuffer[2] = {(void*) 0x20003000, (void*) 0x20005000 };
#include <kernel/thread.h>
void handle_rswd(void) {
int rxc;
int toggle = 0;
#if CONFIG_MDEBUG_TRACE
printf("[ rswdp agent v0.9 ]\n");
@@ -175,7 +179,7 @@ void handle_rswd(void) {
#endif
for (;;) {
rxc = usb_recv(rxbuffer, sizeof(rxbuffer));
rxc = usb_recv(rxbuffer, 4096);
#if CONFIG_MDEBUG_TRACE
int n;
@@ -199,6 +203,7 @@ void handle_rswd(void) {
continue;
}
process_txn(rxbuffer[0], rxbuffer + 1, rxc - 1, txbuffer);
process_txn(rxbuffer[0], rxbuffer + 1, rxc - 1, txbuffer[toggle]);
toggle ^= 1;
}
}