Root/tools/atrf-path/gui.c

Source at commit c9e52c1978ed11ef9c404b381131b67703705fbb created 7 years 3 months ago.
By Werner Almesberger, atusb/atusb.kicad_pcb: bring back component references
1/*
2 * atrf-path/gui.c - Graphical output for atrf-path
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
19#include "SDL.h"
20#include "SDL_gfxPrimitives.h"
21
22#include "at86rf230.h"
23#include "atrf.h"
24#include "misctxrx.h"
25#include "getkey.h"
26
27#include "sweep.h"
28#include "gui.h"
29
30
31#define XRES 320
32#define YRES 240
33
34#define FG_RGBA 0xffffffff /* measurement color */
35#define OK_RGBA 0x00ff00ff
36#define OVER_RGBA 0xffff00ff
37#define UNDER_RGBA 0xff0000ff
38#define LIMIT_RGBA 0xff0000ff
39#define DUMP_RGBA 0x4040ffff
40
41#define CHAN_STEP 20 /* 4 pixels/MHz */
42#define SIDE_STEP 2
43#define CHAN_X_OFFSET 10
44#define Y_MIN -94
45#define Y_MAX -10
46
47#define STATUS_X (XRES-15)
48#define STATUS_Y 15
49#define STATUS_R 8
50
51
52static struct sample **dumps = NULL;
53static int n_dumps = 0;
54
55
56static int avg2y(double avg)
57{
58    return YRES-(avg-Y_MIN)/(Y_MAX-Y_MIN)*YRES-1;
59}
60
61
62static void segment(SDL_Surface *s, int *last_x, int *last_y, int x,
63    const struct sample *res, int first, uint32_t color)
64{
65    int y = avg2y(res->avg);
66
67    if (!first) {
68        aalineColor(s, *last_x, *last_y, x, y, color);
69}
70    *last_x = x;
71    *last_y = y;
72}
73
74
75static void draw(SDL_Surface *s, const struct sample *res, int cont_tx,
76    uint32_t color)
77{
78    int last_x, last_y;
79    int first, x, i;
80
81    x = CHAN_X_OFFSET;
82    first = 1;
83    for (i = 0; i != N_CHAN; i++) {
84        if (cont_tx != CONT_TX_P500K) {
85            segment(s, &last_x, &last_y, x, res, first, color);
86            first = 0;
87        }
88        res++;
89        x += 2*SIDE_STEP;
90
91        if (cont_tx != CONT_TX_M500K) {
92            segment(s, &last_x, &last_y, x, res, first, color);
93            first = 0;
94        }
95        res++;
96        x += CHAN_STEP-2*SIDE_STEP;
97    }
98}
99
100
101static void draw_limit(SDL_Surface *s, const double *v)
102{
103    int x, y, i, last = 0;
104
105    x = CHAN_X_OFFSET;
106    for (i = 0; i != N_CHAN; i++) {
107        y = avg2y(*v);
108        if (i)
109            vlineColor(s, x-CHAN_STEP/2, last, y, LIMIT_RGBA);
110        hlineColor(s, x-CHAN_STEP/2, x+CHAN_STEP/2, y, LIMIT_RGBA);
111        last = y;
112        x += CHAN_STEP;
113        v++;
114    }
115}
116
117
118static void disc(SDL_Surface *s, uint32_t color)
119{
120    filledCircleColor(s, STATUS_X, STATUS_Y, STATUS_R, color);
121    aacircleColor(s, STATUS_X, STATUS_Y, STATUS_R, color);
122}
123
124
125static void triangle(SDL_Surface *s, int cx, int cy, int r, uint32_t color)
126{
127    filledTrigonColor(s, cx, cy-r, cx+r*1.2, cy+r, cx-r*1.2, cy+r, color);
128// aatrigonColor(s, cx, cy-r, cx+r*1.2, cy+r, cx-r*1.2, cy+r, color);
129}
130
131
132static void up(SDL_Surface *s, uint32_t color)
133{
134    triangle(s, STATUS_X, STATUS_Y, STATUS_R, color);
135}
136
137
138static void down(SDL_Surface *s, uint32_t color)
139{
140    triangle(s, STATUS_X, STATUS_Y, -STATUS_R, color);
141}
142
143
144static void indicate(SDL_Surface *s, int fail)
145{
146    static uint32_t last = 0;
147    uint32_t color;
148
149    switch (fail) {
150    case 0:
151        color = OK_RGBA;
152        break;
153    case 1:
154        color = OVER_RGBA;
155        break;
156    case -1:
157        color = UNDER_RGBA;
158        break;
159    default:
160        abort();
161    }
162    if (color == last)
163        color = 0;
164    last = color;
165    switch (color) {
166    case OK_RGBA:
167        disc(s, color);
168        break;
169    case OVER_RGBA:
170        up(s, color);
171        break;
172    case UNDER_RGBA:
173        down(s, color);
174        break;
175    default:
176        break;
177    }
178}
179
180
181static void clear(SDL_Surface *s)
182{
183    SDL_FillRect(s, NULL, SDL_MapRGB(s->format, 0, 0, 0));
184}
185
186
187static void dump(const struct sweep *sweep, const struct sample *res)
188{
189    const size_t size = sizeof(struct sample)*N_CHAN*2;
190
191    print_sweep(sweep, res);
192
193    dumps = realloc(dumps, (n_dumps+1)*sizeof(struct sample *));
194    if (!dumps) {
195        perror("realloc");
196        exit(1);
197    }
198    dumps[n_dumps] = malloc(size);
199    if (!dumps[n_dumps]) {
200        perror("malloc");
201        exit(1);
202    }
203    memcpy(dumps[n_dumps], res, size);
204    n_dumps++;
205}
206
207
208static void draw_dumps(SDL_Surface *s, int cont_tx)
209{
210    int i;
211
212    for (i = 0; i != n_dumps; i++)
213        draw(s, dumps[i], cont_tx, DUMP_RGBA);
214}
215
216
217/* --- temporarily, for optimizing --- */
218
219#if 0
220
221#include <sys/time.h>
222
223
224static double t0;
225
226
227static double t(void)
228{
229    struct timeval tv;
230
231    gettimeofday(&tv, NULL);
232    return tv.tv_sec+tv.tv_usec/1000000.0;
233}
234
235
236static void tstart(void)
237{
238    t0 = t();
239}
240
241
242static void tstop(void)
243{
244    fprintf(stderr, "%.3f\n", t()-t0);
245}
246
247#else
248
249static void tstart(void) {}
250static void tstop(void) {}
251
252#endif
253
254
255int gui(const struct sweep *sweep, int sweeps)
256{
257    SDL_Surface *surf;
258    SDL_Event event;
259    int cycle;
260    int fail = 0;
261
262    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
263        fprintf(stderr, "SDL_init: %s\n", SDL_GetError());
264        exit(1);
265    }
266    atexit(SDL_Quit);
267
268    get_key_init();
269
270    surf = SDL_SetVideoMode(XRES, YRES, 0, SDL_SWSURFACE);
271    if (!surf) {
272        fprintf(stderr, "SDL_SetVideoMode: %s\n", SDL_GetError());
273        exit(1);
274    }
275
276    for (cycle = 0; cycle != sweeps || !sweeps; cycle++) {
277        struct sample res[N_CHAN*2];
278
279        /*
280         * Pass/fail logic:
281         *
282         * Quit exit at any time, without making a pass/fail decision
283         * Pass exit if the current result is "pass"
284         * ignored if the current result is "over"/"under"
285         * Fail exit if the current result is "under"
286         * ignored if the current result is "pass"
287         * ignored if the current result is "over", because this
288         * indicates an invalid measurement, not a defective
289         * device
290         */
291
292        while (SDL_PollEvent(&event))
293            switch (event.type) {
294            case SDL_KEYDOWN:
295                switch (event.key.keysym.sym) {
296                case SDLK_f:
297                    if (cycle && fail < 0)
298                        return -1;
299                    break;
300                case SDLK_p:
301                    if (cycle && !fail)
302                        return 1;
303                    break;
304                case SDLK_d:
305                    if (cycle)
306                        dump(sweep, res);
307                    break;
308                case SDLK_q:
309                    return 0;
310                default:
311                    break;
312                }
313                break;
314            case SDL_QUIT:
315                return 0;
316            default:
317                break;
318            }
319
320        switch (get_key()) {
321        case 'F':
322        case 'f':
323            if (cycle && fail < 0)
324                return -1;
325            break;
326        case 'P':
327        case 'p':
328            if (cycle && !fail)
329                return 1;
330            break;
331        case 'D':
332        case 'd':
333            if (cycle)
334                dump(sweep, res);
335            break;
336        case 'Q':
337        case 'q':
338        case 3: /* Ctrl-C */
339            return 0;
340        default:
341            break;
342        }
343
344        tstart();
345        fail = do_sweep(sweep, res);
346        tstop();
347
348        SDL_LockSurface(surf);
349
350        clear(surf);
351
352        draw_dumps(surf, sweep->cont_tx);
353        draw_limit(surf, sweep->min);
354        draw_limit(surf, sweep->max);
355        indicate(surf, fail);
356        draw(surf, res, sweep->cont_tx, FG_RGBA);
357
358        SDL_UnlockSurface(surf);
359        SDL_UpdateRect(surf, 0, 0, 0, 0);
360    }
361
362    return 0;
363}
364

Archive Download this file



interactive