mirror of
git://projects.qi-hardware.com/ben-wpan.git
synced 2024-11-26 05:17:19 +02:00
tools/atrf-txrx/atrf-txrx.c: new option -R for RTT measurement mode
This is similar to ping (-P) but separates roles more clearly and collects timing statistics instead of visualizing reception.
This commit is contained in:
parent
49ca503cab
commit
c19fccf17c
@ -67,6 +67,7 @@ enum mode {
|
|||||||
mode_hmac,
|
mode_hmac,
|
||||||
mode_per,
|
mode_per,
|
||||||
mode_ping,
|
mode_ping,
|
||||||
|
mode_rtt,
|
||||||
mode_cont_tx,
|
mode_cont_tx,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -452,6 +453,84 @@ static void ping(struct atrf_dsc *dsc, double max_wait_s, int master)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ----- Round-trip time --------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
static void rtt_slave(struct atrf_dsc *dsc)
|
||||||
|
{
|
||||||
|
uint8_t buf[MAX_PSDU];
|
||||||
|
int n;
|
||||||
|
|
||||||
|
while (run) {
|
||||||
|
atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_RX_ON);
|
||||||
|
wait_for_interrupt(dsc, IRQ_TRX_END,
|
||||||
|
IRQ_TRX_END | IRQ_RX_START | IRQ_PLL_LOCK | IRQ_AMI, 0);
|
||||||
|
if (!run)
|
||||||
|
break;
|
||||||
|
n = atrf_buf_read(dsc, buf, sizeof(buf));
|
||||||
|
if (n < 0)
|
||||||
|
exit(1);
|
||||||
|
if (n < 2) {
|
||||||
|
fprintf(stderr, "%d bytes received\n", n);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_PLL_ON);
|
||||||
|
atrf_buf_write(dsc, buf, n);
|
||||||
|
atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_TX_START);
|
||||||
|
wait_for_interrupt(dsc, IRQ_TRX_END,
|
||||||
|
IRQ_TRX_END | IRQ_PLL_LOCK, 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void rtt_master(struct atrf_dsc *dsc, int packets, int size)
|
||||||
|
{
|
||||||
|
uint8_t buf[size+2]; /* +CRC */
|
||||||
|
struct timeval t0, t1;
|
||||||
|
uint8_t irq;
|
||||||
|
int first = 1;
|
||||||
|
double min = 0, max = 0, sum = 0, sum2 = 0, d;
|
||||||
|
int lost = 0, n;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
memset(buf, 0, size+2);
|
||||||
|
for (i = 0; i != packets; i++) {
|
||||||
|
atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_PLL_ON);
|
||||||
|
atrf_buf_write(dsc, buf, size+2);
|
||||||
|
gettimeofday(&t0, NULL);
|
||||||
|
atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_TX_START);
|
||||||
|
wait_for_interrupt(dsc, IRQ_TRX_END,
|
||||||
|
IRQ_TRX_END | IRQ_PLL_LOCK, 10);
|
||||||
|
atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_RX_ON);
|
||||||
|
irq = wait_for_interrupt(dsc, IRQ_TRX_END,
|
||||||
|
IRQ_TRX_END | IRQ_RX_START | IRQ_PLL_LOCK | IRQ_AMI, 1000);
|
||||||
|
if (irq) {
|
||||||
|
gettimeofday(&t1, NULL);
|
||||||
|
d = t1.tv_sec-t0.tv_sec+(t1.tv_usec-t0.tv_usec)*1e-6;
|
||||||
|
sum += d;
|
||||||
|
sum2 += d*d;
|
||||||
|
if (first || d < min)
|
||||||
|
min = d;
|
||||||
|
if (first || d > max)
|
||||||
|
max = d;
|
||||||
|
first = 0;
|
||||||
|
n = atrf_buf_read(dsc, buf, size);
|
||||||
|
if (n != size)
|
||||||
|
fprintf(stderr, "%d bytes received\n", n);
|
||||||
|
} else {
|
||||||
|
lost++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n = packets-lost;
|
||||||
|
printf("%d sent, %d received, %d lost (%g%%)\n",
|
||||||
|
packets, n, lost, lost*100.0/packets);
|
||||||
|
if (n)
|
||||||
|
printf("rtt min/avg/max = %.3f/%.3f/%.3f ms, mdev = %.3f ms\n",
|
||||||
|
min*1000.0, sum*1000.0/n, max*1000.0,
|
||||||
|
sqrt((sum2-sum*sum/n)/n)*1000.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ----- Continuous wave test ---------------------------------------------- */
|
/* ----- Continuous wave test ---------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
@ -490,6 +569,7 @@ static void usage(const char *name)
|
|||||||
" %s [common_options] -H [message]\n"
|
" %s [common_options] -H [message]\n"
|
||||||
" %s [common_options] -E pause_s [repetitions]\n"
|
" %s [common_options] -E pause_s [repetitions]\n"
|
||||||
" %s [common_options] -P [max_wait_s]\n"
|
" %s [common_options] -P [max_wait_s]\n"
|
||||||
|
" %s [common_options] -R [packets size]\n"
|
||||||
" %s [common_options] -T offset [command]\n\n"
|
" %s [common_options] -T offset [command]\n\n"
|
||||||
" text message mode:\n"
|
" text message mode:\n"
|
||||||
" message message string to send (if absent, receive)\n"
|
" message message string to send (if absent, receive)\n"
|
||||||
@ -503,6 +583,10 @@ static void usage(const char *name)
|
|||||||
" Ping-pong mode:\n"
|
" Ping-pong mode:\n"
|
||||||
" -P exchange packets between two stations\n"
|
" -P exchange packets between two stations\n"
|
||||||
" max_wait_s generate a new packet if no response is received (master)\n\n"
|
" max_wait_s generate a new packet if no response is received (master)\n\n"
|
||||||
|
" Round-trip time measurement:\n"
|
||||||
|
" -R send/receive RTT measurement packets\n"
|
||||||
|
" packets number of packets to send (master)\n"
|
||||||
|
" size size of packets in bytes\n"
|
||||||
" constant wave test mode (transmit only):\n"
|
" constant wave test mode (transmit only):\n"
|
||||||
" -T offset test mode. offset is the frequency offset of the constant\n"
|
" -T offset test mode. offset is the frequency offset of the constant\n"
|
||||||
" wave in MHz: -2, -0.5, or +0.5\n"
|
" wave in MHz: -2, -0.5, or +0.5\n"
|
||||||
@ -519,7 +603,7 @@ static void usage(const char *name)
|
|||||||
" -p power transmit power, -17.2 to 3.0 dBm (default %.1f)\n"
|
" -p power transmit power, -17.2 to 3.0 dBm (default %.1f)\n"
|
||||||
" -r rate data rate, 250k, 500k, 1M, or 2M (default: 250k)\n"
|
" -r rate data rate, 250k, 500k, 1M, or 2M (default: 250k)\n"
|
||||||
" -t trim trim capacitor, 0 to 15 (default %d)\n"
|
" -t trim trim capacitor, 0 to 15 (default %d)\n"
|
||||||
, name, name, name, name, name,
|
, name, name, name, name, name, name,
|
||||||
DEFAULT_CHANNEL, atrf_default_driver_name(),
|
DEFAULT_CHANNEL, atrf_default_driver_name(),
|
||||||
2405+5*(DEFAULT_CHANNEL-11), DEFAULT_POWER,
|
2405+5*(DEFAULT_CHANNEL-11), DEFAULT_POWER,
|
||||||
DEFAULT_TRIM);
|
DEFAULT_TRIM);
|
||||||
@ -545,7 +629,7 @@ int main(int argc, char *const *argv)
|
|||||||
int channel = DEFAULT_CHANNEL;
|
int channel = DEFAULT_CHANNEL;
|
||||||
double power = DEFAULT_POWER;
|
double power = DEFAULT_POWER;
|
||||||
uint8_t rate = OQPSK_DATA_RATE_250;
|
uint8_t rate = OQPSK_DATA_RATE_250;
|
||||||
int trim = DEFAULT_TRIM, times = 1;
|
int trim = DEFAULT_TRIM, times = 1, bytes;
|
||||||
uint8_t cont_tx = 0;
|
uint8_t cont_tx = 0;
|
||||||
double pause_s = 0;
|
double pause_s = 0;
|
||||||
char *end;
|
char *end;
|
||||||
@ -555,7 +639,7 @@ int main(int argc, char *const *argv)
|
|||||||
const char *pcap_file = NULL;
|
const char *pcap_file = NULL;
|
||||||
struct atrf_dsc *dsc;
|
struct atrf_dsc *dsc;
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, "c:C:d:E:f:Ho:p:Pr:t:T:")) != EOF)
|
while ((c = getopt(argc, argv, "c:C:d:E:f:Ho:p:Pr:Rt:T:")) != EOF)
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'c':
|
case 'c':
|
||||||
channel = strtoul(optarg, &end, 0);
|
channel = strtoul(optarg, &end, 0);
|
||||||
@ -616,6 +700,9 @@ int main(int argc, char *const *argv)
|
|||||||
else
|
else
|
||||||
usage(*argv);
|
usage(*argv);
|
||||||
break;
|
break;
|
||||||
|
case 'R':
|
||||||
|
set_mode(&mode, mode_rtt);
|
||||||
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
trim = strtoul(optarg, &end, 0);
|
trim = strtoul(optarg, &end, 0);
|
||||||
if (*end)
|
if (*end)
|
||||||
@ -660,6 +747,10 @@ int main(int argc, char *const *argv)
|
|||||||
set_power_dBm(dsc, power, 1);
|
set_power_dBm(dsc, power, 1);
|
||||||
ping(dsc, pause_s, 0);
|
ping(dsc, pause_s, 0);
|
||||||
break;
|
break;
|
||||||
|
case mode_rtt:
|
||||||
|
set_power_dBm(dsc, power, 1);
|
||||||
|
rtt_slave(dsc);
|
||||||
|
break;
|
||||||
case mode_cont_tx:
|
case mode_cont_tx:
|
||||||
set_power_dBm(dsc, power, 0);
|
set_power_dBm(dsc, power, 0);
|
||||||
status = test_mode(dsc, cont_tx, NULL);
|
status = test_mode(dsc, cont_tx, NULL);
|
||||||
@ -678,6 +769,19 @@ int main(int argc, char *const *argv)
|
|||||||
/* fall through */
|
/* fall through */
|
||||||
case mode_cont_tx:
|
case mode_cont_tx:
|
||||||
usage(*argv);
|
usage(*argv);
|
||||||
|
case mode_rtt:
|
||||||
|
times = strtoul(argv[optind], &end, 0);
|
||||||
|
if (*end)
|
||||||
|
usage(*argv);
|
||||||
|
bytes = strtoul(argv[optind+1], &end, 0);
|
||||||
|
if (*end)
|
||||||
|
usage(*argv);
|
||||||
|
dsc = init_txrx(driver, trim, clkm);
|
||||||
|
set_channel(dsc, channel);
|
||||||
|
set_rate(dsc, rate);
|
||||||
|
set_power_dBm(dsc, power, 1);
|
||||||
|
rtt_master(dsc, times, bytes);
|
||||||
|
goto done;
|
||||||
default:
|
default:
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
@ -712,6 +816,9 @@ int main(int argc, char *const *argv)
|
|||||||
set_power_dBm(dsc, power, 1);
|
set_power_dBm(dsc, power, 1);
|
||||||
ping(dsc, pause_s, 1);
|
ping(dsc, pause_s, 1);
|
||||||
break;
|
break;
|
||||||
|
case mode_rtt:
|
||||||
|
usage(*argv);
|
||||||
|
break;
|
||||||
case mode_cont_tx:
|
case mode_cont_tx:
|
||||||
set_power_dBm(dsc, power, 0);
|
set_power_dBm(dsc, power, 0);
|
||||||
status = test_mode(dsc, cont_tx, argv[optind]);
|
status = test_mode(dsc, cont_tx, argv[optind]);
|
||||||
@ -724,6 +831,7 @@ int main(int argc, char *const *argv)
|
|||||||
default:
|
default:
|
||||||
usage(*argv);
|
usage(*argv);
|
||||||
}
|
}
|
||||||
|
done:
|
||||||
|
|
||||||
atrf_close(dsc);
|
atrf_close(dsc);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user