forked from kathrynplant/UTMOST-SNAP
-
Notifications
You must be signed in to change notification settings - Fork 0
/
SNAP_spectrometer_config_with_pps.py
214 lines (179 loc) · 6.8 KB
/
SNAP_spectrometer_config_with_pps.py
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
from __future__ import division
import corr
import numpy as np
import struct
import time
from argparse import ArgumentParser
'''
This streamlines the SNAP configuration process.
outline:
1. Imports
2. This description
3. Variables. Ultimately these will be read from a configuration file.
4. Defines functions
5. Calls functions to configure the snap and packetizer
'''
#---------------------- DEFINE CONFIGURATION PARAMETERS --------------------
#Parse command line argument
p = ArgumentParser(description = 'python SNAP_spectrometer_config_with_pps.py configfile.txt')
p.add_argument('configfile', type = str, default = '', help = 'Give the name of the file with the configuration parameters.')
args = p.parse_args()
configfile = args.configfile
# def line parser
def lineparse(line):
for i in range(len(line)):
if line[i] == '=':
keysplit = line[:i]
valsplit = line[(i+1):]
key = keysplit.strip()
value = valsplit.strip()
return key , value
# load config file
print 'Using config file', configfile
with open(configfile) as f:
raw = f.readlines()
lines = [x.strip() for x in raw]
textlines = [x for x in lines if ((len(x) > 0) and (x[0] != '#'))]
# make dictionary of parameter keywords and their values
paramdict = {}
fails = 0
for line in textlines:
key, value = lineparse(line)
try:
paramdict[key] = eval(value)
except:
print 'Could not evaluate', key, ' ', value
print sys.exc_info()[1]
fails +=1
if fails > 0:
print 'Failed parsing config parameters. Please correct the config file.'
exit()
# Check that all the necessary parameters have been included, and no invalid parameters have been included.
valid = ['PI_IP',
'BOFFILE',
'SNAPID',
'SNAPMAC',
'SNAPIP',
'SNAPPORT',
'DESTMACS',
'DESTINATION_IP_ADDRESSES',
'DESTINATION_PORTS',
'START_CHANNEL']
invalidcount = 0
missingcount = 0
for k in valid:
if k not in paramdict.keys():
print 'Missing ', k, ' please add it to the config file.'
missingcount +=1
for k in paramdict.keys():
if k not in valid:
print 'Invalid parameter', k
invalidcount+=1
if (invalidcount + missingcount) > 0:
print 'Please make sure that you\'re using a config file which includes all of the following parameters and no other parameters:'
print valid
exit()
# Define variables
PI_IP = paramdict['PI_IP'] #string, IP of host raspberry pi
BOFFILE = paramdict['BOFFILE'] #string, name of bof
SNAPID = paramdict['SNAPID'] #8 bit integer, identifies this particular snap board
SNAPMAC = paramdict['SNAPMAC'] #48 bit integers, MAC for SNAP
SNAPIP = paramdict['SNAPIP'] # 32 bit integer, IP address of SNAP
SNAPPORT =paramdict['SNAPPORT'] #integer, port number for ethernet1 to send from
DESTMACS = paramdict['DESTMACS'] #List of 256 48 bit integers, lists all destination MAC addresses for ethernet1.
DESTINATION_IP_ADDRESSES = paramdict['DESTINATION_IP_ADDRESSES'] #list of 32-bit integers, lists destination IP addresses in order of corresponding subbands.
DESTINATION_PORTS = paramdict['DESTINATION_PORTS'] #list of integers, lists destination ports in order of corresponding subbands.
START_CHANNEL = paramdict['START_CHANNEL'] # Lowest channel number of the set of 320 channels to send out the first ethernet port.
#---------------------DEFINE CONFIGURATION FUNCTIONS ----------------------
def progfpga(name_of_bof):
#load the bof
if name_of_bof in r.listbof():
print 'Found the boffile, now programming the FPGA.'
print r.progdev(name_of_bof), 'done'
else:
print 'The raspberry pi does not have that boffile.'
exit()
time.sleep(1)
status = r.read_int('ethernet_status')
if status == 4:
print 'ready to configure ethernet and packetizer'
else:
print "There's a problem, ethernet_status register = ", r.read_int('ethernet_status')
if status <4:
print "Status msb = 0 means that the ethernet link is not up."
exit()
def configurethernet():
# configure ethernet
print 'Configuring the 10Gb ethernet'
r.config_10gbe_core('ten_Gbe_v2',SNAPMAC,SNAPIP,SNAPPORT,DESTMACS,gateway = 0)
# Does it automatically iterate through mac addresses as IP changes? How?
print 'Configuring destination IP addresses and ports'
for I in range(len(DESTINATION_IP_ADDRESSES)):
ip = DESTINATION_IP_ADDRESSES[I]
port = DESTINATION_PORTS[I]
ipregister = 'tx_dest_ip%d' %I
portregister = 'tx_dest_port%d' %I
r.write_int(ipregister,ip)
r.write_int(portregister,port)
print 'done'
def resetandsync():
#reset ethernet block and send sync pulse
print 'Sending pulse to reset ethernet and sync.'
r.write_int('force_new_sync',1)
time.sleep(0.1)
r.write_int('force_new_sync',0)
print 'Done. Ethernet status = %d', r.read_int('ethernet_status')
return
#----------------------CONFIGURE SNAP-------------------------
# Connect to SNAP
r = corr.katcp_wrapper.FpgaClient(PI_IP,7147)
time.sleep(2)
if r.is_connected():
print 'Connected to SNAP'
else:
print 'Not connected to SNAP'
exit()
# load the boffile
progfpga(BOFFILE)
# set SNAP board identifier
r.write_int('pkt_header_SNAPid',SNAPID)
# configure ethernet
configurethernet()
#set reorder map
T = 8; #number of spectra per packet
Bt = 32; #TOTAL number of subbands in spectrum
B = 10; #number of subbands TO SEND
F = 32; #number of frequency channels per subband
M = 2; #number of modules per fft output stream
reorder_length = T*Bt*F*M;
# start = 330; #lowest frequency channel number to send
start = 332 # in order to have it actually start on 330. TODO fix firmware so this offset isn't needed
print "TODO: Fix in firmware the offset which is currently compensated for here."
I = np.ones(reorder_length);
reorder_length = T*Bt*F*M;
I = np.ones(reorder_length)
m_test = np.zeros(reorder_length);
b_test = np.zeros(reorder_length);
f_test = np.zeros(reorder_length);
t_test = np.zeros(reorder_length);
p_test = np.ones(reorder_length);
j=0;
for b in range(B):
for t in range(T):
for f in range(F):
for m in range(M):
i = Bt*F*M*t + F*b +f + Bt*F*m +start;
p = m+f+b+t;
I[2*j] = i;
I[2*j +1] = 1;
j +=1;
j +=128; #defines gap between packets (gap between one set of subbands and the next)
reordermap = I.astype(int)
s = struct.Struct('>16384H')
r.write('reorder1_map1',s.pack(*reordermap))
time.sleep(0.1)
# reset ethernet and send sync pulse
resetandsync()
# Finish with a reminder to set the ADC demux
print "Now run Zara's ADC calibration. Run \n python ~/adc16/adc16_init.py %s -s -d 1 -g <adcgain>" %(PI_IP + ' ' + BOFFILE)
print "Don't forget to adjust the digital gains"