1
0
mirror of git://projects.qi-hardware.com/ben-wpan.git synced 2024-11-29 15:30:37 +02:00

atrf-gpio: new utility to directly access GPIOs (for now atben-only)

- tools/atrf-gpio/: new utility to directly access GPIOs
- tools/Makefile (BEN_DIRS): added atrf-gpio
This commit is contained in:
Werner Almesberger 2011-06-03 15:25:57 -03:00
parent 565fadf258
commit 4924755a15
6 changed files with 472 additions and 2 deletions

View File

@ -11,8 +11,8 @@
# #
BEN_DIRS=atrf-id atrf-path atrf-proxy atrf-reset atrf-rssi atrf-trim \ BEN_DIRS=atrf-gpio atrf-id atrf-path atrf-proxy atrf-reset \
atrf-txrx atrf-xmit atrf-xtal atrf-rssi atrf-trim atrf-txrx atrf-xmit atrf-xtal
DIRS=$(BEN_DIRS) usbwait DIRS=$(BEN_DIRS) usbwait
TARGET_ONLY_DIRS=lib TARGET_ONLY_DIRS=lib

31
tools/atrf-gpio/Makefile Normal file
View File

@ -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)

185
tools/atrf-gpio/atben.c Normal file
View File

@ -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 <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#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);
}
}

204
tools/atrf-gpio/atrf-gpio.c Normal file
View File

@ -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 <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#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;
}

View File

@ -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 */

27
tools/atrf-gpio/atusb.c Normal file
View File

@ -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 <stdlib.h>
#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();
}