-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpinutil.h
70 lines (63 loc) · 1.82 KB
/
pinutil.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#ifndef PINUTIL_H_
#define PINUTIL_H_
/* FixMe: use sysctl to get page size or something, but the current
* code doesn't care about the size so it doesn't really matter so we
* go w/ 4k because that sort of works.
*/
#define REG_MAP_SIZE 0x1000
#if 1
#define LOAD(__p, __t) \
__atomic_load_n(__p, __t)
#define STORE(__p, __v, __t) \
__atomic_store_n(__p, __v, __t)
#else
#define LOAD(__p, __t) \
*(__p)
#define STORE(__p, __v, __t) \
*(__p) = __v
#endif
#define PIN_DIR(__r, __p, __d) do { \
assert((__p) < 54); \
unsigned i = ((__p) / 10); \
unsigned s = 3 * ((__p) % 10); \
uint32_t v = LOAD((__r) + i, __ATOMIC_ACQUIRE); \
v &= ~(3 << s); \
v |= ((__d) << s) & (1 << s); \
STORE((__r) + i, v, __ATOMIC_RELEASE); \
} while (0)
#define PIN_WRITE(__r, __p, __v) do { \
assert((__p) < 54); \
unsigned b = ((__v) ? 0x1c : 0x28) / 4; \
unsigned i = b + ((__p) / 32); \
unsigned s = (__p) % 32; \
STORE((__r) + i, (1 << s), __ATOMIC_RELEASE); \
} while(0)
#define PIN_READ(__r, __p) ({ \
unsigned i = (0x34 / 4) + ((__p) / 32); \
unsigned s= (__p) % 32; \
!!(LOAD((__r) + i, __ATOMIC_ACQUIRE) & (1 << s)); \
})
/* 1 - write GPPUD (94h)
* 2 - hold 150 cycles
* 3 - GPPUDCLKxx (98h / 9Ch)
* 4 - hold 150 cycles
* 5 - clear GPPUD
* 6 - clear GPPUDCLKxx
*
* FixMe: not sure if the manual's reference to cycle ere is the
* host's clocking or the target's clock rate.
*/
#define PIN_CONFIG_HIZ(__r, __p, __s) do { \
uint32_t v = ((__s) < 0 ? 0x01 : /* down */ \
(__s) > 0 ? 0x02 : /* up */ \
0x00); /* disable */ \
int o = (__p) / 32; \
int s = (__p) % 32; \
STORE((__r) + (0x94 / 4), v, __ATOMIC_RELEASE); \
usleep(10000); \
STORE((__r) + (0x98 / 4) + o, 1 << s, __ATOMIC_RELEASE); \
usleep(10000); \
STORE((__r) + (0x98 / 4) + o, 0, __ATOMIC_RELEASE); \
usleep(10000); \
} while(0)
#endif /* PINUTIL_H_ */