From f8c33af1daa417875f8712dc737c00d289d0d514 Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 20 Nov 2018 10:58:32 +0100 Subject: [PATCH] CHG: FPC connector tests. Device -> Client communications works. Adjust armsrc/Makefile and client/Makefile to include the -DWITH_FPC flag to compile with FPC enabled. --- armsrc/appmain.c | 81 ++++++++++++++++++++------------ client/comms.c | 18 +++++--- common/cmd.c | 4 +- common/usart.c | 114 +++++++++++++++------------------------------- common/usart.h | 2 +- uart/uart_posix.c | 6 ++- uart/uart_win32.c | 17 ++++++- 7 files changed, 123 insertions(+), 119 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 60229868d..eed443599 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -628,7 +628,7 @@ void ListenReaderField(int limit) { void UsbPacketReceived(uint8_t *packet, int len) { UsbCommand *c = (UsbCommand *)packet; - //Dbprintf("received %d bytes, with command: 0x%04x and args: %d %d %d",len,c->cmd,c->arg[0],c->arg[1],c->arg[2]); + //Dbprintf("received %d bytes, with command: 0x%04x and args: %d %d %d", len, c->cmd, c->arg[0], c->arg[1], c->arg[2]); switch(c->cmd) { #ifdef WITH_LF @@ -1075,47 +1075,70 @@ void UsbPacketReceived(uint8_t *packet, int len) { #ifdef WITH_FPC case CMD_FPC_SEND: { + + StartTicks(); + DbpString("Mutual USB/FPC sending from device to client"); + + /* + char at[11] = {'\0'}; + static const char* s_at = "AT+BAUD8\0D\0A"; + strncat(at, s_at, sizeof(at) - strlen(at) - 1); + DbpString("Try AT baud rate setting"); + usart_init(); + int16_t res = usart_writebuffer((uint8_t*)&at, sizeof(at)); + WaitMS(1); + Dbprintf("SEND %d | %c%c%c%c%c%c%c%c%c%c%c", res, at[0], at[1], at[2], at[3], at[4], at[5], at[6], at[7], at[8], at[9], at[10]); + + uint8_t my_rx[20]; + memset(my_rx, 0, sizeof(my_rx)); + res = usart_readbuffer(my_rx, sizeof(my_rx)); + WaitMS(1); + Dbprintf("GOT %d | %c%c%c%c%c%c%c%c", res, my_rx[0], my_rx[1], my_rx[2], my_rx[3], my_rx[4], my_rx[5], my_rx[6], my_rx[7]); + */ + + char dest[USB_CMD_DATA_SIZE] = { '\0' }; - - static const char* welcome = "Proxmark3 Serial interface ready\n"; + static const char* welcome = "Proxmark3 Serial interface via FPC ready\n"; strncat(dest, welcome, sizeof(dest) - strlen(dest) - 1); - - sprintf(dest + strlen(dest) - 1, "| Arg0 0x%" PRIx64 " \n", c->arg[0]); - sprintf(dest + strlen(dest) - 1, "| Arg1 0x%" PRIx64 " \n", c->arg[1]); - sprintf(dest + strlen(dest) - 1, "| Arg2 0x%" PRIx64 " \n", c->arg[2]); sprintf(dest + strlen(dest) - 1, "| bytes 0x%02x 0x%02x 0x%02x 0x%02x \n" - ,c->d.asBytes[0], c->d.asBytes[1], c->d.asBytes[2], c->d.asBytes[3]); + , c->d.asBytes[0] + , c->d.asBytes[1] + , c->d.asBytes[2] + , c->d.asBytes[3] + ); + UsbCommand txcmd = { CMD_DEBUG_PRINT_STRING, { strlen(dest), 0, 0 } }; + memcpy(txcmd.d.asBytes, dest, sizeof(dest)); - UsbCommand txcmd; - for (size_t i=0; i < sizeof(UsbCommand); i++) - ((uint8_t*)&txcmd)[i] = 0x00; - - // Compose the outgoing command frame - txcmd.cmd = CMD_DEBUG_PRINT_STRING; - txcmd.arg[0] = strlen(dest); - txcmd.arg[1] = 0; - txcmd.arg[2] = 0; - memcpy(txcmd.d.asBytes, dest, USB_CMD_DATA_SIZE); - + LED_A_ON(); + usart_init(); usart_writebuffer((uint8_t*)&txcmd, sizeof(UsbCommand)); - - DbpString("Justs send to usart"); - LED_A_ON(); + + //usb + cmd_send(CMD_DEBUG_PRINT_STRING, strlen(dest), 0, 0, dest, strlen(dest)); + LED_A_OFF(); + + /* - uint8_t rx[sizeof(UsbCommand)]; - usart_init(); + uint8_t my_rx[sizeof(UsbCommand)]; while (!BUTTON_PRESS() && !usb_poll_validate_length()) { - WaitMS(1); - if (usart_readbuffer(rx, sizeof(rx)) ) - DbpString("got 544"); + LED_B_INV(); + if (usart_readbuffer(my_rx, sizeof(UsbCommand)) ) { + //UsbPacketReceived(my_rx, sizeof(my_rx)); + + UsbCommand *my = (UsbCommand *)my_rx; + if (mc->cmd > 0 ) { + Dbprintf("received command: 0x%04x and args: %d %d %d", my->cmd, my->arg[0], my->arg[1], my->arg[2]); + } + } } */ + //cmd_send(CMD_DEBUG_PRINT_STRING, strlen(dest), 0, 0, dest, strlen(dest)); - //DbpString("finished"); - LED_A_OFF(); + cmd_send(CMD_ACK,0,0,0,0,0); + StopTicks(); break; } #endif diff --git a/client/comms.c b/client/comms.c index 7204aa1c4..97af830df 100644 --- a/client/comms.c +++ b/client/comms.c @@ -146,7 +146,7 @@ static int getCommand(UsbCommand* response) { // that we weren't necessarily expecting, for example a debug print. //----------------------------------------------------------------------------- static void UsbCommandReceived(UsbCommand* c) { - + switch(c->cmd) { // First check if we are handling a debug message case CMD_DEBUG_PRINT_STRING: { @@ -237,7 +237,7 @@ __attribute__((force_align_arg_pointer)) #endif *uart_communication(void *targ) { communication_arg_t *conn = (communication_arg_t*)targ; - size_t rxlen; + size_t rxlen, totallen = 0; UsbCommand rx; UsbCommand *prx = ℞ @@ -247,22 +247,29 @@ __attribute__((force_align_arg_pointer)) disableAppNap("Proxmark3 polling UART"); #endif - while (conn->run) { rxlen = 0; bool ACK_received = false; + if (uart_receive(sp, (uint8_t *)prx, sizeof(UsbCommand) - (prx - &rx), &rxlen) && rxlen) { prx += rxlen; + totallen += rxlen; - if (prx - &rx < sizeof(UsbCommand)) { - PrintAndLogEx(NORMAL, "Foo %d | %d (will loop)", prx - &rx, rxlen); + if ( totallen < sizeof(UsbCommand)) { + + // iceman: this looping is no working as expected at all. The reassemble of package is nonfunctional. + // solved so far with increasing the timeouts of the serial port configuration. + PrintAndLogEx(NORMAL, "Foo %d | %d (loop)", prx - &rx, rxlen); continue; } + + totallen = 0; UsbCommandReceived(&rx); if (rx.cmd == CMD_ACK) { ACK_received = true; } } + prx = ℞ pthread_mutex_lock(&txBufferMutex); @@ -297,7 +304,6 @@ __attribute__((force_align_arg_pointer)) #if defined(__MACH__) && defined(__APPLE__) enableAppNap(); #endif - pthread_exit(NULL); return NULL; diff --git a/common/cmd.c b/common/cmd.c index 281ff0065..dec095750 100644 --- a/common/cmd.c +++ b/common/cmd.c @@ -56,8 +56,8 @@ uint8_t cmd_send(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void sendlen = usb_write( (uint8_t*)&txcmd, sizeof(UsbCommand) ); #ifdef WITH_FPC - usart_init(); - usart_writebuffer( (uint8_t*)&txcmd, sizeof(UsbCommand) ); +// usart_init(); +// usart_writebuffer( (uint8_t*)&txcmd, sizeof(UsbCommand) ); #endif return sendlen; diff --git a/common/usart.c b/common/usart.c index b58a7cbaa..32ccb5ca1 100644 --- a/common/usart.c +++ b/common/usart.c @@ -1,6 +1,6 @@ //----------------------------------------------------------------------------- // Iceman, July 2018 -// edists by - Anticat, August 2018 +// edits by - Anticat, August 2018 // // This code is licensed to you under the terms of the GNU GPL, version 2 or, // at your option, any later version. See the LICENSE.txt file for the text of @@ -14,7 +14,7 @@ #define AT91_BAUD_RATE 115200 volatile AT91PS_USART pUS1 = AT91C_BASE_US1; -volatile AT91PS_PIO pPIOA = AT91C_BASE_PIOA; +volatile AT91PS_PIO pPIO = AT91C_BASE_PIOA; volatile AT91PS_PDC pPDC = AT91C_BASE_PDC_US1; /* @@ -39,90 +39,53 @@ void usart_close(void) { } */ -static uint8_t outbuf[sizeof(UsbCommand)]; -//static uint8_t inbuf[sizeof(UsbCommand)]; - +static uint8_t us_outbuf[sizeof(UsbCommand)]; /// Reads data from an USART peripheral /// \param data Pointer to the buffer where the received data will be stored. /// \param len Size of the data buffer (in bytes). -inline int usart_readbuffer(uint8_t *data, size_t len) { +inline int16_t usart_readbuffer(uint8_t *data, size_t len) { - pUS1->US_PTSR = AT91C_PDC_TXTEN; - pUS1->US_PTCR = AT91C_PDC_TXTEN; - // Check if the first PDC bank is free if (!(pUS1->US_RCR)) { pUS1->US_RPR = (uint32_t)data; pUS1->US_RCR = len; + + pUS1->US_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTDIS; return 2; } // Check if the second PDC bank is free else if (!(pUS1->US_RNCR)) { pUS1->US_RNPR = (uint32_t)data; pUS1->US_RNCR = len; + + pUS1->US_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTDIS; return 1; } else { return 0; } - - /* - pPDC->PDC_PTSR = AT91C_PDC_RXTEN; - pPDC->PDC_PTCR = AT91C_PDC_RXTEN; - - //check if data is available - if (pPDC->PDC_RCR != 0) return -1; - - memcpy(data, inbuf, len); - - //start next transfer - pPDC->PDC_RNPR = (uint32_t)inbuf; - pPDC->PDC_RNCR = sizeof(inbuf); - - return sizeof(inbuf); - */ } -/* -int16_t usart_writebuffer(uint8_t *data, size_t len) { -// pUS1->US_PTSR = AT91C_PDC_TXTEN; - pUS1->US_PTCR = AT91C_PDC_TXTEN; - - // if buffer is sent - if (pUS1->US_TCR != 0) return -1; - - memcpy(outbuf, data, len); - //start next transfer - pUS1->US_TNPR = (uint32_t)outbuf; - pUS1->US_TNCR = sizeof(outbuf); - - return sizeof(outbuf); -} -*/ - -// works. -// transfer to client +// transfer from device to client inline int16_t usart_writebuffer(uint8_t *data, size_t len) { - pUS1->US_PTSR = AT91C_PDC_TXTEN; - pUS1->US_PTCR = AT91C_PDC_TXTEN; - // Check if the first PDC bank is free if (!(pUS1->US_TCR)) { - - memcpy(outbuf, data, len); - - pUS1->US_TPR = (uint32_t)outbuf; - pUS1->US_TCR = sizeof(outbuf); + memcpy(us_outbuf, data, len); + pUS1->US_TPR = (uint32_t)us_outbuf; + pUS1->US_TCR = sizeof(us_outbuf); + + pUS1->US_PTCR = AT91C_PDC_TXTEN | AT91C_PDC_RXTDIS; return 2; } // Check if the second PDC bank is free else if (!(pUS1->US_TNCR)) { - memcpy(outbuf, data, len); - - pUS1->US_TNPR = (uint32_t)outbuf; - pUS1->US_TNCR = sizeof(outbuf); + memcpy(us_outbuf, data, len); + pUS1->US_TNPR = (uint32_t)us_outbuf; + pUS1->US_TNCR = sizeof(us_outbuf); + + pUS1->US_PTCR = AT91C_PDC_TXTEN | AT91C_PDC_RXTDIS; return 1; } else { return 0; @@ -132,19 +95,20 @@ inline int16_t usart_writebuffer(uint8_t *data, size_t len) { void usart_init(void) { // disable & reset receiver / transmitter for configuration - pUS1->US_CR = (AT91C_US_RSTRX | AT91C_US_RSTTX); + pUS1->US_CR = (AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS | AT91C_US_TXDIS); //enable the USART1 Peripheral clock AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_US1); // disable PIO control of receive / transmit pins - pPIOA->PIO_PDR |= (AT91C_PA21_RXD1 | AT91C_PA22_TXD1); + pPIO->PIO_PDR |= (AT91C_PA21_RXD1 | AT91C_PA22_TXD1); // enable peripheral mode A on receive / transmit pins - pPIOA->PIO_ASR |= (AT91C_PA21_RXD1 | AT91C_PA22_TXD1); + pPIO->PIO_ASR |= (AT91C_PA21_RXD1 | AT91C_PA22_TXD1); + pPIO->PIO_BSR = 0; // enable pull-up on receive / transmit pins (see 31.5.1 I/O Lines) - pPIOA->PIO_PPUER |= (AT91C_PA21_RXD1 | AT91C_PA22_TXD1); + pPIO->PIO_PPUER |= (AT91C_PA21_RXD1 | AT91C_PA22_TXD1); // set mode pUS1->US_MR = AT91C_US_USMODE_NORMAL | // normal mode @@ -154,8 +118,19 @@ void usart_init(void) { AT91C_US_NBSTOP_1_BIT | // 1 stop bit AT91C_US_CHMODE_NORMAL; // channel mode: normal + // all interrupts disabled + pUS1->US_IDR = 0xFFFF; + + // iceman, setting 115200 doesn't work. Only speed I got to work is 9600. + // something fishy with the AT91SAM7S512 USART.. Or I missed something + // For a nice detailed sample, interrupt driven but still relevant. + // See https://www.sparkfun.com/datasheets/DevTools/SAM7/at91sam7%20serial%20communications.pdf + // set baudrate to 115200 - pUS1->US_BRGR = (48UL*1000*1000) / (115200*16); + // 115200 * 16 == 1843200 + // + //pUS1->US_BRGR = (48UL*1000*1000) / (9600*16); + pUS1->US_BRGR = 48054841 / (9600 << 4); // Write the Timeguard Register pUS1->US_TTGR = 0; @@ -163,23 +138,6 @@ void usart_init(void) { pUS1->US_FIDI = 0; pUS1->US_IF = 0; - /* - //Empty PDC - pUS1->US_RNPR = (uint32_t)(char *)0; - pUS1->US_RNCR = 0; - pUS1->US_RPR = (uint32_t)(char *)0; - pUS1->US_RCR = 0; - - pUS1->US_TNPR = (uint32_t)(char *)0; - pUS1->US_TNCR = 0; - pUS1->US_TPR = (uint32_t)(char *)0; - pUS1->US_TCR = 0; - */ - - //pUS1->US_PTCR = (AT91C_PDC_RXTEN | AT91C_PDC_TXTEN); - //pUS1->US_PTSR = (AT91C_PDC_RXTEN | AT91C_PDC_TXTEN); - // re-enable receiver / transmitter pUS1->US_CR = (AT91C_US_RXEN | AT91C_US_TXEN); - } \ No newline at end of file diff --git a/common/usart.h b/common/usart.h index 271a24ba4..7e8d3eb7b 100644 --- a/common/usart.h +++ b/common/usart.h @@ -7,6 +7,6 @@ void usart_init(void); void usart_close(void); -int usart_readbuffer(uint8_t *data, size_t len); +int16_t usart_readbuffer(uint8_t *data, size_t len); int16_t usart_writebuffer(uint8_t *data, size_t len); #endif diff --git a/uart/uart_posix.c b/uart/uart_posix.c index 20a577ded..b587d6546 100644 --- a/uart/uart_posix.c +++ b/uart/uart_posix.c @@ -118,8 +118,12 @@ serial_port uart_open(const char* pcPortName) tcflush(sp->fd, TCIOFLUSH); #ifdef WITH_FPC - uart_set_speed(sp, 115200); + if ( uart_set_speed(sp, 115200) ) { printf("[=] UART Setting serial baudrate 115200 [FPC enabled]\n"); + } else { + uart_set_speed(sp, 9600); + printf("[=] UART Setting serial baudrate 9600 [FPC enabled]\n"); + } #else // set speed, works for UBUNTU 14.04 bool success = uart_set_speed(sp, 460800); diff --git a/uart/uart_win32.c b/uart/uart_win32.c index eef350cda..11c90f15f 100644 --- a/uart/uart_win32.c +++ b/uart/uart_win32.c @@ -86,12 +86,20 @@ serial_port uart_open(const char* pcPortName) { } // all zero's configure: no timeout for read/write used. // took settings from libnfc/buses/uart.c +#ifdef WITH_FPC + sp->ct.ReadIntervalTimeout = 1000; + sp->ct.ReadTotalTimeoutMultiplier = 0; + sp->ct.ReadTotalTimeoutConstant = 1500; + sp->ct.WriteTotalTimeoutMultiplier = 1000; + sp->ct.WriteTotalTimeoutConstant = 0; +#else sp->ct.ReadIntervalTimeout = 30; sp->ct.ReadTotalTimeoutMultiplier = 0; sp->ct.ReadTotalTimeoutConstant = 30; sp->ct.WriteTotalTimeoutMultiplier = 30; sp->ct.WriteTotalTimeoutConstant = 0; - +#endif + if (!SetCommTimeouts(sp->hPort, &sp->ct)) { uart_close(sp); printf("[!] UART error while setting comm time outs\n"); @@ -101,7 +109,12 @@ serial_port uart_open(const char* pcPortName) { PurgeComm(sp->hPort, PURGE_RXABORT | PURGE_RXCLEAR); #ifdef WITH_FPC - uart_set_speed(sp, 115200); + if ( uart_set_speed(sp, 115200) ) { + printf("[=] UART Setting serial baudrate 115200 [FPC enabled]\n"); + } else { + uart_set_speed(sp, 9600); + printf("[=] UART Setting serial baudrate 9600 [FPC enabled]\n"); + } #else bool success = uart_set_speed(sp, 460800); if (success) {