Skip to content

Commit 63249f7

Browse files
zhangkai25xiaoxiang781216
authored andcommitted
memcpy data directly without channel at msglen is 4
Signed-off-by: zhangkai25 <[email protected]>
1 parent bfd6185 commit 63249f7

File tree

1 file changed

+81
-72
lines changed

1 file changed

+81
-72
lines changed

drivers/analog/adc.c

Lines changed: 81 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -223,11 +223,12 @@ static int adc_close(FAR struct file *filep)
223223
static ssize_t adc_read(FAR struct file *filep, FAR char *buffer,
224224
size_t buflen)
225225
{
226-
FAR struct inode *inode = filep->f_inode;
227-
FAR struct adc_dev_s *dev = inode->i_private;
226+
FAR struct inode *inode = filep->f_inode;
227+
FAR struct adc_dev_s *dev = inode->i_private;
228+
FAR struct adc_fifo_s *fifo = &dev->ad_recv;
228229
size_t nread;
229230
irqstate_t flags;
230-
int ret = 0;
231+
int ret = 0;
231232
int msglen;
232233

233234
ainfo("buflen: %d\n", (int)buflen);
@@ -267,10 +268,10 @@ static ssize_t adc_read(FAR struct file *filep, FAR char *buffer,
267268

268269
if (buflen >= msglen)
269270
{
270-
/* Interrupts must be disabled while accessing the ad_recv FIFO */
271+
/* Interrupts must be disabled while accessing the fifo FIFO */
271272

272273
flags = enter_critical_section();
273-
while (dev->ad_recv.af_head == dev->ad_recv.af_tail)
274+
while (fifo->af_head == fifo->af_tail)
274275
{
275276
/* Check if there was an overrun, if set we need to return EIO */
276277

@@ -292,106 +293,114 @@ static ssize_t adc_read(FAR struct file *filep, FAR char *buffer,
292293
/* Wait for a message to be received */
293294

294295
dev->ad_nrxwaiters++;
295-
ret = nxsem_wait(&dev->ad_recv.af_sem);
296+
ret = nxsem_wait(&fifo->af_sem);
296297
dev->ad_nrxwaiters--;
297298
if (ret < 0)
298299
{
299300
goto return_with_irqdisabled;
300301
}
301302
}
302303

303-
/* The ad_recv FIFO is not empty. Copy all buffered data that will fit
304+
/* The FIFO is not empty. Copy all buffered data that will fit
304305
* in the user buffer.
305306
*/
306307

307-
nread = 0;
308-
do
308+
if (msglen == 4)
309309
{
310-
uint8_t channel = dev->ad_recv.af_channel[dev->ad_recv.af_head];
311-
int32_t data = dev->ad_recv.af_data[dev->ad_recv.af_head];
312-
313-
/* Will the next message in the FIFO fit into the user buffer? */
314-
315-
if (nread + msglen > buflen)
316-
{
317-
/* No.. break out of the loop now with nread equal to the
318-
* actual number of bytes transferred.
319-
*/
310+
size_t first;
311+
size_t second;
312+
size_t count;
313+
size_t used;
320314

321-
break;
322-
}
315+
used = (fifo->af_tail - fifo->af_head + CONFIG_ADC_FIFOSIZE)
316+
% CONFIG_ADC_FIFOSIZE;
317+
count = MIN(used, buflen / msglen);
323318

324-
/* Feed ADC data to entropy pool */
319+
/* Check if flipping is required and memcopy */
325320

326-
add_sensor_randomness(data);
321+
first = MIN(CONFIG_ADC_FIFOSIZE - fifo->af_head, count);
322+
second = count - first;
323+
memcpy(buffer, &fifo->af_data[fifo->af_head], first * 4);
327324

328-
/* Copy the message to the user buffer */
329-
330-
if (msglen == 1)
325+
if (second > 0)
331326
{
332-
/* Only one channel, return MS 8-bits of the sample. */
333-
334-
buffer[nread] = data >> 24;
327+
memcpy(&buffer[4 * first], &fifo->af_data[0], second * 4);
335328
}
336-
else if (msglen == 2)
329+
330+
fifo->af_head = (fifo->af_head + count) % CONFIG_ADC_FIFOSIZE;
331+
nread = count * msglen;
332+
}
333+
else
334+
{
335+
nread = 0;
336+
do
337337
{
338-
/* Only one channel, return only the MS 16-bits of the sample.
338+
uint8_t channel = fifo->af_channel[fifo->af_head];
339+
int32_t data = fifo->af_data[fifo->af_head];
340+
341+
/* Will the next message in the FIFO fit into
342+
* the user buffer?
339343
*/
340344

341-
int16_t data16 = data >> 16;
342-
memcpy(&buffer[nread], &data16, 2);
343-
}
344-
else if (msglen == 3)
345-
{
346-
int16_t data16;
345+
if (nread + msglen > buflen)
346+
{
347+
/* No.. break out of the loop now with nread equal to the
348+
* actual number of bytes transferred.
349+
*/
347350

348-
/* Return the channel and the MS 16-bits of the sample. */
351+
break;
352+
}
349353

350-
buffer[nread] = channel;
351-
data16 = data >> 16;
352-
memcpy(&buffer[nread + 1], &data16, 2);
353-
}
354-
else if (msglen == 4)
355-
{
356-
int32_t data24;
354+
/* Feed ADC data to entropy pool */
357355

358-
#ifdef CONFIG_ENDIAN_BIG
359-
/* In the big endian case, we simply copy the MS three bytes
360-
* which are indices: 0-2.
361-
*/
356+
add_sensor_randomness(data);
362357

363-
data24 = data;
364-
#else
365-
/* In the little endian case, indices 0-2 correspond to the
366-
* the three LS bytes.
367-
*/
358+
/* Copy the message to the user buffer */
368359

369-
data24 = data >> 8;
370-
#endif
360+
if (msglen == 1)
361+
{
362+
/* Only one channel, return MS 8-bits of the sample. */
371363

372-
/* Return the channel and the most significant 24-bits */
364+
buffer[nread] = data >> 24;
365+
}
366+
else if (msglen == 2)
367+
{
368+
/* Only one channel, return only the
369+
* MS 16-bits of the sample.
370+
*/
373371

374-
buffer[nread] = channel;
375-
memcpy(&buffer[nread + 1], &data24, 3);
376-
}
377-
else
378-
{
379-
/* Return the channel and all four bytes of the sample */
372+
int16_t data16 = data >> 16;
373+
memcpy(&buffer[nread], &data16, 2);
374+
}
375+
else if (msglen == 3)
376+
{
377+
int16_t data16;
380378

381-
buffer[nread] = channel;
382-
memcpy(&buffer[nread + 1], &data, 4);
383-
}
379+
/* Return the channel and the MS 16-bits of the sample. */
384380

385-
nread += msglen;
381+
buffer[nread] = channel;
382+
data16 = data >> 16;
383+
memcpy(&buffer[nread + 1], &data16, 2);
384+
}
385+
else
386+
{
387+
/* Return the channel and all four bytes of the sample */
386388

387-
/* Increment the head of the circular message buffer */
389+
buffer[nread] = channel;
390+
memcpy(&buffer[nread + 1], &data, 4);
391+
}
388392

389-
if (++dev->ad_recv.af_head >= CONFIG_ADC_FIFOSIZE)
390-
{
391-
dev->ad_recv.af_head = 0;
393+
nread += msglen;
394+
395+
/* Increment the head of the circular message buffer */
396+
397+
if (++fifo->af_head >= CONFIG_ADC_FIFOSIZE)
398+
{
399+
fifo->af_head = 0;
400+
}
392401
}
402+
while (fifo->af_head != fifo->af_tail);
393403
}
394-
while (dev->ad_recv.af_head != dev->ad_recv.af_tail);
395404

396405
/* All of the messages have been transferred. Return the number of
397406
* bytes that were read.

0 commit comments

Comments
 (0)