88import pytest
99
1010hardware = ["adsy1100" ]
11- uri = "ip:10.44.3.116"
12-
13- n = 5
14- m = 4
11+ uri = "ip:10.44.3.121"
12+
13+ RATIOS = [
14+ (2000 , 1010 ),
15+ (2000 , 1100 ),
16+ (2000 , 1200 ),
17+ (2000 , 1300 ),
18+ (2000 , 1400 ),
19+ (2000 , 1500 ),
20+ (2000 , 1600 ),
21+ (2000 , 1700 ),
22+ (2000 , 1800 ),
23+ (2000 , 1900 ),
24+ (2000 , 1990 ),
25+ (1562 , 1228 ),
26+ ]
1527
1628@pytest .mark .iio_hardware (hardware )
1729def test_ad9084_rx_capture ():
18- os .makedirs ("sample_rx_capture" , exist_ok = True )
30+ """
31+ Test FSRC invalid (-FS) sample insertion.
32+ Quantifies amount of -FS samples. Does not assert the distribution.
33+ """
34+ os .makedirs ("sample" , exist_ok = True )
1935
2036 ctx = iio .Context (uri )
2137 rx_dev = ctx .find_device ("axi-ad9084-rx-hpc" )
2238 fsrc_dev = ctx .find_device ("axi_fsrc" )
39+ fsrc_ch = fsrc_dev .find_channel ("altvoltage0" , True )
2340
2441 for i in range (4 ):
2542 ch = rx_dev .find_channel (f"voltage{ i } _i" )
@@ -29,7 +46,6 @@ def test_ad9084_rx_capture():
2946 ratio_results = []
3047
3148 mask = iio .ChannelsMask (rx_dev )
32- # Enable all channels, some are not yet considered supported.
3349 mask .channels = [
3450 rx_dev .find_channel ("voltage0_i" ),
3551 rx_dev .find_channel ("voltage0_q" ),
@@ -43,58 +59,78 @@ def test_ad9084_rx_capture():
4359 buf = iio .Buffer (rx_dev , mask )
4460 stream = iio .Stream (buffer = buf , nb_blocks = 1 , samples_count = 1024 )
4561
46- fsrc_ch = fsrc_dev .find_channel ("altvoltage0" , True )
47-
48- rx_dev .debug_attrs ['fsrc_configure_rx' ].value = f"{ n } { m } "
49- rx_dev .debug_attrs ['fsrc_configure_tx' ].value = f"{ n } { m } "
50- rx_dev .debug_attrs ['fsrc_rx_reconfig_spi' ].value = "1"
51- rx_dev .debug_attrs ['fsrc_tx_reconfig_spi' ].value = "1"
52-
53- for rx_state in [1 , 0 ]:
54- fsrc_ch .attrs ["rx_enable" ].value = str (rx_state )
55- rx_state_str = "rx_on" if rx_state == 1 else "rx_off"
56-
57- for r in range (0 , 4 ):
58- block = next (stream )
59- i_data = mask .channels [0 ].read (block )
60- q_data = mask .channels [1 ].read (block )
61-
62- i_samples = np .frombuffer (i_data , dtype = "i2" )
63- q_samples = np .frombuffer (q_data , dtype = "i2" )
64-
65- data = bytearray ()
66- for i , q in zip (i_samples , q_samples ):
67- data .extend (struct .pack ("<h" , i ))
68- data .extend (struct .pack ("<h" , q ))
69-
70- output_file = f"sample_rx_capture/sample_{ n } _{ m } _{ rx_state_str } .dat"
71- with open (output_file , "wb" ) as f :
72- f .write (data )
73-
74- gnuplot = shutil .which ("gnuplot" )
75- if gnuplot :
76- svg_file = f"sample_rx_capture/sample_{ n } _{ m } _{ rx_state_str } .svg"
77- plot_title = f"N={ n } M={ m } ({ rx_state_str } )"
78- gnuplot_cmd = (
79- f"set terminal svg size 1400,1300; "
80- f"set output '{ svg_file } '; "
81- f"plot '{ output_file } ' binary format='%short%short' using 1 with dots title 'I { plot_title } ', "
82- f"'{ output_file } ' binary format='%short%short' using 2 with dots title 'Q { plot_title } '"
83- )
84- subprocess .run ([gnuplot , "-e" , gnuplot_cmd ], check = False )
85-
86- else :
87- print ("gnuplot not found, svg skipped" )
88-
89- valid = sum (1 for s in i_samples if s != - 32768 ) # 0x8000
90- invalid = sum (1 for s in i_samples if s == - 32768 )
91- ratio_exp = n / m
92- ratio_pra = (valid + invalid ) / (valid )
93- result = f"ratio { n } { m } : { ratio_exp :.6f} { ratio_pra :.6f} (invalid,valid) : ({ invalid } ,{ valid } )"
94- print (result )
95-
96- ratio_file = "sample_rx_capture/sample_ratio.txt"
62+ ratio_exp = []
63+ ratio_pra = []
64+
65+ for n , m in RATIOS :
66+ rx_dev .debug_attrs ['fsrc_configure_rx' ].value = f"{ n } { m } "
67+ rx_dev .debug_attrs ['fsrc_rx_reconfig_spi' ].value = "1"
68+
69+ for rx_state in [1 , 0 ]:
70+ fsrc_ch .attrs ["rx_enable" ].value = str (rx_state )
71+ rx_state_str = "rx_on" if rx_state == 1 else "rx_off"
72+
73+ # Flush stale blocks
74+ for _ in range (4 ):
75+ block = next (stream )
76+
77+ # Read voltage0-3 I/Q
78+ channel_data = []
79+ for ch_idx in range (8 ):
80+ raw_data = mask .channels [ch_idx ].read (block )
81+ samples = np .frombuffer (raw_data , dtype = "i2" )
82+ channel_data .append (samples )
83+
84+ # Interleave all channels [v0_i, v0_q, v1_i, v1_q, v2_i, v2_q, v3_i, v3_q, ...]
85+ data = bytearray ()
86+ for sample_idx in range (len (channel_data [0 ])):
87+ for ch_idx in range (8 ):
88+ data .extend (struct .pack ("<h" , channel_data [ch_idx ][sample_idx ]))
89+
90+ output_file = f"sample/sample_{ n } _{ m } _{ rx_state_str } .dat"
91+ with open (output_file , "wb" ) as f :
92+ f .write (data )
93+
94+ gnuplot = shutil .which ("gnuplot" )
95+ if gnuplot :
96+ svg_file = f"sample/sample_{ n } _{ m } _{ rx_state_str } .svg"
97+ plot_title = f"N={ n } M={ m } ({ rx_state_str } )"
98+ # plot voltage{_ch}
99+ _ch = 0
100+ gnuplot_cmd = (
101+ f"set terminal svg size 1400,1300; "
102+ f"set output '{ svg_file } '; "
103+ f"plot '{ output_file } ' binary format='%short%short%short%short%short%short%short%short' using { _ch * 2 + 1 } with dots title 'v{ _ch } _i { plot_title } ', "
104+ f" '{ output_file } ' binary format='%short%short%short%short%short%short%short%short' using { _ch * 2 + 2 } with dots title 'v{ _ch } _q { plot_title } '"
105+ )
106+ subprocess .run ([gnuplot , "-e" , gnuplot_cmd ], check = False )
107+
108+ else :
109+ print ("gnuplot not found, svg skipped" )
110+
111+ # Analyze all 4 channels (I samples from voltage0-3)
112+ channel_stats = []
113+ for ch in range (4 ):
114+ i_samples = channel_data [ch * 2 ] # I channel: 0, 2, 4, 6
115+ valid = sum (1 for s in i_samples if s != - 32768 )
116+ invalid = sum (1 for s in i_samples if s == - 32768 )
117+ ch_ratio = (valid + invalid ) / valid if valid > 0 else float ('inf' )
118+ channel_stats .append ((invalid , valid , ch_ratio ))
119+ print (f" CH{ ch } : invalid={ invalid :4d} , valid={ valid :4d} , ratio={ ch_ratio :.6f} " )
120+
121+ # Use voltage0 as representative for final assertion
122+ invalid , valid , ch_ratio = channel_stats [0 ]
123+ ratio_exp .append (n / m )
124+ ratio_pra .append (ch_ratio )
125+ result = f"ratio { n } { m } : { ratio_exp [- 1 ]:.6f} { ratio_pra [- 1 ]:.6f} (invalid,valid) : ({ invalid } ,{ valid } )"
126+ ratio_results .append (result )
127+ print (result )
128+
129+ for i in range (0 , len (ratio_exp )):
130+ assert abs (ratio_exp [i ] - ratio_pra [i ]) < 0.05 , "ratios are too distant!"
131+
132+ ratio_file = "sample/sample_ratios.txt"
97133 with open (ratio_file , "w" ) as f :
98- f .write (result + "\n " )
134+ f .write (" \n " . join ( ratio_results ) + "\n " )
99135
100- assert abs ( ratio_exp - ratio_pra ) < 0.05 , "ratios are too distant!"
136+ assert len ( ratio_results ) == len ( RATIOS )
0 commit comments