From e0c9e2b0d161a720bcbceff67e8662acc5cd3a70 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 22 May 2019 23:30:52 +0200 Subject: [PATCH] rework usart RX timings --- armsrc/appmain.c | 46 +++++++++++++++++++++++++++++++++++++++------- armsrc/ticks.c | 7 +++++++ armsrc/ticks.h | 1 + client/cmdusart.c | 30 +++++++++++++++++++++++------- 4 files changed, 70 insertions(+), 14 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index bf5db7598..78c9a8571 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1226,9 +1226,29 @@ static void PacketReceived(PacketCommandNG *packet) { } case CMD_USART_RX: { LED_B_ON(); + struct p { + uint32_t waittime; + } PACKED; + struct p *payload = (struct p *) &packet->data.asBytes; + uint16_t available; + uint16_t pre_available = 0; uint8_t *dest = BigBuf_malloc(USART_FIFOLEN); - uint16_t available = usart_rxdata_available(); - + uint32_t wait = payload->waittime; + uint32_t ti = GetTickCount(); + while (true) { + WaitMS(50); + available = usart_rxdata_available(); + if (available > pre_available) { + // When receiving data, reset timer and shorten timeout + ti = GetTickCount(); + wait = 50; + pre_available = available; + continue; + } + // We stop either after waittime if no data or 50ms after last data received + if (GetTickCountDelta(ti) > wait) + break; + } if (available > 0) { uint16_t len = usart_read_ng(dest, available); reply_ng(CMD_USART_RX, PM3_SUCCESS, dest, len); @@ -1248,12 +1268,24 @@ static void PacketReceived(PacketCommandNG *packet) { struct p *payload = (struct p *) &packet->data.asBytes; usart_writebuffer_sync(payload->data, packet->length - sizeof(payload->waittime)); uint16_t available; - WaitMS(payload->waittime); - + uint16_t pre_available = 0; uint8_t *dest = BigBuf_malloc(USART_FIFOLEN); - - available = usart_rxdata_available(); - // Dbprintf("avail (%u)", available); + uint32_t wait = payload->waittime; + uint32_t ti = GetTickCount(); + while (true) { + WaitMS(50); + available = usart_rxdata_available(); + if (available > pre_available) { + // When receiving data, reset timer and shorten timeout + ti = GetTickCount(); + wait = 50; + pre_available = available; + continue; + } + // We stop either after waittime if no data or 50ms after last data received + if (GetTickCountDelta(ti) > wait) + break; + } if (available > 0) { uint16_t len = usart_read_ng(dest, available); reply_ng(CMD_USART_TXRX, PM3_SUCCESS, dest, len); diff --git a/armsrc/ticks.c b/armsrc/ticks.c index 73f68147f..7ece25b93 100644 --- a/armsrc/ticks.c +++ b/armsrc/ticks.c @@ -62,6 +62,13 @@ uint32_t RAMFUNC GetTickCount(void) { return AT91C_BASE_RTTC->RTTC_RTVR;// was * 2; } +uint32_t RAMFUNC GetTickCountDelta(uint32_t start_ticks) { + uint32_t stop_ticks = AT91C_BASE_RTTC->RTTC_RTVR; + if (stop_ticks > start_ticks) + return stop_ticks - start_ticks; + return (UINT32_MAX - start_ticks) + stop_ticks; +} + // ------------------------------------------------------------------------- // microseconds timer // ------------------------------------------------------------------------- diff --git a/armsrc/ticks.h b/armsrc/ticks.h index c6715e177..9ff0d6000 100644 --- a/armsrc/ticks.h +++ b/armsrc/ticks.h @@ -27,6 +27,7 @@ void SpinDelayUs(int us); void StartTickCount(void); uint32_t RAMFUNC GetTickCount(void); +uint32_t RAMFUNC GetTickCountDelta(uint32_t start_ticks); void StartCountUS(void); uint32_t RAMFUNC GetCountUS(void); diff --git a/client/cmdusart.c b/client/cmdusart.c index e5261c79c..a13aa7a6c 100644 --- a/client/cmdusart.c +++ b/client/cmdusart.c @@ -75,12 +75,13 @@ static int usage_usart_txhex(void) { } static int usage_usart_rx(void) { - PrintAndLogEx(NORMAL, "Receive string over USART"); + PrintAndLogEx(NORMAL, "Receive string over USART [t ]"); PrintAndLogEx(NORMAL, _RED_("WARNING: it will have side-effects if used in USART HOST mode!")); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Usage: usart rx [h]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h This help"); + PrintAndLogEx(NORMAL, " t timeout in ms, default is 0ms"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "expected output: Received string"); return PM3_SUCCESS; @@ -90,9 +91,10 @@ static int usage_usart_rxhex(void) { PrintAndLogEx(NORMAL, "Receive bytes over USART"); PrintAndLogEx(NORMAL, _RED_("WARNING: it will have side-effects if used in USART HOST mode!")); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: usart rx [h]"); + PrintAndLogEx(NORMAL, "Usage: usart rxhex [h] [t ]"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h This help"); + PrintAndLogEx(NORMAL, " t timeout in ms, default is 0ms"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "expected output: Received bytes"); return PM3_SUCCESS; @@ -147,11 +149,15 @@ static int usart_tx(uint8_t *data, size_t len) { return resp.status; } -static int usart_rx(uint8_t *data, size_t *len) { +static int usart_rx(uint8_t *data, size_t *len, uint32_t waittime) { clearCommandBuffer(); - SendCommandNG(CMD_USART_RX, NULL, 0); + struct { + uint32_t waittime; + } PACKED payload; + payload.waittime = waittime; + SendCommandNG(CMD_USART_RX, (uint8_t *)&payload, sizeof(payload)); PacketResponseNG resp; - if (!WaitForResponseTimeout(CMD_USART_RX, &resp, 1000)) { + if (!WaitForResponseTimeout(CMD_USART_RX, &resp, waittime + 500)) { return PM3_ETIMEOUT; } if (resp.status == PM3_SUCCESS) { @@ -580,10 +586,15 @@ static int CmdUsartTX(const char *Cmd) { static int CmdUsartRX(const char *Cmd) { uint8_t cmdp = 0; bool errors = false; + uint32_t waittime = 0; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': return usage_usart_rx(); + case 't': + waittime = param_get32ex(Cmd, cmdp + 1, 0, 10); + cmdp += 2; + break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; @@ -597,7 +608,7 @@ static int CmdUsartRX(const char *Cmd) { } uint8_t data[PM3_CMD_DATA_SIZE] = {0x00}; size_t len = 0; - int ret = usart_rx(data, &len); + int ret = usart_rx(data, &len, waittime); if (ret != PM3_SUCCESS) return ret; PrintAndLogEx(NORMAL, "RX:%.*s", len, data); @@ -709,10 +720,15 @@ static int CmdUsartTXhex(const char *Cmd) { static int CmdUsartRXhex(const char *Cmd) { uint8_t cmdp = 0; bool errors = false; + uint32_t waittime = 0; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': return usage_usart_rxhex(); + case 't': + waittime = param_get32ex(Cmd, cmdp + 1, 0, 10); + cmdp += 2; + break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = true; @@ -727,7 +743,7 @@ static int CmdUsartRXhex(const char *Cmd) { uint8_t data[PM3_CMD_DATA_SIZE] = {0x00}; size_t len = 0; - int ret = usart_rx(data, &len); + int ret = usart_rx(data, &len, waittime); if (ret != PM3_SUCCESS) return ret;