Date:2011-04-19 11:35:31 (8 years 5 months ago)
Author:Werner Almesberger
Commit:9ab94a53e26b57d5411d557416c2aefc1b30995d
Message:tools: new utility atrf-xmit for fast transmission tests

- Makefile (DIRS): added atrf-xmit
- atrf-xmit/Makefile, atrf-xmit/atrf-xmit.c: new utility atrf-xmit to
rapidly send packets from one device to another and analyze the outcome
Files: tools/Makefile (1 diff)
tools/atrf-xmit/Makefile (1 diff)
tools/atrf-xmit/atrf-xmit.c (1 diff)

Change Details

tools/Makefile
1212
1313
1414DIRS=atrf-id atrf-path atrf-proxy atrf-reset atrf-rssi atrf-trim atrf-txrx \
15     atrf-xtal
15     atrf-xmit atrf-xtal
1616TARGET_ONLY_DIRS=lib
1717
1818ifeq ($(TARGET),ben_jlime)
tools/atrf-xmit/Makefile
1#
2# atrf-xmit/Makefile - Fast transmission test
3#
4# Written 2011 by Werner Almesberger
5# Copyright 2011 Werner Almesberger
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2 of the License, or
10# (at your option) any later version.
11#
12
13
14MAIN = atrf-xmit
15
16include ../Makefile.common
tools/atrf-xmit/atrf-xmit.c
1/*
2 * atrf-ber/atrf-ber.c - Fast transmission test
3 *
4 * Written 2011 by Werner Almesberger
5 * Copyright 2011 Werner Almesberger
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13
14#include <stdlib.h>
15#include <stdio.h>
16#include <unistd.h>
17
18#include "at86rf230.h"
19
20#include "misctxrx.h"
21#include "atrf.h"
22
23
24#define DEFAULT_CHANNEL 15
25#define DEFAULT_TRIM 8
26#define DEFAULT_POWER 15
27
28#define PSDU_SIZE 127
29
30
31static void init_common(struct atrf_dsc *dsc, int trim, int channel)
32{
33    atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_TRX_OFF);
34    atrf_reg_write(dsc, REG_XOSC_CTRL,
35        (XTAL_MODE_INT << XTAL_MODE_SHIFT) | trim);
36    atrf_set_clkm(dsc, 0);
37    atrf_reg_write(dsc, REG_PHY_CC_CCA, (1 << CCA_MODE_SHIFT) | channel);
38    atrf_reg_write(dsc, REG_IRQ_MASK, 0xff);
39    (void) atrf_reg_read(dsc, REG_IRQ_STATUS);
40}
41
42
43static void init_tx(struct atrf_dsc *dsc, int trim, int channel, int power)
44{
45    uint8_t buf[PSDU_SIZE];
46    int i;
47
48    init_common(dsc, trim, channel);
49    set_power_step(dsc, power, 1);
50    for (i = 0; i != sizeof(buf); i++)
51        buf[i] = i;
52    atrf_buf_write(dsc, buf, sizeof(buf));
53    atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_PLL_ON);
54    wait_for_interrupt(dsc, IRQ_PLL_LOCK, IRQ_PLL_LOCK, 10, 20);
55}
56
57
58static void init_rx(struct atrf_dsc *dsc, int trim, int channel)
59{
60    init_common(dsc, trim, channel);
61    atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_RX_ON);
62    wait_for_interrupt(dsc, IRQ_PLL_LOCK, IRQ_PLL_LOCK, 10, 20);
63}
64
65
66static int xfer_one(struct atrf_dsc *tx, struct atrf_dsc *rx)
67{
68    uint8_t irq;
69    uint8_t buf[PSDU_SIZE+1]; /* +1 for LQI */
70    int n, i;
71
72    atrf_reg_write(tx, REG_TRX_STATE, TRX_CMD_TX_START);
73#if 0
74    irq = wait_for_interrupt(rx, IRQ_TRX_END, IRQ_TRX_END | IRQ_RX_START,
75        1000, 5); /* 5 ms */
76#else
77    /*
78     * Just waiting for the maximum time is much faster than polling the
79     * interrupt, at least for now.
80     */
81    usleep(5000);
82    irq = atrf_reg_read(tx, REG_IRQ_STATUS);
83#endif
84    if (!(irq & IRQ_TRX_END))
85        return 0;
86    if (atrf_reg_read(rx, REG_PHY_RSSI) & RX_CRC_VALID)
87        return 1;
88    n = atrf_buf_read(rx, buf, sizeof(buf));
89    if (n <= 0)
90        return 0;
91    n--; /* we don't care about the LQI */
92    if (n != PSDU_SIZE) {
93        printf("0\n");
94        return 0;
95    }
96    for (i = 0; i != n-2; i++)
97        if (buf[i] != i)
98            break;
99    /*
100     * @@@ We should analyze the CRC here to see if the first or the second
101     * byte got corrupted.
102     */
103    printf("%d\n", i+1);
104    return 0;
105}
106
107
108static void xfer(struct atrf_dsc *tx, struct atrf_dsc *rx, int packets)
109{
110    int got = 0;
111    int i;
112
113    for (i = 0; i != packets; i++)
114        got += xfer_one(tx, rx);
115    printf("%d/%d\n", got, packets);
116}
117
118
119static void usage(const char *name)
120{
121    fprintf(stderr,
122"usage: %s [-c channel] [-p power] [-t trim_tx [-t trim_rx]]\n"
123"%15s driver_tx[:arg] driver_rx[:arg] packets\n\n"
124" -c channel transmit/receive channel, 11 to 26 (default %d)\n"
125" -p power transmit power, 0 to 15 (default %d)\n"
126" -t trim trim capacitor, 0 to 15 (default %d)\n"
127    , name, "",
128    DEFAULT_CHANNEL, DEFAULT_POWER, DEFAULT_TRIM);
129    exit(1);
130}
131
132
133int main(int argc, char **argv)
134{
135    const char *tx_drv, *rx_drv;
136    struct atrf_dsc *tx, *rx;
137    int trim_tx = -1, trim_rx = DEFAULT_TRIM;
138    int channel = DEFAULT_CHANNEL;
139    int power = DEFAULT_POWER;
140    int packets = 1;
141    unsigned long tmp;
142    char *end;
143    int c;
144
145    while ((c = getopt(argc, argv, "c:p:t:")) != EOF)
146        switch (c) {
147        case 'c':
148            tmp = strtoul(optarg, &end, 0);
149            if (*end || tmp < 11 || tmp > 26)
150                usage(*argv);
151            channel = tmp;
152            break;
153        case 'p':
154            tmp = strtoul(optarg, &end, 0);
155            if (*end || tmp > 15)
156                usage(*argv);
157            power = tmp;
158            break;
159        case 't':
160            tmp = strtoul(optarg, &end, 0);
161            if (*end || tmp > 15)
162                usage(*argv);
163            if (trim_tx == -1)
164                trim_tx = tmp;
165            else
166                trim_rx = tmp;
167            break;
168        default:
169            usage(*argv);
170        }
171
172    if (trim_tx == -1)
173        trim_tx = DEFAULT_TRIM;
174
175    switch (argc-optind) {
176    case 3:
177        packets = strtoul(argv[optind+2], &end, 0);
178        if (*end)
179            usage(*argv);
180        /* fall through */
181    case 2:
182        tx_drv = argv[optind];
183        rx_drv = argv[optind+1];
184        break;
185    default:
186        usage(*argv);
187    }
188
189    tx = atrf_open(tx_drv);
190    if (!tx)
191        return 1;
192    rx = atrf_open(rx_drv);
193    if (!rx)
194        return 1;
195
196    init_rx(rx, trim_rx, channel);
197    init_tx(tx, trim_tx, channel, 15-power);
198
199    xfer(tx, rx, packets);
200
201    atrf_reg_write(tx, REG_TRX_STATE, TRX_CMD_TRX_OFF);
202    atrf_reg_write(rx, REG_TRX_STATE, TRX_CMD_TRX_OFF);
203
204    atrf_close(tx);
205    atrf_close(rx);
206
207    return 0;
208}

Archive Download the corresponding diff file



interactive