Root/tools/atspi-txrx/atspi-txrx.c

Source at commit 36e73c4abb520aa65722ef5e1483bcb8b75bf9f4 created 9 years 1 month ago.
By Werner Almesberger, Moved tools/ out of atrf, in preparation of merge with atusd.
1/*
2 * atspi-txrx/atspi-txrx.c - ben-wpan AF86RF230 TX/RX
3 *
4 * Written 2010 by Werner Almesberger
5 * Copyright 2010 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 <string.h>
17#include <usb.h>
18
19#include "at86rf230.h"
20#include "atspi/ep0.h"
21#include "atspi.h"
22
23
24/*
25 * According to IEEE 802.15.4-2003 section E.2.6, channel 15 is the only
26 * channel that falls into the 802.11 guard bands in North America an Europe.
27 */
28
29#define DEFAULT_CHANNEL 15 /* channel 15, 2425 MHz */
30
31/*
32 * Transmit power, dBm. IEEE 802.15.4-2003 section E.3.1.3 specifies a transmit
33 * power of 0 dBm for IEEE 802.15.4. We assume an antenna gain of 3 dB or
34 * better.
35 */
36
37#define DEFAULT_POWER -3.2 /* transmit power, dBm */
38
39
40static double tx_pwr[] = {
41     3.0, 2.6, 2.1, 1.6,
42     1.1, 0.5, -0.2, -1.2,
43    -2.2, -3.2, -4.2, -5.2,
44    -7.2, -9.2, -12.2, -17.2
45};
46
47
48static usb_dev_handle *init_txrx(int trim)
49{
50    usb_dev_handle *dev;
51
52    dev = atspi_open();
53    if (!dev)
54        exit(1);
55    
56    atspi_reset_rf(dev);
57    atspi_reg_write(dev, REG_TRX_STATE, TRX_CMD_TRX_OFF);
58    atspi_reg_write(dev, REG_XOSC_CTRL,
59        (XTAL_MODE_INT << XTAL_MODE_SHIFT) | trim);
60    atspi_reg_write(dev, REG_TRX_CTRL_0, 0); /* disable CLKM */
61
62    return dev;
63}
64
65
66static void set_channel(usb_dev_handle *dev, int channel)
67{
68    atspi_reg_write(dev, REG_PHY_CC_CCA, (1 << CCA_MODE_SHIFT) | channel);
69}
70
71
72static void set_power(usb_dev_handle *dev, double power)
73{
74    int n;
75
76    for (n = 0; n != sizeof(tx_pwr)/sizeof(*tx_pwr)-1; n++)
77        if (tx_pwr[n] <= power)
78            break;
79    atspi_reg_write(dev, REG_PHY_TX_PWR, TX_AUTO_CRC_ON | n);
80}
81
82
83static void receive(usb_dev_handle *dev)
84{
85    uint8_t irq;
86    uint8_t buf[MAX_PSDU+1]; /* PSDU+LQI */
87    int n, ok, i;
88    uint8_t lq;
89
90    atspi_reg_write(dev, REG_TRX_STATE, TRX_CMD_RX_ON);
91
92    (void) atspi_reg_read(dev, REG_IRQ_STATUS);
93
94    fprintf(stderr, "Ready.\n");
95    while (1) {
96        irq = atspi_reg_read(dev, REG_IRQ_STATUS);
97        if (atspi_error())
98            exit(1);
99        if (!irq)
100            continue;
101        if (irq == IRQ_TRX_END)
102            break;
103        fprintf(stderr, "IRQ (0x%02x):", irq);
104        if (irq & IRQ_PLL_LOCK)
105            fprintf(stderr, " PLL_LOCK");
106        if (irq & IRQ_PLL_UNLOCK)
107            fprintf(stderr, " PLL_UNLOCK");
108        if (irq & IRQ_RX_START)
109            fprintf(stderr, " RX_START");
110        if (irq & IRQ_TRX_UR)
111            fprintf(stderr, " TRX_UR");
112        if (irq & IRQ_BAT_LOW)
113            fprintf(stderr, " BAT_LOW");
114        fprintf(stderr, "\n");
115        if (irq & IRQ_TRX_END)
116            break;
117    }
118
119    n = atspi_buf_read(dev, buf, sizeof(buf));
120    if (n < 0)
121        exit(1);
122    if (n < 3) {
123        fprintf(stderr, "%d bytes received\n", n);
124        exit(1);
125    }
126    ok = !!(atspi_reg_read(dev, REG_PHY_RSSI) & RX_CRC_VALID);
127    lq = buf[n-1];
128    fprintf(stderr, "%d bytes payload, CRC %s, LQI %u\n",
129        n-3, ok ? "OK" : "BAD", lq);
130    for (i = 0; i != n-3; i++)
131        putchar(buf[i] < ' ' || buf[i] > '~' ? '?' : buf[i]);
132    putchar('\n');
133}
134
135
136static void transmit(usb_dev_handle *dev, const char *msg)
137{
138    uint8_t buf[MAX_PSDU];
139
140    atspi_reg_write(dev, REG_TRX_STATE, TRX_CMD_PLL_ON);
141
142    /*
143     * We need to copy the message to append the CRC placeholders.
144     */
145    strcpy((void *) buf, msg);
146    atspi_buf_write(dev, buf, strlen(msg)+2);
147
148    /* @@@ should wait for clear channel */
149    atspi_reg_write(dev, REG_TRX_STATE, TRX_CMD_TX_START);
150    /* @@@ should wait for TX done */
151}
152
153
154static void usage(const char *name)
155{
156    fprintf(stderr,
157"usage: %s [-c channel] [-p power] [-t trim] [message]\n"
158" -c channel channel number, 11 to 26 (default %d)\n"
159" -p power transmit power, -17.2 to 3.0 dBm (default %.1f)\n"
160" -t trim trim capacitor, 0 to 15 (default 0)\n"
161        , name , DEFAULT_CHANNEL, DEFAULT_POWER);
162    exit(1);
163}
164
165
166int main(int argc, char *const *argv)
167{
168    int channel = DEFAULT_CHANNEL;
169    double power = DEFAULT_POWER;
170    int trim = 0;
171    char *end;
172    int c;
173    usb_dev_handle *dev;
174
175    while ((c = getopt(argc, argv, "c:p:t:")) != EOF)
176        switch (c) {
177        case 'c':
178            channel = strtoul(optarg, &end, 0);
179            if (*end)
180                usage(*argv);
181            if (channel < 11 || channel > 26)
182                usage(*argv);
183            break;
184        case 'p':
185            power = strtod(optarg, &end);
186            if (*end)
187                usage(*argv);
188            break;
189        case 't':
190            trim = strtoul(optarg, &end, 0);
191            if (*end)
192                usage(*argv);
193            if (trim > 15)
194                usage(*argv);
195            break;
196        default:
197            usage(*argv);
198        }
199
200    switch (argc-optind) {
201    case 0:
202        dev = init_txrx(trim);
203        set_channel(dev, channel);
204        receive(dev);
205        break;
206    case 1:
207        dev = init_txrx(trim);
208        set_channel(dev, channel);
209        set_power(dev, power);
210        transmit(dev, argv[optind]);
211        break;
212    default:
213        usage(*argv);
214    }
215
216    return 0;
217}
218

Archive Download this file



interactive