diff --git a/armsrc/appmain.c b/armsrc/appmain.c index f68739da2..310aa6a0d 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -2051,11 +2051,16 @@ static void PacketReceived(PacketCommandNG *packet) { } PACKED; struct p *payload = (struct p *) &packet->data.asBytes; usart_writebuffer_sync(payload->data, packet->length - sizeof(payload)); + uint16_t available; uint16_t pre_available = 0; uint8_t *dest = BigBuf_malloc(USART_FIFOLEN); uint32_t wait = payload->waittime; + + StartTicks(); + uint32_t ti = GetTickCount(); + while (true) { WaitMS(50); available = usart_rxdata_available(); @@ -2070,12 +2075,15 @@ static void PacketReceived(PacketCommandNG *packet) { 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); } else { reply_ng(CMD_USART_TXRX, PM3_ENODATA, NULL, 0); } + + StopTicks(); BigBuf_free(); LED_B_OFF(); break; @@ -2718,9 +2726,6 @@ void __attribute__((noreturn)) AppMain(void) { } #endif -#ifdef WITH_FPC_USART - usart_init(USART_BAUD_RATE, USART_PARITY); -#endif #ifdef WITH_FLASH // If flash is not present, BUSY_TIMEOUT kicks in, let's do it after USB @@ -2733,6 +2738,10 @@ void __attribute__((noreturn)) AppMain(void) { rdv40_spiffs_check(); #endif +#ifdef WITH_FPC_USART + usart_init(USART_BAUD_RATE, USART_PARITY); +#endif + // This is made as late as possible to ensure enumeration without timeout // against device such as http://www.hobbytronics.co.uk/usb-host-board-v2 // In other words, keep the interval between usb_enable() and the main loop as short as possible. diff --git a/armsrc/usart.c b/armsrc/usart.c index f92e9c701..915d4a445 100644 --- a/armsrc/usart.c +++ b/armsrc/usart.c @@ -46,8 +46,8 @@ void usart_close(void) { } */ -static uint8_t us_inbuf1[USART_BUFFLEN]; -static uint8_t us_inbuf2[USART_BUFFLEN]; +static uint8_t us_in_a[USART_BUFFLEN]; +static uint8_t us_in_b[USART_BUFFLEN]; static uint8_t *usart_cur_inbuf = NULL; static uint16_t usart_cur_inbuf_off = 0; static uint8_t us_rxfifo[USART_FIFOLEN]; @@ -56,7 +56,9 @@ static size_t us_rxfifo_high = 0; static void usart_fill_rxfifo(void) { - uint16_t rxfifo_free ; + + uint16_t rxfifo_free = 0; + if (pUS1->US_RNCR == 0) { // One buffer got filled, backup buffer being used if (us_rxfifo_low > us_rxfifo_high) @@ -79,19 +81,22 @@ static void usart_fill_rxfifo(void) { pUS1->US_RNCR = USART_BUFFLEN; // Swap current buff - if (usart_cur_inbuf == us_inbuf1) - usart_cur_inbuf = us_inbuf2; + if (usart_cur_inbuf == us_in_a) + usart_cur_inbuf = us_in_b; else - usart_cur_inbuf = us_inbuf1; + usart_cur_inbuf = us_in_a; usart_cur_inbuf_off = 0; } else { // Take only what we have room for available = rxfifo_free; for (uint16_t i = 0; i < available; i++) { + us_rxfifo[us_rxfifo_high++] = usart_cur_inbuf[usart_cur_inbuf_off + i]; - if (us_rxfifo_high == sizeof(us_rxfifo)) + + if (us_rxfifo_high == sizeof(us_rxfifo)) { us_rxfifo_high = 0; + } } usart_cur_inbuf_off += available; return; @@ -101,18 +106,20 @@ static void usart_fill_rxfifo(void) { if (pUS1->US_RCR < USART_BUFFLEN - usart_cur_inbuf_off) { // Current buffer partially filled if (us_rxfifo_low > us_rxfifo_high) - rxfifo_free = us_rxfifo_low - us_rxfifo_high; + rxfifo_free = (us_rxfifo_low - us_rxfifo_high); else - rxfifo_free = sizeof(us_rxfifo) - us_rxfifo_high + us_rxfifo_low; + rxfifo_free = (sizeof(us_rxfifo) - us_rxfifo_high + us_rxfifo_low); - uint16_t available = USART_BUFFLEN - pUS1->US_RCR - usart_cur_inbuf_off; + uint16_t available = (USART_BUFFLEN - pUS1->US_RCR - usart_cur_inbuf_off); if (available > rxfifo_free) available = rxfifo_free; + for (uint16_t i = 0; i < available; i++) { us_rxfifo[us_rxfifo_high++] = usart_cur_inbuf[usart_cur_inbuf_off + i]; - if (us_rxfifo_high == sizeof(us_rxfifo)) + if (us_rxfifo_high == sizeof(us_rxfifo)) { us_rxfifo_high = 0; + } } usart_cur_inbuf_off += available; } @@ -121,9 +128,9 @@ static void usart_fill_rxfifo(void) { uint16_t usart_rxdata_available(void) { usart_fill_rxfifo(); if (us_rxfifo_low <= us_rxfifo_high) - return us_rxfifo_high - us_rxfifo_low; + return (us_rxfifo_high - us_rxfifo_low); else - return sizeof(us_rxfifo) - us_rxfifo_low + us_rxfifo_high; + return (sizeof(us_rxfifo) - us_rxfifo_low + us_rxfifo_high); } uint32_t usart_read_ng(uint8_t *data, size_t len) { @@ -143,9 +150,10 @@ uint32_t usart_read_ng(uint8_t *data, size_t len) { uint32_t maxtry = 10 * (3000000 / USART_BAUD_RATE) + tryconstant; while (len) { - uint32_t available = usart_rxdata_available(); + uint32_t available = usart_rxdata_available(); uint32_t packetSize = MIN(available, len); + if (available > 0) { // Dbprintf_usb("Dbg USART ask %d bytes, available %d bytes, packetsize %d bytes", len, available, packetSize); // highest_observed_try = MAX(highest_observed_try, try); @@ -153,8 +161,9 @@ uint32_t usart_read_ng(uint8_t *data, size_t len) { } len -= packetSize; while (packetSize--) { - if (us_rxfifo_low == sizeof(us_rxfifo)) + if (us_rxfifo_low == sizeof(us_rxfifo)) { us_rxfifo_low = 0; + } data[bytes_rcv++] = us_rxfifo[us_rxfifo_low++]; } if (try++ == maxtry) { @@ -183,10 +192,13 @@ int usart_writebuffer_sync(uint8_t *data, size_t len) { void usart_init(uint32_t baudrate, uint8_t parity) { - if (baudrate != 0) + if (baudrate != 0) { g_usart_baudrate = baudrate; - if ((parity == 'N') || (parity == 'O') || (parity == 'E')) + } + + if ((parity == 'N') || (parity == 'O') || (parity == 'E')) { g_usart_parity = parity; + } // For a nice detailed sample, interrupt driven but still relevant. // See https://www.sparkfun.com/datasheets/DevTools/SAM7/at91sam7%20serial%20communications.pdf @@ -262,11 +274,11 @@ void usart_init(uint32_t baudrate, uint8_t parity) { pUS1->US_TCR = 0; pUS1->US_TNPR = (uint32_t)0; pUS1->US_TNCR = 0; - pUS1->US_RPR = (uint32_t)us_inbuf1; + pUS1->US_RPR = (uint32_t)us_in_a; pUS1->US_RCR = USART_BUFFLEN; - usart_cur_inbuf = us_inbuf1; + usart_cur_inbuf = us_in_a; usart_cur_inbuf_off = 0; - pUS1->US_RNPR = (uint32_t)us_inbuf2; + pUS1->US_RNPR = (uint32_t)us_in_b; pUS1->US_RNCR = USART_BUFFLEN; // Initialize our fifo diff --git a/client/src/comms.c b/client/src/comms.c index a8ed8be4c..64bea9f65 100644 --- a/client/src/comms.c +++ b/client/src/comms.c @@ -30,8 +30,8 @@ #include "util_posix.h" // msclock #include "util_darwin.h" // en/dis-ableNapp(); -//#define COMMS_DEBUG -//#define COMMS_DEBUG_RAW +// #define COMMS_DEBUG +// #define COMMS_DEBUG_RAW // Serial port that we are communicating with the PM3 on. static serial_port sp = NULL; @@ -369,6 +369,7 @@ __attribute__((force_align_arg_pointer)) } res = uart_receive(sp, (uint8_t *)&rx_raw.pre, sizeof(PacketResponseNGPreamble), &rxlen); + if ((res == PM3_SUCCESS) && (rxlen == sizeof(PacketResponseNGPreamble))) { rx.magic = rx_raw.pre.magic; uint16_t length = rx_raw.pre.length; @@ -380,6 +381,7 @@ __attribute__((force_align_arg_pointer)) PrintAndLogEx(WARNING, "Received packet frame with incompatible length: 0x%04x", length); error = true; } + if ((!error) && (length > 0)) { // Get the variable length payload res = uart_receive(sp, (uint8_t *)&rx_raw.data, length, &rxlen); @@ -418,10 +420,10 @@ __attribute__((force_align_arg_pointer)) rx.length = 0; // set received length to 0 else { // old frames can't be empty PrintAndLogEx(WARNING, "Received empty MIX packet frame (length: 0x00)"); - error = true; } } + if (!error) { // Get the postamble res = uart_receive(sp, (uint8_t *)&rx_raw.foopost, sizeof(PacketResponseNGPostamble), &rxlen); if ((res != PM3_SUCCESS) || (rxlen != sizeof(PacketResponseNGPostamble))) { @@ -429,6 +431,7 @@ __attribute__((force_align_arg_pointer)) error = true; } } + if (!error) { // Check CRC, accept MAGIC as placeholder rx.crc = rx_raw.foopost.crc; if (rx.crc != RESPONSENG_POSTAMBLE_MAGIC) {