diff options
| author | Hartmut Knaack <knaack.h@gmx.de> | 2015-05-31 08:39:58 -0400 |
|---|---|---|
| committer | Jonathan Cameron <jic23@kernel.org> | 2015-05-31 12:42:32 -0400 |
| commit | 8e926134ef15267f65ddfc7389c8078234610295 (patch) | |
| tree | 866310be47f3ce9c7b2045eeafdf33d750825462 | |
| parent | e83a47cf6a5bdbd3d5677db13ae4df22f5e24b08 (diff) | |
tools:iio:generic_buffer: sign-extend and shift data
Refactor process_scan() to handle signed and unsigned data, respect shifts
and the data mask for 2, 4 and 8 byte sized scan elements.
Signed-off-by: Hartmut Knaack <knaack.h@gmx.de>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
| -rw-r--r-- | tools/iio/generic_buffer.c | 97 |
1 files changed, 62 insertions, 35 deletions
diff --git a/tools/iio/generic_buffer.c b/tools/iio/generic_buffer.c index 419e22736c3a..4cd246426b57 100644 --- a/tools/iio/generic_buffer.c +++ b/tools/iio/generic_buffer.c | |||
| @@ -59,33 +59,80 @@ int size_from_channelarray(struct iio_channel_info *channels, int num_channels) | |||
| 59 | return bytes; | 59 | return bytes; |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | void print2byte(int input, struct iio_channel_info *info) | 62 | void print2byte(uint16_t input, struct iio_channel_info *info) |
| 63 | { | 63 | { |
| 64 | /* First swap if incorrect endian */ | 64 | /* First swap if incorrect endian */ |
| 65 | if (info->be) | 65 | if (info->be) |
| 66 | input = be16toh((uint16_t)input); | 66 | input = be16toh(input); |
| 67 | else | 67 | else |
| 68 | input = le16toh((uint16_t)input); | 68 | input = le16toh(input); |
| 69 | 69 | ||
| 70 | /* | 70 | /* |
| 71 | * Shift before conversion to avoid sign extension | 71 | * Shift before conversion to avoid sign extension |
| 72 | * of left aligned data | 72 | * of left aligned data |
| 73 | */ | 73 | */ |
| 74 | input >>= info->shift; | 74 | input >>= info->shift; |
| 75 | input &= info->mask; | ||
| 75 | if (info->is_signed) { | 76 | if (info->is_signed) { |
| 76 | int16_t val = input; | 77 | int16_t val = (int16_t)(input << (16 - info->bits_used)) >> |
| 78 | (16 - info->bits_used); | ||
| 79 | printf("%05f ", ((float)val + info->offset) * info->scale); | ||
| 80 | } else { | ||
| 81 | printf("%05f ", ((float)input + info->offset) * info->scale); | ||
| 82 | } | ||
| 83 | } | ||
| 77 | 84 | ||
| 78 | val &= (1 << info->bits_used) - 1; | 85 | void print4byte(uint32_t input, struct iio_channel_info *info) |
| 79 | val = (int16_t)(val << (16 - info->bits_used)) >> | 86 | { |
| 80 | (16 - info->bits_used); | 87 | /* First swap if incorrect endian */ |
| 81 | printf("%05f ", ((float)val + info->offset)*info->scale); | 88 | if (info->be) |
| 89 | input = be32toh(input); | ||
| 90 | else | ||
| 91 | input = le32toh(input); | ||
| 92 | |||
| 93 | /* | ||
| 94 | * Shift before conversion to avoid sign extension | ||
| 95 | * of left aligned data | ||
| 96 | */ | ||
| 97 | input >>= info->shift; | ||
| 98 | input &= info->mask; | ||
| 99 | if (info->is_signed) { | ||
| 100 | int32_t val = (int32_t)(input << (32 - info->bits_used)) >> | ||
| 101 | (32 - info->bits_used); | ||
| 102 | printf("%05f ", ((float)val + info->offset) * info->scale); | ||
| 82 | } else { | 103 | } else { |
| 83 | uint16_t val = input; | 104 | printf("%05f ", ((float)input + info->offset) * info->scale); |
| 105 | } | ||
| 106 | } | ||
| 84 | 107 | ||
| 85 | val &= (1 << info->bits_used) - 1; | 108 | void print8byte(uint64_t input, struct iio_channel_info *info) |
| 86 | printf("%05f ", ((float)val + info->offset)*info->scale); | 109 | { |
| 110 | /* First swap if incorrect endian */ | ||
| 111 | if (info->be) | ||
| 112 | input = be64toh(input); | ||
| 113 | else | ||
| 114 | input = le64toh(input); | ||
| 115 | |||
| 116 | /* | ||
| 117 | * Shift before conversion to avoid sign extension | ||
| 118 | * of left aligned data | ||
| 119 | */ | ||
| 120 | input >>= info->shift; | ||
| 121 | input &= info->mask; | ||
| 122 | if (info->is_signed) { | ||
| 123 | int64_t val = (int64_t)(input << (64 - info->bits_used)) >> | ||
| 124 | (64 - info->bits_used); | ||
| 125 | /* special case for timestamp */ | ||
| 126 | if (info->scale == 1.0f && info->offset == 0.0f) | ||
| 127 | printf("%" PRId64 " ", val); | ||
| 128 | else | ||
| 129 | printf("%05f ", | ||
| 130 | ((float)val + info->offset) * info->scale); | ||
| 131 | } else { | ||
| 132 | printf("%05f ", ((float)input + info->offset) * info->scale); | ||
| 87 | } | 133 | } |
| 88 | } | 134 | } |
| 135 | |||
| 89 | /** | 136 | /** |
| 90 | * process_scan() - print out the values in SI units | 137 | * process_scan() - print out the values in SI units |
| 91 | * @data: pointer to the start of the scan | 138 | * @data: pointer to the start of the scan |
| @@ -108,32 +155,12 @@ void process_scan(char *data, | |||
| 108 | &channels[k]); | 155 | &channels[k]); |
| 109 | break; | 156 | break; |
| 110 | case 4: | 157 | case 4: |
| 111 | if (!channels[k].is_signed) { | 158 | print4byte(*(uint32_t *)(data + channels[k].location), |
| 112 | uint32_t val = *(uint32_t *) | 159 | &channels[k]); |
| 113 | (data + channels[k].location); | ||
| 114 | printf("%05f ", ((float)val + | ||
| 115 | channels[k].offset)* | ||
| 116 | channels[k].scale); | ||
| 117 | |||
| 118 | } | ||
| 119 | break; | 160 | break; |
| 120 | case 8: | 161 | case 8: |
| 121 | if (channels[k].is_signed) { | 162 | print8byte(*(uint64_t *)(data + channels[k].location), |
| 122 | int64_t val = *(int64_t *) | 163 | &channels[k]); |
| 123 | (data + | ||
| 124 | channels[k].location); | ||
| 125 | if ((val >> channels[k].bits_used) & 1) | ||
| 126 | val = (val & channels[k].mask) | | ||
| 127 | ~channels[k].mask; | ||
| 128 | /* special case for timestamp */ | ||
| 129 | if (channels[k].scale == 1.0f && | ||
| 130 | channels[k].offset == 0.0f) | ||
| 131 | printf("%" PRId64 " ", val); | ||
| 132 | else | ||
| 133 | printf("%05f ", ((float)val + | ||
| 134 | channels[k].offset)* | ||
| 135 | channels[k].scale); | ||
| 136 | } | ||
| 137 | break; | 164 | break; |
| 138 | default: | 165 | default: |
| 139 | break; | 166 | break; |
