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 /tools/iio | |
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>
Diffstat (limited to 'tools/iio')
-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; |