Root/tools/atrf-xmit/atrf-xmit.c

Source at commit 703ce81dfc675c5ae38537c98fa58eabcb3763b1 created 9 years 3 months ago.
By Werner Almesberger, atrf-xmit.c (xfer_one): pulse SLP_TR instead of sending TRX_CMD_TX_START
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 int verbose = 0;
32
33
34static void init_common(struct atrf_dsc *dsc, int trim, int channel)
35{
36    atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_TRX_OFF);
37    atrf_reg_write(dsc, REG_XOSC_CTRL,
38        (XTAL_MODE_INT << XTAL_MODE_SHIFT) | trim);
39    atrf_set_clkm(dsc, 0);
40    atrf_reg_write(dsc, REG_PHY_CC_CCA, (1 << CCA_MODE_SHIFT) | channel);
41    atrf_reg_write(dsc, REG_IRQ_MASK, 0xff);
42    (void) atrf_reg_read(dsc, REG_IRQ_STATUS);
43}
44
45
46static void init_tx(struct atrf_dsc *dsc, int trim, int channel, int power)
47{
48    uint8_t buf[PSDU_SIZE];
49    int i;
50
51    init_common(dsc, trim, channel);
52    set_power_step(dsc, power, 1);
53    for (i = 0; i != sizeof(buf); i++)
54        buf[i] = i;
55    atrf_buf_write(dsc, buf, sizeof(buf));
56    atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_PLL_ON);
57    wait_for_interrupt(dsc, IRQ_PLL_LOCK, IRQ_PLL_LOCK, 10, 20);
58}
59
60
61static void init_rx(struct atrf_dsc *dsc, int trim, int channel)
62{
63    init_common(dsc, trim, channel);
64    atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_RX_ON);
65    wait_for_interrupt(dsc, IRQ_PLL_LOCK, IRQ_PLL_LOCK, 10, 20);
66}
67
68
69static int xfer_one(struct atrf_dsc *tx, struct atrf_dsc *rx)
70{
71    uint8_t irq;
72    uint8_t buf[PSDU_SIZE+1]; /* +1 for LQI */
73    int n, i;
74
75    atrf_slp_tr(tx, 1, 1);
76#if 0
77    irq = wait_for_interrupt(rx, IRQ_TRX_END, IRQ_TRX_END | IRQ_RX_START,
78        1000, 5); /* 5 ms */
79#else
80    /*
81     * Just waiting for the maximum time is much faster than polling the
82     * interrupt, at least for now.
83     */
84    usleep(5000);
85    irq = atrf_reg_read(tx, REG_IRQ_STATUS);
86#endif
87    if (!(irq & IRQ_TRX_END))
88        return 0;
89    if (atrf_reg_read(rx, REG_PHY_RSSI) & RX_CRC_VALID)
90        return 1;
91    n = atrf_buf_read(rx, buf, sizeof(buf));
92    if (n <= 0)
93        return 0;
94    n--; /* we don't care about the LQI */
95    if (n != PSDU_SIZE) {
96        printf("0\n");
97        return 0;
98    }
99    for (i = 0; i != n-2; i++)
100        if (buf[i] != i)
101            break;
102    /*
103     * @@@ We should analyze the CRC here to see if the first or the second
104     * byte got corrupted.
105     */
106    if (verbose) {
107        printf("%d", i+1);
108        for (i = 0; i != n-2; i++)
109            printf("%s%02x", i ? " " : "\t", buf[i]);
110        printf("\n");
111    } else {
112        printf("%d\n", i+1);
113    }
114    return 0;
115}
116
117
118static void xfer(struct atrf_dsc *tx, struct atrf_dsc *rx, int packets)
119{
120    int got = 0;
121    int i;
122
123    for (i = 0; i != packets; i++)
124        got += xfer_one(tx, rx);
125    printf("%d/%d\n", got, packets);
126}
127
128
129static void usage(const char *name)
130{
131    fprintf(stderr,
132"usage: %s [-c channel] [-p power] [-t trim_tx [-t trim_rx]] [-v]\n"
133"%15s driver_tx[:arg] driver_rx[:arg] [packets]\n\n"
134" -c channel transmit/receive channel, 11 to 26 (default %d)\n"
135" -p power transmit power, 0 to 15 (default %d)\n"
136" -t trim trim capacitor, 0 to 15 (default %d)\n"
137" -v verbose reporting of transmission errors\n"
138    , name, "",
139    DEFAULT_CHANNEL, DEFAULT_POWER, DEFAULT_TRIM);
140    exit(1);
141}
142
143    
144int main(int argc, char **argv)
145{
146    const char *tx_drv, *rx_drv;
147    struct atrf_dsc *tx, *rx;
148    int trim_tx = -1, trim_rx = DEFAULT_TRIM;
149    int channel = DEFAULT_CHANNEL;
150    int power = DEFAULT_POWER;
151    int packets = 1;
152    unsigned long tmp;
153    char *end;
154    int c;
155
156    while ((c = getopt(argc, argv, "c:p:t:v")) != EOF)
157        switch (c) {
158        case 'c':
159            tmp = strtoul(optarg, &end, 0);
160            if (*end || tmp < 11 || tmp > 26)
161                usage(*argv);
162            channel = tmp;
163            break;
164        case 'v':
165            verbose++;
166            break;
167        case 'p':
168            tmp = strtoul(optarg, &end, 0);
169            if (*end || tmp > 15)
170                usage(*argv);
171            power = tmp;
172            break;
173        case 't':
174            tmp = strtoul(optarg, &end, 0);
175            if (*end || tmp > 15)
176                usage(*argv);
177            if (trim_tx == -1)
178                trim_tx = tmp;
179            else
180                trim_rx = tmp;
181            break;
182        default:
183            usage(*argv);
184        }
185
186    if (trim_tx == -1)
187        trim_tx = DEFAULT_TRIM;
188
189    switch (argc-optind) {
190    case 3:
191        packets = strtoul(argv[optind+2], &end, 0);
192        if (*end)
193            usage(*argv);
194        /* fall through */
195    case 2:
196        tx_drv = argv[optind];
197        rx_drv = argv[optind+1];
198        break;
199    default:
200        usage(*argv);
201    }
202
203    tx = atrf_open(tx_drv);
204    if (!tx)
205        return 1;
206    rx = atrf_open(rx_drv);
207    if (!rx)
208        return 1;
209
210    init_rx(rx, trim_rx, channel);
211    init_tx(tx, trim_tx, channel, 15-power);
212
213    xfer(tx, rx, packets);
214
215    atrf_reg_write(tx, REG_TRX_STATE, TRX_CMD_TRX_OFF);
216    atrf_reg_write(rx, REG_TRX_STATE, TRX_CMD_TRX_OFF);
217
218    atrf_close(tx);
219    atrf_close(rx);
220
221    return 0;
222}
223

Archive Download this file



interactive