Repository navigation
Expand file tree
/
Copy pathcli
More file actions
executable file
·144 lines (104 loc) · 3.24 KB
/
Copy pathcli
File metadata and controls
executable file
·144 lines (104 loc) · 3.24 KB
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#!/usr/bin/env python3
import time
import sys
import csv
import pathlib
import os
import spidev
import RPi.GPIO as GPIO
def bytes_to_hex(data):
return ''.join(["%02X " % x for x in data]).strip()
sleep_us = lambda us: time.sleep(us/1000000.0)
CS_PIN = 25
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(CS_PIN, GPIO.OUT)
GPIO.output(CS_PIN, GPIO.HIGH)
class CSR:
def __init__(self, csv_file):
self.items = list(csv.reader(filter(lambda row: row[0] != "#", open(csv_file))))
self.addresses = {}
for item in self.items:
group, name, addr, length, mode = item
if group == 'csr_register':
self.addresses[name] = int(addr, 16)
class Bridge:
def __init__(self):
spi = spidev.SpiDev()
spi.open(0,0)
spi.max_speed_hz = 200
spi.mode = 0
spi.no_cs = True
self.spi = spi
def start(self):
GPIO.output(CS_PIN, GPIO.LOW)
def stop(self):
GPIO.output(CS_PIN, GPIO.HIGH)
def send(self, data, debug=False):
recv = self.spi.xfer3(data)
if debug:
print("{} -> {}".format(data, recv))
return recv
def poke(self, addr, value):
# Map from CSR.csv addresses to actualy internal addresses
addr = int(addr/4)
self.start()
sleep_us(10)
self.send([0x02])
self.send([
(addr >> 0) & 0xFF,
(addr >> 8) & 0xFF,
(value >> 0) & 0xFF,
(value >> 8) & 0xFF,
(value >> 16) & 0xFF,
(value >> 32) & 0xFF,
])
sleep_us(10)
self.stop()
sleep_us(10)
def peek(self, addr):
# Map from CSR.csv addresses to actualy internal addresses
addr = int(addr/4)
self.start()
sleep_us(10)
self.send([0x03])
for shift in [0, 8]:
self.send([(addr >> shift) & 0xFF])
recv = self.send([
(addr >> 0) & 0xFF,
(addr >> 8) & 0xFF,
0x00, 0xCC, 0xCC, 0xCC, 0xCC
])[1:-2]
sleep_us(10)
self.stop()
sleep_us(10)
return recv[::-1]
argstr = " ".join(sys.argv)
if "-h" in argstr or "--help" in argstr or len(sys.argv) == 1:
print("Usage: {} ADDR [DATA]".format(sys.argv[0]))
print("ADDR and DATA can be hex formatted (e.g. 0x0804).")
print("DATA can also be binary formatted (e.g. 0b00000000) or decimal")
print("ADDR can also be a string which matches the register name in csr.csv")
print("ADDR only will read that location and print it")
print("ADDR + DATA will write DATA to ADDR")
sys.exit(0)
addr = sys.argv[1].lower()
if addr[0] == 'x' or addr[0:2] == '0x':
addr = int(sys.argv[1], 16)
else:
csrfile = os.path.join(pathlib.Path(__file__).parent.absolute(), "generated", "csr.csv")
csr = CSR(csrfile)
addr = csr.addresses[addr]
bridge = Bridge()
if len(sys.argv) == 2:
print(bytes_to_hex(bridge.peek(addr)))
elif len(sys.argv) == 3:
data = sys.argv[2].lower()
if data[0:2] == '0x':
data = int(data, 16)
elif data[0:2] == '0b':
data = int(data, 2)
else:
data = int(data)
bridge.poke(addr, data)
print(bytes_to_hex(bridge.peek(addr)))