IEEE 802.15.4 subsystem
Sign in or create your account | Project List | Help
IEEE 802.15.4 subsystem Git Source Tree
Root/
Source at commit 49e7c83796bc04941e9dbcec69bc0751563ff4d4 created 7 years 5 days ago. By Werner Almesberger, atusb/: use ""VDD" symbol from kicad-libs | |
---|---|
1 | /* |
2 | * atrf-gpio/atusb.c - ATUSB-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 <stdlib.h> |
15 | #include <stdio.h> |
16 | |
17 | #include <usb.h> |
18 | |
19 | #include "atusb/ep0.h" |
20 | #include "atrf.h" |
21 | |
22 | #include "atrf-gpio.h" |
23 | |
24 | |
25 | #define FROM_DEV ATUSB_FROM_DEV(0) |
26 | #define TO_DEV ATUSB_TO_DEV(0) |
27 | |
28 | |
29 | static const char *name[24] = { |
30 | "PB0", "PB1/P16", "PB2/P15", "PB3/P14", |
31 | "PB4/SLP_TR", "PB5", "PB6/LED", "PB7", |
32 | "PC0", "PC1/P13", "PC2", "PC3(NC)", |
33 | "PC4", "PC5", "PC6", "PC7/nRST_RF", |
34 | "PD0/IRQ_RF", "PD1/nSS", "PD2/MISO", "PD3/MOSI", |
35 | "PD4", "PD5/SCLK", "PD6", "PD7" |
36 | }; |
37 | |
38 | |
39 | static struct atrf_dsc *orig_dsc; |
40 | static uint8_t orig_data[3], orig_dir[3]; |
41 | |
42 | |
43 | static void dump_port(int port, uint8_t data, uint8_t dir, uint8_t mask) |
44 | { |
45 | int i; |
46 | |
47 | fprintf(stderr, "name\t\tcfg\n"); |
48 | for (i = 0; i != 8; i++) { |
49 | int bit = 1 << (i & 7); |
50 | |
51 | fprintf(stderr, "%-16s%c\n", name[port*8+i], |
52 | mask & bit ? dir & bit ? data & bit ? '1' : '0' : |
53 | data & bit ? 'R' : 'Z' : 'x'); |
54 | } |
55 | } |
56 | |
57 | |
58 | static uint8_t gpio(struct atrf_dsc *dsc, |
59 | uint8_t port, uint8_t *data, uint8_t *dir, uint8_t mask) |
60 | { |
61 | uint8_t buf[3]; |
62 | int res; |
63 | |
64 | res = usb_control_msg(atrf_usb_handle(dsc), |
65 | FROM_DEV, ATUSB_GPIO, *dir << 8 | *data, mask << 8 | port, |
66 | (void *) buf, sizeof(buf), 1000); |
67 | if (res < 0) { |
68 | dump_port(port-1, *data, *dir, mask); |
69 | fprintf(stderr, "ATUSB_GPIO: %s\n", usb_strerror()); |
70 | _exit(1); |
71 | } |
72 | if (res != 3) { |
73 | fprintf(stderr, "ATUSB_GPIO: expected 3 bytes, got %d\n", res); |
74 | _exit(1); |
75 | } |
76 | *data = buf[1]; |
77 | *dir = buf[2]; |
78 | return buf[0]; |
79 | } |
80 | |
81 | |
82 | static void dump(const uint8_t *data, const uint8_t *dir, |
83 | const uint8_t *expect, const uint8_t *got, const uint8_t *read) |
84 | { |
85 | int i; |
86 | |
87 | fprintf(stderr, "name\t\tcfg exp got\n"); |
88 | for (i = 0; i != 24; i++) { |
89 | int port = i >> 3; |
90 | int bit = 1 << (i & 7); |
91 | |
92 | fprintf(stderr, "%-16s%c %c %d", name[i], |
93 | dir[port] & bit ? data[port] & bit ? '1' : '0' : |
94 | data[port] & bit ? 'R' : 'Z', |
95 | read[port] & bit ? expect[port] & bit ? '1' : '0' : '-', |
96 | !!(got[port] & bit)); |
97 | if ((expect[port] ^ got[port]) & read[port] & bit) |
98 | fprintf(stderr, "\t***"); |
99 | fputc('\n', stderr); |
100 | } |
101 | } |
102 | |
103 | |
104 | /* ----- Decode and apply pattern ------------------------------------------ */ |
105 | |
106 | |
107 | static void restore_gpios(void) |
108 | { |
109 | int i, res; |
110 | |
111 | for (i = 0; i != 3; i++) |
112 | gpio(orig_dsc, i+1, orig_data+i, orig_dir+i, 0xff); |
113 | |
114 | res = usb_control_msg(atrf_usb_handle(orig_dsc), |
115 | TO_DEV, ATUSB_GPIO_CLEANUP, 0, 0, NULL, 0, 1000); |
116 | if (res < 0) { |
117 | fprintf(stderr, "ATUSB_GPIO_CLEANUP: %s\n", usb_strerror()); |
118 | _exit(1); |
119 | } |
120 | } |
121 | |
122 | |
123 | void do_atusb(struct atrf_dsc *dsc, const char *pattern, const char *next) |
124 | { |
125 | static int first = 1; |
126 | const char *p; |
127 | int i, pin = 0; |
128 | uint8_t data[3], dir[3], mask[3], read[3], expect[3], got[3]; |
129 | uint8_t bit; |
130 | int port; |
131 | |
132 | data[0] = data[1] = data[2] = 0; |
133 | dir[0] = dir[1] = dir[2] = 0; |
134 | mask[0] = mask[1] = mask[2] = 0; |
135 | read[0] = read[1] = read[2] = 0; |
136 | expect[0] = expect[1] = expect[2] = 0; |
137 | |
138 | if (first) { |
139 | orig_dsc = dsc; |
140 | for (i = 0; i != 3; i++) |
141 | gpio(dsc, i+1, orig_data+i, orig_dir+i, 0); |
142 | atexit(restore_gpios); |
143 | first = 0; |
144 | } |
145 | |
146 | for (p = pattern; *p; p++) { |
147 | bit = 1 << (pin & 7); |
148 | port = pin >> 3; |
149 | switch (*p) { |
150 | case '1': |
151 | data[port] |= bit; |
152 | /* fall through */ |
153 | case '0': |
154 | dir[port] |= bit; |
155 | mask[port] |= bit; |
156 | break; |
157 | case 'H': |
158 | expect[port] |= bit; |
159 | /* fall through */ |
160 | case 'L': |
161 | read[port] |= bit; |
162 | /* fall through */ |
163 | case 'Z': |
164 | data[port] |= bit; |
165 | mask[port] |= bit; |
166 | break; |
167 | case 'h': |
168 | expect[port] |= bit; |
169 | /* fall through */ |
170 | case 'l': |
171 | case 'o': |
172 | read[port] |= bit; |
173 | /* fall through */ |
174 | case 'z': |
175 | mask[port] |= bit; |
176 | break; |
177 | case 'x': |
178 | pin++; |
179 | continue; |
180 | default: |
181 | continue; |
182 | } |
183 | pin++; |
184 | } |
185 | |
186 | for (i = 0; i <= port; i++) |
187 | got[i] = gpio(dsc, i+1, data+i, dir+i, mask[i]); |
188 | for (i = 0; i <= port; i++) |
189 | if ((got[i] & read[i]) != expect[i]) { |
190 | dump(data, dir, expect, got, read); |
191 | fprintf(stderr, "at \"%s\", next \"%s\"\n", pattern, |
192 | next); |
193 | exit(1); |
194 | } |
195 | } |
196 |