24
24
25
25
#include <nuttx/config.h>
26
26
27
+ #include <sys/param.h>
27
28
#include <sys/types.h>
28
29
#include <stdint.h>
29
30
#include <stdbool.h>
@@ -54,6 +55,10 @@ static int adc_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
54
55
static int adc_reset (FAR struct adc_dev_s * dev );
55
56
static int adc_receive (FAR struct adc_dev_s * dev , uint8_t ch ,
56
57
int32_t data );
58
+ static int adc_receive_batch (FAR struct adc_dev_s * dev ,
59
+ FAR const uint8_t * channel ,
60
+ FAR const uint32_t * data ,
61
+ size_t count );
57
62
static void adc_notify (FAR struct adc_dev_s * dev );
58
63
static int adc_poll (FAR struct file * filep , FAR struct pollfd * fds ,
59
64
bool setup );
@@ -79,8 +84,9 @@ static const struct file_operations g_adc_fops =
79
84
80
85
static const struct adc_callback_s g_adc_callback =
81
86
{
82
- adc_receive , /* au_receive */
83
- adc_reset /* au_reset */
87
+ adc_receive , /* au_receive */
88
+ adc_receive_batch , /* au_receive_batch */
89
+ adc_reset /* au_reset */
84
90
};
85
91
86
92
/****************************************************************************
@@ -301,8 +307,8 @@ static ssize_t adc_read(FAR struct file *filep, FAR char *buffer,
301
307
nread = 0 ;
302
308
do
303
309
{
304
- FAR struct adc_msg_s * msg =
305
- & dev -> ad_recv .af_buffer [dev -> ad_recv .af_head ];
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 ];
306
312
307
313
/* Will the next message in the FIFO fit into the user buffer? */
308
314
@@ -317,22 +323,22 @@ static ssize_t adc_read(FAR struct file *filep, FAR char *buffer,
317
323
318
324
/* Feed ADC data to entropy pool */
319
325
320
- add_sensor_randomness (msg -> am_data );
326
+ add_sensor_randomness (data );
321
327
322
328
/* Copy the message to the user buffer */
323
329
324
330
if (msglen == 1 )
325
331
{
326
332
/* Only one channel, return MS 8-bits of the sample. */
327
333
328
- buffer [nread ] = msg -> am_data >> 24 ;
334
+ buffer [nread ] = data >> 24 ;
329
335
}
330
336
else if (msglen == 2 )
331
337
{
332
338
/* Only one channel, return only the MS 16-bits of the sample.
333
339
*/
334
340
335
- int16_t data16 = msg -> am_data >> 16 ;
341
+ int16_t data16 = data >> 16 ;
336
342
memcpy (& buffer [nread ], & data16 , 2 );
337
343
}
338
344
else if (msglen == 3 )
@@ -341,8 +347,8 @@ static ssize_t adc_read(FAR struct file *filep, FAR char *buffer,
341
347
342
348
/* Return the channel and the MS 16-bits of the sample. */
343
349
344
- buffer [nread ] = msg -> am_channel ;
345
- data16 = msg -> am_data >> 16 ;
350
+ buffer [nread ] = channel ;
351
+ data16 = data >> 16 ;
346
352
memcpy (& buffer [nread + 1 ], & data16 , 2 );
347
353
}
348
354
else if (msglen == 4 )
@@ -354,26 +360,26 @@ static ssize_t adc_read(FAR struct file *filep, FAR char *buffer,
354
360
* which are indices: 0-2.
355
361
*/
356
362
357
- data24 = msg -> am_data ;
363
+ data24 = data ;
358
364
#else
359
365
/* In the little endian case, indices 0-2 correspond to the
360
366
* the three LS bytes.
361
367
*/
362
368
363
- data24 = msg -> am_data >> 8 ;
369
+ data24 = data >> 8 ;
364
370
#endif
365
371
366
372
/* Return the channel and the most significant 24-bits */
367
373
368
- buffer [nread ] = msg -> am_channel ;
374
+ buffer [nread ] = channel ;
369
375
memcpy (& buffer [nread + 1 ], & data24 , 3 );
370
376
}
371
377
else
372
378
{
373
379
/* Return the channel and all four bytes of the sample */
374
380
375
- buffer [nread ] = msg -> am_channel ;
376
- memcpy (& buffer [nread + 1 ], & msg -> am_data , 4 );
381
+ buffer [nread ] = channel ;
382
+ memcpy (& buffer [nread + 1 ], & data , 4 );
377
383
}
378
384
379
385
nread += msglen ;
@@ -480,8 +486,8 @@ static int adc_receive(FAR struct adc_dev_s *dev, uint8_t ch, int32_t data)
480
486
{
481
487
/* Add the new, decoded ADC sample at the tail of the FIFO */
482
488
483
- fifo -> af_buffer [fifo -> af_tail ]. am_channel = ch ;
484
- fifo -> af_buffer [fifo -> af_tail ]. am_data = data ;
489
+ fifo -> af_channel [fifo -> af_tail ] = ch ;
490
+ fifo -> af_data [fifo -> af_tail ] = data ;
485
491
486
492
/* Increment the tail of the circular buffer */
487
493
@@ -495,6 +501,63 @@ static int adc_receive(FAR struct adc_dev_s *dev, uint8_t ch, int32_t data)
495
501
return errcode ;
496
502
}
497
503
504
+ /****************************************************************************
505
+ * Name: adc_receive_all
506
+ ****************************************************************************/
507
+
508
+ static int adc_receive_batch (FAR struct adc_dev_s * dev ,
509
+ FAR const uint8_t * channel ,
510
+ FAR const uint32_t * data ,
511
+ size_t count )
512
+ {
513
+ FAR struct adc_fifo_s * fifo = & dev -> ad_recv ;
514
+ size_t used ;
515
+ size_t first ;
516
+ size_t second ;
517
+
518
+ /* Check if adding this new message would over-run the drivers ability to
519
+ * enqueue read data.
520
+ */
521
+
522
+ used = (fifo -> af_tail - fifo -> af_head + CONFIG_ADC_FIFOSIZE )
523
+ % CONFIG_ADC_FIFOSIZE ;
524
+
525
+ if (used + count >= CONFIG_ADC_FIFOSIZE )
526
+ {
527
+ return - ENOMEM ;
528
+ }
529
+
530
+ /* Check if flipping is required and memcopy */
531
+
532
+ first = MIN (count , CONFIG_ADC_FIFOSIZE - fifo -> af_tail );
533
+ second = count - first ;
534
+
535
+ memcpy (& fifo -> af_data [fifo -> af_tail ], data ,
536
+ first * sizeof (uint32_t ));
537
+
538
+ if (channel != NULL )
539
+ {
540
+ memcpy (& fifo -> af_channel [fifo -> af_tail ], channel , first );
541
+ }
542
+
543
+ if (second > 0 )
544
+ {
545
+ memcpy (& fifo -> af_data [0 ], & data [first ],
546
+ second * sizeof (uint32_t ));
547
+
548
+ if (channel != NULL )
549
+ {
550
+ memcpy (& fifo -> af_channel [0 ], & channel [first ], second );
551
+ }
552
+ }
553
+
554
+ fifo -> af_tail = (fifo -> af_tail + count ) % CONFIG_ADC_FIFOSIZE ;
555
+
556
+ adc_notify (dev );
557
+
558
+ return OK ;
559
+ }
560
+
498
561
/****************************************************************************
499
562
* Name: adc_notify
500
563
****************************************************************************/
@@ -655,6 +718,7 @@ static int adc_samples_on_read(FAR struct adc_dev_s *dev)
655
718
656
719
int adc_register (FAR const char * path , FAR struct adc_dev_s * dev )
657
720
{
721
+ FAR struct adc_fifo_s * fifo = & dev -> ad_recv ;
658
722
int ret ;
659
723
660
724
DEBUGASSERT (path != NULL && dev != NULL );
@@ -692,5 +756,9 @@ int adc_register(FAR const char *path, FAR struct adc_dev_s *dev)
692
756
nxmutex_destroy (& dev -> ad_closelock );
693
757
}
694
758
759
+ /* Initialize the af_channale */
760
+
761
+ memset (& fifo -> af_channel [fifo -> af_tail ], 0 , CONFIG_ADC_FIFOSIZE );
762
+
695
763
return ret ;
696
764
}
0 commit comments