1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 |
1 | NO CONTENT: new file 100644 |
|
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 |
|
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 |
@@ -5,6 +5,7 Created on Feb 8, 2016 | |||||
5 | ''' |
|
5 | ''' | |
6 |
|
6 | |||
7 | import string |
|
7 | import string | |
|
8 | import data | |||
8 |
|
9 | |||
9 | def read_dds_file(fp): |
|
10 | def read_dds_file(fp): | |
10 | """ |
|
11 | """ | |
@@ -36,8 +37,7 def read_dds_file(fp): | |||||
36 |
|
37 | |||
37 | """ |
|
38 | """ | |
38 |
|
39 | |||
39 |
|
|
40 | registers = "" | |
40 | dds_registers = [] |
|
|||
41 |
|
41 | |||
42 | for this_line in fp: |
|
42 | for this_line in fp: | |
43 | this_line = str.strip(this_line) |
|
43 | this_line = str.strip(this_line) | |
@@ -48,37 +48,11 def read_dds_file(fp): | |||||
48 | if len(this_line) != 8: |
|
48 | if len(this_line) != 8: | |
49 | continue |
|
49 | continue | |
50 |
|
50 | |||
51 |
|
|
51 | registers += chr(string.atoi(this_line,2)) | |
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] |
|
|||
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] |
|
55 | return parms | |
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 |
|
|||
82 |
|
56 | |||
83 | def read_json_file(fp): |
|
57 | def read_json_file(fp): | |
84 |
|
58 |
General Comments 0
You need to be logged in to leave comments.
Login now