drivers/analog: Fix some data alignment issues in the ADC driver.
This commit is contained in:
parent
552ed255f6
commit
e75e3eb807
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* drivers/analog/adc.c
|
* drivers/analog/adc.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2008-2009, 2016 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2008-2009, 2016-2017 Gregory Nutt. All rights reserved.
|
||||||
* Copyright (C) 2011 Li Zhuoyi. All rights reserved.
|
* Copyright (C) 2011 Li Zhuoyi. All rights reserved.
|
||||||
* Author: Li Zhuoyi <lzyy.cn@gmail.com>
|
* Author: Li Zhuoyi <lzyy.cn@gmail.com>
|
||||||
* Gregory Nutt <gnutt@nuttx.org>
|
* Gregory Nutt <gnutt@nuttx.org>
|
||||||
@ -237,6 +237,14 @@ static ssize_t adc_read(FAR struct file *filep, FAR char *buffer, size_t buflen)
|
|||||||
|
|
||||||
ainfo("buflen: %d\n", (int)buflen);
|
ainfo("buflen: %d\n", (int)buflen);
|
||||||
|
|
||||||
|
/* Determine size of the messages to return.
|
||||||
|
*
|
||||||
|
* REVISIT: What if buflen is 8 does that mean 4 messages of size 2? Or
|
||||||
|
* 2 messages of size 4? What if buflen is 12. Does that mean 3 at size
|
||||||
|
* 4? Or 4 at size 3? The form of the return data should probably really
|
||||||
|
* be specified via IOCTL.
|
||||||
|
*/
|
||||||
|
|
||||||
if (buflen % 5 == 0)
|
if (buflen % 5 == 0)
|
||||||
{
|
{
|
||||||
msglen = 5;
|
msglen = 5;
|
||||||
@ -244,6 +252,7 @@ static ssize_t adc_read(FAR struct file *filep, FAR char *buffer, size_t buflen)
|
|||||||
else if (buflen % 4 == 0)
|
else if (buflen % 4 == 0)
|
||||||
{
|
{
|
||||||
msglen = 4;
|
msglen = 4;
|
||||||
|
}
|
||||||
else if (buflen % 3 == 0)
|
else if (buflen % 3 == 0)
|
||||||
{
|
{
|
||||||
msglen = 3;
|
msglen = 3;
|
||||||
@ -259,6 +268,7 @@ static ssize_t adc_read(FAR struct file *filep, FAR char *buffer, size_t buflen)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
msglen = 5;
|
msglen = 5;
|
||||||
|
}
|
||||||
|
|
||||||
if (buflen >= msglen)
|
if (buflen >= msglen)
|
||||||
{
|
{
|
||||||
@ -315,36 +325,56 @@ static ssize_t adc_read(FAR struct file *filep, FAR char *buffer, size_t buflen)
|
|||||||
|
|
||||||
if (msglen == 1)
|
if (msglen == 1)
|
||||||
{
|
{
|
||||||
/* Only one channel,read highest 8-bits */
|
/* Only one channel, return MS 8-bits of the sample*/
|
||||||
|
|
||||||
buffer[nread] = msg->am_data >> 24;
|
buffer[nread] = msg->am_data >> 24;
|
||||||
}
|
}
|
||||||
else if (msglen == 2)
|
else if (msglen == 2)
|
||||||
{
|
{
|
||||||
/* Only one channel, read highest 16-bits */
|
/* Only one channel, return only the MS 16-bits of the sample.*/
|
||||||
|
|
||||||
*(int16_t *)&buffer[nread] = msg->am_data >> 16;
|
int16_t data16 = msg->am_data >> 16;
|
||||||
|
memcpy(&buffer[nread], &data16, 2);
|
||||||
}
|
}
|
||||||
else if (msglen == 3)
|
else if (msglen == 3)
|
||||||
{
|
{
|
||||||
/* Read channel highest 16-bits */
|
int16_t data16;
|
||||||
|
|
||||||
|
/* Return the channel and the MS 16-bits of the sample. */
|
||||||
|
|
||||||
buffer[nread] = msg->am_channel;
|
buffer[nread] = msg->am_channel;
|
||||||
*(int16_t *)&buffer[nread + 1] = msg->am_data >> 16;
|
data16 = msg->am_data >> 16;
|
||||||
|
memcpy(&buffer[nread + 1], &data16, 2);
|
||||||
}
|
}
|
||||||
else if (msglen == 4)
|
else if (msglen == 4)
|
||||||
{
|
{
|
||||||
/* read channel highest 24-bits */
|
int32_t data24;
|
||||||
|
|
||||||
|
#ifdef CONFIG_ENDIAN_BIG
|
||||||
|
/* In the big endian case, we simply copy the MS three bytes
|
||||||
|
* which are indices: 0-2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
data24 = msg->am_data;
|
||||||
|
#else
|
||||||
|
/* In the little endian case, indices 0-2 correspond to the
|
||||||
|
* the three LS bytes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
data24 = msg->am_data >> 8;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Return the channel and the most significant 24-bits */
|
||||||
|
|
||||||
*(int32_t *)&buffer[nread] = msg->am_data;
|
|
||||||
buffer[nread] = msg->am_channel;
|
buffer[nread] = msg->am_channel;
|
||||||
|
memcpy(&buffer[nread + 1], &data24, 3);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Read all */
|
/* Return the channel and all four bytes of the sample */
|
||||||
|
|
||||||
*(int32_t *)&buffer[nread + 1] = msg->am_data;
|
|
||||||
buffer[nread] = msg->am_channel;
|
buffer[nread] = msg->am_channel;
|
||||||
|
memcpy(&buffer[nread + 1], &msg->am_data, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
nread += msglen;
|
nread += msglen;
|
||||||
|
Loading…
Reference in New Issue
Block a user