|
1 | NO CONTENT: new file 100644 |
|
1 | NO CONTENT: new file 100644 |
@@ -0,0 +1,153 | |||
|
1 | ''' | |
|
2 | Created on Dec 2, 2014 | |
|
3 | ||
|
4 | @author: Miguel Urco | |
|
5 | ||
|
6 | eth_device decorator is used to implement an api to ethernet devices. | |
|
7 | When eth_device decorator is used it adds two parameters to any function (ip and port) | |
|
8 | ||
|
9 | #Definition | |
|
10 | ||
|
11 | @eth_device | |
|
12 | def enable_rf() | |
|
13 | cmd = "xxxxx" | |
|
14 | payload = "xxxxxx" | |
|
15 | ||
|
16 | return cmd, payload | |
|
17 | ||
|
18 | #How to call this function: | |
|
19 | answer = enable_rf(ip, port) | |
|
20 | ||
|
21 | ''' | |
|
22 | import data | |
|
23 | ||
|
24 | from devices.jro_device import eth_device, IdClass | |
|
25 | ||
|
26 | ID_CLASS = IdClass["dds"] | |
|
27 | ||
|
28 | CMD_RESET =0X01 | |
|
29 | CMD_ENABLE =0X02 | |
|
30 | CMD_CHANGEIP =0X03 | |
|
31 | CMD_STATUS =0X04 | |
|
32 | CMD_ECHO =0XFE | |
|
33 | ||
|
34 | DDS_CMD_RESET =0X10 | |
|
35 | DDS_CMD_ENABLE_RF =0x11 | |
|
36 | # DDS_CMD_MULTIPLIER =0X12 | |
|
37 | # DDS_CMD_MODE =0x13 | |
|
38 | # DDS_CMD_FREQUENCY_A =0X14 | |
|
39 | # DDS_CMD_FREQUENCY_B =0x15 | |
|
40 | # DDS_CMD_PHASE_A =0X16 | |
|
41 | # DDS_CMD_PHASE_B =0x17 | |
|
42 | # DDS_CMD_AMPLITUDE_1 =0X19 #Se han invertido la posicion de los canales | |
|
43 | # DDS_CMD_AMPLITUDE_2 =0x18 #en el PCB | |
|
44 | ||
|
45 | DDS_CMD_WRITE =0x50 | |
|
46 | DDS_CMD_READ =0x8000 | |
|
47 | ||
|
48 | @eth_device(ID_CLASS) | |
|
49 | def reset(): | |
|
50 | ||
|
51 | cmd = CMD_RESET | |
|
52 | payload = "" | |
|
53 | ||
|
54 | return cmd, payload | |
|
55 | ||
|
56 | @eth_device(ID_CLASS) | |
|
57 | def change_ip(ip, mask="255.255.255.0", gateway="0.0.0.0"): | |
|
58 | ||
|
59 | cmd = CMD_CHANGEIP | |
|
60 | payload = ip + '/' + mask + '/' + gateway | |
|
61 | ||
|
62 | return cmd, payload | |
|
63 | ||
|
64 | @eth_device(ID_CLASS) | |
|
65 | def status(): | |
|
66 | ||
|
67 | cmd = CMD_STATUS | |
|
68 | payload = "" | |
|
69 | ||
|
70 | return cmd, payload | |
|
71 | ||
|
72 | @eth_device(ID_CLASS) | |
|
73 | def echo(): | |
|
74 | ||
|
75 | cmd = CMD_ECHO | |
|
76 | payload = "" | |
|
77 | ||
|
78 | return cmd, payload | |
|
79 | ||
|
80 | @eth_device(ID_CLASS) | |
|
81 | def enable_rf(): | |
|
82 | ||
|
83 | cmd = DDS_CMD_ENABLE_RF | |
|
84 | payload = chr(0x01) | |
|
85 | ||
|
86 | return cmd, payload | |
|
87 | ||
|
88 | @eth_device(ID_CLASS) | |
|
89 | def disable_rf(): | |
|
90 | ||
|
91 | cmd = DDS_CMD_ENABLE_RF | |
|
92 | payload = chr(0x00) | |
|
93 | ||
|
94 | return cmd, payload | |
|
95 | ||
|
96 | @eth_device(ID_CLASS) | |
|
97 | def read_all_device(): | |
|
98 | ||
|
99 | payload = "" | |
|
100 | ||
|
101 | return DDS_CMD_READ, payload | |
|
102 | ||
|
103 | @eth_device(ID_CLASS) | |
|
104 | def write_all_device(payload): | |
|
105 | ||
|
106 | return DDS_CMD_WRITE, payload | |
|
107 | ||
|
108 | def read_config(ip, port): | |
|
109 | """ | |
|
110 | Output: | |
|
111 | parms : Dictionary with keys | |
|
112 | multiplier : | |
|
113 | frequencyA : | |
|
114 | frequencyB : | |
|
115 | frequencyA_Mhz : | |
|
116 | frequencyB_Mhz : | |
|
117 | modulation : | |
|
118 | phaseA_degrees : | |
|
119 | phaseB_degrees : | |
|
120 | amplitudeI : | |
|
121 | amplitudeQ : | |
|
122 | ||
|
123 | """ | |
|
124 | payload = read_all_device(ip, port) | |
|
125 | ||
|
126 | return data.dds_str_to_dict(payload) | |
|
127 | ||
|
128 | def write_config(ip, port, parms): | |
|
129 | """ | |
|
130 | Input: | |
|
131 | ip : | |
|
132 | port : | |
|
133 | parms : Dictionary with keys | |
|
134 | multiplier : 4 to 20 | |
|
135 | frequencyA : 0 to (2**48-1) equivalent to: 0 - "Master clock" | |
|
136 | frequencyB : 0 to (2**48-1) equivalent to: 0 - "Master clock" | |
|
137 | modulation : 0 to 3 | |
|
138 | phaseA_degrees : 0 - 360 degrees | |
|
139 | phaseB_degrees : 0 - 360 degrees | |
|
140 | amplitudeI : 0 to (2**12-1) equivalent to: 0 - 100% | |
|
141 | amplitudeQ : 0 to (2**12-1) equivalent to: 0 - 100% | |
|
142 | ||
|
143 | """ | |
|
144 | ||
|
145 | payload = data.dict_to_dds_str(parms) | |
|
146 | ||
|
147 | answer = write_all_device(ip, port, payload) | |
|
148 | ||
|
149 | return answer | |
|
150 | ||
|
151 | if __name__ == '__main__': | |
|
152 | # print enable_rf("127.0.0.1", 2000) | |
|
153 | print read_config("127.0.0.1", 2000) No newline at end of file |
@@ -0,0 +1,171 | |||
|
1 | ''' | |
|
2 | Created on Feb 15, 2016 | |
|
3 | ||
|
4 | @author: Miguel Urco | |
|
5 | ''' | |
|
6 | import struct | |
|
7 | ||
|
8 | DDS_NBITS = 48 | |
|
9 | ||
|
10 | def freq_to_binary(freq, mclock): | |
|
11 | ||
|
12 | binary = (float(freq)/mclock)*(2**DDS_NBITS) | |
|
13 | ||
|
14 | return binary | |
|
15 | ||
|
16 | def binary_to_freq(binary, mclock): | |
|
17 | ||
|
18 | freq = (float(binary)/(2**DDS_NBITS))*mclock | |
|
19 | ||
|
20 | return freq | |
|
21 | ||
|
22 | def phase_to_binary(phase): | |
|
23 | ||
|
24 | binary = float(phase)*8192/180.0 | |
|
25 | ||
|
26 | return binary | |
|
27 | ||
|
28 | def binary_to_phase(binary): | |
|
29 | ||
|
30 | phase = float(binary)*180.0/8192 | |
|
31 | ||
|
32 | return phase | |
|
33 | ||
|
34 | def dds_str_to_dict(registers): | |
|
35 | ||
|
36 | """ | |
|
37 | Output: | |
|
38 | parms : Dictionary with keys | |
|
39 | multiplier : | |
|
40 | frequencyA : | |
|
41 | frequencyB : | |
|
42 | frequencyA_Mhz : | |
|
43 | frequencyB_Mhz : | |
|
44 | modulation : | |
|
45 | phaseA_degrees : | |
|
46 | phaseB_degrees : | |
|
47 | amplitudeI : | |
|
48 | amplitudeQ : | |
|
49 | ||
|
50 | """ | |
|
51 | ||
|
52 | if not registers: | |
|
53 | return {} | |
|
54 | ||
|
55 | if len(registers) != 0x28: | |
|
56 | return {} | |
|
57 | ||
|
58 | phaseA = struct.unpack('>H', registers[0x0:0x2])[0] | |
|
59 | phaseB = struct.unpack('>H', registers[0x2:0x4])[0] | |
|
60 | ||
|
61 | frequencyA = struct.unpack('>Q', '\x00\x00' + registers[0x04:0x0A])[0] | |
|
62 | frequencyB = struct.unpack('>Q', '\x00\x00' + registers[0x0A:0x10])[0] | |
|
63 | ||
|
64 | delta_frequency = struct.unpack('>Q', '\x00\x00' + registers[0x10:0x16])[0] | |
|
65 | ||
|
66 | update_clock = struct.unpack('>I', registers[0x16:0x1A])[0] | |
|
67 | ||
|
68 | ramp_rate_clock = struct.unpack('>I', '\x00' + registers[0x1A:0x1D])[0] | |
|
69 | ||
|
70 | control_register = struct.unpack('>I', registers[0x1D:0x21])[0] | |
|
71 | ||
|
72 | amplitudeI = struct.unpack('>H', registers[0x21:0x23])[0] | |
|
73 | amplitudeQ = struct.unpack('>H', registers[0x23:0x25])[0] | |
|
74 | ||
|
75 | amp_ramp_rate = ord(registers[0x25]) | |
|
76 | ||
|
77 | qdac = struct.unpack('>H', registers[0x26:0x28])[0] | |
|
78 | ||
|
79 | multiplier = (control_register & 0x001F0000) >> 16 | |
|
80 | modulation = (control_register & 0x00000E00) >> 9 | |
|
81 | amplitude_enabled = (control_register & 0x00000020) >> 5 | |
|
82 | ||
|
83 | parms = {'clock' : None, | |
|
84 | 'multiplier' : multiplier, | |
|
85 | 'frequencyA' : frequencyA, | |
|
86 | 'frequencyB' : frequencyB, | |
|
87 | 'frequencyA_Mhz' : None, | |
|
88 | 'frequencyB_Mhz' : None, | |
|
89 | 'phaseA' : phaseA, | |
|
90 | 'phaseB' : phaseB, | |
|
91 | 'phaseA_degrees' : binary_to_phase(phaseA), | |
|
92 | 'phaseB_degrees' : binary_to_phase(phaseB), | |
|
93 | 'modulation' : modulation, | |
|
94 | 'amplitudeI' : amplitudeI, | |
|
95 | 'amplitudeQ' : amplitudeQ, | |
|
96 | 'amplitude_enabled' : amplitude_enabled, | |
|
97 | 'delta_frequency' : delta_frequency, | |
|
98 | 'update_clock' : update_clock, | |
|
99 | 'ramp_rate_clock' : ramp_rate_clock, | |
|
100 | 'amp_ramp_rate' : amp_ramp_rate, | |
|
101 | 'qdac' : qdac | |
|
102 | } | |
|
103 | ||
|
104 | return parms | |
|
105 | ||
|
106 | def dict_to_dds_str(parms): | |
|
107 | """ | |
|
108 | Input: | |
|
109 | parms : Dictionary with keys | |
|
110 | multiplier : 4 to 20 | |
|
111 | frequencyA : 0 to (2**48-1) equivalent to: 0 - "Master clock" | |
|
112 | frequencyB : 0 to (2**48-1) equivalent to: 0 - "Master clock" | |
|
113 | modulation : 0 to 3 | |
|
114 | phaseA_degrees : 0 - 360 degrees | |
|
115 | phaseB_degrees : 0 - 360 degrees | |
|
116 | amplitudeI : 0 to (2**12-1) equivalent to: 0 - 100% | |
|
117 | amplitudeQ : 0 to (2**12-1) equivalent to: 0 - 100% | |
|
118 | """ | |
|
119 | ||
|
120 | my_dict = {'clock' : None, | |
|
121 | 'multiplier' : 1, | |
|
122 | 'frequencyA' : 0, | |
|
123 | 'frequencyB' : 0, | |
|
124 | 'frequencyA_Mhz' : 0, | |
|
125 | 'frequencyB_Mhz' : 0, | |
|
126 | 'phaseA_degress' : 0, | |
|
127 | 'phaseB_degress' : 0, | |
|
128 | 'modulation' : 0, | |
|
129 | 'amplitudeI' : 0, | |
|
130 | 'amplitudeQ' : 0, | |
|
131 | 'amplitude_enabled' : 0, | |
|
132 | 'delta_frequency' : 0, | |
|
133 | 'update_clock' : 0, | |
|
134 | 'ramp_rate_clock' : 0, | |
|
135 | 'amplitude_ramp_rate' : 0, | |
|
136 | 'qdac' : 0 | |
|
137 | } | |
|
138 | ||
|
139 | print "PArms", parms | |
|
140 | ||
|
141 | my_dict.update(parms) | |
|
142 | my_dict['phaseA'] = phase_to_binary(my_dict['phaseA_degrees']) | |
|
143 | my_dict['phaseB'] = phase_to_binary(my_dict['phaseB_degrees']) | |
|
144 | ||
|
145 | registers = "" | |
|
146 | ||
|
147 | control_register = (my_dict['multiplier'] << 16) + (my_dict['modulation'] << 9) + (my_dict['amplitude_enabled'] << 5) | |
|
148 | ||
|
149 | registers += struct.pack(">H", my_dict['phaseA']) | |
|
150 | registers += struct.pack(">H", my_dict['phaseB']) | |
|
151 | ||
|
152 | registers += struct.pack(">Q", my_dict['frequencyA'])[2:] | |
|
153 | registers += struct.pack(">Q", my_dict['frequencyB'])[2:] | |
|
154 | ||
|
155 | registers += struct.pack(">Q", my_dict['delta_frequency'])[2:] | |
|
156 | ||
|
157 | registers += struct.pack(">I", my_dict['update_clock']) | |
|
158 | ||
|
159 | registers += struct.pack(">I", my_dict['ramp_rate_clock'])[1:] | |
|
160 | ||
|
161 | registers += struct.pack(">I", control_register) | |
|
162 | ||
|
163 | registers += struct.pack(">H", my_dict['amplitudeI']) | |
|
164 | ||
|
165 | registers += struct.pack(">H", my_dict['amplitudeQ']) | |
|
166 | ||
|
167 | registers += chr(my_dict['amplitude_ramp_rate']) | |
|
168 | ||
|
169 | registers += struct.pack(">H", my_dict['qdac']) | |
|
170 | ||
|
171 | return registers No newline at end of file |
@@ -0,0 +1,396 | |||
|
1 | ''' | |
|
2 | Created on Dec 2, 2014 | |
|
3 | ||
|
4 | @author: Miguel Urco | |
|
5 | ''' | |
|
6 | import time | |
|
7 | import struct | |
|
8 | import socket | |
|
9 | ||
|
10 | DEBUG = False | |
|
11 | CMD_RESET =0X01 | |
|
12 | CMD_ENABLE =0X02 | |
|
13 | CMD_CHANGEIP =0X03 | |
|
14 | ||
|
15 | IdClass={ | |
|
16 | "rc" : 0x01, | |
|
17 | "dds" : 0x02, | |
|
18 | "jars" : 0x03, | |
|
19 | "usrp" : 0x04, | |
|
20 | "echotek" : 0x05, | |
|
21 | "abs" : 0x06, | |
|
22 | "clk_gen" : 0x07 | |
|
23 | } | |
|
24 | ||
|
25 | def ascii2hex(cadena): | |
|
26 | ||
|
27 | hex_cad = '' | |
|
28 | for c in cadena: | |
|
29 | hex_cad += hex(ord(c))[2:].rjust(2,'0') + ' ' | |
|
30 | ||
|
31 | return hex_cad | |
|
32 | ||
|
33 | def ping(host): | |
|
34 | """ | |
|
35 | Returns True if host responds to a ping request | |
|
36 | """ | |
|
37 | import os, platform | |
|
38 | ||
|
39 | # Ping parameters as function of OS | |
|
40 | ping_str = "-n 1" if platform.system().lower()=="windows" else "-c 1" | |
|
41 | ||
|
42 | # Ping | |
|
43 | return os.system("ping " + ping_str + " " + host) == 0 | |
|
44 | ||
|
45 | class IPData(object): | |
|
46 | ||
|
47 | ''' | |
|
48 | Clase para manejar la trama de datos provenientes del/hacia un dispositivo Ethernet. | |
|
49 | La trama de datos es la siguiente: | |
|
50 | ||
|
51 | ********************************** | |
|
52 | ** FORMATO GENERAL DE UNA TRAMA ** | |
|
53 | ********************************** | |
|
54 | ||
|
55 | 1. Cabecera (5 bytes): Secuencia Fija que deber ser "$JRO$" | |
|
56 | 2. Longitud (3 bytes): Cantidad de bytes de la Data, contados desde IdClass hasta el Xor | |
|
57 | 3. Id class (1 byte) : Clase de dispositivo a configurar. Por defecto 0 | |
|
58 | 4. Id device (1 byte): Identificar del dispositivo a configurar. Por defecto 0 | |
|
59 | 5. Cmd (2 bytes): Identificador del comando a ejecutarse. | |
|
60 | 3. Payload (n bytes): Carga Util conteniendo secuencia,comandos y parametros | |
|
61 | 4. Xor (1 byte): Byte de revision de consistencia de la data al aplicar Xor a todos los bytes, | |
|
62 | desde la longitud hasta el payload. | |
|
63 | ||
|
64 | ''' | |
|
65 | __HEADER = "$JRO$" | |
|
66 | ||
|
67 | def __init__(self, ip, port, id_class=0, id_dev=0): | |
|
68 | ''' | |
|
69 | ''' | |
|
70 | self.id_class = id_class | |
|
71 | self.id_dev = id_dev | |
|
72 | ||
|
73 | self.address = (str(ip), int(port)) | |
|
74 | ||
|
75 | self.__iniVariables() | |
|
76 | ||
|
77 | def __iniVariables(self): | |
|
78 | ||
|
79 | self.tx_buffer = None | |
|
80 | self.rx_buffer = None | |
|
81 | ||
|
82 | #self.header = None | |
|
83 | self.len = None | |
|
84 | self.cmd = None | |
|
85 | self.payload = None | |
|
86 | ||
|
87 | self.invalid = True | |
|
88 | self.errormsg = '' | |
|
89 | self.hasPayload = False | |
|
90 | ||
|
91 | def __getXor(self, cadena): | |
|
92 | ''' | |
|
93 | ''' | |
|
94 | #trama = '%03d' %lenght + ipPayload | |
|
95 | xor = 0 | |
|
96 | for character in cadena: | |
|
97 | xor = xor ^ ord(character) | |
|
98 | ||
|
99 | # xor_hex = hex(xor) | |
|
100 | # xor_hex = xor_hex[2:] | |
|
101 | # xor_hex = xor_hex.rjust(2,'0') | |
|
102 | ||
|
103 | return xor | |
|
104 | ||
|
105 | def __verifyXor(self, cadena): | |
|
106 | ||
|
107 | xor = self.__getXor(cadena) | |
|
108 | ||
|
109 | if xor != 0: | |
|
110 | return 0 | |
|
111 | ||
|
112 | return 1 | |
|
113 | ||
|
114 | def __encoder(self, cmd, payload): | |
|
115 | ''' | |
|
116 | Inputs: | |
|
117 | cmd : Entero que indica el tipo de comando | |
|
118 | payload : Cadena de caracteres con informacion, depende del comando | |
|
119 | ||
|
120 | ''' | |
|
121 | ||
|
122 | #seq = '%04d' %(sequence) | |
|
123 | #conf = '%04d' %(confcode) | |
|
124 | ||
|
125 | #Number to Cad: 2 Bytes <> H, 4 Bytes <> I | |
|
126 | cmd_cad = struct.pack(">H", cmd) | |
|
127 | ||
|
128 | data = chr(self.id_class) + chr(self.id_dev) + cmd_cad + payload | |
|
129 | ||
|
130 | len_data = len(data) + 1 # + xor | |
|
131 | len_cad = struct.pack('>I', len_data) | |
|
132 | ||
|
133 | lenAndData = len_cad + chr(self.id_class) + chr(self.id_dev) + cmd_cad + payload | |
|
134 | ||
|
135 | xor = self.__getXor(lenAndData) | |
|
136 | ||
|
137 | trama = self.__HEADER + lenAndData + chr(xor) | |
|
138 | ||
|
139 | self.tx_buffer = trama | |
|
140 | ||
|
141 | return trama | |
|
142 | ||
|
143 | def __decoder(self, rx_buffer): | |
|
144 | ''' | |
|
145 | Evalua la trama y la separa en los campos correspondientes | |
|
146 | ||
|
147 | 4Bytes | 4Bytes | 1Byte | 1 Byte | 2 Bytes | n Bytes | 1 Byte | |
|
148 | Header | Len | Id class | Id dev | Cmd | Payload | Xor | |
|
149 | ||
|
150 | ''' | |
|
151 | self.invalid = True | |
|
152 | self.hasPayload = False | |
|
153 | self.rx_buffer = rx_buffer | |
|
154 | ||
|
155 | try: | |
|
156 | index = rx_buffer.find(self.__HEADER) | |
|
157 | except: | |
|
158 | self.errormsg = "rx_buffer is not a string" | |
|
159 | return 0 | |
|
160 | ||
|
161 | if index == -1: | |
|
162 | self.errormsg = "No header found: %s" %ascii2hex(rx_buffer) | |
|
163 | return 0 | |
|
164 | ||
|
165 | rx_buffer = rx_buffer[index + len(self.__HEADER):] | |
|
166 | ||
|
167 | len_cad = rx_buffer[0:4] | |
|
168 | ||
|
169 | len_data = struct.unpack('>I',len_cad)[0] | |
|
170 | ||
|
171 | lenAndDataAndXor = rx_buffer[0:len_data + 4] #Incluye los 4 bytes de la longitud | |
|
172 | ||
|
173 | dataAndXor = lenAndDataAndXor[4:] | |
|
174 | ||
|
175 | if len(dataAndXor) < len_data: | |
|
176 | self.errormsg = "Data length is lower than %s" %(len_data) | |
|
177 | return 0 | |
|
178 | ||
|
179 | # print self.header, ", ", ascii2hex(lenCad), ", ", ascii2hex(ipDataAndXor), ", ", hex(self.xor) | |
|
180 | ||
|
181 | if not self.__verifyXor(lenAndDataAndXor): | |
|
182 | self.errormsg = "Invalid xor: %s" %lenAndDataAndXor[-1] | |
|
183 | return 0 | |
|
184 | ||
|
185 | self.invalid = False | |
|
186 | ||
|
187 | len_payload = len_data - 5 #Decrementar 1B (id_class), 1B (id_dev), 2B (cmd) y 1B (xor) | |
|
188 | ||
|
189 | id_class = ord(dataAndXor[0]) | |
|
190 | id_dev = ord(dataAndXor[1]) | |
|
191 | cmd_cad = dataAndXor[2:4] | |
|
192 | payload = dataAndXor[4:4+len_payload] | |
|
193 | ||
|
194 | cmd = struct.unpack('>H',cmd_cad)[0] | |
|
195 | ||
|
196 | self.id_class = id_class | |
|
197 | self.id_dev = id_dev | |
|
198 | self.cmd = cmd | |
|
199 | ||
|
200 | if len(payload) < 1: | |
|
201 | self.errormsg = "IP data is valid but it hasn't payload" | |
|
202 | return 1 | |
|
203 | ||
|
204 | self.hasPayload = True | |
|
205 | self.payload = payload | |
|
206 | ||
|
207 | self.errormsg = "Successful" | |
|
208 | ||
|
209 | return 1 | |
|
210 | ||
|
211 | def __decoder_api(self, rx_buffer, debug = DEBUG): | |
|
212 | """ | |
|
213 | Input: | |
|
214 | rx_buffer : Trama recibida como respuesta a un comando enviada a un dispositivo. | |
|
215 | ||
|
216 | Return: | |
|
217 | 0 : Trama recibida incorrecta. La cadena "rx_buffer" no ha sido decodificada correctamente. | |
|
218 | -1 : Dispositivo no inicializado. El dispositivo, dds o rc, no ha sido inicializado | |
|
219 | correctamente. | |
|
220 | -2 : Trama enviada no reconocida. La cadena recibida es correcta y el dispositivo ha sido | |
|
221 | inicializaado correctamente pero la trama enviada no ha sido reconocida por el | |
|
222 | dispositivo o el comando enviado no ha sido implementado. | |
|
223 | >0 : Trama enviada y recibida correctamente | |
|
224 | """ | |
|
225 | ||
|
226 | if not self.__decoder(rx_buffer): | |
|
227 | return "0:Error decoding eth data: " + ascii2hex(self.rx_buffer) | |
|
228 | ||
|
229 | # if self.getPayload() == "OK": | |
|
230 | # return 1 | |
|
231 | # | |
|
232 | # if self.getPayload() == "NI": | |
|
233 | # return -1 | |
|
234 | # | |
|
235 | # if self.getPayload() == "KO": | |
|
236 | # return -2 | |
|
237 | ||
|
238 | if debug: | |
|
239 | print ascii2hex(self.rx_buffer) | |
|
240 | ||
|
241 | return self.payload | |
|
242 | ||
|
243 | def getRxBufferHex(self): | |
|
244 | ||
|
245 | if self.rx_buffer == None: | |
|
246 | return '' | |
|
247 | ||
|
248 | cad = ascii2hex(self.rx_buffer) | |
|
249 | ||
|
250 | return cad | |
|
251 | ||
|
252 | def getTxBufferHex(self): | |
|
253 | ||
|
254 | if self.tx_buffer == None: | |
|
255 | return '' | |
|
256 | ||
|
257 | cad = ascii2hex(self.tx_buffer) | |
|
258 | ||
|
259 | return cad | |
|
260 | ||
|
261 | def isInvalid(self): | |
|
262 | ||
|
263 | return self.invalid | |
|
264 | ||
|
265 | def getCmd(self): | |
|
266 | return self.cmd | |
|
267 | ||
|
268 | def getPayload(self): | |
|
269 | return self.payload | |
|
270 | ||
|
271 | def getErrorMessage(self): | |
|
272 | ||
|
273 | return self.errormsg | |
|
274 | ||
|
275 | def getTxBuffer(self): | |
|
276 | ||
|
277 | return self.tx_buffer | |
|
278 | ||
|
279 | def getRxBuffer(self): | |
|
280 | ||
|
281 | return self.rx_buffer | |
|
282 | ||
|
283 | def __encodeIpCmd(self, ip, mask, gateway): | |
|
284 | ||
|
285 | payload = ip + '/' + mask + '/' + gateway | |
|
286 | return self.__encoder(CMD_CHANGEIP, payload) | |
|
287 | ||
|
288 | def __encodeResetCmd(self): | |
|
289 | ||
|
290 | payload = "" | |
|
291 | return self.__encoder(CMD_RESET, payload) | |
|
292 | ||
|
293 | def __sendTCPData(self, cadena): | |
|
294 | ||
|
295 | sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
|
296 | sck.settimeout(2) | |
|
297 | ||
|
298 | try: | |
|
299 | sck.connect(self.address) | |
|
300 | except: | |
|
301 | return None | |
|
302 | ||
|
303 | # print "TX: ", ascii2hex(cadena) | |
|
304 | ||
|
305 | sck.send(cadena) | |
|
306 | ||
|
307 | rx_buffer = "" | |
|
308 | ||
|
309 | ini = time.time() | |
|
310 | ||
|
311 | try: | |
|
312 | while True: | |
|
313 | ||
|
314 | if time.time() - ini > 0.5: | |
|
315 | break | |
|
316 | ||
|
317 | tmp = sck.recv(255) | |
|
318 | ||
|
319 | if len(tmp) < 1: | |
|
320 | continue | |
|
321 | ||
|
322 | ini = time.time() | |
|
323 | rx_buffer += tmp | |
|
324 | ||
|
325 | finally: | |
|
326 | sck.close() | |
|
327 | ||
|
328 | # print "RX: ", ascii2hex(rx_buffer) | |
|
329 | ||
|
330 | return rx_buffer | |
|
331 | ||
|
332 | def changeIP(self, ip, mask, gateway): | |
|
333 | ||
|
334 | tx_buffer = self.__encodeIpCmd(ip, mask, gateway) | |
|
335 | rx_buffer = self.__sendTCPData(tx_buffer) | |
|
336 | ||
|
337 | sts = self.__decoder_api(rx_buffer) | |
|
338 | ||
|
339 | if sts > 0: | |
|
340 | self.address = (ip, self.address[1]) | |
|
341 | ||
|
342 | return sts | |
|
343 | ||
|
344 | def reset(self): | |
|
345 | ||
|
346 | tx_buffer = self.__encodeResetCmd() | |
|
347 | rx_buffer = self.__sendTCPData(tx_buffer) | |
|
348 | ||
|
349 | return self.__decoder_api(rx_buffer) | |
|
350 | ||
|
351 | def sendData(self, cmd, payload, server=False): | |
|
352 | ||
|
353 | if server: | |
|
354 | tx_buffer = self.__encoder(cmd, payload) | |
|
355 | ||
|
356 | print "TX: ", ascii2hex(tx_buffer) | |
|
357 | ||
|
358 | self.client_connection.sendall(tx_buffer) | |
|
359 | ||
|
360 | else: | |
|
361 | ||
|
362 | tx_buffer = self.__encoder(cmd, payload) | |
|
363 | ||
|
364 | print "TX: ", ascii2hex(tx_buffer) | |
|
365 | ||
|
366 | rx_buffer = self.__sendTCPData(tx_buffer) | |
|
367 | ||
|
368 | if not rx_buffer: | |
|
369 | msg = "0:Could not connect to Device %s" %str(self.address) | |
|
370 | return msg | |
|
371 | ||
|
372 | print "RX: ", ascii2hex(rx_buffer) | |
|
373 | ||
|
374 | return self.__decoder_api(rx_buffer) | |
|
375 | ||
|
376 | def receiveData(self, rx_buffer): | |
|
377 | ||
|
378 | print "RX: ", ascii2hex(rx_buffer) | |
|
379 | ||
|
380 | return self.__decoder(rx_buffer) | |
|
381 | ||
|
382 | ||
|
383 | def eth_device(id_class): | |
|
384 | def inner_func(func): | |
|
385 | def func_wrapper(ip, port, *args): | |
|
386 | ||
|
387 | cmd, payload = func(*args) | |
|
388 | ||
|
389 | ipObj = IPData(ip, port, id_class=id_class) | |
|
390 | ||
|
391 | rx = ipObj.sendData(cmd, payload) | |
|
392 | ||
|
393 | return rx | |
|
394 | ||
|
395 | return func_wrapper | |
|
396 | return inner_func No newline at end of file |
|
1 | NO CONTENT: new file 100644 |
@@ -0,0 +1,122 | |||
|
1 | ''' | |
|
2 | Created on Dec 2, 2014 | |
|
3 | ||
|
4 | @author: Miguel Urco | |
|
5 | ||
|
6 | eth_device decorator is used to implement an api to ethernet devices. | |
|
7 | When eth_device decorator is used it adds two parameters to any function (ip and port) | |
|
8 | ||
|
9 | #Definition | |
|
10 | ||
|
11 | @eth_device | |
|
12 | def enable_rf() | |
|
13 | cmd = "xxxxx" | |
|
14 | payload = "xxxxxx" | |
|
15 | ||
|
16 | return cmd, payload | |
|
17 | ||
|
18 | #How to call this function: | |
|
19 | answer = enable_rf(ip, port) | |
|
20 | ||
|
21 | ''' | |
|
22 | import data | |
|
23 | ||
|
24 | from devices.jro_device import eth_device, IdClass | |
|
25 | ||
|
26 | ID_CLASS = IdClass["rc"] | |
|
27 | ||
|
28 | CMD_RESET =0X01 | |
|
29 | CMD_ENABLE =0X02 | |
|
30 | CMD_CHANGEIP =0X03 | |
|
31 | CMD_STATUS =0X04 | |
|
32 | CMD_ECHO =0XFE | |
|
33 | ||
|
34 | DDS_CMD_RESET =0X10 | |
|
35 | DDS_CMD_ENABLE_RF =0x11 | |
|
36 | # DDS_CMD_MULTIPLIER =0X12 | |
|
37 | # DDS_CMD_MODE =0x13 | |
|
38 | # DDS_CMD_FREQUENCY_A =0X14 | |
|
39 | # DDS_CMD_FREQUENCY_B =0x15 | |
|
40 | # DDS_CMD_PHASE_A =0X16 | |
|
41 | # DDS_CMD_PHASE_B =0x17 | |
|
42 | # DDS_CMD_AMPLITUDE_1 =0X19 #Se han invertido la posicion de los canales | |
|
43 | # DDS_CMD_AMPLITUDE_2 =0x18 #en el PCB | |
|
44 | ||
|
45 | DDS_CMD_WRITE =0x50 | |
|
46 | DDS_CMD_READ =0x8000 | |
|
47 | ||
|
48 | @eth_device(ID_CLASS) | |
|
49 | def reset(): | |
|
50 | ||
|
51 | cmd = CMD_RESET | |
|
52 | payload = "" | |
|
53 | ||
|
54 | return cmd, payload | |
|
55 | ||
|
56 | @eth_device(ID_CLASS) | |
|
57 | def change_ip(ip, mask="255.255.255.0", gateway="0.0.0.0"): | |
|
58 | ||
|
59 | cmd = CMD_CHANGEIP | |
|
60 | payload = ip + '/' + mask + '/' + gateway | |
|
61 | ||
|
62 | return cmd, payload | |
|
63 | ||
|
64 | @eth_device(ID_CLASS) | |
|
65 | def status(): | |
|
66 | ||
|
67 | cmd = CMD_STATUS | |
|
68 | payload = "" | |
|
69 | ||
|
70 | return cmd, payload | |
|
71 | ||
|
72 | @eth_device(ID_CLASS) | |
|
73 | def echo(): | |
|
74 | ||
|
75 | cmd = CMD_ECHO | |
|
76 | payload = "" | |
|
77 | ||
|
78 | return cmd, payload | |
|
79 | ||
|
80 | @eth_device(ID_CLASS) | |
|
81 | def read_all_device(): | |
|
82 | ||
|
83 | payload = "" | |
|
84 | ||
|
85 | return DDS_CMD_READ, payload | |
|
86 | ||
|
87 | @eth_device(ID_CLASS) | |
|
88 | def write_all_device(payload): | |
|
89 | ||
|
90 | return DDS_CMD_WRITE, payload | |
|
91 | ||
|
92 | def read_config(ip, port): | |
|
93 | """ | |
|
94 | Output: | |
|
95 | parms : Dictionary with keys | |
|
96 | ||
|
97 | """ | |
|
98 | payload = read_all_device(ip, port) | |
|
99 | ||
|
100 | return data.rc_str_to_dict(payload) | |
|
101 | ||
|
102 | def write_config(ip, port, parms): | |
|
103 | """ | |
|
104 | Input: | |
|
105 | ip : | |
|
106 | port : | |
|
107 | parms : Dictionary with keys | |
|
108 | ||
|
109 | """ | |
|
110 | ||
|
111 | payload = data.dict_to_rc_str(parms) | |
|
112 | ||
|
113 | answer = write_all_device(ip, port, payload) | |
|
114 | ||
|
115 | return answer | |
|
116 | ||
|
117 | if __name__ == '__main__': | |
|
118 | ip = "10.10.20.150" | |
|
119 | port = 2000 | |
|
120 | ||
|
121 | print status(ip, port) | |
|
122 | print read_config(ip, port) No newline at end of file |
@@ -0,0 +1,26 | |||
|
1 | ''' | |
|
2 | Created on Feb 15, 2016 | |
|
3 | ||
|
4 | @author: Miguel Urco | |
|
5 | ''' | |
|
6 | import struct | |
|
7 | ||
|
8 | def rc_str_to_dict(registers): | |
|
9 | ||
|
10 | parms = {'clock' : 10 | |
|
11 | } | |
|
12 | ||
|
13 | return parms | |
|
14 | ||
|
15 | def dict_to_rc_str(parms): | |
|
16 | """ | |
|
17 | Input: | |
|
18 | parms : Dictionary with keys | |
|
19 | """ | |
|
20 | ||
|
21 | my_dict = {'clock' : 10 | |
|
22 | } | |
|
23 | ||
|
24 | registers = ord(my_dict['clock']) | |
|
25 | ||
|
26 | return registers No newline at end of file |
@@ -0,0 +1,67 | |||
|
1 | ''' | |
|
2 | Created on Feb 8, 2016 | |
|
3 | ||
|
4 | @author: Miguel Urco | |
|
5 | ''' | |
|
6 | ||
|
7 | import string | |
|
8 | import data | |
|
9 | ||
|
10 | def read_rc_file(fp): | |
|
11 | """ | |
|
12 | Function to extract the parameters from a text file with the next format: | |
|
13 | ||
|
14 | Input: | |
|
15 | ||
|
16 | File with the next content: | |
|
17 | ||
|
18 | Phase Adjust Register 1 | |
|
19 | ----------------------- | |
|
20 | 00000000 | |
|
21 | 00000000 | |
|
22 | ||
|
23 | ..... | |
|
24 | ||
|
25 | ----------------------- | |
|
26 | Frequency Tuning Word 1 | |
|
27 | ----------------------- | |
|
28 | 00110101 | |
|
29 | 01111111 | |
|
30 | 11111111 | |
|
31 | 11111111 | |
|
32 | 10100000 | |
|
33 | 00000000 | |
|
34 | ||
|
35 | Output: | |
|
36 | Return configuration parameters for DDS: multiplier, frequency, phase, amplitude, etc. | |
|
37 | ||
|
38 | """ | |
|
39 | ||
|
40 | registers = "" | |
|
41 | ||
|
42 | for this_line in fp: | |
|
43 | this_line = str.strip(this_line) | |
|
44 | ||
|
45 | if not str.isdigit(this_line): | |
|
46 | continue | |
|
47 | ||
|
48 | if len(this_line) != 8: | |
|
49 | continue | |
|
50 | ||
|
51 | registers += chr(string.atoi(this_line,2)) | |
|
52 | ||
|
53 | parms = data.rc_str_to_dict(registers) | |
|
54 | ||
|
55 | return parms | |
|
56 | ||
|
57 | def read_json_file(fp): | |
|
58 | ||
|
59 | kwargs = {} | |
|
60 | ||
|
61 | return kwargs | |
|
62 | ||
|
63 | def write_cr_file(filename): | |
|
64 | pass | |
|
65 | ||
|
66 | def write_json_file(filename): | |
|
67 | pass No newline at end of file |
@@ -1,93 +1,67 | |||
|
1 | 1 | ''' |
|
2 | 2 | Created on Feb 8, 2016 |
|
3 | 3 | |
|
4 | 4 | @author: Miguel Urco |
|
5 | 5 | ''' |
|
6 | 6 | |
|
7 | 7 | import string |
|
8 | import data | |
|
8 | 9 | |
|
9 | 10 | def read_dds_file(fp): |
|
10 | 11 | """ |
|
11 | 12 | Function to extract the parameters from a text file with the next format: |
|
12 | 13 | |
|
13 | 14 | Input: |
|
14 | 15 | |
|
15 | 16 | File with the next content: |
|
16 | 17 | |
|
17 | 18 | Phase Adjust Register 1 |
|
18 | 19 | ----------------------- |
|
19 | 20 | 00000000 |
|
20 | 21 | 00000000 |
|
21 | 22 | |
|
22 | 23 | ..... |
|
23 | 24 | |
|
24 | 25 | ----------------------- |
|
25 | 26 | Frequency Tuning Word 1 |
|
26 | 27 | ----------------------- |
|
27 | 28 | 00110101 |
|
28 | 29 | 01111111 |
|
29 | 30 | 11111111 |
|
30 | 31 | 11111111 |
|
31 | 32 | 10100000 |
|
32 | 33 | 00000000 |
|
33 | 34 | |
|
34 | 35 | Output: |
|
35 | 36 | Return configuration parameters for DDS: multiplier, frequency, phase, amplitude, etc. |
|
36 | 37 | |
|
37 | 38 | """ |
|
38 | 39 | |
|
39 |
|
|
|
40 | dds_registers = [] | |
|
40 | registers = "" | |
|
41 | 41 | |
|
42 | 42 | for this_line in fp: |
|
43 | 43 | this_line = str.strip(this_line) |
|
44 | 44 | |
|
45 | 45 | if not str.isdigit(this_line): |
|
46 | 46 | continue |
|
47 | 47 | |
|
48 | 48 | if len(this_line) != 8: |
|
49 | 49 | continue |
|
50 | 50 | |
|
51 |
|
|
|
52 | ||
|
53 | if len(dds_registers) != 40: | |
|
54 | return kwargs | |
|
55 | ||
|
56 | kwargs['clock'] = 60.0 | |
|
57 | ||
|
58 | kwargs['phase_bin'] = dds_registers[0]*(2**8) + dds_registers[1] | |
|
59 | kwargs['phase_mod_bin'] = dds_registers[2]*(2**8) + dds_registers[3] | |
|
60 | ||
|
61 | kwargs['frequency_bin'] = dds_registers[4]*(2**40) + dds_registers[5]*(2**32) + dds_registers[6]*(2**24) + dds_registers[7]*(2**16) + dds_registers[8]*(2**8) + dds_registers[9] | |
|
62 | kwargs['frequency_mod_bin'] = dds_registers[10]*(2**40) + dds_registers[11]*(2**32) + dds_registers[12]*(2**24) + dds_registers[13]*(2**16) + dds_registers[14]*(2**8) + dds_registers[15] | |
|
63 | ||
|
64 | kwargs['delta_frequency'] = dds_registers[16]*(2**40) + dds_registers[17]*(2**32) + dds_registers[18]*(2**24) + dds_registers[19]*(2**16) + dds_registers[20]*(2**8) + dds_registers[21] | |
|
51 | registers += chr(string.atoi(this_line,2)) | |
|
65 | 52 | |
|
66 | kwargs['update_clock'] = dds_registers[22]*(2**24) + dds_registers[23]*(2**16) + dds_registers[24]*(2**8) + dds_registers[25] | |
|
53 | parms = data.dds_str_to_dict(registers) | |
|
67 | 54 | |
|
68 | kwargs['ramp_rate_clock'] = dds_registers[26]*(2**16) + dds_registers[27]*(2**8) + dds_registers[28] | |
|
69 | ||
|
70 | kwargs['control_register'] = dds_registers[29]*(2**24) + dds_registers[30]*(2**16) + dds_registers[31]*(2**8) + dds_registers[32] | |
|
71 | ||
|
72 | kwargs['multiplier'] = dds_registers[30] & 0x1F | |
|
73 | kwargs['modulation'] = (dds_registers[31] & 0x0E) >> 1 | |
|
74 | kwargs['amplitude_enabled'] = (dds_registers[32] & 0x20) >> 5 | |
|
75 | ||
|
76 | kwargs['amplitude_ch_A'] = (dds_registers[33]*(2**8) + dds_registers[34]) & 0x0FFF | |
|
77 | kwargs['amplitude_ch_B'] = (dds_registers[35]*(2**8) + dds_registers[36]) & 0x0FFF | |
|
78 | ||
|
79 | kwargs['amplitude_ramp_rate'] = dds_registers[37] | |
|
80 | ||
|
81 | return kwargs | |
|
55 | return parms | |
|
82 | 56 | |
|
83 | 57 | def read_json_file(fp): |
|
84 | 58 | |
|
85 | 59 | kwargs = {} |
|
86 | 60 | |
|
87 | 61 | return kwargs |
|
88 | 62 | |
|
89 | 63 | def write_dds_file(filename): |
|
90 | 64 | pass |
|
91 | 65 | |
|
92 | 66 | def write_json_file(filename): |
|
93 | 67 | pass No newline at end of file |
General Comments 0
You need to be logged in to leave comments.
Login now