From 984803bc1b06e882bf3cf434fb4deb2ea3b98f65 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Fri, 2 Sep 2016 15:11:45 -0700 Subject: [PATCH] buffer-utils: Fix orientation axis switch using 4.8 kernel Using 4.8-rc kernel, orientation got flipped. The right-up became normal and normal became right-up. The reason for this is that orientation code of iio-sensor-proxy observes x and y swapped (actually they are not in the data provided by IIO). Although it is triggered by some kernel change, the reliance on g_dir_read_name() to get the correct order of channels is not correct. We should look at the in_xxx_x_index field and calculate correct byte offset in the iio buffer data. For example with 4.8 kernel: from log with added index location printed ** (process:4945): DEBUG: Built channel array for in_accel_y: index: 1, is signed: 1, bytes: 4, bits_used: 32, shift: 0, mask: 0x0, be: 0 ** (process:4945): DEBUG: Built channel array for in_accel_x: index: 0, is signed: 1, bytes: 4, bits_used: 32, shift: 0, mask: 0x0, be: 0 ** (process:4945): DEBUG: Built channel array for in_accel_z: index: 2, is signed: 1, bytes: 4, bits_used: 32, shift: 0, mask: 0x0, be: 0 (Here in_accel_y appeared before in_accel_x in g_dir_read_name(), because of that channel array ordering is wrong hence location was calculated wrong as below) ... ... ** (process:4945): DEBUG: process_scan_1: channel_index: 1, chan_name: in_accel_x, channel_data_index: 0 location: 4 ** (process:4945): DEBUG: process_scan_1: channel_index: 0, chan_name: in_accel_y, channel_data_index: 1 location: 0 ** (process:4945): DEBUG: process_scan_1: channel_index: 2, chan_name: in_accel_z, channel_data_index: 2 location: 8 ** (process:4945): DEBUG: Read from IIO: -880449, 32851, -457812 To fix this we need to calculate the byte offset location using channel_index not in the order they are returned by g_dir_read_name(). The easiest fix is to sort the array of channels in build_channel_array() based on index. Also added some debug to print index and location. After the fix, the above log will change to: ** (process:4674): DEBUG: Built channel array for in_accel_x: index: 0, is signed: 1, bytes: 4, bits_used: 32, shift: 0, mask: 0x0, be: 0 ** (process:4674): DEBUG: Built channel array for in_accel_y: index: 1, is signed: 1, bytes: 4, bits_used: 32, shift: 0, mask: 0x0, be: 0 ** (process:4674): DEBUG: Built channel array for in_accel_z: index: 2, is signed: 1, bytes: 4, bits_used: 32, shift: 0, mask: 0x0, be: 0 (Sorted above, so location of byte offset is correct) ** (process:4674): DEBUG: process_scan_1: channel_index: 0, chan_name: in_accel_x, channel_data_index: 0 location: 0 ** (process:4674): DEBUG: process_scan_1: channel_index: 1, chan_name: in_accel_y, channel_data_index: 1 location: 4 ** (process:4674): DEBUG: process_scan_1: channel_index: 2, chan_name: in_accel_z, channel_data_index: 2 location: 8 ** (process:4674): DEBUG: Read from IIO: 34804, -878496, -448046 Closes: #99 --- src/iio-buffer-utils.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/iio-buffer-utils.c b/src/iio-buffer-utils.c index b4eaac7..b825a84 100644 --- a/src/iio-buffer-utils.c +++ b/src/iio-buffer-utils.c @@ -193,6 +193,15 @@ channel_info_free (iio_channel_info *ci) g_free (ci); } +static int +compare_channel_index (gconstpointer a, gconstpointer b) +{ + const iio_channel_info *info_1 = a; + const iio_channel_info *info_2 = b; + + return (int) (info_1->index - info_2->index); +} + /* build_channel_array() - function to figure out what channels are present */ static iio_channel_info ** build_channel_array (const char *device_dir, @@ -298,14 +307,16 @@ build_channel_array (const char *device_dir, g_dir_close (dp); g_free (scan_el_dir); + g_ptr_array_sort (array, compare_channel_index); + *counter = array->len; ret_array = (iio_channel_info **) g_ptr_array_free (array, FALSE); for (i = 0; i < *counter; i++) { iio_channel_info *ci = ret_array[i]; - g_debug ("Built channel array for %s: is signed: %d, bytes: %d, bits_used: %d, shift: %d, mask: 0x%" G_GUINT64_FORMAT ", be: %d", - ci->name, ci->is_signed, ci->bytes, ci->bits_used, ci->shift, ci->mask, ci->be); + g_debug ("Built channel array for %s: index: %d, is signed: %d, bytes: %d, bits_used: %d, shift: %d, mask: 0x%" G_GUINT64_FORMAT ", be: %d", + ci->name, ci->index, ci->is_signed, ci->bytes, ci->bits_used, ci->shift, ci->mask, ci->be); } return ret_array; @@ -474,6 +485,9 @@ process_scan_1 (char *data, if (strcmp (buffer_data->channels[k]->name, ch_name) != 0) continue; + g_debug ("process_scan_1: channel_index: %d, chan_name: %s, channel_data_index: %d location: %d", + k, buffer_data->channels[k]->name, buffer_data->channels[k]->index, buffer_data->channels[k]->location); + switch (buffer_data->channels[k]->bytes) { /* only a few cases implemented so far */ case 4: