[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:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user