Root/tools/atrf-rssi/gui.c

1/*
2 * atrf-rssi/gui.c - Graphical output for atrf-rssi
3 *
4 * Written 2010-2011 by Werner Almesberger
5 * Copyright 2010-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 <signal.h>
18#include <sys/time.h>
19
20#include "SDL.h"
21#include "SDL_gfxPrimitives.h"
22
23#include "at86rf230.h"
24#include "atrf.h"
25#include "misctxrx.h"
26#include "getkey.h"
27
28#include "zgrid.h"
29#include "digit.h"
30#include "letter.h"
31#include "gui.h"
32
33
34#define XRES 320
35#define YRES 240
36
37#define N_CHAN 16
38#define N_TIME 64
39
40
41#define FG_RGBA 0xffffff00 /* grid foreround color */
42#define BG_RGBA 0x00408080 /* grid background color */
43#define CHAN_RGBA 0xff4040ff /* channel number color */
44#define FREQ_RGBA 0x20ff00ff /* frequency color */
45#define WCHAN_RGBA 0xffff00e0 /* WLAN channel number color */
46#define WLAN_RGBA 0x8080ffff /* WLAN channel occupancy color */
47#define SEL_RGBA WLAN_RGBA /* WLAN area selector */
48
49#define X_STEP 17 /* grid x step */
50#define Y_STEP 2 /* grid y step */
51#define Z_STEP 3 /* z multiplier */
52#define X_STEP_Y 1 /* x shift for each y step */
53#define X_OFFSET 7 /* x coordinate of lower left grid corner */
54#define Y_OFFSET 40 /* y coordinate of lower left grid corner */
55
56#define X_WLAN_OFFSET 31
57#define Y_WLAN_OFFSET 15
58
59#define WLAN_XR (X_STEP*9.5/5)
60#define WLAN_YH 6
61
62#define X_SEL (XRES-20)
63#define Y_SEL (YRES-50)
64
65
66static enum {
67    area_off,
68    area_us,
69    area_eu,
70    area_jp,
71} wlan_area = area_off;
72
73
74static struct timeval t0;
75
76
77static void shift_grid(int *z, int nx, int ny)
78{
79    int *p1, *p0, *s;
80    int x, y;
81
82    p1 = z+(ny-1)*nx;
83    for (y = 1; y != ny; y++) {
84        p0 = s = p1-nx;
85        for (x = 0; x != nx; x++)
86            *p1++ = *p0++;
87        p1 = s;
88    }
89}
90
91
92static void sweep(struct atrf_dsc *dsc, int *z)
93{
94    int chan;
95
96    for (chan = 11; chan <= 26; chan++) {
97        atrf_reg_write(dsc, REG_PHY_CC_CCA, chan);
98        /* 150 us, according to AVR2001 section 3.5 */
99        wait_for_interrupt(dsc, IRQ_PLL_LOCK, IRQ_PLL_LOCK, 1);
100
101        *z++ = Z_STEP*atrf_reg_read(dsc, REG_PHY_RSSI) & RSSI_MASK;
102#if 0
103        if (chan >= 13 && chan <= 19 )
104            z[-1] = 3*28-(chan-16)*(chan-16)*(chan-16)*(chan-16);
105#endif
106    }
107}
108
109
110static void clear(SDL_Surface *s)
111{
112    SDL_FillRect(s, NULL, SDL_MapRGB(s->format, 0, 0, 0));
113}
114
115
116#define CBIG(pos) \
117    x-5+(pos)*6, x-1+(pos)*6, y+8, y+4, y, CHAN_RGBA
118#define CSMALL(pos) \
119    x-7+(pos)*4, x-5+(pos)*4, y+15, y+13, y+11, FREQ_RGBA
120#define CWLAN(pos) \
121    x-4+(pos)*5, x-1+(pos)*5, y+6, y+3, y, WCHAN_RGBA
122#define CSEL(pos) \
123    x-4+(pos)*5, x-1+(pos)*5, y+6, y+3, y, SEL_RGBA
124
125
126static void label_channels(SDL_Surface *s, int sx, int x0, int y0)
127{
128    int x, y, i, c, f;
129
130    x = x0;
131    y = s->h-y0+4;
132    for (i = 0; i != N_CHAN; i++) {
133        c = i+11;
134        digit(s, c/10, CBIG(0));
135        digit(s, c % 10, CBIG(1));
136        f = 2405+5*i;
137        if (i & 1)
138            y++;
139        digit(s, f/1000, CSMALL(0));
140        digit(s, (f/100) % 10, CSMALL(1));
141        digit(s, (f/10) % 10, CSMALL(2));
142        digit(s, f % 10, CSMALL(3));
143        if (i & 1)
144            y--;
145        x += sx;
146    }
147}
148
149
150static void print(SDL_Surface *s, int x, int y, const char *t)
151{
152    int i = 0;
153
154    while (*t) {
155        letter(s, *t, CSEL(i));
156        t++;
157        i++;
158    }
159}
160
161
162static void area_selector(SDL_Surface *s, int x0, int y0)
163{
164    int x, y, r;
165
166    print(s, x0, y0, "EU");
167    print(s, x0, y0+9, "JP");
168    print(s, x0, y0+18, "US");
169    switch (wlan_area) {
170    case area_off:
171        return;
172    case area_eu:
173        y = 0;
174        break;
175    case area_jp:
176        y = 1;
177        break;
178    case area_us:
179        y = 2;
180        break;
181    default:
182        abort();
183    }
184    y = y0+9*y+3;
185    x = x0-8;
186    r = 6;
187    filledTrigonColor(s, x, y, x-r, y+r/2, x-r, y-r/2, SEL_RGBA);
188}
189
190
191static int wlan_channels(void)
192{
193    switch (wlan_area) {
194    case area_us:
195        return 11;
196    case area_eu:
197        return 13;
198    case area_jp:
199        return 14;
200    default:
201        abort();
202    }
203}
204
205
206static int show_wlan_channel(int c)
207{
208    switch (wlan_area) {
209    case area_jp:
210        if (c == 14)
211            return 1;
212        /* fall through */
213    case area_us:
214        return !((c-1) % 5);
215    case area_eu:
216        return !((c-1) % 4);
217    default:
218        abort();
219    }
220}
221
222
223static void label_wlan_channels(SDL_Surface *s, int sx, int x0, int y0)
224{
225    int x, xb, y, i, c;
226
227    xb = x0;
228    y = s->h-y0+4;
229    for (i = 0; i != wlan_channels(); i++) {
230        c = i+1;
231        /* Japan special channel: 22 MHz from channel 13 */
232        if (c == 14)
233            xb += X_STEP*12/5-X_STEP;
234        if (c > 9) {
235            x = xb;
236            digit(s, c/10, CWLAN(0));
237        } else {
238            x = xb-3;
239        }
240        digit(s, c % 10, CWLAN(1));
241        if (show_wlan_channel(c)) {
242            hlineColor(s, xb-WLAN_XR, xb+WLAN_XR, y-WLAN_YH,
243                WLAN_RGBA);
244            vlineColor(s, xb, y-2, y-WLAN_YH+1, WLAN_RGBA);
245        }
246        xb += sx;
247    }
248}
249
250
251void gui(struct atrf_dsc *dsc)
252{
253    SDL_Surface *surf;
254    int z[N_CHAN*N_TIME];
255    SDL_Event event;
256
257    memset(z, 0, sizeof(z));
258    gettimeofday(&t0, NULL);
259    
260    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
261        fprintf(stderr, "SDL_init: %s\n", SDL_GetError());
262        exit(1);
263    }
264    atexit(SDL_Quit);
265
266    get_key_init();
267
268    surf = SDL_SetVideoMode(XRES, YRES, 0, SDL_SWSURFACE);
269    if (!surf) {
270        fprintf(stderr, "SDL_SetVideoMode: %s\n", SDL_GetError());
271        exit(1);
272    }
273
274    while (1) {
275        while (SDL_PollEvent(&event)) {
276            switch (event.type) {
277            case SDL_KEYDOWN:
278                switch (event.key.keysym.sym) {
279                case SDLK_j:
280                    wlan_area = area_jp;
281                    break;
282                case SDLK_e:
283                    wlan_area = area_eu;
284                    break;
285                case SDLK_u:
286                    wlan_area = area_us;
287                    break;
288                case SDLK_q:
289                    return;
290                default:
291                    break;
292                }
293                break;
294            case SDL_QUIT:
295                return;
296            default:
297                break;
298            }
299        }
300
301        switch (get_key()) {
302        case 'J':
303        case 'j':
304            wlan_area = area_jp;
305            break;
306        case 'E':
307        case 'e':
308            wlan_area = area_eu;
309            break;
310        case 'U':
311        case 'u':
312            wlan_area = area_us;
313            break;
314        case 'Q':
315        case 'q':
316            return;
317        default:
318            break;
319        }
320
321        shift_grid(z, N_CHAN, N_TIME);
322        sweep(dsc, z);
323
324        SDL_LockSurface(surf);
325
326        clear(surf);
327        zgrid_draw(surf, z, N_CHAN, N_TIME,
328            X_STEP, Y_STEP, X_STEP_Y,
329            X_OFFSET, Y_OFFSET,
330            FG_RGBA, BG_RGBA);
331        label_channels(surf, X_STEP, X_OFFSET, Y_OFFSET);
332        area_selector(surf, X_SEL, Y_SEL);
333        if (wlan_area != area_off)
334            label_wlan_channels(surf, X_STEP, X_WLAN_OFFSET,
335                Y_WLAN_OFFSET);
336
337        SDL_UnlockSurface(surf);
338        SDL_UpdateRect(surf, 0, 0, 0, 0);
339    }
340}
341

Archive Download this file



interactive