diff --git a/tools/Makefile b/tools/Makefile index dd6c518..356c83b 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -11,8 +11,8 @@ # -BEN_DIRS=atrf-id atrf-path atrf-proxy atrf-reset atrf-rssi atrf-trim \ - atrf-txrx atrf-xmit atrf-xtal +BEN_DIRS=atrf-gpio atrf-id atrf-path atrf-proxy atrf-reset \ + atrf-rssi atrf-trim atrf-txrx atrf-xmit atrf-xtal DIRS=$(BEN_DIRS) usbwait TARGET_ONLY_DIRS=lib diff --git a/tools/atrf-gpio/Makefile b/tools/atrf-gpio/Makefile new file mode 100644 index 0000000..a626159 --- /dev/null +++ b/tools/atrf-gpio/Makefile @@ -0,0 +1,31 @@ +# +# atrf-gpio/Makefile - Build the GPIO test utility +# +# Written 2010, 2011 by Werner Almesberger +# Copyright 2010, 2011 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. +# + + +MAIN = atrf-gpio + +include ../Makefile.common + +MACROS_host += -DHAVE_ATUSB +OBJS_host = atusb.o + +MACROS_ben_openwrt += -DHAVE_ATBEN +OBJS_ben_openwrt = atben.o + +MACROS_ben_jlime += -DHAVE_ATBEN +OBJS_ben_jlime = atben.o + + +$(MAIN): $(OBJS_$(TARGET)) + +clean:: + rm -f $(OBJS_host) $(OBJS_ben_openwrt) $(OBJS_ben_jlime) diff --git a/tools/atrf-gpio/atben.c b/tools/atrf-gpio/atben.c new file mode 100644 index 0000000..23cc253 --- /dev/null +++ b/tools/atrf-gpio/atben.c @@ -0,0 +1,185 @@ +/* + * atrf-gpio/atben.c - ATBEN-specific GPIO driver + * + * Written 2011 by Werner Almesberger + * Copyright 2011 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 "at86rf230.h" +#include "atrf.h" + +#include "atrf-gpio.h" + + +static struct pin { + const char *name; + int bit; +} pins[] = { + { "SCLK", 11 }, + { "MISO", 10 }, + { "SLP_TR", 9 }, + { "MOSI", 8 }, + { "nSEL", 13 }, + { "IRQ", 12 }, + { NULL, 0 } +}; + +static uint32_t orig_dat, orig_pe, orig_dir; +static uint32_t changed = 0; + + +/* ----- Ben hardware ------------------------------------------------------ */ + + +static volatile uint32_t *pdpin, *pddat, *pddats, *pddatc; +static volatile uint32_t *pdpe, *pdpes, *pdpec; +static volatile uint32_t *pddir, *pddirs, *pddirc; + + +static void ben_setup(struct atrf_dsc *dsc) +{ + volatile void *base = atrf_ben_regs(dsc); + + pdpin = base+0x10300; + pddat = base+0x10310; + pddats = base+0x10314; + pddatc = base+0x10318; + + pdpe = base+0x10330; + pdpes = base+0x10334; + pdpec = base+0x10338; + + pddir = base+0x10360; + pddirs = base+0x10364; + pddirc = base+0x10368; +} + + +/* ----- Diagnostic dump --------------------------------------------------- */ + + +static char decode_cfg(uint32_t bit) +{ + if (*pddir & bit) + return *pddat & bit ? '1' : '0'; + return *pdpe & bit ? 'Z' : 'P'; +} + + +static void dump_pd(uint32_t expect, uint32_t got, uint32_t mask) +{ + const struct pin *pin; + + fprintf(stderr, "name\tcfg exp got\n"); + for (pin = pins; pin->name; pin++) { + uint32_t bit = 1 << pin->bit; + + fprintf(stderr, "%s\t%c %d %d", + pin->name, decode_cfg(bit), + !!(expect & bit), !!(got & bit)); + if ((expect ^ got) & mask & bit) + fprintf(stderr, "\t***"); + fputc('\n', stderr); + } +} + + +static void restore_gpios(void) +{ + *pddats = orig_dat & changed; + *pddatc = ~orig_dat & changed; + *pdpes = orig_pe & changed; + *pdpec = ~orig_pe & changed; + *pddirs = orig_dir & changed; + *pddirc = ~orig_dir & changed; +} + + +/* ----- Decode and apply pattern ------------------------------------------ */ + + +void do_atben(struct atrf_dsc *dsc, const char *pattern, const char *next) +{ + static int first = 1; + uint32_t read = 0, expect = 0; + const struct pin *pin = pins; + uint32_t got; + const char *p; + + if (first) { + ben_setup(dsc); + orig_dat = *pddat; + orig_pe = *pdpe; + orig_dir = *pddir; + atexit(restore_gpios); + + first = 0; + } + + for (p = pattern; *p; p++) { + uint32_t bit; + + if (!pin->name) { + fprintf(stderr, "too many pins in \"%s\"\n", pattern); + exit(1); + } + bit = 1 << pin->bit; + switch (*p) { + case '0': + *pddatc = bit; + *pddirs = bit; + break; + case '1': + *pddats = bit; + *pddirs = bit; + break; + case 'H': + expect |= bit; + /* fall through */ + case 'L': + read |= bit; + /* fall through */ + case 'Z': + *pdpec = bit; + *pddirc = bit; + break; + case 'h': + expect |= bit; + /* fall through */ + case 'l': + read |= bit; + /* fall through */ + case 'z': + *pddirc = bit; + *pdpes = bit; + break; + case 'x': + pin++; + continue; + default: + continue; + } + changed |= bit; + pin++; + } + + usleep(1000); + + got = *pdpin; + if ((got & read) != expect) { + dump_pd(expect, got, read); + fprintf(stderr, "at \"%s\", next \"%s\"\n", pattern, next); + exit(1); + } +} diff --git a/tools/atrf-gpio/atrf-gpio.c b/tools/atrf-gpio/atrf-gpio.c new file mode 100644 index 0000000..d2f5042 --- /dev/null +++ b/tools/atrf-gpio/atrf-gpio.c @@ -0,0 +1,204 @@ +/* + * atrf-gpio/atrf-gpio.c - ATBEN/ATUSB GPIO test + * + * Written 2011 by Werner Almesberger + * Copyright 2011 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 "at86rf230.h" +#include "atrf.h" + +#include "atrf-gpio.h" + + +static void atben(struct atrf_dsc *dsc, const char *pattern, const char *next) +{ +#ifdef HAVE_ATBEN + do_atben(dsc, pattern, next); +#else + fprintf(stderr, "not compiled with ATBEN support\n"); + exit(1); +#endif +} + + +static void atusb(struct atrf_dsc *dsc, const char *pattern, const char *next) +{ +#ifdef HAVE_ATUSB + do_atusb(dsc, pattern, next); +#else + fprintf(stderr, "not compiled with ATUSB support\n"); + exit(1); +#endif +} + + +static void bad_reg_op(const char *arg) +{ + fprintf(stderr, "invalid operation \"%s\"\n", arg); + exit(1); +} + + +static int reg_op(struct atrf_dsc *dsc, const char *arg, int doit) +{ + const char *p; + char *end; + unsigned long reg, value; + uint8_t got; + + p = strchr(arg, '='); + if (!p) + p = strchr(arg, ':'); + if (!p) + p = strchr(arg, '!'); + if (!p) + p = strchr(arg, '/'); + if (!p) + return 0; + reg = strtoul(arg, &end, 0); + if (end != p || reg > 0xff) + bad_reg_op(arg); + value = strtoul(p+1, &end, 0); + if (*end || value > 0xff) + bad_reg_op(arg); + if (!doit) + return 1; + switch (*p) { + case '=': + atrf_reg_write(dsc, reg, value); + break; + case ':': + got = atrf_reg_read(dsc, reg); + if (end != p+1 && got != value) { + fprintf(stderr, + "register 0x%02lx: got 0x%02x expected 0x%02lx\n", + reg, got, value); + exit(1); + } + break; + case '!': + atrf_sram_write(dsc, reg, value); + break; + case '/': + got = atrf_sram_read(dsc, reg); + if (got != value) { + fprintf(stderr, + "got 0x%02x expected 0x%02lx\n", got, value); + exit(1); + } + break; + default: + abort(); + } + return 1; +} + + +static void usage(const char *name) +{ + fprintf(stderr, +"usage: %s [-d driver[:arg]] command|pattern ...\n" +" -d driver[:arg] use the specified driver (default: %s)\n\n" +" command is one of:\n" +" reg=value set transceiver register\n" +" reg:[value] read transceiver register and (optionally) verify value\n" +" addr!value write one byte to SRAM\n" +" addr/value read and verify one byte from SRAM\n" +" #... comment\n\n" +" pattern is a sequence of the following characters:\n" +" 0 = output a strong 0 1 = output a strong 1\n" +" L = pull up, expect to read 0 H = pull up, expect to read 1\n" +" l = no pull-up, expect to read 0 h = no pull-up, expect to read 1\n" +" Z = pull up, don't read z = no pull-up, don't read\n" +" x = don't care . = separator\n" + , name, atrf_default_driver_name()); + exit(1); +} + + +/* + * 0 strong 0 out + * 1 strong 1 out + * H pull-up, read 1 + * L pull-up, read 0 + * h no pull-up, read 1 + * l no pull-up, read 0 + * Z pull-up, don't read + * z no pull-up, don't read + * x don't care + * . separator + */ + + +int main(int argc, char *const *argv) +{ + const char *driver = NULL; + struct atrf_dsc *dsc; + int trx_off = 1; + int c, i; + const char *s; + + while ((c = getopt(argc, argv, "d:p")) != EOF) + switch (c) { + case 'd': + driver = optarg; + break; + case 'p': + trx_off = 0; + break; + default: + usage(*argv); + } + + for (i = optind; i != argc; i++) { + if (*argv[i] == '#') + continue; + if (reg_op(NULL, argv[i], 0)) + continue; + for (s = argv[i]; *s; s++) + if (!strchr("01HLhlZzx.", *s)) + fprintf(stderr, + "invalid configuration '%c' in \"%s\"\n", + *s, argv[i]); + } + + dsc = atrf_open(driver); + if (!dsc) + return 1; + + atrf_reset_rf(dsc); + + if (trx_off) { + atrf_reg_write(dsc, REG_TRX_STATE, TRX_CMD_TRX_OFF); + do usleep(100); + while ((atrf_reg_read(dsc, REG_TRX_STATUS) & TRX_STATUS_MASK) + != TRX_STATUS_TRX_OFF); + } + + for (i = optind; i != argc; i++) { + if (*argv[i] == '#') + continue; + if (reg_op(dsc, argv[i], 1)) + continue; + if (atrf_usb_handle(dsc)) + atusb(dsc, argv[i], argv[i+1]); + else + atben(dsc, argv[i], argv[i+1]); + } + +// atrf_close(dsc); + + return 0; +} diff --git a/tools/atrf-gpio/atrf-gpio.h b/tools/atrf-gpio/atrf-gpio.h new file mode 100644 index 0000000..ad7389a --- /dev/null +++ b/tools/atrf-gpio/atrf-gpio.h @@ -0,0 +1,23 @@ +/* + * atrf-gpio/atrf-gpio.h - ATBEN/ATUSB GPIO test + * + * Written 2011 by Werner Almesberger + * Copyright 2011 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 ATRF_GPIO_H +#define ATRF_GPIO_H + +#include "atrf.h" + + +void do_atben(struct atrf_dsc *dsc, const char *pattern, const char *next); +void do_atusb(struct atrf_dsc *dsc, const char *pattern, const char *next); + +#endif /* !ATRF_GPIO_H */ diff --git a/tools/atrf-gpio/atusb.c b/tools/atrf-gpio/atusb.c new file mode 100644 index 0000000..12d5f2b --- /dev/null +++ b/tools/atrf-gpio/atusb.c @@ -0,0 +1,27 @@ +/* + * atrf-gpio/atusb.c - ATUSB-specific GPIO driver + * + * Written 2011 by Werner Almesberger + * Copyright 2011 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 "atrf.h" + +#include "atrf-gpio.h" + + +/* ----- Decode and apply pattern ------------------------------------------ */ + + +void do_atusb(struct atrf_dsc *dsc, const char *pattern, const char *next) +{ + abort(); +}