9void figure_out_approximation(uint64_t numerator, uint64_t denominator)
11 printf(
" ideal: x * %llu / %llu\n", numerator, denominator);
12 assert(numerator < INT_MAX);
13 assert(denominator < INT_MAX);
15 int input_min = -0x8000;
16 int input_max = 0xFFFF;
17 uint32_t p_max = 0x7FFF;
20 double k = (double)numerator / denominator;
23 for (uint8_t shift_candidate = 0; shift_candidate < 32; shift_candidate++)
25 uint32_t p_candidate = round(k * (1 << shift_candidate));
26 if (p_candidate > p_max) {
break; }
28 shift = shift_candidate;
39 double worst_error_percent = 0;
40 for (
int i = input_min; i <= input_max; i++)
42 int ideal = i * (int64_t)numerator / (
int)denominator;
43 int approximate = ((int32_t)i * p) >> shift;
44 int this_error = ideal - approximate;
45 if (abs(this_error) > abs(worst_error))
47 worst_error = this_error;
48 worst_error_percent = 100 * this_error / ideal;
52 printf(
" approx: x * %d >> %u", p, shift);
55 printf(
" (no error)\n");
59 printf(
" (worst error is %d (%.2lf%%) at x=%d)\n", worst_error, worst_error_percent, worst_i);
63void calculate_params(uint8_t isense_range, uint32_t riso, uint32_t rsense)
65 printf(
"Board: riso = %u ohm, isense_range = %u A, rsense = %u ohm\n",
66 riso, isense_range, rsense);
68 printf(
" vcodes to mA:\n");
69 figure_out_approximation((riso + rsense) * 250, 27500 * rsense);
71 printf(
" icodes to mA:\n");
72 figure_out_approximation(1000 * isense_range, 27500);
74 printf(
" pinstant to mW:\n");
75 figure_out_approximation(isense_range * (riso + rsense) * 5, (rsense * 462));
83 calculate_params(30, 4000000, 1000);
84 calculate_params(30, 4000000, 2000);
85 calculate_params(30, 4000000, 4000);