mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-03-03 19:43:09 +08:00
usart working... when debugged...
This commit is contained in:
parent
7ca1e98776
commit
6e744043f5
9 changed files with 162 additions and 118 deletions
|
@ -1106,16 +1106,17 @@ static void PacketReceived(PacketCommandNG *packet) {
|
|||
|
||||
uint8_t my_rx[20];
|
||||
memset(my_rx, 0, sizeof(my_rx));
|
||||
res = usart_readbuffer(my_rx, sizeof(my_rx));
|
||||
res = usart_readbuffer(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'};
|
||||
if (usart_dataavailable()) {
|
||||
char dest[USART_FIFOLEN] = {'\0'};
|
||||
uint16_t available = usart_rxdata_available();
|
||||
if (available > 0) {
|
||||
Dbprintf("RX DATA!");
|
||||
uint16_t len = usart_readbuffer((uint8_t *)dest);
|
||||
uint16_t len = usart_read_ng((uint8_t *)dest, available);
|
||||
dest[len] = '\0';
|
||||
Dbprintf("RX: %d | %02X %02X %02X %02X %02X %02X %02X %02X ", len, dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
|
||||
}
|
||||
|
@ -1142,7 +1143,7 @@ static void PacketReceived(PacketCommandNG *packet) {
|
|||
uint8_t my_rx[sizeof(PacketCommandOLD)];
|
||||
while (!BUTTON_PRESS() && !usb_poll_validate_length()) {
|
||||
LED_B_INV();
|
||||
if (usart_readbuffer(my_rx) ) {
|
||||
if (usart_read_ng(my_rx) ) {
|
||||
//PacketReceived(my_rx, sizeof(my_rx));
|
||||
|
||||
PacketCommandOLD *my = (PacketCommandOLD *)my_rx;
|
||||
|
@ -1568,7 +1569,7 @@ void __attribute__((noreturn)) AppMain(void) {
|
|||
if (ret == PM3_SUCCESS) {
|
||||
PacketReceived(&rx);
|
||||
} else if (ret != PM3_ENODATA) {
|
||||
Dbprintf("Error in frame reception");
|
||||
Dbprintf("Error in frame reception: %d", ret);
|
||||
// TODO DOEGOX if error, shall we resync ?
|
||||
}
|
||||
|
||||
|
|
|
@ -563,6 +563,21 @@ void CloseProxmark(void) {
|
|||
memset(&USB_communication_thread, 0, sizeof(pthread_t));
|
||||
}
|
||||
|
||||
// Gives a rough estimate of the communication delay based on channel & baudrate
|
||||
// Max communication delay is when sending largest frame and receiving largest frame
|
||||
// Empirical measures on FTDI with physical cable:
|
||||
// "hw pingng 512"
|
||||
// usb -> 6..32ms
|
||||
// 460800 -> 40..70ms
|
||||
// 9600 -> 1100..1150ms
|
||||
// ~ = 12000000 / USART_BAUD_RATE
|
||||
// Let's take 2x (maybe we need more for BT link?)
|
||||
static size_t communication_delay(void) {
|
||||
if (send_via_fpc) // needed also for Windows USB USART??
|
||||
return 2 * (12000000 / uart_speed);
|
||||
return 100;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Waits for a certain response type. This method waits for a maximum of
|
||||
* ms_timeout milliseconds for a specified response command.
|
||||
|
@ -580,14 +595,18 @@ bool WaitForResponseTimeoutW(uint32_t cmd, PacketResponseNG *response, size_t ms
|
|||
if (response == NULL)
|
||||
response = &resp;
|
||||
|
||||
// Add delay depending on the communication channel & speed
|
||||
ms_timeout += communication_delay();
|
||||
uint64_t start_time = msclock();
|
||||
|
||||
// Wait until the command is received
|
||||
while (true) {
|
||||
|
||||
while (getReply(response)) {
|
||||
if (cmd == CMD_UNKNOWN || response->cmd == cmd)
|
||||
if (cmd == CMD_UNKNOWN || response->cmd == cmd) {
|
||||
// PrintAndLogEx(INFO, "Waited %i ms", msclock() - start_time);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (msclock() - start_time > ms_timeout)
|
||||
|
@ -600,6 +619,7 @@ bool WaitForResponseTimeoutW(uint32_t cmd, PacketResponseNG *response, size_t ms
|
|||
show_warning = false;
|
||||
}
|
||||
}
|
||||
// PrintAndLogEx(INFO, "Wait timeout after %i ms", msclock() - start_time);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -431,7 +431,7 @@ int main(int argc, char *argv[]) {
|
|||
if (speed == 0)
|
||||
#ifdef WITH_FPC_HOST
|
||||
// Let's assume we're talking by default to pm3 over usart in this mode
|
||||
speed = AT91_BAUD_RATE;
|
||||
speed = USART_BAUD_RATE;
|
||||
#else
|
||||
speed = 460800;
|
||||
#endif
|
||||
|
|
|
@ -227,8 +227,8 @@ int16_t receive_ng(PacketCommandNG *rx) {
|
|||
|
||||
#ifdef WITH_FPC_HOST
|
||||
// Check if there is a FPC packet available
|
||||
return receive_ng_internal(rx, usart_read_ng, true);
|
||||
#else
|
||||
return PM3_ENODATA;
|
||||
if (usart_rxdata_available() > 0)
|
||||
return receive_ng_internal(rx, usart_read_ng, true);
|
||||
#endif
|
||||
return PM3_ENODATA;
|
||||
}
|
||||
|
|
204
common/usart.c
204
common/usart.c
|
@ -38,119 +38,123 @@ void usart_close(void) {
|
|||
}
|
||||
*/
|
||||
|
||||
static uint8_t us_inbuf[sizeof(PacketCommandOLD)];
|
||||
static uint8_t us_outbuf[sizeof(PacketResponseOLD)];
|
||||
/*
|
||||
// transfer from client to device
|
||||
inline int16_t usart_readbuffer(uint8_t *data) {
|
||||
uint32_t rcr = pUS1->US_RCR;
|
||||
if (rcr < sizeof(us_inbuf)) {
|
||||
pUS1->US_PTCR = AT91C_PDC_RXTDIS;
|
||||
memcpy(data, us_inbuf, sizeof(us_inbuf) - rcr);
|
||||
// Reset DMA buffer
|
||||
pUS1->US_RPR = (uint32_t)us_inbuf;
|
||||
pUS1->US_RCR = sizeof(us_inbuf);
|
||||
pUS1->US_PTCR = AT91C_PDC_RXTEN;
|
||||
return sizeof(us_inbuf) - rcr;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
*/
|
||||
static uint8_t us_inbuf1[USART_BUFFLEN];
|
||||
static uint8_t us_inbuf2[USART_BUFFLEN];
|
||||
uint8_t *usart_cur_inbuf = NULL;
|
||||
uint16_t usart_cur_inbuf_off = 0;
|
||||
static uint8_t us_rxfifo[USART_FIFOLEN];
|
||||
static size_t us_rxfifo_low = 0;
|
||||
static size_t us_rxfifo_high = 0;
|
||||
|
||||
uint8_t check = 0;
|
||||
inline int16_t usart_readbuffer(uint8_t *data) {
|
||||
// Check if the first PDC bank is free
|
||||
if (pUS1->US_RCR == 0) {
|
||||
pUS1->US_RPR = (uint32_t)data;
|
||||
pUS1->US_RCR = sizeof(PacketCommandOLD);
|
||||
pUS1->US_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTEN;
|
||||
check = 0;
|
||||
return 2;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void usart_readcheck(uint8_t *data, size_t len) {
|
||||
if (pUS1->US_RCR < len) {
|
||||
if (check == 0) {
|
||||
StartCountUS();
|
||||
check = 1;
|
||||
static void usart_fill_rxfifo(void) {
|
||||
if (pUS1->US_RNCR == 0) { // One buffer got filled, backup buffer being used
|
||||
// TODO check if we have room...
|
||||
uint16_t available = USART_BUFFLEN - usart_cur_inbuf_off;
|
||||
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))
|
||||
us_rxfifo_high = 0;
|
||||
}
|
||||
//300ms
|
||||
if (GetCountUS() > 300000) {
|
||||
pUS1->US_RPR = (uint32_t)data;
|
||||
pUS1->US_RCR = len;
|
||||
check = 0;
|
||||
// Give next buffer
|
||||
pUS1->US_RNPR = (uint32_t)usart_cur_inbuf;
|
||||
pUS1->US_RNCR = USART_BUFFLEN;
|
||||
// Swap current buff
|
||||
if (usart_cur_inbuf == us_inbuf1)
|
||||
usart_cur_inbuf = us_inbuf2;
|
||||
else
|
||||
usart_cur_inbuf = us_inbuf1;
|
||||
usart_cur_inbuf_off = 0;
|
||||
}
|
||||
if (pUS1->US_RCR < USART_BUFFLEN - usart_cur_inbuf_off) { // Current buffer partially filled
|
||||
uint16_t available = USART_BUFFLEN - pUS1->US_RCR - usart_cur_inbuf_off;
|
||||
// TODO check if we have room...
|
||||
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))
|
||||
us_rxfifo_high = 0;
|
||||
}
|
||||
} else {
|
||||
check = 0;
|
||||
usart_cur_inbuf_off += available;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool usart_dataavailable(void) {
|
||||
return pUS1->US_RCR < sizeof(us_inbuf);
|
||||
uint16_t usart_rxdata_available(void) {
|
||||
usart_fill_rxfifo();
|
||||
if (us_rxfifo_low <= us_rxfifo_high)
|
||||
return us_rxfifo_high - us_rxfifo_low;
|
||||
else
|
||||
return sizeof(us_rxfifo) - us_rxfifo_low + us_rxfifo_high;
|
||||
}
|
||||
|
||||
inline int16_t usart_readcommand(uint8_t *data) {
|
||||
if (pUS1->US_RCR == 0)
|
||||
return usart_readbuffer(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
extern bool reply_via_fpc;
|
||||
extern void Dbprintf(const char *fmt, ...);
|
||||
#define Dbprintf_usb(...) {\
|
||||
bool tmp = reply_via_fpc;\
|
||||
reply_via_fpc = false;\
|
||||
Dbprintf(__VA_ARGS__);\
|
||||
reply_via_fpc = tmp;}
|
||||
|
||||
uint32_t usart_read_ng(uint8_t *data, size_t len) {
|
||||
// TODO DOEGOX
|
||||
return 0;
|
||||
if (len == 0) return 0;
|
||||
uint32_t packetSize, nbBytesRcv = 0;
|
||||
uint32_t try = 0;
|
||||
// uint32_t highest_observed_try = 0;
|
||||
// Empirical max try observed: 3000000 / USART_BAUD_RATE
|
||||
// Let's take 10x
|
||||
uint32_t maxtry = 10 * ( 3000000 / USART_BAUD_RATE );
|
||||
|
||||
while (len) {
|
||||
uint32_t available = usart_rxdata_available();
|
||||
|
||||
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);
|
||||
try = 0;
|
||||
}
|
||||
len -= packetSize;
|
||||
while (packetSize--) {
|
||||
data[nbBytesRcv++] = us_rxfifo[us_rxfifo_low++];
|
||||
if (us_rxfifo_low == sizeof(us_rxfifo))
|
||||
us_rxfifo_low = 0;
|
||||
}
|
||||
if (try++ == maxtry) {
|
||||
Dbprintf_usb("Dbg USART TIMEOUT");
|
||||
break;
|
||||
}
|
||||
}
|
||||
// highest_observed_try = MAX(highest_observed_try, try);
|
||||
// Dbprintf_usb("Dbg USART max observed try %i", highest_observed_try);
|
||||
return nbBytesRcv;
|
||||
}
|
||||
|
||||
inline bool usart_commandavailable(void) {
|
||||
return (pUS1->US_RCR == 0);
|
||||
}
|
||||
/*
|
||||
// transfer from device to client
|
||||
inline int16_t usart_writebuffer(uint8_t *data, size_t len) {
|
||||
|
||||
// Wait for one free PDC bank
|
||||
while (pUS1->US_TCR && pUS1->US_TNCR) {};
|
||||
// ? alternative to wait for end of transmissions?
|
||||
// while (!(pUS1->US_CSR & AT91C_US_ENDTX)) {};
|
||||
|
||||
if (pUS1->US_CSR & AT91C_US_ENDTX) {
|
||||
memcpy(us_outbuf, data, len);
|
||||
pUS1->US_TPR = (uint32_t)us_outbuf;
|
||||
// Check if the current PDC bank is free
|
||||
if (pUS1->US_TCR == 0) {
|
||||
pUS1->US_TPR = (uint32_t)data;
|
||||
pUS1->US_TCR = len;
|
||||
pUS1->US_PTCR = AT91C_PDC_TXTEN;
|
||||
while (!(pUS1->US_CSR & AT91C_US_ENDTX)) {};
|
||||
pUS1->US_PTCR = AT91C_PDC_TXTDIS;
|
||||
return len;
|
||||
}
|
||||
// Check if the backup PDC bank is free
|
||||
else if (pUS1->US_TNCR == 0) {
|
||||
pUS1->US_TNPR = (uint32_t)data;
|
||||
pUS1->US_TNCR = len;
|
||||
} else {
|
||||
// we shouldn't be here
|
||||
return 0;
|
||||
}
|
||||
// Make sure TX transfer is enabled
|
||||
pUS1->US_PTCR = AT91C_PDC_TXTEN;// | AT91C_PDC_RXTEN;
|
||||
//wait until finishing all transfers
|
||||
while (pUS1->US_TNCR || pUS1->US_TCR) {};
|
||||
return len;
|
||||
}
|
||||
*/
|
||||
|
||||
// transfer from device to client
|
||||
inline int16_t usart_writebuffer(uint8_t *data, size_t len) {
|
||||
|
||||
while (pUS1->US_TCR && pUS1->US_TNCR) {};
|
||||
|
||||
// Check if the first PDC bank is free
|
||||
if (pUS1->US_TCR == 0) {
|
||||
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_RXTEN;
|
||||
}
|
||||
// Check if the second PDC bank is free
|
||||
else if (pUS1->US_TNCR == 0) {
|
||||
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_RXTEN;
|
||||
}
|
||||
//wait until finishing transfer
|
||||
while (pUS1->US_TCR && pUS1->US_TNCR) {};
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void usart_init(void) {
|
||||
|
||||
|
@ -185,9 +189,7 @@ void usart_init(void) {
|
|||
// all interrupts disabled
|
||||
pUS1->US_IDR = 0xFFFF;
|
||||
|
||||
pUS1->US_BRGR = 48054841 / (AT91_BAUD_RATE << 3);
|
||||
// Need speed?
|
||||
//pUS1->US_BRGR = 48054841 / (460800 << 3);
|
||||
pUS1->US_BRGR = 48054841 / (USART_BAUD_RATE << 3);
|
||||
|
||||
// Write the Timeguard Register
|
||||
pUS1->US_TTGR = 0;
|
||||
|
@ -195,9 +197,13 @@ void usart_init(void) {
|
|||
pUS1->US_FIDI = 0;
|
||||
pUS1->US_IF = 0;
|
||||
|
||||
// Disable double buffers for now
|
||||
// Initialize DMA buffers
|
||||
pUS1->US_TPR = (uint32_t)0;
|
||||
pUS1->US_TCR = 0;
|
||||
pUS1->US_TNPR = (uint32_t)0;
|
||||
pUS1->US_TNCR = 0;
|
||||
pUS1->US_RPR = (uint32_t)0;
|
||||
pUS1->US_RCR = 0;
|
||||
pUS1->US_RNPR = (uint32_t)0;
|
||||
pUS1->US_RNCR = 0;
|
||||
|
||||
|
@ -205,8 +211,10 @@ void usart_init(void) {
|
|||
pUS1->US_CR = (AT91C_US_RXEN | AT91C_US_TXEN);
|
||||
|
||||
// ready to receive
|
||||
pUS1->US_RPR = (uint32_t)us_inbuf;
|
||||
pUS1->US_RCR = 0;
|
||||
pUS1->US_RNCR = 0;
|
||||
pUS1->US_RPR = (uint32_t)us_inbuf1;
|
||||
pUS1->US_RCR = USART_BUFFLEN;
|
||||
usart_cur_inbuf = us_inbuf1;
|
||||
pUS1->US_RNPR = (uint32_t)us_inbuf2;
|
||||
pUS1->US_RNCR = USART_BUFFLEN;
|
||||
pUS1->US_PTCR = AT91C_PDC_RXTEN;
|
||||
}
|
||||
|
|
|
@ -4,17 +4,18 @@
|
|||
#include <stddef.h>
|
||||
#include "proxmark3.h"
|
||||
|
||||
#define AT91_BAUD_RATE 115200
|
||||
//#define USART_BAUD_RATE 9600
|
||||
#define USART_BAUD_RATE 115200
|
||||
//#define USART_BAUD_RATE 460800
|
||||
|
||||
|
||||
void usart_init(void);
|
||||
void usart_close(void);
|
||||
|
||||
int16_t usart_readbuffer(uint8_t *data);
|
||||
int16_t usart_writebuffer(uint8_t *data, size_t len);
|
||||
bool usart_dataavailable(void);
|
||||
int16_t usart_readcommand(uint8_t *data);
|
||||
void usart_readcheck(uint8_t *data, size_t len);
|
||||
uint32_t usart_read_ng(uint8_t *data, size_t len);
|
||||
uint16_t usart_rxdata_available(void);
|
||||
#define USART_BUFFLEN 512
|
||||
#define USART_FIFOLEN (2*USART_BUFFLEN)
|
||||
|
||||
bool usart_commandavailable(void);
|
||||
#endif
|
||||
|
|
|
@ -103,6 +103,7 @@ bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed);
|
|||
/* Gets the current speed of the serial port, in baud.
|
||||
*/
|
||||
uint32_t uart_get_speed(const serial_port sp);
|
||||
extern uint32_t uart_speed;
|
||||
|
||||
#endif // _UART_H_
|
||||
|
||||
|
|
|
@ -60,6 +60,9 @@
|
|||
# define SOL_TCP IPPROTO_TCP
|
||||
#endif
|
||||
|
||||
// To memorise baudrate, we don't want to call get_speed systematically
|
||||
uint32_t uart_speed;
|
||||
|
||||
typedef struct termios term_info;
|
||||
typedef struct {
|
||||
int fd; // Serial port file descriptor
|
||||
|
@ -206,7 +209,8 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) {
|
|||
}
|
||||
}
|
||||
}
|
||||
printf("[=] UART Setting serial baudrate %u\n", speed);
|
||||
uart_speed = uart_get_speed(sp);
|
||||
printf("[=] UART Setting serial baudrate %u\n", uart_speed);
|
||||
return sp;
|
||||
}
|
||||
|
||||
|
@ -408,7 +412,10 @@ bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed) {
|
|||
// Set port speed (Input and Output)
|
||||
cfsetispeed(&ti, stPortSpeed);
|
||||
cfsetospeed(&ti, stPortSpeed);
|
||||
return (tcsetattr(spu->fd, TCSANOW, &ti) != -1);
|
||||
bool result = tcsetattr(spu->fd, TCSANOW, &ti) != -1;
|
||||
if (result)
|
||||
uart_speed = uiPortSpeed;
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t uart_get_speed(const serial_port sp) {
|
||||
|
|
|
@ -42,6 +42,9 @@
|
|||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
|
||||
// To memorise baudrate, we don't want to call get_speed systematically
|
||||
uint32_t uart_speed;
|
||||
|
||||
typedef struct {
|
||||
HANDLE hPort; // Serial port handle
|
||||
DCB dcb; // Device control settings
|
||||
|
@ -121,7 +124,8 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) {
|
|||
}
|
||||
}
|
||||
}
|
||||
printf("[=] UART Setting serial baudrate %i\n", speed);
|
||||
uart_speed = uart_get_speed(sp);
|
||||
printf("[=] UART Setting serial baudrate %u\n", uart_speed);
|
||||
return sp;
|
||||
}
|
||||
|
||||
|
@ -152,6 +156,8 @@ bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed) {
|
|||
spw->dcb.BaudRate = uiPortSpeed;
|
||||
bool result = SetCommState(spw->hPort, &spw->dcb);
|
||||
PurgeComm(spw->hPort, PURGE_RXABORT | PURGE_RXCLEAR);
|
||||
if (result)
|
||||
uart_speed = uiPortSpeed;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue