Commit | Line | Data |
---|---|---|
a87a0712 TJ |
1 | /**@file |
2 | @brief Test baudrate calculator code | |
3 | ||
93de2301 | 4 | @author Thomas Jarosch and Uwe Bonnes |
a87a0712 TJ |
5 | */ |
6 | ||
7 | /*************************************************************************** | |
8 | * * | |
9 | * This program is free software; you can redistribute it and/or modify * | |
10 | * it under the terms of the GNU Lesser General Public License * | |
11 | * version 2.1 as published by the Free Software Foundation; * | |
12 | * * | |
13 | ***************************************************************************/ | |
14 | ||
ac6944cc TJ |
15 | #include <ftdi.h> |
16 | ||
a87a0712 TJ |
17 | #define BOOST_TEST_DYN_LINK |
18 | #include <boost/test/unit_test.hpp> | |
ac6944cc | 19 | #include <boost/foreach.hpp> |
3db4042e | 20 | #include <vector> |
ac6944cc | 21 | #include <map> |
0d119163 | 22 | #include <math.h> |
ac6944cc TJ |
23 | |
24 | using namespace std; | |
25 | ||
26 | extern "C" int convert_baudrate_UT_export(int baudrate, struct ftdi_context *ftdi, | |
27 | unsigned short *value, unsigned short *index); | |
28 | ||
29 | /// Basic initialization of libftdi for every test | |
30 | class BaseFTDIFixture | |
31 | { | |
32 | protected: | |
33 | ftdi_context *ftdi; | |
34 | ||
35 | public: | |
36 | BaseFTDIFixture() | |
37 | : ftdi(NULL) | |
38 | { | |
39 | ftdi = ftdi_new(); | |
40 | } | |
41 | ||
90933196 | 42 | virtual ~BaseFTDIFixture() |
ac6944cc TJ |
43 | { |
44 | delete ftdi; | |
45 | ftdi = NULL; | |
46 | } | |
47 | }; | |
a87a0712 | 48 | |
c4517f98 | 49 | BOOST_FIXTURE_TEST_SUITE(Baudrate, BaseFTDIFixture) |
a87a0712 | 50 | |
ac6944cc TJ |
51 | /// Helper class to store the convert_baudrate_UT_export result |
52 | struct calc_result | |
a87a0712 | 53 | { |
ac6944cc | 54 | int actual_baudrate; |
cb2a07f2 TJ |
55 | unsigned short divisor; |
56 | unsigned short fractional_bits; | |
57 | unsigned short clock; | |
ac6944cc | 58 | |
cb2a07f2 | 59 | calc_result(int actual, unsigned short my_divisor, unsigned short my_fractional_bits, unsigned short my_clock) |
ac6944cc | 60 | : actual_baudrate(actual) |
cb2a07f2 TJ |
61 | , divisor(my_divisor) |
62 | , fractional_bits(my_fractional_bits) | |
63 | , clock(my_clock) | |
ac6944cc TJ |
64 | { |
65 | } | |
66 | ||
67 | calc_result() | |
68 | : actual_baudrate(0) | |
cb2a07f2 TJ |
69 | , divisor(0) |
70 | , fractional_bits(0) | |
71 | , clock(0) | |
ac6944cc TJ |
72 | { |
73 | } | |
74 | }; | |
75 | ||
76 | /** | |
77 | * @brief Test convert_baudrate code against a list of baud rates | |
78 | * | |
79 | * @param baudrates Baudrates to check | |
80 | **/ | |
81 | static void test_baudrates(ftdi_context *ftdi, const map<int, calc_result> &baudrates) | |
82 | { | |
83 | typedef std::pair<int, calc_result> baudrate_type; | |
84 | BOOST_FOREACH(const baudrate_type &baudrate, baudrates) | |
85 | { | |
86 | unsigned short calc_value = 0, calc_index = 0; | |
87 | int calc_baudrate = convert_baudrate_UT_export(baudrate.first, ftdi, &calc_value, &calc_index); | |
88 | ||
89 | const calc_result *res = &baudrate.second; | |
90 | ||
9956d428 UB |
91 | unsigned short divisor = calc_value & 0x3fff; |
92 | unsigned short fractional_bits = (calc_value >> 14); | |
93 | unsigned short clock = (calc_index & 0x200) ? 120 : 48; | |
94 | ||
95 | switch (ftdi->type) | |
96 | { | |
97 | case TYPE_232H: | |
98 | case TYPE_2232H: | |
99 | case TYPE_4232H: | |
100 | fractional_bits |= (calc_index & 0x100) ? 4 : 0; | |
101 | break; | |
102 | case TYPE_R: | |
103 | case TYPE_2232C: | |
104 | case TYPE_BM: | |
105 | fractional_bits |= (calc_index & 0x001) ? 4 : 0; | |
106 | break; | |
107 | default:; | |
108 | } | |
93de2301 | 109 | |
ac6944cc | 110 | // Aid debugging since this test is a generic function |
cb2a07f2 TJ |
111 | BOOST_CHECK_MESSAGE(res->actual_baudrate == calc_baudrate && res->divisor == divisor && res->fractional_bits == fractional_bits |
112 | && res->clock == clock, | |
c4517f98 | 113 | "\n\nERROR: baudrate calculation failed for --" << baudrate.first << " baud--. Details below: "); |
ac6944cc TJ |
114 | |
115 | BOOST_CHECK_EQUAL(res->actual_baudrate, calc_baudrate); | |
cb2a07f2 TJ |
116 | BOOST_CHECK_EQUAL(res->divisor, divisor); |
117 | BOOST_CHECK_EQUAL(res->fractional_bits, fractional_bits); | |
118 | BOOST_CHECK_EQUAL(res->clock, clock); | |
ac6944cc TJ |
119 | } |
120 | } | |
121 | ||
122 | BOOST_AUTO_TEST_CASE(TypeAMFixedBaudrates) | |
123 | { | |
124 | ftdi->type = TYPE_AM; | |
125 | ||
126 | map<int, calc_result> baudrates; | |
3c9ef8f8 | 127 | baudrates[183] = calc_result(183, 16383, 0, 48); |
6777cc70 UB |
128 | baudrates[300] = calc_result(300, 10000, 0, 48); |
129 | baudrates[600] = calc_result(600, 5000, 0, 48); | |
130 | baudrates[1200] = calc_result(1200, 2500, 0, 48); | |
131 | baudrates[2400] = calc_result(2400, 1250, 0, 48); | |
cb2a07f2 | 132 | baudrates[4800] = calc_result(4800, 625, 0, 48); |
6777cc70 UB |
133 | baudrates[9600] = calc_result(9600, 312, 1, 48); |
134 | baudrates[19200] = calc_result(19200, 156, 2, 48); | |
135 | baudrates[38400] = calc_result(38400, 78, 3, 48); | |
136 | baudrates[57600] = calc_result(57554, 52, 3, 48); | |
cb2a07f2 TJ |
137 | baudrates[115200] = calc_result(115385, 26, 0, 48); |
138 | baudrates[230400] = calc_result(230769, 13, 0, 48); | |
6777cc70 UB |
139 | baudrates[460800] = calc_result(461538, 6, 1, 48); |
140 | baudrates[921600] = calc_result(923077, 3, 2, 48); | |
141 | baudrates[1000000] = calc_result(1000000, 3, 0, 48); | |
142 | baudrates[1090512] = calc_result(1000000, 3, 0, 48); | |
143 | baudrates[1090909] = calc_result(1000000, 3, 0, 48); | |
3c9ef8f8 | 144 | baudrates[1090910] = calc_result(1000000, 3, 0, 48); |
6777cc70 UB |
145 | baudrates[1200000] = calc_result(1200000, 2, 1, 48); |
146 | baudrates[1333333] = calc_result(1333333, 2, 2, 48); | |
147 | baudrates[1411764] = calc_result(1411765, 2, 3, 48); | |
148 | baudrates[1500000] = calc_result(1500000, 2, 0, 48); | |
3c9ef8f8 | 149 | baudrates[2000000] = calc_result(1500000, 2, 0, 48); |
6777cc70 | 150 | baudrates[3000000] = calc_result(3000000, 0, 0, 48); |
ac6944cc TJ |
151 | |
152 | test_baudrates(ftdi, baudrates); | |
153 | } | |
154 | ||
6645ac5e | 155 | BOOST_AUTO_TEST_CASE(TypeBMFixedBaudrates) |
ac6944cc | 156 | { |
3db4042e TJ |
157 | // Unify testing of chips behaving the same |
158 | std::vector<enum ftdi_chip_type> test_types; | |
159 | test_types.push_back(TYPE_BM); | |
160 | test_types.push_back(TYPE_2232C); | |
161 | test_types.push_back(TYPE_R); | |
ac6944cc TJ |
162 | |
163 | map<int, calc_result> baudrates; | |
6777cc70 | 164 | baudrates[183] = calc_result(183, 16383, 7, 48); |
aae08071 | 165 | baudrates[184] = calc_result(184, 16304, 4, 48); |
6777cc70 UB |
166 | baudrates[300] = calc_result(300, 10000, 0, 48); |
167 | baudrates[600] = calc_result(600, 5000, 0, 48); | |
168 | baudrates[1200] = calc_result(1200, 2500, 0, 48); | |
169 | baudrates[2400] = calc_result(2400, 1250, 0, 48); | |
cb2a07f2 | 170 | baudrates[4800] = calc_result(4800, 625, 0, 48); |
6777cc70 UB |
171 | baudrates[9600] = calc_result(9600, 312, 1, 48); |
172 | baudrates[19200] = calc_result(19200, 156, 2, 48); | |
173 | baudrates[38400] = calc_result(38400, 78, 3, 48); | |
aae08071 UB |
174 | baudrates[57600] = calc_result(57554, 52, 3, 48); |
175 | baudrates[115200] = calc_result(115385, 26, 0, 48); | |
cb2a07f2 | 176 | baudrates[230400] = calc_result(230769, 13, 0, 48); |
6777cc70 | 177 | baudrates[460800] = calc_result(461538, 6, 1, 48); |
aae08071 | 178 | baudrates[921600] = calc_result(923077, 3, 2, 48); |
6777cc70 UB |
179 | baudrates[1000000] = calc_result(1000000, 3, 0, 48); |
180 | baudrates[1050000] = calc_result(1043478, 2, 7, 48); | |
aae08071 | 181 | baudrates[1400000] = calc_result(1411765, 2, 3, 48); |
6777cc70 UB |
182 | baudrates[1500000] = calc_result(1500000, 2, 0, 48); |
183 | baudrates[2000000] = calc_result(2000000, 1, 0, 48); | |
184 | baudrates[3000000] = calc_result(3000000, 0, 0, 48); | |
ac6944cc | 185 | |
0d119163 UB |
186 | baudrates[(3000000*16/(2*16+15))-1] = calc_result(round(3000000/3.000), 3, 0, 48); |
187 | baudrates[ 3000000*16/(2*16+15) ] = calc_result(round(3000000/3.000), 3, 0, 48); | |
188 | baudrates[(3000000*16/(2*16+15))+1] = calc_result(round(3000000/2.875), 2, 7, 48); | |
189 | baudrates[ 3000000*16/(2*16+13) ] = calc_result(round(3000000/2.875), 2, 7, 48); | |
190 | baudrates[(3000000*16/(2*16+13))+1] = calc_result(round(3000000/2.750), 2, 6, 48); | |
191 | baudrates[ 3000000*16/(2*16+11) ] = calc_result(round(3000000/2.750), 2, 6, 48); | |
192 | baudrates[(3000000*16/(2*16+11))+1] = calc_result(round(3000000/2.625), 2, 5, 48); | |
193 | baudrates[ 3000000*16/(2*16+ 9) ] = calc_result(round(3000000/2.625), 2, 5, 48); | |
194 | baudrates[(3000000*16/(2*16+ 9))+1] = calc_result(round(3000000/2.500), 2, 1, 48); | |
195 | baudrates[ 3000000*16/(2*16+ 7) ] = calc_result(round(3000000/2.500), 2, 1, 48); | |
196 | baudrates[(3000000*16/(2*16+ 7))+1] = calc_result(round(3000000/2.375), 2, 4, 48); | |
197 | baudrates[ 3000000*16/(2*16+ 5) ] = calc_result(round(3000000/2.375), 2, 4, 48); | |
198 | baudrates[(3000000*16/(2*16+ 5))+1] = calc_result(round(3000000/2.250), 2, 2, 48); | |
199 | baudrates[ 3000000*16/(2*16+ 3) ] = calc_result(round(3000000/2.250), 2, 2, 48); | |
200 | baudrates[(3000000*16/(2*16+ 3))+1] = calc_result(round(3000000/2.125), 2, 3, 48); | |
201 | baudrates[ 3000000*16/(2*16+ 1) ] = calc_result(round(3000000/2.125), 2, 3, 48); | |
202 | baudrates[(3000000*16/(2*16+ 1))+1] = calc_result(round(3000000/2.000), 2, 0, 48); | |
93de2301 | 203 | |
3db4042e TJ |
204 | BOOST_FOREACH(const enum ftdi_chip_type &test_chip_type, test_types) |
205 | { | |
206 | ftdi->type = test_chip_type; | |
207 | test_baudrates(ftdi, baudrates); | |
208 | } | |
ac6944cc TJ |
209 | } |
210 | ||
6645ac5e | 211 | BOOST_AUTO_TEST_CASE(TypeHFixedBaudrates) |
ac6944cc | 212 | { |
3db4042e TJ |
213 | // Unify testing of chips behaving the same |
214 | std::vector<enum ftdi_chip_type> test_types; | |
215 | test_types.push_back(TYPE_2232H); | |
216 | test_types.push_back(TYPE_4232H); | |
217 | test_types.push_back(TYPE_232H); | |
ac6944cc TJ |
218 | |
219 | map<int, calc_result> baudrates; | |
6777cc70 | 220 | baudrates[183] = calc_result(183, 16383, 7, 48); |
0d119163 | 221 | baudrates[184] = calc_result(184, 16304, 4, 48); |
6777cc70 UB |
222 | baudrates[300] = calc_result(300, 10000, 0, 48); |
223 | baudrates[600] = calc_result(600, 5000, 0, 48); | |
224 | baudrates[1200] = calc_result(1200, 10000, 0, 120); | |
225 | baudrates[2400] = calc_result(2400, 5000, 0, 120); | |
226 | baudrates[4800] = calc_result(4800, 2500, 0, 120); | |
227 | baudrates[9600] = calc_result(9600, 1250, 0, 120); | |
228 | baudrates[19200] = calc_result(19200, 625, 0, 120); | |
229 | baudrates[38400] = calc_result(38400, 312, 1, 120); | |
c4a2bc3a | 230 | baudrates[57600] = calc_result(57588, 208, 4, 120); |
6777cc70 | 231 | baudrates[115200] = calc_result(115246, 104, 3, 120); |
aae08071 | 232 | baudrates[230400] = calc_result(230216, 52, 3, 120); |
6777cc70 | 233 | baudrates[460800] = calc_result(461538, 26, 0, 120); |
aae08071 | 234 | baudrates[921600] = calc_result(923077, 13, 0, 120); |
6777cc70 UB |
235 | baudrates[1000000] = calc_result(1000000, 12, 0, 120); |
236 | baudrates[1000000] = calc_result(1000000, 12, 0, 120); | |
237 | baudrates[6000000] = calc_result(6000000, 2, 0, 120); | |
238 | baudrates[4173913] = calc_result(4173913, 2, 7, 120); | |
239 | baudrates[8000000] = calc_result(8000000, 1, 0, 120); | |
240 | baudrates[12000000] = calc_result(12000000, 0, 0, 120); | |
ac6944cc | 241 | |
0d119163 UB |
242 | baudrates[(12000000*16/(2*16+15))-1] = calc_result(round(12000000/3.000), 3, 0, 120); |
243 | baudrates[ 12000000*16/(2*16+15) ] = calc_result(round(12000000/3.000), 3, 0, 120); | |
244 | baudrates[(12000000*16/(2*16+15))+1] = calc_result(round(12000000/2.875), 2, 7, 120); | |
245 | baudrates[ 12000000*16/(2*16+13) ] = calc_result(round(12000000/2.875), 2, 7, 120); | |
246 | baudrates[(12000000*16/(2*16+13))+1] = calc_result(round(12000000/2.750), 2, 6, 120); | |
247 | baudrates[ 12000000*16/(2*16+11) ] = calc_result(round(12000000/2.750), 2, 6, 120); | |
248 | baudrates[(12000000*16/(2*16+11))+1] = calc_result(round(12000000/2.625), 2, 5, 120); | |
249 | baudrates[ 12000000*16/(2*16+ 9) ] = calc_result(round(12000000/2.625), 2, 5, 120); | |
250 | baudrates[(12000000*16/(2*16+ 9))+1] = calc_result(round(12000000/2.500), 2, 1, 120); | |
251 | baudrates[ 12000000*16/(2*16+ 7) ] = calc_result(round(12000000/2.500), 2, 1, 120); | |
252 | baudrates[(12000000*16/(2*16+ 7))+1] = calc_result(round(12000000/2.375), 2, 4, 120); | |
253 | baudrates[ 12000000*16/(2*16+ 5) ] = calc_result(round(12000000/2.375), 2, 4, 120); | |
254 | baudrates[(12000000*16/(2*16+ 5))+1] = calc_result(round(12000000/2.250), 2, 2, 120); | |
255 | baudrates[ 12000000*16/(2*16+ 3) ] = calc_result(round(12000000/2.250), 2, 2, 120); | |
256 | baudrates[(12000000*16/(2*16+ 3))+1] = calc_result(round(12000000/2.125), 2, 3, 120); | |
257 | baudrates[ 12000000*16/(2*16+ 1) ] = calc_result(round(12000000/2.125), 2, 3, 120); | |
258 | baudrates[(12000000*16/(2*16+ 1))+1] = calc_result(round(12000000/2.000), 2, 0, 120); | |
259 | ||
3db4042e TJ |
260 | BOOST_FOREACH(const enum ftdi_chip_type &test_chip_type, test_types) |
261 | { | |
262 | ftdi->type = test_chip_type; | |
263 | test_baudrates(ftdi, baudrates); | |
264 | } | |
a87a0712 TJ |
265 | } |
266 | ||
267 | BOOST_AUTO_TEST_SUITE_END() |