Date:2012-06-30 17:38:27 (11 years 8 months ago)
Author:Werner Almesberger
Commit:758d9e7fc46fbb72e05e63fa411077f16bcdc14b
Message:tools/: rename "antorcha" to ant-cl (command line) and move to tools/ant-cl/

Files: tools/Makefile (1 diff)
tools/ant-cl/Makefile (1 diff)
tools/ant-cl/ant-cl.c (1 diff)
tools/ant-cl/hash.c (1 diff)
tools/ant-cl/plot.c (1 diff)
tools/ant-cl/plot.h (1 diff)
tools/antorcha.c (1 diff)
tools/hash.c (1 diff)
tools/plot.c (1 diff)
tools/plot.h (1 diff)

Change Details

tools/Makefile
1#
2# tools/Makefile - Build the Antorcha tool
3#
4# Written 2012 by Werner Almesberger
5# Copyright 2012 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 = antorcha
15
16CFLAGS = -g -I../fw -I../../ben-wpan/tools/include \
17     -I../../ben-wpan/atusb/fw/include \
18     -Wall \
19     $(if $(NOGFX),, -DGFX $(shell sdl-config --cflags)) \
20     $(if $(BEN), -static)
21
22LDLIBS = -L../../ben-wpan/tools/lib -latrf \
23     $(if $(NOGFX),, $(shell sdl-config --libs) -lSDL_gfx) \
24     $(if $(BEN),, -usb)
25
26OBJS = antorcha.o hash.o $(if $(NOGFX),, plot.o)
27
28.PHONY: all ben clean spotless update ping off
29
30all: $(MAIN)
31
32ben:
33        $(MAKE) NOGFX=y BEN=y CC=mipsel-openwrt-linux-gcc
34
35$(MAIN): $(OBJS)
36        $(CC) $(CFLAGS) -o $@ $(OBJS) $(LDLIBS)
37
38clean:
39        rm -f $(OBJS)
40
41spotless: clean
42        rm -f $(MAIN)
43
44update:
45        ./antorcha -F ../fw/antorcha.bin
46
47ping:
48        ./antorcha -P
49
50off:
51        ./antorcha /dev/null
tools/ant-cl/Makefile
1#
2# tools/ant-cl/Makefile - Build the Antorcha command-line tool
3#
4# Written 2012 by Werner Almesberger
5# Copyright 2012 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 = ant-cl
15
16CFLAGS = -g -I../../fw -I../../../ben-wpan/tools/include \
17     -I../../../ben-wpan/atusb/fw/include \
18     -Wall \
19     $(if $(NOGFX),, -DGFX $(shell sdl-config --cflags)) \
20     $(if $(BEN), -static)
21
22LDLIBS = -L../../../ben-wpan/tools/lib -latrf \
23     $(if $(NOGFX),, $(shell sdl-config --libs) -lSDL_gfx) \
24     $(if $(BEN),, -lusb)
25
26OBJS = ant-cl.o hash.o $(if $(NOGFX),, plot.o)
27
28.PHONY: all ben clean spotless update ping off
29
30all: $(MAIN)
31
32ben:
33        $(MAKE) NOGFX=y BEN=y CC=mipsel-openwrt-linux-gcc
34
35$(MAIN): $(OBJS)
36        $(CC) $(CFLAGS) -o $@ $(OBJS) $(LDLIBS)
37
38clean:
39        rm -f $(OBJS)
40
41spotless: clean
42        rm -f $(MAIN)
43
44update:
45        ./antorcha -F ../fw/antorcha.bin
46
47ping:
48        ./antorcha -P
49
50off:
51        ./antorcha /dev/null
tools/ant-cl/ant-cl.c
1/*
2 * tools/ant-cl/ant-cl.c - Antorcha control utility
3 *
4 * Written 2012 by Werner Almesberger
5 * Copyright 2012 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 <stdint.h>
15#include <stdlib.h>
16#include <stdio.h>
17#include <unistd.h>
18#include <string.h>
19#include <signal.h>
20#include <assert.h>
21
22#include <at86rf230.h>
23#include <atrf.h>
24#include <misctxrx.h>
25
26#include <proto.h>
27
28#include "hash.h"
29#include "plot.h"
30
31
32static int verbose = 1;
33static int debug = 0;
34
35
36static void rf_init(struct atrf_dsc *dsc, int trim, int channel)
37{
38    atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_TRX_OFF);
39     atrf_reg_write(dsc, REG_XOSC_CTRL,
40            (XTAL_MODE_INT << XTAL_MODE_SHIFT) | trim);
41    atrf_reg_write(dsc, REG_PHY_CC_CCA, (1 << CCA_MODE_SHIFT) | channel);
42    atrf_reg_write(dsc, REG_IRQ_MASK, 0xff);
43    flush_interrupts(dsc);
44    atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_PLL_ON);
45    wait_for_interrupt(dsc, IRQ_PLL_LOCK, IRQ_PLL_LOCK, 1);
46}
47
48
49static void rf_send(struct atrf_dsc *dsc, void *buf, int len)
50{
51    uint8_t tmp[MAX_PSDU];
52
53    /* Copy the message to append the CRC placeholders */
54    memcpy(tmp, buf, len);
55    atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_PLL_ON);
56    flush_interrupts(dsc);
57    atrf_buf_write(dsc, tmp, len+2);
58    atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_TX_START);
59    wait_for_interrupt(dsc, IRQ_TRX_END,
60        IRQ_TRX_END | IRQ_PLL_LOCK, 10);
61    atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_RX_ON);
62
63    if (debug) {
64        int i;
65        fprintf(stderr, "\r%d:", len);
66        for (i = 0; i != len; i++)
67            fprintf(stderr, " %02x", ((uint8_t *) buf)[i]);;
68        fprintf(stderr, "\n");
69    }
70}
71
72
73static int rf_recv(struct atrf_dsc *dsc, void *buf, int size)
74{
75    uint8_t irq;
76    int len;
77
78    /* Wait up to 100 ms */
79    irq = wait_for_interrupt(dsc, IRQ_TRX_END,
80        IRQ_TRX_END | IRQ_RX_START | IRQ_AMI, 100);
81    if (!irq)
82        return 0;
83    len = atrf_buf_read(dsc, buf, size);
84    if (len < 0)
85        exit(1);
86    if (len < 3) /* CRC and LQI */
87        return 0;
88    return atrf_reg_read(dsc, REG_PHY_RSSI) & RX_CRC_VALID ? len-3 : 0;
89}
90
91
92static void packet_noack(struct atrf_dsc *dsc,
93    uint8_t type, uint8_t seq, uint8_t last, const void *payload, int len)
94{
95    uint8_t tx_buf[PAYLOAD+3] = { type, seq, last };
96
97    assert(len == PAYLOAD);
98    memcpy(tx_buf+3, payload, len);
99    rf_send(dsc, tx_buf, sizeof(tx_buf));
100}
101
102
103static void packet(struct atrf_dsc *dsc,
104    uint8_t type, uint8_t seq, uint8_t last, const void *payload, int len)
105{
106    uint8_t rx_buf[10];
107    int got;
108
109    while (1) {
110        packet_noack(dsc, type, seq, last, payload, len);
111        if (verbose)
112            write(2, ">", 1);
113        got = rf_recv(dsc, rx_buf, sizeof(rx_buf));
114        if (got <= 0) {
115            if (!seq && verbose)
116                write(2, "\b", 1);
117            continue;
118        }
119        if (verbose)
120            write(2, "\b?", 2);
121        if (got < 3)
122            continue;
123        if (verbose)
124            write(2, "\bA", 2);
125        if (rx_buf[0] != type+1 || rx_buf[1] != seq)
126            continue;
127        if (verbose)
128            write(2, "\b.", 2);
129        break;
130    }
131}
132
133
134/* ----- Ping -------------------------------------------------------------- */
135
136
137static void ping(struct atrf_dsc *dsc)
138{
139    uint8_t ping[] = { PING, 0, 0 };
140    uint8_t buf[100];
141    int got, i;
142
143    rf_send(dsc, ping, sizeof(ping));
144    got = rf_recv(dsc, buf, sizeof(buf));
145    if (!got)
146        return;
147    printf("%d: ", got);
148    for (i = 3; i != got; i++)
149        printf("%c", buf[i] >= ' ' && buf[i] <= '~' ? buf[i] : '?');
150    printf("\n");
151}
152
153
154/* ----- Firmware upload --------------------------------------------------- */
155
156
157static const uint8_t unlock_secret[PAYLOAD] = {
158    #include "unlock-secret.inc"
159};
160
161
162static void send_firmware(struct atrf_dsc *dsc, void *buf, int len)
163{
164    uint8_t payload[PAYLOAD];
165    uint8_t last, seq;
166
167    if (verbose)
168        write(2, "firmware ", 9);
169    last = (len+63)/64;
170    seq = 0;
171    packet_noack(dsc, RESET, 0, 0, unlock_secret, PAYLOAD);
172    packet(dsc, FIRMWARE, seq++, last, unlock_secret, PAYLOAD);
173    while (len >= PAYLOAD) {
174        packet(dsc, FIRMWARE, seq++, last, buf, PAYLOAD);
175        buf += PAYLOAD;
176        len -= PAYLOAD;
177    }
178    if (len) {
179        memcpy(payload, buf, len);
180        memset(payload+len, 0, PAYLOAD-len);
181        packet(dsc, FIRMWARE, seq++, last, payload, PAYLOAD);
182    }
183    if (verbose)
184        write(2, "\n", 1);
185}
186
187
188static void firmware(struct atrf_dsc *dsc, const char *name)
189{
190    FILE *file;
191    uint8_t fw[12*1024]; /* we have 8-12kB */
192    ssize_t len;
193
194    file = fopen(name, "r");
195    if (!file) {
196        perror(name);
197        exit(1);
198    }
199    len = fread(fw, 1, sizeof(fw), file);
200    if (len < 0) {
201        perror(name);
202        exit(1);
203    }
204    fclose(file);
205
206    send_firmware(dsc, fw, len);
207}
208
209
210/* ----- Image upload ------------------------------------------------------ */
211
212
213static const uint8_t image_secret[PAYLOAD*2] = {
214    #include "image-secret.inc"
215};
216
217
218static void send_image(struct atrf_dsc *dsc, void *buf, int len)
219{
220    uint8_t payload[PAYLOAD];
221    uint8_t last, seq;
222
223    hash_init();
224    hash_merge(image_secret, sizeof(image_secret));
225    if (verbose)
226        write(2, "image ", 6);
227
228    last = (len+63)/64+3;
229    seq = 0;
230    while (len >= PAYLOAD) {
231        packet(dsc, IMAGE, seq++, last, buf, PAYLOAD);
232        hash_merge(buf, PAYLOAD);
233        buf += PAYLOAD;
234        len -= PAYLOAD;
235    }
236    if (len) {
237        memcpy(payload, buf, len);
238        memset(payload+len, 0, PAYLOAD-len);
239        packet(dsc, IMAGE, seq++, last, payload, PAYLOAD);
240        hash_merge(payload, PAYLOAD);
241    }
242
243    /* @@@ salt */
244    packet(dsc, IMAGE, seq++, last, payload, PAYLOAD);
245    hash_merge(payload, PAYLOAD);
246    packet(dsc, IMAGE, seq++, last, payload, PAYLOAD);
247    hash_merge(payload, PAYLOAD);
248    hash_end();
249
250    /* hash */
251    hash_cp(payload, PAYLOAD, 0);
252    packet(dsc, IMAGE, seq++, last, payload, PAYLOAD);
253    hash_cp(payload, PAYLOAD, PAYLOAD);
254    packet(dsc, IMAGE, seq++, last, payload, PAYLOAD);
255
256    if (verbose)
257        write(2, "\n", 1);
258}
259
260
261static void image(struct atrf_dsc *dsc, const char *name)
262{
263    FILE *file;
264    uint8_t img[200] = { 0 };
265    ssize_t len;
266
267    file = fopen(name, "r");
268    if (!file) {
269        perror(name);
270        exit(1);
271    }
272    len = fread(img, 1, sizeof(img), file);
273    if (len < 0) {
274        perror(name);
275        exit(1);
276    }
277    fclose(file);
278
279    send_image(dsc, img, len);
280}
281
282
283/* ----- Parameter upload -------------------------------------------------- */
284
285
286static struct params params = {
287    .xa_high = XA_HIGH_DEFAULT,
288    .xa_low = XA_LOW_DEFAULT,
289    .px_fwd_left = PX_FWD_LEFT_DEFAULT,
290    .px_fwd_right = PX_FWD_RIGHT_DEFAULT,
291    .px_bwd_left = PX_BWD_LEFT_DEFAULT,
292    .px_bwd_right = PX_BWD_RIGHT_DEFAULT,
293    .tp_fwd_start = TP_FWD_START_DEFAULT,
294    .tp_bwd_start = TP_BWD_START_DEFAULT,
295    .tp_fwd_pix = TP_FWD_PIX_DEFAULT,
296    .tp_bwd_pix = TP_BWD_PIX_DEFAULT,
297};
298
299static struct map {
300    const char *name; /* NULL to mark end */
301    void *p;
302    int bytes; /* 1, 2, or 4 */
303} map[] = {
304    { "xa_high", &params.xa_high, 2 },
305    { "xa_low", &params.xa_low, 2 },
306    { "px_fwd_left", &params.px_fwd_left, 1 },
307    { "px_bwd_left", &params.px_bwd_left, 1 },
308    { "px_fwd_right", &params.px_fwd_right, 1 },
309    { "px_bwd_right", &params.px_bwd_right, 1 },
310    { "tp_fwd_start", &params.tp_fwd_start, 4 },
311    { "tp_bwd_start", &params.tp_bwd_start, 4 },
312    { "tp_fwd_pix", &params.tp_fwd_pix, 2 },
313    { "tp_bwd_pix", &params.tp_bwd_pix, 2 },
314    { NULL }
315};
316
317static int have_params = 0;
318
319
320static void add_param(const char *arg, const char *eq)
321{
322    const struct map *m;
323    size_t len;
324    unsigned long v;
325    char *end;
326    uint8_t *p;
327    int i;
328
329    len = eq-arg;
330    for (m = map; m->name; m++) {
331        if (strlen(m->name) != len)
332            continue;
333        if (!strncmp(arg, m->name, len))
334            break;
335    }
336    if (!m->name) {
337        fprintf(stderr, "unknown parameter \"%.*s\"\n",
338            (int) len, arg);
339        exit(1);
340    }
341    v = strtoul(eq+1, &end, 10);
342    if (*end) {
343        fprintf(stderr, "invalid value \"%s\"\n", eq+1);
344        exit(1);
345    }
346    p = m->p;
347    for (i = 0; i != m->bytes; i++) {
348        *p++ = v;
349        v >>= 8;
350    }
351    if (v) {
352        fprintf(stderr, "value \"%s\" is too large\n", eq+1);
353        exit(1);
354    }
355    have_params = 1;
356}
357
358
359static void send_param(struct atrf_dsc *dsc)
360{
361    uint8_t payload[PAYLOAD];
362
363    if (!have_params)
364        return;
365    hash_init();
366    hash_merge(image_secret, sizeof(image_secret));
367    if (verbose)
368        write(2, "param ", 6);
369    memset(payload, 0, PAYLOAD);
370    memcpy(payload, &params, sizeof(params));
371    packet(dsc, PARAM, 0, 4, payload, PAYLOAD);
372    hash_merge(payload, PAYLOAD);
373
374    /* @@@ salt */
375    packet(dsc, PARAM, 1, 4, payload, PAYLOAD);
376    hash_merge(payload, PAYLOAD);
377    packet(dsc, PARAM, 2, 4, payload, PAYLOAD);
378    hash_merge(payload, PAYLOAD);
379    hash_end();
380
381    /* hash */
382    hash_cp(payload, PAYLOAD, 0);
383    packet(dsc, PARAM, 3, 4, payload, PAYLOAD);
384    hash_cp(payload, PAYLOAD, PAYLOAD);
385    packet(dsc, PARAM, 4, 4, payload, PAYLOAD);
386
387    if (verbose)
388        write(2, "\n", 1);
389}
390
391
392/* ----- Reset ------------------------------------------------------------- */
393
394
395static void reset(struct atrf_dsc *dsc)
396{
397    packet_noack(dsc, RESET, 0, 0, unlock_secret, PAYLOAD);
398}
399
400
401/* ----- Samples ----------------------------------------------------------- */
402
403
404static volatile int run = 1;
405
406
407static void sigint(int sig)
408{
409    run = 0;
410}
411
412
413static int read_sample(uint8_t **s, uint16_t *t_high, uint16_t *t_low,
414    uint16_t *last)
415{
416    int v;
417
418    *t_low = *(*s)++;
419    *t_low |= *(*s)++ << 8;
420    if (*t_low < *last)
421        (*t_high)++;
422    *last = *t_low;
423    v = *(*s)++;
424    v |= *(*s)++ << 8;
425    return v;
426}
427
428
429static void samples(struct atrf_dsc *dsc, int gui)
430{
431    uint8_t buf[MAX_PSDU] = { 0, };
432    int got;
433    uint8_t *s;
434    uint16_t t_high, t_low, last;
435    int x, y;
436    double t;
437
438    buf[0] = 1;
439    packet(dsc, SAMPLE, 0, 0, buf, PAYLOAD);
440
441#ifdef GFX
442    if (gui)
443        plot_init();
444    else
445#endif
446        signal(SIGINT, sigint);
447    while (run) {
448        got = rf_recv(dsc, buf, sizeof(buf));
449        if (got <= 3)
450            continue;
451        if (buf[0] != SAMPLES)
452            continue;
453        if (debug > 1) {
454            int i;
455
456            for (i = 0; i != got; i++)
457                fprintf(stderr, " %02x", buf[i]);
458            fprintf(stderr, "\n");
459        }
460        if (debug)
461            fprintf(stderr, "%d:", got);
462        s = buf+3;
463        t_high = *s++;
464        t_high |= *s++ << 8;
465        last = 0;
466        while (s < buf+got-2) {
467            x = read_sample(&s, &t_high, &t_low, &last);
468            t = (t_high << 16 | t_low)/1000000.0;
469            if (debug)
470                fprintf(stderr, "\t%11.6f %d", t, x);
471            if (!gui)
472                printf("%11.6f\t%d\t", t, x);
473
474            y = read_sample(&s, &t_high, &t_low, &last);
475            t = (t_high << 16 | t_low)/1000000.0;
476            if (debug)
477                fprintf(stderr, "\t%11.6f %d\n", t, y);
478            if (!gui)
479                printf("%11.6f\t%d\n", t, y);
480
481#ifdef GFX
482            if (gui && !plot(x, y))
483                goto quit;
484#endif
485        }
486    }
487#ifdef GFX
488quit:
489#endif
490    buf[0] = 0;
491    packet(dsc, SAMPLE, 0, 0, buf, PAYLOAD);
492}
493
494
495/* ----- Command-line processing ------------------------------------------- */
496
497
498static unsigned get_int(uint8_t *p, int n)
499{
500    unsigned v = 0;
501    int i;
502
503    for (i = 0; i != n; i++)
504        v |= *p++ << (i*8);
505    return v;
506}
507
508
509static void usage(const char *name)
510{
511    const struct map *m;
512
513    fprintf(stderr,
514"usage: %s [-d] [param=value ...] image_file\n"
515   "%6s %s [-d] -F firmware_file\n"
516   "%6s %s [-d] -P\n"
517   "%6s %s [-d] -R\n"
518   "%6s %s [-d] -S [-S]\n\n"
519" -F file firmware upload\n"
520" -P ping (version query)\n"
521" -R reset\n"
522" -S sample with output on stdout. Exit with ^C.\n"
523#ifdef GFX
524" -S -S sample with graphical output. Exit with Q.\n\n"
525#endif
526"Parameters:\n"
527    , name, "", name, "", name, "", name, "", name);
528    for (m = map; m->name; m++)
529        fprintf(stderr, " %s\t(default %u)\n",
530            m->name, get_int(m->p, m->bytes));
531    exit(1);
532}
533
534
535int main(int argc, char **argv)
536{
537    const char *fw = NULL;
538    int do_ping = 0, do_reset = 0, do_sample = 0;
539    struct atrf_dsc *dsc;
540    int c;
541
542    while ((c = getopt(argc, argv, "dF:PRS")) != EOF)
543        switch (c) {
544        case 'd':
545            debug++;
546            break;
547        case 'F':
548            fw = optarg;
549            break;
550        case 'P':
551            do_ping = 1;
552            break;
553        case 'R':
554            do_reset = 1;
555            break;
556        case 'S':
557            do_sample++;
558            break;
559        default:
560            usage(*argv);
561        }
562
563    if (do_ping+do_reset+!!do_sample+!!fw > 1)
564        usage(*argv);
565    if (do_ping || do_reset || do_sample || fw) {
566        if (argc != optind)
567            usage(*argv);
568    } else {
569        if (argc == optind)
570            usage(*argv);
571    }
572
573    dsc = atrf_open(NULL);
574    if (!dsc)
575        return 1;
576
577    rf_init(dsc, 8, 15);
578    if (do_ping)
579        ping(dsc);
580    else if (do_reset)
581        reset(dsc);
582    else if (do_sample)
583        samples(dsc, do_sample > 1);
584    else if (fw)
585        firmware(dsc, fw);
586    else {
587        const char *eq;
588
589        while (optind != argc) {
590            eq = strchr(argv[optind], '=');
591            if (!eq)
592                break;
593            add_param(argv[optind], eq);
594            optind++;
595        }
596        if (argc > optind+1)
597            usage(*argv);
598        if (optind != argc)
599            image(dsc, argv[optind]);
600        send_param(dsc);
601    }
602
603    return 0;
604}
tools/ant-cl/hash.c
1#include "../../fw/hash.c"
tools/ant-cl/plot.c
1/*
2 * tools/ant-cl/plot.c - Sample plot
3 *
4 * Written 2012 by Werner Almesberger
5 * Copyright 2012 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
16#include "SDL.h"
17#include "SDL_gfxPrimitives.h"
18
19#include "plot.h"
20
21
22#define XRES 1024
23#define YRES 1024
24
25#define RADIUS 3
26
27#define OLD_RGBA 0xffffff20
28#define NEW_RGBA 0xffffffff
29
30
31static SDL_Surface *surf;
32static int first = 1;
33static int last_x, last_y;
34
35static SDL_Surface *back;
36static SDL_Rect back_rect = {
37    .x = 0,
38    .y = 0,
39    .w = 2*RADIUS+1,
40    .h = 2*RADIUS+1,
41};
42
43static SDL_Rect front_rect = {
44    .w = 2*RADIUS+1,
45    .h = 2*RADIUS+1,
46};
47
48
49int plot(int x, int y)
50{
51    SDL_Event event;
52
53    if (!first) {
54        SDL_BlitSurface(back, &back_rect, surf, &front_rect);
55        SDL_LockSurface(surf);
56        filledCircleColor(surf, last_x, last_y, RADIUS, OLD_RGBA);
57        SDL_UnlockSurface(surf);
58    }
59
60    front_rect.x = x;
61    front_rect.y = y;
62    x += RADIUS;
63    y += RADIUS;
64
65    SDL_BlitSurface(surf, &front_rect, back, &back_rect);
66    SDL_LockSurface(surf);
67    filledCircleColor(surf, x, y, RADIUS, NEW_RGBA);
68    SDL_UnlockSurface(surf);
69
70    if (!first)
71        SDL_UpdateRect(surf,
72            last_x-RADIUS, last_y-RADIUS, 2*RADIUS+1, 2*RADIUS+1);
73    SDL_UpdateRect(surf, x-RADIUS, y-RADIUS, 2*RADIUS+1, 2*RADIUS+1);
74
75    first = 0;
76    last_x = x;
77    last_y = y;
78
79    while (SDL_PollEvent(&event))
80        switch (event.type) {
81        case SDL_KEYDOWN:
82            switch (event.key.keysym.sym) {
83            case SDLK_c:
84                SDL_LockSurface(surf);
85                SDL_FillRect(surf, NULL,
86                    SDL_MapRGB(surf->format, 0, 0, 0));
87                SDL_UpdateRect(surf, 0, 0, 0, 0);
88                SDL_UnlockSurface(surf);
89                break;
90            case SDLK_q:
91                return 0;
92            default:
93                break;
94            }
95            break;
96        case SDL_QUIT:
97            return 0;
98        default:
99            break;
100        }
101
102    return 1;
103}
104
105
106void plot_init(void)
107{
108    const SDL_PixelFormat *f;
109
110    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
111        fprintf(stderr, "SDL_init: %s\n", SDL_GetError());
112        exit(1);
113    }
114    atexit(SDL_Quit);
115
116    surf = SDL_SetVideoMode(XRES+2*RADIUS+1, YRES+2*RADIUS+1, 0,
117        SDL_SWSURFACE);
118    if (!surf) {
119        fprintf(stderr, "SDL_SetVideoMode: %s\n", SDL_GetError());
120        exit(1);
121    }
122
123    f = surf->format;
124    back = SDL_CreateRGBSurface(SDL_SWSURFACE, 2*RADIUS+1, 2*RADIUS+1,
125        f->BitsPerPixel, f->Rmask, f->Gmask, f->Bmask, f->Amask);
126    if (!back) {
127        fprintf(stderr, "SDL_SetVideoMode: %s\n", SDL_GetError());
128        exit(1);
129    }
130}
tools/ant-cl/plot.h
1/*
2 * tools/ant-cl/plot.h - Sample plot
3 *
4 * Written 2012 by Werner Almesberger
5 * Copyright 2012 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#ifndef PLOT_H
15#define PLOT_H
16
17int plot(int x, int y);
18void plot_init(void);
19
20#endif /* !PLOT_H */
tools/antorcha.c
1/*
2 * tools/antorcha.c - Antorcha control utility
3 *
4 * Written 2012 by Werner Almesberger
5 * Copyright 2012 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 <stdint.h>
15#include <stdlib.h>
16#include <stdio.h>
17#include <unistd.h>
18#include <string.h>
19#include <signal.h>
20#include <assert.h>
21
22#include <at86rf230.h>
23#include <atrf.h>
24#include <misctxrx.h>
25
26#include <proto.h>
27
28#include "hash.h"
29#include "plot.h"
30
31
32static int verbose = 1;
33static int debug = 0;
34
35
36static void rf_init(struct atrf_dsc *dsc, int trim, int channel)
37{
38    atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_TRX_OFF);
39     atrf_reg_write(dsc, REG_XOSC_CTRL,
40            (XTAL_MODE_INT << XTAL_MODE_SHIFT) | trim);
41    atrf_reg_write(dsc, REG_PHY_CC_CCA, (1 << CCA_MODE_SHIFT) | channel);
42    atrf_reg_write(dsc, REG_IRQ_MASK, 0xff);
43    flush_interrupts(dsc);
44    atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_PLL_ON);
45    wait_for_interrupt(dsc, IRQ_PLL_LOCK, IRQ_PLL_LOCK, 1);
46}
47
48
49static void rf_send(struct atrf_dsc *dsc, void *buf, int len)
50{
51    uint8_t tmp[MAX_PSDU];
52
53    /* Copy the message to append the CRC placeholders */
54    memcpy(tmp, buf, len);
55    atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_PLL_ON);
56    flush_interrupts(dsc);
57    atrf_buf_write(dsc, tmp, len+2);
58    atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_TX_START);
59    wait_for_interrupt(dsc, IRQ_TRX_END,
60        IRQ_TRX_END | IRQ_PLL_LOCK, 10);
61    atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_RX_ON);
62
63    if (debug) {
64        int i;
65        fprintf(stderr, "\r%d:", len);
66        for (i = 0; i != len; i++)
67            fprintf(stderr, " %02x", ((uint8_t *) buf)[i]);;
68        fprintf(stderr, "\n");
69    }
70}
71
72
73static int rf_recv(struct atrf_dsc *dsc, void *buf, int size)
74{
75    uint8_t irq;
76    int len;
77
78    /* Wait up to 100 ms */
79    irq = wait_for_interrupt(dsc, IRQ_TRX_END,
80        IRQ_TRX_END | IRQ_RX_START | IRQ_AMI, 100);
81    if (!irq)
82        return 0;
83    len = atrf_buf_read(dsc, buf, size);
84    if (len < 0)
85        exit(1);
86    if (len < 3) /* CRC and LQI */
87        return 0;
88    return atrf_reg_read(dsc, REG_PHY_RSSI) & RX_CRC_VALID ? len-3 : 0;
89}
90
91
92static void packet_noack(struct atrf_dsc *dsc,
93    uint8_t type, uint8_t seq, uint8_t last, const void *payload, int len)
94{
95    uint8_t tx_buf[PAYLOAD+3] = { type, seq, last };
96
97    assert(len == PAYLOAD);
98    memcpy(tx_buf+3, payload, len);
99    rf_send(dsc, tx_buf, sizeof(tx_buf));
100}
101
102
103static void packet(struct atrf_dsc *dsc,
104    uint8_t type, uint8_t seq, uint8_t last, const void *payload, int len)
105{
106    uint8_t rx_buf[10];
107    int got;
108
109    while (1) {
110        packet_noack(dsc, type, seq, last, payload, len);
111        if (verbose)
112            write(2, ">", 1);
113        got = rf_recv(dsc, rx_buf, sizeof(rx_buf));
114        if (got <= 0) {
115            if (!seq && verbose)
116                write(2, "\b", 1);
117            continue;
118        }
119        if (verbose)
120            write(2, "\b?", 2);
121        if (got < 3)
122            continue;
123        if (verbose)
124            write(2, "\bA", 2);
125        if (rx_buf[0] != type+1 || rx_buf[1] != seq)
126            continue;
127        if (verbose)
128            write(2, "\b.", 2);
129        break;
130    }
131}
132
133
134/* ----- Ping -------------------------------------------------------------- */
135
136
137static void ping(struct atrf_dsc *dsc)
138{
139    uint8_t ping[] = { PING, 0, 0 };
140    uint8_t buf[100];
141    int got, i;
142
143    rf_send(dsc, ping, sizeof(ping));
144    got = rf_recv(dsc, buf, sizeof(buf));
145    if (!got)
146        return;
147    printf("%d: ", got);
148    for (i = 3; i != got; i++)
149        printf("%c", buf[i] >= ' ' && buf[i] <= '~' ? buf[i] : '?');
150    printf("\n");
151}
152
153
154/* ----- Firmware upload --------------------------------------------------- */
155
156
157static const uint8_t unlock_secret[PAYLOAD] = {
158    #include "unlock-secret.inc"
159};
160
161
162static void send_firmware(struct atrf_dsc *dsc, void *buf, int len)
163{
164    uint8_t payload[PAYLOAD];
165    uint8_t last, seq;
166
167    if (verbose)
168        write(2, "firmware ", 9);
169    last = (len+63)/64;
170    seq = 0;
171    packet_noack(dsc, RESET, 0, 0, unlock_secret, PAYLOAD);
172    packet(dsc, FIRMWARE, seq++, last, unlock_secret, PAYLOAD);
173    while (len >= PAYLOAD) {
174        packet(dsc, FIRMWARE, seq++, last, buf, PAYLOAD);
175        buf += PAYLOAD;
176        len -= PAYLOAD;
177    }
178    if (len) {
179        memcpy(payload, buf, len);
180        memset(payload+len, 0, PAYLOAD-len);
181        packet(dsc, FIRMWARE, seq++, last, payload, PAYLOAD);
182    }
183    if (verbose)
184        write(2, "\n", 1);
185}
186
187
188static void firmware(struct atrf_dsc *dsc, const char *name)
189{
190    FILE *file;
191    uint8_t fw[12*1024]; /* we have 8-12kB */
192    ssize_t len;
193
194    file = fopen(name, "r");
195    if (!file) {
196        perror(name);
197        exit(1);
198    }
199    len = fread(fw, 1, sizeof(fw), file);
200    if (len < 0) {
201        perror(name);
202        exit(1);
203    }
204    fclose(file);
205
206    send_firmware(dsc, fw, len);
207}
208
209
210/* ----- Image upload ------------------------------------------------------ */
211
212
213static const uint8_t image_secret[PAYLOAD*2] = {
214    #include "image-secret.inc"
215};
216
217
218static void send_image(struct atrf_dsc *dsc, void *buf, int len)
219{
220    uint8_t payload[PAYLOAD];
221    uint8_t last, seq;
222
223    hash_init();
224    hash_merge(image_secret, sizeof(image_secret));
225    if (verbose)
226        write(2, "image ", 6);
227
228    last = (len+63)/64+3;
229    seq = 0;
230    while (len >= PAYLOAD) {
231        packet(dsc, IMAGE, seq++, last, buf, PAYLOAD);
232        hash_merge(buf, PAYLOAD);
233        buf += PAYLOAD;
234        len -= PAYLOAD;
235    }
236    if (len) {
237        memcpy(payload, buf, len);
238        memset(payload+len, 0, PAYLOAD-len);
239        packet(dsc, IMAGE, seq++, last, payload, PAYLOAD);
240        hash_merge(payload, PAYLOAD);
241    }
242
243    /* @@@ salt */
244    packet(dsc, IMAGE, seq++, last, payload, PAYLOAD);
245    hash_merge(payload, PAYLOAD);
246    packet(dsc, IMAGE, seq++, last, payload, PAYLOAD);
247    hash_merge(payload, PAYLOAD);
248    hash_end();
249
250    /* hash */
251    hash_cp(payload, PAYLOAD, 0);
252    packet(dsc, IMAGE, seq++, last, payload, PAYLOAD);
253    hash_cp(payload, PAYLOAD, PAYLOAD);
254    packet(dsc, IMAGE, seq++, last, payload, PAYLOAD);
255
256    if (verbose)
257        write(2, "\n", 1);
258}
259
260
261static void image(struct atrf_dsc *dsc, const char *name)
262{
263    FILE *file;
264    uint8_t img[200] = { 0 };
265    ssize_t len;
266
267    file = fopen(name, "r");
268    if (!file) {
269        perror(name);
270        exit(1);
271    }
272    len = fread(img, 1, sizeof(img), file);
273    if (len < 0) {
274        perror(name);
275        exit(1);
276    }
277    fclose(file);
278
279    send_image(dsc, img, len);
280}
281
282
283/* ----- Parameter upload -------------------------------------------------- */
284
285
286static struct params params = {
287    .xa_high = XA_HIGH_DEFAULT,
288    .xa_low = XA_LOW_DEFAULT,
289    .px_fwd_left = PX_FWD_LEFT_DEFAULT,
290    .px_fwd_right = PX_FWD_RIGHT_DEFAULT,
291    .px_bwd_left = PX_BWD_LEFT_DEFAULT,
292    .px_bwd_right = PX_BWD_RIGHT_DEFAULT,
293    .tp_fwd_start = TP_FWD_START_DEFAULT,
294    .tp_bwd_start = TP_BWD_START_DEFAULT,
295    .tp_fwd_pix = TP_FWD_PIX_DEFAULT,
296    .tp_bwd_pix = TP_BWD_PIX_DEFAULT,
297};
298
299static struct map {
300    const char *name; /* NULL to mark end */
301    void *p;
302    int bytes; /* 1, 2, or 4 */
303} map[] = {
304    { "xa_high", &params.xa_high, 2 },
305    { "xa_low", &params.xa_low, 2 },
306    { "px_fwd_left", &params.px_fwd_left, 1 },
307    { "px_bwd_left", &params.px_bwd_left, 1 },
308    { "px_fwd_right", &params.px_fwd_right, 1 },
309    { "px_bwd_right", &params.px_bwd_right, 1 },
310    { "tp_fwd_start", &params.tp_fwd_start, 4 },
311    { "tp_bwd_start", &params.tp_bwd_start, 4 },
312    { "tp_fwd_pix", &params.tp_fwd_pix, 2 },
313    { "tp_bwd_pix", &params.tp_bwd_pix, 2 },
314    { NULL }
315};
316
317static int have_params = 0;
318
319
320static void add_param(const char *arg, const char *eq)
321{
322    const struct map *m;
323    size_t len;
324    unsigned long v;
325    char *end;
326    uint8_t *p;
327    int i;
328
329    len = eq-arg;
330    for (m = map; m->name; m++) {
331        if (strlen(m->name) != len)
332            continue;
333        if (!strncmp(arg, m->name, len))
334            break;
335    }
336    if (!m->name) {
337        fprintf(stderr, "unknown parameter \"%.*s\"\n",
338            (int) len, arg);
339        exit(1);
340    }
341    v = strtoul(eq+1, &end, 10);
342    if (*end) {
343        fprintf(stderr, "invalid value \"%s\"\n", eq+1);
344        exit(1);
345    }
346    p = m->p;
347    for (i = 0; i != m->bytes; i++) {
348        *p++ = v;
349        v >>= 8;
350    }
351    if (v) {
352        fprintf(stderr, "value \"%s\" is too large\n", eq+1);
353        exit(1);
354    }
355    have_params = 1;
356}
357
358
359static void send_param(struct atrf_dsc *dsc)
360{
361    uint8_t payload[PAYLOAD];
362
363    if (!have_params)
364        return;
365    hash_init();
366    hash_merge(image_secret, sizeof(image_secret));
367    if (verbose)
368        write(2, "param ", 6);
369    memset(payload, 0, PAYLOAD);
370    memcpy(payload, &params, sizeof(params));
371    packet(dsc, PARAM, 0, 4, payload, PAYLOAD);
372    hash_merge(payload, PAYLOAD);
373
374    /* @@@ salt */
375    packet(dsc, PARAM, 1, 4, payload, PAYLOAD);
376    hash_merge(payload, PAYLOAD);
377    packet(dsc, PARAM, 2, 4, payload, PAYLOAD);
378    hash_merge(payload, PAYLOAD);
379    hash_end();
380
381    /* hash */
382    hash_cp(payload, PAYLOAD, 0);
383    packet(dsc, PARAM, 3, 4, payload, PAYLOAD);
384    hash_cp(payload, PAYLOAD, PAYLOAD);
385    packet(dsc, PARAM, 4, 4, payload, PAYLOAD);
386
387    if (verbose)
388        write(2, "\n", 1);
389}
390
391
392/* ----- Reset ------------------------------------------------------------- */
393
394
395static void reset(struct atrf_dsc *dsc)
396{
397    packet_noack(dsc, RESET, 0, 0, unlock_secret, PAYLOAD);
398}
399
400
401/* ----- Samples ----------------------------------------------------------- */
402
403
404static volatile int run = 1;
405
406
407static void sigint(int sig)
408{
409    run = 0;
410}
411
412
413static int read_sample(uint8_t **s, uint16_t *t_high, uint16_t *t_low,
414    uint16_t *last)
415{
416    int v;
417
418    *t_low = *(*s)++;
419    *t_low |= *(*s)++ << 8;
420    if (*t_low < *last)
421        (*t_high)++;
422    *last = *t_low;
423    v = *(*s)++;
424    v |= *(*s)++ << 8;
425    return v;
426}
427
428
429static void samples(struct atrf_dsc *dsc, int gui)
430{
431    uint8_t buf[MAX_PSDU] = { 0, };
432    int got;
433    uint8_t *s;
434    uint16_t t_high, t_low, last;
435    int x, y;
436    double t;
437
438    buf[0] = 1;
439    packet(dsc, SAMPLE, 0, 0, buf, PAYLOAD);
440
441#ifdef GFX
442    if (gui)
443        plot_init();
444    else
445#endif
446        signal(SIGINT, sigint);
447    while (run) {
448        got = rf_recv(dsc, buf, sizeof(buf));
449        if (got <= 3)
450            continue;
451        if (buf[0] != SAMPLES)
452            continue;
453        if (debug > 1) {
454            int i;
455
456            for (i = 0; i != got; i++)
457                fprintf(stderr, " %02x", buf[i]);
458            fprintf(stderr, "\n");
459        }
460        if (debug)
461            fprintf(stderr, "%d:", got);
462        s = buf+3;
463        t_high = *s++;
464        t_high |= *s++ << 8;
465        last = 0;
466        while (s < buf+got-2) {
467            x = read_sample(&s, &t_high, &t_low, &last);
468            t = (t_high << 16 | t_low)/1000000.0;
469            if (debug)
470                fprintf(stderr, "\t%11.6f %d", t, x);
471            if (!gui)
472                printf("%11.6f\t%d\t", t, x);
473
474            y = read_sample(&s, &t_high, &t_low, &last);
475            t = (t_high << 16 | t_low)/1000000.0;
476            if (debug)
477                fprintf(stderr, "\t%11.6f %d\n", t, y);
478            if (!gui)
479                printf("%11.6f\t%d\n", t, y);
480
481#ifdef GFX
482            if (gui && !plot(x, y))
483                goto quit;
484#endif
485        }
486    }
487#ifdef GFX
488quit:
489#endif
490    buf[0] = 0;
491    packet(dsc, SAMPLE, 0, 0, buf, PAYLOAD);
492}
493
494
495/* ----- Command-line processing ------------------------------------------- */
496
497
498static unsigned get_int(uint8_t *p, int n)
499{
500    unsigned v = 0;
501    int i;
502
503    for (i = 0; i != n; i++)
504        v |= *p++ << (i*8);
505    return v;
506}
507
508
509static void usage(const char *name)
510{
511    const struct map *m;
512
513    fprintf(stderr,
514"usage: %s [-d] [param=value ...] image_file\n"
515   "%6s %s [-d] -F firmware_file\n"
516   "%6s %s [-d] -P\n"
517   "%6s %s [-d] -R\n"
518   "%6s %s [-d] -S [-S]\n\n"
519" -F file firmware upload\n"
520" -P ping (version query)\n"
521" -R reset\n"
522" -S sample with output on stdout. Exit with ^C.\n"
523#ifdef GFX
524" -S -S sample with graphical output. Exit with Q.\n\n"
525#endif
526"Parameters:\n"
527    , name, "", name, "", name, "", name, "", name);
528    for (m = map; m->name; m++)
529        fprintf(stderr, " %s\t(default %u)\n",
530            m->name, get_int(m->p, m->bytes));
531    exit(1);
532}
533
534
535int main(int argc, char **argv)
536{
537    const char *fw = NULL;
538    int do_ping = 0, do_reset = 0, do_sample = 0;
539    struct atrf_dsc *dsc;
540    int c;
541
542    while ((c = getopt(argc, argv, "dF:PRS")) != EOF)
543        switch (c) {
544        case 'd':
545            debug++;
546            break;
547        case 'F':
548            fw = optarg;
549            break;
550        case 'P':
551            do_ping = 1;
552            break;
553        case 'R':
554            do_reset = 1;
555            break;
556        case 'S':
557            do_sample++;
558            break;
559        default:
560            usage(*argv);
561        }
562
563    if (do_ping+do_reset+!!do_sample+!!fw > 1)
564        usage(*argv);
565    if (do_ping || do_reset || do_sample || fw) {
566        if (argc != optind)
567            usage(*argv);
568    } else {
569        if (argc == optind)
570            usage(*argv);
571    }
572
573    dsc = atrf_open(NULL);
574    if (!dsc)
575        return 1;
576
577    rf_init(dsc, 8, 15);
578    if (do_ping)
579        ping(dsc);
580    else if (do_reset)
581        reset(dsc);
582    else if (do_sample)
583        samples(dsc, do_sample > 1);
584    else if (fw)
585        firmware(dsc, fw);
586    else {
587        const char *eq;
588
589        while (optind != argc) {
590            eq = strchr(argv[optind], '=');
591            if (!eq)
592                break;
593            add_param(argv[optind], eq);
594            optind++;
595        }
596        if (argc > optind+1)
597            usage(*argv);
598        if (optind != argc)
599            image(dsc, argv[optind]);
600        send_param(dsc);
601    }
602
603    return 0;
604}
tools/hash.c
1#include "../fw/hash.c"
tools/plot.c
1/*
2 * tools/plot.c - Sample plot
3 *
4 * Written 2012 by Werner Almesberger
5 * Copyright 2012 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
16#include "SDL.h"
17#include "SDL_gfxPrimitives.h"
18
19#include "plot.h"
20
21
22#define XRES 1024
23#define YRES 1024
24
25#define RADIUS 3
26
27#define OLD_RGBA 0xffffff20
28#define NEW_RGBA 0xffffffff
29
30
31static SDL_Surface *surf;
32static int first = 1;
33static int last_x, last_y;
34
35static SDL_Surface *back;
36static SDL_Rect back_rect = {
37    .x = 0,
38    .y = 0,
39    .w = 2*RADIUS+1,
40    .h = 2*RADIUS+1,
41};
42
43static SDL_Rect front_rect = {
44    .w = 2*RADIUS+1,
45    .h = 2*RADIUS+1,
46};
47
48
49int plot(int x, int y)
50{
51    SDL_Event event;
52
53    if (!first) {
54        SDL_BlitSurface(back, &back_rect, surf, &front_rect);
55        SDL_LockSurface(surf);
56        filledCircleColor(surf, last_x, last_y, RADIUS, OLD_RGBA);
57        SDL_UnlockSurface(surf);
58    }
59
60    front_rect.x = x;
61    front_rect.y = y;
62    x += RADIUS;
63    y += RADIUS;
64
65    SDL_BlitSurface(surf, &front_rect, back, &back_rect);
66    SDL_LockSurface(surf);
67    filledCircleColor(surf, x, y, RADIUS, NEW_RGBA);
68    SDL_UnlockSurface(surf);
69
70    if (!first)
71        SDL_UpdateRect(surf,
72            last_x-RADIUS, last_y-RADIUS, 2*RADIUS+1, 2*RADIUS+1);
73    SDL_UpdateRect(surf, x-RADIUS, y-RADIUS, 2*RADIUS+1, 2*RADIUS+1);
74
75    first = 0;
76    last_x = x;
77    last_y = y;
78
79    while (SDL_PollEvent(&event))
80        switch (event.type) {
81        case SDL_KEYDOWN:
82            switch (event.key.keysym.sym) {
83            case SDLK_c:
84                SDL_LockSurface(surf);
85                SDL_FillRect(surf, NULL,
86                    SDL_MapRGB(surf->format, 0, 0, 0));
87                SDL_UpdateRect(surf, 0, 0, 0, 0);
88                SDL_UnlockSurface(surf);
89                break;
90            case SDLK_q:
91                return 0;
92            default:
93                break;
94            }
95            break;
96        case SDL_QUIT:
97            return 0;
98        default:
99            break;
100        }
101
102    return 1;
103}
104
105
106void plot_init(void)
107{
108    const SDL_PixelFormat *f;
109
110    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
111        fprintf(stderr, "SDL_init: %s\n", SDL_GetError());
112        exit(1);
113    }
114    atexit(SDL_Quit);
115
116    surf = SDL_SetVideoMode(XRES+2*RADIUS+1, YRES+2*RADIUS+1, 0,
117        SDL_SWSURFACE);
118    if (!surf) {
119        fprintf(stderr, "SDL_SetVideoMode: %s\n", SDL_GetError());
120        exit(1);
121    }
122
123    f = surf->format;
124    back = SDL_CreateRGBSurface(SDL_SWSURFACE, 2*RADIUS+1, 2*RADIUS+1,
125        f->BitsPerPixel, f->Rmask, f->Gmask, f->Bmask, f->Amask);
126    if (!back) {
127        fprintf(stderr, "SDL_SetVideoMode: %s\n", SDL_GetError());
128        exit(1);
129    }
130}
tools/plot.h
1/*
2 * tools/plot.h - Sample plot
3 *
4 * Written 2012 by Werner Almesberger
5 * Copyright 2012 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#ifndef PLOT_H
15#define PLOT_H
16
17int plot(int x, int y);
18void plot_init(void);
19
20#endif /* !PLOT_H */

Archive Download the corresponding diff file

Branches:
master
tornado-v1



interactive