Date:2011-04-13 23:40:39 (8 years 8 months ago)
Author:Werner Almesberger
Commit:a1fc867bf2cb75f439b6e4095eb5a192ed21eeff
Message:atrf-path: option -P to load a min/max profile; pass/fail indication in GUI

- sweep.h (MIN_DIFF, MAX_DIFF, struct sweep): added min/max profile
- sweep.h (do_sweep), atrf-path.c (do_half_sweep, do_sweep): compare
result against limits and return pass/fail decision
- sweep.h (N_CHAN), atrf-path.c (do_half_sweep, do_sweeps), gui.c
(N_CHAN): declare number of channels in one central place instead of
scattering it all around the program
- atrf-path.c (do_read_profile, read_profile, usage, main): new option -P
to read a min/max profile
- gui.c (indicate, main): moved indicator to separate function and
improved blink logic
- gui.c (OVER_RGBA, UNDER_RGBA, indicate, main): change color to indicate
pass/fail
Files: tools/atrf-path/atrf-path.c (8 diffs)
tools/atrf-path/gui.c (4 diffs)
tools/atrf-path/sweep.h (3 diffs)

Change Details

tools/atrf-path/atrf-path.c
1515#include <stdio.h>
1616#include <unistd.h>
1717#include <string.h>
18#include <ctype.h>
1819
1920#include "at86rf230.h"
2021
...... 
110111}
111112
112113
113static void do_half_sweep(const struct sweep *sweep, int cont_tx,
114static int do_half_sweep(const struct sweep *sweep, int cont_tx,
114115    struct sample *res)
115116{
116    int chan;
117    int i, chan;
118    int fail = 0;
117119
118120    if (sweep->cont_tx && sweep->cont_tx != cont_tx)
119        return;
120    for (chan = 11; chan <= 26; chan++) {
121        return 0;
122    chan = 11;
123    for (i = 0; i != N_CHAN; i++) {
121124        set_channel(sweep->rx, chan);
122125        set_channel(sweep->tx, chan);
123126        usleep(155); /* table 7-2, tTR19 */
124127
125128        sample(sweep, cont_tx, res, chan == 11 && !sweep->cont_tx);
129        if (res->avg > sweep->max[i])
130            fail = 1;
131        if (!fail && res->avg < sweep->min[i])
132            fail = -1;
133
126134        res += 2;
135        chan++;
127136    }
137    return fail;
128138}
129139
130140
131void do_sweep(const struct sweep *sweep, struct sample *res)
141int do_sweep(const struct sweep *sweep, struct sample *res)
132142{
133    do_half_sweep(sweep, CONT_TX_M500K, res);
134    do_half_sweep(sweep, CONT_TX_P500K, res+1);
143    int fail1, fail2;
144
145    fail1 = do_half_sweep(sweep, CONT_TX_M500K, res);
146    fail2 = do_half_sweep(sweep, CONT_TX_P500K, res+1);
147    if (fail1 > 0 || fail2 > 0)
148        return 1;
149    if (fail1 < 0 || fail2 < 0)
150        return -1;
151    return 0;
135152}
136153
137154
...... 
154171
155172static void do_sweeps(const struct sweep *sweep, int sweeps)
156173{
157    struct sample res[16*2]; /* 16 channels, 2 offsets */
174    struct sample res[N_CHAN*2]; /* 2 offsets per channel */
158175    int i;
159176
160177    for (i = 0; i != sweeps; i++) {
...... 
166183}
167184
168185
186static int do_read_profile(const char *name, struct sweep *sweep)
187{
188    FILE *file;
189    char buf[300];
190    int got;
191    char *p;
192    double min = MIN_DIFF, max = MAX_DIFF;
193    int n = 0;
194
195    file = fopen(name, "r");
196    if (!file) {
197        perror(name);
198        exit(1);
199    }
200    while (fgets(buf, sizeof(buf), file)) {
201        p = strchr(buf, '\n');
202        if (p)
203            *p = 0;
204        p = strchr(buf, '#');
205        if (p)
206            *p = 0;
207        for (p = buf; *p && isspace(*p); p++);
208        if (!*p)
209            continue;
210        got = sscanf(buf, "%lf %lf", &min, &max);
211        switch (got) {
212        case 0:
213            fprintf(stderr, "can't parse \"%s\"\n", buf);
214            exit(1);
215        case 1:
216            max = MAX_DIFF;
217            /* fall through */
218        case 2:
219            if (min < MIN_DIFF) {
220                fprintf(stderr, "minimum is %g dBm\n",
221                    MIN_DIFF);
222                exit(1);
223            }
224            if (max > MAX_DIFF) {
225                fprintf(stderr, "maximum is %g dBm\n",
226                    MAX_DIFF);
227                exit(1);
228            }
229            if (min > max) {
230                fprintf(stderr, "lower bound > upper bound\n");
231                exit(1);
232            }
233            if (n == N_CHAN) {
234                fprintf(stderr, "too many channels\n");
235                exit(1);
236            }
237            sweep->min[n] = min;
238            sweep->max[n] = max;
239            n++;
240            break;
241        default:
242            abort();
243        }
244    }
245    fclose(file);
246    return n;
247}
248
249
250static void read_profile(const char *name, struct sweep *sweep)
251{
252    int n = 0;
253
254    if (name)
255        n = do_read_profile(name, sweep);
256
257    while (n != N_CHAN) {
258        sweep->min[n] = MIN_DIFF;
259        sweep->max[n] = MAX_DIFF;
260        n++;
261    }
262}
263
264
169265static void usage(const char *name)
170266{
171267    fprintf(stderr,
...... 
175271"%6s %s -g common_args [[sweeps] samples]\n"
176272#endif
177273    "\n"
178" common args: [-p power] [-t trim_tx [-t trim_rx]] [-T offset]\n"
179" driver_tx[:arg] driver_rx[:arg]\n\n"
274" common args: [-p power] [-P profile] [-t trim_tx [-t trim_rx]]\n"
275" [-T offset] driver_tx[:arg] driver_rx[:arg]\n\n"
180276
181277#ifdef HAVE_GFX
182" -g display results graphically\n"
278" -g display results graphically\n"
183279#endif
184" -p power transmit power, 0 to 15 (default %d)\n"
185" -t trim trim capacitor, 0 to 15 (default %d)\n"
186" -T offset constant wave offset in MHz, -0.5 or +0.5 (default: scan both)\n"
280" -p power transmit power, 0 to 15 (default %d)\n"
281" -P profile load profile for pass/fail decisions\n"
282" -t trim trim capacitor, 0 to 15 (default %d)\n"
283" -T offset constant wave offset in MHz, -0.5 or +0.5 (default: scan both)\n"
187284
188285    , name,
189286#ifdef HAVE_GFX
...... 
206303    };
207304    int graphical = 0;
208305    int power = DEFAULT_POWER;
306    const char *profile = NULL;
209307    int sweeps = 1;
210308    unsigned long tmp;
211309    char *end;
212310    int c;
213311
214    while ((c = getopt(argc, argv, "gp:t:T:")) != EOF)
312    while ((c = getopt(argc, argv, "gp:P:t:T:")) != EOF)
215313        switch (c) {
216314        case'g':
217315            graphical = 1;
...... 
223321                usage(*argv);
224322            power = tmp;
225323            break;
324        case 'P':
325            profile = optarg;
326            break;
226327        case 't':
227328            tmp = strtoul(optarg, &end, 0);
228329            if (*end || tmp > 15)
...... 
270371        usage(*argv);
271372    }
272373
374    read_profile(profile, &sweep);
375
273376    sweep.tx = atrf_open(tx_drv);
274377    if (!sweep.tx)
275378        return 1;
tools/atrf-path/gui.c
2929#define XRES 320
3030#define YRES 240
3131
32#define N_CHAN 16
33
34
3532#define FG_RGBA 0xffffffff /* measurement color */
3633#define OK_RGBA 0x00ff00ff
34#define OVER_RGBA 0xffff00ff
35#define UNDER_RGBA 0xff0000ff
3736
3837#define CHAN_STEP 20 /* 4 pixels/MHz */
3938#define SIDE_STEP 2
...... 
8483}
8584
8685
86static void indicate(SDL_Surface *s, int fail)
87{
88    static uint32_t last = 0;
89    uint32_t color;
90
91    switch (fail) {
92    case 0:
93        color = OK_RGBA;
94        break;
95    case 1:
96        color = OVER_RGBA;
97        break;
98    case -1:
99        color = UNDER_RGBA;
100        break;
101    default:
102        abort();
103    }
104    if (color == last)
105        color = 0;
106    last = color;
107
108    filledCircleColor(s, STATUS_X, STATUS_Y, STATUS_R, color);
109    aacircleColor(s, STATUS_X, STATUS_Y, STATUS_R, color);
110}
111
112
87113static void clear(SDL_Surface *s)
88114{
89115    SDL_FillRect(s, NULL, SDL_MapRGB(s->format, 0, 0, 0));
...... 
124150    SDL_Surface *surf;
125151    SDL_Event event;
126152    int cycle = 0;
153    int fail;
127154
128155    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
129156        fprintf(stderr, "SDL_init: %s\n", SDL_GetError());
...... 
145172                event.type == SDL_QUIT)
146173                return;
147174        tstart();
148        do_sweep(sweep, res);
175        fail = do_sweep(sweep, res);
149176        tstop();
150177
151178        SDL_LockSurface(surf);
152179
153180        clear(surf);
154181
155        if (cycle++ & 1) {
156            filledCircleColor(surf, STATUS_X, STATUS_Y, STATUS_R,
157                OK_RGBA);
158            aacircleColor(surf, STATUS_X, STATUS_Y, STATUS_R,
159                OK_RGBA);
160        }
182        indicate(surf, fail);
161183        draw(surf, res, sweep->cont_tx);
162184
163185        SDL_UnlockSurface(surf);
tools/atrf-path/sweep.h
1919#include "atrf.h"
2020
2121
22#define N_CHAN 16
23
24#define MIN_DIFF -97.0 /* RSSI(min)-TX(max) = -94 - 3 */
25#define MAX_DIFF 7.0 /* RSSI(max)-TX(min) = -10 - (-17) */
26
27
2228struct sweep {
2329    struct atrf_dsc *tx;
2430    struct atrf_dsc *rx;
...... 
2733    int power;
2834    uint8_t cont_tx;
2935    int samples;
36    double min[N_CHAN];
37    double max[N_CHAN];
3038};
3139
3240struct sample {
...... 
3543};
3644
3745
38void do_sweep(const struct sweep *sweep, struct sample *res);
46/*
47 * do_sweep returns whether the signal is within the limits:
48 *
49 * 1: at least one sample is above the maximum
50 * 0: all samples are between minimum and maximum
51 * -1: at least one sample below the minimum, and none above the maximum
52 */
53
54int do_sweep(const struct sweep *sweep, struct sample *res);
3955
4056#endif /* !SWEEP_H */

Archive Download the corresponding diff file



interactive