Root/tools/atrf-rssi/gui.c

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

Archive Download this file



interactive