mirror of
git://projects.qi-hardware.com/ben-wpan.git
synced 2024-11-29 16:03:09 +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 \
|
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
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