Root/tools/atrf-gpio/atrf-gpio.c

1/*
2 * atrf-gpio/atrf-gpio.c - ATBEN/ATUSB GPIO 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#include <string.h>
18#include <termios.h>
19#include <fcntl.h>
20#include <errno.h>
21
22#include "at86rf230.h"
23#include "atrf.h"
24
25#include "atrf-gpio.h"
26
27
28#define DEFAULT_DELAY_MS 10
29
30
31/* ----- Board-specific drivers -------------------------------------------- */
32
33
34static void atben(struct atrf_dsc *dsc, const char *pattern, const char *next)
35{
36#ifdef HAVE_ATBEN
37    do_atben(dsc, pattern, next);
38#else
39    fprintf(stderr, "not compiled with ATBEN support\n");
40    exit(1);
41#endif
42}
43
44
45static void atusb(struct atrf_dsc *dsc, const char *pattern, const char *next)
46{
47#ifdef HAVE_ATUSB
48    do_atusb(dsc, pattern, next);
49#else
50    fprintf(stderr, "not compiled with ATUSB support\n");
51    exit(1);
52#endif
53}
54
55
56/* ----- Commands ---------------------------------------------------------- */
57
58
59static void bad_command(const char *arg)
60{
61    fprintf(stderr, "invalid command \"%s\"\n", arg);
62    exit(1);
63}
64
65
66static int command(struct atrf_dsc *dsc, const char *arg, int doit)
67{
68    const char *p;
69    char *end;
70    unsigned long reg, value, mask = 0xff;
71    uint8_t got;
72
73    if (!strcmp(arg, "delay")) {
74        if (doit)
75            usleep(DEFAULT_DELAY_MS*1000);
76        return 1;
77    }
78    if (!strncmp(arg, "delay=", 6)) {
79        value = strtoul(arg+6, &end, 0);
80        if (!value || *end)
81            bad_command(arg);
82        if (doit)
83            usleep(value*1000);
84        return 1;
85    }
86    if (!strcmp(arg, "frame")) {
87        if (doit)
88            atrf_buf_write(dsc, "", 1);
89        return 1;
90    }
91    if (!strcmp(arg, "reset")) {
92        if (doit)
93            atrf_reset_rf(dsc);
94        return 1;
95    }
96    if (!strcmp(arg, "slp_tr")) {
97        if (doit)
98            atrf_slp_tr(dsc, 1, 1);
99        return 1;
100    }
101
102    p = strchr(arg, '=');
103    if (!p)
104        p = strchr(arg, ':');
105    if (!p)
106        p = strchr(arg, '!');
107    if (!p)
108        p = strchr(arg, '/');
109    if (!p)
110        return 0;
111    reg = strtoul(arg, &end, 0);
112    if (end != p || reg > 0xff)
113        bad_command(arg);
114    value = strtoul(p+1, &end, 0);
115    if (value > 0xff)
116        bad_command(arg);
117    if (*end) {
118        if (*p != ':')
119            bad_command(arg);
120        if (*end != '/')
121            bad_command(arg);
122        mask = strtoul(end+1, &end, 0);
123        if (*end || mask > 0xff)
124            bad_command(arg);
125    }
126
127    if (!doit)
128        return 1;
129
130    switch (*p) {
131    case '=':
132        atrf_reg_write(dsc, reg, value);
133        break;
134    case ':':
135        got = atrf_reg_read(dsc, reg);
136        if (end != p+1 && ((got ^ value) & mask)) {
137            fprintf(stderr,
138                "register 0x%02lx: got 0x%02x expected "
139                "0x%02lx/0x%02lx\n", reg, got, value, mask);
140            exit(1);
141        }
142        break;
143    case '!':
144        atrf_sram_write(dsc, reg, value);
145        break;
146    case '/':
147        got = atrf_sram_read(dsc, reg);
148        if (got != value) {
149            fprintf(stderr,
150                "got 0x%02x expected 0x%02lx\n", got, value);
151            exit(1);
152        }
153        break;
154    default:
155        abort();
156    }
157    return 1;
158}
159
160
161/* ----- Pass/Fail/Quit input ---------------------------------------------- */
162
163
164static struct termios old_term;
165
166
167static void restore_term(void)
168{
169    if (tcsetattr(0, TCSAFLUSH, &old_term) < 0)
170        perror("tcsetattr");
171}
172
173
174static void raw(void)
175{
176    struct termios term;
177
178    if (tcgetattr(0, &old_term) < 0) {
179        perror("tcgetattr");
180        exit(1);
181    }
182    term = old_term;
183    cfmakeraw(&term);
184    if (tcsetattr(0, TCSAFLUSH, &term) < 0) {
185        perror("tcsetattr");
186        exit(1);
187    }
188    atexit(restore_term);
189    if (fcntl(0, F_SETFL, O_NONBLOCK) < 0) {
190        perror("fcntl");
191        exit(1);
192    }
193}
194
195
196static void pass_fail(void)
197{
198    ssize_t got;
199    char ch;
200
201    got = read(0, &ch, 1);
202    if (got < 0) {
203        if (errno == EAGAIN)
204            return;
205        perror("read");
206        exit(1);
207    }
208    switch (ch) {
209    case 'P':
210    case 'p':
211        exit(0);
212    case 'F':
213    case 'f':
214    case 'Q':
215    case 'q':
216    case 3: /* Ctrl-C */
217        exit(1);
218    default:
219        break;
220    }
221}
222
223
224/* ----- Command line processing and main loop ----------------------------- */
225
226
227static void usage(const char *name)
228{
229    fprintf(stderr,
230"usage: %s [-c] [-d driver[:arg]] [-p] command|pattern ...\n\n"
231" -c cycle, waiting for Pass/Fail/Quit input\n"
232" -d driver[:arg] use the specified driver (default: %s)\n"
233" -p stay in P_ON state instead of entering TRX_OFF\n\n"
234" command is one of:\n"
235" reg=value set transceiver register\n"
236" reg:[value[/mask]]\n"
237" read transceiver register and (optionally) verify value\n"
238" addr!value write one byte to SRAM\n"
239" addr/value read and verify one byte from SRAM\n"
240" delay[=ms] wait the specified number of milliseconds (default: %d ms)\n"
241" frame write a one-byte frame to the frame buffer\n"
242" reset reset the transceiver\n"
243" slp_tr pulse SLP_TR\n"
244" #... comment\n\n"
245" pattern is a sequence of the following characters:\n"
246" 0 = output a strong 0 1 = output a strong 1\n"
247" L = pull up, expect to read 0 H = pull up, expect to read 1\n"
248" l/o = no pull-up, expect to read 0 h = no pull-up, expect to read 1\n"
249" Z = pull up, don't read z = no pull-up, don't read\n"
250" x = don't care . = separator\n"
251    , name, atrf_default_driver_name(), DEFAULT_DELAY_MS);
252    exit(1);
253}
254
255
256/*
257 * 0 strong 0 out
258 * 1 strong 1 out
259 * H pull-up, read 1
260 * L pull-up, read 0
261 * h no pull-up, read 1
262 * l/o no pull-up, read 0
263 * Z pull-up, don't read
264 * z no pull-up, don't read
265 * x don't care
266 * . separator
267 */
268
269
270int main(int argc, char *const *argv)
271{
272    const char *driver = NULL;
273    struct atrf_dsc *dsc;
274    int cycle = 0;
275    int trx_off = 1;
276    int c, i;
277    const char *s;
278
279    while ((c = getopt(argc, argv, "cd:p")) != EOF)
280        switch (c) {
281        case 'c':
282            cycle = 1;
283            break;
284        case 'd':
285            driver = optarg;
286            break;
287        case 'p':
288            trx_off = 0;
289            break;
290        default:
291            usage(*argv);
292        }
293
294    if (optind == argc)
295        usage(*argv);
296
297    for (i = optind; i != argc; i++) {
298        if (*argv[i] == '#')
299            continue;
300        if (command(NULL, argv[i], 0))
301            continue;
302        for (s = argv[i]; *s; s++)
303            if (!strchr("01HLhloZzx.", *s))
304                fprintf(stderr,
305                    "invalid configuration '%c' in \"%s\"\n",
306                    *s, argv[i]);
307    }
308
309    dsc = atrf_open(driver);
310    if (!dsc)
311        return 1;
312
313    atrf_reset_rf(dsc);
314
315    if (trx_off) {
316        atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_TRX_OFF);
317        do usleep(100);
318        while ((atrf_reg_read(dsc, REG_TRX_STATUS) & TRX_STATUS_MASK)
319            != TRX_STATUS_TRX_OFF);
320    }
321
322    if (cycle)
323        raw();
324
325    while (1) {
326        for (i = optind; i != argc; i++) {
327            if (*argv[i] == '#')
328                continue;
329            if (command(dsc, argv[i], 1))
330                continue;
331            if (atrf_usb_handle(dsc))
332                atusb(dsc, argv[i], argv[i+1]);
333            else
334                atben(dsc, argv[i], argv[i+1]);
335        }
336        if (cycle)
337            pass_fail();
338        else
339            break;
340    }
341
342// atrf_close(dsc);
343
344    return 0;
345}
346

Archive Download this file



interactive