Root/tools/atrf-gpio/atben.c

1/*
2 * atrf-gpio/atben.c - ATBEN-specific GPIO driver
3 *
4 * Written 2011 by Werner Almesberger
5 * Copyright 2011 Werner Almesberger
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13
14#include <stdint.h>
15#include <stdlib.h>
16#include <stdio.h>
17#include <unistd.h>
18
19#include "at86rf230.h"
20#include "atrf.h"
21
22#include "atrf-gpio.h"
23
24
25static struct pin {
26    const char *name;
27    int bit;
28} pins[] = {
29    { "SCLK", 11 },
30    { "MISO", 10 },
31    { "SLP_TR", 9 },
32    { "MOSI", 8 },
33    { "nSEL", 13 },
34    { "IRQ", 12 },
35    { NULL, 0 }
36};
37
38static uint32_t orig_dat, orig_pe, orig_dir;
39static uint32_t changed = 0;
40
41
42/* ----- Ben hardware ------------------------------------------------------ */
43
44
45static volatile uint32_t *pdpin, *pddat, *pddats, *pddatc;
46static volatile uint32_t *pdpe, *pdpes, *pdpec;
47static volatile uint32_t *pddir, *pddirs, *pddirc;
48
49
50static void ben_setup(struct atrf_dsc *dsc)
51{
52    volatile void *base = atrf_ben_regs(dsc);
53
54    pdpin = base+0x10300;
55    pddat = base+0x10310;
56    pddats = base+0x10314;
57    pddatc = base+0x10318;
58
59    pdpe = base+0x10330;
60    pdpes = base+0x10334;
61    pdpec = base+0x10338;
62
63    pddir = base+0x10360;
64    pddirs = base+0x10364;
65    pddirc = base+0x10368;
66}
67
68
69/* ----- Diagnostic dump --------------------------------------------------- */
70
71
72static char decode_cfg(uint32_t bit)
73{
74    if (*pddir & bit)
75        return *pddat & bit ? '1' : '0';
76    return *pdpe & bit ? 'Z' : 'R';
77}
78
79
80static void dump_pd(uint32_t expect, uint32_t got, uint32_t mask)
81{
82    const struct pin *pin;
83
84    fprintf(stderr, "name\tcfg exp got\n");
85    for (pin = pins; pin->name; pin++) {
86        uint32_t bit = 1 << pin->bit;
87
88        fprintf(stderr, "%s\t%c %c %d",
89            pin->name, decode_cfg(bit),
90            mask & bit ? expect & bit ? '1' : '0' : '-',
91            !!(got & bit));
92        if ((expect ^ got) & mask & bit)
93            fprintf(stderr, "\t***");
94        fputc('\n', stderr);
95    }
96}
97
98
99static void restore_gpios(void)
100{
101    *pddats = orig_dat & changed;
102    *pddatc = ~orig_dat & changed;
103    *pdpes = orig_pe & changed;
104    *pdpec = ~orig_pe & changed;
105    *pddirs = orig_dir & changed;
106    *pddirc = ~orig_dir & changed;
107}
108
109
110/* ----- Decode and apply pattern ------------------------------------------ */
111
112
113void do_atben(struct atrf_dsc *dsc, const char *pattern, const char *next)
114{
115    static int first = 1;
116    uint32_t read = 0, expect = 0;
117    const struct pin *pin = pins;
118    uint32_t got;
119    const char *p;
120
121    if (first) {
122        ben_setup(dsc);
123        orig_dat = *pddat;
124        orig_pe = *pdpe;
125        orig_dir = *pddir;
126        atexit(restore_gpios);
127
128        first = 0;
129    }
130
131    for (p = pattern; *p; p++) {
132        uint32_t bit;
133
134        if (!pin->name) {
135            fprintf(stderr, "too many pins in \"%s\"\n", pattern);
136            exit(1);
137        }
138        bit = 1 << pin->bit;
139        switch (*p) {
140        case '0':
141            *pddatc = bit;
142            *pddirs = bit;
143            break;
144        case '1':
145            *pddats = bit;
146            *pddirs = bit;
147            break;
148        case 'H':
149            expect |= bit;
150            /* fall through */
151        case 'L':
152            read |= bit;
153            /* fall through */
154        case 'Z':
155            *pdpec = bit;
156            *pddirc = bit;
157            break;
158        case 'h':
159            expect |= bit;
160            /* fall through */
161        case 'l':
162        case 'o':
163            read |= bit;
164            /* fall through */
165        case 'z':
166            *pddirc = bit;
167            *pdpes = bit;
168            break;
169        case 'x':
170            pin++;
171            continue;
172        default:
173            continue;
174        }
175        changed |= bit;
176        pin++;
177    }
178
179    usleep(1000);
180
181    got = *pdpin;
182    if ((got & read) != expect) {
183        dump_pd(expect, got, read);
184        fprintf(stderr, "at \"%s\", next \"%s\"\n", pattern, next);
185        exit(1);
186    }
187}
188

Archive Download this file



interactive