Skip to content

Commit c42493f

Browse files
committed
projects: eval-powrms: extend precision calibration for reverse signal
For reverse signals a similar, 7 point Lagrange interpolatio is used for calibration Signed-off-by: rbudai98 <[email protected]>
1 parent 3139b9a commit c42493f

File tree

6 files changed

+568
-3
lines changed

6 files changed

+568
-3
lines changed

projects/eval-powrms/src/examples/example/iio_powrms.c

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ static int read_calib_freq_range(void *device, char *buf, uint32_t len,
9494
const struct iio_ch_info *channel, intptr_t priv);
9595
static int write_calib_freq_range(void *device, char *buf, uint32_t len,
9696
const struct iio_ch_info *channel, intptr_t priv);
97+
static int read_calib_freq_range_reverse(void *device, char *buf, uint32_t len,
98+
const struct iio_ch_info *channel, intptr_t priv);
99+
static int write_calib_freq_range_reverse(void *device, char *buf, uint32_t len,
100+
const struct iio_ch_info *channel, intptr_t priv);
97101
static int read_temp_freq_range(void *device, char *buf, uint32_t len,
98102
const struct iio_ch_info *channel, intptr_t priv);
99103
static int write_temp_freq_range(void *device, char *buf, uint32_t len,
@@ -201,6 +205,55 @@ struct iio_attribute powrms_precision_attributes[] = {
201205
.store = write_calib_freq_range,
202206
.priv = MAX_FREQ_RANGE_INDEX, // frequency index 7
203207
},
208+
// New per-frequency range attributes for reverse correction values
209+
{
210+
.name = "calib_10MHz_values_reverse",
211+
.show = read_calib_freq_range_reverse,
212+
.store = write_calib_freq_range_reverse,
213+
.priv = MIN_FREQ_RANGE_INDEX, // frequency index 0
214+
},
215+
{
216+
.name = "calib_100MHz_values_reverse",
217+
.show = read_calib_freq_range_reverse,
218+
.store = write_calib_freq_range_reverse,
219+
.priv = MIN_FREQ_RANGE_INDEX + 1, // frequency index 1
220+
},
221+
{
222+
.name = "calib_1000MHz_values_reverse",
223+
.show = read_calib_freq_range_reverse,
224+
.store = write_calib_freq_range_reverse,
225+
.priv = MIN_FREQ_RANGE_INDEX + 2, // frequency index 2
226+
},
227+
{
228+
.name = "calib_2000MHz_values_reverse",
229+
.show = read_calib_freq_range_reverse,
230+
.store = write_calib_freq_range_reverse,
231+
.priv = MIN_FREQ_RANGE_INDEX + 3, // frequency index 3
232+
},
233+
{
234+
.name = "calib_3000MHz_values_reverse",
235+
.show = read_calib_freq_range_reverse,
236+
.store = write_calib_freq_range_reverse,
237+
.priv = MIN_FREQ_RANGE_INDEX + 4, // frequency index 4
238+
},
239+
{
240+
.name = "calib_4000MHz_values_reverse",
241+
.show = read_calib_freq_range_reverse,
242+
.store = write_calib_freq_range_reverse,
243+
.priv = MIN_FREQ_RANGE_INDEX + 5, // frequency index 5
244+
},
245+
{
246+
.name = "calib_5000MHz_values_reverse",
247+
.show = read_calib_freq_range_reverse,
248+
.store = write_calib_freq_range_reverse,
249+
.priv = MIN_FREQ_RANGE_INDEX + 6, // frequency index 6
250+
},
251+
{
252+
.name = "calib_6000MHz_values_reverse",
253+
.show = read_calib_freq_range_reverse,
254+
.store = write_calib_freq_range_reverse,
255+
.priv = MAX_FREQ_RANGE_INDEX, // frequency index 7
256+
},
204257
// New per-frequency range attributes for temperature calibration values
205258
{
206259
.name = "calib_temp_10MHz_values",
@@ -600,6 +653,86 @@ static int write_calib_freq_range(void *device, char *buf, uint32_t len,
600653
return len;
601654
}
602655

656+
static int read_calib_freq_range_reverse(void *device, char *buf, uint32_t len,
657+
const struct iio_ch_info *channel, intptr_t priv)
658+
{
659+
int freq_index = (int)priv; // frequency range index (0-7)
660+
int written = 0;
661+
int remaining = len;
662+
int start_idx = freq_index *
663+
FREQ_RANGE_VALUES_PER_RANGE; // Starting index for this frequency range
664+
665+
// Write 14 values for this frequency range as comma-separated list
666+
for (int i = 0; i < FREQ_RANGE_VALUES_PER_RANGE
667+
&& remaining > MIN_REMAINING_BUFFER_SIZE; i++) {
668+
float float_value = (float)precision_values_reverse[start_idx + i] *
669+
PRECISION_RESOLUTION;
670+
int bytes = snprintf(buf + written, remaining, "%.7f", float_value);
671+
672+
if (bytes < 0 || bytes >= remaining)
673+
break;
674+
675+
written += bytes;
676+
remaining -= bytes;
677+
678+
// Add comma separator except for last element
679+
if (i < FREQ_RANGE_VALUES_PER_RANGE - 1 && remaining > MIN_COMMA_BUFFER_SIZE) {
680+
buf[written++] = ',';
681+
remaining--;
682+
}
683+
}
684+
685+
return written;
686+
}
687+
688+
static int write_calib_freq_range_reverse(void *device, char *buf, uint32_t len,
689+
const struct iio_ch_info *channel, intptr_t priv)
690+
{
691+
int freq_index = (int)priv; // frequency range index (0-7)
692+
char *token;
693+
char *saveptr;
694+
char buf_copy[CALIB_VALUES_BUFFER_SIZE]; // Buffer for 14 values
695+
int index = 0;
696+
int start_idx = freq_index * FREQ_RANGE_VALUES_PER_RANGE;
697+
int ret;
698+
699+
if (len >= CALIB_VALUES_BUFFER_SIZE) {
700+
return -EINVAL;
701+
}
702+
703+
// Create a copy of the buffer for tokenization
704+
strncpy(buf_copy, buf, len);
705+
buf_copy[len] = '\0';
706+
707+
// Parse comma-separated values
708+
token = strtok_r(buf_copy, ",", &saveptr);
709+
while (token != NULL && index < FREQ_RANGE_VALUES_PER_RANGE) {
710+
float float_value;
711+
if (sscanf(token, "%f", &float_value) == 1) {
712+
// Convert float to integer and store
713+
precision_values_reverse[start_idx + index] = (int32_t)(float_value *
714+
PRECISION_SCALE_FACTOR);
715+
index++;
716+
} else {
717+
return -EINVAL;
718+
}
719+
token = strtok_r(NULL, ",", &saveptr);
720+
}
721+
722+
if (index != FREQ_RANGE_VALUES_PER_RANGE) {
723+
return -EINVAL; // Expected exactly 14 values
724+
}
725+
726+
// Save to EEPROM (write the entire array since EEPROM functions work with full array)
727+
ret = powrms_eeprom_write_precision_array_reverse(precision_values_reverse);
728+
if (ret != IIO_SUCCESS) {
729+
// EEPROM write failed - values are still updated in RAM, so continue
730+
// This allows the system to function even without EEPROM persistence
731+
}
732+
733+
return len;
734+
}
735+
603736
static int read_temp_freq_range(void *device, char *buf, uint32_t len,
604737
const struct iio_ch_info *channel, intptr_t priv)
605738
{
@@ -864,6 +997,90 @@ int powrms_get_precision_array_raw(int32_t *raw_values, int max_count)
864997
return count;
865998
}
866999

1000+
// Reverse precision array utility functions for external access
1001+
int powrms_set_precision_value_reverse(int index, float value)
1002+
{
1003+
if (index < 0 || index >= PRECISION_ARRAY_SIZE)
1004+
return -EINVAL;
1005+
// Convert float to integer for internal storage
1006+
precision_values_reverse[index] = (int32_t)(value * PRECISION_SCALE_FACTOR);
1007+
return 0;
1008+
}
1009+
1010+
float powrms_get_precision_value_reverse(int index)
1011+
{
1012+
if (index < 0 || index >= PRECISION_ARRAY_SIZE)
1013+
return 0.0f;
1014+
// Convert integer to float for external use
1015+
return (float)precision_values_reverse[index] * PRECISION_RESOLUTION;
1016+
}
1017+
1018+
int powrms_set_precision_array_reverse(const float *values, int count)
1019+
{
1020+
if (!values || count > PRECISION_ARRAY_SIZE)
1021+
return -EINVAL;
1022+
1023+
for (int i = 0; i < count; i++) {
1024+
// Convert float to integer for internal storage
1025+
precision_values_reverse[i] = (int32_t)(values[i] * PRECISION_SCALE_FACTOR);
1026+
}
1027+
return 0;
1028+
}
1029+
1030+
int powrms_get_precision_array_reverse(float *values, int max_count)
1031+
{
1032+
if (!values)
1033+
return -EINVAL;
1034+
1035+
int count = (max_count < PRECISION_ARRAY_SIZE) ? max_count :
1036+
PRECISION_ARRAY_SIZE;
1037+
for (int i = 0; i < count; i++) {
1038+
// Convert integer to float for external use
1039+
values[i] = (float)precision_values_reverse[i] * PRECISION_RESOLUTION;
1040+
}
1041+
return count;
1042+
}
1043+
1044+
// Direct integer access functions for MCU internal use (no conversion overhead) - reverse
1045+
int powrms_set_precision_value_raw_reverse(int index, int32_t raw_value)
1046+
{
1047+
if (index < 0 || index >= PRECISION_ARRAY_SIZE)
1048+
return -EINVAL;
1049+
precision_values_reverse[index] = raw_value;
1050+
return 0;
1051+
}
1052+
1053+
int32_t powrms_get_precision_value_raw_reverse(int index)
1054+
{
1055+
if (index < 0 || index >= PRECISION_ARRAY_SIZE)
1056+
return 0;
1057+
return precision_values_reverse[index];
1058+
}
1059+
1060+
int powrms_set_precision_array_raw_reverse(const int32_t *raw_values, int count)
1061+
{
1062+
if (!raw_values || count > PRECISION_ARRAY_SIZE)
1063+
return -EINVAL;
1064+
1065+
for (int i = 0; i < count; i++) {
1066+
precision_values_reverse[i] = raw_values[i];
1067+
}
1068+
return 0;
1069+
}
1070+
1071+
int powrms_get_precision_array_raw_reverse(int32_t *raw_values, int max_count)
1072+
{
1073+
if (!raw_values)
1074+
return -EINVAL;
1075+
1076+
int count = (max_count < PRECISION_ARRAY_SIZE) ? max_count :
1077+
PRECISION_ARRAY_SIZE;
1078+
for (int i = 0; i < count; i++) {
1079+
raw_values[i] = precision_values_reverse[i];
1080+
}
1081+
return count;
1082+
}
1083+
8671084
// Frequency ranges utility functions for external access
8681085
int powrms_set_frequency_range(int index, uint32_t frequency_MHz)
8691086
{
@@ -1040,6 +1257,10 @@ static int write_dev_mode_overwrite_def_calib_values(void *device, char *buf,
10401257
if (ret != IIO_SUCCESS) {
10411258
return len;
10421259
}
1260+
ret = powrms_eeprom_write_def_precision_array_reverse(precision_values_reverse);
1261+
if (ret != IIO_SUCCESS) {
1262+
return len;
1263+
}
10431264
ret = powrms_eeprom_write_def_temp_corr_array(temperature_precision_values);
10441265
if (ret != IIO_SUCCESS) {
10451266
return len;

projects/eval-powrms/src/examples/example/iio_powrms.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,19 @@ int32_t powrms_get_precision_value_raw(int index);
133133
int powrms_set_precision_array_raw(const int32_t *raw_values, int count);
134134
int powrms_get_precision_array_raw(int32_t *raw_values, int max_count);
135135

136+
// Reverse precision array functions (float interface - with conversion)
137+
int powrms_set_precision_value_reverse(int index, float value);
138+
float powrms_get_precision_value_reverse(int index);
139+
int powrms_set_precision_array_reverse(const float *values, int count);
140+
int powrms_get_precision_array_reverse(float *values, int max_count);
141+
142+
// Reverse precision array functions (integer interface - no conversion, for MCU internal use)
143+
int powrms_set_precision_value_raw_reverse(int index, int32_t raw_value);
144+
int32_t powrms_get_precision_value_raw_reverse(int index);
145+
int powrms_set_precision_array_raw_reverse(const int32_t *raw_values,
146+
int count);
147+
int powrms_get_precision_array_raw_reverse(int32_t *raw_values, int max_count);
148+
136149
// Frequency ranges functions
137150
int powrms_set_frequency_range(int index, uint32_t frequency_MHz);
138151
uint32_t powrms_get_frequency_range(int index);

projects/eval-powrms/src/examples/example/powrms_data_processing.c

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ struct powrms_variables input_variables[VARIABLE_NUMBER] = {
9393
// Storage for the 112 precision values as 32-bit integers
9494
// Order 10MHz: X1, Y1, X2, Y2, X3, Y3 , X4, Y4, X5, Y5, X6, Y6, X7, Y7, 100MHz:...
9595
int32_t precision_values[PRECISION_ARRAY_SIZE];
96+
int32_t precision_values_reverse[PRECISION_ARRAY_SIZE];
9697

9798
// Storage for the 24 temperature correction coefficients as 32-bit integers
9899
// Order A1, A2, A3 for each frequency range
@@ -171,6 +172,7 @@ void sync_all_digits_from_values(void)
171172
}
172173

173174
int _calc_interpolating_values(double *x_values, double *y_values,
175+
double *x_values_rev, double *y_values_rev,
174176
uint8_t freq_index, uint32_t local_frequency_MHz, float *position)
175177
{
176178
if (freq_index < FREQUENCY_RANGE_NR - 1) {
@@ -195,6 +197,24 @@ int _calc_interpolating_values(double *x_values, double *y_values,
195197
(float)precision_values[PRECISION_POINTS_FREQ_ALL * freq_index + i * 2 + 1]) *
196198
(*position)) /
197199
PRECISION_SCALE_FACTOR;
200+
x_values_rev[i] = (double)((float)
201+
precision_values_reverse[PRECISION_POINTS_FREQ_ALL *
202+
freq_index + i * 2] +
203+
((float)precision_values_reverse[PRECISION_POINTS_FREQ_ALL *
204+
(freq_index + 1) + i * 2] -
205+
(float)precision_values_reverse[PRECISION_POINTS_FREQ_ALL * freq_index + i * 2])
206+
*
207+
(*position)) /
208+
PRECISION_SCALE_FACTOR;
209+
y_values_rev[i] = (double)((float)
210+
precision_values_reverse[PRECISION_POINTS_FREQ_ALL *
211+
freq_index + i * 2 + 1] +
212+
((float)precision_values_reverse[PRECISION_POINTS_FREQ_ALL *
213+
(freq_index + 1) + i * 2 +
214+
1] -
215+
(float)precision_values[PRECISION_POINTS_FREQ_ALL * freq_index + i * 2 + 1]) *
216+
(*position)) /
217+
PRECISION_SCALE_FACTOR;
198218
}
199219
return 0;
200220
} else if (freq_index == (FREQUENCY_RANGE_NR - 1)) {
@@ -220,11 +240,30 @@ int _calc_interpolating_values(double *x_values, double *y_values,
220240
int32_t curr_y = precision_values[PRECISION_POINTS_FREQ_ALL * curr_range_idx + i
221241
* 2 + 1];
222242

243+
int32_t prev_x_rev = precision_values_reverse[PRECISION_POINTS_FREQ_ALL *
244+
prev_range_idx + i
245+
* 2];
246+
int32_t curr_x_rev = precision_values_reverse[PRECISION_POINTS_FREQ_ALL *
247+
curr_range_idx + i
248+
* 2];
249+
int32_t prev_y_rev = precision_values_reverse[PRECISION_POINTS_FREQ_ALL *
250+
prev_range_idx + i
251+
* 2 + 1];
252+
int32_t curr_y_rev = precision_values_reverse[PRECISION_POINTS_FREQ_ALL *
253+
curr_range_idx + i
254+
* 2 + 1];
255+
223256
// Linear extrapolation: value = curr + (curr - prev) * extrap_factor
224257
x_values[i] = (double)((float)curr_x + (float)(curr_x - prev_x) *
225258
extrap_factor) / PRECISION_SCALE_FACTOR;
226259
y_values[i] = (double)((float)curr_y + (float)(curr_y - prev_y) *
227260
extrap_factor) / PRECISION_SCALE_FACTOR;
261+
x_values_rev[i] = (double)((float)curr_x_rev + (float)(curr_x_rev - prev_x_rev)
262+
*
263+
extrap_factor) / PRECISION_SCALE_FACTOR;
264+
y_values_rev[i] = (double)((float)curr_y_rev + (float)(curr_y_rev - prev_y_rev)
265+
*
266+
extrap_factor) / PRECISION_SCALE_FACTOR;
228267
}
229268
return 0;
230269
} else
@@ -263,9 +302,14 @@ int calculate_power()
263302
static float
264303
temp_corr_coeffs[6]; // Both bottom and top limit coeffs, A1, A2, A3, B1, B2, B3
265304
static double
305+
x_values[PRECISION_POINTS_FREQ]; // Values used for POWER calculations, Y axis points, output power
306+
static double
266307
y_values[PRECISION_POINTS_FREQ]; // Values used for POWER calculations, X axis points, input voltage
267308
static double
268-
x_values[PRECISION_POINTS_FREQ]; // Values used for POWER calculations, Y axis points, output power
309+
x_values_rev[PRECISION_POINTS_FREQ]; // Values used for POWER calculations, Y axis points, output power
310+
static double
311+
y_values_rev[PRECISION_POINTS_FREQ]; // Values used for POWER calculations, X axis points, input voltage
312+
269313
static uint8_t freq_index; // Cached frequency index
270314
int ret;
271315

@@ -287,7 +331,8 @@ int calculate_power()
287331
freq_index++;
288332

289333
// Update interpolating reference points
290-
ret = _calc_interpolating_values(x_values, y_values, freq_index,
334+
ret = _calc_interpolating_values(x_values, y_values, x_values_rev, y_values_rev,
335+
freq_index,
291336
local_frequency_MHz, &position_between_freq_ranges);
292337
if (ret) {
293338
return -EINVAL;
@@ -344,7 +389,7 @@ int calculate_power()
344389
double term = y_values[i];
345390
for (int j = 0; j < PRECISION_POINTS_FREQ; j++) {
346391
if (j != i) {
347-
term *= (VIN1_float - x_values[j]) / (x_values[i] - x_values[j]);
392+
term *= (VIN1_float - x_values_rev[j]) / (x_values_rev[i] - x_values_rev[j]);
348393
}
349394
}
350395
y_1 += term;

projects/eval-powrms/src/examples/example/powrms_data_processing.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ extern int32_t use_eeprom_calibration_data;
113113

114114
// Storage for the 48 precision values as 32-bit integers
115115
extern int32_t precision_values[PRECISION_ARRAY_SIZE];
116+
// Storage for the 48 reverse precision values as 32-bit integers
117+
extern int32_t precision_values_reverse[PRECISION_ARRAY_SIZE];
116118
// External declaration of the temperature precision values array
117119
extern int32_t temperature_precision_values[TEMPERATURE_CORRECTION_COEFFS *
118120
FREQUENCY_RANGE_NR];

0 commit comments

Comments
 (0)