##// END OF EJS Templates
DDS app updated...
Miguel Urco -
r32:e512425c47f1
parent child
Show More
@@ -0,0 +1,93
1 '''
2 Created on Feb 8, 2016
3
4 @author: Miguel Urco
5 '''
6
7 import string
8
9 def read_dds_file(fp):
10 """
11 Function to extract the parameters from a text file with the next format:
12
13 Input:
14
15 File with the next content:
16
17 Phase Adjust Register 1
18 -----------------------
19 00000000
20 00000000
21
22 .....
23
24 -----------------------
25 Frequency Tuning Word 1
26 -----------------------
27 00110101
28 01111111
29 11111111
30 11111111
31 10100000
32 00000000
33
34 Output:
35 Return configuration parameters for DDS: multiplier, frequency, phase, amplitude, etc.
36
37 """
38
39 kwargs = {}
40 dds_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 dds_registers.append(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
66 kwargs['update_clock'] = dds_registers[22]*(2**24) + dds_registers[23]*(2**16) + dds_registers[24]*(2**8) + dds_registers[25]
67
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
82
83 def read_json_file(fp):
84
85 kwargs = {}
86
87 return kwargs
88
89 def write_dds_file(filename):
90 pass
91
92 def write_json_file(filename):
93 pass No newline at end of file
@@ -0,0 +1,7
1 {% extends "dev_conf_edit.html" %}
2 {% load bootstrap3 %}
3 {% load static %}
4 {% load main_tags %}
5
6 {% block extra-js%}
7 {% endblock %} No newline at end of file
@@ -4,6 +4,11 from .models import DDSConfiguration
4 4
5 5 # from django.core.validators import MinValueValidator, MaxValueValidator
6 6
7 EXT_TYPES = (
8 ('dds', '.dds'),
9 ('json', '.json'),
10 )
11
7 12 class DDSConfigurationForm(forms.ModelForm):
8 13
9 14 # frequency_bin = forms.IntegerField(label='Frequency (Binary)', required=False)
@@ -48,3 +53,8 class DDSConfigurationForm(forms.ModelForm):
48 53 class Meta:
49 54 model = DDSConfiguration
50 55 exclude = ('type','parameters')
56
57 class UploadFileForm(forms.Form):
58
59 title = forms.ChoiceField(label='Extension Type', choices=EXT_TYPES)
60 file = forms.FileField() No newline at end of file
@@ -5,6 +5,8 from apps.main.models import Configuration
5 5 from django.core.validators import MinValueValidator, MaxValueValidator
6 6 from django.core.exceptions import ValidationError
7 7
8 from files import read_dds_file, read_json_file
9
8 10 MOD_TYPES = (
9 11 (0, 'Single Tone'),
10 12 (1, 'FSK'),
@@ -17,21 +19,21 class DDSConfiguration(Configuration):
17 19
18 20 DDS_NBITS = 48
19 21
20 clock = models.FloatField(verbose_name='Clock Master (MHz)',validators=[MinValueValidator(5), MaxValueValidator(75)], null=True)
22 clock = models.FloatField(verbose_name='Clock Input (MHz)',validators=[MinValueValidator(5), MaxValueValidator(75)], null=True)
21 23 multiplier = models.PositiveIntegerField(verbose_name='Multiplier',validators=[MinValueValidator(1), MaxValueValidator(20)], default=4)
22 24
23 frequency = models.DecimalField(verbose_name='Frequency (MHz)', validators=[MinValueValidator(0), MaxValueValidator(150)], max_digits=18, decimal_places=16)
25 frequency = models.DecimalField(verbose_name='Frequency (MHz)', validators=[MinValueValidator(0), MaxValueValidator(150)], max_digits=19, decimal_places=16)
24 26 frequency_bin = models.BigIntegerField(verbose_name='Frequency (Binary)',validators=[MinValueValidator(0), MaxValueValidator(2**DDS_NBITS-1)])
25 27
26 28 phase = models.FloatField(verbose_name='Phase (Degrees)', validators=[MinValueValidator(0), MaxValueValidator(360)], default=0)
27 29 # phase_binary = models.PositiveIntegerField(verbose_name='Phase (Binary)',validators=[MinValueValidator(0), MaxValueValidator(2**14-1)])
28 30
29 amplitude_ch_A = models.PositiveIntegerField(verbose_name='Amplitude CH A',validators=[MinValueValidator(0), MaxValueValidator(2**10-1)], blank=True, null=True)
30 amplitude_ch_B = models.PositiveIntegerField(verbose_name='Amplitude CH B',validators=[MinValueValidator(0), MaxValueValidator(2**10-1)], blank=True, null=True)
31 amplitude_ch_A = models.PositiveIntegerField(verbose_name='Amplitude CH A',validators=[MinValueValidator(0), MaxValueValidator(2**12-1)], blank=True, null=True)
32 amplitude_ch_B = models.PositiveIntegerField(verbose_name='Amplitude CH B',validators=[MinValueValidator(0), MaxValueValidator(2**12-1)], blank=True, null=True)
31 33
32 34 modulation = models.PositiveIntegerField(verbose_name='Modulation Type', choices = MOD_TYPES, default = 0)
33 35
34 frequency_mod = models.DecimalField(verbose_name='Mod: Frequency (MHz)', validators=[MinValueValidator(0), MaxValueValidator(150)], max_digits=18, decimal_places=16, blank=True, null=True)
36 frequency_mod = models.DecimalField(verbose_name='Mod: Frequency (MHz)', validators=[MinValueValidator(0), MaxValueValidator(150)], max_digits=19, decimal_places=16, blank=True, null=True)
35 37 frequency_mod_bin = models.BigIntegerField(verbose_name='Mod: Frequency (Binary)',validators=[MinValueValidator(0), MaxValueValidator(2**DDS_NBITS-1)], blank=True, null=True)
36 38
37 39 phase_mod = models.FloatField(verbose_name='Mod: Phase (Degrees)', validators=[MinValueValidator(0), MaxValueValidator(360)], blank=True, null=True)
@@ -71,6 +73,53 class DDSConfiguration(Configuration):
71 73
72 74 return freq
73 75
76 def phase2binary(self, phase):
77
78 binary = phase*8192/180.0
79
80 return binary
81
82 def binary2phase(self, binary):
83
84 phase = binary*180.0/8192
85
86 return phase
87
88 def export_file(self, ext_file="dds"):
89
90 pass
91
92 def update_from_file(self, fp, ext_file="dds"):
93
94 if ext_file == "dds":
95 kwargs = read_dds_file(fp)
96 else:
97 kwargs = read_json_file(fp)
98
99 if not kwargs:
100 return False
101
102 self.clock = kwargs['clock']
103 self.multiplier = kwargs['multiplier']
104
105 mclock = self.clock*self.multiplier
106
107 self.frequency = self.binary2freq(kwargs['frequency_bin'], mclock)
108 self.frequency_bin = kwargs['frequency_bin']
109
110 self.frequency_mod = self.binary2freq(kwargs['frequency_mod_bin'], mclock)
111 self.frequency_mod_bin = kwargs['frequency_mod_bin']
112
113 self.phase = self.binary2phase(kwargs['phase_bin'])
114 self.phase_mod = self.binary2phase(kwargs['phase_mod_bin'])
115
116 self.modulation = kwargs['modulation']
117
118 self.amplitude_ch_A = kwargs['amplitude_ch_A']
119 self.amplitude_ch_B = kwargs['amplitude_ch_B']
120
121 return True
122
74 123 class Meta:
75 124 db_table = 'dds_configurations'
76 125 No newline at end of file
@@ -6,6 +6,6 urlpatterns = (
6 6 url(r'^(?P<id_conf>-?\d+)/edit/$', 'apps.dds.views.dds_conf_edit', name='url_edit_dds_conf'),
7 7 url(r'^(?P<id_conf>-?\d+)/write/$', 'apps.dds.views.dds_conf_write', name='url_write_dds_conf'),
8 8 url(r'^(?P<id_conf>-?\d+)/read/$', 'apps.dds.views.dds_conf_read', name='url_read_dds_conf'),
9 url(r'^(?P<id_conf>-?\d+)/import/$', 'apps.main.views.dev_conf_import', name='url_import_dds_conf'),
9 url(r'^(?P<id_conf>-?\d+)/import/$', 'apps.dds.views.dds_conf_import', name='url_import_dds_conf'),
10 10 url(r'^(?P<id_conf>-?\d+)/export/$', 'apps.main.views.dev_conf_export', name='url_export_dds_conf'),
11 11 )
@@ -2,11 +2,13
2 2 from django.contrib import messages
3 3 from django.shortcuts import redirect, render, get_object_or_404
4 4
5 from django.core.exceptions import ValidationError
6
5 7 # from apps.main.models import Experiment, Configuration
6 8 from apps.main.views import sidebar
7 9
8 10 from .models import DDSConfiguration
9 from .forms import DDSConfigurationForm
11 from .forms import DDSConfigurationForm, UploadFileForm
10 12 # Create your views here.
11 13
12 14 from radarsys_api import dds
@@ -18,8 +20,12 def dds_conf(request, id_conf):
18 20 answer = dds.echo(ip=str(conf.device.ip_address), port=conf.device.port_address)
19 21
20 22 kwargs = {}
23
21 24 kwargs['connected'] = (answer[0] == "1")
22 25
26 if not kwargs['connected']:
27 messages.error(request, message=answer)
28
23 29 kwargs['dev_conf'] = conf
24 30 kwargs['dev_conf_keys'] = ['experiment', 'device',
25 31 'clock', 'multiplier',
@@ -87,8 +93,8 def dds_conf_write(request, id_conf):
87 93 freq_regA=conf.frequency_bin,
88 94 freq_regB=conf.frequency_mod_bin,
89 95 modulation=conf.modulation,
90 phaseA=conf.phase,
91 phaseB=conf.phase_mod,
96 phaseA=conf.phase2binary(conf.phase),
97 phaseB=conf.phase2binary(conf.phase_mod),
92 98 amplitude0=conf.amplitude_ch_A,
93 99 amplitude1=conf.amplitude_ch_B)
94 100
@@ -101,9 +107,9 def dds_conf_write(request, id_conf):
101 107 conf.save()
102 108
103 109 else:
104 messages.error(request, answer)
110 messages.error(request, "Could not write the parameters to this device")
105 111
106 return redirect('url_dds_conf', id_conf=conf.id)
112 return redirect('url_dds_conf', id_conf=id_conf)
107 113
108 114 def dds_conf_read(request, id_conf):
109 115
@@ -120,7 +126,7 def dds_conf_read(request, id_conf):
120 126 dds_model.save()
121 127 return redirect('url_dds_conf', id_conf=conf.id)
122 128
123 messages.error(request, "Parameters could not be saved. Invalid parameters")
129 messages.error(request, "Parameters could not be saved")
124 130
125 131 data = {}
126 132
@@ -130,25 +136,22 def dds_conf_read(request, id_conf):
130 136 port=conf.device.port_address)
131 137
132 138 if not parms:
133 messages.error(request, "Could not read parameters from Device")
139 messages.error(request, "Could not read dds parameters from this device")
134 140 return redirect('url_dds_conf', id_conf=conf.id)
135 141
136 data = {'experiment' : conf.experiment.id,
137 'device' : conf.device.id,
138 'clock' : conf.clock,
139 'multiplier' : parms[0],
142 data = {'multiplier' : parms[0],
140 143 'frequency' : conf.binary2freq(parms[1], parms[0]*conf.clock),
141 144 'frequency_bin' : parms[1],
142 'phase' : parms[4],
145 'phase' : conf.binary2phase(parms[4]),
143 146 'amplitude_ch_A' : parms[6],
144 147 'amplitude_ch_B' : parms[7],
145 148 'modulation' : parms[3],
146 149 'frequency_mod' : conf.binary2freq(parms[2], parms[0]*conf.clock),
147 150 'frequency_mod_bin' : parms[2],
148 'phase_mod' : parms[5],
151 'phase_mod' : conf.binary2phase(parms[5]),
149 152 }
150 153
151 form = DDSConfigurationForm(data)
154 form = DDSConfigurationForm(initial=data, instance=conf)
152 155
153 156 kwargs = {}
154 157 kwargs['id_dev'] = conf.id
@@ -160,4 +163,59 def dds_conf_read(request, id_conf):
160 163 ###### SIDEBAR ######
161 164 kwargs.update(sidebar(conf))
162 165
163 return render(request, 'dds_conf_edit.html', kwargs) No newline at end of file
166 return render(request, 'dds_conf_edit.html', kwargs)
167
168 def dds_conf_import(request, id_conf):
169
170 conf = get_object_or_404(DDSConfiguration, pk=id_conf)
171
172 if request.method == 'POST':
173 file_form = UploadFileForm(request.POST, request.FILES)
174
175 if file_form.is_valid():
176
177 if conf.update_from_file(request.FILES['file']):
178
179 try:
180 conf.full_clean()
181 except ValidationError as e:
182 messages.error(request, e)
183 else:
184 conf.save()
185
186 messages.success(request, "Parameters imported from file: '%s'." %request.FILES['file'].name)
187 messages.warning(request, "Clock Input could not be read from file, using %3.2fMhz by default. Please update it to its real value" %conf.clock)
188 return redirect('url_dds_conf', id_conf=conf.id)
189
190 messages.error(request, "Could not import parameters from file")
191
192 else:
193 file_form = UploadFileForm()
194
195 kwargs = {}
196 kwargs['id_dev'] = conf.id
197 kwargs['title'] = 'Device Configuration'
198 kwargs['form'] = file_form
199 kwargs['suptitle'] = 'Importing file'
200 kwargs['button'] = 'Import'
201
202 kwargs.update(sidebar(conf))
203
204 return render(request, 'dds_conf_import.html', kwargs)
205
206 def handle_uploaded_file(f):
207
208 data = {'multiplier' : 5,
209 'frequency' : 49.92,
210 'frequency_bin' : 45678,
211 'phase' : 0,
212 'amplitude_ch_A' : 1024,
213 'amplitude_ch_B' : 2014,
214 'modulation' : 1,
215 'frequency_mod' : 0,
216 'frequency_mod_bin' : 0,
217 'phase_mod' : 180,
218 }
219
220
221 return data No newline at end of file
@@ -2,6 +2,8 from itertools import chain
2 2 from django.db import models
3 3 from polymorphic import PolymorphicModel
4 4
5 from django.core.urlresolvers import reverse
6
5 7 CONF_TYPES = (
6 8 (0, 'Active'),
7 9 (1, 'Historical'),
@@ -107,25 +109,20 class Configuration(PolymorphicModel):
107 109 self.experiment.name,
108 110 self.device.name)
109 111 def get_absolute_url(self):
110 from django.core.urlresolvers import reverse
112
111 113 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
112 114
113 115 def get_absolute_url_edit(self):
114 from django.core.urlresolvers import reverse
115 116 return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
116 117
117 118 def get_absolute_url_import(self):
118 from django.core.urlresolvers import reverse
119 119 return reverse('url_import_%s_conf' % self.device.device_type.name, args=[str(self.id)])
120 120
121 121 def get_absolute_url_export(self):
122 from django.core.urlresolvers import reverse
123 122 return reverse('url_export_%s_conf' % self.device.device_type.name, args=[str(self.id)])
124 123
125 124 def get_absolute_url_write(self):
126 from django.core.urlresolvers import reverse
127 125 return reverse('url_write_%s_conf' % self.device.device_type.name, args=[str(self.id)])
128 126
129 127 def get_absolute_url_read(self):
130 from django.core.urlresolvers import reverse
131 128 return reverse('url_read_%s_conf' % self.device.device_type.name, args=[str(self.id)]) No newline at end of file
@@ -89,14 +89,13
89 89 <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
90 90 <strong>{{message.tags|title}}!</strong> {{ message }}
91 91 </div>
92 {% endfor %}
93 <br>
92 {% endfor %}
94 93 {% endif %}
95 94 {% endblock %}
96 95
97 96 {% block content %}
98 97 {% endblock %}
99 <br>
98
100 99 </div>
101 100
102 101
@@ -9,7 +9,13
9 9 {% block content-suptitle %}{{suptitle}}{% endblock %}
10 10
11 11 {% block content %}
12 <form class="form" method="post" action="">
12
13 {% if form.is_multipart %}
14 <form class="form" enctype="multipart/form-data" method="post" action="">
15 {% else %}
16 <form class="form" method="post" action="">
17 {% endif %}
18
13 19 {% csrf_token %}
14 20 {% bootstrap_form form layout='horizontal' size='medium' %}
15 21 <div style="clear: both;"></div>
@@ -440,93 +440,33 def dev_conf_read(request, id_conf):
440 440
441 441 conf = get_object_or_404(Configuration, pk=id_conf)
442 442
443 DevConfModel = CONF_MODELS[conf.device.device_type.name]
444 dev_conf = DevConfModel.objects.get(pk=id_conf)
445
446 kwargs = {}
447 kwargs['dev_conf'] = dev_conf
448 kwargs['dev_conf_keys'] = ['experiment', 'device']
449
450 kwargs['title'] = 'Configuration'
451 kwargs['suptitle'] = 'Details'
452
453 kwargs['button'] = 'Edit Configuration'
454
455 ###### SIDEBAR ######
456 kwargs.update(sidebar(conf))
443 messages.error(request, "Read View not implemented yet")
457 444
458 messages.error(request, "Read View not implemented yet for this configuration")
459
460 return render(request, 'dev_conf.html', kwargs)
445 return redirect('url_dev_conf', id_conf=conf.id)
461 446
462 447 def dev_conf_write(request, id_conf):
463 448
464 449 conf = get_object_or_404(Configuration, pk=id_conf)
465 450
466 DevConfModel = CONF_MODELS[conf.device.device_type.name]
467 dev_conf = DevConfModel.objects.get(pk=id_conf)
468
469 kwargs = {}
470 kwargs['dev_conf'] = dev_conf
471 kwargs['dev_conf_keys'] = ['experiment', 'device']
472
473 kwargs['title'] = 'Configuration'
474 kwargs['suptitle'] = 'Details'
475
476 kwargs['button'] = 'Edit Configuration'
477
478 ###### SIDEBAR ######
479 kwargs.update(sidebar(conf))
451 messages.error(request, "Write View not implemented yet")
480 452
481 messages.error(request, "Write View not implemented yet for this configuration")
482
483 return render(request, 'dev_conf.html', kwargs)
453 return redirect('url_dev_conf', id_conf=conf.id)
484 454
485 455 def dev_conf_import(request, id_conf):
486 456
487 457 conf = get_object_or_404(Configuration, pk=id_conf)
488 458
489 DevConfModel = CONF_MODELS[conf.device.device_type.name]
490 dev_conf = DevConfModel.objects.get(pk=id_conf)
491
492 kwargs = {}
493 kwargs['dev_conf'] = dev_conf
494 kwargs['dev_conf_keys'] = ['experiment', 'device']
495
496 kwargs['title'] = 'Configuration'
497 kwargs['suptitle'] = 'Details'
498
499 kwargs['button'] = 'Edit Configuration'
500
501 ###### SIDEBAR ######
502 kwargs.update(sidebar(conf))
459 messages.error(request, "Import View not implemented yet")
503 460
504 messages.error(request, "Import View not implemented yet for this configuration")
505
506 return render(request, 'dev_conf.html', kwargs)
461 return redirect('url_dev_conf', id_conf=conf.id)
507 462
508 463 def dev_conf_export(request, id_conf):
509 464
510 465 conf = get_object_or_404(Configuration, pk=id_conf)
511 466
512 DevConfModel = CONF_MODELS[conf.device.device_type.name]
513 dev_conf = DevConfModel.objects.get(pk=id_conf)
514
515 kwargs = {}
516 kwargs['dev_conf'] = dev_conf
517 kwargs['dev_conf_keys'] = ['experiment', 'device']
518
519 kwargs['title'] = 'Configuration'
520 kwargs['suptitle'] = 'Details'
521
522 kwargs['button'] = 'Edit Configuration'
523
524 ###### SIDEBAR ######
525 kwargs.update(sidebar(conf))
467 messages.error(request, "Export View not implemented yet")
526 468
527 messages.error(request, "Export View not implemented yet for this configuration")
528
529 return render(request, 'dev_conf.html', kwargs)
469 return redirect('url_dev_conf', id_conf=conf.id)
530 470
531 471 def dev_conf_delete(request, id_conf):
532 472
General Comments 0
You need to be logged in to leave comments. Login now