diff --git a/tools/Makefile.common b/tools/Makefile.common index c25dde6..272afd7 100644 --- a/tools/Makefile.common +++ b/tools/Makefile.common @@ -22,6 +22,8 @@ endif CC_host = gcc CC_ben = mipsel-openwrt-linux-gcc +CFLAGS_host = +CFLAGS_ben = LDLIBS_host = -lusb LDLIBS_ben = MACROS_host = -DHAVE_USB @@ -40,5 +42,7 @@ else AR = $(AR_quiet) endif -CFLAGS += -I../../atusb/fw/include -I../include $(MACROS_$(TARGET)) +CFLAGS += $(CFLAGS_$(TARGET)) -I../../atusb/fw/include -I../include \ + $(MACROS_$(TARGET)) LDLIBS = $(LDLIBS_$(TARGET)) -L../lib -latspi +OBJS += $(OBJS_$(TARGET)) diff --git a/tools/atspi-rssi/Makefile b/tools/atspi-rssi/Makefile index a3365e1..268e837 100644 --- a/tools/atspi-rssi/Makefile +++ b/tools/atspi-rssi/Makefile @@ -14,3 +14,10 @@ MAIN = atspi-rssi include ../Makefile.common + +CFLAGS_host += $(shell sdl-config --cflags) +MACROS_host += -DHAVE_GFX +LDLIBS_host += $(shell sdl-config --libs) -lSDL_gfx +OBJS_host = gui.o zgrid.o digit.o + +$(MAIN): $(OBJS_$(TARGET)) diff --git a/tools/atspi-rssi/atspi-rssi.c b/tools/atspi-rssi/atspi-rssi.c index ae47732..cf2203c 100644 --- a/tools/atspi-rssi/atspi-rssi.c +++ b/tools/atspi-rssi/atspi-rssi.c @@ -21,6 +21,12 @@ #include "atspi.h" #include "misctxrx.h" +#ifdef HAVE_GFX +#include "gui.h" +#else +#define gui(dsc) abort() +#endif + static struct timeval t0; static volatile int run = 1; @@ -59,6 +65,12 @@ static void usage(const char *name) { fprintf(stderr, "usage: %s [-n] sweeps\n", name); + +#ifdef HAVE_GFX + fprintf(stderr, +"%6s %s -g\n", "", name); +#endif + exit(1); } @@ -66,12 +78,19 @@ static void usage(const char *name) int main(int argc, char **argv) { struct atspi_dsc *dsc; - unsigned long sweeps, i; + unsigned long arg = 0, i; char *end; int c; + int graphical = 0; - while ((c = getopt(argc, argv, "n")) != EOF) + while ((c = getopt(argc, argv, "gn")) != EOF) switch (c) { +#ifdef HAVE_GFX + case 'g': + graphical = 1; + + break; +#endif case 'n': break; default: @@ -79,8 +98,14 @@ int main(int argc, char **argv) } switch (argc-optind) { + case 0: + if (!graphical) + usage(*argv); + break; case 1: - sweeps = strtoul(argv[optind], &end, 0); + if (graphical) + usage(*argv); + arg = strtoul(argv[optind], &end, 0); if (*end) usage(*argv); break; @@ -100,9 +125,13 @@ int main(int argc, char **argv) * We'll wait for the PLL lock after selecting the channel. */ - gettimeofday(&t0, NULL); - for (i = 0; run && i != sweeps; i++) - sweep(dsc); + if (graphical) + gui(dsc); + else { + gettimeofday(&t0, NULL); + for (i = 0; run && i != arg; i++) + sweep(dsc); + } atspi_reg_write(dsc, REG_TRX_STATE, TRX_CMD_TRX_OFF); diff --git a/tools/atspi-rssi/digit.c b/tools/atspi-rssi/digit.c new file mode 100644 index 0000000..101e355 --- /dev/null +++ b/tools/atspi-rssi/digit.c @@ -0,0 +1,87 @@ +/* + * atspi-rssi/digit.c - Draw 7 segment style digits + * + * Written 2010 by Werner Almesberger + * Copyright 2010 Werner Almesberger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + + +#include + +#include "SDL.h" +#include "SDL_gfxPrimitives.h" + +#include "digit.h" + + +static void hlines_3(SDL_Surface *s, int x0, int x1, int y0, int ym, int y1, + uint32_t fg) +{ + hlineColor(s, x0, x1, y0, fg); + hlineColor(s, x0, x1, ym, fg); + hlineColor(s, x0, x1, y1, fg); +} + + +void digit(SDL_Surface *s, int n, int x0, int x1, int y0, int ym, int y1, + uint32_t fg) +{ + switch (n) { + case 8: + hlineColor(s, x0, x1, ym, fg); + /* fall through */ + case 0: + hlineColor(s, x0, x1, y0, fg); + vlineColor(s, x0, y0, y1, fg); + /* fall through */ + case 7: + hlineColor(s, x0, x1, y1, fg); + vlineColor(s, x1, y0, y1, fg); + break; + + case 1: + lineColor(s, x0, ym, x1, y1, fg); + vlineColor(s, x1, y0, y1, fg); + break; + + case 2: + hlines_3(s, x0, x1, y0, ym, y1, fg); + vlineColor(s, x0, y0, ym, fg); + vlineColor(s, x1, ym, y1, fg); + break; + + case 9: + vlineColor(s, x0, ym, y1, fg); + /* fall through */ + case 3: + hlines_3(s, x0, x1, y0, ym, y1, fg); + vlineColor(s, x1, y0, y1, fg); + break; + + case 4: + hlineColor(s, x0, x1, ym, fg); + vlineColor(s, x0, ym, y1, fg); + vlineColor(s, x1, y0, y1, fg); + break; + + case 6: + hlines_3(s, x0, x1, y0, ym, y1, fg); + vlineColor(s, x0, y0, y1, fg); + vlineColor(s, x1, y0, ym, fg); + break; + + case 5: + hlines_3(s, x0, x1, y0, ym, y1, fg); + vlineColor(s, x0, ym, y1, fg); + vlineColor(s, x1, y0, ym, fg); + break; + + default: + abort(); + } +} diff --git a/tools/atspi-rssi/digit.h b/tools/atspi-rssi/digit.h new file mode 100644 index 0000000..a727547 --- /dev/null +++ b/tools/atspi-rssi/digit.h @@ -0,0 +1,25 @@ +/* + * atspi-rssi/digit.h - Draw 7 segment style digits + * + * Written 2010 by Werner Almesberger + * Copyright 2010 Werner Almesberger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + + +#ifndef DIGIT_H +#define DIGIT_H + +#include + +#include "SDL.h" + + +void digit(SDL_Surface *s, int n, int x0, int x1, int y0, int ym, int y1, + uint32_t fg); + +#endif /* !DIGIT_H */ diff --git a/tools/atspi-rssi/gui.c b/tools/atspi-rssi/gui.c new file mode 100644 index 0000000..4191082 --- /dev/null +++ b/tools/atspi-rssi/gui.c @@ -0,0 +1,147 @@ +/* + * atspi-rssi/gui.c - Graphical output for atspi-rssi + * + * Written 2010 by Werner Almesberger + * Copyright 2010 Werner Almesberger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + + +#include +#include +#include +#include +#include + +#include "SDL.h" +#include "SDL_gfxPrimitives.h" + +#include "at86rf230.h" +#include "atspi.h" +#include "misctxrx.h" + +#include "zgrid.h" +#include "digit.h" +#include "gui.h" + + +#define XRES 320 +#define YRES 240 + +#define N_CHAN 16 +#define N_TIME 64 + + +static struct timeval t0; + + +static void shift_grid(int *z, int nx, int ny) +{ + int *p1, *p0, *s; + int x, y; + + p1 = z+(ny-1)*nx; + for (y = 1; y != ny; y++) { + p0 = s = p1-nx; + for (x = 0; x != nx; x++) + *p1++ = *p0++; + p1 = s; + } +} + + +static void sweep(struct atspi_dsc *dsc, int *z) +{ + int chan; + + for (chan = 11; chan <= 26; chan++) { + atspi_reg_write(dsc, REG_PHY_CC_CCA, chan); + /* 150 us, according to AVR2001 section 3.5 */ + wait_for_interrupt(dsc, IRQ_PLL_LOCK, IRQ_PLL_LOCK, 10, 20); + + *z++ = 3*atspi_reg_read(dsc, REG_PHY_RSSI) & RSSI_MASK; +#if 0 + if (chan >= 13 && chan <= 19 ) + z[-1] = 3*28-(chan-16)*(chan-16)*(chan-16)*(chan-16); +#endif + } +} + + +static void clear(SDL_Surface *s) +{ + SDL_FillRect(s, NULL, SDL_MapRGB(s->format, 0, 0, 0)); +} + + +#define CBIG(pos) \ + x-5+(pos)*6, x-1+(pos)*6, y+8, y+4, y, 0xff4040ff +#define CSMALL(pos) \ + x-7+(pos)*4, x-5+(pos)*4, y+15, y+13, y+11, 0x20ff00ff + + +static void label_channels(SDL_Surface *s, int sx, int x0, int y0) +{ + int x, y, i, c, f; + + x = x0; + y = s->h-y0+4; + for (i = 0; i != N_CHAN; i++) { + c = i+11; + digit(s, c/10, CBIG(0)); + digit(s, c % 10, CBIG(1)); + f = 2405+5*i; + if (i & 1) + y++; + digit(s, f/1000, CSMALL(0)); + digit(s, (f/100) % 10, CSMALL(1)); + digit(s, (f/10) % 10, CSMALL(2)); + digit(s, f % 10, CSMALL(3)); + if (i & 1) + y--; + x += sx; + } +} + + +void gui(struct atspi_dsc *dsc) +{ + SDL_Surface *surf; + int z[N_CHAN*N_TIME]; + + memset(z, 0, sizeof(z)); + gettimeofday(&t0, NULL); + + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + fprintf(stderr, "SDL_init: %s\n", SDL_GetError()); + exit(1); + } + atexit(SDL_Quit); + + surf = SDL_SetVideoMode(XRES, YRES, 0, SDL_SWSURFACE); + if (!surf) { + fprintf(stderr, "SDL_SetVideoMode: %s\n", SDL_GetError()); + exit(1); + } + + while (1) { + shift_grid(z, N_CHAN, N_TIME); + sweep(dsc, z); + + SDL_LockSurface(surf); + + clear(surf); + zgrid_draw(surf, z, N_CHAN, N_TIME, + 17, 2, 1, + 7, 40, + 0xffffff00, 0x00408080); + label_channels(surf, 17, 7, 40); + + SDL_UnlockSurface(surf); + SDL_UpdateRect(surf, 0, 0, 0, 0); + } +} diff --git a/tools/atspi-rssi/gui.h b/tools/atspi-rssi/gui.h new file mode 100644 index 0000000..cba2119 --- /dev/null +++ b/tools/atspi-rssi/gui.h @@ -0,0 +1,21 @@ +/* + * atspi-rssi/gui.h - Graphical output for atspi-rssi + * + * Written 2010 by Werner Almesberger + * Copyright 2010 Werner Almesberger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef GUI_H +#define GUI_H + +#include "atspi.h" + + +void gui(struct atspi_dsc *dsc); + +#endif /* !GUI_H */ diff --git a/tools/atspi-rssi/zgrid.c b/tools/atspi-rssi/zgrid.c new file mode 100644 index 0000000..c9422f1 --- /dev/null +++ b/tools/atspi-rssi/zgrid.c @@ -0,0 +1,99 @@ +/* + * atspi-rssi/zgrid.c - Display a surface in faux 3D with SDL/SDL_gfx + * + * Written 2010 by Werner Almesberger + * Copyright 2010 Werner Almesberger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + + +#include +#include +#include + +#include "SDL.h" +#include "SDL_gfxPrimitives.h" + +#include "zgrid.h" + + +#define SWAP(x, y) \ + do { typeof(x) swap_tmp = (x); (x) = (y); (y) = swap_tmp; } while (0) + + +static int *alloc_row(int nx) +{ + int *p; + + p = malloc(nx*sizeof(*p)); + if (p) + return p; + perror("malloc"); + exit(1); +} + + +static void draw_band(SDL_Surface *s, const int *ax, const int *ay, + const int *bx, const int *by, int n, uint32_t fg, uint32_t bg) +{ + Sint16 px[4], py[4]; + int i; + + for (i = n-2; i >= 0; i--) { + px[0] = ax[i]; + px[1] = ax[i+1]; + px[2] = bx[i+1]; + px[3] = bx[i]; + py[0] = ay[i]; + py[1] = ay[i+1]; + py[2] = by[i+1]; + py[3] = by[i]; + filledPolygonColor(s, px, py, 4, bg); + aalineColor(s, ax[i+1], ay[i+1], bx[i+1], by[i+1], fg); + aalineColor(s, bx[i], by[i], bx[i+1], by[i+1], fg); + } + aalineColor(s, ax[0], ay[0], bx[0], by[0], fg); +} + + +static void draw_polyline(SDL_Surface *s, const int *px, const int *py, + int n, uint32_t rgba) +{ + int i; + + for (i = 0; i != n-1; i++) + aalineColor(s, px[i], py[i], px[i+1], py[i+1], rgba); +} + + +void zgrid_draw(SDL_Surface *s, const int *z, int nx, int ny, + int sx, int sy, int sxy, int x0, int y0, uint32_t fg, uint32_t bg) +{ + int *lx = alloc_row(nx); + int *ly = alloc_row(nx); + int *px = alloc_row(nx); + int *py = alloc_row(nx); + int x, y, yz0; + const int *zp; + uint8_t a; + + for (y = ny-1; y >= 0; y--) { + a = (ny-1-y)*0xe0/(ny-1)+0x1f; + yz0 = s->h-y0-y*sy-1; + zp = z+y*nx; + for (x = 0; x != nx; x++) { + px[x] = x0+x*sx+y*sxy; + py[x] = yz0-zp[x]; + } + if (y != ny-1) { + draw_band(s, px, py, lx, ly, nx, fg | a, bg); + } + SWAP(px, lx); + SWAP(py, ly); + } + draw_polyline(s, lx, ly, nx, fg | 0xff); +} diff --git a/tools/atspi-rssi/zgrid.h b/tools/atspi-rssi/zgrid.h new file mode 100644 index 0000000..a5db289 --- /dev/null +++ b/tools/atspi-rssi/zgrid.h @@ -0,0 +1,24 @@ +/* + * atspi-rssi/zgrid.h - Display a surface in faux 3D with SDL/SDL_gfx + * + * Written 2010 by Werner Almesberger + * Copyright 2010 Werner Almesberger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef ZGRID_H +#define ZGRID_H + +#include + +#include "SDL.h" + + +void zgrid_draw(SDL_Surface *s, const int *z, int nx, int ny, + int sx, int sy, int sxy, int x0, int y0, uint32_t fg, uint32_t bg); + +#endif /* !ZGRID_H */