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: | |
71030195 | 105 | case TYPE_230X: |
9956d428 UB |
106 | fractional_bits |= (calc_index & 0x001) ? 4 : 0; |
107 | break; | |
108 | default:; | |
109 | } | |
93de2301 | 110 | |
ac6944cc | 111 | // Aid debugging since this test is a generic function |
cb2a07f2 TJ |
112 | BOOST_CHECK_MESSAGE(res->actual_baudrate == calc_baudrate && res->divisor == divisor && res->fractional_bits == fractional_bits |
113 | && res->clock == clock, | |
c4517f98 | 114 | "\n\nERROR: baudrate calculation failed for --" << baudrate.first << " baud--. Details below: "); |
ac6944cc TJ |
115 | |
116 | BOOST_CHECK_EQUAL(res->actual_baudrate, calc_baudrate); | |
cb2a07f2 TJ |
117 | BOOST_CHECK_EQUAL(res->divisor, divisor); |
118 | BOOST_CHECK_EQUAL(res->fractional_bits, fractional_bits); | |
119 | BOOST_CHECK_EQUAL(res->clock, clock); | |
ac6944cc TJ |
120 | } |
121 | } | |
122 | ||
123 | BOOST_AUTO_TEST_CASE(TypeAMFixedBaudrates) | |
124 | { | |
125 | ftdi->type = TYPE_AM; | |
126 | ||
127 | map<int, calc_result> baudrates; | |
3c9ef8f8 | 128 | baudrates[183] = calc_result(183, 16383, 0, 48); |
6777cc70 UB |
129 | baudrates[300] = calc_result(300, 10000, 0, 48); |
130 | baudrates[600] = calc_result(600, 5000, 0, 48); | |
131 | baudrates[1200] = calc_result(1200, 2500, 0, 48); | |
132 | baudrates[2400] = calc_result(2400, 1250, 0, 48); | |
cb2a07f2 | 133 | baudrates[4800] = calc_result(4800, 625, 0, 48); |
6777cc70 UB |
134 | baudrates[9600] = calc_result(9600, 312, 1, 48); |
135 | baudrates[19200] = calc_result(19200, 156, 2, 48); | |
136 | baudrates[38400] = calc_result(38400, 78, 3, 48); | |
137 | baudrates[57600] = calc_result(57554, 52, 3, 48); | |
cb2a07f2 TJ |
138 | baudrates[115200] = calc_result(115385, 26, 0, 48); |
139 | baudrates[230400] = calc_result(230769, 13, 0, 48); | |
6777cc70 UB |
140 | baudrates[460800] = calc_result(461538, 6, 1, 48); |
141 | baudrates[921600] = calc_result(923077, 3, 2, 48); | |
142 | baudrates[1000000] = calc_result(1000000, 3, 0, 48); | |
143 | baudrates[1090512] = calc_result(1000000, 3, 0, 48); | |
144 | baudrates[1090909] = calc_result(1000000, 3, 0, 48); | |
3c9ef8f8 | 145 | baudrates[1090910] = calc_result(1000000, 3, 0, 48); |
6777cc70 UB |
146 | baudrates[1200000] = calc_result(1200000, 2, 1, 48); |
147 | baudrates[1333333] = calc_result(1333333, 2, 2, 48); | |
148 | baudrates[1411764] = calc_result(1411765, 2, 3, 48); | |
149 | baudrates[1500000] = calc_result(1500000, 2, 0, 48); | |
3c9ef8f8 | 150 | baudrates[2000000] = calc_result(1500000, 2, 0, 48); |
6777cc70 | 151 | baudrates[3000000] = calc_result(3000000, 0, 0, 48); |
ac6944cc TJ |
152 | |
153 | test_baudrates(ftdi, baudrates); | |
154 | } | |
155 | ||
6645ac5e | 156 | BOOST_AUTO_TEST_CASE(TypeBMFixedBaudrates) |
ac6944cc | 157 | { |
3db4042e TJ |
158 | // Unify testing of chips behaving the same |
159 | std::vector<enum ftdi_chip_type> test_types; | |
160 | test_types.push_back(TYPE_BM); | |
161 | test_types.push_back(TYPE_2232C); | |
162 | test_types.push_back(TYPE_R); | |
71030195 | 163 | test_types.push_back(TYPE_230X); |
ac6944cc TJ |
164 | |
165 | map<int, calc_result> baudrates; | |
6777cc70 | 166 | baudrates[183] = calc_result(183, 16383, 7, 48); |
aae08071 | 167 | baudrates[184] = calc_result(184, 16304, 4, 48); |
6777cc70 UB |
168 | baudrates[300] = calc_result(300, 10000, 0, 48); |
169 | baudrates[600] = calc_result(600, 5000, 0, 48); | |
170 | baudrates[1200] = calc_result(1200, 2500, 0, 48); | |
171 | baudrates[2400] = calc_result(2400, 1250, 0, 48); | |
cb2a07f2 | 172 | baudrates[4800] = calc_result(4800, 625, 0, 48); |
6777cc70 UB |
173 | baudrates[9600] = calc_result(9600, 312, 1, 48); |
174 | baudrates[19200] = calc_result(19200, 156, 2, 48); | |
175 | baudrates[38400] = calc_result(38400, 78, 3, 48); | |
aae08071 UB |
176 | baudrates[57600] = calc_result(57554, 52, 3, 48); |
177 | baudrates[115200] = calc_result(115385, 26, 0, 48); | |
cb2a07f2 | 178 | baudrates[230400] = calc_result(230769, 13, 0, 48); |
6777cc70 | 179 | baudrates[460800] = calc_result(461538, 6, 1, 48); |
aae08071 | 180 | baudrates[921600] = calc_result(923077, 3, 2, 48); |
6777cc70 UB |
181 | baudrates[1000000] = calc_result(1000000, 3, 0, 48); |
182 | baudrates[1050000] = calc_result(1043478, 2, 7, 48); | |
aae08071 | 183 | baudrates[1400000] = calc_result(1411765, 2, 3, 48); |
6777cc70 UB |
184 | baudrates[1500000] = calc_result(1500000, 2, 0, 48); |
185 | baudrates[2000000] = calc_result(2000000, 1, 0, 48); | |
186 | baudrates[3000000] = calc_result(3000000, 0, 0, 48); | |
ac6944cc | 187 | |
0d119163 UB |
188 | baudrates[(3000000*16/(2*16+15))-1] = calc_result(round(3000000/3.000), 3, 0, 48); |
189 | baudrates[ 3000000*16/(2*16+15) ] = calc_result(round(3000000/3.000), 3, 0, 48); | |
190 | baudrates[(3000000*16/(2*16+15))+1] = calc_result(round(3000000/2.875), 2, 7, 48); | |
191 | baudrates[ 3000000*16/(2*16+13) ] = calc_result(round(3000000/2.875), 2, 7, 48); | |
192 | baudrates[(3000000*16/(2*16+13))+1] = calc_result(round(3000000/2.750), 2, 6, 48); | |
193 | baudrates[ 3000000*16/(2*16+11) ] = calc_result(round(3000000/2.750), 2, 6, 48); | |
194 | baudrates[(3000000*16/(2*16+11))+1] = calc_result(round(3000000/2.625), 2, 5, 48); | |
195 | baudrates[ 3000000*16/(2*16+ 9) ] = calc_result(round(3000000/2.625), 2, 5, 48); | |
196 | baudrates[(3000000*16/(2*16+ 9))+1] = calc_result(round(3000000/2.500), 2, 1, 48); | |
197 | baudrates[ 3000000*16/(2*16+ 7) ] = calc_result(round(3000000/2.500), 2, 1, 48); | |
198 | baudrates[(3000000*16/(2*16+ 7))+1] = calc_result(round(3000000/2.375), 2, 4, 48); | |
199 | baudrates[ 3000000*16/(2*16+ 5) ] = calc_result(round(3000000/2.375), 2, 4, 48); | |
200 | baudrates[(3000000*16/(2*16+ 5))+1] = calc_result(round(3000000/2.250), 2, 2, 48); | |
201 | baudrates[ 3000000*16/(2*16+ 3) ] = calc_result(round(3000000/2.250), 2, 2, 48); | |
202 | baudrates[(3000000*16/(2*16+ 3))+1] = calc_result(round(3000000/2.125), 2, 3, 48); | |
203 | baudrates[ 3000000*16/(2*16+ 1) ] = calc_result(round(3000000/2.125), 2, 3, 48); | |
204 | baudrates[(3000000*16/(2*16+ 1))+1] = calc_result(round(3000000/2.000), 2, 0, 48); | |
93de2301 | 205 | |
3db4042e TJ |
206 | BOOST_FOREACH(const enum ftdi_chip_type &test_chip_type, test_types) |
207 | { | |
208 | ftdi->type = test_chip_type; | |
209 | test_baudrates(ftdi, baudrates); | |
210 | } | |
ac6944cc TJ |
211 | } |
212 | ||
6645ac5e | 213 | BOOST_AUTO_TEST_CASE(TypeHFixedBaudrates) |
ac6944cc | 214 | { |
3db4042e TJ |
215 | // Unify testing of chips behaving the same |
216 | std::vector<enum ftdi_chip_type> test_types; | |
217 | test_types.push_back(TYPE_2232H); | |
218 | test_types.push_back(TYPE_4232H); | |
219 | test_types.push_back(TYPE_232H); | |
ac6944cc TJ |
220 | |
221 | map<int, calc_result> baudrates; | |
6777cc70 | 222 | baudrates[183] = calc_result(183, 16383, 7, 48); |
0d119163 | 223 | baudrates[184] = calc_result(184, 16304, 4, 48); |
6777cc70 UB |
224 | baudrates[300] = calc_result(300, 10000, 0, 48); |
225 | baudrates[600] = calc_result(600, 5000, 0, 48); | |
226 | baudrates[1200] = calc_result(1200, 10000, 0, 120); | |
227 | baudrates[2400] = calc_result(2400, 5000, 0, 120); | |
228 | baudrates[4800] = calc_result(4800, 2500, 0, 120); | |
229 | baudrates[9600] = calc_result(9600, 1250, 0, 120); | |
230 | baudrates[19200] = calc_result(19200, 625, 0, 120); | |
231 | baudrates[38400] = calc_result(38400, 312, 1, 120); | |
c4a2bc3a | 232 | baudrates[57600] = calc_result(57588, 208, 4, 120); |
6777cc70 | 233 | baudrates[115200] = calc_result(115246, 104, 3, 120); |
aae08071 | 234 | baudrates[230400] = calc_result(230216, 52, 3, 120); |
6777cc70 | 235 | baudrates[460800] = calc_result(461538, 26, 0, 120); |
aae08071 | 236 | baudrates[921600] = calc_result(923077, 13, 0, 120); |
6777cc70 UB |
237 | baudrates[1000000] = calc_result(1000000, 12, 0, 120); |
238 | baudrates[1000000] = calc_result(1000000, 12, 0, 120); | |
239 | baudrates[6000000] = calc_result(6000000, 2, 0, 120); | |
240 | baudrates[4173913] = calc_result(4173913, 2, 7, 120); | |
241 | baudrates[8000000] = calc_result(8000000, 1, 0, 120); | |
242 | baudrates[12000000] = calc_result(12000000, 0, 0, 120); | |
ac6944cc | 243 | |
0d119163 UB |
244 | baudrates[(12000000*16/(2*16+15))-1] = calc_result(round(12000000/3.000), 3, 0, 120); |
245 | baudrates[ 12000000*16/(2*16+15) ] = calc_result(round(12000000/3.000), 3, 0, 120); | |
246 | baudrates[(12000000*16/(2*16+15))+1] = calc_result(round(12000000/2.875), 2, 7, 120); | |
247 | baudrates[ 12000000*16/(2*16+13) ] = calc_result(round(12000000/2.875), 2, 7, 120); | |
248 | baudrates[(12000000*16/(2*16+13))+1] = calc_result(round(12000000/2.750), 2, 6, 120); | |
249 | baudrates[ 12000000*16/(2*16+11) ] = calc_result(round(12000000/2.750), 2, 6, 120); | |
250 | baudrates[(12000000*16/(2*16+11))+1] = calc_result(round(12000000/2.625), 2, 5, 120); | |
251 | baudrates[ 12000000*16/(2*16+ 9) ] = calc_result(round(12000000/2.625), 2, 5, 120); | |
252 | baudrates[(12000000*16/(2*16+ 9))+1] = calc_result(round(12000000/2.500), 2, 1, 120); | |
253 | baudrates[ 12000000*16/(2*16+ 7) ] = calc_result(round(12000000/2.500), 2, 1, 120); | |
254 | baudrates[(12000000*16/(2*16+ 7))+1] = calc_result(round(12000000/2.375), 2, 4, 120); | |
255 | baudrates[ 12000000*16/(2*16+ 5) ] = calc_result(round(12000000/2.375), 2, 4, 120); | |
256 | baudrates[(12000000*16/(2*16+ 5))+1] = calc_result(round(12000000/2.250), 2, 2, 120); | |
257 | baudrates[ 12000000*16/(2*16+ 3) ] = calc_result(round(12000000/2.250), 2, 2, 120); | |
258 | baudrates[(12000000*16/(2*16+ 3))+1] = calc_result(round(12000000/2.125), 2, 3, 120); | |
259 | baudrates[ 12000000*16/(2*16+ 1) ] = calc_result(round(12000000/2.125), 2, 3, 120); | |
260 | baudrates[(12000000*16/(2*16+ 1))+1] = calc_result(round(12000000/2.000), 2, 0, 120); | |
261 | ||
3db4042e TJ |
262 | BOOST_FOREACH(const enum ftdi_chip_type &test_chip_type, test_types) |
263 | { | |
264 | ftdi->type = test_chip_type; | |
265 | test_baudrates(ftdi, baudrates); | |
266 | } | |
a87a0712 TJ |
267 | } |
268 | ||
269 | BOOST_AUTO_TEST_SUITE_END() |