1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
- """
4
- Created on Fri Oct 23 13:55:56 2020
5
-
6
- @author: alexander
1
+ """Tests for PSL.waveform_generator.
2
+
3
+ When integration testing, connect:
4
+ SQ1 -> LA1
5
+ SQ2 -> LA2
6
+ SQ3 -> LA3
7
+ SQ4 -> LA4
8
+ SI1 -> CH1
9
+ SI2 -> CH2
7
10
"""
8
11
import time
9
12
10
13
import numpy as np
11
-
12
14
import pytest
15
+ from scipy .optimize import curve_fit
16
+ from _pytest .logging import LogCaptureFixture
17
+
13
18
from PSL .logic_analyzer import LogicAnalyzer
14
19
from PSL .oscilloscope import Oscilloscope
20
+ from PSL .packet_handler import Handler
15
21
from PSL .waveform_generator import PWMGenerator , WaveformGenerator
16
- from scipy . optimize import curve_fit
22
+
17
23
18
24
MICROSECONDS = 1e-6
19
25
RELTOL = 0.05
20
26
GOOD_FIT = 0.99
21
27
22
28
23
- def r_squared (y , y_fit ) :
29
+ def r_squared (y : np . ndarray , y_fit : np . ndarray ) -> float :
24
30
"""Calculate the coefficient of determination."""
25
31
ss_res = np .sum ((y - y_fit ) ** 2 ) # Residual sum of squares.
26
32
ss_tot = np .sum ((y - y .mean ()) ** 2 ) # Total sum of squares.
27
33
return 1 - (ss_res / ss_tot )
28
34
29
35
30
36
@pytest .fixture
31
- def pwm (handler ) :
37
+ def pwm (handler : Handler ) -> PWMGenerator :
32
38
handler ._logging = True
33
39
return PWMGenerator (handler )
34
40
35
41
36
42
@pytest .fixture
37
- def wave (handler ) :
43
+ def wave (handler : Handler ) -> WaveformGenerator :
38
44
handler ._logging = True
39
45
return WaveformGenerator (handler )
40
46
41
47
42
48
@pytest .fixture
43
- def la (handler ) :
49
+ def la (handler : Handler ) -> LogicAnalyzer :
44
50
handler ._logging = True
45
51
return LogicAnalyzer (handler )
46
52
47
53
48
54
@pytest .fixture
49
- def scope (handler ) :
55
+ def scope (handler : Handler ) -> Oscilloscope :
50
56
handler ._logging = True
51
57
return Oscilloscope (handler )
52
58
53
59
54
- def test_sine_wave (wave , scope ):
60
+ def test_sine_wave (wave : WaveformGenerator , scope : Oscilloscope ):
55
61
frequency = 500
56
62
wave .load_equation ("SI1" , "sine" )
57
63
wave .generate ("SI1" , frequency )
@@ -78,7 +84,7 @@ def expected_f(x, amplitude, frequency, phase):
78
84
assert coeff_of_det >= GOOD_FIT
79
85
80
86
81
- def test_triangle_wave (wave , scope ):
87
+ def test_triangle_wave (wave : WaveformGenerator , scope : Oscilloscope ):
82
88
frequency = 2000
83
89
wave .load_equation ("SI1" , "tria" )
84
90
wave .generate ("SI1" , frequency )
@@ -107,7 +113,7 @@ def expected_f(x, amplitude, frequency, phase):
107
113
assert coeff_of_det >= GOOD_FIT
108
114
109
115
110
- def test_superposition (wave , scope ):
116
+ def test_superposition (wave : WaveformGenerator , scope : Oscilloscope ):
111
117
frequency = 1000
112
118
amplitude1 = 2
113
119
amplitude2 = 1
@@ -147,7 +153,7 @@ def expected_f(x, amplitude1, amplitude2, frequency, phase):
147
153
assert coeff_of_det >= GOOD_FIT
148
154
149
155
150
- def test_sine_phase (wave , scope ):
156
+ def test_sine_phase (wave : WaveformGenerator , scope : Oscilloscope ):
151
157
frequency = 500
152
158
phase = 90
153
159
wave .load_equation ("SI1" , "sine" )
@@ -168,27 +174,27 @@ def expected_f(x, amplitude, frequency, phase):
168
174
assert phase2_est - phase1_est == pytest .approx (phase * np .pi / 180 , rel = RELTOL )
169
175
170
176
171
- def test_low_frequency_warning (caplog , wave ):
177
+ def test_low_frequency_warning (caplog : LogCaptureFixture , wave : WaveformGenerator ):
172
178
wave .generate ("SI1" , 1 )
173
179
assert "AC coupling" in caplog .text
174
180
175
181
176
- def test_low_frequency_error (wave ):
182
+ def test_low_frequency_error (wave : WaveformGenerator ):
177
183
with pytest .raises (ValueError ):
178
184
wave .generate ("SI1" , 0.05 )
179
185
180
186
181
- def test_high_frequency_warning (caplog , wave ):
187
+ def test_high_frequency_warning (caplog : LogCaptureFixture , wave : WaveformGenerator ):
182
188
wave .generate ("SI1" , 1e4 )
183
189
assert "Frequencies above"
184
190
185
191
186
- def test_dimension_mismatch (wave ):
192
+ def test_dimension_mismatch (wave : WaveformGenerator ):
187
193
with pytest .raises (ValueError ):
188
194
wave .generate ("SI2" , [500 , 1000 ])
189
195
190
196
191
- def test_pwm (pwm , la ):
197
+ def test_pwm (pwm : PWMGenerator , la : LogicAnalyzer ):
192
198
frequency = 5e4
193
199
duty_cycle = 0.4
194
200
pwm .generate ("SQ1" , frequency , duty_cycle )
@@ -198,7 +204,7 @@ def test_pwm(pwm, la):
198
204
assert la .measure_duty_cycle ("LA1" )[1 ] == pytest .approx (duty_cycle , rel = RELTOL )
199
205
200
206
201
- def test_pwm_phase (pwm , la ):
207
+ def test_pwm_phase (pwm : PWMGenerator , la : LogicAnalyzer ):
202
208
frequency = 1e4
203
209
duty_cycle = 0.5
204
210
phase = 0.25
@@ -212,14 +218,14 @@ def test_pwm_phase(pwm, la):
212
218
assert interval * MICROSECONDS == pytest .approx (frequency ** - 1 * phase , rel = RELTOL )
213
219
214
220
215
- def test_set_state (pwm , la ):
221
+ def test_set_state (pwm : PWMGenerator , la : LogicAnalyzer ):
216
222
states = [True , False , True , True ]
217
223
pwm .set_state (* states )
218
224
time .sleep (0.1 )
219
225
assert list (la .get_states ().values ()) == states
220
226
221
227
222
- def test_unchanged_state (pwm , la ):
228
+ def test_unchanged_state (pwm : PWMGenerator , la : LogicAnalyzer ):
223
229
frequency = 2.5e3
224
230
duty_cycle = 0.9
225
231
pwm .generate (["SQ1" , "SQ4" ], frequency , duty_cycle )
@@ -234,25 +240,25 @@ def test_unchanged_state(pwm, la):
234
240
assert la .measure_duty_cycle ("LA4" )[1 ] == pytest .approx (duty_cycle , rel = RELTOL )
235
241
236
242
237
- def test_map_reference_clock (pwm , la ):
243
+ def test_map_reference_clock (pwm : PWMGenerator , la : LogicAnalyzer ):
238
244
prescaler = 5
239
245
pwm .map_reference_clock (["SQ3" ], prescaler )
240
246
assert la .measure_frequency ("LA3" ) == pytest .approx (
241
247
128e6 / (1 << prescaler ), rel = RELTOL
242
248
)
243
249
244
250
245
- def test_pwm_high_frequency_error (pwm ):
251
+ def test_pwm_high_frequency_error (pwm : PWMGenerator ):
246
252
with pytest .raises (ValueError ):
247
253
pwm .generate ("SQ1" , 2e7 , 0.5 )
248
254
249
255
250
- def test_pwm_get_frequency (pwm ):
256
+ def test_pwm_get_frequency (pwm : PWMGenerator ):
251
257
frequency = 1500
252
258
pwm .generate ("SQ2" , frequency , 0.1 )
253
259
assert pwm .frequency == pytest .approx (frequency , rel = RELTOL )
254
260
255
261
256
- def test_pwm_set_negative_frequency (pwm ):
262
+ def test_pwm_set_negative_frequency (pwm : PWMGenerator ):
257
263
with pytest .raises (ValueError ):
258
264
pwm .generate ("SQ1" , - 1 , 0.5 )
0 commit comments