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>
This commit is contained in:
parent
e83a47cf6a
commit
8e926134ef
1 changed files with 64 additions and 37 deletions
|
@ -59,33 +59,80 @@ int size_from_channelarray(struct iio_channel_info *channels, int num_channels)
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
void print2byte(int input, struct iio_channel_info *info)
|
void print2byte(uint16_t input, struct iio_channel_info *info)
|
||||||
{
|
{
|
||||||
/* First swap if incorrect endian */
|
/* First swap if incorrect endian */
|
||||||
if (info->be)
|
if (info->be)
|
||||||
input = be16toh((uint16_t)input);
|
input = be16toh(input);
|
||||||
else
|
else
|
||||||
input = le16toh((uint16_t)input);
|
input = le16toh(input);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Shift before conversion to avoid sign extension
|
* Shift before conversion to avoid sign extension
|
||||||
* of left aligned data
|
* of left aligned data
|
||||||
*/
|
*/
|
||||||
input >>= info->shift;
|
input >>= info->shift;
|
||||||
|
input &= info->mask;
|
||||||
if (info->is_signed) {
|
if (info->is_signed) {
|
||||||
int16_t val = input;
|
int16_t val = (int16_t)(input << (16 - info->bits_used)) >>
|
||||||
|
(16 - info->bits_used);
|
||||||
val &= (1 << info->bits_used) - 1;
|
printf("%05f ", ((float)val + info->offset) * info->scale);
|
||||||
val = (int16_t)(val << (16 - info->bits_used)) >>
|
|
||||||
(16 - info->bits_used);
|
|
||||||
printf("%05f ", ((float)val + info->offset)*info->scale);
|
|
||||||
} else {
|
} else {
|
||||||
uint16_t val = input;
|
printf("%05f ", ((float)input + info->offset) * info->scale);
|
||||||
|
|
||||||
val &= (1 << info->bits_used) - 1;
|
|
||||||
printf("%05f ", ((float)val + info->offset)*info->scale);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print4byte(uint32_t input, struct iio_channel_info *info)
|
||||||
|
{
|
||||||
|
/* First swap if incorrect endian */
|
||||||
|
if (info->be)
|
||||||
|
input = be32toh(input);
|
||||||
|
else
|
||||||
|
input = le32toh(input);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shift before conversion to avoid sign extension
|
||||||
|
* of left aligned data
|
||||||
|
*/
|
||||||
|
input >>= info->shift;
|
||||||
|
input &= info->mask;
|
||||||
|
if (info->is_signed) {
|
||||||
|
int32_t val = (int32_t)(input << (32 - info->bits_used)) >>
|
||||||
|
(32 - info->bits_used);
|
||||||
|
printf("%05f ", ((float)val + info->offset) * info->scale);
|
||||||
|
} else {
|
||||||
|
printf("%05f ", ((float)input + info->offset) * info->scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print8byte(uint64_t input, struct iio_channel_info *info)
|
||||||
|
{
|
||||||
|
/* First swap if incorrect endian */
|
||||||
|
if (info->be)
|
||||||
|
input = be64toh(input);
|
||||||
|
else
|
||||||
|
input = le64toh(input);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shift before conversion to avoid sign extension
|
||||||
|
* of left aligned data
|
||||||
|
*/
|
||||||
|
input >>= info->shift;
|
||||||
|
input &= info->mask;
|
||||||
|
if (info->is_signed) {
|
||||||
|
int64_t val = (int64_t)(input << (64 - info->bits_used)) >>
|
||||||
|
(64 - info->bits_used);
|
||||||
|
/* special case for timestamp */
|
||||||
|
if (info->scale == 1.0f && info->offset == 0.0f)
|
||||||
|
printf("%" PRId64 " ", val);
|
||||||
|
else
|
||||||
|
printf("%05f ",
|
||||||
|
((float)val + info->offset) * info->scale);
|
||||||
|
} else {
|
||||||
|
printf("%05f ", ((float)input + info->offset) * info->scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* process_scan() - print out the values in SI units
|
* process_scan() - print out the values in SI units
|
||||||
* @data: pointer to the start of the scan
|
* @data: pointer to the start of the scan
|
||||||
|
@ -108,32 +155,12 @@ void process_scan(char *data,
|
||||||
&channels[k]);
|
&channels[k]);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
if (!channels[k].is_signed) {
|
print4byte(*(uint32_t *)(data + channels[k].location),
|
||||||
uint32_t val = *(uint32_t *)
|
&channels[k]);
|
||||||
(data + channels[k].location);
|
|
||||||
printf("%05f ", ((float)val +
|
|
||||||
channels[k].offset)*
|
|
||||||
channels[k].scale);
|
|
||||||
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
if (channels[k].is_signed) {
|
print8byte(*(uint64_t *)(data + channels[k].location),
|
||||||
int64_t val = *(int64_t *)
|
&channels[k]);
|
||||||
(data +
|
|
||||||
channels[k].location);
|
|
||||||
if ((val >> channels[k].bits_used) & 1)
|
|
||||||
val = (val & channels[k].mask) |
|
|
||||||
~channels[k].mask;
|
|
||||||
/* special case for timestamp */
|
|
||||||
if (channels[k].scale == 1.0f &&
|
|
||||||
channels[k].offset == 0.0f)
|
|
||||||
printf("%" PRId64 " ", val);
|
|
||||||
else
|
|
||||||
printf("%05f ", ((float)val +
|
|
||||||
channels[k].offset)*
|
|
||||||
channels[k].scale);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Add table
Reference in a new issue