mirror of
git://projects.qi-hardware.com/ben-wpan.git
synced 2024-11-22 12:22:48 +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:
parent
565fadf258
commit
4924755a15
@ -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
|
||||
|
||||
|
31
tools/atrf-gpio/Makefile
Normal file
31
tools/atrf-gpio/Makefile
Normal 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
185
tools/atrf-gpio/atben.c
Normal 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
204
tools/atrf-gpio/atrf-gpio.c
Normal 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;
|
||||
}
|
23
tools/atrf-gpio/atrf-gpio.h
Normal file
23
tools/atrf-gpio/atrf-gpio.h
Normal 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
27
tools/atrf-gpio/atusb.c
Normal 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();
|
||||
}
|
Loading…
Reference in New Issue
Block a user